[hamradio-commits] [xastir] 01/05: Imported Upstream version 2.0.4

Iain Learmonth irl-guest at moszumanska.debian.org
Sat Nov 15 18:59:04 UTC 2014


This is an automated email from the git hooks/post-receive script.

irl-guest pushed a commit to branch master
in repository xastir.

commit aca251bbd821be1161955f5a46f6c4ae529d48eb
Author: Iain R. Learmonth <irl at fsfe.org>
Date:   Sat Nov 15 18:41:49 2014 +0000

    Imported Upstream version 2.0.4
---
 ABOUT-NLS                                       |   226 +
 AUTHORS                                         |    59 +
 CC_OpenStreetMap_logo.png                       |   Bin 0 -> 5299 bytes
 CC_OpenStreetMap_txt.png                        |   Bin 0 -> 1950 bytes
 COPYING                                         |   340 +
 COPYING.LIB.LESSTIF                             |   481 +
 CanadaTopo250k.geo                              |     2 +
 CanadaTopo50k.geo                               |     2 +
 ChangeLog                                       | 30054 ++++++++++++++++++++++
 DEBUG_LEVELS                                    |   123 +
 Davis/.cvsignore                                |    15 +
 Davis/AUTHORS                                   |    24 +
 Davis/COPYING                                   |   340 +
 Davis/CVS/Entries                               |    11 +
 Davis/CVS/Entries.Log                           |     1 +
 Davis/CVS/Repository                            |     1 +
 Davis/CVS/Root                                  |     1 +
 Davis/ChangeLog                                 |     3 +
 Davis/INSTALL                                   |   232 +
 Davis/Makefile.am                               |    43 +
 Davis/NEWS                                      |     3 +
 Davis/README                                    |   211 +
 Davis/bootstrap.sh                              |    10 +
 Davis/configure.ac                              |    67 +
 Davis/src/.cvsignore                            |     4 +
 Davis/src/CVS/Entries                           |     5 +
 Davis/src/CVS/Repository                        |     1 +
 Davis/src/CVS/Root                              |     1 +
 Davis/src/Makefile.am                           |    14 +
 Davis/src/db2APRS.c                             |  1132 +
 Davis/src/defs.h                                |    14 +
 FAQ                                             |  1270 +
 INSTALL                                         |  1623 ++
 LICENSE                                         |  1775 ++
 LaCrosse/.cvsignore                             |    16 +
 LaCrosse/AUTHORS                                |    26 +
 LaCrosse/COPYING                                |   340 +
 LaCrosse/CVS/Entries                            |    12 +
 LaCrosse/CVS/Entries.Log                        |     2 +
 LaCrosse/CVS/Repository                         |     1 +
 LaCrosse/CVS/Root                               |     1 +
 LaCrosse/ChangeLog                              |     3 +
 LaCrosse/INSTALL                                |   232 +
 LaCrosse/Makefile.am                            |    43 +
 LaCrosse/NEWS                                   |     3 +
 LaCrosse/README                                 |   202 +
 LaCrosse/autom4te.cache/CVS/Entries             |     1 +
 LaCrosse/autom4te.cache/CVS/Repository          |     1 +
 LaCrosse/autom4te.cache/CVS/Root                |     1 +
 LaCrosse/bootstrap.sh                           |    10 +
 LaCrosse/configure.ac                           |    68 +
 LaCrosse/src/.cvsignore                         |     4 +
 LaCrosse/src/CVS/Entries                        |     5 +
 LaCrosse/src/CVS/Repository                     |     1 +
 LaCrosse/src/CVS/Root                           |     1 +
 LaCrosse/src/Makefile.am                        |    15 +
 LaCrosse/src/defs.h                             |    15 +
 LaCrosse/src/open2300db2APRS.c                  |   912 +
 LaCrosse/weatherdump.sql                        |    32 +
 Makefile.am                                     |   153 +
 Makefile.in                                     |  1129 +
 NEWS                                            |    39 +
 OSM_template                                    |    52 +
 README                                          |   629 +
 README.CVS                                      |   414 +
 README.CYGWIN                                   |   857 +
 README.Contributing                             |   327 +
 README.Getting-Started                          |   902 +
 README.MAPS                                     |  1518 ++
 README.OSM_maps                                 |   216 +
 README.win32                                    |  1357 +
 TXRadar.geo                                     |    23 +
 UPGRADE                                         |    95 +
 USRadar.geo                                     |    37 +
 WMSRadar.geo                                    |    17 +
 acinclude.m4                                    |  1106 +
 aclocal.m4                                      |   964 +
 bootstrap.sh                                    |    69 +
 callpass.1                                      |    29 +
 callpass/Makefile.am                            |    13 +
 callpass/Makefile.in                            |   501 +
 callpass/callpass.c                             |    81 +
 config.guess                                    |  1511 ++
 config.h.in                                     |   661 +
 config.sub                                      |  1705 ++
 config/24kgrid.dbfawk                           |    42 +
 config/Makefile.am                              |   130 +
 config/Makefile.in                              |   534 +
 config/OSM_Cloudmade_administrative.dbfawk      |    59 +
 config/OSM_Cloudmade_highway.dbfawk             |   106 +
 config/OSM_Cloudmade_natural.dbfawk             |    58 +
 config/OSM_Cloudmade_poi.dbfawk                 |    62 +
 config/OSM_Cloudmade_water_and_coastline.dbfawk |    59 +
 config/arealm.dbfawk                            |    53 +
 config/areawater.dbfawk                         |    52 +
 config/cousub.dbfawk                            |    52 +
 config/cousub00.dbfawk                          |    51 +
 config/edge.dbfawk                              |    87 +
 config/featnames.dbfawk                         |    87 +
 config/gfe_coastal_waters.dbfawk                |    42 +
 config/gfe_coastal_waters_warnings.dbfawk       |    42 +
 config/gfe_fire_weather.dbfawk                  |    42 +
 config/gfe_metro_areas.dbfawk                   |    42 +
 config/gfe_public_weather.dbfawk                |    42 +
 config/gps_wpt.dbfawk                           |    20 +
 config/language-Dutch.sys                       |  1372 +
 config/language-ElmerFudd.sys                   |  1143 +
 config/language-English.sys                     |  1352 +
 config/language-French.sys                      |  1366 +
 config/language-German.sys                      |  1363 +
 config/language-Italian.sys                     |  1354 +
 config/language-MuppetsChef.sys                 |  1143 +
 config/language-OldeEnglish.sys                 |  1143 +
 config/language-PigLatin.sys                    |  1143 +
 config/language-PirateEnglish.sys               |  1143 +
 config/language-Portuguese.sys                  |  1353 +
 config/language-Spanish.sys                     |  1345 +
 config/nwsc_ddmmyy.dbfawk                       |    55 +
 config/nwsc_ddmmyy_09.dbfawk                    |    59 +
 config/nwsc_ddmmyy_09b.dbfawk                   |    59 +
 config/nwsc_ddmmyy_10.dbfawk                    |    59 +
 config/nwsc_ddmmyy_10a.dbfawk                   |    59 +
 config/nwshzddmmyy.dbfawk                       |    42 +
 config/nwsmzddmmyy.dbfawk                       |    41 +
 config/nwsmzddmmyy_09.dbfawk                    |    41 +
 config/nwsmzddmmyy_11.dbfawk                    |    41 +
 config/nwsmzoddmmyy.dbfawk                      |    41 +
 config/nwsozddap12.dbfawk                       |    42 +
 config/nwsozddmmyy.dbfawk                       |    42 +
 config/nwsozddmmyy_09.dbfawk                    |    42 +
 config/nwsw_ddjn12.dbfawk                       |    41 +
 config/nwsw_ddmmyy.dbfawk                       |    41 +
 config/nwsw_ddmmyy_09.dbfawk                    |    41 +
 config/nwsw_ddmmyy_10.dbfawk                    |    41 +
 config/nwsz1ddmmyy.dbfawk                       |    42 +
 config/nwsz_ddmmyy.dbfawk                       |    42 +
 config/nwsz_ddmmyy_09.dbfawk                    |    42 +
 config/nwsz_ddmmyy_10.dbfawk                    |    42 +
 config/nwsz_ddmmyy_10b.dbfawk                   |    42 +
 config/nwsz_ddmmyy_10c.dbfawk                   |    42 +
 config/nwsz_ddmmyy_11.dbfawk                    |    43 +
 config/nwszoddmmyy.dbfawk                       |    42 +
 config/pointlm.dbfawk                           |    63 +
 config/predefined_EVENT.sys                     |   109 +
 config/predefined_SAR.sys                       |   135 +
 config/stored_track.dbfawk                      |    15 +
 config/tabblock.dbfawk                          |    53 +
 config/tgr2shp.dbfawk                           |   263 +
 config/tgr2shppoly.dbfawk                       |   262 +
 config/tgr2shppoly_2006.dbfawk                  |   265 +
 config/tgrcty.dbfawk                            |    48 +
 config/tgrkgl.dbfawk                            |    66 +
 config/tgrlk.dbfawk                             |   247 +
 config/tgrlpt.dbfawk                            |   106 +
 config/tgrlpy.dbfawk                            |    48 +
 config/tgrplc00.dbfawk                          |    38 +
 config/tgrwat.dbfawk                            |    49 +
 config/tl_2009_aiannh.dbfawk                    |    52 +
 config/tl_2009_aits.dbfawk                      |    52 +
 config/tl_2009_arealm.dbfawk                    |   104 +
 config/tl_2009_areawater.dbfawk                 |    74 +
 config/tl_2009_county.dbfawk                    |    55 +
 config/tl_2009_cousub.dbfawk                    |    55 +
 config/tl_2009_edges.dbfawk                     |   100 +
 config/tl_2009_mil.dbfawk                       |    47 +
 config/tl_2009_nn_county.dbfawk                 |    56 +
 config/tl_2009_pointlm.dbfawk                   |   135 +
 config/tl_2009_zcta5.dbfawk                     |    47 +
 config/tnc-startup.aea                          |    47 +
 config/tnc-startup.d700                         |    69 +
 config/tnc-startup.d72_d710                     |    47 +
 config/tnc-startup.kam                          |    43 +
 config/tnc-startup.kpc2                         |    30 +
 config/tnc-startup.kpc3                         |    76 +
 config/tnc-startup.null                         |     0
 config/tnc-startup.paccomm                      |    50 +
 config/tnc-startup.pico                         |    86 +
 config/tnc-startup.sys                          |    56 +
 config/tnc-startup.thd7                         |    79 +
 config/tnc-startup.tnc2                         |    48 +
 config/tnc-startup.tnc2-ui                      |    19 +
 config/tnc-stop.d700                            |    48 +
 config/tnc-stop.d72_d710                        |    39 +
 config/tnc-stop.sys                             |     9 +
 config/tnc-stop.thd7                            |    39 +
 config/tnc-stop.tnc2-ui                         |    12 +
 config/xastir.rgb                               |    92 +
 configure                                       | 14320 +++++++++++
 configure.ac                                    |  1003 +
 depcomp                                         |   630 +
 help/Makefile.am                                |    22 +
 help/Makefile.in                                |   430 +
 help/help-Dutch.dat                             |  3099 +++
 help/help-English.dat                           |  3099 +++
 help/help-French.dat                            |   593 +
 help/help-German.dat                            |  1957 ++
 help/help-Italian.dat                           |  1047 +
 help/help-Portuguese.dat                        |  3099 +++
 help/help-Spanish.dat                           |  1681 ++
 install-sh                                      |   520 +
 m4/Makefile.am                                  |     5 +
 m4/Makefile.in                                  |   364 +
 m4/xmhtml.m4                                    |   215 +
 missing                                         |   376 +
 mkinstalldirs                                   |   162 +
 placeholder                                     |     5 +
 scripts/Coordinate.pm                           |  2465 ++
 scripts/Makefile.am                             |    52 +
 scripts/Makefile.in                             |   467 +
 scripts/Xastir_tigerpoly.py                     |   562 +
 scripts/coord-convert.pl                        |   280 +
 scripts/geopdf2gtiff.pl                         |   231 +
 scripts/get-BOMdata                             |    95 +
 scripts/get-NWSdata                             |    91 +
 scripts/get-fcc-rac.pl                          |   141 +
 scripts/get-gnis                                |    75 +
 scripts/get-maptools.sh                         |   370 +
 scripts/get-pop                                 |    81 +
 scripts/get_shapelib.sh                         |   189 +
 scripts/gpx2shape                               |   218 +
 scripts/icontable.pl                            |   158 +
 scripts/inf2geo.pl                              |   249 +
 scripts/kiss-off.pl                             |    40 +
 scripts/langElmerFudd.pl                        |    94 +
 scripts/langMuppetsChef.pl                      |   145 +
 scripts/langOldeEnglish.pl                      |   129 +
 scripts/langPigLatin.pl                         |    85 +
 scripts/langPirateEnglish.pl                    |   545 +
 scripts/mapblast2geo.pl                         |   200 +
 scripts/mapfgd.pl                               |   258 +
 scripts/object2shp.pl                           |   147 +
 scripts/overlay.pl                              |   248 +
 scripts/ozi2geo.pl                              |   211 +
 scripts/permutations.pl                         |   391 +
 scripts/pos2shp.pl                              |   162 +
 scripts/ridge_radar.pl                          |    62 +
 scripts/slideshow.pl                            |    90 +
 scripts/split_gnis.bash                         |    61 +
 scripts/split_gnis.pl                           |    35 +
 scripts/test_coord.pl                           |   151 +
 scripts/toporama250k.pl                         |   276 +
 scripts/toporama50k.pl                          |   195 +
 scripts/track-get.pl                            |   163 +
 scripts/update_langfile.pl                      |   117 +
 scripts/values                                  |     2 +
 scripts/values.in                               |     2 +
 scripts/values.pl                               |     8 +
 scripts/values.pl.in                            |     8 +
 scripts/waypoint-get.pl                         |   165 +
 scripts/xastir-fixcfg.sh                        |    34 +
 scripts/xastir-migrate.sh                       |    60 +
 src/Makefile.am                                 |   103 +
 src/Makefile.in                                 |   837 +
 src/alert.c                                     |  2275 ++
 src/alert.h                                     |    98 +
 src/awk.c                                       |  1111 +
 src/awk.h                                       |   127 +
 src/bulletin_gui.c                              |   804 +
 src/bulletin_gui.h                              |    38 +
 src/color.c                                     |   304 +
 src/color.h                                     |    53 +
 src/compiledate.c                               |     1 +
 src/database.h                                  |   669 +
 src/datum.c                                     |   818 +
 src/datum.h                                     |   112 +
 src/db.c                                        | 19490 ++++++++++++++
 src/db_gis.c                                    |  2675 ++
 src/db_gis.h                                    |   176 +
 src/dbfawk.c                                    |   498 +
 src/dbfawk.h                                    |    65 +
 src/draw_symbols.c                              |  3547 +++
 src/draw_symbols.h                              |    77 +
 src/fcc_data.c                                  |   503 +
 src/fcc_data.h                                  |    90 +
 src/festival.c                                  |   476 +
 src/festival.h                                  |   102 +
 src/fetch_remote.c                              |   267 +
 src/fetch_remote.h                              |    40 +
 src/geo-find.c                                  |   529 +
 src/geo.h                                       |    49 +
 src/geocoder_gui.c                              |   572 +
 src/gps.c                                       |   874 +
 src/gps.h                                       |    44 +
 src/hashtable.c                                 |   277 +
 src/hashtable.h                                 |   194 +
 src/hashtable_itr.c                             |   212 +
 src/hashtable_itr.h                             |   123 +
 src/hashtable_private.h                         |    80 +
 src/hostname.c                                  |   347 +
 src/hostname.h                                  |    33 +
 src/icon.xbm                                    |    20 +
 src/igate.c                                     |  1443 ++
 src/igate.h                                     |    41 +
 src/interface.c                                 | 10181 ++++++++
 src/interface.h                                 |   276 +
 src/interface_gui.c                             |  9146 +++++++
 src/io-common.c                                 |    70 +
 src/io-mmap.c                                   |   218 +
 src/io.h                                        |    54 +
 src/lang.c                                      |   255 +
 src/lang.h                                      |    39 +
 src/leak_detection.h                            |   101 +
 src/list_gui.c                                  |  2489 ++
 src/list_gui.h                                  |    50 +
 src/locate_gui.c                                |  1220 +
 src/location.c                                  |   104 +
 src/location_gui.c                              |   592 +
 src/main.c                                      | 28028 ++++++++++++++++++++
 src/main.h                                      |   463 +
 src/map_OSM.c                                   |  1655 ++
 src/map_OSM.h                                   |    60 +
 src/map_WMS.c                                   |  1042 +
 src/map_cache.c                                 |  1059 +
 src/map_cache.h                                 |    79 +
 src/map_dos.c                                   |  1364 +
 src/map_gdal.c                                  |  5087 ++++
 src/map_geo.c                                   |  2550 ++
 src/map_gnis.c                                  |  1405 +
 src/map_pdb.c                                   |   585 +
 src/map_pop.c                                   |  1405 +
 src/map_shp.c                                   |  4182 +++
 src/map_tif.c                                   |  2824 ++
 src/map_tiger.c                                 |   969 +
 src/maps.c                                      |  9061 +++++++
 src/maps.h                                      |   230 +
 src/messages.c                                  |  1480 ++
 src/messages.h                                  |   123 +
 src/messages_gui.c                              |  2673 ++
 src/objects.c                                   | 11106 ++++++++
 src/objects.h                                   |   160 +
 src/popup.h                                     |    47 +
 src/popup_gui.c                                 |   382 +
 src/rac_data.c                                  |   386 +
 src/rac_data.h                                  |    63 +
 src/rotated.c                                   |  1618 ++
 src/rotated.h                                   |    89 +
 src/rpl_malloc.c                                |    59 +
 src/rpl_malloc.h                                |    37 +
 src/rtree/Makefile.am                           |    13 +
 src/rtree/Makefile.in                           |   476 +
 src/rtree/card.c                                |    52 +
 src/rtree/card.h                                |    49 +
 src/rtree/index.c                               |   367 +
 src/rtree/index.h                               |   130 +
 src/rtree/node.c                                |   285 +
 src/rtree/rect.c                                |   393 +
 src/rtree/split_l.c                             |   408 +
 src/rtree/split_l.h                             |    54 +
 src/shapelib/ChangeLog                          |   204 +
 src/shapelib/LICENSE.LGPL                       |   483 +
 src/shapelib/Makefile.am                        |    42 +
 src/shapelib/Makefile.in                        |   724 +
 src/shapelib/README                             |    35 +
 src/shapelib/README.tree                        |   172 +
 src/shapelib/contrib/Makefile.am                |    51 +
 src/shapelib/contrib/Makefile.in                |   627 +
 src/shapelib/contrib/Makefile_orig              |    59 +
 src/shapelib/contrib/ShapeFileII.pas            |   254 +
 src/shapelib/contrib/dbfcat.c                   |   209 +
 src/shapelib/contrib/dbfinfo.c                  |   135 +
 src/shapelib/contrib/makefile.vc                |    29 +
 src/shapelib/contrib/my_nan.h                   |    56 +
 src/shapelib/contrib/shpcat.c                   |    99 +
 src/shapelib/contrib/shpcentrd.c                |   190 +
 src/shapelib/contrib/shpdata.c                  |   164 +
 src/shapelib/contrib/shpdxf.c                   |   328 +
 src/shapelib/contrib/shpfix.c                   |   111 +
 src/shapelib/contrib/shpgeo.c                   |  1642 ++
 src/shapelib/contrib/shpgeo.h                   |   177 +
 src/shapelib/contrib/shpinfo.c                  |   147 +
 src/shapelib/contrib/shpproj.c                  |   297 +
 src/shapelib/contrib/shpwkb.c                   |   160 +
 src/shapelib/dbf_api.html                       |   408 +
 src/shapelib/dbfadd.c                           |   151 +
 src/shapelib/dbfcreate.c                        |   150 +
 src/shapelib/dbfdump.c                          |   305 +
 src/shapelib/dbfopen.c                          |  1526 ++
 src/shapelib/libtool                            |  4149 +++
 src/shapelib/makefile.vc                        |    55 +
 src/shapelib/makeshape.sh                       |    21 +
 src/shapelib/mkinstalldirs                      |    38 +
 src/shapelib/shapefil.h                         |   507 +
 src/shapelib/shapelib.def                       |    42 +
 src/shapelib/shapelib.html                      |   334 +
 src/shapelib/shp_api.html                       |   376 +
 src/shapelib/shpadd.c                           |   197 +
 src/shapelib/shpcreate.c                        |   138 +
 src/shapelib/shpdump.c                          |   234 +
 src/shapelib/shpopen.c                          |  1892 ++
 src/shapelib/shprewind.c                        |   140 +
 src/shapelib/shptest.c                          |   333 +
 src/shapelib/shptree.c                          |   705 +
 src/shapelib/shptreedump.c                      |   430 +
 src/shapelib/shputils.c                         |  1124 +
 src/shapelib/stream1.out                        |  1465 ++
 src/shapelib/stream1.sh                         |    28 +
 src/shapelib/stream2.out                        |   530 +
 src/shapelib/stream2.sh                         |    11 +
 src/shapelib/stream3.out                        |    37 +
 src/shp_hash.c                                  |   390 +
 src/shp_hash.h                                  |    39 +
 src/snprintf.c                                  |   747 +
 src/snprintf.h                                  |    59 +
 src/sound.c                                     |   124 +
 src/symbols.h                                   |    33 +
 src/testdbfawk.c                                |   282 +
 src/tile_mgmnt.c                                |   355 +
 src/tile_mgmnt.h                                |    63 +
 src/track_gui.c                                 |  1007 +
 src/track_gui.h                                 |    42 +
 src/util.c                                      |  5738 +++++
 src/util.h                                      |   179 +
 src/view_message_gui.c                          |   732 +
 src/wx.c                                        |  3770 +++
 src/wx.h                                        |    79 +
 src/wx_gui.c                                    |  2116 ++
 src/x_spider.c                                  |  1725 ++
 src/x_spider.h                                  |    48 +
 src/xa_config.c                                 |  2489 ++
 src/xa_config.h                                 |    35 +
 src/xastir.h                                    |   270 +
 src/xastir_udp_client.c                         |   212 +
 symbols/13pct.xbm                               |     5 +
 symbols/25pct.xbm                               |     5 +
 symbols/2x2.xbm                                 |     5 +
 symbols/Makefile.am                             |     8 +
 symbols/Makefile.in                             |   414 +
 symbols/alert.xbm                               |    41 +
 symbols/flood.xbm                               |    41 +
 symbols/icon.png                                |   Bin 0 -> 313 bytes
 symbols/red_flag.xbm                            |    41 +
 symbols/snow.xbm                                |    41 +
 symbols/symbols.dat                             |  4758 ++++
 symbols/torndo.xbm                              |    41 +
 symbols/wind.xbm                                |    41 +
 symbols/winter_storm.xbm                        |    41 +
 symbols/winter_weather.xbm                      |    41 +
 terraserver-reflectivity.geo                    |     2 +
 terraserver-topo.geo                            |     2 +
 terraserver-urban.geo                           |     2 +
 terraserver.geo                                 |     2 +
 testdbfawk.1                                    |    48 +
 worldhi.map                                     |   Bin 0 -> 274556 bytes
 xastir-lsb.spec.in                              |   108 +
 xastir-min.spec                                 |    77 +
 xastir-min.spec.in                              |    77 +
 xastir.1                                        |   108 +
 xastir.spec                                     |    77 +
 xastir.spec.in                                  |    77 +
 xastir_udp_client.1                             |    43 +
 450 files changed, 314202 insertions(+)

diff --git a/ABOUT-NLS b/ABOUT-NLS
new file mode 100644
index 0000000..28d38c7
--- /dev/null
+++ b/ABOUT-NLS
@@ -0,0 +1,226 @@
+Notes on the Free Translation Project
+*************************************
+
+   Free software is going international!  The Free Translation Project
+is a way to get maintainers of free software, translators, and users all
+together, so that will gradually become able to speak many languages.
+A few packages already provide translations for their messages.
+
+   If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site.  But you do *not*
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+   Installers will find here some useful hints.  These notes also
+explain how users should proceed for getting the programs to use the
+available translations.  They tell how people wanting to contribute and
+work at translations should contact the appropriate team.
+
+   When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used.  The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+One advise in advance
+=====================
+
+   If you want to exploit the full power of internationalization, you
+should configure it using
+
+     ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed.  So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias or message inheritance) as the
+implementation here.  It is also not possible to offer this additional
+functionality on top of a `catgets' implementation.  Future versions of
+GNU `gettext' will very likely convey even more functionality.  So it
+might be a good idea to change to GNU `gettext' as soon as possible.
+
+   So you need not provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+INSTALL Matters
+===============
+
+   Some packages are "localizable" when properly installed; the
+programs they contain can be made to speak your own native language.
+Most such packages use GNU `gettext'.  Other packages have their own
+ways to internationalization, predating GNU `gettext'.
+
+   By default, this package will be installed to allow translation of
+messages.  It will automatically detect whether the system provides
+usable `catgets' (if using this is selected by the installer) or
+`gettext' functions.  If neither is available, the GNU `gettext' own
+library will be used.  This library is wholly contained within this
+package, usually in the `intl/' subdirectory, so prior installation of
+the GNU `gettext' package is *not* required.  Installers may use
+special options at configuration time for changing the default
+behaviour.  The commands:
+
+     ./configure --with-included-gettext
+     ./configure --with-catgets
+     ./configure --disable-nls
+
+will respectively bypass any pre-existing `catgets' or `gettext' to use
+the internationalizing routines provided within this package, enable
+the use of the `catgets' functions (if found on the locale system), or
+else, *totally* disable translation of messages.
+
+   When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this.  This might be not what is desirable.  You
+should use the more recent version of the GNU `gettext' library.  I.e.
+if the file `intl/VERSION' shows that the library which comes with this
+package is more recent, you should use
+
+     ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+   By default the configuration process will not test for the `catgets'
+function and therefore they will not be used.  The reasons are already
+given above: the emulation on top of `catgets' cannot provide all the
+extensions provided by the GNU `gettext' library.  If you nevertheless
+want to use the `catgets' functions use
+
+     ./configure --with-catgets
+
+to enable the test for `catgets' (this causes no harm if `catgets' is
+not available on your system).  If you really select this option we
+would like to hear about the reasons because we cannot think of any
+good one ourself.
+
+   Internationalized packages have usually many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language.  Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package.  However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+Using This Package
+==================
+
+   As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+ISO 639 `LL' two-letter code prior to using the programs in the
+package.  For example, let's suppose that you speak German.  At the
+shell prompt, merely execute `setenv LANG de' (in `csh'),
+`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash').  This
+can be done from your `.login' or `.profile' file, once and for all.
+
+   An operating system might already offer message localization for
+many of its programs, while other programs have been installed locally
+with the full capabilities of GNU `gettext'.  Just using `gettext'
+extended syntax for `LANG' would break proper localization of already
+available operating system programs.  In this case, users should set
+both `LANGUAGE' and `LANG' variables in their environment, as programs
+using GNU `gettext' give preference to `LANGUAGE'.  For example, some
+Swedish users would rather read translations in German than English for
+when Swedish is not available.  This is easily accomplished by setting
+`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'.
+
+Translating Teams
+=================
+
+   For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list, courtesy of Linux
+International.  You may reach your translation team at the address
+`LL at li.org', replacing LL by the two-letter ISO 639 code for your
+language.  Language codes are *not* the same as the country codes given
+in ISO 3166.  The following translation teams exist, as of December
+1997:
+
+     Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en',
+     Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian
+     `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja',
+     Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish
+     `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es',
+     Swedish `sv', and Turkish `tr'.
+
+For example, you may reach the Chinese translation team by writing to
+`zh at li.org'.
+
+   If you'd like to volunteer to *work* at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is *not* the same as the list itself, it has
+`-request' appended.  For example, speakers of Swedish can send a
+message to `sv-request at li.org', having this message body:
+
+     subscribe
+
+   Keep in mind that team members are expected to participate
+*actively* in translations, or at solving translational difficulties,
+rather than merely lurking around.  If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `translation at iro.umontreal.ca' to reach the
+coordinator for all translator teams.
+
+   The English team is special.  It works at improving and uniformizing
+the terminology in use.  Proven linguistic skill are praised more than
+programming skill, here.
+
+Available Packages
+==================
+
+   Languages are not equally supported in all packages.  The following
+matrix shows the current state of internationalization, as of December
+1997.  The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination.
+
+     Ready PO files    cs da de en es fi fr it ja ko nl no pl pt ru sl sv
+                     .----------------------------------------------------.
+     bash            |       []          []          []                   |  3
+     bison           |       []          []          []                   |  3
+     clisp           |       [] [] []    []                               |  4
+     cpio            |       []    []    []       [] []    []             |  6
+     diffutils       |       []    []    []                []          [] |  5
+     enscript        |       []    [] [] []          []             []    |  6
+     fileutils       | []    []    []    []       [] []    [] []    [] [] | 10
+     findutils       |       []    []    [] []    [] []    []    []    [] |  9
+     flex            |             []    []       []                   [] |  4
+     gcal            |       []          []          []    []          [] |  5
+     gettext         |    [] []    []    []       [] [] [] [] []    [] [] | 12
+     grep            |       []    []    []       [] [] [] []    [] [] [] | 10
+     hello           |    [] []    []    []       [] [] [] [] []    [] [] | 11
+     id-utils        |       []          []                []             |  3
+     indent          |    [] []                   []       []    []       |  5
+     libc            |       []    []    []       [] []    []          [] |  7
+     m4              |       []          []    []    []          []    [] |  6
+     make            |       []    []    []       [] []    []             |  6
+     music           |                   []                []             |  2
+     ptx             |       []    []    []          [] [] [] []       [] |  8
+     recode          |    [] []    []    []          []    [] []    [] [] |  9
+     sh-utils        |       []    []    []          [] [] [] []       [] |  8
+     sharutils       | []    []    []    []          []                [] |  6
+     tar             | []    []          [] []    [] [] [] [] []    [] [] | 11
+     texinfo         | []    []          []                               |  3
+     textutils       | []    []    []    []       [] [] [] []          [] |  9
+     wdiff           | []    []    []    []          [] [] []          [] |  8
+                     `----------------------------------------------------'
+       17 languages    cs da de en es fi fr it ja ko nl no pl pt ru sl sv
+       27 packages      6  4 25  1 18  1 26  2  1 12 20  9 19  7  4  7 17  179
+
+   Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect.  This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+   For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer.  There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+   If December 1997 seems to be old, you may fetch a more recent copy
+of this `ABOUT-NLS' file on most GNU archive sites.
+
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..ffa06c6
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,59 @@
+
+$Id: AUTHORS,v 1.25 2012/11/01 18:57:18 we7u Exp $
+
+                        Developers and Contributors
+     _________________________________________________________________
+
+   Here we attempt to list most of the Xastir developers and contributors
+   who have devoted large amounts of time to making Xastir one of the best
+   APRS(tm) clients ever.  Unfortunately we can't devote much time to
+   keeping this list current or adding new contributors.
+
+   Xastir was originally written by Frank Giannandrea, KC2GJS (was KC0DGE).
+
+   APRS(tm) is a Trademark of Bob Bruninga
+
+   Developers and Contributors (in alphabetical order):
+
+   DK7IN    Rolf Bleher
+   HI8GN    Jose R Marte A
+   IK0YUP   Alessandro Frigeri
+   KA6HLD   Jerry Dunmire
+   KA9KIM   Mike Sims
+   KB3EGH   Derrick Brashear
+   KB3EHW   Reuven Gevaryahu (our resident docs guy!)
+   KC2ELS   Jack Twilley
+   KD5AMB   Mark Grennan
+   KD6VPE   Jim Sevilla
+   KD6ZWR   Chris Bell
+   KE4NFJ   Gerald Stueve (K4INT)
+   KG4IJB   Charles Byam (fearless leader)
+   KM5VY    Tom Russo
+   N0VH     Jim Chandler
+   N2YGK    Alan Crosswell
+   N3NYN    Michael G Petry
+   N7IPB    Ken Koster
+   N7TAP    Olivier Calle
+   N8YSZ    Dan Brown
+   PE1DNN   Henk de Groot
+   VE3UNW   Richard Hagemyer
+   VE6LFM   Lloyd Miller
+   WE7U     Curt Mills (lackey)
+
+   SmartBeaconing(tm) was invented by Tony Arnerich (KD7TA) and Steve
+   Bragg (KA9MVA) for the HamHUD project.  They offer the algorithm to
+   other authors as long as proper credit is given and the term
+   SmartBeaconing(tm) is used to describe it.  So be it.  Thanks Tony
+   and Steve!
+
+   Thanks go to all the people who have made individual contributions to
+   the Xastir project by sending bug-reports, patches, or who have
+   otherwise supported the project.  There are too many to list.
+
+   If you think that you are missing from this list contact the Xastir
+   Development Team at <http://sourceforge.net/projects/xastir/> or at
+   <http://xastir.sourceforge.net>.
+     _________________________________________________________________
+
+   Copyright (C) 2000-2012 The Xastir Group
+
diff --git a/CC_OpenStreetMap_logo.png b/CC_OpenStreetMap_logo.png
new file mode 100644
index 0000000..dd49add
Binary files /dev/null and b/CC_OpenStreetMap_logo.png differ
diff --git a/CC_OpenStreetMap_txt.png b/CC_OpenStreetMap_txt.png
new file mode 100644
index 0000000..c953572
Binary files /dev/null and b/CC_OpenStreetMap_txt.png differ
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..60549be
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, 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 software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, 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 show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, 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 redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 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 Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, 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 executable.  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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+  5. 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 Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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.
+
+  7. 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 Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  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 program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/COPYING.LIB.LESSTIF b/COPYING.LIB.LESSTIF
new file mode 100644
index 0000000..eb685a5
--- /dev/null
+++ b/COPYING.LIB.LESSTIF
@@ -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/CanadaTopo250k.geo b/CanadaTopo250k.geo
new file mode 100644
index 0000000..661ca67
--- /dev/null
+++ b/CanadaTopo250k.geo
@@ -0,0 +1,2 @@
+TOPORAMA-250k
+
diff --git a/CanadaTopo50k.geo b/CanadaTopo50k.geo
new file mode 100644
index 0000000..c503678
--- /dev/null
+++ b/CanadaTopo50k.geo
@@ -0,0 +1,2 @@
+TOPORAMA-50k
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..243cdf5
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,30054 @@
+2012-11-01 11:57  we7u
+
+	* .cvsignore, AUTHORS, ChangeLog, DEBUG_LEVELS, FAQ, INSTALL,
+	  LICENSE, Makefile.am, NEWS, README, README.CVS, README.CYGWIN,
+	  README.Contributing, README.OSM_maps, README.win32,
+	  REGRESSION_TESTS, UPGRADE, acinclude.m4, bootstrap.sh,
+	  callpass.1, changes.txt, configure.ac, install-xastir,
+	  testdbfawk.1, update-xastir, xastir.1, xastir_udp_client.1,
+	  Davis/Makefile.am, Davis/README, Davis/bootstrap.sh,
+	  Davis/configure.ac, Davis/src/Makefile.am, Davis/src/db2APRS.c,
+	  Davis/src/defs.h, LaCrosse/Makefile.am, LaCrosse/README,
+	  LaCrosse/bootstrap.sh, LaCrosse/configure.ac,
+	  LaCrosse/src/Makefile.am, LaCrosse/src/defs.h,
+	  LaCrosse/src/open2300db2APRS.c, callpass/Makefile.am,
+	  callpass/callpass.c, config/24kgrid.dbfawk,
+	  config/OSM_Cloudmade_administrative.dbfawk,
+	  config/OSM_Cloudmade_highway.dbfawk,
+	  config/OSM_Cloudmade_natural.dbfawk,
+	  config/OSM_Cloudmade_poi.dbfawk,
+	  config/OSM_Cloudmade_water_and_coastline.dbfawk,
+	  config/arealm.dbfawk, config/areawater.dbfawk,
+	  config/cousub.dbfawk, config/cousub00.dbfawk, config/edge.dbfawk,
+	  config/featnames.dbfawk, config/gps_wpt.dbfawk,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, config/nwsc_ddmmyy.dbfawk,
+	  config/nwsc_ddmmyy_09.dbfawk, config/nwsc_ddmmyy_09b.dbfawk,
+	  config/nwsc_ddmmyy_10.dbfawk, config/nwsc_ddmmyy_10a.dbfawk,
+	  config/nwshzddmmyy.dbfawk, config/nwsmzddmmyy.dbfawk,
+	  config/nwsmzddmmyy_09.dbfawk, config/nwsmzddmmyy_11.dbfawk,
+	  config/nwsmzoddmmyy.dbfawk, config/nwsozddap12.dbfawk,
+	  config/nwsozddmmyy.dbfawk, config/nwsozddmmyy_09.dbfawk,
+	  config/nwsw_ddjn12.dbfawk, config/nwsw_ddmmyy.dbfawk,
+	  config/nwsw_ddmmyy_09.dbfawk, config/nwsw_ddmmyy_10.dbfawk,
+	  config/nwsz1ddmmyy.dbfawk, config/nwsz_ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy_09.dbfawk, config/nwsz_ddmmyy_10.dbfawk,
+	  config/nwsz_ddmmyy_10b.dbfawk, config/nwsz_ddmmyy_10c.dbfawk,
+	  config/nwszoddmmyy.dbfawk, config/pointlm.dbfawk,
+	  config/predefined_EVENT.sys, config/predefined_SAR.sys,
+	  config/stored_track.dbfawk, config/tabblock.dbfawk,
+	  config/tgr2shp.dbfawk, config/tgr2shppoly.dbfawk,
+	  config/tgr2shppoly_2006.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrlpt.dbfawk,
+	  config/tgrlpy.dbfawk, config/tgrplc00.dbfawk,
+	  config/tgrwat.dbfawk, config/tl_2009_nn_county.dbfawk,
+	  config/tnc-startup.aea, config/tnc-startup.d700,
+	  config/tnc-startup.d72_d710, config/tnc-startup.kam,
+	  config/tnc-startup.kpc2, config/tnc-startup.kpc3,
+	  config/tnc-startup.paccomm, config/tnc-startup.pico,
+	  config/tnc-startup.sys, config/tnc-startup.thd7,
+	  config/tnc-startup.tnc2, config/tnc-startup.tnc2-ui,
+	  config/tnc-stop.d700, config/tnc-stop.d72_d710,
+	  config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui, help/Makefile.am, help/help-Dutch.dat,
+	  help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, m4/Makefile.am,
+	  scripts/BUILDRPMS, scripts/Coordinate.pm, scripts/LSB-BUILD,
+	  scripts/LSB-BUILD-ALL, scripts/LSB-BUILD-CURL,
+	  scripts/LSB-BUILD-DB, scripts/LSB-BUILD-GDAL,
+	  scripts/LSB-BUILD-GRAPHICSMAGICK, scripts/LSB-BUILD-JASPER,
+	  scripts/LSB-BUILD-JPEG, scripts/LSB-BUILD-LESSTIF,
+	  scripts/LSB-BUILD-PCRE, scripts/LSB-BUILD-PNG,
+	  scripts/LSB-BUILD-ZLIB, scripts/UIView2XastirLog.pl,
+	  scripts/Xastir_tigerpoly.py, scripts/do_xastir_release_dev,
+	  scripts/do_xastir_release_stable, scripts/example_objects.log,
+	  scripts/geopdf2gtiff.pl, scripts/get-fcc-rac.pl,
+	  scripts/get-gnis, scripts/get-maptools.sh, scripts/get-pop,
+	  scripts/get_shapelib.sh, scripts/kiss-off.pl,
+	  scripts/langElmerFudd.pl, scripts/langMuppetsChef.pl,
+	  scripts/langOldeEnglish.pl, scripts/langPigLatin.pl,
+	  scripts/langPirateEnglish.pl, scripts/object2shp.pl,
+	  scripts/pos2shp.pl, scripts/slideshow.pl, scripts/test_coord.pl,
+	  scripts/toporama250k.pl, scripts/toporama50k.pl,
+	  scripts/track-get.pl, scripts/waypoint-get.pl,
+	  scripts/xastir-fixcfg.sh, scripts/xastir-migrate.sh,
+	  src/Makefile.am, src/alert.h, src/awk.h, src/bulletin_gui.h,
+	  src/color.h, src/database.h, src/datum.h, src/db_gis.h,
+	  src/dbfawk.h, src/draw_symbols.h, src/fcc_data.h, src/festival.h,
+	  src/fetch_remote.h, src/geo.h, src/gps.h, src/hashtable.h,
+	  src/hashtable_itr.h, src/hashtable_private.h, src/hostname.h,
+	  src/igate.h, src/interface.h, src/io.h, src/lang.h,
+	  src/leak_detection.h, src/list_gui.h, src/macspeech.c,
+	  src/main.h, src/map_OSM.c, src/map_OSM.h, src/map_cache.h,
+	  src/maps.h, src/messages.h, src/objects.h, src/popup.h,
+	  src/rac_data.h, src/rotated.h, src/rpl_malloc.h, src/shp_hash.h,
+	  src/snprintf.h, src/symbols.h, src/tile_mgmnt.h, src/track_gui.h,
+	  src/util.h, src/wx.h, src/x_spider.h, src/xa_config.h,
+	  src/xastir.h, src/rtree/Makefile.am, src/rtree/card.c,
+	  src/rtree/card.h, src/rtree/gammavol.c, src/rtree/index.c,
+	  src/rtree/index.h, src/rtree/node.c, src/rtree/rect.c,
+	  src/rtree/sphvol.c, src/rtree/split_l.c, src/rtree/split_l.h,
+	  src/rtree/split_q.c, src/rtree/split_q.h,
+	  src/shapelib/Makefile.am, src/shapelib/contrib/Makefile.am,
+	  symbols/Makefile.am, symbols/symbols.dat: Updating the Copyright
+	  notices.  Bumping revision to 2.0.2 in preparation for stable
+	  release.
+
+2012-10-22 17:37  tvrusso
+
+	* src/interface.c: Tidy up a comment and remove some
+	  now-commented-out code.  At this point, everything that I had
+	  hoped to be in the next stable release is in place.
+
+2012-10-22 16:59  we7u
+
+	* src/: interface.c, interface_gui.c, xa_config.c: The rest of the
+	  code to implement "TNC Delay" for the serial tnc types of
+	  interfaces.  This is most useful with a KAM TNC.  Note that one
+	  can hand edit the value up to 9,999,999 us in the Xastir config
+	  file, but pressing the togglebutton will enter 1,000,000 us by
+	  default.  Thanks for that idea Tom!
+
+2012-10-22 16:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.h,
+	  src/interface_gui.c, src/xa_config.c: Implementing the GUI and
+	  save/restore portions of the "Add Delay" togglebutton for the
+	  three types of Serial TNC interfaces.  The back-end code which
+	  actually uses the button value hasn't been coded yet.
+
+2012-10-11 11:25  we7u
+
+	* scripts/get-fcc-rac.pl: Fixing the RAC database fetch/install.
+
+2012-10-11 11:09  we7u
+
+	* scripts/get-NWSdata: Updating for the current set of NWS
+	  filenames.
+
+2012-10-11 10:58  tvrusso
+
+	* symbols/: Makefile.am, icon.png: Add a PNG icon for Xastir,
+	  converted from the icon.xbm file in the src directory.
+
+	  I did this because I generally create a desktop shortcut to
+	  Xastir on my laptop, and as of the most recent version of Gnome I
+	  am unable to use an xbm to do so, but a PNG works.
+
+	  This new icon is installed into ${prefix}/share/xastir/symbols
+	  and may be used by the user to define a custom icon for a desktop
+	  shortcut.
+
+	  Remember, the Xastir project does not directly support
+	  distro-specific (or desktop-specific) packages, but we do want to
+	  make sure that those who generate such packages have the tools
+	  and files they need to do so.
+
+2012-10-10 15:18  tvrusso
+
+	* help/: help-Dutch.dat, help-Portuguese.dat: The Dutch and
+	  Portuguese help files were actually not in Dutch or Portuguese,
+	  but English, and were woefully outdated.
+
+	  Copied the current English helpfile into those two, so at least
+	  the only thing that's wrong with them would be that they're not
+	  in the language they're supposed to be.
+
+2012-10-10 15:16  tvrusso
+
+	* ChangeLog, help/help-English.dat: Regenerate ChangeLog from CVS
+	  logs.
+
+	  Add a "what's new in Xastir 2.0.1" section to the on-line help.
+
+	  Looking over our non-English helpfiles, it is clear that it has
+	  been a very long time since anyone has translated the help into
+	  other languages.  The German help file hasn't been updated since
+	  Xastir 1.2, Spanish hasn't been updated since 1.1, and several
+	  languages have help files, but they're still in English.
+
+2012-10-10 14:46  tvrusso
+
+	* scripts/cvs2cl.pl: Add cvs2cl script (from
+	  http://www.red-bean.com/cvs2cl/cvs2cl.pl) to our tools.  This
+	  generates a ChangeLog from cvs commit logs.
+
+2012-10-07 10:41  tvrusso
+
+	* configure.ac: Move probe for proj to before probe for shapelib.
+	  When using internal shapelib, the probe checks whether "use_proj"
+	  is "yes", but until this commit, use_proj was unset until *AFTER*
+	  the shapelib probe.  This led to warnings from the shell about
+	  unary "=" in a test (if test $use_proj = "yes")
+
+2012-10-05 13:19  we7u
+
+	* scripts/get-NWSdata: Updating a file or two, and changing the
+	  order of FILE1 and FILE2 in the definitions to match the order
+	  they are on the NWS web pages.  We will need to check this file
+	  again on/after Oct 11 as several of the filenames change then.
+
+2012-10-05 12:56  we7u
+
+	* scripts/get-fcc-rac.pl: Changing the RAC address to one that
+	  currently works.  The old site looks to have a brand spanking new
+	  version of Drupal on it, so they may have messed up the rest of
+	  the machine temporarily (or permanently).
+
+2012-09-26 21:15  tvrusso
+
+	* acinclude.m4, configure.ac: Remove some unnecessary macros from
+	  the probes for Berkeley DB.
+
+	  The code in acinclude.m4 to probe for Berkeley DB was copied from
+	  another project, and included a macro that tried to guess how to
+	  add a "runpath" to the build.  On most systems this is either
+	  -Rlibrarydirectory or -Wl,rpath,librarydirectory, but the macro
+	  in our acinclude.m4 was in fact correctly identifying the way to
+	  do it ONLY on Linux, and then discarding the information anyway.
+	  Thus, this was a no-op on Linux, and was wrong elsewhere (but
+	  also a no-op).  The technique used to do the probe also broke
+	  when the compiler was clang, but again, to no effect because the
+	  result was discarded anyway.
+
+	  SO since the result wasn't used, why probe it?  I have removed
+	  the macros and replaced the use of "XASTIR_ADD_LIBRARY_TO" with a
+	  simple shell variable assignment.
+
+	  While I was at it, I removed the deprecated two-argument call to
+	  AM_INIT_AUTOMAKE.  It has started causing newer versions of
+	  automake to complain, and has been deprecated for some time.
+
+2012-09-23 09:19  tvrusso
+
+	* src/: db.c, fcc_data.c, igate.c, interface.c, location_gui.c,
+	  main.c, map_OSM.c, map_WMS.c, map_cache.c, map_geo.c, map_shp.c,
+	  map_tiger.c, maps.c, messages.c, messages_gui.c, objects.c,
+	  rac_data.c, track_gui.c, util.c, xa_config.c, xa_config.h: Big
+	  commit for a little, insidious threading problem.
+
+	  xa_config.c provides a function called get_user_base_dir(char*)
+	  that returns a pointer to a string that is the concatenation of
+	  the base configuration directory for Xastir (usually ~/.xastir,
+	  but selectable by the user with a command line option or
+	  environment variable) and the argument.
+
+	  This function was highly thread-unsafe --- it kept a local static
+	  char array that it used to build the concatenated string, then
+	  returned a pointer to the local array.
+
+	  This function was used in multiple threads, meaning that one
+	  thread could start scribbling into the static array while another
+	  was writing into it.	I first tried to fix this by adding a mutex
+	  that locked the writes for all but one thread at a time, but that
+	  wasn't even good enough, because after unlocking the write mutex
+	  another thread could write into the buffer while the first thread
+	  was reading the results just produced.
+
+	  The result of this mess was a highly unpredictable tendency for
+	  Xastir to start producing corrupted paths from this function.
+	  This would show up most often on multi-core machines with
+	  threading libraries that let threads run simultaneously on
+	  different cores, but it could show up on single-core machines
+	  with just the right scheduler.  It is revealed most easily by
+	  enabling multiple logging options (e.g. TNC logging, NET logging,
+	  WX logging) and PNG snapshots all at once.  In testing, I found
+	  this sufficient to produce corrupted file paths in an hour or so.
+	   I'm somewhat surprised that nobody has ever reported this issue,
+	  because I've been seeing it for ages.
+
+	  This commit replaces the original get_user_base_dir
+	  implementation with one that requires the caller to provide its
+	  own buffer, and completely removes the use of the static buffer.
+	  More than 200 calls to get_user_base_dir had to be modified, but
+	  some simplifcation was also possible --- I was able to replace a
+	  few usages like this:
+
+	     xastir_snprintf(dest_string, sizeof(dest_string), "%s",
+	  get_user_base_dir("tmp"));
+
+	  with:    get_user_base_dir("tmp", dest_string,
+	  sizeof(dest_string));
+
+	  get_user_base_dir still returns the pointer to the destination
+	  string, so it can still be used as an argument to log_data or
+	  xastir_snprintf where necessary.
+
+	  I also replaced several wasteful uses of the function.  There
+	  were places where get_user_base_dir was being called repeatedly
+	  with the same argument many times in a single function.  I
+	  replaced this usage in many cases with a single call to store the
+	  answer in a local buffer, and use that repeatedly.
+
+	  Since implementing this change I have seen Xastir run without
+	  producing a single corrupted path, even with TNC, NET, and WX
+	  logging and PNG snapshots turned on.
+
+2012-09-21 18:32  tvrusso
+
+	* configure.ac, src/main.c: Ifdef out the hack added to main.c to
+	  deal with the broken Xorg-server 1.7.5.  This server version had
+	  a bug that interfered with all motif programs, causing them to
+	  grab the cursor and never release it when a context (pop-up) menu
+	  was created.	The bug was promptly fixed, but not before several
+	  distros locked in version 1.7.5 as their supported version.
+
+	  The workaround ungrabs the cursor, but has the annoying
+	  side-effect of making the user hold down the button that brings
+	  up the menu, rather than allowing a quick click to access it.
+
+	  This commit puts the hack into an ifdef, and enables the user to
+	  select the workaround by adding "--with-xorg_175_workaround" to
+	  the configure line.  The default behavior is now to NOT use the
+	  workaround.
+
+	  The workaround and configure.ac code to enable it should be
+	  removed completely in one release cycle.  Xorg-server 1.7.5 is
+	  long gone, and keeping this code around is a nod to the fact that
+	  some people do not upgrade for years.  One more release cycle
+	  should be enough to forget this mistake ever happened.
+
+2012-09-20 22:11  tvrusso
+
+	* src/map_OSM.c: Patch from Tom Hayward (KD7LXL):
+
+	  This patch fixes an issue in the OSM tile download loop. If a
+	  tile is 404, 403, or any other error that doesn't return a valid
+	  image, imagemagick (or gm) puts the error info in &exception.
+	  Subsequent iterations read &exception, note the error, and fail
+	  to composite any further tiles. This patch adds
+	  GetExceptionInfo() to the end of the loop, so subsequent
+	  iterations do not start off with error info in the exception
+	  struct.
+
+2012-09-19 07:56  tvrusso
+
+	* Davis/src/db2APRS.c, LaCrosse/src/open2300db2APRS.c: Make sure to
+	  include <sys/stat.h> before using umask(), to avoid compiler
+	  warning about implicit declaration.
+
+2012-09-14 13:57  tvrusso
+
+	* config/tnc-startup.kam, src/interface.c: Definitive fix for KAM
+	  TNCs.
+
+	  The KAM apparently does not go into converse mode if one sends
+	  "K\r" and immediately sends the stuff you want to go into the
+	  converse.  It requires a tiny delay between the command to go
+	  into converse mode and the data.
+
+	  I have inserted a 50ms delay after sending the converse command,
+	  which should be insignificant enough that nobody will need it to
+	  be a configurable option.
+
+	  This fix has been confirmed to end the problems with KAM TNCs,
+	  and the 50ms delay was the smallest delay tested.
+
+	  Also commented out two commands in tnc-startup.kam that do not
+	  apparently exist in the KAM.
+
+2012-09-08 15:07  tvrusso
+
+	* Davis/src/db2APRS.c: Reverting my last change to the Davis
+	  Meteo->APRS glue program.  This is in response to testing by Dean
+	  Groe, who is so far the only person on the xastir mailing list
+	  who has fed back any information about the behavior of the code
+	  after my last commit.
+
+	  Turns out that Meteo does not appear to put "Total Rain" (rain
+	  since station reset) into the database in the "raintotal" field,
+	  it appears to put "rain since midnight" there, i.e. "total rain
+	  for today."  This is not what Xastir means, since it has a
+	  separate spot for "today's rain."
+
+	  Thus, it is pointless to be sending the extra data to Xastir,
+	  because it is a duplicate of something else we already have.
+
+	  I am changing only the Davis database glue program, and leaving
+	  in place the LaCrosse changes --- LaCrosse stations *do* maintain
+	  their own record of "total rain" and open2300 does put that data
+	  into the database.  It's just Meteo that doesn't.
+
+2012-08-31 16:39  tvrusso
+
+	* Davis/configure.ac, Davis/src/db2APRS.c,
+	  LaCrosse/src/open2300db2APRS.c, src/wx.c: Fix for Davis and
+	  LaCrosse weather stations.
+
+	  Neither of the two "db2APRS" programs for these stations provided
+	  "total rain" (rain since wx station reset), and thus Xastir would
+	  show a blank in the Own Weather Data dialog box for this.
+
+	  Further, LaCrosse weather stations don't report
+	  rain-since-midnight, and by not having total rain available,
+	  Xastir isn't able to compute the missing datum.
+
+	  This commit does three things:
+
+	    adds total rain to the string that db2APRS and open2300db2APRS
+	  send
+	    adds code to Xastir to parse the new bit of data
+	    adds code to Xastir to compute rain-since-midnight if total
+	  rain
+		  is available AND rain-since-midnight is not sent from the
+	  wx station.
+
+	  WARNING:  THE CODE FOR db2APRS has NOT been tested except to
+	  assure that it compiles cleanly.  I have no Davis weather station
+	  to test it on.
+
+	  The LaCrosse code runs correctly.
+
+2012-08-26 11:34  tvrusso
+
+	* INSTALL, README.Getting-Started: Update documentation to reflect
+	  some changes in GPSMan and GPSManShp.
+
+2012-08-26 11:28  tvrusso
+
+	* src/main.c: Current versions of gpsman and gpsmanshp now require
+	  "Shapefile" and "dim=2" instead of "Shapefile_2D"
+
+	  For quite a long time the gpsman maintainer kept backward
+	  compatibility, but it's gone now.  This commit resolves issue
+	  http://sourceforge.net/tracker/?func=detail&aid=1820056&group_id=45562&atid=443271
+	  in the sourceforge bug tracker.
+
+2012-08-26 11:11  tvrusso
+
+	* acinclude.m4: Remove bashism from configure process, per
+	  sourceforge bug
+
+	  https://sourceforge.net/tracker/?func=detail&aid=3422711&group_id=45562&atid=443271
+
+2012-08-25 09:38  tvrusso
+
+	* src/: awk.c, bulletin_gui.c, color.c, datum.c, db_gis.c,
+	  dbfawk.c, draw_symbols.c, fcc_data.c, festival.c, fetch_remote.c,
+	  geo-client.c, geo-find.c, geocoder_gui.c, gps.c, hashtable.c,
+	  hashtable_itr.c, hostname.c, igate.c, interface.c,
+	  interface_gui.c, io-common.c, io-mmap.c, lang.c, list_gui.c,
+	  locate_gui.c, location.c, location_gui.c, main.c, map_OSM.c,
+	  map_WMS.c, map_cache.c, map_dos.c, map_gdal.c, map_geo.c,
+	  map_gnis.c, map_pdb.c, map_pop.c, map_shp.c, map_tif.c,
+	  map_tiger.c, messages.c, messages_gui.c, objects.c, popup_gui.c,
+	  rac_data.c, rotated.c, rpl_malloc.c, shp_hash.c, snprintf.c,
+	  sound.c, testdbfawk.c, tile_mgmnt.c, track_gui.c,
+	  view_message_gui.c, wx.c, wx_gui.c, x_spider.c, xa_config.c,
+	  xastir_udp_client.c: update neglected copyright dates.
+
+	  Notably, update the one that shows up in the Help->About dialog.
+
+2012-08-22 18:05  tvrusso
+
+	* help/help-English.dat: Update help file to reflect recent change
+	  to "Serial TNC with GPS on AUX port" interface type, documenting
+	  the 'Send Control-E to get GPS data?' checkbox.
+
+	  I can only update this in English.  Translations requested for
+	  our other supported languages.
+
+2012-08-22 17:41  tvrusso
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c,
+	  src/interface_gui.c, src/main.c: Remove a horrid work-around of
+	  some bad behavior of Xastir with Kenwood D7* radios with attached
+	  GPS.
+
+	  Back in 2006, several Xastir users noticed that when Xastir was
+	  attached to a Kenwood D700 (and other Kenwood APRS radios) using
+	  the "TNC with GPS on AUX port" interface type, every time Xastir
+	  tried to transmit the TNC would reply with an "Eh?" error when
+	  sent the MYCALL line that precedes a posit.  We realized that
+	  there must be some kind of junk in the TNC buffer that was
+	  causing the MYCALL line to not be recognized.  In some cases,
+	  this had bad consequences, especially if no previous MYCALL had
+	  succeeded --- the result would be that the TNC would transmit
+	  using the default MYCALL, "NOCALL".
+
+	  Since we couldn't for the life of us figure out what the junk in
+	  the buffer was, we kludged:  Before sending MYCALL, Xastir would
+	  send a carriage return, letting the "eh?" error happen where it
+	  had no consequence.
+
+	  This was a horrid kludge, as it just swept the real problem under
+	  the rug.
+
+	  The real issue is that "Serial TNC with GPS on AUX port" was
+	  written to support devices like the Kantronics KPC-3+, which
+	  requires that Xastir send a Control-E to the TNC in order to poll
+	  it for GPS data.  This is how the KPC-3+ multiplexes the output
+	  serial port --- normally it sends packet data to the serial port,
+	  but immediately after receiving a Control-E from the connected
+	  computer, it sends one NMEA string from the GPS instead.
+
+	  The Kenwwood radios stream the GPS data and packet data together
+	  all the time, and not only do not require a Control-E to switch
+	  between them, they don't even read the Control-Es.
+
+	  The "Eh?" errors from the Kenwood TNCs were it complaining that
+	  MYCALL was preceded by all those Control-E characters that Xastir
+	  had been sending since the last transmit.
+
+	  This commit adds a configuration option to the Serial TNC with
+	  GPS on AUX port set-up dialog so that one can turn this control-E
+	  feature on and off as appropriate.
+
+	  THIS HAS USER-VISIBLE IMPACT FOR ALL KENWOOD USERS:
+
+	  If you are currently using Xastir with a Kenwood radio, after
+	  doing this update you MUST open your interface property dialog
+	  and de-select the 'Send Control-E to get GPS data?" check box.
+	  If you do NOT take this step, you will begin seeing the old "Eh?"
+	  problem on your TNC, and may well transmit your posit as NOCALL.
+
+	  This may seem an annoyance, but really, this is the fix that we
+	  should have put in place six years ago.
+
+2012-08-14 15:14  tvrusso
+
+	* src/db.c: Fix two instances of a logical AND being used where a
+	  bit-wise AND was intended.
+
+	  In this case, the test was supposed to be checking that a station
+	  posit was not a third-party packet, but was improperly doing flag
+	  && ST_3RD_PT instead of flag & ST_3RD_PT.
+
+	  This impacts ONLY speech-enabled band opening alerts.  It is
+	  unlikely that anyone was even using these.  I found this error
+	  only because clang spits out warnings about it.  The specific
+	  warning is that one is attempting to do a logical AND with a
+	  constant value (which is more likely an error than intentional).
+
+2012-08-13 10:22  tvrusso
+
+	* src/: database.h, wx.c: EXPERIMENTAL COMMIT FOR TESTING PURPOSES.
+
+	  This commit modifies the weather station code so taht stations
+	  which provide 1-hour, 24-hour, and since-midnight rain rates
+	  (e.g. Davis through Meteo and db2APRS, LaCrosse, and Davis APRS
+	  Data Logger) do not have those station- provided data overwritten
+	  by Xastir when it tries to recalculate these quantities from
+	  "total rain" (i.e. total rainfall since the weather station was
+	  reset).
+
+	  The Davis Meteo/LaCrosse code does not even provide "total
+	  rainfall" information (though the database they access does in
+	  fact have this information), and the APRS Data Logger does not
+	  provide total rainfall.  All three provide per-hour and 24-hour
+	  rain data, and the Data Logger provides rain-since -midnight.
+
+	  What this code does is add a flag to the WeatherRow structure
+	  that is set to 1 by stations that provide total rain, and to zero
+	  by stations that provide the rate data instead.  In
+	  "cycle_weather", the three rate strings are only overwritten if
+	  the flag is 1, and are left as the station set them if the flag
+	  is 0.
+
+	  This should address issues of transmitted rain rates being
+	  completely incorrect for Davis and LaCrosse stations.
+
+	  Needs a lot more testing to assure that there is no impact on
+	  other stations.  This code should result in no change in Xastir's
+	  behavior for any station other than Davis or LaCrosse.
+
+2012-08-08 19:19  tvrusso
+
+	* src/: main.c, xa_config.c: Patch by Tom Hayward.
+
+	  This commit allows the "posit interval" slider to go all the way
+	  to zero.  If zero, Xastir will not emit timed beacons.
+
+	  It also adds a SIGUSR2 signal handler.  If Xastir receives a
+	  SIGUSR2, it will beacon immediately.
+
+	  This commit provides all the functionality requested by David
+	  Ranch on the Xastir mailing list in this post:
+
+	  http://lists.xastir.org/pipermail/xastir/2012-August/020936.html
+
+2012-07-27 12:58  tvrusso
+
+	* src/: interface.c, interface.h: Remove commented-out, hard-coded
+	  choices of 'conv' and 'k' to put a TNC into "converse" mode.	The
+	  Interface Properties dialog now allows a user to specify this at
+	  run time, and the presence of this commented-out code was
+	  confusing some users into thinking they still might need to edit
+	  source code to change it.
+
+2012-07-24 17:17  tvrusso
+
+	* LaCrosse/weatherdump.sql: Modify mysql database for LaCrosse to
+	  support more digits of precision for wind direction and other
+	  data that can exceed 99.9.
+
+	  "decimal(3,1)" means 3 digits with one past the decimal, i.e.
+	  +/-99.9.  It was being used for fields that could take values
+	  well outside this range.
+
+	  I know that in at least one prior incarnation, this usage
+	  accepted 3 digits to the left of the decimal, but now it doesn't.
+	   My weather station has been misreporting wind direction ever
+	  since I did a major overhaul that required re-loading the mysql
+	  data from a dump.
+
+2012-07-10 14:02  we7u
+
+	* Makefile.am: Tweaking the URL for the cycle map for OSM (shows
+	  contours).
+
+2012-07-05 11:53  tvrusso
+
+	* src/: igate.c, messages.c: Silence some warnings that showed up
+	  when building with CLang instead of GCC.
+
+	  One (in igate.c) is just a misuse of "debug_level && 1024"
+	  instead of "debug_level & 1024), and the changes in messages.c
+	  are all about use of things like:    found =- 1;
+
+	  which it warns as a potential mistake, since it is common to
+	  intend this to be:	found -= 1;
+
+	  Making it   found = -1;
+
+	  clarifies the intent for the compiler and stops it from warning.
+
+2012-05-31 11:49  tvrusso
+
+	* src/wx.c: Fix incorrect test of sscanf return value.	When I
+	  changed the scanf to ignore the PXXX field, I forgot to decrease
+	  the value.
+
+2012-05-31 11:41  tvrusso
+
+	* src/wx.c: Add a string to the APRS DataLogger debug output.
+
+2012-05-26 19:57  tvrusso
+
+	* src/wx.c: Fix what seems to be a serious error in the Davis APRS
+	  DataLogger code.
+
+	  When I first wrote this section I decoded pXXX into "wx_prec_24"
+	  and PXXX into "wx_prec_00" since pXXX means "rain in last 24
+	  hours" and PXXX means "rain since midnight."	But Xastir actually
+	  computes those things itself, and the DAVISMETEO code puts pXXX
+	  into "wx_rain_total" instead.
+
+	  AA9VI has been having Issues with his DataLogger, in that Xastir
+	  is zeroing out the rainfall improperly.  Turns out that's because
+	  I'm never setting wx_rain_total, and Xastir needs that.
+
+	  So I'm removing "rp-" and "rP-" from the debug output, no longer
+	  saving PXXX into wx_prec_00 (it's discarded now), and am now
+	  saving pXXX into wx_rain_total so that Xastir can handle it
+	  properly.
+
+	  This should fix Mike's problem.
+
+2012-05-15 08:29  tvrusso
+
+	* src/map_tif.c: Replace include of "projects.h" with "proj_api.h"
+	  and remove use of what is now considered an internal structure
+	  (struct PJ).	Replace that usage with a pointer to such a
+	  structure (projPJ, which is a typedef to a pointer to a PJ).
+
+	  Proj.4 has removed "projects.h" from the installation of that
+	  library, because much that's in it is considered private
+	  implementation details that should not have been exposed.  That
+	  many packages use those internals directly is considered a
+	  problem in those other packages, and a bug request in proj.4's
+	  bug tracker to reinstate projects.h as an installed file was
+	  closed with the status "wontfix".  Codes that use the public API
+	  of proj.4 are supposed to include "proj_api.h" and use the API
+	  calls, not direct access to internal data structures or functions
+	  that are not intended for use outside the library.
+
+2012-05-14 13:38  tvrusso
+
+	* config/Makefile.am, config/nwsozddap12.dbfawk,
+	  config/nwsw_ddjn12.dbfawk, scripts/get-NWSdata, src/testdbfawk.c:
+	  Update get-NWSdata to fetch the very latest NWS data.  Some of
+	  the files it was trying to get are non longer available.
+
+	  Before committing, I assured that *ALL* files that get-NWSdata
+	  downloads have corresponding matching dbfawk files.  Two of the
+	  files (oz and w) have had their dbf signatures change, so needed
+	  new dbfawk files.  Updated Makefiles to install these new files
+	  (which I've named according to a new convention, instead of
+	  _ddmmyy_year, I'm using mmyy that matches the dbf file to which
+	  it corresponds).
+
+	  Fix a spelling error in testdbfawk ("mathing" instead of
+	  "matching").
+
+2012-05-10 18:55  tvrusso
+
+	* src/: db.c, maps.c: Comment out fprintfs to stderr that were
+	  introduced by last commit.  They are spewing info to stderr of an
+	  exact sort that other types of weather alerts have commented out.
+
+2012-05-08 11:04  tvrusso
+
+	* src/wx.c: Fix debug output for Davis APRS DataLogger so that it
+	  actually prints the decoded values for 24-hour and since-midnight
+	  precipitation.
+
+2012-05-06 09:09  tvrusso
+
+	* configure.ac: make a single change of
+
+	    if [ "$var" = "yes" ]
+
+	  to   if test "$var" = "yes"
+
+	  because I found that a Fedora 15 install was complaining about
+	  the former.
+
+2012-03-05 10:49  we7u
+
+	* symbols/: tornado.xbm, winter_wx.xbm, wntr_strm.xbm: Removing no
+	  longer used weather alert files.  We renamed them slightly to
+	  match the alert_tag text in the NWS weather alerts.
+
+2012-03-05 10:47  we7u
+
+	* symbols/Makefile.am, symbols/torndo.xbm,
+	  symbols/winter_storm.xbm, symbols/winter_weather.xbm,
+	  src/map_shp.c, src/util.c, src/util.h: A rewrite of a patch
+	  supplied by Arnaud, F4EIR, which simplifies how we do alert->tag
+	  processing.  We now grab the alert tag, change it to lower-case,
+	  then find a matching file on the filesystem.	If not found, we
+	  grab one called "alert.xbm" as a default.  This change will allow
+	  adding more files over time for more types (or Country's) alerts.
+	  Arnaud has plans to add support for France's weather alerts.
+
+2012-03-02 12:28  we7u
+
+	* README.Getting-Started, README.MAPS: Updating the copyright year
+	  for these two files.
+
+2012-03-02 12:26  we7u
+
+	* config/Makefile.am, config/gfe_coastal_waters.dbfawk,
+	  config/gfe_coastal_waters_warnings.dbfawk,
+	  config/gfe_fire_weather.dbfawk, config/gfe_metro_areas.dbfawk,
+	  config/gfe_public_weather.dbfawk, scripts/Makefile.am,
+	  scripts/get-BOMdata, src/alert.c, src/db.c, src/maps.c,
+	  src/util.c: Tweaks to allow using Australian Bureau of Metrology
+	  weather alerts in Xastir.  This allows lighting up zones in a
+	  similar manner to the NWS weather alerts.  Thanks to Geoff
+	  Gatward, VK2XJG/VK8GG, for this work!
+
+2012-03-02 12:10  we7u
+
+	* config/nwsmzddmmyy_11.dbfawk, config/nwsz_ddmmyy_11.dbfawk,
+	  scripts/get-NWSdata: Updates to the NWS fetch script and dbfawk
+	  files by Geoff Gatward, VK2XJG/VK8GG.  Thanks!
+
+2012-03-01 10:11  we7u
+
+	* FAQ: Adding 4.34 question/answer from the web-based FAQ, and 4.35
+	  from a question answered by Tom Russo on the mailing list (added
+	  with permission).
+
+2012-02-04 16:10  tvrusso
+
+	* README.Getting-Started, README.MAPS, scripts/Makefile.am: Change
+	  scripts Makefile.am to remove misuse of "pkglib_SCRIPTS" as this
+	  usage was one that was not intended to be correct, but was
+	  silently accepted by older versions of automake.  Now automake
+	  enforces certain rules about what directory prefixes may be used
+	  with what "primaries" (such as _SCRIPTS and _DATA), and "pkglib"
+	  is forbidden as a prefix to "_SCRIPTS."
+
+	  This change also changes where scripts are installed.  They used
+	  to get installed to /usr/local/lib/xastir, now they go to
+	  /usr/local/share/xastir/scripts.  Documentation has been updated
+	  to fix references to the old directory.
+
+2011-10-20 19:08  tvrusso
+
+	* README.MAPS: Testing CVSROOT/loginfo change.
+
+2011-10-20 18:45  we7u
+
+	* src/: interface.c, interface.h, interface_gui.c, xa_config.c:
+	  Added a new box in the TNC properties dialog for setting the
+	  CONVERSE mode command.  If blank it will get set to "k" which
+	  most TNC's accept.  Can be set to "conv" for TNC's like the KPC-2
+	  on an individual port basis.
+
+2011-09-08 12:47  tvrusso
+
+	* config/: Makefile.am, nwsz_ddmmyy_11.dbfawk: Add a new dbfawk
+	  file for the newest NWS Zone file, which once again has different
+	  dbf signature than all previous versions.
+
+2011-09-05 13:24  tvrusso
+
+	* scripts/geopdf2gtiff.pl: Remove creation options for PACKBITS
+	  compression, until I figure out why that's creating tiffs Xastir
+	  can't read.
+
+2011-09-05 12:58  tvrusso
+
+	* scripts/geopdf2gtiff.pl: Add a "fix neatline" option for GeoPDFs
+	  with bad neatlines, such as the most recent US Topo editions,
+	  which have neatlines that include all the collar.
+
+	  This hack works when the user specifies --fixneatline or -f, and
+	  rounds the left, right, top, and bottom of the image down to the
+	  nearest 7.5' quad boundary, and uses those values to construct
+	  its own neatline prior to calling gdalwarp with the -cutline
+	  -crop_to_cutline options.
+
+2011-09-05 10:54  tvrusso
+
+	* scripts/geopdf2gtiff.pl: Add compress=packbits to geotiff
+	  creation options for minor disk space savings.
+
+2011-09-05 10:29  tvrusso
+
+	* scripts/: Makefile.am, geopdf2gtiff.pl: Added script to convert
+	  GeoPDF files to usable GeoTIFF files.
+
+	  This involves extracting the neatline from the GeoPDF, then doing
+	  a gdalwarp to strip the collar and warp to EPSG:4326 coordinate
+	  system (WGS84 equidistant cylindrical projection), and finally to
+	  dither to 8 bit if there is more than one band present.
+
+	  I have found that some GeoPDF files lie about their neatlines,
+	  saying the neatline encloses the whole raster including the
+	  collar.  There is nothing to be done about this except to
+	  hand-craft an FGD file for such GeoPDFs.  With an FGD file,
+	  Xastir will collar-strip itself.  This seems only to be a problem
+	  with some of the fancier new-style GeoPDF files, the "Digital
+	  Maps, Beta."
+
+2011-07-06 00:45  we7u
+
+	* config/: Makefile.am, tnc-startup.d72_d710, tnc-stop.d72_d710:
+	  New start/stop files for Kenwood D72 and D710, contributed by Kai
+	  Günter, LA3QMA.  Thanks!
+
+2011-05-31 08:37  gstueve
+
+	* config/Makefile.am, config/nwsc_ddmmyy_10a.dbfawk,
+	  config/nwsmzddmmyy_11.dbfawk, config/nwsw_ddmmyy_10.dbfawk,
+	  config/nwsz_ddmmyy_10c.dbfawk, scripts/get-NWSdata: Make sure we
+	  have good mapping files for current NWS data files.  Also get
+	  current set of files from NWS.
+
+2011-03-26 20:07  jedunmire
+
+	* src/map_OSM.c:     - fix for downloading tile '5 of 4' bug
+	      - the bug and the fix are cosmetic and should not impact any
+	  other
+		operations.
+
+2011-02-25 22:06  we7u
+
+	* config/: Makefile.am, nwsc_ddmmyy_10.dbfawk, nwshzddmmyy.dbfawk,
+	  nwsz_ddmmyy_10b.dbfawk: Updating dbfawk files to match current
+	  set of NWS Shapefiles.
+
+2011-02-25 15:06  we7u
+
+	* scripts/get-NWSdata: Updating to the most recent valid NWS files
+	  for alerts.  We'll need to update our dbfawk files to match
+	  these.
+
+2011-01-23 17:29  we7u
+
+	* scripts/get-NWSdata: Updating to latest NWS Shapefiles.
+
+2011-01-03 17:30  we7u
+
+	* README: Added the OpenSuSE-11.3 repository to the notes plus a
+	  command-line option to configure which picks up another needed
+	  library location.
+
+2010-12-31 04:58  we7u
+
+	* help/help-English.dat: Revising the tactical callsign text a bit.
+
+2010-12-31 04:41  we7u
+
+	* FAQ: Changed the "Can I run multiple Xastir's at once" answer to
+	  incorporate use of the new(er) "-c" command-line flag.
+
+2010-12-31 04:17  we7u
+
+	* help/help-English.dat: Added info about publishing tactical
+	  callsigns across the air and later revoking those assignments via
+	  APRS messaging.
+
+2010-12-20 15:43  jedunmire
+
+	* src/map_OSM.c:     - Re-organized a few lines in map_OSM.c so
+	  that it not produce an
+		error message when *Magick libraries are not used.
+
+2010-12-04 17:37  tvrusso
+
+	* configure.ac, src/shapelib/contrib/Makefile.am: Fix
+	  configure/make so that it works properly when internal shapelib
+	  is being built on a system without libproj.
+
+2010-11-08 17:48  tvrusso
+
+	* Makefile.am: Fix for bug reported by Jeremy Utley, in which using
+	  DESTDIR at install time was depositing some CC_*.png files in a
+	  directory that ignored DESTDIR.
+
+2010-10-25 20:25  we7u
+
+	* configure.ac: Bumping CVS up to v2.0.1 for further development.
+
+2010-10-25 20:02  we7u
+
+	* configure.ac, scripts/BUILDRPMS, scripts/LSB-BUILD,
+	  scripts/do_xastir_release_dev, scripts/do_xastir_release_stable:
+	  Setting up for the v2.0.0 stable release.
+
+2010-10-24 10:01  we7u
+
+	* config/language-French.sys: Updates by Arnaud, F4EIR.  Thanks!
+
+2010-10-24 09:59  we7u
+
+	* config/language-German.sys: Updates by Rolf, DK7IN.  Thanks!
+
+2010-10-05 07:14  chicoreus
+
+	* scripts/db_gis_mysql.sql: Fixing script to generate database and
+	  tables for MySQL based persistence.  Previous versions include
+	  invalid syntax.
+
+	  Changes herein largely follow patch by Dan Zubey N7NMD.
+
+	  This script has now been tested both with grant statments
+	  commented out and with grants included.
+
+2010-09-30 08:35  gstueve
+
+	* scripts/get-NWSdata: Update files for current boundaries.
+
+2010-09-28 20:55  jedunmire
+
+	* src/map_geo.c:     - eliminate the warning about a missing
+	  prototype for
+		DistroyImagePixels() but enabling prototypes for 'private'
+	  functions
+		in GraphicsMagick.
+
+2010-09-23 19:24  jedunmire
+
+	* src/map_OSM.c:     - changes to transparency code for OSM tiled
+	  maps.
+		This fixes the problem with 16-bit *Magick quantums.
+
+2010-09-21 07:46  we7u
+
+	* src/list_gui.c: A patch by Jason Godfrey, N0RPM, which fixes the
+	  segfault on list close problem.  We were calling
+	  XtDestroyWidget() on child widgets, but calling it on the parent
+	  is sufficient.  We just have to make sure there aren't any
+	  references to those child widgets first.
+
+2010-09-08 11:13  jedunmire
+
+	* Makefile.am, src/Makefile.am, src/tile_mgmnt.c, src/tile_test.c:
+	     - Removed obsolete tile experiment application (tile_test)
+	      - Stopped using http 'newer than' requests for OSM tiles. The
+	  'newer
+		than' test was ignored by all observed OSM servers and
+	  caused
+		corrupted downloads and long delays for the topOSM tiles.
+	      - Changed the names of the TopOSM files so that they layer
+		automatically.
+
+2010-08-17 10:26  gstueve
+
+	* src/main.c: Add setlocale() back in place to calm Warnings about
+	  charset mismatch.
+
+2010-08-14 16:21  we7u
+
+	* src/wx.c: Fixes for One-Wire-Daemon ARNE protocol mode to allow
+	  the use of the current string output:  12 parameters instead of
+	  19.  We allow use of either format now.
+
+2010-08-14 14:32  jedunmire
+
+	* Makefile.am, OSM_template, README.OSM_maps, src/map_OSM.c,
+	  src/map_OSM.h, src/map_geo.c, src/tile_mgmnt.c, src/tile_mgmnt.h,
+	  src/tile_test.c:     - fix for '1 of 0' tile download message
+	      - fixed a memory leak in map_OSM.c
+	      - fixed installation of OSM CC icons
+	      - added support for .jpg tiles
+	      - implemented transparency for tiles. No more red blocks for
+	  missing
+		tiles, tiles can be stacked, and lower levels show through
+	  for
+		missing tiles.
+	      - zoom level limits for OSM maps
+	      - New map definitions for topOSM
+
+2010-08-13 14:53  we7u
+
+	* src/map_shp.c: A fix for segfaults caused by some Shapefile maps.
+	  Kyle and Nathan Mills were my consultants for fixing this bug,
+	  though the final bug-fix was mine.
+
+2010-08-10 02:11  we7u
+
+	* src/xa_config.c: Faster processing of the config file.  We now
+	  call fseek to reset to the beginning of the file only if we don't
+	  find a particular option the first time through.  We were calling
+	  it before every search, plus were reading in another line in the
+	  loop before we checked whether we had found the current option
+	  (making us go one too far each time).
+
+2010-08-10 01:39  we7u
+
+	* .cvsignore, src/.cvsignore: Adding a few files to .cvsignore to
+	  keep the cvs status clean.
+
+2010-08-10 01:22  we7u
+
+	* src/: alert.c, db.c, interface.c, interface.h, util.c, util.h,
+	  x_spider.c, xa_config.c: More work to help assure that config
+	  file reading/writing is consistent no matter the locale.
+	  Replacing more dangerous string functions with safer functions.
+	  Combined split_string_char and split_string into one function.
+	  Added get_float() and store_float() function to simplify code.
+
+2010-08-10 01:07  we7u
+
+	* src/main.c: Adding more setlocale() calls before we read in the
+	  config data.
+
+2010-08-04 04:12  we7u
+
+	* config/: OSM_Cloudmade_administrative.dbfawk, Makefile.am,
+	  OSM_Cloudmade_highway.dbfawk, OSM_Cloudmade_natural.dbfawk,
+	  OSM_Cloudmade_poi.dbfawk,
+	  OSM_Cloudmade_water_and_coastline.dbfawk: Adding dbfawk files for
+	  the Open Street Maps "Cloudmade" Shapefile extracts.
+
+2010-08-01 22:12  we7u
+
+	* configure.ac: Mark GeoTiff support as a "no" if we can't find the
+	  geotiff include files.
+
+2010-08-01 21:06  we7u
+
+	* configure.ac: Removing the extra -I for finding libgeotiff.  It
+	  appears to be distribution-specific, depending on where they
+	  decide to stuff the include files.  libgeotiff itself when
+	  installed from sources goes into /usr/include and Xastir finds it
+	  readily.
+
+2010-08-01 15:25  we7u
+
+	* configure.ac: Updating path to libgeotiff include files.
+
+2010-07-30 20:12  jedunmire
+
+	* README.OSM_maps, src/fetch_remote.c, src/fetch_remote.h,
+	  src/map_OSM.c, src/tile_mgmnt.c, src/tile_mgmnt.h,
+	  src/tile_test.c:   - cached OSM tiles are not checked for updates
+	  after 7 days
+	    - tile downloads will use http pipelining if supported by the
+	  server
+	    - new debug level, 8192 for verbose curl output
+
+2010-07-30 11:18  we7u
+
+	* Makefile.am: Fixing a minor hitch the install-exec-hook.
+
+2010-07-29 14:57  jedunmire
+
+	* src/map_OSM.c:     - fixed compile error when map-cache is
+	  disabled
+
+2010-07-27 09:48  we7u
+
+	* src/fetch_remote.c: Adding a prototype needed on some systems.
+
+2010-07-27 01:40  we7u
+
+	* CC_OpenStreetMap_logo.png, CC_OpenStreetMap_txt.png, ChangeLog,
+	  Makefile.am, OSM_template, README.OSM_maps,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/Makefile.am, src/main.c,
+	  src/map_OSM.c, src/map_OSM.h, src/map_WMS.c, src/fetch_remote.c,
+	  src/fetch_remote.h, src/map_geo.c, src/map_tiger.c, src/maps.c,
+	  src/tile_mgmnt.c, src/tile_mgmnt.h, src/tile_test.c,
+	  src/track_gui.c, src/util.c, src/util.h: Open Street Maps tiling
+	  patches by Jerry Dunmire, KA6HLD.  Way to go Jerry!
+
+2010-07-21 04:52  we7u
+
+	* .cvsignore, src/shapelib/contrib/.cvsignore: Updating .cvsignore
+	  files to current build configuration.
+
+2010-07-12 23:12  we7u
+
+	* src/shapelib/contrib/: my_nan.h, shpgeo.c: Attempting to fix the
+	  "endian-ness" tests.
+
+2010-07-12 11:22  we7u
+
+	* src/shapelib/contrib/my_nan.h: Fixing up BYTE_ORDER so that
+	  internal Shapelib compiles on more machines.
+
+2010-07-11 16:39  we7u
+
+	* src/: main.c, objects.h: Getting rid of the final two compiler
+	  warnings, again by switch to the use of intptr_t instead of int.
+	  Other systems may have more warnings, but this OpenSuSE-11.2
+	  64-bit system compiles Xastir cleanly now.
+
+2010-07-11 16:31  we7u
+
+	* src/: draw_symbols.c, interface.c, map_shp.c, messages_gui.c,
+	  objects.c, shp_hash.c, testdbfawk.c: Getting rid of more compiler
+	  warnings, mostly by casting to/from intptr_t.
+
+2010-07-11 14:41  we7u
+
+	* src/rtree/: index.c, index.h, rect.c: Fixed some long-standing
+	  compiler warnings in the rtree code.	Seems to still work
+	  properly.
+
+2010-07-11 13:30  we7u
+
+	* src/shapelib/: dbfdump.c, shputils.c, contrib/dbfcat.c,
+	  contrib/shpdxf.c, contrib/shpgeo.c, contrib/shpproj.c: More minor
+	  tweaks to get rid of compiler warnings.  Of particular note are
+	  some TODO entries added to a couple of files for two enumerated
+	  values that weren't being handled in "switch" statements.  There
+	  still isn't any code for those case statements, but the compiler
+	  warnings are gone.
+
+2010-07-11 01:01  we7u
+
+	* src/shapelib/shputils.c: Adding some braces for some "if"
+	  statements so that the enclosed else clause won't be ambiguous.
+
+2010-07-11 00:57  we7u
+
+	* src/shapelib/: shpdump.c, shptreedump.c, contrib/shpdxf.c: Fixing
+	  a few more compiler warnings.
+
+2010-07-11 00:51  we7u
+
+	* src/shapelib/: shptreedump.c, shputils.c, contrib/shpcentrd.c,
+	  contrib/shpdata.c, contrib/shpdxf.c, contrib/shpfix.c,
+	  contrib/shpinfo.c, contrib/shpproj.c, contrib/shpwkb.c: Fixing
+	  more compiler warnings.  There are a few left yet.
+
+2010-07-11 00:24  we7u
+
+	* src/shapelib/: dbfdump.c, shprewind.c, shputils.c,
+	  contrib/dbfcat.c, contrib/dbfinfo.c, contrib/shpcentrd.c,
+	  contrib/shpdata.c, contrib/shpdxf.c, contrib/shpgeo.c,
+	  contrib/shpinfo.c, contrib/shpproj.c, contrib/shpwkb.c: Fixing
+	  multiple minor warnings with Shapelib.  Still plenty left.
+
+2010-07-10 23:31  we7u
+
+	* src/shapelib/: Makefile.am, contrib/Makefile.am: Changing the
+	  shapelib and shapelib/contrib Makefile.am files so that the
+	  binaries don't get installed during "make install"
+
+2010-07-10 23:22  we7u
+
+	* src/shapelib/: Makefile.am, shputils.c, contrib/Makefile.am:
+	  Setting up the rest of shapelib and shapelib/contrib so that
+	  everything compiles.	Had to add an include to shputils.c and add
+	  a "1" parameter to exit() in one spot.
+
+2010-07-10 22:52  we7u
+
+	* src/shapelib/: Makefile.am, contrib/Makefile.am: Now building
+	  libshape.a in both the shapelib and the shapelib/contrib
+	  directories so that we can build executables in both places
+	  successfully.
+
+2010-07-10 22:39  we7u
+
+	* src/shapelib/: Makefile.am, contrib/Makefile.am: Adding more
+	  binaries into the build.  The ones in "contrib" still depend on
+	  "libshape.a" in the "shapelib" dir and we still need to figure
+	  out how to build that library first.
+
+2010-07-10 13:53  tvrusso
+
+	* src/shapelib/: Makefile.am, contrib/Makefile.am: Modifications to
+	  internal shapelib support so that dbfinfo (from the contrib
+	  directory) builds when internal shapelib builds.  Until now, none
+	  of the "contrib" programs were built.
+
+2010-07-06 23:16  we7u
+
+	* src/main.c: Patch by Jerry Dunmire to prevent use of F4 key (Open
+	  Street Map optimum zoom) when Disable Fast Zoom is activated on
+	  the Map menu.
+
+2010-07-03 15:09  we7u
+
+	* scripts/: coord-convert.pl, inf2geo.pl, mapfgd.pl, overlay.pl,
+	  ozi2geo.pl, permutations.pl, ridge_radar.pl: Removing the
+	  Copyright noticed from scripts that were released to the public
+	  domain.  They are mutually exclusive.
+
+2010-07-02 00:17  we7u
+
+	* config/tl_2009_aiannh.dbfawk: I screwed up the credit on that
+	  last commit.	Those dbfawk files come to us courtesy of Peter
+	  Gamache, KC0TFB.  Sorry about that!
+
+2010-07-02 00:12  we7u
+
+	* config/: Makefile.am, tl_2009_aiannh.dbfawk, tl_2009_aits.dbfawk,
+	  tl_2009_arealm.dbfawk, tl_2009_areawater.dbfawk,
+	  tl_2009_county.dbfawk, tl_2009_cousub.dbfawk,
+	  tl_2009_edges.dbfawk, tl_2009_mil.dbfawk,
+	  tl_2009_nn_county.dbfawk, tl_2009_pointlm.dbfawk,
+	  tl_2009_zcta5.dbfawk: Contributions by Kevin Paetzold, K1KWP.
+	  Thanks!
+
+2010-07-02 00:08  we7u
+
+	* scripts/: Makefile.am, ridge_radar.pl: Adding ridge_radar.pl,
+	  which computes a .geo file for a particular NWS abbreviation.
+	  Contribution by Jeremy McDermond (NH6Z).  Thanks!
+
+2010-06-30 16:31  we7u
+
+	* src/map_OSM.c: Adding the ImageMagick ifdef's back in.  Patch by
+	  Jerry Dunmire.
+
+2010-06-29 23:41  we7u
+
+	* src/: main.c, map_geo.c: F4 key multiple maps fix by Jerry
+	  Dunmire.
+
+2010-06-29 23:25  we7u
+
+	* src/: interface.c, main.c, wx.c, wx.h: A fix for Radio
+	  Shack/Huger/Oregon Scientific weather stations connected via the
+	  WX200d daemon.  This fix may also help direct-connected weather
+	  stations of the above type, but since I don't have any to test
+	  with, it's unknown until someone tries.
+
+2010-06-29 10:01  we7u
+
+	* Makefile.am, tigermap.geo: First step at removing tigermap.geo:
+	  Making it invisible to the user.
+
+2010-06-28 14:25  we7u
+
+	* OSM_cloudmade_1.geo, OSM_cloudmade_2.geo, OSM_cloudmade_5.geo,
+	  OSM_cloudmade_998.geo, OSM_cloudmade_999.geo, OSM_cycle.geo,
+	  OSM_mapnik.geo, OSM_osmarender.geo, OSM_skiing.geo: Removing .geo
+	  files that are now created from a template.
+
+2010-06-28 13:49  we7u
+
+	* OSM_template: Need to commit a new file after Jerry's latest
+	  patch for things to work for everyone else!
+
+2010-06-28 12:17  we7u
+
+	* OSM_cloudmade_1.osm, OSM_cloudmade_2.osm, OSM_cloudmade_5.osm,
+	  OSM_cloudmade_998.osm, OSM_cloudmade_999.osm, OSM_cycle.osm,
+	  OSM_mapnik.osm, OSM_osmarender.osm, OSM_skiing.osm: A bit of
+	  cleanup:  Getting rid of the no-longer-used *.osm files.
+
+2010-06-28 12:14  we7u
+
+	* Makefile.am, OSM_cloudmade_1.geo, OSM_cloudmade_2.geo,
+	  OSM_cloudmade_5.geo, OSM_cloudmade_998.geo,
+	  OSM_cloudmade_999.geo, OSM_cycle.geo, OSM_mapnik.geo,
+	  OSM_osmarender.geo, OSM_skiing.geo, src/main.c, src/map_OSM.c,
+	  src/map_OSM.h, src/map_geo.c, src/maps.c: Mods by Jerry Dunmmire
+	  WRT OSM.  His notes: Summary of changes:   - scaling corrected
+	  - requested OSM map size limited to 2000x2000 and +/-89 deg
+	  latitude   - no 'binned' zoom levels	 - new function key (F4) to
+	  'optimize' zoom level for OSM   - .osm maps eliminated   - OSM
+	  map files (.geo) built from a single template
+
+	  Details:   scaling corrected:     This required a major rewrite
+	  of the map_OSM.c code since	  the map_tiger.c code that it was
+	  based on did not support     Mercator projection.
+
+	      Note that due to size limitations from the server and the
+	      use of Mercator scaling when the OSM bitmap images are
+	  rendered,
+	      some OSM maps will not fill the display window. This is
+	      particularly common when using a large display window.
+	  Selecting
+	      an optimized OSM zoom level (F4) will generally, but not
+	  always,
+	      result in bit map image that fills the window.
+
+	    map size limitations:
+	      The OSM map server that is used by this code limits the
+	  returned
+	      bitmap image to 2000 pixels in either direction. Also, as a
+	  side
+	      effect of the Mercator projection, latitude values must be
+	      limited to -90 < lat < 90.
+
+	    no binned zoom levels:
+	      Attempts to constrain the linear Xastir scaling to the binned
+	      OSM levels has been unsuccessful. The final straw was a
+	  problem
+	      with float to integer transitions that would result in
+	  looping
+	      and oscillation between levels.
+
+	    new function key to optimize OSM zoom levels:
+	      Since bitmap images do not scale well, they will always look
+	      best when the Xastir scale is closest to the OSM scale. A
+	      function key (F4) has been defined that will adjust the
+	  Xastir
+	      scale to the nearest OSM level and redraw the screen. Note
+	  that
+	      even if the scale is not changed, the F4 key will redraw the
+	      screen- this is intentional on my part.
+
+	      The F4 key works only if an OSM map is selected.
+
+	      If the F4 key is already defined for some other use on your
+	      system you can specify an alternative key by modifying the
+	  map
+	      files (OSM*.geo).  The specified value must be an X11 KeySym
+	      value.  Setting the value to 0 will disable the key.
+
+	    .osm maps eliminated
+	      Since binned scale levels are no longer supported, the .osm
+	      extension is no longer needed. .osm file will not be
+	  installed.
+
+	      If your maps directory (typically
+	      /usr/local/share/xastir/maps/Online/) contains .osm file from
+	  an
+	      previous install you will have to remove them by hand.
+
+	      You should also re-index your files
+	      (Map->Configure->Index:Reindex ALL maps) to remove them from
+	  the
+	      Map Chooser.
+
+	    OSM map files (.geo) built from a single template:
+	      This is primarily of interest to developers and results in a
+	      cleaner source tree.
+
+2010-06-28 12:01  we7u
+
+	* configure.ac: Commenting out the tests for libgps, which we're
+	  currently not using.
+
+2010-06-18 22:35  we7u
+
+	* src/interface.c: Skipping the hostname lookup if we pass an IP
+	  address instead of a hostname.
+
+2010-06-18 22:11  we7u
+
+	* src/interface_gui.c: Changing default GPSD port to 2947.
+
+2010-06-18 21:57  we7u
+
+	* configure.ac, src/interface.c: Changes to support pre-2.90 and
+	  post-2.90 versions of GPSD network connections.  We now send the
+	  "R\r\n" command across (old method), then then send:
+	  ?WATCH={"enable":true,"nmea":true}\r\n (new method).	Between the
+	  two strings either version of GPSD daemon gets kick-started into
+	  sending us NMEA strings.
+
+2010-06-17 20:41  we7u
+
+	* configure.ac: Changing one summary line (text only).
+
+2010-06-17 20:07  we7u
+
+	* configure.ac, src/interface.c: Added the configure test for
+	  libgps and the gps.h header file, necessary to continue with
+	  adding gpsd support into Xastir.  More to do yet.
+
+2010-06-17 16:24  we7u
+
+	* src/util.c: Added a debugging statement, but it's commented out.
+	  Useful at times.
+
+2010-06-15 07:29  we7u
+
+	* OpenStreetMaps.osm: Part of the OSM linear patch by Jerry
+	  Dunmire.
+
+2010-06-15 07:28  we7u
+
+	* Makefile.am, OSM_cloudmade_1.geo, OSM_cloudmade_1.osm,
+	  OSM_cloudmade_2.geo, OSM_cloudmade_2.osm, OSM_cloudmade_5.geo,
+	  OSM_cloudmade_5.osm, OSM_cloudmade_998.geo,
+	  OSM_cloudmade_998.osm, OSM_cloudmade_999.geo,
+	  OSM_cloudmade_999.osm, OSM_cycle.geo, OSM_cycle.osm,
+	  OSM_mapnik.geo, OSM_mapnik.osm, OSM_osmarender.geo,
+	  OSM_osmarender.osm, OSM_skiing.geo, OSM_skiing.osm,
+	  src/map_OSM.c, src/map_OSM.h, src/map_geo.c: OpenStreetMaps
+	  linear scaling patches by Jerry Dunmire.  Thanks!
+
+2010-06-10 19:04  we7u
+
+	* OpenStreetMaps.geo: Another patch by Jerry Dunmire, KA6HLD.
+
+2010-06-10 19:02  we7u
+
+	* Makefile.am, OpenStreetMaps.osm, src/main.c, src/map_geo.c,
+	  src/maps.c: Another OSM patch by Jerry Dunmire, KA6HLD.
+
+2010-06-09 16:28  we7u
+
+	* src/: db.c, igate.c, interface.c, interface_gui.c, main.c,
+	  map_OSM.c, map_WMS.c, map_shp.c, map_tiger.c, maps.c,
+	  messages_gui.c, objects.c, view_message_gui.c, wx_gui.c: More
+	  tweaks by Jerry Dunmire, KA6HLD.  These get rid of some compiler
+	  warnings with newer GCC compilers.
+
+2010-06-09 11:51  we7u
+
+	* AUTHORS, Makefile.am, OpenStreetMaps.geo, src/Makefile.am,
+	  src/main.c, src/map_OSM.c, src/map_OSM.h, src/map_geo.c: Initial
+	  patches to use Open Street Maps with Xastir.	This appears to be
+	  a good replacement for the now-defunct Tigermap server.  Patches
+	  contributed by Jerry Dunmire, KA6HLD.  Thanks Jerry!
+
+2010-05-27 07:01  gstueve
+
+	* scripts/: get-fcc-rac.pl, get-gnis: Uodate copyright info in a
+	  couple of scripts.
+
+2010-05-07 09:23  tvrusso
+
+	* src/main.c: Add a very simple hack cribbed from the "Grace"
+	  project
+
+	  http://patch-tracker.debian.org/patch/series/view/grace/1:5.1.22-5/motiflockup.diff
+
+	  to work around some extreme breakage introduced by Xorg server
+	  around version 1.7.5.  This breakage changed the way the server
+	  handles "passive grabs" and has broken *all* motif programs that
+	  use XmCreatePopupMenu (among other things); such programs will
+	  grab the mouse cursor upon creating the pop-up and restrict
+	  cursor motion to within the parent widget of the intended popup,
+	  rendering the desktop completely unusable until the X server is
+	  killed.  The correct fix is to update Xorg server (the fix is
+	  apparently in the yet-to-be-released 1.7.6), but that is not an
+	  option for some users of systems that only use stable releases of
+	  Xorg, and sometimes not even then (think Ubuntu, where they tend
+	  to stick only to bug-fix updates in a given LTS tree, and don't
+	  go to the next release number).  Thus, it is necessary either to
+	  patch motif libraries or work-around the issue in applications.
+	  Since patching motif libraries is not a reasonable thing to
+	  require of our users, it's worthwhile to hack Xastir.
+
+	  The work-around ungrabs the mouse cursor immediately after the
+	  call to XmCreatePopupMenu.  It's an almost trivial modification
+	  of the code.
+
+	  Tested on Xorg-server 1.6.5 and Xorg-server 1.7.5.  Looks good,
+	  so committing it.
+
+	  The fix does have one unfortunate side effect on the newer server
+	  , as it is somewhat more difficult to tap the right mouse button
+	  and get the right-click menu to stay up, but it is possible.	On
+	  the older server it appears to have no effect at all, which is
+	  good.
+
+2010-04-23 07:00  gstueve
+
+	* src/bulletin_gui.c: Remove annoying blank line from end of
+	  bulletin list.
+
+2010-04-21 12:36  gstueve
+
+	* config/Makefile.am: Fix source identification to work for BSD
+	  make. Should now work for new and old make utilities. I like
+	  these derived language files to test for added labels as I admit
+	  to a language deficiency.
+
+2010-04-19 10:48  gstueve
+
+	* config/Makefile.am: Permit derived language files to be generated
+	  from source file w/o requiring configure elements to be rerun.
+
+2010-04-19 10:45  gstueve
+
+	* config/Makefile.am, config/nwsz_ddmmyy_10.dbfawk,
+	  scripts/get-NWSdata: Add matching dbfawk file for new zone
+	  description file from NWS.
+
+2010-03-10 22:24  we7u
+
+	* src/db.c: Initializing a temp area object's color to a value to
+	  get rid of a compiler warning.
+
+2010-03-10 20:03  chicoreus
+
+	* src/: db.c, db_gis.c, db_gis.h, interface.c, interface_gui.c,
+	  main.c: Mike, W2SWR, attempted to deploy Xastir over a MySQL
+	  database, and in the process helped to find multiple issues,
+	  including both an inability to compile xastir with just
+	  --with-mysql, and multiple causes for segfaults starting and
+	  stopping database interfaces and saving data.  This commit
+	  addresses these issues.
+
+	  Xastir now compiles and runs with either or both --with-mysql and
+	  --with-postgis, as reqired definitions for each have now been
+	  appropriately included with preprocessor directives.
+
+	  The key fix for stability is in db_gis.h, the connection array
+	  has been redefined  from an array pointer to an array, and the
+	  MYSQL object in the Connection struct has been changed from a
+	  MYSQL pointer to a MYSQL.  Calls to methods that pass database
+	  connections have been rewritten to pass the address of the
+	  connection (&aDbConnection), rather than the connection.
+
+	  Multiple other fixes, mostly involving correcting the use of
+	  pointers, have been made to the db_gis.c code, and these have
+	  been tested and found to work with storage and retrieval of large
+	  quantities of internet feed data (on the order of 800,000
+	  records) to both MySQL and Postgis databases, with xastir
+	  compiled with --with-mysql, --with-postgis separately, and with
+	  --with-mysql --with-postgis together.
+
+	  Also fixed a user interface bug that prevented retention of a
+	  selection of mysql(spatial) as a database type.
+
+2010-03-05 21:52  we7u
+
+	* FAQ: Adding more info to the Fedora 12 right-click bug
+	  problem/solution.
+
+2010-02-28 07:47  we7u
+
+	* scripts/inf2geo.pl: Added some comments about GM/IM
+	  prerequisites.  Made it clear what the script does for the user.
+
+2010-02-27 17:33  we7u
+
+	* src/x_spider.c: Client connections to Xastir's server port had
+	  this problem:  The last connected client, if it disconnected,
+	  would lock up the server.  The pointer code taking care of
+	  removing objects in the linked list has been reworked.  It no
+	  longer matters which order of client connects/disconnects are
+	  applied to the server.  Thanks to Nathan Mills for helping me
+	  figure this out and test this.
+
+2010-02-19 17:33  gstueve
+
+	* src/interface.c: Fix spelling in error message that lintian
+	  found.
+
+2010-02-16 20:13  chicoreus
+
+	* src/db_gis.c: The node_path stored to a mysql database is not
+	  being truncated correctly with xastir_snprintf(), as the current
+	  length of the station->node_path_ptr that is providing the
+	  character array is used as the limit, rather than the maximum
+	  length allocated for the node_path into which it is being placed,
+	  thus causing a crash on trying to store a MySQL record for a
+	  position when the path exceeds 56 characters in length.
+
+2010-02-16 17:47  we7u
+
+	* FAQ: Tweaked the Fedora 12 right-click answer to point to "yum
+	  update".
+
+2010-02-11 21:13  we7u
+
+	* src/util.c: Taking an initial WIDE2-1 out of the equation which
+	  looks for WIDEn-N following WIDEn-N.
+
+2010-02-06 19:48  we7u
+
+	* Makefile.am: Setting up README.CYGWIN so that it gets copied to
+	  the docs directory with the rest of the docs during the install
+	  step.
+
+2010-02-03 09:37  we7u
+
+	* FAQ: Added Kevin K1KWP's note about getting right-click menus
+	  working in Fedora 12.
+
+2010-02-01 10:37  gstueve
+
+	* testdbfawk.1, xastir_udp_client.1: Quiet some warnings from
+	  manpages about hyphens and minus signs.
+
+2010-01-31 12:10  we7u
+
+	* configure.ac: Bumping the revision number for new development.
+
+2010-01-31 12:09  we7u
+
+	* README.Contributing: Updating text to call out the new place for
+	  the developers instructions (Xastir.org Wiki).
+
+2010-01-31 00:45  we7u
+
+	* ChangeLog: Committing latest ChangeLog (derived from cvs log)
+	  before release.
+
+2010-01-31 00:44  we7u
+
+	* symbols/symbols.dat: Updated wheelchair symbol plus new power
+	  plant symbol by Kyle Mills.  Thanks!
+
+2010-01-31 00:24  we7u
+
+	* README.CYGWIN: A re-written Cygwin install by David Flood,
+	  KD7MYC.  Thanks!
+
+2010-01-31 00:19  we7u
+
+	* README.MAPS: Tweaks by David Aitcheson, kb3efs.  Thanks!  A few
+	  minor tweaks by we7u.
+
+2010-01-30 23:42  we7u
+
+	* ChangeLog: Committing latest changelog before release.
+
+2010-01-30 23:41  we7u
+
+	* configure.ac, scripts/BUILDRPMS, scripts/LSB-BUILD,
+	  scripts/do_xastir_release_dev, scripts/do_xastir_release_stable:
+	  Preparing for 1.9.8 stable release.  Changing revision numbers.
+
+2010-01-30 18:12  we7u
+
+	* AUTHORS, DEBUG_LEVELS, FAQ, INSTALL, LICENSE, Makefile.am, NEWS,
+	  README, README.CVS, README.Contributing, README.Getting-Started,
+	  README.MAPS, README.win32, REGRESSION_TESTS, UPGRADE,
+	  acinclude.m4, bootstrap.sh, callpass.1, changes.txt,
+	  configure.ac, install-xastir, testdbfawk.1, update-xastir,
+	  xastir.1, xastir_udp_client.1, Davis/Makefile.am, Davis/README,
+	  Davis/bootstrap.sh, Davis/configure.ac, Davis/src/Makefile.am,
+	  Davis/src/db2APRS.c, Davis/src/defs.h, LaCrosse/AUTHORS,
+	  LaCrosse/Makefile.am, LaCrosse/README, LaCrosse/bootstrap.sh,
+	  LaCrosse/configure.ac, LaCrosse/src/Makefile.am,
+	  LaCrosse/src/defs.h, LaCrosse/src/open2300db2APRS.c,
+	  callpass/Makefile.am, callpass/callpass.c, config/24kgrid.dbfawk,
+	  config/Makefile.am, config/arealm.dbfawk,
+	  config/areawater.dbfawk, config/cousub.dbfawk,
+	  config/cousub00.dbfawk, config/edge.dbfawk,
+	  config/featnames.dbfawk, config/gps_wpt.dbfawk,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, config/nwsc_ddmmyy.dbfawk,
+	  config/nwsc_ddmmyy_09.dbfawk, config/nwsc_ddmmyy_09b.dbfawk,
+	  config/nwsmzddmmyy.dbfawk, config/nwsmzddmmyy_09.dbfawk,
+	  config/nwsmzoddmmyy.dbfawk, config/nwsozddmmyy.dbfawk,
+	  config/nwsozddmmyy_09.dbfawk, config/nwsw_ddmmyy.dbfawk,
+	  config/nwsw_ddmmyy_09.dbfawk, config/nwsz1ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/nwsz_ddmmyy_09.dbfawk,
+	  config/nwszoddmmyy.dbfawk, config/pointlm.dbfawk,
+	  config/predefined_EVENT.sys, config/predefined_SAR.sys,
+	  config/stored_track.dbfawk, config/tabblock.dbfawk,
+	  config/tgr2shp.dbfawk, config/tgr2shppoly.dbfawk,
+	  config/tgr2shppoly_2006.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrlpt.dbfawk,
+	  config/tgrlpy.dbfawk, config/tgrplc00.dbfawk,
+	  config/tgrwat.dbfawk, config/tnc-startup.aea,
+	  config/tnc-startup.d700, config/tnc-startup.kam,
+	  config/tnc-startup.kpc2, config/tnc-startup.kpc3,
+	  config/tnc-startup.paccomm, config/tnc-startup.pico,
+	  config/tnc-startup.sys, config/tnc-startup.thd7,
+	  config/tnc-startup.tnc2, config/tnc-startup.tnc2-ui,
+	  config/tnc-stop.d700, config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui, help/Makefile.am, help/help-Dutch.dat,
+	  help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, m4/Makefile.am,
+	  scripts/Coordinate.pm, scripts/LSB-BUILD, scripts/LSB-BUILD-ALL,
+	  scripts/LSB-BUILD-CURL, scripts/LSB-BUILD-DB,
+	  scripts/LSB-BUILD-GDAL, scripts/LSB-BUILD-GRAPHICSMAGICK,
+	  scripts/LSB-BUILD-JASPER, scripts/LSB-BUILD-JPEG,
+	  scripts/LSB-BUILD-LESSTIF, scripts/LSB-BUILD-PCRE,
+	  scripts/LSB-BUILD-PNG, scripts/LSB-BUILD-ZLIB,
+	  scripts/Makefile.am, scripts/UIView2XastirLog.pl,
+	  scripts/Xastir_tigerpoly.py, scripts/example_objects.log,
+	  scripts/get-NWSdata, scripts/get-fcc-rac.pl, scripts/get-gnis,
+	  scripts/get-maptools.sh, scripts/get-pop,
+	  scripts/get_shapelib.sh, scripts/inf2geo.pl, scripts/kiss-off.pl,
+	  scripts/langElmerFudd.pl, scripts/langMuppetsChef.pl,
+	  scripts/langOldeEnglish.pl, scripts/langPigLatin.pl,
+	  scripts/langPirateEnglish.pl, scripts/object2shp.pl,
+	  scripts/overlay.pl, scripts/ozi2geo.pl, scripts/permutations.pl,
+	  scripts/pos2shp.pl, scripts/slideshow.pl, scripts/test_coord.pl,
+	  scripts/toporama250k.pl, scripts/toporama50k.pl,
+	  scripts/track-get.pl, scripts/waypoint-get.pl,
+	  scripts/xastir-fixcfg.sh, scripts/xastir-migrate.sh,
+	  src/Makefile.am, src/alert.c, src/alert.h, src/awk.c, src/awk.h,
+	  src/bulletin_gui.c, src/bulletin_gui.h, src/color.c, src/color.h,
+	  src/database.h, src/datum.c, src/datum.h, src/db.c, src/db_gis.c,
+	  src/db_gis.h, src/dbfawk.c, src/dbfawk.h, src/draw_symbols.c,
+	  src/draw_symbols.h, src/fcc_data.c, src/fcc_data.h,
+	  src/festival.c, src/festival.h, src/geo-client.c, src/geo-find.c,
+	  src/geo.h, src/geocoder_gui.c, src/gps.c, src/gps.h,
+	  src/hashtable.c, src/hashtable.h, src/hashtable_itr.c,
+	  src/hashtable_itr.h, src/hashtable_private.h, src/hostname.c,
+	  src/hostname.h, src/igate.c, src/igate.h, src/interface.c,
+	  src/interface.h, src/interface_gui.c, src/io-common.c,
+	  src/io-mmap.c, src/io.h, src/lang.c, src/lang.h,
+	  src/leak_detection.h, src/list_gui.c, src/list_gui.h,
+	  src/locate_gui.c, src/location.c, src/location_gui.c,
+	  src/macspeech.c, src/main.c, src/main.h, src/map_WMS.c,
+	  src/map_cache.c, src/map_cache.h, src/map_dos.c, src/map_gdal.c,
+	  src/map_geo.c, src/map_gnis.c, src/map_pdb.c, src/map_pop.c,
+	  src/map_shp.c, src/map_tif.c, src/map_tiger.c, src/maps.c,
+	  src/maps.h, src/messages.c, src/messages.h, src/messages_gui.c,
+	  src/objects.c, src/objects.h, src/popup.h, src/popup_gui.c,
+	  src/rac_data.c, src/rac_data.h, src/rotated.c, src/rotated.h,
+	  src/rpl_malloc.c, src/rpl_malloc.h, src/shp_hash.c,
+	  src/shp_hash.h, src/snprintf.c, src/snprintf.h, src/sound.c,
+	  src/symbols.h, src/testdbfawk.c, src/track_gui.c,
+	  src/track_gui.h, src/util.c, src/util.h, src/view_message_gui.c,
+	  src/wx.c, src/wx.h, src/wx_gui.c, src/x_spider.c, src/x_spider.h,
+	  src/xa_config.c, src/xa_config.h, src/xastir.h,
+	  src/xastir_udp_client.c, src/rtree/Makefile.am, src/rtree/card.c,
+	  src/rtree/card.h, src/rtree/gammavol.c, src/rtree/index.c,
+	  src/rtree/index.h, src/rtree/node.c, src/rtree/rect.c,
+	  src/rtree/sphvol.c, src/rtree/split_l.c, src/rtree/split_l.h,
+	  src/rtree/split_q.c, src/rtree/split_q.h,
+	  src/shapelib/Makefile.am, src/shapelib/contrib/Makefile.am,
+	  symbols/Makefile.am, symbols/symbols.dat: Updating Copyright
+	  notice for 2010.
+
+2010-01-25 20:09  chicoreus
+
+	* src/db_gis.c: Make fails with errors	when configured with just
+	  --with-mysql.  Fixing nesting of HAVE_POSTGIS and HAVE_MYSQL
+	  directives so that xastir will build with just --with-mysql.
+	  Both compiler warnings and runtime errors remain when built
+	  --with-mysql --without-postgis.
+
+2010-01-16 22:27  tvrusso
+
+	* src/main.c: Fix three instances of a string compare being
+	  attempted by:    char chararray[EXTENT]    read chararray from
+	  some file    if (chararray == "string literal")    {	  }
+
+	  which is bad form in C and could lead to undefined behavior.	The
+	  correct way to do this is with strcmp or strncmp.  I replaced
+	  this with:
+
+	     if (strncmp(chararray,"string literal",strlen(chararray))==0)
+	     {
+	     }
+
+	  This is silently accepted by most older compilers, but is warned
+	  about by gcc 4.4 (the default compiler in Ubuntu 9.10).
+
+2010-01-12 11:32  tvrusso
+
+	* src/objects.c: Fix to my most recent fix; make sure that the code
+	  that doesn't get the compiler warning actually does the same
+	  thing that it did before the fix.
+
+2010-01-12 09:47  tvrusso
+
+	* src/objects.c: Minor tweak to silence a warning about
+	  "dereferencing type-punned pointer breaks strict-aliasing rules."
+
+2010-01-11 19:30  tvrusso
+
+	* src/: db.c, objects.c:
+	  Fix two bugs.
+
+	  1) Bug 1698474 in the sourceforge tracker (Expire code messes up
+	  internal linked-list order)
+
+	     The title of the bug is erroneous.  The expire code doesn't
+	  mess up
+	     any internal linked-list order.  The expire code was being
+	  messed
+	     up by a broken linked-list order.	What was breaking the list
+	  was
+	     the handling of our own objects.  Code throughout objects.c
+	  was
+	     continually resetting the time stamp of station records to
+	     sec_now() withouth then moving the station record to the end
+	  of the
+	     time-sorted list.	This led to the time-sorted list not being
+	     time-sorted anymore.  The expire code explicitly depends on
+	  the
+	     list remaining sorted at all times.
+
+	     There was also a small block of code dating back to version
+	  1.1 of
+	     db.c that also skipped moving a station record in the
+	  time-sorted
+	     list if it was our object or item.  This very old code appears
+	  to
+	     do nothing at all.  I have removed it.  The time sorted list
+	  MUST
+	     be kept in time-sorted order.  There was also a variable
+	     (object_is_mine_previous) that was set by this block of code
+	  but never
+	     accessed anywhere else.  I've removed that variable, too.
+
+	     Additionally, the check_station_remove function erroneously
+	  checks
+	     "is_my_station" to determine if the station or object in
+	  question is
+	     owned by "me."  It should be checking (is_my_station ||
+	  is_my_object_item)
+	     to be consistent with the older conditional that is commented
+	  out just
+	     above it.
+
+	  2) Creating an object that has the same name as a previously
+	  killed object    would lead to an "immovable" object being
+	  created.  This bug was never	  entered into the issue tracker.
+
+	     Prior to this commit, the following actions would create an
+	  object that
+	     could not be moved:
+
+		 create object a
+		 delete object a
+		 create object a
+
+	     Once the second create was done, the object a could not be
+	  moved by any
+	     means on the screen -- either by dragging with the Move button
+	  down or
+	     using the Modify Object dialog.
+
+	     The reason was that the code to handle resurrecting a killed
+	  object
+	     was improperly flagging the new object as being "my station"
+	  in
+	     addition to being flagged as "my object."	The code that
+	  decodes
+	     position strings would see this flag and refuse to move the
+	  object
+	     "because I know my position better."  Furthermore, the
+	  resurrection
+	     code would remove the old killed record from the name-sorted
+	  list,
+	     but not really delete the station record, leaving it in the
+	     time-sorted list.	This also impacted expiration.	This commit
+	     fixes the improper flagging as "my station" and completely
+	  deletes
+	     the station record for a killed object when we create a new
+	  object
+	     with the same name.
+
+2010-01-01 15:04  we7u
+
+	* src/main.c: Fixed some side-effects regarding zoom boxes when map
+	  lock is enabled.
+
+2010-01-01 06:22  gstueve
+
+	* src/db.c: Recall one of my tests from the wild. It escaped before
+	  its' time.
+
+2009-12-31 03:10  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Finishing up the map
+	  lock code.
+
+2009-12-29 13:56  we7u
+
+	* src/main.c: Detaching the map lock from three areas where they
+	  are more complicated operations and therefore aren't easily done
+	  by mistake.  Therefore no map lock required for those three.
+
+2009-12-27 08:26  gstueve
+
+	* callpass.1, testdbfawk.1, xastir.1, xastir_udp_client.1: Update
+	  APRS site reference to useful URL.
+
+2009-12-27 07:29  gstueve
+
+	* callpass.1: Add reference to xastir in NAME section to allow
+	  `apropos` to associate.
+
+2009-12-25 07:20  we7u
+
+	* README: Updating the SuSE 11.x ham repository info.
+
+2009-12-22 13:37  gstueve
+
+	* Makefile.am, src/db.c, src/lclint.script: Add additional man
+	  pages to list for publication.
+
+2009-12-22 13:20  gstueve
+
+	* callpass.1, testdbfawk.1, xastir.1, xastir_udp_client.1: Add
+	  simple documentation for all applications. Provide APRS reference
+	  in NAME section for 'apropos' & 'whatis' lookup. Make sure NAME
+	  section is parseable for scanning.
+
+2009-12-22 02:56  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/xa_config.c,
+	  src/xastir.h: Adding map zoom/pan lock feature to the Map menu.
+
+2009-12-17 09:44  gstueve
+
+	* xastir.spec.in: Allow rpmbuild spec to work for 64bit
+	  environments also.
+
+2009-12-08 11:34  we7u
+
+	* README.MAPS: Updating the location of the RAC callsign manual
+	  download to match the URL in the get-fcc-rac.pl script.
+
+2009-12-07 16:34  tvrusso
+
+	* FAQ: Update FAQ to include updated answer to the "black images
+	  from imagemagick" question, and add a FAQ about compilation woes
+	  due to use of ImageMagick with HDRI support.
+
+2009-12-04 10:54  tvrusso
+
+	* src/: map_WMS.c, map_geo.c, map_tiger.c:
+	  Fix for the problem where Xastir will display black images when
+	  compiled against GraphicsMagick with its new default QuantumDepth
+	  of 8, or ImageMagick with its optional QuantumDepth of 8.
+
+	  The problem was that when the image was not a colormapped image
+	  (e.g. JPEG or other full color type), Xastir was assuming
+	  (incorrectly) that a Quantum was the same type as the red, green,
+	  and blue components of an XColor, and using the Quantums directly
+	  out of the pixel_pack in a call that required the latter.  The
+	  result was that when pack_pixel_bits returned, the result was
+	  always that the packed pixel bits were always 0x000000, because
+	  it was taking the high-order 8 bits from the unsigned short to
+	  which the unsigned char was being cast.
+
+	  What was needed was a little block of code that massaged the
+	  pixel_pack values into unsigned shorts at that point if
+	  QuantumDepth is 8.
+
+	  This fix applies the same fix to map_tiger, map_geo and map_WMS,
+	  all of which had duplicated code (ugh) that made the same
+	  mistaken assumption of Quantum/unsigned short equivalence.
+
+	  This fix does NOT address the problem that exists on a few
+	  systems, where ImageMagick has been compiled with HDRI (High
+	  Dynamic Range Image) support.  On those systems, a Quantum is not
+	  even an integer type, it's a float or double.  Dealing with
+	  *that* mess will be harder.
+
+	  Ideally, the duplicated code between map_WMS, map_geo, and
+	  map_tiger should be consolidated according to good software
+	  engineering principles.
+
+2009-11-26 08:52  tvrusso
+
+	* LaCrosse/src/open2300db2APRS.c:
+	  Fix for an insidious bug in open2300db2APRS that relied on an
+	  unsafe internal behavior of the mysql API.
+
+	  The function Get_Latest_WX makes 2 SQL queries to the server, one
+	  to get the highest value of the "timestamp" field present in the
+	  DB, an another to get the row with that timestamp.  Only after
+	  the first query was the function calling "row =
+	  mysql_fetch_row(&result)".  That function returns a char ** that
+	  can be used to pick off the field values.  Somehow, despite never
+	  being called after the second query, the row array still managed
+	  (on some systems) to have the right data in it --- presumably
+	  because the API call was returning a pointer to an internal block
+	  of memory that contained the field values, and on the systems
+	  where this worked that block wasn't moving.
+
+	  When I upgraded my BSD system and recompiled mysql, this started
+	  failing, and open2300db2APRS would segfault.
+
+	  Calling mysql_fetch_row after the second query fixes it.
+
+	  While I was at it, I fixed a mistake in some debug output that
+	  prints the number of fields retrieved by the query.
+
+2009-11-09 12:46  we7u
+
+	* scripts/UIView2XastirLog.pl: New script to convert UI-View log
+	  files to Xastir-format log files.  Timestamp info is currently
+	  removed during the conversion.
+
+2009-10-13 23:25  we7u
+
+	* scripts/get-NWSdata: Updating the get-NWSdata script to snag the
+	  latest-latest NWS Shapefile maps used for weather alerts.
+
+2009-10-13 23:24  we7u
+
+	* config/: Makefile.am, nwsc_ddmmyy_09b.dbfawk,
+	  nwsmzddmmyy_09.dbfawk, nwsozddmmyy_09.dbfawk,
+	  nwsw_ddmmyy_09.dbfawk, nwsz_ddmmyy_09.dbfawk: Adding yet another
+	  round of dbfawk files to match new NWS Shapefile signatures.
+
+2009-10-11 22:18  we7u
+
+	* configure.ac: Bumping devel version up to 1.9.7
+
+2009-10-10 11:28  we7u
+
+	* scripts/: do_xastir_release_dev, do_xastir_release_stable:
+	  Updating to new SourceForge release process.
+
+2009-10-10 10:41  we7u
+
+	* ChangeLog, configure.ac, scripts/BUILDRPMS, scripts/LSB-BUILD,
+	  scripts/do_xastir_release_dev, scripts/do_xastir_release_stable:
+	  Preparing for 1.9.6 stable release.
+
+2009-08-12 11:59  we7u
+
+	* src/main.c: Adding minWidth and minHeight to the fallback
+	  resources string in main() to attempt fixing the compiz/fusion
+	  bug with tiny unsizeable dialogs.
+
+2009-08-12 11:14  we7u
+
+	* FAQ: Adding a blurb regarding "compiz" and cigar-shaped windows
+	  in Xastir.   Thanks to Tom R. for this text which I modified
+	  somewhat.
+
+2009-07-31 21:19  tvrusso
+
+	* config/nwsc_ddmmyy_09.dbfawk: Add a comment about the difference
+	  between this file and the nwsc_ddmmyy file.
+
+2009-07-31 21:17  tvrusso
+
+	* config/: Makefile.am, nwsc_ddmmyy_09.dbfawk: Add a new
+	  nwsc_ddmmyy file with different signature to match the very
+	  latest shapefiles.
+
+	  I am adding this as a new dbfawk instead of modifying the
+	  existing one so that those who don't wish to update their
+	  shapefiles will not have to, and those who have only the new ones
+	  will actually be able to use them.  Xastir will pick the dbfawk
+	  file with the matching signature.
+
+2009-07-31 15:38  we7u
+
+	* src/wx_gui.c: Changing the weather alert FINGER server since
+	  WXSVR.net has been offline for a while.  We're switching to
+	  Pete's new system (AE5PL) which is already online and functional.
+
+2009-07-30 12:41  tvrusso
+
+	* symbols/symbols.dat: Change color of ICP (Incident Command Post,
+	  /c) symbol to match the color specified in FEMA and NWCG ICS
+	  materials.  (I'm working through lots of these courses while
+	  simultaneously trying to get Xastir integrated more into our
+	  local SAR system, and getting these discrepancies of terminology
+	  and symbology fixed is important).
+
+2009-07-28 15:51  tvrusso
+
+	* config/predefined_SAR.sys: Make predefined SAR objects conform
+	  with NIMS standard ICS terminology.
+
+	  There is no "Helipoint" in that terminology.	The term "Helispot"
+	  is used for what we were previously calling a "Helipoint."
+
+2009-07-28 15:49  tvrusso
+
+	* src/objects.c: Fix predefined object name to conform with
+	  standard ICS terminology.  A "Helispot" is a temporary landing
+	  place for helicopters.  There is no "Helipoint" in standard ICS
+	  terminology.
+
+2009-07-28 14:35  we7u
+
+	* src/alert.c: Temporary change to allow viewing of compressed-zone
+	  format alerts sent by Pete Loveall, AE5PL's server.
+
+2009-07-27 18:44  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h: Display of latest
+	  comment if H2O symbol plus object or item, and the comment time =
+	  the latest object/item update time.  This is to support fast
+	  viewing of flood gauges during emergencies, using the data from
+	  the Firenet gage.pl script.
+
+2009-06-29 00:14  we7u
+
+	* src/db.c: Fixing Canadian callsign lookup to add VO and VY
+	  prefixes.
+
+2009-06-19 23:01  tvrusso
+
+	* src/shp_hash.c: Insert a conditional around code that uses a
+	  pointer returned by SHPReadObject.  A user is finding that
+	  SHPReadObject is having an fread problem on one of his
+	  shapefiles, and returning NULL.  This commit prevents Xastir from
+	  trying to dereference the null pointer.
+
+2009-06-03 21:25  we7u
+
+	* src/shapelib/: dbfadd.c, dbfcreate.c, shpadd.c, shpcreate.c,
+	  shpdump.c, shptest.c, shptreedump.c, shputils.c: Getting rid of
+	  compiler warnings due to unused variable.
+
+2009-06-03 15:24  we7u
+
+	* src/shapelib/: dbfadd.c, shpcreate.c: Adding includes for
+	  string.h to get rid of compiler warnings.
+
+2009-06-03 14:57  tvrusso
+
+	* src/shapelib/Makefile.am: Not really sure why this worked before
+	  but now doesn't work for Curt, but there was nothing in the
+	  src/shapelib/Makefile.am to make the {shp,dbf}{add,create}
+	  programs link with the shapelib we just built.
+
+	  Put that in.
+
+	  Rebootstrap before trying.
+
+2009-05-22 16:23  we7u
+
+	* scripts/pos2shp.pl: Changed some comments WRT the TODO for the
+	  comment field.
+
+2009-05-22 14:41  we7u
+
+	* README.MAPS: Adding bits about APRS Overlay files and the
+	  pos2shp.pl script.
+
+2009-05-22 14:35  we7u
+
+	* scripts/Makefile.am: Adding pos2shp.pl to list of scripts to
+	  install.
+
+2009-05-22 14:23  we7u
+
+	* scripts/pos2shp.pl: Better version.  Limits $name to 9 chars and
+	  chops trailing spaces on same.
+
+2009-05-22 14:14  we7u
+
+	* scripts/pos2shp.pl: First working version.  Needs more error
+	  checking, needs to assure the name field is properly formatted,
+	  and needs to do something with the comment field yet.
+
+2009-05-22 13:16  we7u
+
+	* scripts/pos2shp.pl: Updated comments, removed live_or_dead code.
+	  Has NOT been converted to parse POS format files yet (Overlay
+	  files).
+
+2009-05-22 11:19  we7u
+
+	* scripts/pos2shp.pl: Start of a pos2shp.pl script.  No code
+	  changes yet from the original object2shp.pl script it started
+	  from.
+
+2009-05-22 10:44  tvrusso
+
+	* src/shapelib/Makefile.am: Change internal shapelib makefile so
+	  that it *does* install the create and add programs if we're
+	  building with internal shapelib.
+
+	  Note:  This should not be tested by those who have shapelib tools
+	  installed from a package unless you know how to do it without
+	  clobbering them.
+
+	  Hint:  configure --prefix=/some/other/base/than/usr/local will
+	  make sure that the new test install doesn't clober anything that
+	  the normal install created.
+
+2009-05-22 10:30  tvrusso
+
+	* src/shapelib/Makefile.am: Add "noinst_PROGRAMS" to the internal
+	  shapelib build so that shpcreate, shpadd, dbfcreate and dbfadd
+	  are built if the user is building the local shapelib.
+
+	  They are not installed, because I didn't want to test that
+	  feature.  To make it so that they *are* installed when make
+	  install is called, one needs only change "noinst_PROGRAMS" in
+	  src/shapelib/Makefile.am to "bin_PROGRAMS" .
+
+2009-05-19 13:47  tvrusso
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/database.h, src/wx.c: Add
+	  support for the Davis 6540 "Weatherlink for APRS" with "Streaming
+	  Data Logger".  This attachment to the Davis Vantage Pro causes
+	  the device to stream APRS posits (sans fromcall, tocall, and
+	  path) to the serial port instead of requiring polling.  With such
+	  a device, Meteo and the associated glue program (db2APRS or
+	  whatever it's called) are unnecessary, so long as this patch is
+	  in place.
+
+	  Also update language files as needed.
+
+2009-05-09 07:15  tvrusso
+
+	* src/db.c: Move "create_garmin_waypoint" call outside of "if
+	  (sound_play_prox_message)" conditional.
+
+	  A local user was completely confused why his garmin wasn't
+	  receiving waypoint data from Xastir, and when I hunted through
+	  the coude found that this feature only works if you have audio
+	  alerts for proximity warnings turned on.  This seems wrong, so I
+	  moved the conditionals around so that waypoints are created if
+	  you're within proximity warning distance, whether or not you've
+	  actually got the old audio alarm turned on for proximity
+	  warnings.
+
+2009-04-30 12:25  gstueve
+
+	* src/: database.h, db.c: Fix band opening logic to ignore 3rd
+	  party traffic. Should make this really work for band opening and
+	  not messages from network. Fix Bug ID:2749796.
+
+2009-04-30 11:52  gstueve
+
+	* src/: main.c, shp_hash.c, shp_hash.h: We already know the current
+	  time, there is no need to ask again.
+
+2009-04-29 20:08  gstueve
+
+	* scripts/get-fcc-rac.pl: Minimize memory footprint for constrained
+	  systems. Do memory intense activity as late as possible.
+
+2009-04-25 23:40  tvrusso
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c:
+	  Fix an annoyance related to DF bearing reports.
+
+	  Sometimes a bad parse of garbled Mic-E data causes Xastir to
+	  think that a D700 (or other mobile) is sending a DF report.  Even
+	  if only a single such garbled transmission is received, the
+	  station is shown with DF bearing information for as long as it's
+	  in the database.  Watching a mobile drive around with randomly
+	  moving DF beam lines is distracting.	Not being able to make it
+	  go away without restarting Xastir has been annoying.
+
+	  Another way for this to happen is for some bonehead (such as
+	  KM5VY) to create a series of DF objects from an external program
+	  with his callsign as base name and sequential numbers to identify
+	  the reports (say "KM5VY-1", "KM5VY-2", etc.) until he happens to
+	  hit the SSID of the station that's sending the reports (say,
+	  KM5VY-8).  What happens is the "object" data gets attached to the
+	  Xastir instance itself.  This bogus beam heading shows up forever
+	  until shutting down Xastir.  This happened today on a SAR ELT DF
+	  practice.  The name of the bonehead has not been changed to
+	  protect the bonehead.
+
+	  This commit adds the ability to clear such bogosity.	Now, the
+	  "Station Info" dialog for any station with DF bearing information
+	  has a "Clear DF Bearing" button that will zero out the bearing
+	  and NRQ strings for the station, removing the unwanted (and
+	  presumably incorrect) bearing lines until the station transmits
+	  them again (which probably means they're wanted and not
+	  incorrect).
+
+2009-04-25 21:53  tvrusso
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/draw_symbols.c,
+	  src/draw_symbols.h, src/main.c, src/main.h, src/xa_config.c:
+	  Add a map-decluttering option.
+
+	  Prior to this commit, "Station->Filter Display->Display DF
+	  Attributes" would draw a pair of bearing lines for every DF
+	  object.  The lines drawn represented the stated beamwidth of the
+	  report.
+
+	  Unfortunately, in a big DFing operation, this rapidly leads to a
+	  huge clutter on the map, making it very difficult, if not
+	  impossible,  to read.  I saw this during a big DF practice this
+	  morning, and just had to change it.
+
+	  I have added two new buttons under Display DF Attributes:
+	  "Display DF Beamwidth" and "Display DF Bearing."  Selecting the
+	  first and not the second gives the current behavior.	Selecting
+	  the second and not the first draws only the stated bearing, not
+	  the beamwidth.  Selecting both draws all three lines for those
+	  who really, really like cluttered maps.  The color of red used
+	  for the bearing line and the beamwidth lines is slightly
+	  different.
+
+	  I tried to set up xa_config so that when people first start up
+	  Xastir after updating, they'll recover the original behavior ---
+	  "Display DF Bearing" defaults to off if it's not found in the
+	  config file.	Unless the new option is deliberately selected,
+	  users should not notice the change.
+
+	  Both Display DF Bearing and Display DF Beamwidth are greyed out
+	  if "Display DF Attributes" is deselected.
+
+	  Updated all the language files with the "update-language.pl"
+	  script to support the new menu items.  A lot of other things got
+	  changed in the language files with this action, but those seemed
+	  mostly to be comments.
+
+2009-04-24 13:10  gstueve
+
+	* scripts/get-fcc-rac.pl: Move sort back to system package. PERL
+	  does parsing well, not sorting.
+
+2009-04-17 16:10  we7u
+
+	* config/: arealm.dbfawk, areawater.dbfawk, cousub.dbfawk,
+	  cousub00.dbfawk, edge.dbfawk, featnames.dbfawk, pointlm.dbfawk,
+	  tabblock.dbfawk: Updating the URL for the Shapefiles to point to
+	  the 2008 shapefiles instead of 2007!
+
+2009-04-17 09:12  we7u
+
+	* config/: Makefile.am, arealm.dbfawk, areawater.dbfawk,
+	  cousub.dbfawk, cousub00.dbfawk, edge.dbfawk, featnames.dbfawk,
+	  pointlm.dbfawk, tabblock.dbfawk: Adding the dbfawk files worked
+	  on by Richard Polivka, N6NKO, Craig Anderson, N6YXK, and Dale
+	  Seaburg, KG5LT, which help to nicely render 2008 Tiger Shapeline
+	  files.
+
+	  A note from Craig about layering:
+
+	    "...use "vi" on the map_index.sys file while xastir is not
+	  running.
+	    Once you are editing the file, use the following 3 commands in
+	  "vi"
+	    to change the layers.  This assumes that, like with my xastir,
+	  new
+	    maps get added into the list at layer 1000.
+
+	    :g/tabblock/s/01000/00995/
+	    :g/pointlm/s/01000/00996/
+	    :g/arealm/s/01000/00997/
+
+	    (translation: global search throughout the file for lines with
+	    "arealm" and substitute on that line for "01000", a "00997")
+
+	    This moves the tabblock (& tabblock00) files, pointlm files,
+	  and
+	    arealm files down underneath the roads maps.  Otherwise the
+	  roads
+	    can get covered up by urban background coloring.  Or you can do
+	  this
+	    through the GUI interface as well."
+
+2009-04-16 19:55  we7u
+
+	* src/wx.c: Fixing up the Peet Bros 2000 data logging and packet
+	  mode decoding for wind direction.  These were really 4-character
+	  fields but the first two chars should be zeroed out.	We were
+	  reading in only the 2nd two characters and then zeroing them out
+	  (the reading of interest).
+
+2009-04-16 14:20  tvrusso
+
+	* scripts/values.pl.in: Change values.pl.in so it references
+	  #!/usr/bin/perl instead of #!/bin/perl.
+
+	  Neither is strictly correct since perl could be installed just
+	  about anywhere on any system, but this brings it in line with all
+	  the rest of the scripts here.
+
+	  Ideally the location of the perl interpreter should be probed by
+	  configure and substituted in all the scripts, but that is
+	  probably more work than it's worth given that all of our scripts
+	  have had /usr/bin/perl hardcoded all this time.
+
+	  #!/usr/bin/env perl
+
+	  is sometimes suggested to make such scripts system-independent,
+	  but this is generally considered a security vulnerability because
+	  it uses the first "perl" that appears in the user's path, which
+	  might be a malicious bit of code.
+
+2009-04-16 12:34  tvrusso
+
+	* configure.ac, scripts/Makefile.am, scripts/values.in,
+	  scripts/values.pl.in: Remove inappropriate use of GNU Make
+	  extensions in scripts/Makefile.am.
+
+	  These were introduced to generate scripts/values and
+	  scripts/values.pl from scripts/values.in and
+	  scripts/values.pl.in, but this is the wrong approach.  Generating
+	  these files from the .in's should be done by adding them to the
+	  configure.ac AC_CONFIG_FILES list and by using standard
+	  substitution strings in the .in files.  Non-standard substitution
+	  strings can also be used if one also adds AC_SUBST calls to the
+	  configure.ac file.
+
+	  The standard substitution string for prefix is @prefix@ not
+	  @PREFIX at .
+
+2009-04-16 12:26  gstueve
+
+	* scripts/Makefile.am: Makefile should actually work properly for
+	  split source/build configuration.
+
+2009-04-16 11:56  gstueve
+
+	* scripts/Makefile.am: Make sure proper Makefile is updated when
+	  Makefile.am is updated.
+
+2009-04-16 11:39  we7u
+
+	* src/: main.c, messages.h, view_message_gui.c, xa_config.c:
+	  Saving/restoring the status of the CAD Objects buttons and the
+	  View Messages TNC/NET/MINE selection buttons.
+
+2009-04-16 11:28  gstueve
+
+	* scripts/: get-NWSdata, get-gnis, get-pop: Remove another possible
+	  bashism reported by checkbashisms script.
+
+2009-04-16 09:25  we7u
+
+	* scripts/: Makefile.am, slideshow.pl: Adding slideshow.pl, a
+	  script which snags the snapshot.png files into a separate
+	  directory and renames them for possible later use as a slideshow
+	  or animated movie.
+
+2009-04-13 13:18  gstueve
+
+	* scripts/get-pop: Position files are only ASCII, don't push AK or
+	  HI through recoding.
+
+2009-04-13 13:10  gstueve
+
+	* scripts/get-pop: Adjust download site to complete list. Retain
+	  tamu site for reference.
+
+2009-04-13 11:34  gstueve
+
+	* src/: locate_gui.c, maps.h: Add ability to locate map features
+	  from population format files.
+
+2009-04-13 11:13  gstueve
+
+	* src/map_pop.c: Missed these. Had compiled on other system.
+	  Mistyped entry.
+
+2009-04-13 10:32  gstueve
+
+	* src/: map_gnis.c, map_pop.c: Found a couple of locations that
+	  could get unhappy about trying to read bad data.
+
+2009-04-13 10:16  gstueve
+
+	* scripts/Makefile.am, scripts/get-pop, src/Makefile.am,
+	  src/map_pop.c, src/maps.c: Reintroduce previous population
+	  geolocator processing into new file type.  The .pop file
+	  extension will reflect the old information. GNIS does not have
+	  authorative population data, we should use census info. The
+	  script will look to aprs.tamu.edu but I was not able to locate
+	  all of the states data files.
+
+2009-04-08 09:24  gstueve
+
+	* scripts/get-gnis: Get rid of bashism that escaped my first tests.
+
+2009-04-08 09:17  gstueve
+
+	* scripts/get-gnis: Add recode to convert AK & HI UTF-16 files to
+	  UTF-8 to give us a fighting chance to actually locate anything in
+	  those states.
+
+2009-04-07 14:17  gstueve
+
+	* scripts/get-gnis: USGS has made geocodes a moving target. Current
+	  file is 20090401.
+
+2009-04-07 02:23  gstueve
+
+	* src/main.c: Repair damage to map properties dialog inflicted by
+	  last check-in.
+
+2009-04-06 09:07  gstueve
+
+	* src/interface_gui.c: Move Path entries around to reduce vertical
+	  challenge.
+
+2009-04-05 17:28  gstueve
+
+	* src/map_gnis.c: Update field sequence to match current GNIS file
+	  layout.
+
+2009-04-04 23:10  gstueve
+
+	* src/list_gui.c: Update max display list to symbolic count.
+
+2009-04-04 21:14  gstueve
+
+	* src/list_gui.c: Clean up station list to actually line up with
+	  icon and line height.
+
+2009-04-04 19:21  gstueve
+
+	* src/objects.c: Maintain pointer to cursor to keep memory usage
+	  clean.
+
+2009-04-04 11:37  gstueve
+
+	* scripts/: .cvsignore, Makefile.am, coord-convert.pl, get-NWSdata,
+	  get-fcc-rac.pl, get-gnis, icontable.pl, values.in, values.pl.in,
+	  xastir-fixcfg.sh, xastir-migrate.sh: Fix the scripts to match the
+	  structure for placement of files by using -prefix from configure
+	  process to allow matchup to FHS placement.
+
+2009-04-04 11:28  gstueve
+
+	* m4/xmhtml.m4: Wrap macro name to keep everyone happy. Remove
+	  autoreconf complaint.
+
+2009-04-03 07:08  gstueve
+
+	* src/: main.c, main.h: Upgrade to session aware application space.
+	  Permit GNOME window manager to clean up without warning message
+	  about unsaved data. Permit restart to keep proper character
+	  translations for display. Clean up some free memory leaks and
+	  update for Motif 2.0 XmString functions.
+
+2009-04-02 18:22  gstueve
+
+	* src/interface.c: Remove extraneous include entry.
+
+2009-04-02 15:09  gstueve
+
+	* src/xastir.h: Remove external reference to internal application
+	  close out function.
+
+2009-03-31 20:06  tvrusso
+
+	* scripts/object2shp.pl: Fix a minor, but completely
+	  inconsequential error in this script.  It would produce
+	  shapefiles with every shape having the same ID attribute.
+	  Doesn't matter at all since ID is not used for anything, but this
+	  is the right fix.
+
+2009-03-31 12:56  we7u
+
+	* src/rac_data.c: Fixing a 64-bit mode bug in the RAC callsign
+	  lookup code.
+
+2009-02-06 09:22  gstueve
+
+	* README.MAPS: Add hint for Australian rules Weather Alerts &
+	  update address for FCC data.
+
+2009-02-06 08:51  gstueve
+
+	* scripts/get-NWSdata: Update to latest from US NWS.
+
+2009-01-08 17:53  we7u
+
+	* README.win32: Adding notes WRT a Cygwin xorg-x11-devel 7.x
+	  compile error and how to fix it, courtesy of David Flood, KD7MYC.
+
+2009-01-02 00:15  we7u
+
+	* src/Makefile.am, src/alert.c, src/alert.h, src/awk.c, src/awk.h,
+	  src/bulletin_gui.c, src/bulletin_gui.h, src/color.c, src/color.h,
+	  src/database.h, src/datum.c, src/datum.h, src/db.c, src/db_gis.c,
+	  src/db_gis.h, src/dbfawk.c, src/dbfawk.h, src/draw_symbols.c,
+	  src/draw_symbols.h, src/fcc_data.c, src/fcc_data.h,
+	  src/festival.c, src/festival.h, src/geo-client.c, src/geo-find.c,
+	  src/geo.h, src/geocoder_gui.c, src/gps.c, src/gps.h,
+	  src/hashtable.c, src/hashtable.h, src/hashtable_itr.c,
+	  src/hashtable_itr.h, src/hashtable_private.h, src/hostname.c,
+	  src/hostname.h, src/igate.c, src/igate.h, src/interface.c,
+	  src/interface.h, src/interface_gui.c, src/io-common.c,
+	  src/io-mmap.c, src/io.h, src/lang.c, src/lang.h,
+	  src/leak_detection.h, src/list_gui.c, src/list_gui.h,
+	  src/locate_gui.c, src/location.c, src/location_gui.c,
+	  src/macspeech.c, src/main.c, src/main.h, src/map_WMS.c,
+	  src/map_cache.c, src/map_cache.h, src/map_dos.c, src/map_gdal.c,
+	  src/map_geo.c, src/map_gnis.c, src/map_pdb.c, src/map_shp.c,
+	  src/map_tif.c, src/map_tiger.c, src/maps.c, src/maps.h,
+	  src/messages.c, src/messages.h, src/messages_gui.c,
+	  src/objects.c, src/objects.h, src/popup.h, src/popup_gui.c,
+	  src/rac_data.c, src/rac_data.h, src/rotated.c, src/rotated.h,
+	  src/rpl_malloc.c, src/rpl_malloc.h, src/shp_hash.c,
+	  src/shp_hash.h, src/snprintf.c, src/snprintf.h, src/sound.c,
+	  src/symbols.h, src/testdbfawk.c, src/track_gui.c,
+	  src/track_gui.h, src/util.c, src/util.h, src/view_message_gui.c,
+	  src/wx.c, src/wx.h, src/wx_gui.c, src/x_spider.c, src/x_spider.h,
+	  src/xa_config.c, src/xa_config.h, src/xastir.h,
+	  src/xastir_udp_client.c, AUTHORS, DEBUG_LEVELS, FAQ, INSTALL,
+	  LICENSE, Makefile.am, NEWS, README, README.CVS,
+	  README.Contributing, README.Getting-Started, README.MAPS,
+	  README.win32, REGRESSION_TESTS, UPGRADE, acinclude.m4,
+	  bootstrap.sh, changes.txt, configure.ac, install-xastir,
+	  update-xastir, xastir.1, m4/Makefile.am: Updating copyright
+	  notices for 2009.
+
+2009-01-01 23:58  we7u
+
+	* src/: rtree/Makefile.am, rtree/card.c, rtree/card.h,
+	  rtree/gammavol.c, rtree/index.c, rtree/index.h, rtree/node.c,
+	  rtree/rect.c, rtree/sphvol.c, rtree/split_l.c, rtree/split_l.h,
+	  rtree/split_q.c, rtree/split_q.h, shapelib/Makefile.am,
+	  shapelib/contrib/Makefile.am: Updating the copyright notices for
+	  2009.
+
+2009-01-01 23:56  we7u
+
+	* scripts/: LSB-BUILD, LSB-BUILD-ALL, LSB-BUILD-CURL, LSB-BUILD-DB,
+	  LSB-BUILD-GDAL, LSB-BUILD-GRAPHICSMAGICK, LSB-BUILD-JASPER,
+	  LSB-BUILD-JPEG, LSB-BUILD-LESSTIF, LSB-BUILD-PCRE, LSB-BUILD-PNG,
+	  LSB-BUILD-ZLIB, Makefile.am, Xastir_tigerpoly.py,
+	  example_objects.log, get-NWSdata, get-fcc-rac.pl, get-gnis,
+	  get-maptools.sh, get_shapelib.sh, langElmerFudd.pl,
+	  langMuppetsChef.pl, langOldeEnglish.pl, langPigLatin.pl,
+	  langPirateEnglish.pl, toporama250k.pl, toporama50k.pl,
+	  xastir-fixcfg.sh, xastir-migrate.sh: Updating copyright notices
+	  for 2009.
+
+2009-01-01 23:54  we7u
+
+	* callpass/: Makefile.am, callpass.c: Updating the copyright
+	  notices for 2009.
+
+2009-01-01 23:51  we7u
+
+	* symbols/Makefile.am, symbols/symbols.dat, LaCrosse/Makefile.am,
+	  LaCrosse/README, LaCrosse/bootstrap.sh, LaCrosse/configure.ac,
+	  LaCrosse/src/Makefile.am, LaCrosse/src/defs.h,
+	  LaCrosse/src/open2300db2APRS.c, help/Makefile.am,
+	  help/help-Dutch.dat, help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat,
+	  Davis/Makefile.am, Davis/README, Davis/bootstrap.sh,
+	  Davis/configure.ac, Davis/src/Makefile.am, Davis/src/db2APRS.c,
+	  Davis/src/defs.h, config/24kgrid.dbfawk, config/Makefile.am,
+	  config/gps_wpt.dbfawk, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  config/nwsc_ddmmyy.dbfawk, config/nwsmzddmmyy.dbfawk,
+	  config/nwsmzoddmmyy.dbfawk, config/nwsozddmmyy.dbfawk,
+	  config/nwsw_ddmmyy.dbfawk, config/nwsz1ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/nwszoddmmyy.dbfawk,
+	  config/predefined_EVENT.sys, config/predefined_SAR.sys,
+	  config/tgr2shp.dbfawk, config/tgr2shppoly.dbfawk,
+	  config/tgr2shppoly_2006.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrlpt.dbfawk,
+	  config/tgrlpy.dbfawk, config/tgrplc00.dbfawk,
+	  config/tgrwat.dbfawk, config/tnc-startup.aea,
+	  config/tnc-startup.d700, config/tnc-startup.kam,
+	  config/tnc-startup.kpc2, config/tnc-startup.kpc3,
+	  config/tnc-startup.paccomm, config/tnc-startup.pico,
+	  config/tnc-startup.sys, config/tnc-startup.thd7,
+	  config/tnc-startup.tnc2, config/tnc-startup.tnc2-ui,
+	  config/tnc-stop.d700, config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui: Updating the copyright notices for 2009.
+
+2008-12-31 20:37  we7u
+
+	* src/xa_config.c: Changing xastir.cnf -> xastir.cnf.1 to a
+	  copy_file() call instead of a move().  This assures that we'll
+	  always have a config file in place even if we error-out before we
+	  can complete the next block which renames xastir.cnf.tmp ->
+	  xastir.cnf.
+
+2008-12-31 20:18  we7u
+
+	* src/xa_config.c: A better ordering for writing the config file.
+	  We now write a temporary file.  If successful, we rename all the
+	  backups and then rename the temporary file as the current config
+	  file.  This should help to minimize the instances of config file
+	  corruption.
+
+2008-12-09 08:10  we7u
+
+	* FAQ, README, README.Contributing, README.Getting-Started,
+	  README.win32: Adding notes about having to subscribe to the
+	  mailing lists before posting.
+
+2008-11-26 09:39  we7u
+
+	* src/draw_symbols.c: Correcting a comment.
+
+2008-11-24 12:27  we7u
+
+	* scripts/example_objects.log: Adding a link to the Xastir Wiki
+	  where images of these objects can be seen.
+
+2008-11-12 15:26  tvrusso
+
+	* src/map_geo.c: Comment out the use of GetOnePixel and the
+	  variable it assigns to.
+
+	  This is for two reasons:
+
+	   1) F*!#*ng ImageMagick has broken its API yet again with version
+	  6.4.5,
+	      making GetOnePixel no longer compatible with usage prior to
+	  6.4.4
+	   2) map_geo.c does this:
+		PixelPacket target;
+		target=GetOnePixel(image,0,0)
+	      after which it does NOTHING with the pixel so retrieved.	So
+	  commenting
+	      out this useless line is less work than what I had started
+	  doing,
+	      which was hacking the configure detection of ImageMagick to
+	  distinguish
+	      between pre-6.4.5 and post-6.4.5, and coding around this
+	  garbage.
+
+	  I Hate ImageMagick.
+
+2008-10-17 00:18  we7u
+
+	* config/tnc-startup.aea: Turning on the HID function which is
+	  required on AEA TNC's for proper identification if they're
+	  digipeating.	Since we have digipeating turned on in this file...
+
+2008-10-16 09:20  we7u
+
+	* ChangeLog: Updating for devel release.
+
+2008-10-08 21:57  we7u
+
+	* src/map_shp.c: Getting rid of a 64-bit compiler warning by
+	  changing an "(int)NULL" to a "0".
+
+2008-10-08 21:56  we7u
+
+	* src/db.c: Changing a debug format so that it doesn't cause a
+	  warning on 64-bit machines.
+
+2008-10-08 08:11  we7u
+
+	* src/maps.c: Getting rid of two compiler warnings:  One by forcing
+	  a terminator into the first char of a string buffer instead of
+	  doing an empty xastir_snprintf(), another by casting a strlen()
+	  result to an int for an fprintf.
+
+2008-10-07 23:10  we7u
+
+	* src/shp_hash.c: Reverting back to the original code for strncpy()
+	  in this module:  The previous change caused a panic.
+
+2008-10-07 22:59  we7u
+
+	* src/shp_hash.c: Getting rid of another strncpy() call.
+
+2008-10-07 22:43  we7u
+
+	* src/util.c: Forcibly terminating a string as an added precaution.
+
+2008-10-07 22:42  we7u
+
+	* src/shp_hash.c: Adding some blank lines to delimit an strcpy()
+	  call.
+
+2008-10-07 22:41  we7u
+
+	* src/objects.c: Getting rid of an strcat() call.
+
+2008-10-07 22:41  we7u
+
+	* src/db.c: Getting rid of some strncpy() calls.
+
+2008-10-07 22:40  we7u
+
+	* src/awk.c: Updating a comment.
+
+2008-10-07 22:14  we7u
+
+	* src/: db.c, fcc_data.c, hostname.c, igate.c, interface.c,
+	  interface_gui.c, locate_gui.c, map_WMS.c, map_geo.c, map_shp.c,
+	  map_tiger.c, maps.c, messages.c, objects.c, util.c, wx.c,
+	  x_spider.c, xa_config.c: Fixing some off-by-one errors in string
+	  handling.
+
+2008-10-07 21:42  we7u
+
+	* src/: alert.c, main.c: Fixing some off-by-one errors in string
+	  handling.
+
+2008-10-06 22:04  we7u
+
+	* src/main.c: Fixing the my_text string buffer in TrackMouse() so
+	  that it won't get overrun.  The worst conditions are English
+	  Units, Dist/Bearing Status enabled, Degrees/Minutes/Seconds,
+	  zoomed out to world view and putting the mouse in the "corner" of
+	  the world (10,000+ miles).  This results in about 54 characters
+	  being used whereas the original string buffer was only capable of
+	  holding 49.
+
+2008-09-26 07:30  gstueve
+
+	* src/x_spider.c: Make sure both sides of the pipe are satisfied
+	  before releasing the memory. The system is not happy about trying
+	  to read data from free space.
+
+2008-09-24 12:44  we7u
+
+	* .cvsignore: Ignore the derived file "xastir-lsb.spec" as well.
+
+2008-09-24 12:18  we7u
+
+	* src/.cvsignore: Ignoring testdbfawk now instead of testawk file.
+
+2008-09-24 11:03  gstueve
+
+	* src/map_tiger.c: Found one more place that needed to release
+	  ExceptionInfo when interrupted.
+
+2008-09-24 09:16  tvrusso
+
+	* README.MAPS, scripts/LSB-BUILD, src/Makefile.am, src/testawk.c,
+	  src/testdbfawk.c: Rename "testawk" to "testdbfawk" and add it to
+	  the list of programs that "make install" will install.
+
+	  This addresses a couple of issues:   0) Testawk is a *terrible*
+	  name for this program, because in fact it does      not test
+	  "awk", the system program, but rather "dbfawk," the Xastir
+	  feature inspired by awk but completely unrelated to awk in any
+	  other sense.	  1) testawk was never installed by Xastir's build
+	  process, meaning that       packagers of Xastir binaries for
+	  various systems did not bundle this	    little program with
+	  their binary packages.  There is even a bug in       debian's bug
+	  tracker from an Xastir user asking that the xastir package
+	  have testawk installed (in a non-standard place because of its
+	     "generic, even misleading name") by the .deb package.
+
+	  I've updated README.MAPS and the LSB-BUILD script to make them
+	  refer to testdbfawk instead of testawk.  I'll still have to
+	  change various web resources so they point at the new program,
+	  too.
+
+2008-09-22 13:19  we7u
+
+	* src/x_spider.c: Removing an earlier change 'cuz it makes the
+	  server ports die when a client disconnects.  Without this line
+	  they appear to be solid again.
+
+2008-09-11 06:07  we7u
+
+	* src/main.c: Grey'ing out the xfontsel buttons when that app's not
+	  available.
+
+2008-09-09 22:38  we7u
+
+	* src/xa_config.c: Saving/restoring the tracking station callsign
+	  to/from the config file, but not saving the state of the tracking
+	  toggle.  This means that the last tracked callsign will be
+	  remembered but tracking will not be on when Xastir starts up.
+
+2008-09-09 22:17  we7u
+
+	* src/db.c: A proper label for the new "Track Station" button on
+	  the Station Info dialog.
+
+2008-09-09 22:11  we7u
+
+	* src/db.c: Initial working version of "Track Station" from the
+	  Station Info dialog.	Still needs additions to the language files
+	  for the button label.
+
+2008-09-09 20:10  we7u
+
+	* src/interface.c: Adding some comments near four areas that cause
+	  compiler warnings which we can currently do nothing about.
+
+2008-09-09 20:09  we7u
+
+	* src/testawk.c: Changing an int* to an int to get rid of a
+	  compiler warning about a mismatch.
+
+2008-09-09 20:07  we7u
+
+	* acinclude.m4: Adding /opt/local/ directory to the test for
+	  binaries (MacPorts).	Changing the order of some compiler flags
+	  to help find GM before IM on FreeBSD systems.
+
+2008-09-09 08:47  we7u
+
+	* src/util.c: Changing the return type for a curl function to get
+	  rid of a warning caused by newer versions of libcurl.
+
+2008-09-09 08:37  we7u
+
+	* src/: main.c, track_gui.c: Adding #ifdef's around SED and MV
+	  calls.
+
+2008-09-09 08:20  we7u
+
+	* src/main.c: Added #ifdef around XFONTSEL call so that absence of
+	  the binary won't cause compile problems.
+
+2008-09-08 09:13  we7u
+
+	* ChangeLog, scripts/Makefile.am: Adding lang* scripts to package
+	  build.  Updating ChangeLog to latest.
+
+2008-09-03 08:46  gstueve
+
+	* config/.cvsignore: Get CVS to forget about the generated language
+	  files.
+
+2008-09-03 08:43  gstueve
+
+	* src/main.c: Get valgrind to stop complaining about the lost
+	  blocks in the app_context.
+
+2008-09-03 06:06  we7u
+
+	* scripts/langPirateEnglish.pl: Translating "Maps" as well as
+	  "Map".
+
+2008-08-31 16:45  we7u
+
+	* scripts/langMuppetsChef.pl: Enabling more of the regex.  Much
+	  better "translation".
+
+2008-08-31 16:27  we7u
+
+	* scripts/: langElmerFudd.pl, langMuppetsChef.pl, langPigLatin.pl,
+	  langPirateEnglish.pl: More updates to the derived language
+	  scripts.
+
+2008-08-31 15:31  we7u
+
+	* scripts/langOldeEnglish.pl: Rewriting the script so that
+	  anchoring & substitutions work in the regex.
+
+2008-08-31 13:52  we7u
+
+	* bootstrap.sh, scripts/langElmerFudd.pl,
+	  scripts/langMuppetsChef.pl, scripts/langOldeEnglish.pl,
+	  scripts/langPigLatin.pl, scripts/langPirateEnglish.pl: Updates to
+	  derived languages scripts, preparing for possible future uses.
+
+2008-08-31 09:26  we7u
+
+	* scripts/langPirateEnglish.pl: More for TLAPD.
+
+2008-08-30 18:56  we7u
+
+	* scripts/langPirateEnglish.pl: More Pirate updates.
+
+2008-08-30 18:14  we7u
+
+	* scripts/langPirateEnglish.pl: Latest Pirate updates.
+
+2008-08-30 17:31  we7u
+
+	* scripts/langPirateEnglish.pl: Added a few more Xastir-specific
+	  translations.
+
+2008-08-30 16:30  we7u
+
+	* INSTALL, README.Getting-Started, README.win32, bootstrap.sh,
+	  config/Makefile.am, help/help-English.dat, help/help-German.dat,
+	  help/help-Italian.dat, help/help-Portuguese.dat,
+	  help/help-Spanish.dat, src/main.c: Adding five new official
+	  languages to the "-l" flag in Xastir.
+
+2008-08-30 16:28  we7u
+
+	* scripts/: langElmerFudd.pl, langMuppetsChef.pl,
+	  langOldeEnglish.pl, langPirateEnglish.pl: Adding more official
+	  languages.
+
+2008-08-29 22:21  we7u
+
+	* scripts/langPigLatin.pl: Changing a comment to avoid the RCS tag
+	  substitution as well.
+
+2008-08-29 22:19  we7u
+
+	* scripts/langPigLatin.pl: Changed the match string so that RCS/CVS
+	  won't substitute a new Id: string in our REGEX expression.
+
+2008-08-29 22:12  we7u
+
+	* scripts/langPigLatin.pl: Renamed from PigLatin.pl
+
+2008-08-29 22:11  we7u
+
+	* scripts/PigLatin.pl: Moving this file to langPigLatin.pl
+
+2008-08-28 08:14  gstueve
+
+	* scripts/: get-maptools.sh, get_shapelib.sh: Use available
+	  resources to make use of temporary file as safe as possible.
+
+2008-08-28 07:24  gstueve
+
+	* scripts/get_shapelib.sh: Use same library logic as
+	  get-maptools.sh and clear temporary file for our use.
+
+2008-08-28 07:22  gstueve
+
+	* scripts/get-maptools.sh: Make sure to get temporary file out of
+	  way so we don't copy into something outside our expectation.
+
+2008-08-27 06:25  tvrusso
+
+	* acinclude.m4: Introduce proper quoting of AC_CACHE_CHECK
+	  arguments in XASTIR_GUESS_RUNPATH_SWITCH macro.
+
+2008-08-27 06:23  tvrusso
+
+	* acinclude.m4: Fix the XASTIR_GUESS_RUNPATH_SWITCH macro so that
+	  it uses AC_CACHE_CHECK with a CACHE-ID that conforms to the
+	  naming conventions expected.
+
+	  In versions of autoconf 2.62 and later, using a CACHE-ID without
+	  the "_cv_" string included in its name produces an annoying and
+	  possibly confusing warning message:
+
+	   configure.ac:572: warning: AC_CACHE_VAL(xastir_runpath_switch,
+	  ...): suspicious cache-id, must contain _cv_ to be cached
+	   ../../lib/autoconf/general.m4:1973: AC_CACHE_VAL is expanded
+	  from...
+	   ../../lib/autoconf/general.m4:1993: AC_CACHE_CHECK is expanded
+	  from...
+	   acinclude.m4:1131: XASTIR_GUESS_RUNPATH_SWITCH is expanded
+	  from...
+	   acinclude.m4:1120: XASTIR_ADD_LIBPATH_TO is expanded from...
+	   acinclude.m4:964: XASTIR_BERKELEY_DB_CHK_LIB is expanded from...
+	   ../../lib/m4sugar/m4sh.m4:508: AS_IF is expanded from...
+	   ../../lib/autoconf/general.m4:2461: AC_COMPILE_IFELSE is
+	  expanded from...
+	   ../../lib/autoconf/general.m4:2469: AC_TRY_COMPILE is expanded
+	  from...
+	   acinclude.m4:1059: XASTIR_BERKELEY_DB_CHK is expanded from...
+	   configure.ac:572: the top level
+
+	  several times during bootstrap.  By renaming
+	  "xastir_runpath_switch" to "xastir_cv_runpath_switch" throughout
+	  acinclude.m4, this warning is silenced and the variable is cached
+	  as intended.
+
+	  According to the autoconf documentation, cache variables *MUST*
+	  have the "_cv_" string in their names.  It is only in recent
+	  versions of autoconf that violating this requirement is actually
+	  flagged as a warning.
+
+2008-08-25 08:19  gstueve
+
+	* src/testawk.c: Add prefix to indicate that we are printing
+	  hexadecimal value.
+
+2008-08-21 09:50  gstueve
+
+	* src/bulletin_gui.c: Make sure everything is allocated for
+	  bulletins before use.
+
+2008-08-21 09:48  gstueve
+
+	* src/dbfawk.c: Release memory & directory after we finish with
+	  them.
+
+2008-08-18 19:02  gstueve
+
+	* scripts/get-fcc-rac.pl: No need to extract unsorted file to disk.
+	  Process directly into script.
+
+2008-08-15 13:24  we7u
+
+	* configure.ac, scripts/BUILDRPMS: Setting up for 1.9.5 development
+	  versions.
+
+2008-08-15 12:51  we7u
+
+	* ChangeLog: Updating ChangeLog to match latest changes (for
+	  upcoming stable release).
+
+2008-08-15 12:50  we7u
+
+	* configure.ac, scripts/BUILDRPMS, scripts/LSB-BUILD,
+	  scripts/do_xastir_release_dev, scripts/do_xastir_release_stable:
+	  Updating version numbers for upcoming stable release.
+
+2008-08-15 12:41  we7u
+
+	* configure.ac: Checking for curl/curl.h include file in the
+	  libcurl test to make sure we can actually compile with it.  Also
+	  only check for wget if the libcurl tests fail.
+
+2008-08-14 21:39  we7u
+
+	* configure.ac: Adding a "--without-libcurl" option to configure.
+
+2008-08-14 21:36  we7u
+
+	* acinclude.m4: Slight reformatting of help text (added spaces).
+
+2008-08-12 12:16  we7u
+
+	* src/db.c: Changing a tab to a newline at the end of Tactical Call
+	  in Station Info box.	This prepares us for longer tactical calls.
+
+2008-08-05 20:03  gstueve
+
+	* src/map_geo.c: Found one more place to release ExceptionInfo for
+	  ImageMagick, hopefully last needed to minimize unbalanced memory
+	  usage in maps.
+
+2008-08-04 07:27  we7u
+
+	* xastir-min.spec.in, xastir.spec.in, scripts/BUILDRPMS: Getting
+	  rid of include/Xm/Xm.h requirement in RPM build spec files.
+	  Uncommenting a few print statements in the BUILDRPMS script that
+	  were commented out by mistake.
+
+2008-08-03 10:26  we7u
+
+	* xastir-min.spec.in, xastir.spec.in: Updating to new path for
+	  Motif include files.
+
+2008-08-03 09:18  we7u
+
+	* scripts/BUILDRPMS: Preparing for creation of SuSE-11.0 RPM's.
+
+2008-08-01 19:14  we7u
+
+	* src/db.c: Adding debug_level filtering to the TACTICAL code.
+
+2008-08-01 07:55  we7u
+
+	* ChangeLog: Updating ChangeLog before doing -dev release.
+
+2008-08-01 05:42  gstueve
+
+	* src/: map_geo.c, map_WMS.c, map_tiger.c: Make sure that error
+	  returns are covered by ImageMagick release code.
+
+2008-07-31 23:21  gstueve
+
+	* src/map_gdal.c: Give GDAL a chance to release data from
+	  GDALAllRegister at end of run.
+
+2008-07-31 20:24  gstueve
+
+	* src/map_WMS.c: Make sure to deal with cleaning up ExceptionInfo
+	  when finished with map.
+
+2008-07-31 20:20  gstueve
+
+	* src/map_tiger.c: Make sure to cleanup allocated space before
+	  returning to caller.	ImageMagick exceptionInfo needed to be
+	  destroyed when finished.
+
+2008-07-31 17:09  we7u
+
+	* src/: main.c, xa_config.c: Reverting to "fixed" font as the
+	  default for the SYSTEM and STATION fonts.
+
+2008-07-30 08:24  we7u
+
+	* src/: database.h, db.c, util.c: More Tactical Call changes:
+	  Assignments before a station shows up work.  Clearing an
+	  assignment causes the string to be freed and the pointer nulled.
+	  Max tactical call length is now 57.
+
+2008-07-28 02:10  we7u
+
+	* src/db.c: Cleaning up the input parameters for one of the new
+	  tactical call helper routines.  Leading/trailing spaces on
+	  callsign or tac-callsign affect the results little now.
+	  Lower-case callsigns are converted to upper case now.  One minor
+	  annoyance:  Blanking out callsigns using messages to TACTICAL
+	  results in this being displayed in the station chooser when there
+	  are more than one station under the mouse:  "()".  The proper
+	  display should be the callsign in that case, so perhaps spaces
+	  are still getting saved in the tactical callsign slot -or- the
+	  tactical callsign string isn't getting free'd and the pointer
+	  NULLed out (the latter is most likely).
+
+2008-07-28 01:37  we7u
+
+	* src/: db.c, util.c, util.h: The beginnings of being able to share
+	  Tactical Call data with others over the air.	This code works,
+	  decoding messages sent to "TACTICAL" which are in one of these
+	  four formats:     My Home	WE7U-3=My Home	   WE7U-3=My
+	  Home;WE7U-12=Curt's Jeep;WE7U-15=I Don't Know
+	  WE7U-3=;WE7U-12=;WE7U-15= In the first case it'll assign "My
+	  Home" as the tactical callsign for the station that sent the
+	  message.  In the last case it'll remove tactical callsigns for
+	  the listed stations.	For testing remember that you can't send a
+	  new message to TACTICAL until the previous message has either
+	  timed-out or been cancelled.
+
+2008-07-18 08:26  gstueve
+
+	* scripts/get-NWSdata: Update to current Marine Zone. There are
+	  changes due in September for a few of the zone files. Need to
+	  watch for implementation date.
+
+2008-07-11 15:03  tvrusso
+
+	* acinclude.m4: Fix spelling error in AC_SEARCH_LIBS line for
+	  Magick/MagickCore.  This is mostly irrelevant, because LIBS
+	  already has the right stuff in it if Magick-config --libs isn't
+	  lying, and for most users this test will be a no-op.
+
+2008-07-10 08:46  chicoreus
+
+	* src/db_gis.c: Issue: 2015173 Missing #ifdef for MySQL causes
+	  xastir to segfault when built with only --with-postgis. Found by
+	  Jeffrey Johnson.
+
+2008-07-07 15:26  tvrusso
+
+	* src/maps.c: Fix map metadata for upper left corner.
+
+	  Previously, the code was using the same coordinate pair to
+	  compute the upper left and lower right corner strings.  For some
+	  reason, this ultimately made somewhat correct labels for UTM, but
+	  completely wrong labels for Lat/Lon.
+
+	  Since this simple change makes the code produce correct labels
+	  for all coordinate systems, and the other shouldn't have worked
+	  for any, I feel safe committing it.  But I would have liked to
+	  understand why it worked at all for UTM.
+
+2008-07-07 09:53  we7u
+
+	* ChangeLog: [no log message]
+
+2008-07-03 07:55  gstueve
+
+	* src/alert.c: Increase size of titles for alerts to allow for
+	  large area alerts to be processed w/o loss of compressed info.
+
+2008-07-03 06:12  we7u
+
+	* src/db.c: If text on black background style selected, draw a
+	  black rectangle in that corner of the map first so that the scale
+	  lines show up well.
+
+2008-07-02 17:12  gstueve
+
+	* AUTHORS, src/main.h: Update current callsign for K4INT.
+
+2008-07-02 12:06  gstueve
+
+	* src/map_WMS.c: Remove extra fclose(f) of already closed file.
+	  Keep everyone happy.
+
+2008-07-02 11:03  we7u
+
+	* src/db.c: Decode DAO patch by Tapio Sokura, OH2KKU.  This doesn't
+	  do anything with any datum transmitted, but does give us the
+	  extra precision sent via the DAO extension.  We still need to
+	  change the white precision rectangle for the station on our map
+	  to make it smaller (not included in this change).
+
+2008-07-02 06:54  we7u
+
+	* src/db.c: Feature request 756236:  Have Range Scale and Ruler
+	  text at bottom of map screen follow the same text style selection
+	  as the station text, to make them easier to read.
+
+2008-07-01 20:04  we7u
+
+	* src/: bulletin_gui.c, db.c, draw_symbols.c, geocoder_gui.c,
+	  interface_gui.c, list_gui.c, locate_gui.c, location_gui.c,
+	  main.c, map_geo.c, maps.c, messages_gui.c, objects.c,
+	  popup_gui.c, track_gui.c, view_message_gui.c, wx_gui.c, xastir.h:
+	  The remaining major updates to allow changing the "system" or
+	  "menu" font throughout the applicaton.
+
+2008-06-30 18:47  gstueve
+
+	* scripts/get-gnis: Remove extra path separator.
+
+2008-06-30 16:40  we7u
+
+	* src/: draw_symbols.c, main.c, maps.c, popup_gui.c, xa_config.c,
+	  xastir.h: Patches to implement a GUI interface for changing
+	  fonts, plus added error-checking to some of the font code.
+
+2008-06-30 16:39  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: The first of two
+	  commits adding a GUI interface for changing system/
+	  station/atv_id fonts.
+
+2008-06-30 07:02  gstueve
+
+	* scripts/get-gnis: Update path for file from USGS and adjust
+	  suffix for current file layout.
+
+2008-06-27 13:10  we7u
+
+	* src/main.c: More menus converted to allow using user-specified
+	  fonts.
+
+2008-06-27 12:48  we7u
+
+	* src/: main.c, popup_gui.c, xa_config.c, xastir.h: Adding the
+	  capability for users to specify the fonts used for the system
+	  fonts, station fonts (on map screen), and the ATV_ID font.
+	  Currently the users will have to edit the fonts in xastir.cnf,
+	  but later a GUI access method for editing can be added.
+
+2008-06-27 12:45  we7u
+
+	* src/maps.c: Fixing the initialization of arrays for map labels.
+
+2008-06-27 06:41  we7u
+
+	* configure.ac, src/main.c, src/track_gui.c: Adding path tests for
+	  "mv", "sed", and "xfontsel", plus the correct bits of code in the
+	  .c files to use those paths.
+
+2008-06-26 12:10  we7u
+
+	* src/main.c: Specifying more of the font characteristics for the
+	  font used when USE_LARGE_STATION_FONT is defined.
+
+2008-06-26 07:41  we7u
+
+	* src/db.c: A fix for the Citizen's Weather filter to get rid of
+	  the new "DW" prefixed stations, plus more strict filtering so
+	  that we don't also get rid of Uruguay and Phillipines weather
+	  stations with this same filter.
+
+2008-06-25 16:30  we7u
+
+	* src/main.c: Fixing the system fonts so that they work on more
+	  systems.
+
+2008-06-25 06:41  we7u
+
+	* scripts/toporama250k.pl: Updated the instructions for running the
+	  script plus got rid of DOS line-end characters that had somehow
+	  crept in.  Those line-end characters prevented the Perl
+	  interpreter from running on Linux.
+
+2008-06-25 06:39  we7u
+
+	* scripts/toporama50k.pl: Updated the instructions for running the
+	  script.
+
+2008-06-25 06:38  we7u
+
+	* help/help-English.dat: Changed the name of the fcc-get script to
+	  get-fcc-rac.pl
+
+2008-06-25 06:37  we7u
+
+	* src/db.c: Station Info:  Special-case check for objects sent by
+	  "WINLINK".  We keep the object name as the "origin" in this case
+	  instead of "WINLINK".  This solves the "FCC" instead of "RAC"
+	  button problem for objects with Canadian callsigns, allowing us
+	  to look of RAC licensing information.
+
+2008-06-24 08:52  we7u
+
+	* README.Getting-Started, README.MAPS: Updating the name of the
+	  get-fcc-rac.pl script in the docs.
+
+2008-06-24 08:48  we7u
+
+	* scripts/: Makefile.am, fcc-get, fcc-get.pl, get-fcc-rac.pl:
+	  Combined fcc-get and fcc-get.pl into one script called
+	  get-fcc-rac.pl
+
+2008-06-23 15:42  we7u
+
+	* README: Adding the SuSE-11.0 Ham Radio repository URL.
+
+2008-06-13 06:43  gstueve
+
+	* scripts/get-NWSdata: Remove the bashism to keep people happy.
+
+2008-06-13 00:37  gstueve
+
+	* config/nwsz_ddmmyy.dbfawk: Actually get the signature template
+	  right for Watches.
+
+2008-06-13 00:25  gstueve
+
+	* config/: nwsmzddmmyy.dbfawk, nwsz_ddmmyy.dbfawk: Actually get the
+	  template to match the available dataset.
+
+2008-06-12 20:27  gstueve
+
+	* scripts/get-NWSdata: Missed that one of the files was in a
+	  different directory.
+
+2008-06-12 18:49  gstueve
+
+	* scripts/get-NWSdata: Introduced bashism to reduce size & improve
+	  consistency for all files.
+
+2008-06-12 12:30  gstueve
+
+	* config/Makefile.am, config/nwsz1ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, scripts/get-NWSdata: Adjust script and
+	  dbfawk for current set of files from NWS.  There are newer sets
+	  of files for upcoming dates.
+
+2008-06-11 06:39  gstueve
+
+	* src/x_spider.c: Reduce side effects of free memory by clearing
+	  pointer after deallocation.
+
+2008-06-09 12:28  we7u
+
+	* scripts/: LSB-BUILD, LSB-BUILD-ALL, LSB-BUILD-GRAPHICSMAGICK:
+	  Committing latest changes for LSB build.  Am not done yet getting
+	  LSB to build properly on OpenSUSE-10.3, but this is a good start.
+
+2008-06-09 12:25  we7u
+
+	* ChangeLog: Keeping it up to date with CVS commits.
+
+2008-06-09 12:23  we7u
+
+	* scripts/do_xastir_release_stable: Changed SF upload process to
+	  match what they currently allow.
+
+2008-06-09 12:23  we7u
+
+	* scripts/do_xastir_release_dev: Change SF upload process to match
+	  what they currently allow.
+
+2008-06-04 04:23  gstueve
+
+	* src/db.c: Allow Objects that have space in name to work with
+	  Tactical Call Sign addition.
+
+2008-05-30 08:32  gstueve
+
+	* src/db.c: Add tactical call sign to station pick list when
+	  multiple stations under cursor.
+
+2008-05-29 10:15  we7u
+
+	* FAQ, README.Getting-Started: Updating some of the PATH wording.
+
+2008-05-27 12:04  gstueve
+
+	* src/messages.c: Start fixing elements to allow Group & Bulletin
+	  messages to go unacknowledged.
+
+2008-05-21 09:08  tvrusso
+
+	* src/util.c: Fix makeMultiline (an unused function) so that it
+	  produces offsets in the same sense that xastir decodes them ---
+	  i.e. that positive longitude offsets are west of the reference
+	  point.
+
+2008-05-09 11:20  gstueve
+
+	* src/interface.c: Make sure not to add break character if no
+	  altitude to be reported.
+
+2008-05-09 11:18  gstueve
+
+	* src/: util.c, util.h: Make sure course and speed are treated as
+	  non-negative numbers only.
+
+2008-05-06 04:05  gstueve
+
+	* scripts/fcc-get.pl: Remove extra CR at end of each line and deal
+	  with full list only once.
+
+2008-05-05 13:00  gstueve
+
+	* scripts/: Makefile.am, fcc-get, fcc-get.pl: Adjust fcc file
+	  processing to deal with vanity call update.
+
+2008-05-02 09:58  tvrusso
+
+	* acinclude.m4: Change "AC_CHECK_LIB" to "AC_SEARCH_LIBS" for
+	  ImageMagick.
+
+	  A recent update to ImageMagick stuffs the "WriteImage" function
+	  into libMagickCore instead of libMagick, and the older probe was
+	  missing it.
+
+	  With this change, I see that WriteImage gets found without adding
+	  anything to LIBS, because "Magick-config" already stuffed the
+	  right thing into LIBS.
+
+2008-04-13 22:31  we7u
+
+	* src/util.c: Fixing a bug found with latest wget:  --timestamping
+	  and -O options can't be used together.  Getting rid of the
+	  timestamping option which we can live without.
+
+2008-04-13 21:31  we7u
+
+	* src/util.c: Updating wget and libcurl fetches to specify "Xastir"
+	  as the user-agent string in the request.  This is to support the
+	  new restrictions that findu.com has implemented.
+
+2008-03-20 21:11  chicoreus
+
+	* src/: db.c, interface_gui.c, main.c: Minor cleanup of comments
+	  and un-needed code from testing problems with database
+	  connections.
+
+2008-03-20 21:00  chicoreus
+
+	* src/: db.c, db_gis.c, db_gis.h, interface.c, interface_gui.c,
+	  main.c: Identified and fixed problem underlying stability of
+	  multiple database connections (space for connection structures
+	  was incorrectly allocated so that writing an error message into
+	  one connection overwrote memory used by another connection).
+	  Fixed additional problems related to connection failures and
+	  added more resilience to database connection problems.
+
+2008-03-18 19:10  chicoreus
+
+	* src/: db.c, db_gis.c, db_gis.h, interface.c, interface_gui.c,
+	  main.c, main.h: Overhaul of the way sql database connections are
+	  handled, reducing the complexity by eliminating the
+	  ConnectionList struct, and creating an array of Connections, one
+	  for each interface.  More than one database connection can now be
+	  run at once, though there is still an issue with pointers or
+	  memory handling somewhere and instabilites can be produced by
+	  stopping and starting database connections.
+
+	  Moved all the db_gis related debug_level tests from 1 to 4096.
+
+2008-03-11 20:27  tvrusso
+
+	* acinclude.m4: Fix a fairly dumb thing in the probe for Berkeley
+	  DB --- it was always resetting the result (BDB_LIB_FOUND) to
+	  "-ldb" even if the actual library found was something else.  This
+	  variable was used only to report to the user what library was
+	  found, never as the actual "-l" flag.  This could have led to
+	  confusion, but not improper operation.
+
+2008-03-06 12:47  we7u
+
+	* scripts/BUILDRPMS: Updating to SuSE-10.3 for generation of RPM's.
+
+2008-03-03 20:00  tvrusso
+
+	* README.MAPS: Add link to FAA digital data products web site.	You
+	  can purchase FAA sectionals in GeoTIFF format there.
+
+2008-02-29 08:54  chicoreus
+
+	* src/: database.h, db.c, db_gis.c, interface_gui.c: Added trails
+	  to db_gis code. Multiple points from one station retrieved from a
+	  database query are added as trailpoints.  Existing stations heard
+	  from other sources and retrieved from a database query aren't
+	  duplicated as DataRows, but have appropriate trail points added
+	  (if the existing position is older than the database data, the
+	  existing position becomes as trailpoint; if the database data is
+	  older, it gets added as trailpoints).
+
+	  Added timeformat to add_simple_station, as Postgresql and MySQL
+	  timestamps don't both include the local timezone "%z" in the
+	  current simple station query formats.
+
+	  Added APRS_WXn character constants as a workaround, since
+	  AprsTypes and Record Type character constants are used
+	  inconsistently in DataRow.record_type, and AprsTypes without
+	  character constants don't write cleanly into MySQL or Postgresql
+	  database records.
+
+	  Added and commented out lines to start database connections from
+	  interfaces Left commented out as multiple open database
+	  connections are still unstable and segfault.
+
+2008-02-27 20:02  gstueve
+
+	* scripts/fcc-get: FCC moved the database again. Look for it in new
+	  place.
+
+2008-02-21 20:57  chicoreus
+
+	* src/: database.h, db.c, db_gis.c, interface.c: Improvements to
+	  the tollerance of the db_gis code to problems with connections to
+	  databases and improved reporting of problems in making
+	  connections.
+
+	  Added code to add tracks for stations retrieved from the
+	  database.  Still needs work, as the existing db.c code for adding
+	  stations and points to the tracks of stations makes different
+	  assumptions about the order in which positions are recieved than
+	  the order of records queried in db_gis.c.
+
+2008-02-21 20:51  chicoreus
+
+	* scripts/: db_gis_mysql.sql, db_gis_postgis.sql: Adding some
+	  indexes to speed up retrieval of station records.  Adding a view
+	  that could be used with mapserver to return icon files for each
+	  station.
+
+2008-02-16 08:15  we7u
+
+	* src/main.c: Switching the Garmin RINO processing to use
+	  uncompressed packets for now as there is a problem with either
+	  this section of code or the Compressed encoding code for
+	  particular positions.  Change the ABOUT message to include
+	  additional copyright information.
+
+2008-02-07 18:47  chicoreus
+
+	* src/: main.c, main.h, maps.c, maps.h, xa_config.c: Adding two new
+	  KML export features:
+
+	  1) KML Snapshots - on a regular basis (using the same timing as
+	  PNG snapshots), write all currently known stations to a kml file.
+
+	  2) KML file to accompany PNG snapshots.  After converting
+	  snapshot.png to snapshot.jpg, the accompanying snapshot.kml file
+	  can be used to layer the snapshot.jpg image on the landscape in a
+	  kml application.
+
+	  The KML produced is valid and appears to work, but hasn't been
+	  extensively tested.
+
+	  This (along with the allready committed export a single station
+	  track to kml feeature) should complete the feature request for
+	  KML export:
+	  http://sourceforge.net/tracker/index.php?func=detail&aid=1863377&group_id=45562&atid=443274
+
+2008-02-07 18:35  chicoreus
+
+	* help/help-English.dat: Added help text describing KML export and
+	  snapshot features.
+
+2008-02-07 18:33  chicoreus
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding menu item
+	  for regular snapshots of all heard stations to a kml file,
+	  analogus to png snapshots.
+
+2008-02-07 18:29  chicoreus
+
+	* scripts/: kml_snapshot_feed.kml, kml_snapshot_to_web.sh: An
+	  example kml file and a shell script to allow png snapshots with
+	  their accompanying snapshot.kml file to be used as a regularly
+	  updated kml feed on a webserver (allowing the current snapshot
+	  from xastir to be draped over the landscape in a kml application
+	  remotely subscribing to the feed.)
+
+2008-01-29 19:08  chicoreus
+
+	* help/help-English.dat: Correcting a spelling error (found by
+	  Curt).
+
+	  Placing more references to button titles in quotes to make the
+	  description of the station info dialog more consistent.
+
+	  Clarifying (hopefully) some of the description of saving tracks
+	  from the station info dialog.
+
+2008-01-25 21:45  chicoreus
+
+	* src/: db.c, util.c, util.h: Added a utility function to return a
+	  date/time in w3c timestamp format, required for valid timestamps
+	  in kml files.
+
+	  Rearranged the log station to kml code, and added timestamped
+	  placemarks for each location of a station in a track.  This
+	  produces kml output that validates, and should behave like the
+	  "Shroeder" whale shark example file (moving a station location
+	  along its track as a time slider control is moved in Google
+	  Earth).  This has not yet been tested to see if the behavior is
+	  as desired.
+
+2008-01-24 22:21  chicoreus
+
+	* INSTALL, config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, help/help-English.dat: Localization
+	  for Station->Export All->Export kml menu items.
+
+	  User documentation of KML export.
+
+	  User documentation for spatial database support.
+
+	  Added some fault recovery comments to spatial database
+	  configuration section of INSTALL.
+
+2008-01-24 22:18  chicoreus
+
+	* src/: database.h, db.c, main.c: Adding Station->Export all menu,
+	  with option to export all station records to a single kml file.
+
+2008-01-24 14:36  chicoreus
+
+	* src/: interface_gui.c, main.c, objects.c: Fix for bug 1863228.
+	  Lesstif doesn't yet fully support combo boxes, which are used in
+	  4 places in Xastir (for user configurable predefined objects file
+	  in defaults dialog, cad object line type in the cad object
+	  details dialog, and twice in the interface properties dialog when
+	  defining a sql database interface.
+
+	  An alternate lesstif menu that mimics a combo box control
+	  (modified from xpdf's XPDFViewer.cc), is applied in three of
+	  these four cases (the fourth currently only has a single option,
+	  and might not be the best control for the situation, picking
+	  database schema type[s]).
+
+	  This has been tested on lesstif 0.94.4 and openmotif 2.3.0.
+
+2008-01-23 00:23  we7u
+
+	* src/interface.c: Added "volatile" keyword to a couple of
+	  variables to assure they don't get overwritten by longjmp.
+
+2008-01-22 23:34  we7u
+
+	* src/track_gui.c: Converting from mucking with pointers to pass to
+	  variables to a thread, to passing a pointer to a struct instead.
+	  This last method should avoid architecture-dependent problems in
+	  the download findu trail processing.
+
+2008-01-22 23:08  we7u
+
+	* src/track_gui.c: Added a comment regarding a section of code
+	  which does type-punning and may be architecture-dependent.
+
+2008-01-22 23:07  we7u
+
+	* src/messages.c: Commented out "altgroup" section of conditional
+	  which always equates to true ('cuz it's an address).
+
+2008-01-22 23:05  we7u
+
+	* src/interface.c: Added a couple of comments.
+
+2008-01-22 22:00  we7u
+
+	* src/map_cache.c: Reformatting debug statement so that it won't
+	  generate compiler warnings.
+
+2008-01-22 20:49  we7u
+
+	* src/wx.c: Fixing a buffer overrun.  Found via a compiler warning
+	  on OpenSuSE-10.3
+
+2008-01-22 20:48  we7u
+
+	* src/map_geo.c: Reformatting a debug statement so it won't cause
+	  compiler warnings.
+
+2008-01-22 20:47  we7u
+
+	* src/map_gdal.c: Getting rid of a conditional that always
+	  evaluates as true:  The address of "label".
+
+2008-01-22 20:46  we7u
+
+	* src/map_dos.c: Fixing an array overflow condition that has
+	  existed for a LONG time.  Found via a compiler warning on
+	  OpenSuSE-10.3
+
+2008-01-22 20:45  we7u
+
+	* src/map_WMS.c: Changing debug statement format so it won't cause
+	  a compiler warning to be issued.
+
+2008-01-22 20:43  we7u
+
+	* INSTALL: Adding a note about RINO's:	That Xastir cannot cause a
+	  poll of the remote RINO units over the air.
+
+2008-01-18 18:49  chicoreus
+
+	* src/db_gis.c: More cleanup of db_gis code.
+
+2008-01-18 18:48  chicoreus
+
+	* src/main.c: Adding test in UpdateTime to avoid opening the same
+	  database interface twice during startup if it is marked to both
+	  activate on startup and load stations on startup.
+
+2008-01-17 19:21  chicoreus
+
+	* src/: db.c, db_gis.c, main.c: Minor stability improvements to
+	  db_gis code.	Adding some sanity checks for null database
+	  connections when running queries to reduce segfaults.
+
+	  Begining cleanup of the db_gis code.	Removing some leftover
+	  unused variables and code.  Explicit type casting of some
+	  pointers in function calls to suppress compiler warnings.
+
+2008-01-16 20:33  chicoreus
+
+	* src/: database.h, db.c, db_gis.c, main.c, objects.c: First pass
+	  at exporting station tracks as kml files.  On clicking store
+	  track on the station information dialog, both an xastir format
+	  file and a kml file for the selected station will be written to
+	  ~/.xastir/tracklogs
+
+	  Added more comments on how database schema version and series
+	  compatability should work.
+
+	  Fixed (superficially) a bug where station data would be written
+	  to a non-open database connection causing a segfault.  Connection
+	  handling in db_gis is fragile and needs review.
+
+2008-01-16 11:38  we7u
+
+	* scripts/: BUILDRPMS, LSB-BUILD: Updating to 1.9.3 release number.
+
+2008-01-16 11:33  we7u
+
+	* AUTHORS, ChangeLog, DEBUG_LEVELS, FAQ, INSTALL, LICENSE,
+	  Makefile.am, NEWS, README, README.CVS, README.Contributing,
+	  README.Getting-Started, README.MAPS, README.win32,
+	  REGRESSION_TESTS, UPGRADE, acinclude.m4, bootstrap.sh,
+	  changes.txt, configure.ac, install-xastir, update-xastir,
+	  xastir.1, Davis/Makefile.am, Davis/README, Davis/bootstrap.sh,
+	  Davis/configure.ac, Davis/src/Makefile.am, Davis/src/db2APRS.c,
+	  Davis/src/defs.h, LaCrosse/Makefile.am, LaCrosse/README,
+	  LaCrosse/bootstrap.sh, LaCrosse/configure.ac,
+	  LaCrosse/src/Makefile.am, LaCrosse/src/defs.h,
+	  LaCrosse/src/open2300db2APRS.c, callpass/Makefile.am,
+	  callpass/callpass.c, config/24kgrid.dbfawk, config/Makefile.am,
+	  config/gps_wpt.dbfawk, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  config/nwsc_ddmmyy.dbfawk, config/nwsmzddmmyy.dbfawk,
+	  config/nwsmzoddmmyy.dbfawk, config/nwsozddmmyy.dbfawk,
+	  config/nwsw_ddmmyy.dbfawk, config/nwsz_ddmmyy.dbfawk,
+	  config/nwszoddmmyy.dbfawk, config/predefined_EVENT.sys,
+	  config/predefined_SAR.sys, config/tgr2shp.dbfawk,
+	  config/tgr2shppoly.dbfawk, config/tgr2shppoly_2006.dbfawk,
+	  config/tgrcty.dbfawk, config/tgrkgl.dbfawk, config/tgrlk.dbfawk,
+	  config/tgrlpt.dbfawk, config/tgrlpy.dbfawk,
+	  config/tgrplc00.dbfawk, config/tgrwat.dbfawk,
+	  config/tnc-startup.aea, config/tnc-startup.d700,
+	  config/tnc-startup.kam, config/tnc-startup.kpc2,
+	  config/tnc-startup.kpc3, config/tnc-startup.paccomm,
+	  config/tnc-startup.pico, config/tnc-startup.sys,
+	  config/tnc-startup.thd7, config/tnc-startup.tnc2,
+	  config/tnc-startup.tnc2-ui, config/tnc-stop.d700,
+	  config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui, help/Makefile.am, help/help-Dutch.dat,
+	  help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, m4/Makefile.am,
+	  scripts/LSB-BUILD, scripts/LSB-BUILD-ALL, scripts/LSB-BUILD-CURL,
+	  scripts/LSB-BUILD-DB, scripts/LSB-BUILD-GDAL,
+	  scripts/LSB-BUILD-GRAPHICSMAGICK, scripts/LSB-BUILD-JASPER,
+	  scripts/LSB-BUILD-JPEG, scripts/LSB-BUILD-LESSTIF,
+	  scripts/LSB-BUILD-PCRE, scripts/LSB-BUILD-PNG,
+	  scripts/LSB-BUILD-ZLIB, scripts/Makefile.am, scripts/PigLatin.pl,
+	  scripts/Xastir_tigerpoly.py, scripts/example_objects.log,
+	  scripts/fcc-get, scripts/get-NWSdata, scripts/get-gnis,
+	  scripts/get-maptools.sh, scripts/get_shapelib.sh,
+	  scripts/toporama250k.pl, scripts/toporama50k.pl,
+	  scripts/xastir-fixcfg.sh, scripts/xastir-migrate.sh,
+	  src/Makefile.am, src/alert.c, src/alert.h, src/awk.c, src/awk.h,
+	  src/bulletin_gui.c, src/bulletin_gui.h, src/color.c, src/color.h,
+	  src/database.h, src/datum.c, src/datum.h, src/db.c, src/db_gis.c,
+	  src/db_gis.h, src/dbfawk.c, src/dbfawk.h, src/draw_symbols.c,
+	  src/draw_symbols.h, src/fcc_data.c, src/fcc_data.h,
+	  src/festival.c, src/festival.h, src/geo-client.c, src/geo-find.c,
+	  src/geo.h, src/geocoder_gui.c, src/gps.c, src/gps.h,
+	  src/hashtable.c, src/hashtable.h, src/hashtable_itr.c,
+	  src/hashtable_itr.h, src/hashtable_private.h, src/hostname.c,
+	  src/hostname.h, src/igate.c, src/igate.h, src/interface.c,
+	  src/interface.h, src/interface_gui.c, src/io-common.c,
+	  src/io-mmap.c, src/io.h, src/lang.c, src/lang.h,
+	  src/leak_detection.h, src/list_gui.c, src/list_gui.h,
+	  src/locate_gui.c, src/location.c, src/location_gui.c,
+	  src/macspeech.c, src/main.c, src/main.h, src/map_WMS.c,
+	  src/map_cache.c, src/map_cache.h, src/map_dos.c, src/map_gdal.c,
+	  src/map_geo.c, src/map_gnis.c, src/map_pdb.c, src/map_shp.c,
+	  src/map_tif.c, src/map_tiger.c, src/maps.c, src/maps.h,
+	  src/messages.c, src/messages.h, src/messages_gui.c,
+	  src/objects.c, src/objects.h, src/popup.h, src/popup_gui.c,
+	  src/rac_data.c, src/rac_data.h, src/rotated.c, src/rotated.h,
+	  src/rpl_malloc.c, src/rpl_malloc.h, src/shp_hash.c,
+	  src/shp_hash.h, src/snprintf.c, src/snprintf.h, src/sound.c,
+	  src/symbols.h, src/testawk.c, src/track_gui.c, src/track_gui.h,
+	  src/util.c, src/util.h, src/view_message_gui.c, src/wx.c,
+	  src/wx.h, src/wx_gui.c, src/x_spider.c, src/x_spider.h,
+	  src/xa_config.c, src/xa_config.h, src/xastir.h,
+	  src/xastir_udp_client.c, src/rtree/Makefile.am, src/rtree/card.c,
+	  src/rtree/card.h, src/rtree/gammavol.c, src/rtree/index.c,
+	  src/rtree/index.h, src/rtree/node.c, src/rtree/rect.c,
+	  src/rtree/sphvol.c, src/rtree/split_l.c, src/rtree/split_l.h,
+	  src/rtree/split_q.c, src/rtree/split_q.h,
+	  src/shapelib/Makefile.am, src/shapelib/contrib/Makefile.am,
+	  symbols/Makefile.am, symbols/symbols.dat: Updating the copyright
+	  notices for 2008.
+
+2008-01-16 10:32  we7u
+
+	* configure.ac: Preparing for devel release, bumping revision
+	  number.
+
+2008-01-10 07:35  chicoreus
+
+	* src/: interface.c, main.c, objects.c: Fixing bug where
+	  objects/items created by the user are not displayed until Xastir
+	  is restarted.
+
+	  Adding more debugging information when loading predefined objects
+	  from a file.
+
+2008-01-09 21:06  chicoreus
+
+	* src/: db.c, db_gis.c: Fix from Curt for some compile warnings in
+	  xastirWKTPointToLatitude().
+
+	  Fix to incorrect data being written to MySQL table
+	  simpleStationSpatial in the origin and node_path fields.
+
+	  Note: When selecting data from MySQL simpleStationSpatial, use
+	  the AsText() function on position.  For example, to retrieve the
+	  10 most recently heard stations: select station, symbol, overlay,
+	  aprstype, AsText(position), transmit_time, origin,  record_type,
+	  node_path from simpleStationSpatial order by transmit_time desc
+	  limit 10 ;
+
+2008-01-08 17:22  chicoreus
+
+	* src/interface.c: Possible bug fix for the can't have two sql
+	  database interfaces open at the same time issue.
+
+	  Pointers around Connections need review.
+
+2008-01-08 07:00  chicoreus
+
+	* src/: db_gis.c, db_gis.h, interface.c, main.c: db_gis.c
+	  closeConnection now linked to stop button on interfaces.
+
+	  SQL database state (open,closed,error[on connect only]) state
+	  shown on interface list.
+
+2008-01-07 20:35  chicoreus
+
+	* INSTALL, scripts/db_gis_mysql.sql, scripts/db_gis_postgis.sql,
+	  src/db_gis.c, src/interface_gui.c, src/objects.c: Added some
+	  installation instructions for spatial database support.
+
+	  Added a workaround for lesstif not having full implementation of
+	  combo boxes (borrowed from xpdf's XPDFViewer.cc) to the dbms
+	  selection control on the spatial database interface dialog.  Fix
+	  needs to be propagated to several other places.
+
+	  Fixes to sql scripts to build mysql and postgis database tables.
+
+2008-01-01 14:58  chicoreus
+
+	* src/: database.h, db.c, db_gis.c, db_gis.h, interface.c,
+	  interface.h, interface_gui.c, main.c, main.h, xa_config.c:
+	  Significant updates to db_gis code, supporting storage of station
+	  data to both MySQL and postgis enabled Postgresql databases.
+	  Stations heard in Xastir can have the core station information
+	  logged to either a Postgres or MySQL database (Bug: currently
+	  both aren't working at the same time), and then retrieved in a
+	  subsequent Xastir session (or by a different Xastir instance, or
+	  by another GIS application (such as QGIS over a postgis database
+	  populated from Xastir)).
+
+	  Tested with MySQL 5.0.32, may not work with MySQL 4.1.  Tested
+	  with Postgres 8.1.9
+
+2008-01-01 14:50  chicoreus
+
+	* scripts/: db_gis_mysql.sql, db_gis_postgis.sql: Adding sql
+	  scripts to create tables for persistent storage of basic station
+	  data.  One script for mysql, another for postgis enabled
+	  postgresql.  Currently only supports a single simple table with
+	  the minimun station information.
+
+2007-12-18 12:56  tvrusso
+
+	* configure.ac: Fix improper probing of curl library when LSB is
+	  not being used.
+
+	  AC_CHECK_LIB can have two or three arguments.  With two arguments
+	  it tests for the presence of a function named in the second
+	  argument in the library named by the first argument, and if found
+	  defines HAVE_LIBxxxxx and adds -lxxxxx to LIBS.
+
+	  In the three-argument case, it does the probe the same way, but
+	  instead of the default "define HAVE_LIBxxxxx and add -lxxxxx to
+	  LIBS" it does what it's told in the third argument.  That means
+	  if you want to rely on HAVE_LIBxxxxx and LIBS="${LIBS} -lxxxxx"
+	  then you have to do it yourself in the third argument.
+
+	  The AC_CHECK_LIB for curl was only doing the extra thing, which
+	  was to set "use_curl" to "yes".
+
+	  I recently discovered this by trying to build and use xastir on a
+	  freshly installed system that had libcurl but no wget (most of my
+	  other systems have both).  The bug in the use of AC_CHECK_LIB
+	  meant that libcurl was found, but never linked in nor was
+	  HAVE_LIBCURL ever set in config.h.
+
+	  With this fix, curl is now both properly detected *and* the
+	  detection properly communicated to the code.
+
+2007-12-13 22:23  tvrusso
+
+	* config/tgr2shp.dbfawk: Add "P" feature class to handle
+	  "Provisional" road data in TIGER/Line shapefiles.  According to
+	  the TIGER/Line Technical Documentation for feature class "P"
+
+	     The U.S. Census Bureau has created a new CFCC type that may
+	  appear on
+	     street features only.  Some streets that normally would be
+	  classified as
+	     "A" class features may be coded with a "P" instead of the "A"
+	  to indicate
+	     that the feature is a a "provisional" feature.  Provisional
+	  features are
+	     those streets that were added from reference sources or other
+	  programs
+	     in preparation for Census 2000, but were not field verified by
+	  census staff
+	     during field operations or through the use of aerial
+	  photography or imagery.
+	     As these featues are verified in futuer operations the
+	  provisional flag
+	     will be removed for subsequent TIGER/Line releases.  The
+	  numeric portion
+	     of the CFCC still classifies the street as if an "A" were
+	  preceding it.
+
+	  So this just involves changing the matching pattern from
+	  CFCC=A... to CFCC=[AP]... in all the feature-class A rules.
+
+2007-12-05 08:40  tvrusso
+
+	* README.MAPS: Add more text to the section on Geocommuity's DRG
+	  Data Bundle deals.  Turns out that some areas have DRGs produced
+	  by some agency other than the USGS, and those agencies don't
+	  necessarily produce GeoTiff files with proper metadata.  The
+	  Tennesee Valley Authority is among those agencies that don't
+	  properly include GeoTiff tags for projection and datum.  This
+	  renders DRG data bundles for states with portions of their area
+	  covered by the TVA partially defective --- special preprocessing
+	  is necessary to get the files into a state that can be used in
+	  Xastir.
+
+2007-11-14 07:05  tvrusso
+
+	* README.MAPS: Add a pointer to a vendor of inexpensive GeoTIFF
+	  format DRGs for the US.  They're one of the USGS's data partners
+	  that is listed elsewhere in the document, but in a different
+	  context.
+
+	  Thanks to Eric, KZ5ED, for calling it to my attention.
+
+2007-11-07 13:37  tvrusso
+
+	* src/: main.c, map_WMS.c, map_geo.c, map_tiger.c, maps.c: Work
+	  around the fact that ImageMagick's api.h rudely includes their
+	  autoconf-generated config.h, which therefore defines the same
+	  PACKAGE and VERSION macros that we do.
+
+	  In most files, this produces an annoying but harmless warning
+	  message about a redefinition.  For main.c, however, it cause
+	  Magick's PACKAGE name and VERSION to be used in place of our own.
+	   That is, our About window will announce that we're ImageMagick
+	  version 6.3.x.
+
+	  For the files in which it's a harmless warning, I've done an
+	  #undef of the two macros to shut up the compiler warnings.
+
+	  In main.c, I've created two new char* variables and initialized
+	  them to PACKAGE and VERSION before including magick's api.h, and
+	  then undef'd them.  This preservs the contents of our macros by
+	  substituting them in C code right away, then gets rid of them so
+	  the warnings are shut up.
+
+	  Attempting to do:   #define XASTIR_PACKAGE PACKAGE   #undef
+	  PACKAGE   #include <magick/api.h>   #undef PACKAGE   #define
+	  PACKAGE XASTIR_PACKAGE
+
+	  doesn't help.  All that does is silence the warning.	Magick's
+	  package name is still used when we try to use the PACKAGE macro
+	  later.  Macro expansions aren't variable assignments, and the
+	  code above does nothing more than define PACKAGE to PACKAGE and
+	  thence to "ImageMagick", after briefly allowing api.h to change
+	  its meaning without warning.
+
+	  Adding an "#undef XASTIR_PACKAGE" after all that is even worse,
+	  and results in fatal compilation errors.  There's probably some
+	  preprocessor game that can be played to kludge this, but saving
+	  the string we want to keep somewhere where it's safe from
+	  preprocessor meddling seems the better choice.
+
+2007-11-06 09:10  we7u
+
+	* configure.ac, scripts/BUILDRPMS, scripts/LSB-BUILD,
+	  scripts/do_xastir_release_dev, scripts/do_xastir_release_stable:
+	  Preparing for 1.9.2 stable release.
+
+2007-09-24 19:41  we7u
+
+	* src/track_gui.c: Finished the regex code for converting
+	  HTML->Text for downloaded findu.com tracks.
+
+2007-09-22 03:53  we7u
+
+	* src/track_gui.c: Commenting out unused variable.
+
+2007-09-22 03:25  we7u
+
+	* configure.ac: Commenting out the html2text discovery code.
+
+2007-09-22 03:25  we7u
+
+	* configure.ac: Checking in the html2text discovery code in case we
+	  may want it in the future.
+
+2007-09-22 03:24  we7u
+
+	* src/track_gui.c: Doing the html2text via sed statements.
+
+2007-09-22 01:29  we7u
+
+	* src/track_gui.c: Converting the downloaded findu.com raw packets
+	  from HTML to text.  Still need to look for "html2text" and find
+	  out it's path in the autoconf scripts in order to integrate this
+	  properly.
+
+2007-09-16 18:31  tvrusso
+
+	* src/interface_gui.c: Fix misplaced #endif /* HAVE_DB */ that was
+	  breaking the gui for networked AGWPE.
+
+2007-09-04 13:09  we7u
+
+	* src/db.c: Changing the new variable "i" to "ii" to make it easier
+	  to search for in the sources, plus getting rid of the declaration
+	  for the case where we're not using an SQL database (to get rid of
+	  a compiler warning).
+
+2007-08-31 05:20  gstueve
+
+	* src/map_geo.c: Add subroutine to release memory consistently for
+	  exit points.
+
+2007-08-28 16:16  we7u
+
+	* scripts/PigLatin.pl: Updated one comment.
+
+2007-08-28 15:32  we7u
+
+	* scripts/PigLatin.pl: Initial commit.
+
+2007-08-24 06:44  gstueve
+
+	* src/igate.c: Push active groups through the gateway between
+	  RF<->INet.
+
+2007-08-24 06:42  gstueve
+
+	* src/: messages.c, messages.h: Export group_active for use in
+	  igate of group transmission list.
+
+2007-08-22 08:42  gstueve
+
+	* src/alert.c: Make sure to test against initialized data.
+
+2007-08-20 20:10  chicoreus
+
+	* src/db.c, src/db_gis.c, src/db_gis.h, src/interface.c,
+	  src/interface_gui.c, src/main.c, symbols/symbols.dat: Cleaning up
+	  db_gis code.
+
+	  Some cleanup of error messages.  Moved some debugging messages
+	  into debug_level & 1.
+
+	  Altered simpleStation table structure to add three more columns:
+
+	  alter table simpleStation add column origin varchar(9) not null
+	  default ''; alter table simpleStation add column record_type
+	  varchar(1); alter table simpleStation add column node_path
+	  varchar(56);
+
+	  These seem necessary for recreating DataRow records out of
+	  simpleStation database records.
+
+	  Added more testing and handling of data that is to be written to
+	  database records.  Still needs better sanitizing.  Tested saving
+	  DataRow records derived from internet feeds to MySQL (old), and
+	  Postgresql(8)/Postgis records.
+
+2007-08-20 12:22  we7u
+
+	* src/main.c: Adding two casts to (int *) back in.  They are
+	  required to get rid of compiler warnings with some versions of
+	  GCC.
+
+2007-08-17 15:08  gstueve
+
+	* src/: map_WMS.c, map_cache.c, map_geo.c, map_tiger.c: Make sure
+	  to free allocated memory after we are done playing with it.
+
+2007-08-16 12:28  gstueve
+
+	* src/main.c: Make sure colors are identified as Pixel not int
+	  types.
+
+2007-08-16 12:26  gstueve
+
+	* src/list_gui.c: Make sure SL_scroll is initialized for full
+	  operation.
+
+2007-08-16 10:36  gstueve
+
+	* src/map_geo.c: Make sure we return the exception data to free
+	  space when done. Don't leave it as unclaimed uggage.
+
+2007-08-16 10:01  gstueve
+
+	* src/list_gui.c: Make sure the station_list displays give back the
+	  memory after they are done playing with it. They are not expected
+	  to lose it.
+
+2007-08-15 10:57  gstueve
+
+	* src/draw_symbols.c: Pixel values are 'unsigned long' not 'int' on
+	  64 bit machines.
+
+2007-08-15 10:41  gstueve
+
+	* src/: main.c, main.h, xastir.h: Type of colors & trail_colors is
+	  Pixel, not int. Especially on 64 bit machines.
+
+2007-08-15 08:44  we7u
+
+	* src/map_cache.c: Backing out this change as it caused this error
+	  and Xastir to blow up when a new map image was cached to disk:
+	  "glibc detected *** double free or corruption"
+
+2007-08-14 09:41  we7u
+
+	* src/util.c: Adding a minor comment.  Thanks to Gerald Stueve for
+	  re-examining all this code.  He's doing a WONDERFUL job of
+	  finding/fixing bugs!
+
+2007-08-14 09:28  we7u
+
+	* src/: db_gis.c, db_gis.h: Adding the RCS ID tag and tweaking the
+	  copyright statements to show correct dates and attribution for
+	  these two files.
+
+2007-08-13 13:23  gstueve
+
+	* src/main.c: Clear entire block of appshell, not just first
+	  pointer space.
+
+2007-08-13 13:22  gstueve
+
+	* src/x_spider.c: No need to have extra layer of callback, go
+	  directly to exit.
+
+2007-08-13 12:55  gstueve
+
+	* src/x_spider.c: Allow the subprocesses to cleanup and exit on
+	  interrupt.
+
+2007-08-13 12:54  gstueve
+
+	* src/rac_data.c: Make sure we aren't checking against unitialized
+	  data.
+
+2007-08-13 09:17  tvrusso
+
+	* README.MAPS:
+	  Add the answer to a frequently asked question about TIGER/Line
+	  2006 SE shapefile zip files ("what's the difference between the
+	  Polylines and Polygons directory?").
+
+2007-08-11 19:00  chicoreus
+
+	* src/: db_gis.c, db_gis.h: Simple schema insert added for
+	  Postgresql/postgis.  Tested with Postgresql 8.2 and postgis
+	  1.2.1.
+
+	  Simple station records can now be written to MySQL and
+	  Postgresql/Postgis databases, but xastir can't yet extract any
+	  data back.
+
+2007-08-10 16:15  gstueve
+
+	* src/util.c: Make sure to initialize string before testing fixed
+	  offset values.  Valgrind identified the dereferences with errors.
+
+2007-08-10 16:11  gstueve
+
+	* src/map_cache.c: Valgrind again. Make sure to release memory
+	  after using it.
+
+2007-08-10 16:09  gstueve
+
+	* src/db.c: More valgrind identified errors. Make sure to
+	  initialize tested variables.
+
+2007-08-10 15:48  gstueve
+
+	* src/x_spider.c: Add clear_proc_title to clean up environment
+	  pointers.
+
+2007-08-10 07:06  gstueve
+
+	* src/x_spider.c: valgrind is our friend. Make sure not to step
+	  back too far for line end.
+
+2007-08-09 13:12  gstueve
+
+	* src/map_shp.c: Make sure to Destroy a region before overwriting
+	  the value.  Identified by valgrind.
+
+2007-08-09 07:07  gstueve
+
+	* src/wx_gui.c: change to newer function -	      item =
+	  XmStringCreateLtoR(temp, XmFONTLIST_DEFAULT_TAG); +
+	  item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG,
+	  XmCHARSET_TEXT, NULL); to replace deprecated function.
+
+2007-08-08 08:29  we7u
+
+	* src/interface.c: Moving one of the SQL debug printf's inside an
+	  #ifdef block so that we won't normally see it.
+
+2007-08-07 18:55  chicoreus
+
+	* src/: db_gis.c, db_gis.h: Change to error handling in the event
+	  of an xastir coordinate for a station that doesn't translate to a
+	  valid lat/long - returns error message indicating conversion
+	  problem rather than as database problem.
+
+2007-08-07 13:33  gstueve
+
+	* src/map_pdb.c: Allow more granularity for debugging actions.
+	  Remove unneeded global definitions.
+
+2007-08-07 10:29  chicoreus
+
+	* src/interface_gui.c: Removing some unecessary debugging messages.
+
+2007-08-07 09:24  chicoreus
+
+	* src/: interface.c, interface_gui.c: Bug fix - SQL database
+	  interface definitions were always being placed as interface 0 in
+	  the interface list.
+
+2007-08-07 09:08  we7u
+
+	* src/interface.c: Adding "#ifdef HAVE_DB" around the SQL database
+	  interface type so that it doesn't appear in the list unless
+	  configure finds that we have support for it.
+
+2007-08-07 09:05  we7u
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding the SQL
+	  Database string to the other language files.
+
+2007-08-07 08:31  we7u
+
+	* src/messages_gui.c: Commenting out an unused variable which
+	  causes a compiler warning.
+
+2007-08-07 08:31  we7u
+
+	* src/interface_gui.c: Adding "#ifdef HAVE_DB" around a couple of
+	  fprintf's.
+
+2007-08-06 18:06  chicoreus
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/database.h, src/db.c,
+	  src/db_gis.c, src/db_gis.h, src/interface.c, src/interface.h,
+	  src/interface_gui.c, src/main.c, src/messages_gui.c, src/util.c,
+	  src/util.h, src/xa_config.c: Further work on sql server
+	  (MySQL/Postgis) support.  Began integration of sql connection
+	  management with interface UI.  Able to create a connection to a
+	  MySQL database, and on starting it, save list of all current
+	  stations to a simple single table db.
+
+	  Code still needs substantial work before it is usable.
+
+2007-07-30 10:13  we7u
+
+	* INSTALL: Updating libgeotiff instructions for latest released
+	  version (1.2.4).
+
+2007-07-27 08:55  we7u
+
+	* README.Getting-Started: Adding another note explaining that
+	  "internal" on the Shapelib summary line is ok.
+
+2007-07-27 08:48  we7u
+
+	* README.Getting-Started, configure.ac: Getting rid of the
+	  "Building with" text on the configure summary line.  Fixing one
+	  of the README's to match.
+
+2007-07-25 08:53  we7u
+
+	* INSTALL: Revising the install instructions for the optional
+	  Shapefile utilities to correspond to the current sources.
+
+2007-07-25 08:45  we7u
+
+	* src/shapelib/contrib/: dbfcat.c, dbfinfo.c, shpcat.c,
+	  shpcentrd.c, shpdxf.c, shpfix.c, shpgeo.c, shpinfo.c, shpproj.c:
+	  Adding includes necessary for warning-free compiles.
+
+2007-07-25 08:45  we7u
+
+	* src/shapelib/contrib/.cvsignore: Adding shpproj executable to CVS
+	  ignore.
+
+2007-07-25 08:37  we7u
+
+	* src/shapelib/: Makefile_shapelib_orig, shpcreate.c, shpdump.c,
+	  shprewind.c: Added shprewind.c to the "clean" target of the
+	  original Makefile.  Added stdlib.h includes to some of the
+	  utilities to get a clean compile.
+
+2007-07-25 08:10  we7u
+
+	* INSTALL: Adding instructions for compiling some of the optional
+	  Shapelib utilities and contributed Shapelib utilities.
+
+2007-07-23 09:58  we7u
+
+	* src/db_gis.c: Moving the strtof test below the config.h include.
+
+2007-07-23 08:58  tvrusso
+
+	* configure.ac, src/db_gis.c: Fix up usage of strtof for systems
+	  that are so old they don't have this function.
+
+2007-07-18 09:20  we7u
+
+	* src/db.c: Correcting a spelling error in a debug statement.
+
+2007-07-16 07:38  chicoreus
+
+	* INSTALL: Fixing typo in install documentation.  Patch from Jim
+	  Tittsler - jtittsler Tracker: [ 1695864 ] INSTALL typo
+	  ImageMagick->GraphicsMagick
+
+2007-07-14 20:39  chicoreus
+
+	* src/main.c: [no log message]
+
+2007-07-14 20:37  chicoreus
+
+	* src/: Makefile.am, db_gis.c, db_gis.h, lclint.script: Framework
+	  for spatial database support.  Should compile, but won't do
+	  anything yet.
+
+2007-07-14 20:33  chicoreus
+
+	* acinclude.m4, configure.ac: Adding tests for MySQL, Postgresql,
+	  and Postgis for spatial database support
+
+2007-07-09 20:03  tvrusso
+
+	* README.MAPS: Fix up mistaken information about TIGER/Line data.
+	  Update pointers to geocoding files (we were still pointing users
+	  to the 2003 data, which is a poor match to recent TIGER/Line
+	  shapefiles).
+
+2007-07-06 15:43  we7u
+
+	* configure.ac: For the summary, we now refuse to display the
+	  developer section unless one of those options has been enabled.
+	  This is so normal users don't have to worry about that section.
+
+2007-07-06 15:06  we7u
+
+	* configure.ac: More additions to the summary output.
+
+2007-07-06 14:32  we7u
+
+	* configure.ac: Changing some of the summary text.
+
+2007-07-06 12:24  we7u
+
+	* src/main.c: Bumping up the size of the Help->About "Libraries
+	  Used" string.
+
+2007-07-06 12:17  we7u
+
+	* configure.ac: A few more small tweaks to the configure summary
+	  output.
+
+2007-07-06 12:04  we7u
+
+	* configure.ac: Reformatting the configure summary output.  Adding
+	  wget/libcurl to the summary as well.
+
+2007-07-02 16:43  tvrusso
+
+	* configure.ac: Remove hack to use external rtree library ---
+	  differences between GRASS's rtree library and ours make it so
+	  that we can't use them interchangably.  The difference is in the
+	  size of floating point variables used in the Rect structure (we
+	  use floats as did the original author, GRASS uses it modified to
+	  have doubles, which vastly increases memory usage for no real
+	  gain).
+
+	  This should remedy all of the Fedora users problems.	Unless it
+	  doesn't.
+
+2007-07-02 16:37  tvrusso
+
+	* src/: map_shp.c, shp_hash.c, rtree/card.c, rtree/card.h,
+	  rtree/index.c, rtree/index.h, rtree/node.c, rtree/rect.c,
+	  rtree/split_l.c, rtree/split_l.h: Turns out that putting a suffix
+	  on all symbols in the rtree library was very simple and fast, so
+	  I Just Did It.
+
+	  This should probably fix the problem for Fedora users with GDAL
+	  installed from repository, once I remove the "external rtree" bit
+	  from configure.ac.
+
+2007-07-02 15:08  we7u
+
+	* FAQ: Adding a section to the Map Problems/Solutions question
+	  about deleting the Xastir user directory and starting over when
+	  all else fails.
+
+2007-07-02 14:34  we7u
+
+	* FAQ: Added some debugging instructions for maps not working.
+
+2007-07-02 14:19  we7u
+
+	* FAQ: Updating the version number where "APX" is quoted.
+
+2007-07-02 12:34  we7u
+
+	* FAQ: Added a question/answer about how to solve the problem:
+	  station trail not displaying.
+
+2007-07-02 12:12  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Changing the ALTNET box
+	  so that it is smaller and has a label.
+
+2007-07-02 05:55  tvrusso
+
+	* src/rtree/: split_l.c, split_l.h: Undo the
+	  CoverSplit->l_CoverSplit change made last week.
+
+	  The real issue was that some repositories have a GDAL that
+	  includes GRASS libraries including a libgrass_rtree that
+	  duplicates the rtree functionality.  Xastir's rtree library is
+	  precisely the one that GRASS uses (based on public domain (i.e.
+	  uncopyrighted) software from www.superliminal.com), and this
+	  leads to a link conflict that produces an obscure and cryptic
+	  error message at link time.
+
+	  Renaming the CoverSplit variable was just a band-aid that was
+	  suggested for a trial run while diagnosing the problem, not a
+	  recommended fix.
+
+2007-07-01 21:20  tvrusso
+
+	* configure.ac: Add a note at the end that tells whether we're
+	  using external rtree (e.g.  from GDAL) or our own internal
+	  version.
+
+2007-07-01 21:12  tvrusso
+
+	* configure.ac: Fix configure so that it checks for the presence of
+	  RTreeSearch in other libraries before it builds our own rtree
+	  library.
+
+	  This is necessary because some repositories have a GDAL that was
+	  built with GRASS support (against current recommendations), and
+	  that brings in an rtree library unbidden.  The result of trying
+	  to link our own in unconditionally is a cryptic message about
+	  CoverSplit not being relocatable.
+
+	  The only testing I've done is that this doesn't break builds with
+	  GDAL that has no GRASS support.  I am unable to test it in the
+	  case for which it is intended.  I'll have to ask that someone
+	  with an F7 system do that.
+
+2007-06-29 13:22  we7u
+
+	* src/rtree/: split_l.c, split_l.h: Trying a rename of CoverSplit
+	  to l_CoverSplit to see if this fixes the Fedora linking problem.
+
+2007-06-21 12:10  we7u
+
+	* src/interface.c: Removing stale lockfiles when it was our own
+	  process group which created them earlier.
+
+2007-06-20 09:25  we7u
+
+	* src/map_geo.c: Adding a few comments to the code for the new
+	  transparent color linked list functions.
+
+2007-06-20 09:18  we7u
+
+	* README.MAPS: Tweaking the TRANSPARENT note to state that multiple
+	  lines may be used.
+
+2007-06-20 09:11  we7u
+
+	* WMSRadar.geo, src/map_geo.c: Commenting out debug fprintf plus
+	  adding another black and a white color as transparent colors to
+	  WMSRadar.geo.
+
+2007-06-20 08:42  we7u
+
+	* src/: main.h, map_WMS.c, map_geo.c, maps.h: First attempt at
+	  multiple TRANSPARENT support for .geo files.	Not fully tested
+	  yet, but doesn't appear to fall over either.
+
+2007-06-15 11:44  we7u
+
+	* scripts/LSB-BUILD: Updating to latest rev number for release.
+
+2007-06-10 09:53  tvrusso
+
+	* scripts/get-NWSdata: Update get-NWSdata to pull down the new
+	  files instead of trying to get some old and now non-existent
+	  files.
+
+2007-05-28 16:59  chicoreus
+
+	* src/: main.c, main.h, objects.c: Disabling close polygon item on
+	  CAD menu when not in draw mode.
+
+2007-05-28 12:53  tvrusso
+
+	* src/util.c: Fix a comment about multiline length.
+
+2007-05-28 12:51  tvrusso
+
+	* src/: db.c, util.c, util.h:
+	  Make the add_comment function stop stripping leading spaces.
+	  This is to allow multiline objects with no leading text, which
+	  otherwise get broken.
+
+	  Add a makeMultiline function to util.c.  Given arrays of lat/lon
+	  pairs, will produce a multiline string representing that array
+	  and a centroid value that can be used for creating an object.
+
+	  Bunch of debugging output added to extract_multipoint that I
+	  needed to help me track down why my multilines were disappearing
+	  (it was because of the leading space stripping).
+
+	  Nobody is calling makeMultiline yet.	It could be used for
+	  transmitting CAD objects if someone wanted to hack that in.
+
+	  I've tested makeMultiline in an external program to generate
+	  strings, then created objects by pasting the strings into the
+	  comment box of the create object dialog.
+
+2007-05-21 07:51  tvrusso
+
+	* README.MAPS: Update the TIGER/Line information.
+
+2007-05-09 10:36  tvrusso
+
+	* config/: Makefile.am, tgr2shppoly_2006.dbfawk: Add a new DBFAWK
+	  file for the 2006 TIGER/Line data.
+
+	  This data has "UACU" and "URCU" fields instead of the RS_A15 and
+	  RS_A16 fields that older TIGER/Line data had.
+
+2007-05-04 13:18  we7u
+
+	* help/help-English.dat: Added a note stating that all PHG values
+	  must be specified before Xastir will transmit the values.
+
+2007-05-02 13:58  we7u
+
+	* src/interface.c: Checking the result code, providing more info on
+	  why an "open" failed.
+
+2007-05-02 12:54  we7u
+
+	* configure.ac, scripts/BUILDRPMS: Setting up for the next devel
+	  release.
+
+2007-05-02 12:14  we7u
+
+	* ChangeLog, configure.ac, scripts/BUILDRPMS, scripts/LSB-BUILD,
+	  scripts/do_xastir_release_dev, scripts/do_xastir_release_stable:
+	  Preparing for stable 1.9.0 release.
+
+2007-04-27 09:55  tvrusso
+
+	* src/db.c: Cast the time_t value to (long int) before passing to
+	  fprintf.  On some systems (e.g. FreeBSD) time_t isn't a long, and
+	  using a %ld format for it generates a warning.  On other systems,
+	  time_t *is* a long int and using a %d format generates a warning.
+
+	  So punt: cast to (long int) and use %ld.  This should make all
+	  those systems shut up with their warnings.
+
+2007-04-27 06:52  we7u
+
+	* src/db.c: Changing some debug printf's from %d to %ld for
+	  printing some time variables.
+
+2007-04-27 06:47  we7u
+
+	* src/db.c: Changing some printf's to %ld instead of %d for some
+	  debug time printouts.
+
+2007-04-27 06:45  we7u
+
+	* src/db.c: Adding a missing "void" in a function header.
+
+2007-04-27 06:44  we7u
+
+	* src/database.h: Adding a missing "void" in a function
+	  declaration.
+
+2007-04-20 10:03  we7u
+
+	* FAQ: Added some debugging instructions for the missing
+	  "xastir.rgb" file and/or other files upon Xastir startup.
+
+2007-04-16 11:17  tvrusso
+
+	* src/: database.h, db.c: More debugging code to look into bug
+	  #1698474
+
+	  Add a "dump_time_sorted_list" method and calls to it so we can
+	  actually view the entire time sorted list as soon as the sanity
+	  check fails.
+
+	  Also reduce the debugging expire time from 1 hour to 5 minutes.
+
+2007-04-12 08:40  we7u
+
+	* FAQ: Adding a link to the timing slider dialog screen capture.
+
+2007-04-11 10:33  we7u
+
+	* FAQ: Added section 4.28 describing the problem with missing
+	  labels on the Configure->Timing dialog.  It also describes what
+	  the labels should be.
+
+2007-04-09 08:20  we7u
+
+	* config/language-German.sys: Updates by Rolf Bleher, DK7IN.
+	  Thanks!
+
+2007-03-31 12:49  tvrusso
+
+	* src/: database.h, db.c: Add some sanity checking to the
+	  EXPIRE_DEBUG logic.
+
+	  I am still seeing that every few weeks my xastir run starts to
+	  have stations that should have expired 10 days ago, but still has
+	  'em.	This really screws up the ALOHA calculations.
+
+	  This sanity checking just goes through the entire time-sorted
+	  list and checks to see if any stations are older than the expire
+	  time, and does this immediately after the expiration is
+	  processed.  The sanity checking only happens when EXPIRE_DEBUG is
+	  defined.
+
+	  The expire code assumes that the list is sorted by time, and
+	  stops when it finds a station newer than the expire time.  If the
+	  list is somehow getting corrupted and no longer properly sorted,
+	  that would explain the behavior I'm seeing.  I still haven't
+	  found the problem, but this should at least tell me if the list
+	  management has a bug or not.
+
+2007-03-22 10:05  gstueve
+
+	* scripts/fcc-get: Sort only on callsign. Don't use following
+	  fields.
+
+2007-03-13 07:55  gstueve
+
+	* scripts/fcc-get: Actually use web instead of older ftp server to
+	  get fcc data.
+
+2007-03-13 07:32  gstueve
+
+	* scripts/fcc-get: Make sure not to get rid of an old fcc data file
+	  if unable to get replacement file.
+
+2007-03-07 21:17  tvrusso
+
+	* src/: database.h, db.c: Change "check_station_remove" and
+	  "check_message_remove" to take a time_t for curr_time instead of
+	  an int.  time_t's are what's passed in, so let's keep it
+	  consistent.
+
+	  I do not believe this has anything at all to do with the fact
+	  that my xastir instance isn't deleting stations on the 1-day
+	  cycle I ask it to --- on my system a time_t and an int are the
+	  same size, and time_t is defined as an int32, not an unsigned or
+	  anything.  But it's still the right thing to do.
+
+2007-03-06 13:58  we7u
+
+	* src/map_geo.c: Getting rid of a compiler warning when we compile
+	  with ImageMagick.
+
+2007-03-06 11:31  we7u
+
+	* src/: map_WMS.c, map_geo.c, map_tiger.c, maps.c: Changing the
+	  path to the GraphicsMagick api.h file to match what we're
+	  currently compiling against.
+
+2007-03-06 11:30  we7u
+
+	* scripts/LSB-BUILD: Forcing the use of GraphicsMagick instead of
+	  ImageMagick, per the newer command-line flags we use for Xastir's
+	  configure.
+
+2007-02-27 15:19  gstueve
+
+	* src/bulletin_gui.c: Move display update until after the new data
+	  is posted to list.
+
+2007-02-27 13:33  gstueve
+
+	* src/alert.c: Keep trying to clear out old data for new messages.
+
+2007-02-24 14:08  gstueve
+
+	* src/wx_gui.c: Make sure updating Wx Alert List doesn't crash
+	  because selected item was replaced by unselected item.
+
+2007-02-22 08:29  we7u
+
+	* INSTALL: Adding "ldconfig" invocations for GM/IM installs.
+
+2007-02-22 08:14  we7u
+
+	* INSTALL: Changing the command-line options for configuring
+	  GraphicsMagick to something a bit simpler.
+
+2007-02-22 07:26  gstueve
+
+	* src/alert.c: Compressed Wx alerts are precisely 3 elements long.
+
+2007-02-22 07:20  gstueve
+
+	* src/: alert.c, util.c: Really, really take care of NWS_ message
+	  from Thailand.  Remove stale compressed weather alerts from
+	  consideration.
+
+2007-02-21 08:47  gstueve
+
+	* src/util.c: Fix error case from Thailand station sending message
+	  to NWS_ about 80th birthday anniversary of King.
+
+2007-02-21 08:02  gstueve
+
+	* src/db.c: Make conditional look like what it is (a for loop, not
+	  simple while).
+
+2007-02-16 20:11  gstueve
+
+	* src/db.c: Make sure debug_level is tested as BitWise value NOT
+	  logical value.
+
+2007-02-16 13:01  we7u
+
+	* INSTALL: Grammar error.  Fixed.
+
+2007-02-16 12:22  gstueve
+
+	* src/main.c: Fixed [ 1553641 ] Zoom Error (Integer Math?).
+	  Increment by 1 for 10% zoom-out when less than zoom level 10.
+
+2007-02-16 11:48  we7u
+
+	* scripts/get-NWSdata: Updating the script to snag the
+	  latest-latest files.
+
+2007-02-16 11:48  we7u
+
+	* src/map_geo.c: Getting rid of a compiler warning having to do
+	  with the wrong size specified in an printf.
+
+2007-02-16 11:48  we7u
+
+	* INSTALL: Adding GraphicsMagick instructions.
+
+2007-02-16 09:05  we7u
+
+	* scripts/LSB-BUILD: Moving the defines for the REV and FILENAME
+	  near the top.  Deleting old xastir-lsb-*.bz2 files before we
+	  start so that we don't upload old files each time.
+
+2007-02-15 08:41  we7u
+
+	* README.Getting-Started: Adding a comment about how to test audio
+	  file playing from the command-line.
+
+2007-02-14 07:20  we7u
+
+	* src/maps.c: Adding more comments.  No code changes.
+
+2007-02-13 12:22  gstueve
+
+	* src/maps.c: Make sure all sides of the box are checked, not just
+	  three of them.  Also make sure if an alert is not on screen clear
+	  it off.
+
+2007-02-13 07:30  we7u
+
+	* src/interface_gui.c: Changing the defaults for new internet
+	  connections to: rotate.aprs.net, port 14580, filter "m/500",
+	  reconnect enabled.
+
+2007-02-13 05:21  gstueve
+
+	* scripts/fcc-get: Update script to retrieve Canadian callsign data
+	  from new location.  I had not gotten a new update from previous
+	  location since September, 2006.
+
+2007-02-09 22:52  we7u
+
+	* README.Getting-Started: Adding an entry for the new "Home" key
+	  function.
+
+2007-02-09 22:49  we7u
+
+	* src/main.c: The "Home" key now centers the map on your station's
+	  position.
+
+2007-02-09 19:31  we7u
+
+	* src/map_geo.c: Changing back to the original path for the
+	  Toposerver images.  The problem was fixed on findu's end.
+
+2007-02-09 19:04  we7u
+
+	* src/map_cache.c: Commenting out one assignment (not used) which
+	  causes a compiler warning on some systems.
+
+2007-02-09 18:24  we7u
+
+	* Davis/README: Fixing an errant path in the instructions.
+
+2007-02-08 13:02  we7u
+
+	* src/map_geo.c: Hopefully a tweak that will help make online
+	  Toporama maps work again in the future.  Have to wait for Gerry
+	  to look at the server configuration before we'll know for sure.
+
+2007-02-06 12:30  we7u
+
+	* src/maps.c: Casting some long int results to int's.
+
+2007-02-06 08:24  we7u
+
+	* src/maps.c: A fix for the UTM/MGRS major grid lines not
+	  appearing.
+
+2007-02-06 06:55  we7u
+
+	* scripts/inf2geo.pl: Updating the script to use GraphicsMagick's
+	  "gm" program.  If not found, try ImageMagick's "identify"
+	  program.  If that not found, output an error message suggesting
+	  that one or the other be installed.
+
+2007-02-06 06:14  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing "MGRS"
+	  label to "MGRS2".  When it was implemented they were calling the
+	  two available ones "MGRS-Old" and "MGRS-New".  Now "MGRS-New" is
+	  called "MGRS2" and there's talk of an "MGRS3" soon...
+
+2007-01-27 10:41  tvrusso
+
+	* configure.ac: re-enable check for the X Printing Extension
+	  library.  Apparently this is needed by libXm and some systems do
+	  not properly bring in the indirect dependence through the dynamic
+	  loader.
+
+	  It would probably be better to detect that condition than just
+	  blindly checking for Xp (which we don't use).
+
+	  Regardless, it should never be necessary to install development
+	  headers for libXp just to build xastir, which was what one user
+	  was confused about and which led me to remove the check in the
+	  first place.
+
+2007-01-24 13:19  tvrusso
+
+	* configure.ac: Remove probe for the X Printing Extension library.
+
+	  Xastir doesn't use it, and there's no point probing for it.
+
+	  Someone was confused into thinking they needed to install it on
+	  Ubuntu 6.10 because configure said it couldn't find the library.
+	  They don't, coz we don't use it.
+
+2007-01-16 07:15  we7u
+
+	* scripts/LSB-BUILD: We now remove /opt/Xastir/* during the build
+	  so that we get a clean tar file, plus dates have been added to
+	  the filename.
+
+2007-01-13 19:57  we7u
+
+	* src/messages_gui.c: We now check whether Lesstif is compiled in
+	  and skip doing the dynamic widget thing on the Send Message
+	  dialog if so.
+
+2007-01-12 11:52  we7u
+
+	* src/messages_gui.c: Another LSB/Lesstif tweak, plus making sure
+	  we fill in the history on Send Message dialogs brought up through
+	  the new "Show Pending Messages" menu entry.
+
+2007-01-12 10:39  we7u
+
+	* src/maps.c: Changing strcasestr to strstr for Cygwin
+	  compatibility.  We don't really need case-insensitive matching
+	  there anyway.
+
+2007-01-12 09:13  we7u
+
+	* acinclude.m4: A fix for the GraphicsMagick/ImageMagick problem
+	  where GM is not on the system but Xastir tries to compile with
+	  it.
+
+2007-01-12 08:49  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/messages.h,
+	  src/messages_gui.c: Adding a "Show Pending Messages" menu option
+	  to the Message menu.	This one looks through the outgoing queue
+	  and brings up a Send Message dialog for each current QSO.
+
+2007-01-09 09:33  we7u
+
+	* src/messages_gui.c: Another couple of tweaks to keep Lesstif from
+	  segfaulting with the LSB compile.
+
+2007-01-08 13:47  we7u
+
+	* src/xa_config.c: Updated some comments.  No code changes.
+
+2007-01-08 13:21  we7u
+
+	* src/messages_gui.c: Fixes to prevent segfaults with LSB-Xastir.
+	  It appears that Lesstif cannot currently handle removing/adding
+	  widgets to an already-realized dialog without segfaulting.  Here
+	  we stick with the default one-long-input-field if we're compiling
+	  for LSB.
+
+2007-01-05 12:20  we7u
+
+	* src/db.c: Moved the code which _only_ depends on
+	  search_station_name() higher in the Station_data() function so
+	  that the dialog doesn't get drawn if not needed.
+
+2007-01-05 12:00  we7u
+
+	* scripts/LSB-BUILD-ALL: Switching back to Lesstif-0.95.0 as 0.94.4
+	  didn't improve things.
+
+2007-01-05 11:52  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/maps.c: Fixing the print
+	  properties dialog so that it only comes up if "gv" is detected.
+	  Getting rid of gv-specific options on the command-line when "gv"
+	  is not being used as a print-previewer.  Adding a couple of
+	  strings to the language files.
+
+2007-01-04 12:28  we7u
+
+	* scripts/LSB-BUILD-ALL: Changing some comments.  No code changes.
+
+2007-01-04 10:12  we7u
+
+	* scripts/LSB-BUILD-ALL: Switching from Lesstif-0.95.0 to 0.94.4
+	  for a while to see if the resulting binary is more stable.
+
+2007-01-03 11:38  we7u
+
+	* symbols/Makefile.am, symbols/symbols.dat, src/rtree/Makefile.am,
+	  src/rtree/card.c, src/rtree/card.h, src/rtree/gammavol.c,
+	  src/rtree/index.c, src/rtree/index.h, src/rtree/node.c,
+	  src/rtree/rect.c, src/rtree/sphvol.c, src/rtree/split_l.c,
+	  src/rtree/split_l.h, src/rtree/split_q.c, src/rtree/split_q.h,
+	  src/Makefile.am, src/alert.c, src/alert.h, src/awk.c, src/awk.h,
+	  src/bulletin_gui.c, src/bulletin_gui.h, src/color.c, src/color.h,
+	  src/database.h, src/datum.c, src/datum.h, src/db.c, src/dbfawk.c,
+	  src/dbfawk.h, src/draw_symbols.c, src/draw_symbols.h,
+	  src/fcc_data.c, src/fcc_data.h, src/festival.c, src/festival.h,
+	  src/geo-client.c, src/geo-find.c, src/geo.h, src/geocoder_gui.c,
+	  src/gps.c, src/gps.h, src/hashtable.c, src/hashtable.h,
+	  src/hashtable_itr.c, src/hashtable_itr.h,
+	  src/hashtable_private.h, src/hostname.c, src/hostname.h,
+	  src/igate.c, src/igate.h, src/interface.c, src/interface.h,
+	  src/interface_gui.c, src/io-common.c, src/io-mmap.c, src/io.h,
+	  src/lang.c, src/lang.h, src/leak_detection.h, src/list_gui.c,
+	  src/list_gui.h, src/locate_gui.c, src/location.c,
+	  src/location_gui.c, src/macspeech.c, src/main.c, src/main.h,
+	  src/map_WMS.c, src/map_cache.c, src/map_cache.h, src/map_dos.c,
+	  src/map_gdal.c, src/map_geo.c, src/map_gnis.c, src/map_pdb.c,
+	  src/map_shp.c, src/map_tif.c, src/map_tiger.c, src/maps.c,
+	  src/maps.h, src/messages.c, src/messages.h, src/messages_gui.c,
+	  src/objects.c, src/objects.h, src/popup.h, src/popup_gui.c,
+	  src/rac_data.c, src/rac_data.h, src/rotated.c, src/rotated.h,
+	  src/rpl_malloc.c, src/rpl_malloc.h, src/shp_hash.c,
+	  src/shp_hash.h, src/snprintf.c, src/snprintf.h, src/sound.c,
+	  src/symbols.h, src/testawk.c, src/track_gui.c, src/track_gui.h,
+	  src/util.c, src/util.h, src/view_message_gui.c, src/wx.c,
+	  src/wx.h, src/wx_gui.c, src/x_spider.c, src/x_spider.h,
+	  src/xa_config.c, src/xa_config.h, src/xastir.h,
+	  src/xastir_udp_client.c, src/shapelib/Makefile.am,
+	  src/shapelib/contrib/Makefile.am, config/24kgrid.dbfawk,
+	  config/Makefile.am, config/gps_wpt.dbfawk,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, config/nwsc_ddmmyy.dbfawk,
+	  config/nwsmzddmmyy.dbfawk, config/nwsmzoddmmyy.dbfawk,
+	  config/nwsozddmmyy.dbfawk, config/nwsw_ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/nwszoddmmyy.dbfawk,
+	  config/predefined_EVENT.sys, config/predefined_SAR.sys,
+	  config/tgr2shp.dbfawk, config/tgr2shppoly.dbfawk,
+	  config/tgrcty.dbfawk, config/tgrkgl.dbfawk, config/tgrlk.dbfawk,
+	  config/tgrlpt.dbfawk, config/tgrlpy.dbfawk,
+	  config/tgrplc00.dbfawk, config/tgrwat.dbfawk,
+	  config/tnc-startup.aea, config/tnc-startup.d700,
+	  config/tnc-startup.kam, config/tnc-startup.kpc2,
+	  config/tnc-startup.kpc3, config/tnc-startup.paccomm,
+	  config/tnc-startup.pico, config/tnc-startup.sys,
+	  config/tnc-startup.thd7, config/tnc-startup.tnc2,
+	  config/tnc-startup.tnc2-ui, config/tnc-stop.d700,
+	  config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui, scripts/LSB-BUILD,
+	  scripts/LSB-BUILD-ALL, scripts/LSB-BUILD-CURL,
+	  scripts/LSB-BUILD-DB, scripts/LSB-BUILD-GDAL,
+	  scripts/LSB-BUILD-GRAPHICSMAGICK, scripts/LSB-BUILD-JASPER,
+	  scripts/LSB-BUILD-JPEG, scripts/LSB-BUILD-LESSTIF,
+	  scripts/LSB-BUILD-PCRE, scripts/LSB-BUILD-PNG,
+	  scripts/LSB-BUILD-ZLIB, scripts/Makefile.am,
+	  scripts/Xastir_tigerpoly.py, scripts/example_objects.log,
+	  scripts/fcc-get, scripts/get-NWSdata, scripts/get-gnis,
+	  scripts/get-maptools.sh, scripts/get_shapelib.sh,
+	  scripts/toporama250k.pl, scripts/toporama50k.pl,
+	  scripts/xastir-fixcfg.sh, scripts/xastir-migrate.sh, AUTHORS,
+	  DEBUG_LEVELS, FAQ, INSTALL, LICENSE, Makefile.am, NEWS, README,
+	  README.CVS, README.Contributing, README.Getting-Started,
+	  README.MAPS, README.win32, REGRESSION_TESTS, UPGRADE,
+	  acinclude.m4, bootstrap.sh, changes.txt, configure.ac,
+	  install-xastir, update-xastir, xastir.1, Davis/Makefile.am,
+	  Davis/README, Davis/bootstrap.sh, Davis/configure.ac,
+	  Davis/src/Makefile.am, Davis/src/db2APRS.c, Davis/src/defs.h,
+	  LaCrosse/Makefile.am, LaCrosse/README, LaCrosse/bootstrap.sh,
+	  LaCrosse/configure.ac, LaCrosse/src/Makefile.am,
+	  LaCrosse/src/defs.h, LaCrosse/src/open2300db2APRS.c,
+	  callpass/Makefile.am, callpass/callpass.c, help/Makefile.am,
+	  help/help-Dutch.dat, help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, m4/Makefile.am:
+	  Updating Copyright info.
+
+2006-12-29 18:35  we7u
+
+	* src/maps.c: Moving a new variable declaration above statements in
+	  the function.
+
+2006-12-29 10:57  we7u
+
+	* src/maps.c: Moving many of the error messages to pop-up dialogs
+	  for the user-instigated print and print preview functions.  We
+	  also now allow a previewer other than "gv" to be used, although
+	  we're still passing gv-specific parameters to it (something more
+	  to fix).
+
+2006-12-29 10:10  we7u
+
+	* src/: maps.c, xa_config.c: Added #ifdef's for GV_PATH and
+	  LPR_PATH so that we compile ok on systems which don't have these
+	  two utilities.
+
+2006-12-28 23:27  we7u
+
+	* src/maps.c: More changes to printing.  Printing direct should be
+	  functional now.
+
+2006-12-28 22:37  we7u
+
+	* src/: maps.c, maps.h, xa_config.c: Revising the new printing code
+	  a bit more.  Now saves/restores the printer and previewer paths
+	  from file plus allows the user to change them.  More to do yet.
+
+2006-12-28 16:14  we7u
+
+	* src/: main.c, maps.c, maps.h: A start towards having a separate
+	  dialog for printing or print previewing/printing.  Not complete
+	  yet, but shows the direction I'm heading.
+
+2006-12-20 18:51  we7u
+
+	* acinclude.m4: Removing the libdb-5.0 options.
+
+2006-12-20 16:04  we7u
+
+	* acinclude.m4: Fixing the variable save/restore code for the
+	  GraphicsMagick and ImageMagick tests.
+
+2006-12-19 22:54  we7u
+
+	* scripts/get-maptools.sh: Adding checks for "wget", "gtar",
+	  "bsdtar", "tar", and "gunzip".  The script will attempt to
+	  configure to the set of utilities that are available.  If the
+	  proper utilities cannot be found the script will exit before
+	  downloading any files.
+
+2006-12-19 17:38  we7u
+
+	* scripts/get-maptools.sh: Searching for GNU tar before continuing
+	  with the script.
+
+2006-12-19 13:45  tvrusso
+
+	* src/map_shp.c: Remove unused variable to silence warnings.
+
+2006-12-19 13:39  tvrusso
+
+	* src/: main.c, map_shp.c, util.c, util.h: A tiny addition: make
+	  sure we always write out a valid ".prj" file to go with any of
+	  the shapefiles we create (currently, that's GPS downloads and
+	  saved APRS tracks).
+
+	  Doing so makes sure that tools other than Xastir that use the
+	  .prj file to determine the coordinate system of a shapefile will
+	  know what's in there.  This includes OGR's projection
+	  transformation tools, the QGIS GIS data viewer, and other GIS
+	  software such as GRASS or (ugh) ESRI products.  It is a cardinal
+	  sin to create GIS data that doesn't tell you what coordinate
+	  system it's in.
+
+	  Strike one dark stain from our souls.
+
+2006-12-18 23:31  tvrusso
+
+	* configure.ac: Switch default for rtree from no to yes.  It will
+	  now build as long as shapefile support is building, unless
+	  explicitly disabled.
+
+	  Disabling rtree now requires "--without-rtree".
+
+2006-12-18 13:09  we7u
+
+	* xastir.spec.in: Forcing ImageMagick over GraphicsMagick, as that
+	  is what is supplied with SuSE.  Also enabling rtree.
+
+2006-12-18 13:09  we7u
+
+	* xastir-min.spec.in: Forcing ImageMagick over GraphicsMagick for
+	  this package, as that's what is supplied with SuSE.
+
+2006-12-18 11:45  we7u
+
+	* acinclude.m4: Removing "/opt/lib" and "/opt/bin" for OSX search
+	  paths as these are not used by DarwinPorts/MacPorts.
+
+2006-12-18 11:35  we7u
+
+	* acinclude.m4: Simplifying the ImageMagick and GraphicsMagick
+	  tests, but adding extra search paths when configuring on OSX.
+	  Adding more libdb paths to the search paths for that library.
+
+2006-12-18 11:30  we7u
+
+	* configure.ac: Commenting out some warnings regarding ImageMagick
+	  and GraphicsMagick: This info is self-evident in the configure
+	  output now.
+
+2006-12-16 22:55  we7u
+
+	* scripts/get-maptools.sh: Taking out the hard-coded path to "tar".
+
+2006-12-15 12:56  we7u
+
+	* acinclude.m4: Adding searches for ImageMagick and GraphicsMagick
+	  in "/opt/local/bin" (OSX DarwinPorts).
+
+2006-12-15 12:53  we7u
+
+	* configure.ac: Correcting the GM/IM logic, adding comments.
+
+2006-12-15 10:32  tvrusso
+
+	* config/Makefile.am, config/stored_track.dbfawk, src/map_shp.c:
+	  Add a Label field to the dbf file created by the "Store Track"
+	  feature when shapelib is available.  Add a dbfawk file so that
+	  stored tracks can be rendered properly even if they aren't in the
+	  GPS directory.  Users can customize presentation of the stored
+	  track by copying the global dbfawk file to the directory with the
+	  shapefile, giving it the same basename as the shapefile, and
+	  tweaking it as needed.
+
+	  This should allow more convenient use of the maps created by
+	  storing tracks than the method that based rendering on the file
+	  name and directory.
+
+2006-12-15 09:43  we7u
+
+	* src/main.c: Reversing the order of the
+	  HAVE_GRAPHICSMAGICK/HAVE_IMAGEMAGICK #ifdef's.
+
+2006-12-15 08:06  we7u
+
+	* acinclude.m4: Reformatting a couple of lines.  No code changes.
+
+2006-12-14 22:02  tvrusso
+
+	* src/map_shp.c: Fix of my previous fix to the GPS vs. DBFAWK
+	  issue.  Somehow I managed to get it to ignore the fact that the
+	  file was in the GPS directory even when there *WAS* no dbfawk
+	  file.  The problem was that I tested for the non-nullness of
+	  "sig_info" after sig_info was filled in with a default
+	  signature's pointer.	Needed to put the test before that default
+	  case.
+
+2006-12-14 13:22  we7u
+
+	* configure.ac: Giving up for now on skipping the wget tests if
+	  libcurl is found.  Also moved "rtree" out of the experimental
+	  category, putting it up with the other regular options (above the
+	  dashed line in the summary).
+
+2006-12-14 12:17  we7u
+
+	* scripts/LSB-BUILD: Added a comment.
+
+2006-12-14 12:17  we7u
+
+	* acinclude.m4, configure.ac: Removing the tests for "cat" and
+	  "cp".  Tweaking the "wget" code a bit more (but still not skipped
+	  if libcurl is found first).
+
+2006-12-14 12:15  we7u
+
+	* src/: main.c, objects.c: Using the new copy_file() function
+	  instead of /bin/cp.
+
+2006-12-14 12:14  we7u
+
+	* src/: util.c, util.h: Added copy_file() function written by Adam
+	  Hahn, AI4QB, and contributed to the public domain.  We've
+	  modified it from his initial code so any bugs are our fault.
+
+2006-12-14 09:06  we7u
+
+	* acinclude.m4: Commenting out the code which checks for the "cat"
+	  command.  We don't use it anywhere in our code.
+
+2006-12-13 21:34  we7u
+
+	* acinclude.m4: Fixing some errors I introduced with the last
+	  commit.
+
+2006-12-13 21:02  we7u
+
+	* acinclude.m4: Improvements in the ImageMagick and GraphicsMagick
+	  detection.
+
+2006-12-12 22:50  tvrusso
+
+	* src/: main.c, map_shp.c: Make DBFAWK trump the gps_flag.
+
+	  This means that if a file is in the GPS directory and there is a
+	  DBFAWK file to go with it, the DBFAWK file controls the
+	  rendering.  It is still the case that if there is NO dbfawk file,
+	  or if DBFAWK is not enabled, the hard-coded GPS stuff (i.e. fixed
+	  width and line style, color taken from file name) is used.
+
+	  Also, change the dbfawk file created upon GPS download to match
+	  the style that the hard-coded GPS stuff would use.
+
+2006-12-12 22:46  we7u
+
+	* acinclude.m4, configure.ac: A few tweaks to the
+	  GraphicsMagick/ImageMagick tests.
+
+2006-12-12 19:06  we7u
+
+	* acinclude.m4, configure.ac, src/objects.c, src/xa_config.c,
+	  src/xastir.h, src/maps.h, src/maps.c, src/main.c, src/map_WMS.c,
+	  src/map_geo.c, src/map_tiger.c: Changes to allow using
+	  GraphicsMagick library and "gm convert" in place of the
+	  ImageMagick library and "convert".  Xastir will now prefer
+	  GraphicsMagick over ImageMagick if both are present on the
+	  system.
+
+2006-12-12 09:57  we7u
+
+	* scripts/: LSB-BUILD-ALL, LSB-BUILD-CURL, LSB-BUILD-DB,
+	  LSB-BUILD-GDAL, LSB-BUILD-GRAPHICSMAGICK, LSB-BUILD-JASPER,
+	  LSB-BUILD-JPEG, LSB-BUILD-LESSTIF, LSB-BUILD-PCRE, LSB-BUILD-PNG,
+	  LSB-BUILD-ZLIB: Updating some comments.
+
+2006-12-12 08:38  we7u
+
+	* scripts/LSB-BUILD: Enabling the Festival client to be compiled
+	  into LSB.  This has a couple of small downsides:  1) The user
+	  will get a "cannot connect to Festival" message on start up if
+	  they haven't installed/run the festival daemon, and 2) If
+	  anything else is running on localhost TCP port 1314 Xastir may
+	  try to talk to it.  The upside is that installing/running a
+	  Festival daemon will work with the LSB binary to produce speech.
+
+2006-12-12 08:36  we7u
+
+	* acinclude.m4: Removing define for FESTIVAL_PATH.  We don't use
+	  this in our code, plus if we chose to later it'd make another
+	  external dependency that'd need to be solved for the LSB
+	  distribution.  I believe this was originally added in case we
+	  wished to call the festival binary directly instead of doing a
+	  TCP connection to the festival daemon on port 1314.
+
+2006-12-12 07:49  we7u
+
+	* README.win32, acinclude.m4, src/wx_gui.c: Getting rid of our
+	  dependence on the "/usr/bin/finger" external executable.  It's
+	  been replaced by our own TCP/IP finger code.	This is used for
+	  fetching the NOAA weather text from "wxsvr.net".
+
+2006-12-12 06:35  we7u
+
+	* src/db.c: Comment correction.
+
+2006-12-11 12:39  we7u
+
+	* scripts/LSB-BUILD: Cleaning up the lsbappchk calls.
+
+2006-12-11 12:38  we7u
+
+	* LICENSE: Minor changes to comments.
+
+2006-12-11 09:22  we7u
+
+	* scripts/LSB-BUILD: A minor change to the flags for lsbappchk.
+
+2006-12-10 20:19  tvrusso
+
+	* src/main.c: Change the "display_level" value in the stuff output
+	  as a dbfawk file for downloaded gps tracks.
+
+	  The value that was there was absurdly low.
+
+2006-12-08 21:02  we7u
+
+	* scripts/LSB-BUILD-XPM: We don't appear to need a separate libXpm
+	  so deleting the build script for it.
+
+2006-12-08 21:00  we7u
+
+	* scripts/LSB-BUILD-ALL: Removing the libXpm build as we're picking
+	  it up automatically from somewhere else now that we've enabled
+	  the header files for it.
+
+2006-12-08 20:56  we7u
+
+	* LICENSE: Removing libXpm license as we don't appear to need to
+	  include a separate libXpm anyway.  We're already picking it up
+	  from LSB or from Motif or something.
+
+2006-12-08 13:48  we7u
+
+	* scripts/LSB-BUILD-ALL: Putting the XPM build one step later.
+
+2006-12-08 13:16  we7u
+
+	* scripts/LSB-BUILD-ALL: Adding a comment about libXpm.
+
+2006-12-08 13:14  we7u
+
+	* scripts/LSB-BUILD-ALL: Adding libXpm build to the script.
+
+2006-12-08 13:12  we7u
+
+	* scripts/LSB-BUILD-XPM: An LSB build script for libXpm.
+
+2006-12-08 13:11  we7u
+
+	* scripts/LSB-BUILD: Adding libXpm instructions for the LSB build.
+
+2006-12-08 13:10  we7u
+
+	* configure.ac: Adding libXpm to the LSB build.  Needed for
+	  Snapshots and Printing.
+
+2006-12-08 13:09  we7u
+
+	* LICENSE: Adding the license for libXpm.
+
+2006-12-08 12:16  we7u
+
+	* scripts/LSB-BUILD: Copying "gm" from GraphicsMagick into our LSB
+	  build.
+
+2006-12-08 12:15  we7u
+
+	* scripts/LSB-BUILD-GRAPHICSMAGICK: Installing "gm" utility as well
+	  (that's where we can get to "convert" in GraphicsMagick).
+
+2006-12-08 12:14  we7u
+
+	* src/main.c: Restarting the Xastir binary no matter where it was
+	  configured to be installed.
+
+2006-12-08 12:13  we7u
+
+	* configure.ac: Setting defines for Xastir paths.  We can use them
+	  in the C-code to do things like restart ourselves.
+
+2006-12-08 12:12  we7u
+
+	* acinclude.m4: Setting up to be able to do Printing and Snapshots
+	  with the LSB version.
+
+2006-12-08 12:12  we7u
+
+	* INSTALL: Documenting the depending on Xpm for Printing and
+	  Snapshots.
+
+2006-12-08 08:04  we7u
+
+	* src/wx_gui.c: Fixing up the finger code for fetching NOAA weather
+	  alert text.  We now pipe STDERR to STDOUT so that we can see any
+	  errors in the dialog.  The syntax is shell-specific so we perhaps
+	  need a better way to do it.  The syntax used should work for SH
+	  or BASH shells, and I think Korn shell, but not for CSH?  We also
+	  now use HAVE_FINGER defines to enable/disable the actual finger
+	  call in the code.
+
+2006-12-08 06:58  we7u
+
+	* LICENSE: Changing some comments.
+
+2006-12-08 06:45  we7u
+
+	* src/wx_gui.c: Using the new FINGER_PATH that we now put into
+	  config.h via acinclude.m4.
+
+2006-12-08 06:44  we7u
+
+	* acinclude.m4: Adding a search for the "finger" binary.
+
+2006-12-07 12:22  we7u
+
+	* xastir-lsb.spec.in, scripts/LSB-BUILD: Changing install location
+	  for LSB-like (non-certified) version from /opt/lsb-xastir/ to
+	  /opt/Xastir/
+
+2006-12-07 12:09  we7u
+
+	* xastir-lsb.spec.in: Changing the install location from
+	  /opt/lsb-xastir to /opt/xastir.  We don't have (and probably will
+	  never request/pay for) LSB compliance.
+
+2006-12-07 11:58  we7u
+
+	* Makefile.am, xastir-lsb.spec.in: Adding more docs to the install
+	  locations.
+
+2006-12-07 11:49  we7u
+
+	* scripts/: LSB-BUILD-ALL, LSB-BUILD-CURL, LSB-BUILD-DB,
+	  LSB-BUILD-GDAL, LSB-BUILD-GRAPHICSMAGICK, LSB-BUILD-JASPER,
+	  LSB-BUILD-JPEG, LSB-BUILD-LESSTIF, LSB-BUILD-PCRE, LSB-BUILD-PNG,
+	  LSB-BUILD-ZLIB: Adding a comment which states we do NOT have LSB
+	  compliance.
+
+2006-12-07 11:48  we7u
+
+	* xastir-lsb.spec.in, scripts/LSB-BUILD: Adding a comment which
+	  states that we do NOT have LSB-compliance.
+
+2006-12-07 11:47  we7u
+
+	* LICENSE: Documenting the licenses for the optional libraries that
+	  we might distribute with an Xastir statically-linked binary.
+
+2006-12-07 11:47  we7u
+
+	* COPYING.LIB.LESSTIF: Adding the license file for Lesstif, for the
+	  case where we're distributing an Xastir statically-linked binary.
+
+2006-12-07 09:33  we7u
+
+	* configure.ac, scripts/LSB-BUILD, scripts/LSB-BUILD-ALL,
+	  scripts/LSB-BUILD-CURL, scripts/LSB-BUILD-DB,
+	  scripts/LSB-BUILD-GRAPHICSMAGICK, scripts/LSB-BUILD-JASPER,
+	  scripts/LSB-BUILD-JPEG, scripts/LSB-BUILD-LESSTIF,
+	  scripts/LSB-BUILD-PCRE, scripts/LSB-BUILD-PNG,
+	  scripts/LSB-BUILD-ZLIB: More changes to the LSB Xastir build and
+	  the LSB build for the optional libraries.  We now install the
+	  libraries in /opt/lsb-tmp/ and then compile Xastir statically
+	  against the libraries there, via symlinks from the
+	  /opt/lsb/include/ and /opt/lsb/lib/ directories.
+
+2006-12-06 11:46  we7u
+
+	* scripts/: LSB-BUILD, LSB-BUILD-CURL, LSB-BUILD-DB,
+	  LSB-BUILD-GDAL, LSB-BUILD-GRAPHICSMAGICK, LSB-BUILD-JASPER,
+	  LSB-BUILD-JPEG, LSB-BUILD-LESSTIF, LSB-BUILD-PCRE, LSB-BUILD-PNG,
+	  LSB-BUILD-ZLIB: Minor tweaks for LSB compiling.
+
+2006-12-06 11:45  we7u
+
+	* scripts/LSB-BUILD-ALL: An one-stop-shopping script to build the
+	  optional libraries under LSB before we compile Xastir under LSB.
+
+2006-12-05 12:45  we7u
+
+	* src/main.c: Correcting one comment.
+
+2006-12-05 06:43  we7u
+
+	* scripts/LSB-BUILD: Removing the gdal symlinks from the comments
+	  as we've handled them in configure.ac/acinclude.m4 instead.
+	  Xastir will look for gdal in /opt/lsb-gdal/lib and
+	  /opt/lsb-gdal/include directories.
+
+2006-12-05 06:42  we7u
+
+	* configure.ac: Removing "(Experimental)" from the LSB summary
+	  line.  Changing "lsb" to "LSB" which is more proper.
+
+2006-12-04 11:52  we7u
+
+	* scripts/LSB-BUILD-GDAL: Adding a commented-out option.  No effect
+	  to the code.
+
+2006-12-04 09:51  tvrusso
+
+	* src/shapelib/contrib/: doc/shpproj.txt, tests/shpproj.sh: Just
+	  noticed that I never cvs added these two files from the shapelib
+	  distribution.  Since we are currently distributing the whole
+	  shapelib distribution with unmodified license, it is necessary to
+	  include all of the whole shapelib distribution.
+
+2006-12-04 09:30  we7u
+
+	* scripts/LSB-BUILD-GDAL: Initial attempt to get GDAL compiled
+	  under LSB.  Not functional yet.
+
+2006-12-04 09:29  we7u
+
+	* scripts/LSB-BUILD: Added a couple of steps to create the .tar.bz2
+	  file and transfer it to the download site.
+
+2006-12-04 08:27  we7u
+
+	* src/util.c: Enabling CURLOPT_NOSIGNAL option to libcurl if the
+	  libcurl version supports it.	This prevents segfaults for the
+	  case where we get a DNS timeout when initiating a libcurl
+	  transfer.
+
+2006-12-03 14:01  we7u
+
+	* scripts/LSB-BUILD: Changes in comments for GDAL compiling under
+	  LSB.	GDAL is not working yet though for LSB.
+
+2006-12-03 13:58  we7u
+
+	* configure.ac: Enabling GDAL library for LSB compile.
+
+2006-12-03 13:54  we7u
+
+	* src/util.c: Enabling another curl option if compiling w/LSB.
+
+2006-12-03 13:50  we7u
+
+	* src/track_gui.c: Adding a comment.
+
+2006-12-01 13:47  we7u
+
+	* configure.ac: Changing some of the text to GraphicsMagick when
+	  doing LSB compiles.
+
+2006-12-01 13:47  we7u
+
+	* USRadar.geo: Changing the black value to match the LSB
+	  GraphicsMagick.
+
+2006-12-01 13:38  we7u
+
+	* src/: map_geo.c, maps.c: Updating some messages to include
+	  GraphicsMagick.
+
+2006-12-01 13:27  we7u
+
+	* scripts/: LSB-BUILD-DB, LSB-BUILD: Adding Berkeley DB to the LSB
+	  build to enable map caching.
+
+2006-12-01 12:47  we7u
+
+	* scripts/LSB-BUILD-GRAPHICSMAGICK: Enabling PNG in the build.	It
+	  works now.
+
+2006-12-01 12:46  we7u
+
+	* scripts/LSB-BUILD: Updating the build comments.
+
+2006-12-01 12:21  we7u
+
+	* scripts/LSB-BUILD-JASPER: An LSB build script for the Jasper
+	  library, to give us jpeg-2000 support in GraphicsMagick.
+
+2006-12-01 12:20  we7u
+
+	* scripts/LSB-BUILD-GRAPHICSMAGICK: Making jpeg images work for us.
+
+2006-12-01 11:34  we7u
+
+	* scripts/LSB-BUILD: Updating some comments.
+
+2006-12-01 11:32  we7u
+
+	* configure.ac: GrahicsMagick-LSB changes.
+
+2006-12-01 09:49  we7u
+
+	* scripts/LSB-BUILD-GRAPHICSMAGICK: A build script for
+	  GraphicsMagick under LSB.
+
+2006-12-01 09:48  we7u
+
+	* scripts/LSB-BUILD: Adding GrahicsMagick support.
+
+2006-12-01 07:49  we7u
+
+	* scripts/LSB-BUILD-PNG: Adding an LSB build script for the libpng
+	  library, needed for GraphicsMagick or ImageMagick.
+
+2006-11-30 21:05  we7u
+
+	* scripts/LSB-BUILD-CURL: Adding an LSB build script for libcurl.
+
+2006-11-30 21:03  we7u
+
+	* scripts/LSB-BUILD: Updating the notes.
+
+2006-11-30 21:01  we7u
+
+	* configure.ac: Enabling libcurl for LSB.
+
+2006-11-30 13:20  we7u
+
+	* scripts/LSB-BUILD: Updating the comments.
+
+2006-11-30 13:15  we7u
+
+	* scripts/LSB-BUILD: Adding pcre and dbfawk to the LSB build
+	  script.
+
+2006-11-30 13:14  we7u
+
+	* scripts/LSB-BUILD-PCRE: An LSB build script for the PCRE library.
+
+2006-11-30 12:33  we7u
+
+	* scripts/LSB-BUILD: Adding some comments.
+
+2006-11-30 12:04  we7u
+
+	* scripts/LSB-BUILD-LESSTIF: Adding a commented out command which
+	  is useful to see what will be installed without actually
+	  installing anything.
+
+2006-11-30 12:04  we7u
+
+	* scripts/LSB-BUILD: Modifying build to include geotiff and proj
+	  support.
+
+2006-11-30 12:03  we7u
+
+	* scripts/: LSB-BUILD-JPEG, LSB-BUILD-ZLIB: Adding scripts to build
+	  libjpeg and libz under LSB.  Needed for geotiff support.
+
+2006-11-30 12:02  we7u
+
+	* configure.ac: LSB mods for geotiff.
+
+2006-11-30 09:26  we7u
+
+	* scripts/LSB-BUILD: Adding libproj to the mix.  It is
+	  LSB-compliant.
+
+2006-11-27 08:35  we7u
+
+	* scripts/LSB-BUILD: Adding rtree to the LSB build.
+
+2006-11-27 08:19  we7u
+
+	* scripts/LSB-BUILD-LESSTIF: Changes to comments.
+
+2006-11-27 08:18  we7u
+
+	* scripts/LSB-BUILD: Updating to match my current working copy of
+	  the file.
+
+2006-11-27 08:17  we7u
+
+	* xastir-lsb.spec.in: Updating to match my current copy.
+
+2006-11-27 08:06  we7u
+
+	* src/map_geo.c: Adding an LF to one warning message.
+
+2006-11-24 11:57  we7u
+
+	* configure.ac: Adding the RPM spec file for LSB.
+
+2006-11-24 11:51  we7u
+
+	* xastir-lsb.spec.in: Inital attempt at an RPM spec file for LSB.
+	  Not complete yet.
+
+2006-11-24 11:46  we7u
+
+	* xastir-min.spec.in, xastir.spec.in: Correcting the "Source" line
+	  in the header so the version number comes out right.
+
+2006-11-22 11:48  we7u
+
+	* scripts/LSB-BUILD-LESSTIF: Updating comments.
+
+2006-11-22 11:46  we7u
+
+	* scripts/LSB-BUILD: Stripping the executables created, adding some
+	  more comments.
+
+2006-11-22 11:30  we7u
+
+	* scripts/LSB-BUILD-LESSTIF: Updating the notes at the top to show
+	  the SUCCESSFUL way of compiling Lesstif against LSB.
+
+2006-11-22 11:27  we7u
+
+	* scripts/LSB-BUILD: Updated to show latest LSB build method.
+
+2006-11-21 07:52  we7u
+
+	* scripts/LSB-BUILD: Updating the comments.
+
+2006-11-21 07:35  we7u
+
+	* scripts/LSB-BUILD-LESSTIF: Adding more comments at the top.
+
+2006-11-20 15:37  we7u
+
+	* scripts/LSB-BUILD-LESSTIF: Adding a comment, commenting out a
+	  currently-unused line, and enabling shared libs to be created.
+
+2006-11-20 15:33  we7u
+
+	* scripts/LSB-BUILD: Adding a comment plus commenting out a
+	  currently-unused line.
+
+2006-11-20 15:17  we7u
+
+	* configure.ac: Another LSB mod.
+
+2006-11-20 14:52  we7u
+
+	* scripts/: LSB-BUILD, LSB-BUILD-LESSTIF: Preliminary scripts for
+	  building LSB-compatible Lesstif and Xastir.  They're not fully
+	  functional yet.
+
+2006-11-20 14:50  we7u
+
+	* scripts/fcc-get: Fixing the RCS tag.
+
+2006-11-20 10:31  we7u
+
+	* src/shapelib/Makefile.am: Updating the Copyright year.
+
+2006-11-20 10:24  we7u
+
+	* scripts/fcc-get: Changing the RAC portion of the script to match
+	  their current server configuration.
+
+2006-11-19 14:05  tvrusso
+
+	* README.win32: Another tiny update to README.win32 to bring it
+	  up-to-date with the reality of today's cygwin and sync with the
+	  Wiki HowTo:Windows page.
+
+2006-11-19 14:00  tvrusso
+
+	* README.win32: Fix up another little issue with this document.
+
+	  I'm doing this piecemeal, because I'm finding things as I'm
+	  editing the same information on the Wiki, and want this file to
+	  be consistent with that.
+
+2006-11-19 13:56  tvrusso
+
+	* README.win32: Fix up a little error in the "building shapelib
+	  from source" section.  It referred to a "_reent" error when
+	  really it was about the error involving "__getreent".
+
+2006-11-19 13:34  tvrusso
+
+	* README.win32: Add note about preferring internal shapelib support
+	  unless the external is needed for something other than xastir.
+
+	  This should cut down on our "How do I get around this error
+	  message..." support questions from new Cygwin users.
+
+2006-11-17 07:45  kg4ijb
+
+	* ChangeLog: [no log message]
+
+2006-11-17 00:53  tvrusso
+
+	* scripts/get-maptools.sh: Found yet another annoying issue with
+	  libgeotiff build on ubuntu (and probably anywhere where gcc 4 is
+	  used).
+
+	  The problem is that the official tarball has the modification
+	  times of configure.in newer than configure, and a makefile that
+	  regenerates configure whenever it's older than configure.in ---
+	  and then runs it with no arguments.  Since we need to run
+	  configure with some arguments, that completely messes everything
+	  up.
+
+	  Add a "touch configure" command to the commented-out part of the
+	  script that makes configure newer than configure.in and bypasses
+	  that part of the  Makefile.  A kludge upon a kludge upon a
+	  kludge.
+
+	  I missed this subtlety because when I finally tracked down the
+	  "ld -shared" issue, it was in a dirty directory -- one that had
+	  already had configure regenerated and which therefore no longer
+	  had the broken timestamps.
+
+2006-11-16 21:31  tvrusso
+
+	* scripts/get-maptools.sh: Add commented-out fix for GCC 4.x issues
+	  with libgeotiff.
+
+	  Not uncommenting them, because it might be wrong on some
+	  platforms that don't use GCC at all.
+
+2006-11-16 20:13  tvrusso
+
+	* scripts/get-maptools.sh: A number of small fixes to the
+	  get-maptools script:	 1) Make sure $XASTIR_TMP exists before
+	  trying to download files into it   2) Fix a typo (LDCONf_FILE vs.
+	  LDCONF_FILE)	 3) Update version of gdal to 1.3.2 (1.3.1 does not
+	  compile in recent GCC)   4) Build geotiff before gdal, since gdal
+	  will use the libgeotiff if it finds it.
+
+2006-11-16 09:12  we7u
+
+	* Makefile.am: Getting rid of the symlink I recently added which
+	  pointed from /usr/local/share/xastir/doc to
+	  /usr/local/doc/xastir.  Near as I can tell we're fairly well
+	  FHS-compliant now with Xastir.
+
+2006-11-15 12:11  we7u
+
+	* Makefile.am: Forcing the removal of the old
+	  $prefix/share/xastir/doc directory and creating a symlink to the
+	  new location.
+
+2006-11-15 11:49  we7u
+
+	* Makefile.am, xastir-min.spec.in, xastir.spec.in: Moving the doc
+	  files to an FHS-compliant directory.	For a user installing from
+	  sources they'll get installed in "/usr/local/share/doc/xastir/"
+	  instead of the old location of "/usr/local/share/xastir/doc".
+
+2006-11-15 08:45  we7u
+
+	* Makefile.am, xastir-min.spec.in, xastir.spec.in: Changing the man
+	  page directory from $prefix/man to $prefix/share/man, per FHS-2.3
+	  and LSB-3.1
+
+2006-11-15 07:50  we7u
+
+	* xastir-min.spec.in: Changing "--without-shapelib" to
+	  "--with-internal-shapelib" to take adantage of the new shapelib
+	  library we include with Xastir.
+
+2006-11-15 07:48  we7u
+
+	* .cvsignore: Adding two derived files back in.
+
+2006-11-15 07:47  we7u
+
+	* xastir-min.spec, xastir.spec: Put these files into CVS by
+	  mistake.  They are derived files.  Silly me.
+
+2006-11-15 07:08  we7u
+
+	* scripts/BUILDRPMS: Changing the "minimum" description to include
+	  building with internal Shapelib.
+
+2006-11-15 07:08  we7u
+
+	* .cvsignore: Updating for current list of files.
+
+2006-11-15 07:07  we7u
+
+	* xastir-min.spec, xastir.spec: Adding the spec files that I've
+	  been using.  I'm surprised that they weren't added before, but I
+	  had added them to my .cvsignore file and so didn't notice.
+
+2006-11-14 13:30  we7u
+
+	* src/shapelib/dbfopen.c: The last revision also commented out an
+	  unused variable that I forgot to mention in the cvs log.
+
+2006-11-14 13:28  we7u
+
+	* src/shapelib/: shpopen.c, shptree.c: Commenting out some
+	  variables that give off compiler warnings.
+
+2006-11-14 13:28  we7u
+
+	* src/shapelib/dbfopen.c: Casting a couple of variables to int's to
+	  get rid of compiler warnings.
+
+2006-11-14 12:58  we7u
+
+	* README.Getting-Started: Adding missing command-line options to
+	  the docs.
+
+2006-11-14 12:42  we7u
+
+	* src/xa_config.c: Changing some default settings, useful for
+	  first-time users of Xastir to see what more of the options might
+	  be plus give them a good operational starting point.
+
+2006-11-14 12:09  kg4ijb
+
+	* ChangeLog: [no log message]
+
+2006-11-14 11:52  we7u
+
+	* configure.ac: Fixing up the Shapelib config options.
+
+2006-11-14 11:52  we7u
+
+	* xastir.1: Updating the man page a bit.
+
+2006-11-14 08:28  we7u
+
+	* configure.ac: Changes to make it obvious in the configure output
+	  text and in Help->About that we're using the internal Shapelib.
+	  This change doesn't affect summary.log.
+
+2006-11-14 07:41  we7u
+
+	* src/main.c: Putting a newline in front of the Motif version
+	  string in Help->About.
+
+2006-11-14 00:19  tvrusso
+
+	* configure.ac: Fix the "-I" flag in CPPFLAGS when local shapelib
+	  is being built.
+
+	  As it was, the compiler would not find the local shapefil.h file
+	  unless you were building in the actual xastir source code
+	  directory, or if shapefil.h was already installed system-wide.
+
+	  Noticed this while attempting a fresh build on a brand new
+	  laptop, on which I'd decided to attempt the simplest possible
+	  build, with no shapelib installed.
+
+2006-11-13 11:46  we7u
+
+	* README.Getting-Started: Added notes about the private copy of
+	  Shapelib and when it might be used, the "wget" requirement for
+	  the get-NWSdata script, putting in a callsign when initially
+	  starting Xastir, and a list of various places to get Xastir help.
+
+2006-11-13 11:43  we7u
+
+	* README.win32: Mentioning the private Shapelib version and when it
+	  might be used.
+
+2006-11-13 11:43  we7u
+
+	* README.MAPS: Mentioning "wget" as a requirement for get-NWSdata.
+	  Mentioning the private install of Shapelib.
+
+2006-11-13 11:41  we7u
+
+	* INSTALL: Adding info about the alternate method of getting
+	  Shapefile support.
+
+2006-11-13 07:10  tvrusso
+
+	* README.Contributing: Fix up a mistake in the description of
+	  "build directories", and add a reference to that technique to an
+	  earlier section that advocates doing all the builds in the source
+	  directory.
+
+	  Build directories are such a powerful tool for developers, we
+	  should make sure we recommend it when talking about doing
+	  multiple builds.
+
+2006-11-13 06:56  tvrusso
+
+	* README.win32: Attach a date to qualify the meaning of "latest" in
+	  the ImageMagick section.
+
+2006-11-13 06:48  tvrusso
+
+	* src/Makefile.am: Add a testawk_LDADD line to src/Makefile.am so
+	  that this test program can link if shapelib is not installed.
+
+	  I have no idea why this didn't fail when I was testing the
+	  shapelib addition.
+
+2006-11-13 06:25  we7u
+
+	* README.win32: Updating the description for ImageMagick bug.
+
+2006-11-13 06:24  we7u
+
+	* src/: .cvsignore, shapelib/.cvsignore: Adding another couple of
+	  derived files to the .cvsignore file.
+
+2006-11-12 17:36  we7u
+
+	* src/main.c: Enabling default map on initial startup, plus if the
+	  callsign is "NOCALL", bring up the Configure->Station dialog.
+
+2006-11-12 17:26  we7u
+
+	* src/xa_config.c: Getting rid of many of the messages you get on
+	  startup when config file settings are missing.
+
+2006-11-11 16:26  tvrusso
+
+	* src/shapelib/contrib/Makefile.am: Add CVS revision information
+	  and copyright.
+
+2006-11-11 16:11  we7u
+
+	* README.MAPS: Adding attribution for the default map.
+
+2006-11-11 15:46  tvrusso
+
+	* configure.ac, src/shapelib/Makefile.am, src/shapelib/shprewind,
+	  src/shapelib/contrib/.cvsignore, src/shapelib/contrib/Makefile,
+	  src/shapelib/contrib/Makefile.am,
+	  src/shapelib/contrib/Makefile_orig: Add EXTRA_DIST and
+	  DIST_SUBDIRS lines so that the shapelib stuff is properly bundled
+	  when doing a "make dist" for release.
+
+	  The Makefile.am in the contrib directory does not actually build
+	  any of the contrib codes.  That's another step for another
+	  moment.  I just wanted to make sure that any make dist that is
+	  done is sure to bundle the entire shapelib directory in order to
+	  comply with the terms of the license.
+
+	  The "Makefile_orig" script in the shapelib/contrib directory
+	  could be used temporarily to build the shapelib tools.
+	  Ultimately, they could be built by the new makefile, but it's not
+	  really the goal of this exercise to do all that.  In fact, at
+	  some point it might be reasonable for xastir's shapelib directory
+	  to contain only the files needed for building the library, but
+	  that will probably require modifying it to be under GPL instead
+	  of LGPL.  That's just a matter of editing some license files, not
+	  any code.
+
+	  Also, removed the shprewind file from the shapelib directory.
+	  This is a linux binary that for some reason was in the shapelib
+	  source tarball I had.  It should never have been added to
+	  xastir's CVS repository.
+
+2006-11-11 15:01  we7u
+
+	* Makefile.am: Adding a default map to the distribution.
+
+2006-11-11 14:51  we7u
+
+	* worldhi.map: Adding a default map.  Map was created by Keith
+	  Sproul, WU2Z, and used with his permission.
+
+2006-11-10 13:49  tvrusso
+
+	* src/shapelib/.cvsignore: Add .cvsignore.
+
+2006-11-10 13:49  tvrusso
+
+	* src/shapelib/Makefile.in: CVS cleanup.
+
+2006-11-10 13:48  tvrusso
+
+	* configure.ac, src/Makefile.am, src/shapelib/ChangeLog,
+	  src/shapelib/LICENSE.LGPL, src/shapelib/Makefile.am,
+	  src/shapelib/Makefile.in, src/shapelib/Makefile_shapelib_orig,
+	  src/shapelib/README, src/shapelib/README.tree,
+	  src/shapelib/dbf_api.html, src/shapelib/dbfadd.c,
+	  src/shapelib/dbfcreate.c, src/shapelib/dbfdump.c,
+	  src/shapelib/dbfopen.c, src/shapelib/libtool,
+	  src/shapelib/makefile.vc, src/shapelib/makeshape.sh,
+	  src/shapelib/mkinstalldirs, src/shapelib/shapefil.h,
+	  src/shapelib/shapelib.def, src/shapelib/shapelib.html,
+	  src/shapelib/shp_api.html, src/shapelib/shpadd.c,
+	  src/shapelib/shpcreate.c, src/shapelib/shpdump.c,
+	  src/shapelib/shpopen.c, src/shapelib/shprewind,
+	  src/shapelib/shprewind.c, src/shapelib/shptest.c,
+	  src/shapelib/shptree.c, src/shapelib/shptreedump.c,
+	  src/shapelib/shputils.c, src/shapelib/stream1.out,
+	  src/shapelib/stream1.sh, src/shapelib/stream2.out,
+	  src/shapelib/stream2.sh, src/shapelib/stream3.out,
+	  src/shapelib/contrib/Makefile,
+	  src/shapelib/contrib/ShapeFileII.pas,
+	  src/shapelib/contrib/dbfcat.c, src/shapelib/contrib/dbfinfo.c,
+	  src/shapelib/contrib/makefile.vc, src/shapelib/contrib/my_nan.h,
+	  src/shapelib/contrib/shpcat.c, src/shapelib/contrib/shpcentrd.c,
+	  src/shapelib/contrib/shpdata.c, src/shapelib/contrib/shpdxf.c,
+	  src/shapelib/contrib/shpfix.c, src/shapelib/contrib/shpgeo.c,
+	  src/shapelib/contrib/shpgeo.h, src/shapelib/contrib/shpinfo.c,
+	  src/shapelib/contrib/shpproj.c, src/shapelib/contrib/shpwkb.c:
+	  Add shapelib as an internal library, and use it if we don't find
+	  an external one.
+
+	  Make a loud warning if we do so, because the result of this is
+	  that we'll have a bigger executable.
+
+	  This commit is bigger than it needs to be, because it includes
+	  all of shapelib, including the contrib directory.
+
+	  Added an automake-generated Makefile for this thing.
+
+	  Builds only a static library, and calls it "libshape.a" instead
+	  of "libshp.a" so that if we use ask to use the static one while
+	  there is also an external one installed, the linker doesn't pull
+	  in the shared library one unbidden.
+
+	  This stuff can be tested on a system with libshp installed by
+	  configuring with "--without-shapelib"
+
+	  I will be removing Makefile.in because it's not supposed to be in
+	  CVS.	My mistake.
+
+2006-11-09 14:34  kg4ijb
+
+	* ChangeLog: [no log message]
+
+2006-11-09 08:23  we7u
+
+	* src/xa_config.c: Changing the default window size on initial
+	  startup.  The minimum width/height are set up in
+	  main.c:create_appshell() anyway, so we can't reduce the window
+	  small enough to cause segfaults by doing this change.
+
+2006-11-09 08:21  we7u
+
+	* src/main.c: Changed one comment.  No code changes.
+
+2006-11-05 17:16  tvrusso
+
+	* README.win32: Add information about problems with Cygwin
+	  ImageMagick.	The notes in the README.win32 refer to "recent
+	  versions" of cygwin containing ImageMagick 5.5.7, which is very
+	  outdated.  Current versions of Cygwin come with 6.0.4, and there
+	  are real problems due to that version being linked with Display
+	  Postscript support --- X.org stopped supporting that, and now
+	  ImageMagick doesn't work on Cygwin unless you find a few DLLs off
+	  the net.
+
+	  The paragraph I added here points the user at an article that
+	  explains the issue and shows two workarounds (installing the DLLs
+	  or building ImageMagick from source code instead).
+
+2006-11-03 12:31  we7u
+
+	* src/util.c: Adding a diff by Tapio Sokura, which a few comment
+	  changes by me.  Thanks! This fixes the lower-case callsigns
+	  problem for internet paths.
+
+2006-11-02 10:34  we7u
+
+	* scripts/BUILDRPMS: Setting up for building RPM's for the current
+	  development version.
+
+2006-11-02 08:03  we7u
+
+	* configure.ac: Setting up for the next development source version
+	  number.
+
+2006-11-02 06:43  we7u
+
+	* configure.ac, scripts/BUILDRPMS, scripts/do_xastir_release_dev,
+	  scripts/do_xastir_release_stable: Setting up to do the 1.8.4
+	  release.
+
+2006-11-01 06:57  we7u
+
+	* config/language-German.sys: Updates by Rolf Bleher.  Thanks!
+
+2006-10-26 08:52  we7u
+
+	* Davis/: configure.ac, src/db2APRS.c, src/defs.h: Tweaks by Bruce
+	  Bennett:  "I fixed some issues brought out by the latest MySQL
+	  (5.0.x ver), added metric/english switch, rooted out some old
+	  bugs and made some improvement on debug messages."
+
+2006-10-26 06:50  we7u
+
+	* src/db.c: Fixing problems with Aloha circle units in multiple
+	  places.
+
+2006-10-25 08:16  we7u
+
+	* REGRESSION_TESTS: Lining up the line to match the rest.
+
+2006-10-24 11:03  we7u
+
+	* REGRESSION_TESTS: Adding another test which disables the
+	  /usr/include/magick/ directory before attempting a compile.  This
+	  disables ImageMagick.
+
+2006-10-24 11:02  we7u
+
+	* src/map_geo.c: Adding another two ifdef's so that the code will
+	  compile in the case that we have XPM support but no ImageMagick
+	  support.
+
+2006-10-11 14:39  we7u
+
+	* src/db.c: Another patch by Jesse, KF4HZU.  Thanks!
+
+2006-10-05 09:11  we7u
+
+	* src/db.c: Skipping any processing of lines from logfiles that
+	  begin with '#'.
+
+2006-10-05 08:29  we7u
+
+	* src/db.c: A fix for numeric overlays on base-91 packets by Jesse,
+	  KF4HZU.
+
+2006-10-05 07:46  we7u
+
+	* src/db.c: Some SKY bulletins came in that had "EMERGENCY" in the
+	  text.  This caused Xastir to try to process the packets twice on
+	  order to get a position first and then pop up the emergency
+	  dialogs.  Since there was no position in the packet this caused
+	  an infinite loop as Xastir passed the packet through the
+	  processing again and again.  The fix is to NOT send a packet
+	  through the processing again, which will make it necessary for
+	  Xastir to receive two EMERGENCY packets if a position is not
+	  known yet for the station, but it will at least not cause Xastir
+	  to get in an infinite loop.  We also skip storing any SKY packets
+	  now as they just take up memory and we never do anything further
+	  with the packets.
+
+2006-09-27 12:23  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding US National
+	  Grid designator to the MGRS label.  If in NAD83/WGS84 they are
+	  equivalent.
+
+2006-09-25 06:24  we7u
+
+	* src/main.c: A tweak by Dick Reichenbach, KC8OBZ, to split the
+	  status line into two lines when using a 640x480 display.  Thanks!
+
+2006-09-20 08:22  tvrusso
+
+	* src/interface.c: Add comments to show where it is necessary to
+	  fix data_out_ax25 so that it isn't confused by leading
+	  white-space in commands.
+
+	  No code changes.  The idea was to document what I know I need to
+	  do to fix the problem that Mike Fenske saw when the \r was added
+	  before MYCALL commands.  The quick fix was not to add the \r if
+	  sending to an AX25 port, but the clean fix would be to make
+	  data_out_ax25 not care about leading white space.
+
+2006-09-19 20:14  tvrusso
+
+	* src/interface.c: What might be a less intrusive way of
+	  introducing that extra carriage return into the MYCALL line.
+
+	  The code for AX25 ports tries to decode the mycall line, and that
+	  decoding was getting confused by the leading \r.  This quick
+	  "fix" simply checks to see if we're writing to an AX25 port, and
+	  if so, doesn't add the \r.
+
+	  A more correct way to fix this would be to fix the decoding of
+	  MYCALLs by data_out_ax25 so it doesn't get tripped up by the
+	  first \r.  This is meant to be a quick hack to let both things
+	  work properly until I figure out how to desensitize
+	  data_out_ax25.
+
+2006-09-19 19:55  tvrusso
+
+	* src/interface.c: Removing carriage return I had put in before
+	  MYCALL sent to TNCs.
+
+	  The original intent was to do what was supposed to be an
+	  inconsequential extra carriage return when writing to the TNC to
+	  work around  some garbled data issues that are happening on
+	  D700s.
+
+	  Unfortunately, some bit of code downstream of
+	  "output_my_aprs_data" is seeing the extra carriage return and
+	  screwing up.	Bleah.
+
+	  Removing the "fix" until I figure out what is going on.
+
+2006-09-19 09:12  chicoreus
+
+	* src/list_gui.c: Removing double cast.
+
+2006-09-19 08:58  chicoreus
+
+	* src/: database.h, db.c, list_gui.c: Fixing bugs in previous
+	  commit.  Added note about database.h being name used instead of
+	  db.h Previous commit email message bounced, changes were:
+
+	  1) Converted hard coded MY_TRAIL_DIFF_COLOR to user configurable
+	  my_trail_diff_color and added to configuration ui and config
+	  file.  2) Linked station icon in station list to an onclick
+	  callback to center the map on the station.  Included alternate
+	  callback to pop up station details window.  Needs checking, as I
+	  think the callback needs to filter mouse events.  3) Added, but
+	  haven't yet internationalized display of area in acres when
+	  measuring distances/areas on the map.  Needs to be generalised
+	  and linked to all the places display of an area might be desired.
+
+2006-09-19 07:43  chicoreus
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, help/help-English.dat, src/db.c,
+	  src/list_gui.c, src/main.c, src/main.h, src/xa_config.c: Three
+	  changes: 1) Converted hard coded MY_TRAIL_DIFF_COLOR to user
+	  configurable my_trail_diff_color and added to configuration ui
+	  and config file.  2) Linked station icon in station list to an
+	  onclick callback to center the map on the station.  Included
+	  alternate callback to pop up station details window.	Needs
+	  checking, as I think the callback needs to filter mouse events.
+	  3) Added, but haven't yet internationalized display of area in
+	  acres when measuring distances/areas on the map.  Needs to be
+	  generalised and linked to all the places display of an area might
+	  be desired.
+
+2006-09-19 06:55  we7u
+
+	* src/db.c: Removing the '*' after our callsign when injecting
+	  packets into the internet (our injection ID that we add).
+
+2006-09-15 09:59  tvrusso
+
+	* src/interface.c: Inexplicable fix for an equally inexplicable but
+	  very persistent problem.
+
+	  My Kenwood D700 complains loudly ("EH?") almost every time Xastir
+	  tries to set MYCALL before a posit.
+
+	  This commit adds a carriage return right before MYCALL is sent.
+	  For whatever reason, this eliminates the problem.  Clearly, the
+	  d700 gets in some strange state where the first command sent
+	  after re-entering command mode is not recognized every time.
+
+	  Since a failure of MYCALL to be set before transmit can mean the
+	  wrong callsign (or NOCALL) being attached to a posit, this is
+	  potentially a significant fix.  I will comment more on it in a
+	  follow-up email to the users mailing list.
+
+2006-09-15 09:53  we7u
+
+	* INSTALL: A tweak by Chip, N1MIE.
+
+2006-09-10 18:03  we7u
+
+	* src/db.c: Backing out the igate changes until they can be tested
+	  further.  They appear to have broken most or all igating -> RF.
+
+2006-09-08 17:35  we7u
+
+	* src/: db.c, main.c, main.h, messages.c, messages_gui.c,
+	  popup_gui.c, track_gui.c: Implementing command-line flags for
+	  tracking a station and for disabling popups plus disabling Send
+	  Message dialogs on incoming messages.  May need some more
+	  tweaking to get rid of all popups, but this should be a good
+	  start.
+
+2006-09-08 11:10  we7u
+
+	* src/db.c: Attempting to igate more types of packets to RF, for
+	  the cases where it is appropriate to do so.  This should fix the
+	  directed query problem, at least when gating _to_ RF.  Will look
+	  at the other case as well (gating->INET), which may not be
+	  broken.
+
+2006-09-02 16:43  we7u
+
+	* src/db.c: Adding parsing for RDF packets, with checking to make
+	  sure they really _are_ RDF packets this time.
+
+2006-09-01 06:21  we7u
+
+	* src/db.c: Added a date/timestamp to bearing/distance popup for
+	  emergency packets.
+
+2006-09-01 06:05  we7u
+
+	* src/db.c: Tweaking the processing of emergency packets (Mic_E
+	  packets and standard packets) so that the packet gets processed
+	  twice if the first time comes up with a 0.0 distance (which means
+	  an unknown distance).  This often allows us to match our distance
+	  check ( < 280 miles ) the first time a packet is received,
+	  instead of having to wait for the 2nd occurrence of the packet.
+	  Also:  We now bring up a popup with the bearing and distance to
+	  the emergency station if it passes our checks.
+
+2006-09-01 04:46  we7u
+
+	* src/db.c: Added another comment in the RDF section.
+
+2006-09-01 04:45  we7u
+
+	* src/messages_gui.c: Changing input focus to the first message box
+	  after sending each message.  For D700 or D7 mode to make typing
+	  messages easier.
+
+2006-08-31 14:36  we7u
+
+	* src/: db.c, main.c, maps.c, maps.h, util.c, util.h: Writing wx
+	  alerts to file in the correct format now.  Storing/restoring wx
+	  alerts from file.  Fixed a bug in the weather alerts code where
+	  they wouldn't draw right away.
+
+2006-08-31 14:27  we7u
+
+	* src/wx_gui.c: Skipping NULL alert entries instead of returning
+	  when we hit the first one.  This lets us see all of the active
+	  alerts.
+
+2006-08-30 12:29  we7u
+
+	* src/: db.c, main.c, main.h, messages_gui.c, xa_config.c: Logging
+	  for messages and weather alerts.  Starting to add more buttons to
+	  the Send Message->Change Path dialog.
+
+2006-08-30 12:21  we7u
+
+	* src/Makefile.am: Putting the files in correct alphabetical order.
+
+2006-08-30 04:38  we7u
+
+	* src/db.c: This change implements the capability to receive
+	  messages that were sent to our other SSID's.	We don't ack them.
+	  They cause a Send Message box to pop up like normal except
+	  there's a special note prepended to each message line stating
+	  which SSID the message was sent to.  This allows us to catch
+	  messages sent to our other stations and respond to them if
+	  desired.  We skip displaying these messages if the message
+	  originated from our station, as two message boxes for the same
+	  QSO is very confusing (and unnecessary).
+
+2006-08-30 04:12  we7u
+
+	* src/interface.c: Fixes for KISS mode when using "DIRECT PATH".
+
+2006-08-29 15:34  we7u
+
+	* src/: db.c, main.c: Adding context-sensitive Send Message To
+	  option to the mouse menu.
+
+2006-08-29 15:26  we7u
+
+	* src/messages_gui.c: Changing to APRHH and APHH as the TOCALLS
+	  which mean a HamHUD.
+
+2006-08-29 15:24  we7u
+
+	* src/view_message_gui.c: Making "Mine Only" take precedence over
+	  the range in the View->Messages dialog.
+
+2006-08-29 07:31  we7u
+
+	* src/messages_gui.c: Minor fixes to the Send Message changes.
+	  Tied the select_station_type capability into the New/Refresh
+	  Callsign button as well.
+
+2006-08-29 05:15  we7u
+
+	* src/xa_config.c: Checking for blank strings in config file,
+	  replacing with defaults where it makes sense.
+
+2006-08-28 18:01  we7u
+
+	* src/messages_gui.c: Fixing HamHUD-II detect and setting max size
+	  of messages to 20 for that device.
+
+2006-08-28 16:23  we7u
+
+	* src/messages_gui.c: Initial attempt to have the Send Message
+	  dialog automatically choose the HamHUD/D700/D7 settings based on
+	  the remote station.
+
+2006-08-28 12:29  we7u
+
+	* src/: messages.c, messages.h, messages_gui.c: Added Send Message
+	  formatting for HamHUD 20-character display.
+
+2006-08-25 15:33  we7u
+
+	* src/: db.c, messages.c, messages.h, messages_gui.c: Adding error
+	  messages to the Send Message dialog.	Fixing directed queries.
+	  Adding D7A and D700 input modes to the Send Message dialog.
+	  Fixed a long message bug so 67-char messages can now be sent.
+
+2006-08-25 15:24  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding some
+	  warning messages for the Send Message dialog.
+
+2006-08-25 04:42  we7u
+
+	* src/db.c: Changed the Capabilities display in View Incoming Data
+	  so that it shows my own outgoing ?IGATE? packets as well.
+
+2006-08-25 04:25  we7u
+
+	* src/messages_gui.c: Updated some comments.  No code changes.
+
+2006-08-24 16:49  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/messages_gui.c, src/view_message_gui.c: Implementing Station
+	  Capabilities and Mine Only options on Incoming Data dialog.
+	  Added Mine Only and interface selection options to View Messages
+	  dialog.
+
+2006-08-24 16:29  we7u
+
+	* src/popup_gui.c: Protecting popup functions from possible bad
+	  inputs.
+
+2006-08-23 13:45  we7u
+
+	* src/db.c: Implemented 120-second random delay before responding
+	  to an ?IGATE?  query.  Implemented the response for an ?APRS?
+	  query, including the 120-second random delay.
+
+2006-08-23 08:53  we7u
+
+	* src/main.c: Refuse to print out the measured angle for the case
+	  where we're doing on-screen measuring at zoom==1.  Angles change
+	  at that zoom level.
+
+2006-08-23 08:09  we7u
+
+	* src/map_geo.c: Adding a comment about a future Terra/Toposerver
+	  enhancement: Crossing UTM zone boundaries, splitting the map
+	  fetch into two fetches.
+
+2006-08-23 07:14  we7u
+
+	* src/maps.c: Added more debug output from map_visible()
+
+2006-08-23 07:14  we7u
+
+	* src/map_geo.c: Separating "zstr" used in UTM->lat/long calls into
+	  zstr0 and ztr1.  We were running into problems when we crossed
+	  UTM zones with a map.
+
+2006-08-23 07:12  we7u
+
+	* src/main.c: Added a method to have Xastir spit out coordinates in
+	  Xastir Coordinate System.  Change a global variable at the top of
+	  main.c to a 1 to enable it.
+
+2006-08-23 05:19  we7u
+
+	* src/maps.c: Adding some debug statements.
+
+2006-08-23 05:17  we7u
+
+	* src/map_geo.c: Changing one comment.
+
+2006-08-23 05:17  we7u
+
+	* src/main.c: Moving reload_object_item() and
+	  Restore_CAD_Objects_from_file() from main() up into UpdateTime().
+	  This is so that the image can be created and the global map
+	  corner variables updates first.  Points were getting rejected on
+	  loading because these variables were not initialized yet.
+
+2006-08-22 11:20  tvrusso
+
+	* src/messages_gui.c: Fix the
+	  Send_message_change_path_destroy_shell function so it doesn't
+	  ever try to destroy a shell when the pointer is null.
+
+	  This was causing segfaults for me whenever a messaging dialog was
+	  closed, whether I'd accessed a change_path dialog or not.
+
+2006-08-22 08:27  we7u
+
+	* src/messages_gui.c: Closing the Change Path dialog if the Send
+	  Message dialog is closed.
+
+2006-08-22 07:20  we7u
+
+	* src/messages_gui.c: Setting the path and change path widgets so
+	  that they stretch properly with the dialog.
+
+2006-08-22 07:12  we7u
+
+	* src/messages_gui.c: Simplifying the Send Message dialog a bit
+	  more, taking the Reverse Path widgets out of that dialog.  They
+	  still exist in the Change Path dialog.
+
+2006-08-22 05:35  we7u
+
+	* src/messages_gui.c: Minor adjustments to the widgets of the Send
+	  Message and Change Path dialogs.
+
+2006-08-22 04:55  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/messages_gui.c: Swapping a
+	  couple of lines of widgets in the Send Message dialog.  More
+	  tweaks to lang strings for Send Message and Change path dialogs.
+
+2006-08-22 04:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/messages.h, src/messages_gui.c:
+	  Creating language file entries for new Send Message and Change
+	  Path widgets.  Adding "Reverse Path:" labels to both dialogs.
+
+2006-08-22 04:08  we7u
+
+	* src/messages_gui.c: Changing reverse-path calculation to get rid
+	  of Q-construct and anything after it before reversing the path.
+
+2006-08-21 19:35  we7u
+
+	* src/messages_gui.c: A better Send Message dialog.  More testing
+	  to be done yet, but so far it looks better than the old.
+
+2006-08-21 18:01  we7u
+
+	* src/: interface.c, messages.c, messages.h, messages_gui.c: The
+	  beginnings of a separate dialog for changing the path from the
+	  Send Message dialog.	Mostly working as-is but not very pretty.
+
+2006-08-21 09:18  we7u
+
+	* src/messages_gui.c: Added some TODO comments to Send_Message().
+
+2006-08-21 06:58  we7u
+
+	* src/popup.h: Cranking up max popups to 30.
+
+2006-08-21 06:33  we7u
+
+	* src/db.c: A fix for bug #1474401, where an auto-answer or some
+	  other message to us which doesn't have a message-ID ends up
+	  showing up in a Group Message dialog.  This fix makes them appear
+	  in a Send Message dialog, plus we refuse to ack them which is
+	  correct behavior.
+
+2006-08-21 04:44  we7u
+
+	* src/main.c: Changing from a 1us delay to a 2ms delay inside
+	  UpdateTime().  Adding/ changing some comments.
+
+2006-08-21 04:42  we7u
+
+	* src/interface.c: Moving one debug line inside the data_lock block
+	  to make sure it doesn't get corrupted by another thread.
+
+2006-08-19 15:19  we7u
+
+	* src/interface.c: More correct fixes for truncation problem with
+	  new incoming data queue code.
+
+2006-08-19 11:54  we7u
+
+	* src/interface.c: A fix for the circular queue pointer problem.
+	  The read pointer was not getting advanced in the same manner
+	  around the queue as the write pointer, giving us an off-by-one
+	  error.
+
+2006-08-19 10:42  we7u
+
+	* src/interface.c: A temporary fix to the new queue code problem
+	  where it truncates the last character off the strings.
+
+2006-08-18 14:52  tvrusso
+
+	* src/map_shp.c: Remove commented-out ifndef of label-skipping
+	  code.  It won't be needed.
+
+2006-08-18 08:28  we7u
+
+	* src/map_shp.c: Adding an #ifndef block for Tom Russo to play
+	  with.  Currently commented out.  If the block is enabled it will
+	  cause Xastir to draw every label for each polyline instead of
+	  skipping some based on zoom level.
+
+2006-08-18 06:57  we7u
+
+	* src/map_shp.c: Added some comments.
+
+2006-08-18 04:07  we7u
+
+	* src/: interface.c, interface.h, main.c: Shortening the delay at
+	  the end of UpdateTime() again to 10.	Global variables for
+	  passing data from the read threads to main have been changed to a
+	  circular queue.  This lets us queue up data from the read threads
+	  when we're busy drawing maps and such, then process it quickly
+	  when we're freed up.
+
+2006-08-18 04:02  we7u
+
+	* src/x_spider.c: Shortening delays so that we don't corrupt
+	  packets if we're fed them quickly by the pipe from Xastir.
+
+2006-08-17 05:59  we7u
+
+	* src/database.h: Renaming a function parameter so that it's not
+	  confused with a global variable name.
+
+2006-08-17 05:47  we7u
+
+	* src/db.c: Renaming a function parameter so that it won't be
+	  confused with a global variable name.
+
+2006-08-15 03:38  we7u
+
+	* src/map_shp.c: Patch for RTREE functionality with the new
+	  Shapefile speed mods.
+
+2006-08-14 13:06  we7u
+
+	* src/map_shp.c: Fixing an infinite loop condition that can happen
+	  if a Shapefile has points below -180.0 or above 180.0.
+
+2006-08-14 12:38  we7u
+
+	* src/track_gui.c: Changing from "sed --in-place" to "sed -i",
+	  perhaps more compatible across versions?
+
+2006-08-14 12:34  we7u
+
+	* src/track_gui.c: Fixing findu.com fetch trail function for
+	  base-91 packets w/no comment/course/speed/altitude.
+
+2006-08-14 11:01  we7u
+
+	* FAQ: Added another bit to the "remote restart" section.
+
+2006-08-14 08:53  we7u
+
+	* src/map_gnis.c: Reorganization to provide speedups.  This one
+	  cuts about 50% of the time when zoomed in.
+
+2006-08-14 08:52  we7u
+
+	* src/map_gdal.c: Limiting to screen size instead of +/-32767.
+	  Added a comment about another possible optimization.
+
+2006-08-14 05:24  we7u
+
+	* INSTALL: Adding an invocation line for gprof that I use so I
+	  don't need to figure it out each time.
+
+2006-08-14 05:12  we7u
+
+	* src/: map_gdal.c, map_shp.c, maps.c, maps.h: Removing error-text
+	  parameter from map_visible_lat_lon() as we're not using it.
+	  Changed the order of checks in map_visible_lat_lon() to perhaps
+	  speed things up slightly based on which lines get his most often
+	  (gprof). Changed skip parameter for HandlePendingEvents in
+	  map_shp.c from 50 to 64, which is a power of 2 (perhaps faster?)
+	  and roughly the switchover point (via gprof) for lower CPU.
+
+2006-08-11 16:58  we7u
+
+	* src/: db.c, draw_symbols.c, map_gdal.c, map_shp.c, maps.c,
+	  maps.h, objects.c: Added dupe-checking for screen points to
+	  draw_vector and draw_point.  Reduced the number of
+	  HandlePendingEvents calls we're doing inside the inner loop of
+	  map_shp.c.  The end result is a speedup in Shapefile drawing.
+
+2006-08-11 05:04  we7u
+
+	* src/maps.h: Getting rid of stub for recompute_lat_lon() function
+	  which was deleted.
+
+2006-08-11 05:03  we7u
+
+	* src/: maps.c, util.c: Getting rid of duplicate code in the form
+	  of recompute_lat_long() and the global variables it populated.
+	  We have duplicate functionality in the f_NW_corner_longitude,
+	  f_SE_corner_longitude, f_SE_corner_latitude, and
+	  f_NW_corner_latitude global variables and the code that populates
+	  them.
+
+2006-08-10 09:15  we7u
+
+	* src/db.c: Took out a bit too much on one of the previous 2 or 3
+	  revisions.  Adding computation of screen coordinates back in for
+	  trail labels.
+
+2006-08-10 09:09  we7u
+
+	* src/: db.c, draw_symbols.c, map_gnis.c, map_shp.c, objects.c:
+	  Moving screen boundary checks into draw_nice_string() and
+	  removing them from lots of other places.
+
+2006-08-10 09:08  we7u
+
+	* src/maps.c: Adding a clip2d_screen() function for line-clipping
+	  to screen boundaries.  Not used yet.
+
+2006-08-10 06:01  we7u
+
+	* src/maps.c: Added some sanity checking for dbfawk font_size
+	  variable.
+
+2006-08-10 05:41  we7u
+
+	* src/map_gdal.c: Added some comments.
+
+2006-08-10 04:35  we7u
+
+	* src/db.c: Changing to draw_point() instead of XDrawPoint for the
+	  vertice point drawing of tracklines.
+
+2006-08-09 21:02  we7u
+
+	* src/: db.c, draw_symbols.c, util.h, main.c, map_dos.c,
+	  map_gdal.c, map_gnis.c, map_shp.c, maps.c: Adding protection for
+	  the parameters of the XDraw* calls, making sure they don't go
+	  over 16 bits.
+
+2006-08-09 07:56  we7u
+
+	* src/draw_symbols.c: Changing the lu16 inline function to pass
+	  back the correct type and check against the correct max number.
+	  Added a bunch of comments elsewhere.
+
+2006-08-09 07:03  we7u
+
+	* src/draw_symbols.c: Limiting params to X11 drawing calls to
+	  16-bit values.  This should help prevent segfaults.  We're
+	  actually limiting them more than we need to in most cases, but
+	  this should be ok.
+
+2006-08-09 04:36  we7u
+
+	* src/db.c: Added a debug line and comment.  This one lets us play
+	  with/display aloha circles on startup if uncommented.
+
+2006-08-09 04:35  we7u
+
+	* src/draw_symbols.c: Fix for Aloha circle not getting drawn if it
+	  doesn't fit entirely on the screen.
+
+2006-08-08 15:32  we7u
+
+	* src/Makefile.am: A fix for a permissions problem that happens
+	  with compiledate.c every once in a while.  This fix is by Dan
+	  Brown.
+
+2006-08-08 15:30  we7u
+
+	* src/draw_symbols.h: Checking in a header file that didn't get
+	  checked in with the other sources during the last commit.
+	  Dropped a couple of parameters from the draw_symbol() function.
+
+2006-08-08 12:41  we7u
+
+	* src/: db.c, draw_symbols.c: Fixed draw_pod_circle(),
+	  draw_bearing(), draw_phg_rng() and draw_DF_circle() so that they
+	  draw even when the symbol is off-screen.
+
+2006-08-08 07:34  we7u
+
+	* src/db.c: Fix for ambiguity box not getting disabled.
+
+2006-08-08 06:05  we7u
+
+	* src/maps.c: Added some comments about possible optimizations in
+	  the draw_point and draw_point_ll functions.  Commented out the
+	  check against drawing long vectors to screen there as the clip2d*
+	  algorithms should take care of that for us.
+
+2006-08-08 05:36  we7u
+
+	* src/maps.c: Moving some of the functions to a different order
+	  that makes more sense.  No real code changes.
+
+2006-08-07 13:19  tvrusso
+
+	* config/: 24kgrid.dbfawk, nwsc_ddmmyy.dbfawk, nwsmzddmmyy.dbfawk,
+	  nwsmzoddmmyy.dbfawk, nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk,
+	  nwsz_ddmmyy.dbfawk, nwszoddmmyy.dbfawk, tgr2shp.dbfawk,
+	  tgr2shppoly.dbfawk, tgrcty.dbfawk, tgrkgl.dbfawk, tgrlk.dbfawk,
+	  tgrlpt.dbfawk, tgrlpy.dbfawk, tgrplc00.dbfawk, tgrwat.dbfawk: Fix
+	  broken dbffields variables in all dbfawk files.
+
+	  The dbfawk file is supposed to have semicolon-terminated
+	  statements.  Unfortunately, the parser is busted and doesn't
+	  actually handle the case where the semicolons are omitted
+	  correctly.  So, for example,
+
+	   BEGIN {
+	    dbfinfo="Blah:Diblah:Diblahdiblah";
+	    dbffields="Blah:Diblah:Diblahdiblah"
+	  }
+
+	  winds up getting the newline-space at the end of the line added
+	  to dbffields, and thus in the list of names to be retrieved from
+	  the dbf file.  This never matches the last field when applied to
+	  the dbf files, which have no such extra characters in the field
+	  names.
+
+	  This bug is masked by *how* the dbffields variables were actually
+	  set in the included dbfawk files:  BEGIN {
+	  dbfinfo="Blah:Diblah:Diblahdiblah";
+	  dbffields="Blah:Diblah:Diblahdiblah"}
+
+	  That is, since there was no newline between " and }, dbfawk
+	  didn't do the wrong thing.
+
+	  Unfortunately, many people have patterned their own dbfawk files
+	  after the ones in the config directory, and so this
+	  missing-semicolon deal got propagated (I am among those
+	  propagating it, as all my shape_web dbfawk files omitted the
+	  semicolon, but also put the brace right after the ").  The
+	  problem only gets exposed when the user inserts a newline after
+	  the quote.
+
+	  This commit adds the semicolon (and a newline) after the
+	  dbffields closing quote.
+
+	  The real fix is to fix the dbfawk/awk parser so it doesn't let
+	  syntax errors like this slip through.
+
+2006-08-07 12:56  we7u
+
+	* src/maps.c: Renaming the window corner global variables.
+
+2006-08-07 12:55  we7u
+
+	* src/main.c: Renaming the window corner global variables.
+	  Updating some new global variables describing the SE corner in
+	  float and long format when necessary.
+
+2006-08-07 12:53  we7u
+
+	* src/: objects.c, xa_config.c, util.c: Renaming the window corner
+	  global variables.
+
+2006-08-07 12:50  we7u
+
+	* src/: location.c, location_gui.c, map_WMS.c, map_dos.c,
+	  map_gdal.c, map_geo.c, map_gnis.c, map_pdb.c, map_shp.c,
+	  map_tif.c, map_tiger.c: Renaming the window corner global
+	  variables.
+
+2006-08-07 12:49  we7u
+
+	* src/: db.c, draw_symbols.c, xastir.h: Renaming the global
+	  variables describing the corners of the map window.  Fixes for
+	  aloha circles and multipoing drawings so that they should appear
+	  if the symbol they're attached to is off-screen.
+
+2006-08-07 06:49  we7u
+
+	* src/draw_symbols.c: Getting rid of unused code.
+
+2006-08-07 06:37  we7u
+
+	* src/maps.c: Adding clipt(), clip2d(), clipt_long(), and
+	  clip2d_long() functions.  These are implementations of the
+	  Liang/Barsky/Slater line-clipping algorithm.	Modified
+	  draw_vector() and draw_vector_ll() to use them.  Changing cutoff
+	  points for points/vectors to be consistent (+/-16000).
+
+2006-08-07 06:33  we7u
+
+	* src/db.c: Changing draw_trail() to use the draw_vector()
+	  function.
+
+2006-08-07 06:27  we7u
+
+	* src/: map_gdal.c, map_shp.c: Tweaking the pixel min/max cutoff
+	  numbers to make them consistent throughout the code.
+
+2006-08-07 04:13  we7u
+
+	* src/draw_symbols.c: Changed one comment.  No code changes.
+
+2006-08-04 07:35  we7u
+
+	* src/maps.c: Changed draw_point() so that if it lies outside the
+	  screen we don't call the X11 draw routine.
+
+2006-08-04 05:57  we7u
+
+	* src/draw_symbols.c: A fix for dead-reckoning where the angle goes
+	  whacko at close-in zoom levels.
+
+2006-08-04 04:42  we7u
+
+	* src/db.c: Setting the precision rectangle sizes for our own
+	  station, whether transmit is enabled or not.
+
+2006-08-04 04:17  we7u
+
+	* src/track_gui.c: Using raw.cgi instead of rawposit.cgi to fetch
+	  packets from findu.  This allows us to snag ALL packets from the
+	  station during the specified period instead of just posits.
+	  Weather, status, etc.
+
+2006-08-04 03:55  we7u
+
+	* src/db.c: Fixing the display of altnet's.  Somewhere along the
+	  line we reversed it accidentally.
+
+2006-08-03 16:32  we7u
+
+	* src/db.c: Tweaking the NMEA decoding routines so that they pass
+	  back the number of digits after the decimal point.  Changing the
+	  display for NMEA so that the number of digits changes the size of
+	  the "precision" rectangle.
+
+2006-08-03 16:26  we7u
+
+	* src/util.c: Fixing convert_lat_s2l() and convert_lon_s2l() so
+	  that they can handle from 0 to 6 characters after the decimal
+	  point for lat/long conversions.
+
+2006-08-03 08:57  we7u
+
+	* src/: db.c, objects.c: Fixing the problem where objects don't
+	  appear on the map after created.  Also fixed transmission of
+	  objects so that if they have a course/speed the new position is
+	  sent out at the transmit interval.
+
+2006-08-03 03:46  we7u
+
+	* src/: database.h, db.c, draw_symbols.c, draw_symbols.h: The
+	  beginnings of the correct way of drawing the "precision"
+	  rectangles.  Not all of the different types of packets are
+	  correctly sized yet, but many are.
+
+2006-08-02 17:19  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h: Changing "precision"
+	  circles to rectangles, with the correct direction offset from the
+	  symbol for the different hemispheres.  They are slightly too
+	  large at the moment, but at least of reasonable size.
+
+2006-08-02 08:26  we7u
+
+	* src/util.c: The chdir() call in log_data() appears to corrupt our
+	  "file" parameter.  We don't appear to need the chdir() function
+	  call anyway, so have commented it out.  We get passed the
+	  complete root-anchored path/filename as-is.
+
+2006-08-02 05:30  we7u
+
+	* src/db.c: Allowing the Station Chooser dialog to be closed
+	  without forcing the Station Info dialog to be closed.  Commenting
+	  out the restore_position section in Station_data() as it isn't
+	  working correctly.
+
+2006-08-02 04:58  we7u
+
+	* src/objects.c: Changed/added some comments.  No code changes.
+
+2006-08-02 04:53  we7u
+
+	* src/objects.c: Backing out the update of the Edit & Delete CAD
+	  Objects dialogs when allocating the first vertice of a new CAD
+	  Object.  It's a bit confusing when the windows move on top of the
+	  drawing area when you do the first click, so I decided not to
+	  update then.
+
+2006-08-02 04:47  we7u
+
+	* src/objects.c: Updating the Edit and Delete CAD Objects dialogs
+	  at more places: *) When we create the first vertice on a new
+	  polygon *) When we hit either the Done or Cancel buttons on the
+	  Close Polygon    dialog.
+
+2006-08-01 07:49  we7u
+
+	* src/: objects.c, util.c: Effectively removing the rounding code
+	  that was added on 6/21/2006.	The rounding was not done properly
+	  to take into account overflow from seconds to minutes, or from
+	  minutes to degrees.
+
+2006-08-01 05:49  we7u
+
+	* src/popup_gui.c: Bumping up the min size for popup messages
+	  slightly.
+
+2006-08-01 05:40  we7u
+
+	* src/popup_gui.c: A start at fixing the problem where a popup
+	  message will come up too small on the screen and can't be
+	  resized.  We now set a minimum size and don't fix the size, so it
+	  can be resized if necessary to read the message.
+
+2006-07-31 06:42  we7u
+
+	* src/objects.c: Fixed double-dash option for CAD objects.  Update
+	  Edit/Erase CAD object dialogs if objects are changed.  Use
+	  "<Empty Label>" names if no actual label is selected.  Commented
+	  out one message to STDERR during normal pre-defined objects
+	  processing, fixed up another message here to use
+	  get_user_base_dir() or get_data_base_dir() as appropriate.
+
+2006-07-31 06:30  we7u
+
+	* src/interface.c: Notifying the operator if emergency beacon mode
+	  is enabled but no transmits are actually occuring, for various
+	  reasons.
+
+2006-07-31 06:28  we7u
+
+	* src/messages.h: Cranking up max message windows from 10 to 25.
+
+2006-07-31 06:27  we7u
+
+	* src/main.c: Warning the user if ALTNET is enabled on startup (can
+	  be confusing when a new user sets this and then sees no
+	  stations).  Setting a fixed beacon interval of 60 seconds if
+	  emergency beacon mode is enabled.
+
+2006-07-31 06:25  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding more
+	  strings for popup messages throughout the code, plus language
+	  strings for CAD Objects.
+
+2006-07-25 07:53  we7u
+
+	* src/util.c: A first attempt at snagging course/speed out of the
+	  previous posit if the last posit doesn't have it, for
+	  dead-reckoning purposes.  It will only do this if the previous
+	  posit is still within the dead-reckoning timeout period.  The
+	  goal here is to do dead-reckoning properly for stations which
+	  alternate GPGGA/GPRMC sentences (GPGGA don't have course/speed).
+
+2006-07-24 12:04  we7u
+
+	* src/draw_symbols.c: Removing dead or useless code.  Reorganizing
+	  some of the tests where we determine whether to draw a particular
+	  symbol or attribute based on whether it is in the current view.
+
+2006-07-24 12:01  we7u
+
+	* src/db.c: Changing to setting flags in the station record when
+	  it's our station or object/item, then checking flags, instead of
+	  checking the "call_sign" or "origin" constantly throughout the
+	  code with string compares.  Got rid of the second drawing
+	  iteration where we were drawing new stations to the screen _and_
+	  to pixmap_final.  We now draw to the screen and rely on the next
+	  full screen-update to do the rest.
+
+2006-07-24 11:54  we7u
+
+	* src/main.c: Fixing the -geometry flag so that it works for
+	  strings like: "-geometry -0-0"
+
+2006-07-22 07:47  tvrusso
+
+	* src/dbfawk.c: Possible fix for bug that prevents dbfawk files
+	  with a single field in the dbffields list from working unless a
+	  colon is added to the end of the list.
+
+	  This appears to be a very platform dependent bug, as I have never
+	  been able to reproduce the problem.  But the fix is still valid
+	  --- the issue is that no null terminator is added to a field name
+	  unless a colon is found.
+
+	  This fix doesn't break anything, but I'm unable to verify that it
+	  actually fixes the problem reported, since I have never actually
+	  seen that problem in action.
+
+2006-07-20 13:05  we7u
+
+	* src/maps.c: Dump a couple of messages out from map_indexer() to
+	  STDERR.  This makes it evident why Xastir is so busy when first
+	  started up in a fresh config directory, if there are a lot of
+	  maps present on the system.
+
+2006-07-20 12:28  we7u
+
+	* src/main.c: Nope, 50 was too slow, but 25 looks good so far.
+
+2006-07-20 12:23  we7u
+
+	* src/main.c: Slowing down the main UpdateTime() loop again.  We
+	  seem to keep up with a 2.6 kernel with nexttime=50.  Previously
+	  10.
+
+2006-07-19 07:40  we7u
+
+	* src/: igate.c, interface.c, main.c, maps.c, messages.c,
+	  xa_config.c: Fixes to get rid of complete path in the config file
+	  for variables that need to change between different configs.	If
+	  a user has specified a complete path (other than the default
+	  path), Xastir will honor it.	If the default path is there,
+	  Xastir will shorten it so that multiple configs may use it.
+
+2006-07-19 04:27  we7u
+
+	* src/: database.h, db.c, list_gui.c, objects.c: Getting rid of
+	  many of the is_my_call() invocations, instead setting flag bits
+	  in the DataRow->flag variable to specify whether it's our
+	  callsign-SSID or whether it's an object/item owned by us.  This
+	  gets rid of literally millions of string compares.
+
+2006-07-17 17:41  we7u
+
+	* src/db.c: Skip doing dead-reckoning if scale > 8000.	Doing
+	  point-caching of last-point-drawn in draw_trail() to reduce the
+	  amount of drawing we do when it's the same screen pixel over and
+	  over (when zoomed out).
+
+2006-07-17 17:38  we7u
+
+	* src/database.h: Adding a new flag definition in preparation for a
+	  rewrite of the is_my_call() function.
+
+2006-07-17 09:12  we7u
+
+	* src/: map_WMS.c, map_geo.c, map_tiger.c: Patch for bug 1522493 by
+	  Dan Brown, n8ysz:  The caching "bad" files problem.  It should
+	  whack things out of the cache if, for whatever reason, they're
+	  unusable.
+
+2006-07-17 04:57  we7u
+
+	* src/: main.c, xa_config.c, xa_config.h: More tweaks by Dan Brown,
+	  n8ysz:  Cleaned up the get_user_base_dir() in xa_config.c to be
+	  more careful about returning complete paths.
+
+2006-07-16 12:02  tvrusso
+
+	* src/: color.c, map_geo.c: Clean up transparency code for .geo
+	  maps, removing debug output.
+
+	  This now works properly for 16 and 24 bit DirectColor/TrueColor
+	  displays.  It is horribly broken for 8-bit displays, but as far
+	  as I can tell it was horribly broken *before* I started.  On
+	  8-bit displays the WMSRadar image doesn't even get displayed,
+	  transparent or not, before *and* after my changes.  I was unable
+	  to figure out why.
+
+2006-07-16 10:21  tvrusso
+
+	* src/: color.c, map_geo.c: An interim commit of partial fixes to
+	  the transparency problem on .geo files.
+
+	  Mostly committing this to get it to a machine that has a display
+	  that isn't 24-bit for testing.
+
+	  Lots of cruft in here needs editing out after testing is
+	  complete.
+
+2006-07-14 11:50  we7u
+
+	* README.Getting-Started, xastir.1: Updates by Dan Brown, n8ysz.
+
+2006-07-14 08:53  we7u
+
+	* src/: main.c, xa_config.c: Additions/fixes to implement alternate
+	  Xastir config directories.  Patch submitted by Dan Brown, n8ysz.
+
+2006-07-13 05:10  we7u
+
+	* scripts/get-NWSdata: Fixing up the domain names so that they all
+	  match (for consistency).
+
+2006-07-12 10:47  we7u
+
+	* scripts/get-NWSdata: Updating one NWS shapefile name to latest
+	  version.
+
+2006-07-12 10:47  we7u
+
+	* README.MAPS: Updating the text for NWS Shapefile names to match
+	  the NOAA website.
+
+2006-07-12 07:24  we7u
+
+	* src/draw_symbols.c: A fix for the bug where text-on-black obscure
+	  text above/below slightly due to the black background.  We now
+	  separate the text by another pixel and the problem goes away.
+
+2006-07-11 09:06  tvrusso
+
+	* WMSRadar.geo: Tweak transparency value.  For some time now, the
+	  actual "no reflection" value that's been coming in has been hex
+	  value  0x010101, not "0x000000".  On 24-bit displays that means
+	  that the default file was displaying with an opaque nearly-black
+	  background instead of a transparent one.
+
+	  The actual no-reflection value returned by the WMS server has
+	  changed back and forth between 0x000000 and 0x010101 often in the
+	  history of the WMSRadar file and will probably need to be changed
+	  again some time in the future.  It has been pretty consistently
+	  0x010101 for several weeks now.
+
+2006-07-11 07:38  we7u
+
+	* src/db.c: Fixing incorrect timestamps for local station.  This
+	  was causing track points to get expired immediately so that the
+	  station didn't show a track if being run with only a GPS
+	  interface.
+
+2006-07-11 06:02  we7u
+
+	* src/draw_symbols.c: Fixes for dead-reckoning 180 degree problem
+	  and for the DR arc being slightly off.
+
+2006-07-11 05:18  we7u
+
+	* src/draw_symbols.c: Removing dead code.
+
+2006-07-11 05:06  we7u
+
+	* src/draw_symbols.c: More efficient dead-reckoning code plus
+	  commenting out unused sections of code.
+
+2006-07-11 04:41  we7u
+
+	* src/draw_symbols.c: More tweaks to dead-reckoning.  We now
+	  attempt to display the arc and the DR'ed trail if either the
+	  symbol or the DR'ed symbol are on-screen.  Added an "if" clause
+	  to the DR'ed symbol drawing so it is only drawn when on-screen.
+	  Commented out old code that we're not using anymore.
+
+2006-07-11 04:01  we7u
+
+	* src/util.c: Another fix by Dan Brown, n8ysz.	This one keeps the
+	  log files at or below the max logfile size.
+
+2006-07-11 03:59  we7u
+
+	* src/interface.c: Removing a duplicate include line.  Thanks to
+	  Dan Brown for finding it.
+
+2006-07-10 20:15  we7u
+
+	* src/draw_symbols.c: Implenting DR arcs again.  Problems near/at
+	  180 degrees, but other than that it seems to work fine.
+
+2006-07-10 10:24  we7u
+
+	* src/db.c: Disabling the XtRemoveGrab() function call which causes
+	  warnings on some OS'es.  I don't believe we actually need it.
+	  We'll find out for sure when more users try out this version.
+
+2006-07-10 10:23  we7u
+
+	* src/draw_symbols.c: Test code for re-enabling the dead-reckoning
+	  arc's.  Not complete/correct yet, but it's a start.
+
+2006-07-10 09:40  we7u
+
+	* src/wx.c: Fixes by Mike Loebl, kb1mts, to add barometric pressure
+	  and humidity decoding to ARNE format.
+
+2006-07-10 05:57  we7u
+
+	* src/main.c: Fixing high CPU usage problems on FreeBSD, changing
+	  nexttime from 2ms to 10ms.  Thanks to Carl Makin for this tweak.
+
+2006-07-10 04:09  we7u
+
+	* src/util.c: Fixes by Dan Brown, n8ysz, for Xastir bug 1518805:
+	  "Log files can fill up hard drive".  We now limit a log file to
+	  about 2MB at which point we roll it over to a new filename and
+	  create a new empty file to write to.	We keep up to 3 of these
+	  backup files plus the current log file at any given time, which
+	  makes for between 6MB and 8MB of data that we keep.
+
+2006-07-07 09:10  we7u
+
+	* README.Contributing: Added a section by Dan Brown.
+
+2006-07-07 08:06  we7u
+
+	* scripts/BUILDRPMS: Tweaking the rev number.
+
+2006-07-06 09:23  we7u
+
+	* src/main.c: Fixes by Dan Brown, n8ysz, for Xastir bugs 1515197
+	  "segfault if XASTIR_USER_BASE no existing" and 1517761, "No error
+	  check on config dir mkdir".
+
+2006-07-06 08:36  we7u
+
+	* src/: main.c, track_gui.c: Fixes for the blank label problem on
+	  sliders with certain releases of OpenMotif.  This relates to
+	  problems with using XtVaTypedArg within an
+	  XtVaCreateManagedWidget() function.  Instead we now call
+	  XmStringCreateLocalized() before the call, and XmStringFree()
+	  afterwards.
+
+2006-07-05 07:17  we7u
+
+	* src/: Makefile.am, main.c: A patch to add compile time/date to
+	  the Help->About dialog, by Dan Brown, N8YSZ.
+
+2006-06-29 10:04  we7u
+
+	* src/xa_config.c: Making the igate -> RF path default be
+	  "WIDE2-1".
+
+2006-06-27 07:25  we7u
+
+	* src/igate.c: Reorganizing the logic slightly to make it easier to
+	  understand w.r.t. the gating of objects/items/stations to RF via
+	  the nws-stations.txt file.  Added/updated several comments.
+
+2006-06-23 09:03  we7u
+
+	* src/db.c: Adding more comments.  No code changes.
+
+2006-06-23 08:31  we7u
+
+	* src/igate.c: Changing igating->RF around so that if a station or
+	  object name is found in the nws-stations.txt file, it will get
+	  gated to RF whether or not "TCPXX" is found in the path.  This
+	  allows more types of things to be gated to RF if manually
+	  specified in the nws-stations.txt file.
+
+2006-06-22 05:42  we7u
+
+	* src/db.c: Mostly changes to comments, but changed the error
+	  ellipses from black to white.  Still need to draw truncation
+	  rectangles instead in some cases.
+
+2006-06-21 07:49  we7u
+
+	* src/objects.c: Tweaking the rounding in objects.c
+
+2006-06-21 06:12  we7u
+
+	* src/util.c: Changing some comments.
+
+2006-06-21 05:41  we7u
+
+	* src/: interface.c, util.c: Fixing up posits so that we round
+	  properly instead of truncating the higher resolution digits.	For
+	  some-odd reason the fprintf doesn't round up properly at 0.5, so
+	  we add a 0.01 to the number so that it rounds up.
+
+2006-06-21 04:51  we7u
+
+	* src/db.c: Changing one comment.
+
+2006-06-20 05:55  we7u
+
+	* src/: database.h, db.c, draw_symbols.c: An attempt to do the
+	  error ellipses for position packets.	This is most likely not the
+	  display we'll finalize on, but it's a start.	We draw circles for
+	  the less-precise posits, but as Tom Russo pointed out they should
+	  probably be rectangles.  Also, the GPGGA/GPRMC/GPGLL code needs
+	  some work w.r.t. these.
+
+2006-06-19 14:47  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h: Making sure we don't
+	  try to do dead-reckoning on stations that have position ambiguity
+	  enabled.
+
+2006-06-19 11:58  we7u
+
+	* README: Adding notes for OpenSuSE 10.1
+
+2006-06-16 13:29  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h: More ambiguity fixes.
+
+2006-06-16 12:58  we7u
+
+	* src/: database.h, db.c: Correcting the spelling of "ellipse".
+
+2006-06-16 12:08  we7u
+
+	* src/draw_symbols.c: Changes to a few comments.
+
+2006-06-16 12:06  we7u
+
+	* src/: database.h, db.c, draw_symbols.c, draw_symbols.h: Adding a
+	  variable for doing error_ellipses around posits.  Not in use yet.
+	  Changed the position ambiguity around so that it is correct and
+	  the symbol position inside the rectangle is correct.	Still need
+	  to fix up the grid-square code in the draw_ambiguity function
+	  though.
+
+2006-06-15 14:28  we7u
+
+	* src/draw_symbols.c: Fixing up some of the ambiguity rectangle
+	  stuff.  All but the grid squares look ok now, but the smallest
+	  rectangle ends up with the symbol placed off-center, which still
+	  needs to be fixed.
+
+2006-06-15 12:46  we7u
+
+	* src/draw_symbols.c: Changing from stippled ambiguity rectangles
+	  to solid lines.
+
+2006-06-15 07:33  we7u
+
+	* src/draw_symbols.c: Changing ambiguity rectangles from filled to
+	  unfilled, plus drawing lines from symbol to each corner of
+	  rectangle so we know which symbol is being drawn with the
+	  ambiguity.
+
+2006-06-14 13:55  we7u
+
+	* src/database.h: Doesn't make much sense to add the new parameter
+	  to the station database at this time when code doesn't use it.
+	  It would only take up memory.  Commenting it out for now until we
+	  get to using it.
+
+2006-06-14 13:50  we7u
+
+	* src/database.h: Preliminary addition of an error_elipse storage
+	  area for the station record.	Not actually used in the code yet
+	  as we're still discussing how it should best be used/displayed.
+
+2006-06-14 07:17  gstueve
+
+	* src/util.c: Only check VHF porion of path. Still need to process
+	  2nd portion for proper behavior.
+
+2006-06-14 07:13  gstueve
+
+	* src/util.c: Only change lower case characters to uppper, don't
+	  bother to rewrite upper.
+
+2006-06-14 07:10  gstueve
+
+	* src/util.c: Fix spelling in comment.
+
+2006-06-12 09:17  we7u
+
+	* FAQ: Added "socat" to the FAQ.
+
+2006-06-08 14:04  we7u
+
+	* src/: db.c, objects.c: Changed some comments to show the last
+	  GPROF percentages for the heavy-hitters.  No code changes here.
+
+2006-06-07 07:18  we7u
+
+	* config/tnc-startup.d700: Changed the comments at the top.  Added
+	  note about Alinco's.
+
+2006-06-07 07:03  tvrusso
+
+	* FAQ: Update pointer to latest version of the FAQ.  The URLs that
+	  were here were very outdated.
+
+2006-06-06 12:22  we7u
+
+	* src/db.c: Some packets with an extra digit in the latitude end up
+	  going through the compressed packet decode routine.  This fix
+	  causes those packets to be rejected from that routine.
+
+2006-06-05 15:01  we7u
+
+	* Davis/src/db2APRS.c: Davis mods by Clay Jackson, n7qnm.  Added
+	  some MySQL error checking, set it up so it would always get the
+	  'latest' records, and generally improved the error handling
+	  (things like 0 or >100 pct humidity, pressure below 26 or above
+	  31, and so on).
+
+2006-06-05 12:20  we7u
+
+	* scripts/get-NWSdata: Tweaking the script so that it only fetches
+	  files we don't already have.
+
+2006-06-05 12:19  we7u
+
+	* configure.ac: Bumping revision for devel to 1.8.3.
+
+2006-06-05 11:50  we7u
+
+	* configure.ac, scripts/BUILDRPMS, scripts/do_xastir_release_dev:
+	  Updating to 1.8.2 to get ready for stable release.
+
+2006-06-05 11:43  we7u
+
+	* scripts/do_xastir_release_stable: Updating default version
+	  number.
+
+2006-06-05 10:14  we7u
+
+	* README.MAPS: Added a section describing how to create your own
+	  Shapefile maps with Xastir.  Added a section describing CAD
+	  Object polygons.
+
+2006-06-05 09:46  we7u
+
+	* scripts/fcc-get: Updating to match newer "sort" function's
+	  syntax.
+
+2006-06-02 09:43  we7u
+
+	* config/language-German.sys: Updates by DK7IN.  Thanks!
+
+2006-06-02 08:35  we7u
+
+	* scripts/get-NWSdata: Updating to latest NOAA filenames.
+
+2006-06-01 10:05  we7u
+
+	* README.MAPS: Fixing the path for gpx2shape so that people look
+	  for it in the scripts directory.
+
+2006-06-01 10:04  we7u
+
+	* scripts/Makefile.am: Adding gpx2shape to the build.
+
+2006-06-01 10:04  we7u
+
+	* scripts/gpx2shape: A nice contribution by James Washer.  Convert
+	  GPX files to Shapefiles.
+
+2006-06-01 09:35  we7u
+
+	* README.MAPS: Added a blurb about National Geographic's Topo,
+	  TPO/TPG files, mapXchange, gpsbabel, and gpx2shape.pl.
+
+2006-06-01 07:17  we7u
+
+	* README.MAPS: A bit added by Kyle Kienapfel regarding the Canada
+	  topo file.  Thanks!
+
+2006-05-31 13:39  we7u
+
+	* src/igate.c: Disallowing igating of general queries in either
+	  direction.  Directed queries still get gated as appropriate.
+
+2006-05-31 13:36  we7u
+
+	* src/db.c: Added some comments.
+
+2006-05-31 12:57  we7u
+
+	* src/: db.c, wx.c: Fixing the backwards conversions for wind speed
+	  for Peet Bros.  Ultimeter-II weather stations.  The correct units
+	  are km/h if the sentence begins with '#', and mph if the sentence
+	  begins with '*'.
+
+2006-05-31 12:30  we7u
+
+	* src/wx.c: Changes to comments/added some comments.
+
+2006-05-31 11:39  we7u
+
+	* src/wx.c: Zeroing the first two digits on wind speed for Peet
+	  Bros 2k as per the docs.
+
+2006-05-31 11:25  we7u
+
+	* src/wx.c: Changing a few variables to make the code more
+	  consistent.  Instead of pointing back to the original data to
+	  check for ">7", we look at the first character of our substring
+	  temp_data1[0].
+
+2006-05-31 11:09  we7u
+
+	* src/wx.c: Fixes for Peet weather stations, negative value
+	  decoding.
+
+2006-05-30 13:06  we7u
+
+	* src/map_gnis.c: Fixes to make Xastir handle the type of GNIS
+	  files found at:
+	  <http://geonames.usgs.gov/domestic/download_data.htm> which have
+	  shorter lines than the ones at:
+	  <http://geonames.usgs.gov/stategaz/>
+
+2006-05-30 11:50  we7u
+
+	* src/interface.c: Really complicated fix for Xastir dropping the
+	  last character of a packet.  A fix for the last fix I put in.
+
+2006-05-30 09:07  we7u
+
+	* src/db.c: Changed one comment.
+
+2006-05-30 08:18  we7u
+
+	* src/: database.h, db.c, interface.c, main.c: A bug fix for KISS
+	  or AGWPE ports.  The AX.25 header increases in size when it gets
+	  converted to TAPR2-style headers.  If there were enough
+	  digipeaters in the path then the complete packet can get
+	  truncated on the tail-end.  This patch fixes it by allocating a
+	  separate buffer that is quite large for each packet before the
+	  header decoding function.
+
+2006-05-17 12:28  we7u
+
+	* src/db.c: Fixing the reply-ack problem during messaging.  It was
+	  an off-by-one error.	Our ack_string looked like "}5o" instead of
+	  "5o", which made the comparison fail.
+
+2006-05-13 09:27  we7u
+
+	* src/Makefile.am: Adding rpl_malloc.h to the build.
+
+2006-05-12 13:32  tvrusso
+
+	* FAQ: Add command for converting Root files to new scheme.
+
+	  Of course, if someone could check this file out to see the
+	  commands, they've already done the conversion...
+
+2006-05-12 13:05  we7u
+
+	* scripts/do_xastir_release_dev: Fixing a typo.
+
+2006-05-12 13:03  we7u
+
+	* install-xastir: Updating to the latest SourceForge CVS server
+	  names.
+
+2006-05-12 13:00  we7u
+
+	* scripts/: do_xastir_release_dev, do_xastir_release_stable:
+	  Updating to correspond to latest CVS server names.
+
+2006-05-12 12:44  we7u
+
+	* FAQ, README.CVS, README.win32: Updating the CVS instructions to
+	  correspond to the changes implemented today on SourceForge.
+
+2006-05-12 12:44  we7u
+
+	* config/tnc-startup.d700: Adding "HEADERLN off", which we appear
+	  to have missed at some point.
+
+2006-05-04 08:01  we7u
+
+	* README.win32: Added a note about what to call COM1/COM2 in
+	  Cygwin.
+
+2006-04-29 10:19  tvrusso
+
+	* symbols/symbols.dat: Change \V symbol (VORTAC) to something that
+	  looks like what the other APRS codes use, matching the VORTAC
+	  symbol on aviation charts.
+
+2006-04-24 12:21  we7u
+
+	* src/: alert.c, awk.c, bulletin_gui.c, color.c, datum.c, db.c,
+	  dbfawk.c, draw_symbols.c, fcc_data.c, festival.c, geo-find.c,
+	  geocoder_gui.c, gps.c, hashtable.c, hashtable_itr.c, hostname.c,
+	  igate.c, interface.c, interface_gui.c, io-common.c, io-mmap.c,
+	  lang.c, list_gui.c, locate_gui.c, location.c, location_gui.c,
+	  macspeech.c, main.c, map_WMS.c, map_cache.c, map_dos.c,
+	  map_gdal.c, map_geo.c, map_gnis.c, map_pdb.c, map_shp.c,
+	  map_tif.c, map_tiger.c, maps.c, messages.c, messages_gui.c,
+	  objects.c, rotated.c, rpl_malloc.c, shp_hash.c, snprintf.c,
+	  sound.c, testawk.c, track_gui.c, util.c, view_message_gui.c,
+	  wx.c, wx_gui.c, x_spider.c, xastir_udp_client.c: More fixes for
+	  rpl_malloc, plus made the callouts for config.h more consistent.
+
+2006-04-24 10:20  we7u
+
+	* src/: Makefile.am, festival.c, rotated.c, util.c, util.h:
+	  Separating out the rpl_malloc code so that it can be used in
+	  other programs like testawk.
+
+2006-04-24 10:19  we7u
+
+	* src/: rpl_malloc.c, rpl_malloc.h: Separating out the rpl_malloc
+	  stuff so that it can be used in other programs like testawk.
+
+2006-04-21 14:01  we7u
+
+	* src/db.c: Correcting spelling in one comment.
+
+2006-04-21 13:51  we7u
+
+	* src/db.c: This change clears the transmitted message so it won't
+	  get transmitted again after a REJ packet, and gets rid of a
+	  printf to STDERR for each REJ.
+
+2006-04-21 12:58  we7u
+
+	* src/db.c: Added support for REJ packets, including igating of
+	  same.  Yet to be tested.
+
+2006-04-21 12:57  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added a "*REJECT*"
+	  string for REJ packets.
+
+2006-04-20 09:47  we7u
+
+	* README.win32: A tweak by Wes Johnston for getting bootstrap.sh to
+	  run properly.
+
+2006-04-20 08:05  we7u
+
+	* src/wx.c: Reverting back to the code for version 1.54, as the
+	  rounding for negative numbers wasn't done correctly and caused
+	  more harm than good.
+
+2006-04-20 07:22  we7u
+
+	* symbols/: alert.xbm, flood.xbm, red_flag.xbm, snow.xbm,
+	  tornado.xbm, wind.xbm, winter_wx.xbm, wntr_strm.xbm: Thanks to
+	  Jason Winningham, kg4wsv, for these weather alert pics that stack
+	  up much more nicely than the originals, while leaving more of the
+	  map below visible.
+
+2006-04-10 07:31  we7u
+
+	* scripts/get-maptools.sh: Script to get/install several of the map
+	  libraries, written by Dan Brown, N8YSZ.
+
+2006-04-05 09:13  we7u
+
+	* scripts/Makefile.am: Adding two of the newer scripts into the
+	  Makefile.
+
+2006-04-05 09:09  we7u
+
+	* README.win32: A tweak by Joe Cotton to get the finger command
+	  working in Xastir/Cygwin.
+
+2006-03-16 18:32  tvrusso
+
+	* INSTALL: Put the word "shapelib" closer to the place where we
+	  explain how to install it, so it is more quickly found by a
+	  search with "less" or "grep".
+
+2006-03-16 00:03  tvrusso
+
+	* README.MAPS: Fixx mispleling.
+
+2006-03-16 00:02  tvrusso
+
+	* README.MAPS: Added a little commentary about the mrsiddecode
+	  program.
+
+2006-03-13 17:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/objects.c: Shortening "Area" to
+	  "A" for CAD objects.	Also shortening the unit descriptions.
+
+2006-03-13 17:32  we7u
+
+	* src/db.c: Refusing to do the emergency popups until/unless we
+	  have a position for a station.  It's hard to help someone if we
+	  don't know where they are at.  This keeps Xastir from annoying
+	  the crap out of people every 30 minutes if a posit for that
+	  station isn't coming in, but a packet with certain keywords _is_
+	  coming in regularly.
+
+2006-03-10 12:56  we7u
+
+	* INSTALL: Added another note about libtiff-3.8.0
+
+2006-03-10 12:45  we7u
+
+	* INSTALL: Adding solution text regarding the libgdal/libgeotiff
+	  GTIFProj4ToLatLong problem.
+
+2006-03-10 12:28  tvrusso
+
+	* README.MAPS: Fix a handful of mispleellings and mistales.
+
+2006-03-10 12:09  tvrusso
+
+	* README.MAPS: Rearrange some of the discussion of how to
+	  manipulate randomly mutilated GeoTIFF files.
+
+2006-03-10 08:16  we7u
+
+	* README.MAPS: Adding a section about using gdal_translate to
+	  convert crappy geoTIFF's to usable ones.  Thanks to Tom Russo for
+	  the info on how to do this.
+
+2006-03-10 08:15  we7u
+
+	* INSTALL: Slightly changing some wording in the gdal section.
+	  Nothing of importance.
+
+2006-03-09 12:47  we7u
+
+	* INSTALL: Updating various library revision numbers.  Added a note
+	  about a possible geoTIFF conflict when installing GDAL.
+
+2006-03-09 12:46  we7u
+
+	* src/map_tif.c: Making sure that Proj.4 error messages appear only
+	  under the correct circumstances.
+
+2006-03-08 18:43  we7u
+
+	* src/db.c: Initial implementation of a distance check for
+	  warnings/alerts.  Default is set to 280 miles or kilometers
+	  (whichever mode you are set in), and the check defaults to ON,
+	  meaning it will check each time whether the station is within
+	  that distance.  This version has no user controls for the new
+	  functionality implemented yet.
+
+2006-03-07 18:44  we7u
+
+	* src/wx.c: Fixing the rounding for some of the values that can be
+	  negative, coming from weather stations.
+
+2006-03-07 16:41  we7u
+
+	* FAQ, README.Getting-Started, README.win32: Updating/Adding
+	  instructions for snagging NWS files via new script.
+
+2006-03-07 09:56  we7u
+
+	* README.MAPS: Adding filename patterns to the NWS file
+	  descriptions.
+
+2006-03-07 09:56  we7u
+
+	* scripts/get-NWSdata: Adding the fire weather zones to the mix.
+
+2006-03-07 09:05  we7u
+
+	* README.MAPS: Adding a bit about the get-NWSdata script.
+
+2006-03-07 09:04  we7u
+
+	* scripts/get-NWSdata: Modified the script to do one
+	  download/unzip/delete the .zip file, then start on the next.
+	  This will keep disk space requirements down plus not have the
+	  .zip files hanging around when we're all done.
+
+2006-03-07 08:53  we7u
+
+	* scripts/get-NWSdata: A new script to fetch NWS data files used
+	  for weather alerts.  Curt, WE7U and Steven, WM5Z had a hand in
+	  writing it.
+
+2006-03-03 12:31  we7u
+
+	* src/db.c: Checking for 8-bit characters in Mic-E packets, except
+	  for the case of 8-bit telemetry extension fields where we skip
+	  the check.
+
+2006-03-03 08:19  we7u
+
+	* src/track_gui.c: Re-enabling the popup on findu track download
+	  failure, as it doesn't appear to be the source of James Ewen's
+	  segfaults when his DNS failure occurs.  It appears to be a
+	  segfault from libcurl itself.
+
+2006-03-02 14:53  we7u
+
+	* README.win32: Added a note about compiling libproj into gdal
+	  statically in order to install on Cygwin.
+
+2006-03-01 10:37  we7u
+
+	* config/tnc-startup.thd7: Commenting out the hbaud line and adding
+	  a comment about it.
+
+2006-03-01 08:30  we7u
+
+	* README.Contributing: Added a note about core files appearing
+	  where you least expect them.
+
+2006-03-01 08:02  we7u
+
+	* src/track_gui.c: Adding comments near another popup message that
+	  could conceivably cause segfaults:  The "Success" message from
+	  fetching a findu trail.  This particular popup has worked
+	  properly for me with no segfaults so far.  We may need to
+	  investigate whether multiple threads writing to X11 at the same
+	  time can cause segfaults.  I believe I've seen this in other
+	  cases, but my memory may be faulty on this matter.
+
+2006-02-28 11:29  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/maps.c, src/maps.h,
+	  src/xa_config.c: Checking in mods by Dalen Kruse, KC0OVU, which
+	  implement a timing slider for snapshots with a range from 1 to 30
+	  minutes.
+
+2006-02-28 00:01  we7u
+
+	* src/track_gui.c: Getting rid of the GUI stuff in fetch findu
+	  trail:  It happens in a separate thread now and we can't write to
+	  the GUI from two threads at once due to possible segfaults.
+
+2006-02-27 13:02  we7u
+
+	* src/wx.c: A fix for negative values being interpreted incorrectly
+	  due to varying sizes of INT on different systems.
+
+2006-02-27 11:40  we7u
+
+	* config/tnc-startup.thd7: Changing HBAUD to 9600 so that it
+	  matches the default serial port speed.
+
+2006-02-24 19:01  tvrusso
+
+	* src/db.c: Fix appallingly stupid mistake in passing arguments to
+	  XtVaSetValues.
+
+	  I coulda *sworn* I had just copied what was already there, but
+	  apparently not.
+
+	  This fixes the problem where the Incoming Data scrolled text
+	  widget was not scrolling to the bottom of the incoming data as
+	  new stuff was added.
+
+2006-02-24 10:38  tvrusso
+
+	* src/db.c: Complete refactor of how the "packet_data_string" stuff
+	  is updated and displayed.
+
+	  We no longer do "memmove" to cycle old data out of the array, but
+	  rather use a two-dimensional array of strings treated as a ring.
+	  Data is shifted out of the Display Incoming Data dialog box using
+	  XmReplaceText calls.
+
+	  I have tested this out in several ways and it appears to function
+	  precisely as the old one was intended to do.	This *might* be the
+	  solution to the sporadic segfaults we've been seeing and the less
+	  harmful "line too long for array" warnings.
+
+2006-02-23 16:38  we7u
+
+	* src/db.c: Add a null pointer check to delete_station_memory().
+	  Changed an "if" to an "else" clause in insert_new_station(),
+	  which just made the code slightly simpler but didn't change any
+	  operation.  Multiple comment changes.
+
+2006-02-23 16:01  we7u
+
+	* src/xa_config.c: Increasing the default for Internet Map Timeout
+	  from 90 to 120 seconds.
+
+2006-02-23 15:59  we7u
+
+	* src/util.c: Adding messages something like "Possible timeout, try
+	  increasing Internet Map Timeout" to the libcurl and wget code.
+
+2006-02-22 08:53  chicoreus
+
+	* src/maps.c: Adding grid labels for UTM major grid.  All grid
+	  types and resolutions now have some kind of labeling available.
+
+2006-02-22 08:51  chicoreus
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added metadata
+	  text for UTM major zones.
+
+2006-02-19 12:50  rzg
+
+	* src/dbfawk.c:
+	  Small memory leak found by valgrind; I think this should fix it.
+
+2006-02-19 12:02  tvrusso
+
+	* scripts/object2shp.pl: Bug fix.  Make sure to ignore comment
+	  lines in the object file, or any other lines that don't start
+	  with semicolon.
+
+2006-02-19 11:56  tvrusso
+
+	* README.MAPS: Add explanation of how to use object2shp.pl into
+	  README.MAPS under the "Rolling your own shapefile maps" section.
+
+2006-02-19 11:48  tvrusso
+
+	* scripts/: Makefile.am, object2shp.pl: Per discussion on xastir
+	  mailing list, a script to create shapefile maps from the
+	  object.log file.  This will enable quick and dirty generation of
+	  special purpose map overlays by plunking down objects, creating
+	  shapefiles, then deleting the objects.
+
+2006-02-16 21:50  we7u
+
+	* src/: database.h, db.c, list_gui.c: Changing the names of
+	  pointers so that their function is more easily recognizable.
+
+2006-02-16 12:45  we7u
+
+	* src/x_spider.c: Added more output messages in case of error which
+	  suggest killing old Xastir processes in order to remove the
+	  error.
+
+2006-02-16 12:44  we7u
+
+	* src/: db.c, messages.c: Fixing up msg_data_add() so that we can
+	  tell when we've rejected a message.  Tweaked the code which
+	  invokes it so that it knows the difference between
+	  new/old/rejected messages.
+
+2006-02-15 08:46  chicoreus
+
+	* src/: maps.c, maps.h: Refinements to the calculation of latitude
+	  and longitude grid spacing.  Triming the latitude and longitude
+	  strings in the grid border when zoomed out.  Reduced the number
+	  of variables being passed in the functions called by draw_grid()
+	  by moving them to function calls or constants.
+
+2006-02-14 14:00  we7u
+
+	* src/db.c: Initializing struct pointers to NULL right after malloc
+	  of the struct, before we try inserting it into any linked lists.
+
+2006-02-14 13:11  we7u
+
+	* src/: database.h, db.c, gps.c, igate.c, objects.c: Converting all
+	  MAX_TNC_LINE_SIZE (was 300) to MAX_LINE_SIZE (currently 512).
+	  Just simplifying things.
+
+2006-02-14 12:07  we7u
+
+	* src/db.c: Printing out ALL of the guard bands that get corrupted,
+	  not just the first one that's noticed.
+
+2006-02-14 11:59  we7u
+
+	* src/db.c: Adding a couple more guard bands, changing them to only
+	  10 chars each, making the error text print out which guard band
+	  was corrupted.
+
+2006-02-14 11:34  we7u
+
+	* src/db.c: Making the Incoming Data display's char array
+	  manipulation code a bit less scary.  It had the potential to
+	  overflow if conditions were just right, but the conditions were
+	  extremely unlikely to occur.
+
+2006-02-14 11:33  we7u
+
+	* src/interface.c: Bumping up the sizes of some char arrays.  Just
+	  because.  Probably don't help much, but don't hurt either.
+
+2006-02-14 11:32  we7u
+
+	* src/main.h: Removing some unused defines.
+
+2006-02-13 12:30  we7u
+
+	* src/: db.c, interface.c, interface.h, main.c: Adding guard bands
+	  around the main station pointer variables, plus code to check for
+	  intrusion into those guard bands.  This may help us to find the
+	  current segfault problem.
+
+2006-02-12 16:13  chicoreus
+
+	* help/help-English.dat: Changing the grid border help to include
+	  latitude and longitude.
+
+2006-02-12 16:10  chicoreus
+
+	* src/maps.c: First cut at an algorithmic method for determining
+	  the spacing of latitude and longitude grid lines at a scale
+	  appropriate for the current window size and map zoom.
+
+2006-02-12 10:03  we7u
+
+	* src/db.c: Correcting some debug output message text.
+
+2006-02-11 18:10  we7u
+
+	* src/db.c: Doing some more error-checking in the station record
+	  pointers.  We do an abort() if we end up with dangling pointers,
+	  which should give us a core dump immediately.
+
+2006-02-10 12:27  we7u
+
+	* REGRESSION_TESTS, configure.ac: Tweaks to add more regression
+	  tests and format the output so that it's easier to read.
+
+2006-02-10 11:13  tvrusso
+
+	* README.Contributing: Add a section on using separate "build
+	  directories" to maintain specialized builds rather than building
+	  in the source tree.
+
+2006-02-09 17:08  we7u
+
+	* src/maps.c: Fixes for the map grid segfault problem.
+
+2006-02-09 15:14  tvrusso
+
+	* README.Contributing: Change commentary on how to do debugging
+	  builds.
+
+2006-02-09 14:32  we7u
+
+	* README.Contributing: Adding a debugging note from Tom Russo.
+
+2006-02-09 13:27  tvrusso
+
+	* acinclude.m4: Change XASTIR_COMPILER_FLAGS so that it doesn't
+	  insert "-g -O2" unconditionally.  That is unnecessary since we
+	  call AC_PROG_CC, which *conditionally* inserts "-g -O2" into
+	  CFLAGS if the user hasn't specified CFLAGS on the configure line.
+
+	  This should allow users to build specialized debugging versions
+	  such as ./configure CFLAGS="-O -g -fno-inline" and not have
+	  configure stick a "-O2" in unbidden.
+
+2006-02-09 12:41  we7u
+
+	* src/maps.c: A temporary fix to skip computing the UTM/MGRS grid
+	  if we run into a problem, before we segfault.
+
+2006-02-09 12:14  we7u
+
+	* src/maps.c: Adding some comments.
+
+2006-02-09 12:12  we7u
+
+	* src/maps.c: Again splitting the minor UTM grid stuff into
+	  separate functions.
+
+2006-02-09 11:40  we7u
+
+	* src/maps.c: Reorganizing the draw_grid() function.  Breaking it
+	  up into smaller pieces.
+
+2006-02-08 07:11  we7u
+
+	* src/main.c: Checking for proper status of unlink in
+	  pid_file_check().
+
+2006-02-08 06:28  we7u
+
+	* src/main.c: Removing some code that doesn't get used in the RINO
+	  download section of the switch.
+
+2006-02-06 18:37  we7u
+
+	* src/maps.c: Commenting out unnecessary code.
+
+2006-02-06 18:33  we7u
+
+	* INSTALL, README.Getting-Started, UPGRADE, update-xastir:
+	  Clarifying the use of SUID root a bit.  Removing that command
+	  from update-xastir so that the default will be to create a core
+	  file.
+
+2006-02-06 13:35  we7u
+
+	* src/maps.c: Some fixes for segfaults and divide-by-zero faults in
+	  the draw_grid() function.  At least one more segfault path
+	  remains in this body of code.
+
+2006-02-06 09:03  we7u
+
+	* README.Contributing: Adding more info to the debugger info.
+
+2006-02-06 08:21  we7u
+
+	* src/db.c: Tweaking Mic-E decoding logic to properly decode
+	  overlay characters.
+
+2006-02-03 10:09  chicoreus
+
+	* src/util.h: Missing an extern
+
+2006-02-03 09:47  chicoreus
+
+	* src/: maps.c, util.c, util.h: Adding MGRS to labeled grid border.
+
+2006-02-03 09:46  chicoreus
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing grid
+	  metadata text to allow MGRS support.
+
+2006-02-02 14:02  we7u
+
+	* src/maps.c: Extending some char arrays so that they're long
+	  enough to hold the terminator.
+
+2006-02-02 10:58  chicoreus
+
+	* src/: main.c, maps.c, util.c, xastir.h: Added degree and minutes
+	  symbols to lat/long grid border labels by adding constants for
+	  convert_xastir_to_UTM() to produce strings containing these
+	  symbols.  Truncation of trailing zeroes on UTM grid labels, with
+	  number of zeroes removed depending on utm_grid_spacing_m.
+	  Changed following feedback from use of printed maps during a
+	  GPSAR training.  Added internationalization for lat/long and UTM
+	  grid border metadata.  Added metadata on top border for labeled
+	  lat/long grids.  Latitude drawn on both left and right borders.
+	  Put the xastir coordinate to MGRS conversion into a function that
+	  extracts the components of the MGRS string separately, then made
+	  convert_xastir_to_MGRS_str() a wrapper around this function in
+	  prepration for labeling the MGRS grid.
+
+2006-02-02 09:57  we7u
+
+	* README.Contributing: Adding info about core dumps and how to
+	  bring up a debugger.
+
+2006-02-02 08:49  we7u
+
+	* README.Getting-Started, src/main.c: Reversing the meaning of the
+	  "-t" command-line flag:  The segfault handler is now turned off
+	  by default (meaning we'll dump core instead).  The "-t" flag
+	  turns on the internal segfault handler now instead of disabling
+	  it.
+
+2006-02-02 08:04  we7u
+
+	* configure.ac: Commenting out the code that removed the "-g" GCC
+	  option.  As Tom pointed out, it was a bad idea.
+
+2006-02-02 07:29  chicoreus
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added
+	  internationalization strings for metadata line for top border of
+	  map when map grid border is displayed.
+
+2006-02-02 07:10  we7u
+
+	* src/util.c: A fix for the missing UTM grids with gcc-4.x problem.
+
+2006-02-02 07:10  we7u
+
+	* src/maps.c: Changing one debug output line.
+
+2006-02-01 08:42  we7u
+
+	* acinclude.m4: Patching the search list for Berkely DB library by
+	  adding 4.3 and 4.4 search paths.
+
+2006-02-01 08:24  chicoreus
+
+	* src/maps.c: Added border labels for latitude and longitude grid.
+
+2006-01-31 10:32  chicoreus
+
+	* src/maps.c: More tuning of labeled border for UTM grid.  Added
+	  Zone number and letter in all four corners when two zones are
+	  shown.  All text in border changed to black with border color
+	  outline.  For two zones, northings for one zone appear on the
+	  left side of the screen northings for the other on the right.
+	  The left zone is labeled in black, the right zone labeled in
+	  blue.  Minor fixes to turn off display of labels where they run
+	  off the screen.
+
+2006-01-30 07:31  tvrusso
+
+	* configure.ac, src/maps.c: "roundf", recently used in maps.c, is a
+	  newer extension that is not present in systems that still have
+	  old C compilers.
+
+	  Insert a check for roundf, and a workaround for systems that
+	  don't support it.
+
+2006-01-28 11:21  we7u
+
+	* bootstrap.sh: Fixing the file test syntax to use Bourne syntax
+	  instead of Bash.
+
+2006-01-27 20:36  chicoreus
+
+	* src/maps.c: Minor changes and bug fixes to the UTM grid border
+	  labeling code.  Includes rounding of the grid labels to correctly
+	  label 10,000 m, 1,000m, and 100m grids, not just the 100m grid.
+
+2006-01-27 15:40  chicoreus
+
+	* src/: maps.c, rotated.c: Added code to RotatedTextItem in
+	  rotated.c library to handle special case of rotation of text 90
+	  degrees counter clockwise.  In this case, text is rotated by
+	  directly transposing x and y coordinates, rather than by applying
+	  a sine and cosine transformation to rotate the text, something
+	  that produces an italic appearance to the rotated text (making it
+	  harder to read, especially when printed).  This change is to
+	  support more legible text on the labeled UTM grid on the border
+	  of the map, especially for producing maps to be printed.
+
+	  Also made minor changes to border label code in maps.c to make
+	  quick and dirty improvements to appearance.
+
+2006-01-27 08:30  we7u
+
+	* Davis/bootstrap.sh, LaCrosse/bootstrap.sh: Since the three
+	  bootstrap.sh scripts are the same anyway, run the one from one
+	  directory up instead so that we don't have to keep rev'ing all
+	  three of them when a change is needed.  Like, duh!
+
+2006-01-27 08:14  we7u
+
+	* Davis/bootstrap.sh, LaCrosse/bootstrap.sh: Updating for Solaris.
+
+2006-01-27 08:10  we7u
+
+	* bootstrap.sh: Removing the comment marks that I shouldn't have
+	  committed to CVS.
+
+2006-01-27 08:05  we7u
+
+	* bootstrap.sh: Updating for automake system directories on
+	  Solaris.
+
+2006-01-27 06:57  we7u
+
+	* README: Updating the SuSE 10 notes to mention libcurl-dev as
+	  well.
+
+2006-01-26 14:51  we7u
+
+	* Davis/src/Makefile.am: Installing the compiled db2APRS into the
+	  bin directory.
+
+2006-01-26 12:57  we7u
+
+	* scripts/BUILDRPMS: Getting rid of some shell warnings.
+
+2006-01-26 12:39  we7u
+
+	* Makefile.am, scripts/BUILDRPMS: Adding LaCrosse directory into
+	  the build.
+
+2006-01-26 11:06  we7u
+
+	* Davis/.cvsignore, LaCrosse/.cvsignore: Updating the list of files
+	  that CVS should skip.
+
+2006-01-26 08:59  we7u
+
+	* Davis/bootstrap.sh, LaCrosse/bootstrap.sh: Updating bootstrap.sh
+	  for separate weather apps so they are the same as the main Xastir
+	  bootstrap.sh
+
+2006-01-26 07:55  n0vh
+
+	* LaCrosse/: weatherdump.sql, src/Makefile.am: SQL file of open2300
+	  database
+
+2006-01-26 07:44  we7u
+
+	* Davis/: .cvsignore, src/.cvsignore: Adding .cvsignore files for
+	  the Davis directories to reduce the amount of "noise" that cvs
+	  status returns.
+
+2006-01-26 07:42  we7u
+
+	* LaCrosse/: .cvsignore, src/.cvsignore: Adding .cvsignore files
+	  for these two new directories so that cvs status doesn't return
+	  too many unneeded lines.
+
+2006-01-26 07:38  n0vh
+
+	* LaCrosse/src/open2300db2APRS.c: Fixed an issue with SIGPWR on
+	  non-Linux systems
+
+2006-01-26 07:38  n0vh
+
+	* LaCrosse/configure.ac: Minor updates to compile on non-linux
+	  systems
+
+2006-01-25 15:11  n0vh
+
+	* LaCrosse/README: Minor correction to directory in BUILD section
+
+2006-01-25 14:46  n0vh
+
+	* LaCrosse/README: Changed to make it more relavent to
+	  open2300db2APRS
+
+2006-01-25 12:34  n0vh
+
+	* LaCrosse/src/open2300db2APRS.c.bak: Not needed.
+
+2006-01-25 12:26  we7u
+
+	* LaCrosse/src/open2300db2APRS.c: Fixing a warning given by gcc-4.
+	  clen must be a socklen_t instead of an int.
+
+2006-01-25 11:52  n0vh
+
+	* LaCrosse/src/: Makefile, Makefile.in, open2300db2APRS,
+	  open2300db2APRS.o: Removed files that should be in CVS
+
+2006-01-25 11:50  n0vh
+
+	* LaCrosse/Makefile.am: Put back this needed file
+
+2006-01-25 11:49  n0vh
+
+	* LaCrosse/: Makefile, Makefile.am, Makefile.in, aclocal.m4,
+	  config.h, config.h.in, config.log, config.status, configure,
+	  stamp-h1: Removed files that should be there
+
+2006-01-25 11:36  n0vh
+
+	* LaCrosse/: AUTHORS, COPYING, ChangeLog, INSTALL, Makefile,
+	  Makefile.am, Makefile.in, NEWS, README, aclocal.m4, bootstrap.sh,
+	  config.h, config.h.in, config.log, config.status, configure,
+	  configure.ac, stamp-h1, src/Makefile, src/Makefile.am,
+	  src/Makefile.in, src/defs.h, src/open2300db2APRS,
+	  src/open2300db2APRS.c, src/open2300db2APRS.c.bak,
+	  src/open2300db2APRS.o: Support for LaCrosse WX-23xx weather
+	  station support
+
+2006-01-25 11:33  n0vh
+
+	* config/: language-English.sys, language-French.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Update for future
+	  LaCrosse 23xx weather station support.
+
+2006-01-25 11:32  n0vh
+
+	* config/language-Dutch.sys: Updated with future LaCrosse 23xx
+	  stuff.
+
+2006-01-25 08:46  chicoreus
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added missing
+	  "MAPFONT008|Border Labels||" to support user selectable font for
+	  drawing labels on the UTM tickmarks on the labled border.
+
+2006-01-23 21:46  we7u
+
+	* src/: maps.c, maps.h: Fixing up some function prototypes to get
+	  rid of some compiler warnings.
+
+2006-01-23 15:47  chicoreus
+
+	* config/language-English.sys, src/db.c, src/main.c, src/maps.c,
+	  src/xa_config.c, src/xastir.h: Drawing fonts with an outline on
+	  the border results in text that is very difficult to read on a
+	  printout.  Added a user selectable font for drawing labels on the
+	  UTM tickmarks on the labled border.
+
+2006-01-23 12:41  we7u
+
+	* src/map_tif.c: Getting rid of dependencies on cpl_csv.h, which
+	  contains a private (not public) interface.
+
+2006-01-23 12:02  we7u
+
+	* src/: main.c, main.h: Testing for old/new kernel based on number
+	  of signals available.  We then use this to decide whether to set
+	  "OLD_PTHREADS", which enables or disables the SIGUSR1 handler in
+	  the code.  Old kernels only has 32 signals, therefore Linux
+	  Pthreads used SIGUSR1 and SIGUSR2 in their implementation.  We
+	  use SIGUSR1 for our Snapshot-on-demand function, therefore we
+	  must disable this code if we're running older Pthreads on Linux.
+
+2006-01-23 12:00  we7u
+
+	* configure.ac, src/util.c: Testing for deprecated/new pthread
+	  functions, modifying code to correspond based on what's found.
+
+2006-01-20 13:15  we7u
+
+	* src/x_spider.c: Another small tweak for Linux Standard Base 3.0
+	  compliance.
+
+2006-01-20 09:58  we7u
+
+	* README: Tweaked the SuSE 10 notes regarding a bootstrap.sh
+	  warning.
+
+2006-01-20 08:52  we7u
+
+	* README, bootstrap.sh: Formatting changes to bootstrap.sh.  Added
+	  a section to README which details getting rid of an SuSE-10
+	  warning when running bootstrap.sh.
+
+2006-01-19 12:43  we7u
+
+	* README: Adding a note about SuSE 10.0 and problems with AX.25
+	  kernel mode.
+
+2006-01-19 12:24  we7u
+
+	* bootstrap.sh: Fixing a problem in Automake 1.9 (on SuSE 10 at
+	  least) where the mkinstalldir script doesn't get copied over by
+	  Automake.  We have to copy it over ourselves after we invoke
+	  Automake.
+
+2006-01-19 09:20  we7u
+
+	* REGRESSION_TESTS: Updated the format a bit.
+
+2006-01-19 09:17  we7u
+
+	* src/db.c: A fix for another killer packet.  This one had to do
+	  with a while loop overrunning an ack_string variable.  Changed to
+	  xastir_snprintf() functions there and it solved the immediate
+	  problem.
+
+2006-01-18 14:40  we7u
+
+	* src/map_tif.c: Commenting out an include because it causes an
+	  error on Cygwin.  Of course it causes a warning under gcc-4.0 on
+	  Linux when it's commented out...
+
+2006-01-18 12:13  we7u
+
+	* REGRESSION_TESTS: Updating the tests for LSB and to make them
+	  more convenient to run.
+
+2006-01-18 09:10  we7u
+
+	* FAQ: Adding some VNC configuration info.
+
+2006-01-18 08:50  we7u
+
+	* INSTALL: Updating/re-ordering the list of configure options.
+
+2006-01-18 08:49  we7u
+
+	* src/map_tif.c: Getting rid of some gcc-4.0 compiler warnings.
+
+2006-01-18 08:49  we7u
+
+	* Davis/src/db2APRS.c: Getting rid of a gcc-4.0 compiler warning
+	  about signedness.
+
+2006-01-18 08:48  we7u
+
+	* Davis/bootstrap.sh: Making the script parallel the main Xastir
+	  bootstrap script.
+
+2006-01-18 07:31  we7u
+
+	* src/interface_gui.c: Mods to comply with maximum baud rates
+	  allowed under LSB.
+
+2006-01-18 07:11  we7u
+
+	* acinclude.m4, configure.ac, src/util.c: Initial tweaks to help
+	  get Xastir compiled under Linux Standard Base 3.0 (LSB 3.0).
+	  Have more work to do to get there, but this is a good start.
+
+2006-01-18 07:00  we7u
+
+	* src/: main.c, map_cache.c: A fix for the X11 fault caused when
+	  the DB Library header/library versions don't match.  The code
+	  should now just disable map caching and keep right on going.
+
+2006-01-18 06:48  we7u
+
+	* src/x_spider.c: Changing one declaration to get rid of one gcc4.0
+	  warning.
+
+2006-01-17 13:06  we7u
+
+	* src/alert.c, src/awk.c, src/bulletin_gui.c, src/color.c,
+	  src/datum.c, src/db.c, src/dbfawk.c, src/draw_symbols.c,
+	  src/fcc_data.c, src/festival.c, src/geo-client.c, src/geo-find.c,
+	  src/geocoder_gui.c, src/gps.c, src/hashtable.c,
+	  src/hashtable_itr.c, src/hostname.c, src/igate.c,
+	  src/interface.c, src/interface_gui.c, src/io-common.c,
+	  src/io-mmap.c, src/lang.c, src/list_gui.c, src/locate_gui.c,
+	  src/location.c, src/location_gui.c, src/macspeech.c, src/main.c,
+	  src/map_cache.c, src/Makefile.am, src/map_WMS.c, src/map_dos.c,
+	  src/map_gdal.c, src/map_geo.c, src/map_gnis.c, src/map_pdb.c,
+	  src/map_shp.c, src/map_tif.c, src/map_tiger.c, src/maps.c,
+	  src/messages.c, src/messages_gui.c, src/objects.c,
+	  src/popup_gui.c, src/rac_data.c, src/rotated.c, src/shp_hash.c,
+	  src/snprintf.c, src/sound.c, src/testawk.c, src/track_gui.c,
+	  src/util.c, src/view_message_gui.c, src/wx.c, src/wx_gui.c,
+	  src/x_spider.c, src/xa_config.c, src/xastir_udp_client.c,
+	  AUTHORS, DEBUG_LEVELS, FAQ, INSTALL, LICENSE, Makefile.am, NEWS,
+	  README, README.CVS, README.Contributing, README.Getting-Started,
+	  README.MAPS, README.win32, REGRESSION_TESTS, UPGRADE,
+	  acinclude.m4, bootstrap.sh, changes.txt, configure.ac,
+	  install-xastir, update-xastir, xastir.1, help/Makefile.am,
+	  help/help-Dutch.dat, help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, m4/Makefile.am,
+	  scripts/Makefile.am, scripts/Xastir_tigerpoly.py,
+	  scripts/example_objects.log, scripts/fcc-get, scripts/get-gnis,
+	  scripts/get_shapelib.sh, scripts/inf2geo.pl, scripts/ozi2geo.pl,
+	  scripts/toporama250k.pl, scripts/toporama50k.pl,
+	  scripts/xastir-fixcfg.sh, scripts/xastir-migrate.sh: Updating
+	  copyright info.
+
+2006-01-17 13:03  we7u
+
+	* symbols/Makefile.am, symbols/symbols.dat, config/24kgrid.dbfawk,
+	  config/gps_wpt.dbfawk, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, config/nwsc_ddmmyy.dbfawk,
+	  config/tnc-startup.aea, config/tnc-startup.d700,
+	  config/tnc-startup.kam, config/tnc-startup.kpc2,
+	  config/tnc-startup.kpc3, config/tnc-startup.paccomm,
+	  config/tnc-startup.pico, config/tnc-startup.sys,
+	  config/tnc-startup.thd7, config/tnc-startup.tnc2,
+	  config/tnc-startup.tnc2-ui, config/tnc-stop.d700,
+	  config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui, config/Makefile.am,
+	  config/nwsmzddmmyy.dbfawk, config/nwsmzoddmmyy.dbfawk,
+	  config/nwsozddmmyy.dbfawk, config/nwsw_ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/nwszoddmmyy.dbfawk,
+	  config/predefined_EVENT.sys, config/predefined_SAR.sys,
+	  config/tgr2shp.dbfawk, config/tgr2shppoly.dbfawk,
+	  config/tgrcty.dbfawk, config/tgrkgl.dbfawk, config/tgrlk.dbfawk,
+	  config/tgrlpt.dbfawk, config/tgrlpy.dbfawk,
+	  config/tgrplc00.dbfawk, config/tgrwat.dbfawk,
+	  callpass/Makefile.am, callpass/callpass.c, Davis/Makefile.am,
+	  Davis/README, Davis/bootstrap.sh, Davis/configure.ac,
+	  Davis/src/Makefile.am, Davis/src/db2APRS.c, Davis/src/defs.h,
+	  src/alert.h, src/awk.h, src/bulletin_gui.h, src/color.h,
+	  src/database.h, src/datum.h, src/dbfawk.h, src/draw_symbols.h,
+	  src/fcc_data.h, src/festival.h, src/geo.h, src/gps.h,
+	  src/hashtable.h, src/hashtable_itr.h, src/hashtable_private.h,
+	  src/hostname.h, src/igate.h, src/interface.h, src/io.h,
+	  src/lang.h, src/leak_detection.h, src/list_gui.h, src/main.h,
+	  src/map_cache.h, src/maps.h, src/messages.h, src/objects.h,
+	  src/popup.h, src/rac_data.h, src/rotated.h, src/shp_hash.h,
+	  src/snprintf.h, src/symbols.h, src/track_gui.h, src/util.h,
+	  src/wx.h, src/x_spider.h, src/xa_config.h, src/xastir.h: Updating
+	  copyright info.
+
+2006-01-17 12:10  we7u
+
+	* scripts/BUILDRPMS: Correcting bugs that crept in.
+
+2006-01-17 11:58  we7u
+
+	* scripts/BUILDRPMS: Updating script for latest SuSE RPM build.
+
+2006-01-17 11:47  we7u
+
+	* INSTALL, README: Updating notes to call out latest packages.
+	  Adding SuSE 10.0 instructions to README.
+
+2006-01-16 10:21  we7u
+
+	* scripts/BUILDRPMS: Updating script for latest release numbers.
+
+2006-01-16 09:12  we7u
+
+	* configure.ac: Bumping version to 1.8.1 for new mods.
+
+2006-01-16 09:04  we7u
+
+	* configure.ac, scripts/do_xastir_release_dev,
+	  scripts/do_xastir_release_stable: Preparing for 1.8.0 release.
+
+2006-01-13 07:34  we7u
+
+	* bootstrap.sh: Changing the prompts a bit.  We now see a countdown
+	  to completion.
+
+2006-01-12 16:06  tvrusso
+
+	* README.MAPS: Fix error in command line for sorting the EN.dat
+	  file from FCC.
+
+2006-01-12 08:58  we7u
+
+	* config/language-German.sys: Another update from Rolf.
+
+2006-01-12 07:25  we7u
+
+	* config/language-German.sys: Updates by Rolf Bleher, DK7IN.
+	  Thanks!
+
+2006-01-11 12:28  we7u
+
+	* src/db.c: Processing/decoding the altitude extension on more
+	  packet types.  Altitude wasn't being decoded for some weather and
+	  grid packets.  It is now.
+
+2006-01-11 12:27  we7u
+
+	* help/help-English.dat: Adding some notes about lack of altitude
+	  in compressed-mode posits.
+
+2006-01-11 07:43  we7u
+
+	* src/db.c: Fixing a decoding bug w.r.t. lower-case N/S/E/W in a
+	  couple of types of packets.
+
+2006-01-10 09:03  francais1
+
+	* config/language-French.sys: More updates from Jacques Chion, with
+	  some tweaks and translation of GPSS* strings.
+
+2006-01-09 14:10  we7u
+
+	* config/language-Dutch.sys: Updates by Han Sytsma, PE1FAM.
+	  Thanks!
+
+2006-01-06 18:45  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Fixing a bug on the GPS
+	  Status dialog.  It wasn't reporting the correct status for WAAS.
+	  Corrected that and added more possibilities for status.
+
+2006-01-03 13:59  chicoreus
+
+	* src/db.c: Minor bugfix: Range Scale and Scale bar were drawn
+	  displaced when border was on and grid was off (even though border
+	  is only shown when grid is on).
+
+2006-01-02 13:34  we7u
+
+	* src/db.c: Fixing segfault that occurs in extract_multipoints()
+	  when data == NULL.
+
+2005-12-31 18:38  chicoreus
+
+	* help/help-English.dat: Added Documentation of Map/Enable Map
+	  Border.
+
+2005-12-31 07:13  chicoreus
+
+	* src/maps.c: Bug fixes in the labeling of utm zones, northing
+	  lines, and easting lines when the grid is labeled.  When grid is
+	  finely spaced on the screen, only alternate lines are labeled.
+	  Grid and zones are labeled correctly and reasonably most of the
+	  time when more than one lettered zone row appears on the screen.
+	  Still has some problems, but works for most places.
+
+2005-12-29 13:11  we7u
+
+	* INSTALL: Added instructions for updating /etc/ld.so.conf.d/
+	  directory for those systems that use this alternate method.
+	  Courtesy of Dale, KB9JJA.  Thanks!
+
+2005-12-20 18:01  chicoreus
+
+	* src/: main.c, objects.c: Performance tuning: Moved call to
+	  redraw_symbols out of CAD_vertice_allocate to prevent repeated
+	  redrawing on each vertex of each cad object loaded from a file at
+	  startup.
+
+2005-12-20 10:24  chicoreus
+
+	* src/maps.c: In trying to work out what draw_grid is doing, added
+	  some documentation to the utm_grid structures.  Added a test
+	  inside draw_grid so that the utm grid labeling code is only
+	  running for utm_grid.zone elements that contain rows and columns.
+
+2005-12-19 10:18  chicoreus
+
+	* src/maps.c: Minor bugfix and additional comments on code for
+	  labeling UTM grid.  Changed format to include leading zeroes for
+	  easting and northing.
+
+2005-12-19 09:40  chicoreus
+
+	* README.MAPS: Added brief discussion of gdalinfo and
+	  gdal_translate for handling geotiff files that aren't in byte
+	  form or contain multiple bands.
+
+2005-12-16 14:13  chicoreus
+
+	* src/maps.c: Added the ability to draw a 1 pixel outline in a
+	  different color to rotated text in
+	  draw_rotated_label_text_common() and some of its wrappers.
+
+2005-12-16 14:09  chicoreus
+
+	* src/xa_config.c: Making draw_labeled_grid_border persistent
+	  between restarts.
+
+2005-12-15 14:10  chicoreus
+
+	* src/: db.c, main.c, main.h, maps.c: First cut at adding a labeled
+	  border to the map shown on the screen for printing.  This can be
+	  used, for example, to print maps with a labeled UTM grid for a
+	  SAR task team showing the area they are to search.  Metadata
+	  about the map is displayed in the top border, coordinates of grid
+	  lines are displayed on the bottom and right borders (to make it
+	  easier for people to correctly read and report UTM coordinates in
+	  the form zone easting northing.  The labeled border is displayed
+	  when both the grid and the border are enabled.  There are still
+	  problems and missing features.  The rotated font on the right
+	  border is not the pretty font used on the rest of the border.
+	  The border and grid labels are only drawn for a UTM grid, not for
+	  a Lat/Lon grid.  Zone designators are not properly displayed when
+	  more than one zone is visible on the screen.	When grid lines are
+	  closely spaced, the grid labels overlap on the screen.
+
+2005-12-15 10:31  we7u
+
+	* README.win32: Fixing a typo.
+
+2005-12-15 10:24  chicoreus
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: First rough cut at
+	  adding a labeled border to a map to allow the printing of
+	  arbitrary maps with a labeled grid (that can, for example, be
+	  printed and given to SAR task teams).  If the map grid is
+	  enabled, and the border is enabled, a white border is drawn as
+	  part of the grid and labels for each grid line are added in this
+	  border.  Metadata describing the map are also added in the
+	  border.  This is a first rough cut with several problems.  It is
+	  only implemented for a UTM grid, not for a Lat/Long grid.  The
+	  rotated numbers do not use the same clean font as the non-rotated
+	  numbers.  The labels in the border are not clearly
+	  distinguishable when the grid is tightly spaced on the screen.
+	  The zone labels do not work properly when more than one zone is
+	  on the screen.  The choice of labeling the bottom border and the
+	  right border with the UTM grid line easting and northings is
+	  deliberate to help people to correctly read the map and report
+	  UTM coordinates in the form: zone easting northing.
+
+2005-12-13 14:11  we7u
+
+	* config/Makefile.am: Correcting the name of the dbfawk file that
+	  we want automatically removed.  I forgot the underline first time
+	  around.
+
+2005-12-13 07:54  we7u
+
+	* src/objects.c: Tweaking a debug statement so we don't get a
+	  segfault if we hit a null pointer.
+
+2005-12-12 18:50  chicoreus
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added localization
+	  strings for map display of CAD object metadata.  Added update of
+	  CAD objects on toggle of display of metadata.
+
+2005-12-12 14:56  chicoreus
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/database.h, src/main.c,
+	  src/main.h, src/objects.c, src/objects.h: Adding more user
+	  interface elements to CAD Object display 1) Clarifying user side
+	  handling of raw_probability as a percent 2) Allow user to set CAD
+	  boundary line type 3) Allow user to toggle on and off display of
+	  CAD Polygons, Label, Area,	and probability.
+
+2005-12-11 10:20  we7u
+
+	* src/main.c: Fixing the Station->Configure submenu.  Wasn't
+	  working on Lesstif but was fine on OpenMotif.  Should work on
+	  both now.
+
+2005-12-07 18:55  chicoreus
+
+	* help/help-English.dat: Edited CAD object text to reflect the
+	  movement of the CAD object functions from the mouse menu to the
+	  toolbar and the View and Map menus.  Added some text for
+	  Probability Circle Objects.
+
+2005-12-07 17:04  we7u
+
+	* src/interface.c: Only twiddle DTR on HSP ports if global transmit
+	  is enabled.
+
+2005-12-07 17:02  we7u
+
+	* src/objects.c: Very minor formatting change.	No code changes.
+
+2005-12-07 12:40  we7u
+
+	* config/Makefile.am: Automating the deletion of the
+	  nwsfzddmmyy.dbfawk file from the /usr/local/share/xastir/config
+	  directory during install.  We don't use it anymore and it causes
+	  problems if present.
+
+2005-12-07 10:38  we7u
+
+	* src/interface.c: Patch by Paul Morris, modified slightly by me,
+	  to make objects work for the case when global transmits have been
+	  disabled.
+
+2005-12-07 09:32  tvrusso
+
+	* config/: Makefile.am, nwsfz_ddmmyy.dbfawk: Remove unnecessary
+	  (and problematic) nwsfz_ddmmyy.dbfawk file.
+
+2005-12-07 08:09  we7u
+
+	* src/map_gdal.c: Moving some struct typedef's and nested functions
+	  out of the main function so that it will compile with latest
+	  MacOSX GCC compiler.
+
+2005-12-06 22:41  we7u
+
+	* src/map_shp.c: Made code more correct by changing alert->title to
+	  modified_title in a couple of places.  modified_title is a copy
+	  of alert->title so the real-world effects of this change are
+	  little to none.  Tweaked some comments in the area as well.
+
+2005-12-06 19:04  tvrusso
+
+	* config/nwsmzddmmyy.dbfawk: Fix incorrect key generation for
+	  mzddmmyy.shp file.
+
+	  The key produced by the dbfawk rule must match the key that comes
+	  from the NWS alert.  These will generally be "XX_Zyyy".  The "ID"
+	  field of the mzddmmyy.dbf record is of form "XXZyyy", and prior
+	  to this commit it was used directly as the key, thereby never
+	  matching any alerts.	This fix inserts the _ character after the
+	  first to characters of the ID field to produce a usable key.
+
+2005-12-06 13:35  we7u
+
+	* src/map_shp.c: Added more debugging text for dbfawk and wx
+	  alerts.
+
+2005-12-06 12:53  we7u
+
+	* src/maps.c: Correcting some comments.
+
+2005-12-06 12:50  we7u
+
+	* src/maps.c: Adding a bit more text to one wx alert debug message.
+
+2005-12-06 12:26  we7u
+
+	* src/interface.c: Moving a nested function so that it is no longer
+	  nested.  This is necessary in order to compile on MacOSX with
+	  their latest GCC compiler.
+
+2005-12-06 11:34  we7u
+
+	* src/util.c: Changing a nested function to non-nested in order to
+	  enable compiling with the latest MacOSX compiler.
+
+2005-12-04 19:05  we7u
+
+	* src/: main.c, xastir.h, festival.c: Adding a "Test" button to the
+	  Configure->Speech dialog for testing the speech subsystem and for
+	  adjusting the audio levels (by an external program).
+
+2005-12-01 11:32  we7u
+
+	* update-xastir: Changing the "make" step so that it doesn't run as
+	  root.
+
+2005-12-01 09:22  we7u
+
+	* src/map_gdal.c: Commenting out and include that we're currently
+	  not using.
+
+2005-11-29 22:36  we7u
+
+	* src/map_pdb.c: Implementing the same sorts of map interruption
+	  capability for PocketAPRS maps that we just did for the other
+	  types of maps.
+
+2005-11-28 19:16  we7u
+
+	* src/: map_WMS.c, map_gdal.c, map_geo.c, map_shp.c, map_tif.c,
+	  map_tiger.c: Adding more map interrupt code, to make it
+	  easier/faster to interrupt map drawing by panning or zooming.
+
+2005-11-28 12:51  we7u
+
+	* src/map_shp.c: Adding capability to interrupt map drawing and
+	  start over in the inner loops of the GNIS and DOS map drawing
+	  functions.  This makes panning or zooming cause an interrupt much
+	  quicker while drawing maps, allowing Xastir to restart the redraw
+	  process sooner.
+
+2005-11-28 12:43  we7u
+
+	* src/: map_dos.c, map_gnis.c: Adding capability to interrupt map
+	  drawing and start over in the inner loops of the GNIS and DOS map
+	  drawing functions.  This makes panning or zooming cause an
+	  interrupt much quicker while drawing maps, allowing Xastir to
+	  restart the redraw process sooner.
+
+2005-11-23 14:37  we7u
+
+	* scripts/do_xastir_release_stable: Adding another admin script so
+	  that it won't get lost.
+
+2005-11-23 14:32  we7u
+
+	* scripts/do_xastir_release_dev: Adding another couple of admin
+	  scripts so they won't ever get lost.
+
+2005-11-23 14:28  we7u
+
+	* scripts/STABLE: Adding another admin script to the repository so
+	  that it won't get lost.
+
+2005-11-23 14:27  we7u
+
+	* scripts/BUILDRPMS: Adding the RPM Build script so that it will be
+	  available as an example to others.
+
+2005-11-23 11:34  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/map_cache.c: Disabling map
+	  caching if dblib header/library mismatch, to help prevent
+	  segfaults.  Also doing a popup now when this condition is found
+	  as Xastir starts up.
+
+2005-11-23 11:33  we7u
+
+	* NWS-TEST.log: Changed some comments.
+
+2005-11-23 11:33  we7u
+
+	* README.MAPS: Added a blurb about how to test weather alert
+	  functionality.
+
+2005-11-22 14:31  we7u
+
+	* NWS-TEST.log: Added some more notes.
+
+2005-11-22 12:49  we7u
+
+	* NWS-TEST.log: Moved one OR alert over to the coast and made it
+	  blue, to stand out more against the other alerts.
+
+2005-11-22 12:35  we7u
+
+	* NWS-TEST.log: Moving all of the tests to the Northwest region so
+	  we don't have to look all over the country for them.
+
+2005-11-22 11:57  we7u
+
+	* NWS-TEST.log: Changing the colors for adjacent alerts, making it
+	  easier to differentiate between them.
+
+2005-11-22 10:41  we7u
+
+	* NWS-TEST.log: Adding a file which can be used to test out the
+	  weather alert functionality.
+
+2005-11-18 16:36  we7u
+
+	* src/map_shp.c: Fix for RED_FLAG weather alerts.
+
+2005-11-18 12:00  we7u
+
+	* src/main.c: Making more menus detachable.  Splitting the toolbar
+	  buttons vertically by a few more pixels to make it look better on
+	  Cygwin.
+
+2005-11-18 11:59  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Getting rid of a
+	  couple of unused labels, reclaiming one for the new "Draw"
+	  toolbar togglebutton.
+
+2005-11-18 07:48  we7u
+
+	* src/wx_gui.c: Changed tab to spaces.
+
+2005-11-17 09:04  we7u
+
+	* src/main.c: Adding the cad polygons list to the map->CAD Objects
+	  submenu.  It still has a link in the View menu as well.
+
+2005-11-17 08:56  we7u
+
+	* src/main.c: Moving the remaining CAD Object stuff to the Map menu
+	  (from the mouse menu)
+
+2005-11-17 07:41  we7u
+
+	* src/objects.c: Changing colors of CAD Polygon labels and
+	  probability.	Extending string so that it display 0.00% through
+	  100.00% and displays the '%' sign.
+
+2005-11-17 06:57  we7u
+
+	* .cvsignore: Added make.log and xastir-min.spec
+
+2005-11-16 22:55  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/objects.c,
+	  src/objects.h: Moving Draw CAD functions to main menu and
+	  toolbar.
+
+2005-11-16 18:43  we7u
+
+	* src/objects.c: Adding a cancel button to the CAD Objects detailed
+	  info dialog.	Fixing the area size as listed in the same dialog.
+
+2005-11-16 13:50  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing from
+	  "Erase All" to "Erase" for menu entry.
+
+2005-11-16 13:50  we7u
+
+	* src/main.c: Changing one comment.
+
+2005-11-16 13:00  we7u
+
+	* src/objects.c: Changing "Cancel" to "Close" on CAD Object list
+	  dialog.
+
+2005-11-16 12:52  we7u
+
+	* src/objects.c: Fixing CAD area labels and comments so that they
+	  get retrieved properly from file.
+
+2005-11-16 12:19  we7u
+
+	* src/main.c: Moving some items from the Map and Station menu into
+	  Configure submenus.
+
+2005-11-16 11:33  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/main.h,
+	  src/objects.c, src/objects.h: More from Paul Morris:	Allows
+	  edits of the data associated with CAD objects and moving more of
+	  the Close CAD object code into functions.  It also adds
+	  localization to the delete CAD object dialog.
+
+2005-11-16 10:08  we7u
+
+	* xastir-min.spec.in, Makefile.am, configure.ac: Adding a new
+	  spec.in file which skips all of the optional libraries except for
+	  ImageMagick.
+
+2005-11-10 14:38  gstueve
+
+	* src/map_shp.c: Add test for debugging alert match to reduce noise
+	  on display.
+
+2005-11-10 08:57  we7u
+
+	* scripts/fcc-get: Yet another try to fix the Id string.
+
+2005-11-10 08:37  we7u
+
+	* scripts/fcc-get: Trying to fix Id string again.
+
+2005-11-10 08:36  we7u
+
+	* scripts/fcc-get: Fixing the RCS Id: string so that it gets
+	  populated by CVS.
+
+2005-11-10 07:51  gstueve
+
+	* src/objects.c: Use the time that was already provided. Don't
+	  bother system for it again.
+
+2005-11-10 07:28  gstueve
+
+	* src/: alert.c, alert.h, bulletin_gui.c, bulletin_gui.h,
+	  database.h, db.c, main.c, messages.c, messages.h, popup.h,
+	  popup_gui.c: Use the time that we already have from UpdateTime
+	  and not keep asking the system for it over and over again.
+
+2005-11-10 06:59  gstueve
+
+	* scripts/fcc-get: Remove the extra CR where ever possible, real OS
+	  has no need for such.
+
+2005-11-09 06:03  gstueve
+
+	* src/interface.c: Adjust error messages to describe problem in
+	  current function.
+
+2005-11-08 21:57  gstueve
+
+	* config/Makefile.am: Add old zone file dbf into Makefile list.
+
+2005-11-08 21:44  gstueve
+
+	* config/: Makefile.am, nwsmzoddmmyy.dbfawk: Add back in the old mz
+	  dbf definition.
+
+2005-11-08 17:40  gstueve
+
+	* src/maps.c: Add cancelled Alerts to list of mapped but don't draw
+	  on display.
+
+2005-11-08 16:07  gstueve
+
+	* config/nwszoddmmyy.dbfawk: Add old Zone file match for older dbf
+	  structure.
+
+2005-11-08 11:15  gstueve
+
+	* src/main.c: We already have a good idea of what time it is inside
+	  UpdateTime. It is NOT necessary to always be asking the system
+	  what time it is within one function and its support routines.
+	  This is not a '25 or 6 to 4' need.
+
+2005-11-08 06:52  gstueve
+
+	* src/: database.h, db.c, main.c: Make packet display logic much
+	  more efficient. Do it all in fewest moves.
+
+2005-11-08 06:35  gstueve
+
+	* src/map_gnis.c: Visual optimization. Make things easier to read.
+
+2005-11-07 14:33  we7u
+
+	* src/db.c: Changing comments about KISS variants.
+
+2005-11-07 12:33  we7u
+
+	* src/db.c: Changed one comment.
+
+2005-11-07 09:04  we7u
+
+	* src/main.c: Adding a NULL parameter to close out the parameter
+	  list for two XtVaGetValues() calls.
+
+2005-11-07 06:14  gstueve
+
+	* src/fcc_data.c: Optimize the use of substr so the function is
+	  MUCH more efficient.
+
+2005-11-07 06:12  gstueve
+
+	* config/: nwsmzddmmyy.dbfawk, nwsz_ddmmyy.dbfawk: The newer
+	  shapefiles no longer have the additional fields, so system was
+	  not matching file structure. Make it match better.
+
+2005-11-06 16:14  we7u
+
+	* src/util.c: Fixing the remove_trailing_dash_zero() routine.  It
+	  was changing "-10" into "-1" which is quite wrong.
+
+2005-11-03 12:15  we7u
+
+	* src/: db.c, interface.c: Making sure we don't transmit if the
+	  global disable or the individual interface disables are
+	  activated.
+
+2005-11-02 11:01  we7u
+
+	* src/db.c: Adding some notes about KISS and CRC's.
+
+2005-11-02 07:40  we7u
+
+	* src/xastir_udp_client.c: Changed length from int to socklen_t to
+	  get rid of warning messages for some compilers.
+
+2005-11-01 13:32  gstueve
+
+	* src/util.c: Go back to whining about dual-band TNC separator.
+
+2005-11-01 11:21  gstueve
+
+	* src/alert.c: Add debugging detail for unparsed alerts.
+
+2005-11-01 11:18  gstueve
+
+	* src/util.c: First cut to stop whining on dual-band TNC with
+	  WIDEn-m paradigm.
+
+2005-10-26 21:58  we7u
+
+	* src/interface.c: Truncating transmitted posits at the
+	  spec-specified length.  Long comments can't make us transmit
+	  out-of-spec packets anymore.
+
+2005-10-26 21:52  we7u
+
+	* src/sound.c: Added a missing include that causes a problem on
+	  Solaris if missing.
+
+2005-10-26 12:16  we7u
+
+	* src/main.c: Re-enabling the messages to STDERR when SIGHUP is
+	  sent to the main process and a restart is occurring.	Add comment
+	  about disabling SIGHUP handler in child processes.
+
+2005-10-26 12:14  we7u
+
+	* src/interface.c: Tweaks to assure that the global disables on the
+	  Interface menu have the correct effect.
+
+2005-10-26 12:11  we7u
+
+	* src/: hostname.c, macspeech.c, sound.c, x_spider.c: Regressing to
+	  default SIGHUP handler in child processes instead of our special
+	  restart() signal handler.
+
+2005-10-26 12:07  we7u
+
+	* REGRESSION_TESTS: Added date stamps and more comments.
+
+2005-10-26 08:46  we7u
+
+	* src/main.c: Changing the messages that appear as Xastir shuts
+	  down, putting them back under debug_level control in restart().
+	  restart() gets called multiple times due to sending SIGHUP to the
+	  TCP/UDP servers during shutdown, and the messages were appearing
+	  multiple times if those servers were running.
+
+2005-10-25 18:01  we7u
+
+	* src/util.c: Fixing the alert expiration problem.  May need to be
+	  checked when we switch out of daylight savings time again.
+
+2005-10-25 13:08  we7u
+
+	* src/main.c: Adding an include so that we can use the ComboBox
+	  widget.
+
+2005-10-25 13:04  we7u
+
+	* src/main.c: Limiting the selection box for preconfigured object
+	  filenames on the Configure->Defaults dialog to three items.
+
+2005-10-25 12:53  we7u
+
+	* src/main.c: Minor cleanups of the predefined object code:  Added
+	  a few free's for XmStrings, allocated memory before an
+	  XtGetValues call.
+
+2005-10-25 12:25  we7u
+
+	* src/: util.c, util.h: Making rpl_malloc() compile in all cases
+	  and put a prototype for it in util.h to get rid of more compiler
+	  warnings.  rpl_malloc() only gets used if AC_FUNC_MALLOC detetcs
+	  a version of malloc that doesn't return a valid pointer if you
+	  try to malloc zero bytes.
+
+	  These changes make it compile ok on FC4.
+
+2005-10-25 08:18  we7u
+
+	* src/util.c: Added some comments.
+
+2005-10-24 20:37  we7u
+
+	* REGRESSION_TESTS: Added some notes about future directions we
+	  could go to make the tests a bit more complete.
+
+2005-10-24 20:36  we7u
+
+	* FAQ: Tweaked the "restart Xastir" paragraph to keep it
+	  up-to-date.
+
+2005-10-24 12:29  we7u
+
+	* src/: main.c, main.h: Patch to allow SIGHUP to cause Xastir to
+	  restart properly.  This patch also appears to carry along the
+	  original command-line parameters and environment to the new task.
+	  The xastir.pid file is correct in all cases, and in fact the
+	  main process ID doesn't change between restarts.
+
+2005-10-24 12:27  we7u
+
+	* src/macspeech.c: Spawning a separate process for sending the text
+	  to the Mac OSX speech subsystem.  We also incorporate a limit of
+	  10 processes that can be waiting for the subsystem to be freed
+	  up.  If 10 processes are waiting and another speech request is
+	  made, the latter is dropped.	No provision is made for the ORDER
+	  that the (up to) ten processes get access to the speech subsystem
+	  either so the order will most likely get mixed up if you're
+	  trying to send speech strings out too fast.
+
+2005-10-24 08:52  we7u
+
+	* help/help-English.dat, src/main.c, src/objects.c, src/objects.h:
+	  Another SAR patch from Paul Morris.  Here's what he says:  This
+	  one implements a dialog for selecting CAD objects to delete from
+	  the Erase All CAD polygon menu item along with implementing
+	  delete by name in CAD_object_delete().  It also adds some help
+	  text on prepared objects and CAD objects and changes the
+	  XmStringCreateLocalized() calls to XmStringCreateLtoR().
+
+2005-10-21 21:46  we7u
+
+	* src/main.c: Restarting on SIGHUP a bit better.  It now sends
+	  argv[] at least the first time around.  Need to figure out why
+	  the 2nd time doesn't work at all.  Perhaps signal handlers are
+	  getting messed up on reboot?
+
+2005-10-21 13:28  we7u
+
+	* src/objects.c: Another tweak by Paul Morris for proper handling
+	  of CAD objects.
+
+2005-10-21 12:33  we7u
+
+	* FAQ: Reworded text for SIGHUP.
+
+2005-10-21 12:27  we7u
+
+	* FAQ: Adding the SIGHUP stuff to the FAQ.
+
+2005-10-21 12:18  we7u
+
+	* README.Getting-Started: Added some more signals to the External
+	  Stimuli section.
+
+2005-10-21 12:11  we7u
+
+	* src/main.c: Adding support for SIGHUP.  Xastir will
+	  save/exit/restart if a SIGHUP is received.  Also enabled a
+	  #define near the top of main.c that enables the xastir.pid
+	  processing.  If someone attempts to start Xastir and there's a
+	  process running with that PID, Xastir will exit.
+
+	  The SIGHUP support works, but the command-line parameters aren't
+	  carried through as the normal processing for them devours them
+	  out of the argv[] array.  We need to save that array away or use
+	  a non-destructive method of processing the parameters.
+
+2005-10-21 11:02  we7u
+
+	* src/objects.c: Small tweak so that the code looks in the
+	  /usr/local/share/xastir/config directory for the predefined
+	  objects for now.  Later we'll add the capability of overriding
+	  the system files with local user files.
+
+2005-10-21 10:41  we7u
+
+	* src/interface_gui.c: Reordering the management & positioning
+	  statements so that it doesn't appear on the screen until it gets
+	  positioned.
+
+2005-10-21 07:27  tvrusso
+
+	* src/: main.c, objects.c: Move variable declarations to tops of
+	  blocks to satisfy old-fashioned compilers that hate the modern
+	  practice of declaring variables just before their use.
+
+2005-10-20 15:47  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing
+	  pre-defined objects labels to more descriptive words.
+
+2005-10-20 15:02  we7u
+
+	* src/main.c: Getting rid of Button1 assignment for CAD objects.
+	  This prevents us from zooming/panning/measuring while creating a
+	  CAD object.
+
+2005-10-20 14:52  we7u
+
+	* config/Makefile.am: Adding predefined files to Makefile so
+	  they'll get installed.
+
+2005-10-20 14:52  we7u
+
+	* config/: predefined_EVENT.sys, predefined_SAR.sys: Example
+	  pre-defined SAR/Event object files by Paul Morris.
+
+2005-10-20 14:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, help/help-English.dat,
+	  src/database.h, src/main.c, src/main.h, src/objects.c,
+	  src/objects.h, src/xa_config.c: Patch by Paul Morris, AA3SD, to
+	  tweak CAD objects functionality a bit and add pre-defined
+	  SAR/Event objects from files.
+
+2005-10-20 13:34  we7u
+
+	* src/color.c: Reformatting.  No real code changes.
+
+2005-10-20 13:12  gstueve
+
+	* src/: alert.c, alert.h, wx_gui.c: Reintroduce SKYWARN addendum to
+	  Wx Messages & sort Wx Alert list.  Only sort list if window is
+	  activated.
+
+2005-10-20 13:08  gstueve
+
+	* src/: map_shp.c, maps.c: Move the on_screen decision to a
+	  position where it really works.
+
+2005-10-20 10:58  we7u
+
+	* README.MAPS: Changing one sentence to make things more clear.
+
+2005-10-20 10:57  we7u
+
+	* README.MAPS: Removing an unnecessary statement.
+
+2005-10-20 10:53  we7u
+
+	* README.MAPS: Was missing a pipe symbol in the new sort command.
+	  Also use the same command for all operating systems with this
+	  tweak.
+
+2005-10-20 10:21  we7u
+
+	* README.MAPS: Fix submitted by A. Carver for FCC database sorting
+	  for Cygwin.
+
+2005-10-20 09:35  we7u
+
+	* src/interface_gui.c: Changing default path to WIDE2-2 instead of
+	  WIDE for new interfaces.
+
+2005-10-20 05:41  gstueve
+
+	* src/maps.c: Activate debugging messages from commented fprintf
+	  messages.
+
+2005-10-20 05:35  gstueve
+
+	* src/util.c: Clamp limits of map to nearest edge. Not
+	  clipping/clamping & report error.
+
+2005-10-19 18:29  we7u
+
+	* src/: map_WMS.c, map_geo.c, map_tif.c, map_tiger.c: Commenting
+	  out the XFreeColors() calls for now.	Cygwin seems to be much
+	  more sensitive to these calls than Linux.
+
+2005-10-19 13:24  we7u
+
+	* src/interface.c: Disabling sending of my own posits to x_spider
+	  if transmit_disable is non-zero.
+
+2005-10-19 13:19  we7u
+
+	* src/interface.c: Cease sending packets to x_spider if
+	  loopback_only is in effect.
+
+2005-10-19 13:19  we7u
+
+	* src/objects.c: Added some comments.
+
+2005-10-19 12:54  we7u
+
+	* src/objects.c: Getting rid of "Transmitting objects/items"
+	  statusline message if transmit of those types of packets is
+	  disabled globally.
+
+2005-10-19 12:21  we7u
+
+	* src/: map_WMS.c, map_geo.c, map_tif.c, map_tiger.c: Adding
+	  XFreeColors() calls just before each XAllocColor() call.  This is
+	  to keep the counters in sync that count how many times each color
+	  is allocated, hopefully preventing the can't allocate color
+	  warning messages.
+
+2005-10-19 12:20  we7u
+
+	* src/color.c: Adding a comment.  No code changes.
+
+2005-10-17 14:35  we7u
+
+	* configure.ac: Bumping version number to 1.7.1 for further
+	  development.
+
+2005-10-17 14:12  we7u
+
+	* configure.ac: Bumping the release number to 1.7.0.
+
+2005-10-17 13:46  francais1
+
+	* config/language-French.sys: Merci a Jacques Chion, F6CWO
+
+2005-10-17 13:41  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Fixing some typos:
+	  Missing pipe symbols at the end of strings.  French language file
+	  will be fixed shortly too, along with a few more translations.
+	  Thanks to Olivier for catching these.
+
+2005-10-17 12:16  we7u
+
+	* README, help/help-English.dat: Added notes about Bob Bruninga's
+	  list of generic callsigns that should be gated to RF.
+
+2005-10-17 11:53  we7u
+
+	* help/help-English.dat: Added a What's New section for
+	  up-and-coming 1.7.0 release.	Added notes regarding gating
+	  specific stations to RF and which generic callsigns that Bob
+	  Bruninga recommends doing that with.
+
+2005-10-17 11:51  we7u
+
+	* README.win32: Reformatting the list of languages available.
+
+2005-10-17 11:50  we7u
+
+	* README.Getting-Started: Changing the revision number in an
+	  example.  Updating the example Xastir help text.
+
+2005-10-17 11:49  we7u
+
+	* README.Contributing: Changing a revision number in an example.
+
+2005-10-17 11:49  we7u
+
+	* README: Adding a note about a few calls that Bob Bruninga
+	  recommends always gating to RF.
+
+2005-10-17 11:47  we7u
+
+	* INSTALL: Tweaking formatting of -l language notes.
+
+2005-10-16 10:16  we7u
+
+	* config/language-German.sys: An update to the German language file
+	  by Rolf Bleher, DK7IN.  Thanks!
+
+2005-10-15 18:51  we7u
+
+	* config/language-Dutch.sys: Updates by Han Sytsma.  Thanks!
+
+2005-10-15 18:50  we7u
+
+	* config/language-English.sys: Fixing a typo.
+
+2005-10-15 10:30  we7u
+
+	* src/map_tif.c: Making sure the projects.h include isn't needed
+	  unless libgdal is compiled in as well.  Got rid of UV define and
+	  changed invocation to "projUV" instead.
+
+2005-10-15 09:42  we7u
+
+	* src/map_tif.c: Fixing a problem caused by the new code which
+	  fixes the gdal/geotiff bug.  This fix cuases the original
+	  functions to be called if gdal isn't installed.
+
+2005-10-14 11:06  we7u
+
+	* src/map_tif.c: Received permission from Frank Warmerdam to use
+	  some of his code inside Xastir, relicensing it under GPL.  We use
+	  this new right to include one function in map_tif.c which allows
+	  us to keep topo maps support even when libgdal is compiled in.
+
+2005-10-14 08:11  we7u
+
+	* README.win32: Added a note about running configure from an xterm
+	  so that "gv" support will be compiled in.  If run from a non-X11
+	  window, "gv" configure test fails.
+
+2005-10-13 13:51  francais1
+
+	* config/language-French.sys: Some more strings translated, but not
+	  all...
+
+2005-10-13 08:39  gstueve
+
+	* src/main.c: Put the full title back on the window, so we can know
+	  what machine is running the app.
+
+2005-10-12 17:09  we7u
+
+	* src/messages.c: Added code that will switch back to RF if no
+	  TX-enabled INET interfaces are up.
+
+2005-10-12 13:09  we7u
+
+	* src/messages.c: New message routing which should take care of a
+	  bug-list item: Ceasing to transmit when messaging with internet
+	  station and internet interfaces go down.  Problem remaining with
+	  this code:  We transmit out RF interfaces even if QSO'ing with
+	  station over internet interface.
+
+2005-10-12 11:33  we7u
+
+	* src/: locate_gui.c, main.c, messages_gui.c, track_gui.c, util.c,
+	  util.h: Fixing all of the callsign entry fields so that "-0" is
+	  truncated from the end of the string when used.
+
+2005-10-11 16:52  we7u
+
+	* src/main.c: Tweaks to convert callsign-0 to callsign for
+	  configure station dialog.
+
+2005-10-11 10:12  we7u
+
+	* src/db.c: Added a bit of debugging.  No effect for normal
+	  operation.
+
+2005-10-11 08:16  we7u
+
+	* src/db.c: Slightly better igating of messages.  This versions
+	  saves the message+acks away and then uses that exact string again
+	  when igating it, instead of putting together the bits and pieces
+	  at that point like the previous code.
+
+2005-10-10 22:07  we7u
+
+	* src/db.c: Another tweak to get reply-ack's propagated through an
+	  Xastir igate to RF.  This one is tested and works.
+
+2005-10-10 18:29  we7u
+
+	* src/db.c: Comment changes.  Also changed the fprintf() for REJ
+	  packets to only dump text to STDERR if the REJ was sent to
+	  my_callsign.
+
+2005-10-10 12:11  we7u
+
+	* src/db.c: Changed one comment.
+
+2005-10-10 11:52  we7u
+
+	* src/db.c: Added comments.  fprintf() to stderr when we receive a
+	  REJ packet. We can receive those when a Kenwood radio's message
+	  buffer is full.
+
+2005-10-10 11:48  we7u
+
+	* src/messages.c: Minor tweaks w.r.t. REPLY-ACK protocol.  Making
+	  sure we strip off the unneeded portion before we check the ACK.
+
+2005-10-10 09:31  we7u
+
+	* src/db.c: Fixing igating of messages to RF for messages with
+	  REPLY-ACK protocol at the end.  We were originally sending our
+	  processed ACK at the end which knocked off the free-ack portion.
+	  Now we send the full five-character unprocessed REPLY-ACK.
+
+2005-10-10 09:29  we7u
+
+	* src/igate.c: Adding some comments.
+
+2005-10-10 08:23  we7u
+
+	* src/main.c: Fixing a couple of compiler problems via casting.
+	  Problems were not seen with SuSE compiler but were seen on other
+	  systems.
+
+2005-10-07 18:16  we7u
+
+	* src/objects.c: Tweaks to avoid other object/item/station names
+	  when creating SAR objects.  Xastir will now add a number to the
+	  end of the typical name (starting at "2") in order to create a
+	  unique name.	This makes for extremely fast placement of
+	  important mission objects without worrying about old mission
+	  objects or conflicting with other people's current missions.
+
+2005-10-07 18:13  we7u
+
+	* src/main.c: Added some comments.
+
+2005-10-07 18:10  we7u
+
+	* src/db.c: Added some comments.
+
+2005-10-07 18:07  we7u
+
+	* src/track_gui.c: Added a comment.
+
+2005-10-07 18:05  we7u
+
+	* src/list_gui.c: Added some comments.
+
+2005-10-07 13:16  we7u
+
+	* src/objects.c: Added some comments.
+
+2005-10-07 12:49  we7u
+
+	* src/objects.c: Adding fprintf() statements to help work on the
+	  SAR objects code.
+
+2005-10-07 12:26  we7u
+
+	* src/: main.c, xa_config.c, xastir.h: Checking in some work having
+	  to do with saving/restoring X/Y offsets for the main window.	The
+	  code doesn't work yet so it commented out.
+
+2005-10-07 12:25  we7u
+
+	* src/objects.c: Adding some comments about future coding that
+	  needs to be done w.r.t. SAR objects.
+
+2005-10-07 11:16  we7u
+
+	* src/Makefile.am: Another minor tweak for the icon.
+
+2005-10-07 11:15  we7u
+
+	* src/Makefile.am: Adding the icon.xbm file into the Makefiles.
+
+2005-10-06 13:50  tvrusso
+
+	* src/: main.c, objects.c: Move declarations of variables to before
+	  first executable lines of code, to satisfy old-fashioned
+	  compilers (gcc 2.95, etc.)
+
+2005-10-06 13:45  we7u
+
+	* src/icon.xbm: Someone pointed out that the RF radiation wasn't
+	  symmetrical.	Now it is.
+
+2005-10-06 12:46  we7u
+
+	* src/objects.c: Commenting out a debug statement.
+
+2005-10-06 12:39  we7u
+
+	* src/: main.c, objects.c, objects.h: Commenting out the wm_hints
+	  code.  Adding a "Create SAR Objects" entry to the mouse menu.
+	  That last was written and contributed by Paul J.  Morris, aa3sd.
+	  Thanks!
+
+2005-10-06 12:37  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding "Create SAR
+	  Objects" right-click mouse menu.
+
+2005-10-06 12:19  we7u
+
+	* src/icon.xbm: Added radio transmissions emanating from the
+	  antenna.
+
+2005-10-05 23:47  we7u
+
+	* src/: icon.xbm, main.c: Separating out the icon into its own
+	  file.
+
+2005-10-05 22:49  we7u
+
+	* src/main.c: Casting to type "Dimension" is not proper for
+	  parameters passed to XtSetArg().  Have changed to variables of
+	  that type for parameter passing.  Also cleaned up the -geometry
+	  code a bit.  The windows are now sized properly per the
+	  command-line parameters.
+
+2005-10-05 17:25  we7u
+
+	* src/main.c: A better version of the -geometry code that is
+	  starting to work on Cygwin.  The size is larger than specified,
+	  perhaps because it is based on char sizes instead of pixels?
+	  Anyway, this part of the code is starting to work.
+
+2005-10-05 11:37  we7u
+
+	* src/main.c: Rearranging things.  No code changes.
+
+2005-10-05 08:34  we7u
+
+	* src/main.c: Another attempt at the -geometry stuff.  Here we only
+	  use size_hints in one case, plus we lock down the minWidth and
+	  minHeight of the main widget when we create it (to the size we
+	  want it to appear as), but change those parameters before we map
+	  the window to the screen.  This method was borrowed from the
+	  Lincity project where they do similar things.  As usual, this
+	  stuff works for me on Linux/FVWM2.
+
+2005-10-04 12:12  we7u
+
+	* src/: main.c, xa_config.c: Another shot at this -geometry stuff.
+	  Moved the size_hints stuff after the window is mapped.  Added an
+	  icon.
+
+2005-10-04 09:11  we7u
+
+	* src/main.c: Reducing the number of size_hints variables I'm
+	  setting.  Changing XtPopup() to XMapWindow() for appshell.
+
+2005-10-03 13:13  we7u
+
+	* src/xa_config.c: Tweaking SCREEN_ZOOM to match new
+	  highest-allowed value for zoom level.
+
+2005-10-03 13:11  we7u
+
+	* src/main.c: Allow a higher zoom level for entire world, for
+	  rather small map windows.
+
+2005-10-03 13:05  we7u
+
+	* src/main.c: Attempting to recenter view when zooming out all the
+	  way.	Doesn't quite work yet.
+
+2005-10-03 12:56  we7u
+
+	* src/main.c: Getting rid of the X-dimension checks in
+	  check_range() in order to make it easier to play at the +/-180
+	  boundaries.
+
+2005-10-03 12:51  we7u
+
+	* src/main.c: A slightly better system for controlling left/right
+	  edges of map when at left/right edge of world.  check_range().
+
+2005-10-03 11:34  we7u
+
+	* src/main.c: Fixes for -geometry support and main window
+	  save/restore support.
+
+2005-10-03 11:33  we7u
+
+	* src/xa_config.c: Changing the minimum size that can be restored
+	  to for Xastir's main window.
+
+2005-10-02 12:27  we7u
+
+	* src/main.c: Adding window manager hints back in.
+
+2005-10-01 23:26  we7u
+
+	* src/: db.c, draw_symbols.c, geocoder_gui.c, interface_gui.c,
+	  list_gui.c, locate_gui.c, maps.c, xastir.h, bulletin_gui.c,
+	  main.c, messages_gui.c, objects.c, popup_gui.c, track_gui.c,
+	  view_message_gui.c, wx_gui.c: Getting rid of the Global.top
+	  widget which was unmapped.  Making appshell be the top level
+	  widget.  Added parsing for the -geometry command-line variable
+	  via XParseGeometry() so that we can tell when either the
+	  height/width or the x/y offsets have been specified.	We then set
+	  up appshell based on that info or using the config file data if
+	  it wasn't specified on the command-line.
+
+2005-10-01 17:46  we7u
+
+	* src/main.c: Commenting out the 100x100 minimum window size
+	  parameters.
+
+2005-09-30 13:16  we7u
+
+	* src/main.c: Commenting out the code which sets
+	  min_width/min_height in the XSizeHints struct.
+
+2005-09-30 11:25  we7u
+
+	* src/main.c: Commenting out base_width and base_height parameters
+	  as they override the min_width/min_height parameters if
+	  specified.  We only need one set.
+
+2005-09-30 11:02  we7u
+
+	* src/main.c: Another shot at the XSizeHints stuff (-geometry).
+	  Learning a bit more with each iteration.
+
+2005-09-30 08:58  we7u
+
+	* src/main.c: Of course some of those I commented out previously
+	  appear to matter, so here they are, enabled in the code again.
+
+2005-09-30 08:51  we7u
+
+	* src/main.c: Getting rid of a few unused variables.  Commenting
+	  out sections in the geometry setting portions that appear to have
+	  no effect.
+
+2005-09-30 07:44  tvrusso
+
+	* DEBUG_LEVELS: Change statement that the highest debug level is
+	  2047 to 4095.  There is now a debug level of 2048 (ALOHA
+	  calculation and multipoint object debugging).
+
+2005-09-30 07:27  we7u
+
+	* INSTALL, help/help-English.dat: Updating the docs regarding TCP
+	  and UDP server ports.
+
+2005-09-30 07:01  we7u
+
+	* src/main.c: Changed PSize flag to USSize to indicate that the
+	  user had specified the size of the window in that one case.  This
+	  gives it a higher priority.
+
+2005-09-30 06:46  we7u
+
+	* help/help-English.dat: Updating the xastir_udp_client
+	  description.
+
+2005-09-30 05:26  we7u
+
+	* src/db.c: Telemetry fix which adds it as status to the station
+	  record, submitted by Andrew Rich, vk4tec.  Thanks!
+
+2005-09-30 02:50  we7u
+
+	* src/main.c: Took another look at the XSizeHints struct.  Might
+	  work better now to provide proper geometry hints to window
+	  managers.
+
+2005-09-29 12:19  we7u
+
+	* src/map_tif.c: Casting to the correct type for X11 calls.
+
+2005-09-29 12:19  we7u
+
+	* src/: db.c, location.c, main.c, map_WMS.c, map_dos.c, map_geo.c,
+	  map_gnis.c, map_pdb.c, map_shp.c, map_tiger.c, maps.c, objects.c,
+	  popup_gui.c: Casting to the correct type in X11 calls.  Adding
+	  more debug output to create_appshell() for -geometry stuff.
+
+2005-09-29 11:00  we7u
+
+	* acinclude.m4: Fix by	Thorsten Lockert.  Fixes a problem on
+	  MacOSX where -lgdal can have revision numbers after it.  Without
+	  this fix the test compile using gdal fails.
+
+2005-09-29 08:42  we7u
+
+	* src/main.c: Added more debugging output for -geometry.
+
+2005-09-29 07:59  we7u
+
+	* src/main.c: Moving some variable declarations to the correct
+	  spot.  Ended up originally putting them after a bit of functional
+	  code, but they must be at the start of a block for many
+	  compilers.
+
+2005-09-29 07:37  we7u
+
+	* src/main.c: Changing to 3rd-party packets for packets sent from
+	  UDP to the RF ports.
+
+2005-09-28 13:21  we7u
+
+	* src/main.c: Commenting out some unused variables.
+
+2005-09-28 13:02  we7u
+
+	* src/main.c: More mods for UDP->RF.  This version may be working
+	  but it needs testing on a system with real RF interfaces to see
+	  if it behaves properly.
+
+2005-09-28 09:24  we7u
+
+	* src/: main.c, x_spider.c, x_spider.h: Continuing work on support
+	  for UDP server port.	We're getting closer now to supporting
+	  sending of packets to RF.
+
+2005-09-28 09:22  we7u
+
+	* src/xastir_udp_client.c: Changed the help text.
+
+2005-09-28 09:03  we7u
+
+	* symbols/symbols.dat: Adding the /F, Farm Equipment, symbol, as a
+	  green tractor.  Also added hash mark delimiters between each
+	  symbol definition.
+
+2005-09-28 07:50  we7u
+
+	* config/language-German.sys: Updates by Andreas Bier, dl1hrc.
+	  Thanks!
+
+2005-09-27 08:16  we7u
+
+	* src/main.c: Simplifying startup of the application in main().
+	  Changing to XtVaOpenApplication, which supersedes the function
+	  call we were using before, and removing some explicit function
+	  calls that are handled automatically by both the old and the new
+	  function call (unnecessary code).  These changes are being made
+	  to implement proper support for the "-geometry" command-line
+	  flag.
+
+2005-09-25 19:35  we7u
+
+	* src/: alert.h, database.h, db.c, draw_symbols.c, geocoder_gui.c,
+	  interface.c, main.h, maps.h, track_gui.c, util.h, Makefile.am,
+	  main.c, maps.c, util.c: Moving the Object/Item/Cad_Object code
+	  into objects.h and objects.c.
+
+2005-09-25 19:26  we7u
+
+	* src/: objects.c, objects.h: Moving nearly all of the
+	  Object/Item/CAD Object code into one header and one source file.
+	  This makes main.c quite a bit smaller.
+
+2005-09-24 11:21  we7u
+
+	* src/main.c: Proper numeric checks for Global.top size/offsets,
+	  for deciding whether to make the 2nd Xastir window (the first
+	  visible window) copy either set of parameters.
+
+2005-09-24 11:00  we7u
+
+	* src/: list_gui.c, main.c: Changing variables used in
+	  XtVaGetValues() calls to "Dimension" or "Position".  Adding an
+	  out-of-range check for dimension for the case where we're
+	  attempting to discover whether the first window has had -geometry
+	  specified.
+
+2005-09-23 17:18  we7u
+
+	* src/main.c: First working version of the "-geometry" command-line
+	  flag.  Will hopefully know soon if it works on all platforms we
+	  support.  Let the testing begin!
+
+2005-09-23 12:01  we7u
+
+	* src/main.c: "-geometry" switch now works for sizing the
+	  application (instead of "-g"), but the X/Y offsets still don't
+	  work.
+
+2005-09-22 19:18  tvrusso
+
+	* src/main.c: Give "appshell_width" and "appshell_height" initial
+	  values of 0.	This allows the contents of the xastir.cnf file's
+	  SCREEN_WIDTH and SCREEN_HEIGHT to be used if no geometry is
+	  specified in -g.  As it was, if one didn't give -g then these two
+	  settings in the config file were ignored and a 100x100 window
+	  appeared on every start-up.
+
+2005-09-22 13:32  we7u
+
+	* src/main.c: A fix for Xastir hanging if the -g flag is used but
+	  only offsets are specified.
+
+2005-09-22 13:07  we7u
+
+	* src/main.c: Initial implementation of the "-g" geometry
+	  command-line flag.  It supports sizing the application, but
+	  doesn't support X/Y offsets yet.  That's in the works though.
+
+2005-09-21 22:29  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/track_gui.c: Added success/failure popups to findu trail
+	  download.  Changed max_trail_colors to a define instead of an
+	  int.	Added a Change Trail Color button to the Station Info
+	  dialog.
+
+2005-09-21 11:51  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/track_gui.c: Popping up an error
+	  if the new backgrounded fetch findu trail fails.  Changing
+	  variables that the thread depends on to "static" so they'll be
+	  around when the thread needs them.
+
+2005-09-20 17:35  tvrusso
+
+	* acinclude.m4: Restructure test for gv slightly, so that
+	  AC_PATH_PROG is called first, and version is tested if gv is
+	  found.  The case where gv is found, but `gv -v | cut -d ' ' -f 1`
+	  not being "gv" is in fact a sign of error that needs to be
+	  reported in a meaningful way.
+
+	  Turns out that when I do my normal cygwin build (which is usually
+	  done in a non-X cygwin run to save memory), the old way of
+	  probing gv found the gv executable, but because "gv -v" tries to
+	  connect to the X server and reports failure if it can't,
+	  configure was telling me that gv was found, but the build would
+	  actually happen without gv.  This was quite confusing.
+
+	  With the new test as committed here, I still can't build with gv
+	  outside of an xterm on cygwin, but the reason actually shows up
+	  in the configure output.
+
+2005-09-17 11:33  we7u
+
+	* src/lang.h: Bumping up the size of the language buffer as we're
+	  bumping up against the limits now for some languages.
+
+2005-09-16 16:46  we7u
+
+	* src/xastir_udp_client.c: Changing some comments and the usage
+	  text.
+
+2005-09-16 16:45  we7u
+
+	* src/track_gui.c: Trying to protect the track download so that
+	  only one can be done at once.  Not perfect yet as sometimes the
+	  GUI locks up.  More to do.
+
+2005-09-16 16:34  we7u
+
+	* config/language-English.sys: Changing "New Call" to "New Station"
+	  for the speech strings.  I think it sounds better.
+
+2005-09-16 14:09  we7u
+
+	* config/language-English.sys: Adding an 's' to the end of "Enable
+	  Server Ports".
+
+2005-09-16 14:09  we7u
+
+	* config/language-German.sys: Updates courtesy of Andreas Bier,
+	  dl1hrc.  Thanks!
+
+2005-09-16 13:18  we7u
+
+	* help/help-English.dat: Tweaking the text regarding the UDP
+	  server/client.  Adding more about the -identify command-line
+	  flag.
+
+2005-09-16 13:14  we7u
+
+	* src/xastir_udp_client.c: Making the output from the -identify
+	  response go to STDOUT instead of STDERR.  Only makes sense so it
+	  can be piped more easily into scripts and such.
+
+2005-09-16 13:09  we7u
+
+	* src/xastir_udp_client.c: Implemented the "-identify" command-line
+	  flag.  The "message" portion must have at least a single char in
+	  order for the identify query to be sent to the server.
+
+2005-09-16 12:37  we7u
+
+	* help/help-English.dat, src/x_spider.c: Now we send UDP packets
+	  out the x_spider TCP ports as well, if the packet is
+	  authenticated properly.
+
+2005-09-16 12:26  we7u
+
+	* src/x_spider.c: Adding a "-identify" option to the UDP server.
+	  It returns a UDP packet containing the callsign.
+
+2005-09-16 11:48  we7u
+
+	* src/track_gui.c: Putting the fetch_findu_trail function into a
+	  separate background thread.
+
+2005-09-16 11:48  we7u
+
+	* help/help-English.dat: Adding text about the UDP server feature
+	  and the xastir_udp_client.
+
+2005-09-16 07:38  we7u
+
+	* src/: x_spider.h, xastir_udp_client.c: Moving the default port
+	  for UDP from 2024 to 2023, as TCP and UDP can co-exist on the
+	  same port number.
+
+2005-09-15 16:59  we7u
+
+	* src/xastir_udp_client.c: Fixed the hostname lookup.  You can now
+	  specify any hostname and port.
+
+2005-09-15 12:38  we7u
+
+	* src/util.c: Adding the long integer time at the beginning of the
+	  timestamp line for the log files.  Makes sorting easy.
+
+2005-09-15 11:56  we7u
+
+	* src/: util.c, wx.c: Changing timestamping to add a timestamp line
+	  per packet instead of once per 30 seconds.
+
+2005-09-15 11:47  we7u
+
+	* src/: x_spider.c, xastir_udp_client.c: Adding authentication to
+	  the UDP packets.
+
+2005-09-15 11:45  we7u
+
+	* src/db.c: Allowing user-defined and telemetry packets to be
+	  gated.
+
+2005-09-15 07:54  we7u
+
+	* src/.cvsignore: Adding xastir_udp_client to the ignore list.
+
+2005-09-15 07:52  we7u
+
+	* src/: Makefile.am, x_spider.c: Renaming the UDP client from
+	  udp_client to xastir_udp_client.
+
+2005-09-15 07:51  we7u
+
+	* src/xastir_udp_client.c: Renaming this file from udp_client.c to
+	  xastir_udp_client.c, to avoid similar names for UDP clients.
+
+2005-09-15 07:50  we7u
+
+	* src/udp_client.c: Renaming this file to xastir_udp_client.c
+
+2005-09-14 21:53  we7u
+
+	* src/: interface.c, main.c, x_spider.c, x_spider.h: Adding a UDP
+	  server at port 2024.
+
+2005-09-14 21:45  we7u
+
+	* src/Makefile.am: Adding the udp client.
+
+2005-09-14 21:44  we7u
+
+	* src/udp_client.c: Initial checkin of a UDP client.  Currently
+	  this is hard-coded to talk to the localhost address, but that can
+	  be fixed later.  It also hangs currently if the server isn't
+	  responding.
+
+2005-09-09 13:08  we7u
+
+	* src/db.c: Fixing a typo in one of the new langcode() string
+	  callouts.
+
+2005-09-09 12:20  we7u
+
+	* src/: db.c, main.c, util.c: Replacing a bunch of hard-coded
+	  strings with langcode() strings.
+
+2005-09-09 12:19  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding more
+	  language strings to replace hard-coded strings.
+
+2005-09-08 21:46  we7u
+
+	* src/: draw_symbols.c, fcc_data.c, geocoder_gui.c, map_cache.c,
+	  rac_data.c, view_message_gui.c, xa_config.c: Adding language
+	  strings for previously hard-coded values.  Changed get_long and
+	  get_int functions in xa_config.c to give better output when
+	  variables are missing or out-of-range in the config file upon
+	  Xastir startup.
+
+2005-09-08 21:40  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding more
+	  language strings for previously hard-coded English values.
+
+2005-09-08 09:49  we7u
+
+	* INSTALL: Adding a blurb about conflicts between GDAL internal
+	  libraries and external libraries that Xastir can use.
+
+2005-09-08 09:39  tvrusso
+
+	* acinclude.m4: Move -lgdal to end of LIBS line if it's found.
+
+	  It is possible for gdal to be using its own internal geotiff
+	  library, and this can interfere with use of an external one in
+	  xastir.  Having it later in the line than geotiff can fix that.
+
+	  This could cause problems for systems with busted linkers that
+	  need gdal to be earlier than everything it depends on.  If that
+	  happens, it might be necessary to add the contents of
+	  "gdal-config --dep-libs" to LIBS after -lgdal.
+
+2005-09-08 08:58  we7u
+
+	* src/map_tif.c: Commenting out some unnecessary includes.  Adding
+	  some error messages when function calls fail.  Minor reformatting
+	  w.r.t.  braces to match the Xastir project standard.
+
+2005-09-07 12:30  we7u
+
+	* src/main.c: Assuring that the "System time jumped backwards 1
+	  seconds!" message doesn't say "0 seconds!", as I've seen recently
+	  due to the way the code was originally written.
+
+2005-09-02 18:42  we7u
+
+	* acinclude.m4: More appropriate output for the case where gv is
+	  not found by configure.
+
+2005-09-02 16:00  we7u
+
+	* acinclude.m4: Adding a clause for the case where no usable "gv"
+	  is found.
+
+2005-09-02 15:34  we7u
+
+	* acinclude.m4: Another stab at trying to do the "gv" revision
+	  tests.
+
+2005-09-02 15:34  we7u
+
+	* src/maps.c: Pop up warning messages if we try to print but don't
+	  have the proper support compiled in.
+
+2005-09-02 13:54  we7u
+
+	* acinclude.m4, src/maps.c: Tweaks to hopefully determine
+	  automatically which version of "gv" is being used and change the
+	  code to correspond to the proper API.
+
+2005-09-02 12:30  we7u
+
+	* src/maps.c: Preparing for configure.ac tests that will determine
+	  the "gv" version, then we can change how we call up "gv" based on
+	  that.
+
+2005-09-02 08:47  we7u
+
+	* src/x_spider.c: Changing to a <CR><LF> combination for the
+	  "Hello" server message, per the APRS INET conventions.
+
+2005-09-01 10:00  we7u
+
+	* README.Getting-Started: Modified the note regarding geocode
+	  files.
+
+2005-09-01 08:08  we7u
+
+	* configure.ac, src/main.c: Adding a test for sigignore() to
+	  configure.ac, and code to use it in main.c.  We were getting a
+	  warning under Solaris by using signal() with SIG_IGN as the
+	  parameter.
+
+2005-09-01 07:43  we7u
+
+	* src/util.c: Adding strings.h include.  Need for Solaris.
+
+2005-08-31 21:16  we7u
+
+	* config/tnc-startup.kpc3: Removing "exp on" from the file.  I
+	  guess SOMEBODY doesn't think we need AEA commands in a KANTRONICS
+	  config file.	The nerve!
+
+2005-08-31 14:42  we7u
+
+	* REGRESSION_TESTS: Blowing away the autom4te.cache directory at
+	  the start of each run, to make sure that we start out
+	  ultra-clean.
+
+2005-08-31 09:59  we7u
+
+	* configure.ac: Attempt to remove "-no-unused" from linking stage
+	  for Cygwin builds, as GCC links to complain about that flag
+	  during linking.
+
+2005-08-30 14:19  we7u
+
+	* acinclude.m4: Changing grep syntax so that it will work with
+	  non-GNU grep (Solaris).  Getting rid of dash near the end.
+
+2005-08-30 13:52  we7u
+
+	* src/: awk.c, bulletin_gui.c, db.c, main.c, map_WMS.c, map_dos.c,
+	  map_gdal.c, map_geo.c, map_gnis.c, map_pdb.c, map_shp.c,
+	  map_tif.c, map_tiger.c, maps.c: Mucking about with the strings.h
+	  includes.
+
+2005-08-30 13:28  kd6zwr
+
+	* src/: awk.c, geo-find.c, io-common.c, map_gnis.c: protecting the
+	  strings.h with an ifdef, and casting isspace() family of macros
+	  to match man page (int).
+
+2005-08-30 12:41  we7u
+
+	* src/awk.c: Adding a strings.h include for Solaris support.
+
+2005-08-30 11:33  we7u
+
+	* src/db.c: Displaying the raw packet in a dialog for the case
+	  where we detect "EMERGENCY" in the comment field or one of the
+	  emergency-type destination callsigns in a packet.
+
+2005-08-30 11:31  we7u
+
+	* config/tnc-startup.paccomm: Commenting out a "WIDE" alias that
+	  remained.  Changed it to "LOCAL" also.
+
+2005-08-30 11:31  we7u
+
+	* src/locate_gui.c: Skipping the dialog destroy call if you hit the
+	  FCC/RAC lookup or the Locate button.	The dialog now has to be
+	  manually cleared by hitting the Cancel button.
+
+2005-08-29 08:06  we7u
+
+	* src/: db.c, interface.c, wx.c: Fixing warnings seen on OSX 10.4.
+	  Very minor "signedness" warnings in string functions.
+
+2005-08-27 17:21  we7u
+
+	* src/x_spider.c: Tweaking a patch provided by James Washer that
+	  will send a string out the server port on each connect.  My
+	  chances were merely to the format of the string.  Thanks go to
+	  James for the patch itself.
+
+2005-08-26 14:12  tvrusso
+
+	* configure.ac, src/hostname.c: Fix so that hostname.c can compile
+	  on systems that define neither sighandler_t nor sig_t.  This is
+	  necessary because of the new cast to sighandler_t of the second
+	  argument of signal() that was put there to shut gcc warnings up.
+
+2005-08-25 14:29  we7u
+
+	* acinclude.m4: Getting rid of some extra restores of variables
+	  that I shouldn't have added last go-around.
+
+2005-08-25 13:48  we7u
+
+	* acinclude.m4: Summary text and summary.log were incorrect if gdal
+	  wasn't found.  Fixed.
+
+2005-08-25 08:11  we7u
+
+	* src/db.c: Commenting out some debug code.
+
+2005-08-24 21:27  we7u
+
+	* src/xa_config.c: Simplifying the get_long() and get_int() code
+	  per discussions with Tom Russo.  Also attempting to get rid of
+	  some compiler warnings that we see with FreeBSD.
+
+2005-08-24 10:58  we7u
+
+	* src/main.c: Switching the state of trap_segfault variable to make
+	  more sense.
+
+2005-08-24 09:50  we7u
+
+	* src/main.c: Change in text suggested by James Washer.  Also added
+	  the -t option to the command-flag help text.
+
+2005-08-24 09:07  we7u
+
+	* src/xa_config.c: Removing some ill-advised casts to time_t's.
+	  Was trying to get rid of warnings that appear on FreeBSD, but
+	  this was the wrong approach and didn't fix the problem.
+
+2005-08-23 21:08  tvrusso
+
+	* configure.ac, src/hostname.c: Change logic for deciding when to
+	  use a sigjmp_buf vs. a jmp_buf.
+
+	  The code that was originally here would only work if sigjmp_buf
+	  was a #define, but on some systems it's a typedef.  The new code
+	  works for both.
+
+2005-08-23 19:53  we7u
+
+	* src/: awk.c, bulletin_gui.c, map_gdal.c, maps.c: Fixing up
+	  function headers to be ANSI-C compliant.
+
+2005-08-23 16:25  we7u
+
+	* INSTALL: Tweaking the GDAL install instructions a bit more.
+
+2005-08-23 16:04  we7u
+
+	* INSTALL: Updating the GDAL install instructions.
+
+2005-08-23 14:38  we7u
+
+	* configure.ac: Changing the summary format slightly.  No code
+	  changes.
+
+2005-08-23 14:23  we7u
+
+	* configure.ac: Drawing a line in the configure summary between the
+	  normal and the more unusual parameters.
+
+2005-08-23 14:18  we7u
+
+	* configure.ac: Changing some text on the summary output.  No code
+	  changes.
+
+2005-08-23 13:52  tvrusso
+
+	* acinclude.m4: Add configure-time check for usability of
+	  -Wno-unused-parameter. Older compilers (not newer as was
+	  indicated in the comments) don't like that and need -Wno-unused
+	  instead.
+
+	  Return -W to the CFLAGS, and use whatever -Wno-unused* works.
+
+2005-08-23 12:39  we7u
+
+	* src/interface.c: Added a new time_t variable that we can use to
+	  call ctime() with, in order to avoid a compiler warning.
+
+2005-08-23 12:38  we7u
+
+	* src/xa_config.c: Changing a bunch of pointer casts from "long *"
+	  to "time_t *" to avoid compiler warnings.
+
+2005-08-23 12:36  we7u
+
+	* src/util.c: Casting some time_t's to long's to avoid compiler
+	  warnings.
+
+2005-08-23 12:35  we7u
+
+	* src/main.c: Casting a time_t to an unsigned long to remove a
+	  compiler warning.  Fixing up a function header to make it ANSI-C
+	  compliant.
+
+2005-08-23 12:32  we7u
+
+	* src/db.c: Casting some time_t's to long's to get rid of warnings.
+
+2005-08-23 12:32  we7u
+
+	* src/alert.c: Casting some time_t's to unsigned long's to get rid
+	  of warnings.
+
+2005-08-23 12:30  we7u
+
+	* acinclude.m4: Taking some of the new compiler flags back out as
+	  one of them isn't recognized on some versions of GCC, and the
+	  other causes too many warnings without it.  Hopefully we can add
+	  the "-W" back in at a later date once we figure out how to get
+	  rid of the "unused parameter" warnings on a case-by-case basis.
+
+2005-08-22 16:02  we7u
+
+	* src/io-mmap.c: Cleaning up compiler warnings.
+
+2005-08-22 15:21  we7u
+
+	* acinclude.m4: Adding "-W" and "-Wno-unused_parameter" compiler
+	  flags.  Still a clean compile with SuSE Linux 9.0.  No errors, no
+	  warnings.
+
+2005-08-22 11:45  we7u
+
+	* src/: db.c, interface.c, interface.h: Added is_local_interface()
+	  and is_network_interface() functions.  Changed packet_data_add()
+	  to use them, and to changes it functionality so that packets
+	  transmitted to local interfaces would be visible in the incoming
+	  data dialog.
+
+2005-08-22 11:37  we7u
+
+	* src/: shp_hash.c, shp_hash.h: Fixing up prototypes and function
+	  headers so that they are ANSI-C compatible.
+
+2005-08-22 11:36  we7u
+
+	* src/rtree/: card.c, gammavol.c, index.c, index.h, node.c, rect.c:
+	  Fixing up prototypes and function headers so they are ANSI-C
+	  compatible.
+
+2005-08-22 11:35  we7u
+
+	* REGRESSION_TESTS: Tweaking to match new format for summary.log
+	  file (we only want to show the first line now).
+
+2005-08-19 18:53  we7u
+
+	* src/: database.h, db.c, map_cache.c, map_cache.h, map_shp.c,
+	  maps.c, testawk.c: Fixing up function and prototype definitions
+	  so they are ansi-C standard and will pass the new compiler tests
+	  that were just added.
+
+2005-08-19 18:40  we7u
+
+	* acinclude.m4: Adding more strict compiler checking.
+
+2005-08-19 18:27  we7u
+
+	* INSTALL: Adding notes about malloc debugging.
+
+2005-08-19 14:31  we7u
+
+	* src/draw_symbols.c: Adding/changing some comments.
+
+2005-08-19 14:26  we7u
+
+	* src/draw_symbols.c: Real fix for memory leak in the font metrics
+	  code.  Don't know why we need a '1' parameter for this system
+	  call, but with a '0' we end up with a leak.
+
+2005-08-19 13:32  we7u
+
+	* src/draw_symbols.c: Fix for big memory leak.
+
+2005-08-19 11:33  tvrusso
+
+	* configure.ac, src/hostname.c: Add probe for sighandler_t
+	  definition, and code to work around it being missing.
+
+2005-08-18 16:54  we7u
+
+	* src/interface.c: Fooled myself.  Last fixes weren't fixes but
+	  stopped the compile.	Will rework that fix later.
+
+2005-08-18 16:51  we7u
+
+	* src/interface.c: Putting a few casts in to get rid of "-pedantic"
+	  warnings.
+
+2005-08-18 16:21  we7u
+
+	* src/map_cache.c: Getting rid of three more "-pedantic" warnings.
+
+2005-08-18 16:09  we7u
+
+	* src/interface.c: More tweaks so that the "-pedantic" compiler
+	  flag will show fewer warnings.
+
+2005-08-18 15:56  we7u
+
+	* src/: hostname.c, shp_hash.c: Fixing up minor warnings that the
+	  "-pedantic" compiler flag revealed.
+
+2005-08-18 15:27  we7u
+
+	* src/: alert.c, db.c: Getting rid of another couple of warnings
+	  that the "-pedantic" compiler flag revealed.	Very minor stuff.
+
+2005-08-18 15:11  we7u
+
+	* src/hashtable_private.h: Removing the semicolon at the end of a
+	  function that "-pedantic" compiler flag caught.
+
+2005-08-18 14:49  tvrusso
+
+	* acinclude.m4, src/testawk.c: Make use of LIBS in the gdal probe
+	  without gdal-config match the usage with gdal-config
+
+	  fix bogon in awk_rule table in testawk.c
+
+2005-08-18 14:43  we7u
+
+	* src/messages_gui.c: Casting to an "int" in order to get around a
+	  compiler warning that we get if we turn on stricter checking.
+
+2005-08-18 14:42  we7u
+
+	* src/main.c: Adding a missing initializer.
+
+2005-08-18 14:00  we7u
+
+	* src/: leak_detection.h, util.h: Tweaks by Tom Russo to make the
+	  new include arrangement work on FreeBSD.  Evidently I broke that
+	  platform with my most recent include file changes.
+
+2005-08-18 08:28  we7u
+
+	* src/view_message_gui.c: Moving the dmalloc code to a separate
+	  header file.
+
+2005-08-18 08:27  we7u
+
+	* src/util.c: Messing with the hash iterator free's again.  Moving
+	  dmalloc code to a separate header file.
+
+2005-08-18 08:26  we7u
+
+	* src/: map_gdal.c, maps.c, wx_gui.c: Messing with the hash
+	  iterator free's again.
+
+2005-08-18 08:26  we7u
+
+	* src/leak_detection.h: Here's where the malloc and dmalloc code
+	  was moved to.  The order in which this is done with respect to
+	  the libgc code is critical, therefore it has all been moved to
+	  this one header file so the order can be closely guarded.
+
+2005-08-18 08:24  we7u
+
+	* src/interface_gui.c: Removing the dmalloc code.
+
+2005-08-18 08:23  we7u
+
+	* src/: hashtable_private.h, hashtable_itr.c: Removing the xastir.h
+	  include.
+
+2005-08-18 08:22  we7u
+
+	* src/hashtable.c: Moving a comment.
+
+2005-08-18 08:22  we7u
+
+	* src/db.c: Removing dmalloc ifdef's.
+
+2005-08-18 08:21  we7u
+
+	* src/alert.c: Getting rid of dmalloc ifdef's.	We use libgc to do
+	  similar things.  Messing with the iterator ifdef's again.
+
+2005-08-17 13:16  we7u
+
+	* src/util.c: Skipping the free() of the hashtable iterator in all
+	  cases.
+
+2005-08-17 13:13  we7u
+
+	* src/maps.c: Moving alert-related code to debug level 2.  Skipping
+	  hash iterator free() calls for now as they cause segfaults if
+	  libgc is compiled in.
+
+2005-08-17 13:11  we7u
+
+	* src/db.c: Changing debug_level to 2 for wx_alert-related code.
+
+2005-08-17 13:10  we7u
+
+	* src/alert.c: Added some debug statements.  Skipping hash iterator
+	  free() as it causes segfaults.
+
+2005-08-17 12:13  we7u
+
+	* src/util.c: Adding leak_detector.h include.  Simplifying
+	  add_tactical_to_hash() function.
+
+2005-08-17 12:12  we7u
+
+	* src/: map_WMS.c, map_cache.c, map_dos.c, map_gdal.c, map_geo.c,
+	  map_gnis.c, map_pdb.c, map_shp.c, map_tif.c, map_tiger.c, maps.c,
+	  messages.c, messages_gui.c, popup_gui.c, rac_data.c, rotated.c,
+	  shp_hash.c, snprintf.c, sound.c, testawk.c, track_gui.c, util.h,
+	  view_message_gui.c, wx.c, wx_gui.c, x_spider.c, x_spider.h,
+	  xa_config.c, xastir.h: Adding leak_detector.h include.
+
+2005-08-17 12:11  we7u
+
+	* src/main.c: Adding leak_detector.h include.  Changing memory leak
+	  check to every 60 seconds (from 5 minutes).
+
+2005-08-17 12:08  we7u
+
+	* src/: awk.c, bulletin_gui.c, color.c, datum.c, db.c, dbfawk.c,
+	  draw_symbols.c, fcc_data.c, festival.c, geo-find.c,
+	  geocoder_gui.c, gps.c, hashtable.c, hashtable_itr.c, hostname.c,
+	  igate.c, interface.c, interface.h, interface_gui.c, io-common.c,
+	  io-mmap.c, lang.c, list_gui.c, locate_gui.c, location.c,
+	  location_gui.c, macspeech.c: Adding leak_detector.h include.
+
+2005-08-17 12:06  we7u
+
+	* src/alert.c: Adding leak_detector.h include.	Simplifying the
+	  add_wx_alert_to_hash function.
+
+2005-08-17 12:04  we7u
+
+	* src/Makefile.am: Adding the leak_detector.h file.
+
+2005-08-17 12:02  we7u
+
+	* src/leak_detection.h: Moving the LIBGC defines/includes into a
+	  new header file.  The order in which these are used in a C module
+	  is important, as is the order that the thread includes are done.
+	  This will help assure that the order remains consistent so that
+	  the memory leak detection will work.
+
+2005-08-17 11:59  we7u
+
+	* INSTALL: Tweaking the libgc instructions.
+
+2005-08-15 17:47  we7u
+
+	* src/util.c: Separating out the pointers so we can better keep
+	  track of them, assuring that we're not overwriting anything we
+	  shouldn't.  Freeing some malloc'ed space for the case where hash
+	  inserts fail.
+
+2005-08-15 17:45  we7u
+
+	* src/shp_hash.c: Freeing some malloc'ed space for the case where
+	  hash inserts fail.
+
+2005-08-15 17:44  we7u
+
+	* src/map_gdal.c: Freeing some malloc'ed space for the cases where
+	  hash inserts fail.
+
+2005-08-15 17:44  we7u
+
+	* src/alert.c: Changing a memcpy to an xastir_snprintf call in
+	  order to assure that the string is terminated.  Added some
+	  debugging set_dangerous/clear_dangerous calls.
+
+2005-08-15 17:42  we7u
+
+	* src/main.c: Making the RINO download timeout slider always
+	  visible in the timing dialog, but insensitive if gpsman is not
+	  compiled in.
+
+2005-08-15 13:01  we7u
+
+	* configure.ac: Adding a very short summary of the configure tests
+	  and results to summary.log.  This should aid in debugging as we
+	  can more quickly see what passed/failed on a particular user's
+	  machine.
+
+2005-08-14 23:43  we7u
+
+	* src/map_shp.c: Committing Tom Russo's fix to remove colon chars
+	  in track->shapefile save routine.  Seems Cygwin doesn't like
+	  colons in filenames.
+
+2005-08-13 09:43  we7u
+
+	* README.win32: Fixing a couple of typos.
+
+2005-08-12 22:21  we7u
+
+	* src/main.c: Moving one define to the top of the file.  This one
+	  contains some copyright dates and appears in the Help dialog, so
+	  must be updated periodically.  This new location for it is much
+	  better than having it hidden in the middle of the file.
+
+2005-08-12 22:07  we7u
+
+	* src/util.c: Adding spaces around the "==" in the #if statement
+	  added today.
+
+2005-08-12 20:17  we7u
+
+	* acinclude.m4, configure.ac: Taking out the new MALLOC test added
+	  today as AC_FUNC_MALLOC already does what we need.
+
+2005-08-12 14:37  we7u
+
+	* acinclude.m4, configure.ac, src/util.c: Adding rpl_malloc()
+	  function in util.c, and the associated hooks into acinclude.m4
+	  and configure.ac to get it called.  This is to replace malloc()
+	  for those cases where malloc() doesn't behave properly.
+
+2005-08-12 14:36  we7u
+
+	* INSTALL: Adding a note about libgc's extra memory usage.
+
+2005-08-12 13:41  we7u
+
+	* config/language-Portuguese.sys: Shortening the Portuguese version
+	  of "Enable Weather Alerts" string.
+
+2005-08-12 12:37  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added a Reset
+	  button to the Change Debug Level dialog.
+
+2005-08-12 12:36  we7u
+
+	* src/: alert.c, main.c, map_gdal.c, maps.c, util.c, wx_gui.c:
+	  Added a reset button to the Change Debug Level dialog.  Made the
+	  Enable WX Alerts menu item be grey'ed out if Shapelib not
+	  installed.  Added debug statements multiple places.  Put
+	  #ifndef's around a bunch of free(iterator) statements for the
+	  case when libgc is configured into the compile (else segfaults
+	  occur).
+
+2005-08-12 12:27  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-German.sys, language-Italian.sys, language-Spanish.sys:
+	  Removing "Counties" from the Enable Weather Alerts text.
+
+2005-08-12 08:38  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Adding a custom zoom
+	  option to the right-click zoom levels menu.
+
+2005-08-11 13:40  we7u
+
+	* src/main.c: Moving the Center & Zoom dialog to the Maps menu.
+
+2005-08-11 12:46  we7u
+
+	* REGRESSION_TESTS: Added a default configure/compile at the end,
+	  both to test this case and to get the codebase back to normal for
+	  the system it's run on.
+
+2005-08-11 12:20  we7u
+
+	* REGRESSION_TESTS: Removed a couple of el-stupido test cases.
+	  Nice'ed everything.
+
+2005-08-10 18:37  we7u
+
+	* configure.ac: Adding warnings so that library dependencies are
+	  obvious.  Adding code so that missing dependencies cause
+	  dependent libraries to be skipped.
+
+2005-08-10 18:35  we7u
+
+	* INSTALL: Added an ASCII-art drawing showing the library
+	  dependencies.
+
+2005-08-10 14:06  we7u
+
+	* configure.ac: Adding another configure warning for missing
+	  library.
+
+2005-08-10 12:00  we7u
+
+	* REGRESSION_TESTS: Adding tests for ALL libraries minus one, each
+	  in turn.
+
+2005-08-10 11:58  we7u
+
+	* configure.ac: Forcing use_rtree to OFF and issuing a warning if
+	  Shapelib is not being used.
+
+2005-08-10 11:39  we7u
+
+	* src/: main.c, shp_hash.c: Fixing the code for the case where
+	  rtree has been requested buy Shapelib is not compiled in.  It
+	  makes no sense to do this, but at least it will compile for this
+	  case now.
+
+2005-08-10 11:38  we7u
+
+	* src/track_gui.c: Tweaking the Fetch Findu Trail function so that
+	  it matches what findu is capable of for the trail duration.
+	  Changed the start time and duration time max values to #defines
+	  at the top of the file so we can change it more easily next time
+	  around.
+
+2005-08-09 08:57  tvrusso
+
+	* acinclude.m4: Fix for broken fix of broken fix of probe for gdal.
+
+	  After I fixed the multiply-included -lgdal issue and made sure
+	  that I'd separated out -Ls from -ls, I never made sure that the
+	  -l got into LIBS.  I was counting on AC_CHECK_LIB to do that, but
+	  it only does so if you don't provide an ACTION-IF-FOUND.
+
+2005-08-08 20:53  tvrusso
+
+	* acinclude.m4: Add ugly hack to work around gdal-config's
+	  idiosyncratic merging of LDFLAGS and LIBS data with the single
+	  "gdal-config --libs" command.  Other programs with -config
+	  scripts have --ldflags and --libs to keep the stuff separate.
+
+2005-08-08 20:18  tvrusso
+
+	* acinclude.m4: Fix broken attempt to replace old flags into
+	  variables after failing test.
+
+2005-08-08 14:12  francais1
+
+	* config/language-French.sys: Incorporated most changes from
+	  Jacques Chion
+
+2005-08-08 12:27  we7u
+
+	* src/track_gui.c: Adding a debug statement.
+
+2005-08-06 11:11  tvrusso
+
+	* acinclude.m4: Fix up AC_CHECK_GDAL so it uses LIBS instead of
+	  LDFLAGS.  This makes it more consistent with other usages.
+	  gdal-config --libs actuall returns both LDFLAGS and LIBS type
+	  information, and using its output for LDFLAGS winds up putting
+	  the -lgdal flag very early in the link line.	This could be a
+	  problem on some systems.
+
+2005-08-06 11:05  tvrusso
+
+	* acinclude.m4: Fix dumb mistake in the section that handles the
+	  "gdal-config not found" condition.
+
+2005-08-06 11:01  tvrusso
+
+	* acinclude.m4, configure.ac: Make probe for gdal use gdal-config
+	  if it can be found.
+
+	  If gdal-config is in the user's path, use it to get LDFLAGS and
+	  CPPFLAGS to help the probe for gdal.h and libgdal.a.	Otherwise,
+	  use the current settings of LDFLAGS and CPPFLAGS and hope they're
+	  found.
+
+	  In doing this, I think I see that the probe
+	  XASTIR_CHECK_IMAGEMAGICK has a few bugs in it.
+
+2005-08-06 00:14  tvrusso
+
+	* src/db.c: Fix new emergency processing in decode_ax25_line so
+	  that it only attempts to work on valid packets.  This was causing
+	  segfaults at strcmp(my_callsign,call_sign) when connecting to an
+	  internet server (upon receiving the # javAPRServ line), because
+	  call_sign was NULL.
+
+2005-08-05 18:14  we7u
+
+	* REGRESSION_TESTS: Making the output a bit easier to understand.
+
+2005-08-04 20:13  we7u
+
+	* src/draw_symbols.c: Using font metrics to determine size of font.
+	  We then use that to determine the size for the black rectangle
+	  underneath the font.
+
+2005-08-04 12:34  we7u
+
+	* src/: db.c, draw_symbols.h, draw_symbols.c: Drawing a line
+	  between the waypoint symbol and the station that originated it.
+	  Per the spec.
+
+2005-08-03 18:52  we7u
+
+	* symbols/symbols.dat: Updating a symbol or three.
+
+2005-08-03 13:16  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c, src/main.c,
+	  src/main.h: Have implemented an EMERGENCY BEACON transmit
+	  capability.  Look for it under the "Help" menu (appropriate,
+	  no?).
+
+2005-08-03 12:15  we7u
+
+	* REGRESSION_TESTS: More minor cleanups.  No real changes.
+
+2005-08-03 12:01  we7u
+
+	* src/db.c: Added emergency beacon decode for the string
+	  "EMERGENCY" anywhere in the packet, plus the strings:     ALARM
+	  ALERT     WARNING	  WXALARM     EM If seen in the TO: field
+	  of the packet.  This matches the decoding provided by APRS+SA for
+	  this feature.
+
+2005-08-02 13:22  we7u
+
+	* REGRESSION_TESTS: Small tweaks to improve the output and give us
+	  info while it is running instead of all the output at the end.
+
+2005-08-01 21:40  we7u
+
+	* REGRESSION_TESTS: Changing the order of the individual flag tests
+	  to match the summary output order from "configure".
+
+2005-08-01 21:18  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Taking "RELAY" out
+	  of the digipeat? label.
+
+2005-08-01 21:16  we7u
+
+	* REGRESSION_TESTS: Fiximg the grep at the end.
+
+2005-08-01 19:33  we7u
+
+	* REGRESSION_TESTS: Initial checkin.  A "dumb" script the way it is
+	  currently written, but it could be made much more intelligent
+	  over time, and extended to perform more tests.
+
+2005-08-01 19:29  we7u
+
+	* symbols/symbols.dat: Changing the symbols to be more
+	  spec-compliant.  The spec keeps changing on us.  Added an SUV
+	  symbol.  Moved the Shelter symbol to the secondary table.
+	  Changed the background on the Storm Watch symbol to orange
+	  instead of red.  Still need to do the waypoint symbol so it is a
+	  red circle and have a line going between it and the mobile
+	  transmitting it, plus need to change "No Sym Yet" to a circle
+	  with a slash through it, per the latest spec addendum.  It would
+	  be worth taking a look at all the symbols to verify compliance.
+
+2005-08-01 19:26  we7u
+
+	* src/map_geo.c: Getting rid of a compiler warning (unused
+	  variable) when ImageMagick isn't compiled in.
+
+2005-08-01 15:08  tvrusso
+
+	* src/map_shp.c: Move declaration of draw_filled out of WITH_DBFAWK
+	  ifdef.
+
+2005-08-01 14:34  we7u
+
+	* src/main.c: Updating the year on the Help->About copyright
+	  notice.
+
+2005-08-01 12:43  we7u
+
+	* configure.ac, help/help-English.dat: Bumping version to 1.6.1 for
+	  further development.
+
+2005-08-01 11:11  we7u
+
+	* help/help-English.dat: Updating the what's new section for 1.6.0.
+
+2005-08-01 10:54  we7u
+
+	* README.Contributing, README.Getting-Started, configure.ac,
+	  help/help-English.dat: Bumping the version to 1.6.0.
+
+2005-07-30 23:19  we7u
+
+	* src/: bulletin_gui.c, db.c, interface_gui.c, maps.h,
+	  locate_gui.c, location_gui.c, main.c, map_gnis.c, messages_gui.c,
+	  wx_gui.c: Adding new capability to the Map Feature Search
+	  function:  Now returns a chooser dialog that allows seeing up to
+	  the first fifty matches for the search, then centering the map on
+	  any of them.	Also tweaked array sizes throughout the code used
+	  for sending parameters to X11 calls.
+
+2005-07-29 12:32  we7u
+
+	* src/: locate_gui.c, map_gnis.c, maps.h: Changing locate_place()
+	  to gnis_locate_place() because it is too similar to the function
+	  Locate_place().  Added some comments w.r.t. putting in a chooser
+	  option for the Locate Map Feature function.
+
+2005-07-29 12:31  we7u
+
+	* src/db.c: Changing some comments.  No code changes.
+
+2005-07-29 12:29  we7u
+
+	* src/xa_config.c: Calling the new remove_all_spaces() function on
+	  one variable read in from the config file.
+
+2005-07-29 12:29  we7u
+
+	* src/: util.c, util.h: Added a "remove_all_spaces" function.
+
+2005-07-28 13:41  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/map_tif.c,
+	  src/xa_config.c: Implementing the XOR function for combining USGS
+	  DRG colors with underlying map colors.  Changed some labels with
+	  respect to this new function.
+
+2005-07-26 12:50  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing the DRG
+	  Color Filtering labels to the correct color names.
+
+2005-07-26 12:39  tvrusso
+
+	* src/map_gdal.c: Fix extern declaration of draw_shapefile_map
+
+2005-07-26 12:32  tvrusso
+
+	* src/main.c: Add a comment.
+
+2005-07-26 12:16  tvrusso
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/map_dos.c,
+	  src/map_gdal.c, src/map_geo.c, src/map_gnis.c, src/map_pdb.c,
+	  src/map_shp.c, src/map_tif.c, src/maps.c, src/maps.h: Implement
+	  auto detection of USGS DRG topo maps (the ones actually from
+	  USGS, with proper GeoTIFF tags).
+
+	  Changed map driver interface to take a struct of map flags
+	  instead of a single "draw_filled" integer.
+
+	  Changed map properties to support setting of Yes/No/Auto for a
+	  given map's "USGS DRG" field.  If Yes, the color map is assumed
+	  to be USGS's and the color settings in Map->Configure USGS DRG
+	  are used.  If No, all colors in the colormap are displayed.  If
+	  Auto, the tiff's Image Description tag is queried and if it
+	  begins with "USGS DRG GeoTIFF" then it's as if the setting was
+	  Yes, and if it doesn't (or the tag does not exist) then it is as
+	  if the setting was No.
+
+	  Added rowcol to map properties dialog to handle the extra buttons
+	  without widening the window.
+
+	  Cleaned up the code in main.c that locates the filename in a map
+	  properties line.  It was being done by hardcoding the offset in 8
+	  places to 31.  Moved the magic number to a preprocessor symbol so
+	  it only needs to be changed once now.  There has got to be a
+	  cleaner way still, but that's enough for now.
+
+	  Changed all map drivers to support the new map_data_flags struct
+	  instead of the int draw_filled.
+
+	  Changed language files.  Not sure I got all of them right.
+
+2005-07-25 10:00  tvrusso
+
+	* src/xa_config.c: Change DRG_COLORS settings so that they default
+	  to ON if a config file is read in that doesn't contain the
+	  settings.  This will make sure that users who upgrade don't get
+	  surprised by having all their topo maps disappear upon upgrading.
+
+2005-07-23 19:29  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/map_tif.c,
+	  src/xa_config.c, src/xastir.h: Added a Configure USGS DRG dialog.
+	  Allows turning on/off various drawing colors on geoTIFF images.
+
+2005-07-22 18:27  we7u
+
+	* src/map_tif.c: Added a couple of defines at the top that control
+	  whether we display an entire topo map or just the contours, and
+	  which color we display them in.
+
+2005-07-22 12:42  we7u
+
+	* src/util.c: Cleaning up the curl code a bit more:  Removed
+	  unnecssary includes and moved the one remaining include up to the
+	  top of the file.
+
+2005-07-21 23:17  we7u
+
+	* config/language-Dutch.sys: Translating one label.
+
+2005-07-21 23:08  we7u
+
+	* src/: track_gui.c, map_WMS.c, map_geo.c, map_tiger.c, maps.c,
+	  util.c, util.h: Consolidating all of the libcurl and wget
+	  functionality into util.c:fetch_remote_file().  This should make
+	  the code much easier to maintain and extend.
+
+2005-07-21 21:33  we7u
+
+	* INSTALL: Adding some instructions provided by Tom Russo for
+	  specifying an unusual location of libdb to configure.
+
+2005-07-21 13:04  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/geocoder_gui.c:
+	  Correcting the "Find Address" label in several spots.
+
+2005-07-21 12:53  we7u
+
+	* INSTALL: Adding a list of libraries for a full-up Xastir compile
+	  on SuSE 9.0 to aid people in deciding which libraries might be
+	  needed.
+
+2005-07-20 19:19  we7u
+
+	* src/: map_cache.c, map_cache.h, main.c: Added a run-time check
+	  for matching versions in db.h and libdb.so.
+
+2005-07-20 19:12  we7u
+
+	* src/track_gui.c: Fixing the duration hours slider so that it
+	  can't be any larger than the start hours slider.
+
+2005-07-20 11:50  we7u
+
+	* INSTALL: Adding some text having to do with using the optional
+	  Berkeley DB Library for map caching.
+
+2005-07-20 11:49  we7u
+
+	* acinclude.m4: Adding some comments to the
+	  XASTIR_BERKELEY_DB_CHK_LIB function.	Things we need to
+	  add/figure out in order to assure that the Berkeley DB Library
+	  can be successfully used with Xastir.
+
+2005-07-19 22:13  we7u
+
+	* help/help-English.dat: Added an example of how to use the Fetch
+	  trail from Findu timing sliders.
+
+2005-07-19 22:09  we7u
+
+	* src/: main.h, db.c, xa_config.c: Implementing user-configurable
+	  digipeater callsigns.  Users will now be able to edit the
+	  comma-delimited string in their xastir.cnf file.  There are no
+	  GUI tie-ins for editing the string at this point.
+
+2005-07-19 21:43  we7u
+
+	* help/help-English.dat: Adding some more detail about the Map
+	  Chooser->Properties dialog.  Adding some new text about the
+	  user-configurable relay digipeater callsigns which will be
+	  committed to CVS shortly.
+
+2005-07-19 21:41  we7u
+
+	* configure.ac: Reordering the summary.log and Help->About library
+	  strings plus adding the few that were missing.
+
+2005-07-19 21:38  we7u
+
+	* README.MAPS: Minor tweak to one comment.  Nothing substantial.
+
+2005-07-19 12:24  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Fixing up the displayed
+	  string for Beam Heading objects, "Bearing:" string.
+
+2005-07-18 11:12  tvrusso
+
+	* src/draw_symbols.c: Fix for broken DF directional lines when
+	  zoomed in tight.  Restricts range of lines to something close to
+	  the screen, rather than the full range allowed by the DF object's
+	  NRQ (or the default of 512 nautical miles.
+
+2005-07-16 23:19  we7u
+
+	* src/interface_gui.c: Allowing the passcode to be longer (up to 20
+	  chars).  Useful in a few instances, and similar to what's allowed
+	  currently in the AGWPE code.
+
+2005-07-16 23:17  we7u
+
+	* src/x_spider.c: Adding a #define and some #ifdef's that allow
+	  compiling the code in either standalone daemon mode or
+	  called-function mode.
+
+2005-07-15 09:30  we7u
+
+	* src/main.c: Adding spaces to the help text.
+
+2005-07-15 09:18  we7u
+
+	* xastir.spec.in: Re-ordering the docs alphabetically.	No real
+	  change.
+
+2005-07-13 12:37  we7u
+
+	* src/util.c: Adding some comments.  Preparatory to redoing some
+	  code.
+
+2005-07-12 19:44  tvrusso
+
+	* config/tgr2shppoly.dbfawk: Make polygon boundaries the same color
+	  as fill.  Now that boundaries are no longer stippled the same way
+	  as the fill, the black boundaries are too glaring.
+
+2005-07-12 16:06  tvrusso
+
+	* src/map_shp.c: Reset stipple style to solid when drawing
+	  boundaries of polygons with dbfawk.  They were getting drawin in
+	  the stipple pattern used for fill, which made for fuzzy
+	  boundaries.
+
+2005-07-11 12:25  we7u
+
+	* configure.ac: Fixing the Geotiff summary line so that it says
+	  "no" if libproj isn't found.	It was blank until now in this
+	  case.
+
+2005-07-11 12:24  we7u
+
+	* src/map_geo.c: Moving one line so that this will compile ok
+	  without warnings if no ImageMagick.
+
+2005-07-11 10:50  we7u
+
+	* src/xastir.h: If ImageMagick is not found, util.c compile will
+	  fail without this change.
+
+2005-07-11 07:55  tvrusso
+
+	* src/main.c: Put use of map_cache_fetch_disable into the same
+	  ifdef as the definition of that variable, so that people who
+	  aren't using map caching can link.
+
+2005-07-10 10:56  tvrusso
+
+	* FAQ: Change question 5.4 to actually have "5.4" in its title.
+
+2005-07-10 08:37  tvrusso
+
+	* scripts/Xastir_tigerpoly.py: Add -d flag to the Usage error
+	  message.
+
+2005-07-10 08:36  tvrusso
+
+	* scripts/Xastir_tigerpoly.py: Add "-d" option to this script to
+	  allow dissolution of common boundaries between polygons with the
+	  same Landmark designation.
+
+	  This is done by scanning all PolyChainLink records, checking that
+	  both left and right polygon have associated AreaLandmark records,
+	  and that both AreaLandmark records point to the same Land record.
+	   If they do, then the two polygons are dissolved into one.
+
+	  The option is not the default.
+
+	  Using this option makes the output shapefile be topologically
+	  inequivalent to the original TIGER/Line data, and as such they
+	  are suitable only for display.  Distributing data produced in
+	  this manner should be done with a prominient disclaimer pointing
+	  out that the shapefiles are for display purposes, not serious GIS
+	  use.
+
+	  Dissolving polygons in this way makes the TIGER data look much
+	  nicer (but still pretty ugly) in xastir -- large landmarks no
+	  longer have many copies of the labels, and no longer have ugly
+	  internal dashed boundaries that mean nothing.
+
+2005-07-08 20:30  we7u
+
+	* src/dbfawk.c: A fix for the emacs temp-file bug that is invoked
+	  by temp file symlinks of the form ".*.dbfawk" while editing
+	  dbfawk files.  The code will now ignore anything but regular
+	  files, and ignores directories and files that have a leading
+	  period.
+
+2005-07-08 20:27  we7u
+
+	* src/: main.c, map_WMS.c, map_cache.c, map_cache.h, map_geo.c,
+	  map_tiger.c: Enabling the reload maps (without cache) option on
+	  the Map menu, with the back-end code in place to implement it.  A
+	  few tweaks to the map_cache_del() function to return with error
+	  code under certain conditions.
+
+2005-07-08 13:19  we7u
+
+	* src/main.c: Comment changes only.
+
+2005-07-08 12:24  we7u
+
+	* src/main.c: Changed some comments.
+
+2005-07-08 00:07  we7u
+
+	* src/main.c: Implemented "Flush Entire Map Cache" function.
+
+2005-07-07 19:22  we7u
+
+	* src/xastir.h: Renaming tigermap_timeout to net_map_timeout.
+
+2005-07-07 19:21  we7u
+
+	* src/: map_geo.c, main.c, map_WMS.c, map_tiger.c, util.c,
+	  xa_config.c: Moving the tigermap slider to the
+	  file->configure->timing dialog.  Changing it's label so that it
+	  is obvious it is for all internet map downloads, not just
+	  Tigermaps.  Changing the tigermap_timeout global variable to
+	  net_map_timeout to more fully reflect its use.
+
+2005-07-07 18:52  we7u
+
+	* help/help-English.dat: Updating map caching lingo.  Adding more
+	  special .GEO file keywords and updating some that were there to
+	  match the latest code.
+
+2005-07-07 18:49  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding some
+	  strings for map caching controls.  Tweaking another string having
+	  to do with the map download timeout slider.
+
+2005-07-07 18:47  we7u
+
+	* README.MAPS: Updating the lingo w.r.t. map caching.
+
+2005-07-07 18:46  we7u
+
+	* INSTALL: Minor comment change.
+
+2005-07-06 22:38  we7u
+
+	* src/: map_WMS.c, map_geo.c, map_tiger.c, util.c: Making the curl
+	  timeouts track with the tigermap_timeout global variable.
+	  Previously they were set to a fixed 30 second timeout.  Not
+	  enough for slow links.
+
+2005-07-06 20:38  tvrusso
+
+	* config/tgr2shppoly.dbfawk: Make intermittent water polygons a
+	  pale stippled fill.
+
+2005-07-06 18:25  we7u
+
+	* src/map_geo.c: Added some comments.  Made one fprintf only active
+	  in debug mode.
+
+2005-07-06 13:35  tvrusso
+
+	* scripts/Xastir_tigerpoly.py: While trying to understand why my
+	  TIGER polygon maps have so many identically-named small polygons,
+	  I discovered an error in the Xastir_tigerpoly.py script that was
+	  propagated from the original GDAL tigerpoly.py script.
+
+	  The TIGER/Line format has a "Type I" record that links complete
+	  chains (Type 1) to "GT-Polygons" through the "POLYIDL" and
+	  "POLYIDR" attributes.  But according to the TIGER/Line
+	  documentation, a Type I record that contains identical POLYIDL
+	  and POLYIDR attributes is a line that is internal to a polygon,
+	  and should not be included in its boundary.  The original
+	  tigerpoly.py script from which Xastir_tigerpoly.py was derived
+	  simply added all lines with either POLYIDL or POLYIDR to the
+	  boundary of polygon POLYID.  That means that these internal
+	  points were not only incorrectly added to the boundary of POLYID,
+	  they were added twice.
+
+	  A simple test to throw away such "PolyChainLink" data (in the OGR
+	  parlance, "Type I record" in the TIGER parlance) removes this
+	  incorrect assembly of polygon boundaries.
+
+	  This does *not* fix the issue of there being lots of tiny,
+	  identically-named polygons in a given area (that's just how the
+	  data is), but it DOES correct the "Error in computing fill/hole
+	  ring" warnings I've been getting since forever, every time these
+	  TIGER/Line-converted polygon shapefiles are loaded.  It also
+	  fixes the problem I had trying to import these polygon shapefiles
+	  into GRASS, which noticed and griped angrily about the
+	  topological incorrectness of the data.
+
+	  Unfortunately, taking advantage of this fix would require
+	  regenerating all the TIGER polygon shapefiles that are up on
+	  xastir.tamu.edu --- probably not worth the effort.  But should
+	  there be a new round of corrected TIGER data that gets processed,
+	  the script is now producing (more) topologically correct
+	  shapefiles.
+
+	  It might be a good idea to feed this back to Frank Warmerdam, on
+	  whose tigerpoly.py script Xastir_tigerpoly.py was based.
+
+2005-07-06 12:58  we7u
+
+	* src/: main.h, map_geo.c, map_tiger.c: Adding a parameter to the
+	  draw_tiger_map() function, to be used for future implementation
+	  in the tiger code for a "refresh map w/o cache" option.
+
+2005-07-06 12:28  we7u
+
+	* src/: main.h, map_WMS.c, map_geo.c: Added caching for all types
+	  of internet maps, disabled by adding a "REFRESH" tag to the .geo
+	  file.
+
+2005-07-06 12:27  we7u
+
+	* src/map_cache.c: Added some bulletproofing and some more debug
+	  messages.
+
+2005-07-06 12:26  we7u
+
+	* src/map_tiger.c: Changed one debug message.
+
+2005-07-06 08:27  we7u
+
+	* src/map_tiger.c: Adding some comments.
+
+2005-07-06 08:25  we7u
+
+	* src/map_tif.c: Changing a printf into an fprintf.
+
+2005-07-06 08:22  we7u
+
+	* src/: hostname.c, main.c, messages.c, sound.c, x_spider.c:
+	  Changing some printf's to fprintf's, snprintf's to
+	  xastir_snprintf's.  Adding timestamp to x_spider messages which
+	  are sent to the console.
+
+2005-07-01 15:23  we7u
+
+	* INSTALL, README.Getting-Started, configure.ac: Adding a
+	  "--without-map-cache" flag to configure.  Updating docs to match.
+
+2005-06-30 17:12  we7u
+
+	* src/map_tiger.c: Fixing a compile problem that occurs if
+	  ImageMagick isn't installed.
+
+2005-06-30 17:11  we7u
+
+	* src/map_gdal.c: Removing "static" from the function returns of
+	  functions defined inside functions.  Evidently the latest GCC
+	  enforces that restriction.
+
+2005-06-30 17:09  we7u
+
+	* README.MAPS, FAQ, README.win32, help/help-English.dat,
+	  help/help-German.dat, help/help-Portuguese.dat: Cleaning up some
+	  docs w.r.t. Terraserver info.  Adding a few more FAQ entries that
+	  come up from time to time.
+
+2005-06-30 13:29  we7u
+
+	* FAQ: Adding a bit about the Terraserver zone-crossing problem.
+
+2005-06-30 13:16  we7u
+
+	* Makefile.am, terraserver-reflectivity.geo, terraserver-topo.geo,
+	  terraserver-urban.geo, terraserver.geo, toposerver.geo,
+	  src/map_geo.c: Changed the name of toposerver.geo to
+	  terraserver-topo.geo.  Added more options for terraserver so that
+	  we can use all four options available currently.  Put a bit more
+	  debugging code and parameter checking code into map_geo.c.
+
+2005-06-29 09:29  we7u
+
+	* src/map_gdal.c: Putting draw_shapefile_map() between ifdef's, as
+	  it isn't defined in some cases (if shapelib isn't available).
+
+2005-06-25 17:46  tvrusso
+
+	* FAQ: Just copy a FAQ heading into the TOC.
+
+2005-06-25 17:30  tvrusso
+
+	* src/maps.c: Undo bonehead commit by KM5VY (me).
+
+	  I had mistakenly thought that "draw_filled" was a new map index
+	  parameter, and tried to get the index_retrieve_from_file function
+	  to set defaults for shapefiles differently.
+
+	  This was an error, as draw_filled has always existed.
+
+	  There is no way to "fix up" the index when running with new code
+	  -- the user is simply going to have to go through the map
+	  properties and turn Auto on if he/she wants filled shapefiles to
+	  respect the dbfawk file's settings.
+
+	  The reason I thought the commit was right was that I was testing
+	  it on an index that had been passed through awk to remove the
+	  draw_filled variable.  It then inserted reasonable defaults, but
+	  that's not the point.
+
+	  It's unfortunate that a user with an existing batch of filled
+	  shapefiles and dbfawk enabled will wind up surprised that they
+	  stopped being filled, but that's the way it is.
+
+2005-06-25 09:02  we7u
+
+	* src/util.c: A fix for digipeating:  valid_path() was adding an
+	  asterisk on to the end of wideN-n/traceN-n digi's that had n!=N.
+	  This caused unused digi's that were earlier in the path to be
+	  skipped in the relay_digipeat() code.  For instance a path of
+	  "wide1-1,wide2-2" was working, but a path of "wide1-1,wide2-1"
+	  was being changed into "wide1-1,wide2-1*", and the wide1-1 digi
+	  would be skipped.
+
+2005-06-24 16:09  we7u
+
+	* src/db.c: Length of temp variable was too short to handle max
+	  header length.
+
+2005-06-23 22:55  we7u
+
+	* src/map_cache.c: Adding a bunch of segfault debug code in order
+	  to find a problem that one user is having with map caching of
+	  tigermaps.
+
+2005-06-23 13:26  we7u
+
+	* AUTHORS: Adding Dan Brown to the list.
+
+2005-06-23 13:14  we7u
+
+	* AUTHORS: Adding Alan Crosswell to the list.
+
+2005-06-23 13:10  we7u
+
+	* AUTHORS: Adding Tom Russo to the list.
+
+2005-06-23 12:27  we7u
+
+	* AUTHORS: Adding Derrick to the list.
+
+2005-06-23 09:07  tvrusso
+
+	* src/maps.c: Fix migration of pre-"auto fill" map_index.sys to new
+	  format.
+
+2005-06-22 22:47  tvrusso
+
+	* src/map_shp.c: Fix broken handling of "auto" shapefile filling.
+
+	  There was a test of "draw_filled" to see if it was set to "auto",
+	  but if it was, then draw_filled was changed to whatever the
+	  dbfawk file "filled" value was.  Since that was always 0 or 1, it
+	  meant that every shape after the first one would not have
+	  "draw_filled" set to auto anymore, and the entire shapefile would
+	  be filled with whatever that first shape's value was (on or off).
+
+2005-06-22 12:47  we7u
+
+	* src/map_shp.c: Fixing up the default polygon fill condition for
+	  when dbfawk file is not present (just a comment change) or for
+	  when dbfawk support is not compiled into Xastir, for the case
+	  where "Auto" fill is selected.
+
+2005-06-22 12:30  we7u
+
+	* README.MAPS, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  src/main.c, src/map_shp.c, src/maps.c, src/maps.h: Implementing
+	  an "Auto" function in the Map Properties dialog for polygon
+	  fills.  "Auto" will cause a dbfawk file to be used, if it is
+	  present.  The "Yes" (On) and "No" (Off) filled options that
+	  existed before will now override a dbfawk file, so you can use a
+	  Shapefile map in three different ways now from the Map Properties
+	  dialog.  I use this "No" option for instance to make the NOAA
+	  Counties Shapefile into a vector map so I can overlay it on top
+	  of a raster map, use the "Yes" function to use it as a base map
+	  of the U.S., or use the "Auto" function to get all the advanced
+	  per-object coloring possible from the dbfawk file, including
+	  county names, border colors, etc.
+
+	  The default setting for new Shapefiles will be "Auto".  Default
+	  for all other types of maps will be "No" or "Off".
+
+2005-06-21 18:15  we7u
+
+	* src/db.c: Updating some comments.
+
+2005-06-21 18:12  we7u
+
+	* src/map_tiger.c: Adding set/clear_dangerous() calls to aid in
+	  debugging segfaults.
+
+2005-06-21 18:10  we7u
+
+	* src/: util.c, util.h, map_gdal.c: Moving set_dangerous() and
+	  clear_dangerous to util.c/util.h and making them globally
+	  available.  These routines set/clear a string which gets dumped
+	  out upon segfault.  A debugging tool mostly.
+
+2005-06-21 13:13  we7u
+
+	* src/db.c: Moved check for zero unused digipeater fields in
+	  relay_digipeat() function down a few lines in the code, to AFTER
+	  where we reposition past the destination callsign.
+
+2005-06-21 12:43  we7u
+
+	* src/util.c: Adding checks for used-up WIDEn-N/TRACEn-N digipeater
+	  slots and for maximum total digipeats to the check_unproto_path()
+	  function.  Max digipeats is only allowed to be as high as
+	  MAX_WIDES + 1, no more.  For instance, if MAX_WIDES is 4, then
+	  "WIDE1-1,WIDE4-4" is legal, "WIDE1-1,WIDE,WIDE4-4", "WIDE5-5", or
+	  "WIDE,WIDE,WIDE,WIDE,WIDE,WIDE" are not.
+
+2005-06-21 08:18  we7u
+
+	* config/nwsc_ddmmyy.dbfawk: Changing back to filled and black
+	  border for the counties.  It just makes too excellent of a base
+	  map at present as-is.  Will tweak back to non-filled once the
+	  Xastir code is changed to allow overriding that parameter in Map
+	  Properties.
+
+2005-06-21 08:09  we7u
+
+	* config/nwsc_ddmmyy.dbfawk: Reducing the line width for the county
+	  borders.
+
+2005-06-21 08:05  we7u
+
+	* config/: nwsc_ddmmyy.dbfawk, nwsfz_ddmmyy.dbfawk,
+	  nwsmzddmmyy.dbfawk, nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk,
+	  nwsz_ddmmyy.dbfawk: Changing to non-filled.  Will soon try to
+	  tweak Xastir code so that the filled option can be chosen in the
+	  map properties and override the dbfawk setting, so at least the
+	  counties file can be selectively chosen to be filled.  It makes a
+	  good base map sometimes.
+
+2005-06-20 13:34  we7u
+
+	* src/map_cache.c: A tweak by Dan Brown to help eliminate segfaults
+	  in Tigermap caching.
+
+2005-06-20 08:05  we7u
+
+	* config/: nwsc_ddmmyy.dbfawk, nwsfz_ddmmyy.dbfawk,
+	  nwsmzddmmyy.dbfawk, nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk,
+	  nwsz_ddmmyy.dbfawk: Changing default fill color to dark grey
+	  instead of purple.
+
+2005-06-17 07:35  we7u
+
+	* WMSRadar.geo: Changing a comment.
+
+2005-06-14 14:01  we7u
+
+	* src/interface.c: Commenting out a debug fprintf statement.
+
+2005-06-14 12:59  we7u
+
+	* src/: interface.c, interface.h: Adding a #define in interface.h
+	  called CONVERSE_MODE.  This can be set to "k" or "conv" via
+	  different defines to account for different TNC command sets.
+
+2005-06-14 12:39  we7u
+
+	* src/interface.c: Changed some comments.
+
+2005-06-13 19:45  we7u
+
+	* config/: Makefile.am, tnc-startup.tnc2: Adding a TAPR-2 style
+	  startup file.  This one is mostly a copy of the
+	  tnc-startup.paccomm file for the moment, but will probably
+	  diverge from it over time.
+
+2005-06-10 09:55  tvrusso
+
+	* src/db.c: Add additional check on wx stations to aloha
+	  calculations.  APRSDos only checks the symbol for "_", we were
+	  only checking if there's any WX data.  I was finding that some
+	  stations with _ symbols were not being classed as wx stations,
+	  apparently because their last posit had no weather or something.
+
+	  Add "_" to the test.
+
+2005-06-09 18:19  we7u
+
+	* DEBUG_LEVELS: Adding Multipoint to the 2048 level description.
+	  Naming the function in main.c that must be changed if more levels
+	  are added.
+
+2005-06-08 22:08  tvrusso
+
+	* DEBUG_LEVELS, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  src/database.h, src/db.c, src/main.c: Several improvements of
+	  ALOHA reporting, as discussed on xastir-dev
+
+	  1) Change #ifdef DEBUG_ALOHA to a debug level test (2048) 2) Add
+	  periodic display of ALOHA range in status line 3) Add a
+	  "View->ALOHA Statistics" menu option.  Pops up a dialog with
+	  ALOHA    range, number of stations in ALOHA circle, count of
+	  various types of    stations, and age of ALOHA calculation.
+
+2005-06-08 09:00  we7u
+
+	* FAQ: Adding a bit about how to turn off the aloha circle display.
+
+2005-06-08 08:45  we7u
+
+	* src/main.c: Calculating the Aloha circle even if the feature is
+	  turned off.  This means that if the feature is turned back on
+	  again the circle will be accurate.  The processing occurs so
+	  seldom anyway that it's not much of a hit.
+
+2005-06-07 22:33  tvrusso
+
+	* src/map_tiger.c: Fix initialization of local_filename[0] so that
+	  gcc 2.95 can compile this file.
+
+2005-06-07 22:16  tvrusso
+
+	* src/db.c: Fix mistake in logic of aloha_distance() that was
+	  letting some oddly configured mobiles to slip through the cracks
+	  (those with trackpoints and no speed).
+
+2005-06-07 13:04  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing the aloha
+	  circle string to "Display" instead of "Disable".
+
+2005-06-07 13:01  we7u
+
+	* src/: db.c, main.c: Fixing some minor errors in the aloha toggle
+	  code.  Changing the name of the toggle and callback to be more
+	  consistent with the rest of the code.
+
+2005-06-07 12:54  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h:
+	  Adding an option to disable the Aloha Circle.  This option is not
+	  saved to the config file, by choice.	It's intended that the
+	  Aloha circle be on the map for the default case so that people
+	  might make use of it.  The toggle has been added for those rare
+	  cases where the Aloha Circle needs to be removed from the screen.
+
+2005-06-07 09:25  we7u
+
+	* src/map_tiger.c: Reorganization by Dan Brown, n8ysz.	This is in
+	  preparation for another way-cool feature that Dan is working on.
+	  Stay tuned!
+
+2005-06-07 05:33  tvrusso
+
+	* src/draw_symbols.h: Declare draw_aloha_circle to suppress
+	  compilation warnings.
+
+2005-06-06 23:06  tvrusso
+
+	* src/database.h: Put an ifdef around a struct element only used
+	  for debugging.  This should cut down on memory use during ALOHA
+	  calculation when not debugging.
+
+2005-06-06 22:54  tvrusso
+
+	* FAQ, src/database.h, src/db.c, src/draw_symbols.c, src/main.c:
+	  Feature request 1043058
+
+	  Add function to display ALOHA circles on the map.  ALOHA radius
+	  calculated according to Bob Bruninga's alohacir.txt file, and
+	  private communications.
+
+2005-06-02 08:27  we7u
+
+	* README.win32: Adding a note about shutting down applications
+	  before updating files.
+
+2005-06-01 13:11  we7u
+
+	* scripts/Makefile.am: Adding get_shapelib.sh to list of scripts to
+	  install.
+
+2005-06-01 13:06  we7u
+
+	* INSTALL, README.win32: Adding notes about the
+	  xastir/scripts/get_shapelib.sh script.
+
+2005-06-01 13:04  we7u
+
+	* scripts/get_shapelib.sh: Script to get/install Shapelib by Dan
+	  Brown, n8ysz.  Thanks!
+
+2005-06-01 12:24  we7u
+
+	* INSTALL, README.win32, src/db.c, src/gps.c: Adding some notes
+	  about building Shapelib that Dan Brown came up with.	Tweaking
+	  the GPS GPGGA and GPRMC comments in the sources.
+
+2005-05-31 19:48  tvrusso
+
+	* README.MAPS: Remove statement that is no longer true.
+
+2005-05-31 15:25  tvrusso
+
+	* src/map_tif.c: Make lat/lon rasters subject to same kinds of
+	  scan-line-skipping optimizations as UTM rasters have always had.
+
+	  The trick was to realize that "scale_y" has units of "hundredths
+	  of seconds per pixel" and that PixelScale in lat/long rasters has
+	  the units of "degrees per pixel".
+
+2005-05-31 12:32  we7u
+
+	* WMSRadar.geo, src/main.h, src/map_WMS.c, src/map_geo.c,
+	  src/maps.h: Implementing TRANSPARENT keyword for WMS maps and
+	  changing WMSradar.geo to correspond.
+
+2005-05-25 12:12  gstueve
+
+	* src/alert.c: Fix spelling in comment.
+
+2005-05-25 11:42  we7u
+
+	* WMSRadar.geo, src/map_WMS.c: Moving the VERSION tag into the .geo
+	  file.  Some servers are picky about this, so it can't be
+	  hard-coded.
+
+2005-05-24 12:49  we7u
+
+	* src/map_WMS.c: Adding/changing some comments.
+
+2005-05-24 12:21  we7u
+
+	* src/map_WMS.c: Moving more of the WMS parameters into the .geo
+	  file instead of hard-coding them.
+
+2005-05-24 12:20  we7u
+
+	* WMSRadar.geo: Moving more of the parameters into the .geo file
+	  instead of hard-coding them.
+
+2005-05-24 07:23  we7u
+
+	* WMSRadar.geo: Getting rid of the county outlines in the
+	  downloaded image.
+
+2005-05-23 13:16  we7u
+
+	* src/map_WMS.c: Corected some comments.  Turned off debug output.
+
+2005-05-23 12:59  we7u
+
+	* WMSRadar.geo, src/map_WMS.c: Moving more of the parameters into
+	  the .geo file instead of hard-coded (allows more options to be
+	  specified via the .geo files).  Tweaked the scaling so that the
+	  vertical scaling is correct now.
+
+2005-05-23 12:30  we7u
+
+	* src/util.c: Tweaking the lat/long string conversion routines so
+	  they'll handle more input formats.
+
+2005-05-20 07:33  we7u
+
+	* src/map_WMS.c: Small tweaks to the URL generation for WMS
+	  servers.  Map registration is not correct yet.
+
+2005-05-19 08:43  we7u
+
+	* src/.cvsignore: Adding "xastir" as well so that we won't see that
+	  in the CVS status listings.  It's obviously a derived file.
+
+2005-05-19 08:26  we7u
+
+	* .cvsignore, callpass/.cvsignore, config/.cvsignore,
+	  help/.cvsignore, m4/.cvsignore, scripts/.cvsignore,
+	  src/.cvsignore, src/rtree/.cvsignore, symbols/.cvsignore: Adding
+	  more lines to the .cvsignore files in order to clean up CVS
+	  status listings.
+
+2005-05-19 08:01  we7u
+
+	* Makefile.am, WMSRadar.geo, src/Makefile.am, src/main.h,
+	  src/map_WMS.c, src/map_geo.c: Adding initial support for WMS map
+	  formats.  This is not complete yet, but the functionality is
+	  enough to give a taste for what is possible in the near future.
+	  Registration is still a bit off plus we need to add methods for
+	  the user to specify layers desired, specifying WMS servers from
+	  the GUI, etc.
+
+2005-05-18 12:24  we7u
+
+	* src/gps.c: Modified parsing of GPGGA and GPRMC NMEA sentences to
+	  handle more variations in the sentence structure.
+
+2005-05-18 12:23  we7u
+
+	* src/db.c: Changing some comments and debug statements having to
+	  do with GPGGA and GPRMC NMEA sentence parsing.
+
+2005-05-18 09:41  we7u
+
+	* src/gps.c: Tweak to the GPGGA parsing to allow a '3' for GPS fix
+	  quality.
+
+2005-05-17 13:41  we7u
+
+	* src/util.c: I've had this patch around for a couple of weeks.  It
+	  should allow matching on non-numeric SSID's for messaging now,
+	  such as "WHO-IS" and "AE5PL-EM", which are the two test cases
+	  that broke messaging earlier.  It has not been fully tested on RF
+	  yet, but appears to work when directly on the internet feeds.
+
+2005-05-09 10:09  we7u
+
+	* configure.ac, help/help-English.dat: Setting up for further CVS
+	  development of Xastir.  Changing rev to 1.5.1 to differentiate it
+	  from the 1.5.0 stable release.  Added a new "What's New in Xastir
+	  BETA" section to the help-English.dat file.
+
+2005-05-09 09:34  we7u
+
+	* README.Contributing, README.Getting-Started, configure.ac,
+	  help/help-English.dat: Updating for soon to be done 1.5.0
+	  release.
+
+2005-05-09 09:32  we7u
+
+	* src/db.c: Spelling fix in comment.  No code changes.
+
+2005-05-06 13:59  we7u
+
+	* src/awk.c: Another tweak by by John Laxson, KC0PZN.  This one
+	  fixes something that I messed up when I incorporated his first
+	  patch.
+
+2005-05-05 12:36  we7u
+
+	* src/interface.c: Changed one comment.  No code changes.
+
+2005-05-05 12:23  we7u
+
+	* src/awk.c: Tweak by John Laxson, KC0PZN, to speed up dbfawk on
+	  MacOSX.  Thanks!
+
+2005-05-05 12:19  we7u
+
+	* README: Getting rid of version number where it's not needed.
+	  Will save us some work in the future.
+
+2005-04-29 15:06  kd6zwr
+
+	* src/interface.c: Fixes for segmentation faults on Solaris.
+	  Sending a NULL pointer to a %s argument to any of the *printf()
+	  functions (actually strlen() inside it) causes the fault.  This
+	  patch intializes two vars to "" instead of NULL, {Which is OK!!}
+	  protects a function by whacking NULLs into ""s, and moves a debug
+	  printf below a NULL check.
+
+2005-04-26 11:24  we7u
+
+	* src/interface.c: If an interface goes down due to a connection
+	  being lost or inactivity, the 1st check_ports() call will bring
+	  it back up now.  Previously it would wait for the 2nd
+	  check_ports() call before bringing it back up.
+
+2005-04-25 12:44  we7u
+
+	* README.MAPS: Added a paragraph about splitting large Shapefiles
+	  into tiles.
+
+2005-04-25 12:44  we7u
+
+	* README.Getting-Started: Minor changes to a couple of sentences.
+
+2005-04-19 10:39  we7u
+
+	* src/track_gui.c: Fix by David Flood, kd7myc.	Turns of TrackMe
+	  button if you leave tracking on but change the call being tracked
+	  via the menus.  Thanks!
+
+2005-04-17 21:31  rzg
+
+	* help/help-English.dat: Updated the "what's new", shamelessly
+	  ripping parts of curt's release notes because I'm behind in
+	  keeping up with CVS. :-P
+
+2005-04-15 10:42  we7u
+
+	* xastir.spec.in: Adding a few more docs to the doc list.
+
+2005-04-15 10:02  we7u
+
+	* src/: interface.c, interface.h, interface_gui.c, xa_config.c:
+	  Changes by Andreas Bier, DL1HRC, to allow setting a tnc2multi
+	  into KISS mode via a togglebutton on the interface dialog.  We
+	  can probably extend this later to put other types of TNC's into
+	  KISS mode and/or to take them out of KISS mode when shutting down
+	  the interface.
+
+	  I also changed the default for new interfaces to have
+	  RELAY/WIDE1-1 digipeat turned off.
+
+2005-04-15 09:30  we7u
+
+	* README.Contributing: More info about diff's and patching.
+
+2005-04-15 09:01  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changes by Andreas
+	  Bier, DL1HRC.  Thanks!
+
+2005-04-14 12:38  we7u
+
+	* README.Getting-Started: Adding more notes about the 2nd-tier
+	  servers.
+
+2005-04-14 11:31  we7u
+
+	* Makefile.am: Adding the new doc into the Makefile structure.
+
+2005-04-14 10:35  we7u
+
+	* README.Contributing: Adding a document to assist budding
+	  developers.
+
+2005-04-13 08:50  we7u
+
+	* src/util.c: Fixing a path check problem.  It wasn't verifying
+	  that the char before the '-' was a digit before applying N-n
+	  checks to the callsign.
+
+2005-04-12 21:12  we7u
+
+	* README.Getting-Started: Pointing to a list of 2nd-tier servers
+	  instead of suggesting Firenet.us.
+
+2005-04-12 08:50  we7u
+
+	* help/help-Dutch.dat, help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, src/interface.c:
+	  Changing the default path.  Changing the docs to match.
+
+2005-04-11 13:07  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys, tnc-startup.aea,
+	  tnc-startup.kam, tnc-startup.kpc2, tnc-startup.kpc3,
+	  tnc-startup.paccomm, tnc-startup.pico, tnc-startup.sys: Changing
+	  from RELAY to WIDE1-1 in prompts and TNC startup files.
+
+2005-04-11 12:51  we7u
+
+	* FAQ, README.Getting-Started: Updating the path discussions to
+	  cover the new scheme (WIDE1-1 instead of RELAY).
+
+2005-04-06 12:26  we7u
+
+	* src/: db.c, util.c: Making the "RELAY" digipeat work with either
+	  RELAY or WIDE1-1, per the latest APRSSIG recommendations on how
+	  to do paths and digipeating.
+
+2005-04-06 10:03  we7u
+
+	* src/util.c: Allowing WIDE1-1 as a RELAY type of callsign per the
+	  new paradism.
+
+2005-03-31 12:43  we7u
+
+	* src/: db.c, util.c: Fixes to make the new WHO-IS server work with
+	  Xastir.
+
+2005-03-30 09:12  we7u
+
+	* src/: map_geo.c, map_tiger.c, util.c: Changing text of one type
+	  of error message.
+
+2005-03-25 22:33  we7u
+
+	* README.MAPS: Added a note about a blemish in the Haversine
+	  formula we use for distance calculation.
+
+2005-03-25 12:53  we7u
+
+	* scripts/permutations.pl: Changes to the comments/description.
+
+2005-03-25 12:26  we7u
+
+	* src/datum.h: Changing some comments.
+
+2005-03-25 09:06  we7u
+
+	* README.MAPS: Added a summary regarding our distance/angle/area
+	  calculations.
+
+2005-03-24 12:25  we7u
+
+	* src/: datum.h, main.c, util.c: Switching to Gerry-recommended
+	  Earth radii plus putting them into central defines in datum.h.
+	  That makes them easier to update in the future.
+
+2005-03-23 22:05  we7u
+
+	* src/main.c: Converting the Measure function from calculating area
+	  via planar geometry to computing it using spherical calculations.
+	  It should be much closer to reality now, particularly as one
+	  zooms out.
+
+2005-03-23 21:57  we7u
+
+	* src/util.c: Changing some comments.
+
+2005-03-23 21:51  we7u
+
+	* src/util.h: Making a couple of routines available to other
+	  modules.
+
+2005-03-23 12:36  we7u
+
+	* src/util.c: Converting the distance calculations from using the
+	  Law of Cosines for Spherical Geometry to using the Haversine
+	  Formula.  This should be more accurate for shorter distances, no
+	  real change for longer distances.
+
+2005-03-23 09:33  we7u
+
+	* src/main.c: Bumping the check interval for inactivity from 1
+	  minute to 5 minutes.	This means that if we lose an internet
+	  connection we might not get it back for between 10 to 15 minutes
+	  (instead of the current 2 to 3 minutes), but it also means that
+	  server connections won't bounce up and down as much if there are
+	  few packets coming down the pipe.  One packet every 5 minutes is
+	  enough to keep the connection going.
+
+2005-03-22 15:10  we7u
+
+	* src/util.c: Changed some comments.
+
+2005-03-22 13:11  we7u
+
+	* src/draw_symbols.c: Added/changed some comments.
+
+2005-03-22 12:38  we7u
+
+	* README.Getting-Started: Added an enumeration of the various ways
+	  of controlling Xastir itself.
+
+2005-03-21 20:57  we7u
+
+	* src/: database.h, db.c, draw_symbols.c: Fixes for DF objects to
+	  make the beamwidths and angles correct.  Also fixed the
+	  "Unusable" beamwidth so that it still appears as a DF object in
+	  the Object->Modify dialog.
+
+2005-03-20 16:33  tvrusso
+
+	* src/testawk.c: Add initializer for pattern, add variable for
+	  label_color, and add appropriate code so that dbfawk files that
+	  set label_color can be tested.
+
+2005-03-18 13:20  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/util.c, src/db.c: Fixing
+	  decoding of compressed DF beam objects/items.  Fixing the display
+	  in Station Info of DF stations.
+
+2005-03-18 12:09  we7u
+
+	* src/: db.c, main.c: Fixes for varying truncation on object/item
+	  comments.  We were allowing comments that were longer than 43
+	  chars, which were truncated during later transmits by
+	  check_and_transmit_objects_items().  We now no longer allow the
+	  extra length packets to be transmitted.  The spaces that were
+	  added for Pmin/Pmax are now no longer added: that was another
+	  cause for the varying truncation of the comment.
+
+	  Fixed the object/item transmit routines so that we can now send
+	  compressed-mode for all types.  The decode routines now have to
+	  catch up.
+
+2005-03-17 13:16  we7u
+
+	* src/db.c: Better implmentation of my debug tweak that will work
+	  with more compilers.
+
+2005-03-17 13:07  we7u
+
+	* src/db.c: Removing some comments.
+
+2005-03-17 12:30  we7u
+
+	* src/draw_symbols.c: More work on dead-reckoning to position the
+	  ghost symbols and the dashed lines correctly.  Have disabled the
+	  arcs for now as the positioning is not correct for them with the
+	  current code.
+
+2005-03-17 12:28  we7u
+
+	* src/util.c: Added poor-man's rounding to the places we construct
+	  the transmitted lat/long's.  This helps with dead-reckoning of
+	  symbols at close-in zoom levels.
+
+2005-03-17 12:27  we7u
+
+	* src/db.c: Added a define and some ifndef's to make some debug
+	  easier.
+
+2005-03-17 07:34  we7u
+
+	* src/map_cache.c: Tweaks by Dan Brown, N8YSZ.
+
+2005-03-17 07:21  we7u
+
+	* src/database.h: Changed one comment.
+
+2005-03-16 13:36  we7u
+
+	* src/: igate.c, interface.c, interface_gui.c, location_gui.c,
+	  main.c, map_geo.c, map_gnis.c, map_shp.c, map_tif.c, maps.c,
+	  util.c, wx.c, xa_config.c: Checking the return codes for
+	  scanf/sscanf/fscanf functions.
+
+2005-03-16 12:15  we7u
+
+	* src/: alert.c, db.c: Checking the return codes of
+	  scanf/sscanf/fscanf functions.
+
+2005-03-16 11:34  we7u
+
+	* src/util.c: A workaround for an sscanf() bug that shows up on
+	  Cygwin.  It wasn't parsing the lat/long properly in
+	  compress_posit().  Re-coded the routine to do everything
+	  manually.  The other 60 or so places that scanf() and it's
+	  variants are used should also be checked for correct operation on
+	  Cygwin.
+
+2005-03-15 16:50  we7u
+
+	* src/util.c: Fix for incorrect compressed packets on Cygwin.
+	  Evidently the 'N' in the latitude is getting passed to the
+	  routine as an 'n', which causes the problem.	The root cause of
+	  the problem is probably that the latitude variable is getting
+	  messed up sometime earlier.
+
+2005-03-15 11:25  we7u
+
+	* src/wx.c: Tweaks for Davis WX station by Clay Jackson, n7qnm.
+
+2005-03-14 17:58  we7u
+
+	* src/: database.h, db.c: Decoding weather from "Position with
+	  Timestamp no APRS messaging" packets.
+
+2005-03-14 13:15  we7u
+
+	* src/: database.h, db.c, main.c: Fixing a bug that crept in while
+	  coding some object/item stuff.  Moving some comments to a more
+	  appropriate place.  Commenting out the last_modified_time
+	  variable for now, as it's not actually implemented in the
+	  dead-reckoning code yet.
+
+2005-03-13 19:11  we7u
+
+	* src/: database.h, db.c, main.c: Dead-reckoning of objects and
+	  items:  Working a bit better with this version.  We now use the
+	  latest DR'ed position when making a change to the object/item.
+	  Moving a DR'ed object/item works.  One thing that doesn't work
+	  now is trying to update the position of a moving object/item
+	  using the Modify dialog:  The lat/long boxes are ignored now in
+	  favor of the DR'ed position.	Also note that the on-screen DR
+	  function is a bit off in speed and direction from the more
+	  accurate function that actually moves the object along.  This is
+	  yet to be fixed.
+
+2005-03-11 22:38  we7u
+
+	* src/db.c: Dead-reckoning for compressed objects/items as well.
+
+2005-03-11 22:10  we7u
+
+	* src/db.c: Better accuracy for the angle calculations for object
+	  dead-reckoning.
+
+2005-03-11 21:19  we7u
+
+	* src/db.c: Transmitting dead-reckoned object/item positions is
+	  starting to work in this version.  More to do yet, but it could
+	  be useful as-is.
+
+2005-03-11 08:45  we7u
+
+	* src/db.c: Commenting out the code that moves dead-reckoned
+	  objects.  Not correct yet.
+
+2005-03-11 07:52  we7u
+
+	* src/db.c: Initial version of dead-reckoning for objects.
+	  Dead-reckoned positions are transmitted now at the decaying
+	  transmit interval.  Still need to do more work on this, like
+	  computing the latest dead-reckoned position and transmitting that
+	  position at the point an object/item is changed, correcting the
+	  disparity between the on-screen DR and the transmitted DR
+	  (on-screen DR appears to compute angle based on screen pixels,
+	  while the transmitted DR computes angle based on lat/long).  The
+	  log file is ignored in these changes also:  If Xastir crashes or
+	  is shut down, time for the DR object will be lost and it will
+	  start DR'ing at the point it was last transmitted at before
+	  shutdown.
+
+2005-03-10 13:02  we7u
+
+	* src/: database.h, db.c, main.c: Preliminary work for fixing
+	  dead-reckoning of objects/items.  More to do yet, but this
+	  last_modified_time variable is needed to get started on the
+	  problem.
+
+2005-03-08 13:05  we7u
+
+	* src/main.c: Mods by Dan Brown, N8YSZ.  Prevent multiple Xastir's
+	  from getting run by a single user.  The prevents config files
+	  from getting corrupted.
+
+2005-03-08 10:31  we7u
+
+	* FAQ: Updates by Dan Brown and myself.
+
+2005-03-08 09:16  tvrusso
+
+	* configure.ac: Fix dummm mistake in help text for --with-rtree
+
+2005-03-03 11:41  we7u
+
+	* README.MAPS: Added the temporary Wiki location.
+
+2005-03-03 11:39  we7u
+
+	* README.MAPS: Added a note about the populated places GNIS file.
+
+2005-03-03 09:24  we7u
+
+	* README: Adding a note about n1ofz's web page and binary Xastir
+	  installation.
+
+2005-03-02 11:47  we7u
+
+	* README: Added a note about gating stations, objects, and items to
+	  RF.
+
+2005-03-02 11:41  we7u
+
+	* src/igate.c: Removing a debug printf that is used for checking
+	  out gating to RF.
+
+2005-03-02 09:39  we7u
+
+	* src/interface_gui.c: Fix for an annoying warning that X11 puts
+	  out when you add an interface in Xastir.
+
+2005-03-02 08:56  tvrusso
+
+	* src/map_tif.c: Comment out warning when a geotiff file has no
+	  PCS.
+
+	  Geotiffs without PCS (Projected Coordinate System) tags are
+	  assumed to be lat/lon rasters.  Now that this capability is being
+	  more widely used, especially by users outside the US, this
+	  warning is just an annoyance.  It was only there because it was
+	  once cause to reject a raster if it had no PCS.
+
+2005-03-01 12:55  we7u
+
+	* src/igate.c: Allowing nws-stations.txt changes to take effect
+	  right away for stations being gated to RF.  If the file has been
+	  changed, the in-memory database gets updated.
+
+2005-03-01 12:32  we7u
+
+	* src/main.c: Allow re-creating of an object or item that has been
+	  killed and is still in the database.	Previous code wouldn't
+	  allow that and brought up a warning popup.  Now the popup happens
+	  only if a "live" object/item is in the database with the same
+	  name.
+
+2005-03-01 12:05  we7u
+
+	* src/: igate.h, db.c, igate.c: Igating of specific objects/items
+	  to RF is now possible by listing the object or item name in
+	  data/nws-stations.txt.  The listing is case-insensitive.  Putting
+	  a wild-card source callsign in that file doesn't get
+	  objects/items from that station igated to RF, but other packets
+	  from that callsign do get gated.  Objects/items have to be
+	  specifically listed by name, as the code stands now.
+
+2005-03-01 11:36  we7u
+
+	* src/db.c: Proper RF gating of objects/items when the originating
+	  callsign is specified in the data/nws-stations.txt file.  The
+	  previous code was incorrect w.r.t. object/item gating.
+
+2005-03-01 09:09  we7u
+
+	* src/: db.c, igate.c: Initial attempt at gating individual
+	  stations through to RF, if those stations are spelled out in the
+	  data/nws-stations.txt file.  Wildcarding is inherent, so "we7u"
+	  will match "we7u", "we7ua", and "we7uaa" through "we7uzz".  This
+	  change also means that any packets (like posits perhaps) from an
+	  NWS station that are not weather alerts will now get gated to RF.
+	  Hopefully this won't be a problem.  I've left an fprintf() in
+	  the code so you'll see which new packets are gated through to RF
+	  (prints to STDERR).  We'll remove that fprintf() later once we're
+	  satisfied with the new operation.
+
+2005-02-28 09:11  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h: Fixing the selected
+	  stations count (on status bar) for dead-reckoned stations.  They
+	  were getting counted twice, once for the non-ghosted and once for
+	  the ghosted symbol.
+
+2005-02-26 18:04  shadow
+
+	* INSTALL: update imagemagick info
+
+2005-02-24 16:01  we7u
+
+	* FAQ: Adding instructions for running more than one Xastir at once
+	  on the same machine.
+
+2005-02-20 10:07  tvrusso
+
+	* README: Bring some of the FreeBSD notes up to date.  It is no
+	  longer necessary to use "gmake" instead of "make" with xastir's
+	  build on FreeBSD, and the comments about autoconf versions were
+	  very old.
+
+	  Also, change reference to the "current" version 1.1.x of xastir.
+
+2005-02-18 11:38  we7u
+
+	* README: Changes suggested by Dan Brown, plus another one or two
+	  added by me.	Fixing mailing list and Xastir link addresses.
+
+2005-02-17 01:14  we7u
+
+	* src/util.c: Better version of the function which checks the
+	  unproto paths as they are entered by the user.  This one checks
+	  for all the proper relations between the n-N numbers, and limits
+	  them to MAX_WIDES (which is set in util.h).
+
+2005-02-16 15:20  tvrusso
+
+	* src/util.c: Repair check_unproto_path to fix mistakes I'd made in
+	  last commit (atoi() on a character rather than string), and
+	  rearrange things so that some odd usages in the original code
+	  still work.
+
+	  I have not cleaned it up properly.  Instances of changing
+	  character pointers in a conditional remain as they were in
+	  original code, and flagging "bad" paths like "WIDE1-2" results in
+	  "Path too long" error message when it should say instead "very
+	  strange path".  But it will NOT reject paths like WIDE2-1
+	  anymore, and will accept paths like WIDE7-2 (even though the
+	  first digit is essentially meaningless when used this way).
+
+	  This time I actually tested these fixes and they work.
+
+2005-02-16 13:38  tvrusso
+
+	* src/util.c: Simple change to stop "WIDEN-n" where N!=n being
+	  flagged as a "Bad Path"
+
+	  Instead, it now checks that N>=n, and only reports "N<n" as a bad
+	  path.
+
+	  The "N!=n is bad" has been there since October 2004, when the
+	  path-checking code was first added.
+
+	  This addresses comment raised on xastir mailing list on 16 Feb
+	  2005.
+
+2005-02-16 09:14  we7u
+
+	* README.MAPS: Added notes about 2004 Tiger/Line data plus methods
+	  of converting Tiger/Line data to Shapefile data.  Thanks go to
+	  Tom Russo for most of the added text.
+
+2005-02-16 08:46  we7u
+
+	* README: Adding notes provided by Carl Makin regarding FreeBSD
+	  ports.
+
+2005-02-15 11:42  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/track_gui.c: Fixing a problem
+	  where you can request another findu track while the previous
+	  track or some other file is still being processed by Xastir.	A
+	  popup now asks you to wait and then retry the request.
+
+2005-02-14 16:32  we7u
+
+	* config/language-Dutch.sys: Updates by Han Sytsma, PE1FAM.
+	  Thanks!
+
+2005-02-14 14:38  we7u
+
+	* scripts/toporama250k.pl:  Modifications for latitudes above 67
+	  degrees north contributed by Tom
+	  Tessier, VE4TRT.  Thanks!
+
+2005-02-07 11:28  we7u
+
+	* README.win32: Updating the note about spaces in usernames.
+
+2005-02-04 11:36  we7u
+
+	* scripts/fcc-get, src/fcc_data.c, src/main.c, src/rac_data.c,
+	  src/xa_config.c: Minor tweaks to fcc-get script.  Dump text to
+	  stderr if we're re-indexing the fcc or rac data.  Bumped max
+	  tiger timeout from 180 sec to 300 sec.
+
+2005-02-04 10:34  we7u
+
+	* scripts/fcc-get: Still attemping to get the CVS ID string
+	  correct.  Didn't accept the correct format the first go-around.
+
+2005-02-04 10:26  we7u
+
+	* scripts/fcc-get: Fixing the CVS Id string.
+
+2005-02-04 10:26  we7u
+
+	* scripts/fcc-get: Added comments.  Added a filter for the FCC data
+	  to get rid of extra control chars in the middle of the lines.
+
+2005-02-01 08:15  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding (tm) to
+	  "APRS" strings.
+
+2005-02-01 08:12  we7u
+
+	* AUTHORS, FAQ, INSTALL, README, README.Getting-Started,
+	  README.MAPS, README.win32, changes.txt, xastir.1, xastir.spec.in,
+	  help/help-English.dat: Fixing up the APRS trademark text.
+
+2005-01-29 09:32  we7u
+
+	* src/: interface.c, messages_gui.c: Fix for the "(null)" text
+	  appearing in the Packet Data dialog when using custom messages.
+	  It now reports the path being used.
+
+2005-01-28 17:16  we7u
+
+	* src/maps.c: More speedups, this time in index_retrieve().  This
+	  takes it way down the profiling list so that it isn't an issue
+	  anymore.
+
+2005-01-26 13:36  we7u
+
+	* src/util.c: Fix for bug pointed out by Tapio Sokura.	We could
+	  end up with an item name with a ';' character in it, an the
+	  previous if/then contructs would guess wrong.
+
+2005-01-26 13:30  we7u
+
+	* src/db.c: Fix for objects/items deleted by someone else.  Xastir
+	  wasn't calling the disown_object_item() function previously for
+	  this case.
+
+2005-01-26 13:27  we7u
+
+	* src/util.c: Added debug statement.  Currently commented out.
+
+2005-01-26 13:11  we7u
+
+	* src/interface.c: Making sure that any paths are in upper-case as
+	  transmitted.
+
+2005-01-25 18:11  we7u
+
+	* src/interface.c: Tweaks so that any transmit will show in the
+	  Display Packet Data dialog, one per interface which has transmit
+	  enabled and is active.  This allows the user to see the paths
+	  being used for each transmit for each interface.  The transmit
+	  string used to show a generic path before, plus would appear in
+	  that dialog whether any interfaces were up/transmit enabled.
+	  Also, if transmit objects was disabled, the dialog used to show a
+	  transmit as if something went out.  This has been fixed.  Minor
+	  problems remain such as a "(null)" as a path for x-spider
+	  interface transmits.	Perhaps other interfaces might have the
+	  similar problems.
+
+2005-01-25 15:43  we7u
+
+	* src/interface.c: Added some debug code for testing Serial KISS
+	  interfaces.
+
+2005-01-24 22:05  we7u
+
+	* DEBUG_LEVELS, FAQ, INSTALL, README, README.CVS,
+	  README.Getting-Started, README.MAPS, README.win32, UPGRADE,
+	  help/help-English.dat: Spelling corrections.
+
+2005-01-24 13:52  we7u
+
+	* README.win32: Tweaks to the gdal install instructions: *)
+	  Requires Shapelib so that Xastir can configure in GDAL *) More
+	  configure options needed for GDAL so that it will
+	  configure/compile    on Win32 systems.
+
+2005-01-23 12:49  we7u
+
+	* src/: alert.c, alert.h, map_shp.c, util.c, wx_gui.c, maps.c,
+	  db.c: Hash table implementation for weather alert storage.  This
+	  makes things much faster.  Still have alert_list[] array used in
+	  one place in alert.c.  That bit of code needs to be rewritten.
+
+2005-01-21 12:40  we7u
+
+	* src/alert.c: Another minor speedup for the weather alert code.
+	  Getting rid of a couple of unnecessary calls.  Renaming one
+	  function so that it's uses are clear.
+
+2005-01-20 15:57  we7u
+
+	* src/db.c: Faster-yet is_my_call() function.
+
+2005-01-20 15:40  we7u
+
+	* src/db.c: Minor efficiency increase for is_my_call() function.
+	  We don't need to check the length of the two strings as strcmp()
+	  does that already.
+
+2005-01-20 09:51  tvrusso
+
+	* configure.ac: Move AH_BOTTOM call up to near the AC_CHECK_TYPES
+	  that tests for socklen_t
+
+2005-01-20 09:38  tvrusso
+
+	* acconfig.h, configure.ac: Remove deprecated acconfig.h file.
+
+	  Add "modern" usage of AH_BOTTOM to configure.ac to accomplish the
+	  same thing.
+
+2005-01-19 23:27  tvrusso
+
+	* src/map_gnis.c: Add check that latitude and longitude fields
+	  actually begin with digits before attempting to use the fields as
+	  lat/lon values.
+
+	  This fixes the bogus bounding box problem that was leading to
+	  xastir loading gnis files that should have been out of view.	It
+	  had been showing all GNIS files as having the equator as lower
+	  boundary, for example.
+
+2005-01-19 16:45  shadow
+
+	* acconfig.h, src/interface.c: deal with socklen_t not being
+	  defined everywhere
+
+2005-01-18 09:06  we7u
+
+	* src/: db.c, draw_symbols.c: Fixing the selected station count (on
+	  the status line) so that it more accuractely reflects the number
+	  of stations on the screen (whatever made it through the station
+	  filters).
+
+2005-01-15 21:15  rzg
+
+	* help/help-English.dat: Updates to the helpfile.
+
+2005-01-14 09:07  tvrusso
+
+	* INSTALL: Add a brief note about enabling spatial indexing, and a
+	  reference to the original author's web site per request.
+
+2005-01-13 20:16  tvrusso
+
+	* src/rtree/: card.c, card.h, gammavol.c, index.c, index.h, node.c,
+	  rect.c, sources.htm, sphvol.c, split_l.c, split_l.h, split_q.c,
+	  split_q.h: Correct name and contact information for author of the
+	  rtree code per her request.
+
+2005-01-12 20:02  tvrusso
+
+	* src/map_shp.c: Add a couple of lines of debugging output
+	  (selectable with debug level 16) to try to track down why labels
+	  for weather alerts aren't showing up until the map is refreshed,
+	  and not the first time it's drawn.
+
+2005-01-11 17:30  we7u
+
+	* src/: main.c, db.c, util.c, util.h: New code which uses a hash
+	  table to store the tactical callsigns.  This gets the tactical
+	  callsign number out of the total stations received number, plus
+	  should be a better implementation all the way around after all
+	  the minor bugs are found.
+
+2005-01-10 18:06  we7u
+
+	* src/: main.c, util.c: Fixing the slight Maidenhead grid problem
+	  (off by one).  Starting to implement a new set of tactical call
+	  functions, but the old system is currently still in place.  When
+	  fully implemented the tactical call quantity won't add to our
+	  received station count number.
+
+2005-01-10 13:39  we7u
+
+	* src/util.c: Added some comments.
+
+2005-01-10 13:39  we7u
+
+	* src/map_shp.c: Changes to comments/white-space only.
+
+2005-01-09 16:09  tvrusso
+
+	* src/map_shp.c: Add additional cases for switch statement to allow
+	  3D point and polygon files to be recognized and displayed.  All
+	  these do is let the 3D versions be treated by the same code as
+	  the 2D versions --- the Z coordinate is simply ignored.
+
+	  If xastir ever becomes a 3D-rendering APRS code these cases could
+	  be handled differently.
+
+	  I have no instances of 3D point or polygon shapefiles, so did not
+	  test these changes.  The 3D polyline cases I have do display
+	  properly.
+
+2005-01-09 15:10  tvrusso
+
+	* src/map_shp.c: Add two tiny changes that allow 3-D polyline
+	  shapefiles to be displayed.
+
+	  All this does is allow xastir to recognize 3D polyline shapefiles
+	  (SHPT_ARCZ) and display them as if they were 2-D (by ignoring all
+	  but the X and Y coordinates).  The finnish shapefiles that were
+	  causing the crash fixed by the previous commit were 3D shapefiles
+	  that can now be displayed without first being converted to 2D
+	  with ogr2ogr.
+
+2005-01-09 15:06  tvrusso
+
+	* src/: map_shp.c, shp_hash.c: map_shp.c:  move block of code that
+	  accesses rtrees and shapefile hashes to after the block that
+	  includes the "return if just indexing".  This lets us skip the
+	  hashtable lookup and rtree generation for maps that are merely
+	  being index.
+
+	  shp_hash.c: add a test before RTreeInsertRect to make sure that
+	  the bounding box being passed is valid (i.e. that it won't fail
+	  the assertion inside the RTreeInsertRect routine), and skip the
+	  shape if not.
+
+	  This should fix the crashes Curt was seeing a few days ago when
+	  including some defective Finland shapefiles in his map directory.
+
+2005-01-09 11:46  tvrusso
+
+	* src/: Makefile.am, rtree/Makefile.am: Fix for distribution
+	  problems:
+
+	    add DIST_SUBDIRS line so that distribution generation doesn't
+	  have a
+	    conditional.  This allows conditional compilation, but
+	  unconditional
+	    distribution of the directory.
+
+	    fix SOURCES line in src/rtree/Makefile.am to reference only
+	  files that exist
+
+2005-01-09 11:30  tvrusso
+
+	* src/Makefile.am: Undo change made this morning.  Forcing rtree
+	  into the SUBDIRS means that it will be built even if the user
+	  hasn't specified --with-rtree.  If it fails to build Makefile.in
+	  in the rtree directory then a different solution (perhaps
+	  changing configure.ac so it doesn't try to generate
+	  src/rtree/Makefile) is needed.
+
+	  But I can't reproduce the problem --- every time I run bootstrap
+	  it generates the Makefile.in in the rtree directory.
+
+2005-01-09 10:54  we7u
+
+	* src/Makefile.am: Adding rtree as a subdirectory in the make
+	  process.
+
+2005-01-08 02:24  we7u
+
+	* src/rtree/Makefile.am, src/rtree/card.c, src/rtree/card.h,
+	  src/rtree/gammavol.c, src/rtree/index.c, src/rtree/index.h,
+	  src/rtree/node.c, src/rtree/rect.c, src/rtree/sphvol.c,
+	  src/rtree/split_l.c, src/rtree/split_l.h, src/rtree/split_q.c,
+	  src/rtree/split_q.h, update-xastir: Updating Copyright notice.
+
+2005-01-08 02:19  we7u
+
+	* AUTHORS, FAQ, INSTALL, LICENSE, Makefile.am, NEWS, README,
+	  README.CVS, README.Getting-Started, README.MAPS, README.win32,
+	  UPGRADE, acinclude.m4, bootstrap.sh, changes.txt, configure.ac,
+	  install-xastir, xastir.1, src/Makefile.am: Updating Copyright
+	  notice.
+
+2005-01-08 02:06  we7u
+
+	* src/: alert.c, awk.c, bulletin_gui.c, color.c, datum.c, dbfawk.c,
+	  draw_symbols.c, fcc_data.c, festival.c, geocoder_gui.c, gps.c,
+	  hostname.c, igate.c, interface.c, interface_gui.c, lang.c,
+	  list_gui.c, locate_gui.c, location.c, location_gui.c,
+	  macspeech.c, map_cache.c, map_dos.c, map_gdal.c, map_geo.c,
+	  map_gnis.c, map_pdb.c, map_shp.c, map_tif.c, map_tiger.c, maps.c,
+	  messages.c, messages_gui.c, popup_gui.c, rac_data.c, rotated.c,
+	  shp_hash.c, snprintf.c, sound.c, testawk.c, track_gui.c, util.c:
+	  Updating Copyright notice.
+
+2005-01-08 01:54  we7u
+
+	* src/: geo-find.c, io-common.c, io-mmap.c, geo-client.c,
+	  hashtable.c, hashtable_itr.c, main.c, view_message_gui.c, wx.c,
+	  wx_gui.c, x_spider.c, xa_config.c, db.c: Updating Copyright
+	  notice.
+
+2005-01-08 01:46  we7u
+
+	* src/: alert.h, awk.h, bulletin_gui.h, color.h, database.h,
+	  datum.h, dbfawk.h, draw_symbols.h, fcc_data.h, festival.h, geo.h,
+	  gps.h, hashtable.h, hashtable_itr.h, hashtable_private.h,
+	  hostname.h, igate.h, interface.h, io.h, lang.h, list_gui.h,
+	  main.h, map_cache.h, maps.h, messages.h, popup.h, rac_data.h,
+	  rotated.h, shp_hash.h, snprintf.h, symbols.h, track_gui.h,
+	  util.h, wx.h, x_spider.h, xa_config.h, xastir.h: Updating
+	  Copyright notice.
+
+2005-01-08 01:33  we7u
+
+	* Davis/src/: Makefile.am, db2APRS.c, defs.h: Updating Copyright
+	  notice.
+
+2005-01-08 01:30  we7u
+
+	* Davis/: Makefile.am, bootstrap.sh, README, configure.ac: Updating
+	  Copyright notice.
+
+2005-01-08 01:27  we7u
+
+	* scripts/Makefile.am, scripts/Xastir_tigerpoly.py,
+	  scripts/example_objects.log, scripts/fcc-get, scripts/get-gnis,
+	  scripts/inf2geo.pl, scripts/ozi2geo.pl, scripts/toporama250k.pl,
+	  scripts/toporama50k.pl, scripts/xastir-fixcfg.sh,
+	  scripts/xastir-migrate.sh, symbols/Makefile.am,
+	  symbols/symbols.dat: Updating Copyright notice.
+
+2005-01-08 01:23  we7u
+
+	* help/Makefile.am, help/help-Dutch.dat, help/help-English.dat,
+	  help/help-French.dat, help/help-German.dat,
+	  help/help-Italian.dat, help/help-Portuguese.dat,
+	  help/help-Spanish.dat, m4/Makefile.am: Updating Copyright notice.
+
+2005-01-08 01:19  we7u
+
+	* config/24kgrid.dbfawk, config/Makefile.am, config/gps_wpt.dbfawk,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, config/nwsc_ddmmyy.dbfawk,
+	  config/nwsmzddmmyy.dbfawk, config/nwsozddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/tgr2shp.dbfawk,
+	  config/tgr2shppoly.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrlpt.dbfawk,
+	  config/tgrplc00.dbfawk, config/tgrwat.dbfawk,
+	  config/tnc-startup.aea, config/tnc-startup.d700,
+	  config/tnc-startup.kam, config/tnc-startup.kpc2,
+	  config/tnc-startup.kpc3, config/tnc-startup.paccomm,
+	  config/tnc-startup.pico, config/tnc-startup.sys,
+	  config/tnc-startup.thd7, config/tnc-startup.tnc2-ui,
+	  config/tnc-stop.d700, config/tnc-stop.sys, config/tnc-stop.thd7,
+	  config/tnc-stop.tnc2-ui, config/nwsfz_ddmmyy.dbfawk,
+	  config/nwsw_ddmmyy.dbfawk, config/tgrlpy.dbfawk,
+	  callpass/Makefile.am, callpass/callpass.c: Updating Copyright
+	  notice.
+
+2005-01-06 22:14  we7u
+
+	* DEBUG_LEVELS: More tweaks by Dan Brown, n8ysz.
+
+2005-01-05 09:16  we7u
+
+	* DEBUG_LEVELS: Tweaks by several members of the mailing list,
+	  compiled by Dan Brown, n8ysz.  Thanks!
+
+2005-01-04 09:20  we7u
+
+	* src/: messages.c, messages_gui.c: Last commit on these two files
+	  was done in error, and caused the previous commit to be undone.
+
+2005-01-04 09:06  we7u
+
+	* src/: interface.h, interface.c, interface_gui.c: Fixing the
+	  Interface Control dialog so that it updates immediately whenever
+	  status of an interface changes.
+
+2005-01-03 17:28  we7u
+
+	* src/: messages.c, messages_gui.c: Interface control dialog now
+	  changes quickly when status on an interface changes.
+
+2005-01-03 11:30  we7u
+
+	* src/maps.c: The XpmWriteFileFromPixmap() library call was changed
+	  so as to not allow absolute paths.  We had to change our code to
+	  comply with the new XPM API.
+
+2005-01-03 10:28  we7u
+
+	* src/maps.c: Tweaks suggested by Tom Russo to more fully report
+	  errors from XpmWriteFileFromPixmap().  I added returns for the
+	  cases where we get these errors so that we don't try to continue
+	  processing non-existent or ancient snapshot or print files.
+
+2005-01-01 21:26  tvrusso
+
+	* scripts/split_gnis.pl, src/map_gnis.c: split_gnis.pl:  remove
+	  dependency on Text::CSV_XS, change to work with current gnis
+	  files.  The script was apparently written when gnis files were
+	  still comma separated, but that's not true anymore.
+
+	  map_gnis: changes to a few comments.
+
+2004-12-30 23:56  we7u
+
+	* src/: messages.c, messages_gui.c: Fixes so that the current path
+	  setting in the Send Message dialog takes effect for messages in
+	  the outgoing queue and ack's in the delayed ack queue.
+
+2004-12-30 13:21  we7u
+
+	* src/: util.c, util.h: Adding the xastir_debug() function which we
+	  can use instead of our current scheme for dumping out extra
+	  messages to STDERR during various stages of debugging.
+
+2004-12-30 08:36  we7u
+
+	* src/messages.c: Tweak to cause Send Message and Send Group
+	  Message dialogs to pop to the top of the window stack when new
+	  messages are received.
+
+2004-12-30 08:34  we7u
+
+	* src/db.c: Fix for directed version query so that it doesn't pop
+	  up a Send Group Message dialog when received.
+
+2004-12-29 12:59  we7u
+
+	* src/db.c: Storing the 3rd-party path in the station record for
+	  the case were we hear the 3rd-party packet on RF and haven't
+	  heard the station directly on RF for at least the last hour.
+
+2004-12-29 12:31  we7u
+
+	* src/: db.c, interface.c: Adding the transmitted packets into the
+	  Incoming Data dialog.  Doesn't include posits that we're sending.
+	  Only one copy of the outgoing data is shown, no matter how many
+	  ports we have open, and the path that is shown is the one we'd
+	  use for a network interface, as we change the transmitted path
+	  based on the interface type normally.
+
+2004-12-29 08:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/messages.c, src/messages.h,
+	  src/messages_gui.c: Tweaks to allow ACK's to follow a custom path
+	  set in the Send Message dialog, change the path on delayed ACK's
+	  to match the current custom path, and tweaks to change the path
+	  on pending TX messages to match the current custom path.  Also
+	  have a change in here to bring up a popup if a custom message is
+	  entered and the Send Message dialog is closed (thereby throwing
+	  away the custom path), but couldn't get it to trigger only when
+	  desired, so that function is commented out at present.
+
+2004-12-28 13:04  we7u
+
+	* src/interface.c: Changing one debug fprintf statement.
+
+2004-12-28 12:29  we7u
+
+	* src/: db.c, messages.h, messages_gui.c, view_message_gui.c,
+	  xa_config.c: Making sure VIEW_MESSAGE_LIMIT can't be set too low.
+	  Adding some tweaks so that the custom path set in the Send
+	  Message dialog will get used for ACK's as well, assuming the
+	  dialog doesn't get closed.
+
+2004-12-28 08:14  we7u
+
+	* README.win32: Updating the notes about the CD's a bit.
+
+2004-12-27 22:16  tvrusso
+
+	* config/nwsc_ddmmyy.dbfawk, config/nwsfz_ddmmyy.dbfawk,
+	  config/nwsmzddmmyy.dbfawk, config/nwsozddmmyy.dbfawk,
+	  config/nwsw_ddmmyy.dbfawk, config/nwsz_ddmmyy.dbfawk,
+	  src/map_shp.c: Change all dbfawk files for NWS county/zone
+	  shapefiles so the display_level is very high.
+
+	  Until last week or so, display_level was always ignored for
+	  polygon shapefiles, so this didn't matter.  Now that
+	  draw_shapefile_map actually uses the parameter for these it
+	  becomes important that the value be big enough to display such
+	  shapefiles at reasonable zooms.
+
+	  map_shp.c: change display_level in default dbfawk rule (the one
+	  used when no dbfawk file is found) to have display_level=65536.
+	  This means that a shapefile for which no dbfawk file is found
+	  will always have all of its lines and polygons displayed at
+	  almost all zoom levels, unless the user disables display of that
+	  shapefile using map properties min/max zoom parameters.
+
+2004-12-26 13:13  we7u
+
+	* src/: db.c, messages.c: More tweaks to the delayed ack queue for
+	  messaging.  We now check for ack's that are too close together
+	  time-wise in the queue and refuse to queue them up.  We don't
+	  want to send too many ack's all together and trash the channel.
+
+2004-12-26 10:57  tvrusso
+
+	* src/: map_shp.c, maps.c: Add facility to purge dbfawk signatures
+	  on map index operation.  They are reloaded upon first shapefile
+	  redraw.
+
+2004-12-26 10:54  tvrusso
+
+	* src/rtree/.cvsignore: Add a .cvsignore file to the rtree
+	  directory, ignore Makefile.in
+
+2004-12-26 01:10  we7u
+
+	* src/: db.c, messages.c, messages.h, main.c: Adding the capability
+	  to schedule ACK's some number of seconds out.  We now use this to
+	  schedule ack's at t+30, t+60, and t+90 seconds if we find that
+	  we're getting duplicate messages from a station we're conversing
+	  with.
+
+2004-12-25 18:15  we7u
+
+	* src/: db.c, bulletin_gui.c: Fixing bulletins so that they don't
+	  pop up unless we wish them to.  Must have broken that recently
+	  with some other changes.
+
+2004-12-24 15:28  we7u
+
+	* src/db.c: Making the Send Message window update when we get an
+	  ACK.
+
+2004-12-24 12:27  we7u
+
+	* src/db.c: There _are_ code changes in this commit.  This tweak
+	  gets rid of the constantly popping-up Send Message dialogs when
+	  you're doing messaging.  If you start a QSO and then close the
+	  dialog, it should pop up again on the FIRST ACK that you receive,
+	  on a TIMEOUT of the message, or on the FIRST INSTANCE OF A NEW
+	  MESSAGE from the other party.
+
+2004-12-24 12:16  we7u
+
+	* src/messages_gui.c: Added a debug message, then commented it out.
+	  No code changes.
+
+2004-12-24 12:15  we7u
+
+	* src/messages.c: Comment changes.  No code changes.
+
+2004-12-24 12:12  we7u
+
+	* src/messages.h: Added a comment.  No code changes.
+
+2004-12-24 10:55  tvrusso
+
+	* src/: messages_gui.c, shp_hash.c: message_gui.c:  add test to
+	  get_path_data to make sure it never tries to use a null pointer
+	  in xastir_snprintf.  It is now possible for xastir to leave a
+	  path null when it receives a posit or message via RF that has
+	  been gated to RF from an Igate.  Until that's fixed, it's
+	  important not to try to dereference the null pointer.
+
+	  shp_hash.c add standard xastir header comments.
+
+2004-12-24 00:50  tvrusso
+
+	* src/: hashtable_itr.c, shp_hash.c: Re-insert line I accidentally
+	  deleted along with debugging cruft, comment out line that
+	  declared variable only used in debugging to silence warnings.
+
+2004-12-23 23:39  tvrusso
+
+	* src/: hashtable_itr.c, hashtable_itr.h, shp_hash.c: For-sure fix
+	  of segfaults in the new "decaying rtree" stuff.
+
+	  Turns out that the hashtable_iterator code has some built-in
+	  assumptions that we'll never actually have an empty hashtable.
+	  The hashtable_iterator_value routine always dereferenced the
+	  entry it pointed to, even though hashtable_iterator sets that to
+	  null if the table's empty.
+
+	  Rather than insert code all over the place that tests the
+	  internals of the iterator structure, I've hacked on the
+	  hashtable_iterator code to return null if it was asked for
+	  nonsense, and tests for null pointers before dereferencing.
+
+	  Also, the hashtable_itr.h file defined inline versions of the
+	  hashtable_iterator_key and hashtable_iterator_value functions
+	  even though hashtable_iterator.c defined them as regular
+	  functions.  This was a source of much additional baldness when
+	  trying to debug until I realized it.	Ifdef'd those out.
+
+2004-12-23 23:19  we7u
+
+	* src/db.c: Getting rid of the multiple audio alerts or speech
+	  alerts upon receipt of a message.  Should only alert on the first
+	  copy of each now.
+
+2004-12-23 21:51  we7u
+
+	* src/: messages.h, messages_gui.c: In the Send Message dialog:
+	  Moving the reverse path test into its own uneditable text field.
+	  It is too problematic trying to use it by default for messaging,
+	  but it's a useful reference for choosing the outgoing custom path
+	  for the QSO.
+
+2004-12-23 21:48  we7u
+
+	* README.win32: Munging the e-mail addresses so that spammers have
+	  to work harder to pick them up.
+
+2004-12-23 20:26  we7u
+
+	* README.win32: Updating the CD & Network install blurbs at the
+	  top.
+
+2004-12-23 10:49  we7u
+
+	* src/map_cache.c: Tweaks by Dan Brown, N8YSZ.
+
+2004-12-23 07:57  tvrusso
+
+	* src/: map_shp.c, shp_hash.c: Add check for hashtable iterator
+	  being null before using it.  If we've been idle for a long time
+	  then it could be the case that the entire hashtable's been purged
+	  and so this test is necessary.  I think this was the source of
+	  the segfaults I saw over the past couple of days after several
+	  hours of unattended operation.
+
+2004-12-22 23:54  we7u
+
+	* src/view_message_gui.c: Changing the format of messages in the
+	  View->Message Traffic window to single-line format, unless the
+	  line is long in which case it wraps.
+
+2004-12-22 19:09  tvrusso
+
+	* src/map_shp.c: Fix for a logic mistake I introduced last night.
+
+	  This might be the source of the unpredictable segfaults I'm
+	  seeing at random times hours apart.  If not, I'll get that one
+	  pinned down ASAP.  This was still a mistake, even if it's not the
+	  source of those.
+
+2004-12-22 14:56  we7u
+
+	* src/: database.h, db.c, main.c, main.h: Fixing selected station
+	  count so that it updates immediately on the status line if the
+	  number changes.  Change the "stations" variable to
+	  "station_count" to make it easier to grep for in the future.
+
+2004-12-22 14:49  we7u
+
+	* src/interface_gui.c: Fixing Interface Control dialog so that it
+	  looks the same after properties have been changed.  It had been
+	  missing the up/down designation per port.
+
+2004-12-22 10:07  we7u
+
+	* src/: main.c, main.h, db.c: Making the selected stations count on
+	  the status line update quickly when it changes.
+
+2004-12-22 08:44  we7u
+
+	* src/main.c: Fixing the Select All button in Map
+	  Chooser->Properties so that it doesn't toggle the selections, but
+	  actually does what its label says it'll do.
+
+2004-12-21 23:18  we7u
+
+	* src/db.c: Changes to Group Messages/Queries so that multi-line
+	  messages will show in the dialog, and so that messages that don't
+	  require ack's don't show up as unacked (highlighted) in the
+	  dialog.
+
+2004-12-21 22:48  tvrusso
+
+	* src/rtree/node.c: Clean up debugging output mistakenly committed.
+
+2004-12-21 22:22  tvrusso
+
+	* src/: main.c, map_shp.c, maps.c, maps.h, shp_hash.c, shp_hash.h,
+	  rtree/node.c: Round of RTree usage optimizations.
+
+	  1) If a shapefile's bounding box is entirely contained in the
+	  current viewport,    don't bother doing an RTreeSearch for
+	  visible shapes --- just read the    file sequentially.  Don't
+	  even bother accessing the hash table for the file.
+
+	  2) Store a time stamp every time a shapefiles hash table entry is
+	  accessed.
+
+	  3) Every hour, walk through the hash table and purge records that
+	  have not    been accessed in 1 hour.	(this needs to become a
+	  configurable time)
+
+	  This should improve memory usage for a few special use cases, and
+	  free up RAM wasted on shapefiles that are not really going to
+	  benefit from having the RTree fast lookup.
+
+	  I've not run this for long times to see how the memory usage
+	  behaves --- once the RTree is allocated and freed, the processes
+	  resident size doesn't seem to drop down, but it does make the
+	  space that was freed available for indexing a different
+	  shapefile.
+
+	  There are probably many ways to make this even more flexible and
+	  automatically adaptive to the users' usage patterns.	This should
+	  be a good start, though.
+
+2004-12-21 21:08  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.h, src/main.c:
+	  The ST_DIRECT stuff appears to be fixed now.	This tweak makes
+	  the APRS-Direct query work properly again plus adds a
+	  selected/total stations display to the status line where there
+	  was just total stations listed before.
+
+2004-12-21 19:23  we7u
+
+	* src/db.c: Another tweak to the ST_DIRECT stuff.  This tweak
+	  causes us to overwrite the saved path only if 1) the current
+	  packet is direct, 2) the ST_DIRECT path is not set, or 3)
+	  ST_DIRECT is set but nothing has been heard direct for the last
+	  hour.  The end result is that we should see the most recent
+	  directly-heard path in Station Info, unless the station has not
+	  been heard direct for the last hour, in which case we may see a
+	  digipeated path or an INET path there.
+
+2004-12-21 17:35  we7u
+
+	* src/db.c: More work on fixing up the ST_DIRECT flag.
+
+2004-12-21 12:29  we7u
+
+	* src/: database.h, db.c: Attempting a fix to the ST_DIRECT bit
+	  being set incorrectly at times, for stations that straddle both
+	  RF and INET feeds.  Lots of things were inter-related here, so
+	  this may not be the final fix.  It should be better than the old
+	  code though.
+
+2004-12-20 17:58  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c, src/main.c,
+	  src/messages.c: Combining the two Interface dialogs into one
+	  dialog.  Fixing the Map Chooser->Properties dialog so that it
+	  keeps the selected list each time you change something.
+
+2004-12-20 14:14  tvrusso
+
+	* src/: map_shp.c, shp_hash.c, rtree/index.c, rtree/index.h,
+	  rtree/node.c, rtree/split_l.c: Give GCC fewer things to whine
+	  about.
+
+	  In each case here where gcc whined about possible use of
+	  variables before initialization, code was in place that would
+	  always set that variable first.  But it was all in conditionals
+	  that gcc couldn't possibly know were always true before any use
+	  of the variables.  Added initializers to shut it up.
+
+2004-12-19 21:39  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/messages_gui.c: Fixing transmit
+	  of messags so that the three illegal chars (per the spec) cannot
+	  be transmitted.  We now substitute '.' for any of those three,
+	  then alert the operator that we've done so via a popup message.
+
+2004-12-19 18:56  we7u
+
+	* src/db.c: Added code to check for incorrect case in queries and
+	  notify us.  This may be used to send a message back to the
+	  originator asking them to please follow the APRS spec, or the
+	  messages may be ignored.  They go to STDERR currently.  The same
+	  code was added to the unimplemented query sections, but commented
+	  out.
+
+2004-12-19 00:44  we7u
+
+	* src/db.c: Fixing the Station Info dialog so that it will display
+	  stations in the Station Chooser dialog +/- 20 pixels in either
+	  direction from the mouse pointer.
+
+2004-12-18 17:08  we7u
+
+	* src/x_spider.c: Adding some returns in the case of a few socket &
+	  pipe errors, to get the process to close and not waste CPU on
+	  Cygwin.
+
+2004-12-18 13:06  tvrusso
+
+	* configure.ac, src/Makefile.am: Change configure and makefiles so
+	  that if the user does not ask for rtree, the library isn't even
+	  built and the -L/-l options aren't used.
+
+	  Not doing this before was just laziness on my part.
+
+2004-12-18 12:43  tvrusso
+
+	* src/rtree/Makefile.in: Removing something that should not have
+	  been committed --- Makefile.in is supposed to be created by
+	  bootstrap.
+
+2004-12-18 12:29  tvrusso
+
+	* src/rtree/sources.htm: Fix up pointers to original source code
+	  location and author's web site.
+
+2004-12-17 23:51  we7u
+
+	* src/shp_hash.c: Fixing up some #ifdef's for the shapefil.h
+	  include.
+
+2004-12-17 17:58  we7u
+
+	* src/x_spider.c: Changing some error messages.
+
+2004-12-17 04:15  tvrusso
+
+	* configure.ac, src/Makefile.am, src/map_shp.c, src/maps.c,
+	  src/maps.h, src/shp_hash.c, src/shp_hash.h,
+	  src/rtree/Makefile.am, src/rtree/Makefile.in, src/rtree/card.c,
+	  src/rtree/card.h, src/rtree/gammavol.c, src/rtree/index.c,
+	  src/rtree/index.h, src/rtree/node.c, src/rtree/rect.c,
+	  src/rtree/sources.htm, src/rtree/sphvol.c, src/rtree/split_l.c,
+	  src/rtree/split_l.h, src/rtree/split_q.c, src/rtree/split_q.h:
+	  Experimental "RTree" spatial indexing feature.
+
+	  To enable, use "--with-rtree" in configure.
+
+	  Current implementation is very memory intensive, but speeds up
+	  rendering of large shapefiles.  Needs further work.
+
+	  without the "--with-rtree" option the code behaves as before, all
+	  changes are ifdef'd out.
+
+2004-12-16 20:36  we7u
+
+	* src/x_spider.c: Added a couple of test for a closed pipe or
+	  socket.  Trying to solve an x_spider problem on Cygwin where we
+	  get error messages at the server's STDERR when a client
+	  disconnects.
+
+2004-12-16 12:40  tvrusso
+
+	* src/db.c: Exclude own station from "DIRECTS" reply to APRSD
+	  query.
+
+2004-12-15 22:01  tvrusso
+
+	* src/testawk.c: Minor tweaks to README.MAPS
+
+	  Change testawk.c to remove a feature that uses command line args
+	  as a dbfawk program literal --- this is why usages like   testawk
+	  foo.dbfawk foo.bar (a likely guess at usage) lead to segfaults
+	  instead of helpful messages.	Change usage string to reflect
+	  reality.
+
+	  I hope nobody really used that feature, but it doesn't seem
+	  likely, and it was definitely the case that the segfaults were
+	  confusing users.
+
+2004-12-15 21:29  tvrusso
+
+	* README.MAPS, src/db.c: README.MAPS: add a little explanation of
+	  how to use testawk (which has the habit of segfaulting on
+	  commandlines it doesn't understand)
+
+	  db.c:  An attempt to make APRSD (Direct Station Query) responses
+	  not be limited to a single line when there are too many direct
+	  stations to fit on that line.
+
+	  I have not been able to test the db.c change yet, as I can't hear
+	  more than 5 stations directly, so I have to commit this and wait
+	  till my partner in crime in Albuquerque can get this update,
+	  rebuild xastir, and run long enough to hear a few dozen direct
+	  stations so I can query him.
+
+2004-12-15 13:58  tvrusso
+
+	* config/Makefile.am: Add 24kgrid.dbfawk to list of things to
+	  install.
+
+2004-12-15 09:56  tvrusso
+
+	* config/24kgrid.dbfawk: Adding dbfawk for the 24kgrid shapefile
+	  from geocomm.com.
+
+2004-12-15 09:03  we7u
+
+	* README.MAPS: Added a pointer to the Canadian shapefile street
+	  maps.
+
+2004-12-14 20:30  we7u
+
+	* src/map_tiger.c: Moving the "Loading..." message to below where
+	  the variable is initialized which it uses to print.
+
+2004-12-14 13:26  we7u
+
+	* README.MAPS: Making the IMAGESIZE line requirements more
+	  noticeable.
+
+2004-12-14 12:17  we7u
+
+	* src/: database.h, db.c, main.c: Adding interface numbers to the
+	  Incoming Data dialog.  "sp" for packet received on the server
+	  port (port 2023), 1 or 2-digit numbers for anything else.
+
+2004-12-14 11:39  we7u
+
+	* src/interface.c: Fixing the double-header problem for packets
+	  heading out port 2023.  Hopefully this is the last of it.
+
+2004-12-14 08:01  we7u
+
+	* src/interface_gui.c: Fix to prevent bringing up an interface upon
+	  changing its properties.  Fix by Dan Brown, n8ysz.
+
+2004-12-12 19:19  tvrusso
+
+	* src/db.c: Change to look for message ID after *final* "{" in a
+	  message rather than first.  This improves interoperability with
+	  UI-View, which will ack a malformed message like:
+	  KB7ZVA-1>APU25N,TCPIP*,qAC,KB7ZVA-1::KM5VY	:{Duh{76 (the first
+	  { is technically illegal) by acking message 76, whereas prior to
+	  this commit xastir would see the message ID as "Duh{7" and do:
+	  KM5VY>APX142,TCPIP*::KB7ZVA-1 :ackDuh{7 causing UI-View to ack
+	  message 7, and assorted other nonsense.
+
+	  Tested only by having one instance of xastir send a malformed
+	  message to another and seeing the ack of the real message ID.
+
+2004-12-12 14:21  tvrusso
+
+	* config/tgr2shppoly.dbfawk, src/map_shp.c: Make polygon draws
+	  respect the "skip_it" step --- until now it was not possible to
+	  use the dbfawk variable "display_level" to shut off drawing
+	  specific polygons at large zooms.  Don't know why I hadn't
+	  noticed that all that wasn't working.
+
+	  Now that they're being paid attention to, had to tweak all the
+	  display_levels in tgr2shppoly.dbfawk so things show up at
+	  reasonable levels.
+
+2004-12-09 18:35  we7u
+
+	* configure.ac: Fixing the comment so that it is accurate.
+
+2004-12-09 18:32  we7u
+
+	* configure.ac: Adding a case statement for Cygwin that will change
+	  "-O2" compiler flags to " ".	This should speed up Cygwin
+	  compiling a great deal, at the expense of slightly larger, more
+	  inefficent executables.
+
+2004-12-09 12:27  we7u
+
+	* INSTALL, README.Getting-Started, configure.ac, update-xastir:
+	  Making --without-errorpopups be the default.	Must add
+	  "--with-errorpopups" in order to get the previous operation now.
+	  Added some code to configure.ac to remove the "-g" compiler
+	  option, so we'll get stripped executables by default now.
+
+2004-12-08 08:57  we7u
+
+	* src/: gps.c, interface_gui.c: Disabling the time-set togglebutton
+	  when running Cygwin.
+
+2004-12-08 06:58  we7u
+
+	* src/main.c: Finally, a fix for the keyboard modifiers problem,
+	  where any modifiers enabled will mess up the mouse menus.  The
+	  problem turned out to be a Motif 2.x function that doesn't work
+	  properly with modifiers.  Switching to the Motif 1.x function
+	  that accomplishes the same thing fixed it.
+
+2004-12-07 21:45  we7u
+
+	* src/: map_geo.c, map_tiger.c, util.c: Conditionally compiling
+	  various libcurl calls into the code based on libcurl version.
+
+2004-12-07 11:39  we7u
+
+	* src/: map_geo.c, map_tiger.c, util.c: Adding some currently
+	  unused options for libcurl.  These are options that were added
+	  recently, so only some libcurl versions have them.  They have to
+	  do with ftp and http proxying.
+
+2004-12-07 10:48  we7u
+
+	* FAQ: Changed the proxy note a bit.
+
+2004-12-07 09:48  we7u
+
+	* FAQ: Added instructions for getting through and http proxy
+	  server.
+
+2004-12-07 09:32  we7u
+
+	* src/: map_geo.c, map_tiger.c, util.c: Adding another libcurl
+	  option so that it can read the ~/.netrc file.  This is needed by
+	  those using http proxy servers so they can get through the
+	  firewall.
+
+2004-12-07 00:05  we7u
+
+	* src/: util.c, util.h: Added a new define to util.h so that the
+	  maximum WIDE/TRACE digi's can be specified.
+
+2004-12-06 23:16  we7u
+
+	* src/util.c: Fix to allow multiple specific callsigns in path
+	  without Xastir complaining about it.
+
+2004-12-06 22:01  we7u
+
+	* src/: interface.c, messages.c, view_message_gui.c: Some HP/UX
+	  fixes by Dan Brown.  Another fix for transmit KISS packets,
+	  getting rid of 0x00 bytes between the KISS frames.
+
+2004-12-05 13:46  we7u
+
+	* scripts/Makefile.am: Added get-gnis to the list.
+
+2004-12-05 13:41  we7u
+
+	* scripts/get-gnis: Script to snag GNIS files from the download
+	  site.  Written by Dan Brown, N8YSZ.
+
+2004-12-05 13:20  we7u
+
+	* src/: map_cache.c, map_cache.h: More good tweaks by Dan Brown,
+	  N8YSZ.
+
+2004-12-04 10:05  we7u
+
+	* README.MAPS: Added a writeup for map caching, courtesy of Dan
+	  Brown, n8ysz.
+
+2004-12-04 08:56  we7u
+
+	* FAQ: Added a bit about the MAGICK_HOME variable.
+
+2004-12-04 08:49  we7u
+
+	* FAQ: Added Festival debugging info.
+
+2004-12-01 11:45  we7u
+
+	* src/: messages.c, messages_gui.c: Added some comments.  Fixed
+	  multi-line messages so that they appear correctly in the Send
+	  Message dialog.
+
+2004-11-30 20:34  we7u
+
+	* src/: database.h, db.c, messages.c: Adding the tries counter to
+	  the Send Message dialog.
+
+2004-11-30 14:59  tvrusso
+
+	* config/tgr2shppoly.dbfawk: Another really minor tweak to tiger
+	  polygon shapefile colorings.
+
+	  Looks like there are no easily selected (by CFCC) city boundaries
+	  in the files created by Xastir_tigerpoly.py, which makes it
+	  impossible to color them with the current dbfawk file.  Gonna
+	  have to figure that out.
+
+2004-11-30 13:23  we7u
+
+	* src/db.c: Variable-length non-highlighting for the interval timer
+	  value.  Lets us keep the line as short as possible yet still do
+	  the highlighting in the correct place (the message text).
+
+2004-11-30 13:12  we7u
+
+	* src/: database.h, db.c, messages.c: Displaying the message timer
+	  interval in the Send Message dialog for active messages.
+
+2004-11-30 12:24  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/messages.c, src/messages.h,
+	  src/messages_gui.c: Updates to messenging.  We can now see queued
+	  messages before they get to the transmit stage.  New button added
+	  to kick the timer back to original values (to get a QSO going
+	  again).  Timer value is currently sent to STDERR, but will
+	  eventually be placed into the Send Message GUI as well.
+
+2004-11-30 10:43  tvrusso
+
+	* config/tgr2shppoly.dbfawk, config/xastir.rgb, src/color.h,
+	  src/main.c: changes to coloration of shapefile tiger polygons.
+	  Matches online colors a little better now.
+
+2004-11-29 22:56  we7u
+
+	* src/: map_tiger.c, map_cache.c, map_cache.h: More map caching
+	  mods by Dan Brown, n8ysz.
+
+2004-11-29 21:14  we7u
+
+	* src/messages.c: Getting rid of extra message transmit before
+	  timeout.  This causes us to transmit exactly MAX_TRIES times,
+	  instead of MAX_TRIES + 1.
+
+2004-11-29 12:55  we7u
+
+	* src/: database.h, db.c, messages.c: Adding a "CANCELLED"
+	  indicator to the Send Message box for those messages that made it
+	  to transmit from the queue but got manually cancelled by the
+	  user.
+
+2004-11-29 11:58  we7u
+
+	* src/: messages.h, messages.c: More RF-friendly decaying algorithm
+	  for messages.  We start at 7 seconds and double the interval each
+	  time.  Timeout occurs at about 2 hours if no ACK received.
+
+2004-11-29 11:37  we7u
+
+	* src/x_spider.c: Changing from LF to CRLF in lines sent to clients
+	  which have connected to the server port.
+
+2004-11-28 10:03  tvrusso
+
+	* acinclude.m4: Change probe for db.h to use AC_TRY_COMPILE instead
+	  of AC_CHECK_HEADER, so that we can apply the same usability test
+	  that is present in map_cache.c.
+
+2004-11-27 18:56  we7u
+
+	* src/x_spider.c: Making sure that lines sent out the server port
+	  have "\r\n" at the end.  Before we just had '\r', which doesn't
+	  correspond to the way the internet servers did it.
+
+2004-11-25 22:10  we7u
+
+	* README.win32: Completing the GDAL/OGR library instructions for
+	  Cygwin.
+
+2004-11-25 17:35  we7u
+
+	* README.win32: Adding Dave Flood's comments about compiling
+	  GDAL/OGR under Cygwin.
+
+2004-11-23 09:19  we7u
+
+	* scripts/inf2geo.pl: Added usage messages if invoked without
+	  parameters.
+
+2004-11-22 08:59  we7u
+
+	* update-xastir: Adding timestamps and output to make.log for each
+	  step.
+
+2004-11-20 22:26  we7u
+
+	* acinclude.m4: A small change to hopefully make configure find the
+	  correct convert.exe on Cygwin/Windows installations.
+
+2004-11-19 22:13  we7u
+
+	* README.win32: Adding a note about documenting the system
+	  variables soas to guard against changes in the future.
+
+2004-11-19 19:15  we7u
+
+	* README.win32: Adding info at the top about CD installs that are
+	  available.
+
+2004-11-19 18:49  we7u
+
+	* src/: map_geo.c, map_tiger.c, util.c: Backing out a few libcurl
+	  options that aren't in earlier libcurl packages.
+
+2004-11-19 11:01  we7u
+
+	* README.win32: Getting the db libraries listed properly.
+
+2004-11-19 08:26  we7u
+
+	* update-xastir: Change in a comment.
+
+2004-11-19 08:11  we7u
+
+	* README.win32: Fixing the order of the Cygwin packages.
+
+2004-11-19 07:20  we7u
+
+	* update-xastir: Tweaks for Cygwin to eliminate the "sudo" keyword
+	  there.
+
+2004-11-18 16:03  we7u
+
+	* install-xastir: Changing the comments around at the end to
+	  simplify things.
+
+2004-11-18 14:16  we7u
+
+	* install-xastir: Adding more comments at the end.
+
+2004-11-18 13:06  we7u
+
+	* update-xastir: Adding a couple of command-line options to the cvs
+	  update command.
+
+2004-11-18 12:51  we7u
+
+	* install-xastir: A script to help in the initial install of Xastir
+	  via CVS.  For those folks challenged by the Unix way of doing
+	  things.
+
+2004-11-18 12:29  we7u
+
+	* README.CVS, README.win32: Updating the instructions with respect
+	  to the "update-xastir" script.
+
+2004-11-18 12:23  we7u
+
+	* update-xastir: Added a comment.
+
+2004-11-18 10:59  we7u
+
+	* INSTALL, README.CVS, README.win32, UPGRADE, update-xastir: Adding
+	  an update-xastir script and tweaking updating instructions a bit.
+
+2004-11-17 10:48  we7u
+
+	* README: Added HP/UX instructions per Dan Brown, N8YSZ.  Current
+	  state of HP/UX port is:  Segfaults when connected to internet
+	  server, but appears to run otherwise.  Not fully tested.
+
+2004-11-17 10:28  we7u
+
+	* src/main.c: Fixing up a return that shouldn't pass back a
+	  parameter.
+
+2004-11-17 09:57  we7u
+
+	* src/main.c: Checking for map interrupts and returning, just
+	  before each call to display_file(), which is the function which
+	  draws objects/tracks.
+
+2004-11-17 09:46  we7u
+
+	* src/: map_geo.c, map_tiger.c, util.c: Adding timeouts to libcurl
+	  calls.  Wget calls already have them.
+
+2004-11-17 09:00  we7u
+
+	* src/map_geo.c: If ImageMagick is not found, we now refuse to load
+	  a .geo map unless "xpm" is found in the filename.
+
+2004-11-17 08:11  we7u
+
+	* src/: maps.c, maps.h, map_gdal.c, map_geo.c, map_gnis.c,
+	  map_pdb.c, map_shp.c, map_tif.c, map_tiger.c, map_dos.c: Setting
+	  default map layers based on the type of file.  Raster map = 0,
+	  vector maps = 1000, GNIS = 99,999.
+
+2004-11-16 14:50  we7u
+
+	* configure.ac: Reversing the order of the map caching/Imagemagick
+	  checks.  Just in case.  We've had trouble before where if
+	  ImageMagick checks fail, they corrupt some of the settings for
+	  the other checks, unless ImageMagick is the last of the bunch.
+
+2004-11-16 12:09  we7u
+
+	* FAQ: Getting rid of "localhost" on the netcat example line.
+	  Redundant.
+
+2004-11-16 12:04  we7u
+
+	* FAQ: Updating the netcat info in the FAQ.
+
+2004-11-16 10:15  we7u
+
+	* README.win32: Tweaking the library install instructions per David
+	  Flood.
+
+2004-11-15 21:05  we7u
+
+	* src/maps.c: Prevent a segfault when Xastir is having trouble
+	  writing the map objects to file.
+
+2004-11-15 10:05  tvrusso
+
+	* acinclude.m4: Fix of fix for fix of fix of probe for db library.
+
+	  Amounts to removing a comment character from a critical line that
+	  I'd accidentally commented out.
+
+	  Without this fix, building xastir on a machine without a db
+	  library installed will fail with an error message at link stage
+	  about a missing "-ldb".  That's because the configure script
+	  never reset the LIBS variable after the probe.
+
+2004-11-15 08:52  we7u
+
+	* src/map_cache.c: Moving more of the includes inside the #ifdef.
+	  Including config.h so we get a direct answer as to whether
+	  USE_MAP_CACHE is defined before we include anything else.
+
+2004-11-15 08:22  we7u
+
+	* src/map_cache.c: Moving a couple of includes below the
+	  USE_MAP_CACHE #ifdef.  Makes it compile on systems that don't
+	  have the map caching enabled.
+
+2004-11-13 17:10  tvrusso
+
+	* acinclude.m4:
+	  Handful of changes to improve probe of db for map caching.
+
+	  1) remove attempts to probe db version 3 libraries, coz the code
+	  that uses    db actually won't work unless the version is 4 or
+	  above.
+
+	  2) make the probe stop probing when it finds a library that
+	  works.  Otherwise    the probe keeps overwriting the "dblib"
+	  variable with "no".
+
+	  3) comment out the attempt to probe for db_open if db_create
+	  isn't found.	   That would only work if the code that uses
+	  db_create were inside appropriate	ifdefs, which was probably
+	  the case in the package from which the autoconf     macro was
+	  obtained.
+
+	  4) Change the comment about "FreeBSD puts this in a weird place"
+	  enough    to give a reader an idea of where to look.
+
+2004-11-13 16:54  we7u
+
+	* src/map_cache.c: Moving the #ifdef below the #includes, so that
+	  we have a chance of having the USE_MAP_CACHE variable be defined.
+
+2004-11-13 16:12  tvrusso
+
+	* acinclude.m4, configure.ac: A minor tweak to add "Building with
+	  map caching.....: " to the list of things that are printed out at
+	  the end of the configuration run.
+
+2004-11-13 06:00  tvrusso
+
+	* src/map_cache.c: Move the #endif for USE_MAP_CACHE to a place
+	  where it actually takes out code that can't compile if
+	  USE_MAP_CACHE isn't defined.
+
+2004-11-12 16:40  shadow
+
+	* acinclude.m4: link against the real libdb we found; use the
+	  header path for it we found
+
+2004-11-12 16:17  we7u
+
+	* README.win32: Adding libdb and libdb-devel as necessary libs.
+
+2004-11-12 15:50  we7u
+
+	* INSTALL: Adding a blurb about libdb.
+
+2004-11-12 11:31  we7u
+
+	* README.win32: Added info about NTFS "convert.exe" getting run
+	  instead of ImageMagick's "convert.exe".  Added instructions
+	  written up by Randy, KK6RW, regarding auto-starting Xastir.
+	  William McKeehan, KI4HDU, contributed to those instructions and
+	  was the inspiration for them.
+
+2004-11-12 10:52  we7u
+
+	* src/: map_cache.c, map_cache.h: Moving variables to the top of
+	  the blocks (for the BSD guys), changing the expire time for maps
+	  to 6 months instead of one hour.
+
+2004-11-12 10:47  we7u
+
+	* src/map_tiger.c: Moving the variable declaration up to the top of
+	  the block before those FreeBSD guys get on my case!
+
+2004-11-12 10:24  we7u
+
+	* acinclude.m4, src/Makefile.am: The final two pieces to enable the
+	  new feature, if the Berkeley DB libraries are installed and
+	  usable.
+
+2004-11-12 09:17  we7u
+
+	* configure.ac: Added a comment.
+
+2004-11-12 09:10  we7u
+
+	* acinclude.m4: A tweak to add "-ldb" to the LIBS line if the DB
+	  library is found.
+
+2004-11-12 09:09  we7u
+
+	* src/: map_cache.c, map_cache.h, map_tiger.c: Adding code that
+	  performs caching of tigermaps, courtesy of Dan Brown, N8YSZ.
+
+2004-11-12 09:03  we7u
+
+	* src/main.c: Preliminary work to include a new map feature.
+
+2004-11-12 08:37  we7u
+
+	* INSTALL: Adding another link for a list of internet servers, plus
+	  a link to the filtering syntax web page.  Links courtesy of Rick
+	  Green.  Thanks!
+
+2004-11-11 09:19  we7u
+
+	* INSTALL: Updating the GDAL instructions somewhat.
+
+2004-11-10 11:58  we7u
+
+	* src/db.h: Removing db.h.  It has been renamed as database.h.
+
+2004-11-10 11:58  shadow
+
+	* acinclude.m4, configure.ac:
+	  berkeley db configure test. may need slight tweaking for which
+	  function it tests for (db_open/db_create/solmething else)
+
+2004-11-10 11:58  we7u
+
+	* src/: Makefile.am, alert.h, db.c, draw_symbols.c, util.c, util.h,
+	  wx.h, xastir.h: Renaming db.h to database.h in order to avoid a
+	  conflict with Berkeley DB include file of the same name.
+
+2004-11-10 11:56  we7u
+
+	* src/database.h: Renaming db.h to database.h, in order to avoid a
+	  potential conflict with the berkeley DB include file of the same
+	  name.
+
+2004-11-05 15:07  we7u
+
+	* src/festival.c: Closing the file descriptor for the socket at the
+	  point where the Festival connect fails.
+
+2004-11-05 08:57  we7u
+
+	* configure.ac: Bumping the development sources up to 1.4.2.  Just
+	  released 1.4.1 stable.
+
+2004-11-05 08:37  we7u
+
+	* src/: igate.c, util.c: Assuring that we don't igate packets while
+	  reading tactical calls in from file.
+
+2004-11-04 12:27  we7u
+
+	* src/: db.c, igate.c, main.c: Fixing the problem where reading in
+	  a log file causes the packets to be igated to the NET.
+
+2004-11-04 10:53  we7u
+
+	* src/map_gdal.c: Free'ing the hash iterators at the correct
+	  points.
+
+2004-11-02 12:37  we7u
+
+	* src/: hashtable.c, hashtable_itr.c, hashtable_private.h: Tweaks
+	  so that the GC_MALLOC/GC_FREE defines apply to the hashtable code
+	  as well.
+
+2004-11-02 07:20  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c: Making the transmit
+	  and Interface->Properties long-path warning messages different.
+
+2004-11-02 07:19  we7u
+
+	* src/util.c: Changing one variable so that it local to where it is
+	  used instead of at the top of the routine.  Changed flags to be
+	  counting flags instead of booleans, so we can later use them to
+	  count digipeater types.  Added some comments.
+
+2004-11-01 12:34  we7u
+
+	* src/util.c: Tweaking the path-check code so that trace,wide2-2
+	  and wide,wide2-2 paths and similar are allowed.
+
+2004-11-01 09:11  tvrusso
+
+	* configure.ac, src/util.c: Add probe for strndup to configure.ac.
+	  Ifdef use of strndup in src/util.c.
+
+	  strndup is a GNU extension and not portable to non-GNU systems.
+
+	  strdup is portable, so is used if strndup isn't available.
+
+2004-10-30 14:13  we7u
+
+	* src/: interface.c, interface_gui.c: Adding path checks to the
+	  igate path.
+
+2004-10-30 14:01  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding another
+	  string for igate path checking.
+
+2004-10-30 13:23  tvrusso
+
+	* README.win32: Add note to section on installing libproj and
+	  libgeotiff.
+
+	  Both of these libraries are now available directly through cygwin
+	  setup, simplifying the installation.
+
+2004-10-30 12:06  we7u
+
+	* src/interface.c: Adding the path check code into each posit and
+	  object/item transmit, at the spot where the unproto path is
+	  selected.  This probably needs to be added to the igate path code
+	  as well.
+
+2004-10-29 13:15  we7u
+
+	* src/interface_gui.c: Another tweak by Ryan Butler, KB0JQO, to
+	  check UNPROTO paths on more types of interfaces.
+
+2004-10-29 13:00  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c, src/util.c,
+	  src/util.h: Tweaks by Ryan Butler, KB0JQO, to check the unproto
+	  paths on interfaces for excessively long paths.  Performs the
+	  path checks when you hit the OK button on the
+	  Interface->Properties dialog.
+
+2004-10-29 08:53  we7u
+
+	* src/map_gdal.c: Enabling tiger polygons for normal use.  Tweaked
+	  the code so that the polygon reassembly only gets done if we have
+	  "filled" enabled for that map.
+
+2004-10-29 07:53  we7u
+
+	* src/map_gdal.c: Experimentally derived at better hash sizes
+	  (twice the max size needed for any county in the state of WA).
+	  Correct code now for free'ing the landmark hash.  Sped up the
+	  TLID linked list code, but still testing that to make sure the
+	  polygons are made correctly (it reverses the order that the line
+	  segments are added to the geometryCollection).
+
+2004-10-28 22:14  we7u
+
+	* src/map_gdal.c: More tweaks to the tiger code.  Still not enabled
+	  for general use.
+
+2004-10-27 10:03  we7u
+
+	* src/map_gdal.c: First working version of Tiger polygon code.
+	  #ifdef'ed out of the compile at present.
+
+2004-10-27 10:02  we7u
+
+	* src/Makefile.am: Adding the hashtable files.
+
+2004-10-27 09:58  we7u
+
+	* src/: hashtable.c, hashtable.h, hashtable_itr.c, hashtable_itr.h,
+	  hashtable_private.h: Adding generic hashtable functions.
+
+2004-10-26 23:24  we7u
+
+	* src/map_gdal.c: Starting to draw some filled polygons for Tiger
+	  maps.  Still not ready for prime-time so the code is still
+	  disabled by an #ifdef.
+
+2004-10-26 22:44  we7u
+
+	* src/map_gdal.c: More Tiger polygon code changes.  The code is
+	  generating polygon geometries from the tiger data now, so the
+	  next step is to start drawing them.
+
+2004-10-26 19:55  we7u
+
+	* src/map_gdal.c: Implementing hash functions for the Tiger polygon
+	  code.  Still #ifdef'ed out, so it won't get compiled in
+	  currently.
+
+2004-10-23 20:38  tvrusso
+
+	* README.MAPS: Mention the Xastir_tigerpoly.py script in the place
+	  where this file previously said that shapefile conversion of
+	  TIGER/Line data didn't contain polygon features.
+
+2004-10-23 15:24  we7u
+
+	* src/main.c: Fixing the segfault caused by closing the Map labels
+	  font dialag before closing xfontsel.	Had to put in a couple of
+	  "xfontsel_query = 0" statements in the callbacks for the Map
+	  labels font dialog.
+
+2004-10-22 08:25  we7u
+
+	* src/map_gdal.c: Added some debug code.  It's not enabled
+	  currently.
+
+2004-10-21 19:54  we7u
+
+	* src/map_gdal.c: Added much of the code needed to reconstruct the
+	  Tiger polygons.  The new code is commented out right now as it's
+	  not quite complete and it really slows things down as well.
+	  Optimization will happen AFTER the code is working.
+
+2004-10-21 12:45  we7u
+
+	* src/map_gdal.c: Changed some comments.
+
+2004-10-21 12:28  we7u
+
+	* src/map_gdal.c: Changed one variable name from i to ii (easier to
+	  grep for).  Added some comments.
+
+2004-10-21 01:55  tvrusso
+
+	* config/tgr2shppoly.dbfawk: Don't display name of feature if it is
+	  "None" (what some fields output by Xastir_tigerpoly.py get, a
+	  feature inherited from tigerpoly.py -- haven't figured out why).
+
+2004-10-21 01:51  tvrusso
+
+	* config/Makefile.am, config/tgr2shppoly.dbfawk,
+	  scripts/Makefile.am, scripts/Xastir_tigerpoly.py: Add python/OGR
+	  script to generate polygon shapefiles from TIGER/Line data.  Add
+	  dbfawk file to make them look less ugly than if there weren't
+	  one.
+
+	  Putting this in CVS merely to get it out there for community
+	  hackage.
+
+2004-10-20 21:19  we7u
+
+	* src/map_gdal.c: Added some comments.
+
+2004-10-20 14:30  we7u
+
+	* src/: geo-find.c, geocoder_gui.c: Find Address works again.
+
+2004-10-20 12:37  tvrusso
+
+	* src/map_gdal.c: Fix mid-function declarations to allow
+	  compilation by gcc 2.95.
+
+2004-10-20 09:42  we7u
+
+	* src/map_gdal.c: Changes to comments only.
+
+2004-10-20 08:37  we7u
+
+	* src/map_gdal.c: More messing with water layers.  Nothing major.
+
+2004-10-19 19:17  we7u
+
+	* src/map_gdal.c: Commenting out the "Loading" message.
+
+2004-10-19 18:13  we7u
+
+	* src/map_gdal.c: Shapefiles are working again in GDAL.
+
+2004-10-19 11:36  we7u
+
+	* src/map_gdal.c: More color and line tweaks.  This change probably
+	  disables Shapefiles, but SDTS and TIGER/Line files display
+	  properly now.
+
+2004-10-19 09:02  we7u
+
+	* src/map_gdal.c: Moving all of the color code into the
+	  guess_vector_attributes function.  Later we'll be able to convert
+	  this function into our map preferences system once that is fully
+	  defined.  Added color to the SDTS files.
+
+2004-10-19 07:45  we7u
+
+	* src/map_gdal.c: Faster determination of layer name.
+
+2004-10-18 22:22  we7u
+
+	* src/map_gdal.c: Starting to support proper color scheme for
+	  SDTS-format maps.  At least have contours in yellow and other
+	  layers in black now.
+
+2004-10-18 21:08  we7u
+
+	* src/map_gdal.c: Fixing OGR indexing so that the transform is
+	  invoked every time.  Required for UTM/State-plane maps.
+
+2004-10-18 13:17  we7u
+
+	* src/maps.c: Changing default Shapefile translator back to
+	  Shapelib.
+
+2004-10-18 13:09  we7u
+
+	* src/map_gdal.c: Truncating the points better.  Was truncating at
+	  0 for negative values, which doesn't work.  We just need to keep
+	  away from the +16000/-16000 points and greater, which invoke X11
+	  drawing bugs.  Truncating at zero creates dummy lines along our
+	  top and left window borders.
+
+2004-10-18 12:58  we7u
+
+	* src/map_gdal.c: Very weak attempt at detecting hypsography and
+	  hydropraphy SDTS files to decide to color them yellow, keyed off
+	  "HY"or "HP" anywhere in the full filename (that's why it is
+	  weak).  Other SDTS maps get colored black currently.
+
+2004-10-18 11:57  we7u
+
+	* src/: bulletin_gui.c, db.c, list_gui.c, main.c, main.h,
+	  map_gdal.c, maps.c, util.c, view_message_gui.c, wx_gui.c,
+	  xa_config.c: Changing the name of a global variable.	Tweaking
+	  elevation for SDTS contours so that they are in the correct
+	  units.
+
+2004-10-18 09:39  we7u
+
+	* src/map_gdal.c: Outputting the correct label on elevations now
+	  from SDTS files.  Later will try to switch it to match the
+	  setting of the Enable English Units togglebutton so that we can
+	  get a consistent display.
+
+2004-10-18 07:55  we7u
+
+	* src/map_gdal.c: Added some notes.  No code changes.
+
+2004-10-15 21:25  we7u
+
+	* src/map_gdal.c: Changing text from "ft" to "m" for elevation.
+	  SDTS file appear to have elevation in meters.  Also changing back
+	  to yellow for the contour lines as it is highly visible whereas
+	  the white/gray is not in many cases.
+
+2004-10-15 12:24  we7u
+
+	* src/map_gdal.c: Default coloring for raw Tiger/Line maps.
+
+2004-10-15 09:27  we7u
+
+	* src/map_gdal.c: Repositioning labels slightly.  Fixing segfault
+	  caused by earlier "skip" option.
+
+2004-10-15 08:36  we7u
+
+	* src/map_gdal.c: Changing to lighter colors again for contours and
+	  their labels.  They need to show up on top of terraserver images.
+	  Brown doesn't cut it.  Changed the contours to gray80 and the
+	  labels to white.
+
+2004-10-15 07:56  we7u
+
+	* src/map_gdal.c: Changing to brown for the contours and
+	  corresponding labels.  Closer to the USGS topo map colors.
+
+2004-10-15 07:44  we7u
+
+	* src/map_gdal.c: Drawing more labels along each object.  Tied to
+	  zoom level so that we reduce the quantity of labels as we zoom
+	  out.
+
+2004-10-15 07:22  we7u
+
+	* src/map_gdal.c: Setting a few hard-coded default colors from some
+	  types of map objects.  Later we'll redo this so that the
+	  preferences come from a file.  Re-enabled code that dumps out the
+	  layer information.  Added elevation display for SDTS-format DLG
+	  contours.
+
+2004-10-14 21:12  we7u
+
+	* src/map_gdal.c: Several fixes.  Spatial filtering now works
+	  properly.
+
+2004-10-14 12:52  we7u
+
+	* src/map_gdal.c: Simplified some of the code.	Have SDTS contours
+	  working again, but have a problem with those files and spatial
+	  filtering yet.  This version works but puts out error messages to
+	  STDERR with SDTS files.
+
+2004-10-13 23:05  we7u
+
+	* src/map_gdal.c: Sped up GDAL maps:  Implemented the spatial
+	  filtering mechanism inherent in the library.	We now filter using
+	  our viewport as the bounding rectangle, which really speeds
+	  things up as you zoom in.
+
+2004-10-13 22:57  we7u
+
+	* src/maps.c: Fix for draw_vector function.  It now rearranges the
+	  bottom/top/left/right if it's called with things out of order,
+	  before calling map_visible.  This gets fewer vectors rejected due
+	  to being off-screen/more vectors actually get drawn.
+
+2004-10-12 08:34  we7u
+
+	* src/map_gdal.c: Fixing up debug messages.  Sending weather alerts
+	  off to the draw_shapefile_map function for now.
+
+2004-10-11 19:11  we7u
+
+	* src/map_gdal.c: Nicer labels for OGR plus rotation.
+
+2004-10-11 13:12  we7u
+
+	* src/map_gdal.c: Slight reformatting.	No code changes.
+
+2004-10-11 13:06  we7u
+
+	* src/map_gdal.c: Labels for OGR point files as well.  Untested.
+
+2004-10-11 12:56  we7u
+
+	* src/map_gdal.c: Initial labels for OGR vector maps.  Not colored
+	  yet, not rotated, but better than nothing, which is what we had
+	  before!
+
+2004-10-11 12:15  tvrusso
+
+	* src/map_tif.c: Add some error messages to the "geoTIFF file not
+	  in proper format" block, so the user can see what is actually
+	  wrong with the file.
+
+2004-10-11 09:27  we7u
+
+	* scripts/: toporama250k.pl, toporama50k.pl: Tweaking one comment
+	  that gets written out to the .geo files.
+
+2004-10-10 12:16  tvrusso
+
+	* src/testawk.c: Fix mistake in font_size output --- make sure
+	  appears on correct line.
+
+2004-10-10 12:01  tvrusso
+
+	* src/testawk.c: Add "font_size" variable to those that are read
+	  and output by testawk.  testawk still lags significantly behind
+	  xastir in what it reads and outputs.
+
+2004-10-08 11:33  we7u
+
+	* scripts/: toporama250k.pl, toporama50k.pl: Oops.  Changing
+	  copyright to correct one.
+
+2004-10-08 11:31  we7u
+
+	* scripts/: toporama250k.pl, toporama50k.pl: Adding copyright and
+	  licensing info.
+
+2004-10-08 11:20  we7u
+
+	* scripts/: Makefile.am, toporama250k.pl, toporama50k.pl: Scripts
+	  to snag Canadian toporama map files and create .geo files for
+	  them.  Created mostly from code submitted by Adi Linden, VA3ADI.
+
+2004-10-07 19:15  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Making a few more
+	  warnings go to popups instead of STDERR.  Fixing object/item code
+	  so that you can't create a new object/item that has the same name
+	  as another station/object/item in the database.
+
+2004-10-07 14:43  we7u
+
+	* src/: db.c, geocoder_gui.c: Removing some white space.
+
+2004-10-07 10:16  we7u
+
+	* src/main.c: Fixing another Xt call that should have a NULL at the
+	  end.
+
+2004-10-07 09:29  we7u
+
+	* src/main.c: Slightly better check_range() function.  This one
+	  snaps the left/right of the map to the left/right of the display
+	  in most cases.  Still more work to do before I'll be satisfied
+	  with the operation though.
+
+2004-10-07 08:44  we7u
+
+	* src/main.c: Tweaking check_range() so that it doesn't allow us to
+	  zoom out beyond the N/S poles.  It will resize the Y scale factor
+	  so that it fits the window perfectly N/S.  More work will
+	  probably be done on this function later so that we fit E/W
+	  perfectly as we zoom out as well (depending on the window's
+	  aspect ratio).
+
+2004-10-07 08:14  shadow
+
+	* src/: db.c, main.c: update calls to XrtVaGetValues to terminate
+	  with NULL
+
+2004-10-06 22:45  we7u
+
+	* src/main.c: Minor tweak to how center/zoom is calculated.  Check
+	  for edge of earth now.  May be more tweaks to come for this part
+	  of the code.
+
+2004-10-06 22:17  we7u
+
+	* src/main.c: Tweaking a few more minor GUI things for Map View
+	  object creation.
+
+2004-10-06 21:44  we7u
+
+	* src/main.c: Computes proper range now when creating Map View
+	  objects.
+
+2004-10-06 20:28  we7u
+
+	* src/db.c: Fixing transmit of objects/items so that they send out
+	  PHG or RNG as the first parameter in the comment field.
+
+2004-10-06 17:15  we7u
+
+	* src/main.c: Fixing the language command-line switch.	Initial
+	  implementation of the code for creating Map View objects (not
+	  complete yet).
+
+2004-10-05 22:17  shadow
+
+	* src/awk.c: awk_find_sym can return NULL; don't assume src->type
+	  is valid.
+
+2004-10-05 17:20  shadow
+
+	* config/tgr2shp.dbfawk: dd missing double-quote in FENAME default
+	  case handling
+
+2004-10-05 10:11  we7u
+
+	* src/: db.c, main.c: Fixing the Move Object function so that we
+	  can only move objects that we already own.  Any SSID will work.
+	  If we don't own it, we have to adopt the object first before we
+	  can move it.	This keeps us from accidentally moving objects if
+	  we accidentally leave the Move function on and then click/drag on
+	  the map display.
+
+2004-10-05 08:54  we7u
+
+	* Makefile.am: Adding a new Texas radar geo file.
+
+2004-10-05 08:54  we7u
+
+	* TXRadar.geo: Adding a new geo file for Texas radar, contributed
+	  by Gerry Creager.
+
+2004-10-04 22:12  we7u
+
+	* src/db.c: Fixing a typo in extract_powergain_range() which caused
+	  it to skip parsing PHG strings.
+
+2004-10-04 13:20  we7u
+
+	* FAQ: Adding another link for the remote serial port stuff.
+
+2004-10-04 12:58  we7u
+
+	* src/db.c: Reducing the number of positions displayed in Station
+	  Info from 100 to 50.	This is in order to speed up the automatic
+	  updates version of the Station Info dialog.
+
+2004-10-04 12:25  we7u
+
+	* FAQ: Adding links to the serial port redirectory programs,
+	  courtesy of Mike Fenske.
+
+2004-10-04 10:17  we7u
+
+	* src/wx.c: Fixing the 000/360 wind course problem.  We should now
+	  transmit "360" when the wind direction is 0, as the APRS spec
+	  requires.
+
+2004-10-04 10:16  we7u
+
+	* README.CVS: Adding a note about the "wheel" group and sudo.
+
+2004-10-04 09:20  we7u
+
+	* FAQ: Adding info regarding connecting to remote serial ports.
+
+2004-10-04 09:17  we7u
+
+	* README.MAPS: Adding a link to the national transportation atlas
+	  map files, link provided by Derrick J Brashear.
+
+2004-10-04 08:32  we7u
+
+	* src/xa_config.c: Changing default fonts to be non-italic.  A bit
+	  more readable.
+
+2004-10-03 12:46  we7u
+
+	* configure.ac: Small tweak to avoid a conflict with a
+	  similarly-named define in the GDAL library.
+
+2004-10-03 00:04  we7u
+
+	* src/testawk.c: Giving up on this file for now in terms of
+	  compiling with strict error-checking.
+
+2004-10-02 23:17  we7u
+
+	* src/interface.c: Fixing a few more problems that were found by
+	  compiling with strict error-checking.
+
+2004-10-02 22:43  we7u
+
+	* src/: interface.c, testawk.c, x_spider.c: More tweaks from
+	  compiling with stronger error-checking.
+
+2004-10-02 22:19  we7u
+
+	* src/main.c: Fixing up a few things found by running with these
+	  compile flags: "-g -O2 -pipe -Wall -pthread -Wpointer-arith -W
+	  -pedantic"
+
+2004-10-02 21:58  we7u
+
+	* src/: db.c, draw_symbols.c, geo-find.c, hostname.c, map_shp.c,
+	  map_tif.c, maps.c, util.c, wx.c, x_spider.c: Fixing up a few
+	  things found by running with these compile flags: "-g -O2 -pipe
+	  -Wall -pthread -Wpointer-arith -W -pedantic"
+
+2004-10-02 11:08  we7u
+
+	* src/: draw_symbols.c, locate_gui.c, maps.c, messages_gui.c,
+	  testawk.c, xastir.h, main.c: Tweaks to get rid of compiler
+	  warnings on 64-bit CPU's.  Fixing up mostly casts to/from
+	  pointers and int's using some macros from the FreeCIV project to
+	  help us.
+
+2004-10-01 09:19  we7u
+
+	* README.CVS: Adding "sudo" instructions.
+
+2004-09-29 09:04  tvrusso
+
+	* src/map_shp.c: Repair broken stippling of filled polygons under
+	  dbfawk.
+
+	  Before this commit, stippling was set too early in the code and
+	  not turned off before label drawing began, rendering map labels
+	  for stippled polygons unreadable.
+
+2004-09-29 00:10  tvrusso
+
+	* README.MAPS, src/map_shp.c: Add "fill_stipple" dbfawk variable,
+	  and support for it.
+
+	  Now, if a dbfawk file sets filled=1, fill_style=2, and
+	  fill_stipple={0,1,2}, the filled polygons will be stippled
+	  instead of solid.
+
+	  fill_stipple=0 gives 13% stipple fill_stipple=1 gives 25% stipple
+	  fill_stipple=2 gives 50% stipple.
+
+	  "fill_style=2" corresponds to FillStippled per XSetFillStyle.
+
+2004-09-28 14:53  gstueve
+
+	* src/messages.c: Add check for DOS EOL markup.
+
+2004-09-28 11:01  we7u
+
+	* FAQ: Added a bit about NumLock/ScrollLock/CapsLock messing up
+	  Motif programs, and one way to solve it.
+
+2004-09-28 08:40  we7u
+
+	* src/db.c: Fixing Station Chooser dialog so that it expands
+	  properly.  It used to increase the size of the buttons instead of
+	  increasing the size of the station window.
+
+2004-09-27 09:49  tvrusso
+
+	* FAQ: Add FAQ entries for autoconf-related FAQs.
+
+2004-09-27 08:04  tvrusso
+
+	* Makefile.am: Return "dist-bzip2" to the AUTOMAKE_OPTIONS
+	  variable.
+
+	  it is true that --dist-bzip2 is not a valid automake option, but
+	  the AUTOMAKE_OPTIONS variable doesn't generate --options for
+	  automake, it has an effect on the generated makefile itself.	In
+	  this case, dist-bzip2 adds a dist-bzip2 target to the makefile.
+
+	  As far as I can tell, the folks who are having trouble with this
+	  option are not in fact using automake 1.6.3 or later.  In ha2vr's
+	  case it turned out he was actually using automake 1.4, even
+	  though automake 1.9 was supposedly installed on his system.
+
+2004-09-26 17:29  tvrusso
+
+	* Makefile.am, acinclude.m4, bootstrap.sh: Per discussions on
+	  xastir mailing list:
+
+	   -  remove "dist-bzip2" from "AUTOMAKE_OPTIONS" in Makefile.am.
+	   -  Fix underquoted AC_DEFUN of AC_CHECK_GMTOFF
+
+	  Also, add a print statement to end of "bootstrap.sh" so it's
+	  clear when it's finished successfully.
+
+2004-09-24 14:16  we7u
+
+	* src/wx.c: Fixing the offsets and data length for the Peet
+	  Complete-mode wind speed fields.
+
+2004-09-24 12:42  we7u
+
+	* src/main.c: Commenting out some debug code.
+
+2004-09-24 12:42  we7u
+
+	* src/util.c: Removing some dead code from the compressed posit
+	  routine.
+
+2004-09-24 12:35  we7u
+
+	* src/db.c: Fixing symbol drawing so that Map View objects "range"
+	  circles aren't drawn.  Fixing compressed posits so that csT bytes
+	  are always removed when decoding.  Adding "Current Range:" output
+	  to Station Info dialog.
+
+2004-09-24 12:32  we7u
+
+	* src/draw_symbols.c: Reducing the size of the wind barbs as we
+	  zoom out.
+
+2004-09-24 12:30  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added range output
+	  to Station Info dialog.  Added missing tactical call string to
+	  some language files.
+
+2004-09-24 09:49  tvrusso
+
+	* src/db.h: Remove DOS line terminators.  Reformat long lines.
+
+2004-09-23 20:29  we7u
+
+	* src/: db.c, main.c, main.h: This change implements decoding for
+	  Map View "eyeball" objects.
+
+2004-09-22 13:00  we7u
+
+	* src/main.c: Adding a bit more output to the "time has reversed"
+	  fprintf's.  We now dump out the number of seconds we went
+	  backwards and the date/time of the event.
+
+2004-09-22 12:25  we7u
+
+	* README.CVS: Added a note about autoconf and automake.
+
+2004-09-20 12:15  we7u
+
+	* src/x_spider.c: Another tweak to allow multiple spaces between
+	  "pass" and the passcode.
+
+2004-09-20 12:10  we7u
+
+	* src/x_spider.c: Fixing user/pass login in the Server code so that
+	  both of them are position-independent.
+
+2004-09-19 19:29  tvrusso
+
+	* src/main.c: Add the base file name to the dbfawk file for
+	  downloaded GPS tracks and routes.  This allows the name of the
+	  track to be displayed along with the line data when these files
+	  are used outside of the GPS directory.
+
+	  I forgot to add this component of the data in in my first commit.
+
+2004-09-19 16:52  tvrusso
+
+	* README.MAPS: A little cleanup of the discussion involving
+	  "gdalwarp."
+
+2004-09-19 16:39  tvrusso
+
+	* README.MAPS, src/map_tif.c: This is a patch I've been using for
+	  several months now: it allows xastir to use geotiff files that
+	  are already unprojected lat/lon maps.  It simply checks the "PCS"
+	  key in the geotif file, and if it's not there then the file is
+	  assumed to be in lat/lon and can be used as is without
+	  transformation.
+
+	  It has no effect on maps that are not already in lat/lon, and so
+	  will be invisible to anyone who hasn't needed the ability to read
+	  in unprojected geotiff files.
+
+	  README.MAPS updated to explain that gdalwarp can be used to
+	  convert maps into lat/lon unprojected maps.  Also added a place
+	  to find useful geotiff maps that need such conversion (FAA
+	  sectionals from aviationtoolbox.org).
+
+	  Tweaked the stuff on shapefile reprojection.	What was there were
+	  verbose snippets from an email exchange between Curt and me.
+	  Made them a bit shorter and more to-the-point.
+
+	  The importing of lat/lon geotiff files is significantly slower
+	  than the importing of USGS quads, because the optimized reads
+	  that skip over scanlines based on zoom level don't work.  I
+	  intended to figure out how to make them work, but never did the
+	  work.  If folks start using this a lot and get me to bump it up
+	  in priority I can revisit it.
+
+2004-09-19 15:50  tvrusso
+
+	* config/Makefile.am, config/gps_wpt.dbfawk, src/main.c: config:
+	  New DBFAWK file for waypoints files downloaded through GPSMan.
+	  Now, DBFAWK-	enabled xastir will display names of waypoints next
+	  to the symbol, no matter  what directory they're put in.
+
+	   Add gps_wpt.dbfawk file to makefile.
+
+	  src:	make xastir write out a simple dbfawk file to go along with
+	  GPSMan track	and route shapefiles.  Prior to this, these files
+	  would only display in the  selected color if they were copied
+	  into /usr/local/share/xastir/maps/GPS,  and would display in all
+	  black if they were anywhere else.
+
+	  Unfortunately, because we have no control over the fields created
+	  by GPSMan for these shapefiles, it is not possible to stick the
+	  color itself into the dbf file, as Alan had suggested in various
+	  comments in the code.
+
+	  To use these new things:   for waypoints, do nothing -- the
+	  dbfawk file is generic and applies to any   GPSMan waypoint file.
+
+	    For tracks and routes: Make sure to copy the dbfawk file when
+	  you copy the
+	     shapefile and dbf file to a maps directory.  Xastir will use
+	  it.
+
+	    For tracks and routes downloaded prior to this patch: the
+	  dbfawk file is
+	    simple, just copy one for a map of the same color.
+
+2004-09-18 13:30  we7u
+
+	* src/map_shp.c: Fixing the "Loading" and "Indexing" messages so
+	  that they don't overrun our limited real estate on the status
+	  line.
+
+2004-09-18 13:25  we7u
+
+	* src/: map_dos.c, map_geo.c, map_gnis.c, map_pdb.c, map_tif.c,
+	  map_tiger.c: Fixing the "Loading" and "Indexing" messages during
+	  map activity so that they don't overrun our limited real estate
+	  on the status line.
+
+2004-09-17 13:44  we7u
+
+	* src/interface.c: Increasing the wait time in the loop where we're
+	  connecting up network interfaces.  Was 20ms, now 250ms.
+
+2004-09-17 12:56  we7u
+
+	* src/: fcc_data.c, geocoder_gui.c, locate_gui.c, location_gui.c,
+	  map_gnis.c, rac_data.c, track_gui.c: Bypassing the new configure
+	  flag with a few more popups that are user-requested.
+
+2004-09-17 12:46  we7u
+
+	* src/: main.c, popup_gui.c, xastir.h: Tweaks so that a few of the
+	  popups will continue to display in that manner (instead of
+	  heading to STDERR).
+
+2004-09-17 12:22  we7u
+
+	* INSTALL, README.Getting-Started, acinclude.m4, configure.ac,
+	  src/popup_gui.c: Implementing the "--without-errorpopups"
+	  configure flag.  If invoked, popup_messages() writes to STDERR
+	  instead of causing a popup dialog to appear.
+
+2004-09-17 10:12  tvrusso
+
+	* src/main.c: Put Cygwin-specific setting of nexttime into the
+	  UpdateTime function.
+
+	  Remove the two Cygwin-specific usleep(2) from the end of
+	  UpdateTime.
+
+	  With these changes, running xastir on Cygwin under Win2K on a
+	  2GHz machine went from taking up 90+% of the CPU to taking around
+	  20% --- most of that in system processes, and mostly that high
+	  when X events are being processed.
+
+2004-09-16 12:31  we7u
+
+	* configure.ac: Bumping the revision to 1.4.1, as we just did a
+	  stable release at 1.4.0.
+
+2004-09-16 07:47  we7u
+
+	* src/xa_config.c: Changing default sound command from "vplay" to
+	  "play" as it is much more common.
+
+2004-09-16 07:00  tvrusso
+
+	* src/map_gnis.c: Quick, trivial commit both to make sure I'm set
+	  up right and to remove a slightly annoying error message when I'm
+	  looking at New Mexico with GNIS: Add "ruin" as a recognized gnis
+	  entry type.
+
+	  Ideally, this mapping of gnis entries to zoom level limits should
+	  be in metadata rather than a large if/elseif/elseif... block, but
+	  that's another issue.
+
+2004-09-15 13:19  we7u
+
+	* src/db.c: Re-ordering "if" statements to speed things up
+	  slightly.
+
+2004-09-15 12:59  we7u
+
+	* src/db.c: Another speedup (lower CPU usage).
+
+2004-09-15 12:44  we7u
+
+	* src/alert.c: Reducing CPU usage of normal_title().
+
+2004-09-15 12:43  we7u
+
+	* src/db.h: Slowing down minimum object timing by another five
+	  seconds.  Reduces how often we look through our database, keeping
+	  CPU usage down.
+
+2004-09-15 10:08  we7u
+
+	* src/db.c: Swapping two "if" statements in a loop, as the
+	  is_my_call() function appears to be faster than the boolean
+	  operations to determine whether it's an object/item.
+
+2004-09-14 12:32  we7u
+
+	* src/db.c: Making is_my_call() and
+	  check_and_transmit_objects_items() more efficient.  Found during
+	  profiling that these routines were eating up CPU.
+
+2004-09-13 19:50  we7u
+
+	* INSTALL, configure.ac: Adding the "--with-profiling" flag.
+	  Updating docs to reflect it.
+
+2004-09-13 12:56  we7u
+
+	* src/map_shp.c: Changing label storage to a hash table instead of
+	  an array, to speed things up.  Using the first character of the
+	  string as the hash index.  Tried using lower 7 bits of first two
+	  chars, and lower 6 bits of first two chars: Profiling showed that
+	  using the first character was faster.
+
+2004-09-13 12:54  we7u
+
+	* src/rotated.c: Moving math into appropriate parts of loop to
+	  speed it up.	Anything that is static through all iterations of a
+	  loop is moved outside that loop for speed.
+
+2004-09-10 16:09  we7u
+
+	* src/draw_symbols.c: Implementing a cache for the most recent five
+	  symbols used.  Speeds up drawing by quite a bit (found by
+	  profiling).
+
+2004-09-10 12:26  we7u
+
+	* src/main.c: More speedups found by profiling.  Checking for new
+	  gps map only once per second now, updating the stations count on
+	  the status line once per second instead of continuously.
+
+2004-09-10 09:19  we7u
+
+	* src/main.c: Adding some Cygwin-specific usleep's in UpdateTime()
+	  in order to reduce CPU usage on those systems.
+
+2004-09-10 08:49  we7u
+
+	* src/awk.c: Sped up awk_find_sym() a bit.
+
+2004-09-10 08:37  we7u
+
+	* src/rotated.c: Sped up font rotation by moving some
+	  floating-point math outside the inner loop.
+
+2004-09-10 08:27  we7u
+
+	* src/alert.c: Fixing a minor compiler warning.
+
+2004-09-09 20:37  we7u
+
+	* src/maps.c: Fixing a bug I introduced earlier today while
+	  speeding up map indexing.
+
+2004-09-09 12:59  we7u
+
+	* src/maps.c: Speeding up the maps.c:index_retrieve() function.
+	  Making it more efficient.  Perhaps the next step would be to turn
+	  it into a hash lookup, but that would require changing perhaps
+	  several other routines to match.
+
+2004-09-09 09:11  we7u
+
+	* README.Getting-Started: Adding another note about callpass.
+
+2004-09-09 08:06  we7u
+
+	* INSTALL: Adding another note to the profiling section.
+
+2004-09-08 20:43  we7u
+
+	* src/alert.c: Major speedup in weather alert code, found through
+	  profiling.
+
+2004-09-08 12:22  we7u
+
+	* INSTALL: Adding a section on checking for memory leaks.
+
+2004-09-08 10:48  we7u
+
+	* INSTALL: Adding profiling instructions.
+
+2004-09-07 14:40  we7u
+
+	* FAQ: Added a bit about MacOSX USB adapters, courtesy of Jeff
+	  Wigal, WY7Q.
+
+2004-09-07 14:06  we7u
+
+	* src/util.c: Changing format for time so that Cygwin can
+	  understand more of it.  Tweak courtesy of Henk de Groot.
+
+2004-09-07 10:15  we7u
+
+	* README.Getting-Started, README.win32: Tweaking the notes about
+	  GPSMan/gpsmanshp.
+
+2004-09-07 08:39  we7u
+
+	* src/festival.c: Adding some usleep() function calls for the case
+	  where we can't open a socket to Festival, so that we don't spin
+	  our wheels too fast trying to open sockets.
+
+2004-09-06 21:06  rzg
+
+	* help/help-English.dat: Done the body, just "whats new" section
+	  left.
+
+2004-09-06 18:44  we7u
+
+	* src/main.c: Fixes for the Filled and Automaps columns in Map
+	  Chooser->Properties dialog.
+
+2004-09-04 23:24  rzg
+
+	* help/help-English.dat: Updating helpfile some more, still have
+	  last 1/3rd to go over and "whats new" section to write. FIXMEs up
+	  for grabs; and if anyone otherwise wants to help let me know.
+
+2004-09-03 08:16  we7u
+
+	* src/db.c: Drawing symbol after we draw circles and other items.
+	  Trying to keep the text on top so that it is more readable.
+
+2004-09-02 22:37  we7u
+
+	* src/db.c: Moving the weather info to the top of the Station Info
+	  dialog, for the cases where we have weather info stored.  The
+	  weather info is the most important info for that station in that
+	  case, so it should be readable without scrolling.  Stations
+	  without weather data are unaffected by this change.
+
+2004-09-02 20:19  we7u
+
+	* src/db.c: Fixed a small bug in positionless weather decoding
+	  where it wasn't decoding course/speed fields.  We now take
+	  another look for course/speed if either of them are empty.
+	  Before both of them had to be empty before we tried another type
+	  of parsing for them.	Did the and->or conversion in several
+	  places in extract_weather(), so the change affects more than just
+	  positionless weather packets.
+
+2004-09-02 13:58  we7u
+
+	* config/language-Dutch.sys: Another tweak from Henk & Han.
+
+2004-09-02 11:36  we7u
+
+	* config/language-Dutch.sys: More mods by Henk.
+
+2004-09-02 10:51  we7u
+
+	* FAQ: Updating the locale-specific answers.
+
+2004-09-02 10:45  we7u
+
+	* src/main.c: Fixing the locale for numbers to "C".  We require
+	  this in order to be able to write and parse our config files and
+	  .geo files properly when the LC_NUMERIC or LANG environment
+	  variables are set to something else.	This affects the printf and
+	  scanf sorts of functions.
+
+2004-09-02 07:49  we7u
+
+	* src/: main.c, xa_config.c: Bumping the max timeout for tigermaps
+	  from 120 to 180 seconds since so many people are getting timeouts
+	  with it.
+
+2004-09-01 12:34  we7u
+
+	* config/language-Dutch.sys: Updates by Han Sytsma, PE1FAM, and
+	  Henk de Groot, PE1DNN.  Thanks!
+
+2004-09-01 10:51  we7u
+
+	* README.Getting-Started, configure.ac: Bumping to the next release
+	  number, 1.4.
+
+2004-09-01 08:37  we7u
+
+	* config/language-Spanish.sys: A few translations by Charles
+	  Twardy.  Thanks!
+
+2004-08-31 11:56  we7u
+
+	* config/language-Dutch.sys: Updates by Henk de Groot, PE1DNN.
+	  Thanks!
+
+2004-08-31 11:05  we7u
+
+	* help/help-English.dat: Minor tweaks to descriptions about object
+	  timing.
+
+2004-08-31 10:30  francais1
+
+	* config/language-French.sys: Updated
+
+2004-08-31 09:52  we7u
+
+	* config/language-Portuguese.sys: Updates by David Quental, CT1DRB.
+	  Thanks!
+
+2004-08-31 09:46  we7u
+
+	* src/db.c: Tweak which helps to prevent parsing of weather fields
+	  out of comment data.
+
+2004-08-31 09:08  rzg
+
+	* help/help-English.dat: Updating helpfile for release, about 1/3rd
+	  done.
+
+2004-08-31 07:40  we7u
+
+	* config/language-Italian.sys: Updates by Alessandro Frigeri,
+	  IK0YUP.  Thanks!
+
+2004-08-30 08:49  we7u
+
+	* src/interface.c: Adding a terminating zero to the AGWPE packets
+	  in port_read() instead of in parse_agwpe_packet().
+
+2004-08-30 08:28  we7u
+
+	* src/interface.c: Adding a string terminator to the end of the
+	  AGWPE raw packets before we start processing them.  This keeps
+	  portions of previously received packets from getting appended to
+	  our current string during our processing.
+
+2004-08-30 07:38  we7u
+
+	* README.win32: Changing to Henk de Groot's optimized Festival
+	  install instructions.
+
+2004-08-28 15:43  we7u
+
+	* README.win32: Added Festival instructions for Win32 courtesy of
+	  Tom Russo.  Thanks!
+
+2004-08-27 13:09  we7u
+
+	* src/main.c: Fix for high CPU-usage when time skips backwards.
+	  This fix causes Xastir to sleep a bit in the UpdateTime() loop
+	  until time catches up again, thereby avoiding the problem.  It
+	  also dumps a message out to STDERR as it goes into/out of this
+	  mode.
+
+2004-08-27 07:44  we7u
+
+	* src/map_gdal.c: Changed the gdal output on startup to show only
+	  those map formats that have been enabled in Xastir AND are
+	  supported by the GDAL library that we're compiled against.
+
+2004-08-27 07:16  we7u
+
+	* config/language-German.sys: Tweaks by Rolf Bleher, DK7IN.
+	  Thanks!
+
+2004-08-26 18:07  shadow
+
+	* configure.ac: update libgeotiff/libtiff/libproj configure tests
+	  such that 1) libproj is checked for only once 2) libtiff is used
+	  if found when testing for libgeotiff
+
+	  revised test from Tom Russo KM5VY and tested on MacOS X and
+	  Linux.
+
+2004-08-26 14:03  we7u
+
+	* src/db.c: Fixing the code so that snow can be parsed out of a
+	  weather report only if course/speed has already been
+	  parsed/deleted from the string.
+
+2004-08-26 11:09  we7u
+
+	* src/alert.c: Fix for high-CPU bug when malformed NWS weather
+	  alert packet is received.
+
+2004-08-25 12:45  we7u
+
+	* src/db.c: Fix for truncated lines when using AGWPE or Serial KISS
+	  TNC interfaces.
+
+2004-08-25 12:40  we7u
+
+	* src/interface.c: Changed comments.  No code changes.
+
+2004-08-25 12:39  we7u
+
+	* src/main.c: Changed a comment.  No code changes.
+
+2004-08-24 18:59  we7u
+
+	* scripts/: Makefile.am, kiss-off.pl: Adding a kiss-off script to
+	  take a TNC out of KISS mode.
+
+2004-08-24 18:53  we7u
+
+	* src/: main.c, db.c: Fixing the object/item comment-field bug.
+
+2004-08-23 21:47  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, help/help-English.dat,
+	  src/messages.c, src/messages.h, src/messages_gui.c: Changing the
+	  label on the Clear Messages button, adding a new button for
+	  deleting the outgoing messages to that station, relocating the
+	  buttons to the bottom row.
+
+2004-08-23 12:48  we7u
+
+	* README.Getting-Started: Added notes about where to look for
+	  instructions for other OS'es.
+
+2004-08-22 11:39  we7u
+
+	* src/main.c: Changed one comment.
+
+2004-08-21 17:01  we7u
+
+	* src/: db.c, util.c, util.h: More fixes for xastir_snprintf size
+	  parameter, including adding a size parameter to a few other
+	  functions that can be used to prevent overrunning strings.
+
+2004-08-21 16:55  we7u
+
+	* src/wx.c: Reformatting of code and rechecking the size parameter
+	  for xastir_snprintf function calls.
+
+2004-08-20 23:48  we7u
+
+	* src/wx_gui.c: Reformatting some code.
+
+2004-08-20 23:35  we7u
+
+	* src/: view_message_gui.c, x_spider.c: More cleanup of the size
+	  parameter for xastir_snprintf calls.
+
+2004-08-20 23:13  we7u
+
+	* src/: db.c, geocoder_gui.c, gps.c, hostname.c, igate.c,
+	  interface.c, maps.c: Cleaning up the size parameter for a bunch
+	  of xastir_snprintf calls.
+
+2004-08-20 13:50  we7u
+
+	* src/db.c: Fix for bad longitude for your own station.
+
+2004-08-20 11:38  we7u
+
+	* src/db.c: Fixing problem with truncated comment/status strings.
+	  Was setting the length in the xastir_snprintf() call to the
+	  length of the pointer instead of the length of the malloc'ed
+	  string buffer.
+
+2004-08-20 10:27  we7u
+
+	* src/maps.c: Added a comment.
+
+2004-08-20 10:25  we7u
+
+	* src/: awk.c, geo-find.c: Reformatting of geo-find.c.	Added
+	  comment to both files.
+
+2004-08-20 10:22  we7u
+
+	* src/db.c: Moving ptr into the block where it is used.
+
+2004-08-20 10:19  kd6zwr
+
+	* src/db.c: Moving a declaration up to the top to allow it to be
+	  compiled.
+
+2004-08-20 09:52  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Reducing the
+	  resolution on the snow reports, as they are only reported by
+	  inch, not by 100's of an inch.
+
+2004-08-19 21:06  we7u
+
+	* src/: alert.c, awk.c, db.c, geo-find.c, igate.c, interface.c,
+	  messages_gui.c, util.c, view_message_gui.c, wx.c, x_spider.c:
+	  More on the strcat/strcpy/strncpy reduction/elimination.  I think
+	  this finishes off all the strcat/strcpy calls, and there are only
+	  24 strncpy calls left in the code.
+
+2004-08-19 13:10  we7u
+
+	* README.Getting-Started: Attempting to answer the question: "Why
+	  must I compile from sources?"
+
+2004-08-19 12:54  we7u
+
+	* Makefile.am: Adding the new README.Getting-Started into the
+	  installation scripts.
+
+2004-08-19 12:48  we7u
+
+	* README.Getting-Started: Spellling fix.
+
+2004-08-19 12:45  we7u
+
+	* README.Getting-Started: First checkin.  Fairly complete.
+
+2004-08-19 12:38  we7u
+
+	* src/: alert.c, bulletin_gui.c, db.c, dbfawk.c, gps.c, gps.h,
+	  hostname.c, hostname.h, igate.c, interface.c, interface_gui.c,
+	  location_gui.c, main.c, map_shp.c, map_tiger.c, messages_gui.c,
+	  rotated.c, view_message_gui.c, wx_gui.c: More work to eliminate
+	  strcat/strcpy/strncpy from the code.
+
+2004-08-18 23:45  we7u
+
+	* src/: map_tiger.c, maps.c, x_spider.c: More strcat/strcpy fixes.
+	  Changing to safer string-handling routines.
+
+2004-08-18 23:38  we7u
+
+	* src/: db.c, interface.c, main.c, map_dos.c, messages_gui.c,
+	  popup_gui.c, rac_data.c, sound.c, track_gui.c, xa_config.c,
+	  location_gui.c, alert.c, datum.c, draw_symbols.c, fcc_data.c,
+	  festival.c, geocoder_gui.c, gps.c, igate.c, list_gui.c,
+	  locate_gui.c, map_geo.c, map_gnis.c, messages.c, util.c, wx.c,
+	  map_shp.c: More strcat/strcpy fixes.	Changing to much safer
+	  string-handling routines.
+
+2004-08-18 23:31  we7u
+
+	* src/: geo.h, gps.h, main.h, messages.h, wx.h, xastir.h:
+	  strcat/strcpy fixes.	Changing to much safer string-handling
+	  routines.
+
+2004-08-18 13:35  we7u
+
+	* src/: alert.c, fcc_data.c, hostname.c, igate.c, interface_gui.c,
+	  locate_gui.c, map_geo.c, map_shp.c, maps.c, messages.c,
+	  messages_gui.c, util.c, x_spider.c: Converting more strcat()
+	  function calls to strncat().	Safer.
+
+2004-08-17 21:59  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/db.h, src/list_gui.c,
+	  src/maps.c, src/wx.c: Changed wx_snow to be inches instead of
+	  1/100 inch.  We now ghost the weather info (mostly) separately
+	  from posit info.  Got rid of "<br>" from track logs read in from
+	  findu.com.  Fixed realloc's in maps.c so that they won't cause a
+	  memory leak if they fail.  Fixed Peet Bros. complete mode
+	  decoding so that the proper wind speed is parsed.  Fix by Matt
+	  Werner, kb0kqa, for the 3-hour barometric pressure reading for
+	  Peet Bros. complete mode parsing.
+
+2004-08-17 17:17  we7u
+
+	* src/main.c: Changed formatting, added comments.  No code changes.
+
+2004-08-17 09:41  we7u
+
+	* src/wx.c: Fix for 3-hour barometer with Peet U2000 in complete
+	  mode.  Still testing to see if this is the proper fix, but so far
+	  it looks good.
+
+2004-08-16 17:51  we7u
+
+	* src/db.c: Fixing the "Move" function so that you can drag/drop
+	  objects/items that are right on top of each other.  The selection
+	  dialog will pop up so you can choose which one to move.
+
+2004-08-14 09:43  we7u
+
+	* src/main.c: Fixing object/item generation so that a space is
+	  prefixed to the comment field only in the case where multipoint
+	  polygons are present.  The space is necessary in order to parse
+	  multipoint objects properly, but is not desired for other
+	  objects/items where it would limit the extent of the comment.
+
+2004-08-12 17:26  we7u
+
+	* src/map_gnis.c: Update to GNIS search code for new pipe-delimited
+	  file format that the USGS is distributing.
+
+2004-08-12 17:25  we7u
+
+	* INSTALL, README.MAPS, help/help-English.dat: Updates to the docs
+	  to match new RINO, Server Port, and other interface changes that
+	  were done recently.
+
+2004-08-12 13:46  kd6zwr
+
+	* src/x_spider.c: Moved some declarations up to the top of
+	  Server().  Inline decls cause problems on some compilers... (like
+	  my gcc 2.96 under linux).
+
+2004-08-12 13:00  we7u
+
+	* src/map_gnis.c: Updating the GNIS map code to handle the latest
+	  pipe-delimited files from the USGS.  Still need to update the
+	  search code, but the display code appears to work fine now.
+
+2004-08-12 10:03  we7u
+
+	* src/interface.c: Added some debug code for tracking down errant
+	  raw packets in the AGWPE code.
+
+2004-08-11 13:15  we7u
+
+	* src/main.c: A bit of reformatting, plus sending to the x_spider
+	  server after raw packets have been converted to TAPR-2 format
+	  packets.
+
+2004-08-11 10:40  we7u
+
+	* src/: main.c, x_spider.c: Tweaks by Tom Russo for FreeBSD
+	  compatibility.  Thanks!
+
+2004-08-10 19:16  we7u
+
+	* src/: hostname.c, main.h, sound.c, x_spider.c: More fun with
+	  process naming.
+
+2004-08-10 12:59  we7u
+
+	* src/x_spider.c: Added a note about future plans for process
+	  naming.
+
+2004-08-10 12:51  we7u
+
+	* src/: main.c, x_spider.c, x_spider.h: Code that changes the
+	  process name in "ps" listings for the x_spider daemon and client
+	  connections.	Doesn't work on other operating systems, and
+	  doesn't work for "top" listings.
+
+2004-08-09 11:32  we7u
+
+	* src/x_spider.c: Disabling the Nagle algorithm and enabling
+	  SO_KEEPALIVE for the server port connections.
+
+2004-08-07 11:12  we7u
+
+	* src/interface.c: Modified AGWPE parsing routine and associated
+	  code.  We've now turned off "monitor" mode and turned on "raw"
+	  mode in AGWPE.  The "raw" packets get thrown into our standard
+	  KISS decoding routines, which gives us the possibility of
+	  supporting OpenTrac (a binary protocol) and digipeating on AGWPE
+	  ports in the future.	The "monitor" mode decoding has been left
+	  for now, but later on we'll probably delete it.  Also:  Added
+	  output to STDERR for the AGWPE server version and for the port
+	  descriptions.
+
+2004-08-06 12:57  we7u
+
+	* src/db.c: Change to comment.	No code changes.
+
+2004-08-06 09:29  we7u
+
+	* src/interface.c: Minor changes to comments and debug output
+	  messages.
+
+2004-08-05 13:02  we7u
+
+	* src/: db.c, festival.c, main.c, interface.c, sound.c, util.c,
+	  util.h: Re-wrote the agwpe parsing code.  It should be more
+	  bulletproof now, but still has some debug stuff in it for NWS_
+	  and NWS- messages.  Fixed a segfault caused by one of the new
+	  strncpy() functions that I switched to in util.c:spell_it_out().
+
+2004-08-04 13:04  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Changing the Modify
+	  Object/Item dialogs so that you must adopt an object/item that
+	  you don't own before you're allowed to delete it.  Adopting or
+	  Modifying someone else's object causes you to transmit it as a
+	  live object owned by you.  After that, you may delete it.  If the
+	  client that previously owned it saw your live object, it'll know
+	  that you own it and that you can delete it.  Without this
+	  adoption process, UI-View32 clients will hold on to an object
+	  that you're trying to kill.
+
+2004-08-04 12:07  we7u
+
+	* help/help-English.dat: Tweaking the note about AGWPE network
+	  authentication.  We can use that now.
+
+2004-08-04 11:54  we7u
+
+	* src/: interface.c, interface_gui.c: Fixes for AGWPE.	Network
+	  loging with authentication should work now.
+
+2004-08-03 14:21  we7u
+
+	* src/db.c: Fix to allow objects/items to get through the server
+	  port and get igated.
+
+2004-08-03 13:04  we7u
+
+	* src/util.c: Small tweak to valid_inet_name() where it is checking
+	  for the "aprsd" string.  It didn't appear to be general enough to
+	  catch all possibilities.  Now it should be.
+
+2004-08-03 12:57  we7u
+
+	* src/db.c: Changed one sizeof() to a strlen() for emergency
+	  messages.  Fixing object/item timing intervals so that if the
+	  timing slider is reduced, the max interval is reduced for already
+	  existing objects as well.
+
+2004-08-03 12:42  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing the
+	  displayed label for the object/item timing.  It's a max interval
+	  now.	The actual timing is under the control of an exponential
+	  decay algorithm.
+
+2004-07-30 16:15  we7u
+
+	* src/util.c: A fix for the csT bytes on compressed posits.  Turns
+	  out we need to send the spaces, and the compressed posit field is
+	  a fixed length.
+
+2004-07-30 15:24  we7u
+
+	* src/db.c: Adding some debug output.
+
+2004-07-29 21:06  we7u
+
+	* src/sound.c: Replacing strcpy function with safer ones.
+
+2004-07-29 21:02  we7u
+
+	* src/: list_gui.c, locate_gui.c, location_gui.c, map_tif.c,
+	  map_tiger.c, maps.c, messages_gui.c, rotated.c, track_gui.c,
+	  util.c, view_message_gui.c: Replacing strcpy functions with safer
+	  ones.
+
+2004-07-29 20:57  we7u
+
+	* src/: color.c, color.h, dbfawk.c, draw_symbols.c, fcc_data.c,
+	  geo-find.c, geocoder_gui.c, hostname.c, igate.c, interface_gui.c,
+	  lang.c: Getting rid of strcpy functions.  Replacing them with
+	  safer functions.
+
+2004-07-29 17:02  we7u
+
+	* callpass/callpass.c: Geting rid of strcpy() function call.
+
+2004-07-29 14:15  we7u
+
+	* src/db.c: Changed some strcopy() functions to xastir_snprintf()
+	  functions.
+
+2004-07-29 13:48  we7u
+
+	* src/util.c: Reformatting to match the rest of the code.  No
+	  actual code changes.
+
+2004-07-28 22:42  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.h, src/xa_config.c,
+	  src/db.c, src/main.c: Adding CWOP WX station filtering toggle.
+	  Letting Xastir display wind speed when wind course is not
+	  available.
+
+2004-07-28 12:17  we7u
+
+	* src/: db.c, igate.c, x_spider.c: Fixing message igating through
+	  x_spider connects.
+
+2004-07-28 10:48  we7u
+
+	* src/x_spider.c: Fix for FreeBSD courtesy of Tom Russo.  Thanks!
+
+2004-07-26 17:08  we7u
+
+	* src/: db.c, x_spider.c: Per-client authentication for the
+	  x_spider listening port.  Printf's for each client
+	  connect/disconnect, and each successful authentication.
+	  Non-authenticated clients can talk to each other and the server,
+	  and can receive data from the server, but can't sent anything
+	  through the server.  Igating must also be turned on to get data
+	  from authenticated clients up to the internet connections.
+
+2004-07-26 16:57  we7u
+
+	* symbols/symbols.dat: Adding the new Rocket symbol that Bob. B.
+	  just added to the spec.
+
+2004-07-26 16:55  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.d700, tnc-startup.kam,
+	  tnc-startup.kpc2, tnc-startup.kpc3, tnc-startup.paccomm,
+	  tnc-startup.pico, tnc-startup.sys, tnc-startup.thd7,
+	  tnc-startup.tnc2-ui: Reenabling the CWID stuff.  Some countries
+	  evidently require it.
+
+2004-07-26 14:02  we7u
+
+	* src/x_spider.c: Changing the authentication comments slightly for
+	  x_spider.
+
+2004-07-26 13:59  we7u
+
+	* src/x_spider.c: Adding client authentication to the x_spider
+	  server.  Clients cannot send data upstream until they
+	  authenticate.  Clients can still receive data without
+	  authenticating or send data to other connected clients.
+
+2004-07-26 13:57  we7u
+
+	* src/util.c: Removing unused define.
+
+2004-07-26 12:39  we7u
+
+	* config/tnc-startup.sys: Adding another CWID command that will
+	  turn off that feature for some TNC's.
+
+2004-07-26 12:21  we7u
+
+	* config/: tnc-startup.paccomm, tnc-startup.pico: Correct CWID
+	  commands for Paccomm TNC's.
+
+2004-07-26 11:49  we7u
+
+	* config/: tnc-startup.kpc2, tnc-startup.kpc3: Correct commands to
+	  turn off CWID.
+
+2004-07-26 11:44  we7u
+
+	* config/tnc-startup.kam: The correct command for turning of CWID.
+
+2004-07-26 11:16  we7u
+
+	* config/tnc-startup.kam: Turning off CWID.
+
+2004-07-26 10:04  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.d700, tnc-startup.kpc2,
+	  tnc-startup.kpc3, tnc-startup.paccomm, tnc-startup.pico,
+	  tnc-startup.sys, tnc-startup.thd7, tnc-startup.tnc2-ui: Adding
+	  "CWID off" command.
+
+2004-07-25 07:19  rzg
+
+	* help/help-English.dat: Updated the list of new features.
+
+2004-07-24 15:49  we7u
+
+	* src/: db.c, igate.c, interface.c, main.c, util.c: Tweaking the
+	  server stuff so that connected clients get igated through the
+	  "master" Xastir instance if igating -> Net is enabled.
+
+2004-07-23 09:57  we7u
+
+	* src/db.c: Ignore case when comparing newly received
+	  comment/status strings with previously received ones, to decide
+	  which ones to throw into the list.  With a case-sensitive
+	  compare, we were getting two instances of similar comment/status
+	  strings cluttering up our lists, when it was really the same info
+	  being presented but in a different case.
+
+2004-07-23 09:31  we7u
+
+	* src/main.c: Cygwin fixes by KJ5O.  Thanks!
+
+2004-07-22 19:31  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c, src/main.c,
+	  src/main.h, src/x_spider.c, src/xa_config.c: GUI support for the
+	  new server port.
+
+2004-07-21 18:56  we7u
+
+	* src/: Makefile.am, db.c, igate.c, interface.c, main.c, main.h,
+	  x_spider.c, x_spider.h: Adding a listener socket for multiple
+	  clients.  Currently this must be enabled by uncommenting a
+	  #define near the top of main.c.  Adds a listening socket at port
+	  2023 which allows any number of clients to connect.  Spawns a
+	  listener for each active client, kills them when the client
+	  disconnects.	All packets received or transmitted by Xastir go to
+	  these clients, all packets sent by the clients are received by
+	  Xastir and by all of the other connected clients.  "telnet
+	  localhost 2023" to test out the functionality after compiling in
+	  the server support.
+
+2004-07-21 11:38  gstueve
+
+	* src/view_message_gui.c: Add macro so someone's comment can be
+	  answered. Don't try to put too many arguments into a fixed array.
+
+2004-07-20 11:41  we7u
+
+	* src/db.c: Sorting and display of status/comment records by
+	  date/time.
+
+2004-07-20 11:14  we7u
+
+	* src/db.h: Bumping max status/comment lines per station from 10 to
+	  20.  Am testing with 50 locally to see whether bumping it up more
+	  will seriously affect memory usage.  Depending on the results,
+	  may bump these numbers up even more.
+
+2004-07-19 19:42  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/db.h, src/x_spider.c:
+	  Adding date/timestamps to Status and Comment records.
+
+2004-07-19 14:17  we7u
+
+	* src/: alert.c, alert.h, db.c, db.h: Moving a couple of define's
+	  to the .h files and increasing the number of alerts and messages
+	  that we allocate when we run out.  This hopefully will help to
+	  keep the number of large allocations down plus keep the larger
+	  allocations from ending up at the very end of the heap.  If we
+	  keep a small increment, we realloc() more often plus the large
+	  blocks will end up closer to the end of the heap, meaning we
+	  won't be able to reduce our memory impact much later.
+
+2004-07-19 09:13  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.d700, tnc-startup.kpc2,
+	  tnc-startup.kpc3, tnc-startup.paccomm, tnc-startup.sys,
+	  tnc-startup.thd7, tnc-startup.tnc2-ui: Adding "HID off" where it
+	  was missed.  Some TNC's may require slightly different commands
+	  for this.  I don't have them to test with so I'll have to wait
+	  for users to let me know the proper commands.
+
+2004-07-16 11:27  we7u
+
+	* configure.ac, src/alert.c, src/db.c, src/main.c, src/map_gdal.c,
+	  src/xastir.h: Adding support for "libgc", which is a
+	  Boehm-Demers-Weiser garbage collection library.  The advantage
+	  for us is that it can find/report memory leaks.  Install it, then
+	  add "--with-libgc" to the configure line to compile it in.  It
+	  will report memory leaks on the console.  This patch fixes two
+	  leaks found by libgc, plus changes the increments used for
+	  relloc'ing alerts and messages.
+
+2004-07-15 14:32  we7u
+
+	* src/: awk.c, db.c, dbfawk.c, igate.c, main.c, map_gdal.c,
+	  map_shp.c, maps.c, rotated.c: Protection for
+	  malloc/calloc/realloc calls.	Checking the return value for
+	  non-NULL.
+
+2004-07-15 13:01  we7u
+
+	* src/maps.c: Added some comments.
+
+2004-07-15 12:58  we7u
+
+	* src/: alert.c, db.c, igate.c, messages.c: Added/changed warning
+	  messages when realloc's fail.
+
+2004-07-15 10:26  we7u
+
+	* src/main.c: Reuven found a missing #ifdef for the RINO stuff.
+	  Thanks!
+
+2004-07-15 10:16  we7u
+
+	* src/messages.c: Reformatting to take out tabs.
+
+2004-07-15 10:09  we7u
+
+	* src/db.c: Changed some debug code that is used to test expire
+	  times for messages and stations.
+
+2004-07-15 08:29  gstueve
+
+	* src/messages.c: Make sure to look for Special groups and safety
+	  check group names.
+
+2004-07-14 14:07  we7u
+
+	* FAQ, INSTALL, acinclude.m4, configure.ac: Motif detection tweaks
+	  by Tom Russo.
+
+2004-07-14 12:48  we7u
+
+	* src/db.c: Reformatting and comment changes.  No code changes.
+
+2004-07-14 12:13  we7u
+
+	* src/db.c: Better code for drawing callsign at each trackpoint.
+	  This draws the callsign at every single point.
+
+2004-07-14 09:31  we7u
+
+	* src/main.c: An attempt to fix the menu GPS Status so that it
+	  works.  Still need an expiration mechanism for the data here.
+
+2004-07-14 09:29  we7u
+
+	* FAQ: Added an LDD note, inspired by Jack Twilley.
+
+2004-07-13 14:02  we7u
+
+	* src/db.c: Comment changes.
+
+2004-07-13 12:21  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/xa_config.c: Added a new button to the Station Filter dialog:
+	  "Label All Points".	Doesn't actually label _ALL_ trackpoints,
+	  but labels most of them with the callsign.  This is helpful to
+	  identify whose tracks belong to who.
+
+2004-07-13 07:54  we7u
+
+	* src/: alert.c, db.c, db.h, list_gui.c, main.c, main.h,
+	  messages.c, messages.h, messages_gui.c, track_gui.c, util.c:
+	  Combined MAX_CALL and MAX_CALLSIGN defines into MAX_CALLSIGN,
+	  reduced the size of it from 20 chars.  Added MAX_COMMENT_LINES
+	  and MAX_STATUS_LINES, currently set to 10 each, which limit how
+	  many unique status/comment lines are saved per station.  Added
+	  MAX_TACTICAL_CALL in order to separate that parameter from
+	  MAX_CALLSIGN, as the tactical call needs to be longer but didn't
+	  want to waste the memory for all callsigns by making them all
+	  long.  Changed the alert memory allocation from 100 alert blocks
+	  to 25 alert blocks (finer grained malloc's).	Added more
+	  comments.
+
+2004-07-09 14:11  we7u
+
+	* src/main.c: Throwing Base-91 Compressed APRS packets into our
+	  decoding instead of standard APRS packets.  This keeps the
+	  resolution that the RINO's are capable of.  Doesn't affect how
+	  the Object packets are transmitted: For that setting refer to the
+	  toggle on the File->Configure->Defaults dialog.
+
+2004-07-09 10:32  we7u
+
+	* src/main.c: Better timestamp for RINO-derived APRS Objects.
+	  Issues:  currently sends localtime instead of UTC, plus the
+	  gpstrans files we're getting the timestamp from appear to have
+	  the download time/date instead of the waypoint creation
+	  time/date.  These need to be fixed at some point.
+
+2004-07-09 08:19  rzg
+
+	* src/alert.c: Fixed read of unitialized data according to
+	  valgrind.
+
+2004-07-08 16:34  rzg
+
+	* src/main.c: Fixed comparisions of unitialized variables, and
+	  another small bug.
+
+2004-07-08 14:49  we7u
+
+	* src/main.c: Initializing some variables as they are defined.
+
+2004-07-08 14:49  we7u
+
+	* src/map_geo.c: Added some comments.
+
+2004-07-08 14:48  we7u
+
+	* src/interface.c: Reformatting.  No code changes.
+
+2004-07-08 14:48  we7u
+
+	* src/draw_symbols.c: Initializing a variable as it is defined.
+
+2004-07-08 12:38  we7u
+
+	* src/main.c: Commenting out RINO debug fprintf() statements.
+
+2004-07-08 12:07  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/main.h,
+	  src/xa_config.c: Implemented auto-download capability for the
+	  RINO waypoints.  A new slider added to the
+	  File->Configure->Timing dialog.  A setting of 0 disables the
+	  function.  Anything else invokes GPSMan at the interval selected,
+	  downloading all waypoints from a RINO, and creating APRS objects
+	  out of those that have "APRS" as the beginning four characters of
+	  the waypoint name.
+
+2004-07-08 08:50  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Initial support for
+	  Garmin RINO "contact" waypoints.  A new entry on the Interface
+	  menu allows snagging waypoints from a RINO.  Any that begin with
+	  the letters "APRS" will have those four letters removed and then
+	  a standard APRS object is created from them and starts
+	  transmitting out from Xastir over APRS.  We're using
+	  non-compressed Objects so that they will be visible on Kenwood
+	  displays, at the expense of throwing away some of the position
+	  resolution.  The menu link-in may change, as we'll eventually go
+	  to an automatic poll scheme of the RINO instead of this manual
+	  operation.  Currently requires a connected RINO on a serial port
+	  and GPSMan support compiled into Xastir.
+
+2004-07-07 11:15  we7u
+
+	* INSTALL: Tweaked the instructions for GDAL ever so slightly.
+
+2004-07-07 09:30  we7u
+
+	* configure.ac: Added a comment from Tom Russo.  We need to make
+	  some changes to the Motif detect so that we're assured we have
+	  working headers/libraries before we get to the compile stage.
+
+2004-07-06 15:29  we7u
+
+	* configure.ac: Replacing our Motif search code with better code
+	  from the "vim" project.  This code is purported to find the most
+	  recent variant of Motif on the system and use that, if there's
+	  more than one on the system.	It also looks quite a few more
+	  places for the libraries/headers than our old code.
+
+2004-07-06 11:23  we7u
+
+	* src/main.c: Added comments.
+
+2004-07-02 13:19  we7u
+
+	* src/locate_gui.c: Fixed one printf format that had too many
+	  format specifiers in it.
+
+2004-07-01 17:20  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/gps.c, src/gps.h, src/main.c:
+	  Adding GPS Quality info to the command line and to a new
+	  View->GPS Status option.
+
+2004-07-01 14:33  we7u
+
+	* src/xa_config.c: Setting more reasonable lower defaults for a
+	  couple of timing parameters.
+
+2004-07-01 14:16  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/locate_gui.c: FCC/RAC callsign
+	  lookup which doesn't depend on stations being on the screen.
+
+2004-07-01 09:26  we7u
+
+	* src/bulletin_gui.c: Fix by Tom Russo for FreeBSD.
+
+2004-06-30 22:00  we7u
+
+	* src/maps.c: Converting from a strcpy() to a memmove() due to
+	  another bug that Reuven found.  strcpy() cannot handle
+	  overlapping strings, while memmove() can.
+
+2004-06-30 21:16  we7u
+
+	* src/main.c: Fixing memory leaks.
+
+2004-06-30 21:13  we7u
+
+	* src/db.c: Fixing memory leaks.
+
+2004-06-30 21:09  we7u
+
+	* src/: messages_gui.c, track_gui.c, view_message_gui.c: Fixing
+	  memory leaks.
+
+2004-06-30 21:05  we7u
+
+	* src/: list_gui.c, locate_gui.c, location_gui.c, messages.c:
+	  Fixing memory leaks.
+
+2004-06-30 21:00  we7u
+
+	* src/interface_gui.c: Fixing memory leaks.
+
+2004-06-30 20:55  we7u
+
+	* src/: bulletin_gui.c, geocoder_gui.c: Fixing memory leaks.
+
+2004-06-30 14:00  we7u
+
+	* src/db.c: Fixing a bug Reuven found:	Doing an "if" based on the
+	  value of an uninitialized variable.
+
+2004-06-30 13:53  we7u
+
+	* src/db.c: Fixing an indexing bug that Reuven found (via
+	  "valgrind").	We can't go past index 0 if we've assigned '\0' to
+	  a string.
+
+2004-06-30 13:36  rzg
+
+	* src/: color.c, dbfawk.c, main.c: Minor memory leak fixes.
+
+2004-06-30 13:32  we7u
+
+	* src/list_gui.c: Fixing a memory leak that Reuven discovered.
+
+2004-06-30 12:43  we7u
+
+	* src/db.c: Fixing a bug found by Reuven in the GLL decode routine.
+
+2004-06-30 10:54  we7u
+
+	* src/: db.h, db.c: Moved multipoints into a separate record,
+	  allocating only when needed.	This provides additional memory
+	  savings over the tweaks that went in yesterday, with no loss in
+	  speed/efficiency.
+
+2004-06-29 20:45  we7u
+
+	* src/: db.c, db.h: Tweaks to significantly reduce memory usage.
+
+2004-06-29 12:42  we7u
+
+	* src/wx.c: Fixing all the 2^16 constants.  Ten of them were
+	  incorrect.
+
+2004-06-29 11:41  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c: Added language
+	  strings for CAD objects and tactical calls.
+
+2004-06-28 09:56  we7u
+
+	* src/main.c: Added a comment.	No code changes.
+
+2004-06-27 17:15  rzg
+
+	* src/main.c: Fixed array size error, to fix stack smashing issue.
+
+2004-06-25 16:24  we7u
+
+	* config/: Makefile.am, tnc-startup.tnc2-ui, tnc-stop.tnc2-ui:
+	  Start/stop TNC files contributed by Alessio Sangalli, IW2NYD, for
+	  the TNC2-UI TNC used in Europe.
+
+2004-06-24 14:23  we7u
+
+	* FAQ: Added a bit about ImageMagick and color-depth.
+
+2004-06-24 13:49  we7u
+
+	* src/: db.c, main.c: Adding some debug stuff to the expire code.
+	  Tweaking the status line station readout so it will reflect the
+	  current number of stations in all cases.
+
+2004-06-24 13:08  we7u
+
+	* src/main.c: Erasing box after Measure operation.
+
+2004-06-24 13:00  we7u
+
+	* src/: db.c, main.c: Removing tac-call capability for
+	  objects/items.  The saving/restoring of these on startup is a
+	  problem.  Perhaps we can add the functionality back in later for
+	  these, but probably only if we own the objects/items ourselves.
+	  Even then, deleting the objects/items needs to be looked at
+	  carefully.
+
+2004-06-24 12:29  we7u
+
+	* src/: db.c, db.h, main.c, util.c: Fix for Move function.  Also
+	  changed tactical call so that it takes up less memory.
+
+2004-06-23 16:19  we7u
+
+	* src/main.c: Rearranging the Station menu slightly so that it is
+	  harder to delete all stations by mistake.  It's now at the bottom
+	  of the menu.
+
+2004-06-23 12:54  we7u
+
+	* src/main.c: Adding a define, commented out currently, which sets
+	  all flags properly for a 640x480 touch-screen.  Has no effect
+	  unless comments are removed.
+
+2004-06-23 12:25  we7u
+
+	* src/: interface.c, main.c: Backing out the changes that were just
+	  made for the Serial TNC Aux GPS interface.  Turns out the code
+	  was right all along.	The user that is experiencing difficulties
+	  with a KAM+ must have some other sort of problem.
+
+2004-06-23 11:10  we7u
+
+	* src/interface.c: Serial TNC AUX GPS interfaces weren't parsing
+	  GPS data out of the datastream.  This should fix it.	More
+	  testing to come.
+
+2004-06-23 11:05  we7u
+
+	* src/main.c: Comment changes.
+
+2004-06-23 10:30  we7u
+
+	* src/main.c: Changing one debug printf()
+
+2004-06-22 13:44  we7u
+
+	* src/main.c: Fixing the code so that the SWAP_MOUSE_BUTTONS #ifdef
+	  works properly again.
+
+2004-06-22 12:36  we7u
+
+	* src/db.c: Adding tactical call button to Station Info dialog.
+	  This is required for cases where multiple calls are near the
+	  pointer, else we can't assign tactical calls.
+
+2004-06-22 10:41  we7u
+
+	* src/db.c: Fixed a memory leak in the expire routines, where
+	  status data was not getting free'd.
+
+2004-06-22 10:20  we7u
+
+	* src/db.c: Fixing bug in expire code introduced by newly-added
+	  tactical call code.
+
+2004-06-21 14:10  we7u
+
+	* src/: db.c, main.c, main.h, xa_config.c: Adding a toggle flag for
+	  selecting only stations with tactical callsigns.
+
+2004-06-21 11:03  we7u
+
+	* src/: db.c, util.c: Restoring of tactical calls from file when
+	  Xastir starts up or after all stations are cleared.  Dummy
+	  records are created which then get coupled to the real info when
+	  the station gets heard on the air.  Also tweaked the expire code
+	  so that stations with tac-calls don't get expired.  They should
+	  still get cleared from the screen, but the station and all it's
+	  original data, including tac-call, should appear again when the
+	  station re-appears on frequency.  That new addition to the expire
+	  code is not tested fully yet.
+
+2004-06-21 09:08  we7u
+
+	* src/: db.c, main.c, util.c, util.h: Logging of tactical calls to
+	  disk.  Added Clear Tactical Calls and Clear Tactical History menu
+	  options.  Restore of tactical calls from disk at startup is not
+	  coded yet.
+
+2004-06-18 22:24  we7u
+
+	* src/db.c: Adding the callsign or the object/item name as a label
+	  in the Assign Tactical Call dialog, so that we know what we're
+	  renaming.
+
+2004-06-18 13:32  we7u
+
+	* src/db.c: Instant update when changing a tactical call.
+
+2004-06-18 13:01  we7u
+
+	* src/db.c: Minor tweaks to the tactical call stuff.  Allows 19
+	  chars now for the name.
+
+2004-06-18 12:28  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/db.h, src/main.c:
+	  Implementing Tactical Calls.	Added to the right-click mouse
+	  menu.
+
+2004-06-18 10:09  we7u
+
+	* src/interface.c: Comment changes.
+
+2004-06-18 10:07  we7u
+
+	* src/interface.c: Mostly comment changes.  Added "Counts" to the
+	  generic measurements table ( units[] ).
+
+2004-06-18 08:46  we7u
+
+	* src/interface.c: Changing some comments.
+
+2004-06-18 08:38  we7u
+
+	* src/interface.c: Minor comment change.
+
+2004-06-18 08:35  we7u
+
+	* src/interface.c: Minor tweaks to the OpenTrac classification
+	  messages.
+
+2004-06-18 08:24  we7u
+
+	* src/interface.c: Adding in catch-all clauses for OpenTrac
+	  elements that are new or not-yet-implemented.
+
+2004-06-18 08:03  we7u
+
+	* src/interface.c: Putting in more dummy routines for the
+	  unimplemented OpenTrac element decoding.
+
+2004-06-18 07:30  we7u
+
+	* src/main.c: Fixing the AUX-TNC type so that it actually tries to
+	  parse the GPS sentences.  It didn't appear to do that with the
+	  earlier code, while other types of interfaces did parse them.
+
+2004-06-18 06:51  we7u
+
+	* src/interface.c: Adding parsing for more OpenTrac elements.  Not
+	  much is done with the data yet, but the placeholders are there
+	  now.	Added better reporting for various classes of unknown
+	  OpenTrac element types also.
+
+2004-06-18 00:08  we7u
+
+	* src/interface.c: Added some comments.
+
+2004-06-17 16:33  we7u
+
+	* src/interface.c: More very minor OpenTrac tweaks.
+
+2004-06-17 15:46  we7u
+
+	* src/interface.c: Minor tweaks so that the OpenTrac comment field
+	  gets cleared before we process each piece, plus adding a space
+	  before the displayname part of the OpenTrac comment.
+
+2004-06-17 15:11  we7u
+
+	* FAQ: Added another question/answer about problems caused by the
+	  LANG environment variable setting.
+
+2004-06-17 12:28  we7u
+
+	* src/interface.c: Limiting the comment field on the converted
+	  OpenTrac packets to 40 chars, which is the max for a Base-91
+	  compressed APRS packet.
+
+2004-06-17 12:18  we7u
+
+	* src/interface.c: Converting strcat() to strncat() functions in
+	  the OpenTrac routines.
+
+2004-06-17 12:03  we7u
+
+	* src/interface.c: Changed some comments.  No code changes.
+
+2004-06-17 11:10  we7u
+
+	* src/interface.c: Higher-resolution OpenTrac positioning.  We now
+	  convert to Base-91 Compressed APRS packets before throwing them
+	  into our standard decoding.  This should give us 1/100 sec
+	  lat/long resolution, instead of the 60' resolution we had before.
+	  This new code is untested as of yet.
+
+2004-06-17 10:46  we7u
+
+	* src/: util.c, xastir.h: Adding a higher-resolution lat/long
+	  format, so we can make better use of OpenTrac resolution.
+
+2004-06-17 08:06  we7u
+
+	* src/interface.c: Changing from issuing the "conv" command to
+	  issuing the "k" command to get the TNC into converse mode.  One
+	  european TNC doesn't implement the "conv" command.
+
+2004-06-16 16:27  we7u
+
+	* config/: tnc-startup.d700, tnc-startup.thd7: Adding TXD settings
+	  to the Kenwood startup files.
+
+2004-06-14 23:23  we7u
+
+	* src/interface.c: Added a comment.
+
+2004-06-14 22:31  we7u
+
+	* config/: Makefile.am, tnc-startup.kpc2: Initial kpc2 startup file
+	  by Tom Russo.  Thanks!
+
+2004-06-14 20:10  we7u
+
+	* src/util.c: Changing one debug fprintf.
+
+2004-06-14 13:40  we7u
+
+	* src/interface.c: Removing an error messaging having to do with
+	  the tnc-start/stop META tag.	This error message gets thrown out
+	  at odd times if you happen to have META in a comment in those
+	  file.  Not needed.
+
+2004-06-14 13:14  we7u
+
+	* README.win32: Liblcms is now a Cygwin package, so changing the
+	  instructions to match.  Thanks to Henk de Groot for this info!
+
+2004-06-14 12:53  we7u
+
+	* config/Makefile.am: Adding a new stop file for the TH-D7A.
+
+2004-06-14 12:49  we7u
+
+	* config/: tnc-stop.thd7, tnc-startup.thd7: Changes to the
+	  tnc-startup.d7a startup file by Henk de Groot, PE1DNN.  Also a
+	  new tnc-stop.d7a file from him.  Thanks!
+
+2004-06-11 12:45  we7u
+
+	* config/Makefile.am: Adding the new D700 start/stop files.
+
+2004-06-11 12:44  we7u
+
+	* config/: tnc-startup.d700, tnc-stop.d700: Adding files that David
+	  Flood, KD7MYC, came up with to start/top a Kenwood D700A and put
+	  it into the proper modes in each case.
+
+2004-06-10 19:26  we7u
+
+	* src/interface.c: Tweaks to allow more control in the
+	  tnc-startup.sys file.  Adds a pause and a no-ctrl-C capability.
+
+2004-06-10 16:51  we7u
+
+	* Davis/src/db2APRS.c: Memory leak update by Bruce Bennett, KB8ROP.
+	  Thanks!
+
+2004-06-08 08:37  we7u
+
+	* config/language-Dutch.sys: Updates by Han Sytsma.  Thanks!
+
+2004-06-07 14:13  we7u
+
+	* configure.ac: Bumping the development rev. up to 1.3.3.
+
+2004-06-07 13:01  we7u
+
+	* INSTALL: A note about adding a flag to the configure command-line
+	  to help it find the Motif include files.
+
+2004-06-07 11:11  we7u
+
+	* src/alert.c: Fixing string overflow problem triggered by extreme
+	  number of compressed alerts.
+
+2004-06-04 15:47  we7u
+
+	* src/: rac_data.c, rac_data.h: Fixing a possible buffer overflow
+	  problem that Tom Russo found.  Thanks!
+
+2004-06-04 13:39  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.paccomm, tnc-startup.pico,
+	  tnc-startup.sys: More PID filtering stuff.
+
+2004-06-04 12:42  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.kam, tnc-startup.kpc3,
+	  tnc-startup.paccomm, tnc-startup.pico, tnc-startup.sys: Adding
+	  PID filtering so that only 0xf0 PID's make it through in converse
+	  mode (APRS packets).
+
+2004-06-04 10:36  we7u
+
+	* src/fcc_data.c: Fix by Tom Russo.
+
+2004-06-04 10:20  we7u
+
+	* config/tnc-startup.kam: Adding PID OFF.
+
+2004-06-04 09:53  we7u
+
+	* config/tnc-startup.kpc3: Adding "PID off" so that other protocols
+	  don't show up in converse/monitor mode.
+
+2004-06-03 22:49  we7u
+
+	* src/main.c: Zoom-in box tweaks.  These prevent the vectors from
+	  being drawn over again if a screen update has happened.  Keeps
+	  extra line segments from appearing while doing the zoom-in box
+	  mouse operation.
+
+2004-06-03 16:01  we7u
+
+	* config/language-Dutch.sys: Updates by Han Sytsma, PE1FAM.
+	  Thanks!
+
+2004-06-03 15:00  francais1
+
+	* config/language-French.sys: Updated somewhat
+
+2004-06-03 14:36  we7u
+
+	* src/main.c: Widening the zoom-in line width slightly.  Looks very
+	  nice now/more visible.
+
+2004-06-03 14:11  we7u
+
+	* config/language-Italian.sys: Updates by Alessandro Frigeri,
+	  IK0YUP.  Thanks!
+
+2004-06-03 13:47  we7u
+
+	* config/language-German.sys: Updates by Rolf Bleher, DK7IN.
+	  Thanks!
+
+2004-06-03 09:49  we7u
+
+	* src/main.c: Better zoom-in box operation.  Much better!
+
+2004-06-02 14:28  we7u
+
+	* src/main.c: Added another variable which we check against in
+	  order to NOT draw the zoom-in box when we're in the menus.
+
+2004-06-02 12:43  we7u
+
+	* src/map_gdal.c: Fixing the out-of-bounds check after the
+	  coordinate conversion.
+
+2004-06-02 11:19  we7u
+
+	* src/main.c: Adding a visible selection outline to the zoom-in
+	  function.  The outline updates once per second currently and
+	  doesn't clean up after itself, but they disappear fairly quickly
+	  anyway.
+
+2004-06-02 09:41  we7u
+
+	* configure.ac: Adding Davis stuff.
+
+2004-06-02 09:40  we7u
+
+	* Makefile.am: Adding Davis directory.
+
+2004-06-02 09:38  we7u
+
+	* Davis/src/: Makefile.am, db2APRS.c, defs.h: Moved these from
+	  xastir/src/Davis/src to xastir/Davis/src
+
+2004-06-02 09:37  we7u
+
+	* Davis/: AUTHORS, COPYING, ChangeLog, INSTALL, Makefile.am, NEWS,
+	  README, bootstrap.sh, configure.ac: Moved these from
+	  xastir/src/Davis to xastir/Davis
+
+2004-06-01 20:28  we7u
+
+	* src/Makefile.am: Removing Davis from the list of subdirectories
+	  for now.
+
+2004-06-01 15:49  we7u
+
+	* src/Makefile.am: Tweaks to include the Davis code in the released
+	  tgz files.
+
+2004-05-30 22:34  we7u
+
+	* src/: dbfawk.c, map_shp.c: More Tom Russo fixes, also removing
+	  some debug code that I added earlier.
+
+2004-05-30 18:28  rzg
+
+	* INSTALL, README.MAPS, help/help-English.dat: Updates to all the
+	  docs, some more README.MAPS cleanups/updates.
+
+2004-05-28 17:45  we7u
+
+	* src/map_shp.c: Correcting what I submitted earlier to match what
+	  Tom Russo sent me.  My oops.
+
+2004-05-28 16:02  we7u
+
+	* src/: alert.c, map_shp.c: Tom Russo's tweak to allow red flag
+	  alerts in their current transmitted form to be displayed by
+	  Xastir.  Thanks!
+
+2004-05-28 15:44  we7u
+
+	* symbols/Makefile.am: Adding new red_flag.xbm file to the mix.
+
+2004-05-28 15:43  we7u
+
+	* symbols/red_flag.xbm: New warning by Tom Russo.
+
+2004-05-28 12:23  we7u
+
+	* config/: nwsc_ddmmyy.dbfawk, nwsfz_ddmmyy.dbfawk,
+	  nwsmzddmmyy.dbfawk, nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk,
+	  nwsz_ddmmyy.dbfawk: More tweaks from Tom Russo.  This one is
+	  intended to supply a "BOGUS" default value for the key if the
+	  shapefile has NULL entries.
+
+2004-05-28 12:16  we7u
+
+	* src/main.c: Mostly comment changes.  Also removing the exit when
+	  Festival can't be connected to (which I don't think worked
+	  anyway).
+
+2004-05-28 12:03  we7u
+
+	* src/map_shp.c: Changed an exit() to a return() for the case where
+	  dbfawk fails.
+
+2004-05-28 12:03  we7u
+
+	* src/: hostname.c, sound.c: Added some comments.
+
+2004-05-28 11:34  we7u
+
+	* src/map_shp.c: Comment change.
+
+2004-05-28 11:09  we7u
+
+	* src/map_shp.c: Here's a fix for the missing weather alert
+	  problem, when using dbfawk.  Turns out the latest zone file from
+	  NOAA has an unexpected mostly-NULL entry for shape 144, which
+	  caused our compare to match on that shape in all cases.  It's
+	  definitely an incorrect shapefile entry, but it caused a problem
+	  in our code as well which needed to be fixed.  We now check again
+	  using the title length if we got a match due to the key length
+	  being 0.
+
+2004-05-28 07:48  we7u
+
+	* config/: nwsc_ddmmyy.dbfawk, nwsfz_ddmmyy.dbfawk,
+	  nwsmzddmmyy.dbfawk, nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk,
+	  nwsz_ddmmyy.dbfawk: Tweaks by Tom Russo to reset fill_style in
+	  each dbfawk file.  Thanks!
+
+2004-05-26 19:11  we7u
+
+	* src/: awk.c, dbfawk.c, map_shp.c: More of Tom Russo's memory leak
+	  fixes.  Thanks!
+
+2004-05-26 14:14  we7u
+
+	* src/: awk.c, dbfawk.c, map_shp.c: Minor comment changes.  Changed
+	  to correct cleanup routine for one type of object.  More memory
+	  leak fixes.
+
+2004-05-26 12:15  we7u
+
+	* src/map_shp.c: Adding some more "free" stuff before yet another
+	  return.
+
+2004-05-26 09:11  we7u
+
+	* src/xa_config.c: Changing default for weather alert updates to 60
+	  seconds instead of 30.
+
+2004-05-25 22:57  we7u
+
+	* src/awk.c: Closing another small memory leak.
+
+2004-05-25 21:42  we7u
+
+	* src/map_shp.c: Handling another error condition.
+
+2004-05-25 21:37  we7u
+
+	* src/dbfawk.c: More comments.	Handled a few error conditions.
+	  Perhaps closed a few minor memory leaks.
+
+2004-05-25 16:17  we7u
+
+	* src/map_shp.c: More comments.
+
+2004-05-25 13:45  we7u
+
+	* src/: awk.c, map_shp.c: More comments.
+
+2004-05-25 13:01  we7u
+
+	* src/: dbfawk.c, awk.c: Added some comments.
+
+2004-05-25 13:00  we7u
+
+	* src/rotated.c: Added some comments regarding malloc's/free's.
+
+2004-05-25 00:30  we7u
+
+	* src/dbfawk.c: More comments.
+
+2004-05-24 23:53  we7u
+
+	* src/dbfawk.c: Moving some free() code to the proper places.
+
+2004-05-24 23:08  we7u
+
+	* src/map_shp.c: More comments.
+
+2004-05-24 21:34  we7u
+
+	* src/dbfawk.c: Adding more comments.
+
+2004-05-24 21:18  we7u
+
+	* src/: dbfawk.c, map_shp.c: Adding comments/printf's regarding
+	  allocation/deallocation of memory.
+
+2004-05-24 21:11  we7u
+
+	* src/: awk.c, testawk.c: Adding comments regarding allocations and
+	  free'ing of memory.
+
+2004-05-24 18:55  we7u
+
+	* src/: dbfawk.c, map_shp.c: More memory leak fixes for dbfawk.
+	  Getting better!
+
+2004-05-24 14:53  we7u
+
+	* src/: map_shp.c, dbfawk.c: Adding some free() statements to exit
+	  points in map_shp.c, to de-allocate memory that was allocated
+	  earlier in the function via dbfawk calls.
+
+2004-05-24 11:02  gstueve
+
+	* src/main.c: Actually maintain count of visible alerts on screen
+	  for increasing alert count.
+
+2004-05-24 10:51  we7u
+
+	* FAQ: Added a few more notes about what do do for "missing Motif"
+	  messages.
+
+2004-05-23 17:01  n2ygk
+
+	* src/: dbfawk.c, dbfawk.h, map_shp.c: Tom's "bloatpatch" for
+	  memory leak.
+
+2004-05-22 18:54  rzg
+
+	* README.MAPS: Some formatting fixes, updated URL for quad index
+	  shapefile.
+
+2004-05-22 12:42  we7u
+
+	* acinclude.m4, configure.ac: Mods by Tom Russo to allow the
+	  --without flags to work properly for festival and gpsman.
+	  Thanks!
+
+2004-05-21 11:49  jtwilley
+
+	* configure.ac: applied Tom Russo's emergency patch - will examine
+	  later
+
+2004-05-20 14:46  we7u
+
+	* src/map_shp.c: Closing a small memory leak in the dbfawk stuff.
+	  More to come.  Thanks to Tom Russo for finding this one.
+
+2004-05-19 16:23  we7u
+
+	* src/main.c: Fixing the local station so that compressed posits
+	  turn off ambiguity.
+
+2004-05-19 16:08  we7u
+
+	* INSTALL, README.MAPS, configure.ac, xastir.spec.in: Making dbfawk
+	  be compiled in by default.  Added --without-* flags for all of
+	  the optional libraries so that they can be disabled.	Made
+	  geotiff compilation dependent on libproj being present.  Made
+	  dbfawk compilation dependent on shapelib and pcre being present.
+	  The tests for the libraries are skipped entirely if the proper
+	  --without-* flag is passed to configure.
+
+2004-05-19 09:05  we7u
+
+	* config/Makefile.am: Adding the fire alert dbfawk file to the
+	  distribution.
+
+2004-05-19 09:04  we7u
+
+	* config/nwsfz_ddmmyy.dbfawk: Adding a dbfawk file for Fire weather
+	  alerts.
+
+2004-05-19 08:55  we7u
+
+	* config/nwsz_ddmmyy.dbfawk: Latest dbfawk file for weather zone
+	  shapefile.
+
+2004-05-18 13:28  we7u
+
+	* config/nwsz_ddmmyy.dbfawk: Added a commented line which works
+	  with fire zone files.  Can't add it in yet as it appears to be
+	  mutually exclusive with the other line before it which works for
+	  regular zone files.
+
+2004-05-18 13:26  we7u
+
+	* src/map_shp.c: Added a comment.
+
+2004-05-18 12:54  we7u
+
+	* README.MAPS, src/map_shp.c, src/maps.c: Adding support for fire
+	  zone maps.  Works now for non-dbfawk compiles, but need to get
+	  dbfawk working with them as well.  The WXSVR should eventually
+	  start sending these types of alerts to us on firenet.
+
+2004-05-18 09:42  we7u
+
+	* src/db.c: Had to move the variable declarations up in the code
+	  block, else it fails compile on FreeBSD.  Thanks to Tom Russo for
+	  this fix.
+
+2004-05-17 13:06  we7u
+
+	* src/db.c: A small tweak to make the FCC/RAC lookup for
+	  objects/items look at the FROM callsign instead of the
+	  object/item names.  Now we can look up who is sending the objects
+	  in our database.
+
+2004-05-17 12:44  we7u
+
+	* src/db.c: Fixing the weather alert by "Station Info" lookups so
+	  that it works for more objects from the weather server.
+
+2004-05-17 11:45  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/wx.h, src/wx_gui.c:
+	  Adding the capability to finger the WXSVR if an object/item and
+	  has "WXSVR" in the path.  This is from a new button "Fetch NWS
+	  Alert" in the Station Info dialog.  It takes the place of the
+	  FCC/RAC button if the above conditions are met.
+
+2004-05-13 10:17  we7u
+
+	* configure.ac: Moving the ImageMagick check so that it is the
+	  absolute last check, so that it doesn't mess up the GDAL check
+	  either.  Added comments stating that the IM check should stay as
+	  the last check.
+
+2004-05-13 09:51  we7u
+
+	* configure.ac: Moving the ImageMagick test to later in the
+	  configuration.  It appears to mess up the tests for other
+	  libraries if it fails.  Now only the GDAL test is below it.
+
+2004-05-12 13:49  we7u
+
+	* src/alert.c: Additional comments.
+
+2004-05-12 12:33  we7u
+
+	* scripts/overlay.pl: Correcting the math for lat/long.
+
+2004-05-12 11:56  we7u
+
+	* src/interface.c: Making sure that the AGWPE path is upper-case.
+
+2004-05-12 11:45  we7u
+
+	* src/interface.c: Fixing a bug in AGWPE path for objects/items.
+	  This bug was caused by a different use of variables between the
+	  output_aprs_data() and output_my_aprs_data() functions, and then
+	  copying code from one to the other without changing the
+	  variables.  Variable names are now more common between them, so
+	  this problem should be less likely to occur in the future.
+
+2004-05-12 09:44  we7u
+
+	* scripts/overlay.pl: Changes to comments.
+
+2004-05-12 09:16  we7u
+
+	* scripts/: overlay.pl, Makefile.am: Adding overlay.pl, which
+	  creates either Xastir log file format or Xastir object.log format
+	  files from CSV files.  Used to create object overlays (actually
+	  APRS Items in this case) out of spreadsheet data.
+
+2004-05-11 10:07  we7u
+
+	* README.win32: Added a comment about an error caused by line-wrap
+	  in the Shapelib Makefile.
+
+2004-05-10 13:51  we7u
+
+	* src/: main.h, main.c: Adding #ifdef's for "OLD_PTHREADS", which
+	  knock out the SIGUSR1 handler if "OLD_PTHREADS" is defined in
+	  "main.h".
+
+2004-05-10 12:33  we7u
+
+	* src/db.c: Proper code for randomizing the object/item transmit
+	  times a bit.
+
+2004-05-10 09:39  we7u
+
+	* scripts/Makefile.am: Adding a few of the newer scripts to the
+	  install portion.
+
+2004-05-08 19:54  we7u
+
+	* src/: main.c, db.c: Tweaking the object/item timing to make sure
+	  that any changes to an object cause the object to immediately go
+	  to the initial state of the decay algorithm.
+
+2004-05-08 18:55  we7u
+
+	* src/db.c: Fixing the random number modulus operations for
+	  transmitting objects/items.  It appears however that the rand()
+	  and random() functions are broken on this system, always
+	  returning 0.
+
+2004-05-07 14:09  we7u
+
+	* src/db.c: Reducing the randomizing of object/item TX times from
+	  33% of interval to 20% of interval.
+
+2004-05-07 13:45  we7u
+
+	* src/db.c: Randomizing object/item transmit a bit so that they
+	  don't get transmitted together when restarting with active
+	  objects/items.  This causes them to diverse fairly well after
+	  about the third transmit iteration.
+
+2004-05-07 13:21  we7u
+
+	* src/util.c: Adding some comments.
+
+2004-05-07 11:02  we7u
+
+	* src/db.c: Fix for objects/items:  If we're using the name of one
+	  that has already been killed, we now delete the old record
+	  completely before creating the new one.  This keeps us from
+	  drawing tracklines from one to the other or keeping info that
+	  doesn't apply to the new object/item.
+
+2004-05-07 09:19  we7u
+
+	* src/util.c: Fixing the logging of objects/items.  There were
+	  problems with removing spaces from Items which made them not
+	  found in the search, and problems with comments in front of lines
+	  in the log file.
+
+2004-05-07 09:16  we7u
+
+	* src/: db.c, db.h: Comment changes.  No code changes.
+
+2004-05-06 16:27  we7u
+
+	* src/messages.c: Reducing the initial time interval between
+	  transmitted messages from 15 to 7 seconds.
+
+2004-05-06 16:19  we7u
+
+	* src/: db.h, messages.c: Minor comment changes.
+
+2004-05-06 14:40  we7u
+
+	* src/: db.h, db.c, main.c: Implementing the decaying algorithm for
+	  timing of object/item transmits, similar to how Bob Bruninga does
+	  it in aprsDOS.  Also added a segfault fix for moving Items (same
+	  fix as done earlier for moving Objects).
+
+2004-05-04 10:59  we7u
+
+	* INSTALL: Bumping rev. numbers for some of the optional libraries.
+
+2004-05-03 11:58  we7u
+
+	* README.MAPS: Added some geodesy links.
+
+2004-04-30 13:27  we7u
+
+	* INSTALL: Adding more URL's to lists of internet servers.
+
+2004-04-29 15:30  we7u
+
+	* FAQ: Adding a section describing the fixes for the CVS hostname
+	  change at SourceForge.
+
+2004-04-28 14:43  shadow
+
+	* configure.ac: Test for linker support of -Wl,--no-keep-memory
+	  rather than assuming it's safe everywhere; MacOS 10.3.x doesn't
+	  support it.
+
+2004-04-27 09:23  we7u
+
+	* INSTALL: Added instructions for connecting to an internet server
+	  plus a pointer to the current list of servers.
+
+2004-04-26 12:31  we7u
+
+	* README.win32: Additions by Henk de Groot.  Thanks!
+
+2004-04-26 11:14  we7u
+
+	* INSTALL, README.win32: Shapelib links updates, thanks to Wes
+	  Johnston for pointing this out.
+
+2004-04-23 10:46  we7u
+
+	* src/interface.c: OpenTrac patch by J. Lance Cotton, KJ5O.
+	  Thanks!
+
+2004-04-23 10:35  we7u
+
+	* src/igate.c: Refusing to gate OpenTrac packets (which have been
+	  converted to APRS-format by Xastir) to/from RF or the INET.
+
+2004-04-21 16:01  we7u
+
+	* src/main.c: Working version of the new Center & Zoom mouse menu
+	  function.
+
+2004-04-21 14:59  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Starting to add a new
+	  mouse menu entry:  "Center & Zoom".  Non-functional so far but
+	  won't take much more work to finish it.
+
+2004-04-15 14:19  we7u
+
+	* README.win32: An update to the link-step memory-hog note.
+
+2004-04-15 10:12  we7u
+
+	* README.win32: Added a note about the link-stage being very memory
+	  hungry/taking a lot of time to complete on Cygwin.
+
+2004-04-14 14:31  we7u
+
+	* configure.ac: Adding the no-keep-memory flag to LDFLAGS which
+	  makes the link stage on Cygwin much faster.
+
+2004-04-14 10:12  we7u
+
+	* README.win32: Specifying a minimum set of xorg packages necessary
+	  for installing the X11 stuff.  Thanks to Henk for figuring this
+	  out for us!
+
+2004-04-12 14:21  we7u
+
+	* configure.ac: Removing one line to make output prettier.
+
+2004-04-12 14:14  we7u
+
+	* README.win32: Updating the package names for X11 plus removing a
+	  few packages that are unnecessary.
+
+2004-04-12 13:18  we7u
+
+	* README.win32: Changing names of Cygwin packages to correspond to
+	  Cygwin's current naming scheme for the X11 server.
+
+2004-04-12 12:40  we7u
+
+	* README.win32: Removed the xwinclip package from the requirements
+	  per Henk de Groot.  Added notes by James Cour, K1ZC, and Tim
+	  Baggett, AA5DF, regarding the network audio instructions.
+
+2004-04-09 13:07  we7u
+
+	* README.win32: Removing the "for future development" notes from
+	  the pcre descriptions.  We use that library for dbfawk support.
+
+2004-04-09 09:44  we7u
+
+	* README.MAPS: Adding more notes that might make the initial user's
+	  decision easier as to which libraries to compile in for the
+	  desired functionality.
+
+2004-04-08 09:14  we7u
+
+	* config/: Makefile.am, tgr2shp.dbfawk: Adding Tom Russo's
+	  tgr2shp.dbfawk file to our standard set.  Useful for the 2003
+	  tiger data that just came out.
+
+2004-04-06 21:13  we7u
+
+	* INSTALL: Adding a note about needing "pcre" to compile in dbfawk
+	  support.
+
+2004-04-06 09:21  we7u
+
+	* src/main.c: Adding a command-line option to deselect all maps:
+	  "-m"
+
+2004-04-06 08:08  we7u
+
+	* src/map_shp.c: Fix by Tom Russo:  If running with dbfawk, sets
+	  everything to defaults in case a dbfawk file fails to reset
+	  things when done.
+
+2004-04-05 13:14  we7u
+
+	* README.win32: Added a note about winclip.
+
+2004-04-02 17:19  we7u
+
+	* src/: geo.h, geocoder_gui.c: Extending the lengths of the input
+	  fields for the Find Address function.
+
+2004-04-02 14:16  we7u
+
+	* README.win32: Added a note by Henk regarind lcms.
+
+2004-04-02 13:30  we7u
+
+	* README.MAPS: Added the Wiki page.
+
+2004-04-02 08:03  we7u
+
+	* configure.ac: Bumping the rev number.
+
+2004-04-01 09:11  we7u
+
+	* src/geo-find.c: Getting rid of some more compiler warnings.
+
+2004-04-01 07:25  we7u
+
+	* src/geocoder_gui.c: Fixing a compiler warning.
+
+2004-03-31 22:11  we7u
+
+	* src/util.c: Better implementation of the higher resolution s2l
+	  routines.
+
+2004-03-31 20:46  shadow
+
+	* INSTALL, help/help-English.dat: document the find address feature
+
+2004-03-31 20:26  we7u
+
+	* src/util.c: Backing out the changes done earlier today.  Will try
+	  again to implement higher resolution NMEA strings at a later
+	  date.
+
+2004-03-31 20:16  shadow
+
+	* README.MAPS: Add pointer to Census 2003 data. Add pointer to
+	  geocoder data files.
+
+2004-03-31 10:56  we7u
+
+	* src/util.c: Extending the NMEA sentence decoding to handle DD
+	  MM.MMMM format, which the new Tinytrak-3 chips can put out.  That
+	  resolution ends up being 0.6 counts of our Xastir coordinate
+	  system, so we need to resolve down to that level to avoid losing
+	  much.
+
+2004-03-30 14:58  we7u
+
+	* src/db.c: Changing from circles to an 'X' for marking a found
+	  address.
+
+2004-03-30 12:49  we7u
+
+	* src/xa_config.c: Saving/restoring the Mark Destination button
+	  state for the Find Address function.
+
+2004-03-30 12:44  we7u
+
+	* src/: db.c, geo.h, geocoder_gui.c: Added a togglebutton that
+	  enables/disables the marking of the destination for the Find
+	  Address function.
+
+2004-03-30 12:21  we7u
+
+	* src/: db.c, geo.h, geocoder_gui.c: Initial attempt at marking the
+	  destination target for a Find Address query.	There's not
+	  capability yet for removing the marking, but you can always seek
+	  another address and it will move to the new one.  Will probably
+	  change to some other marking at some point (a big 'X' perhaps?),
+	  and need to find a way to remove the mark that makes sense.
+
+2004-03-30 08:58  we7u
+
+	* src/geocoder_gui.c: Minor re-arranging of the Find Address
+	  dialog's widgets.
+
+2004-03-29 15:57  we7u
+
+	* src/io-mmap.c: Adding an include to get rid of compiler warnings
+	  about memcpy().
+
+2004-03-29 15:40  we7u
+
+	* src/: LICENSE.geocoder, geo-client.c, geo-find.c, geo.h,
+	  geocoder_gui.c, io-common.c, io-mmap.c, io.h, Makefile.am,
+	  main.c, main.h, xa_config.c: Geocoding support added by Derrick J
+	  Brashear, based off code written by Daniel Egenor that was
+	  released under GPL license.
+
+2004-03-26 10:17  we7u
+
+	* Makefile.am: Moving the .geo files into a subdirectory called
+	  "Online".
+
+2004-03-25 08:35  we7u
+
+	* src/gps.c: Enabling setuid priviledge at the point where
+	  settimeofday() is called.  Thanks to William Baguhn, kc9asi, for
+	  pointing this out.
+
+2004-03-24 17:29  shadow
+
+	* src/macspeech.c: macspeech support, but i need to write autoconf
+	  gunk, it just pretends to be festival
+
+2004-03-23 15:12  we7u
+
+	* INSTALL, README.win32: Updating Cygwin instructions:	com1 ->
+	  /dev/ttyS0 and similar for com2.
+
+2004-03-23 14:59  we7u
+
+	* acinclude.m4: Tweaking Cygwin serial ports to more standard port
+	  names.
+
+2004-03-23 10:01  we7u
+
+	* src/wx.c: Changes by Bruce Bennett.
+
+2004-03-22 14:12  we7u
+
+	* src/map_geo.c: Moving an #ifdef so that no compiler warnings are
+	  generated when ImageMagick support is missing.
+
+2004-03-22 13:52  we7u
+
+	* acinclude.m4: Fixes for Cygwin regarding comm ports.
+
+2004-03-22 09:23  we7u
+
+	* README.win32: Adding instructions to side-step the "detecting
+	  devices" hang on WinXP.
+
+2004-03-21 12:58  rzg
+
+	* help/help-English.dat: Added info on the comment field in
+	  interfaces; started a new tally of what changed since release.
+
+2004-03-19 14:38  we7u
+
+	* src/map_gnis.c: Removing trailing spaces while reading lines in
+	  from GNIS files.  They are notorious for having many spaces at
+	  the ends of the lines.
+
+2004-03-19 12:37  we7u
+
+	* src/map_shp.c: The rest of the code needed for the
+	  XReadBitmapFile() call failure, in order to make sure everything
+	  keeps running.
+
+2004-03-19 12:34  we7u
+
+	* src/map_shp.c: Getting rid of the exit(1) that we were doing when
+	  the XReadBitmapFile() call was failing during long runtimes.
+	  It's annoying if the bitmap is not found but it shouldn't kill
+	  all of Xastir in that case.  I'll be checking to see if further
+	  changes to the code are necessary though to prevent segfaults
+	  happening later in that part of the code.
+
+2004-03-19 09:52  we7u
+
+	* scripts/split_gnis.pl: Added an RCS tag.  Still needs a copyright
+	  blurb.
+
+2004-03-19 09:51  we7u
+
+	* src/interface.c: Fixing the long transmit delay, which was in
+	  port_write at the final select() call.
+
+2004-03-18 19:21  jtwilley
+
+	* scripts/split_gnis.pl:
+
+	  Added split_gnis.pl to scripts directory.
+
+	  The split_gnis.pl script will take any number of state-wide GNIS
+	  files listed on the command line and create smaller files based
+	  on county names.
+
+2004-03-18 15:14  we7u
+
+	* src/maps.c: Adding S57 map format to Xastir's supported map
+	  types.  File extension currently has to be ".s57" for these types
+	  of maps to be recognized by Xastir.
+
+2004-03-18 10:11  we7u
+
+	* scripts/ozi2geo.pl: Changed one comment.
+
+2004-03-18 09:58  we7u
+
+	* scripts/ozi2geo.pl: Initial attempt at a conversion script from
+	  OziExplorer .map format to Xastir's .geo format.  This version
+	  works with the one example map I had to work with.  More than
+	  likely more work will be needed on the script as more types of
+	  maps are tried.
+
+2004-03-15 15:49  we7u
+
+	* scripts/split_gnis.bash: Added a comment about "dos2unix".
+
+2004-03-15 15:47  we7u
+
+	* scripts/split_gnis.bash: Script written by William Baguhn,
+	  kc9asi.  Splits a GNIS files into smaller pieces which are more
+	  quickly loaded by Xastir when zoomed in.
+
+2004-03-15 09:08  we7u
+
+	* USRadar.geo: Tweaks by Gerry Creager.
+
+2004-03-12 20:54  we7u
+
+	* USRadar.geo: Mods by Gerry Creager.
+
+2004-03-10 20:11  we7u
+
+	* src/interface_gui.c: Implementing GUI input fields for the
+	  Interface->Properties "comment" field for each interface.
+
+2004-03-10 09:50  we7u
+
+	* src/interface_gui.c: Minor comment change.
+
+2004-03-09 14:59  we7u
+
+	* README.MAPS: Another note from Tom Russo on converting between
+	  datums.
+
+2004-03-09 13:18  we7u
+
+	* src/interface_gui.c: Adding some bookmarks.  Places that might
+	  need to be tweaked for MKISS.
+
+2004-03-09 08:47  we7u
+
+	* src/interface_gui.c: Wiping out old interface params from config
+	  file when an interface is deleted.
+
+2004-03-09 08:34  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c: Minor tweaks to
+	  the MKISS GUI.  Not functional yet.
+
+2004-03-08 22:54  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Updated language
+	  strings for MKISS and interface comments.
+
+2004-03-08 22:42  we7u
+
+	* src/: db.c, interface_gui.c, xa_config.c: Adding new MKISS
+	  interface (not complete yet).  Adding interface comment
+	  capability.
+
+2004-03-08 22:32  we7u
+
+	* src/interface.h: Adding new fields.  Needed for MKISS interface
+	  and for adding comments to interfaces.
+
+2004-03-08 13:16  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Updates to
+	  language strings for MKISS TNC's.
+
+2004-03-08 13:13  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/igate.c,
+	  src/interface.c, src/interface.h, src/interface_gui.c,
+	  src/main.c: Initial stab at creating a new SERIAL_MKISS interface
+	  type.  So far it's an identical copy of the SERIAL_KISS interface
+	  type, but that will change soon.  Intent is to support multi-port
+	  KISS TNC's such as the Kantronics KAM.
+
+2004-03-04 15:12  we7u
+
+	* USRadar.geo, help/help-English.dat, src/color.c, src/color.h,
+	  src/map_geo.c, src/maps.h: Fix for the TRANSPARENT tag in .geo's:
+	  Wasn't working right on 16-bit versus 24-bit Xwindows servers.
+
+2004-03-03 14:54  we7u
+
+	* src/map_geo.c: Toporama map speedups made possible by Steve
+	  Dimse's changes on the server.
+
+2004-03-02 13:19  we7u
+
+	* README.win32: A note by Steve Peters, N1TYE, regarding the lcms
+	  library on Cygwin.
+
+2004-03-02 09:56  we7u
+
+	* src/map_geo.c: Terraserver is playing games, changing their URL
+	  again.  Changing back to the original one we used to use, which
+	  works for us again.  The newer URL was returning all black
+	  images.
+
+2004-03-02 00:10  we7u
+
+	* src/map_geo.c: Commenting out debug output.
+
+2004-03-02 00:07  we7u
+
+	* src/maps.c: Sending tab map files to draw_ogr_map().
+
+2004-03-01 23:50  we7u
+
+	* Makefile.am, src/map_geo.c: Initial version of code to support
+	  Canadian Toporama maps, downloading them automatically over the
+	  'net from mm.aprs.net, including the dynamically generated .geo
+	  files.
+
+2004-03-01 23:47  we7u
+
+	* CanadaTopo250k.geo, CanadaTopo50k.geo: Initial checkin.
+
+2004-03-01 09:31  we7u
+
+	* README.MAPS: Changing notes regarding where to find free DRG
+	  maps.
+
+2004-02-29 18:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c: Tweaking the
+	  Interface Start/Stop dialog so that it is much more readable.
+
+2004-02-29 12:31  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/xa_config.c: Added two new trail sliders to the timing
+	  dialog.  They both control whether trails are displayed, one
+	  based on max distance, one based on max time.  If either max
+	  distance or max time are exceeded for new trails, that segment is
+	  not drawn.  Does not affect trail points that have already been
+	  received, just new trail points.
+
+2004-02-27 19:12  we7u
+
+	* src/main.c: Modifying the Move function so that it drops through
+	  all the dialogs and doesn't require any OK buttons to be pressed
+	  to effect the move.  This is useful for drawing the expected
+	  route of a SAR team and documenting it via Shapefiles.  It's much
+	  faster to do so now.	Downside: Unintentionally moving an object
+	  gets an automatic confirm, and you'll have to move it back
+	  manually or else edit the object.log file by hand and read it in
+	  again.
+
+2004-02-27 18:00  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/xa_config.c: Adding
+	  a "Disable Posit Dupe-Checks" option to Configure->Defaults.
+	  Disables the 30-minute dupe-checks that Xastir does when each
+	  packet is received.  Does not affect igate dupe-checks.
+
+2004-02-27 17:26  we7u
+
+	* src/: db.c, main.h, util.c: Turning off trail-point dupe-checking
+	  when reading in objects/items from file.  This lets us show SAR
+	  teams leaving and returning to base later, without having the
+	  last trail segment missing.
+
+2004-02-27 17:00  we7u
+
+	* src/db.c: Updating some comments.
+
+2004-02-27 15:42  we7u
+
+	* help/help-English.dat: Adding notes about trails and why some
+	  segments don't display.
+
+2004-02-27 14:58  we7u
+
+	* src/db.c: Changing the distance at which Xastir will skip a track
+	  segment, from >1 degree lat/long to >2 degrees.  Any track
+	  segment less than 2 degrees in N/S and E/W length will get drawn,
+	  as long as the time between posits is less than 45 minutes.  If
+	  over 45 minutes, the segment gets skipped as well.
+
+2004-02-26 15:25  we7u
+
+	* src/interface.c: New code to avoid opening the same serial port
+	  twice for two different interfaces.
+
+2004-02-26 15:19  we7u
+
+	* src/db.c: Changing some debug code.
+
+2004-02-26 13:48  we7u
+
+	* INSTALL: Added a note about how to test the festival server by
+	  telnet'ing to it.
+
+2004-02-26 12:30  we7u
+
+	* src/: map_geo.c, map_tiger.c, track_gui.c: Fixing the problem
+	  where a failed internet download (map or tracklog) would cause an
+	  older version of the same to get displayed.  We now delete the
+	  old filename from our ~/.xastir/tmp directory before attempting
+	  the download each time.
+
+2004-02-26 12:07  we7u
+
+	* src/: db.c, db.h: Adding a retry timeout for killed object/items.
+	  We'll now transmit killed objects 11 times before ceasing to
+	  transmit them.
+
+2004-02-24 11:34  we7u
+
+	* README: Additions by Alan Shackelford, NG3B.
+
+2004-02-24 09:28  we7u
+
+	* README.MAPS: More good info from Tom Russo, KM5VY.
+
+2004-02-23 14:52  we7u
+
+	* README.MAPS: Added the FIPS locator URL.  Useful stuff!
+
+2004-02-21 22:32  we7u
+
+	* INSTALL: Updating some libtiff/libgeotiff notes.
+
+2004-02-21 12:35  kd6zwr
+
+	* src/map_shp.c: Add label levels for point style shapefiles when
+	  using dbfawk
+
+2004-02-13 13:40  we7u
+
+	* src/maps.c: Fixing the prime meridian line for UTM grid.  Wasn't
+	  being drawn at all zoom levels.
+
+2004-02-13 08:54  we7u
+
+	* README.win32: Added a warning about KDE.
+
+2004-02-12 14:18  we7u
+
+	* src/: interface.h, interface.c: New method of waiting for data to
+	  get to serial TNC's before closing the port.	Method and most of
+	  the code contributed by Erik G. Burrows, KG6HEA.  Additional code
+	  by WE7U to prevent locking up with poorly-behaved serial devices.
+
+2004-02-11 14:40  we7u
+
+	* src/map_geo.c: Making transparent images work again after the
+	  raster_intensity changes a few weeks back.
+
+2004-02-11 13:35  we7u
+
+	* src/main.c: Fixing an annoying floating-point conversion bug in
+	  the Map Intensity menus.  For 70% and 90%, they were reported as
+	  60% and 80% in the menus.
+
+2004-02-11 10:24  we7u
+
+	* Makefile.am, USRadar.geo, src/map_geo.c, src/maps.h: Changing to
+	  an unsigned long for holding the transparency value.	Adding
+	  USRadar.geo as an installed map ('cuz it's just way cool).
+
+2004-02-10 14:18  we7u
+
+	* src/db.c: Making the 'h' in timestamp be case-insensitive on
+	  receive.
+
+2004-02-10 14:18  we7u
+
+	* src/db.c: Making the 'h' in a timestamp be case-insensitive on
+	  receive.
+
+2004-02-09 12:20  we7u
+
+	* src/db.c: Making N/S/E/W and the timestamp 'Z' non case-specific.
+	  This was requested by Bob Bruninga on the APRSSIG mailing list
+	  recently (sometime in january 2004, before our last stable
+	  release).
+
+2004-02-06 14:39  we7u
+
+	* src/interface_gui.c: Changing default path from RELAY,WIDE to
+	  WIDE.
+
+2004-02-06 13:33  we7u
+
+	* configure.ac, src/main.c: Adding a list of the compiled-in
+	  libraries to the Help->About dialog.
+
+2004-02-05 11:00  we7u
+
+	* INSTALL, README.CVS, README.win32: Updating CVS instructions
+	  because SourceForge isn't handling compression currently.
+
+2004-02-04 12:41  we7u
+
+	* bootstrap.sh: Adding the CVS tag line.
+
+2004-02-04 08:49  we7u
+
+	* src/: main.c, map_shp.c: Changing some error messages to provide
+	  more detail.
+
+2004-02-02 23:10  we7u
+
+	* README.win32: Mods by David Flood, KD7MYC.  Thanks!
+
+2004-02-02 14:31  we7u
+
+	* configure.ac: Bumping the patch number so we can separate
+	  development versions from most recent stable release.
+
+2004-02-02 13:41  we7u
+
+	* config/language-German.sys: Updates by Rolf, DK7IN.
+
+2004-02-02 12:58  we7u
+
+	* src/main.c: Updating the Help->About message.  Thanks for
+	  reminding me Ren!
+
+2004-02-02 08:37  we7u
+
+	* configure.ac: Bumping the revision to 1.3.0.	Getting ready for
+	  stable release.
+
+2004-02-02 08:35  we7u
+
+	* help/help-English.dat: Very minor changes to the What's New
+	  section.
+
+2004-02-01 23:26  rzg
+
+	* help/help-English.dat: Moved old "What's new" list out of the
+	  way.
+
+2004-02-01 23:23  rzg
+
+	* help/help-English.dat: What's new section. Could use proofreading
+	  and the addition of stuff I forgot.
+
+2004-01-30 15:48  shadow
+
+	* README: update README to reflect what's needed to get MacOS X
+	  with GDAL.
+
+2004-01-30 13:51  we7u
+
+	* xastir.spec.in: Correcting the path to the man pages.
+
+2004-01-30 10:12  we7u
+
+	* symbols/symbols.dat: Implemented Wheelchair, Shelter, and
+	  proposed Waypoint symbol.  Also changed one description from "HF
+	  Gateway" to "Any Gateway (w/overlay char)".  The "Any Gateway"
+	  symbol still needs to be changed into something which would
+	  display an overlay char nicely.  The Shelter symbol may need to
+	  be changed into something more recognizable.
+
+2004-01-29 17:47  n2ygk
+
+	* xastir.spec.in: --with-dbfawk.  Curt: toss this if you feel
+	  dbfawk is not cooked enough.
+
+2004-01-29 08:53  we7u
+
+	* INSTALL: Updating the gpsman/gpsmanshp instructions for systems
+	  with tcl8.4 instead of tcl8.3.
+
+2004-01-28 10:42  we7u
+
+	* AUTHORS: Got rid of reference to non-existent file.  Add note
+	  stating we don't try to keep this file up to date.
+
+2004-01-28 10:11  we7u
+
+	* UPGRADE: Added more notes about migrating to latest Xastir.
+
+2004-01-28 09:42  we7u
+
+	* README.CVS: Added another note about sticky tags.
+
+2004-01-26 12:50  we7u
+
+	* INSTALL: Adding a note about the port names for Cygwin.
+
+2004-01-26 08:18  we7u
+
+	* src/: Makefile.am, alert.c, alert.h, awk.c, awk.h,
+	  bulletin_gui.c, bulletin_gui.h, color.c, color.h, datum.c,
+	  datum.h, db.c, db.h, dbfawk.c, dbfawk.h, draw_symbols.c,
+	  draw_symbols.h, fcc_data.c, fcc_data.h, festival.c, festival.h,
+	  gps.c, gps.h, hostname.c, hostname.h, igate.c, igate.h,
+	  interface.c, interface.h, interface_gui.c, lang.c, lang.h,
+	  list_gui.c, list_gui.h, locate_gui.c, location.c, location_gui.c,
+	  main.c, main.h, map_dos.c, map_gdal.c, map_geo.c, map_gnis.c,
+	  map_pdb.c, map_shp.c, map_tif.c, map_tiger.c, maps.c, maps.h,
+	  messages.c, messages.h, messages_gui.c, popup.h, popup_gui.c,
+	  rac_data.c, rac_data.h, rotated.c, rotated.h, snprintf.c,
+	  snprintf.h, sound.c, symbols.h, testawk.c, track_gui.c,
+	  track_gui.h, util.c, util.h, view_message_gui.c, wx.c, wx.h,
+	  wx_gui.c, x_spider.c, x_spider.h, xa_config.c, xa_config.h,
+	  xastir.h: Updating copyright notices.
+
+2004-01-26 08:11  we7u
+
+	* LICENSE, README.win32, callpass/Makefile.am, callpass/callpass.c,
+	  config/Makefile.am, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  config/nwsc_ddmmyy.dbfawk, config/nwsmzddmmyy.dbfawk,
+	  config/nwsozddmmyy.dbfawk, config/nwsw_ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrlpt.dbfawk,
+	  config/tgrlpy.dbfawk, config/tgrplc00.dbfawk,
+	  config/tgrwat.dbfawk, config/tnc-startup.aea,
+	  config/tnc-startup.kam, config/tnc-startup.kpc3,
+	  config/tnc-startup.paccomm, config/tnc-startup.pico,
+	  config/tnc-startup.sys, config/tnc-startup.thd7,
+	  config/tnc-stop.sys, help/Makefile.am, help/help-Dutch.dat,
+	  help/help-English.dat, help/help-French.dat,
+	  help/help-German.dat, help/help-Italian.dat,
+	  help/help-Portuguese.dat, help/help-Spanish.dat, m4/Makefile.am,
+	  scripts/Makefile.am, scripts/example_objects.log,
+	  scripts/fcc-get, scripts/xastir-fixcfg.sh,
+	  scripts/xastir-migrate.sh, symbols/Makefile.am,
+	  symbols/symbols.dat: Updating copyright notices.
+
+2004-01-26 08:09  we7u
+
+	* AUTHORS, DEBUG_LEVELS, INSTALL, Makefile.am, NEWS, README,
+	  README.CVS, README.MAPS, UPGRADE, acinclude.m4, bootstrap.sh,
+	  changes.txt, configure.ac, xastir.1, xastir.spec.in: Updating
+	  copyright notices.  Adding a few more docs to the spec file.
+
+2004-01-22 19:26  we7u
+
+	* src/xa_config.c: Adding sys/stat.h call that is needed to compile
+	  this file on MacOSX.
+
+2004-01-22 18:34  we7u
+
+	* README.CVS: Updating the "unsticky" instructions for CVS.
+
+2004-01-21 16:14  rzg
+
+	* FAQ: Added a bit on support, fixed numbering, a typo, and
+	  copyright year.
+
+2004-01-21 15:48  we7u
+
+	* README.CVS: Added the "diff" line to .cvsrc note.  Added "sticky"
+	  tags STABLE and RELEASE and explanations of how to use them.
+
+2004-01-21 08:47  we7u
+
+	* src/xa_config.c: Changing default for "Expand Dirs" in Map
+	  Chooser to 1.  Better for new users.
+
+2004-01-20 13:34  we7u
+
+	* FAQ: Another note about ImageMagick dependencies and "spec"
+	  files.
+
+2004-01-20 13:32  we7u
+
+	* FAQ: Adding some notes about ImageMagick and failed dependencies.
+
+2004-01-19 15:02  we7u
+
+	* src/maps.c: Attempting to fix an indexing bug.  New files are not
+	  picked up by indexing.  This fix picks the later of ctime/mtime
+	  to use for the timestamp.  Contributed by Reuven.
+
+2004-01-19 13:33  we7u
+
+	* src/: main.c, maps.c: Commented out some dead code in maps.c.
+	  Added new USR1 signal handler code by Tim Gimmel, KB4AMA.  Just
+	  send a USR1 signal via "kill -USR1 <pid>" and Xastir will create
+	  a new snapshot.  Useful for web page front-ends.
+
+2004-01-16 12:25  gstueve
+
+	* src/: alert.c, alert.h: Change numeric index references in flags
+	  to symbolic and fixed end-of-data to match sizeof data not fixed
+	  numeric values.
+
+2004-01-16 12:18  gstueve
+
+	* scripts/fcc-get: Update for new diretory layout with generic path
+	  name & add passive ftp.
+
+2004-01-16 10:14  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.h, src/wx.c: Initial support
+	  for Davis Weather Monitor II, Wizard III, and Vantage Pro weather
+	  stations, written by Bruce Bennett.  Thanks Bruce!
+
+2004-01-15 13:28  we7u
+
+	* src/xa_config.c: Attempting to recover from backup file renaming
+	  when things go wrong.  We'll try to get as close to the original
+	  state of the files as we can.
+
+2004-01-15 13:09  we7u
+
+	* src/xa_config.c: More config file backup copies code.  We now
+	  back out the renaming if the new config file can't be created, so
+	  we're left with the original config and two backups in that case.
+
+2004-01-15 11:02  we7u
+
+	* FAQ, src/interface.c, src/interface_gui.c, src/xa_config.c:
+	  Simplified the all interfaces up/down logic.	It should work
+	  better now.  Changed the config file backup code so that
+	  xastir.cnf.1 through xastir.cnf.3 are created.  This should help
+	  insulate us a bit better from crashes, as we'll have more old
+	  copies of the config file to draw from if the main config file
+	  (xastir.cnf) gets trashed.
+
+2004-01-15 08:56  we7u
+
+	* configure.ac: Adding a line in for getting rid of duplicates in
+	  the LIBS variable.  Commented out while testing so that it
+	  doesn't hurt any installations.
+
+2004-01-14 15:07  we7u
+
+	* src/main.c: Adding more sprintf's in cases of failure to create
+	  symlinks.
+
+2004-01-14 12:07  we7u
+
+	* configure.ac: Extending one comment.	No code changes.
+
+2004-01-14 12:00  we7u
+
+	* src/main.c: Minor tweak to two fprintf strings.
+
+2004-01-12 11:44  we7u
+
+	* src/main.c: Changing back to a previous configuration for the end
+	  of the create_appshell() function.  Attempting to get rid of this
+	  problem:   "attempt to add non-widget child "DropSiteManager" to
+	  parent "xastir"   which support only widgets" while not
+	  re-creating this problem:   "Shell widget xastir has zero width
+	  and/or height".
+
+2004-01-09 10:57  rzg
+
+	* help/help-English.dat, src/maps.c: Map index checking now allows
+	  negative layer numbers.  Minor helpfile updates
+
+2004-01-09 08:11  we7u
+
+	* src/map_gdal.c: More checks for invalid extents while indexing.
+	  If all 0's or outside indexes of the earth, we skip adding it to
+	  the index.
+
+2004-01-08 13:38  we7u
+
+	* src/main.c: Re-establishing the XtRealizeWidget() call in main
+	  that was commented out to help fix the "zero width or height"
+	  error on startup.  Now we specify a minimum size in the
+	  XtVaAppInitialize() call that preceeds it, so the old problem
+	  shouldn't reoccur.
+
+2004-01-08 13:34  we7u
+
+	* src/main.c: Gives an initial size to the application.  Makes it
+	  appear to come up faster.  Whether or not it actually does is
+	  beside the point.  May help to get rid of the initial sizing
+	  problem: "Error: Shell widget xastir has zero width and/or
+	  height".
+
+2004-01-07 08:42  we7u
+
+	* configure.ac: Minor tweaks to some AC_MSG_ERROR calls.
+
+2004-01-07 08:42  we7u
+
+	* INSTALL: Minor tweaks to the make instructions here and there.
+
+2004-01-04 13:37  we7u
+
+	* src/map_gdal.c: Correcting the limits for OGR indexing.
+
+2003-12-30 07:38  we7u
+
+	* src/maps.c: Changing startup STDERR output to show which library
+	  (Shapelib/OGR) is providing Shapefile support.
+
+2003-12-26 09:26  we7u
+
+	* src/interface.c: Bumping the read/write loop timeouts to 100ms.
+	  This should provide reasonable response time when killing ports,
+	  yet keep CPU usage low when no data is being read/written.
+
+2003-12-26 08:17  we7u
+
+	* src/interface.c: Bumping the timeout in port_write() select to
+	  500ms.  That timeout is used to jump out of the select() so that
+	  we can check whether the interface has gone down.  It does not
+	  need to be very small, and in fact causes high CPU usage on
+	  freebsd systems if it's below about 1ms.  Linux can handle
+	  somewhat smaller delays (100us is ok on Linux).
+
+2003-12-24 17:07  rzg
+
+	* help/help-English.dat: Whatsnew update, and tigermap.geo is
+	  back...
+
+2003-12-23 17:49  we7u
+
+	* src/: main.c, map_gdal.c, maps.c, xastir.h: Added another output
+	  line to the segfault handler.  Minor tweaks to the OGR code.
+
+2003-12-23 07:25  we7u
+
+	* src/map_gdal.c: Added some comments.
+
+2003-12-22 18:59  we7u
+
+	* src/map_gdal.c: Starting to add map preferences code to the OGR
+	  map-drawing functions.
+
+2003-12-20 16:18  we7u
+
+	* src/main.c: Getting rid of a couple of messages used for cad
+	  object debug.  Put them inside ifdef's.
+
+2003-12-19 16:28  we7u
+
+	* src/: map_geo.c, map_shp.c, map_tiger.c: Fixing
+	  raster_map_intensity for tiger and .geo maps.  Changes in
+	  comments and remove of debugging code in map_shp.c
+
+2003-12-19 13:33  we7u
+
+	* src/map_geo.c: Minor tweak to make toposerver files work again
+	  and make the .geo code look like the tiger code w.r.t. image
+	  intensity.
+
+2003-12-19 12:59  we7u
+
+	* src/map_gdal.c: Improvements to the line drawing routines mostly.
+	  OGR stuff.
+
+2003-12-19 12:59  we7u
+
+	* src/maps.c: Major speed improvements to map_onscreen(),
+	  map_visible(), and map_visible_lat_lon() routines.
+
+2003-12-19 12:58  we7u
+
+	* src/main.c: Moved routines around.  No code changes.
+
+2003-12-18 16:04  we7u
+
+	* src/map_gdal.c: Tweaks to OGR polygons.
+
+2003-12-18 13:06  we7u
+
+	* src/map_gdal.c: Working X11 Regions for drawing OGR "hole" or
+	  innner polygons.
+
+2003-12-18 07:06  we7u
+
+	* src/alert.c: Zero'ing out newly-added alert entries after each
+	  realloc() call.
+
+2003-12-17 22:45  we7u
+
+	* src/map_tiger.c: ImageMagick brightness code change by Jim
+	  Chandler, N0VH.
+
+2003-12-17 22:40  we7u
+
+	* src/map_gdal.c: Starting to add the framework for doing X11
+	  Regions.  Will allow doing "fill" and "hole" polygons as we
+	  currently do in the Shapelib code.
+
+2003-12-17 13:07  we7u
+
+	* src/map_gdal.c: More comments.
+
+2003-12-17 12:58  we7u
+
+	* src/map_gdal.c: Minor comment changes.
+
+2003-12-17 12:56  we7u
+
+	* src/map_gdal.c: More fill/hole polygon stuff.  Currently drawing
+	  polygons with dashed lines for "hole" polygons, solid for "fill"
+	  polygons.  This is if the use has decided not to fill the shapes.
+	  For filled shapes, the hole polygons aren't drawn at all
+	  currently.
+
+2003-12-17 12:36  we7u
+
+	* src/map_gdal.c: More comments.  Starting to add polygon fill/hole
+	  differentiation code.
+
+2003-12-17 12:06  we7u
+
+	* src/map_gdal.c: More comments.
+
+2003-12-17 10:24  we7u
+
+	* src/map_gdal.c: Comment changes only.
+
+2003-12-17 07:42  we7u
+
+	* src/map_gdal.c: Fixing OGR polygons so they work again, still
+	  non-filled though.
+
+2003-12-17 07:14  we7u
+
+	* src/map_gdal.c: More comment changes.
+
+2003-12-17 07:04  we7u
+
+	* src/map_gdal.c: Changing default colors and changing a few
+	  comments.  The colors won't stay, but they're useful at the
+	  moment for debugging.
+
+2003-12-16 12:08  we7u
+
+	* src/maps.c: Added some comments.
+
+2003-12-16 10:16  we7u
+
+	* src/interface.c: Fixes to make the OpenTrac tweaks compile
+	  properly.
+
+2003-12-16 10:09  we7u
+
+	* src/interface.c: Fixes to OpenTrac decoding by Scott Miller.
+
+2003-12-16 08:19  we7u
+
+	* src/alert.c: An attempt to skip over alert_list[] entries that
+	  are zeroed (title has '\0' as the first character) while doing an
+	  alert_match().
+
+2003-12-15 09:19  we7u
+
+	* src/interface.c: Patch by Brian Heaton to prefix the port number
+	  to the incoming string we dump out via our segfault handler.
+
+2003-12-15 07:56  we7u
+
+	* README.MAPS: Added another SDTS note.
+
+2003-12-13 10:36  we7u
+
+	* INSTALL: Added another GDAL comment.
+
+2003-12-13 10:33  we7u
+
+	* src/map_gdal.c: Moved some XSet... calls down into the OGR
+	  drawing section.  Above the indexing section they caused
+	  segfaults.  We must not be calling the indexing functions with a
+	  valid widget?
+
+2003-12-12 17:16  we7u
+
+	* README.MAPS: Adding more map links for some new map formats.
+
+2003-12-12 13:20  we7u
+
+	* src/map_gdal.c: Faster OGR polygons.	Transforming all of the
+	  points at once for each polygon.
+
+2003-12-12 13:02  we7u
+
+	* src/map_gdal.c: Faster OGR line drawing.  Recognize more datums
+	  that we don't have to convert (faster again).
+
+2003-12-12 12:31  we7u
+
+	* src/map_gdal.c: Removing unneeded code.  Adding more comments.
+
+2003-12-12 12:24  we7u
+
+	* src/map_gdal.c: Adding comments.
+
+2003-12-12 12:20  we7u
+
+	* src/map_gdal.c: Renaming OGR helper functions to make sure there
+	  aren't any clashes later with similar functions.
+
+2003-12-12 12:17  we7u
+
+	* src/map_gdal.c: Speeding up OGR Point drawing.  Changing default
+	  point color to white.
+
+2003-12-12 12:03  we7u
+
+	* src/map_gdal.c: Faster OGR line/polygon drawing by checking
+	  extents on those datatypes that allow fast extent checking.
+
+2003-12-12 12:02  we7u
+
+	* configure.ac: Minor summary text change.
+
+2003-12-12 08:23  we7u
+
+	* src/map_gdal.c: Added TODO list for OGR and moved the Draw
+	  routines above the main OGR routine (getting rid of the
+	  prototypes).
+
+2003-12-12 08:04  we7u
+
+	* README.MAPS: Added a note about SDTS files.
+
+2003-12-12 07:46  we7u
+
+	* src/map_gdal.c: A bit of cleanup in the new OGR routines.
+
+2003-12-12 07:30  we7u
+
+	* src/map_gdal.c: Creating OGR Draw_Points() function which is
+	  similar to the Draw_Lines() and Draw_Polygons() functions.  Skips
+	  drawing points that are outside the view.
+
+2003-12-12 06:55  we7u
+
+	* INSTALL: Changes to the GDAL/OGR notes.
+
+2003-12-11 17:50  we7u
+
+	* src/map_gdal.c: Optimizing Draw_Lines() and Draw_Polygons()
+	  functions in the OGR routines.  We now check the extents of each
+	  feature and skip drawing it if it's not in our view.
+
+2003-12-11 12:35  we7u
+
+	* src/: main.c, map_gdal.c: Fixing map_interrupts so that they work
+	  properly and quickly.  A few places were broken, including the
+	  new OGR code.
+
+2003-12-11 11:42  we7u
+
+	* src/map_gdal.c: Changed some variable names.	Added some debug
+	  code, looking for sources of memory leaks.
+
+2003-12-10 22:43  we7u
+
+	* INSTALL: Added a new site for Shapelib.
+
+2003-12-10 16:31  we7u
+
+	* src/map_gdal.c: On-the-fly coordinate transforms while drawing.
+
+2003-12-10 11:14  we7u
+
+	* src/maps.c: Adding more map types that are accepted by OGR.
+
+2003-12-10 10:18  we7u
+
+	* src/map_gdal.c: Changed some comments.
+
+2003-12-10 10:16  we7u
+
+	* src/maps.c: Adding mif/mid (Mapinfo) to list of accepted map
+	  types for OGR.
+
+2003-12-10 00:01  we7u
+
+	* src/map_gdal.c: Minor reformatting.
+
+2003-12-09 23:13  we7u
+
+	* src/map_gdal.c: Added a comment.
+
+2003-12-09 17:03  we7u
+
+	* src/map_gdal.c: Better Polygons for OGR.
+
+2003-12-09 12:27  we7u
+
+	* src/map_gdal.c: Drawing of OGR polygons is now working.
+
+2003-12-09 08:55  we7u
+
+	* src/map_gdal.c: Slightly faster drawing code due to fewer sets of
+	  debug loops.	More comments.
+
+2003-12-09 00:22  we7u
+
+	* src/: map_gdal.c, maps.c, maps.h: Added a new draw function for
+	  points.  More tweaks to the OGR code.
+
+2003-12-08 15:43  we7u
+
+	* src/interface.c: Checking that I can stat a file and that it is a
+	  regular file before attempting to send a file of commands to the
+	  TNC.
+
+2003-12-08 13:22  we7u
+
+	* src/map_gdal.c: Adding indexing for files where spatial
+	  coordinate system is not known, but they still fall within the
+	  normal lat/long boundaries for file extents.	We're assuming
+	  they're in geographic WGS84 coordinates in this case and allowing
+	  the indexing to complete.
+
+2003-12-08 12:56  jtwilley
+
+	* config/tnc-startup.null: Added a zero-byte file named
+	  'tnc-startup.null' for those times when users do not want their
+	  TNC configurations changed by xastir.
+
+2003-12-08 12:19  we7u
+
+	* src/map_gdal.c: Comment updates.  No code changes this time.
+
+2003-12-08 12:10  we7u
+
+	* src/map_gdal.c: Took out some debug stuff that messed with
+	  converting to nad27 datum for test runs.  Generalized the code so
+	  that it works with projected coordinate systems.  No computes
+	  file extents for state-plane coordinate systems.  It should also
+	  work for UTM projected coordinate systems.
+
+2003-12-07 23:50  we7u
+
+	* src/map_gdal.c: For file extents (indexing):	Datum translation
+	  is working now for geographic coordinate systems.  Not
+	  implemented yet for projected coordinate systems.  Haven't
+	  implemented datum translation for drawing yet.
+
+2003-12-07 23:47  we7u
+
+	* src/maps.c: Forcing shapefiles back to the old code for now.
+
+2003-12-07 23:46  we7u
+
+	* src/maps.c: More debug for map_driver stuff.
+
+2003-12-07 12:23  we7u
+
+	* src/interface.c: Reducing delay in port_write for checking queue.
+	  Down to 100us from 200ms.  Makes writing to interfaces much
+	  snappier, but doesn't bog down CPU.  Cranking up channel_data()
+	  busy wait from 1 to 2us.
+
+2003-12-07 09:16  we7u
+
+	* src/: main.c, xa_config.c: Fixing the 10% zoom in bug when at
+	  zoom level 1.
+
+2003-12-06 12:10  we7u
+
+	* src/map_gdal.c: Filling in a bit more for the OGR indexing code.
+
+2003-12-06 09:20  we7u
+
+	* src/interface.c: Reducing many of the usleep() delays while
+	  transmitting to serial TNC's.  Users will have to rely on the new
+	  delay slider to add delays if they get into weird operation with
+	  any particular TNC.
+
+2003-12-05 23:44  we7u
+
+	* src/map_gdal.c: More changes to debug output.
+
+2003-12-05 23:36  we7u
+
+	* src/map_gdal.c: Partial map indexing working for OGR.  Must be
+	  geographic coordinate system.  Haven't implemented conversions
+	  from other datums or coordinate systems to geographic WGS84/NAD83
+	  yet.
+
+2003-12-05 22:33  we7u
+
+	* src/map_gdal.c: Printing out extents now.  Should have indexing
+	  implemented soon.
+
+2003-12-05 22:02  we7u
+
+	* src/map_gdal.c: More reformatting for debug purposes.
+
+2003-12-05 19:11  we7u
+
+	* src/map_gdal.c: Better formatting for OGR debug statements.
+
+2003-12-05 17:36  we7u
+
+	* src/map_gdal.c: Filling in more features.  Slowly.
+
+2003-12-05 14:07  we7u
+
+	* src/xa_config.c: Changing the default serial_char_pacing to 1ms
+	  instead of 25ms.
+
+2003-12-05 13:08  we7u
+
+	* src/map_gdal.c: Working version of what I checked in last time.
+	  ;-)
+
+2003-12-05 13:01  we7u
+
+	* src/map_gdal.c: More good info in the OGR code.
+
+2003-12-05 12:40  we7u
+
+	* src/map_gdal.c: Fleshing out more details in the OGR driver.
+
+2003-12-05 11:39  we7u
+
+	* src/xa_config.c: Adding save/restore for serial character pacing.
+
+2003-12-05 11:14  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c, src/main.c,
+	  src/main.h, src/map_gdal.c: Speeding up OGR.	Adding a new
+	  inter-character delay timing slider that affects serial-port
+	  TNC's.
+
+2003-12-04 10:58  we7u
+
+	* src/map_gdal.c: Changed some comments.
+
+2003-12-04 10:08  we7u
+
+	* src/map_gdal.c: Adding map interrupt capability to the OGR code.
+
+2003-12-04 08:39  we7u
+
+	* src/maps.c: Fixing up the callouts to GDAL/OGR.  We direct
+	  Shapefile stuff to draw_shapefile_map() right now instead of
+	  GDAL/OGR.  Tiger goes to GDAL/OGR.  This can be changed via a
+	  define near the top of maps.c so that Shapefile goes to OGR as
+	  well.
+
+2003-12-04 08:36  we7u
+
+	* src/map_shp.c: Getting rid of duplicate definition of font_size.
+
+2003-12-04 08:21  n2ygk
+
+	* src/map_shp.c: fix the font_size fix to use FONT_DEFAULT
+
+2003-12-04 00:43  we7u
+
+	* src/maps.c: Adding more vector types.  Currently commented out,
+	  but the GDAL/OGR code will eventually support them.
+
+2003-12-04 00:36  we7u
+
+	* src/main.c: Added more vector formats to the Vector button in Map
+	  Chooser.
+
+2003-12-04 00:25  we7u
+
+	* src/map_gdal.c: Several segfaults fixed.  Handles polyline
+	  shapefiles and raw Tiger/Line polylines so far.
+
+2003-12-03 23:23  we7u
+
+	* src/map_shp.c: Fixing a compile problem for non-dbfawk compiles.
+
+2003-12-03 17:08  n2ygk
+
+	* src/: main.c, map_dos.c, map_pdb.c, map_shp.c, maps.c, maps.h,
+	  xa_config.c, xastir.h: multiple font_sizes in maps/config/map
+	  label font
+
+2003-12-03 17:05  n2ygk
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys,
+	  nwsc_ddmmyy.dbfawk, nwsmzddmmyy.dbfawk, nwsozddmmyy.dbfawk,
+	  nwsw_ddmmyy.dbfawk, nwsz_ddmmyy.dbfawk, tgrcty.dbfawk,
+	  tgrkgl.dbfawk, tgrlk.dbfawk, tgrlpt.dbfawk, tgrlpy.dbfawk,
+	  tgrplc00.dbfawk, tgrwat.dbfawk: font_size
+
+2003-12-03 14:18  we7u
+
+	* README.MAPS: Added a note about Tiger/Line maps (coming soon).
+
+2003-12-03 13:08  we7u
+
+	* src/map_gdal.c: Added some comments.
+
+2003-12-03 12:53  we7u
+
+	* src/map_shp.c: Removing the debug OGR code for the moment.
+
+2003-12-03 12:52  we7u
+
+	* src/map_gdal.c: OGR drawing for Shapefile polylines is starting
+	  to work.  Not pretty yet.  Points/Polygons not working yet.
+
+2003-12-03 12:51  we7u
+
+	* src/maps.h: Adding a prototype for a function needed in
+	  draw_gdal.c
+
+2003-12-03 12:07  we7u
+
+	* src/map_gdal.c: More OGR library stuff.  Am at the point where I
+	  have access to the points/polylines/polygons...
+
+2003-12-03 08:19  we7u
+
+	* src/: main.c, maps.h: Changing the Map Properties dialog so that
+	  it only shows maps that were selected in the Map Chooser.  Also
+	  the Ok and Cancel buttons in the Map Chooser are greyed-out when
+	  the Properties dialog is active (necessary due to the way I
+	  implemented the new feature).
+
+2003-12-03 00:18  we7u
+
+	* src/main.c: Added some comments.
+
+2003-12-02 23:42  jtwilley
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added "Select All"
+	  line to the other language files.
+
+2003-12-02 23:04  jtwilley
+
+	* config/language-English.sys, src/main.c: Added "Select All"
+	  button to "Map Properties" dialog.
+
+2003-12-02 16:25  we7u
+
+	* src/map_shp.c: Forgot an #ifdef.
+
+2003-12-02 16:23  we7u
+
+	* src/: map_gdal.c, map_shp.c, maps.c: Debug OGR code.	Nothing
+	  truly functional yet.  Just getting a feel for how to go about
+	  it.
+
+2003-12-02 15:06  we7u
+
+	* configure.ac: Broke libproj check out into its own section and
+	  summary line.  We still need it checked in the libgeotiff section
+	  as well though, as we depend on proj there too.
+
+2003-12-02 14:16  we7u
+
+	* src/: map_gdal.c, maps.c: Changing some warning messages.
+
+2003-12-02 14:02  we7u
+
+	* src/map_gdal.c: Getting rid of compiler warnings.
+
+2003-12-02 13:50  we7u
+
+	* configure.ac: Moving the pcre summary next to the dbfawk summary
+	  at the end of configure.  Reordered some of the rest as well,
+	  putting all of the map libraries together.
+
+2003-12-01 13:13  we7u
+
+	* src/x_spider.c: Adding an include to make a compiler warning
+	  disappear.
+
+2003-12-01 12:56  we7u
+
+	* INSTALL: Removing a note that is no longer needed.  CVS GDAL has
+	  been tweaked to fix it.
+
+2003-11-29 11:12  we7u
+
+	* src/x_spider.c: Flushing out the feature set for x_spider.  Not
+	  ready for prime-time yet, but getting closer.  It now echoes
+	  anything received from one client out to all other connected
+	  clients.  No provision yet for detecting disconnected clients and
+	  removing their pipe structures.
+
+2003-11-29 00:44  we7u
+
+	* src/x_spider.c: Filling in more details for x_spider.  Not
+	  functional yet.
+
+2003-11-29 00:10  we7u
+
+	* src/: x_spider.c, x_spider.h: More of the x_spider server code
+	  filled in.  Not functional yet.
+
+2003-11-28 22:34  we7u
+
+	* src/: Makefile.am, x_spider.c, x_spider.h: Initial code for
+	  x_spider server.  This is an APRS multiplexer that will
+	  eventually allow multiple other clients (Xastir or otherwise) to
+	  connect to a running Xastir and TX/RX APRS data between them.
+	  This will allow the other clients to share the TNC, AX.25, and
+	  network ports that Xastir is hooked up to.  The code is not
+	  functional in that capacity yet, but it is a nice multi-connect
+	  echo server as it stands.
+
+2003-11-28 22:26  we7u
+
+	* src/: map_gdal.c, maps.c: Adding prototype for draw_ogr_map().
+	  No real code yet.
+
+2003-11-28 22:10  we7u
+
+	* src/main.c: Fix for the stupid "PACKAGE" warnings that the GDAL
+	  include file causes.	Fix figured out originally by Jack for the
+	  ImageMagick stuff, duplicated by me in the GDAL include area.
+
+2003-11-28 21:57  we7u
+
+	* src/main.c: Slowing down the UpdateTime() loop iteration.  Some
+	  systems (RedHat/FreeBSD) appear to use up a lot of CPU time if
+	  this is set to '1' or '0'.  Setting it to '2'.  Will crank it up
+	  some more if people still report high CPU usage.
+
+2003-11-28 14:55  kd6zwr
+
+	* src/: main.c, map_gdal.c, maps.c: Cleaning up GDAL init, starting
+	  gdal code.
+
+2003-11-26 18:47  we7u
+
+	* src/maps.c: Changing from strstr() to strncmp() for matching
+	  selected directories with files inside them.	Much more exact.
+
+2003-11-26 14:10  we7u
+
+	* src/main.c: Clearing the selected bits in the in-memory map index
+	  before we try to resync with the selected_maps.sys file's idea of
+	  what maps are selected.
+
+2003-11-26 12:04  we7u
+
+	* INSTALL: Adding GDAL instructions (not that there's much that can
+	  be done with it yet, but it's still nice to see the future list
+	  of supported map formats on startup!).
+
+2003-11-26 09:37  we7u
+
+	* src/maps.c: Getting rid of compiler warning when XPM is not
+	  available.  This fix makes sure that the snapshot thread doesn't
+	  even get defined in that case.
+
+2003-11-26 09:00  we7u
+
+	* src/testawk.c: Fixing another couple of compiler warnings.
+
+2003-11-26 08:54  we7u
+
+	* src/awk.c: Fixing more compiler warnings.  Trivial stuff.
+
+2003-11-26 08:43  we7u
+
+	* src/maps.c: Getting rid of another compiler warning.
+
+2003-11-26 08:35  we7u
+
+	* src/map_tif.c: Getting rid of compiler warnings.
+
+2003-11-26 08:29  we7u
+
+	* src/maps.c: Getting rid of compiler warnings and removing dead
+	  code.
+
+2003-11-26 08:25  we7u
+
+	* src/map_tiger.c: Fixing a compiler warning, although I can't for
+	  the life of me figure out why the compiler is confused.  Perhaps
+	  all of the #ifdef's confused it.
+
+2003-11-26 08:14  we7u
+
+	* src/map_shp.c: Fixing a compiler warning.
+
+2003-11-26 08:01  we7u
+
+	* src/interface.c: Changing one variable to unsigned to get rid of
+	  a compiler warning.  We don't need a signed variable there
+	  anyway.
+
+2003-11-25 18:19  we7u
+
+	* src/main.c: Converting to square meters/feet when the CAD
+	  object's area is too small for miles/km.
+
+2003-11-25 14:34  n2ygk
+
+	* config/tgrlk.dbfawk: label color blue for water
+
+2003-11-25 14:14  we7u
+
+	* src/main.c: Making the End Draw Mode function write the CAD
+	  objects out to disk as well.	This makes it possible to save open
+	  polygons (polylines) instead of only closed polygons.
+
+2003-11-25 12:49  we7u
+
+	* src/main.c: Persistent CAD Objects.  They get save/restored
+	  to/from file now.
+
+2003-11-25 10:32  we7u
+
+	* src/db.h: Changing the saved polygon area from an int to a float.
+
+2003-11-25 10:31  we7u
+
+	* src/main.c: Leaving the calculations in square nautical miles
+	  until we're finished, then converting to what the user needs.
+	  Saving the area now in the object in units of square kilometers.
+
+2003-11-25 10:01  we7u
+
+	* src/main.c: Issuing a popup message with the area measurement.
+
+2003-11-25 09:49  we7u
+
+	* src/main.c: More corrections to the area calculation.
+
+2003-11-25 09:33  we7u
+
+	* src/main.c: Forgot to add in the minus signs again.  Area should
+	  be closer to being correct now for polygons.
+
+2003-11-25 09:25  we7u
+
+	* src/main.c: Computing area of a polygon.  Correctly now I think.
+
+2003-11-25 07:29  we7u
+
+	* src/main.c: More CAD Drawing stuff.  We now only compute area on
+	  polygons with 3 or more points, and don't "close" a polygon
+	  unless it has 3 or more points.
+
+2003-11-25 07:14  we7u
+
+	* src/main.c: More CAD Drawing stuff.
+
+2003-11-25 07:05  n2ygk
+
+	* src/map_shp.c: update comments
+
+2003-11-25 00:46  we7u
+
+	* src/main.c: Beginnings of computing area for a drawn polygon.
+
+2003-11-24 23:42  we7u
+
+	* src/: db.c, db.h, main.c, main.h, util.c, util.h: First
+	  semi-functional implementation of CAD drawing functions.  No
+	  persistent storage has been implemented yet.
+
+2003-11-24 16:45  we7u
+
+	* src/maps.h: Exporting another function I'll need later in another
+	  module.
+
+2003-11-24 14:38  we7u
+
+	* src/main.c: Renaming one function.
+
+2003-11-24 14:33  we7u
+
+	* src/main.c: Changing a few comments.
+
+2003-11-24 13:55  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/datum.c, src/db.c,
+	  src/list_gui.c, src/main.c, src/main.h, src/maps.c,
+	  src/xa_config.c: Adding the capability to use the special UTM
+	  zones with a new UTM selection, instead of using them only for
+	  MGRS.  Seems some areas use them for regular UTM as well.
+
+2003-11-24 13:32  we7u
+
+	* src/main.c: Added more comments and some function prototypes for
+	  CAD objects.
+
+2003-11-24 12:49  we7u
+
+	* src/main.c: Non-blocking xfontsel code.  Main app keeps humming
+	  along now even when xfontsel is up and running.
+
+2003-11-24 11:20  rzg
+
+	* help/help-English.dat: Updates for recent changes.
+
+2003-11-24 10:35  we7u
+
+	* src/main.c: Added some comments to the xfontsel code.
+
+2003-11-24 10:24  n2ygk
+
+	* src/main.c: simplified implementation of xfontsel using popen.
+
+2003-11-23 23:07  we7u
+
+	* src/main.c: Added another comment regarding xfontsel and possible
+	  conversion to another thread.
+
+2003-11-23 22:50  we7u
+
+	* src/main.c: We now write the output of xfontsel back into the Map
+	  Label Font dialog via the use of an intermediate file we write to
+	  ~/.xastir/tmp.
+
+2003-11-23 21:50  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added xfontsel option to
+	  map label font dialog.
+
+2003-11-22 20:38  we7u
+
+	* src/main.c: More temporary CAD drawing changes.  These allow
+	  experimentation without the drawings disappearing.  Drawings do
+	  not survive pan or zoom though.
+
+2003-11-22 15:40  we7u
+
+	* src/main.c: Added crosshair cursor for Measure/Move modes, and
+	  pencil cursor for CAD Draw mode.
+
+2003-11-21 13:55  we7u
+
+	* src/db.c: Fixing a pointer problem that Jack Twilley found.  This
+	  one occurs when we're deleting expired stations from our database
+	  in time order.  We weren't saving a pointer to the next
+	  time-ordered record before free'ing the memory for the first.
+
+2003-11-16 22:14  we7u
+
+	* src/main.c: Adding some comments.  No code changes.
+
+2003-11-16 15:33  we7u
+
+	* README.MAPS: Added a note from Tom Russo regarding limitations of
+	  shpproj.
+
+2003-11-13 10:37  we7u
+
+	* src/main.c: Added an erase option for the CAD objects.
+	  Non-functional so far.
+
+2003-11-13 10:11  we7u
+
+	* src/main.c: Moving more menu stuff around.  Making it harder to
+	  move my station using the mouse.  Put Pan stuff in a submenu to
+	  make the main mouse menu shorter.
+
+2003-11-13 09:52  we7u
+
+	* src/main.c: More Draw CAD-mode stuff.
+
+2003-11-13 09:29  we7u
+
+	* src/main.c: More draw CAD objects stuff.  Not ready for
+	  prime-time yet.
+
+2003-11-13 08:16  we7u
+
+	* src/main.c: Moving the "Move my station here" menu option to the
+	  very bottom, more out of the way.
+
+2003-11-13 07:27  n2ygk
+
+	* config/nwsc_ddmmyy.dbfawk, config/nwsmzddmmyy.dbfawk,
+	  config/nwsozddmmyy.dbfawk, config/nwsw_ddmmyy.dbfawk,
+	  config/nwsz_ddmmyy.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrlpt.dbfawk,
+	  config/tgrlpy.dbfawk, config/tgrplc00.dbfawk,
+	  config/tgrwat.dbfawk, src/map_shp.c, src/maps.c, src/maps.h:
+	  Centered area polygon labels.  Use light blue for area label
+	  color.
+
+2003-11-12 13:23  we7u
+
+	* INSTALL: Changing some instructions to use "su -c" instead of
+	  "su" and "exit".
+
+2003-11-11 21:37  we7u
+
+	* src/main.c: Very preliminary etch-a-sketch mode.  Allows the
+	  operator to draw lines on top of the map display.  Eventually
+	  this will be turned into something useful.  Right now the lines
+	  disappear at the next screen refresh.
+
+2003-11-11 07:03  n2ygk
+
+	* config/: nwsc_ddmmyy.dbfawk, nwsmzddmmyy.dbfawk,
+	  nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk, nwsz_ddmmyy.dbfawk,
+	  tgrcty.dbfawk, tgrkgl.dbfawk, tgrlk.dbfawk, tgrlpt.dbfawk,
+	  tgrlpy.dbfawk, tgrplc00.dbfawk, tgrwat.dbfawk: "pattern" set to
+	  match X line attribute.  Also some other minor tweaking.
+
+2003-11-11 07:02  n2ygk
+
+	* src/map_shp.c: add default dbfawk when signature not found.
+	  change "pattern" to just be the X line attribute pattern (0, 1,
+	  or 2).
+
+2003-11-10 09:18  we7u
+
+	* src/main.c: Changing the default symbol to a dot.  Used to be the
+	  emergency symbol, which is probably not a good idea as a default.
+
+2003-11-10 08:39  we7u
+
+	* src/main.c: Saving/restoring comment and name fields when
+	  switching between different types of Create Object/Item dialogs.
+
+2003-11-10 07:20  n2ygk
+
+	* src/map_shp.c: Use 'fill_color' to fill polygons; 'color' for
+	  polygon border.
+
+2003-11-10 06:57  n2ygk
+
+	* config/: tgrlk.dbfawk, tgrlpt.dbfawk, tgrwat.dbfawk: fill_color
+
+2003-11-10 06:56  n2ygk
+
+	* config/: Makefile.am, tgrlpy.dbfawk, tgrplc00.dbfawk: More
+	  dbfawk's
+
+2003-11-10 06:55  n2ygk
+
+	* README.MAPS: use consistent style for variable names
+
+2003-11-08 17:42  jtwilley
+
+	* configure.ac, src/dbfawk.c, src/testawk.c: Tom Russo's patch to
+	  help dbfawk build under FreeBSD.
+
+2003-11-07 22:57  we7u
+
+	* src/main.c: Added some comments.
+
+2003-11-07 22:49  we7u
+
+	* src/main.c: Fixes for Map Chooser Properties buttons.  The string
+	  offset was incorrect after the strings were shortened.  Fixed
+	  now.
+
+2003-11-07 13:46  we7u
+
+	* src/maps.c: Fixing a problem whereby the weather alert filenames
+	  are guessed wrong if there are similarly-names zip files in the
+	  Counties directory.
+
+2003-11-07 10:15  we7u
+
+	* src/main.c: Fixing objects/items with respect to probability
+	  circles and multipoint polygons.  We can now do compressed
+	  objects/items with these features, and we get a space before the
+	  multipoint string, as the spec requires.
+
+2003-11-06 15:27  we7u
+
+	* src/db.c: Changing the extract_multipoints() function so that it
+	  doesn't remove the multipoint string from the comment field of
+	  objects or items.  This allows us to transmit the multipoint
+	  string every time we transmit the object/item.
+
+2003-11-06 15:26  we7u
+
+	* src/draw_symbols.c: Changed one comment.
+
+2003-11-06 09:21  we7u
+
+	* src/interface.c: OpenTrac bug-fix by Henk.  Thanks!
+
+2003-11-06 09:13  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/main.c: Fixing Map Properties columns for other languages.
+
+2003-11-06 09:02  we7u
+
+	* config/language-English.sys, src/main.c: Making Map Properites
+	  even narrower.
+
+2003-11-06 08:21  we7u
+
+	* src/main.c: Reorganizing the buttons on Map Chooser->Properties
+	  so that the dialog will be narrower.
+
+2003-11-06 07:56  we7u
+
+	* src/main.c: Moving some of the Map menu into a submenu.
+	  Lesser-used stuff now resides in a Configure submenu off the Map
+	  menu.
+
+2003-11-06 07:44  we7u
+
+	* config/language-English.sys: Changing a few labels in the menus.
+	  Minor stuff.
+
+2003-11-05 22:54  jtwilley
+
+	* config/tnc-startup.aea: Moved 'EXP on' to the top of the file and
+	  commented out lines which produce errors on my AEA PK-232.
+
+2003-11-05 10:35  we7u
+
+	* src/maps.c: Fixing the high CPU-usage bug with XDrawLines() in
+	  draw_grid with UTM grids.
+
+2003-11-05 10:10  we7u
+
+	* src/maps.c: Added an interation max to the while loop in
+	  draw_grid().	Just in case.
+
+2003-11-05 07:06  n2ygk
+
+	* src/map_shp.c: Fix WX alerts
+
+2003-11-04 15:24  we7u
+
+	* src/map_shp.c: Patch submitted by Tom Russo, KM5VY.  Allows
+	  dbfawk to control more than just color.
+
+2003-11-04 15:00  we7u
+
+	* src/main.c: Added a rather stupid fix for the problem: 'Error:
+	  attempt to add non-widget child "DropSiteManager" to parent
+	  "xastir"'.  Making a couple of harmless Motif calls before
+	  calling XtVaCreateWidget in create_appshell().
+
+2003-11-04 14:24  we7u
+
+	* src/map_geo.c: Wrapping a call with ifdef's for people that don't
+	  have ImageMagick compiled in.
+
+2003-11-04 14:20  we7u
+
+	* tigermap.geo: Adding this file so that Tigermap may be a normal
+	  option in the Map Chooser.
+
+2003-11-04 13:46  we7u
+
+	* src/main.c: Moving things around to different menus.	Cleaning up
+	  the interface just a bit.
+
+2003-11-04 11:28  we7u
+
+	* src/xa_config.c: Remembering Tigermap config settings between
+	  sessions.
+
+2003-11-04 09:17  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  src/main.c, src/map_tiger.c, src/xa_config.c, src/xastir.h:
+	  Making the regular Map Intensity controls work for the TigerMap
+	  intensity as well.  Simplifying the user interface a bit.
+
+2003-11-04 08:46  we7u
+
+	* Makefile.am, src/main.c, src/main.h, src/map_geo.c,
+	  src/map_tiger.c, src/xa_config.c: Moving Tigermap enable to the
+	  Map Chooser (so that all maps are selected/deselected from one
+	  dialog).  Removed the Enable button from the Tigermap config
+	  dialog.
+
+2003-11-03 13:22  we7u
+
+	* src/location_gui.c: Removing unnecessary db.h include.
+
+2003-11-03 13:22  we7u
+
+	* src/: bulletin_gui.c, datum.c, db.c, db.h, gps.c, interface.c,
+	  interface_gui.c, list_gui.c, locate_gui.c, main.c, messages.c,
+	  messages_gui.c, track_gui.c, util.c, util.h, view_message_gui.c,
+	  wx.c, xa_config.c: Fixed the problem with coordinate calc and
+	  inputting UPS coordinates.  Moved some routines from db.c to
+	  util.c that were general-purpose string routines.  Got rid of
+	  unnecessary db.h includes.
+
+2003-11-03 12:59  we7u
+
+	* src/main.c: Added a debug line.
+
+2003-11-03 11:04  we7u
+
+	* src/util.c: Fixing the "nice" formatting for UTM so that extra
+	  spaces aren't added on the status line for MGRS coordinates.
+
+2003-11-03 10:59  we7u
+
+	* src/: datum.c, db.c, list_gui.c, main.c, util.c, util.h: Cleaning
+	  up the MGRS_string stuff.  Formatting the string nicely for the
+	  Coordinate Calculator.
+
+2003-11-03 09:19  we7u
+
+	* src/datum.c: Fixed utm_ups_to_ll() function for the south polar
+	  region.
+
+2003-11-03 09:13  we7u
+
+	* src/util.c: Switching back to original math.
+
+2003-11-03 08:33  we7u
+
+	* src/datum.c: Added a comment about the problems with
+	  utm_ups_to_ll() function in the south polar region.
+
+2003-11-03 08:14  we7u
+
+	* src/main.c: Adding MGRS to Coordinate Calculator as an output
+	  format.  Still has problems in the south polar region, but other
+	  than that it appears to work properly.
+
+2003-11-03 08:10  we7u
+
+	* src/util.c: Switching to MGRS zones when doing MGRS conversions,
+	  and restoring the "coordinate_system" variable when done.
+	  Changed some math to make it more understandable what was going
+	  on.
+
+2003-11-03 08:08  we7u
+
+	* src/datum.c: Changed a comment.
+
+2003-11-01 10:57  we7u
+
+	* src/util.c: Correct 2-letter digraphs now for the UPS regions
+	  while using MGRS coordinates.
+
+2003-10-31 21:15  we7u
+
+	* src/util.c: Changing the formatting for MGRS.
+
+2003-10-31 16:35  we7u
+
+	* src/util.c: MGRS appears to be functional in the UTM area.  Still
+	  needs work in the UPS (polar) areas.
+
+2003-10-31 15:35  we7u
+
+	* src/: datum.c, datum.h, db.c, list_gui.c, main.c, main.h, maps.c,
+	  util.c, util.h, xa_config.c: Initial code for implementing MGRS
+	  coordinates.	Not quite ready for prime-time yet.
+
+2003-10-31 15:34  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding a label for
+	  selecting MGRS coordinates.
+
+2003-10-30 14:32  we7u
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding Max/Min
+	  Zoom headings to Map Chooser->Properties dialog for other
+	  language files.
+
+2003-10-30 10:50  we7u
+
+	* src/xa_config.c: More error-checking for lat/long as read in from
+	  the config file.  In case someone hand-edits the station location
+	  and gets the format wrong.
+
+2003-10-29 19:38  we7u
+
+	* src/maps.c: Fixing the edges of the earth, UTM grid style.
+
+2003-10-29 13:03  we7u
+
+	* src/: datum.c, datum.h, maps.c: Fixing the UTM grid.	Added
+	  "MGRS_grid" variable.  If set, we draw the irregular grids and
+	  report UTM coordinates using those grids.  If zero, we draw the
+	  regularly-spaced six-degree zones and report using those regular
+	  zones.
+
+2003-10-29 12:50  we7u
+
+	* src/maps.c: Correcting UTM grid for the civilian UTM grid
+	  (non-MGRS grid).
+
+2003-10-29 12:27  we7u
+
+	* src/main.c: Saving our place in the Map Properties dialog.  No
+	  more scrolling trying to get back to where you were.
+
+2003-10-29 11:59  we7u
+
+	* src/main.c: Commenting out debug code.
+
+2003-10-29 11:51  we7u
+
+	* src/main.c: Commenting out a debug line.
+
+2003-10-29 11:23  we7u
+
+	* src/maps.c: Adding code to migrate from old map_index.sys format
+	  to the new format.  Accepts either 8 or 10 parameters per line
+	  and writes out the new 10-parameter format if the 8-parameter
+	  format is found.  Swapped the max_zoom and min_zoom parameters to
+	  further down the data line.
+
+2003-10-28 22:26  jtwilley
+
+	* config/language-English.sys, src/main.c, src/maps.c, src/maps.h:
+	  Added support for max/min zoom levels.  Work still needs to be
+	  done on removing existing zoom-level-sensitive code and
+	  supporting other languages.
+
+2003-10-28 16:35  we7u
+
+	* src/main.c: Moved the "XtRealize" call down lower in the routine,
+	  after the size has been specified.  This is to help get rid of
+	  the "Error: Shell widget xastir has zero width and/or height"
+	  problem that some users have been having.
+
+2003-10-28 16:29  we7u
+
+	* src/main.c: Moving the "manage" call for the main app down lower
+	  after the size of the widget has been specified.  Attempting to
+	  get rid of the "Error: Shell widget xastir has zero width and/or
+	  height" problem that some users are still having.
+
+2003-10-28 15:46  we7u
+
+	* src/xa_config.c: Setting screen_height and screen_width to
+	  minimums of 40 and 100.
+
+2003-10-28 15:20  we7u
+
+	* src/main.c: Getting rid of the auto-clear function for the map
+	  chooser topo and vector buttons.  They are now additive instead
+	  of exclusive.
+
+2003-10-28 07:02  n2ygk
+
+	* src/list_gui.c: Fix X crash when list width/height somehow get
+	  set to zero.
+
+2003-10-27 17:40  rzg
+
+	* INSTALL, README.MAPS: Minor updates. I'm still around. :-)
+
+2003-10-23 12:48  uid74947
+
+	* src/maps.c: Another comment.
+
+2003-10-22 17:30  we7u
+
+	* src/maps.c: Comment changes.
+
+2003-10-22 17:22  we7u
+
+	* src/maps.c: More comments.
+
+2003-10-22 17:19  we7u
+
+	* src/maps.c: Changing the scale at which the UTM subgrid starts to
+	  be drawn.  We weren't drawing it properly at scales of 2048 and
+	  up anyway.
+
+2003-10-22 17:15  we7u
+
+	* src/maps.c: More comment changes.
+
+2003-10-22 16:44  we7u
+
+	* src/maps.c: Adding comments.	More checking for invalid numbers
+	  in draw_grid().
+
+2003-10-22 16:19  we7u
+
+	* src/maps.c: Commenting out some debug lines.
+
+2003-10-22 16:06  we7u
+
+	* src/maps.c: Fixing another bug in draw_grid() that caused a
+	  segfault while drawing UTM grids.  Added more debug and comments.
+	  The segfault fix causes some grid lines to get skipped but
+	  that's better than a segfault.
+
+2003-10-22 14:39  we7u
+
+	* src/maps.c: More comment changes.
+
+2003-10-22 14:08  we7u
+
+	* src/maps.c: Correcting some comments.
+
+2003-10-22 13:53  we7u
+
+	* src/maps.c: Correcting some comments based on input from Peter
+	  Dana.
+
+2003-10-22 13:50  we7u
+
+	* src/maps.c: Added another comment.
+
+2003-10-22 12:50  we7u
+
+	* src/maps.c: Adding lots of comments in the draw_grid() function.
+	  Trying to understand Olivier's code for drawing UTM grids, so it
+	  can be improved in the areas of major grid intersections, and in
+	  handling the irregular zone widths.
+
+2003-10-22 11:43  we7u
+
+	* src/maps.c: Changed some comments.
+
+2003-10-22 09:33  we7u
+
+	* src/maps.c: Last log message should have said:  Changed/updated
+	  some comments.  No code changes.  Same for this log message.
+
+2003-10-22 09:32  we7u
+
+	* src/maps.c: [no log message]
+
+2003-10-22 06:57  n2ygk
+
+	* README.MAPS, config/tgrlpt.dbfawk, src/map_shp.c: dbfawk symbol
+	  support for point shapefiles
+
+2003-10-21 08:22  n2ygk
+
+	* src/map_shp.c: duh - sym[4] to fit the null at the end!
+
+2003-10-21 08:21  n2ygk
+
+	* src/map_shp.c: sym[3] to allow for overlay char too
+
+2003-10-21 08:20  n2ygk
+
+	* README.MAPS: document "roll your own shapefile maps"
+
+2003-10-19 15:31  we7u
+
+	* src/main.c: Added a comment.	No code changes.
+
+2003-10-19 15:28  we7u
+
+	* src/maps.c: Changing the UTM/UPS grid so that only two zones each
+	  are drawn at the poles (in the UPS region).
+
+2003-10-19 15:26  we7u
+
+	* src/datum.c: Fixing the output zone number in the UPS regions to
+	  "00".
+
+2003-10-17 23:13  we7u
+
+	* src/maps.c: Tweaking the UTM grid so that it extends to the
+	  poles, now that I know what the UPS grid (near the poles) should
+	  look like.
+
+2003-10-17 22:55  we7u
+
+	* src/: datum.c, datum.h, main.c, map_geo.c, maps.c, util.c:
+	  Implemented proper UTM/UPS to Lat/Long conversions.  Also fixed
+	  the coordinate calculator so it would accept UPS coordinates.
+
+2003-10-17 21:49  we7u
+
+	* src/: datum.c, datum.h, main.c, map_geo.c, maps.c, util.c:
+	  Implemented proper UPS output, when using UTM/UPS and near the
+	  poles.
+
+2003-10-17 20:22  we7u
+
+	* src/datum.c: Temporarily making the easting and northing for the
+	  UPS areas (near the poles) equal to all zeroes.  This is to
+	  prevent someone thinking that the numbers we're showing are valid
+	  coordinates.	We haven't been computing proper coordinates in the
+	  UPS areas.  Am still working on the problem and hope to have
+	  valid UPS numbers by the end of the weekend.
+
+2003-10-17 14:21  we7u
+
+	* src/datum.c: Changed some comments.  Added some output if we're
+	  trying to convert a UPS coordinate to Lat/Long.
+
+2003-10-17 13:39  we7u
+
+	* src/: datum.c, datum.h: Changed utm_letter_designator() to
+	  properly handle the zones for UPS grid.  Still need to get the
+	  easting/northing numbers to work right, but the zone letters are
+	  now correct.
+
+2003-10-17 12:50  we7u
+
+	* src/datum.c: Modified utm_letter_designator() function so that
+	  'Z' is displayed above 84N, and 'A' is displayed below 80S.  It's
+	  better than it was, but we still need to implement full UPS
+	  coordinate systems in the pole regions.
+
+2003-10-17 12:38  we7u
+
+	* src/main.c: Tweaking TrackMouse() so that the coordinates stop
+	  changing when the mouse goes off the edge of the earth.
+
+2003-10-17 08:21  n2ygk
+
+	* src/map_shp.c: still incomplete attempt at handling fill styles.
+
+2003-10-17 08:19  n2ygk
+
+	* config/: Makefile.am, tgrlpt.dbfawk: add tgrlpt (Tiger/Line
+	  landmark points)
+
+2003-10-17 08:18  n2ygk
+
+	* config/tgrlk.dbfawk: add complete documentation of CFCC codes
+
+2003-10-17 02:13  we7u
+
+	* bootstrap.sh: Added a line to remove the autom4te.cache directory
+	  and contents.  This sometimes gets in the way when running
+	  autoheader, and I have to delete it manually in that case.  No
+	  more.
+
+2003-10-16 16:38  we7u
+
+	* src/map_geo.c: Excluding map indexing from being able to set the
+	  map refresh interval.
+
+2003-10-16 16:09  we7u
+
+	* src/: map_gdal.c, maps.c: Minor comment changes.
+
+2003-10-16 15:59  we7u
+
+	* src/: map_gdal.c, maps.c: Dumping out map types on startup.
+
+2003-10-16 14:48  we7u
+
+	* src/map_gdal.c: Changed comments.  No code changes.
+
+2003-10-16 14:44  we7u
+
+	* configure.ac: Moving the GDAL stuff after shapelib and
+	  libgeotiff.  We want GDAL to get linked AFTER the other
+	  libraries, at least until we get GDAL fully integrated.  If GDAL
+	  is linked earlier than these other libraries, function calls get
+	  made to GDAL instead of the correct libraries.
+
+2003-10-16 14:42  we7u
+
+	* src/map_tif.c: Added more debugging output.
+
+2003-10-16 14:39  we7u
+
+	* src/maps.c: Added more debug info.
+
+2003-10-16 14:11  we7u
+
+	* src/map_gdal.c: Minor stuff, getting ready to try to open a file.
+
+2003-10-16 12:40  we7u
+
+	* src/map_gdal.c: Printing out OGR drivers as well now.
+
+2003-10-16 12:33  we7u
+
+	* src/map_gdal.c: Nicer formatting for the GDAL drivers.
+
+2003-10-16 12:30  we7u
+
+	* src/map_gdal.c: Better formatting for listing GDAL drivers.
+	  Starting to add code to list OGR drivers as well.
+
+2003-10-16 11:58  we7u
+
+	* src/map_gdal.c: Print out a list of all registered GDAL drivers
+	  upon Xastir startup.
+
+2003-10-16 09:56  we7u
+
+	* src/map_gdal.c: Moved the #warning text inside the #ifdef block.
+	  Will only see the warning if GDAL is installed and usable on your
+	  system.
+
+2003-10-16 09:48  we7u
+
+	* src/map_gdal.c: Minor changes to comments.  Removed a #define
+	  that shouldn't have been committed.
+
+2003-10-16 09:42  we7u
+
+	* src/map_gdal.c: Added example code snippets from the GDAL
+	  tutorial.
+
+2003-10-16 09:07  we7u
+
+	* configure.ac, src/main.c, src/map_gdal.c, src/maps.h: More
+	  initial framework for GDAL integration.  Now adds it to the list
+	  of supported libraries in "configure", and adds the library to
+	  the link line.
+
+2003-10-16 08:30  we7u
+
+	* src/Makefile.am: Adding map_gdal.c to the list of files.
+
+2003-10-16 08:29  we7u
+
+	* src/map_gdal.c: Adding initial file framework for integrating the
+	  GDAL library.  No real code here yet.
+
+2003-10-14 13:49  we7u
+
+	* src/map_geo.c: Another #ifdef fix regarding raster_map_intensity.
+
+2003-10-14 13:44  we7u
+
+	* src/main.c: More #ifdef cleanup regarding raster_map_intensity.
+
+2003-10-14 13:37  we7u
+
+	* src/: main.c, maps.h, xa_config.c: Fixing #ifdef's, consistent
+	  with new uses of raster_map_intensity variable (used to be
+	  geotiff_map_intensity).
+
+2003-10-13 14:46  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/draw_symbols.c,
+	  src/draw_symbols.h, src/main.c, src/main.h, src/xa_config.c:
+	  Implementing Henk de Groot's icon outline code.  Added code to
+	  make the changes instantly visible in the drawing area.  Thanks
+	  Henk!
+
+2003-10-13 14:30  we7u
+
+	* src/: main.c, map_geo.c, map_tif.c, maps.c, maps.h, xa_config.c:
+	  Attached geo files to the raster intensity variable, so they can
+	  be darkened from the menus now.  Had to hard-code toposerver
+	  images to be 100% brightness though, as the colors get strange on
+	  that particular image.  Other images can be fixed by adding the
+	  "modulate" tag to the .geo file, if this problem should surface
+	  elsewhere.
+
+2003-10-13 13:22  we7u
+
+	* src/maps.c: More efficient snapshot code:  Moved the .geo code
+	  back into the separate thread now that the symbol-blanking bug is
+	  fixed.
+
+2003-10-13 12:57  we7u
+
+	* src/maps.c: Fixed snapshots so that .geo file creation works
+	  without blanking symbols on the screen.  The code was leaving
+	  incorrect values in global variables that were later used by the
+	  symbol drawing code.
+
+2003-10-13 10:57  we7u
+
+	* src/: main.c, maps.c, xastir.h: Fixing the
+	  symbols-going-away-after-snapshot problem.  Unfortunately it
+	  appears that the .geo code for snapshots is the problem.  Will
+	  have to figure out why yet and then reinstate that part of the
+	  code.
+
+2003-10-12 21:22  we7u
+
+	* src/: main.c, maps.c, xastir.h: Attempting to fix the snapshot
+	  problem where stations disappear off the display.  Created
+	  another Pixmap:  pixmap_snapshot, and copy pixmap_final to it
+	  just before the snapshot thread is started.  This should separate
+	  any accesses to the data so that no conflicts occur while making
+	  the snapshot.
+
+2003-10-09 19:20  we7u
+
+	* src/maps.c: Tweaking the width of the equator line in UTM grid
+	  (again).
+
+2003-10-09 19:14  we7u
+
+	* src/maps.c: Minor changes to equator/prime meridian again for
+	  UTM.
+
+2003-10-09 18:41  we7u
+
+	* src/maps.c: Changing line widths for the lat/long grid and the
+	  major UTM zones to width 2.  This makes them more noticeable
+	  against the smaller UTM subgrid and against map lines.
+
+2003-10-09 13:16  we7u
+
+	* src/maps.c: Changing the color for lat/long grids as well so that
+	  they work with the gc_tint stuff and show up on maps well.
+
+2003-10-09 13:09  we7u
+
+	* src/maps.c: Changing to gc_tint for map grids so that the grid
+	  can always be seen on top of maps.
+
+2003-10-09 12:52  we7u
+
+	* src/maps.c: Switching to purple lines as they show up well on
+	  topo and terraserver maps.
+
+2003-10-09 12:47  we7u
+
+	* src/maps.c: Changing the smaller UTM grids to display in bright
+	  yellow.  Easier to see on maps.
+
+2003-10-09 09:18  we7u
+
+	* src/maps.c: Initial attempt at finer UTM grids, using preliminary
+	  code by Olivier Calle (N7TAP).  The code handles the irregular
+	  regions near/above Norway for the major UTM grid zones only (not
+	  for the minor grids yet).  There are known problems near the zone
+	  boundaries with lines not getting drawn or incorrect lines
+	  getting drawn.  For the most part, if you're inside a zone and
+	  not in the irregular zone area, this code works very well, and is
+	  very fast!
+
+2003-10-09 09:03  we7u
+
+	* src/: db.c, main.c, map_geo.c: Changing a few printf's to
+	  fprintf's.
+
+2003-10-08 12:48  we7u
+
+	* src/maps.c: Simplified code for drawing UTM grid.
+
+2003-10-08 12:12  we7u
+
+	* src/maps.c: Changing the UTM grid to dashed lines instead of
+	  solid.
+
+2003-10-08 11:31  we7u
+
+	* src/maps.c: Proper UTM grid, including irregular areas near
+	  Norway.  Area from 84N to 90N and 80S to 90S is still in
+	  question, as that is in the UPS coordinate system area (the
+	  poles).  Also, the UTM coordinates on the status line are
+	  incorrect when the mouse pointer is moved into these areas.
+
+2003-10-08 10:16  we7u
+
+	* src/maps.c: More draw_vector stuff.  Both Xastir coordinate
+	  system and lat/long vector drawing functions work now.  Still
+	  need to work on the "is it in the view" code, as it's not working
+	  correctly..
+
+2003-10-08 09:42  we7u
+
+	* src/maps.c: Added more UTM grid comments.
+
+2003-10-08 09:37  we7u
+
+	* src/maps.c: Adding a new draw_vector() function, which I'll use
+	  for drawing the UTM grid shortly.  Changed/added a bunch of
+	  comments in draw_grid() regarding UTM.
+
+2003-10-07 12:59  we7u
+
+	* src/maps.c: Changed some comments.
+
+2003-10-07 11:51  we7u
+
+	* src/maps.c: Tweaked the boundary checks before the XDrawLine
+	  call.  Added/changed some comments regarding UTM grid.
+
+2003-10-06 19:41  we7u
+
+	* src/maps.c: Initial UTM grid attempt.  This mod causes the six
+	  degree vertical lines to be drawn that define the major UTM
+	  zones.  It will draw them if the map grid is enabled and UTM is
+	  the selected coordinate system.
+
+2003-10-02 16:51  we7u
+
+	* src/db.c: Fixing the Pmin/Pmax stuff so that it gets transmitted
+	  properly across the air.
+
+2003-10-02 13:21  we7u
+
+	* src/maps.c: Xastir now creates a snapshot.geo file corresponding
+	  to the snapshot.png file.
+
+2003-10-02 10:08  we7u
+
+	* README.win32: Added a note about removing the "-local" option for
+	  nasd.
+
+2003-10-02 07:09  n2ygk
+
+	* src/main.c: Duh.  Hung Map_font off of Gamma_correct button.
+
+2003-09-30 06:57  n2ygk
+
+	* INSTALL, README.MAPS: document dbfawk
+
+2003-09-28 15:39  n2ygk
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Add map label font
+	  selection (please translate these!)
+
+2003-09-28 00:03  we7u
+
+	* src/xastir.h: Minor tweak to fix a compile problem in main.c with
+	  sizeof().
+
+2003-09-27 07:18  n2ygk
+
+	* config/language-English.sys, src/awk.c, src/awk.h, src/dbfawk.c,
+	  src/main.c, src/map_shp.c, src/maps.c, src/xa_config.c,
+	  src/xastir.h: Add user-selectable MAPS_LABEL_FONT.  Add
+	  dbfawk-selectable label color.  Add "skip" keyword to dbfawk to
+	  permit overriding bad shapefile dbf data.
+
+2003-09-26 16:34  we7u
+
+	* README.win32: Clarified that maps can go in the maps directory
+	  and subdirectories thereof.
+
+2003-09-26 16:26  we7u
+
+	* README.win32: Added a note about possible problems with IM-5.5.7.
+
+2003-09-26 16:22  we7u
+
+	* README.MAPS: Specified where the sound files go.
+
+2003-09-26 10:06  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added an "Apply" button
+	  to the Map Chooser that applies the changes immediately without
+	  destroying the Map Chooser.
+
+2003-09-26 09:16  we7u
+
+	* README.win32: Added note about Perl 5.8 and page faults while
+	  compiling.
+
+2003-09-19 16:48  we7u
+
+	* README.win32: Added a note about ImageMagick being necessary to
+	  view .geo maps.
+
+2003-09-19 16:41  we7u
+
+	* README.win32: Added a Win2k note.
+
+2003-09-19 16:34  we7u
+
+	* README.win32: Minor edits.
+
+2003-09-19 16:06  we7u
+
+	* README.win32: Added to more XFree86 packages to the selections.
+
+2003-09-19 15:40  we7u
+
+	* README.win32: Better fix for the _reent bug.
+
+2003-09-19 15:37  we7u
+
+	* README.win32: Added another note about the _reent bug.
+
+2003-09-19 10:58  we7u
+
+	* README.MAPS: Minor changes to the download NOAA weather alert
+	  maps section.
+
+2003-09-19 10:57  we7u
+
+	* src/util.c: Caused the code to recognize "NWS_" as valid.  Didn't
+	  appear to be doing so, which might have been knocking out a lot
+	  of compressed weather alerts.
+
+2003-09-19 10:57  we7u
+
+	* src/db.c: Changed some comments.
+
+2003-09-19 10:56  we7u
+
+	* src/alert.c: Minor changes to comments and added another possible
+	  case for SOLAR that can get parsed (don't know if it'll ever get
+	  used).
+
+2003-09-18 12:38  we7u
+
+	* src/main.c: Setting the initial symbol to be a hiker when
+	  creating new object/item with probability circle toggle enabled.
+
+2003-09-18 12:04  we7u
+
+	* src/: main.c, db.c: Working implementation of SAR probability
+	  circles.
+
+2003-09-17 17:24  we7u
+
+	* src/: db.c, db.h, draw_symbols.c, draw_symbols.h, main.c: Half of
+	  an implementation for drawing Search & Rescue probability
+	  circles.  Have the encoding parts and display parts done.  Next
+	  need to do the decoding so that the circles show up on the map.
+
+2003-09-16 10:46  we7u
+
+	* src/xastir.h: Adding preliminary support for the libgc garbage
+	  collection library.  Disabled by default.  This gives automatic
+	  garbage collection of unused memory space to Xastir.	During long
+	  runtimes, this seems to improve memory usage a bit.
+
+2003-09-16 10:13  we7u
+
+	* src/map_geo.c: Fixing trans_skip for the non-ImageMagick case.
+
+2003-09-15 11:49  we7u
+
+	* README.win32: Very minor wording change in the CVS instructions.
+
+2003-09-12 07:48  n2ygk
+
+	* configure.ac, src/dbfawk.c, src/map_shp.c: properly
+	  conditionalize WITH_DBFAWK.  More dbfawk tweaks in map_shp
+
+2003-09-11 15:04  jtwilley
+
+	* src/dbfawk.c: Added check for DBFAWK define.
+
+2003-09-11 13:19  n2ygk
+
+	* config/nwsc_ddmmyy.dbfawk, src/map_shp.c: Fix a stupid error in
+	  symtbl
+
+2003-09-10 13:53  rzg
+
+	* help/help-English.dat: whatsnew update
+
+2003-09-10 13:27  kd6zwr
+
+	* README.MAPS, help/help-English.dat, src/map_geo.c, src/maps.h:
+	  Changing TRANSPARENT geo tag to accept a user defined color to
+	  zap.
+
+2003-09-09 06:56  n2ygk
+
+	* config/nwsc_ddmmyy.dbfawk, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrwat.dbfawk, src/map_shp.c: more
+	  dbfawk tweaking
+
+2003-09-08 07:37  n2ygk
+
+	* config/nwsc_ddmmyy.dbfawk, config/nwsozddmmyy.dbfawk,
+	  config/nwsw_ddmmyy.dbfawk, config/nwsz_ddmmyy.dbfawk,
+	  src/map_shp.c: more dbfawk tweaks.  WX alerts now search
+	  properly.
+
+2003-09-05 14:25  we7u
+
+	* src/main.c: Removed some unneeded comments.
+
+2003-09-05 14:12  we7u
+
+	* src/main.c: Taking out the Move/Measure menu prevention logic for
+	  the case where the mouse buttons are _not_ swapped.
+
+2003-09-05 13:20  we7u
+
+	* src/main.c: Preventing the mouse menu from coming up if SWAP
+	  buttons is enabled and we're doing the Move or Measure functions.
+
+2003-09-05 12:47  we7u
+
+	* src/main.c: Added another define that allows moving the mouse
+	  menu to button1.
+
+2003-09-05 12:07  we7u
+
+	* src/main.c: Swapping zoom/pan buttons so that zoom buttons are
+	  more often on the screen with a small window size.
+
+2003-09-05 06:56  n2ygk
+
+	* config/: Makefile.am, nwsc_ddmmyy.dbfawk, nwsmzddmmyy.dbfawk,
+	  nwsozddmmyy.dbfawk, nwsw_ddmmyy.dbfawk, nwsz_ddmmyy.dbfawk: First
+	  pass at handling WX alerts with dbfawk
+
+2003-09-04 23:37  we7u
+
+	* src/main.c: Added some notes about xmodmap for swapping mouse
+	  buttons in a touchscreen configuraton.
+
+2003-09-04 15:48  we7u
+
+	* config/language-English.sys: Making Z-In/Z-Out labels shorter to
+	  help fit on 640x480 LCD screen.
+
+2003-09-04 15:28  we7u
+
+	* src/main.c: Changing the optional SMALL system font.
+
+2003-09-04 14:39  n2ygk
+
+	* src/testawk.c: Make it compile even without DBFAWK
+
+2003-09-04 14:22  we7u
+
+	* INSTALL: Added a bit more about libgeotiff's private include
+	  directory.
+
+2003-09-04 11:00  we7u
+
+	* src/main.c: Another tweak for fixed-size small displays.  This
+	  new define forces dialogs to pop up over the main application,
+	  near the left top corner.
+
+2003-09-04 10:11  we7u
+
+	* src/main.c: Adding an option for a much smaller default system
+	  font.  Useful for smaller displays.
+
+2003-09-04 10:10  we7u
+
+	* config/language-English.sys: Making Zoom buttons smaller by
+	  shortening the string.  Needed for smaller displays.
+
+2003-09-04 09:40  we7u
+
+	* src/: main.c, xa_config.c: Allowing much smaller screen sizes for
+	  Xastir.  It should start up in roughly the same size as saved now
+	  also.
+
+2003-09-04 09:18  we7u
+
+	* src/main.c: Changing the minimum size for the main window down to
+	  1/4 VGA.  This allows it to be resized much smaller than before.
+	  Useful for fixed-size LCD displays.
+
+2003-09-04 09:11  we7u
+
+	* FAQ: Added a few more words about why stations might not appear
+	  on the screen.
+
+2003-09-04 07:38  n2ygk
+
+	* src/map_shp.c: more dbfawk tweaking
+
+2003-09-03 17:01  we7u
+
+	* INSTALL: Revised the libgeotiff instructions slightly.
+
+2003-09-03 12:37  we7u
+
+	* README.win32: Added "touch .cvspass" to the instructions.  Some
+	  Windows boxes fail without this.
+
+2003-09-03 11:26  kd6zwr
+
+	* README.MAPS, help/help-English.dat: Documenting the new
+	  TRANSPARENT and CROP .geo file tags.
+
+2003-09-03 08:19  n2ygk
+
+	* configure.ac, src/Makefile.am, src/awk.c, src/dbfawk.c,
+	  src/dbfawk.h, src/map_shp.c, src/testawk.c: change to use
+	  WITH_DBFAWK.	dbfawk now searches for mapfilename.dbfawk before
+	  looking in config/*.dbfawk, enabling map-specific special cases.
+
+2003-09-03 00:28  kd6zwr
+
+	* src/: map_geo.c, maps.h: Adding TRANSPARENT and CROP tags to the
+	  geo file.  First cut at transparent, needs to be augmented to
+	  allow a list of colors to zap.
+
+2003-09-02 16:43  jtwilley
+
+	* configure.ac: Moved AM_INIT_AUTOMAKE and added arguments.
+
+	  Added documentation for AM_INIT_AUTOMAKE.
+
+2003-09-02 14:05  n2ygk
+
+	* config/tgrcty.dbfawk, src/map_shp.c: tgrcty: fix Louisiana FIPS
+	  code map_shp: start adding layer setting via dbfawk too
+
+2003-09-02 10:50  we7u
+
+	* README.win32: Added another comment about "nano" being more
+	  user-friendly than "vi", for people coming from a Windows
+	  background.
+
+2003-08-30 13:41  jtwilley
+
+	* src/awk.c: Added reference to <sys/types.h> to match dbfawk.c
+
+2003-08-29 09:50  n2ygk
+
+	* configure.ac, config/Makefile.am, config/tgrcty.dbfawk,
+	  config/tgrkgl.dbfawk, config/tgrlk.dbfawk, config/tgrwat.dbfawk,
+	  src/Makefile.am, src/awk.c, src/awk.h, src/dbfawk.c,
+	  src/dbfawk.h, src/gps.c, src/map_shp.c, src/testawk.c,
+	  src/tgrcty.dbfawk, src/tgrkgl.dbfawk, src/tgrlk.dbfawk: gps.c:
+	  handle spurious compile time warning everything else: add dbfawk
+	  support for shapefile maps.  Enable with:	./configure
+	  --with-dbfawk
+
+2003-08-22 21:37  we7u
+
+	* src/interface_gui.c: Adding another #include, needed for usleep()
+	  call.
+
+2003-08-21 15:01  we7u
+
+	* src/db.c: Changed some comment formatting.
+
+2003-08-21 14:10  we7u
+
+	* src/interface_gui.c: Adding a delay after shutting down a port
+	  before it is brought up again.  These delays are in the
+	  interfaces->properties menu when changing an interface that's
+	  running.
+
+2003-08-21 12:31  we7u
+
+	* src/: db.c, db.h: Added a new flag to WeatherRow called wx_storm.
+	  We wet it when we find any kind of a severe storm, then use that
+	  flag in our logic that decides how to draw things.  This gets rid
+	  of wind barbs for some severe storms.
+
+2003-08-21 11:01  we7u
+
+	* scripts/inf2geo.pl: New revisions by ZL2UMF.	Thanks!
+
+2003-08-21 09:42  we7u
+
+	* src/igate.c: We now drop generic queries heading to RF.  Also
+	  tweaked the log reject messages to be more consistent.
+
+2003-08-21 09:30  we7u
+
+	* src/igate.c: Removed the '*' requirement for TCPXX*, so we now
+	  reject anything with TCPXX in it.  Added NOGATE options for
+	  dropping packets to all igate functions.  Added generic query
+	  rejection for gating to 'net.  Still need to add it into the
+	  gate-to-rf code.
+
+2003-08-20 12:55  we7u
+
+	* symbols/symbols.dat: Changing the "smoke" symbol so that it shows
+	  a volcano instead of a smokestack.  This is more inline with the
+	  reason the weather server puts out these symbols, and is more
+	  recognizable than the smokestack symbol anyway.
+
+2003-08-20 11:05  we7u
+
+	* src/main.c: Changing the network port check from 7.5 minutes down
+	  to one minute.  This should reconnect ports more quickly if/when
+	  they go down.
+
+2003-08-18 16:16  we7u
+
+	* src/db.c: Removing a back-slash that got in there accidentally.
+
+2003-08-18 15:46  we7u
+
+	* src/db.c: Getting the sort order correct for inserting records
+	  into the station database.  Didn't work well with the wrong
+	  order.
+
+2003-08-18 11:09  we7u
+
+	* src/db.c: Commenting out some speedup code in
+	  station_shortcuts_update_function() that may be causing problems
+	  at present.
+
+2003-08-18 10:40  we7u
+
+	* src/maps.c: Henk's fix to a pointer problem that I created
+	  recently.
+
+2003-08-16 23:04  we7u
+
+	* src/db.c: Fixing a bug in the hash table code which looks for
+	  station matches.  Making the clear all stations function faster
+	  by clearing out the hash table first.
+
+2003-08-15 18:40  we7u
+
+	* src/maps.c: Making index_retrieve() faster by relying on
+	  alphanumerical ordering of the map files in the index list.  We
+	  now save the pointer between runs, and start searching the list
+	  at the point we left off.
+
+2003-08-15 18:12  we7u
+
+	* src/main.c: Minor comment cleanup and removing dead code.
+
+2003-08-15 18:04  we7u
+
+	* src/main.c: Better pointers for Map Chooser select updates.
+
+2003-08-15 17:53  we7u
+
+	* src/main.c: Changing from n*n searches to n searches for updating
+	  selected bits when closing Map Chooser.
+
+2003-08-15 17:12  we7u
+
+	* src/interface.c: Bumping out of port_read less often.  This is
+	  only to check whether the thread should be taken down anyway.  If
+	  a packet is waiting for us to read it, we'll wake up out of the
+	  select() anyway.
+
+2003-08-15 16:55  we7u
+
+	* src/main.c: Rearranging some if statements to get a little more
+	  speed out of it.
+
+2003-08-15 16:11  we7u
+
+	* src/: main.c, maps.c, maps.h: Added caching of XmString values
+	  corresponding to the map filenames for the Map Chooser.  The
+	  first time bringing up Map Chooser will be at the same speed as
+	  before.  Second and succeeding invocations of the Map Chooser
+	  should be a bit faster because the XmString's are used from the
+	  map index records again instead of being created from scratch
+	  each time.
+
+2003-08-15 12:30  we7u
+
+	* src/interface.c: CPU-usage optimization tweak to port_read().
+
+2003-08-15 12:11  we7u
+
+	* src/: interface.c, main.c: CPU-usage tweak for dtr_all_set calls.
+	  It was getting called constantly whenever an HSP port was
+	  enabled.
+
+2003-08-15 11:51  we7u
+
+	* src/maps.c: CPU-usage tweak to index_retrieve().
+
+2003-08-15 11:20  we7u
+
+	* src/db.c: Yet another CPU-usage tweak.  This one is to
+	  search_station_name().  It's more efficient now at finding
+	  stations in the linked list, using a hash table as a jumping-off
+	  point.
+
+2003-08-14 15:02  we7u
+
+	* src/map_shp.c: Changing the level at which shorelines get drawn.
+
+2003-08-14 14:59  we7u
+
+	* src/map_shp.c: Setting up more levels at which things won't be
+	  drawn.  Will make things faster/less cluttered.
+
+2003-08-14 14:46  we7u
+
+	* src/map_shp.c: Optimizing shapefile vector drawing.  We don't
+	  convert the coordinates for each point now unless we're going to
+	  draw the darn thing.
+
+2003-08-14 13:52  we7u
+
+	* src/maps.c: More speedups.
+
+2003-08-14 13:27  we7u
+
+	* src/map_shp.c: Added some comments.
+
+2003-08-14 09:12  we7u
+
+	* src/: main.c, maps.c, maps.h, xastir.h: First part of speeding up
+	  Shapefile drawing by staying with lat/long values as much as
+	  possible, rather than doing conversions to Xastir coordinate
+	  system at every step.  The end goal is to do as little math as
+	  possible to put pixels on the screen.  These changes give a
+	  slight speedup to shapefile drawing, noticeable only when loading
+	  lots of maps.
+
+2003-08-13 16:26  we7u
+
+	* src/map_shp.c: Reverting back to last version.  Floats made
+	  CPU-usage worse in this case.
+
+2003-08-13 15:49  we7u
+
+	* src/map_shp.c: Speedups.  Using floating point operations instead
+	  of unsigned longs.
+
+2003-08-13 12:45  gstueve
+
+	* .cvsignore, callpass/.cvsignore, config/.cvsignore,
+	  help/.cvsignore, m4/.cvsignore, scripts/.cvsignore,
+	  src/.cvsignore, symbols/.cvsignore: Ignore generated files within
+	  CVS base.
+
+2003-08-13 12:38  we7u
+
+	* src/draw_symbols.c: Made the symbol() routine more efficient.
+	  Uses much less CPU now.
+
+2003-08-12 11:48  we7u
+
+	* src/interface.c: More performance improvements.
+
+2003-08-12 11:45  we7u
+
+	* src/popup_gui.c: Another performance improvement.  Only check for
+	  expired popups every two minutes.
+
+2003-08-12 10:29  we7u
+
+	* src/bulletin_gui.c: Another performance improvement.	The timing
+	  was set up such that find_zero_position_bulletins() ran every
+	  time UpdateTime() was started.  We now wait 15 seconds between
+	  each invocation.
+
+2003-08-11 16:57  we7u
+
+	* src/: db.c, messages.c: More optimizations for speed/CPU-usage.
+	  Hash table entry creation is now more efficient.
+	  Check_and_transmit_messages now gets skipped if we ran it already
+	  that second.
+
+2003-08-11 16:15  we7u
+
+	* src/main.c: Added a comment.
+
+2003-08-11 16:05  we7u
+
+	* INSTALL: Added RH9 ImageMagick instructions, courtesy of Wes
+	  Johnston.
+
+2003-08-11 15:40  we7u
+
+	* src/: db.c, main.c: Moved station # display code from db.c to
+	  main.c:UpdateTime() so that the number of stations will
+	  accurately reflect our count even when no packets are coming in.
+
+2003-08-11 15:08  we7u
+
+	* src/interface.c: Another performance/CPU-usage tweak.
+
+2003-08-11 14:48  we7u
+
+	* src/main.c: Another performance tweak.  This one lets you handle
+	  multiple high-speed 'net connections and keeps up with the
+	  receive queues.
+
+2003-08-11 14:07  we7u
+
+	* src/interface.c: Performance enhancements.  Helps Xastir to keep
+	  up with very fast network interfaces.
+
+2003-08-11 13:24  we7u
+
+	* src/main.c: Making UpdateTime() run more often, which helps us
+	  keep up with fast internet feeds.
+
+2003-08-11 12:57  we7u
+
+	* src/db.c: Changing how often we check for stations and messages
+	  to expire from our database.	This should also reduce CPU usage.
+
+2003-08-11 11:31  we7u
+
+	* src/bulletin_gui.c: Another CPU-usage tweak.	Running through all
+	  of the messages looking for new bulletins every 15 seconds
+	  instead of every 2.  Keeps mscan_file() calls down a bit, which
+	  is using a lot of CPU if run often.
+
+2003-08-11 07:04  n2ygk
+
+	* src/: awk.c, awk.h, dbfawk.c, dbfawk.h, testawk.c: Save a newer
+	  snapshot of in-progress code.  Still not baked.
+
+2003-08-08 18:03  we7u
+
+	* src/db.c: Implementing a 14-bit hash table for station record
+	  lookup.  This appears to have a BIG effect on CPU usage.  May be
+	  a bit before the codebase is stable again though, but the gains
+	  are definitely worth it.  It gives us a feeling for what an SQL
+	  database will do for us.
+
+2003-08-08 16:16  we7u
+
+	* src/db.c: Implemented an array of pointers for the station linked
+	  list.  Each entry represents one possible starting letter/number
+	  for the callsign.  We use this to speed up the search for a
+	  particular record, which is our hardest hitter in terms of
+	  CPU-usage right now.	This appears to reduce Xastir's CPU
+	  requirements by quite a bit, particularly when a lot of stations
+	  are in the database.
+
+2003-08-07 13:47  we7u
+
+	* src/draw_symbols.c: Backing out one change which broke the port
+	  activity symbols.  They're working again now.
+
+2003-08-07 10:01  we7u
+
+	* src/Makefile.am: Taking out the awk/dbfawk stuff temporarily
+	  until it can be compiled on most systems again.
+
+2003-08-06 17:54  we7u
+
+	* src/maps.c: Another speedup.
+
+2003-08-06 16:19  we7u
+
+	* src/draw_symbols.c: Speeding up the loading of symbols.
+
+2003-08-06 16:18  we7u
+
+	* src/lang.c: Breaking out of a loop as soon as we get a non-match.
+
+2003-08-06 10:43  we7u
+
+	* README.win32: Added a note regarding Windows not allowing access
+	  to files at times.
+
+2003-08-05 07:34  n2ygk
+
+	* src/: Makefile.am, awk.c, dbfawk.c, dbfawk.h, testawk.c: more
+	  dbfawk utility functions.  I'll be integrating this into
+	  map_shp.c RSN!
+
+2003-08-04 16:13  we7u
+
+	* src/main.c: Another small change which makes a difference in CPU
+	  usage.
+
+2003-08-04 15:36  we7u
+
+	* src/draw_symbols.c: Changing draw colors only when necessary.
+	  Found this one while profiling using gprof.  May be more to
+	  change in this procedure to speed things up a bit..
+
+2003-08-02 10:00  we7u
+
+	* src/main.c: Tweaked Coordinate Calculator so that it checks
+	  lat/long minutes/seconds values for negative numbers and >= 60.0.
+	  If out-of-range numbers are found, the error text is displayed
+	  in the dialog and a warning message is written to STDERR with a
+	  bit more detail on the problem found.  Later this STDERR output
+	  should probably go to a popup or the main dialog instead, and
+	  language strings should be created for them.
+
+2003-07-31 09:01  we7u
+
+	* src/view_message_gui.c: Making the Close button larger.
+
+2003-07-31 08:21  we7u
+
+	* src/view_message_gui.c: Made the View->All Messages dialog
+	  resizable in both directions.
+
+2003-07-31 06:00  we7u
+
+	* src/bulletin_gui.c: Fixed View->Bulletins dialog so that it is
+	  resizable in both directions.
+
+2003-07-27 22:20  we7u
+
+	* src/: db.c, main.c: Improved Display Packet Data dialog.  This
+	  one is resizable and very fast.  Much better than the previous
+	  implementation.
+
+2003-07-26 17:11  we7u
+
+	* symbols/symbols.dat: Added the MODIS Earth Observation symbol.
+	  Added a comment specifying where to find the color definitions
+	  used for symbols.
+
+2003-07-26 09:35  we7u
+
+	* src/map_dos.c: Commented out some fprintf's that were getting
+	  quite verbose when certain Win/DOS maps were loaded.	Warnings
+	  were that we were trying to call draw/fill polygon routines with
+	  1 or 2 points.
+
+2003-07-25 13:00  we7u
+
+	* src/main.c: Cranked up the delay on REDRAW from 2 to 3 seconds.
+	  Changed the dead-reckoning code to schedule a map redraw instead
+	  of doing on itself (which probably duplicated some drawing).	CPU
+	  usage seems to be down because of these changes.
+
+2003-07-25 11:18  we7u
+
+	* src/gps.c: Improved GPS parsing code.  Fixed buffer overflow
+	  problems and restructured code.
+
+2003-07-25 07:36  we7u
+
+	* src/: gps.c, interface.c: Added line-terminations after strncpy()
+	  calls and a bunch of comments at those places as well.
+
+2003-07-24 14:18  we7u
+
+	* src/main.c: Adding more comments.
+
+2003-07-24 14:14  we7u
+
+	* src/: db.c, main.c: Adding uncompressed altitude extension to
+	  compressed objects/items.
+
+2003-07-24 09:17  we7u
+
+	* README.win32: Some very minor changes to the Cygwin instructions.
+
+2003-07-24 06:33  n2ygk
+
+	* src/: awk.c, testawk.c, tgrcty.dbfawk, tgrkgl.dbfawk,
+	  tgrlk.dbfawk: Add some samples dbfawk files.	Remove incorrect
+	  "re" pointer.
+
+2003-07-23 14:34  we7u
+
+	* src/: map_dos.c, map_geo.c, map_gnis.c, map_pdb.c, map_shp.c,
+	  map_tif.c, map_tiger.c, maps.c, util.c: We now copy the map
+	  pixmap to the display if we're loading maps when the
+	  interrupt_drawing_now variable gets set.
+
+2003-07-23 13:29  we7u
+
+	* src/map_shp.c: Changing the quantites of labels drawn for each
+	  zoom level.
+
+2003-07-23 12:17  we7u
+
+	* src/: Makefile.am, map_geo.c, map_tiger.c, maps.c: Fixes for
+	  handling various combinations of Xpm/ImageMagick libraries
+	  installed/not-installed.  Re-ordered the compile order for the
+	  source files to mostly alphabetical order.
+
+2003-07-23 10:33  we7u
+
+	* src/: db.c, location.c, main.c, main.h: Adding more map interrupt
+	  capability to tracking and button callback functions.
+
+2003-07-23 09:20  we7u
+
+	* README.win32: Added a note about spaces in
+	  filenames/directories/user accounts.
+
+2003-07-22 13:13  we7u
+
+	* src/map_shp.c: Fixing colors so that generated map files put into
+	  the maps/GPS directory will show up properly.
+
+2003-07-22 11:15  we7u
+
+	* README.win32: Changed View to Full for selecting packages.  Added
+	  pcre and pcre-devel to the list.
+
+2003-07-22 07:11  n2ygk
+
+	* src/: awk.c, awk.h, testawk.c: add begin, end_rec.  Add some dbf
+	  stuff to testawk.c
+
+2003-07-21 09:51  we7u
+
+	* src/awk.c: Initializing a pointer to NULL to get rid of another
+	  compiler warning.
+
+2003-07-20 10:44  n2ygk
+
+	* src/: awk.c, awk.h, testawk.c: Make awk.* cleanly compile with
+	  -Wall
+
+2003-07-18 14:05  we7u
+
+	* src/: main.h, main.c, maps.c: Setting up code so that the Disable
+	  All Maps toggle will immediately take effect while loading maps.
+
+2003-07-18 13:58  we7u
+
+	* configure.ac: Removing -Wall from configure.ac.  Jack Twilley
+	  added the correct fix to acinclude.m4.
+
+2003-07-18 13:52  jtwilley
+
+	* acinclude.m4: Wrapped gcc-specific tests in an if test for gcc.
+	  Added -Wall to CFLAGS when using gcc.
+
+2003-07-18 13:15  we7u
+
+	* configure.ac: Adding "-Wall" to CFLAGS.  Not sure if this is the
+	  perfect way to get it included into src/Makefile, but this method
+	  definitely works.
+
+2003-07-18 12:49  we7u
+
+	* src/gps.c: Adding a define necessary before including time.h, in
+	  order to get strptime() function defined on some versions of
+	  Linux.
+
+2003-07-18 12:12  we7u
+
+	* src/interface.c: Adding casts to first parameter of
+	  pthread_cleanup_push() so that after macro substitution the
+	  compiler is still happy with the 2nd parameter of
+	  _pthread_cleanup_push().
+
+2003-07-18 11:13  we7u
+
+	* INSTALL: Removing tabs.
+
+2003-07-18 06:14  rzg
+
+	* help/help-English.dat: Moved some stuff around, AGWPE now a
+	  section, minor corrections.
+
+2003-07-17 19:29  n2ygk
+
+	* INSTALL, configure.ac, src/Makefile.am, src/awk.c, src/awk.h,
+	  src/testawk.c: Start adding support for my awk-like metadata for
+	  shapefiles: Tests for -lpcre, documentation of where to find
+	  pcre, and awk.c, awk.h which is the code that will be called once
+	  I get the nerve to do some serious hacking on map_shp.c:-)
+
+2003-07-17 14:54  we7u
+
+	* README.win32: Added another note about the .cvspass file.
+
+2003-07-17 12:37  we7u
+
+	* src/util.c: Fixing timezone for non Cygwin systems.  #ifdef's
+	  were a bit wrong.
+
+2003-07-17 12:25  we7u
+
+	* README.win32: Adding a few more error messages that might occur
+	  while doing CVS operations.
+
+2003-07-17 08:28  we7u
+
+	* src/db.c: Making Tropical Storm/Tropical Depression/Hurricane
+	  wind speed rings disappear at the ghosting time.
+
+2003-07-16 14:07  we7u
+
+	* src/interface.c: Installing thread cleanup routines.	These
+	  should take care of unlocking mutex's when the threads terminate
+	  for any reason.  Should keep the rest of the program running.
+
+2003-07-15 22:25  we7u
+
+	* README.win32: Changing the note about creating the .cvsrc file.
+	  Trying to make it VERY CLEAR that a Unix-type editor must be
+	  used.
+
+2003-07-15 15:58  we7u
+
+	* src/util.c: Changing the begin_critical_section() functio (mutex
+	  locks).  If a resource has already been locked, output a warning
+	  message and skip trying to lock again.  This should allow Xastir
+	  to recover should locks or unlocks be tried twice or more in
+	  sequence.  Warning messages will get printed, but the threads
+	  should continue to run.
+
+2003-07-15 15:42  we7u
+
+	* src/main.c: Adding the busy cursor in a couple of places so that
+	  we have a better indication of when map drawing is taking place.
+
+2003-07-15 13:46  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Cranking up the GPS
+	  timing if it is set lower than 3 seconds.  We also now present a
+	  popup to the user to notify them that the GPS timing has been
+	  changed.
+
+2003-07-15 13:23  we7u
+
+	* src/main.c: Adding a timeout for HSP ports for GPS listener mode.
+
+2003-07-15 12:34  we7u
+
+	* src/interface.c: First attempt at fixing some of the HSP
+	  interface's problems.  This one will send strings other than
+	  GPGGA and GPRMC through the normal decoding sequence.  That will
+	  at least process received TNC strings, which the previous code
+	  did not.
+
+2003-07-15 11:13  we7u
+
+	* src/util.c: Skip copying final pixmap to display if we have a map
+	  interrupt.
+
+2003-07-15 11:08  we7u
+
+	* src/map_tiger.c: Commenting out a bunc of the map interrupt code
+	  to see if it eliminates segfaults that some users are seeing.
+
+2003-07-15 07:17  n2ygk
+
+	* src/: alert.c, color.c, color.h, db.c, list_gui.c, main.c,
+	  map_dos.c, map_geo.c, map_gnis.c, map_pdb.c, map_shp.c,
+	  map_tif.c, map_tiger.c, maps.c, maps.h, util.c, xa_config.c,
+	  xastir.h: Update to newer emacs c-basic-offset
+
+2003-07-14 14:37  we7u
+
+	* README.win32: Changed "diff" to "diffutils", as they apparently
+	  changed what package "diff" could be found in.
+
+2003-07-14 14:26  we7u
+
+	* README.win32: Adding a blurb about the final-final dialog for
+	  Cygwin installs that must have it's OK button pressed for the
+	  whole thing to finish.
+
+2003-07-14 13:31  we7u
+
+	* help/: help-English.dat, help-German.dat, help-Italian.dat,
+	  help-Portuguese.dat, help-Spanish.dat: Changing docs to match new
+	  /usr/local/share/xastir/* directories.
+
+2003-07-14 13:24  we7u
+
+	* FAQ, INSTALL, README.MAPS, README.win32, UPGRADE: Changing docs
+	  to match newer /usr/local/share directory structure.
+
+2003-07-11 08:44  we7u
+
+	* src/util.c: GMT -> Localtime fixes for both Unix and Cygwin.
+
+2003-07-10 13:25  we7u
+
+	* src/util.c: Timezone changes for Cygwin.
+
+2003-07-10 12:06  we7u
+
+	* src/interface.c: Changes for HSP.
+
+2003-07-10 12:00  we7u
+
+	* src/draw_symbols.c: Forcing expire of severe weather polygons at
+	  a 10 minute interval, ignoring the user-settable ghosting period
+	  for these objects.
+
+2003-07-09 17:18  we7u
+
+	* src/main.c: Changing one comment.
+
+2003-07-09 17:18  we7u
+
+	* src/interface.c: Changing some usleep's throughout.  Mostly
+	  making them larger, having to do with starting/stopping
+	  interfaces.
+
+2003-07-09 17:04  we7u
+
+	* src/interface_gui.c: Backing out a few of the TAB_GROUP items.
+	  Don't work for some widgets.	Cause segfaults.  This version
+	  appears to work properly.
+
+2003-07-09 16:34  we7u
+
+	* src/interface_gui.c: Setting up tab groups for all of the
+	  interface GUI dialogs.
+
+2003-07-09 15:55  we7u
+
+	* src/interface_gui.c: Fixing tab groups for Interfaces->Properties
+	  dialog for internet servers.	Probably more to come for other
+	  interface types.
+
+2003-07-09 15:26  we7u
+
+	* src/draw_symbols.c: Detaching multipoint object drawing from the
+	  "Include Expired Data" toggle.  They now expire at the ghosting
+	  interval.
+
+2003-07-09 15:02  we7u
+
+	* src/xa_config.c: Making the default for displaying old data equal
+	  to zero now instead of 1.
+
+2003-07-07 16:51  we7u
+
+	* src/main.c: Causing display updates once per 60 seconds, even
+	  with no input triggers.
+
+2003-07-07 16:19  we7u
+
+	* src/map_shp.c: Adding in maximum zoom levels for various water
+	  features.  They still need fine-tuning.
+
+2003-07-07 14:30  we7u
+
+	* src/db.c: Added a limit to the number of trackpoints displayed in
+	  Station Info.  This prevents lockups when display Station Info on
+	  extremely long paths, for instance:  TrackMe with GPS enabled,
+	  displaying Station Info on my own station.
+
+2003-07-07 14:20  we7u
+
+	* src/main.c: Added in the map interrupt stuff for drawing
+	  symbols/tracks.  Maps and symbols/tracks now appear to be drawn &
+	  interrupted together.
+
+2003-07-07 13:56  we7u
+
+	* src/interface.c: Tweaks for HSP interfaces.  DTR should be reset
+	  now after sending waypoint strings out to the GPS on an HSP port.
+
+2003-07-07 13:23  we7u
+
+	* src/main.c: Changed some comments.
+
+2003-07-07 13:22  we7u
+
+	* src/interface.c: Changed a comment.
+
+2003-07-07 11:09  we7u
+
+	* scripts/xastir-fixcfg.sh: Script now removes the map_index.sys
+	  file and moves the selected_maps.sys file to
+	  selected_maps.sys.backup
+
+2003-07-07 10:57  we7u
+
+	* src/maps.c: Changed some comments.
+
+2003-07-07 10:17  we7u
+
+	* scripts/icontable.pl: Changed path to match new Xastir directory
+	  structure.
+
+2003-07-07 09:33  we7u
+
+	* UPGRADE: Added instructions for migrating to Xastir's new
+	  directory structure.
+
+2003-07-05 08:28  n0vh
+
+	* scripts/fcc-get: Updated to reflect the new directory structure.
+
+2003-07-04 15:17  we7u
+
+	* scripts/xastir-migrate.sh: Changing script so that it deletes the
+	  old files and not the new.
+
+2003-07-04 12:32  we7u
+
+	* src/: db.c, location.c, main.c, main.h, map_dos.c, map_geo.c,
+	  map_gnis.c, map_pdb.c, map_shp.c, map_tif.c, map_tiger.c, maps.c:
+	  A better implementation of the interrupt-map-loading function.
+	  We still end up with tracks/stations drawn strangely when we
+	  first interrupt, but that's the next problem I'll tackle.
+
+2003-07-04 10:10  rzg
+
+	* help/help-English.dat: Listing the last few changes...
+
+2003-07-04 02:11  we7u
+
+	* src/main.c: Made some of the mouse and keyboard operations
+	  interruptible.
+
+2003-07-03 14:30  we7u
+
+	* src/: map_dos.c, map_geo.c, map_gnis.c, map_pdb.c, map_shp.c,
+	  map_tif.c, map_tiger.c: More map interrupting capability.
+	  Currently works for resizing quite nicely.
+
+2003-07-03 13:23  we7u
+
+	* src/: map_geo.c, maps.c: Adding in more map drawing interruption
+	  capability.
+
+2003-07-03 12:13  we7u
+
+	* src/: main.c, main.h, maps.c: Added some flags that get set by
+	  da_resize, which then immediately exits allowing X11 to continue.
+	  If interrupt_drawing_now is set, map drawing ceases after the
+	  map we're currently loading is finished.  If request_resize is
+	  set, then a resize operation is started by UpdateTime.  We can
+	  add checks for interrupt_drawing_now to other routines later in
+	  order to stop map drawing more quickly.  Next is to do a similar
+	  thing for the da_input function, so that a keypress or mouse
+	  click can interrupt map loading.
+
+2003-07-03 10:32  n2ygk
+
+	* scripts/Makefile.am: eliminate duplicate config data
+
+2003-07-03 10:07  n2ygk
+
+	* xastir.spec.in: Patches are now integrated in the main trunk.
+
+2003-07-02 14:49  we7u
+
+	* scripts/: migrate-config.sh, migrate-dirs.sh: Removed these two
+	  files in favor of two new files by Alan.
+
+2003-07-02 14:48  we7u
+
+	* scripts/: xastir-fixcfg.sh, xastir-migrate.sh: Minor tweaks.
+	  Added Id tags for CVS and more directories.
+
+2003-07-02 14:19  n2ygk
+
+	* Makefile.am, configure.ac, config/Makefile.am, help/Makefile.am,
+	  scripts/Makefile.am, symbols/Makefile.am: Changed locations of
+	  shared xastir files.	After make install you should run
+	  scripts/xastir-migrate.sh and scripts/xastir-fixcfg.sh.  The
+	  former fixes the shared files directory.  The latter fixes your
+	  personal xastir.cnf references to those shared files.
+
+2003-07-02 14:03  n2ygk
+
+	* scripts/: Makefile.am, xastir-fixcfg.sh, xastir-migrate.sh: Add
+	  xastir-fixcfg.sh and xastir-migrate.sh
+
+2003-07-02 08:49  we7u
+
+	* README.win32: Added a chmod command for creating a script for
+	  starting Xastir.
+
+2003-07-02 07:11  n2ygk
+
+	* src/map_dos.c: fix reversed cleanup of __LCLINT__ ifdef that was
+	  wrong.
+
+2003-07-01 23:10  we7u
+
+	* src/map_dos.c: Fixed some minor bugs w.r.t. DOS map decoding.
+
+2003-06-30 14:37  we7u
+
+	* src/maps.c: Fixing a naming problem for a variable.
+
+2003-06-30 09:53  we7u
+
+	* src/maps.h: Adding more prototypes needed by some of the map
+	  files that have been newly separated out from maps.c.
+
+2003-06-30 09:52  we7u
+
+	* src/maps.c: Commenting out an unused function.
+
+2003-06-30 09:52  we7u
+
+	* src/map_dos.c: Commenting out some unused variables.
+
+2003-06-26 08:37  n2ygk
+
+	* src/: Makefile.am, map_dos.c, map_geo.c, map_gnis.c, map_pdb.c,
+	  map_shp.c, map_tif.c, map_tiger.c, maps.c, maps.h: split maps.c
+	  into several map-specific files.
+
+2003-06-25 12:00  we7u
+
+	* src/main.c: Update tracking station call if TrackMe is enabled
+	  when we change our own station callsign.
+
+2003-06-22 12:48  we7u
+
+	* src/maps.c: Decoding school district types in shapefiles and
+	  displaying as a yellow border.
+
+2003-06-20 19:06  we7u
+
+	* src/main.c: More moving save station trail and GPSMAN functions
+	  to use the local users' ~/.xastir/gps and ~/.xastir/tracklogs
+	  directories.
+
+2003-06-20 19:05  we7u
+
+	* src/maps.c: Starting to move GPS and Save station trail functions
+	  so that they use ~/.xastir/gps and ~/.xastir/tracklogs
+	  directories.
+
+2003-06-20 18:27  we7u
+
+	* src/: maps.c, track_gui.c: Shortening the temp files to get rid
+	  of "xastir_" and the username.
+
+2003-06-20 16:55  we7u
+
+	* src/: main.c, track_gui.c, maps.c: Moving temporary files into
+	  the users ~/.xastir/tmp directory.
+
+2003-06-20 16:10  we7u
+
+	* src/maps.c: Changing default auto_maps for directories and .geo
+	  files to 0.
+
+2003-06-20 15:52  we7u
+
+	* scripts/: migrate-config.sh, migrate-dirs.sh: Migration scripts
+	  by Alan Crosswell, N2YGK.
+
+2003-06-20 15:29  we7u
+
+	* src/track_gui.c: Added some comments regarding the date/timestamp
+	  that's available on findu.com for track downloads.
+
+2003-06-20 14:57  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h, main.c: Tweaks to
+	  display signpost symbol data next to symbol.	Also allow letters
+	  now instead of just digits, as the spec appears to allow this.
+	  Next thing to bring us fully into compliance is to only show the
+	  signpost data at close-in zoom levels (minor), and perhaps also
+	  to show the data on top of the sign (also minor).
+
+2003-06-18 11:40  we7u
+
+	* src/main.c, config/language-Dutch.sys,
+	  config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys:
+	  Fixes for the Map Chooser confusion regarding the clear and the
+	  map-type selection buttons.
+
+2003-06-18 11:12  we7u
+
+	* src/maps.c: Tweaks by  Derrick J Brashear, KB3EGH, to handle
+	  non-USGS geotiff images properly.
+
+2003-06-17 21:13  rzg
+
+	* help/help-English.dat: Beginnings of new BETA section, list
+	  form...
+
+2003-06-17 18:29  kd6zwr
+
+	* src/maps.c: Adding check for raster maps that are too big or
+	  small for display.   define FUZZYRASTER to enable.
+
+2003-06-17 17:24  we7u
+
+	* config/xastir.rgb, src/main.c: Making a color change that Henk
+	  wanted, so that yellow tracks can be seen on top of yellow map
+	  fills.
+
+2003-06-17 17:02  we7u
+
+	* src/maps.c: Added MAP_SCALE_CHECK define and associated code.
+	  Will skip maps whose extents are smaller than 4% of the view
+	  size.  The define is commented out by default so that the check
+	  is not performed.
+
+2003-06-17 12:48  we7u
+
+	* src/xa_config.c: Added a comment.
+
+2003-06-16 15:56  we7u
+
+	* src/interface.c: Support for sequence numbers in OpenTrac
+	  packets.  Can send multiple positions in one packet.
+
+2003-06-16 13:48  we7u
+
+	* help/help-English.dat: More details on the REFRESH .geo tag.
+
+2003-06-16 11:50  we7u
+
+	* src/interface.c: Fixing a small bug in the OpenTrac text output
+	  regarding symbols.
+
+2003-06-16 11:49  we7u
+
+	* src/: db.c, maps.c, util.c: Changing puts() calls to fprintf().
+
+2003-06-16 10:34  we7u
+
+	* help/help-English.dat: Added the REFRESH tag description for .geo
+	  files.
+
+2003-06-15 17:33  we7u
+
+	* configure.ac: Bumping rev number past the last stable rev number.
+
+2003-06-14 00:19  we7u
+
+	* src/interface.c: Translating from OpenTrac symbols to APRS
+	  symbols.
+
+2003-06-13 22:35  we7u
+
+	* src/interface.c: Taking out devel code that's not working yet.
+
+2003-06-13 18:47  kd6zwr
+
+	* src/: main.c, main.h, maps.c: Added REFRESH tag to geo files.
+
+2003-06-13 16:34  we7u
+
+	* src/interface.c: Terminating the list with empty strings.
+
+2003-06-13 16:08  we7u
+
+	* src/interface.c: Adding a symbol translation table for OpenTrac.
+	  Not used in the code yet.
+
+2003-06-13 15:22  we7u
+
+	* src/interface.c: Initial OpenTrac decode routines.  Implemented
+	  only for AX.25 interfaces to date.
+
+2003-06-13 15:17  we7u
+
+	* src/maps.h: Adding an export for a routine which will be needed
+	  in interface.c soon.
+
+2003-06-13 14:15  we7u
+
+	* configure.ac: Bumping rev up to 1.2.0 in preparation for stable
+	  release.
+
+2003-06-13 13:42  rzg
+
+	* help/help-English.dat: Adding a bit about the green and blue
+	  weather boxes (multipoints)
+
+2003-06-11 11:15  we7u
+
+	* help/: help-English.dat, help-Portuguese.dat: Fixed some of the
+	  FIXME's.
+
+2003-06-11 10:42  we7u
+
+	* help/: help-German.dat, help-Portuguese.dat: Changed "BETA" to
+	  "1.2".
+
+2003-06-11 10:32  rzg
+
+	* help/help-English.dat: Release will be 1.2
+
+2003-06-08 09:15  we7u
+
+	* src/gps.c: Removing tabs (again).
+
+2003-06-07 15:43  kd6zwr
+
+	* src/gps.c: fixing null pointer reference
+
+2003-06-07 15:43  kd6zwr
+
+	* src/db.c: fixing compiler warnings
+
+2003-06-07 07:19  francais1
+
+	* config/language-French.sys: Updated
+
+2003-06-07 00:29  we7u
+
+	* config/language-Italian.sys: A few more translations by Marco
+	  Calistri, IK5BCU.
+
+2003-06-06 17:34  we7u
+
+	* src/draw_symbols.c: Changing tabs to spaces.
+
+2003-06-06 17:19  we7u
+
+	* src/main.c: Converting more tabs to spaces.
+
+2003-06-06 17:12  we7u
+
+	* src/track_gui.c: Changing more tabs to spaces.
+
+2003-06-06 17:04  we7u
+
+	* src/: interface.c, maps.c: Changing more tabs to spaces.
+
+2003-06-06 16:57  we7u
+
+	* src/: db.c, igate.c, popup_gui.c, wx_gui.c, xa_config.c: Removing
+	  tabs that snuck into the source code.  Replaced with spaces.
+
+2003-06-06 12:50  we7u
+
+	* src/maps.c: Adding another error message in Snapshot thread.	If
+	  we get a system() call error but errno is zero, this fprintf()
+	  will get triggered.
+
+2003-06-06 12:49  we7u
+
+	* src/db.c: Changes by Henk de Groot, PE1DNN.
+
+2003-06-06 12:37  we7u
+
+	* README.win32: More revisions to the note about modifier keys.
+
+2003-06-05 17:02  we7u
+
+	* README.win32: Added a few notes about the libraries which
+	  currently cannot be used with Cygwin.
+
+2003-06-05 16:56  we7u
+
+	* README.win32: Revising a few notes.  Added a new section
+	  detailing how to keep Cygwin and Xastir up-to-date.
+
+2003-06-05 13:55  we7u
+
+	* src/maps.c: Checking errno in snapshot routine if the system call
+	  returns a possible error.
+
+2003-06-05 13:11  we7u
+
+	* acinclude.m4, src/maps.c: Reverting back to older snapshot
+	  method.  Removing configure message regarding old ImageMagick
+	  versions, as even the old versions appear to currently work with
+	  the Tigermap intensity slider.
+
+2003-06-05 10:54  we7u
+
+	* src/db.c: Changes by Henk de Groot, PE1DNN.  Fixes weather packet
+	  parsing problems for packets containing spaces or dots in place
+	  of data.
+
+2003-06-05 10:05  we7u
+
+	* README.win32: Added notes about X modifier keys and Cygwin web
+	  sites.
+
+2003-06-05 09:53  we7u
+
+	* README.win32: Adding more notes about Cygwin's network installer.
+
+2003-06-04 15:35  rzg
+
+	* help/help-English.dat: Fixing the formatting in a few spots and
+	  correcting an unlear statment.
+
+2003-06-04 09:05  we7u
+
+	* src/: maps.c, track_gui.c, util.c, util.h: Fixing a bug where we
+	  don't return from map routines properly on a libcurl error.
+
+2003-06-03 14:49  we7u
+
+	* src/main.c: Fixing a bug in the Map Chooser which occurs when
+	  deselecting files.  It was putting a warning message to STDERR.
+
+2003-06-03 14:31  we7u
+
+	* FAQ: Added a note about color tinting using Hummingbird eXceed.
+
+2003-06-03 14:01  we7u
+
+	* README.win32: Added notes about totally black images for geotiff
+	  files and how to fix it.
+
+2003-06-02 16:58  we7u
+
+	* src/maps.c: Knocking out the snapshot code for the case where
+	  ImageMagick isn't present.  When Jack is finished, he can take
+	  the #ifdef back out.
+
+2003-06-02 16:23  jtwilley
+
+	* src/maps.c: Use new acinclude.m4 logic to include correct
+	  ImageMagick header.
+
+2003-06-02 16:20  jtwilley
+
+	* acinclude.m4: Added extra header checks for ImageMagick.
+
+2003-06-02 02:49  jtwilley
+
+	* src/maps.c: Replaced XpmWriteFileFromPixmap + system("convert")
+	  with ImageMagick code
+
+2003-05-30 22:47  we7u
+
+	* src/maps.c: Fixing some ambiguous if/else bracing.
+
+2003-05-30 22:43  we7u
+
+	* src/db.c: Fixing some ambiguous if/else braces.
+
+2003-05-30 15:51  jtwilley
+
+	* acinclude.m4: Checked in fabulous new ImageMagick code.
+
+2003-05-30 12:16  we7u
+
+	* src/maps.c: Protecting some draw functions from getting called
+	  with too few vertices.
+
+2003-05-30 11:54  we7u
+
+	* src/rotated.c: Added code to skip XFillPolygon() call if the
+	  number of points is too few or negative.
+
+2003-05-30 11:44  we7u
+
+	* src/draw_symbols.c: Added some comments.  No code changes.
+
+2003-05-29 08:27  we7u
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Spanish.sys: Changing spacing
+	  slightly to align Map Properties dialog column headings.
+
+2003-05-29 08:26  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-05-29 08:25  we7u
+
+	* config/language-Italian.sys: Changes by Alessandro Frigeri,
+	  IK0YUP.
+
+2003-05-28 17:12  we7u
+
+	* README.win32: Added instructions for snagging/installing liblcms,
+	  needed by later versions of ImageMagick.
+
+2003-05-28 16:21  we7u
+
+	* src/maps.c: Terraserver changed to a new hostname.  Changing to
+	  correspond.
+
+2003-05-28 13:33  we7u
+
+	* config/language-German.sys, help/help-German.dat: Changes by Rolf
+	  Bleher, DK7IN.
+
+2003-05-28 13:24  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-05-28 12:58  we7u
+
+	* config/language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-05-28 12:57  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-05-28 11:49  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-05-28 11:18  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-05-28 11:09  we7u
+
+	* config/language-German.sys: Translation of "Moisture" by Rolf
+	  Bleher, DK7IN.
+
+2003-05-28 10:33  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c: More
+	  translations.  Also changing "meters" to "m".
+
+2003-05-28 10:14  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c: Changing a few
+	  more hard-coded strings.
+
+2003-05-27 18:00  rzg
+
+	* help/help-English.dat: Grammar corrections. :-P
+
+2003-05-27 16:44  we7u
+
+	* INSTALL, README.win32: More ImageMagick notes.
+
+2003-05-27 15:24  we7u
+
+	* src/db.c: Fixed how we handle space/dot-filled
+	  temperature/humidity fields.
+
+2003-05-27 13:43  we7u
+
+	* src/main.c: Commenting out the new ifdef.  Forgot to after
+	  testing.
+
+2003-05-27 13:40  we7u
+
+	* src/: main.c, interface_gui.c: Separated out the LARGE_FONT
+	  #ifdef's into two: USE_LARGE_SYSTEM_FONT and
+	  USE_LARGE_STATION_FONT.  This is to help the visually impaired.
+	  Made the cursor position visible in more of the
+	  Interfaces->Properties dialogs.
+
+2003-05-27 13:25  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-05-27 10:57  we7u
+
+	* help/help-English.dat: Clarified the note about IMAGESIZE being
+	  required for .geo files with URL's, optional for local images.
+
+2003-05-27 10:56  we7u
+
+	* README.MAPS: Another note about IMAGESIZE being a required
+	  parameter for .geo files with URL's in them.
+
+2003-05-24 22:52  we7u
+
+	* src/: maps.c, popup_gui.c: Moved some code and added comments to
+	  make it very obvious that fonts are not to be loaded often.
+	  Causes memory leaks.
+
+2003-05-24 21:58  we7u
+
+	* src/main.c: Adding a method to switch to larger fonts, helpful to
+	  visually-impaired users.  Uncomment the USE_LARGE_FONTS #ifdef at
+	  the top of main.c to enable these larger fonts.  Off by default.
+
+2003-05-24 00:57  we7u
+
+	* src/main.c: Re-doing the widget geometry for the Configure->Audio
+	  Alarms dialog.  It now works with large or small fonts.
+
+2003-05-24 00:05  we7u
+
+	* src/draw_symbols.c: Added some comments.
+
+2003-05-23 16:30  we7u
+
+	* src/maps.c: Fixing intensity slider for Tigermap by switching
+	  from LevelImage() call to ModulateImage() call.
+
+2003-05-23 15:59  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-05-23 15:59  we7u
+
+	* config/: language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-05-23 14:58  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-05-23 14:18  we7u
+
+	* src/xa_config.c: Setting initial default for
+	  MAP_CHOOSER_EXPAND_DIRS to 1, so that the terraserver.geo and
+	  toposerver.geo files will appear by default for new users.
+
+2003-05-23 13:32  we7u
+
+	* terraserver.geo, toposerver.geo: Adding these files to the
+	  sources.
+
+2003-05-23 13:32  we7u
+
+	* Makefile.am: Auto-installing terraserver.geo and toposerver.geo
+	  in the maps directory.
+
+2003-05-23 13:29  we7u
+
+	* README.win32: More explanation of CVS errors when SourceForge is
+	  too busy.
+
+2003-05-23 13:19  we7u
+
+	* README.win32, help/help-English.dat: Added TOPOSERVER
+	  instructions.
+
+2003-05-23 13:16  we7u
+
+	* README.MAPS: Added the TOPOSERVER keyword and explanation.
+
+2003-05-23 13:11  we7u
+
+	* src/maps.c: On-line topo maps.  I considered the utility of this
+	  versus not adding it until after release.  This is just too
+	  useful for new (and old) users not to have put it in.  Enjoy!
+	  Geo file with "TOPOSERVER" in it will get you online topo maps.
+
+2003-05-23 12:06  we7u
+
+	* src/main.c: Fixing SmartBeaconing dialog so that it's aligned
+	  properly.
+
+2003-05-23 11:44  we7u
+
+	* src/main.c: SmartBeaconing dialog now supports metric units.
+
+2003-05-23 10:52  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c,
+	  src/track_gui.c: Changing more hard-coded strings into
+	  language-specific strings.
+
+2003-05-23 10:08  we7u
+
+	* help/help-English.dat: More minor spelling on consistency
+	  changes.
+
+2003-05-23 09:14  we7u
+
+	* config/language-Portuguese.sys: Making the time periods
+	  correspond with the English file.
+
+2003-05-22 22:14  we7u
+
+	* help/help-English.dat: Lots of minor tweaks throughout the file.
+
+2003-05-22 14:01  we7u
+
+	* help/help-English.dat: Minor updates.
+
+2003-05-22 13:20  we7u
+
+	* README.MAPS: Updating the NOAA filenames for the alert
+	  shapefiles.
+
+2003-05-22 12:37  we7u
+
+	* README: Correcting spelling.
+
+2003-05-22 12:33  we7u
+
+	* README.MAPS: Added notes about setting up permissions for
+	  maps/GPS directory.
+
+2003-05-22 12:22  we7u
+
+	* AUTHORS, INSTALL, NEWS, README.MAPS: Tweaking docs here and
+	  there.
+
+2003-05-22 12:02  we7u
+
+	* DEBUG_LEVELS: Swapped the two sections.  Most useful info at the
+	  top of the file now.
+
+2003-05-22 11:58  we7u
+
+	* DEBUG_LEVELS, FAQ, INSTALL, LICENSE, NEWS, README, README.CVS,
+	  README.MAPS, README.win32, UPGRADE: Adding/changing copyright
+	  notice.
+
+2003-05-22 11:48  we7u
+
+	* README.win32: Adding more notes.  Reworking existing notes to
+	  make them more understandable to Windows-folk.
+
+2003-05-22 09:32  we7u
+
+	* INSTALL: Adding info regarding matching up the libtiff/libgeotiff
+	  versions.
+
+2003-05-21 16:16  we7u
+
+	* src/: db.h, main.c: Reversing the direction of the two Area
+	  Object lines, to correspond with dos/winAPRS and UI-View.
+
+2003-05-21 16:16  we7u
+
+	* src/draw_symbols.c: Added some comments.
+
+2003-05-21 15:40  francais1
+
+	* src/: db.c, db.h, draw_symbols.c, draw_symbols.h: Fixed corridor
+	  > 127 bug (now works up to 999, which I believe is the spec
+	  limit)
+
+2003-05-21 15:34  we7u
+
+	* src/draw_symbols.c: Added some comments.
+
+2003-05-21 14:18  we7u
+
+	* src/draw_symbols.c: Implemented area object ellipse display
+	  exactly the same as circle display.  This is what UI-View is
+	  doing.  dos/WinAPRS don't implement ellipses at all.
+
+2003-05-21 13:31  we7u
+
+	* config/language-German.sys, help/help-German.dat: Changes by Rolf
+	  Bleher, DK7IN.
+
+2003-05-21 12:56  we7u
+
+	* src/maps.c: Canceling certain warning messages while indexing.
+
+2003-05-21 12:30  we7u
+
+	* README.CVS: Updates to match our current codebase and how we do
+	  things.
+
+2003-05-21 12:22  we7u
+
+	* src/main.c: Fixing the Map Properties strings so that they are
+	  auto-centered in the columns and truncated to the column widths.
+
+2003-05-21 11:45  we7u
+
+	* src/main.c: Truncating language strings in Map Properties columns
+	  (the "yes" string) so that it fits our column width.
+
+2003-05-21 10:01  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-05-21 09:45  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-05-21 09:44  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-05-21 09:44  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-05-21 09:22  francais1
+
+	* config/language-French.sys: Translated added English
+
+2003-05-20 17:15  we7u
+
+	* src/: interface.c, main.c: Correcting some grammar.
+
+2003-05-20 17:14  we7u
+
+	* README.win32: Removing the Perl 5.6 restriction.  Perl 5.8
+	  appears to work properly now with Xastir and it's optional
+	  libraries.
+
+2003-05-20 14:28  we7u
+
+	* config/language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-05-20 12:51  we7u
+
+	* config/language-Italian.sys: Adding some missing strings.
+
+2003-05-20 12:22  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Fixing more hard-coded
+	  language strings.
+
+2003-05-20 12:09  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Fixing hard-coded
+	  strings.  Added missing GPS strings in Italian file.
+
+2003-05-20 11:16  we7u
+
+	* FAQ: Added two more questions/answers.
+
+2003-05-20 10:34  we7u
+
+	* src/: bulletin_gui.c, fcc_data.c, gps.c, interface.c, lang.c,
+	  main.c, maps.c, messages.c, rac_data.c, util.c,
+	  view_message_gui.c, wx.c, alert.h: Fixing up the <time.h> and
+	  <sys/time.h> includes with the proper ifdef's.
+
+2003-05-19 20:42  rzg
+
+	* help/help-English.dat: Typo fixes pointed out by Rolf, minor
+	  other things.
+
+2003-05-19 20:28  rzg
+
+	* INSTALL, README.CVS, README.MAPS, UPGRADE: Adding copyright
+	  notices to the docs that lack.
+
+2003-05-19 13:14  we7u
+
+	* README.win32: Changes by Kirk Mefford, KC2ELO.
+
+2003-05-19 12:52  we7u
+
+	* src/main.c: Correcting the time.h include to make it sys/time.h.
+
+2003-05-19 11:24  we7u
+
+	* README.win32: Adding checkboxes.
+
+2003-05-19 11:13  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-05-19 10:57  we7u
+
+	* README.win32: Changes by Wes Johnston, edited slightly by me.
+
+2003-05-19 10:35  we7u
+
+	* INSTALL: Added another festival note from Alan Crosswell.
+
+2003-05-19 09:59  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-05-18 11:29  we7u
+
+	* config/language-Italian.sys: Changes by Marco Calistri, IK5BCU.
+
+2003-05-16 17:07  we7u
+
+	* src/maps.c: Removing the debug fprintf() statement.
+
+2003-05-16 17:03  we7u
+
+	* src/maps.c: Fix for wrong guessing of road widths for some types
+	  of Shapefiles.
+
+2003-05-16 16:06  we7u
+
+	* INSTALL: Shapelib instructions for MacOSX.
+
+2003-05-16 14:44  we7u
+
+	* README.win32: More detailed instructions for Shapelib
+	  integration.
+
+2003-05-16 13:12  we7u
+
+	* README.win32: More ImageMagick notes for Cygwin.  Setting the
+	  MAGICK_HOME variable with the new X configuration.
+
+2003-05-16 11:16  we7u
+
+	* README.win32: Adding a note about the 'X' in the system tray.
+
+2003-05-16 11:10  we7u
+
+	* README.win32: Changing desktop shortcut to start from Cygwin home
+	  directory.
+
+2003-05-16 11:02  we7u
+
+	* README.win32: Updated Cygwin instructions to allow using Xwindows
+	  apps and Windows apps from the same desktop transparently.  No
+	  Xwindows large box anymore!
+
+2003-05-15 12:32  we7u
+
+	* src/maps.c: Adding another helpful message for the case where a
+	  GEO file is being opened, but perhaps no support is compiled in
+	  for the map format.
+
+2003-05-15 12:18  we7u
+
+	* src/maps.c: Spit out appropriate error messages if various
+	  optional map libraries are not installed and the user tries to
+	  load unsupported map types.
+
+2003-05-15 11:12  we7u
+
+	* src/: maps.c, track_gui.c: Changing one warning message.
+
+2003-05-15 08:09  we7u
+
+	* configure.ac: Bumping the revision up to 1.1.5.
+
+2003-05-15 07:47  we7u
+
+	* Makefile.am: Getting rid of the last remnants of README.1ST.
+	  Adding other doc files.
+
+2003-05-14 22:18  rzg
+
+	* FAQ, README.1ST, README.win32: Docs cleanup take 5.
+
+2003-05-14 22:07  jtwilley
+
+	* Makefile.am, xastir.spec.in: Removed references to README.1ST and
+	  TODO
+
+2003-05-14 21:02  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-05-14 20:59  we7u
+
+	* src/main.c: Moving the time.h include outside the
+	  HAVE_IMAGEMAGICK ifdef's.
+
+2003-05-14 19:14  rzg
+
+	* README: Took last important bit from README.1ST, ready to trash
+	  it...
+
+2003-05-14 17:14  we7u
+
+	* config/language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-05-14 17:08  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-05-14 16:30  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-05-14 16:29  we7u
+
+	* config/language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-05-14 16:06  francais1
+
+	* config/language-French.sys: Updated 2 strings to match English.
+
+2003-05-14 16:02  we7u
+
+	* config/language-English.sys: Updating the reindexing strings.
+
+2003-05-14 15:50  we7u
+
+	* AUTHORS, DEBUG_LEVELS, FAQ, INSTALL, NEWS, README, README.CVS,
+	  README.MAPS, UPGRADE, changes.txt: Adding/Changing to Id: RCS tag
+	  in files.
+
+2003-05-14 15:41  we7u
+
+	* README.MAPS: Updating a NOAA URL.
+
+2003-05-14 13:47  we7u
+
+	* config/language-Spanish.sys: Changed by Jose R. Marte A.,  HI8GN.
+
+2003-05-14 12:44  francais1
+
+	* config/language-French.sys: Updated
+
+2003-05-14 09:28  rzg
+
+	* README.MAPS, help/help-English.dat: Docs- big cleanup take 4!
+
+2003-05-14 09:14  rzg
+
+	* INSTALL, README, README.1ST, UPGRADE: Docs- big cleanup take 3!
+
+2003-05-14 08:42  rzg
+
+	* INSTALL, README.1ST, README.CVS, README.MAPS: Docs- big cleanup
+	  take 2!
+
+2003-05-14 08:40  rzg
+
+	* TODO, UPDATES: Docs - big clean up take 1!
+
+2003-05-13 14:56  jtwilley
+
+	* README.win32: Added Kirk Mefford's suggestion re: creating .cvsrc
+	  file
+
+2003-05-12 23:59  we7u
+
+	* src/db.c: CPU Usage fixes.  We no longer do complete symbol
+	  updates at a high rate.  We update only the new symbol, then do
+	  cleanup at a 60-second rate sometime later.  CPU usage drops a
+	  bit with this latest code.
+
+2003-05-12 16:59  we7u
+
+	* src/main.c: Slowed down UpdateTime() iterations so that the
+	  read/write threads would have time to do their thing.  Cranked up
+	  the maximum packets processed by UpdateTime() in one iteration.
+	  Added a usleep() after processing each packet so that the read
+	  threads would have time to put another packet in the queue.  CPU
+	  time has gone down by these changes, but we still appear to keep
+	  up with the incoming packets.
+
+2003-05-12 16:56  we7u
+
+	* src/interface.c: Speeding up the receive threads.  They don't
+	  take any CPU time anyway, so this doesn't hurt CPU usage.  They
+	  process one line then wait for the main thread to pick it up
+	  before they process the next line.
+
+2003-05-12 13:59  we7u
+
+	* src/main.c: Changing main.c:UpdateTime() to wait 15ms between
+	  each run instead of 10.  This reduces CPU time a bit, yet still
+	  allows packets to get processed from the receive queues.  20ms
+	  appeared to be too slow.  Will investigate adding longer delays
+	  between graphics updates in this routine, yet allowing packet
+	  processing to proceed at a fast pace.  That should further reduce
+	  CPU cycles yet not get behind in the receive queues.	At that
+	  point we might reduce the delay again between UpdateTime() runs.
+
+2003-05-12 12:39  we7u
+
+	* README.win32: Updating the list of Cygwin packages to include
+	  tcl/tk and Curl.
+
+2003-05-11 22:18  we7u
+
+	* config/language-Italian.sys: Another phrase translated by Marco
+	  Calistri, IK5BCU.
+
+2003-05-11 08:06  we7u
+
+	* config/language-Italian.sys: Adding a missing string.  In English
+	  so far (until I get an Italian translation of it).
+
+2003-05-10 16:42  we7u
+
+	* src/maps.c: Fix by Magne M�hre, la1bfa, for segfault generated
+	  when Shapefiles can't be created on the file system, usually due
+	  to permissions problems in /usr/local/maps/GPS.
+
+2003-05-10 00:31  we7u
+
+	* src/alert.c: Converting one more strcpy to strncpy.
+
+2003-05-10 00:15  we7u
+
+	* src/alert.c: Fixing another killer packet bug in the alert code.
+
+2003-05-09 14:13  we7u
+
+	* config/language-English.sys: Changing one label slightly
+	  regarding reindexing.
+
+2003-05-09 10:43  we7u
+
+	* src/maps.c: Tweaks to maintain selected map properties when a
+	  full reindexing is requested.
+
+2003-05-08 23:39  we7u
+
+	* src/: maps.c, maps.h, main.c: Implementing an indexing scheme
+	  that takes care of finding updated files quickly, deleting
+	  records for deleted files, and wasting everything and starting
+	  from scratch to build a new index.  This code can do all of that.
+
+2003-05-08 23:32  we7u
+
+	* README.win32: Removed an email address so that Kirk won't get
+	  spammed by the spambots.
+
+2003-05-08 23:28  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changing/Adding
+	  Map Re-Index strings for menus.
+
+2003-05-08 17:44  rzg
+
+	* README.win32: Sound Alert information from Kirk Mefford
+	  kc2elo at softhome.net
+
+2003-05-08 14:36  we7u
+
+	* src/main.c: Changed a comment.
+
+2003-05-08 12:31  we7u
+
+	* src/db.c: Fixing the Station Info dialog so that the multipoint
+	  strings aren't shown.  They're now removed from the string inside
+	  the extract_multipoint() function.
+
+2003-05-07 22:26  we7u
+
+	* src/alert.c: Fixing the alert matching so that a new alert will
+	  match a pre-existing CANCL packet in the list.  This is in
+	  response to a bug on the bug-list.
+
+2003-05-07 13:32  francais1
+
+	* src/maps.c: Fixed relative paths to images in .geo files
+
+2003-05-06 21:32  kd6zwr
+
+	* src/maps.c: Made IMAGESIZE tag optional for geo files,
+	  (imagemagic ping to autodetect size) Also allow absolute
+	  pathnames in geo files, as well as relative.
+
+2003-05-06 14:49  we7u
+
+	* src/db.c: Don't draw wind barbs for severe storm objects.
+
+2003-05-06 13:33  we7u
+
+	* src/db.c: Adding the other types of severe storms that the
+	  weather server can issue.  This is part of the general hurricane
+	  bug fix on the bug list.
+
+2003-05-06 13:19  we7u
+
+	* src/db.c, src/db.h, symbols/symbols.dat: Moving wind speed into
+	  the proper field (so that it shows up in Station Info) for
+	  hurricanes.  This is a partial fix for a bug on the buglist.
+	  Changing the tornado symbol so that it stands out more (thanks to
+	  Dale Huguley for that one).
+
+2003-05-06 08:17  we7u
+
+	* help/help-English.dat: Added a description of the weather watch
+	  box colors/patterns, courtesy of Dale Huguley.
+
+2003-05-05 21:22  we7u
+
+	* src/util.c: Correcting for daylight savings time when converting
+	  from zulu time to Unix epoch time.  Also added some debug code.
+
+2003-05-05 16:08  jtwilley
+
+	* README.1ST: Minor correction to FreeBSD notes.
+
+2003-05-05 13:36  we7u
+
+	* src/alert.c: Changed some comments.  No code changes.
+
+2003-05-05 11:00  we7u
+
+	* src/alert.c: Fixing another "killer packet" problem:	If we got
+	  an uncompressed message that looked like a weather alert but was
+	  simply a test message, we segfaulted while trying to move
+	  uninitialized strings around.
+
+2003-05-02 17:31  we7u
+
+	* src/: db.c, alert.c: Rewrote weather alert handling so that
+	  compressed format weather alert packets are parsed/displayed
+	  correctly.
+
+2003-05-02 11:03  kd6zwr
+
+	* src/maps.c: Initialize a few variables to NULL to shut up -Wall
+
+2003-05-02 10:43  we7u
+
+	* help/help-English.dat: Added a note about IMAGESIZE now being a
+	  required keyword in .GEO files.
+
+2003-05-02 01:44  we7u
+
+	* src/db.c: Re-wrote relay_digipeat() so that it is more correct.
+	  It now appears to get to the correct part of the path before
+	  checking for my_call or RELAY.
+
+2003-05-01 09:47  kd6zwr
+
+	* src/: maps.c, maps.h: Changed reading in map index to much faster
+	  mode, and added a sort routine to make sure it is still sorted
+	  correctly.
+
+2003-05-01 09:38  we7u
+
+	* src/db.c: Reordered the widgets in the Station Info dialog so
+	  that it can be resized properly.  This is to take another bug off
+	  the buglist regarding oversized Station Info dialog that can't be
+	  resized.  It can now.
+
+2003-04-30 23:38  we7u
+
+	* README.1ST: Added some notes about tiger file types and NOAA
+	  weather alert shapefiles.
+
+2003-04-30 21:19  we7u
+
+	* src/maps.c: Working code for Shapefile polygon "holes"!!!
+
+2003-04-30 13:22  we7u
+
+	* src/util.c: Adding two more lower-case letters to those accepted
+	  by valid_path() for Q-constructs.
+
+2003-04-30 13:10  we7u
+
+	* src/maps.c: More debug stuff.  More work on Shapefile holes in
+	  polygons.
+
+2003-04-30 12:50  we7u
+
+	* src/util.c: Added more debug statements to valid_path().
+
+2003-04-30 10:50  rzg
+
+	* help/help-English.dat, FAQ: Qxx, and other minor updates to help
+	  and FAQ.
+
+2003-04-30 09:02  we7u
+
+	* src/maps.c: Comment changes.	No code changes (yet!).
+
+2003-04-29 14:37  jtwilley
+
+	* src/main.c: Fixed warnings with libcurl.
+
+	  Started GDAL integration.
+
+2003-04-29 13:24  we7u
+
+	* src/maps.c: Changing/adding comments.
+
+2003-04-29 13:02  we7u
+
+	* src/maps.c: Implementing a better fill/hole ring-direction
+	  algorithm for Shapefiles.  This one is snagged directly from
+	  Shapelib and used by permission of the author, Frank Warmerdam.
+
+2003-04-28 23:03  we7u
+
+	* src/maps.c: More tweaks to the Shapefile "hole" ring code.  Not
+	  fully implemented yet, but added some speed improvements.  Next
+	  is to implement a clip-mask in the form of regions.
+
+2003-04-28 22:59  we7u
+
+	* src/interface.c: Getting rid of an unused variable.
+
+2003-04-28 21:59  rzg
+
+	* README.1ST: Updates WTR igating weather alerts, minor spacing
+	  changes, and nicer libcurl URL.
+
+2003-04-28 21:24  jtwilley
+
+	* README.1ST: Added URL for libcurl.
+
+2003-04-28 20:57  we7u
+
+	* src/db.c: Changed the extract_GLL() function from using strtok()
+	  to split_string().
+
+2003-04-28 17:04  we7u
+
+	* src/db.c: Converted extract_RMC() to using split_string() instead
+	  of strtok().
+
+2003-04-28 16:17  we7u
+
+	* src/db.c: Removing unused variables.
+
+2003-04-28 16:08  we7u
+
+	* src/db.c: Re-wrote extract_GGA() to avoid a segfault with a
+	  killer packet.  Need to re-write extract_RMC() and extract_GLL()
+	  in a similar manner.	The fix is to get rid of strtok() and use
+	  util.c:split_string() instead.
+
+2003-04-28 14:50  we7u
+
+	* src/: interface.c, util.c, util.h: Moved split_string() function
+	  to util.c/util.h in preparation for using it from more places in
+	  the code (instead of just interface.c).
+
+2003-04-28 11:47  we7u
+
+	* src/maps.c: Making debug levels more consistent.
+
+2003-04-28 11:43  we7u
+
+	* src/maps.c: Adding new routine which can determine whether a
+	  Shape ring is a fill or a hole ring.	This is part of the work to
+	  implement the "holes" properly for Shapefiles.
+
+2003-04-28 10:27  we7u
+
+	* config/language-Spanish.sys: Changes by Jose R. Marte A., HI8GN.
+
+2003-04-27 20:45  we7u
+
+	* src/maps.c: Adding more comments.
+
+2003-04-26 23:38  we7u
+
+	* src/maps.c: More comment changes.  No code changes.
+
+2003-04-26 23:15  we7u
+
+	* README.1ST: Changed the location for the Tiger/Line->Shapefile
+	  downloads.
+
+2003-04-26 18:21  we7u
+
+	* src/maps.c: Working on the Shapelib drawing function "hole"
+	  problem.  So far just adding comments and example code in
+	  comments.  No code changes yet.
+
+2003-04-25 17:32  we7u
+
+	* src/maps.c: Adding more comments.
+
+2003-04-25 17:09  we7u
+
+	* src/maps.c: Added comments.
+
+2003-04-25 15:49  we7u
+
+	* config/language-Italian.sys: Another tweak by Marco Calistri,
+	  IK5BCU.
+
+2003-04-25 15:45  we7u
+
+	* src/maps.c: Changing to "Nonconvex" parameter for the rest of the
+	  XFillPolygon calls.  This should speed up drawing a bit.
+
+2003-04-25 15:30  we7u
+
+	* src/maps.c: Changing XFillPolygons to use Nonconvex parameter,
+	  which speeds up map drawing for cases where the line doesn't
+	  cross its own path.  Added some comments.
+
+2003-04-25 15:29  we7u
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-Italian.sys, language-Spanish.sys: Correcting one bug
+	  left in the files due to a mistyped character.  Checking in
+	  latest Italian translation by Marco Calistri, IK5BCU.
+
+2003-04-25 13:36  we7u
+
+	* README.win32, README.1ST: Added notes about libcurl.
+
+2003-04-24 17:25  jtwilley
+
+	* src/maps.c: Added code to support libcurl.  Added code to remove
+	  PACKAGE_* warnings.
+
+2003-04-24 17:24  jtwilley
+
+	* src/track_gui.c: Added code to support libcurl.
+
+2003-04-24 17:20  jtwilley
+
+	* src/main.c: Added code to support libcurl.  Added code to remove
+	  PACKAGE_* warnings.
+
+2003-04-24 17:19  jtwilley
+
+	* src/util.c: Added code for curl_fwrite and curl_getfile.
+
+2003-04-24 17:15  jtwilley
+
+	* src/util.h: Added declarations for curl_fwrite and curl_getfile.
+
+2003-04-24 17:04  jtwilley
+
+	* configure.ac: Added check for libcurl.
+
+2003-04-24 15:25  we7u
+
+	* src/: interface.c, maps.c: Adding comments.
+
+2003-04-24 14:06  we7u
+
+	* README.win32: Revising the Perl interpreter to install.  There
+	  are problems with 5.8.0 yet.
+
+2003-04-23 13:16  we7u
+
+	* src/interface.c: Changing port_read() to a 50ms delay instead of
+	  20ms.  Last checkin was a slight oops.
+
+2003-04-23 13:15  we7u
+
+	* src/interface.c: Speeding up the port_read() and port_write()
+	  delays again.  We were starting to get behind at processing
+	  packets from full-feeds, with 100ms delays.  Changed to 50ms
+	  delays and we appear to catch up when we get a bit behind.  The
+	  correct solution for this is to use select() to wait for data to
+	  process, instead of using it as a short sleep function.
+	  Something to change another day...
+
+2003-04-22 23:08  we7u
+
+	* src/maps.c: Minor revisions to the create_shapefile from APRS
+	  Trail functions.  Maps are now saved in the /maps/GPS/ directory
+	  and are red dashed lines by default.	They appear in the Map
+	  Chooser once re-index maps has been run.
+
+2003-04-22 10:34  we7u
+
+	* src/: db.c, main.c, main.h, maps.c, maps.h: The "Store Track"
+	  button on the Station Info dialog now saves the station track as
+	  a Shapefile map in /var/tmp/, if Shapelib has been compiled in.
+	  The Shapefile filename will contain the callsign and a
+	  date/timestamp.  The original function of the button still
+	  remains as well:  It also saves the info in the original text
+	  format.
+
+2003-04-22 01:35  jtwilley
+
+	* src/main.c: Added tnc_data_clean call to static TNC case.
+
+2003-04-22 01:30  jtwilley
+
+	* src/interface.c: Replaced broken routine in tnc_data_clean with
+	  working routine.
+
+2003-04-21 15:45  we7u
+
+	* src/interface.c: Changed port_write() so that it'll send blocks
+	  of characters across network interfaces, single chars with
+	  inter-character pacing across serial interfaces.
+
+2003-04-18 17:21  we7u
+
+	* xastir.spec.in: Updated spec input file.  Starting to work.
+
+2003-04-18 17:21  we7u
+
+	* Makefile.am: Adding xastir/GNIS/ directory to install.  Used for
+	  searching.
+
+2003-04-18 15:37  we7u
+
+	* README.win32: Updating library versions that we've tested with.
+
+2003-04-18 13:59  we7u
+
+	* README.1ST: Updating optional library versions that Xastir has
+	  been tested with.
+
+2003-04-18 13:48  we7u
+
+	* xastir.spec.in: Fixes so that man page gets installed correctly.
+
+2003-04-18 12:47  we7u
+
+	* xastir.spec.in: Tweaks to make the spec file more up-to-date.
+	  The changes fix several of the failures in building RPM's, but
+	  still fails building the man page.
+
+2003-04-18 12:09  we7u
+
+	* README.win32: Updating docs to latest Shapefile version tested.
+
+2003-04-18 11:46  we7u
+
+	* README.1ST: Updating version of Shapelib library to latest
+	  tested.
+
+2003-04-17 15:08  we7u
+
+	* src/igate.c: Added a comment.
+
+2003-04-17 14:32  we7u
+
+	* src/igate.c: Adding AGWPE devices to the dupe queues for igating.
+
+2003-04-17 13:35  we7u
+
+	* README.1ST: Adding another map link.
+
+2003-04-17 10:24  we7u
+
+	* README.1ST: Another GPSMan note.
+
+2003-04-17 10:21  we7u
+
+	* README.1ST: Updating the libgeotiff instructions.
+
+2003-04-17 10:11  we7u
+
+	* README.1ST, README.win32: Re-organization of the wetnet
+	  directories.	Changed links in README's to match.
+
+2003-04-17 09:56  we7u
+
+	* README.1ST, README.win32: Changed from eskimo.com to wetnet.net
+	  for some of the optional map library download sites.
+
+2003-04-16 17:12  we7u
+
+	* src/igate.c: We now allow partial matches of NWS data, but the
+	  strings defined in the nws-stations.txt file must be at least
+	  three characters long in order to create a valid match.
+
+2003-04-16 16:42  we7u
+
+	* src/: interface.c, interface_gui.c, location_gui.c, maps.c:
+	  Fixing more possible scanf()/sscanf() buffer overflow conditions.
+
+2003-04-16 16:40  we7u
+
+	* config/language-Spanish.sys: Updates by Jose R. Marte A., HI8GN.
+
+2003-04-16 16:27  we7u
+
+	* src/igate.c: Fixing a possible buffer overflow condition where
+	  we're reading the nws-stations.txt file into an array.
+
+2003-04-16 16:14  we7u
+
+	* README.1ST: Miscellaneous maps notes.  Put in eskimo.com as an
+	  alternate location for some of the map libaries.
+
+2003-04-16 15:56  we7u
+
+	* README.win32: Added more download sites for the optional map
+	  libraries.
+
+2003-04-16 14:12  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-04-16 14:04  we7u
+
+	* config/language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-04-16 12:32  we7u
+
+	* config/language-Spanish.sys: Adding the strings back in that were
+	  added yesterday but left out of the last translation.
+
+2003-04-16 12:29  we7u
+
+	* config/language-Spanish.sys: Updates by Jose R. Marte A., HI8GN.
+
+2003-04-16 10:14  we7u
+
+	* src/interface.c: Added comments.  Added character pacing on write
+	  again for the DEVICE_NET_AGWPE interface.  It's separate from the
+	  others so that it can be fine-tuned.
+
+2003-04-15 17:24  we7u
+
+	* src/interface.c: Adding some debug statements.
+
+2003-04-15 15:14  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Putting in language
+	  strings instead of hard-coded English for Configure->Timing
+	  dialog.
+
+2003-04-15 15:04  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Fixes for hard-coded
+	  English strings in Maps->Enable/Configure Tigermap dialog.
+
+2003-04-15 14:34  we7u
+
+	* src/main.c: Fixing Configure->Defaults dialog so that all of the
+	  widgets are visible in all of our supported languages.
+
+2003-04-15 13:41  we7u
+
+	* config/language-Dutch.sys: Changes by Han Sytsma, PE1FAM.
+
+2003-04-15 13:00  we7u
+
+	* src/interface_gui.c: Disabling relay digipeat for AGWPE interface
+	  until raw transmit packet frames can be implemented.
+
+2003-04-15 12:52  we7u
+
+	* src/db.c: Added a comment.
+
+2003-04-15 12:51  we7u
+
+	* src/interface.c: Comments.  Changed test packet callsigns.
+
+2003-04-15 09:04  we7u
+
+	* config/language-German.sys: Changes by Rolf Bleher, DK7IN.
+
+2003-04-15 08:41  we7u
+
+	* config/language-English.sys: Committing changes for Rolf Bleher,
+	  DK7IN.
+
+2003-04-15 01:21  we7u
+
+	* src/interface.c: Fix to igate_path for AGWPE interfaces.
+
+2003-04-14 09:32  we7u
+
+	* config/language-Spanish.sys: Updates by Jose R. Marte A., HI8GN.
+
+2003-04-13 08:51  rzg
+
+	* help/help-English.dat: Various updates for new features, and typo
+	  fixes, more to come.
+
+2003-04-11 18:32  we7u
+
+	* src/: db.c, db.h, festival.c, festival.h, main.c, main.h,
+	  rotated.c, rotated.h, wx.c, wx_gui.c: Corrected some
+	  inconsistencies found by running the compiler at higher warning &
+	  pedantic levels.
+
+2003-04-11 17:07  we7u
+
+	* src/: maps.c, messages_gui.c, util.c: More minor cleanups.
+
+2003-04-11 16:59  we7u
+
+	* src/: bulletin_gui.c, db.c, gps.c, interface.c, interface.h,
+	  main.c, maps.c: Minor cleanups.  Lots of them.
+
+2003-04-11 16:58  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-04-11 15:36  we7u
+
+	* config/language-Portuguese.sys: Tweaks to add missing strings.
+
+2003-04-11 15:30  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2003-04-11 15:13  we7u
+
+	* README.1ST: Another tweak by J. Lance Cotton.
+
+2003-04-11 15:08  we7u
+
+	* README.1ST: Added instructions for reprojecting Shapefiles,
+	  courtesy of Derrick J Brashear and J. Lance Cotton.
+
+2003-04-11 14:07  we7u
+
+	* src/: db.c, interface_gui.c: Setting up for relay digipeating
+	  using AGWPE interfaces.  Untested.
+
+2003-04-11 13:49  we7u
+
+	* src/igate.c: Added AGWPE to igating code.
+
+2003-04-11 13:42  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c,
+	  src/interface_gui.c: Implemented the transmit radioport option
+	  for AGWPE interfaces.  This can be adapted to other multi-port
+	  TNC interfaces later.
+
+2003-04-11 13:26  we7u
+
+	* src/interface.c: Backing out one change to avoid high CPU-usage
+	  in the port_write() function.  Added comments to the port_read()
+	  and port_write() threads to hopefully eliminate this sort of
+	  problem in the future.
+
+2003-04-11 11:17  we7u
+
+	* src/interface.c: Added code to disable Nagle's algorithm for
+	  TCP/IP sockets : TCP_NODELAY setsockopt().
+
+2003-04-11 10:25  we7u
+
+	* src/interface.c: Eliminated line pacing for network connections.
+	  Added more serial types to the character pacing code.
+
+2003-04-10 17:10  we7u
+
+	* src/interface.c: Fixing a lock problem and commenting out some
+	  debug packets for AGWPE.
+
+2003-04-10 14:17  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Tweaking AGWPE
+	  labels.
+
+2003-04-10 14:13  we7u
+
+	* src/interface_gui.c: Removing filter options from AGWPE
+	  Properties dialog.  Doesn't apply.
+
+2003-04-10 14:05  we7u
+
+	* src/interface_gui.c: Extending the length for AGWPE passwords.
+
+2003-04-10 13:58  we7u
+
+	* src/interface_gui.c: More AGWPE stuff.
+
+2003-04-10 12:49  kd6zwr
+
+	* src/maps.c: Fix for systems with both Xpm.h and XpmI.h
+
+2003-04-10 12:46  we7u
+
+	* src/interface.c: Getting rid of unused variables and old code.
+
+2003-04-10 12:40  we7u
+
+	* src/interface.c: Moved the unproto path selection into its own
+	  routine.  More code changes to support agwpe.
+
+2003-04-10 11:14  we7u
+
+	* README.1ST: Specifying an alternate ftp site to get the radar
+	  geo's from.
+
+2003-04-10 09:45  we7u
+
+	* README.1ST, help/help-English.dat: Adding a few notes about the
+	  .GEO file format specifying that decimal degrees are used for
+	  lat/lon in these files.
+
+2003-04-08 14:30  we7u
+
+	* src/interface.c: Changing input parameter for send_agwpe_packet()
+	  to accept a digi path instead of a list of digi's.  This will
+	  integrate into the Xastir method of specifiying paths more
+	  easily.
+
+2003-04-08 13:33  we7u
+
+	* src/interface.c: Changing the AGWPE login ID to be callsign minus
+	  SSID (removed SSID).
+
+2003-04-07 23:17  we7u
+
+	* src/interface.c: Initial transmit capability for AGWPE
+	  interfaces.  Currently the path is hard-coded to RELAY,WIDE2-2,
+	  but that will change given time.  The method of specifying the
+	  path differs greatly from Xastir's original method, plus the
+	  Properties GUI for AGWPE needs to be reworked to add in the
+	  optional path fields.
+
+2003-04-07 10:26  we7u
+
+	* src/interface.c: Commenting out some debugging printf's.
+
+2003-04-06 13:25  we7u
+
+	* src/main.c: The other small tweak needed in order to decode AGWPE
+	  packets.
+
+2003-04-06 13:22  we7u
+
+	* src/interface.c: AGWPE interface receive mode is not functional.
+	  Transmit is still being worked on.
+
+2003-04-05 11:16  we7u
+
+	* src/interface.c: More AGWPE code.  We're getting packets sent in
+	  both directions now, although the login/password packet doesn't
+	  appear to be accepted properly yet.  No decoding/encoding of real
+	  packets is implemented yet.
+
+2003-04-04 16:55  we7u
+
+	* src/xa_config.c: Fixing this so that it handles the correct types
+	  of interfaces.
+
+2003-04-04 14:04  we7u
+
+	* src/interface.c: Added some comments.
+
+2003-04-04 13:50  we7u
+
+	* src/interface.c: More AGWPE stuff.  Not functional yet.
+
+2003-04-04 12:52  we7u
+
+	* src/interface.c: Send the login packet to AGWPE only if the
+	  passwd string has something in it.
+
+2003-04-04 11:48  we7u
+
+	* src/interface.c: More AGWPE interface code.  Now sending
+	  login/password string and command to ask AGWPE to send us the
+	  monitored packets.  Don't have transmit or the receive decode of
+	  those packets completed yet, but debug code is in place that
+	  looks for complete headers and packets and notifies us on
+	  reception.
+
+2003-04-03 23:48  we7u
+
+	* src/interface.c: More AGWPE stuff.  Not functional yet.
+
+2003-04-03 17:12  we7u
+
+	* src/interface.c: More AGWPE work.  Not functional yet.
+
+2003-04-03 14:40  we7u
+
+	* src/interface.c: Reformatting.  No code changes.
+
+2003-04-03 14:24  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.c, src/interface.h,
+	  src/interface_gui.c: Initial steps at adding network support for
+	  AGWPE.
+
+2003-04-03 12:57  we7u
+
+	* src/: main.c, maps.h: Adding my test_create_shapefile stuff back
+	  in, this time with the proper #ifdef's so that everybody can
+	  still compile the code whether they have shapelib installed or
+	  not.
+
+2003-04-03 11:52  we7u
+
+	* src/: main.c, maps.c: Spawning off a separate thread for doing
+	  the Snapshot() function.
+
+2003-04-03 09:39  we7u
+
+	* src/maps.c: Changing the Snapshot function so that it can reduce
+	  to 256 colors if necessary when converting from XPM to PNG.
+
+2003-04-02 13:01  francais1
+
+	* src/interface.c: Enable suid privileges around bind to reset from
+	  callsign (RELAY digipeat bugfix with 2.2.19 kernels, I hope.)
+
+2003-04-02 11:30  we7u
+
+	* src/main.c: Disabling my test_create_shapefile_map entry.  Some
+	  people can't get Xastir to compile with it in there, and it's
+	  test code anyway.
+
+2003-04-01 16:27  we7u
+
+	* src/: main.c, maps.c, maps.h: Testing of the shapefile creation
+	  function.  Attached to the "Test" button on the menus.
+
+2003-04-01 15:25  we7u
+
+	* src/maps.c: Changed to comments.  No code changes.
+
+2003-04-01 13:13  we7u
+
+	* src/interface.c: Adding some white space.  No code changes this
+	  time.
+
+2003-04-01 09:55  we7u
+
+	* src/xastir.h: Enabling serial KISS tnc relay digipeat
+	  functionality by default.  Initial testing shows that this
+	  portions of relay digipeat is working.  AX.25 relay digipeat
+	  still needs a bit of work to get the source callsign to be set
+	  properly.
+
+2003-04-01 01:09  we7u
+
+	* src/: db.c, interface.c: Changes to make RELAY digipeating
+	  functional for Serial KISS TNC interfaces.  May have fixed AX.25
+	  interfaces as well.
+
+2003-03-31 23:16  we7u
+
+	* src/db.c: Better debug output for relay_digipeat() function.
+
+2003-03-31 15:31  we7u
+
+	* src/db.c: More debug messages for relay_digipeat() function.
+	  Again, will be removed later.
+
+2003-03-31 14:59  we7u
+
+	* src/db.c: Adding some debug output for relay digipeat.  It'll be
+	  removed later when we get things working properly.
+
+2003-03-28 17:05  we7u
+
+	* src/db.c: More KISS variant comments.
+
+2003-03-28 16:37  we7u
+
+	* src/db.c: Added another kiss variant to the comments.
+
+2003-03-28 16:34  we7u
+
+	* src/db.c: Added some notes about KISS protocol variants.  No code
+	  changes.
+
+2003-03-28 11:13  we7u
+
+	* src/maps.c: Changing point shapefiles so that if labels are
+	  turned off, the symbols still get drawn.
+
+2003-03-28 10:33  we7u
+
+	* src/: interface.c, db.c: Added comments.  Now mask off the AX.25
+	  P/F bit before checking the control byte for 0x03 (UI Frame).
+	  Now drop the Serial KISS packet if the final result is not 0x03.
+
+2003-03-27 15:57  we7u
+
+	* src/db.c: Taking out the control byte == 0x03 restriction for
+	  Serial KISS packets.	MKISS TNC's encode the channel number in
+	  the control byte.
+
+2003-03-27 15:46  we7u
+
+	* src/db.c: Added a note to decode_ax25_header() function.
+
+2003-03-27 15:42  we7u
+
+	* README.1ST: Added a GPSMan install step to set the permissions on
+	  the /usr/local/xastir/maps/GPS/ directory so that files could be
+	  written there.
+
+2003-03-27 15:33  we7u
+
+	* src/db.c: Changing the Serial KISS interface to ignore packets if
+	  the control byte != 0x03 and the PID byte != 0x0f.  This will
+	  make it co-exist on channels that might have other protocols on
+	  them (net/rom, tcp/ip, etc.).  The AX.25 interface code already
+	  had the PID==0x0f restriction on it.
+
+2003-03-27 14:32  we7u
+
+	* README.win32: Changed "go.bat" to just "go".	Less typing to get
+	  things rolling that way.
+
+2003-03-27 14:16  we7u
+
+	* README.win32: Added zip/unzip to the list of packages to install.
+	  Helps when installing some map files later.
+
+2003-03-27 11:21  we7u
+
+	* README.win32: Added some blank lines.
+
+2003-03-27 11:17  we7u
+
+	* README.1ST: Added notes about how to decompress the World
+	  shapefile.
+
+2003-03-27 11:11  francais1
+
+	* FAQ: Added a lesstif/openmotif entry
+
+2003-03-26 22:10  we7u
+
+	* README.win32: More details for the user in terms of creating
+	  subdirectories while adding in the optional libraries.
+
+2003-03-26 11:55  we7u
+
+	* Makefile.am: Added the xastir/maps/GPS/ directory to the
+	  directories created during install.  This directory is required
+	  for GPSMan to operate with Xastir properly.
+
+2003-03-26 11:28  we7u
+
+	* src/main.c: Updating about message to contain 2003 instead of
+	  2002.
+
+2003-03-26 10:41  we7u
+
+	* src/main.c: Changing the method of parameter passing between
+	  GPS_operations() and gps_transfer_thread() in order to solve a
+	  user's problem.
+
+2003-03-26 10:00  we7u
+
+	* src/main.c: A few minor tweaks to GPS_operations and
+	  gps_transfer_thread, mostly to debug problems with parameter
+	  passing.
+
+2003-03-24 15:28  we7u
+
+	* README.win32: One more note to get libgeotiff working on Cygwin.
+	  Must rename the libtiff dll's in order to be compatible with the
+	  version of libgeotiff.
+
+2003-03-24 13:36  we7u
+
+	* README.win32: Removed warning note above the geotiff
+	  instructions:  It is working again with the current instructions.
+
+2003-03-24 12:52  we7u
+
+	* README.win32: Some minor additions to the libproj install that
+	  helps the libgeotiff install to complete.
+
+2003-03-23 18:46  we7u
+
+	* README.win32: Added more notes to clarify places where some users
+	  were tripping up.
+
+2003-03-23 18:45  we7u
+
+	* README.1ST: Added asterisks next to the note about the Shapefile
+	  world map.
+
+2003-03-22 00:28  we7u
+
+	* src/interface.h: Reversed order of arguments for socklen_t
+	  typedef.
+
+2003-03-21 16:50  we7u
+
+	* README.win32: Taking out some old notes that aren't applicable
+	  anymore.
+
+2003-03-21 16:49  jtwilley
+
+	* configure.ac: Forgot to actually include -lax25 when detecting it
+
+2003-03-21 16:48  we7u
+
+	* README.win32: Another minor Cygwin tweak.
+
+2003-03-21 16:28  we7u
+
+	* src/util.c: Another minor Cygwin tweak.
+
+2003-03-21 16:25  we7u
+
+	* README.win32: More Cygwin tweaks.
+
+2003-03-21 16:02  jtwilley
+
+	* src/: interface.c, interface_gui.c: Changed references of
+	  HAVE_AX25 to HAVE_LIBAX25 to match new configure.
+
+2003-03-21 12:44  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Removing the "Are You
+	  Sure?" button on exit (to keep peace with the other war-monger
+	  developers ;-)
+
+2003-03-20 14:29  jtwilley
+
+	* acinclude.m4, configure.ac, src/hostname.c, src/interface.c,
+	  src/interface.h, src/main.c, src/maps.c, src/maps.h, src/util.c,
+	  src/wx_gui.c, src/xa_config.c: Massive configuration overhaul --
+	  moving functions from configure.ac to acinclude.m4 and beginning
+	  to streamline configure.ac, with attendant changes in various
+	  source files.
+
+2003-03-18 14:59  we7u
+
+	* src/: db.c, interface_gui.c, xastir.h: Tweaks to enable testing
+	  of RELAY digipeat with serial KISS TNC's.  One define in xastir.h
+	  needs to be changed in order to enable it.
+
+2003-03-18 14:39  francais1
+
+	* src/: db.c, interface_gui.c: Allowed selection of AX25 relay
+	  digipeat
+
+2003-03-18 14:28  we7u
+
+	* src/: gps.c, gps.h, main.c: Changing how GPS status messages are
+	  done.
+
+2003-03-18 13:50  we7u
+
+	* src/: gps.c, interface.c, main.c, xastir.h: Fixes for the GPS
+	  high-CPU usage.  We now save GPRMC and GPGGA strings in global
+	  variables, dropping all other strings.  At the GPS Check
+	  Interval, we decode up to two strings that we have saved most
+	  recently.
+
+2003-03-17 14:58  we7u
+
+	* configure.ac: Another ImageMagick tweak for Cygwin.
+
+2003-03-17 12:39  we7u
+
+	* configure.ac: Trying another small tweak for Cygwin.	It's not
+	  currently recognizing the ImageMagick libraries installed in
+	  /usr/lib.
+
+2003-03-16 23:29  we7u
+
+	* src/main.c: We now call reload_object_item() after we clear all
+	  stations.  This keeps locally-owned objects on our screen and in
+	  our in-memory database.
+
+2003-03-16 21:54  we7u
+
+	* README.1ST: Added a Festival note from J. Lance Cotton.
+
+2003-03-14 21:59  we7u
+
+	* src/main.c: Fixing an errand comment on a #endif statement.
+
+2003-03-14 17:01  we7u
+
+	* README.win32: Tweaking the Cygwin/ImageMagick notes.
+
+2003-03-14 16:41  we7u
+
+	* README.win32: More optional library notes.  Trying to work
+	  through the problems with the latest
+	  ImageMagick/proj.4/libgeotiff libraries.
+
+2003-03-14 13:10  we7u
+
+	* README.win32: More notes about problems with geotiff maps and
+	  current Cygwin versions.
+
+2003-03-14 11:51  we7u
+
+	* README.win32: Adding more notes about the impure_ptr problem.
+
+2003-03-14 11:43  we7u
+
+	* README.win32: Changing the version of libgeotiff called out.
+
+2003-03-14 11:41  we7u
+
+	* README.1ST: Removed Cygwin info.  It now tells Windows users to
+	  refer to the README.win32 file instead.
+
+2003-03-13 10:29  we7u
+
+	* README.1ST: Added a bit to the GPSMan notes.
+
+2003-03-12 20:43  we7u
+
+	* README.1ST: Minor fixes to the gpsman instructions.
+
+2003-03-12 13:20  francais1
+
+	* src/interface.c: Fix to remove the star before the
+	  ax25_aton_entry call because it would call it a bad callsign.
+
+2003-03-12 11:23  we7u
+
+	* src/main.c, configure.ac, README.1ST: Added support for the
+	  production version of GPSMan.  Have at it!
+
+2003-03-11 17:02  we7u
+
+	* README.win32: Minor cygwin changes.
+
+2003-03-11 16:43  we7u
+
+	* README.1ST, README.win32: Slight changes to Cygwin instructions.
+
+2003-03-11 16:26  we7u
+
+	* README.win32: Adding a Cygwin/Win32 specific README file to make
+	  it easier for Windows users to get up and running with Xastir.
+	  Initial check-in.
+
+2003-03-07 17:31  we7u
+
+	* README.1ST: More Cygwin changes.
+
+2003-03-07 17:25  we7u
+
+	* README.1ST: More Cygwin changes.
+
+2003-03-07 16:36  we7u
+
+	* README.1ST: More Cygwin notes.
+
+2003-03-07 16:15  we7u
+
+	* README.1ST: Correcting some Cygwin libproj notes.
+
+2003-03-07 14:07  we7u
+
+	* README.1ST: Minor change to library revision number for Cygwin.
+
+2003-03-07 14:02  we7u
+
+	* README.1ST: More Cygwin notes.
+
+2003-03-07 13:46  we7u
+
+	* README.1ST: Added notes regarding "make install-strip" option.
+
+2003-03-07 13:10  we7u
+
+	* configure.ac: libproj/libgeotiff fixes for Cygwin.
+
+2003-03-07 11:07  we7u
+
+	* README.1ST: Tweaked the comments about creating the terraserver
+	  .geo file.
+
+2003-03-07 11:03  we7u
+
+	* src/maps.c: Starting to add shapefile creation functions.  Intend
+	  to use these to save station trails to map files eventually.
+
+2003-03-06 14:41  we7u
+
+	* configure.ac, src/main.c: Changed some comments.
+
+2003-03-06 14:21  we7u
+
+	* README.1ST: Added initial notes regarding gpsmanshp and GPSMan.
+
+2003-03-06 14:04  we7u
+
+	* configure.ac: Adding checks for GPSman and gpsmanshp.so.  Not
+	  ready for prime-time yet, but should be soon.
+
+2003-03-06 10:47  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/gps.c, src/interface.c,
+	  src/main.c: Added a popup when GPS data goes stale.  We now allow
+	  one posit when GPS interfaces are first enabled before we
+	  consider the data stale and disable transmit of My Position.
+	  Removed the statusline messages that happen when we successfully
+	  decode GPRMC or GPGGA sentences:  They were causing too much CPU
+	  time on Yellow Dog Linux (powerPC).
+
+2003-03-05 16:39  we7u
+
+	* src/interface.c: Fix the case where someone plays with a GPS
+	  interface and then turns it off again.  Before this change,
+	  posits would be disabled unless GPS interface was re-enabled that
+	  had good data coming in, or unless the user restarted Xastir.
+
+2003-03-05 15:32  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/maps.c: Language
+	  strings for GPS operations.  Added more colors.  Create default
+	  time/date filename if no filename given.
+
+2003-03-05 14:04  we7u
+
+	* src/main.c: Added a UI to the gps transfer code.  Not enabled yet
+	  for users.
+
+2003-03-05 13:54  we7u
+
+	* src/maps.c: Minor changes to new GPS stuff.
+
+2003-03-04 16:51  we7u
+
+	* src/maps.c: Removing the color portion of the filename for GPS
+	  map labels.
+
+2003-03-04 16:49  we7u
+
+	* src/main.c: Changed a few comments.
+
+2003-03-04 16:34  we7u
+
+	* src/main.c: Minor updates to new GPS stuff.  Not enabled for
+	  normal use yet.
+
+2003-03-04 15:55  we7u
+
+	* src/main.c: Converted to switch statement in new GPS transfer
+	  routines.  Can now because it's an int.
+
+2003-03-04 15:42  we7u
+
+	* src/main.c: Separated the GPS transfer functions into their own
+	  thread.  GPS transfers now run concurrently with the other
+	  threads, updating the map view when they complete.
+
+2003-03-04 12:34  we7u
+
+	* README.1ST: More Cygwin libproj and libgeotiff notes.
+
+2003-03-04 11:13  we7u
+
+	* README.1ST: Correcting spelling.
+
+2003-03-04 10:51  we7u
+
+	* src/: main.c, maps.c: More experimental GPSMan stuff.  Not ready
+	  for release yet.
+
+2003-02-28 17:52  we7u
+
+	* README.1ST: More Cygwin libgeotiff notes.
+
+2003-02-28 17:48  we7u
+
+	* src/maps.c: Changing the line style for GPS info.
+
+2003-02-28 17:38  we7u
+
+	* README.1ST: More Cygwin notes.
+
+2003-02-28 17:31  we7u
+
+	* README.1ST: More Cygwin stuff:  libgeotiff.
+
+2003-02-28 16:30  we7u
+
+	* src/maps.c: Rotating the labels to horizontal for GPS maps.
+	  Changing orange to lighter orange.
+
+2003-02-28 16:20  we7u
+
+	* src/maps.c: Chopping off the ".shp" portion of the GPS labels.
+
+2003-02-28 16:00  we7u
+
+	* src/maps.c: More label/color stuff for gps maps.
+
+2003-02-28 15:48  we7u
+
+	* src/maps.c: Adding labels to the GPS tracks/routes.
+
+2003-02-28 13:39  we7u
+
+	* src/maps.c: More GPS stuff.  Not enabled yet.
+
+2003-02-28 13:19  we7u
+
+	* src/main.c: Turning off the new GPS stuff.
+
+2003-02-28 12:48  we7u
+
+	* src/main.c: More gps transfer stuff.	Not ready for prime-time
+	  yet.
+
+2003-02-27 16:40  we7u
+
+	* configure.ac: Reversing the order of lib checking for libproj and
+	  libgeotiff.
+
+2003-02-27 16:30  jtwilley
+
+	* ChangeLog, configure.ac: Cleaned up XASTIR_TOCALL in configure.ac
+	  to no longer require SHORT_VERSION
+
+2003-02-27 15:52  we7u
+
+	* README.1ST: More Cygwin notes.  libgeotiff stuff.
+
+2003-02-27 15:31  we7u
+
+	* README.1ST: More changes for Cygwin.	Installation of Proj.4 now
+	  complete and documented.  I'm still working on installation of
+	  libgeotiff.
+
+2003-02-27 12:53  we7u
+
+	* src/main.c: Preliminary support for GPSMan:  Downloads track,
+	  creates Shapefile map, auto-imports and displays said map in
+	  Xastir.  Requires pre-release GPSMan plus gpsmanshp.tgz file
+	  installed.  Also requires that the "WE7U" define at the top of
+	  main.c be defined to put the new code into operation.
+
+2003-02-27 09:39  we7u
+
+	* configure.ac: Added a tweak to look for the Shapelib include file
+	  in subdirectory _not_ ending in /libshp/
+
+2003-02-26 10:09  we7u
+
+	* src/: alert.c, alert.h: Removing dead code.  Changed/added a few
+	  comments and debug messages.	Removed prototypes from alert.h
+	  that aren't being used.
+
+2003-02-26 09:38  we7u
+
+	* configure.ac: Taking out extra X11 include path that was just
+	  added for linux recently.
+
+2003-02-25 17:55  we7u
+
+	* src/: bulletin_gui.c, bulletin_gui.h, db.c, db.h: Fixes for
+	  bulletin popups.
+
+2003-02-25 13:45  we7u
+
+	* src/db.c: Changes to comments only.
+
+2003-02-25 12:50  we7u
+
+	* src/: alert.c, alert.h, db.c, maps.c: Changing NWS weather alerts
+	  so that they are no longer stored in the message database and
+	  rescanned periodically.  They now go straight to the alert_list.
+
+2003-02-25 10:04  we7u
+
+	* src/: bulletin_gui.c, bulletin_gui.h: Fixing another bug having
+	  to do with zero-distance bulletins popping up when the user
+	  settings tell Xastir not to.
+
+2003-02-25 09:31  we7u
+
+	* src/main.c: Added Map Display Bookmarks button to right-click
+	  mouse menu.
+
+2003-02-24 23:03  we7u
+
+	* configure.ac: Adding a path for Linux configure to help find
+	  Motif include files on some systems.
+
+2003-02-24 22:30  kd6zwr
+
+	* ChangeLog, src/db.c: Made my_station_gps_change update sec_heard
+	  to fix DR of my station.
+
+2003-02-24 16:41  we7u
+
+	* configure.ac: Adding /usr/X11R6/include/Xm as an include path for
+	  Motif/Lesstif for Slackware 8.1.  May need additional things in
+	  order to link to the library as well.
+
+2003-02-24 16:29  we7u
+
+	* src/db.c: Added more comments.
+
+2003-02-24 16:26  we7u
+
+	* src/db.c: Added some comments.
+
+2003-02-24 15:40  we7u
+
+	* src/maps.c: Getting rid of unneeded code.
+
+2003-02-24 15:40  we7u
+
+	* src/db.c: Added some comments.
+
+2003-02-24 15:26  we7u
+
+	* src/: db.c, maps.c, maps.h: Starting to change the weather alert
+	  code to make it independent of the message database.	Part-way to
+	  that goal.  This version just relocates the weather alerts scan
+	  of the message database into the db.c code at the point where we
+	  received the alert.  The next step is to just throw the alert
+	  onto the alert_list and skip the message database portion
+	  altogether.  This current code appears to still be fully
+	  functional w.r.t. weather alerts.
+
+2003-02-24 14:45  we7u
+
+	* src/maps.c: Re-org of a bit of code w.r.t. weather alerts (no
+	  major changes though).  Lots of comment changes.
+
+2003-02-24 13:58  we7u
+
+	* src/draw_symbols.c: Tweaks to watch boxes for Gerry Wheeler.
+
+2003-02-24 13:35  we7u
+
+	* src/maps.c: Removed dead code.  Changed some comments.
+
+2003-02-24 13:04  we7u
+
+	* src/: alert.c, maps.c: Changes to comments only.
+
+2003-02-24 12:46  we7u
+
+	* src/: alert.c, main.c: Setting the proper variables so that a
+	  screen update happens in a timely manner after WX alerts expire.
+
+2003-02-24 12:23  we7u
+
+	* src/: alert.c, main.c, maps.c, wx_gui.c: We now expire wx alerts
+	  only in main.c:UpdateTime(), and only every 60 seconds.  If any
+	  are expired, it schedules a screen update.
+
+2003-02-24 11:41  we7u
+
+	* src/: alert.c, alert.h, maps.c: More minor work on wx alerts.
+
+2003-02-24 11:28  jtwilley
+
+	* ChangeLog: Added entry for change made to src/interface.c
+
+2003-02-24 11:25  jtwilley
+
+	* src/interface.c: Changed timeouts to 100 milliseconds from 100
+	  microseconds.
+
+2003-02-24 10:25  we7u
+
+	* src/: alert.c, alert.h, maps.c, wx_gui.c, xa_config.c: Moved
+	  alert expiration code into common alert_expire() function.
+
+2003-02-23 08:58  we7u
+
+	* src/alert.c: Making an int more global.  Needed for wx alert
+	  expire code elsewhere.
+
+2003-02-23 08:56  we7u
+
+	* src/alert.h: Adding an extern int that other code needs now for
+	  wx alert expiration.
+
+2003-02-23 08:48  we7u
+
+	* src/alert.c: Changed a comment.
+
+2003-02-23 08:44  we7u
+
+	* src/maps.c: Another tweak to wx alert expiration.
+
+2003-02-23 08:40  we7u
+
+	* src/wx_gui.c: Another small tweak to expiration for wx alerts.
+
+2003-02-23 08:37  we7u
+
+	* src/util.c: Tweaking the alert expiration stuff some more.
+
+2003-02-23 01:52  we7u
+
+	* src/: alert.c, alert.h, maps.c, util.c, wx_gui.c: Fixed incorrect
+	  expiration times for weather alerts.	Proper local expiration
+	  time is now computed and stored.  View->WX Alerts dialog appears
+	  to update correctly as alerts come and go.  Weather alert slots
+	  get re-used by new alerts properly.  We might have incorrect
+	  expiration times for weather alerts twice a year when daylight
+	  savings time switches though.
+
+2003-02-22 08:41  n0vh
+
+	* src/main.c: Fixed the intensity slider since 0 was causing xastir
+	  to crash.  Set the minimum to something reasonable.
+
+2003-02-21 17:16  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added a new button the
+	  Stations menu:  Reload Object/Item History.
+
+2003-02-21 16:58  we7u
+
+	* src/sound.c: Adding some spacing.  No code changes.
+
+2003-02-21 15:53  we7u
+
+	* src/: alert.c, alert.h, maps.c, wx_gui.c: Fixes to weather
+	  alerts.  Should re-use weather alert slots in the array now, and
+	  should expire things properly as well.
+
+2003-02-21 12:46  we7u
+
+	* configure.ac: Modifying the error messages to make them
+	  consistent and provide useful info to the user.
+
+2003-02-21 11:47  we7u
+
+	* configure.ac: Taking out some commented-out code and some
+	  irrelevant comments.
+
+2003-02-20 21:10  n0vh
+
+	* src/main.c: Logging indicator now changes color to highlight that
+	  it's logging.
+
+2003-02-20 20:31  n0vh
+
+	* src/: main.c, main.h: Added a status text box at the bottom of
+	  the window that indicates that xastir is logging to disk.
+
+2003-02-20 15:31  we7u
+
+	* src/bulletin_gui.c: A few fixes for bulletins.  Also added a
+	  callback for the togglebutton on the View->Bulletins dialog.
+
+2003-02-20 14:34  we7u
+
+	* src/db.c: Added a debugging message.
+
+2003-02-20 14:18  we7u
+
+	* src/main.c: Changing the "Test" function a bit.
+
+2003-02-20 12:00  we7u
+
+	* src/bulletin_gui.c: Changing time between receiving a new
+	  bulletin and checking whether it is within our range:  From 15
+	  seconds to 60 seconds.  This actually delays our getting notice
+	  of each new bulletin, but helps to prevent popping up bulletins
+	  when a bulletin comes in and then a posit comes in later for that
+	  station (putting that station outside our range).  The cause of
+	  the bulletin window popping up appears to be these
+	  inside-our-range/ outside-our-range-when-a-posit-comes-in
+	  bulletins.
+
+2003-02-20 11:32  we7u
+
+	* src/maps.c: Changed/added some comments.  No code changes.
+
+2003-02-20 10:31  we7u
+
+	* configure.ac: Added more search paths for Solaris 8/9 binaries.
+
+2003-02-20 02:10  we7u
+
+	* bootstrap.sh: Added status messages.
+
+2003-02-20 01:51  we7u
+
+	* src/: alert.c, bulletin_gui.c, db.c, draw_symbols.c, gps.c,
+	  hostname.c, interface.c, interface_gui.c, list_gui.c,
+	  locate_gui.c, main.c, maps.c, popup_gui.c, rac_data.c, rotated.c,
+	  snprintf.c, track_gui.c, util.c, view_message_gui.c, wx_gui.c,
+	  xa_config.c: Added comments.
+
+2003-02-20 01:45  we7u
+
+	* src/: bulletin_gui.h, db.h, draw_symbols.h, festival.h, gps.h,
+	  hostname.h, igate.h, list_gui.h, main.h, maps.h, rotated.h,
+	  snprintf.h, track_gui.h, util.h, wx.h, xastir.h: Added comments.
+
+2003-02-20 01:00  we7u
+
+	* src/: maps.c, track_gui.c, util.c: More fixes for calling
+	  external programs.
+
+2003-02-20 00:33  we7u
+
+	* src/: maps.c, track_gui.c, util.c: Checking for existence of
+	  external programs before trying to invoke them.  If they don't
+	  exist, we call "echo" instead (relatively harmless).
+
+2003-02-19 23:56  we7u
+
+	* src/: alert.c, wx_gui.c: Added code to clear out expired weather
+	  alerts so that later alerts can use that slot.  Also caused the
+	  View->Weather Alerts dialog to skip empty slots.
+
+2003-02-19 22:47  we7u
+
+	* bootstrap.sh: Separating out the -a and -c params on the automake
+	  line, for Cygwin.
+
+2003-02-19 17:22  francais1
+
+	* configure.ac: A little tweakage
+
+2003-02-19 17:13  we7u
+
+	* src/: maps.c, util.c: Changing code to use new paths computed via
+	  configure.
+
+2003-02-19 17:07  we7u
+
+	* configure.ac: Changing the quoting on some of the newer code I
+	  just added.
+
+2003-02-19 16:46  we7u
+
+	* configure.ac: Removing the "cat" checks as we don't use it
+	  currently.
+
+2003-02-19 16:31  we7u
+
+	* configure.ac: Path discovery for more utilities that we use from
+	  within Xastir.
+
+2003-02-19 15:43  we7u
+
+	* configure.ac, src/interface.c, src/maps.c, src/track_gui.c:
+	  Removing __CYGWIN__ #ifdef's.
+
+2003-02-19 14:40  we7u
+
+	* configure.ac, src/util.c: Getting rid of __FreeBSD__ #ifdef,
+	  replacing it with HAVE_GMTOFF test/ variable/#ifdef.
+
+2003-02-19 13:55  we7u
+
+	* configure.ac, src/gps.c, src/interface_gui.c: Getting rid of
+	  OS-specific #ifdef's related to settimeofday() function, where
+	  the GPS time can be used to set system time.
+
+2003-02-19 13:15  we7u
+
+	* configure.ac: Streamlined the ImageMagick checks.  Added more
+	  comments.  Temporarily commented out the "-Ldir -llibrary"
+	  MacOSX/ImagMagick line which is probably unnecessary.  Will add
+	  it back if tests on MacOSX show it to be required.
+
+2003-02-19 12:44  we7u
+
+	* configure.ac: Streamlining geotiff and libintl code.	Added
+	  comments here and there.
+
+2003-02-19 11:44  we7u
+
+	* configure.ac: Streamlining the X11 library checking code.
+
+2003-02-19 10:51  we7u
+
+	* configure.ac: A bit of housecleaning.  Pretty'ing up the
+	  warning/error messages.  Re-ordering the operating
+	  system-specific areas.
+
+2003-02-19 10:00  we7u
+
+	* configure.ac: Making all of the MacOSX comments have exactly the
+	  same spelling/case.  Easier to grep for in the future.  No code
+	  changes.
+
+2003-02-19 09:35  we7u
+
+	* configure.ac: MacOSX/ImageMagick fix.
+
+2003-02-18 22:20  we7u
+
+	* configure.ac: Removing two brackets that give Mandrake linux
+	  fits.
+
+2003-02-18 14:11  kg4ijb
+
+	* Makefile.am: bzip mod didn't propagate
+
+2003-02-18 14:05  kg4ijb
+
+	* src/Makefile.am: yikes!, automake_option was my bad, removed.
+
+2003-02-18 13:33  we7u
+
+	* src/Makefile.am: Moving the AUTOMAKE_OPTIONS to before the line
+	  continuation char.  It doesn't work where it was put.  Is it
+	  necessary?  Should it be somewhere else in the file?
+
+2003-02-18 13:16  we7u
+
+	* configure.ac: Added some debugging info back in.  Commented out
+	  so a typical user won't be bothered by it.
+
+2003-02-18 12:49  kg4ijb
+
+	* callpass/Makefile.am, config/Makefile.am, help/Makefile.am,
+	  symbols/Makefile.am, m4/Makefile.am, scripts/Makefile.am,
+	  src/Makefile.am: ID message
+
+2003-02-18 12:44  kg4ijb
+
+	* configure.ac: cleaned output and removed all libtool dependancies
+
+2003-02-18 12:43  kg4ijb
+
+	* Makefile.am: removed unecessary automake_options
+
+2003-02-18 12:04  we7u
+
+	* scripts/Makefile.am: Adding missing scripts.	Fixing things so
+	  that "make dist" works properly.
+
+2003-02-18 11:56  we7u
+
+	* bootstrap.sh: Copying the files into the directory instead of
+	  making symlinks.
+
+2003-02-18 11:36  we7u
+
+	* Makefile.am, configure.ac: More fixes to allow "make dest" to
+	  work.
+
+2003-02-18 11:04  we7u
+
+	* Makefile.am: Adding a forgotten subdirectory that makes "make
+	  dist" fail if not present.
+
+2003-02-18 10:57  we7u
+
+	* Makefile.am: Removing the lt* files.
+
+2003-02-18 09:34  we7u
+
+	* src/: main.c, xa_config.c: Changing range for Tigermap intensity
+	  from 50-100% to 0-100%.
+
+2003-02-18 08:23  we7u
+
+	* configure.ac: Bumping revision up to 1.1.4
+
+2003-02-16 22:53  we7u
+
+	* README.1ST: Added a few notes after the lines calling out
+	  bootstrap.sh.
+
+2003-02-16 21:25  we7u
+
+	* configure.ac: Another tweak for ImageMagick on MacOSX.
+
+2003-02-16 09:37  we7u
+
+	* README.1ST: Added a note to the MacOSX section:  Installing
+	  Xastir into /sw.
+
+2003-02-16 09:30  we7u
+
+	* configure.ac: Another ImageMagick fix for MacOSX.
+
+2003-02-16 01:49  we7u
+
+	* README.1ST: Added some more Solaris notes, courtesy of Chris
+	  Bell.
+
+2003-02-16 01:35  we7u
+
+	* configure.ac: Added check for sched_yield() function in librt
+	  (needed for Solaris).
+
+2003-02-15 15:44  we7u
+
+	* src/util.c: Changing back to a __solaris__ ifdef for now.
+
+2003-02-15 14:35  we7u
+
+	* configure.ac: Another fix for ImageMagick on MacOSX.
+
+2003-02-15 14:30  we7u
+
+	* configure.ac, src/hostname.c, src/interface.c,
+	  src/interface_gui.c, src/main.c, src/maps.c, src/snprintf.h,
+	  src/util.c, src/xa_config.c: Removing a lot of OS-specific
+	  #ifdef's, changing to function-specific #ifdef's instead.
+
+2003-02-15 12:10  we7u
+
+	* src/xa_config.c: Temporarily removing the CYGWIN #ifdef, to see
+	  if we have the proper configure.ac support for Cygwin now.
+
+2003-02-15 12:09  we7u
+
+	* src/gps.c: Cygwin change.  Getting rid of CYGWIN tag and
+	  replacing with config.h stuff.
+
+2003-02-15 11:39  we7u
+
+	* configure.ac, src/gps.c, src/interface.c: More MacOSX fixes.
+	  Using variables in config.h now instead of #ifdef MACOSX.
+
+2003-02-15 10:45  we7u
+
+	* src/: gps.c, interface.c: Changing __MacOSX__ tag to MACOSX.
+
+2003-02-15 09:59  we7u
+
+	* configure.ac, src/gps.c, src/hostname.c, src/interface.c,
+	  src/main.c, src/maps.c, src/snprintf.h, src/util.c: MacOSX and
+	  Solaris fixes related to the new Autoconf stuff.
+
+2003-02-14 19:55  kg4ijb
+
+	* configure.ac: *BSD CFLAGS and pthread check
+
+2003-02-14 17:15  we7u
+
+	* configure.ac: Fix for finding Motif libraries on Solaris.
+
+2003-02-14 16:11  we7u
+
+	* configure.ac: Another MacOSX change.
+
+2003-02-14 15:13  we7u
+
+	* configure.ac: Another fix for MacOSX regarding Xm/Xm.h
+
+2003-02-14 14:47  we7u
+
+	* README.1ST: Cygwin/fvwm2 window manager instructions.
+
+2003-02-14 13:55  we7u
+
+	* configure.ac: Changing the old ImageMagick warning message
+	  slightly.
+
+2003-02-14 13:39  we7u
+
+	* configure.ac: Mac OSX/Fink ImageMagick fixes.  Also moved the old
+	  version warning to the end of that section.
+
+2003-02-14 12:59  we7u
+
+	* configure.ac: Mac OSX/Fink mods to help find Shapelib.
+
+2003-02-14 10:30  we7u
+
+	* README.1ST: Added cvs update note to Cygwin section.
+
+2003-02-14 10:15  we7u
+
+	* configure.ac: Tweaking some comments.
+
+2003-02-14 10:09  we7u
+
+	* configure.ac: Adding an RCS tag so we can track revisions.
+
+2003-02-14 09:50  kg4ijb
+
+	* configure.ac: Fixed the tocall problem.  Versioning only needs to
+	  be done in ac_init
+
+2003-02-14 01:34  we7u
+
+	* README.1ST: More Cygwin changes.
+
+2003-02-13 15:39  we7u
+
+	* README.1ST: More Cygwin updates.
+
+2003-02-13 15:22  we7u
+
+	* README.1ST: Updated to reflect new configure.ac stuff.
+
+2003-02-13 14:46  we7u
+
+	* configure.ac: Fixing the TOCALL.  The "APX$SHORT_VERSION" thing
+	  doesn't work.  :-(
+
+2003-02-13 13:42  we7u
+
+	* src/: interface.c, interface.h, interface_gui.c: Added "Networked
+	  Database" GUI code for Brenda Wallace to have as a front-end for
+	  her database code.
+
+2003-02-13 13:40  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Adding strings for
+	  future networked database GUI.
+
+2003-02-13 13:35  kg4ijb
+
+	* ChangeLog:
+	  * bootstrap.sh - routine to rebuild autostuff environment
+
+2003-02-13 13:31  kg4ijb
+
+	* bootstrap.sh: builds necessary autostuff files in appropriate
+	  order
+
+2003-02-13 13:12  kg4ijb
+
+	* ChangeLog: [no log message]
+
+2003-02-13 13:05  kg4ijb
+
+	* symbols/Makefile.in: removed, locally generated
+
+2003-02-13 13:00  kg4ijb
+
+	* src/Makefile.in, scripts/Makefile.in, m4/Makefile.in,
+	  help/Makefile.in, config/Makefile.in, callpass/Makefile.in:
+	  removed files that are generated locally
+
+2003-02-13 12:48  kg4ijb
+
+	* ChangeLog, Makefile.in: removed remote files that are generated
+	  locally
+
+2003-02-13 12:38  kg4ijb
+
+	* acconfig.h, acinclude.m4: Removed old configure files and added
+	  new ac
+
+2003-02-13 12:33  kg4ijb
+
+	* configure.ac: * Removed old configure files and added new ac
+
+2003-02-13 12:29  kg4ijb
+
+	* config.guess, config.h.in, config.sub, configure, configure.in,
+	  install-sh, ltconfig, ltmain.sh, missing, mkinstalldirs: make way
+	  for new configure
+
+2003-02-13 09:24  we7u
+
+	* README.1ST: More changes to the Cygwin notes.
+
+2003-02-12 15:00  we7u
+
+	* src/: main.c, track_gui.c: Fixing some errant string lengths on
+	  some XtVaTypedArg calls.
+
+2003-02-12 14:31  we7u
+
+	* README.1ST: Slight changes to Cygwin notes.
+
+2003-02-11 20:18  we7u
+
+	* src/main.c: Correcting a slight misspelling.
+
+2003-02-11 11:14  we7u
+
+	* README.1ST: More CVS/Cygwin info.
+
+2003-02-10 15:42  we7u
+
+	* README.1ST: Changes to the Shapelib portion of the Cygwin notes.
+
+2003-02-10 14:29  we7u
+
+	* acinclude.m4: Formatting for better readability.  No code
+	  changes.
+
+2003-02-10 13:54  we7u
+
+	* acinclude.m4, config.h.in, configure: Adding more error output
+	  for Shapelib file searches during configure.
+
+2003-02-10 13:27  we7u
+
+	* configure, configure.in: Small change to wording of Cygwin
+	  warning message.
+
+2003-02-10 13:17  we7u
+
+	* acconfig.h, config.h.in, configure, configure.in: Starting to add
+	  Cygwin support to autotools.
+
+2003-02-10 12:20  we7u
+
+	* src/db.c: Fix for 3rd-party packets being marked as local
+	  stations in Xastir.  We now check the "third-party" variable at
+	  that stage of the code.
+
+2003-02-10 10:54  we7u
+
+	* src/db.c: A fix by Reuven w.r.t. setting the messaging-capable
+	  flag for the case of '@' packets.  Curt added some run-time debug
+	  code for finding own object deletions that'll be in effect until
+	  we're sure the problem has gone away.
+
+2003-02-10 03:26  we7u
+
+	* src/maps.c: Adding Map Labels On/Off capability to pocketAPRS
+	  maps.
+
+2003-02-07 17:35  we7u
+
+	* README.1ST: Reformatted some Cygwin notes.
+
+2003-02-07 17:33  we7u
+
+	* README.1ST: More Cygwin.
+
+2003-02-07 17:33  we7u
+
+	* README.1ST: More Cygwin stuff.
+
+2003-02-07 16:29  we7u
+
+	* README.1ST: More Cygwin note changes.
+
+2003-02-07 09:31  we7u
+
+	* README.1ST: Updated Cygwin information regarding CVS and extra
+	  map libraries.
+
+2003-02-06 12:29  we7u
+
+	* README.1ST: Added general notes about how to
+	  configure/compile/install Xastir.  Several people have mentioned
+	  to me that it's not clear how to go about this.
+
+2003-02-06 11:45  we7u
+
+	* src/: maps.c, track_gui.c: Specifying path to wget directly only
+	  on Cygwin systems.
+
+2003-02-06 11:28  we7u
+
+	* README.1ST: Adding notes about Cygwin/ImageMagick, which works by
+	  the way!
+
+2003-02-06 10:11  we7u
+
+	* README.1ST: Another Cygwin note.
+
+2003-02-06 09:36  we7u
+
+	* README.1ST: Tweaking the Cygwin/CVS note.
+
+2003-02-05 23:57  we7u
+
+	* src/: maps.c, track_gui.c: Adding a path for the "wget"
+	  executable.  Hard-coding it to /usr/bin right now.
+
+2003-02-05 17:13  we7u
+
+	* README.1ST: More Cygwin stuff.
+
+2003-02-05 14:57  we7u
+
+	* README.1ST: Added Cygwin/Shapelib notes.
+
+2003-02-05 11:38  we7u
+
+	* README.1ST: More Cygwin.
+
+2003-02-05 11:19  we7u
+
+	* README.1ST: More Cygwin notes.
+
+2003-02-05 10:33  we7u
+
+	* README.1ST: More Cygwin notes.
+
+2003-02-05 09:34  we7u
+
+	* README.1ST: Added notes about Xastir on Cygwin.
+
+2003-02-04 22:14  rzg
+
+	* help/help-English.dat: Some updates to helpfile for config|timing
+	  and filtering.
+
+2003-02-04 17:02  we7u
+
+	* src/gps.c: Adding some more CYGWIN flags around variable
+	  definitions.	This part of the code isn't used under Cygwin.
+
+2003-02-04 11:30  we7u
+
+	* src/interface.c: Changing default paths from "RELAY,WIDE" to
+	  "WIDE,WIDE2-2".
+
+2003-02-04 00:43  we7u
+
+	* src/maps.c: Getting rid of warning output that really isn't all
+	  that useful.
+
+2003-02-04 00:06  we7u
+
+	* src/main.c: Added zoom in/out buttons to toolbar.
+
+2003-02-03 20:08  jtwilley
+
+	* src/: alert.c, bulletin_gui.c, color.c, db.c, draw_symbols.c,
+	  fcc_data.c, gps.c, hostname.c, interface.c, interface_gui.c,
+	  lang.c, list_gui.c, locate_gui.c, location_gui.c, maps.c,
+	  messages.c, messages_gui.c, popup_gui.c, rac_data.c, rotated.c,
+	  sound.c, track_gui.c, util.c, wx.c, wx_gui.c, xa_config.c:
+	  Changed all printf's to write to stderr instead of stdout
+
+2003-02-03 19:52  jtwilley
+
+	* src/: igate.c, main.c: Changed all printf's to write to stderr
+	  instead of stdout
+
+2003-02-03 17:19  we7u
+
+	* src/igate.c: Changes to formatting and comments only.  No code
+	  changes.
+
+2003-02-03 17:03  we7u
+
+	* src/main.c: Re-ordered the timing params on the Configure-Timing
+	  dialog to make more sense.
+
+2003-02-03 16:42  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Changing the label for
+	  the Configure->Timing dialog.
+
+2003-02-03 16:19  we7u
+
+	* src/main.c: Added another slider for setting the station removal
+	  time from the database.
+
+2003-02-03 14:29  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/igate.c, src/main.c: Separated
+	  the timing sliders from the Configure->Defaults dialog, making a
+	  new Configure->Timing dialog out of them.
+
+2003-02-03 13:12  we7u
+
+	* src/main.c: Changing max posit rate to every 60 minutes instead
+	  of every 45.
+
+2003-02-03 12:56  we7u
+
+	* src/main.c: Added separate object/item TX timer and associated
+	  slider in Configure->Defaults.  Now people with WX stations that
+	  want to transmit every 5 minutes can set their object/item TX
+	  rate separately.  Also changed the posit rate slider to go from
+	  0.5 to 45 minutes (30 seconds to 45 minutes).
+
+2003-02-03 12:21  we7u
+
+	* src/: db.c, main.c, main.h, util.c, xa_config.c: Separate TX
+	  timer for objects and items.	New slider in Configure->Defaults
+	  for it as well.  Probably needs more testing to assure that it's
+	  working correctly.
+
+2003-02-03 11:38  we7u
+
+	* src/: db.c, db.h, main.c, main.h: Added a slider for setting the
+	  dead-reckoning timeout value.
+
+2003-02-03 11:21  we7u
+
+	* src/main.c: Changed Configure->Defaults timing values to sliders.
+	  Makes the code much simpler plus gives the users more options in
+	  setting the values.
+
+2003-02-02 23:21  jtwilley
+
+	* acinclude.m4, config.guess, config.sub, missing, mkinstalldirs:
+
+	  Modified files to work with autoconf 2.53.  There are some minor
+	  bugs still, but they are being worked on.
+
+2003-02-02 23:19  jtwilley
+
+	* COPYING: Changed example to be Y2K-compliant.
+
+2003-02-02 23:19  jtwilley
+
+	* ChangeLog:
+
+	  Updated autoconf files for new version.  Fixed COPYING Y2K
+	  distraction.
+
+2003-02-02 21:49  we7u
+
+	* src/: db.c, db.h, draw_symbols.c, xa_config.c: Added
+	  DEAD_RECKONING_TIMEOUT value to xastir.cnf.  The function is no
+	  longer tied to the ghosting interval.
+
+2003-02-02 21:05  we7u
+
+	* src/: db.c, db.h, xa_config.c: Added a global variable
+	  st_direct_timeout which is saved in the config file.	This
+	  specifies the timeout value for the ST_DIRECT bit.
+
+2003-02-02 08:42  we7u
+
+	* src/db.c: Added comments around the ST_DIRECT bit
+	  setting/clearing code.  Change the ST_DIRECT bit timeout from 1
+	  minute to 1 hour.  This gives stations that transmit only every
+	  30 minutes (common) a chance to be seen as an ST_DIRECT station.
+	  As the comments show in that section of code, that timeout value
+	  will in the future probably change into a global variable that is
+	  set within the config file.
+
+2003-02-01 23:22  we7u
+
+	* src/db.c: Fixed a pointer-to-integer comparison (compiler
+	  warning).  Reformatted the code per Xastir project specs.
+
+2003-02-01 20:45  jtwilley
+
+	* ChangeLog:
+
+	  Updated ChangeLog for solution for request ID #678322
+
+2003-02-01 20:42  jtwilley
+
+	* src/db.h:
+
+	  Added direct_heard variable to station data structure.  This
+	  variable is set each time a direct packet is received from a
+	  station.
+
+2003-02-01 20:40  jtwilley
+
+	* src/db.c:
+
+	  Removed old support for direct stations and added new complete
+	  direct station support.  Paths with WIDE and TRACE entries of all
+	  kinds are properly checked for directness.
+
+2003-02-01 02:14  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/db.h, src/interface.c,
+	  src/main.c, src/util.c: Partial fixes for GUI lockups due to lots
+	  of locally-controlled objects: Moved delays in interface routine
+	  so that they'd only take effect if the interface was up and
+	  transmit was enabled (both global and per-interface transmit
+	  controls).  Added a statusline() the lets us know when we're
+	  retransmitting our objects/items.  Delayed transmit of our items
+	  for 30 seconds after initial startup.  We will still have delays
+	  each POSIT_interval when our objects get sent:  Something like 2
+	  seconds * number of up/tx-enabled interfaces * number of objects.
+
+2003-01-31 17:04  we7u
+
+	* src/draw_symbols.c: Added code to prevent wind barbs from getting
+	  drawn if their position is off-screen.
+
+2003-01-30 17:17  we7u
+
+	* src/db.c: Adding code to assure that locally-controlled objects
+	  don't expire.
+
+2003-01-30 16:15  we7u
+
+	* src/interface_gui.c: Reducing the length of the filtering input
+	  box to 190.
+
+2003-01-30 14:48  we7u
+
+	* src/interface.c: Checking for NULL pointer for filter_string.
+
+2003-01-30 14:09  we7u
+
+	* src/: interface_gui.c, interface.c: Changed to sending empty
+	  string instead of NULL if filter_string not specified when
+	  calling add_device().
+
+2003-01-30 13:34  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface.h, src/interface.c,
+	  src/interface_gui.c, src/xa_config.c: Implemented a user
+	  interface for specifying filter parameters for internet servers.
+
+2003-01-30 11:48  kd6zwr
+
+	* src/main.c: commented out some unfinished code that slipped
+	  out...
+
+2003-01-30 11:45  kd6zwr
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/xa_config.c,
+	  src/xastir.h: added toggle for skipping map index on startup,
+	  moved index-now button to map pulldown.
+
+2003-01-29 16:12  we7u
+
+	* src/db.c: Changed comments.  No code changes.
+
+2003-01-29 14:08  we7u
+
+	* src/igate.c: Implemented passcode checking before sending packets
+	  to each inet server.
+
+2003-01-29 12:14  we7u
+
+	* src/: util.c, util.h: Adding hashing functions into the code.
+	  This will be used soon to verify igate transmit permissions.
+
+2003-01-29 10:17  we7u
+
+	* src/maps.c: Tweaking the Locate Map Feature code to handle GNIS
+	  files that aren't formatted correctly (missing double quotes on
+	  fields).
+
+2003-01-28 13:12  we7u
+
+	* symbols/symbols.dat: Made the 'X' smaller on the laptop.
+
+2003-01-28 13:11  we7u
+
+	* symbols/symbols.dat: Added laptop computer.  Put X-windows on
+	  both of the new computers.  ;-)
+
+2003-01-28 13:05  we7u
+
+	* symbols/symbols.dat: Created desktop computer symbol.
+
+2003-01-28 12:49  we7u
+
+	* symbols/symbols.dat: A better helicopter.  Easier to recognize
+	  both with maps and without.
+
+2003-01-27 23:51  we7u
+
+	* symbols/symbols.dat: Second attempt at a Skywarn symbol.
+
+2003-01-27 23:34  we7u
+
+	* symbols/symbols.dat: Initial attempt at a Skywarn symbol.
+
+2003-01-27 23:07  we7u
+
+	* symbols/symbols.dat: Added blank symbols for /L, /l, and \y
+	  (desktop computer, laptop computer, Skywarn symbols).
+
+2003-01-27 15:58  we7u
+
+	* src/main.c: Tweaking the update symbol portion of Create
+	  Object/Item dialog:  Invalid overlays won't update the symbol in
+	  the dialog.
+
+2003-01-27 15:18  we7u
+
+	* src/: db.c, main.c: Fixing the compressed posit overlay problems
+	  and the illegal overlay problems.
+
+2003-01-27 13:15  we7u
+
+	* src/: db.c, main.c: Fix for modify object/item dialog:  Overlay
+	  characters.
+
+2003-01-27 13:01  francais1
+
+	* symbols/symbols.dat: Shrunk box back down a bit
+
+2003-01-27 12:08  we7u
+
+	* src/db.c: Fixed  Create_object_item_tx_string() such that the
+	  overlay characters for objects/items don't get lost on
+	  retransmit.
+
+2003-01-27 10:48  we7u
+
+	* symbols/symbols.dat: Made white square box larger and gave it
+	  single-pixel border.
+
+2003-01-27 10:37  we7u
+
+	* symbols/symbols.dat: Made the white circle symbol (used with
+	  overlays) bigger.
+
+2003-01-27 00:53  we7u
+
+	* symbols/symbols.dat: Changed the overlay circle (alternate
+	  table).  Made it a bit bigger so that the overlayed characters
+	  are easier to read.
+
+2003-01-26 23:13  we7u
+
+	* symbols/symbols.dat: Added Incident Command Post symbol at "q"
+	  position.  Square split diagonally, half white/half green.
+
+2003-01-25 20:09  we7u
+
+	* src/list_gui.c: View->Weather Stations:  Didn't convert
+	  barometric pressure to inches mercury when english units
+	  selected.  Now it does.
+
+2003-01-23 20:57  we7u
+
+	* src/xa_config.c: Correcting error messages for get_int() and
+	  get_long() functions.
+
+2003-01-23 20:49  we7u
+
+	* src/xa_config.c: Tweaked lower limit in xa_config.c for
+	  TIGERMAP_INTENSITY from 60 to 50.  This was causing user
+	  problems, and should have been 50 to begin with.
+
+2003-01-23 16:38  we7u
+
+	* help/: help-Dutch.dat, help-English.dat, help-French.dat,
+	  help-German.dat, help-Italian.dat, help-Portuguese.dat,
+	  help-Spanish.dat: Updated copyright notice.
+
+2003-01-23 16:34  we7u
+
+	* src/main.c, src/main.h, src/maps.c, src/maps.h, src/messages.c,
+	  src/messages.h, src/messages_gui.c, src/popup.h, src/popup_gui.c,
+	  src/rac_data.c, src/rac_data.h, src/snprintf.c, src/snprintf.h,
+	  src/sound.c, src/symbols.h, src/track_gui.c, src/track_gui.h,
+	  src/util.c, src/util.h, src/view_message_gui.c, src/wx.c,
+	  src/wx.h, src/wx_gui.c, src/xa_config.c, src/xa_config.h,
+	  src/xastir.h, src/location_gui.c, src/draw_symbols.c,
+	  src/draw_symbols.h, src/fcc_data.c, src/fcc_data.h, src/gps.c,
+	  src/gps.h, src/hostname.c, src/hostname.h, src/igate.c,
+	  src/igate.h, src/interface.c, src/interface.h,
+	  src/interface_gui.c, src/lang.c, src/lang.h, src/list_gui.c,
+	  src/list_gui.h, src/locate_gui.c, src/location.c, src/db.c,
+	  src/db.h, AUTHORS, README, xastir.1, callpass/callpass.c,
+	  src/alert.c, src/alert.h, src/bulletin_gui.c, src/bulletin_gui.h,
+	  src/color.c, src/color.h, symbols/symbols.dat: Updating copyright
+	  notice.
+
+2003-01-23 14:10  rzg
+
+	* help/help-English.dat: Updates for most recent stations menu
+	  changes, copyright year.
+
+2003-01-23 11:42  we7u
+
+	* src/igate.c: Implemented NOGATE and RFONLY options in igate.c.
+	  If either of these are seen, the packet won't be gated into the
+	  internet.
+
+2003-01-23 11:17  francais1
+
+	* src/main.c: Fixed up overlooking of old_data sensitiveness
+	  Removed unnecessary code
+
+2003-01-22 17:21  francais1
+
+	* src/: main.h, main.c, db.c, xa_config.c: Added display selection
+	  for wind barb.  No more storing 0,1,2 in config, split out to
+	  match the structs.
+
+2003-01-22 17:18  francais1
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added strings for
+	  change to weather display selection because I added wind barb
+	  display selection.
+
+2003-01-22 12:07  we7u
+
+	* src/xa_config.c: We now save/restore the filter togglebutton
+	  settings.
+
+2003-01-20 18:12  francais1
+
+	* src/db.c: Fixed dead reckoning disappears when course or speed
+	  display disabled bug.
+
+2003-01-18 17:09  rzg
+
+	* help/help-English.dat: Updated for stations menu changes.
+
+2003-01-17 10:28  francais1
+
+	* src/xa_config.c: Storing of speed/short and weather/temp_only was
+	  backwards
+
+2003-01-17 09:22  we7u
+
+	* src/db.c: Fixed direct stations query to also check ST_DIRECT to
+	  choose stations.  Thanks Reuven for pointing that out!
+
+2003-01-17 00:10  we7u
+
+	* src/db.c: Added some comments about ST_DIRECT.
+
+2003-01-16 22:58  we7u
+
+	* src/db.c: Temporary tweak to the ST_VIATNC code:  Changed from 20
+	  to 50 the quantity of packets required from a 'net interface that
+	  will cause a reset of the ST_VIATNC bit in the station record.
+	  Later this should be changed to a timer.
+
+2003-01-16 13:38  francais1
+
+	* src/db.c, src/main.c, src/main.h, src/xa_config.c,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys: Added Mine, Via Digi, Stations and
+	  Objects to Select
+
+2003-01-16 10:19  francais1
+
+	* config/: language-French.sys, language-Spanish.sys: Tweaked
+	  French and Spanish a bit
+
+2003-01-16 10:08  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Changed "Select
+	  Local" to "Select Direct".
+
+2003-01-16 09:56  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.kam, tnc-startup.kpc3,
+	  tnc-startup.paccomm, tnc-startup.pico, tnc-startup.sys,
+	  tnc-startup.thd7: Added "PASSALL off" to the tnc startup files.
+
+2003-01-16 09:22  we7u
+
+	* src/: db.c, db.h: Changed ST_LOCAL flag to ST_DIRECT.  Makes more
+	  sense.
+
+2003-01-15 14:25  francais1
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/draw_symbols.c,
+	  src/draw_symbols.h, src/main.c, src/main.h, src/xa_config.c:
+	  Update of data filtering and display menus
+
+2003-01-15 12:12  we7u
+
+	* src/main.c: Tweak to dead-reckoning.	Moved the
+	  sec_last_dr_update variable to the main.c globals area.  This
+	  should preserve the last time between runs of UpdateTime().
+
+2003-01-14 23:46  we7u
+
+	* src/festival.c: Added some more error checking.
+
+2003-01-14 13:08  we7u
+
+	* src/: festival.h, festival.c: Fixed the non-connect to Festival
+	  Server problem.  This problem existed when Festival was started
+	  up after Xastir.  Now Xastir will try to connect to the server
+	  when speech is desired, but will not try a new socket connection
+	  any more often than every 60 seconds.
+
+2003-01-14 09:19  we7u
+
+	* src/maps.c: Print a warning in draw_geo_image_map() if the image
+	  file cannot be read for some reason (typically permissions
+	  problems).
+
+2003-01-13 22:23  kd6zwr
+
+	* src/main.c: Added error checking for setting my station postion
+	  from mouse popup menu.
+
+2003-01-13 21:33  kd6zwr
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added mouse popup menu
+	  item to set my station position
+
+2003-01-12 22:22  we7u
+
+	* src/: db.c, interface.c, interface.h, main.c: Added some
+	  debugging statements in the extract_weather functions.  Added a
+	  new global string that holds the last packet processed by file
+	  read or channel_data functions.  If a segfault occurs, this last
+	  packet is dumped to STDERR along with the segfault message.  This
+	  might help in the future to find "killer" packets.
+
+2003-01-12 08:22  we7u
+
+	* src/maps.c: Changed wget parameters to more verbose keywords.  No
+	  real code changes.
+
+2003-01-11 18:28  rzg
+
+	* help/help-English.dat, README.1ST: Updated helpfile for findu.com
+	  old code removal, minor readme changes.
+
+2003-01-11 08:38  we7u
+
+	* src/maps.c: Removed old dead findu.com code (older method of
+	  accessing it, no longer used) from maps.c
+
+2003-01-11 08:30  we7u
+
+	* src/track_gui.c: Fixed findu.com get station tracks.	Was using
+	  hard-coded IP address before, now uses domain name in URL.
+
+2003-01-09 17:15  we7u
+
+	* src/db.c: Implemented a range scale display.
+
+2003-01-08 13:55  we7u
+
+	* FAQ: Added a question/answer about ImageMagick's
+	  CompressImageColormap() function call.
+
+2003-01-07 21:13  kg4ijb
+
+	* src/interface.c: Check for glibc version on socket call line ~840
+
+2003-01-07 20:43  rzg
+
+	* FAQ, README.1ST:
+	  Minor updates about -devel files, minor spacing changes to
+	  README.1ST.
+
+2003-01-07 14:26  francais1
+
+	* Makefile.am, Makefile.in, xastir.spec.in: Removed creation of
+	  placeholder map directories.
+
+2003-01-06 14:42  we7u
+
+	* scripts/: Coordinate.pm, inf2geo.pl, permutations.pl,
+	  test_coord.pl, track-get.pl, waypoint-get.pl: Changed to
+	  inf2geo.pl to accomodate other image formats.  Tweaks to other
+	  scripts regarding copyright notices only.
+
+2003-01-06 14:22  rzg
+
+	* help/help-English.dat, README.1ST:
+	  Finished off "What's new", updates to map properties help,
+	  addition of fcc-get script.
+
+2003-01-06 09:07  kg4ijb
+
+	* src/: festival.c, interface.c: remove deprecated params to socket
+
+2003-01-06 08:54  gstueve
+
+	* scripts/Makefile.am: Add helper script to retrieve FCC & RAC
+	  files for XASTIR use.
+
+2003-01-06 08:42  gstueve
+
+	* scripts/: Makefile.in, fcc-get: Add helper script to retrieve RCC
+	  & RAC data files for XASTIR use.
+
+2003-01-05 11:54  kd6zwr
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/main.h,
+	  src/xa_config.c: Adding distance/bearing on status line.
+
+2003-01-03 10:25  we7u
+
+	* src/main.c: Dead code go bye-bye.
+
+2003-01-02 13:48  we7u
+
+	* src/maps.c: Adding more parameter checking after the sscanf in
+	  the map_index restore_from_file function.
+
+2003-01-01 21:58  we7u
+
+	* README.1ST: A few updates to the map directory portions.
+
+2003-01-01 20:08  rzg
+
+	* help/help-English.dat:
+	  More updates to "What's new", added instructions for rain gauge
+	  reporting size correction.
+
+2002-12-31 13:57  we7u
+
+	* src/: draw_symbols.c, maps.c, util.c: Speeding up get_line again
+	  (don't need all the filtering anymore since the Map Chooser bug
+	  was found).  Fixing get_line() calls so that the arrays are long
+	  enough to contains what's read from file.
+
+2002-12-30 11:06  we7u
+
+	* src/maps.c: Fixing segfaults that could occur if GNIS files had
+	  short lines or lines containing control characters.  Now checking
+	  for NULL returns from index() calls.
+
+2002-12-29 16:36  rzg
+
+	* help/help-English.dat:
+	  More updates to "whats new" section; typo fixes.
+
+2002-12-29 15:04  rzg
+
+	* README.1ST, help/help-English.dat: Round 1 of "pre-release"
+	  changes: Reorganized and cleaned up README.1ST, updated some
+	  portions as needed. Updated helpfile for map chooser changes.
+
+	  Still need more README work, especially doing something with all
+	  that security stuff and perhaps the OS specific stuff. And the
+	  helpfile "Whats new" needs to be written more nicely, I started
+	  but ran out of time.
+
+2002-12-28 15:41  kd6zwr
+
+	* src/maps.c: Changed the sscanf fix... cleared the string to all
+	  nulls before sscanf.	The temp string broke solaris... *sigh*.
+	  This works everywhere now??
+
+2002-12-28 12:55  kd6zwr
+
+	* src/maps.c: Added a temp string to avoid a sscanf bug(?) to
+	  prevent junk showing up in the map chooser window.
+
+2002-12-27 14:18  we7u
+
+	* src/util.c: Fixing tabs in util.c:get_line().
+
+2002-12-27 12:54  we7u
+
+	* src/maps.c: Looking for control characters in the routine that
+	  parses the map_index.sys file and creates the in-memory map
+	  index.
+
+2002-12-27 11:53  we7u
+
+	* src/maps.c: More error-checking w.r.t. map indexing.
+
+2002-12-26 17:09  we7u
+
+	* src/maps.c: Checking for control characters as we're saving the
+	  map_index data to disk.
+
+2002-12-26 16:33  we7u
+
+	* src/maps.c: Looking for all control characters instead of just
+	  '\r' or '\n'.  Added another warning message if control chars are
+	  found.  Changed some comments.
+
+2002-12-25 07:32  we7u
+
+	* src/: draw_symbols.c, main.c, maps.c: Added error checking at the
+	  points where different xbitmap files were being loaded, and where
+	  symbols.data is loaded.  Xastir will now output an error message
+	  before croaking if these files are not present.
+
+2002-12-24 17:26  we7u
+
+	* src/: maps.c, util.c: More filtering changes in and around
+	  get_line().  Intended to help with the weird characters Map
+	  Chooser problem.
+
+2002-12-24 14:27  we7u
+
+	* src/maps.c: Commenting out debug printf statements.
+
+2002-12-24 12:00  we7u
+
+	* src/maps.c: More error checking:  Looking for control characters
+	  in file/directory names during map indexing.
+
+2002-12-24 08:24  we7u
+
+	* src/maps.c: Added some code to spit out warning messages to
+	  STDOUT if control characters other then '\n' are found in
+	  map_index.sys.
+
+2002-12-23 00:16  we7u
+
+	* src/maps.c: Initial implementation of the draw_filled flag in the
+	  map drawing routines which can make use of it.
+
+2002-12-22 11:24  we7u
+
+	* src/maps.c: Deleting dead code.  Adding comments.  Set a pointer
+	  to NULL after calling a routine that might free the memory space.
+
+2002-12-22 10:54  we7u
+
+	* src/maps.c: Changed function which reads map_index.sys in from
+	  disk so that it forces a sorted order for in-memory map list.
+
+2002-12-21 23:29  we7u
+
+	* src/maps.c: More error-checking while creating map indexes.
+
+2002-12-21 08:25  we7u
+
+	* src/maps.c: Added comments.  Changed a few compares to read
+	  better.  No real code changes.
+
+2002-12-21 08:08  we7u
+
+	* src/maps.c: Added more error-checking and debug output to the map
+	  indexing routines.
+
+2002-12-21 00:27  we7u
+
+	* src/: main.c, maps.c: Fully functional automaps selection from
+	  the Map Chooser->Properties dialog.
+
+2002-12-21 00:08  we7u
+
+	* src/main.c: More automaps stuff.  Can now tweak the value in the
+	  map_index.sys file from the Map Chooser->Properties dialog.
+	  Back-end code still has to be written to use this information.
+
+2002-12-20 23:46  we7u
+
+	* src/: main.c, maps.c, maps.h: Adding automaps enable/disable to
+	  the Map Chooser->Properties dialog.  More to do yet.
+
+2002-12-20 22:38  we7u
+
+	* src/maps.c: Added some debug lines.
+
+2002-12-20 21:40  we7u
+
+	* src/main.c: Moved some of the widgets to the bottom rowcol form
+	  in the Map Properties dialog.
+
+2002-12-20 17:18  we7u
+
+	* src/: main.c, maps.h: Map Chooser->Properties now brings up new
+	  dialog which allows setting map layers and draw_filled fields.
+	  draw_filled is not used yet in the code.
+
+2002-12-20 12:59  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Changed to Dirs/Maps
+	  Selected in map chooser instead of just files.
+
+2002-12-20 12:36  we7u
+
+	* src/maps.c: Added some comments.
+
+2002-12-20 12:07  we7u
+
+	* src/main.c: Changing the manual map index button back to its
+	  original code, where it only updates the map index instead of
+	  re-indexing from scratch.  This keeps the manually-tweaked
+	  map_level & draw_filled fields intact.  The original reason for
+	  starting from scratch was to remove deleted maps.  This happens
+	  anyway after two Xastir restarts, so starting the list from
+	  scratch isn't really needed anyway.
+
+2002-12-20 11:52  we7u
+
+	* src/maps.c: Fixes to re-indexing so that files and directories
+	  get good default values in the index.
+
+2002-12-20 11:52  we7u
+
+	* src/main.c: New stuff having to do with Map Chooser Properties
+	  button.  Not fully implemented yet.
+
+2002-12-20 11:51  we7u
+
+	* src/maps.h: Added a prototype for a function that I need to use
+	  in main.c
+
+2002-12-19 17:04  we7u
+
+	* src/: main.c, main.h, maps.c: Initial attempt at sorting/drawing
+	  maps based on map layer.  It works! Next step is to get some more
+	  GUI hooks for it so that the user can specify which maps go on
+	  which layer, and which layers to enable for drawing.
+
+2002-12-19 12:36  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added a count of how
+	  many maps are currently selected to the map chooser.	Doesn't
+	  quite work the way I'd like yet, but it is useful.  It shows how
+	  many maps are marked in the in-memory map index as selected.
+	  That quantity can change when you tweak things in the map chooser
+	  and then hit OK.
+
+2002-12-18 22:03  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/maps.h: More tweaks
+	  to the Map Chooser.  Fully resizable now.  Add new button at the
+	  top which will eventually be used to change map properties.
+	  Changed how the "None" button works, and renamed it to "Clear".
+
+2002-12-15 23:56  we7u
+
+	* src/maps.c: Yet another attempt to clean up garbage that some
+	  people are seeing in the map index.  In this tweak I check the
+	  sscanf call to make sure that the proper number of fields have
+	  been parsed from each input line.  If not, that record in the
+	  map_index is dropped.
+
+2002-12-15 23:07  we7u
+
+	* README.1ST: Tweaks by Tate, KC7ZRU.  Thanks!
+
+2002-12-15 23:03  we7u
+
+	* src/main.c: Changed map re-indexing button so that it deletes the
+	  entire in-memory index, then re-creates it from scratch.  It is
+	  slower than the old method, but guarantees that deleted/added
+	  maps will show up in the map chooser without have to restart
+	  Xastir to do it.
+
+2002-12-15 21:41  we7u
+
+	* src/festival.c: Change to some debug code.
+
+2002-12-15 18:28  we7u
+
+	* src/festival.c: Now doing a check in the festival code for
+	  duplicate strings.  Only one string is held in the queue for 30
+	  seconds.  If the same string comes in, festival refuses to speak
+	  it.
+
+2002-12-14 23:00  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/main.h,
+	  src/xa_config.c: Added an "Expand Directories" button to the map
+	  chooser.
+
+2002-12-14 21:34  we7u
+
+	* src/: main.c, maps.c: Better implementation of map directory
+	  select/de-select in the Map Chooser.
+
+2002-12-14 15:04  we7u
+
+	* src/maps.c: A few small tweaks to how map_index strings get
+	  created for directories.
+
+2002-12-14 00:16  we7u
+
+	* src/main.c: Commented out a couple of debugging statements.
+
+2002-12-13 23:52  we7u
+
+	* src/: main.c, maps.c: First functional version of Map Chooser
+	  where clicking on a directory will select all maps below it.
+	  Still a few bugs left to squash, but it works!
+
+2002-12-13 22:35  we7u
+
+	* src/maps.c: Finished getting map directories to show up properly
+	  and in sorted order in the Map Chooser.  They're selectable as
+	  well.  Still have to write the code to recurse through these
+	  directories when selected/de-selected.  Not fully functional yet.
+
+2002-12-13 17:04  we7u
+
+	* src/maps.c: Starting to implement storage of map directories in
+	  the map index.  Not complete yet.
+
+2002-12-13 12:04  we7u
+
+	* src/main.c: Tweaks to comments.
+
+2002-12-13 09:42  we7u
+
+	* src/main.c: Including Chris Bell's new routines for
+	  directory-at-a-time map file selection.  These routines are not
+	  integrated into Xastir yet.  They need to be tweaked to fit into
+	  the new map_index method of map selection, and the Lesstif/Motif
+	  functions need to be combined into one function.  This is a work
+	  in progress.
+
+2002-12-10 14:51  we7u
+
+	* src/db.c: Fix for dead-reckoning for compressed objects/items.
+
+2002-12-10 14:13  we7u
+
+	* FAQ: Added a note about the missing freetype library during
+	  linking.
+
+2002-12-10 13:52  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added a new "Re-index
+	  Maps" button to the configure menu.  Useful for those instances
+	  where you've added a new map but don't want to restart Xastir in
+	  order to start using it.
+
+2002-12-10 13:15  we7u
+
+	* README.1ST: Added a note about James Jefferson's nice world map
+	  in Shapefile format.
+
+2002-12-10 12:48  we7u
+
+	* src/main.c: Fixed to map chooser.  Changes now apply only to the
+	  in-dialog list until/unless the OK button is pressed.  If Cancel
+	  or any other button is pressed, the changes do not take effect or
+	  get written to the selected_maps.sys disk file.
+
+2002-12-09 09:18  we7u
+
+	* README.1ST: Updating e-mail address.
+
+2002-12-07 20:57  we7u
+
+	* src/: draw_symbols.c, igate.c, maps.c, maps.h, util.c: Tweaks to
+	  help fix buffer overflows in several areas of the code.  Some of
+	  them may have been caused by get_line() in util.c, which has been
+	  rewritten to prevent overflowing the string passed into it.  Also
+	  added a new define: MAX_FILENAME, which is used to declare sizes
+	  of char arrays.
+
+2002-12-07 00:00  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/locate_gui.c: Upon
+	  receipt of a Mic-E emergency packet:	No longer bring up a popup
+	  dialog.  Now bring up only a Locate Station dialog, but the
+	  titlebar has been changed to read "Emergency Locate!".
+
+2002-11-26 16:35  we7u
+
+	* src/xa_config.c: More water gage stuff.
+
+2002-11-26 15:56  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h:
+	  Adding a display toggle for water gage objects.
+
+2002-11-26 09:12  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2002-11-25 23:05  we7u
+
+	* src/: bulletin_gui.c, db.c: Finishing up the
+	  bulletins-before-posits code.  Now bulletins come up as soon as
+	  the posits for that station are received.
+
+2002-11-25 17:10  we7u
+
+	* src/: db.c, db.h: Start of trying to fix distance=0 bulletins for
+	  when posit comes in later.  A bit more code to write, but this
+	  keeps track of whether or now the posit is currently known.
+
+2002-11-25 13:19  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/bulletin_gui.c, src/main.c,
+	  src/main.h, src/xa_config.c: Something several of you have asked
+	  about in the past:  A way to stop the popup and display of
+	  bulletins with zero distances.  Two togglebuttons in this case
+	  control the same global variable:  One toggle on the
+	  Configure->Defaults dialog, and another on the View->Bulletins
+	  dialog.
+
+2002-11-25 10:40  rzg
+
+	* help/help-English.dat: Updates for dead-reckoning, other minor
+	  changes.
+
+2002-11-25 09:42  we7u
+
+	* README.1ST: A bit more about installing festival from RPM's and
+	  changing the default voice.
+
+2002-11-23 22:11  we7u
+
+	* src/util.c: Tweaks to the speech stuff so that we don't add
+	  commas to the SSID portion of a callsign.  This makes it speak
+	  -12 as "dash twelve".
+
+2002-11-23 20:20  we7u
+
+	* README.1ST: Added a blurb about festival and starting it in
+	  server mode.	Useful for those that can't read the English help
+	  file (where it is also documented).
+
+2002-11-23 08:18  we7u
+
+	* src/util.c: Speech stuff now looks for a number in the text
+	  (before a dash).  If found, it adds commas so that Festival will
+	  speak each letter.  If not found, it feeds the string directly to
+	  Festival to let it try to pronounce it.
+
+2002-11-23 00:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/festival.c,
+	  src/main.c, src/popup_gui.c, src/util.c, src/util.h: Changes to
+	  make Festival speak callsigns out letter by letter.
+
+2002-11-22 17:16  we7u
+
+	* scripts/inf2geo.pl: Tweaked to handle different cases for
+	  filenames, and to put the proper case into the GEO file for the
+	  GIF file.
+
+2002-11-22 15:39  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c: Separated out
+	  more festival speech strings from the other language strings.
+	  Changed the "New Station" speech string to just "New" to speed
+	  things up a bit.
+
+2002-11-22 11:20  we7u
+
+	* README.1ST: Added the su & exit around the "make lib_install" for
+	  the Shapelib install.  Thanks Bob!
+
+2002-11-21 21:15  we7u
+
+	* src/: maps.c, popup_gui.c: Code fixes for when required fonts
+	  can't be found.  Error messages are output and Xastir recovers,
+	  instead of segfaulting.
+
+2002-11-21 17:56  we7u
+
+	* src/popup_gui.c: Changing to another font.
+
+2002-11-21 17:44  we7u
+
+	* src/xa_config.c: Deleting a duplicated variable.
+
+2002-11-21 17:38  we7u
+
+	* README.1ST: Added notes about the two new auto-identification
+	  methods.
+
+2002-11-21 17:06  we7u
+
+	* src/popup_gui.c: Correcting small error in variable name.
+
+2002-11-21 16:53  we7u
+
+	* src/popup_gui.c: Moved the Speech ID stuff to the beginning of
+	  the ID routine so that the spoken text and the screen ID will
+	  occur at roughly the same time.
+
+2002-11-21 16:50  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/popup_gui.c, src/xa_config.c, src/xastir.h: Added station ID
+	  in the form of large text across the screen, and spoken station
+	  ID via festival.  Occurs every 9.5 minutes if two new variables
+	  in the config file are enabled.
+
+2002-11-21 10:20  we7u
+
+	* src/util.c: Minor tweak to make sure that objects/items only get
+	  one hash mark added to the front of the line in the
+	  ~.xastir/config/object.log file.
+
+2002-11-19 10:29  francais1
+
+	* src/: main.c, main.h, xa_config.c: Added "hidden" conf file value
+	  to adjust DR update rate Default is 30 s
+
+2002-11-19 10:20  we7u
+
+	* src/db.c: Fixes so that dead-reckoning and "Display Moving
+	  Stations" work properly even when we only have one position from
+	  a station.  They are now classified with ST_MOVING flag if the
+	  speed is non-zero.
+
+2002-11-19 09:59  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/draw_symbols.c, src/main.c,
+	  src/main.h, src/xa_config.c: Added new buttons to enable/disable
+	  the different dead-reckoning display objects.  This allows users
+	  to get the display as cluttered or uncluttered as they like.
+
+2002-11-19 09:10  we7u
+
+	* src/xa_config.c: Changing default for dead-reckoning to ON.
+
+2002-11-18 16:25  francais1
+
+	* src/: draw_symbols.c, main.c: Added call to draw_symbols in
+	  UpdateTime at least every 30 s if dead reckoning drawing is
+	  turned on.  Tweaked dead reckoning graphics to draw the DR trail
+	  in a dashed line and draw an arc that gets larger as time from
+	  last posit grows until it turns into a circle.
+
+2002-11-18 13:19  we7u
+
+	* src/draw_symbols.c: Fixing the bug where weather stations hit the
+	  clear interval but wind barbs still get drawn.
+
+2002-11-17 21:48  kd6zwr
+
+	* src/main.c: added keysyms for pgup/pgdn on sun keyboards
+
+2002-11-14 18:02  we7u
+
+	* src/util.c: Code to handle disowning of object that other people
+	  take over, and to comment out our own objects from the object.log
+	  file when we delete them.  This keeps us from retransmitting the
+	  objects when Xastir restarts.
+
+2002-11-14 16:25  we7u
+
+	* src/: main.c, util.c, util.h: More object stuff.  More to do yet.
+
+2002-11-14 15:50  we7u
+
+	* src/: db.c, util.c, util.h: The start of code to allow disowning
+	  an object that someone else is assuming control over.  Xastir
+	  already does this while running, but it doesn't write the data to
+	  the object.log file, so when it starts up, it owns the object
+	  again.
+
+2002-11-14 14:07  we7u
+
+	* src/db.c: Saving empty-string for speed instead of "0" if speed
+	  is unknown on a parsed packet.
+
+2002-11-14 12:40  we7u
+
+	* src/db.c: Unlinking DR functions from Display Course/Speed
+	  toggles.
+
+2002-11-14 11:30  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/draw_symbols.c,
+	  src/draw_symbols.h, src/main.c, src/main.h, src/xa_config.c:
+	  Initial implementation of dead-reckoning by J. Lance Cotton,
+	  KJ5O.  Thanks very much to him for doing this!!!
+
+2002-11-13 15:31  we7u
+
+	* src/maps.c: Forcing terraserver map extents in the index to be at
+	  the edges of the earth.  Added more statusline messages for
+	  loading/indexing maps (more consistent now).
+
+2002-11-13 14:13  we7u
+
+	* src/maps.c: An attempt to fix the buffer overflow problems with
+	  map indexing.
+
+2002-11-13 13:19  we7u
+
+	* src/main.c: We now delete/recreate our own station record only if
+	  we change our callsign.  All other changes just cause an update
+	  to the current record.
+
+2002-11-13 12:43  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: New "Waiting for
+	  GPS data.." string.
+
+2002-11-13 12:40  we7u
+
+	* src/: db.c, interface.c, main.c, main.h: Implemented a countdown
+	  from when GPS data goes invalid.  It is decremented each time a
+	  posit occurs.  When it reaches zero, posits stop.  Valid GPS data
+	  parsing will reset it back to the starting count.  Also reduced
+	  the size of the tracked station circles in order to more easily
+	  read the station data.
+
+2002-11-12 18:23  we7u
+
+	* src/db.c: Added another blue circle for tracked stations.  Now
+	  three concentric circles.
+
+2002-11-12 18:17  we7u
+
+	* src/db.c: Making a tracked station have both a yellow and red
+	  circle to make it easier to see against different map
+	  backgrounds.
+
+2002-11-12 18:07  we7u
+
+	* src/: db.c, interface.c, main.c, main.h: Added
+	  "my_position_valid" variable, initially set to 1.  As soon as a
+	  GPS interface of any type is started up, this variable gets set
+	  to zero, and it holds off posits.  Once the first valid GPS
+	  position is parsed, this variable is again set to 1, and posits
+	  proceed normally.  As Xastir comes up, interfaces are brought up
+	  before the first posit, so if a GPS interface is enabled on
+	  startup, no posits will occur until the first GPS posit is parsed
+	  properly.  This variable could be used later to disable posits
+	  when GPS data becomes unusable or stops coming in.  This feature
+	  is not implemented yet though.
+
+2002-11-12 15:23  we7u
+
+	* src/db.c: Changed tracked stations circle from Red to Yellow to
+	  make it easier for partially colorblind people to see against a
+	  background of topo maps.
+
+2002-11-12 14:56  we7u
+
+	* src/db.c: Got rid of another bug off the buglist.  Now only
+	  stations that are currently visible will be selected for Station
+	  Info operations.
+
+2002-11-12 14:15  we7u
+
+	* src/main.c: Changed the order of startup so that map indexing is
+	  completed before interfaces are brought up.
+
+2002-11-12 10:56  we7u
+
+	* src/maps.c: Changes intended to keep variables from going
+	  out-of-bounds.  I'm attempting to get more DRG-Enhanced map
+	  formats working.  These changes don't quite make them work, but
+	  they do make it better and catch some out-of-bounds problems.
+
+2002-11-11 15:01  we7u
+
+	* configure, configure.in, ltconfig: OpenBSD 3.1/IA32 patches by
+	  Yasholomew Yashinski.  Thanks!
+
+2002-11-09 18:04  kd6zwr
+
+	* src/main.c: Fix for white foreground on solaris (uninitialized
+	  color)
+
+2002-11-07 16:14  we7u
+
+	* README.1ST: Added a note about MrSID file compression.
+
+2002-11-07 16:10  we7u
+
+	* README.1ST: Added some notes about DRG-E files.
+
+2002-11-06 22:40  we7u
+
+	* README.1ST: Added some "su" lines and some comments about
+	  "ginstall".
+
+2002-11-06 15:15  we7u
+
+	* FAQ: Added a section about geoTIFF's causing segfaults.
+
+2002-11-06 12:47  we7u
+
+	* README.1ST: Added a section describing the FGD file format
+	  portion that we use.
+
+2002-11-01 16:56  we7u
+
+	* src/maps.c: Changed one comment.
+
+2002-10-31 16:27  we7u
+
+	* src/maps.c: Added checks in the geoTIFF code for neat-line map
+	  boundaries being outside normal limits.  If found, output warning
+	  message, reset the corner to something more reasonable, and
+	  continue on.
+
+2002-10-31 13:52  we7u
+
+	* src/: datum.h, maps.c: Converting from using proj.4 to using
+	  datum.h/datum.c in order to do our datum translations for geoTIFF
+	  maps.
+
+2002-10-30 13:40  francais1
+
+	* src/: draw_symbols.c, main.c, xastir.h: Added support for 25% and
+	  12.5% stipples when drawing station ambiguity.
+
+2002-10-30 13:38  francais1
+
+	* symbols/: 13pct.xbm, 25pct.xbm, Makefile.am, Makefile.in: Added
+	  pixmaps for 25% and 12.5% stipples
+
+2002-10-30 11:08  we7u
+
+	* src/: db.c, draw_symbols.c, main.c: Fixed some conversion
+	  problems for speed/wind speed.  Added some notes.  Wind barbs are
+	  not shown properly in knots instead of mph.
+
+2002-10-29 14:26  we7u
+
+	* src/db.c: Tweaks to the wind direction/wind speed decoding for
+	  weather stations.  We were missing speed/direction for many
+	  weather packets.  Many more wind barbs are now showing up.
+
+2002-10-28 22:34  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/main.h,
+	  src/xa_config.c: Added a new toggle to the Defaults dialog for
+	  enabling/disabling warnings for modifier keys.
+
+2002-10-25 15:04  we7u
+
+	* README.1ST: Changing some notes regarding map permissions and
+	  running as the root user.
+
+2002-10-25 13:34  we7u
+
+	* README.1ST: Added a note about map and map directory permissions.
+	  Added warnings regarding running programs as the root user.
+
+2002-10-24 17:32  rzg
+
+	* help/help-English.dat: Updates for the Map and Station menu
+	  changes.
+
+2002-10-23 16:12  we7u
+
+	* src/draw_symbols.c: Cleanup of debug code & comments for the wind
+	  barb stuff.
+
+2002-10-23 13:28  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h, main.c: Wind Barb
+	  implementation.  Enable/Disable togglebutton has yet to be added
+	  to disable these.
+
+2002-10-22 15:16  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2002-10-22 14:37  we7u
+
+	* help/help-English.dat: Another item for your todo list.
+
+2002-10-22 14:12  we7u
+
+	* src/maps.c: Tweak to weather alert code to compensate for NULL
+	  fields in the NOAA shapefiles.  Weather alerts should now appear
+	  in the proper places even if using newer NOAA files.
+
+2002-10-21 23:35  rzg
+
+	* README.1ST: Oops, didn't mean to revert that stuff...
+
+2002-10-21 23:29  rzg
+
+	* README.1ST, FAQ, help/help-English.dat: Minor fixes/updates to
+	  docs.
+
+2002-10-20 22:53  francais1
+
+	* src/db.c: ST_VIATNC is what I really wanted...
+
+2002-10-20 22:26  we7u
+
+	* src/interface.c: Moved a variable inside the proper #ifdef
+	  statements.  It was causing a compiler warning on systems without
+	  kernel AX.25 interface support.
+
+2002-10-20 21:30  francais1
+
+	* src/: main.c, maps.c, maps.h: Enabled +/= and - to change the
+	  grid size a bit.
+
+2002-10-20 20:15  francais1
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h:
+	  Expanded "Display Stations" into "Display Local Stations" and
+	  "Display Non-Local Stations"
+
+2002-10-20 18:06  francais1
+
+	* src/: db.c, interface.c, interface_gui.c: First pass at relay
+	  digipeating over an ax25 interface.  Look for the define
+	  I_WANT_TO_TRY_AX25_RELAY_DIGIPEAT in db.c and interface_gui.c
+
+2002-10-19 12:06  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c: Added an ID
+	  string to the status line for the periods when no traffic is
+	  coming in.  If the ID string doesn't appear for 9 minutes
+	  straight, it is forced onto the statusline for a few seconds in
+	  order to meet ID requirements.  This is useful for beaming an
+	  Xastir image over amateur fast-scan television.  Tweaked the
+	  Configure->Station callsign block so that all characters of a
+	  full callsign plus SSID are displayed.  Tweaked the weather
+	  symbol display code so that "   " and "..." are not taken to be a
+	  zero reading.
+
+2002-10-18 15:42  we7u
+
+	* src/maps.c: Changes in the GNIS map-reading code to accomodate
+	  the lack of consistency in how the GNIS files are formatted.
+
+2002-10-18 14:04  we7u
+
+	* README.1ST: Added a note from Chris about GNIS file.
+
+2002-10-18 12:34  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Broke up Stations menu
+	  into submenus.
+
+2002-10-18 10:13  we7u
+
+	* src/main.c: Set default ON for new togglebuttons on stations
+	  menu.
+
+2002-10-17 22:30  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h:
+	  Initial attempt at some station/object display filtering.  What
+	  is coded so far works, but most of the variables are not saved in
+	  the config file yet.	May need more togglebuttons & variables
+	  implemented yet.
+
+2002-10-17 15:41  we7u
+
+	* AUTHORS: Minor cleanups and added a few contributors.
+
+2002-10-17 15:23  we7u
+
+	* README.1ST: Move "Previous Install Notes" section to a later
+	  point in the file.
+
+2002-10-17 15:05  we7u
+
+	* src/db.c: Tweaks to get rid of compiler warnings for Debian/S390.
+	  Changed char's to int's and got rid of some casts.
+
+2002-10-17 12:13  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2002-10-16 14:10  we7u
+
+	* src/db.c: Added draw_symbol_filtered() function.  Will eventually
+	  add code to this function which implements display filtering.
+
+2002-10-15 14:28  we7u
+
+	* src/: db.c, draw_symbols.c, draw_symbols.h: Implemented different
+	  colors for tropical storm/depression and hurricane packets, for
+	  the three different wind speeds:  Green = gale force wind radius,
+	  yellow = tropical storm wind radius, red = hurricane wind radius.
+
+2002-10-15 13:38  we7u
+
+	* src/db.c: Converted storm circles from nautical miles to miles
+	  before calling draw_pod_circle.  Ranges are now correct.  Added a
+	  couple of comments as well regarding things yet to be done.
+
+2002-10-11 16:25  we7u
+
+	* src/wx.c: Added a comment about Dallas rain gauge.
+
+2002-10-11 12:55  we7u
+
+	* src/db.c: Initial attempt at drawing circles around storm objects
+	  (radius of winds).  Need to convert from nautical miles to miles
+	  and perhaps change to a different method of drawing, but this
+	  works for now.
+
+2002-10-11 12:54  we7u
+
+	* src/wx.c: Commented out a debug line.
+
+2002-10-11 12:53  we7u
+
+	* src/draw_symbols.c: Added some comments.
+
+2002-10-10 15:56  we7u
+
+	* src/wx.c: Wind speed for Dallas one-wire WX station.
+
+2002-10-10 15:21  we7u
+
+	* src/wx.c: Correction to temperature conversion for Dallas WX
+	  station.
+
+2002-10-10 15:19  we7u
+
+	* src/wx.c: Support for wind direction for Dallas WX station (using
+	  OWW daemon for the data feed).
+
+2002-10-10 13:40  we7u
+
+	* src/interface.c: Now handle 0x00 characters in port_read, for the
+	  case where the One-Wire Weather daemon ("OWW") sends them to us.
+	  Temperature from a Dallas one-wire station is now initially coded
+	  and appears to be working.
+
+2002-10-10 13:38  we7u
+
+	* src/wx.c: Changed some comments and put one message under
+	  debug_level control.
+
+2002-10-10 13:05  francais1
+
+	* src/util.c: phg_decode was missing the phg circle radius/2 stuff
+	  put into phg_decode.
+
+2002-10-10 01:48  we7u
+
+	* src/: db.h, wx.c: Initial support for Dallas One-Wire weather
+	  station.  Xastir gets it's data from the OWW server.	We
+	  currently only parse out the temperature, and it appears we only
+	  do that once when the network port is brought up.  More
+	  functionality to be added later.
+
+2002-10-08 22:52  we7u
+
+	* src/: main.h, maps.c, maps.h, track_gui.c: Fixed bug where
+	  TrackMe button didn't get disabled when tracking was cleared from
+	  the menus.  Map indexing now removes indexes for deleted files.
+	  Another ImageMagick API change is now handled in our code.
+
+2002-10-08 21:32  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: We now check for
+	  modifier keys when the third mouse button press is detected and
+	  dump out a warning message asking the user to turn off the
+	  modifier keys.
+
+2002-10-04 00:20  we7u
+
+	* src/db.c: More correct parsing of Storm Data.
+
+2002-10-03 17:31  we7u
+
+	* src/db.c: Commenting out debug statements.
+
+2002-10-03 17:29  we7u
+
+	* src/: db.c, db.h: The start of decoding storm data.  More to do
+	  in terms of units conversion and display, but the basic packet
+	  decoding is coded and working.
+
+2002-10-03 16:06  we7u
+
+	* src/maps.c: Added a comment.
+
+2002-10-03 11:35  we7u
+
+	* src/: maps.c, track_gui.c: Small tweaks to wget error messages.
+
+2002-10-03 11:25  we7u
+
+	* src/: main.c, maps.c, maps.h: Updates to map indexing.  Starting
+	  to work as intended now.
+
+2002-10-02 16:39  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/maps.c,
+	  src/xa_config.c, src/xastir.h: Added a Disable Raster Map
+	  togglebutton to the maps menu.  Added "Indexing" text to the
+	  statusline as we're indexing maps.
+
+2002-10-02 15:28  we7u
+
+	* src/maps.c: Changed auto_maps to use the in-memory map index.
+	  Lot's of tweaks to sort the map index.  Now use the .geo
+	  filenames instead of the http/ftp URL's.  Got rid of shx/dbf
+	  filenames (using shp instead).  This got rid of the
+	  triple-drawing of shapefiles that was ocurring with automaps.
+	  Added statusline() calls to all of the draw functions.
+
+2002-10-01 10:43  we7u
+
+	* src/maps.c: Added more error output for geoTIFF's, where proj may
+	  not have been installed correctly.
+
+2002-09-30 16:50  we7u
+
+	* src/interface_gui.c: Minor correction.  This window was WAY too
+	  long when I defined 30 interfaces.  The new length is more
+	  reasonable.
+
+2002-09-30 16:06  we7u
+
+	* src/: interface.h, interface_gui.c, main.c: Upp'ed the number of
+	  interface to 15.  Tweaked the GUI and other portions of the code
+	  to handle whatever MAX_IFACE_DEVICES is set to.  Xastir should
+	  theoretically be able to handle any number of interfaces now, but
+	  it's only been tested so far up to 15.
+
+2002-09-30 00:19  we7u
+
+	* README.1ST: Added a note about the 24kgrid file available from
+	  gisdatadepot.
+
+2002-09-29 23:41  we7u
+
+	* README.1ST: Added a more specific path for getting GNIS
+	  datafiles.
+
+2002-09-29 22:04  we7u
+
+	* README.1ST: Added a few more sources of Shapefile maps.
+
+2002-09-26 16:11  we7u
+
+	* src/maps.c: Fixes for Tigermap and GEO file segfaults.  Saw
+	  segfaults with Tigermaps when "wget" returned a zero-length file.
+	  These changes fix this problem.
+
+2002-09-26 13:39  we7u
+
+	* src/db.c: Limiting the new togglebutton to work only on objects
+	  containing weather, not on all objects.
+
+2002-09-26 13:29  we7u
+
+	* src/: db.c, main.c: A better logical relation between the
+	  togglebuttons for the new "Display WX Object/Item" button.
+
+2002-09-26 12:39  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Minor change to
+	  Display Weather Object strings.
+
+2002-09-26 12:30  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/xa_config.c: Added a new toggle for enable/disabling weather
+	  objects.
+
+2002-09-25 15:23  we7u
+
+	* src/wx_gui.c: Widening some fields by one character width in Own
+	  Weather Data dialog.
+
+2002-09-25 15:13  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/wx_gui.c: Changing barometric
+	  pressure display in inches Mercury to have two digits after the
+	  decimal point.
+
+2002-09-25 01:28  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/wx.c, src/wx.h,
+	  src/wx_gui.c: Implemented English/Metric barometric pressure for
+	  Own Weather Station dialog and for Station Info dialog.
+
+2002-09-25 00:49  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added another
+	  string for weather stuff.
+
+2002-09-24 16:49  we7u
+
+	* src/maps.c: Just adding some blank lines to delineate the
+	  different functions.	More real code changes to come later.
+
+2002-09-24 13:11  we7u
+
+	* src/db.c: Better handling of weather stations and weather
+	  objects.  We now try to parse the course/speed field _and_ the
+	  'c' and 's' fields in all cases, and can handle some of the
+	  different field positions that some of the RAWS weather objects
+	  present to us.
+
+2002-09-24 10:34  we7u
+
+	* src/db.c: Changed wx_fuel_moisture so that a 00 reading equates
+	  to 100%.
+
+2002-09-23 23:48  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/db.h: Added parsing of
+	  Fuel Temperature and Fuel Moisture for RAWS weather objects, and
+	  the corresponding display in the Station Info dialog.
+
+2002-09-23 22:53  we7u
+
+	* src/db.c: Added some comments.
+
+2002-09-23 11:46  we7u
+
+	* help/help-English.dat: _Very_ minor spelling fixes.
+
+2002-09-23 11:40  we7u
+
+	* src/maps.c: Changes to the lat/long gridlines by Thierry Leconte:
+	  "Now, the code draw solid line and 3 types of dashed lines.
+	  Solid line is, as previously, for equator and Greenwich meridian.
+	  The 3 dashed line corespond to locator coord scheme : 1st dasher
+	  line for big square (2 first letters) 2nd dashed line for the 2
+	  numbers 3rd dashed line for small square (2 last letter).
+	  Depending of the zooming, the code could draw 1,2 or the 3 line
+	  types."  We might wish to change the sizes of the boxes, but the
+	  ideas behind it and the implementation are great!  Thanks
+	  Thierry!
+
+2002-09-23 11:29  rzg
+
+	* help/help-English.dat: Updates for object persistance and a few
+	  more on the new features list to be documented at some point. I
+	  still exist. :-)
+
+2002-09-23 10:38  we7u
+
+	* src/: maps.c, util.c: Fixes by Tom Russo for map indexing of GNIS
+	  files and for reading in zero-length files.  Thanks Tom!
+
+2002-09-19 15:52  we7u
+
+	* src/main.c: Changes by Thierry Leconte which make degrees/minutes
+	  symbols appear in the status line, and add the Maidenhead grid
+	  locator to it as well.  Small changes by we7u to tweak the widths
+	  of the textfields on the status line.
+
+2002-09-19 14:13  we7u
+
+	* src/wx.c: More changes for Peet Bros. U2K weather station
+	  decoding by David L.	Norris.
+
+2002-09-19 13:57  we7u
+
+	* src/: main.c, main.h, maps.c, xa_config.c: Getting rid of WIN_MAP
+	  variables once and for all.
+
+2002-09-19 13:49  we7u
+
+	* src/db.c: More careful string copying of callsigns in a couple of
+	  places.  There was a possibility of overrunning the destination
+	  string before.
+
+2002-09-19 13:27  we7u
+
+	* src/db.c: Adjusting buffer lengths to handle longer packets.
+
+2002-09-19 12:28  we7u
+
+	* src/: main.h, xastir.h: Change to allow u2k complete record mode
+	  (long packets) to get through the decoding functions.
+
+2002-09-19 12:16  we7u
+
+	* src/wx.c: Another small tweak to rain totals for u2k.
+
+2002-09-19 11:12  we7u
+
+	* src/wx.c: Changes for Peet Bros. U2K weather station decoding by
+	  David L.  Norris.
+
+2002-09-19 09:32  we7u
+
+	* src/maps.c: Commenting out the map index printf's in maps.c
+
+2002-09-19 01:08  we7u
+
+	* src/main.c: Adding new language string for TrackMe button.
+
+2002-09-19 01:03  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added new language
+	  string for TrackMe button.
+
+2002-09-19 00:56  we7u
+
+	* src/: main.c, track_gui.c, track_gui.h, xa_config.c: Implemented
+	  new TrackMe button on the main window.  State is saved in config
+	  file so that Xastir starts up in the correct mode.
+
+2002-09-18 15:48  we7u
+
+	* src/: main.c, maps.c, xa_config.c: Added more map types to the
+	  VECTOR button on map chooser.  Now selects ".map", ".gnis",
+	  ".pdb", and ".shp" files.  Changed default name of "winmaps.sys"
+	  file to "selected_maps.sys".	This last change will only take
+	  effect on new installations, or if the winmaps.sys file is
+	  deleted.
+
+2002-09-18 14:21  we7u
+
+	* src/: main.c, maps.c: Map indexing, saving/restoring from files.
+	  This version is more space-efficient.  We could do more speedups
+	  by doing a sort and binary search through the index, or using a
+	  hash.
+
+2002-09-18 12:35  we7u
+
+	* src/maps.c: Small tweak to correct code which creates the empty
+	  map index file.
+
+2002-09-18 12:30  we7u
+
+	* src/maps.c: Killing off the saving of the map index for now.
+	  Plan on implementing a more space-efficient storage.
+
+2002-09-18 12:17  we7u
+
+	* src/: maps.h, main.c, maps.c: Now saving/restoring the map index
+	  to a file.
+
+2002-09-18 11:41  we7u
+
+	* src/: main.c, main.h, maps.c, maps.h, xa_config.c: Initial
+	  implementation of map indexing, still need to save/restore the
+	  map index linked list to a file.  Currently the indexing occurs
+	  _after_ the first map draw, then succeeding map draws check the
+	  index which speeds things up considerably.  The plan is to write
+	  the index to a file, read it in _before_ the first map draw, and
+	  then re-index only when new files appear or files are changed in
+	  the map directory.
+
+2002-09-12 10:48  we7u
+
+	* src/main.c: Added the Station Last Heard button into the
+	  Sensitive enable/disable for Symbols in the menu.  It was getting
+	  grey'ed out and not returning to the Sensitive state as the
+	  Symbols Enable button was toggled.
+
+2002-09-12 09:56  we7u
+
+	* src/maps.c: Fixes to draw_shapefile_map() to set a default line
+	  width, for cases where specific maps are not recognized later in
+	  the code.  The problem was that other areas in the drawing code
+	  (probably tracklines) where causing map lines to get drawn in
+	  double or triple width at times.
+
+2002-09-10 16:35  we7u
+
+	* src/maps.c: Added a default line width setting to the start of
+	  the polyline drawing portion of draw_shapefile_map().  This is an
+	  attempt to get rid of the double line-widths that are sometimes
+	  seen on the screen.
+
+2002-09-10 16:14  we7u
+
+	* src/db.c: Fixing the new track detector for the save track
+	  function.
+
+2002-09-10 15:14  we7u
+
+	* src/: db.c, db.h: A bit of housekeeping.  Renaming the TrackRow2
+	  struct to TrackRow, since the old TrackRow is now deleted from
+	  the code.
+
+2002-09-10 12:22  we7u
+
+	* src/: db.h, db.c: Fixes for station track storage.
+
+2002-09-10 10:04  we7u
+
+	* src/main.c: Creating the .xastir/tracklogs directory
+	  automatically on startup.
+
+2002-09-09 16:29  we7u
+
+	* src/maps.c: Tweak to handle parsing of newer format bounding
+	  coordinates from USGS .fgd files.
+
+2002-09-03 09:23  francais1
+
+	* src/list_gui.c: Bug 604044 All station names were ghosted.
+	  Fixed.
+
+2002-08-29 17:44  we7u
+
+	* src/maps.c: Changed some comments.
+
+2002-08-29 14:01  we7u
+
+	* src/main.c: Changing language list to alphabetical.
+
+2002-08-29 08:49  we7u
+
+	* src/: bulletin_gui.c, db.c, util.c: Putting several debug
+	  printf's under debug_level control.
+
+2002-08-28 13:41  we7u
+
+	* src/: db.c, util.c: Fix for bulletins popping up that are out of
+	  range.  We were computing the distance from our station based on
+	  the destination callsign (BLNx) instead of the originating
+	  callsign.
+
+2002-08-27 15:43  we7u
+
+	* src/: util.h, util.c: Added higher precision timers in order to
+	  time code sections.
+
+2002-08-27 15:42  we7u
+
+	* config/language-Dutch.sys: Changed by Han Sytsma, PE1FAM.
+
+2002-08-26 14:52  we7u
+
+	* scripts/: coord-convert.pl, permutations.pl, test_coord.pl:
+	  Modifying each script to add a path to /usr/local/lib in order to
+	  find the Coordinate.pm module.
+
+2002-08-26 12:08  we7u
+
+	* src/db.c: Added a few comments.
+
+2002-08-24 11:52  kd6zwr
+
+	* src/maps.c: Explicitly defined shorts as unsigned to fix wrapping
+	  problems with palm maps.
+
+2002-08-23 10:06  we7u
+
+	* README.1ST: Added a note about Tiger 2000 maps converted to
+	  Shapefiles.
+
+2002-08-22 15:43  we7u
+
+	* src/maps.c: Added some casts.
+
+2002-08-22 14:58  we7u
+
+	* README.1ST: Updated the fcc/rac call lookup installation
+	  instructions.
+
+2002-08-22 13:58  we7u
+
+	* src/maps.c: More comments.
+
+2002-08-22 12:47  we7u
+
+	* src/maps.c: More comments.
+
+2002-08-22 12:12  we7u
+
+	* scripts/: Makefile.am, Makefile.in: Adding coord-convert.pl and
+	  permutations.pl to install.
+
+2002-08-22 11:33  we7u
+
+	* src/maps.c: Changing some comments.  No code changes.
+
+2002-08-22 09:51  we7u
+
+	* src/maps.c: Adding some comments to the palm map routine.
+
+2002-08-22 09:43  we7u
+
+	* src/maps.c: Changed a single-letter variable to two letters to
+	  make it easier to grep for in the code.
+
+2002-08-21 17:19  we7u
+
+	* src/: bulletin_gui.c, bulletin_gui.h, db.c, main.c: Fixes for
+	  bulletins popping up.  Now waits 15 seconds to see if a posit
+	  comes in before attempting to pop up the bulletins dialog.  Added
+	  filtering for characters output by an extract_multipoints debug
+	  message.
+
+2002-08-21 11:24  we7u
+
+	* src/list_gui.c: Now grey out the object/item name as well if it
+	  has been deleted.  In the View->Object & Item dialogs.
+
+2002-08-21 11:17  we7u
+
+	* src/db.c: Putting out debug message in order to debug possible
+	  bulletin problem.
+
+2002-08-21 11:16  we7u
+
+	* src/list_gui.c: We now show deleted objects/items in the "View"
+	  dialogs as ghosted.
+
+2002-08-20 15:07  kd6zwr
+
+	* src/main.c: Bumped up the test for debug level dialog.
+
+2002-08-16 15:54  we7u
+
+	* FAQ: More minor tweaks to the same section.
+
+2002-08-16 15:50  we7u
+
+	* FAQ: Minor addition to the "why can't I see stations" paragraph.
+
+2002-08-15 16:57  we7u
+
+	* src/maps.c: Moved the USGS Quad labels left by one square.  They
+	  appear to be in the correct places now.
+
+2002-08-15 14:27  we7u
+
+	* config/tnc-startup.paccomm: New startup file for Pac-Comm TNC's
+	  with version 5.x firmware.
+
+2002-08-15 10:22  we7u
+
+	* scripts/coord-convert.pl: Added the capability to handle "48N
+	  122W" and similar inputs.  Fixed a bug in DD MM.MM conversions.
+
+2002-08-14 15:04  we7u
+
+	* src/db.c: An attempt to prevent Emergency popups about the same
+	  callsign from appearing more often than every 30 minutes.
+
+2002-08-14 13:51  we7u
+
+	* scripts/: coord-convert.pl, permutations.pl: Adding a blank line
+	  between user input and output lines.
+
+2002-08-14 11:21  we7u
+
+	* scripts/permutations.pl: And handling yet another format...
+
+2002-08-14 11:15  we7u
+
+	* scripts/permutations.pl: Tweaks to more properly format some
+	  inputs.
+
+2002-08-14 10:55  we7u
+
+	* scripts/permutations.pl: Tweaks to allow shorter lat/lon strings
+	  to be processed.
+
+2002-08-14 10:12  we7u
+
+	* scripts/permutations.pl: Added the capability to write APRS Items
+	  to a log file that can be sucked in by Xastir.
+
+2002-08-14 09:52  we7u
+
+	* src/db.c: Minor tweak to get rid of compiler warning.
+
+2002-08-14 08:49  francais1
+
+	* src/util.c: Nasty lat/lon to/from UTM conversion bug.  (Wasn't
+	  referencing correct ellipsoid.) Also made last 2 characters of
+	  grid square location lowercase since that seems more common.
+
+2002-08-14 08:49  francais1
+
+	* src/main.c: Nasty lat/lon to/from UTM conversion bug.  (Wasn't
+	  referencing correct ellipsoid.)
+
+2002-08-13 17:12  we7u
+
+	* scripts/permutations.pl: New script which will show various
+	  permutations for a lat/lon or UTM input.  Eventually plan to have
+	  this script write a log file containing objects so that Xastir
+	  can plot each of the positions.  This will be useful in quickly
+	  determining which of the formats is within the area of interest.
+	  Developed this for Search & Rescue applications.
+
+2002-08-13 16:51  we7u
+
+	* scripts/coord-convert.pl: Added a range check for the Easting
+	  value.  Not exact, but better than nothing.
+
+2002-08-13 15:34  we7u
+
+	* scripts/coord-convert.pl: Added capability to use UTM as the
+	  input coordinate.
+
+2002-08-13 14:36  we7u
+
+	* scripts/: Coordinate.pm, test_coord.pl: Getting the dates right
+	  for the copyright.
+
+2002-08-13 14:34  we7u
+
+	* scripts/: Coordinate.pm, coord-convert.pl, test_coord.pl: Tweaks
+	  to headers.
+
+2002-08-13 14:01  we7u
+
+	* src/db.c: Commenting out debug statement.
+
+2002-08-13 13:47  we7u
+
+	* src/db.c: Fixed Mic-E decoding problem having to do with position
+	  ambiguity.  We have to specifically test for 'L' in the
+	  destination field as it doesn't match the general bit patterns.
+	  Stupid spec anyway.
+
+2002-08-13 11:39  we7u
+
+	* src/: db.c, db.h, draw_symbols.c, draw_symbols.h: Severe storm
+	  objects by Gerry Wheeler, KG4NBB.  Dale Huguley, KG5QD's weather
+	  server (on the 'net) generates severe storm objects and
+	  boundaries based on NWS data.  These objects are now decoded and
+	  drawn by Gerry's new code additions.
+
+2002-08-12 17:03  we7u
+
+	* scripts/: Coordinate.pm, coord-convert.pl, test_coord.pl: Utility
+	  for converting between coordinates, written in Perl.	Also has
+	  UMS coordinates.
+
+2002-08-12 12:04  we7u
+
+	* src/maps.c: Pre-pending the quad index to the quad name.
+
+2002-08-12 11:36  we7u
+
+	* src/maps.c: Fix for some labels on quad overlay shapefile.
+
+2002-08-11 09:57  we7u
+
+	* README.1ST: Changed the URL where the Mac OS X instructions
+	  reside.
+
+2002-08-09 17:34  we7u
+
+	* src/maps.c: Nicer labels for the quad names.
+
+2002-08-09 17:26  we7u
+
+	* src/maps.c: Initial support for USGS Quad overlay shapefile.
+
+2002-08-09 16:33  we7u
+
+	* README.1ST: A bit more about ldconfig.
+
+2002-08-08 23:33  we7u
+
+	* src/: util.c, util.h, wx.c: Changes to 30-second timestamps in
+	  logfiles:  Now closely emulate the date/time string that the
+	  date(1) command generates.
+
+2002-08-06 16:14  we7u
+
+	* src/util.c: Getting rid of a message that appears if the
+	  .xastir/config/object.log file doesn't exist.
+
+2002-08-06 13:42  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added a clear button for
+	  the object/item history file.
+
+2002-08-06 13:00  we7u
+
+	* src/: main.c, util.c, util.h, xastir.h: Implementation of
+	  persistent objects/items.  Each new, deleted, or moved
+	  object/item is logged to "~/.xastir/config/object.log".  This
+	  file is read in and each line processed on startup.  This will
+	  also show tracklines for moved objects as each change is logged
+	  to the file.
+
+2002-08-06 11:33  we7u
+
+	* src/db.c: Adding "AA:" to the beginning of auto-response
+	  messages.
+
+2002-08-06 09:52  francais1
+
+	* src/maps.c: IsPseudoClass in ImageMagick 5.3.1 doesn't quite act
+	  like I would have thought.  Changed to different check.
+
+2002-08-05 15:29  we7u
+
+	* src/: messages_gui.c, view_message_gui.c: More tweaks regarding
+	  fonts.  Seems we can set foreground color but not background on a
+	  couple of widgets.  Trying to set background color causes a
+	  segfault.
+
+2002-08-05 15:07  we7u
+
+	* src/: messages_gui.c, view_message_gui.c: Move segfault fixes in
+	  new code.
+
+2002-08-05 15:05  we7u
+
+	* src/view_message_gui.c: Fix for segfault in newly introduced
+	  code.
+
+2002-08-05 13:48  we7u
+
+	* src/: bulletin_gui.c, draw_symbols.c, location_gui.c, main.c,
+	  messages_gui.c, track_gui.c, view_message_gui.c, xastir.h: Added
+	  defines for foreground and background font colors.  This and the
+	  associated code changes should help to alleviate the problem
+	  where font colors would accidentally change during runtime due to
+	  color-ls being run in the starting Xterm.
+
+2002-07-26 09:35  we7u
+
+	* help/help-English.dat: Very minor changes to the new scripts
+	  section.
+
+2002-07-26 09:30  we7u
+
+	* src/messages_gui.c: Put another message under debug_level
+	  control.
+
+2002-07-26 08:45  rzg
+
+	* help/help-English.dat: Added scripts section, minor update to new
+	  features list.
+
+2002-07-25 22:24  we7u
+
+	* src/messages_gui.c: Commenting out some debug messages.
+
+2002-07-25 20:29  we7u
+
+	* src/: db.c, igate.c, igate.h, main.c: Implemented SENT and HEARD
+	  queues for igating->RF.  Dupes are now eliminated.  This includes
+	  if another igate beat us to getting a packet on RF:  In that case
+	  we don't add to the traffic on RF by sending it out too.
+
+2002-07-24 12:58  we7u
+
+	* src/db.c: Fix for igating:  We were testing the ST_VIATNC flag
+	  for a station first to see if it had been heard via a TNC
+	  interface.  This flag gets reset if the last 20 packets were
+	  heard from non-TNC interfaces.  We now check the
+	  heard_via_tnc_last_time timestamp to see if it's nonzero.  This
+	  timestamp does _not_ get set to 0.  The code in
+	  heard_via_tnc_in_past_hour() should work better for igating now.
+
+2002-07-23 15:04  we7u
+
+	* src/: interface_gui.c, xa_config.c: Changing txtail default value
+	  to from 10ms to 30ms.  Should be proper for 1200 baud.
+
+2002-07-23 14:37  we7u
+
+	* README.1ST: Added Lindows to the list.
+
+2002-07-23 14:27  we7u
+
+	* src/: interface.c, interface.h, interface_gui.c, xa_config.c:
+	  Turned "Full Duplex" KISS parameter into a togglebutton.
+
+2002-07-23 13:43  we7u
+
+	* src/: interface.c, interface.h, interface_gui.c, xa_config.c:
+	  Added TxTail parameter to the KISS properties dialog.
+
+2002-07-23 13:07  we7u
+
+	* src/messages_gui.c: Putting more debug messages under debug_level
+	  control.
+
+2002-07-22 19:41  rzg
+
+	* help/help-English.dat: Added mention of RELAY digipeating and
+	  fixed a formatting thing.
+
+2002-07-22 11:08  we7u
+
+	* configure, configure.in: Bumping it to version 1.1.3.  Getting
+	  ready for another development release.
+
+2002-07-22 10:41  we7u
+
+	* src/: db.c, interface_gui.c: Commenting out debug message.
+	  Making Relay Digipeat togglebuttons insensitive until the code to
+	  implement them is functional.
+
+2002-07-20 00:44  we7u
+
+	* src/db.c: Don't relay from KISS interface if transmit for that
+	  interface is turned off.
+
+2002-07-20 00:31  we7u
+
+	* src/interface_gui.c: Changes to make RELAY digipeat insensitive
+	  when transmit is disabled for that interface.
+
+2002-07-19 23:50  we7u
+
+	* src/interface.c: Commenting out another debug statement.
+
+2002-07-19 23:48  we7u
+
+	* src/interface.c: Fixes to AX.25 interfaces that were broken
+	  earlier by KISS TNC changes.
+
+2002-07-19 17:02  we7u
+
+	* src/interface.c: Changes to serial lockfiles.  Now closes port
+	  before removing lock.  Attempts to close port and remove lock if
+	  open fails for any number of reasons.
+
+2002-07-19 15:19  we7u
+
+	* src/interface.c: Fixes for errant long packets.  Code had the
+	  wrong number for the length of the incoming strings.
+
+2002-07-19 13:51  we7u
+
+	* src/: db.c, interface.c: Found an off-by-one error in
+	  incoming_data_length.  Changed a lot of comments w.r.t. KISS
+	  interfaces.
+
+2002-07-19 01:06  we7u
+
+	* src/: db.c, db.h, interface.c, interface.h, main.c: More work on
+	  RELAY digipeating for Serial KISS TNC interfaces.  Getting
+	  closer, but this version is still non-functional.
+
+2002-07-18 17:02  we7u
+
+	* src/: db.c, db.h, main.c: More preparation for later coding of
+	  the RELAY digipeat function.	Not implemented yet.
+
+2002-07-18 16:49  we7u
+
+	* src/: db.c, main.c: More comments.
+
+2002-07-18 16:48  we7u
+
+	* src/interface.c: Fixing another double-lock problem.
+
+2002-07-18 16:36  we7u
+
+	* src/main.c: Added an important comment.
+
+2002-07-18 16:34  we7u
+
+	* src/interface.c: Fixing a double-lock problem that I introduced
+	  earlier today.
+
+2002-07-18 14:55  we7u
+
+	* src/interface_gui.c: Adding a debug_level statement in that was
+	  missing.
+
+2002-07-18 14:47  we7u
+
+	* src/interface_gui.c: Adding relay_digipeat stuff to the AX.25
+	  interface GUI.
+
+2002-07-18 14:40  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/interface.h,
+	  src/interface_gui.c, src/xa_config.c: Preliminary code including
+	  GUI support for RELAY digipeating on Serial KISS TNC interfaces.
+	  The back-end code is not implemented yet, so right now it looks
+	  pretty but doesn't do anything.  The plan is to add similar
+	  support for AX.25 kernel interfaces.	Regular serial TNC
+	  interfaces and NET interfaces don't need this capability.  For
+	  regular serial TNC's RELAY digipeating is turned on/off in the
+	  config file for that interface.
+
+2002-07-18 13:01  we7u
+
+	* help/help-English.dat: Removed the serial port settings from the
+	  Serial KISS TNC descriptions.  The port is set to 8N1 by default
+	  now and cannot be changed.
+
+2002-07-18 12:59  we7u
+
+	* src/interface_gui.c: Changed interface properties dialog when
+	  dealing with Serial KISS TNC interfaces:  No longer is the user
+	  presented with serial parameter choices which are not allowed to
+	  be changed anyway.
+
+2002-07-18 12:39  we7u
+
+	* help/help-English.dat: Changed KISS interface description to
+	  agree with the code, which forces the N81 option for serial port
+	  parameters now.
+
+2002-07-18 12:37  we7u
+
+	* src/interface_gui.c: Forcing KISS interfaces to N81 for the
+	  serial port parameters.
+
+2002-07-18 12:17  we7u
+
+	* help/help-English.dat: Just spelling fixes.
+
+2002-07-18 12:14  we7u
+
+	* help/help-English.dat: A few minor additions/corrections to the
+	  KISS, TNC, and AX.25 interface descriptions.
+
+2002-07-18 12:04  we7u
+
+	* src/interface.c: Added some locks where a few were missing.
+	  Added code to send the KISS parameters down to the TNC when the
+	  port is first opened.
+
+2002-07-18 10:45  rzg
+
+	* help/help-English.dat: Updates for serial KISS TNC, message
+	  paths, igate paths, and more..
+
+2002-07-18 09:31  we7u
+
+	* src/: db.c, db.h, interface.c, interface.h, interface_gui.c,
+	  main.c, messages_gui.c: Reorganized KISS parameter widgets in the
+	  dialog.  Changed to string,length instead of relying on the
+	  terminating zero in the string for transmitting strings.  This is
+	  due to the fact that KISS packets can have 0x00 in them as data.
+	  Fixed the problems with non-posit packet transmission and the
+	  Serial KISS TNC interface.
+
+2002-07-17 18:01  we7u
+
+	* src/: interface.c, interface.h, interface_gui.c, xa_config.c:
+	  Added kiss parameters to the properties dialog.
+
+2002-07-17 16:17  we7u
+
+	* src/main.c: Better behaved positioning of dialogs.  They won't
+	  get positioned quite as far down the screen now.
+
+2002-07-17 16:06  we7u
+
+	* src/igate.c: Reformatted all of the igating routines.  Added a
+	  specific check so that we don't re-inject TCPIP or TCPXX packets
+	  back into the internet (we don't want looping).  The routines are
+	  much more understandable now and should be easier to maintain.
+
+2002-07-17 13:54  we7u
+
+	* src/interface.c: Changed/added comments.  Deleted the section of
+	  code in port_read() that looked for AX.25 flag characters, as
+	  KISS packets should not normally contain them.  We instead will
+	  try breaking apart the KISS packets based on \n and \r
+	  characters.
+
+2002-07-17 13:05  we7u
+
+	* src/: db.c, db.h: Changing to unsigned char for one parameter so
+	  that we can check all eight bits of each char.
+
+2002-07-17 13:01  we7u
+
+	* src/db.c: Lots of comment changes.  Added check code to the
+	  decoding functions to look for and correct concatenated KISS
+	  packets.  Currently the tacked-on packets will get deleted.  This
+	  should get fixed in later revisions.
+
+2002-07-17 12:25  we7u
+
+	* src/interface.c: Reformatted, changed/added comments.  No code
+	  changes.
+
+2002-07-17 02:04  we7u
+
+	* src/interface.c: Initial code to implement Serial KISS TNC
+	  transmit.
+
+2002-07-16 17:00  we7u
+
+	* src/interface.c: More preparation for doing KISS TNC transmit.
+	  Not finished yet.
+
+2002-07-16 15:33  we7u
+
+	* src/interface.c: Tweak to check for NULL in igate_path.  Lot's of
+	  comment changes.
+
+2002-07-16 14:32  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c: Fixed language
+	  string for KISS TNC dialog.  Added comments.
+
+2002-07-16 14:09  we7u
+
+	* src/interface.c: A few more small tweaks to help with closing
+	  Serial KISS TNC interfaces.
+
+2002-07-16 11:26  we7u
+
+	* src/db.c: Added some comments.
+
+2002-07-16 09:47  we7u
+
+	* src/: db.c, db.h, interface.c, interface_gui.c, main.c: Initial
+	  implementation of Serial KISS TNC support.  This one is
+	  receive-only.  Still have to write the code to generate the
+	  outgoing AX.25 header for transmitting.  This one may be unstable
+	  yet, but the instability should only affect Xastir instances with
+	  this port enabled.
+
+2002-07-15 16:25  we7u
+
+	* src/interface.c: Commented out some debugging code.
+
+2002-07-15 16:24  we7u
+
+	* src/: igate.c, interface.h, interface_gui.c, xa_config.c, main.c,
+	  interface.c: The start of code to implement serial port KISS tnc
+	  functionality (without using kernel-mode AX.25 ports).  Not
+	  functional yet.
+
+2002-07-15 16:03  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Just starting to
+	  add Serial KISS TNC capability.  Not functional yet.
+
+2002-07-15 01:02  we7u
+
+	* src/interface.c: Fixed one problem with igate_path.  Added a
+	  bunch of comments, reformatted some code, changed some variable
+	  names.
+
+2002-07-13 10:38  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/igate.c,
+	  src/interface.c, src/interface.h, src/main.c, src/messages.c,
+	  src/messages.h, src/messages_gui.c, src/wx.c, src/xastir.h:
+	  Implemented reverse path for messaging.  Xastir now tries to
+	  figure out a reasonable return path when doing messaging.
+
+2002-07-12 16:59  we7u
+
+	* src/messages_gui.c: Adding some code in preparation for setting
+	  up individual return paths for messaging.  This code figures out
+	  the return path from the last path received for that station,
+	  including dropping "RELAY" callsigns and asterisks and converting
+	  WIDEn-N callsigns to their original glory.  Converts TRACE and
+	  TRACEn-N callsigns to WIDE and WIDEn-N as well.
+
+2002-07-12 14:09  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/igate.c,
+	  src/interface.c, src/interface.h, src/interface_gui.c,
+	  src/main.c, src/messages.c, src/wx.c, src/xa_config.c:
+	  Implemented separate unproto path for igating.  Change it via the
+	  properties dialog for affected interfaces.  If nothing entered,
+	  it will round-robin between the other three interfaces or select
+	  a default path.
+
+2002-07-12 12:15  we7u
+
+	* src/db.c: Now have red circle around tracked station.
+
+2002-07-12 11:08  we7u
+
+	* src/: db.c, main.c: Added Maidenhead Grid Locator output to the
+	  Coordinate Calculator.
+
+2002-07-12 09:52  we7u
+
+	* src/main.c: Added mnemonics keys to the right mouse button menu.
+	  Now if you select it via the Maps menu you can still navigate
+	  through it via keyboard.  Note that some of the options won't
+	  work properly without a mouse pointer pointing to an object on
+	  the screen, like Station Info.  For those options needing to snag
+	  the mouse pointer, it appears to use whatever point the mouse
+	  pointer is on (as usual).  If the pointer is outside the drawing
+	  area, all bets are off.
+
+2002-07-11 17:20  we7u
+
+	* src/db.c: Proper rounding of course when saving track data.
+
+2002-07-11 16:54  we7u
+
+	* src/db.c: Tweaking altitude/speed/course displays to skip over
+	  the first trackpoint, which is the same as our current data.	We
+	  now look at the next oldest trackpoint to try to pull out
+	  slightly older data for display purposes.
+
+2002-07-11 16:31  we7u
+
+	* help/help-English.dat: A few changes to the SmartBeaconing
+	  parameter descriptions.
+
+2002-07-11 16:22  we7u
+
+	* src/db.c: Decoupling speed/course from each other for display
+	  purposes.
+
+2002-07-11 16:10  we7u
+
+	* src/util.c: Reducing PHG circles by 1/2, per Bob Bruninga's
+	  recommendations.
+
+2002-07-11 15:46  we7u
+
+	* src/db.c: Skipping first tracklog entry when filling in the
+	  Station Info dialog.	It's the same as the first line or "Last
+	  Position".
+
+2002-07-11 15:07  we7u
+
+	* src/util.c: Small change to valid_path() to allow "qAC" and
+	  similar q-codes to pass through.  This is a new addition from
+	  Dale Heatherington to the aprsd server for anti-looping purposes.
+
+2002-07-11 14:45  we7u
+
+	* src/db.c: Changed minimum length check for GGA/RMC strings and
+	  put one debug message inside debug_level logic.
+
+2002-07-11 14:36  we7u
+
+	* src/db.c: More general code for parsing RMC and GGA sentences.
+	  Now allows any number of digits after the decimal point for the
+	  lat/long fields.
+
+2002-07-11 12:51  we7u
+
+	* src/db.c: Tweak to make bad Mic-E positions not draw tracks.
+
+2002-07-11 09:03  rzg
+
+	* help/help-English.dat: Updates to new features list, added
+	  smartbeaconing help, other minor stuff.
+
+2002-07-09 15:38  we7u
+
+	* src/db.c: Expire code for trackpoints.  Currently uses the
+	  station expire variable for choosing when to expire each
+	  trackpoint.  Called from draw_trail() for each station.
+
+2002-07-09 14:12  we7u
+
+	* src/maps.c: Now outputs warning messages for Shapefile maps that
+	  have bad lat/lon values.  This lets the user know which map files
+	  or which shapes within the file have problems.
+
+2002-07-09 13:00  we7u
+
+	* src/interface.c: Searching for excessively long packets earlier
+	  in the process.  Now we drop them on the floor before the decode
+	  routines.
+
+2002-07-09 11:12  we7u
+
+	* src/db.c: Tweaked a debug line to output more data.
+
+2002-07-09 10:55  we7u
+
+	* src/: db.c, gps.c, interface.c, interface.h, main.c, util.c,
+	  wx.c: String lengths can be MAX_DEVICE_BUFFER length, currently
+	  defined to be 4096 characters, when going into the decode
+	  routines.  These are fixes to handle these long line lengths in a
+	  graceful manner.
+
+2002-07-08 20:17  rzg
+
+	* src/db.c: Moving a newline in debugging code so it won't get
+	  lost.
+
+2002-07-08 18:02  kd6zwr
+
+	* src/maps.c: One more GNIS icon - parks.
+
+2002-07-08 15:43  we7u
+
+	* src/: alert.c, db.c, draw_symbols.c, interface.c, main.c, maps.c,
+	  messages.c, view_message_gui.c: Changing a bunch of comments.
+	  Mostly removing "we7u" bookmarks.
+
+2002-07-07 18:30  rzg
+
+	* README.1ST: Weather shapefiles are moving...
+
+2002-07-04 11:26  we7u
+
+	* src/: db.c, db.h, list_gui.c: Changes which implement
+	  dynamically-allocated tracklogs.  Expiration and function which
+	  writes track to file need to be worked on yet.
+
+2002-07-03 23:28  we7u
+
+	* src/db.c: Slight reformatting and added a few comments.  No real
+	  code changes.
+
+2002-07-03 17:03  we7u
+
+	* src/db.c: Commenting out some debug statements.
+
+2002-07-03 16:59  we7u
+
+	* src/db.c: Added a few comments.
+
+2002-07-03 16:46  we7u
+
+	* src/db.c: Found that the first trackpoint was getting skipped
+	  when displaying in Station Info dialog.  Fixed it.  We also now
+	  look in the first tracklog point for course/speed/altitude if any
+	  of these parameters are missing in the current data.	Found other
+	  problems in tracklog indexing in db.c that need to be fixed yet.
+
+2002-07-03 12:16  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/maps.c, src/xa_config.c: Added a new togglebutton that
+	  enables bulletin popup for new bulletins.  Moved the smartbeacon
+	  enable button to its dialog.
+
+2002-07-03 11:22  we7u
+
+	* src/db.c: Reverting back to old Bulletin method for now.  New
+	  method doesn't work right if bulletin received w/no posit, then
+	  posit is received later.
+
+2002-07-03 11:14  we7u
+
+	* README.1ST: Added a blurb about LD_LIBRARY_PATH variable being
+	  ignored when running Xastir as SUID root.
+
+2002-07-03 11:10  we7u
+
+	* src/: bulletin_gui.c, db.c: Fixed bulletins so that they don't
+	  pop up if distance is zero, unless the range setting is set to
+	  zero.  It was getting much too annoying the other way when
+	  connected to a cached network feed.  With the new code these
+	  things will cause bulletins to pop up:   Distance non-zero and
+	  within range setting.    Range setting set to zero.  The user can
+	  also bring up the View->Bulletins dialog and it will still show
+	  the zero-range bulletins in any case.
+
+2002-07-03 09:09  francais1
+
+	* src/maps.c: Applied, slightly tweaked and tested patch from
+	  Derrick Brashear which adds support for different PHOTOMETRIC
+	  geotiffs.
+
+2002-07-02 16:25  we7u
+
+	* src/: db.c, util.c, util.h: Added Maidenhead grid locators to
+	  Station Info dialog.	Code by dl9sau which was derived from
+	  Wampes util/qth.c code by dk5sg.
+
+2002-07-02 14:31  we7u
+
+	* src/maps.c: Added more detailed debug messages for the case where
+	  lat/lon to be converted is outside the proper ranges.
+
+2002-07-02 14:30  we7u
+
+	* src/alert.c: Quieting some debug messages having to do with
+	  compressed weather alerts (which aren't implemented yet).
+
+2002-07-02 12:40  we7u
+
+	* src/main.c: Tweaked TigerMap config dialog so that strings in
+	  different languages would cause a resize of the dialog, and the
+	  dialog would be smaller/easier to use with smaller screen
+	  resolutions.
+
+2002-07-02 11:10  n0vh
+
+	* src/: main.c, maps.c, xa_config.c, xastir.h: Added code to allow
+	  the user to set the timeout for getting tigermaps from the menu.
+
+2002-06-28 14:03  we7u
+
+	* src/maps.c: Patch for corrupt fgd files by Derrick J Brashear.
+
+2002-06-28 13:44  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/db.h: Separated out
+	  storage and display of comments/status.
+
+2002-06-28 11:18  we7u
+
+	* src/maps.c: Added an 'X' symbol and a nicely-drawn label for
+	  waypoing shapefiles.
+
+2002-06-28 10:47  we7u
+
+	* src/maps.c: Changes to make waypoint Shapefiles appear properly
+	  in Xastir.
+
+2002-06-27 20:30  n0vh
+
+	* src/main.c: More minor updates.
+
+2002-06-27 20:21  n0vh
+
+	* src/: main.c, track_gui.c: Clean up some of the tigermap menu
+	  items and reformatted them.
+
+2002-06-27 13:12  we7u
+
+	* README.1ST: Added notes regarding ld.so.cache to the Shapelib
+	  section.
+
+2002-06-26 10:34  we7u
+
+	* src/maps.c: Fix for missing IMAGESIZE tag in .geo file:  We
+	  output an error message and skip loading that file.  Someday we
+	  may wish to try to find out the imagesize via calls to the
+	  imagemagick or xpm libraries.
+
+2002-06-26 09:46  we7u
+
+	* src/db.c: Bulletins no longer cause a refresh of the Send Message
+	  dialogs.
+
+2002-06-26 08:50  francais1
+
+	* src/: list_gui.c, list_gui.h, xa_config.c: Added a number of
+	  lists definition to the end of the list number definitions so
+	  that the code doesn't need touching every time you add a new
+	  list.  Moved list number definitions to list_gui.h so that I can
+	  see them from xa_config.c.
+
+2002-06-25 17:20  we7u
+
+	* src/db.h: Added a line for is_my_call().
+
+2002-06-25 17:13  we7u
+
+	* src/: list_gui.c, main.c, xa_config.c: New list for viewing
+	  objects/items that we own.
+
+2002-06-25 17:12  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: New strings for
+	  new list.
+
+2002-06-25 16:45  we7u
+
+	* help/help-English.dat: Spelling.
+
+2002-06-25 16:28  rzg
+
+	* help/help-English.dat: Updated helpfile for recent changes.
+
+2002-06-25 15:03  we7u
+
+	* src/: bulletin_gui.c, bulletin_gui.h, db.c: Fixes for annoying
+	  bulletins.  It should only pop up the bulletin dialog now when
+	  new bulletins come in that are within range.	It's possible to
+	  receive a bulletin without having a posit from that station, then
+	  get a posit, making it outside the range.  In this case you may
+	  get a popup without knowing why.  It's better than what it was
+	  doing before though.
+
+2002-06-25 12:41  we7u
+
+	* src/: list_gui.c, main.c, xa_config.c: Added "View->Objects &
+	  Items" list.
+
+2002-06-25 12:33  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Added string for
+	  new View->Objects & Items dialog.
+
+2002-06-24 15:40  we7u
+
+	* src/draw_symbols.c: Changed DF beam-heading objects to draw in
+	  red3.  Using stippling the lines were not visible on some map
+	  backgrounds.	Also narrowed the lines for pod_circles (not fully
+	  implemented yet).
+
+2002-06-24 12:28  we7u
+
+	* src/main.c: Added comments.  No code changes.
+
+2002-06-24 12:27  we7u
+
+	* config/language-Portuguese.sys: Updates by David Quental, CT1DRB.
+	  Thanks!
+
+2002-06-22 11:01  n0vh
+
+	* src/track_gui.c: Update GUI so that the length of the track
+	  downloaded from FINDU can be selected.
+
+2002-06-21 20:28  n0vh
+
+	* src/maps.c: Commented all the findu code out from maps.c since
+	  it's now done from track_gui.c.  It will be removed in the
+	  future.
+
+2002-06-21 14:20  we7u
+
+	* src/: draw_symbols.c, draw_symbols.h: Added draw_pod_circle()
+	  function.  It has yet to be tied to a GUI anywhere.
+
+2002-06-21 12:36  we7u
+
+	* src/db.c: Added some comments.
+
+2002-06-21 12:36  we7u
+
+	* src/util.c: Added a comment.
+
+2002-06-21 12:21  we7u
+
+	* src/db.c: Leave my_last_speed in knots so it is consistent
+	  throughout the code.
+
+2002-06-21 12:18  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Converted more strings
+	  to use langcode().
+
+2002-06-21 12:17  we7u
+
+	* src/interface.c: Added some comments.
+
+2002-06-21 12:15  we7u
+
+	* src/gps.c: Added a commented-out debug statement.
+
+2002-06-21 12:15  we7u
+
+	* src/: draw_symbols.c, main.h: Added a comment.
+
+2002-06-21 07:49  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Converted Coordinate
+	  Calculator to use langcode() strings.
+
+2002-06-21 07:35  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added langcode() strings
+	  for the new Configure->SmartBeaconing dialog.
+
+2002-06-21 07:02  we7u
+
+	* src/main.c: Initial GUI for setting SmartBeaconing parameters.
+
+2002-06-20 15:41  we7u
+
+	* src/main.c: Adding bearing degrees to the Measure function.
+
+2002-06-20 15:23  we7u
+
+	* src/bulletin_gui.c: We now create the View->Bulletins dialog when
+	  bulletins come in.
+
+2002-06-20 14:01  we7u
+
+	* src/: igate.c, interface.c, messages.c: Added/modified some
+	  comments.
+
+2002-06-20 12:47  we7u
+
+	* src/interface.c: Added a 250ms delay after writing each waypoint.
+
+2002-06-20 10:44  we7u
+
+	* src/gps.c: Added some notes to the waypoint creation routine.
+
+2002-06-20 10:36  we7u
+
+	* src/gps.c: Fixed problem with lower-case characters when creating
+	  waypoints.
+
+2002-06-19 17:17  we7u
+
+	* src/: db.c, gps.c, gps.h, interface.c, interface.h: For those of
+	  you with Garmin GPS units:  Set up the audio proximity alarm
+	  range for some distance around your station and Xastir will now
+	  create waypoints for each APRS station/object/item that it hears
+	  within that range.  They'll appear on your Garmin map display as
+	  waypoints.  Enjoy! You can delete the waypoints by type.  They
+	  appear as the circle with the 'X' in the middle.  You may want to
+	  change other waypoints to some other type before you play with
+	  this new Xastir feature.
+
+2002-06-19 10:53  we7u
+
+	* src/db.c: Fixed remove_leading_spaces() as it didn't work at all
+	  as coded.  It liked to truncate after the first word.  Also fixed
+	  some malloc sizes added recently.
+
+2002-06-19 10:44  francais1
+
+	* src/db.c: strlen, not sizeof
+
+2002-06-18 17:06  we7u
+
+	* src/: db.c, db.h, list_gui.c: Additional memory savings for the
+	  node_path variable in the station database.  Changed it to a
+	  pointer and allocate exact space for the string when stored or
+	  updated.
+
+2002-06-18 16:19  we7u
+
+	* src/: db.c, db.h, list_gui.c, main.c: More space savings.  Turned
+	  comment into a pointer in the station record and allocate just
+	  the space we need for it.
+
+2002-06-18 15:21  we7u
+
+	* src/: db.c, db.h, list_gui.c, main.c: Changed to
+	  dynamically-allocated linked list of comment strings in the
+	  station database.  This results in memory savings due to no empty
+	  strings being stored for stations without comment fields.  It
+	  also shows all status and comment strings that have been seen for
+	  each station now in the Station Info dialog.	We'll have loads of
+	  fun tracking MIC-E expansion on the internet servers now!
+
+2002-06-18 11:55  we7u
+
+	* src/draw_symbols.c: Simplifying the logic a bit.  Same general
+	  idea.
+
+2002-06-18 11:13  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c: Added "(tm)"
+	  everywhere "SmartBeaconing" was listed.
+
+2002-06-18 11:07  we7u
+
+	* AUTHORS, README.1ST: Notes and credit for the SmartBeaconing(tm)
+	  algorithm added.
+
+2002-06-18 10:58  we7u
+
+	* src/db.c: Changes to comments only.
+
+2002-06-18 10:35  we7u
+
+	* src/: db.c, draw_symbols.c: Changed they symbol time-since-heard
+	  color to white if over 24 hours.  Added a bunch of comments for
+	  SmartBeaconing.
+
+2002-06-17 16:16  we7u
+
+	* src/db.c: Minor comment change.
+
+2002-06-17 15:13  we7u
+
+	* src/: db.c, main.c: Commenting out debug printf's.  Changed some
+	  other comments.
+
+2002-06-17 14:40  we7u
+
+	* src/db.c: More comments.  Another tweak to SmartBeaconing:  If
+	  we've sped up a bit the code will now bring the next beacon in
+	  closer (in time), instead of waiting for the next slow beacon to
+	  reset to the slower interval.
+
+2002-06-17 14:16  we7u
+
+	* src/db.c: Added a few SmartBeaconing comments.
+
+2002-06-17 13:11  we7u
+
+	* src/: db.c, main.c: Another few SmartBeaconing tweaks.  Setting
+	  defaults for variables to prevent multiple beacons as we get
+	  started.
+
+2002-06-17 12:19  we7u
+
+	* src/: db.c, main.c: A few SmartBeaconing tweaks.  Commented out
+	  the experimental SmartBeaconing tweaks that caused a beacon when
+	  entering/exiting stop mode.  Changed how other SmartBeaconing
+	  math was done.
+
+2002-06-17 11:42  we7u
+
+	* src/draw_symbols.c: Added color-coding for time-since-last-heard
+	  display.  Green for 0-29 mins, Yellow for 30-59 minutes, Red for
+	  60 mins to infinity.	This is to help keep track of which
+	  stations are active and which haven't been heard for a while.
+
+2002-06-17 10:16  we7u
+
+	* src/db.c: Moved the "reversed symbol" message into a debug level.
+
+2002-06-14 17:19  we7u
+
+	* src/xa_config.c: Tweaking SmartBeaconing defaults to something
+	  more reasonable.
+
+2002-06-14 15:51  we7u
+
+	* src/xa_config.c: Saving SmartBeaconing parameters (all 7) in the
+	  config file.
+
+2002-06-14 15:28  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c, src/xa_config.c: Added
+	  Enable SmartBeaconing togglebutton, language strings for it, and
+	  save its state in the config file.  More to do.
+
+2002-06-14 14:15  we7u
+
+	* src/: db.c, main.c, main.h: The beginnings of SmartBeaconing
+	  support.  The working code is in there but the GUI interface is
+	  not coded yet.
+
+2002-06-14 10:58  we7u
+
+	* src/draw_symbols.c: Changed "time since last report" display to
+	  show "hr" and "min" based on time.
+
+2002-06-13 16:42  we7u
+
+	* src/db.c: Fix for compressed object/item comments getting eaten.
+
+2002-06-13 15:53  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/draw_symbols.c,
+	  src/draw_symbols.h, src/main.c, src/main.h, src/xa_config.c:
+	  Added "Display Last Report Time" option to stations menu.
+
+2002-06-13 14:07  we7u
+
+	* src/db.c: Final fix for trail expiring on active objects/items.
+
+2002-06-13 12:22  we7u
+
+	* src/db.c: Fixes which check for locally controlled object/item
+	  which has moved.  If it has, update the time-sorting of the
+	  record and update the timestamp in the station record.  This
+	  should fix the problem where an expired object, when moved, stays
+	  ghosted.
+
+2002-06-13 11:47  we7u
+
+	* src/messages_gui.c: Making Send Message dialog wide enough so
+	  that spec-compliant-length messages won't wrap to a new line.
+
+2002-06-13 11:21  we7u
+
+	* src/: alert.c, maps.c: Converting a few more snprintf's to
+	  xastir_snprintf's.  This change is necessary for those systems
+	  that don't have snprintf in their libraries.
+
+2002-06-12 17:12  we7u
+
+	* src/db.c: Added some notes regarding expiration of objects.
+
+2002-06-12 16:29  we7u
+
+	* src/: db.c, main.c, util.c: More fixes for compressed
+	  objects/items.  Speed/course seem to be working now.
+
+2002-06-12 16:23  we7u
+
+	* help/help-English.dat: Minor changes regarding compressed
+	  objects/items.
+
+2002-06-12 15:57  rzg
+
+	* help/help-English.dat: Updates wrt. compressed objects/posits,
+	  and satellite ack mode.
+
+2002-06-12 14:52  we7u
+
+	* src/: db.c, main.c, util.c: A few fixes for compressed position
+	  objects/items.  Adding course/speed to compressed objects/items
+	  as well.
+
+2002-06-10 17:08  we7u
+
+	* src/main.c: A minor tweak the position ambiguity togglebuttons
+	  having to do with switching compressed mode on and off.
+
+2002-06-10 16:52  we7u
+
+	* src/db.c: Disabling position ambiguity on receive end if a
+	  compressed posit is received for that station.
+
+2002-06-10 16:46  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/main.h,
+	  src/xa_config.c: Moved the compressed_posit togglebutton to the
+	  Configure->Station dialog.  Added a compress_objects_items
+	  togglebutton to the Configure->Defaults dialog.
+
+2002-06-10 15:02  we7u
+
+	* src/main.c: Fixes to give increased resolution for lat/lon when
+	  using compressed packets for objects/items.
+
+2002-06-10 14:43  we7u
+
+	* src/: db.c, util.c: Fixed compressed positions so that we can
+	  take advantage of the higher resolution.
+
+2002-06-08 12:05  n0vh
+
+	* src/xa_config.c: Added some missing #ifdef statements for
+	  tigermap data in the config file
+
+2002-06-07 18:34  we7u
+
+	* src/: db.c, main.c: Initial support for transmitting
+	  objects/items with compressed positions.  They're not displaying
+	  in the proper positions on the map yet though.
+
+2002-06-07 13:48  we7u
+
+	* src/interface.c: Added debugging into to interface.c.  Changed
+	  the way that we run through all interfaces when transmitting.
+
+2002-06-07 13:42  we7u
+
+	* src/util.c: Added support for lat/lon string conversions where we
+	  have more digits after the decimal point.
+
+2002-06-07 11:10  we7u
+
+	* src/: db.c, xastir.h: Bring up Locate Station window if an
+	  Emergency message is received.  The operator has a choice whether
+	  to center on the station or just dismiss the dialog.
+
+2002-06-07 09:48  n0vh
+
+	* src/main.c: Load Tigermaps prior to disk maps so disk maps can be
+	  overlayed if desired.
+
+2002-06-07 08:52  n0vh
+
+	* src/main.c: Disable all maps now also functions with new
+	  TigerMaps routines.
+
+2002-06-06 18:40  n0vh
+
+	* src/maps.c: More code cleanup in the tigermap section.  Still
+	  some optimizations to go.
+
+2002-06-06 18:12  n0vh
+
+	* src/xa_config.c: Updated to save the tiger_flag and
+	  tigermap_intensity in the users config file.
+
+2002-06-06 17:02  we7u
+
+	* src/db.c: Added a popup dialog for MIC-E emergency messages.
+	  Displays the callsign of the station in trouble.
+
+2002-06-06 15:03  we7u
+
+	* src/: messages.c, xa_config.c: Moved range checking for
+	  message_counter to xa_config.  More efficient.  Only needs to be
+	  done once when starting up.
+
+2002-06-06 14:45  we7u
+
+	* src/: messages.c, xa_config.c, xastir.h: Converted
+	  message_counter to a string.	Changed message sequence numbers to
+	  be 2 characters within this range: 0-9A-Za-z.  This prevents
+	  lockups when messaging with APRS+ stations.
+
+2002-06-06 14:43  we7u
+
+	* src/db.c: Removed old code.
+
+2002-06-06 11:00  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/db.c, src/main.c, src/xastir.h:
+	  Implemented satellite ack mode, where the Reply/Ack protocol is
+	  used to send ack's through satellites, and ack's like "ack001"
+	  are disabled entirely.
+
+2002-06-06 10:03  we7u
+
+	* src/: db.c, db.h, messages.c: Changes which implement full
+	  Reply/Ack protocol.  This should speed up messaging dramatically
+	  when involved in live QSO's with the APRS programs that support
+	  this protocol.  This lists currently includes aprsDOS, APRS+, and
+	  Xastir.
+
+2002-06-05 13:28  we7u
+
+	* src/: db.c, db.h, messages.c: Marking timed-out messages in Send
+	  Message dialog properly.  Small changes to Reply/Ack sequence
+	  numbers.
+
+2002-06-04 16:13  we7u
+
+	* src/: messages.c, xa_config.c: Switching to base-90 for message
+	  sequence numbers (all the way to lower-case 'z').  Also tweaked
+	  xa_config.c to help us avoid the message_counter rollover
+	  problem.
+
+2002-06-04 15:47  we7u
+
+	* src/messages.c: Changed from base-91 to base-89 format for
+	  message sequence numbers.  This is to avoid use of the '{'
+	  character within the sequence.
+
+2002-06-04 15:25  we7u
+
+	* src/messages.c: Converted outgoing sequence numbers to
+	  2-character base-91 encoding.  Added a trailing '}' character to
+	  signify that we're Reply-Ack protocol capable.
+
+2002-06-04 14:32  we7u
+
+	* src/messages.c: Had to take out the '}' from the sequence number
+	  as it messed things up.
+
+2002-06-04 14:20  we7u
+
+	* src/: db.c, messages.c: Message sequence numbers are saved
+	  through restarts now.  Added more comments.
+
+2002-06-04 13:27  we7u
+
+	* src/db.c: Changed several comments.  Decoding of Reply/Ack
+	  protocol (free-ride ACK's) is now tested and working.  This
+	  really speeds up live messaging.  When encoding of the free-ride
+	  ACK's is implemented as well it'll speed up messaging even more.
+
+2002-06-03 17:50  rzg
+
+	* README.1ST, help/help-English.dat: Updates for tigermap changes
+	  and minor bits I missed in the previous update.
+
+2002-06-03 13:30  we7u
+
+	* src/db.c: Minor changes to Reply/Ack's.
+
+2002-06-03 13:14  we7u
+
+	* src/db.c: The beginnings of Reply/Ack protocol decode.  Not fully
+	  tested.  Encode not implemented yet.
+
+2002-06-03 09:45  francais1
+
+	* src/maps.c: Fixed up imagemagick_options struct a bit.  Removed
+	  some imagemagick_options stuff from draw_tiger_map because it is
+	  not being setup since there is no .geo file.	Fixed
+	  draw_tiger_map intensity/levels bug.
+
+2002-06-03 09:21  we7u
+
+	* src/maps.c: Changing some line widths and colors back to what we
+	  had before the weekend.  We're not trying to duplicate the
+	  TigerMap servers colors or look-and-feel.  We need more subdued
+	  colors so that symbols and tracks show up better on top of the
+	  maps.  The line widths are necessary in order to more quickly
+	  identify major roads without having to rely only on color.
+
+2002-06-03 09:18  francais1
+
+	* src/maps.c: Removed extraneous ifdef
+
+2002-06-03 08:38  we7u
+
+	* src/gps.c: Fixes for decoding GPS NMEA sentences where there are
+	  4 digits after the decimal point.  Garmin GPS-35 and the NavMan
+	  both put out an extra digit.
+
+2002-06-03 07:59  we7u
+
+	* src/main.c: Fixed segfault bug in Config_tiger.
+
+2002-06-03 07:23  we7u
+
+	* src/maps.c: Added another #ifdef around a LevelImage() call.
+
+2002-06-02 14:59  n0vh
+
+	* config/language-English.sys, config/language-French.sys,
+	  config/language-German.sys, config/language-Italian.sys,
+	  config/language-Portuguese.sys, config/language-Spanish.sys,
+	  src/main.c, src/main.h, src/maps.c, src/xastir.h: Made more
+	  updates to support tigermap menu item.  A file is no longer
+	  required.  Also, I made display of tigermaps a separate
+	  subroutine.  This should probably be done with some of the other
+	  items in draw_geo_image_map as well.	N0VH
+
+2002-06-02 14:54  n0vh
+
+	* config/language-Dutch.sys: Made more updates to support tigermap
+	  menu item.  A file is no longer required.  Also, I made display
+	  of tigermaps a separate subroutine.  This should probably be done
+	  with some of the other items in draw_geo_image_map as well.  N0VH
+
+2002-06-01 12:00  n0vh
+
+	* src/: main.c, maps.c: Added Tigermap menu support.
+
+2002-06-01 11:59  n0vh
+
+	* src/xastir.h: Added some external vars to support Tigermap menus.
+
+2002-06-01 11:54  n0vh
+
+	* config/language-Spanish.sys: Added items to support Tigermap
+	  menus.
+
+2002-06-01 11:52  n0vh
+
+	* config/language-Italian.sys: Added items to support Tigermap
+	  menu.
+
+2002-06-01 11:50  n0vh
+
+	* config/: language-French.sys, language-German.sys,
+	  language-Portuguese.sys: Added items to support Tigermap menus.
+
+2002-06-01 11:49  n0vh
+
+	* config/language-English.sys: Added items to support Tigermap
+	  configuration menus.
+
+2002-06-01 11:47  n0vh
+
+	* config/language-Dutch.sys: Added new lines to support the
+	  Tigermap configuration menus.
+
+2002-06-01 11:46  n0vh
+
+	* README.1ST: Removed reference to putting TIGERMAP in a .geo file
+	  which no longer works.
+
+2002-05-31 17:32  we7u
+
+	* src/db.c: Initial attempt to handle Reply/Ack messaging protocol
+	  (on the receive side only).  Only implemented for APRS messaging,
+	  not UI-View messaging.
+
+2002-05-31 14:24  we7u
+
+	* src/db.c: Fixes for last_ack timer.  We now refuse to send ack's
+	  or auto_answer messages any faster than every 30 seconds, even if
+	  multiple interfaces are sending us copies of the same message.
+
+2002-05-31 12:36  we7u
+
+	* src/maps.c: Simplified the print properties dialog.	Commented
+	  out unused options.
+
+2002-05-30 08:04  n0vh
+
+	* src/igate.c: More cleanup of the status messages written to the
+	  console.
+
+2002-05-29 21:32  n0vh
+
+	* src/igate.c: Cleaned up some of the status messages by adding a
+	  newline to the end.
+
+2002-05-29 17:07  francais1
+
+	* src/maps.c: Imagemagick drawing speedup for some cases.
+
+2002-05-29 16:59  francais1
+
+	* src/: util.c, util.h: Added a simple function to roughly time
+	  code execution.
+
+2002-05-28 09:48  we7u
+
+	* src/xa_config.c: Patch for incorrect lat/long limits by Henk de
+	  Groot, PE1DNN.  Thanks Henk!
+
+2002-05-24 17:07  we7u
+
+	* src/: db.c, db.h: Attempting to get rid of duplicate ack's and
+	  autoreply messages.  This attempt is at least partially
+	  successful.
+
+2002-05-24 15:01  we7u
+
+	* src/: db.c, util.c: Fixed spelling error in util.c.  Fixes for
+	  incorrect sorting in Send Message window for the case where the
+	  remote client has restarted and is re-using sequence numbers:
+	  Xastir will now replace the older messages in the database and
+	  update the timestamp, which keeps the proper ordering for a QSO.
+	  Messages older than 8 hours with the same text will also get
+	  replaced and get a new timestamp.
+
+2002-05-22 14:05  we7u
+
+	* src/: gps.c, interface.c, interface_gui.c, xa_config.c: Mods for
+	  CYGWIN by Charles Suprin, AA1VS.
+
+2002-05-21 14:33  we7u
+
+	* src/db.c: Getting rid of unneeded extra message_update() calls.
+
+2002-05-21 12:27  we7u
+
+	* src/db.c: More messaging fixes.
+
+2002-05-21 12:02  we7u
+
+	* src/: messages_gui.c, db.c: Fixes for text corruption in Send
+	  Message window.  Needs further testing.
+
+2002-05-21 10:19  we7u
+
+	* src/: util.c, view_message_gui.c: Fixing distance calculation
+	  such that it returns 0.0 if we haven't heard a posit from the
+	  remote station yet.
+
+2002-05-21 09:18  we7u
+
+	* src/view_message_gui.c: View->Messages history dump now obeys the
+	  distance limit set at the top of the form.
+
+2002-05-20 14:49  we7u
+
+	* src/: view_message_gui.c, xa_config.c: We now dump all currently
+	  active messages out to the view->messages window when it's first
+	  opened.  Different format, but still useful.	The format is
+	  easily tweaked later.  Also changed the default
+	  VIEW_MESSAGE_LIMIT to 10000.	This can be tweaked by the user in
+	  the ~/.xastir/xastir.cnf file.  Max allowed by the code is now
+	  99999.
+
+2002-05-18 00:06  kd6zwr
+
+	* src/maps.c: Draw symbols for GNIS files.
+
+2002-05-17 16:55  we7u
+
+	* src/interface.c: Temporary fix for CYGWIN.  Disables use of HSP
+	  adapter.  Better fix needs to be implemented.
+
+2002-05-17 16:52  we7u
+
+	* src/interface_gui.c: Mods for CYGWIN.
+
+2002-05-17 15:56  we7u
+
+	* src/: main.c, messages_gui.c: Added <Enter> as another method to
+	  send a message in the Send Message dialog.
+
+2002-05-17 15:26  we7u
+
+	* src/db.c: Quick check for a zero time in the message database.
+	  If found, fill in with current time and print out a warning.
+
+2002-05-17 14:14  we7u
+
+	* src/db.c: Only cause a Send Message dialog update on the first
+	  ack.	Subsequent ack's cause no update.
+
+2002-05-17 11:37  we7u
+
+	* src/db.c: Update message windows only when the first message or
+	  the first ack comes in, or when the message doesn't match the
+	  same sequence number message already stored.	This helps to
+	  reduce flashing of the messages windows due to multiple copies of
+	  ack's/messages being received.
+
+2002-05-17 00:01  we7u
+
+	* src/db.c: Changes to eliminate dupes in Send Message dialog.
+	  Also changes to keep the message sequence more normal.
+
+2002-05-16 16:29  we7u
+
+	* src/: db.c, interface.c: Fixes for reverse video instantly on
+	  sending a message, before it's acked.
+
+2002-05-16 15:35  we7u
+
+	* src/db.c: Messaging fixes.  Outstanding packets are now reverse
+	  video.
+
+2002-05-16 14:47  we7u
+
+	* src/: db.c, db.h, messages.c: The start of visual indicators for
+	  unacked messages.  Not completely working yet, but doesn't break
+	  functionality either.
+
+2002-05-16 09:38  we7u
+
+	* src/: gps.c, interface_gui.c: Fixes for Mac OS X (no strptime
+	  call), and for non-linux systems.  The "Set System Clock from GPS
+	  Data?" togglebutton should be grey'ed out now for non-linux
+	  systems.
+
+2002-05-14 20:26  rzg
+
+	* help/help-English.dat: Updated/rewrote .geo section for n7tap's
+	  new additions.
+
+2002-05-14 11:56  francais1
+
+	* src/maps.c: Backed out previous change.
+
+2002-05-14 09:56  n0vh
+
+	* src/maps.c: [no log message]
+
+2002-05-10 17:22  we7u
+
+	* src/messages_gui.c: Allowing multiple messages to be queued up
+	  without having to wait for an ack for each one.
+
+2002-05-10 17:21  we7u
+
+	* src/messages.c: Allowing multiple messages to get queued up
+	  without having to wait for an ack for each one.
+
+2002-05-10 17:20  we7u
+
+	* src/db.c: Reformatted one line.  No code changes.
+
+2002-05-10 15:50  we7u
+
+	* src/: messages.c, messages.h: Slightly better timing of
+	  messaging.  Also free's up the queue after a message times out.
+	  More work to be done.
+
+2002-05-10 15:22  we7u
+
+	* src/db.c: Added some notes about a bug in messaging.
+
+2002-05-10 08:08  francais1
+
+	* src/main.c: Added a missing if defined HAVE_IMAGEMAGICK
+
+2002-05-09 22:59  we7u
+
+	* src/: db.c, main.c, messages.c, messages_gui.c: Messaging in the
+	  Send Message dialog are now sorted by time.  The window is also
+	  resizable now in both directions.  The 5-second update of the
+	  window has been replaced by code which updates the window
+	  whenever new messages arrive.
+
+2002-05-09 16:34  francais1
+
+	* src/maps.c: Fixes for older imagemagick versions.
+
+2002-05-09 15:29  francais1
+
+	* src/: color.c, color.h, main.c, maps.c, maps.h, xa_config.c: Sped
+	  up drawing of DirectColor images on a DirectColor screen.  It was
+	  very slow because it called XAllocColor for every pixel in a
+	  jpeg.  It now uses saved information on the default display
+	  visual to pack the RGB into the correct bits for the pixel.  I
+	  did this because I was finding some nasty color effects with the
+	  image intensity settings.  I decided to leave image intensity
+	  around for geotiffs, but now use gamma correction from
+	  Imagemagick for all other image formats that go through
+	  imagemagick.	There can now be a gamma setting in each .geo file
+	  and there is an overall adjustment which will subtract or add to
+	  the individual image gamma.  While I was at it, I enabled the
+	  ability to specify several of the imagemagick enhancement
+	  functions in .geo files.
+
+2002-05-09 14:31  we7u
+
+	* src/main.c: Filling the drawing area with grey right away.  Gets
+	  rid of garbage that shows up on the screen sometimes when
+	  starting Xastir.
+
+2002-05-09 13:28  we7u
+
+	* xastir.spec.in, scripts/Makefile.am, scripts/Makefile.in: Tweaks
+	  to make the appropriate scripts get installed in /usr/local/bin,
+	  with the appropriate execute permissions.
+
+2002-05-09 13:07  we7u
+
+	* help/help-English.dat: Correcting spelling of "finger".
+
+2002-05-09 13:04  we7u
+
+	* Makefile.am, Makefile.in: Adding the scripts directory as a
+	  target of the Makefiles.
+
+2002-05-09 12:58  rzg
+
+	* README, README.1ST, help/help-English.dat: Assorted helpfile
+	  updates: point shapefiles, weather stipples, and random work on
+	  README.
+
+2002-05-09 12:55  rzg
+
+	* FAQ: Changes "XASTIR" to "Xastir" to match other docs.
+
+2002-05-09 12:34  we7u
+
+	* configure, configure.in, xastir.spec.in: Tweaks to install
+	  scripts into /usr/local/xastir/script/ directory.
+
+2002-05-09 12:33  we7u
+
+	* scripts/: Makefile.am, Makefile.in: Adding Makefiles to install
+	  scripts into /usr/local/xastir/scripts/ directory.
+
+2002-05-08 13:52  we7u
+
+	* scripts/waypoint-get.pl: Here's the companion script to
+	  track-get.pl.  This one will snag all of the waypoints out of a
+	  Garmin GPS and create an APRS item out of each one.  The
+	  resulting file can be read in by Xastir as a log file to make the
+	  waypoints appear on the map screen.
+
+2002-05-08 12:48  we7u
+
+	* scripts/track-get.pl: Added another message at the end.
+
+2002-05-08 12:38  we7u
+
+	* src/: db.c, main.c, main.h: Fixes for some compiler warnings, by
+	  Chris Bell, KD6ZWR.
+
+2002-05-08 12:04  we7u
+
+	* scripts/track-get.pl: New Perl script which can fetch the
+	  tracklog from a Garmin GPS, then create a log file which can be
+	  read by Xastir.  Read in the log file and you'll have a track on
+	  Xastir's map screen.	Needs tweaks to Xastir in order to view
+	  more than 100 points of the track at a time.
+
+2002-05-07 22:45  we7u
+
+	* src/maps.c: GNIS code fixes by Chris Bell, KD6ZWR.
+
+2002-05-07 11:40  we7u
+
+	* src/: main.c, maps.h: Xastir will now do a PNG snapshot every
+	  time the "Enable PNG Snapshots" button is re-enabled.  This beats
+	  waiting 5 minutes for the next snapshot while you're
+	  experimenting with things.
+
+2002-05-06 22:19  we7u
+
+	* src/maps.c: First implementation of Point-type Shapefiles.  Seems
+	  to work fine so far.
+
+2002-05-06 16:04  we7u
+
+	* src/db.c: Reformatting a warning message to make sure that we
+	  only output printable chars to STDOUT.
+
+2002-05-06 15:01  we7u
+
+	* src/: db.c, util.c: Fixes for AEA formatted headers.	They now
+	  should get converted properly to TAPR-2 style headers.  What was
+	  missing was the re-arranging of the callsigns in the header to
+	  the correct order.
+
+2002-05-05 17:53  we7u
+
+	* src/maps.c: Changing default color for pedestrian trails, used if
+	  later code doesn't set the color explicitly.
+
+2002-05-04 09:55  we7u
+
+	* src/xa_config.c: Another tweak to limits checking.
+
+2002-05-03 22:38  we7u
+
+	* src/xa_config.c: Tweaking the value limits for list window sizes.
+
+2002-05-03 16:52  we7u
+
+	* src/maps.c: Fixing a segfault for non Tiger-based Shapefiles
+	  (like the NOAA interstates file).
+
+2002-05-03 15:58  we7u
+
+	* src/maps.c: Fix for incorrect line colors at times for
+	  Shapefiles.  We also make city borders narrower as we zoom out.
+
+2002-05-03 15:16  francais1
+
+	* src/list_gui.c: Added mouse scroll wheel support to list dialogs.
+	  Uses standard button4/5 method no modifier moves 2 lines shift
+	  moves 1 line control moves 10 lines
+
+2002-05-03 13:52  we7u
+
+	* src/maps.c: Changing colors of cities and borders around/between
+	  cities.
+
+2002-05-03 12:28  we7u
+
+	* src/maps.c: More subdued colors for the major roads.	Cranked the
+	  width down a bit too.
+
+2002-05-03 12:14  we7u
+
+	* src/maps.c: Setting up more default colors.  Pedestrian trails
+	  are now red.	Dashed lines for trails, 4WD roads, ferry
+	  crossings.  Glaciers are now white.
+
+2002-05-03 10:22  we7u
+
+	* src/maps.c: Getting rid of compiler warning by adding "color.h"
+	  as an include file.  This is needed for the GetPixelByName() call
+	  I added.
+
+2002-05-03 09:57  we7u
+
+	* src/maps.c: Cleaning up properly with warning message for Point
+	  and Multipoint Shapefiles, which aren't implemented yet in
+	  Xastir.
+
+2002-05-02 16:53  we7u
+
+	* src/maps.c: This ones for Ken:  Download and select plc00 files
+	  from GeographyNetwork to get the "designated places" boundaries
+	  filled in with PaleGoldenrod color.  The code will also label
+	  these areas.	Create the following subdirectories to get the
+	  layering right:
+
+	      county (cty00)
+	      designated_places (plc00)
+	      h2o (lkH and wat)
+	      misc (lkC)
+	      rail (lkB)
+	      roads (lkA)
+
+2002-05-02 14:25  we7u
+
+	* src/maps.c: Changing water back to Steel Blue.
+
+2002-05-02 13:58  we7u
+
+	* src/maps.c: More comments.  Shortened another string "State
+	  Route" to "State" that occurs in the ESRI Tiger/Line Shapefiles.
+	  Changed the county polygon back to gray so that tracks show up
+	  better.
+
+2002-05-02 12:28  we7u
+
+	* src/maps.c: Added comments.  Made some optimizations in the
+	  Shapefile code.  Shortened some labels that get drawn.
+
+2002-05-01 20:28  rzg
+
+	* README.1ST: Update to README.1ST with more shapefile locations
+	  and other minor edits.
+
+2002-05-01 15:43  we7u
+
+	* src/maps.c: Changing how many labels appear at certain zoom
+	  levels with Shapefiles.
+
+2002-05-01 15:12  we7u
+
+	* src/maps.c: Optimization: Only doing floating point operations
+	  for label rotation when we know we're going to be drawing the
+	  label.  Changes by Chris Bell to help alleviate upside-down
+	  labels.
+
+2002-05-01 14:23  we7u
+
+	* src/maps.c: Rotated labels for Shapefile maps.  This be a good
+	  thing!
+
+2002-05-01 12:11  we7u
+
+	* src/maps.c: Better label drawing.  Quantities of identical labels
+	  drawn in the viewport are now determined by zoom level.
+
+2002-04-30 17:08  we7u
+
+	* src/db.c: Fixing directed query responses.  They now show up in a
+	  popup window.
+
+2002-04-30 15:53  we7u
+
+	* src/: main.c, xa_config.c, xa_config.h: get_int() and get_long()
+	  now check for min/max values, and assign a default value if the
+	  number is outside this range.  Also prints a warning message if
+	  it has to assign the default.
+
+2002-04-30 13:50  we7u
+
+	* src/maps.c: Changing the levels at which smaller roads and labels
+	  for those roads get drawn.  All roads are drawn at zoom 64 and
+	  lower.  Labels for small roads start showing up at zoom 16 and
+	  lower.
+
+2002-04-30 11:57  we7u
+
+	* src/maps.c: Converting back to "convert" without path until we
+	  get configure support for figuring out the path.
+
+2002-04-30 11:31  we7u
+
+	* src/maps.c: Adding another path to convert.
+
+2002-04-30 11:30  we7u
+
+	* src/maps.c: Added path to "convert" command.	Added checks around
+	  system() command.
+
+2002-04-29 17:02  we7u
+
+	* src/maps.c: Fixed some conversion problems when converting to
+	  screen coordinate system.
+
+2002-04-29 10:40  we7u
+
+	* src/maps.c: Implemented map levels for the Shapefile code.  The
+	  togglebutton in the Maps menu now works for Shapefiles.
+
+2002-04-27 16:47  we7u
+
+	* src/maps.c: Setting up more zoom levels for Shapefile roads.
+
+2002-04-27 16:03  we7u
+
+	* src/maps.c: Created linked list for Shapelib labels already
+	  drawn.  Keeps us from drawing 50 labels that all say the same
+	  thing.  Added some zoom levels for labels of various types.
+
+2002-04-27 12:52  we7u
+
+	* src/maps.c: Getting rid of lesser roads at zoom levels 100 and
+	  above.
+
+2002-04-27 07:59  we7u
+
+	* src/maps.c: Reducing the width of water until I can figure out
+	  how Tigermap decided to determine their width.
+
+2002-04-26 23:39  we7u
+
+	* src/maps.c: A few color & width changes for shapefile maps.
+
+2002-04-26 16:51  we7u
+
+	* src/maps.c: Setting number of lanes (line width) for Tiger and
+	  Mapshots maps.
+
+2002-04-26 11:27  we7u
+
+	* src/maps.c: Changed paths to a brown color.
+
+2002-04-26 11:14  we7u
+
+	* src/maps.c: Corrected some of the headings.  Split railroads out
+	  as a separate flag and a new color.
+
+2002-04-26 10:16  we7u
+
+	* src/: main.c, main.h, xa_config.c: Created a #define in main.h
+	  for enabling/disabling the "Transmit Raw WX data" togglebutton.
+	  The #define enabling this button is commented out.  Most likely
+	  the only people interested in this button would be people
+	  debugging code for certain Peet Bros. weather stations where the
+	  raw data from them is allowed over the air by the APRS spec.
+
+2002-04-26 08:53  francais1
+
+	* src/: main.c, maps.h, xa_config.c: Make map intensity menu show
+	  up in the correct cases.
+
+2002-04-26 08:50  francais1
+
+	* src/maps.c: Make GNIS labels more readable
+
+2002-04-25 16:04  we7u
+
+	* src/maps.c: Fixing up mapshots maps for rivers/lakes.  Also being
+	  proactive in trying to eliminate possible future segfaults in the
+	  Shapelib code.
+
+2002-04-25 14:23  we7u
+
+	* src/maps.c: Label fix for mapshots.com roads.
+
+2002-04-25 13:18  we7u
+
+	* src/maps.c: Changed fill color for land masses from darkgray to
+	  grey73 (a bit lighter, and the same color as the menus).
+
+2002-04-25 11:56  we7u
+
+	* src/maps.c: Added shapefile decoding of colors/types for
+	  mapshots.com county maps made from tiger data.
+
+2002-04-25 10:52  we7u
+
+	* src/maps.c: Added some comments.
+
+2002-04-25 00:00  we7u
+
+	* src/: maps.c, maps.h: Fixes for Shapefile segfaults:	Can't
+	  retrieve a field that's higher than fieldcount, else segfault.
+
+2002-04-24 16:00  we7u
+
+	* src/: maps.c, maps.h: Fix for segfaults in Shapefiles.
+
+2002-04-24 15:23  francais1
+
+	* src/maps.c: Tweaked some color problems with turning labels on.
+	  Tweaked river drawing slightly.
+
+2002-04-24 15:09  francais1
+
+	* src/maps.c: Made gnis map files draw regardless of the labels
+	  setting since a gnis map is all labels, so if you picked it, you
+	  want it drawn, period.
+
+2002-04-24 14:23  we7u
+
+	* src/maps.c: Adding missing free() calls in draw_shapefile_map().
+
+2002-04-24 13:06  we7u
+
+	* src/maps.c: Fixing segfault problem with Shapefile maps.
+
+2002-04-24 11:28  francais1
+
+	* src/maps.c: IMHO, I've improved the guessing of what shapefile we
+	  are dealing with and also the drawing colors and style...
+
+2002-04-24 11:24  francais1
+
+	* src/: draw_symbols.c, main.c, xastir.h: Changed name of
+	  pixmap_stipple to pixmap_2x2_stipple and made it load from an xbm
+
+2002-04-24 11:23  we7u
+
+	* src/maps.c: Minor change to get rid of compiler warning.  Changed
+	  static variable to non-static.
+
+2002-04-24 11:08  francais1
+
+	* symbols/: 2x2.xbm, Makefile.am, Makefile.in: Added bitmap for 50%
+	  stipple
+
+2002-04-24 10:51  francais1
+
+	* src/: util.c, util.h: A couple new functions that will be useful
+	  for UTM grid
+
+2002-04-24 10:50  francais1
+
+	* src/main.c: Added SteelBlue for drawing lakes, rivers (plain blue
+	  seemed pretty harsh and SteelBlue is a background color as well,
+	  so that it can be the ocean)
+
+2002-04-24 09:58  we7u
+
+	* src/xa_config.c: Commented out annoying debug statements that get
+	  in the way each time.
+
+2002-04-24 09:54  we7u
+
+	* src/: alert.h, maps.c: Speedups for weather alerts.  Once we know
+	  what the bounding rectangle is for an alert, we stuff it into the
+	  alert struct.  load_alert_maps() then uses that info to determine
+	  whether a shape is within the viewport, without having to snag
+	  that info from the Shapefile each time.
+
+2002-04-24 09:20  we7u
+
+	* src/maps.c: Removed old code.  Put in warning printf for old
+	  weather alert stuff in routine that doesn't handle it anymore.
+	  Changed some comments.
+
+2002-04-24 08:41  francais1
+
+	* src/maps.c: Added equator and central meridian drawing as a black
+	  line when a grid is asked for.  Teasing for utm grid drawing.
+
+2002-04-24 01:06  we7u
+
+	* src/: alert.c, alert.h, maps.c: Added "index" field to alert
+	  records, initially set to -1.  This gets filled in with the index
+	  into the Shapefile when the shape is searched for.  This
+	  dramatically speeds up drawing of weather alerts 'cuz the search
+	  is skipped on the 2nd and later uses of the alert.
+
+2002-04-23 23:03  francais1
+
+	* src/: main.c, maps.c, xastir.h: Initial support for using
+	  stipples for weather alerts with a description of the alert
+	  event.
+
+2002-04-23 22:57  francais1
+
+	* symbols/: Makefile.am, Makefile.in, alert.xbm, flood.xbm,
+	  snow.xbm, tornado.xbm, wind.xbm, winter_wx.xbm, wntr_strm.xbm:
+	  Added bitmap files for use as weather map stipples
+
+2002-04-23 22:08  francais1
+
+	* src/maps.c: Fixed indentation
+
+2002-04-23 17:01  we7u
+
+	* src/wx_gui.c: Detailed weather alerts now show up in their own
+	  resizable dialog.
+
+2002-04-23 16:39  francais1
+
+	* src/main.c: Added support for zooming in and out with buttons 6 &
+	  7 and for panning up and down with the scroll wheel.
+
+2002-04-23 00:31  we7u
+
+	* src/: alert.c, wx_gui.c: Cleaning up some debug messages I put in
+	  for the weather alert code.
+
+2002-04-22 23:32  we7u
+
+	* src/wx_gui.c: Added the capability to finger the weather server
+	  by double-clicking on a weather alert line in the View->Weather
+	  Alerts dialog.  The output currently appears in the xterm that
+	  you start Xastir from.
+
+2002-04-22 23:14  we7u
+
+	* src/wx_gui.c: Changed View->Weather Alerts dialog to
+	  single-select mode.  Added a callback and callback function for
+	  the double-click operation.
+
+2002-04-22 22:46  we7u
+
+	* src/wx_gui.c: Changed View->Weather Alerts dialog so that it can
+	  be resized.
+
+2002-04-22 22:16  we7u
+
+	* src/: alert.c, alert.h, db.c, wx_gui.c: Decoded SKY alerts.  They
+	  now get associated with the proper weather alert packets.
+	  Tweaked View->Weather Alerts dialog to display them properly and
+	  added a horizontal scrollbar to that dialog.
+
+2002-04-22 17:03  rzg
+
+	* FAQ:
+	  Fixed the numbering....
+
+2002-04-22 16:57  rzg
+
+	* FAQ, README.1ST, help/help-English.dat:
+	  Updates to FAQ, README.1ST. and help=English.dat, mostly with
+	  regard to the weather alert changeover to shapefile format.
+
+2002-04-22 14:08  we7u
+
+	* src/alert.c: Fix to weather alerts.  Expired alerts will now be
+	  removed from the View->Weather Alert dialog after they've been
+	  expired more than one hour.
+
+2002-04-22 09:57  we7u
+
+	* src/alert.c: The start of adding "CIVIL" as another weather
+	  alert.  Not completely functional yet.  Also added more of Dale
+	  Hugueley's comments.
+
+2002-04-22 09:47  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+	  Thanks!
+
+2002-04-20 21:26  we7u
+
+	* src/db.c: Slight reformatting.
+
+2002-04-20 15:13  we7u
+
+	* src/alert.c: Took out last patch.  New alerts will now create a
+	  new entry, even if there is a cancel with the same zone that was
+	  received earlier.
+
+2002-04-20 12:23  we7u
+
+	* src/maps.c: Fix for changing line widths on shapefile maps.
+
+2002-04-20 10:48  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+	  Thanks!
+
+2002-04-20 10:34  we7u
+
+	* README.1ST: Updated the APRS Server list.
+
+2002-04-19 21:16  we7u
+
+	* src/: alert.c, maps.c: Fixes for weather alerts.  CANCL packets
+	  are starting to work now.
+
+2002-04-19 16:27  we7u
+
+	* src/: alert.c, alert.h, maps.c: Changed global variable
+	  "alert_tag" to "alert_status" so that it won't be confused with
+	  the alert struct "alert_tag" field.  Added loads of comments.
+
+2002-04-19 13:58  we7u
+
+	* src/alert.c: More comments.
+
+2002-04-19 12:30  we7u
+
+	* src/alert.c: Updated some comments.
+
+2002-04-19 09:29  we7u
+
+	* src/wx_gui.c: Slight reformatting of View->Weather Alerts dialog.
+
+2002-04-19 00:11  we7u
+
+	* src/wx_gui.c: Reformatted View->Weather Alerts dialog slightly:
+	  Shorter lines and easier to read.
+
+2002-04-18 23:42  we7u
+
+	* src/: alert.c, alert.h, wx_gui.c: Added issue date/time to
+	  weather alerts and View->Weather Alerts dialog.
+
+2002-04-18 21:42  we7u
+
+	* xastir.1: Minor tweaks to eliminate redundancy, shorten the
+	  copyright years, make the words flow better.
+
+2002-04-18 17:38  rzg
+
+	* xastir.1:
+	  Minor formatting changes to look more manpage-like.
+
+2002-04-18 16:39  we7u
+
+	* src/maps.c: Speedup for weather alerts.  Skip searching through
+	  Shapefiles if we already have a filename for the alert.
+
+2002-04-18 15:59  we7u
+
+	* xastir.1: Added the "-i" flag (private colormap) to the man page.
+
+2002-04-18 15:46  francais1
+
+	* src/: main.c, maps.c: I don't believe we need to check if it is a
+	  symbolic link when we use stat, because it will follow the link.
+
+2002-04-18 15:28  we7u
+
+	* src/: color.c, db.c, main.c, maps.c, xa_config.c, xastir.h:
+	  Private colormap changes by Chris Bell, KD6ZWR.  Change to
+	  weather alert timing by WE7U.
+
+2002-04-18 12:58  we7u
+
+	* config/language-Portuguese.sys: Changes by David Quental, CT1DRB.
+
+2002-04-18 09:11  we7u
+
+	* src/maps.c: Corrected some comments.	Corrected some filename
+	  prefixes.  Added the capability to use symbolic linked files as
+	  weather alerts (I think, not fully tested yet).
+
+2002-04-18 09:10  we7u
+
+	* src/wx_gui.c: Added "Expired:" tag to expired weather alerts in
+	  the View->Weather Alerts dialog.
+
+2002-04-18 09:09  we7u
+
+	* src/main.c: Added the capability to read symbolic links as maps
+	  (I think).  Not fully tested yet.
+
+2002-04-18 09:08  we7u
+
+	* src/alert.c: Added some comments.
+
+2002-04-17 16:57  we7u
+
+	* src/alert.c: Changed some comments.
+
+2002-04-17 16:48  we7u
+
+	* src/: alert.c, main.c, maps.c, xa_config.c: More weather alert
+	  tweaks, including the beginning of compressed weather alert
+	  decoding.
+
+2002-04-17 13:58  we7u
+
+	* src/wx_gui.c: Reformatted weather alert expire date/time in
+	  View->Weather Alerts dialog.
+
+2002-04-17 13:52  we7u
+
+	* src/: alert.c, wx_gui.c: Fixed parsing problem for weather alerts
+	  where objects after a space were being parsed as new alerts.
+
+2002-04-17 12:58  we7u
+
+	* src/: alert.c, alert.h, db.c, wx_gui.c: Changing View->Weather
+	  Alerts dialog so that it displays the data we'll need for
+	  fingering the weather server to get additional data about a
+	  particular alert.
+
+2002-04-17 11:36  we7u
+
+	* src/maps.c: Fix for weather alerts disappearing at different zoom
+	  levels or while panning around.  The problem had to do with the
+	  alert getting marked as being outside the viewport, then they
+	  wouldn't be looked at again.
+
+2002-04-16 18:02  we7u
+
+	* src/maps.c: closedir() to go with the opendir().  ;-)
+
+2002-04-16 16:17  we7u
+
+	* src/maps.c: Fixes for "too many open files" in shapefile weather
+	  alerts.
+
+2002-04-16 14:16  we7u
+
+	* src/: alert.c, db.c, maps.c: Fixes to regular shapefile maps.
+	  Cleanup after shapefile weather alert additions.
+
+2002-04-16 12:44  we7u
+
+	* src/maps.c: Fixes for county weather warning alerts.
+
+2002-04-16 11:34  we7u
+
+	* src/: alert.c, maps.c, xa_config.c: Shapefile wx alert changes.
+	  Starting to work for zones.  More work to do on other types.
+
+2002-04-16 09:17  we7u
+
+	* src/maps.c: Fix for Shapefile weather alerts.  Nearly there now.
+
+2002-04-16 02:19  we7u
+
+	* src/maps.c: More shapefile wx alert changes.
+
+2002-04-16 01:03  we7u
+
+	* src/maps.c: More weather alert shapefile coding done.
+
+2002-04-15 21:30  we7u
+
+	* src/maps.c: We now figure out the complete filename starting with
+	  the first few characters of the shapefile.  We look in the
+	  directory to figure out a match for the zone.  This should make
+	  it so that we can update the shapefiles at any time and won't
+	  have to change any configuration or code in order to use the new
+	  files.
+
+2002-04-15 20:30  we7u
+
+	* src/maps.c: Initial decoding for the different types of weather
+	  alerts.  Soon we'll be able to match up real filenames to the
+	  zones and start drawing them.
+
+2002-04-15 17:07  we7u
+
+	* src/maps.c: Added some more comments.
+
+2002-04-15 16:04  we7u
+
+	* src/: alert.c, db.c, maps.c: I'm breaking the weather alerts by
+	  checking in this code, but have tagged the "stable" repository
+	  with a "we7u-safe" tag, so we can recover if things get broken
+	  too badly.  Forward we go!
+
+	  I've also released xastir-1.1.2 in the development area of the
+	  Files section on SourceForge.  That is the "we7u-safe" tagged
+	  version of the sources.
+
+2002-04-12 15:49  we7u
+
+	* src/wx.c: Changing to capital 'X' for the weather-station-type
+	  designator in our transmitted weather reports, per Bob Bruninga's
+	  ok on the APRSSPEC mailing list, 04/12/2002.
+
+2002-04-12 14:50  we7u
+
+	* src/maps.c: Shapefile wx alert small changes.  We're not there
+	  yet.
+
+2002-04-12 12:50  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Portuguese.sys, language-Spanish.sys: Tweaked one popup
+	  message.
+
+2002-04-12 11:11  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: We now allow four
+	  different symbols for weather stations, but print a warning if
+	  trying to use an NWS symbol.	If trying to run a weather station
+	  with a different symbol, the software will set the symbol to the
+	  standard weather symbol automatically.
+
+2002-04-11 23:04  we7u
+
+	* src/alert.c: Changed some comments.
+
+2002-04-11 16:02  we7u
+
+	* src/alert.c: More comments.
+
+2002-04-11 14:49  we7u
+
+	* src/alert.c: More comments.
+
+2002-04-11 12:58  we7u
+
+	* src/alert.c: Changed a comment.
+
+2002-04-11 12:58  we7u
+
+	* src/alert.c: Changed some comments.
+
+2002-04-11 12:53  we7u
+
+	* src/alert.c: More comments.
+
+2002-04-11 12:52  we7u
+
+	* src/alert.c: More comments added.
+
+2002-04-11 12:46  we7u
+
+	* src/alert.c: More comments added.
+
+2002-04-11 12:01  we7u
+
+	* src/alert.c: More comments.
+
+2002-04-11 11:40  we7u
+
+	* src/alert.c: More comments.
+
+2002-04-11 11:27  we7u
+
+	* src/alert.c: Reformatted some of the code, added comments.
+	  Preparing for Shapefile weather alert coding.
+
+2002-04-11 10:13  we7u
+
+	* src/alert.c: Fixed possible string overrun.  Added a few
+	  comments.
+
+2002-04-10 21:28  we7u
+
+	* xastir.1: Updates by Jose Marte, HI8GN.
+
+2002-04-10 16:59  we7u
+
+	* src/alert.c: Added more comments.
+
+2002-04-10 16:02  we7u
+
+	* src/alert.c: Added a bunch of comments.
+
+2002-04-10 14:35  we7u
+
+	* src/db.c: Changed one output message to make it more correct.
+
+2002-04-10 13:03  we7u
+
+	* src/util.c: Fixing a compile warning for MacOS X.
+
+2002-04-10 12:58  we7u
+
+	* src/lang.c: Fixing a warning which shows up while compiling on
+	  MacOS X.
+
+2002-04-10 12:00  we7u
+
+	* Makefile.am, Makefile.in: Changed to more standard way of
+	  specifying man pages.
+
+2002-04-10 10:21  we7u
+
+	* configure, configure.in, src/wx.c: Bumped up to version number
+	  1.1.2 to more easily see who's running the latest weather code.
+	  Added some comments to wx.c
+
+2002-04-09 23:28  we7u
+
+	* src/wx.c: Adding more casts back in.
+
+2002-04-09 23:04  we7u
+
+	* src/wx.c: Adding some necessary casts back in to the weather
+	  code.
+
+2002-04-09 21:53  we7u
+
+	* Makefile.am, Makefile.in: Tweaked Makefiles to install new Xastir
+	  man page.
+
+2002-04-09 21:41  we7u
+
+	* xastir.1: A few small tweaks.
+
+2002-04-09 21:33  we7u
+
+	* xastir.1: Initial man page by Jose R. Marte A., HI8GN.
+
+2002-04-09 21:33  we7u
+
+	* xastir.spec.in: Man page added by Jose R. Marte A., HI8GN.
+
+2002-04-09 21:30  we7u
+
+	* config/language-Spanish.sys: Updates by Jose R. Marte A., HI8GN.
+
+2002-04-09 21:23  we7u
+
+	* help/help-Spanish.dat: Updates by Jose R. Marte A., HI8GN.
+
+2002-04-09 16:04  we7u
+
+	* src/wx.c: Commented out the Peet Brothers U2000 Complete Record
+	  Mode parsing of today's rain total.  It conflicts with the more
+	  generic method of calling compute_rain() from the incrementing
+	  long-term rain total.
+
+2002-04-09 15:38  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c, src/wx.c,
+	  src/xa_config.c: Preparation for correcting rain gauge
+	  measurements for various types of weather stations.
+
+2002-04-09 13:34  we7u
+
+	* src/: interface_gui.c, main.c: Moving "default:" cases to end of
+	  switch statements.
+
+2002-04-09 09:35  francais1
+
+	* src/main.c: Force redraw on coordinate system change.  This will
+	  make sense when I check in the UTM grid code.
+
+2002-04-09 02:25  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/interface_gui.c, src/wx.c: Code
+	  to handle different types of rain gauges.  Nearly complete.
+
+2002-04-09 00:51  we7u
+
+	* src/: db.c, wx.c: Added some comments.
+
+2002-04-08 23:13  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Portuguese.sys,
+	  config/language-Spanish.sys, src/main.c: Added code to force the
+	  symbol to one of the two weather symbols that are legal in the
+	  APRS spec, for the cases where we're transmitting weather data.
+
+2002-04-08 14:15  rzg
+
+	* help/help-English.dat: Minor helpfile update.
+
+2002-04-08 13:29  we7u
+
+	* src/: main.c, main.h, maps.c: Fixed zooming-by-dragging, a mouse
+	  operation, so that the entire box that is dragged will appear in
+	  the final view.
+
+2002-04-08 11:57  we7u
+
+	* src/wx.c: Preparing to tweak Peet Bros code for 0.1mm and 0.01"
+	  rain gauges.	No real code changes yet.
+
+2002-04-07 11:48  we7u
+
+	* config/language-Spanish.sys: Deleted duplicate lines.
+
+2002-04-06 11:47  we7u
+
+	* config/language-Italian.sys: Updated to correspond more closely
+	  with the English language file.
+
+2002-04-06 11:11  we7u
+
+	* config/: language-Dutch.sys, language-French.sys,
+	  language-German.sys, language-Spanish.sys: Keeping the other
+	  language files in sync with the English file.
+
+2002-04-06 10:56  we7u
+
+	* config/language-Portuguese.sys: Adding some missing strings.
+
+2002-04-06 10:11  we7u
+
+	* help/: Makefile.am, Makefile.in: Portuguese help file stuff.
+
+2002-04-06 10:09  we7u
+
+	* xastir.spec.in, help/help-Portuguese.dat, src/main.c: Potuguese
+	  help file stuff.
+
+2002-04-06 09:56  we7u
+
+	* config/Makefile.in: Adding Portuguese language.
+
+2002-04-06 09:53  we7u
+
+	* README.1ST, xastir.spec.in, config/Makefile.am,
+	  config/language-English.sys, config/language-Portuguese.sys,
+	  src/main.c: Tweaks to add Portuguese language to Xastir.
+
+2002-04-06 08:06  we7u
+
+	* config/language-Portuguese.sys: Thanks to David Quental for
+	  tranlating the language file to Portuguese!
+
+2002-04-05 19:31  we7u
+
+	* src/main.c: Tweak to make gps interval time switch as soon as the
+	  user changes it in the default menu.
+
+2002-04-05 14:50  we7u
+
+	* src/: main.c, main.h, maps.c: Modifying zooming in with the mouse
+	  such that it now figures out whether most of the mouse movement
+	  was in the horizontal or in the vertical direction, then computes
+	  the new zoom level based on that.  Previous to this change
+	  zooming was calculated based only on vertical movement.
+
+2002-04-05 11:14  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Spanish.sys: Changed the final exit label.
+
+2002-04-05 08:25  gstueve
+
+	* src/db.c: Reintroduce groups to the land of messaging.
+
+2002-04-04 16:59  we7u
+
+	* src/main.c: Tweaked one hotkey string that I forgot to.
+
+2002-04-04 16:41  we7u
+
+	* src/main.c: Fixed Map Chooser so that the list approriately shows
+	  what was most recently selected/de-selected via the buttons.
+
+2002-04-04 15:37  we7u
+
+	* src/main.c: Mapped the coordinate calculator to a button in the
+	  maps menu.
+
+2002-04-04 01:39  we7u
+
+	* src/main.c: Changed "About" text to say 1999-2002.
+
+2002-04-04 01:24  we7u
+
+	* src/db.c: Changed Station_data() code so that it's not destroyed
+	  and re-created each time if "Automatic Updates" are enabled.
+	  Broke out code that filled in the text into a separate function.
+
+2002-04-03 23:33  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/main.c: Implemented "Exit Now!" submenu off the File->Exit
+	  menu to make it harder to exit the program by mistake.  It takes
+	  a deliberate effort now to do so.
+
+2002-04-03 23:10  we7u
+
+	* src/main.c: Changed Map Chooser so that only the OK and Cancel
+	  buttons will dismiss the dialog.
+
+2002-04-03 22:56  we7u
+
+	* src/maps.c: First attempt to make Shapefiles more bulletproof.
+	  Missing fields shouldn't cause segfaults anymore.
+
+2002-04-02 23:13  we7u
+
+	* src/rac_data.c: Added a popup to the RAC data search for the case
+	  where the callsign isn't found.
+
+2002-04-02 22:25  we7u
+
+	* src/fcc_data.c: Fixed severe wait when a U.S. callsign is not in
+	  the database.  Also added a popup for the cases where the
+	  callsign isn't found.
+
+2002-04-02 14:01  we7u
+
+	* src/main.c: Coordinate calculator OK button is now grey'ed out
+	  until a successful calculation occurs.
+
+2002-04-02 13:44  we7u
+
+	* src/main.c: Added some debug_level statements for some printf's.
+
+2002-04-02 13:37  we7u
+
+	* src/main.c: Fixed truncation problems affecting accuracy in the
+	  last digits for the Coordinate Calculator dialog.
+
+2002-04-02 13:21  we7u
+
+	* src/main.c: Most of the coordinate calculator stuff is working
+	  now.	Still a few minor truncation problems to track down and
+	  fix.
+
+2002-04-02 09:32  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/main.c: Now change title on Coordinate Calculator dialog
+	  based on which dialog called us.  Also changed some strings to
+	  langcode strings for Coordinate Calculator and associated code.
+
+2002-04-02 08:55  we7u
+
+	* src/main.c: Added a bunch more comments having to do with the
+	  Coordinate Calculator.
+
+2002-04-01 23:43  we7u
+
+	* src/: main.c, wx_gui.c: Added linkages between Coordinate
+	  Calculator and the calling dialogs, in both directions.
+
+2002-04-01 15:42  we7u
+
+	* src/: main.c, util.c: Fixing coordinate calculator.  Got rid of
+	  rounding errors by going to fixed-point arithmetic.  Added
+	  comments to util.c.
+
+2002-04-01 14:53  we7u
+
+	* src/util.c: Switched to fixed-point arithmetic for lat/lon
+	  conversions to strings.  Got rid of floating-point rounding
+	  errors.
+
+2002-04-01 14:52  we7u
+
+	* src/main.c: Added space between lat/lon values on status line.
+	  More readable.
+
+2002-04-01 13:37  we7u
+
+	* src/main.c: Changed Coordinate Calculator to use higher precision
+	  DD MM SS.S format.
+
+2002-04-01 12:52  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/list_gui.c, src/util.c: Changed dd mm ss format to dd mm ss.s
+	  for more precision.  It's more similar now to the precision of
+	  the other formats.
+
+2002-04-01 12:28  we7u
+
+	* src/util.c: Correct some comments.
+
+2002-03-31 23:57  we7u
+
+	* src/wx.c: Updated some comments.
+
+2002-03-31 22:50  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/interface.h, src/interface_gui.c, src/xa_config.c: Added
+	  KD6VPE's changes to add tenth/hundredth rain gauge types to the
+	  weather interfaces.  This is to support the two types of rain
+	  gauges for Peet Brothers weather stations.  This patch implements
+	  a global variable and the interface widgets needed to manipulate
+	  it, but does _not_ implement the code to do anything with the
+	  variable yet.
+
+2002-03-30 10:00  we7u
+
+	* src/main.c: Changed Coordinate Calc help text so that it is
+	  obviously not good output data.
+
+2002-03-30 09:23  we7u
+
+	* src/main.c: Added some help text output to Coordinate Calculator
+	  if the user enters something that isn't recognized.
+
+2002-03-30 01:17  we7u
+
+	* src/main.c: Very minor changes to Coordinate Calculator.  No
+	  additional functionality.
+
+2002-03-30 00:12  we7u
+
+	* src/main.c: More Coordinate Calculator stuff.  UTM input is
+	  working now.
+
+2002-03-29 18:40  we7u
+
+	* src/main.c: Added some simulated output for what the Coordinate
+	  Calculator should display.
+
+2002-03-29 15:47  we7u
+
+	* src/main.c: More code for the Coordinate Calculator.
+
+2002-03-29 15:00  we7u
+
+	* src/main.c: Added Coordinate_calc button to Object Create/Modify.
+
+2002-03-29 14:45  we7u
+
+	* src/main.c: More coordinate calculator code.	Not functional yet.
+
+2002-03-29 10:43  francais1
+
+	* src/alert.c: Fixed errant tabs
+
+2002-03-28 21:53  francais1
+
+	* src/alert.c: There were several strncpy's without a following
+	  str[last] = `\0` statement.  One of them caused a segfault.  This
+	  whole file probably needs looking over for such problems.  I
+	  fixed a few I thought need the statement or in the case of some
+	  memmove's, seemed wrong to me.
+
+2002-03-28 16:19  we7u
+
+	* src/: lang.c, main.c: Fixed langcode segfault.  Fixed a
+	  lang_hotkey that was wrong.
+
+2002-03-28 15:52  we7u
+
+	* src/main.c: The beginnings of a coordinate calculator for
+	  inputting coordinates in different formats.
+
+2002-03-28 15:31  we7u
+
+	* src/list_gui.h: Knocking off a compiler warning.
+
+2002-03-28 11:28  we7u
+
+	* src/: list_gui.c, main.c: View->Mobile Stations list now updates
+	  instantly when the coordinate system is changed.
+
+2002-03-28 11:02  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/list_gui.c: Added multiple coordinate display capability to
+	  View->Mobile Stations dialog.
+
+2002-03-28 10:41  francais1
+
+	* src/main.c: Added calls to TrackMouse for the map-moving key
+	  events so that the position status line gets updated.
+
+2002-03-28 10:27  francais1
+
+	* src/main.c: Commented out code that clears mouse pointer location
+	  status line when we leave Xastir window because I believe we may
+	  be trying to write down that information in another window or
+	  some such action.
+
+2002-03-27 16:54  francais1
+
+	* src/: db.c, main.c, util.c, xastir.h: Added and enabled DDMMSS
+	  coordinate format.
+
+2002-03-27 16:21  we7u
+
+	* src/db.c: Added dd.dddd and UTM capability to the Station Info
+	  dialog as well.
+
+2002-03-27 14:26  we7u
+
+	* src/main.c: Removed unused variables.  Changed some comments.
+
+2002-03-27 13:22  we7u
+
+	* src/: main.c, util.c, util.h: Created convert_xastir_to_UTM_str()
+	  function to create a UTM string.
+
+2002-03-27 12:59  we7u
+
+	* src/util.c: Added some comments.
+
+2002-03-27 12:49  we7u
+
+	* src/main.c: Enclosed some calculations used only in debug mode
+	  inside if (debug_level) construct.  Added a few comments here and
+	  there.
+
+2002-03-27 10:21  we7u
+
+	* src/db.c: Fixed a problem caused by the mass update to new debug
+	  levels:  The station callsign was truncated in Station Info
+	  dialog if in debug level that wasn't 0 or 1.	Also changed this
+	  dialog such that the characters which make up the symbol are
+	  always visible between the symbol and the callsign, whether in
+	  debug mode or not.  I want to see this information.
+
+2002-03-27 09:38  we7u
+
+	* scripts/mapfgd.pl: Updates by Derrick J. Brashear, KB3EGH, to
+	  handle 1:63360 maps.
+
+2002-03-26 23:57  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/main.c, src/main.h, src/xa_config.c: Added a
+	  File->Configure->Coordinate System menu option which allows
+	  selecting between four different methods of displaying
+	  coordinates.	Currently this only modifies the status bar
+	  display.  Only three of the four options are currently
+	  implemented.
+
+2002-03-26 15:43  we7u
+
+	* src/main.c: Added timestamp output to stderr on segfault.
+
+2002-03-26 15:36  we7u
+
+	* src/: util.c, util.h, wx.c: Added 30 second timestamps to each
+	  logfile.  Moved hour() and minute() routines from wx.c to util.c,
+	  renamed to get_hours() and get_minutes().  Added get_seconds()
+	  routine.  Added code to wx.c:cycle_weather() routine to do the
+	  logfile timestamps.  Cycle_weather currently runs every 30
+	  seconds.
+
+2002-03-22 23:20  we7u
+
+	* xastir.spec.in: Trimmed down version that still works nicely.
+	  Installs /usr/local/bin/xastir as SUID root.
+
+2002-03-22 22:34  we7u
+
+	* xastir.spec.in: Fixed for binary RPM's.
+
+2002-03-22 14:46  we7u
+
+	* xastir.spec.in: Updated link to project sources.
+
+2002-03-22 14:33  we7u
+
+	* xastir.spec.in: Corrected misspelling.
+
+2002-03-19 08:37  we7u
+
+	* config/tnc-startup.kpc3: More tweaks to the kpc3 startup file by
+	  we7u.
+
+2002-03-18 22:00  we7u
+
+	* config/tnc-startup.pico: A few more pico changes by we7u.
+
+2002-03-18 21:41  we7u
+
+	* config/: tnc-startup.aea, tnc-startup.sys: Added "echo off" to
+	  two tnc startup files.  This prevents echo'ed commands from
+	  showing up in the middle of tnc data.
+
+2002-03-18 21:25  we7u
+
+	* config/tnc-startup.pico: Changes hinted at by Jeff Brenton,
+	  KA9VNV.  Changed into PicoPacket syntax by Curt, WE7U.
+
+2002-03-18 21:07  we7u
+
+	* config/tnc-startup.kpc3: Added changes suggested by Jeff Brenton,
+	  KA9VNV.
+
+2002-03-18 10:00  we7u
+
+	* config/language-Italian.sys: Fixes by Marco Calistri, IK5BCU.
+
+2002-03-15 09:39  we7u
+
+	* help/help-English.dat: Fixed minor spelling errors.
+
+2002-03-15 09:35  we7u
+
+	* README.1ST: Fixed minor spelling errors.
+
+2002-03-14 20:58  rzg
+
+	* README.1ST, help/help-English.dat:
+	  Updated helpfile and README.1ST.
+
+2002-03-13 09:22  we7u
+
+	* scripts/mapfgd.pl: Fixes by Derrick J. Brashear for "k" format
+	  maps.
+
+2002-03-12 09:00  we7u
+
+	* src/maps.c: Fixing some segfaults that can occur in the geoTIFF
+	  code if certain TIFF tags aren't present in the image.  Thanks to
+	  Derrick J. Brashear for pointing this out.  I used his patch with
+	  modifications.
+
+2002-03-11 15:36  we7u
+
+	* config/: tnc-startup.kam, tnc-startup.kpc3, tnc-startup.sys:
+	  Changed "mfilter off" to "filter off" for kam and kpc3.  Added
+	  "filter off" to tnc-startup.sys as well.  Both mfilter and filter
+	  are in that file, making it work for both types of TNC's.
+
+2002-03-11 12:53  we7u
+
+	* src/lang.c: Added a bit of bulletproofing for lang.c.
+
+2002-03-11 10:49  we7u
+
+	* config/: Makefile.am, Makefile.in, tnc-startup.aea: Added
+	  tnc-startup.aea file and tweaked Makefiles to install it.
+
+2002-03-11 10:06  we7u
+
+	* config/: tnc-startup.kam, tnc-startup.kpc3, tnc-startup.sys:
+	  Adding "mfilter off" to most tnc startup files.
+
+2002-03-11 01:17  we7u
+
+	* src/interface.c: Increased inter-character delay to 25ms.
+	  PicoPacket doesn't work with 20ms.  This is only for writes on
+	  serial port TNC's.
+
+2002-03-11 00:06  we7u
+
+	* config/tnc-startup.pico: Fullduplex not recognized by my
+	  PicoPacket.  Fulldup is.
+
+2002-03-10 23:39  we7u
+
+	* src/interface.c: Moved character write pacing to the proper
+	  routine.
+
+2002-03-10 23:01  we7u
+
+	* src/: interface.c, main.c, main.h: Setuid patches by Jack
+	  Twilley.  Serial port throttling by we7u.
+
+2002-03-08 14:48  we7u
+
+	* src/interface_gui.c: Fix for Xastir blowing up when changing
+	  properties on a serial TNC interface.
+
+2002-03-07 15:33  we7u
+
+	* config/Makefile.in: Adding PicoPacket startup file.
+
+2002-03-07 15:31  we7u
+
+	* Makefile.in: Adding backslash back in at the appropriate point.
+
+2002-03-07 15:30  we7u
+
+	* acconfig.h, config.h.in, configure: Fixes for warning when
+	  running autoheader.
+
+2002-03-07 15:03  we7u
+
+	* config/tnc-startup.pico: A few more tweaks to the picopacket
+	  startup file.
+
+2002-03-07 12:58  we7u
+
+	* src/gps.c: Changed a few variables to globals.  This is to allow
+	  two different GPS sentences to update the current info, then
+	  perform a screen update using the combined data.  Fixed the code
+	  so that receipt of one valid GPS sentence doesn't disable
+	  decoding of the next.
+
+2002-03-07 12:49  we7u
+
+	* config/tnc-startup.pico: Swapped the order of the GPS string
+	  captures.
+
+2002-03-07 12:49  we7u
+
+	* src/interface.c: Added some debugging statements.
+
+2002-03-07 10:56  we7u
+
+	* config/tnc-startup.pico: Proper commands for a Pico.	Tested.
+
+2002-03-07 10:55  we7u
+
+	* src/interface.c: Added a delay after sending each init string to
+	  a serial TNC.  This is needed to allow the TNC enough time to
+	  process the command before sending the next.
+
+2002-03-07 08:58  we7u
+
+	* Makefile.am: Adding a backslash that was erroneously deleted from
+	  Makefile.am.	Thanks to Jack Twilley for pointing this out.
+
+2002-03-06 17:02  we7u
+
+	* config/: Makefile.am, tnc-startup.pico: Added a startup file for
+	  a Paccomm PicoPacket.
+
+2002-03-06 15:58  we7u
+
+	* src/gps.c: Setting the time from GPS data now requires only that
+	  a $GPRMC string be received, the OS be Linux, and that the Xastir
+	  binary must be SUID root.  It no longer requires the $GPGGA
+	  sentence to set the time.
+
+2002-03-06 13:57  we7u
+
+	* config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  src/main.c: Changed 20 & 10 second GPS update rates down to 15 &
+	  5.
+
+2002-03-06 13:13  we7u
+
+	* src/db.c: Added station trails for the local station.  Improved
+	  station/trail update rate for Track-Me mode.
+
+2002-03-06 11:48  we7u
+
+	* src/db.c: Added the capability to track ourselves.  Uses the
+	  Track Station facility, so the map moves when we get too near the
+	  edge of the viewport.
+
+2002-03-06 10:11  we7u
+
+	* src/interface_gui.c: Added a missing mutex unlock that was
+	  preventing getting to the properties dialog for the new interface
+	  type.
+
+2002-03-06 01:52  we7u
+
+	* src/gps.c: Blanking out fields for which we don't have actual
+	  data values.
+
+2002-03-06 01:44  we7u
+
+	* src/interface.c: Added else clause s.t. it changes the type to
+	  "aprs data" if the nmea tests fail.
+
+2002-03-06 01:29  we7u
+
+	* src/interface.c: A few small tweaks to tnc_get_data_type().
+	  Wasn't detecting NMEA data properly.
+
+2002-03-06 01:17  we7u
+
+	* src/gps.c: Updating local position after decoding each GPRMC or
+	  GPGGA string.
+
+2002-03-06 01:03  we7u
+
+	* src/gps.c: Now updates local position when either $GPRMC or
+	  $GPGGA are received.	Both are not required except for setting
+	  time.  Added #ifdef __linux__ around the settime call.
+
+2002-03-06 00:30  we7u
+
+	* src/interface.c: Modified tnc_get_data_type() function so that it
+	  doesn't call the decode_ax25_line() function.  The latter
+	  function is destructive to its first parameter, which is the APRS
+	  packet.  It was causing the packet to be destroyed before it
+	  could be parsed and added to the database.
+
+2002-03-06 00:27  we7u
+
+	* src/db.c: Corrected spelling error in debug output.
+
+2002-03-06 00:25  we7u
+
+	* src/main.c: Added a couple of comments.
+
+2002-03-05 23:53  we7u
+
+	* src/interface_gui.c: Added "Set Time" button to two more GPS
+	  interfaces.  Took it away from the "Serial TNC" interface.
+
+2002-03-05 22:42  we7u
+
+	* src/main.c: Widening the debug_level form to handle up to debug
+	  level 2047.
+
+2002-03-05 13:28  we7u
+
+	* AUTHORS, ChangeLog, DEBUG_LEVELS, Makefile.am, README.1ST,
+	  acinclude.m4, config.guess, config.sub, configure.in, install-sh,
+	  missing, mkinstalldirs, help/help-English.dat,
+	  help/help-French.dat, help/help-German.dat,
+	  help/help-Italian.dat, help/help-Spanish.dat,
+	  scripts/icontable.pl, scripts/mapblast2geo.pl, scripts/mapfgd.pl,
+	  src/datum.c, src/datum.h, src/db.c, src/draw_symbols.c,
+	  src/festival.c, src/gps.c, src/interface.c, src/interface.h,
+	  src/interface_gui.c, src/list_gui.c, src/main.c, src/maps.c,
+	  src/messages.c, src/rotated.c, src/rotated.h, src/snprintf.c,
+	  src/snprintf.h, src/util.c, src/xa_config.c: Expanded tabs.
+
+2002-03-05 00:18  we7u
+
+	* src/: db.c, db.h, gps.c, igate.c, interface.c, interface.h,
+	  interface_gui.c, lang.c, main.c, maps.c, util.c, xa_config.c:
+	  Changes by Owen DeLong <owen at delong.com>:  Changing to bit-mapped
+	  debug levels.  Added new interface type "Serial TNC w/GPS on AUX
+	  port", which is for Kantronics KAM, KPC3+, and Paccomm PicoPacket
+	  TNC's that respond to <CTRL>-E for fetching GPS strings.  Added
+	  new DEBUG_LEVELS file that describes the new standard levels.
+	  Added more debug statements througout the code.  Added comments
+	  for GPGGA sentence.  Added "dbadd" parameter to decode_ax25_line,
+	  if it's set on return, add the data to the database.	Filter
+	  "cmd:" out of incoming data.	Decode time/data from GPRMC and
+	  GPGGA strings, used to set system time to GPS time.  Altitude
+	  units now decoded from GPGGA strings.  Changed hard-coded device
+	  numbers to ennumerated values.  New black background choice.
+	  Added "char *envp[]" to parameters for main.
+
+	  Still needed: Set time fixes for other operating systems.  Smooth
+	  time transition instead of force to new value.  "Set Time" button
+	  for remaining two GPS interface types.
+
+2002-03-04 13:41  we7u
+
+	* DEBUG_LEVELS: Added by Owen DeLong <owen at delong.com>:  Changing
+	  to bit-mapped debug levels.  This file documents what each level
+	  is for.
+
+2002-03-04 13:36  we7u
+
+	* src/: track_gui.c, wx.c: Changes by Owen DeLong
+	  <owen at delong.com>:  Changing to bit-mapped debug levels.
+
+2002-03-04 13:33  we7u
+
+	* src/: alert.c, hostname.c, maps.c, messages.c: Changes by Owen
+	  DeLong <owen at delong.com>:  Changing to bit-mapped debug levels.
+
+2002-03-04 13:20  we7u
+
+	* symbols/symbols.dat: Changes by Owen DeLong <owen at delong.com>,
+	  KB6MER to support: New interface type.
+
+2002-03-04 13:19  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Spanish.sys: Changes by Owen DeLong <owen at delong.com>,
+	  KB6MER to support: New interface type, setting time via GPS, new
+	  Black map background color, more debugging messages.
+
+2002-02-25 16:10  we7u
+
+	* README.1ST: Minor tweaks to again test mailing list notification.
+
+2002-02-25 16:06  we7u
+
+	* README.1ST: Minor tweaks to test new mailing list.
+
+2002-02-25 14:29  we7u
+
+	* README.1ST: Added a blurb about the "--prefix" config option.
+
+2002-02-25 12:43  francais1
+
+	* config.h.in, configure, configure.in, src/xa_config.h,
+	  src/xa_config.c: Changes to allow the use of --prefix with
+	  configure.  By default should install and run from
+	  /usr/local/xastir as before.
+
+2002-02-25 01:22  we7u
+
+	* src/interface.c: Added a couple of debug messages.  Fixed the
+	  AX.25 reconnect problem.  Decreased several fixed waits.
+
+2002-02-22 23:41  we7u
+
+	* src/db.c: Added more debug output in decode_Mic_E function.  One
+	  statement will print out even without debug mode if the symbol
+	  table and symbol characters are switched.
+
+2002-02-19 16:28  rzg
+
+	* help/help-English.dat: Updated helpfile.
+
+2002-02-16 23:52  we7u
+
+	* src/main.c: Changed "Measure" function to go to feet or meters if
+	  the total length is less than a mile or kilometer.
+
+2002-02-16 21:21  we7u
+
+	* src/util.c: FreeBSD time fix by Jack Twilley <jmt at twilley.org>.
+
+2002-02-15 21:51  we7u
+
+	* src/main.c: Fixing the main window (actually the main popup!) so
+	  that it initially shows at the correct size, instead of resizing
+	  shortly after.
+
+2002-02-15 15:55  we7u
+
+	* src/maps.c: Fixed Shapefile maps so that they work with more
+	  shapefiles.  Unknown shapes are drawn in black just like the
+	  roads.  Lakes shapefiles have to start with "lk" in the filename
+	  now to be recognized and drawn as blue lakes.
+
+2002-02-15 12:49  we7u
+
+	* src/main.c: Reordering the management of the appshell popup in an
+	  attempt to get rid of the bug:  "Shell widget has zero width or
+	  height" that occurs on some systems.
+
+2002-02-14 14:37  we7u
+
+	* src/xa_config.c: Changing default greying out of stations from
+	  120 minutes down to 80 minutes.  This works better for some of
+	  the satellites we can use for APRS, per Bob Bruninga's
+	  recommendations.
+
+2002-02-14 09:33  we7u
+
+	* src/: db.c, main.c, main.h, util.c, util.h, xa_config.c: Tracked
+	  station speech patches contributed by Alan Crosswell
+	  <alan at columbia.edu>, n2ygk.
+
+2002-02-14 09:08  we7u
+
+	* config/: language-Dutch.sys, language-English.sys,
+	  language-French.sys, language-German.sys, language-Italian.sys,
+	  language-Spanish.sys: Tracked station speech patches contributed
+	  by Alan Crosswell <alan at columbia.edu>, n2ygk.
+
+2002-02-13 12:55  we7u
+
+	* src/maps.c: Tiger map tweaks submitted by Jim Chandler, N0VH.
+
+2002-02-13 11:14  we7u
+
+	* src/wx.c: Added a comment at the top describing the weather
+	  stations we currently support.
+
+2002-02-13 10:40  we7u
+
+	* config.guess, config.sub, missing: Checking in latest versions of
+	  these files, snagged from:
+	  http://subversions.gnu.org/cgi-bin/cvsweb/autoconf/config/
+
+2002-02-13 09:36  we7u
+
+	* configure, configure.in: Bumping the development version up to
+	  version 1.1.1
+
+2002-02-13 08:44  we7u
+
+	* missing, config.sub: Updated file sent to me by Jack Twilley
+	  <jmt at twilley.org>.
+
+2002-02-11 17:27  dk7in
+
+	* scripts/: mapblast2geo.pl, update_langfile.pl:
+	  Old E-Mail deleted.
+
+2002-02-11 16:08  dk7in
+
+	* scripts/icontable.pl:
+	  Old E-Mail address deleted.
+
+2002-02-11 15:21  we7u
+
+	* scripts/mapfgd.pl: New script by Derrick J Brashear, KB3EGH.
+	  This one creates .fgd files from geotiff .tif files.	Useful for
+	  topo maps you find on the net that don't come with .fgd files.
+
+2002-02-11 14:22  we7u
+
+	* src/maps.c: A tweak by Derrick J Brashear, KB3EGH, which avoids
+	  problems with user defined horizontal datums in geoTIFF.
+
+2002-02-10 12:04  kg4ijb
+
+	* Makefile.am: didn't get committed :/
+
+2002-02-10 01:06  we7u
+
+	* callpass/Makefile: Removing Makefile.  This is created
+	  automatically during the "configure" stage.
+
+2002-02-09 16:56  kg4ijb
+
+	* Makefile.in, configure, configure.in, callpass/Makefile,
+	  callpass/Makefile.am, callpass/Makefile.in, callpass/callpass.c,
+	  m4/Makefile.in: Moved callpass* to ./callpass.  Automake doesn't
+	  handle recursives very well
+
+2002-02-09 06:48  kg4ijb
+
+	* config.h.in, configure, configure.in, m4/Makefile.in: Added
+	  config check for Xpm (hack) untill I can do something better.
+
+2002-02-09 06:14  kg4ijb
+
+	* configure, configure.in, m4/Makefile.in: updated release
+	  information
+
+2002-02-07 20:45  kg4ijb
+
+	* m4/Makefile.in: rebuilds
+
+2002-02-06 16:58  we7u
+
+	* Makefile.am: Added a forgotten root-level Makefile.am file.
+
+2002-02-05 16:59  we7u
+
+	* help/: help-English.dat, help-Dutch.dat, help-French.dat,
+	  help-German.dat, help-Italian.dat, help-Spanish.dat: Updated web
+	  page pointers.
+
+2002-02-05 16:57  we7u
+
+	* AUTHORS, FAQ, README, README.1ST: Updated web page pointers and
+	  CVS instructions.
+
+2002-02-05 16:22  we7u
+
+	* AUTHORS, FAQ, README, README.1ST: Tweaking web page addresses for
+	  the new sourceforge project address.
+
+2002-02-04 21:00  we7u
+
+	* src/lclint.script: Added more debug statements.  Added new files
+	  to it.
+
+2002-02-04 20:58  we7u
+
+	* src/maps.c: Changed the ifdef's around that check for ImageMagick
+	  and XPM libraries.  The proper pieces of code should be
+	  enabled/disabled now for whichever of these two libraries are
+	  found on the system.
+
+2002-02-04 20:55  we7u
+
+	* src/main.h: Undef'ing VERSION only when lclint is being run
+	  against the code.
+
+2002-02-04 20:54  we7u
+
+	* src/main.c: Added some debug statements.
+
+2002-02-01 19:18  kg4ijb
+
+	* src/list_gui.c, src/list_gui.h, src/locate_gui.c, src/location.c,
+	  src/location_gui.c, src/main.c, src/main.h, src/maps.c,
+	  src/maps.h, src/messages.c, src/messages.h, src/messages_gui.c,
+	  src/popup.h, src/popup_gui.c, src/rac_data.c, src/rac_data.h,
+	  src/rotated.c, src/rotated.h, src/sound.c, src/symbols.h,
+	  src/track_gui.c, src/track_gui.h, src/util.c, src/util.h,
+	  src/view_message_gui.c, src/wx.c, src/wx.h, src/wx_gui.c,
+	  src/xa_config.c, src/xa_config.h, src/xastir.h, src/snprintf.h,
+	  src/snprintf.c, symbols/Makefile.am, symbols/Makefile.in,
+	  symbols/symbols.dat: Initial revision
+
+2002-02-01 19:18  kg4ijb
+
+	* src/list_gui.c, src/list_gui.h, src/locate_gui.c, src/location.c,
+	  src/location_gui.c, src/main.c, src/main.h, src/maps.c,
+	  src/maps.h, src/messages.c, src/messages.h, src/messages_gui.c,
+	  src/popup.h, src/popup_gui.c, src/rac_data.c, src/rac_data.h,
+	  src/rotated.c, src/rotated.h, src/sound.c, src/symbols.h,
+	  src/track_gui.c, src/track_gui.h, src/util.c, src/util.h,
+	  src/view_message_gui.c, src/wx.c, src/wx.h, src/wx_gui.c,
+	  src/xa_config.c, src/xa_config.h, src/xastir.h, src/snprintf.h,
+	  src/snprintf.c, symbols/Makefile.am, symbols/Makefile.in,
+	  symbols/symbols.dat: rc1 intital import
+
+2002-02-01 19:15  kg4ijb
+
+	* ABOUT-NLS, AUTHORS, COPYING, ChangeLog, FAQ, INSTALL, LICENSE,
+	  Makefile.in, NEWS, README, README.1ST, TODO, UPDATES, acconfig.h,
+	  acinclude.m4, changes.txt, config.guess, config.h.in, config.sub,
+	  configure, configure.in, install-sh, missing, mkinstalldirs,
+	  placeholder, stamp-h.in, xastir.spec.in, ltconfig, ltmain.sh,
+	  config/Makefile.am, config/Makefile.in,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  config/tnc-startup.kam, config/tnc-startup.kpc3,
+	  config/tnc-startup.sys, config/tnc-startup.thd7,
+	  config/tnc-stop.sys, config/xastir.rgb, help/Makefile.am,
+	  help/Makefile.in, help/help-Dutch.dat, help/help-English.dat,
+	  help/help-French.dat, help/help-German.dat,
+	  help/help-Italian.dat, help/help-Spanish.dat, intl/Makefile.in,
+	  intl/VERSION, intl/bindtextdom.c, intl/cat-compat.c,
+	  intl/dcgettext.c, intl/dgettext.c, intl/explodename.c,
+	  intl/finddomain.c, intl/gettext.c, intl/gettext.h,
+	  intl/gettextP.h, intl/hash-string.h, intl/intl-compat.c,
+	  intl/l10nflist.c, intl/libgettext.h, intl/libintl.h,
+	  intl/linux-msg.sed, intl/loadinfo.h, intl/loadmsgcat.c,
+	  intl/localealias.c, intl/po2tbl.sed, intl/po2tbl.sed.in,
+	  intl/textdomain.c, intl/xopen-msg.sed, m4/Makefile.am,
+	  m4/Makefile.in, m4/xmhtml.m4, po/Makefile.in, po/Makefile.in.in,
+	  po/POTFILES, po/POTFILES.in, po/cat-id-tbl.c, po/en.po, po/fr.po,
+	  po/nl.po, po/stamp-cat-id, po/xastir.pot,
+	  scripts/example_objects.log, scripts/icontable.pl,
+	  scripts/inf2geo.pl, scripts/mapblast2geo.pl,
+	  scripts/update_langfile.pl, src/Makefile.am, src/Makefile.in,
+	  src/alert.c, src/alert.h, src/bulletin_gui.c, src/bulletin_gui.h,
+	  src/color.c, src/color.h, src/datum.c, src/datum.h, src/db.c,
+	  src/db.h, src/draw_symbols.c, src/draw_symbols.h, src/fcc_data.c,
+	  src/fcc_data.h, src/festival.c, src/festival.h, src/gps.c,
+	  src/gps.h, src/hostname.c, src/hostname.h, src/igate.c,
+	  src/igate.h, src/interface.c, src/interface.h,
+	  src/interface_gui.c, src/lang.c, src/lang.h, src/lclint.script:
+	  Initial revision
+
+2002-02-01 19:15  kg4ijb
+
+	* ABOUT-NLS, AUTHORS, COPYING, ChangeLog, FAQ, INSTALL, LICENSE,
+	  Makefile.in, NEWS, README, README.1ST, TODO, UPDATES, acconfig.h,
+	  acinclude.m4, changes.txt, config.guess, config.h.in, config.sub,
+	  configure, configure.in, install-sh, missing, mkinstalldirs,
+	  placeholder, stamp-h.in, xastir.spec.in, ltconfig, ltmain.sh,
+	  config/Makefile.am, config/Makefile.in,
+	  config/language-Dutch.sys, config/language-English.sys,
+	  config/language-French.sys, config/language-German.sys,
+	  config/language-Italian.sys, config/language-Spanish.sys,
+	  config/tnc-startup.kam, config/tnc-startup.kpc3,
+	  config/tnc-startup.sys, config/tnc-startup.thd7,
+	  config/tnc-stop.sys, config/xastir.rgb, help/Makefile.am,
+	  help/Makefile.in, help/help-Dutch.dat, help/help-English.dat,
+	  help/help-French.dat, help/help-German.dat,
+	  help/help-Italian.dat, help/help-Spanish.dat, intl/Makefile.in,
+	  intl/VERSION, intl/bindtextdom.c, intl/cat-compat.c,
+	  intl/dcgettext.c, intl/dgettext.c, intl/explodename.c,
+	  intl/finddomain.c, intl/gettext.c, intl/gettext.h,
+	  intl/gettextP.h, intl/hash-string.h, intl/intl-compat.c,
+	  intl/l10nflist.c, intl/libgettext.h, intl/libintl.h,
+	  intl/linux-msg.sed, intl/loadinfo.h, intl/loadmsgcat.c,
+	  intl/localealias.c, intl/po2tbl.sed, intl/po2tbl.sed.in,
+	  intl/textdomain.c, intl/xopen-msg.sed, m4/Makefile.am,
+	  m4/Makefile.in, m4/xmhtml.m4, po/Makefile.in, po/Makefile.in.in,
+	  po/POTFILES, po/POTFILES.in, po/cat-id-tbl.c, po/en.po, po/fr.po,
+	  po/nl.po, po/stamp-cat-id, po/xastir.pot,
+	  scripts/example_objects.log, scripts/icontable.pl,
+	  scripts/inf2geo.pl, scripts/mapblast2geo.pl,
+	  scripts/update_langfile.pl, src/Makefile.am, src/Makefile.in,
+	  src/alert.c, src/alert.h, src/bulletin_gui.c, src/bulletin_gui.h,
+	  src/color.c, src/color.h, src/datum.c, src/datum.h, src/db.c,
+	  src/db.h, src/draw_symbols.c, src/draw_symbols.h, src/fcc_data.c,
+	  src/fcc_data.h, src/festival.c, src/festival.h, src/gps.c,
+	  src/gps.h, src/hostname.c, src/hostname.h, src/igate.c,
+	  src/igate.h, src/interface.c, src/interface.h,
+	  src/interface_gui.c, src/lang.c, src/lang.h, src/lclint.script:
+	  rc1 intital import
+
diff --git a/DEBUG_LEVELS b/DEBUG_LEVELS
new file mode 100644
index 0000000..0e0887f
--- /dev/null
+++ b/DEBUG_LEVELS
@@ -0,0 +1,123 @@
+
+$Id: DEBUG_LEVELS,v 1.18 2012/11/01 18:57:18 we7u Exp $
+
+This file has three parts.  The first part describes the new structure for
+debug levels.  The second part describes the debug_level definitions that
+were in the old code and which files they were in.  The third part
+describes how to use use debugging at run time.  The debug level structure
+was modified in February of 2002 by KB6MER.  Questions/comments/flames can
+be sent to kb6mer at arrl.net
+
+Here's how things are after KB6MER tweaked it all...
+
+New Scheme:
+-----------
+1       General basic debugging (any system)
+2       Messages, WX, Objects, and Items, Port Data Flow
+4       X Object Debugging
+8       X Window Object Debugging
+16      Map Debugging (maps.c)
+32      Language Debugging (maps.c)
+64      Database Object Debugging
+128     GPS Interface Detailed debugging
+256     station and trail display detailed debugging
+512     Map import/export function debugging
+1024    Internet Transaction debugging
+2048    ALOHA radius and Multipoint object debugging.
+
+4096    Levels 4096 and above will require modification to the
+        main.c:Change_debug_level_change_data() function to change
+        the bounds checking, and are available for future use.
+
+------------------------------------------------------------------
+
+Old Scheme:
+-----------
+Places where debug level is referenced in old code, and the levels
+referenced (if debug_level xx), where xx is >0, &1, etc.
+
+alert.c >0
+bulletin_gui.c &1
+db.c >=2 &1 &128 &32 &256 ()
+gps.c &128
+hostname.c &256
+igate.c &2
+interface.c &128 &2 &1
+interface_gui.c &128
+lang.c &32
+main.c &4 <0/>255(need to change limits) &8 &128 &1 &15
+maps.c &16 &2 >=2 &4 &1 &8
+messages.c >1 &1 >5
+messages_gui.c &2
+track_gui.c >=2
+util.c &1
+wx.c >2 &1
+xa_config.c &1 &2
+
+
+
+
+------------------------------------------------------------------
+
+How to Use the Debug Levels
+
+Xastir debugging is turned on at run time by using the "-v" command line
+option and/or the File -> Configure -> Change Debug Level pull-down. 
+ 
+As laid out above, in the source code, debugging output is turned on by a
+bitwise "and" (&) of the currently set DEBUG_LEVEL against a number
+appropriate to the module currently being executed. 
+
+For example, in the "maps.c" the following lines appear: 
+
+    if ( debug_level & 512 )
+        fprintf(stderr,"Creating %s\n", xpm_filename );
+
+The highest debug level for Xastir is 4095, and debug levels are additive. 
+If you want to have "general basic debugging" and "GPS interface Detail"
+and "Map Debugging" you'd use:
+
+1 + 128 + 512 = 641
+
+xastir -v 641 
+
+Debug information typically is sent to "standard error" - which is normally
+File Descriptor #2 in Unix parlance.  Using common Unix shells, such as
+Bash, you can "redirect" the output to be intermingled with the "standard
+output" (file descriptor #1).  This allows you to get all of the normal
+output, plus all of the debug output in one stream, which can be "piped" to
+another command, such as grep.  This can used to search for specific items
+in the debug output. 
+
+For example, to check debug information to see whether or not map caching
+is working, you can turn on debug level 512, redirect stderr to stdout and
+the grep for map cache specific output:
+
+xastir -v 512 2>&1 |grep map_cache
+
+Another little trick, to be used when you're running programs that
+call other programs, or scripts that call other scripts/programs:
+
+    (xastir -v 512 2>&1) | grep map_cache
+
+The parenthesis cause that portion to be run in a sub-shell, and then
+that sub-shell's STDERR is piped to STDOUT by the "2>&1" portion, so
+you get ANYTHING that went to STDERR or STDOUT from that command or
+anything that it calls.  This is how you can get a "make" command to
+spit everything into one file.
+
+Of course you can also do:
+
+    (xastir -v 512 2>&1) | tee xastir.log
+
+Which will pipe everything to your screen and to the xastir.log
+file.  You could then type "tail -f xastir.log | grep map_cache" in
+another window and watch that subset of the error messages there.
+That way you won't miss anything.
+
+
+
+
+------------------------------------------------------------------
+Copyright (C) 2002-2012 The Xastir Group
+
diff --git a/Davis/.cvsignore b/Davis/.cvsignore
new file mode 100644
index 0000000..f7ead90
--- /dev/null
+++ b/Davis/.cvsignore
@@ -0,0 +1,15 @@
+make.log
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.h
+config.h.in
+config.log
+config.status
+configure
+stamp-h1
+mkinstalldirs
+depcomp
+install-sh
+missing
diff --git a/Davis/AUTHORS b/Davis/AUTHORS
new file mode 100644
index 0000000..350c4f6
--- /dev/null
+++ b/Davis/AUTHORS
@@ -0,0 +1,24 @@
+
+$Id: AUTHORS,v 1.1 2004/06/02 16:37:59 we7u Exp $
+
+
+                        Developers and Contributions
+    _________________________________________________________________
+
+    First, thanks go out to the great folks at the xastir team - a
+    wonderful APRS application set and helpful folks!
+
+    Thanks also to Andreas Muller, author of meteo and a great
+    resource for information and help.
+    
+    Elements of this software are taken from wx200d ver 1.2
+    by Tim Witham, and it is modeled after that application.
+			
+    Finally, thanks to the MySQL folks for the key element - the
+    database.
+
+    KB8ROP      Bruce Bennett       bruts at adelphia.net
+    _________________________________________________________________
+
+    Copyright (C) 2003-2004 Bruce Bennett KB8ROP
+
diff --git a/Davis/COPYING b/Davis/COPYING
new file mode 100644
index 0000000..60549be
--- /dev/null
+++ b/Davis/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, 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 software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, 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 show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, 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 redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 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 Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, 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 executable.  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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+  5. 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 Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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.
+
+  7. 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 Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  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 program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Davis/CVS/Entries b/Davis/CVS/Entries
new file mode 100644
index 0000000..c97764a
--- /dev/null
+++ b/Davis/CVS/Entries
@@ -0,0 +1,11 @@
+/.cvsignore/1.2/Thu Jan 26 19:06:14 2006//
+/AUTHORS/1.1/Wed Jun  2 16:37:59 2004//
+/COPYING/1.1/Wed Jun  2 16:37:59 2004//
+/ChangeLog/1.1/Wed Jun  2 16:37:59 2004//
+/INSTALL/1.1/Wed Jun  2 16:37:59 2004//
+/Makefile.am/1.8/Thu Nov  1 18:57:18 2012//
+/NEWS/1.1/Wed Jun  2 16:37:59 2004//
+/README/1.9/Thu Nov  1 18:57:18 2012//
+/bootstrap.sh/1.12/Thu Nov  1 18:57:18 2012//
+/configure.ac/1.10/Thu Nov  1 18:57:18 2012//
+D
diff --git a/Davis/CVS/Entries.Log b/Davis/CVS/Entries.Log
new file mode 100644
index 0000000..d269bfe
--- /dev/null
+++ b/Davis/CVS/Entries.Log
@@ -0,0 +1 @@
+A D/src////
diff --git a/Davis/CVS/Repository b/Davis/CVS/Repository
new file mode 100644
index 0000000..7cd0aef
--- /dev/null
+++ b/Davis/CVS/Repository
@@ -0,0 +1 @@
+xastir/Davis
diff --git a/Davis/CVS/Root b/Davis/CVS/Root
new file mode 100644
index 0000000..6a998ee
--- /dev/null
+++ b/Davis/CVS/Root
@@ -0,0 +1 @@
+:ext:we7u at xastir.cvs.sourceforge.net:/cvsroot/xastir
diff --git a/Davis/ChangeLog b/Davis/ChangeLog
new file mode 100644
index 0000000..298ac9e
--- /dev/null
+++ b/Davis/ChangeLog
@@ -0,0 +1,3 @@
+
+# $Id: ChangeLog,v 1.1 2004/06/02 16:37:59 we7u Exp $
+
diff --git a/Davis/INSTALL b/Davis/INSTALL
new file mode 100644
index 0000000..dd6f3b3
--- /dev/null
+++ b/Davis/INSTALL
@@ -0,0 +1,232 @@
+
+$Id: INSTALL,v 1.1 2004/06/02 16:37:59 we7u Exp $
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Davis/Makefile.am b/Davis/Makefile.am
new file mode 100644
index 0000000..bdccfa4
--- /dev/null
+++ b/Davis/Makefile.am
@@ -0,0 +1,43 @@
+
+# $Id: Makefile.am,v 1.8 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+
+AUTOMAKE_OPTIONS = gnu dist-bzip2
+ACLOCAL_AMFLAGS = -I m4
+
+D=      `date +%G%m%d.%H%M%S`
+
+SUBDIRS = src
+
+
+#if DAVIS
+#MyWX = davis
+#else
+#MyWX =
+#endif
+#noinst_PROGRAMS = $(MyWX)
+
+
+# Remove this file here (it is created via configure), not from within intl.
+# DISTCLEANFILES =
+
+EXTRA_DIST = aclocal.m4 AUTHORS bootstrap.sh ChangeLog config.h.in \
+        config.status configure.ac COPYING INSTALL NEWS \
+        README bootstrap.sh
+
+MAINTAINERCLEANFILES = configure config.status aclocal.m4 \
+        Makefile.in Makefile config.guess config.sub install-sh \
+        missing mkinstalldirs
+
+#docdir=${pkgdatadir}/doc
+#doc_DATA=AUTHORS FAQ ChangeLog LICENSE README README.CVS \
+#        README.MAPS README.win32 COPYING INSTALL UPGRADE
+
+#mandir=${prefix}/man
+#man_MANS=xastir.1
+
+ChangeLog::
+
+
diff --git a/Davis/NEWS b/Davis/NEWS
new file mode 100644
index 0000000..42f428b
--- /dev/null
+++ b/Davis/NEWS
@@ -0,0 +1,3 @@
+
+$Id: NEWS,v 1.1 2004/06/02 16:37:59 we7u Exp $
+
diff --git a/Davis/README b/Davis/README
new file mode 100644
index 0000000..c3f19c1
--- /dev/null
+++ b/Davis/README
@@ -0,0 +1,211 @@
+
+$Id: README,v 1.9 2012/11/01 18:57:18 we7u Exp $
+
+Copyright (C) 2004 Bruce Bennett <bruts at adelphia.net>
+Portions Copyright (C) 2004-2012  The Xastir Group
+(Modified for the Xastir project under GPL license)
+
+
+Davis Weather Station support for Xastir - db2APRS
+
+
+OVERVIEW
+--------
+
+This is a bridge utility between "meteo", a Davis Weather Station 
+data storage & display application by Andreas Muller (see 
+http://meteo.othello.ch) and "Xastir", the APRS package for
+Linux (see http://www.xastir.org). It allows your Davis weather 
+data to be used by Xastir for local station data.
+
+You will need to obtain and install Xastir, mysql and meteo as 
+outlined in the following sections. After Xastir and meteo are
+in working order, this utility can be run as a daemon to provide 
+weather data to Xastir (or any other APRS-format application).
+
+"db2APRS" watches for new weather data in the database, retrieves
+the new data, formats it in APRS "position less" ASCII format and
+makes it available on a TCP port of your choosing. Xastir is 
+capable of reading this data (see note under Xastir installation).
+
+
+INSTALLATION
+------------
+
+Steps in order:
+
+1) Install mysql - initial tested version mysql-3.23.58
+   although version 4 is released and has some significant 
+   improvements - and version 4 *should* work (to be tested yet). 
+   If you use an RPM or DPK binary-image version, be sure to add 
+   the mysql-devel headers. For the latest image-version, see 
+   http://www.mysql.com and follow the links to the downloads. 
+   I used mysql-3.23.58-pc-linux-i686.tar.gz from that site.   
+
+2) Install meteo - tested versions meteo-0.9.4 and meteo-0.9.8
+   Version 0.9.9 is available and based on the change documented
+   will work. See the instructions for installing & then setting 
+   up meteo that come with the tar ball. Obtain the latest meteo 
+   at http://meteo.othello.ch - the setup is rather involved but
+   worth the efort. Some SQL/XML skills can help here, but are 
+   not absolutely required...
+
+3) Install or update your installation for Xastir to the latest
+   version (http://www.sourceforge.net, project Xastir) 
+
+4) Install db2APRS -  version 0.1.2
+   See instructions below.
+
+
+SETTINGS & STARTUP
+------------------
+
+1) mysql - it is recommended by mysql to set up passwords, but for
+   this usage it doesn't matter. In fact, it's a bit of a pain.
+   TODO - db2APRS has the annoying fault of clearly displaying 
+   the password used for the mysql database for anyone to see via 
+   'ps -ef'. Start mysqld before db2APRS, meteo and Xastir in your 
+   boot-time initializations.
+
+2) meteo - my testing used a one minute data accumulation rate. 
+   Thirty seconds would more closely match Xastir, but the 
+   database growth rate would be twice as fast (about 600  
+   Mbytes/year at 30 sec rate). Set your desired rate using the 
+   meteopoll command line options. I run the full meteopoll 
+   package with  averaging, graphs and meteodequeue - but the 
+   only *required*  element is meteopoll. Start the meteopoll 
+   daemon after mysqld is up. (meteodequeue is recommended - see 
+   the doc's that come with meteo and man pages).
+
+3) db2APRS - see "db2APRS RUN OPTIONS" below. Start this daemon 
+   after mysqld and before Xastir. When meteopoll isn't running, 
+   you will get old weather data, time stamped by Xastir as new 
+   data.
+
+4) xastir - start this last, if you are auto-opening the WX port.
+   Set the weather port as a network weather station on 
+   "localhost", port number as chosen in "db2APRS RUN OPTIONS" 
+   (default is 1313). Make sure your station is set to one of the
+   "w/weather data" and your Icon is set to a weather Icon.
+
+
+db2APRS RUN OPTIONS
+-------------------
+
+The db2APRS utility takes standard short & long command line 
+options, which can be displayed by "db2APRS -?". Here's the list:
+
+  -h	--help	
+
+      Show help info and exit.
+
+  -v    --verbose
+
+      Useful with the -n switch, for trouble-shooting, not for 
+      normal operation. Tells you more than you really wanted to  
+      know, but I recommend that you use this switch while you 
+      try to initially set up db2APRS.
+
+  -c	--cport [port#]
+
+      Choose which TCP/IP port data comes out from. If not used,
+      port number 1313 is the default. HINT: "telnet localhost 
+      [port#]" is a handy way to verify db2APRS operation.
+
+  -s	--sensor [sensor group#]
+
+      Indicate what group of sensors are the outdoor ones. 
+      If not supplied, sensor number 1 is the default. 
+      HINT: Tables "station" and "sensor" in the meteo
+      database control what your "sensor" (which means 
+      sensor group) definitions are for your "station".
+      
+  -u 	--user [database user]	
+
+      Username for mysql database connection. If unspecfied 
+      defaults to "meteo" (which is per the meteo setup intended
+      to be a read-only account for meteo).
+
+  -p 	--password [db passwd]	
+
+      Password for mysql connection. If unspecfied, no password  
+      is supplied. NOTE: this password is unfortunately visible 
+      to anyone on your system running 'ps -ef'. TO BE FIXED.
+
+  -b 	--database [database]	
+
+      Database name for mysql connection. If not supplied the 
+      default is "meteo".
+
+  -n	--nodaemon
+
+      Run in the fore-ground as a program. Useful for debugging
+      or initial setup, when used with -v.
+
+  -r	--repeat
+      
+      Keep going till killed - if not specified, one pass is 
+      performed and then db2APRS exits. The only case where this  
+      switch is *not* used is during initial setup/debug.
+
+Typical example: "./db2APRS -r -u meteo -p meteo" for normal use
+or "./db2APRS -r -n -v -u test -p password" for debugging.
+
+
+OPERATIONAL DETAILS
+-------------------
+
+db2APRS connects to the specified mysql database, extracts the 
+latest timestamp and compares it to the last timestamp it read. 
+If newer, the outdoor weather data (extception: air pressure is
+taken as indoor=outdoor) bearing this timestamp is extracted 
+and formatted in the APRS "position less" string format with a  
+Davis and X-APRS tag on the end. Any connecting client is given 
+this string at 25 second intervals, after new database entries 
+are checked for.
+
+This daemon could run on any networked Linux machine instead of 
+the machine hosting Xastir, if desired (it's a good way around 
+lack of processing power, disk space or serial ports!).
+
+Note that the db2APRS daemon keeps providing data to Xastir even 
+when no new entries in the database have been made. This could 
+lead to errors in the timestamp on the data that Xastir is 
+transmitting.
+
+
+BUILD db2APRS
+-------------
+
+It's the usual:
+
+$ cd xastir/Davis
+$ ./bootstrap.sh
+$ ./configure
+$ make
+$ su -c 'make install'
+
+
+ACKNOWLEGEMENTS & AUTHORS
+-------------------------
+
+db2APRS is the product of Bruce Bennett, callsign KB8ROP 
+<bruts at adelphia.net> It is freely available at no charge 
+under the GNU GENERAL PUBLIC LICENSE (see "COPYING" document)
+NO WARRANTY, expressed or implied, use at your own risk.
+
+Please feel free to contact me with test results & comments 
+at the above EMAIL address
+
+Code portions and style taken from wx200d by Tim Witham 
+<twitham at quiknet.com>, et. al.
+
+meteo is the work of Andreas Muller <afm at othello.ch>, et. al.
+
+mysql is the product of MySQL - see http://www.mysql.com for
+team details.
+
+and finally, Xastir is the brain child of Frank Giannandrea et. 
+al. (see http://www.xastir.org for current EMAIL addresses)
+
+
diff --git a/Davis/bootstrap.sh b/Davis/bootstrap.sh
new file mode 100755
index 0000000..84e7096
--- /dev/null
+++ b/Davis/bootstrap.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# $Id: bootstrap.sh,v 1.12 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+#
+
+../bootstrap.sh
+
diff --git a/Davis/configure.ac b/Davis/configure.ac
new file mode 100755
index 0000000..45003fd
--- /dev/null
+++ b/Davis/configure.ac
@@ -0,0 +1,67 @@
+#
+# $Id: configure.ac,v 1.10 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2004 Bruce Bennett <bruts at adelphia.net>
+# Portions Copyright (C) 2004-2012  The Xastir Group
+# (Modified for the Xastir project under GPL license)
+#
+#
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.53)
+AC_INIT(db2APRS, 0.2.0, bruts at adelphia.net)
+AM_INIT_AUTOMAKE(db2APRS, 0.2.0)
+AC_CONFIG_SRCDIR([src/db2APRS.c])
+AM_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_PROG_INSTALL
+AC_PROG_CC
+
+# Checks for libraries.
+# Use MySQL's script for library config, if available
+MYSQL_CONFIG=mysql_config
+AC_MSG_CHECKING(for a fully installed MySQL)
+if ${MYSQL_CONFIG} --libs > /dev/null 2>&1
+then
+    MYSQL_VERSION=`${MYSQL_CONFIG} --version`
+    MYSQL_LIBS=`${MYSQL_CONFIG} --libs`
+    LIBS=`${MYSQL_CONFIG} --libs`
+    MYSQL_CFLAGS=`${MYSQL_CONFIG} --cflags`
+    CFLAGS="$CFLAGS $MYSQL_CFLAGS"
+    AC_SUBST(MYSQL_LIBS)
+    AC_SUBST(MYSQL_CFLAGS)
+    AC_MSG_RESULT(...found ${MYSQL_VERSION})
+else
+    AC_MSG_RESULT(MySQL is not fully installed)
+    AC_MSG_CHECKING(if there at least are the needed MySQL client libs)
+    AC_CHECK_LIB(mysqlclient,mysql_close)
+    if test $ac_cv_lib_mysqlclient_mysql_close = no; then
+    
+        AC_MSG_ERROR(*** No MySQL client library found - See README ***)
+    else
+        AC_MSG_RESULT(found a usable libmysqlclient)
+    fi
+fi
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h syslog.h unistd.h])
+if ${MYSQL_CONFIG} --libs > /dev/null 2>&1
+then
+    AC_MSG_RESULT(mysql.h path defined in CFLAGS)
+else
+    AC_CHECK_HEADERS([mysql.h],MYSQL_INC="yes",AC_MSG_ERROR(*** MySQL include file mysql.h not found - See README ***))
+fi
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_FUNC_STRTOD
+AC_CHECK_FUNCS([memset select socket strrchr strtol])
+AC_CONFIG_FILES([Makefile src/Makefile])
+AC_OUTPUT
diff --git a/Davis/src/.cvsignore b/Davis/src/.cvsignore
new file mode 100644
index 0000000..5f7f600
--- /dev/null
+++ b/Davis/src/.cvsignore
@@ -0,0 +1,4 @@
+.deps
+Makefile
+Makefile.in
+db2APRS
diff --git a/Davis/src/CVS/Entries b/Davis/src/CVS/Entries
new file mode 100644
index 0000000..43b520a
--- /dev/null
+++ b/Davis/src/CVS/Entries
@@ -0,0 +1,5 @@
+/.cvsignore/1.1/Thu Jan 26 15:44:36 2006//
+/Makefile.am/1.9/Thu Nov  1 18:57:18 2012//
+/db2APRS.c/1.15/Thu Nov  1 18:57:18 2012//
+/defs.h/1.9/Thu Nov  1 18:57:18 2012//
+D
diff --git a/Davis/src/CVS/Repository b/Davis/src/CVS/Repository
new file mode 100644
index 0000000..18c0af6
--- /dev/null
+++ b/Davis/src/CVS/Repository
@@ -0,0 +1 @@
+xastir/Davis/src
diff --git a/Davis/src/CVS/Root b/Davis/src/CVS/Root
new file mode 100644
index 0000000..6a998ee
--- /dev/null
+++ b/Davis/src/CVS/Root
@@ -0,0 +1 @@
+:ext:we7u at xastir.cvs.sourceforge.net:/cvsroot/xastir
diff --git a/Davis/src/Makefile.am b/Davis/src/Makefile.am
new file mode 100644
index 0000000..546c1db
--- /dev/null
+++ b/Davis/src/Makefile.am
@@ -0,0 +1,14 @@
+# $Id: Makefile.am,v 1.9 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+
+bin_PROGRAMS = db2APRS
+noinst_PROGRAMS =
+
+db2APRS_SOURCES = \
+    db2APRS.c defs.h
+
+
+db2APRS_LINK=$(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+
diff --git a/Davis/src/db2APRS.c b/Davis/src/db2APRS.c
new file mode 100644
index 0000000..f97c41c
--- /dev/null
+++ b/Davis/src/db2APRS.c
@@ -0,0 +1,1132 @@
+/******************************************************************
+ *
+ * @(#)$Id: db2APRS.c,v 1.15 2012/11/01 18:57:18 we7u Exp $
+ *
+ * Copyright (C) 2004 Bruce Bennett <bruts at adelphia.net>
+ * Portions Copyright (C) 2004-2012 The Xastir Group
+ *
+ * (see the files README and COPYING for more details)
+ *
+ * This file implements all of the database to APRS daemon.
+ *
+ *
+    
+        Davis/Data Base Weather --> APRS Weather
+
+        Intended use: 
+		
+        Create & provide APRS style packet string
+        without position information from MySQL database
+        weather information stored there by meteo-0.9.4
+        (See http://meteo.othello.ch for source) to
+        xastir-1.2.1 (See http://www.xastir.org for source)
+
+        Note:  "meteo-0.9.x" is a weather data accumulator
+        aimed at Davis weather stations, which stores weather
+        data in a mysql database.  It is configured in two 
+        places, an XML file (default name meteo.xml) and in
+        the database named in the XML file (default database 
+        name is "meteo")		
+
+        Output is to the ip hostname:port required in the 
+        command line.
+
+    ACKNOWLEGEMENTS:
+
+        Elements of this software are taken from wx200d ver 1.2
+        by Tim Witham <twitham at quiknet.com>, and it is modeled
+        after that application. 
+
+*******************************************************************/
+#include <config.h>
+#include <defs.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <syslog.h>
+#include <errno.h>
+#include <getopt.h>
+#include <mysql.h>
+
+#define MAXARGS 20      /* maximum CGI args to parse */
+#define TMPLEN 128      /* max length of CGI */
+#define BUFLEN 32       /* max length of hostname:port */
+
+#define POLL_INTERVAL	90		// default polling interval
+
+#define VALID_WINDDIR   0x001
+#define VALID_WINDSPD   0x002
+#define VALID_WINDGST   0x004
+#define VALID_TEMP      0x008
+#define VALID_RAIN      0x010
+#define VALID_RAIN24H   0x020
+#define VALID_HUMIDITY  0x040
+#define VALID_AIRPRESS  0x080
+#define VALID_RAINDAY	0x100
+
+#define MTPS2MPH        2.2369
+#define DEGC2DEGF       1.8
+#define MM2IN100TH      3.937
+#define INHG2HPA10TH    338.638
+
+#define OUTDOOR_SENSOR  1
+
+    //---From the static table "mfield", which really should be dynamically read here---
+    //     (but then I couldn't use a switch statement)
+
+#define TEMPERATURE         0
+#define TEMPERATURE_MIN     1
+#define TEMPERATURE_MAX     2
+#define HUMIDITY            10
+#define HUMIDITY_MIN        11
+#define HUMIDITY_MAX        12
+#define WETNESS             20
+#define WETNESS_MIN         21
+#define WETNESS_MAX         22
+#define AIR_PRESSURE        30
+#define AIR_PRESSURE_MIN    31
+#define AIR_PRESSURE_MAX    32
+#define SOLAR               40
+#define UV                  41
+#define RAIN                50
+    // note: "51" is really rain total
+#define RAIN_PER_DAY        51
+#define RAIN_PER_HOUR       52
+#define WIND_SPEED          60
+#define WIND_DIRECTION      61
+#define WIND_GUST           62
+#define WIND_X              63
+#define WIND_Y              64
+#define MOISTURE            70
+#define WATERLEVEL          71
+#define WATERLEVEL_MIN      72
+#define WATERLEVEL_MAX      73
+#define BATTERY             110
+#define TRANSMITTER         111
+#define DURATION            120
+#define SAMPLES             121
+
+struct dbinfo {
+    char user[30];
+    char pswrd[15];
+    char name[30];
+} db;
+	
+char *progname;
+char *query;
+int *current = 0;
+
+int opt;
+
+MYSQL       mysql;    // Yeah, globals...
+MYSQL_RES   *result;
+MYSQL_ROW   row;
+
+char last_timestamp[20];
+char last_datetime[20];
+char death_msg[120];
+
+int debug_level;
+
+char wxAPRShost[BUFLEN];
+int wxAPRSport = PORT;
+int outdoor_instr = OUTDOOR_SENSOR;
+
+/******************************************************************
+1/4/2003
+            Usage brief
+
+*******************************************************************/
+void usage(int ret)
+{
+    if (query)
+        printf("Content-type: text/plain\nStatus: 200\n\n");
+    printf("usage: %s [options] \n",progname);
+    printf("VERSION: %s\n",VERSION);
+    printf("  -h    --help                      show this help and exit\n");
+    printf("  -v    --verbose                   debugging info --> stderr\n");
+    printf("  -c    --cport [port#]             IP port for data output\n");
+    printf("  -s    --sensor [sensor group#]    from meteo, your OUTDOOR sensor set\n");
+    printf("  -u    --user [database user]      username for mysql - default meteo\n");
+    printf("  -p    --password [db passwd]      password for mysql - default none\n");
+    printf("  -b    --database [database]       database name - default meteo\n");
+    printf("  -n    --nodaemon                  do not run as daemon\n");
+    printf("  -r    --repeat                    keep running\n");
+    printf("  -i    --interval [seconds]        polling interval\n");
+    printf("  -m    --metric                    data base is in metric units\n");
+    printf("options may be uniquely abbreviated; units are as defined in APRS\n"); 
+    printf("Specification 1.0.1 for positionless weather data (English/hPa).\n");
+    exit(ret);
+}
+
+
+
+
+
+/******************************************************************
+1/2/2003
+            Make an APRS string out of WX data
+
+*******************************************************************/
+
+int APRS_str(char *APRS_buf, 
+            char *datetime,
+            double winddir,
+            double windspeed,				
+            double windgust,
+            double temp,
+            double rain1hr,
+            double rain24hr,
+            double rainday,
+            double humidity,
+            double airpressure,
+            unsigned int valid_data_flgs,
+            int Metric_Data)
+{
+
+    int intval;
+    char pbuf[10];
+
+    if (APRS_buf == NULL) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Null string buffer for APRS string.\n");
+        return -1;  //  Ooo!!  *****Nasty Bad Exit Point Here****
+
+    }
+//  timestamp first
+    sprintf(APRS_buf, "_%s",datetime);
+//
+    if(valid_data_flgs & VALID_WINDDIR) {
+        intval = (winddir + 0.5); // rounding to whole degrees
+        if (intval > 360) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind direction > 360\n");
+            sprintf(APRS_buf, "c...");
+        } 
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind direction negative\n");
+            sprintf(APRS_buf, "c...");
+
+        } 
+        else {
+        sprintf(pbuf, "c%0.3d", intval);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Wind direction flagged as invalid\n");
+        sprintf(pbuf, "c...");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_WINDSPD) {
+        if (Metric_Data)
+            intval = (windspeed*MTPS2MPH + 0.5); // converting & rounding to whole MPH 
+        else
+            intval = (windspeed + 0.5); // rounding to whole MPH
+        if (intval > 600) { // Let's be reasonable here - center of a tornado??
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind speed > 600 MPH\n");
+            sprintf(pbuf, "s...");
+
+        }
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind speed negative\n");
+            sprintf(pbuf, "s...");
+
+        }
+        else {
+            sprintf(pbuf, "s%0.3d", intval);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Wind speed flagged as invalid\n");
+        sprintf(pbuf, "s...");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_WINDGST) {
+        if (Metric_Data)
+            intval = (windgust*MTPS2MPH + 0.5); // converting & rounding to whole MPH
+        else
+            intval = (windgust + 0.5); // rounding to whole MPH
+        if (intval > 600) { // Let's be reasonable here - center of a tornado??
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind gust > 600 MPH\n");
+            sprintf(pbuf, "g...");
+
+        }
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind speed negative\n");
+            sprintf(pbuf, "g...");
+
+        } 
+        else {
+            sprintf(pbuf, "g%0.3d", intval);
+        }
+
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Wind speed flagged as invalid\n");
+        sprintf(pbuf, "g...");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_TEMP) {
+        if (Metric_Data)
+            intval = ((temp)*DEGC2DEGF + 0.5)+32; // converting & rounding to whole Deg F
+        else
+            intval = (temp + 0.5); // rounding to whole Deg F
+        if (intval > 200) { // Let's be reasonable here - boiling?
+            if (debug_level & 1)
+                fprintf(stderr,"err: Temperature > 200 Deg F\n");
+            sprintf(pbuf, "t...");
+        }
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Temperature < -99 Deg F\n");
+            sprintf(pbuf, "t...");
+        }
+        else {
+            if (intval < 0) sprintf(pbuf,"t%0.2d",intval);
+            else sprintf(pbuf, "t%0.3d", intval);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Temperature flagged as invalid\n");
+        sprintf(pbuf, "t...");
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_RAIN) {
+        if (Metric_Data)
+            intval = ((rain1hr)*MM2IN100TH + 0.5); // converting & rounding to whole 1/100 inch
+        else
+            intval = (rain1hr*100.0 + 0.5); // rounding to whole 1/100 inch
+        if (intval > 999) { // 10 in/hr? Garden Hose -> rain gauge?
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/Hr > 9.99 inch\n");
+            sprintf(pbuf, "\0\0\0\0");
+        }
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/Hr negative\n");
+            sprintf(pbuf, "\0\0\0\0");
+        }
+        else {
+            sprintf(pbuf, "r%0.3d", intval);
+        }
+    }
+    else {
+
+        if (debug_level & 1)
+            fprintf(stderr,"info: Rainfall/Hr flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_RAIN24H) {
+        if (Metric_Data)
+            intval = ((rain24hr)*MM2IN100TH + 0.5); // converting & rounding to whole 1/100 inch
+        else
+            intval = (rain24hr*100.0 + 0.5); // rounding to whole 1/100 inch
+        if (intval > 999) { // Can't handle greater than 9.99 inches of rain in 24 hours
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/24Hr > 9.99 inch - reporting 9.99 inches\n");
+            sprintf(pbuf, "p999");
+
+        }
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/Hr negative\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        }
+        else {
+            sprintf(pbuf, "p%0.3d", intval);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Rainfall/24Hr flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_RAINDAY) {
+        if (Metric_Data)
+            intval = ((rainday)*MM2IN100TH + 0.5); // converting & rounding to whole 1/100 inch
+        else
+            intval = (rainday*100.0 + 0.5); // rounding to whole 1/100 inch
+        if (intval > 999) { // Can't handle greater than 9.99 inches of rain per day
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/day > 9.99 inch - reporting 9.99 inches\n");
+            sprintf(pbuf, "P999");
+        }
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/day negative\n");
+            sprintf(pbuf, "\0\0\0\0");
+        }
+        else {
+            sprintf(pbuf, "P%0.3d", intval);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Rainfall/day flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_HUMIDITY) {
+        intval = (humidity + 0.5); // rounding to whole percent
+        if (intval > 100) { // Unlike the space shuttle engines, 100 % is max
+            if (debug_level & 1)
+                fprintf(stderr,"err: Humidity reported > 100%\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        }
+        else if (intval < 1) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Humidity reported < 1%\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        }
+        else {
+            if (intval == 100) intval = 0;  // Report 100% as 'h00'
+            sprintf(pbuf, "h%0.2d", intval);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Humidity flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_AIRPRESS) {
+        if (Metric_Data)
+            intval = (airpressure*10.0 + 0.5); //  rounding to whole tenth of a hPa
+        else
+            intval = (airpressure*INHG2HPA10TH + 0.5); // convering In-Hg to 1/10 hPa and rounding
+        if (intval > 20000) { //two atmospheres - about 29 PSIA
+            if (debug_level & 1)
+                fprintf(stderr,"err: Air Pressure reported > 2 Atmospheres%\n");
+                sprintf(pbuf, "\0\0\0\0");
+        }
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Air Pressure reported negative%\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else {
+            sprintf(pbuf, "b%0.5d", intval);
+        }
+    } else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Air Pressure flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+    strcat(APRS_buf,"xDvs\n");  // add X aprs and Davis WX station ID's and <lf>
+
+    if (debug_level & 1)
+        fprintf(stderr,"\ninfo: APRS Version of WX - %s\n\n",APRS_buf);
+    return strlen(APRS_buf);
+}
+
+
+
+
+
+/******************************************************************
+1/2/2003
+            Get the latest set of Weather Data from the Data Base
+
+*******************************************************************/
+
+int Get_Latest_WX( double *winddir,
+                double *windspeed,				
+                double *windgust,
+                double *temp,
+                double *rain1hr,
+                double *rain24hr,
+                double *rainday,
+                double *humidity,
+                double *airpressure,
+                unsigned int *valid_data_flgs)
+{
+    long last_hour_timestamp;
+    long int last_24_timestamp;
+    long int last_day_timestamp;
+    char query_buffer[240];
+    int nrows, row_cnt, item_count;
+    int found_sensor;
+    long local_offset;  // could be as big as 12 hrs times 3600 seconds...
+
+    // Find latest, see if it's new to us
+    // --new to us is a simple timestamp follower, so upon startup
+    // it will always read one set of data, assuming any exists
+
+    if (mysql_query(&mysql, "SELECT MAX(timekey) from sdata")) {
+        sprintf(death_msg,"err: Latest timestamp query failed - exiting: %s\n", mysql_error(&mysql));
+        if (debug_level & 1){
+            fprintf(stderr,"%s",death_msg);
+        }
+        return -1;
+    }
+ 
+     if (!(result = mysql_store_result(&mysql))) {
+         sprintf(death_msg,"err: Latest timestamp query failed - exiting: %s\n", mysql_error(&mysql));
+         if (debug_level & 1){
+             fprintf(stderr,"%s",death_msg);
+         }
+         return -1;
+    }
+
+    if (mysql_num_rows(result) != 1 ) {
+        sprintf(death_msg,"err: Latest timestamp query failed - exiting: number of results %d\n",
+                mysql_num_rows(result));
+        if (debug_level & 1){
+            fprintf(stderr,"%s",death_msg);
+        }
+         // release query buffer
+        mysql_free_result(result);
+        return -1;
+    }
+
+    row = mysql_fetch_row(result);
+
+     if( row[0] == NULL ) {
+         sprintf(death_msg,"err: NULL result for timestamp query\n");
+         if (debug_level & 1){
+             fprintf(stderr,"%s",death_msg);
+         }
+        // release query buffer
+        mysql_free_result(result);
+        return -1;
+    }
+    // if no new data, exit with zero status
+
+    if (!strncmp(last_timestamp, row[0], 11)) {
+        if (debug_level & 1)
+            fprintf(stderr,"info: No new weather data recorded - exiting: no data\n");
+        // release query buffer
+        mysql_free_result(result);
+        return 0;
+    }
+    strcpy(last_timestamp, row[0]);	  // For next pass & following query
+        
+    if( debug_level & 1) fprintf(stdout,"Timestamp: %s\n",last_timestamp);
+
+    // release query buffer
+    mysql_free_result(result);
+
+    sprintf(query_buffer,"SELECT value,sensorid,fieldid,from_unixtime(timekey,'%%m%%d%%H%%i%%S') FROM sdata WHERE timekey = %s", last_timestamp);
+
+    if (mysql_query(&mysql, query_buffer)) {
+        sprintf(death_msg,"err: Latest Weather Data query failed - exiting: %s\n\t --Query: %s\n", 
+                mysql_error(&mysql), query_buffer);
+        if (debug_level & 1){
+            fprintf(stderr,"%s",death_msg);
+        }
+        return -1;
+    }
+
+    if (!(result = mysql_store_result(&mysql))) {
+        sprintf(death_msg,"err: Latest Weather Data query failed - exiting: %s\n", mysql_error(&mysql));
+        if (debug_level & 1){
+            fprintf(stderr,"%s",death_msg);
+        }
+        return -1;
+    }
+    if ((nrows=mysql_num_rows(result)) < 1 ) {
+        sprintf(death_msg,"err: Latest Weather Data query failed - exiting: number of results %d\n",nrows);
+        if (debug_level & 1){
+            fprintf(stderr,"%s",death_msg);
+        }
+        // release query buffer
+        mysql_free_result(result);
+        return -1;
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Latest Weather Data query: number of types of readings %d\n",nrows);
+    }
+
+    *valid_data_flgs = 0;
+    item_count = 0;
+    for (row_cnt = 0; row_cnt < nrows; row_cnt++) {
+        row = mysql_fetch_row(result);
+        strcpy(last_datetime,row[3]);
+
+        if(atoi(row[1]) == outdoor_instr) {	 // sensors are really groups of data
+            found_sensor = atoi(row[1]);
+            if(debug_level & 1)
+                fprintf(stderr,"info: found an outdoor sensor: (%d) ",found_sensor);
+            
+            switch (atoi(row[2]))  {  // type of reading
+                case WIND_DIRECTION :
+                    *winddir = strtod(row[0],NULL);
+                    *valid_data_flgs |= VALID_WINDDIR;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"wind direction %f\n ",*winddir);
+                    break;
+                case WIND_SPEED : 
+                    *windspeed = strtod(row[0],NULL);
+                    *valid_data_flgs |= VALID_WINDSPD;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"wind speed %f\n ",*windspeed);
+                    break;
+                case WIND_GUST :
+                    *windgust = strtod(row[0],NULL); 
+                    *valid_data_flgs |= VALID_WINDGST;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"wind gust speed %f\n ",*windgust);
+                    break;
+                case TEMPERATURE :
+                    *temp = strtod(row[0],NULL);
+                    *valid_data_flgs |= VALID_TEMP;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"temperature %f\n ",*temp);
+                    break;
+                case HUMIDITY :
+                    *humidity = strtod(row[0],NULL);
+                    *valid_data_flgs |= VALID_HUMIDITY;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"humidity %f\n ",*humidity);
+                    break;
+                case AIR_PRESSURE :
+                    *airpressure = strtod(row[0],NULL);
+                    *valid_data_flgs |= VALID_AIRPRESS;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"air pressure %f\n ",*airpressure);
+                    break;
+                case RAIN_PER_DAY :
+                    if(debug_level & 1)
+                        fprintf(stderr,"rain-per-day total (not used), now calculated...\n ");
+                    break;
+                case WIND_X :
+                   if(debug_level & 1)
+                       fprintf(stderr,"wind x... not used \n");
+                   break;
+                case WIND_Y :
+                   if(debug_level & 1)
+                       fprintf(stderr,"wind y... not used \n");
+                   break;
+                case DURATION :
+                   if(debug_level & 1)
+                      fprintf(stderr,"duration... not used \n");
+                   break;
+                case SAMPLES :
+                   if(debug_level & 1)
+                      fprintf(stderr,"samples... not used \n");
+                   break;
+                default :
+                    if(debug_level & 1) fprintf(stderr,"unknown field %s\n",row[2]);
+                    break;
+            }
+        }
+        else {      // Must be indoor
+            if (debug_level & 1) fprintf(stderr,"info: indoor sensor found\n");
+            switch (atoi(row[2]))  {  // type of reading
+                case AIR_PRESSURE :
+                    *airpressure = strtod(row[0],NULL);
+                    *valid_data_flgs |= VALID_AIRPRESS;
+                    item_count++;
+                    if(debug_level & 1)
+                        fprintf(stderr,"air pressure %f\n ",*airpressure);
+                    break;
+                 default :
+                    if(debug_level & 1) fprintf(stderr,"unused field %s\n",row[2]);
+                    break;
+            }
+        }
+    }
+
+    if(debug_level & 1) fprintf(stderr,"loop ends\n");
+    // release query buffer
+    mysql_free_result(result);
+
+    /*        get rain figures	*/
+    /*
+    /*        hourly first		*/
+    last_hour_timestamp = atol(last_timestamp) - 3600;
+    sprintf(query_buffer,"SELECT round(sum(value),2) FROM sdata WHERE timekey > %ld and fieldid = %d", last_hour_timestamp,RAIN);
+
+    if (mysql_query(&mysql, query_buffer)) {
+        sprintf(death_msg,"err: rain 1 hour query failed - exiting: %s\n\t --Query: %s\n", mysql_error(&mysql), query_buffer);
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+     }
+    if (!(result = mysql_store_result(&mysql))) {
+        sprintf(death_msg,"err: rain 1 hour store failed - exiting: %s\n", mysql_error(&mysql));
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if ((mysql_num_rows(result)) > 0) {
+        row = mysql_fetch_row(result);
+        if (row[0] != NULL) {
+            *rain1hr = strtod(row[0],NULL);
+            if(debug_level & 1) fprintf(stderr,"rain last hour %f\n ",*rain1hr);
+            // *rain1hr = *rain1hr * 100;  // AFTER metric conversion if needed
+            *valid_data_flgs |= VALID_RAIN;
+            item_count++;
+        }
+        else {
+            *rain1hr = 0;
+            *valid_data_flgs |= VALID_RAIN;   //None, but valid
+            if(debug_level & 1) fprintf(stderr,"no rain recorded in last hour\n");
+        }
+    }     
+    // release query buffer
+    mysql_free_result(result);
+
+/*    Last 24 hours    */
+
+    last_24_timestamp = atol(last_timestamp) - 86400;
+    sprintf(query_buffer,"SELECT round(sum(value),2) FROM sdata WHERE timekey > %ld and fieldid = %d", last_24_timestamp,RAIN);
+
+    if (mysql_query(&mysql, query_buffer)) {
+        sprintf(death_msg,"err: rain 24 hour query failed - exiting: %s\n\t --Query: %s\n", mysql_error(&mysql), query_buffer);
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if (!(result = mysql_store_result(&mysql))) {
+        sprintf(death_msg,"err: rain 24 hour store failed - exiting: %s\n", mysql_error(&mysql));
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if ((mysql_num_rows(result)) > 0) {
+        row = mysql_fetch_row(result);
+        if (row[0] != NULL) {
+            *rain24hr = strtod(row[0],NULL);
+            if(debug_level & 1) fprintf(stderr,"rain last 24 hours %f\n ",*rain24hr);
+            //*rain24hr = *rain24hr * 100;	   // After metric conversion, if needed
+            item_count++;
+            *valid_data_flgs |= VALID_RAIN24H;
+        }
+        else {
+           *rain24hr = 0;
+           *valid_data_flgs |= VALID_RAIN24H;   // Zero is valid too
+           if(debug_level & 1) fprintf(stderr,"no rain recorded in last 24 hours\n");
+        }
+    }     
+    // release query buffer
+    mysql_free_result(result);
+#define CALC_MIDNIGHT
+#ifdef CALC_MIDNIGHT
+    // Timestamps are seconds since midnight Jan 1 1970, so an integer divide and multiply by 
+    // seconds in 24 hrs (86400) yields the latest midnight time stamp value.
+    last_day_timestamp = (atol(last_timestamp) / 86400)*86400;
+    if(debug_level & 1)
+        fprintf(stderr,"info: timestamp for prior midnight - %ld\n",last_day_timestamp);
+    sprintf(query_buffer,"SELECT offset FROM station WHERE id = (SELECT stationid from sensor WHERE id = %d)", found_sensor);
+    if (mysql_query(&mysql, query_buffer)) {
+        sprintf(death_msg,"err: station time offset query failed - exiting: %s\n\t --Query: %s\n", mysql_error(&mysql), query_buffer);
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if (!(result = mysql_store_result(&mysql))) {
+        sprintf(death_msg,"err: station time offset store failed - exiting: %s\n", mysql_error(&mysql));
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if ((mysql_num_rows(result)) > 0) {
+        row = mysql_fetch_row(result);
+        if (row[0] != NULL) {
+            local_offset = atol(row[0]);
+            if (debug_level & 1) fprintf(stderr,"info: station time offset: %ld\n", local_offset);
+        }
+    }
+    mysql_free_result(result);
+#else
+
+/*    since midnite    */
+
+/*    we can get the timestamp for midnite from the avg table		*/
+    last_day_timestamp = 0;
+    sprintf(query_buffer,"SELECT max(timekey) FROM avg WHERE fieldid = %d and intval = 86400", last_hour_timestamp,RAIN);
+    if (mysql_query(&mysql, query_buffer)) {
+        sprintf(death_msg,"err: midnite timekey query failed - exiting: %s\n\t --Query: %s\n", mysql_error(&mysql), query_buffer);
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if (!(result = mysql_store_result(&mysql))) {
+        sprintf(death_msg,"err: midnite timekey store failed - exiting: %s\n", mysql_error(&mysql));
+        if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+        return -1;
+    }
+    if ((mysql_num_rows(result)) > 0) {
+        row = mysql_fetch_row(result);
+        if (row[0] != NULL) {
+            last_day_timestamp = strtod(row[0],NULL);
+        }
+    }
+    mysql_free_result(result);
+#endif
+
+    if (last_day_timestamp > 0) {
+#ifndef CALC_MIDNIGHT
+        last_day_timestamp += 115200;	// add 8 hours for offset - this should really be queried
+#else
+        last_day_timestamp -= local_offset; // From the database
+#endif
+        sprintf(query_buffer,"SELECT round(sum(value),2) FROM sdata WHERE timekey > %ld and fieldid = %d", last_day_timestamp,RAIN);
+        if (mysql_query(&mysql, query_buffer)) {
+            sprintf(death_msg,"err: rain last day query failed - exiting: %s\n\t --Query: %s\n", mysql_error(&mysql), query_buffer);
+            if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+            return -1;
+        }
+        if (!(result = mysql_store_result(&mysql))) {
+            sprintf(death_msg,"err: rain last day store failed - exiting: %s\n", mysql_error(&mysql));
+            if (debug_level & 1) fprintf(stderr,"%s",death_msg);
+            return -1;
+        }
+        if ((mysql_num_rows(result)) > 0) {
+            row = mysql_fetch_row(result);
+            if (row[0] != NULL) {
+                *rainday = strtod(row[0],NULL);
+                if(debug_level & 1) fprintf(stderr,"rain since midnite %f\n ",*rainday);
+                // *rainday = *rainday * 100;  // AFTER metric conversion, if needed.
+                item_count++;
+                *valid_data_flgs |= VALID_RAINDAY;
+            }
+            else {
+                *rainday = 0;
+                *valid_data_flgs |= VALID_RAINDAY;  // None is valid...
+                if(debug_level & 1) fprintf(stderr,"no rain recorded in last 24 hours\n");
+            }
+        }
+
+        // release query buffer (where used)
+        mysql_free_result(result);
+
+    }
+    if (debug_level & 1) 
+        fprintf(stderr,"info: success - Weather Data number of reading types %d\n",item_count);
+
+    return item_count;
+}
+
+
+
+
+
+/******************************************************************
+1/5/2003
+            SIGPIPE signal handler
+
+*******************************************************************/
+void pipe_handler(int sig)		/*  */
+{
+    signal(SIGPIPE, SIG_IGN);
+    if (sig == SIGPIPE) {		// client went bye-bye
+        shutdown(*current, 2); 
+        close(*current);
+        *current = -1;
+        if (debug_level & 1)
+            fprintf(stderr, "info: %s - TCP client timed out", progname); 
+    }
+}
+
+
+
+
+
+/******************************************************************
+1/5/2003
+            SIGTERM signal handler
+
+*******************************************************************/
+void term_handler(int sig)
+{
+    if (debug_level & 1)
+        fprintf(stderr, "info: %s - ordered to DIE, complying", progname);
+
+    // release query buffer	& close connection
+    mysql_free_result(result);
+
+    mysql_close(&mysql);
+
+    exit( 0 );
+}
+
+
+
+
+
+/******************************************************************
+1/2/2003
+        Coordinating MAIN point
+
+*******************************************************************/
+int main(int argc, char **argv)
+{
+    const char *flags = "Hhvnmrc:u:p:d:s:i:";
+    char WX_APRS[120];
+    char logstr[80];
+    int data_len = 0 ;
+    double winddir;
+    double windspeed;				
+    double windgust;
+    double temp;
+    double rain1hr;
+    double rain24hr;
+    double rainday;
+    double humidity;
+    double airpressure;
+    unsigned int valid_data_flgs;
+    int Metric_Dat, dsts = 0;
+    int  pid, s, fd[CONNECTIONS];
+    socklen_t clen = sizeof(struct sockaddr_in);
+    int *max = 0,  c;
+    int not_a_daemon = 0, repetitive = 0, tcp_wx_port = PORT;
+    int  i, index = 0;
+    struct sockaddr_in server, client;
+    struct in_addr bind_address;
+    fd_set rfds;
+    struct timeval tv;
+    int poll_interval = POLL_INTERVAL;
+    int dly_cnt = 1;
+    FILE *pidfile;
+    const char *pidfilename = "/var/run/db2APRS.pid";
+    char cmd[120];
+
+    struct option longopt[] = {
+        {"help", 0, 0, 'h'},
+        {"refresh", 0, 0, 'r'},
+        {"verbose", 0, 0, 'v'},
+        {"user", 1, 0, 'u'},
+        {"password", 1, 0, 'p'},
+        {"database", 1, 0, 'd'},
+        {"cport", 1, 0, 'c'},
+        {"sensor",1, 0, 's'},
+        {"nodaemon", 0, 0, 'n'},
+        {"interval",1, 0, 'i'},
+        {"metric",0, 0, 'm'},
+        {0, 0, 0, 0}
+    };
+
+    debug_level = 0;
+
+    strcpy(db.user,"meteo");	 // set default values for database access
+    strcpy(db.name,"meteo");
+    memset(db.pswrd,0,15);
+
+    mysql_init(&mysql);
+
+
+    progname = strrchr(argv[0], '/');
+    if (progname == NULL)
+        progname = argv[0];
+    else
+        progname++;
+
+    while ((opt = getopt_long(argc, argv, flags, longopt, &index)) != EOF) { 
+        switch (opt) {        /* parse command-line or CGI options */
+            case 'r':
+                repetitive = 1;
+                break;
+            case 'v':
+                fprintf(stdout,"Verbose mode set:\n");
+                debug_level = 1;
+                break;
+            case 'u':      // mysql username 
+                strncpy(db.user,(char *)optarg,30);
+                break;
+            case 'p':      // mysql password 
+                strncpy(db.pswrd,(char *)optarg,15);
+                break;
+            case 'd':      // mysql database name
+                strncpy(db.name,(char *)optarg,30);
+                break;
+            case 'n':       /* do not fork and become a daemon */
+                not_a_daemon = 1;
+                break;
+            case 'c':       /* port to use */
+                tcp_wx_port = strtol(optarg, NULL, 0);
+                break;
+            case 's':                   /* sensor number for outdoor data */
+                outdoor_instr  = atoi(optarg);
+                break;
+            case 'i':                   /* polling interval in seconds */
+                poll_interval  = atoi(optarg);
+                break;
+            case 'm':                   // Metric data from data base
+                Metric_Dat = 1;
+                break;
+            case '?':
+            case 'h':
+            case 'H':
+                usage(0);
+                break;
+            default :
+                usage(1);
+        }
+    }
+    if (debug_level & 1) {
+        fprintf(stdout,"Starting...");
+        if (repetitive) fprintf(stdout, " forever ");
+        else fprintf(stdout, " one pass only ");
+        fprintf(stdout," with  database user=%s, password=%s, for database=%s\n",
+            db.user, db.pswrd, db.name);
+        if(not_a_daemon) fprintf(stdout," as a program ");
+        else fprintf(stdout," as a daemon ");
+        fprintf(stdout, " using TCP port %d\n",tcp_wx_port);
+        fprintf(stdout, "an with an outdoor sensor group number of %d\n",outdoor_instr);
+    }
+
+    if (!not_a_daemon) {            /* setup has worked; now become a daemon? */
+
+        if ((pid = fork()) == -1) {
+            syslog(LOG_ERR, "can't fork() to become daemon: %m"); 
+            exit(20);
+        }
+        else if (pid) {
+            pidfile = fopen(pidfilename, "w");
+            fprintf(pidfile,"%d\n",pid);
+            fclose(pidfile);
+            exit (0);
+        }
+        syslog(LOG_ERR, "Started\n"); 
+        setsid();
+        for (i = 0; i < NOFILE; i++) if ( i != s) close(i);
+    }
+
+         // Data base connection
+
+
+    if (!(mysql_real_connect(&mysql, "localhost", db.user, db.pswrd, db.name, 0, NULL, 0))) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Data Base connect for user:%s to database:%s failed - exiting: \n\t%s\n",
+                    db.user, db.name, mysql_error(&mysql));
+        exit(9);
+    }
+
+    server.sin_family = AF_INET;
+    bind_address.s_addr = htonl(INADDR_ANY);
+    server.sin_addr = bind_address;
+    server.sin_port = htons(tcp_wx_port);
+
+    if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+        if (debug_level & 1)
+            fprintf(stderr, "err: %s - no socket", progname);
+        exit(10);
+    }
+    /* <dirkx at covalent.net> / April 2001 Minor change to allow quick
+     * (re)start of deamon or client while there are pending
+     * conncections during the quit. To avoid addresss/port in use
+     * error.  */
+    i = 1;
+    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) == -1) {
+    if (debug_level & 1)
+        fprintf(stderr, "err: %s - setsockopt", progname);
+    }
+    if (bind(s, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) {
+        if (debug_level & 1)
+            fprintf(stderr, "err: %s - cannot bind to socket", progname);
+        exit(11);
+    }
+    if (listen(s, CONNECTIONS) == -1) {
+        if (debug_level & 1)
+            fprintf(stderr, "err: %s - listen", progname);
+        exit(12);
+    }
+
+    if (debug_level & 1)
+        fprintf(stdout,"Sockets UP.\n");
+
+    umask(0022);
+    for (i = 0; i < CONNECTIONS; i++) fd[i] = -1;
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+
+
+    /* catch signals to close the database connection */
+    signal( SIGTERM, term_handler );/* termination */
+#if defined(SIGPWR) /* SIGPWR is linux centric */
+    signal( SIGPWR, term_handler ); /* power failure */
+#endif
+    if (debug_level & 1) fprintf(stdout,"Main Loop...\n");
+    dly_cnt = 2; // initial delay
+    do {
+        if(!(dly_cnt--)) {
+            dly_cnt = poll_interval;    // Every 'dly_cnt' passes check for WX data update
+            dsts = Get_Latest_WX(&winddir,&windspeed,&windgust,
+                &temp,&rain1hr,&rain24hr,&rainday,&humidity,&airpressure, &valid_data_flgs);
+            if ( dsts < 0 ) {
+                if (debug_level & 1) fprintf(stderr, "err: Get_Latest returned %d\n",dsts);
+                syslog(LOG_ERR,death_msg);
+                exit(dsts);
+            }
+            // If no new data, make no new string either...
+            if(dsts)
+            {
+                data_len = APRS_str(WX_APRS, last_datetime, winddir,windspeed,windgust,
+                    temp, rain1hr, rain24hr, rainday, humidity, airpressure, 
+                    valid_data_flgs,Metric_Dat);
+
+                if (!data_len) {
+                    if (debug_level & 1)
+                        fprintf(stderr, "err: WX info formatting problem!");
+                    syslog(LOG_ERR,"WX Data format error\n");
+                    exit(13);
+                 }
+            } else if (debug_level & 1)
+                 fprintf(stderr,"Found no new data this pass...\n");
+        }
+        FD_ZERO(&rfds);
+        FD_SET(s, &rfds);
+        if (select(s + 1, &rfds, NULL, NULL, &tv) > 0) {
+            for (current = fd; (*current > 0) && (current < fd + CONNECTIONS - 1); current++);
+            if (current > max) max = current;
+            if ((*current = accept(s, (struct sockaddr *)&client, &clen)) != -1)
+                write(*current, WX_APRS, data_len);
+        }
+        if (dly_cnt == poll_interval) {
+            if (debug_level & 1) fprintf(stdout,"Updating clients:");
+            for (current = fd; current <=max; current++)
+            if (*current > 0) {   // active socket
+                if (debug_level & 1) fprintf(stdout," #");
+                signal(SIGPIPE, pipe_handler);
+                write(*current, WX_APRS, data_len);
+        }
+        if (debug_level & 1) fprintf(stdout," done\n");
+        }
+        sleep(1);
+    } while (repetitive);
+
+    mysql_close(&mysql);
+
+    if (debug_level & 1) fprintf(stdout,"Exiting normally.\n");
+    syslog(LOG_ERR,"Terminated normally\n");
+    exit(0);
+}
diff --git a/Davis/src/defs.h b/Davis/src/defs.h
new file mode 100644
index 0000000..ad2dfa4
--- /dev/null
+++ b/Davis/src/defs.h
@@ -0,0 +1,14 @@
+
+// $Id: defs.h,v 1.9 2012/11/01 18:57:18 we7u Exp $
+//
+// Copyright (C) 2004 Bruce Bennett <bruts at adelphia.net>
+// Portions Copyright (C) 2004-2012 The Xastir Group
+//
+//
+// Dummy info here for now...
+//
+
+
+#define PORT	1313
+#define CONNECTIONS	20
+#define NOFILE		20
diff --git a/FAQ b/FAQ
new file mode 100644
index 0000000..91f41c5
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,1270 @@
+                  Xastir Frequently Asked Questions
+
+$Id: FAQ,v 1.89 2012/11/01 18:57:18 we7u Exp $
+
+The latest version of this FAQ is always available from the Xastir
+project's CVS repository on SourceForge, at
+<http://xastir.cvs.sourceforge.net/xastir/xastir/FAQ?&view=auto>.
+
+The Questions
+-------------
+
+1.  Background
+
+    1.1 What is Xastir?
+    1.2 How and why was Xastir created?
+    1.3 Why the name "Xastir"?
+    1.4 OK, so how does Xastir compare to other APRS(tm) clients?
+    1.5 How thoroughly tested is Xastir?
+    1.6 Whom do I contact for support?
+    1.7 Where can I submit Bug reports or feature requests?
+    1.8 Is there any more information on Xastir?
+    1.9 Where can I get Xastir?
+
+2.  General Technical Questions
+
+    2.1 "Why can't I...? Why won't...work?" What to do in case of problems
+    2.2 How do I submit a patch to the Xastir Development Group?
+    2.3 What's the best hardware/operating system/...
+    2.4 Why isn't there a binary for my platform?
+
+3.  Building Xastir
+
+    3.1  Why do I get error messages when running "bootstrap.sh"?
+    3.1a  Why do I get strange warnings when I run bootstrap.sh?
+    3.2 Why won't Xastir compile with my system's cc?
+    3.3 I'm using gcc and I get some compilation errors, what is wrong?
+    3.4 The linking stage is failing because it isn't linking in the
+        freetype library.  What to do?
+    3.5 During the linking stage, it's giving me "undefined reference to
+        `CompressImageColormap'".  What to do?
+    3.6 Some of the text looks strange, writes over itself and other
+        user interface weirdness occurs.  Why?
+    3.7 Why isn't ImageMagick recognized and used during Xastir's
+        "configure" stage?
+    3.8 Why do I get an error now when trying to do a "cvs update"?
+    3.9 Why does compilation of map_geo, map_WMS or map_tiger fail with "invalid operands to binary <<" errors?
+
+4.  Running Xastir
+
+    4.1 Why do I get wrong texts in menus or other places when using a
+        non-English language file?
+    4.2 I run Xastir under Linux, and I get an error about loading a shared
+        library.
+    4.3 I run Xastir under Linux, and try to set up an ax25 device, but get a
+        "Hard Fail" error on the interface. There is a "permission denied" error
+        in the terminal from which I started Xastir.
+    4.4 I run Xastir, and get on the air, but nobody else sees me on their screens.
+    4.5 I run Xastir, and get on the air, but none of the other stations
+        appear on my screen?
+    4.6 Who is this APX190 guy who all my stuff is getting sent to? Who are these
+        RELAY, WIDE and TRACE people digipeating packets, and why are they putting
+        different callsigns in the fields where their names used to be? Why
+        doesn't anyone answer me when I connect to them? HELP!!!
+    4.7 When weather alerts come in, the counties on my map don't highlight.
+    4.8 I have geoTIFF support compiled and working, but when I select a map, it
+        gives me a -38 error converting the datum, and it doesn't display in the
+        right place.
+    4.9 Xastir runs slowly/loads maps slowly.
+    4.10 I installed a new version of lesstif, but the help menu shows the old
+         version.
+    4.11 Why does Xastir seg-fault sometimes when indexing or loading
+         geoTIFF images?
+    4.12 Why doesn't Xastir run on RedHat 9.0 properly?
+    4.13 Why do I see "Character '\55' not supported in font"?
+    4.14 Why do I see strong blue tinting for the maps?
+    4.15 My config file got munged.  How do I recover?
+    4.16 Why can't I set my position in Xastir correctly?
+    4.17 Why do I get black map images when I use ImageMagick?
+    4.18 Why does my MacOSX machine w/USB->Serial adapters hang?
+    4.19 Why do NumLock/ScrollLock/CapsLock interfere with mouse/keyboard operation?
+    4.20 How to I redirect serial ports from one computer to another?
+    4.21 I have Festival compiled in, but I can't get any speech, why?
+    4.22 ImageMagick gives me: "no decode delegate", why?
+    4.23 How do I get through an http proxy server with Xastir in
+         order to fetch maps?
+    4.24 Can I run multiple copies of Xastir at once?
+    4.25 Why doesn't Terraserver work for some locations?
+    4.26 Some station or config settings are not getting saved, why?
+    4.27 Why are my colors messed up when running via VNC?
+    4.28 Why are the labels missing in the Configure->Timing dialog?
+    4.29 Xastir can't find "xastir.rgb" or some other file.  What's wrong?
+    4.30 Why can't I see station trails as stations move around?
+    4.31 Why don't the maps I installed show up in the Map Chooser?
+    4.32 Dialogs are tiny bullet-shaped windows with no handles.  Why?
+    4.33 Fedora 12 right-click menus don't work.
+    4.34 What about using Xastir with a TNC-X with built-in USB on a Mac?
+    4.35 Why do I get "Bitmap not found? /usr/share/xastir/symbols/2x2.xbm"
+
+5.  Features
+
+    5.1  Why doesn't Xastir include <insert your feature here>?
+
+    5.2  Why doesn't Xastir digipeat packets sent to the RELAY or
+         WIDE1-1 aliases?
+
+    5.3  How do I take a snapshot of my current view? 
+
+    5.4  What is that yellow circle on my map?
+
+    5.5 How can I restart Xastir remotely/from a script/command-line?
+
+
+The Answers
+-----------
+
+1. Background
+
+    1.1 What is Xastir?
+
+
+    Xastir is an APRS(tm) client program that uses amateur radio and Internet
+    services to convey GPS mapping, weather, and positional data in a graphical
+    application.  It has been developed by and for amateur radio enthusiasts to
+    provide real-time data in an easy to use package.
+
+    1.2 How and why was Xastir created?
+
+    There were already several APRS(tm) client programs available to the
+    Mac/DOS world when Frank Giannandrea, KC2GJS decided to develop
+    a Unix client using X Window's and the Motif/LessTiff widget set.
+    From its meager beginnings, Xastir is now a very robust client that
+    meets the needs of the Ham community.
+
+    1.3  Why the name Xastir?
+
+    Xastir is an acronym for X Amateur Station Tracking and Information
+    Reporting.  Besides it sounds much cooler that those other names ;)
+
+    1.4 OK, so how does Xastir compare to other APRS(tm) clients?
+
+    Being actively developed by and for Hams, Xastir is constantly being
+    improved upon to reflect the changing state of APRS(tm).  Xastir has
+    all the functionality you would find in any other APRS(tm) client,
+    from any OS, and quite possibly some unique features.
+
+    1.5 How thoroughly tested is Xastir?
+
+    Xastir is currently in use by hundreds of Hams from around the world.
+    The Xastir Group maintains rigorous standards before releasing new
+    versions of our client.  When bugs do show up, we release patches and
+    new versions as soon as they are available.
+
+    1.6 Whom do I contact for support?
+
+    This FAQ may answer many of users frequent questions.  However, there are
+    two active mailing lists that users could use to help answer any other
+    questions.  Both mailing list are by subscription only and can be accessed
+    through the Xastir web-site.  See the top of this document for the
+    addresses.  You must be subscribed in order to post messages.
+
+    1.7 Where can I submit Bug reports or feature requests?
+
+    The mailing lists are a good place to bring up bugs or feature requests.
+    Note that you must be subscribed in order to post messages.  See above.
+
+    Another good place to document the request or bug in a more permanent
+    manner is the sourceforge tracker. There are separate bug and feature
+    request trackers, both listed at the Xastir project page,
+    http://sourceforge.net/projects/xastir/
+
+    1.8 Is there any more information on Xastir?
+
+    See the main Xastir web-site for more information.  See the top of
+    this document for the addresses.
+
+    1.9 Where can I get Xastir?
+
+    Source code and binaries for several popular Linux distributions is
+    available through the Xastir web-site
+
+
+2. General Technical Questions
+
+    2.1 "Why can't I...? Why won't... work?" What to do in case of
+        problems.
+
+    If are having trouble running the Xastir software:
+
+        1.  Check the FAQ!
+
+            The latest version of the Xastir FAQ can be found on the
+            Xastir web-site.  See the top of this document for the
+            addresses.
+
+        2.  Ask on the "xastir" mailing list.
+
+            Many Xastir users and developers can be found roaming its
+            virtual halls, so it is suggested that you seek wisdom there.
+            The chances are good that you'll get your question answered
+            there.  You must be subscribed in order to post messages.
+
+    2.2 How do I submit a patch to the Xastir Development Group?
+
+    The Xastir Development Group encourages patches from outside developers.
+    There are two main "types" of patches: small bug fixes and general
+    improvements.  Improvements, modifications, and additions should
+    follow the instructions below:
+
+    In general, the first course of action is to be a member of the
+    "xastir-dev" mailing list. This indicates to the Group that you are
+    closely following the latest developments. Your patch file should be
+    generated using either 'diff -c' or 'diff -u' against the latest CVS
+    tree. To submit your patch, send email to the "xastir-dev" mailing list
+    with a Subject: line that starts with [PATCH] and includes a general
+    description of the patch. In the body of the message, the patch should be
+    clearly described and then included at the end of the message. If the
+    patch-file is long, you can note a URL to file itself. Use of MIME
+    enclosures/attachments should be avoided.
+
+    Be prepared to respond to any questions about your patches and possibly
+    defend your code. If your patch results in a lot of discussion, you
+    may be asked to submit an updated patch that incorporates all changes and
+    suggestions.
+
+    2.3 What's the best hardware/operating system?
+
+    Anything that works for "you".
+
+    2.4 Why isn't there a binary for my platform?
+
+    The developers make sure that the software builds and works correctly on
+    the platforms available to them; this does not necessarily mean that
+    your platform is one of them. In addition, the Xastir Project is primarily
+    source oriented, meaning that the distributing valid and build-able source
+    code is the purpose of a release, not making sure that there is a binary
+    package for all of the supported platforms.
+
+    
+3. Building Xastir
+
+    3.1  Why do I get error messages when running "bootstrap.sh"?
+
+    The xastir build procedure requires automake 1.6.3 or later and 
+    autoconf 2.53 or later.  Using anything older than those will 
+    not work.  
+
+    To be very sure of what version of autoconf and automake you're using
+    please examine the output of "automake --version" and "autoconf --version"
+    Do not trust your system's package management software to tell you what
+    version is installed.  Some systems install more than one different 
+    version of autoconf/automake and you can't be sure which one you're using
+    unless you look at the actual version number reported by the tools
+    themselves.
+
+    Worse still, some systems install multiple versions of autoconf
+    and automake and name them in ways that confuses everything 
+    (e.g. "automake19" or "autoconf253").  If that's the case on your system,
+    you could either edit bootstrap.sh by hand to force it to find the right
+    ones (adding paths or suffixes or whatever it takes), or you could just
+    end-run the process and download the source code for a suitable version
+    of automake and autoconf from www.gnu.org, use "--prefix=" options when 
+    configuring both of them, build them, and install them into
+    someplace your system won't care about.  For example, assuming you've 
+    untar'ed, say automake-1.6.3 and autoconf-2.57 into the current
+    directory, and that xastir lives in your directory as /home/me/src/xastir:
+       cd automake-1.6.3
+       ./configure --prefix=/home/me/src/xastir
+       make install
+       cd ../autoconf-2.57        
+       ./configure --prefix=/home/me/src/xastir
+       make install
+       cd /home/me/src/xastir
+       export PATH=/home/me/src/xastir/bin:$PATH
+       ./bootstrap.sh
+
+    This will completely bypass any odd version of automake and autoconf that
+    your system might use, and will insulate you from incompatible changes
+    in those installed tools if you upgrade your OS.
+
+    3.1a  Why do I get strange warnings when I run bootstrap.sh
+
+    The various configure.ac, acinclude.m4, and Makefile.am files that are used
+    by Xastir's autoconf'd build process were designed for automake 1.6.3
+    and autoconf 2.53.  Using a much more recent version than those could 
+    result in warning messages because the tools aren't strictly backward 
+    compatible.  Most of these warnings are harmless.
+
+    3.2. Why won't Xastir compile with my system's cc?
+
+    If Xastir won't compile on your system, it is probably due to
+    one of the following causes:
+
+    - The configure script doesn't recognize your system environment.
+
+      This might be either because it's completely unknown or because
+      the specific environment (include files, OS version, etc) isn't
+      explicitly handled. If this happens, you may need to port the
+      software to your OS yourself.
+
+    - Your systems C compiler is garbage.
+
+      Some operating systems include a default C compiler that is either
+      not ANSI C-compliant or suffers from other deficiencies. The
+      usual recommendation in cases like this is to acquire, install,
+      and use gcc.
+
+    - Your include files may be confused.
+
+      In some cases, we have found that a compiler installation or system
+      upgrade has left the C header files in an inconsistent state. Make
+      sure that your include directory tree is in sync with the compiler
+      and operating system.
+
+    - You haven't installed all the necessary libraries and include files.
+
+      Xastir depends on at least the X, and Motif or LessTif include files.
+      Be sure these are installed before trying to compile the application.
+      Many Linux distributions name these packages <packagename>-dev or
+      <packagename>-devel.
+      NOTE: If you installed ImageMagick from a binary distribution, it will be
+      dependent on the shared libraries for the various graphics formats
+      installed on system on which it was compiled. Be sure you have these same
+      libraries installed, or you'll get a link error.
+      NOTE: The ImageMagick-devel package included with RedHat 8 is missing
+      some files needed for Xastir. The version in the beta directory on
+      RedHat's ftp site works.
+
+      A message like "*** Cannot find Motif include files" either means that 
+      you are missing the development package for Motif/OpenMotif/Lesstif, or 
+      that it is installed in a place where configure can't find it.  It is
+      recommended that you use Motif or OpenMotif instead of Lesstif, as you'll
+      have few problems with those libraries.  For SuSE 9.0, install the
+      "openmotif-libs", "openmotif-devel", and "openmotif" packages.  Other
+      distributions have similar naming.  If you have the Motif libraries and
+      headers installed in a place where Xastir doesn't look for them, see 
+      the references to the "--with-motif-includes" and 
+      "--with-motif-libraries" configure options in the INSTALL file.
+
+    - Your operating system or compiler may be out of version.
+
+      Software vendors issue new releases for a reason; sometimes to add
+      functionality, but more often to fix bugs that have been
+      discovered. Try upgrading your compiler and/or your operating
+      system.
+
+    3.3 I'm using gcc and I get some compilation errors, what is wrong?
+
+    GCC parses your system header files and produces a modified subset which
+    it uses for compiling. This behavior ties GCC tightly to the version of
+    your operating system. So, for example, if you were running IRIX 5.3 when
+    you built GCC and then upgrade to IRIX 6.2 later, you will have to
+    rebuild GCC. Similarly for Solaris 2.4, 2.5, or 2.5.1 when you upgrade
+    to 2.6. Sometimes you can type "gcc -v" and it will tell you the version
+    of the operating system it was built against.
+
+    If you fail to do this, then it is very likely that Xastir will fail to
+    build. One of the most common errors is with readv, writev, or uio.h.
+    This is not a bug with Xastir. You will need to re-install GCC.
+
+    3.4 The linking stage is failing because it isn't linking in the
+        freetype library.  What to do?
+
+    This is, yet again, an ImageMagick problem.  ImageMagick as
+    installed on some systems needs this library linked in.  The
+    "Magick-config" script is supposed to supply a list of all of the
+    libraries that ImageMagick needs, but evidently they forgot one.
+    To get around this problem, you can add "-lfreetype" to the link
+    line to get the compile to complete.
+
+    3.5 During the linking stage, it's giving me "undefined reference to
+        `CompressImageColormap'".  What to do?
+
+    This is, yet again, an ImageMagick problem.  ImageMagick decided to change
+    their API on us again.  Newer releases of Xastir work around this problem
+    by checking the version of ImageMagick you have and changing the function
+    call to match.
+
+    3.6 Some of the text looks strange, writes over itself and other
+        user interface weirdness occurs.  Why?
+
+    This has been seen to occur due to bugs in some versions of LessTif.
+    You may want to try OpenMotif instead if it is available for your
+    distribution.  One caveat that was found on Slackware 8.1 is the need
+    to delete all the text in the /usr/X11R6/lib/X11/config/host.def file
+    otherwise it still refers to the LessTif installation.
+
+    3.7 Why isn't ImageMagick recognized and used during Xastir's
+        "configure" stage?
+
+    You might have forgotten to install both ImageMagick and the
+    ImageMagick-devel RPM.  Another possibility is that your particular RPM's
+    might not contain all of the library dependencies that you need, like
+    libcms or zlib.  Check carefully through "config.log" to see if the
+    ImageMagick detection code says something like:  "ld: cannot find -llcms",
+    "ld: cannot find -lz", or "ld: cannot find -ljpeg".  Install the additional
+    libraries that it needs, and perhaps development packages for them as well.
+    NOTE:  If the "spec" file for the ImageMagick/ImageMagick-devel RPM's had
+    the proper dependencies listed, you would have been asked to install all of
+    the dependent libraries before you could have even installed the
+    ImageMagick RPM's.  Encourage your vendor to fix the "spec" files for those
+    RPM's to include all dependencies.
+
+    3.8 Why do I get an error now when trying to do a "cvs update"?
+
+    SourceForge changed things around a bit on Apr 29th, 2004.  The changes
+    they made broke CVS for everyone.  The error message you get may look like
+    the following:
+
+        "Unknown host: cvs.xastir.sf.org"
+
+    Luckily the fix is simple.  Run these commands from the top directory where
+    you have the Xastir sources:
+
+    find -name Root -path \*CVS\* -exec perl -pi.bak -e's/cvs.xastir.sf.net/cvs.sf.net/' \{\} \;
+    find -name Root -path \*CVS\* -exec perl -pi.bak -e's/cvs.xastir.sourceforge.net/cvs.sf.net/' \{\} \;
+
+    Okay, are we having fun yet?  They changed things again for us
+    on May 12, 2006.  We now want this as the name of the CVS server
+    in the CVS/Root files:   "xastir.cvs.sourceforge.net", so the perl command
+    to use after that date has become:
+
+    find -name Root -path \*CVS\* -exec perl -pi.bak -e's/cvs.sf.net/xastir.cvs.sourceforge.net/' \{\} \;
+
+
+   3.9 Why does compilation of map_geo, map_WMS or map_tiger fail with "invalid operands to binary <<" errors?
+
+   This is a problem with ImageMagick.  In short, your ImageMagick
+   installation has been built with an option incompatible with
+   Xastir.
+
+   New versions of ImageMagick include experimental support for High
+   Dynamic Range Images (HDRI).  This support changes the data type of
+   a Quantum (pixel value) from an 8- or 16-bit integer quantity to a
+   floating point.  Xastir assumes that all pixel values are integer
+   types, and uses operations on those values based on that
+   assumption.  
+
+   You have two choices for getting around this issue: rebuild
+   ImageMagick without HDRI support, or use GraphicsMagick instead.
+
+4. Running Xastir
+
+    4.1 Why do I get wrong texts in menus or other places when using a
+        non-English language file?
+
+    The development is done mainly with the English language file, so
+    other languages may not be up to date.
+
+    Those texts like IC>PULDNMBC02 are placeholders for missing entries
+    in the language file. You can add the local meaning of that string
+    in the English language file to your language file. And send it to
+    the Xastir development team...
+
+    4.2 I run Xastir under Linux, and I get an error about loading a shared
+        library.
+
+    Xastir uses many shared libraries, including lesstif, and perhaps libax25,
+    libproj, libtiff, libgeotiff, libz, libjpeg, etc. These errors indicate
+    ld.so, the Linux dynamic linker, can't find the shared libraries.
+    * First, check that all the libraries are installed. Check the INSTALL
+    file for the locations to get these libraries if you've accidently removed
+    one of them.
+    * Run "ldd /usr/local/bin/xastir".  This will print out a list of libraries
+    that Xastir is looking for and the locations they are expected to be at.
+    * Check that the locations of the libraries are in /etc/ld.so.conf. This
+    should probably be set up by your Linux distribution, but if you've
+    added new library directories after install, you'll need to add them here.
+    This is most applicable to lesstif which installs its libraries in
+    non-standard locations. Read the lesstif installation instructions for
+    more information on this. (Very recent versions create symlinks in
+    /usr/local/lib, so you probably won't need to do anything aside from
+    running ldconfig.)
+    * If you had a libc5 system and hand upgraded it to libc6, and are
+    attempting to link against both libc5 and libc6 built libraries at once,
+    stop now and recompile all your libraries against libc6. The dynamic
+    linkers are different for libc5 and libc6 programs, and linking against
+    libraries built with both versions is bound to cause trouble. This setup
+    has caused many people lots of headaches. Just upgrade your distribution.
+
+    4.3  I run Xastir under Linux, and try to set up an ax25 device, but get a
+         "Hard Fail" error on the interface. There is a "permission denied"
+         error in the terminal from which I started Xastir.
+
+    As mentioned in INSTALL and helpfile, Xastir must be setuid root to use
+    Linux ax25. This is required because Xastir needs the ability to edit its
+    source callsign, and use other advanced options that the Linux ax25 stack
+    restricts to root.
+
+    4.4 I run Xastir, and get on the air, but nobody else sees me on their
+        screens.
+
+    From a software standpoint, check that you have transmitting enabled
+    on your interface, and that the disable transmission "all" and "my
+    position" options in the Interfaces menu are not enabled. Check that ALTNET
+    support in File|Configure|Defaults isn't enabled.
+
+    Also check that your digipeater path is set reasonably; other
+    hams in your area could probably help with this, as the exact settings
+    depend on your setup and on your area's network. The other possibilities
+    are hardware problems: Is the output level on your TNC or soundcard
+    correct? Is PTT on your radio getting triggered? Is your TXdelay set
+    reasonably? All of these possibilities are beyond the scope of this FAQ.
+    An easy way to determine if your hardware works correctly is to try it on
+    conventional packet.
+
+    4.5 I run Xastir, and get on the air, but none of the other stations
+        appear on my screen?
+
+    Did you set up your TNC startup files correctly to remove any extra data
+    from the packet headers? Are you using the correct startup file?  See
+    INSTALL.
+
+    Check that the Display Incoming Data windows is actually showing
+    data coming in.  If not, check your radio's volume/squelch
+    levels and your cabling, both between the radio/TNC and between
+    the TNC/Computer.
+
+    Check that ALTNET support in File|Configure|Defaults is disabled.
+    If activated, it only shows stations transmitting TO the callsign
+    listed in the box.  I sometimes set it to APX or APX190 in order to
+    see who's running Xastir/who's running the _latest_ Xastir.  Set
+    it to "WEIRD" and you'll only see those transmitting to "WEIRD".
+
+    Check all of your Stations|Filter Data and Stations|Filter Display
+    settings. "Select Stations" and "Display Symbols" must be selected.
+
+    If you are using an older version of Xastir, Qxx packets are considered
+    invalid. This is a newer addition to APRS(tm), and recent Xastir releases
+    decode this correctly.
+
+    4.6 Who is this APX190 guy who all my stuff is getting sent to? Who are
+        these RELAY, WIDE and TRACE people digipeating packets, and why are
+        they putting different callsigns in the fields where their names used
+        to be? Why doesn't anyone answer me when I connect to them? HELP!!!
+
+    You must be used to conventional packet. APRS(tm) is inherently different
+    from conventional packet. There are many online resources that explain the
+    basics of APRS(tm), but I'll try to summarize here. APRS(tm) is an
+    unconnected protocol, where you broadcast UI (unnumbered information)
+    packets to the world. Since these packets aren't directed toward a
+    specific user, the TO address of the packet is simply a summary of the
+    software you're running. AP=APRS(tm), X=X Windowing System, 110=Version 1.10.
+
+    RELAY, WIDE, TRACE, WIDEn-N, and TRACEn-N are aliases for generic
+    digipeaters, although all but the WIDEn-N variants are now deprecated
+    (should no longer be used).  Some base stations have their TNC's configured
+    to digipeat with the call of "WIDE1-1" (we used to use "RELAY" for these,
+    but "WIDE1-1" has now taken its place).  Newer digipeater software
+    substitutes their own call for "WIDEn-N" to enable people to see who
+    digipeated them.  See the README.Getting-Started file for a bit more info
+    on paths, including recommended paths for different types of stations.
+
+    To talk to people, you send them messages from within Xastir, you don't
+    "call" them like on typical packet. Most TNC's are set up to ignore classic
+    packet "calls" so you won't get any response. When sending messages to
+    people in your area, do check in their comments that they are people and
+    not stand-alone digipeaters or similar. ;) Thanks to the worldwide APRSserv
+    Internet system, you can send messages to any APRS(tm) user anywhere in the
+    world, provided they're within range of an Igate. Most users are; if your
+    area isn't and you have a 24/7 Internet connection, Xastir can be your
+    area's Igate! (Please check your local laws, as Igating is illegal in some
+    countries!) There are also experimental systems for sending messages via
+    amateur radio satellites, but that is beyond the scope of this FAQ.
+
+
+    4.7 When weather alerts come in, the counties on my map don't highlight.
+
+    First of all, did you download and install the new shapefile weather maps
+    as described in the INSTALL file? (Running scripts/get-NWSdata automates
+    this somewhat for you now)
+
+    Did you compile with shapefile support?
+
+    Check that Map|Enable Weather Alerts is enabled, and "Map|Disable All Maps"
+    is _not_ selected .
+
+    4.8 I have geoTIFF support compiled and working, but when I select a map,
+        it gives me a -38 error converting the datum, and it doesn't display in
+        the right place.
+
+    Did you install libgeotiff before libproj? This error you'll see if you
+    ignored the note in the INSTALL file about this. Recompile libgeotiff and
+    the problem should vanish.
+    If this is not the case, check the datum of the geoTIFF file, and make
+    sure it is one of the ones supported by Xastir. The listgeo program
+    included with libgeotiff can tell you the datum of a map.
+
+    4.9 Xastir runs slowly/loads maps slowly.
+
+    There are many things that can effect the speed of your Xastir software,
+    including the speed of the computer, the amount of memory available, the
+    number of active interfaces, the complexity/type/number of maps you use,
+    and the options you used to compile Xastir and helper libraries. The
+    developers aren't aware of any specific cases in which there would be
+    performance problems; generally these are limitations of your computer.
+    Xastir, when using only basic maps, runs reasonably on a Pentium 60. If
+    you use higher detail maps, such as the tiger line maps suggested in
+    README.MAPS, you'll need a faster computer to be able to load the maps
+    quickly. Also be sure you have a few Megabytes of memory available for
+    Xastir, because paging to disk decreases speed rapidly. If you have the
+    Internet interface, as well as TNC's and weather stations all active
+    at the same time, you'll see a slowdown on a slower computer. Also, if you
+    compiled Xastir or libax25/libtiff/libgeotiff/etc with debugging (-g),
+    recompile these software without debugging and with optimization ON (-O2).
+
+    4.10 I installed a new version of lesstif, but the help menu shows the old
+         version.
+
+    The help menu shows the version of lesstif that Xastir was compiled with,
+    not necessarily the version you're running now. Assuming you compiled it
+    with the new version, check that the new version is the only copy
+    installed. If you install in /usr/local/LessTif/, the default location,
+    be sure you remove any older version from /usr/LessTif/ or
+    /usr/X11R6/LessTif/, as some distributions use those locations.
+
+    4.11 Why does Xastir seg-fault sometimes when indexing or loading
+         geoTIFF images?
+
+    The geoTIFF code must use an API in the TIFF code that is non-public.
+    Unfortunately this means that the geoTIFF code must know more about TIFF
+    than the normal application using the TIFF library.  If the private TIFF
+    include file included with the geoTIFF code doesn't match your installed
+    version of TIFF, you can run into seg-fault problems.
+
+    Solutions for this include:  1) Installing TIFF from sources, or
+    2) Grabbing the sources for your installed version of TIFF, copying one
+    include file from TIFF into the geoTIFF sources and recompiling/installing
+    geoTIFF.  Either of these solutions will make the geoTIFF code recognize
+    and use the proper structures in TIFF should prevent the seg-faulting.
+
+    In the future we hope that either the geoTIFF code will become part of
+    the TIFF code, or that the private TIFF API will become public.  Either
+    of these changes should fix this problem for good.
+
+    4.12 Why doesn't Xastir run on RedHat 9.0 properly?
+
+    The RH kernels have implemented the new(er) New Posix Threading Library
+    (NPTL) as well as back-ported many of the new bells and whistles set to
+    appear in the 2.6.x kernels.  You might experience a great improvement
+    for apps that are heavily threaded.  NPTL is supposed to be backward
+    compatible but we have seen apps that have had problems.  You can revert
+    back to the older LinuxThreads implementation by setting the environment
+    variable: 
+
+    LD_ASSUME_KERNEL=<kernel-version>
+
+    in a shell before starting the app The following versions are available:
+
+       - 2.4.1 - Linuxthreads with floating stacks
+
+       - 2.2.5 - Linuxthreads without floating stacks
+
+    or, you can disable NPTL altogether for dynamically linked
+    applications by using 'nosysinfo' as a boot time option.
+
+    4.13 Why do I see "Character '\55' not supported in font"?
+
+    This message and similar have to do with localization and OpenMotif/
+    Lesstif.  For most of us this is a benign message and can be ignored.
+    If you simply can't stand it any more set LANG="C" or LANG="en_US".  In
+    RH 9 the default LANG is set to en_US.UTF-8 and this is where the warnings
+    are coming from.
+
+    A quick way to address this on RedHat 8 and 9 is to edit your
+    /etc/sysconfig/i18n config file.  I believe the original file looks
+    like:
+
+    LANG="en_US.UTF-8"
+    SUPPORTED="en_US.UTF-8:en_US:en"
+    SYSFONT="latarcyrheb-sun16"
+
+    Change the "LANG=" line to:
+
+    LANG="en_US"
+
+    and reboot.
+
+    With the original setting you get some weird character mappings.  For
+    example, running "man ls", all of the dashes (-) disappeared from my
+    screen until I changed the LANG setting.
+
+    4.14 Why do I see strong blue tinting for the maps?
+
+    Strong blue (or perhaps other color) tinting of the image may be
+    due to running the display over a Hummingbird eXceed session.
+    Try running it locally and you should see the proper colors.
+    Try changing the eXceed session to use more bits of color.
+
+    4.15 My config file got munged.  How do I recover?
+
+    Xastir saves previous revisions of the config file as
+    "xastir.cnf.1" through "xastir.cnf.3".  Look for them in the
+    ~/.xastir/config directory.  Kill Xastir, then copy one of the
+    backup files to "xastir.cnf" in order to recover your previous
+    settings.  Xastir will use the "xastir.cnf" file the next time
+    it starts up.
+
+    Older Xastir versions saved only one copy of the config file as
+    "xastir.bak".
+
+    4.16 Why can't I set my position in Xastir correctly?
+
+    If your LC_NUMERIC environment variable is set to something other than
+    "C", it can cause commas and periods to be swapped when Xastir tries to
+    read/write files.  We've tried to address this in the latest Xastir code,
+    forcing LC_NUMERIC="C" inside Xastir itself.  Another solution is to type
+    this when starting Xastir (from a BASH shell.  If you use another type of
+    shell, modify the syntax accordingly):
+
+        export LC_NUMERIC="C"; xastir &
+
+    4.17 Why do I get black map images when I use ImageMagick?
+
+    There was a bug in versions of Xastir prior to the CVS version of
+    4 December 2009 that caused this problem if ImageMagick (or
+    GraphicsMagick) were compiled with QuantumDepth not equal to 16
+    (GraphicsMagick now defaults this parameter to 8).  The bug was
+    fixed, and current versions of Xastir should not have this
+    problem.  If you are running an older version than 4 December
+    2009, updating will likely solve this problem for you.
+
+    If you are running a version higher than 1.9.7 or a CVS version
+    checked out after 4 December 2009, then the problem lies
+    elsewhere.  It may be due to bugs in your particular version of
+    ImageMagick, but more likely it's related to the color-depth of
+    your X-Server.  If you are using 8-bit, 24-bit, or 32-bit
+    color-depth: Try 16-bit, which is the color-depth best supported
+    by the Xastir code.
+
+    4.18 Why does my MacOSX machine w/USB->Serial adapters hang?
+
+    Use ports such as /dev/cu.usbserial0 for USB to serial adapters
+    on MacOSX.
+
+    4.19 Why do NumLock/ScrollLock/CapsLock interfere with mouse/keyboard
+         operation?
+
+    Because they are treated as modifiers by Motif.  Here's an FVWM2 document
+    (FVWM2 is a window manager) that talks about it:
+
+    http://www.fvwm.org/documentation/faq/index.php?theme=navigate
+
+    See section 5.5 of that document which talks about these keys.  If you type
+    these commands and then restart your window manager it may take care of
+    your problem, but then those keys will be disabled and you won't be able to
+    use in other applications:
+
+        xmodmap -e "clear Lock"
+        xmodmap -e "clear Mod2"
+        xmodmap -e "clear Mod5"
+
+    4.20 How to I redirect serial ports from one computer to another?
+
+    For Linux, try a program called "remserial". It works as a
+    client/server pair to do exactly what you want.  Google should
+    find it for you.  One user was able to use a spare serial port
+    on his windows box using "remserial" on the Linux computer and a
+    program called "serproxy" on the windows machine. Another one I
+    have to try for windows is comfoolery.  See links below.
+
+    Another option is to use a Perl script on each end to do the
+    conversion.
+
+    Yet another is to use "netcat".  "man nc" or "man netcat" should
+    tell you about it.  It redirects tcpip data seamlessly under
+    Linux.  On SuSE the docs for it are in
+    /usr/share/doc/packages/netcat.  Try a command line like this:
+
+        cat /dev/ttyS0 | nc -l -p 3000
+    or
+        cat /dev/ttyS0 | netcat -l -p 3000
+
+    That should make a listening socket at port 3000 which listens
+    to the /dev/ttyS0 serial port.  "telnet localhost 3000" should
+    show you any data coming in on that serial port.  Connect Xastir
+    across the network to that listening socket to get the data.
+
+    If you want to put your GPS on a remote serial port, use the
+    gpsd daemon to do it.
+
+    if you wish to put your weather station on a remote serial port,
+    investigate using OWW (for Dallas weather stations), wx200d
+    daemon for some Radio Shack/Huger/Oregon Scientific weather
+    stations, or Meteo daemon for Davis weather stations.
+
+    You may also connect to a remote AGWPE instance for using remote
+    TNC's/soundcards.  Note that AGWPE runs only on Windows.
+
+    Yet another which looks to be netcat recoded/extended:  socat
+    
+    Comfoolery:     http://www.brianpoe.com/comfoolery/
+    Serproxy:       http://freshmeat.net/projects/serproxy/
+    Serproxy:       http://www.lspace.nildram.co.uk/freeware.html
+    Remserial:      http://lpccomp.bc.ca/remserial/
+    Socat:          http://www.dest-unreach.org/socat/
+ 
+
+    4.21 I have Festival compiled in, but I can't get any speech, why?
+
+    a) You must start the Festival server daemon before starting Xastir.
+    Start it via this command :
+
+        festival_server &
+
+    b) If the server is running, but you get this: "festival_client:
+    connect to server failed", then you may have some tweaks to do
+    to your system files in order to allow Xastir (or anything else)
+    to connect to Festival.  Try this first to see whether anything
+    can connect to Festival:
+
+        telnet localhost 1314
+
+    If the server is running properly it'll let you connect.  If it
+    does, try typing:
+
+        (SayText "Hello, World")
+
+    If that doesn't work, check your audio mixer settings first, then
+    proceed to c) below:
+
+    c) Some people have an "/etc/hosts" file that has an incorrect
+    line for localhost.  You should have a line which has 127.0.0.1
+    at the start, and has "localhost" somewhere on that line as well.
+    Like this:
+
+        127.0.0.1 localhost localhost.localdomain
+
+    d) On one Debian box, it was an issue with "/etc/hosts.allow".  
+    See "man 8 tcpd" or "man 5 hosts_access" for detailed info about
+    how to configure /etc/hosts.allow and /etc/hosts.deny.  It's
+    part of the tcpwrappers stuff that allows you to configure which
+    hosts have access to which services on your system.
+
+    4.22 ImageMagick gives me: "no decode delegate", why?
+
+    README.win32 has a bit of info about this one, as it most often happens
+    on Win32 systems.  It has been seen on other systems as well though.
+    The short answer is that you may have to set the environment variable
+    "MAGICK_HOME" to the location where the ImageMagick modules reside.
+    This is only necessary if ImageMagick doesn't have the location
+    pre-compiled into it.  The example for Win32 systems is:
+
+        export MAGICK_HOME=/usr
+
+    Added to the ~/.profile file, so that the BASH shell gets this defined
+    each time you log in.  The location "/usr" will probably be different
+    on a non-Windows machine, so change the line above as required for your
+    system.
+
+    4.23 How do I get through an http proxy server with Xastir in
+         order to fetch maps?
+
+    *) Install libcurl and/or wget.
+    *) Set the HTTP_PROXY and FTP_PROXY environment variables in
+       your ~/.profile file.  Libcurl has additional options that
+       can be set:  HTTPS_PROXY, GOPHER_PROXY, and ALL_PROXY.
+    *) Create and fill in the ~/.netrc and/or .wgetrc files with
+       proper values.  Set the permissions on it so that only you
+       can read/write the file:  "chmod 600 .netrc".  Typical
+       contents of the file are shown below:
+
+            http_proxy = http://proxy.yoyodyne.com:18023/
+            ftp_proxy = http://proxy.yoyodyne.com:18023/
+
+    4.24 Can I run multiple copies of Xastir at once?
+
+    Yes, but you must keep the configuration directories separate for
+    each copy by using a command-line flag. Xastir will create the new
+    config directory and fill it with defaults if it doesn't already
+    exist. Here's the method. Substitute your user name where it says
+    "<user>":
+
+        xastir &    # starts up first Xastir copy against ".xastir" directory
+        xastir -c /home/<user>/.xastir2 &    # starts up 2nd Xastir copy against ".xastir2" directory
+        xastir -c /home/<user>/.xastir3 &    # starts up 3rd Xastir copy against ".xastir3" directory
+
+    To make the process easier if you use this method a lot, create
+    aliases by editing your .profile (This assumes you're running BASH
+    or Bourne shells):
+
+        alias xastir2='xastir -c /home/<user>/.xastir2 &'
+        alias xastir3='xastir -c /home/<user>/.xastir3 &'
+
+    After sourcing your new .profile (The command is ". .profile" from
+    your home directory) or logging out and back in again, you can type
+    "xastir2" or "xastir3" as a command to start up the additional
+    copies of Xastir.
+
+    Older methods, may still be useful at times: 
+
+    Do this to allow more than one user to access your X display and to
+    create additional users, each capable of running one Xastir session:
+
+        xhost localhost
+
+    This lets other users on your machine use the X11 display.
+
+    Create another user (or two or three) using whatever facilities
+    your system uses to do this.
+
+        xterm &     # Start up an xterm window in the background
+        su 2nduser. # su to one of your new usernames
+        xastir &    # Start up Xastir as that user, in the background
+
+    Optional:
+    Set up your 1st Xastir instance with the server port enabled.
+    Connect the 2nd instance to localhost:2023.  This way one Xastir
+    will get its feed from the other.
+
+    You can start up a third Xastir in the same manner, starting
+    with the "xterm &" command and then doing "su 3rduser" instead,
+    then "xastir &" as that third username.
+
+    Many Xastir sessions can all get their feed from one Xastir
+    session, or they can be connected to different TNC's or server
+    ports.
+
+    4.25 Why doesn't Terraserver work for some locations?
+
+    Terraserver is based on the UTM coordinate system.  If you're trying
+    to request map images that cross a UTM zone boundary, Terraserver
+    may not work at that location.  Zoom in closer or pan left/right
+    in order to avoid this problem.
+
+    4.26 Some station or config settings are not getting saved, why?
+
+    A few of the menu settings do not get saved.  This is on purpose.
+    If you are having more serious troubles, like for instance your
+    station location setting isn't getting saved between Xastir runs,
+    check your LANG setting (see question 4.13 above).
+
+    4.27 Why are my colors messed up when running via VNC?
+
+    VNC may have a different colormap or colordepth than the system Xastir is
+    running on.  Here is one invocation that a user used which worked.
+    Substitute the appropriate parameters for your system of course:
+
+    vncserver :5 -name melecom -depth 24 -geometry 800x600 -pixelformat rgb565
+
+    4.28 Why are the labels missing in the Configure->Timing dialog?
+
+    Some versions of the Lesstif widget set have this bug.  Try
+    switching to a different version of Lesstif or switch to
+    OpenMotif and you should see the labels again.  So that you can
+    actually operate Xastir, here's what you _should_ have seen:
+
+        On the left:
+        ------------
+        Posit TX Interval (min)
+        Object/Item TX Interval (min)
+        GPS Check Interval (sec)
+        Dead-Reckoning Timeout (min)
+        New Track Time (min)
+        RINO -> Objects Interval (min), 0=Disabled
+        Snapshot Interval (min)
+
+        On the right:
+        -------------
+        Station Ghosting Time (min)
+        Station Clear Time (hours)
+        Station Delete Time (days)
+        Serial Inter-Char Delay (ms)
+        New Track Interval (degrees)
+        Internet Map Timeout (sec)
+
+    A screenshot on the Wiki of this dialog:
+    <http://www.xastir.org/wiki/index.php/Notes:Timing_Slider_Dialog_Screenshot>
+
+    4.29 Xastir can't find "xastir.rgb" or some other file.  What's wrong?
+
+    This could be one of several things.  We'll check them in order:
+
+    a) If you get this exact message:
+
+        "Error! can not find color file: /xastir/config/xastir.rgb"
+
+    Then it could be that you're not getting a variable defined on
+    the compile line.  This text or similar should appear for each
+    file compiled:
+
+        -DXASTIR_DATA_BASE=\"/usr/local/share/xastir\"
+
+    If you're not seeing this, or the variable is defined to an
+    empty string or is otherwise incorrect, you may need to
+    upgrade/downgrade your autoconf or automake packages and rerun
+    the Xastir install starting at the "./bootstrap.sh" stage.
+
+    b) Did you run the "make install" stage as root or using "sudo"
+    after you compiled Xastir?  If not, Xastir couldn't install
+    files it needs to run.
+
+    c) Another possible problem is a corrupt or very old
+    ~/.xastir/config/xastir.cnf file.  Check for this by typing:
+
+        cd
+        mv .xastir .xastir.save
+        xastir
+
+    If it comes up ok this time, then either paths in your config
+    file are incorrect or the config file is corrupt.  If there's no
+    change, go back to your original configuration by typing:
+
+        cd
+        rm -rf .xastir  # NOTE: this will delete ~/.xastir and all contents!
+        mv .xastir.save .xastir
+
+    d) Yet another thing to check is the value in your LANG variable.
+    It should be either "en_US" or "C" for Xastir to read/write
+    config files correctly:
+
+        echo $LANG
+
+    If it is something else, start Xastir like this:
+
+        export LANG=en_US; xastir -geometry -0-0 &
+
+    You can create an alias in your shell for this so that you don't
+    have to remember to type it each time.
+
+    e) Perhaps you're trying to run an old Xastir executable that
+    was compiled with different paths, or you have an LSB-Xastir
+    installed and have compiled or installed Xastir in the normal
+    fashion as well.  Type this to see where the executable is
+    trying to run from:
+
+        which xastir
+    -or-
+        whereis xastir
+
+    f) It's possible that your autoconf/automake packages need to be
+    upgraded or downgraded.  These packages are somewhat version
+    dependent on each other, so it's likely that you'll have to do
+    this upgrade or downgrade as a pair for things to work correctly.
+    After the upgrade or downgrade, recompile Xastir starting at the
+    "./bootstrap.sh" stage so that the configure and Makefile
+    scripts are re-created.
+
+        ./bootstrap.sh
+        ./configure
+        make
+
+    Make sure that you now see a reasonable path for the
+    XASTIR_DATA_BASE variable on each compile line.
+
+    4.30 Why can't I see station trails as stations move around?
+
+    Enable Station->Filter Display->Display Trail
+
+    File->Configure->Timing->"New Track Time" and "New Track Interval
+    should be set above zero.  Defaults for these are 45 and 1
+    respectively.
+
+    If this problem and others occur, such as your latitude/longitude
+    getting lost between runs, this might indicate a problem with
+    your LANG variable.  See question #4.26 above.
+
+    4.31 Why don't the maps I installed show up in the Map Chooser?
+
+    Install the maps in the correct place, normally
+    "/usr/local/share/xastir/maps/" or subdirectories below there. If
+    running LSB-Xastir it's "/opt/Xastir/share/xastir/maps/".
+
+    Make sure the map directories and files have read permissions
+    for the user.
+
+    Select "Map->Configure->Index: Add New Maps", then check in Map
+    Chooser to see if the map is listed.  If not, try the "Reindex
+    ALL Maps" option.
+
+    Verify that you have installed the map libraries necessary to
+    handle the types of maps you're wishing to use: "Help->About".
+    Also you can check the messages written to STDERR in the shell
+    you start Xastir from.
+
+    Check this file to see if map indexing found the file at all.
+    It's the same file that Map Chooser reads to display the map
+    selections:
+
+        ~/.xastir/config/map_index.sys
+
+    If the map is a raster map, you can check whether your installed
+    ImageMagick or GraphicsMagick can display the image.
+
+        For IM:   display <filename>
+        For GM:   gm display <filename>
+
+    If it's an internet-based map you're trying to download/display,
+    verify in the Xterm that you have internet maps enabled using
+    either libcurl or wget.  Check manually whether curl or wget
+    (whichever Xastir is using) can fetch a remote file.  Check
+    whether a file like ~/.xastir/tmp/map.gif or map.jpg shows up
+    after you try to fetch a file, even if Xastir doesn't display
+    it.  See if one of the above "display" commands will display it
+    if so.  Check the File->Configure->Timing dialog for the
+    "Internet Map Timeout" setting: Adjust it upwards if Xastir is
+    timing out fetching the remove map.
+
+    If all else fails, try removing the ~/.xastir directory and all
+    contents.  Warning:  This will cause you to lose all of your
+    personal Xastir configuration, including callsign, location,
+    bookmarks, map levels and other map settings, etc.  Once you've
+    done this, verify that your LANG setting is either "C" or
+    "en_US", with no additional characters in there, then start
+    Xastir from that same shell with the correct LANG setting.
+    Xastir should index all of your maps on startup. After it is
+    complete, bring up the Map Chooser and all available maps should
+    be listed.
+
+    4.32 Dialogs are tiny bullet-shaped windows with no handles.  Why?
+
+    This is caused by an interaction between "Motif" and "compiz".
+    "compiz" is enabled in some versions of Ubuntu Linux with a
+    "Desktop Effects" menu item.  They changed the default to *ON*
+    several releases ago.  "compiz" is a window manager which
+    enables eye-candy effects such as animated window
+    opening/closing, 3-D effects, and so forth.  To fix this
+    problem, turn *OFF* "Desktop Effects" which will disable
+    "compiz" and re-enable the default window manager.
+
+    4.33 Fedora 12 right-click menus don't work.
+
+    This was a Fedora X11 bug and has been fixed.  Do a "yum
+    update" on your system to get the latest Fedora fixes.
+
+    If you're having troubles with another OS, read this thread to
+    get some insight into the problem:
+      https://bugzilla.redhat.com/show_bug.cgi?id=543647
+
+    It appears to be a bug in the X11 server and can affect OpenMotif
+    and Lesstif apps.  I didn't read every comment though.  There were
+    definitely many dead-ends as they went along discussing it.
+
+    4.34 What about using Xastir with a TNC-X with built-in USB on a Mac?
+
+    You will need the device drivers from FTDI, downloadable from their website at
+    http://www.ftdichip.com/Drivers/VCP.htm
+
+    Note: the TNC-X packet datarate is fixed at 1200 baud, however the serial
+    communication with the computer is configurable via internal jumpers. It's
+    been observed that setting the com port to 1200 baud results in a deaf TNC-X.
+    Setting the com port to 9600 baud works well, however. 
+
+    4.35 Why do I get "Bitmap not found? /usr/share/xastir/symbols/2x2.xbm"
+
+    The problem is that you probably have previously installed a binary version 
+    of Xastir from your system's repository --- and Linux packages are set up
+    to install files in /usr (e.g. binaries to /usr/bin, libraries to /usr/lib/,
+    and supporting files to /usr/share).  But CVS xastir, like almost all source
+    packages, installs to /usr/local (/usr/local/bin, /usr/local/lib, 
+    /usr/local/share).  When you de-installed your binary package and installed
+    the source version, it removed the /usr/ stuff and installed the files in
+    /usr/local/.
+
+    Your configuration files for Xastir still point to the old locations, and
+    Xastir is confused because files it's expecting aren't there.
+
+    You have two approaches to fix this:
+
+      1) If you have not used Xastir a lot and don't have a whole lot of 
+         custom configurations (map selections, interface properties, etc.) then
+         you can just move your ~/.xastir/config/xastir.cnf file and let Xastir
+         regenerate a default set-up.  Many people here recommend that approach
+         because it's just a matter of one command:  
+
+            mv  .xastir/config/xastir.cnf  .xastir/config/xastir.cnf_old
+
+         But this will blow away all your customizations, so it might not be the
+         best choice.  Note that you can still glean information from the old
+         copy of the config file to help set up the new.
+
+      2) Change all references to "/usr/" in your configuration files to "/usr/local".
+         Most of these will be in ~/.xastir/config/xastir.cnf so it's just a matter
+         of editing that one file and changing them all.  
+
+    It is always an issue when you switch from a pre-compiled linux package to
+    a source build.
+
+5.  Features
+
+    5.1  Why doesn't Xastir include <insert your feature here>?
+
+    Probably because someone hasn't taken the time to write the feature or
+    enough people have complained loud enough that it wasn't there.  The
+    feature set of Xastir is user/developer driven. So get busy!
+
+    5.2  Why doesn't Xastir digipeat packets sent to the RELAY or
+    WIDE1-1 aliases?
+
+    If you're running serial-port connected TNC's, the "tnc-startup.*"
+    files that get installed in /usr/local/share/xastir/config should set up
+    your TNC to respond to these packets.  Select Interfaces->Properties,
+    then select the interface, click Properties, then select the Setup
+    and Shutdown files at the bottom of that dialog.  When an interface
+    is brought up the Setup file will be downloaded to the TNC.
+    "myalias WIDE1-1" is the command most TNC's accept for defining a
+    digipeating alias.  That command or similar should be in the Setup file
+    that you use.
+
+    Use "myalias WIDE1-1" with the new path scheme discussed on
+    APRSSIG during early April, 2005:  RELAY/WIDE/TRACE/TRACEn-n are
+    deprecated (should not be used).
+
+    If you're running kernel AX.25 interfaces, then you'll need to run
+    another package to handle digipeating on these interfaces, perhaps
+    digi_ned.
+
+
+    5.3  How do I take a snapshot of my current view? 
+
+    You can cause a snapshot to occur by enabling Snapshot in the File menu.
+    It takes a snapshot every five minutes starting immediately when the
+    togglebutton is first enabled.  This means you can change views and
+    disable/enable to take an immediate snapshot each time as well.
+
+    You can also send a "SIGUSR1" signal from another process and Xastir
+    will take a snapshot. The feature was added so that someone could
+    press a button on a web page and cause Xastir to make a new snapshot.
+
+    For Example, from the shell you can do: 
+
+        kill -SIGUSR1 `cat ~/.xastir/xastir.pid`
+
+    Snapshots will are stored under ~/.xastir/tmp/
+
+
+    5.4 What is that yellow circle on my map?
+
+    Somewhere around a half-hour or an hour after you start Xastir with 
+    a connected TNC, you will begin to see a yellow circle surrounding your 
+    station at some zoom levels.  This is your "ALOHA Circle,"
+    the circle containing approximately the number of stations that should 
+    saturate your local APRS channel.  See 
+    http://web.usna.navy.mil/~bruninga/aprs/ALOHAcir.txt for details.
+    The short story is you should set your path so your packets don't
+    travel farther than this circle's radius.  
+
+    This circle is shown when your station is in view and you are
+    zoomed out far enough to contain the circle in the viewport.  Its
+    radius is recalculated once every half an hour from the stations
+    you've heard on RF.  Stations you hear from internet servers or
+    other non-RF sources are not included in the calculation.  The
+    circle can be turned off from the Station->Filter Display menu
+    but it will be enabled again each time you restart Xastir.
+
+    5.5 How can I restart Xastir remotely/from a script/command-line?
+
+    Send a SIGHUP to the process.  This will cause Xastir to save
+    its configs, exit, then restart with the same environment and
+    command-line parameters as it initially had.
+
+    For Example, from the shell you can do: 
+
+        kill -SIGHUP `cat ~/.xastir/xastir.pid`
+
+    NOTE:  This SIGHUP trick doesn't work if you've configured
+    Xastir with profiling ( "./configure --with-profiling" ).
+
+
+----------------------------------------------------------------
+
+APRS(tm) is a Trademark of Bob Bruninga
+
+If you find other problems, or would like to point out other caveats to add to
+this FAQ, please point them out to the developers on the Xastir-dev mailing
+list.  The addresses for the mailing lists may be found on the main Xastir
+web pages, which are listed at the top of this document.  You must be subscribed
+in order to post messages.
+
+
+Copyright (C) 2000-2012 The Xastir Group
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..574bc2f
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,1623 @@
+
+$Id: INSTALL,v 1.108 2012/11/01 18:57:18 we7u Exp $
+
+
+General steps to configure/compile/install Xastir:
+(See detailed steps and library installation instructions below)
+----------------------------------------------------------------------
+
+1) Get one of the source releases and explode it.
+
+  mkdir xastir
+  cp xastir*.tgz xastir
+  cd xastir
+  tar xzvf xastir*
+
+An alternative to the above steps is to use CVS to download the
+Xastir sources.  See README.CVS for those instructions.   CVS allows
+you to easily keep up to date with the developers.
+
+2) Go into the xastir directory to build the executable:
+
+  cd xastir*
+
+If you used CVS to fetch the sources, you need one more step here
+before you run configure:  "./bootstrap.sh"
+
+  ./configure
+  make
+  su (become the root user)
+  make install (make install-strip can be used after the first time)
+  chmod 4555 /usr/local/bin/xastir (only if you use kernel ax.25, see below) 
+  exit (from root)
+
+3) Xastir should be installed in /usr/local/bin (the default on most
+systems).  You can run it by typing this from a shell:
+
+    xastir &
+
+
+Short summary of libraries Xastir can use:
+-------------------------------------------------------------------------
+Motif or OpenMotif or LessTiff  Required  The GUI widget set
+pthreads                        Required  Threading capability
+Shapelib                        Recommended ESRI Shapefile maps and WX alerts
+pcre                            Recommended used with Shapefile maps
+Xpm                             Optional  XPM images + Snapshots + Printing
+ImageMagick                     Optional  MANY graphics images
+libtiff/libgeotiff/libproj      Optional  geoTIFF maps (USGS topos)
+AX.25                           Optional  Kernel AX.25 networking support
+festival                        Optional  Speaking alerts
+libcurl or wget                 Optional  Internet images as maps
+GPSMan/gpsmanshp                Optional  Converts GPS data to Shapefiles
+GDAL/OGR                        Optional  Many formats (coming soon)
+libdb (4.0 or newer)            Optional  Internet map caching (fast!)
+libpq                           Experimental Persistent data with Postgis
+libmysqlclient                  Experimental Persistent data with MySQL
+
+Library/Option Heirarchy:
+-------------------------
+
+    ImageMagick (Usually requires additional libraries)
+
+    GDAL/OGR (Usually requires additional libraries)
+
+    error_popups (Annoying popups, turned off by default)
+
+    libgc (developer stuff:  memory leak testing)
+
+    "festival --server &" (Xastir connects to this server)
+      |
+      `-----------> Festival
+ 
+    gprof
+      |
+      `-+---------> profiling (developer stuff)
+       /
+      |
+    gprof-helper.so
+
+    libax25
+      |
+      `-----------> AX25
+
+    libProj
+      |
+      `-+-------+-> GeoTiff
+       /       /
+      /       /
+    libtiff  /
+            /
+    libgeotiff
+
+    gpsmanshp
+      |
+      `-+------+--> GPSMan
+       /      /
+      |      /
+    tcl/tk  /
+           /
+    ShapeLib 
+      |
+      +-----------> rtree
+      |
+      `-+---------> Dbfawk
+       /
+      |
+    PCRE
+
+    libcurl or wget
+       |
+       `-+--------> map_caching
+        /
+       |
+    Berkeley DB
+
+
+    MySQL --------> MySQL database interfaces (Experimental)
+      |
+      `-+---------> db2APRS (Xastir connects to this server)
+       /
+      |
+    Meteo
+
+    Postgresql
+      |
+      `-+--------> Postgis database interfaces (Experimental)
+        |                      +
+       /        QGIS [station data in another GIS application]
+      |
+    Postgis
+
+---------------------------------
+
+
+Installing only the required libs gives you these capabilities:
+
+    PocketAPRS maps
+    aprsDOS maps
+    WinAPRS maps
+    MacAPRS maps
+    GNIS labels
+    Address searching
+    serial port and Internet gateway connectivity.
+
+Adding XPM or ImageMagick libs, ImageMagick's "convert" utility, and
+the "gv" utility gives you printing capability.  Postscript or
+emulated postscript printing capability is required for this as well.
+
+Adding XPM or ImageMagick libs plus "convert" also give the
+capability to create automatic PNG images on disk from the map
+screen (useful for web pages!).
+
+Adding Shapelib support also gives you the capability to use Tiger
+2000 maps which were converted to Shapefile format by ESRI.  This
+allows you to use free detailed street maps for any point in the
+U.S.
+
+Adding other libraries gives you the additional capabilities listed
+above.
+
+For those who would like to see the full list of libraries Xastir
+might use (to decide what packages to install), here's the ldd
+command run against a pretty much fully-loaded Xastir.  Note that
+quite a few of these libraries are pulled in by the ImageMagick
+library, and your library list may look little like it due to
+differences in how ImageMagick was compiled:
+
+  > ldd /usr/local/bin/xastir
+    libXm.so.3 => /usr/X11R6/lib/libXm.so.3 (0x40030000)
+    libXt.so.6 => /usr/X11R6/lib/libXt.so.6 (0x40287000)
+    libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x402db000)
+    libMagick.so.0 => /usr/lib/libMagick.so.0 (0x403d7000)
+    liblcms.so.1 => /usr/lib/liblcms.so.1 (0x4052f000)
+    libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x40553000)
+    libexif.so.9 => /usr/lib/libexif.so.9 (0x405a9000)
+    libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x405be000)
+    libSM.so.6 => /usr/X11R6/lib/libSM.so.6 (0x405cc000)
+    libICE.so.6 => /usr/X11R6/lib/libICE.so.6 (0x405d5000)
+    libbz2.so.1 => /usr/lib/libbz2.so.1 (0x405ed000)
+    libz.so.1 => /usr/lib/libz.so.1 (0x405fd000)
+    libpthread.so.0 => /lib/i686/libpthread.so.0 (0x4060c000)
+    libm.so.6 => /lib/i686/libm.so.6 (0x4065d000)
+    libdb-4.1.so => /usr/lib/libdb-4.1.so (0x40680000)
+    libXpm.so.4 => /usr/X11R6/lib/libXpm.so.4 (0x40744000)
+    librt.so.1 => /lib/librt.so.1 (0x40755000)
+    libcurl.so.2 => /usr/lib/libcurl.so.2 (0x40768000)
+    libXp.so.6 => /usr/X11R6/lib/libXp.so.6 (0x4078f000)
+    libshp.so.1 => /usr/local/lib/libshp.so.1 (0x40797000)
+    libpcre.so.0 => /usr/lib/libpcre.so.0 (0x4079f000)
+    libproj.so.0 => /usr/local/lib/libproj.so.0 (0x407ab000)
+    libtiff.so.3 => /usr/lib/libtiff.so.3 (0x407e2000)
+    libgeotiff.so => /usr/local/lib/libgeotiff.so (0x4082b000)
+    libax25.so.0 => /usr/lib/libax25.so.0 (0x4084d000)
+    libgdal.so.1 => /usr/local/lib/libgdal.so.1 (0x40856000)
+    libc.so.6 => /lib/i686/libc.so.6 (0x40b64000)
+    libdl.so.2 => /lib/libdl.so.2 (0x40c97000)
+    /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
+    libssl.so.0.9.7 => /usr/lib/libssl.so.0.9.7 (0x40c9b000)
+    libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0x40ccb000)
+    libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x40dbd000)
+    libjasper-1.700.so.2 => /usr/lib/libjasper-1.700.so.2 (0x40ddd000)
+    libpng.so.3 => /usr/lib/libpng.so.3 (0x40e2c000)
+    libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40e5b000)
+    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40f1b000)
+
+
+
+Things you need for this version:
+---------------------------------
+ * Get Lesstif/OpenMotif from your favorite Linux/Unix distribution.
+-or-
+ * Lesstif: www.lesstif.org (look below for RED-HAT instructions)
+-or-
+ * OpenMotif: www.openmotif.org
+
+ * AX25 packages: (if you want support for kernel AX25 interfaces)
+    Lib AX25:http://prdownloads.sourceforge.net/ax25/libax25-0.0.7.tar.gz
+    AX25 apps:http://prdownloads.sourceforge.net/ax25/ax25-apps-0.0.4.tar.gz
+    AX25 tools:http://prdownloads.sourceforge.net/ax25/ax25-tools-0.0.8.tar.gz
+    The apps package is not required, but strongly suggested. These versions
+     are current as of the writing of this document; feel free to use newer
+     versions.  Make sure the versions you choose match your kernel version.
+    Also note that there are patches required to the 2.4 kernel for AX.25
+    kernel networking.  See the linux-hams mailing list for details.
+
+ * You should have glibc on your system that supports threads!
+
+
+For geoTIFF support (such as USGS DRG topo maps) you also need:
+
+    libtiff (should be on your distribution's CD's):
+    ------------------------------------------------
+        http://www.libtiff.org
+
+    libproj (proj-4.4.9):
+    ---------------------
+        http://proj.maptools.org/
+        http://www.remotesensing.org/proj/
+        http://wetnet.net/~we7u/xastir/
+
+    Datum translations (proj-nad27 or proj-datumgrid):
+    --------------------------------------------------
+        http://proj.maptools.org/
+        ftp://ftp.remotesensing.org/pub/proj/
+        http://wetnet.net/~we7u/xastir/
+
+    libgeotiff (libgeotiff-1.1.5 or libgeotiff-1.2.4):
+    --------------------------------------------------
+        http://dl.maptools.org/dl/geotiff/libgeotiff/
+        http://www.remotesensing.org/geotiff/geotiff.html
+        ftp://ftp.remotesensing.org/pub/geotiff/libgeotiff/
+        http://wetnet.net/~we7u/xastir/
+
+    Please note that the order of installation for the above libraries is
+    critical.  Follow the instructions below carefully.  Also, the particular
+    libgeotiff you use depends on the version of libtiff you have installed.
+
+For Linux kernel AX.25 interfaces, you require these packages:
+    Lib AX25:http://prdownloads.sourceforge.net/ax25/libax25-0.0.11.tar.gz
+    AX25 apps:http://prdownloads.sourceforge.net/ax25/ax25-apps-0.0.6.tar.gz
+    AX25 tools:http://prdownloads.sourceforge.net/ax25/ax25-tools-0.0.8.tar.gz
+    The apps package is not required, but strongly suggested. These versions
+     are current as of the writing of this document; feel free to use newer
+     versions.  Make sure the versions you choose are compatible with your
+     kernel version. See the AX.25 HOWTO and the linux-hams mailing list for
+     details.
+
+For speech support via the festival speech synthesis software you need:
+    festival:
+       http://www.speech.cs.cmu.edu/festival/
+       http://at.rpmfind.net/opsys/linux/RPM/redhat/7.0/powertools/i386/festival-1.4.1-5.i386.html
+
+    If you're running a slightly older version of Linux you'll need to install 
+    festival from sources to make it work properly.
+
+For ESRI Shapefile format maps/weather alert maps:
+    Shapelib:
+        http://shapelib.maptools.org/
+        http://wetnet.net/~we7u/xastir/
+    pcre:
+        http://www.pcre.org
+
+For GDAL/OGR:
+    http://www.gdal.org/
+    http://remotesensing.org/gdal/
+    http://www.maptools.org
+    http://wetnet.net/~we7u/xastir/
+
+For ImageMagick support for maps in any of 68 major graphics formats,
+   including the capability to use online maps and weather radar images:
+    ImageMagick:
+        http://www.imagemagick.org/
+
+To use online maps or findu.com historical data, you'll need wget or
+   libcurl/libcurl-devel installed.  Many systems have these pre-installed,
+   so check first.  You may need to upgrade your installed version for
+   this feature to work correctly from within Xastir:
+    Wget:
+        ftp://ftp.gnu.org/gnu/wget/
+    libcurl:
+        http://curl.sourceforge.net/
+
+
+To download GPS tracks/waypoints/routes from a Garmin GPS into Xastir,
+converting to Shapefile format maps as it runs, you'll need gpsmanshp and
+GPSMan.  GPSMan 6.0 and later has command-line support built-in so that
+Xastir can control it directly, but only GPSMan 6.1 and later are currently
+usable with Xastir:
+    gpsmanshp:
+        http://www.ncc.up.pt/gpsmanshp/
+    GPSMan:
+        http://www.ncc.up.pt/gpsman/
+        http://sunsite.unc.edu/pub/Linux/science/cartography
+
+See below for instructions on installing all of these libraries. Once the 
+  libraries are installed, ./configure should find the libraries and allow
+  compiling in support for the new features.
+
+
+If you wish to enable/disable configure's testing of certain
+features, you can add any of the following flags to configure:
+
+    --without-ax25
+    --without-festival
+    --without-gpsman
+    --without-imagemagick
+    --without-libproj
+    --without-geotiff
+    --without-gdal
+    --without-shapelib
+    --without-pcre
+    --without-dbfawk
+    --without-map-cache
+    --with-errorpopups
+    --with-libgc
+    --with-profiling
+    --with-rtree
+    --with-lsb
+    --with-postgis
+    --with-mysql
+
+For example, "./configure --without-ax25" will disable the AX.25
+networking code in Xastir.
+
+If you have installed Xastir before, read the "UPGRADE" file for
+information on changes in file location and permissions.
+
+
+First Time Install:
+-------------------
+
+   1. OPTIONAL:  If you wish to use AX.25 interfaces, install the AX.25
+      packages.  Verify that they are configured and working. Use "listen"
+      to watch the packets fly by after getting AX.25 configured and hooked
+      to a TNC.  Use the AX.25 HOWTO document to guide you in this process.
+
+
+   2. Install LessTif or OpenMotif
+
+     If you already have Motif or OpenMotif on your system, including
+     the development headers, then you won't need to install LessTif. Most
+     distributions include one of these; step 2a describes building from
+     source, while 2b describes installing from pre-built packages on
+     your distribution. Now that OpenMotif is available, you may be happier
+     running it than LessTif, but either one should work with Xastir.
+
+     Some users have had problems with OpenMotif, and others have had troubles
+     with LessTif. Symptoms are often menu problems (menus don't draw
+     correctly, menus won't respond to clicks). If you encounter these
+     problems, then uninstall the current Motif and install the other.  Several
+     Mac users have reported problems with OpenMotif, so LessTif may be a
+     better place to start.
+
+        2a. Download LessTif version 0.91.1 or higher or download OpenMotif.
+        Follow the instructions provided, compile it and install it.
+
+        Usually,
+         ./configure
+         make
+         su (root)
+         make install
+         /sbin/ldconfig
+         exit (from root)
+
+        Or you can try any other OSF/Motif(R) version 1.2
+
+
+       2b. Install LessTif or OpenMotif (from a package)
+
+       Download the lestif-devel (if it exists) and lestif, and install it
+       as your distribution instructs you to install packages.
+
+
+   3. OPTIONAL:  Install geoTIFF support.  Allows using USGS DRG topo maps or
+     other types of geoTIFF maps/images and has the ability to tile smaller
+     maps into a larger contiguous map of an area:
+
+
+       3a.  Check/Edit your startup files:
+       -----------------------------
+       Check that /usr/local/lib, /usr/lib, and /usr/X11R6/lib are
+       all listed in /etc/ld.so.conf, and run /sbin/ldconfig to
+       re-create the system's cache file. If you don't have
+       permission to edit this file:
+            Edit ~/.bashrc, ~/.bash_profile, .cshrc, or
+            .login and add:
+
+            export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/usr/X11R6/lib
+
+       This will let the loader find the shared libraries when it tries to
+       load Xastir into memory.
+
+       If you instead have a /etc/ld.so.conf.d directory, then this will add
+       the /usr/local/lib directory to the search:  Create a file in the
+       /etc/ld.so.conf.d called "local.conf".  The file should contain exactly
+       one line:
+
+            /usr/local/lib
+
+       Use your favorite text editor or use these commands:
+
+           echo "/usr/local/lib" > /etc/ld.so.conf.d/local.conf
+           ldconfig -v
+
+       Check that you aren't already defining LD_LIBRARY_PATH somewhere else.
+       If so, just add the paths above to it.  Make sure this environment
+       variable is defined in the current shell you're using to compile Xastir.
+       Note that if you're running Xastir SUID root, the LD_LIBRARY_PATH
+       variable is ignored.
+
+
+       3b. Install libproj:
+       --------------------
+     NOTE: You must install libproj BEFORE compiling libgeotiff, because
+       libgeotiff uses libproj to do the datum translations. If you install
+       libgeotiff first, datum translations won't work.
+
+       proj-nad27-1.1.tar.gz or proj-datumgrid-1.3.zip must be decompressed in
+       the nad subdirectory of the proj distribution directory before you run
+       configure.
+        
+        tar xzvf proj-4.4.9.tar.gz (or newer)
+        cd proj-4.4.9/nad
+        unzip ../../proj-datumgrid-1.3.zip (or tar xzvf ../../proj-nad27-1.1.tar.gz)
+        cd ..
+        ./configure
+        make
+        su (root)
+        make install
+        /sbin/ldconfig
+        exit (from root)
+
+        libproj should now be installed in:
+
+            /usr/local/include/
+            /usr/local/lib/
+            /usr/local/bin/
+            /usr/local/share/proj/
+
+       You may need to do this (as root) if the "make install" portion fails
+       because it can't find "ginstall":
+
+       cd /usr/bin
+       ln -s install ginstall
+
+       Then retry the "make install" portion above.
+
+
+       3c. Upgrade libtiff if needed:
+       -----------------------------
+       The best way to install libtiff is to get it from the ftp site
+       for your Linux distribution.  You must have libtiff 3.5.5 or
+       newer for libgeotiff 1.1.x to compile and run correctly, or libtiff
+       3.6.0 BETA or newer for libgeotiff 1.2.x to work correctly.
+
+       If you're using libtiff 3.6.0 BETA or newer, things are simplified.
+       Just use libgeotiff 1.2.x or newer and they should play nicely together.
+
+       ---------
+       Notes for older libtiff (less than 3.6.0 BETA):
+
+           If you are compiling libtiff from source, you must use
+           "make install_private" because the libtiff private include files
+           are required for libgeotiff to compile and work correctly.
+
+           You may also snag just the include files listed below from the
+           source distribution or the source RPM, and copy them manually to
+           their destinations.
+
+           The errors you'll get if you don't match up the older libtiff and
+           libgeotiff by way of the include files:  Xastir will seg-fault when
+           it tries to read a geotiff file.
+       ---------
+
+       If you upgrade libtiff, check that programs like XV, ImageMagick, and
+       the Gimp still run (if you have these programs installed).  Graphics
+       programs that read/write TIFF format depend on libtiff.
+
+
+       3d. Install libgeotiff:
+       -----------------------
+
+     NOTE: Depending on your version of libtiff, either libgeotiff-1.1.5 or
+       libgeotiff-1.2.4 may compile properly.  libgeotiff is intimately
+       tied to your version of libtiff.  libgeotiff 1.2.x or greater
+       requires libtiff-3.6.0 BETA or later.  If your version of libtiff is
+       older, get libgeotiff 1.1.4 or 1.1.5.  For the latter case you may
+       also have to download the sources for your version of libtiff in
+       order to copy one libtiff header file into the libgeotiff source
+       directory.
+
+     -----------------------
+     Pre 3.6.0 libtiff NOTE: You may need to snag some files from your exact
+       libtiff source distribution and place them into your /usr/include
+       directory before libgeotiff will compile.  Note:  I said use files from
+       the EXACT same distribution of libtiff that you already have installed!
+
+            libtiff/tiffconf.h
+            libtiff/tiffiop.h
+            libtiff/tif_dir.h
+            contrib/dosdjgpp/port.h
+
+       Drop all four files into the /usr/include/ directory, creating no 
+       subdirectories at all.  This allows the libgeotiff code to "see"
+       into the libtiff library so that it can use some functions that
+       aren't normally (publicly) available.  Try to make sure that
+       you're not overwriting any files in /usr/include/ by the same name.
+       Some of these files may already be present in /usr/local/.  If so,
+       they should be exact duplicates.  "diff filename1 filename2" will
+       tell you if there are any differences between two files.
+
+       If you'd rather not mess with the /usr/include directory,
+       you can drop the four files into the
+       libgeotiff-1.1.5/libtiff_private/ directory instead.  Libgeotiff
+       will pick up the files there, issue a warning to you that you're
+       using private include files, yet still compile in support for your
+       particular version of libtiff.
+
+       With libgeotiff-1.2.4/libtiff-3.6.0-beta or newer you shouldn't
+       need to copy these files across.  The newer libtiff and libgeotiff
+       can work together using public interfaces.
+     ------------------------
+
+        tar xzvf libgeotiff-1.2.4.tar.gz (or newer)
+        cd libgeotiff-1.2.4
+        ./configure
+        make
+        su (root)
+        make install
+        /sbin/ldconfig (tells the loader about the new libraries)
+        exit (from root)
+       libgeotiff should now be installed in:
+
+            /usr/local/include/
+            /usr/local/lib/
+            /usr/local/share/epsg_csv/
+            /usr/local/bin/
+
+       If you must re-run "configure" for any of these libraries, remember to 
+       delete "config.status" and "config.cache" files first.
+
+
+   4. RECOMMENDED:  Install ESRI Shapefile support.  Allows using many sources
+     of online polygon, polyline, and point maps, including ones from NOAA.
+     This is also the format for weather alert maps.  This support is provided
+     by the shapelib package.
+
+     NOTE:  There are TWO ways to install Shapelib, using the version of
+     Shapelib that comes with Xastir (statically linked with Xastir), or using
+     a separate Shapelib shared library (dynamically linked with Xastir).  If
+     you ONLY require Shapelib for Xastir and won't need it for any other
+     program, then you may use the private copy distributed with Xastir,
+     skipping the Shapelib install instructions in this section.  If you have
+     other programs which need Shapelib, then it is recommended that you
+     install Shapelib first as a shared library, per the instructions below.
+     If you skip the instructions in this sections, "./configure" will set the
+     compile up so that the private Shapelib code will be statically
+     linked to the executable.
+
+     It isn't clear from the install instructions in shapelib, but just 
+     installing the library is sufficient, and just typing "make" and 
+     "make install" doesn't make or install the libraries.  Take these steps:
+
+       make lib
+       su (root)
+       make lib_install
+       /sbin/ldconfig
+       exit (from root)
+
+     and you should have what you need.
+ 
+     You may also need to tweak "/etc/ld.so.conf" to contain the proper path
+     to the libraries and then run /sbin/ldconfig to update "/etc/ld.so.cache".
+     Once this is done the loader should be able to find the Shapelib library.
+     Must run /sbin/ldconfig as root for the system to be able to re-create its
+     cache file.  See the instructions earlier in this file if you have an
+     /etc/ld.so.conf.d directory instead (section 3A).
+
+     For MacOSX:  Bill Owen, N2RKL, suggested the following for
+     ShapeLib:
+
+       "The shapelib Makefile wouldn't work out of the box, so I
+       figured out what the important bits were and built them by
+       hand:"
+
+       -----------------------------------------------
+         cc -c shpopen.c
+         cc -c shptree.c
+         cc -c dbfopen.c
+         ar cru libshp.a shpopen.o shptree.o dbfopen.o
+         sudo cp libshp.a /sw/lib
+         sudo ranlib /sw/lib/libshp.a
+         sudo mkdir /sw/include/libshp
+         sudo cp shapefil.h /sw/include/libshp/
+       -----------------------------------------------
+
+    Note that you'll have to set up /etc/sudoers file to allow those
+    commands to be run by a normal user before sudo will work for
+    you.  See the README.CVS file for sudo instructions.
+
+
+    Note from Gale Wilkinson, kc4pl:
+    > >
+    > > How do you get shapelib to "make" properly under cygwin?    I
+    > > have installed the latest cygwin (packages per the win32
+    > > install notes) and then downloaded and unpacked the latest
+    > > shapelib source package for compiling.  But when trying to do
+    > > the "make lib" it errors out part way through the process.
+    > > The error seems to be:
+    > >
+    > >  dbfopen.lo: In function 'DBFReadAttribute':
+    > > /home/gwilkinson/src/shapelib-1.2.10/dbfopen.c:724:undefined reference to '__getreent'
+    > > /home/gwilkinson/src/shapelib-1.2.10/dbfopen.c:716:undefined reference to '__getreent'
+    > > make: *** [lib] Error 1
+
+    Dan Brown, n8ysz, responded:
+    >
+    > I wrote this to get/make shapelib: 
+    >
+    > http://brauhaus.org/xastir/get_shapelib.sh
+    > or
+    > http://brauhaus.org/xastir/get_shapelib.sh.txt
+
+    This script is now also in the Xastir sources as
+    "xastir/scripts/get_shapelib.sh".
+
+
+    COMPILING OPTIONAL UTILITIES FOR SHAPELIB:
+
+    These utilities are sometimes useful when writing dbfawk rules
+    but aren't necessary for running Xastir.
+
+      cd xastir/src/shapelib
+      make -f Makefile_shapelib_orig
+
+      cd contrib
+      make -f Makefile_orig
+
+     You'll be left with useful executables in the xastir/src/shapelib and
+     xastir/src/shapelib/contrib directories.  It's your choice whether to
+     copy them to a directory in your path (perhaps /usr/local/bin?) to make
+     them easier to use.
+
+
+   5. OPTIONAL:  Install -either- GraphicsMagick or ImageMagick support as
+     shown below.  Xastir will use one or the other but not both.  It'll prefer
+     GraphicsMagick over ImageMagick if both are installed.  Do step 5a -or- 5b
+     below to get this type of image support compiled into Xastir.
+
+     Allows using more than 68 different graphics format files as maps, by
+     creating an associated .geo file for each with tie-points.  This support
+     will allow use of online Tiger and Terraserver maps with Xastir, and NOAA
+     weather radar images.  Other people are working on integrating even more
+     online mapping sources.  This will also allow you to use any GIF/JPG/XPM/
+     BMP/... image as an Xastir map. Installation instructions are included in
+     the package. If you choose to install from a binary install, be sure that
+     you have all the graphic format libraries that it was originally built
+     with.
+
+     The easiest way to install one of these is via a package from your linux
+     distribution's CD or ftp site. If you install from such a package, make
+     sure the header files are installed. These are often in a separate package
+     called GraphicsMagick-devel or ImageMagick-devel or similar.
+
+ 
+   5a. OPTIONAL:  Install GraphicsMagick support.
+
+     Download the GraphicsMagick sources from:
+
+     http://www.graphicsmagick.org
+
+     Uncompress/un-tar them...
+
+        tar -xzvf Gr*
+
+     Change directory to the newly created GraphicsMagick directory and
+     compile:
+
+        cd Gr*
+        ./configure --with-quantum-depth=16 --enable-shared
+        make
+        su -c 'make install'
+        su -c '/sbin/ldconfig'
+
+     Skip the next step (5b) as you only need ImageMagick support installed if
+     you _don't_ install GraphicsMagick.
+ 
+ 
+   5b. OPTIONAL:  Install ImageMagick graphics support.
+
+     Note that Xastir's "./configure" stage may fail trying to compile in
+     ImageMagick support.  If this happens, make sure you have the ImageMagick
+     development package installed if using RPM packages, or have installed
+     the ImageMagick header files.  If it still fails, check the "config.log"
+     file _very_ carefully.  Often ImageMagick tests fail due to some other
+     library that ImageMagick depends upon being absent, such as liblcms,
+     libbz2, or others.  This can also cause AX.25 support to be dropped in our
+     current "configure" script.  We're working on that.
+
+     Until the RPM packagers for ImageMagick include all of the dependent
+     libraries in their RPM dependency list, the best way to assure that
+     ImageMagick is installed properly is to install it from sources.
+
+     -------------------------------------------------------------------------
+     Note: Red Hat 9.0's install of ImageMagick does not work with
+     XASTIR.  It will need to be removed and installed from sources.
+     If w3m text based web browser is installed, you will need to remove
+     it before removing ImageMagick:
+
+        rpm -e w3m
+        rpm -e ImageMagick
+
+     Download the Imagemagick sources from:
+
+	ftp://ftp.imagemagick.org/pub/ImageMagick/
+
+     At the time of writing, this was
+
+	ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-5.5.7-34.tar.gz
+
+     But you may need to get a newer version by the time you read this.
+
+     Uncompress/un-tar them...
+
+        tar -xzvf im*
+
+     Change directory to the newly created ImageMagick directory and
+     compile:
+
+        cd im*
+        ./configure
+        make
+        su -c 'make install'
+        su -c '/sbin/ldconfig'
+
+     These instructions are courtesy of Wes Johnston.
+     -------------------------------------------------------------------------
+
+
+   6. OPTIONAL:  If your system doesn't have wget or libcurl/libcurl-devel
+     installed, and you want to use online maps, install either or both of
+     those packages now. Installation instructions are included in the
+     package.  Some older versions of wget don't work properly with
+     Xastir, so even if you already have wget you may need to upgrade it.
+
+     Please refer to the wget man pages or the web pages at
+     http://www.gnu.org/software/wget/wget.html for info concerning wget.
+
+     Note that if the remote server is down, Xastir can appear to hang
+     for a bit before wget times out.  Xastir calls wget with no retries
+     and a 30-second timeout, but one user reported that wget takes one
+     minute fifteen seconds to time out.  Also note that the users ~/.wgetrc
+     and the system-wide wgetrc file can change the timeouts and retries as
+     well.  See the man pages for details.  Pay particular attention to
+     which file/command-line-options take priority over others.  It looks
+     like the command-line option "--execute command" will allow overriding
+     the .wgetrc files, which means the user can override the hard-coded
+     timeouts/retries in Xastir by specifying new defaults in their ~/.wgetrc
+     file.
+
+     Libcurl should be a drop-in replacement for the wget functionality that
+     we use, and it's a faster and more secure method.
+
+   7. OPTIONAL:  Installing gpsmanshp/GPSMan allows Xastir to fetch GPS
+     waypoints/routes/tracks from a GPS.  Xastir can fetch the data
+     automatically, create a Shapefile map, then index/select/display the
+     new map.
+
+     Make sure you have Shapelib installed first (see above instructions).
+
+     Note that you may have to change the gpsmanshp Makefile to call out
+     "TCLVERSION = 8.4" instead of 8.3, depending upon which version of tcl is
+     installed on your system.  Use your package manager to determine this
+     ("rpm -q -a | grep tcl"), or you may be able to find out in /usr/lib by
+     typing "ls -ld tcl*".
+
+     Install gpsmanshp:
+
+     tar xzvf gpsmanshp_1.2.2.tgz
+     cd gpsmanshp
+     make
+     su -c 'make install'
+
+     Install GPSMan:
+
+     tar xzvf gpsman-6.0.tgz
+     cd gpsman-6.0
+     vi gpsman.tcl
+       Change SRCDIR line to: "set SRCDIR /usr/lib/gpsman"
+     su (root)
+     mkdir /usr/lib/gpsman
+     cp gpsman.tcl /usr/lib/gpsman
+     ln -s /usr/lib/gpsman/gpsman.tcl /usr/X11R6/bin/gpsman
+     cd gmsrc
+     cp * /usr/lib/gpsman
+     cp -R gmicons /usr/lib/gpsman
+     chmod -R 755 /usr/lib/gpsman
+     chmod 644 /usr/lib/gpsman/gmicons
+     chmod 777 /usr/local/share/xastir/maps/GPS   (IMPORTANT!)
+     exit (from root)
+
+     Verify that GPSMan will start up and will download information from a
+     Garmin GPS in Garmin-Garmin mode.  This also creates the configuration
+     files needed to use GPSMan with Garmin GPS's from within Xastir (sets
+     GPS type, serial port, etc within GPSMan's configs).
+
+   8. OPTIONAL: Install Festival for speech support
+      To use speech you must have a sound card and the 'festival' speech
+      synthesis software installed. Install Festival and start it in 'server'
+      mode prior to starting up XASTIR.  The normal command for this is
+      "festival --server &". More info about the speech features is in the
+      Xastir help file. An easy way to get festival installed on some systems
+      is to go to rpmfind.com and search for both festival and festival-dev,
+      then install the RPM's found. Red Hat RPM's installed onto SuSE 7.3 with
+      no problems. Note that the default voice doesn't speak numbers very well.
+      Edit /usr/share/festival/voices.scm and put "ked_diphone" at the first of
+      the "defvar default-voice-priority-list". This will change the default
+      voice to "ked_diphone".
+
+      Note that you can start up the festival server and test it out manually
+      by typing these commands:
+
+        telnet localhost 1314
+        (SayText "Hello")
+
+      To exit, press control-] and then type "quit".
+
+   9. OPTIONAL:  Install GDAL/OGR for support of many more map formats.
+
+      NOTE:  There are some cases where adding GDAL can mess up support for a
+      few of the other libraries, like Shapelib, libproj, or libgeotiff.  GDAL
+      may be compiled with support these libraries internally and it is
+      possible to have Xastir linked against some of GDAL's internal libraries
+      but using the external library headers.  If the versions of each are
+      sufficiently different, things may not work right.  If you run into such
+      problems you can either reconfigure GDAL to use external libraries for
+      these three or configure Xastir without GDAL support.  Also see the note
+      below about libtiff-3.8.0.
+
+      NOTE:  This is currently being added to Xastir:  Some support is there
+      now for the vector formats, but it isn't "pretty" yet.  Should you wish
+      to see what map formats your system will support once GDAL/OGR are fully
+      integrated into Xastir, proceed with the following:
+
+        cd ~src (or wherever you keep your sources)
+        export CVSROOT=:pserver:cvsanon at cvs.maptools.org:/cvs/maptools/cvsroot
+        cvs login
+        Password: <ENTER>
+        cvs checkout gdal
+
+      Optionally you can also use one of the newer GDAL releases, so in that
+      case just download that instead of the above instructions, then do the
+      following instructions for either:
+
+        cd gdal
+        ./configure --without-mysql 
+        make
+        su (root)
+        make install
+        /sbin/ldconfig
+        exit (from root)
+
+      A configure line that worked with older GDAL code was:
+
+        ./configure --without-jasper --without-ld-shared
+
+      Here's another GDAL configure command which forces GDAL to use its own
+      internal libraries for some of the formats:
+
+      ./configure --without-mysql --with-libz=internal --with-png=internal \
+      --with-jpeg=internal --with-geotiff=internal --with-libtiff=internal \
+      --with-gif=internal 
+
+      Also note that as of Dec 11, 2003, a major memory leak bug in the OGR
+      code was fixed, having to do with Shapefiles.  Please run a version of
+      GDAL/OGR that is newer than that date (or use the CVS version as
+      described above).
+
+      In one case linking in GDAL caused some GTIFProj4ToLatLong calls to break
+      in an odd manner due to Xastir linking in libgeotiff functions from the
+      GDAL library in that case instead of the libgeotiff library:  GeoTIFF's
+      with UTM coordinates stop working.  Configuring Xastir without GDAL
+      support -or- upgrading libtiff to 3.8.0 fixes the problem.
+
+   10. OPTIONAL:  Install Berkely DB Library to enable map caching
+      of internet maps.
+
+      Please note that segfaults (crashes) in Berkeley DB calls can be caused
+      by having multiple versions of the library installed.  The programming
+      interface has changed between the versions.  If you compile Xastir with
+      one version's header files but Xastir links to another version's
+      library, you can easily end up with segfaults when Xastir runs.  SuSE
+      Linux for instance has these available which you _should_ install:
+
+            db 
+            db-devel
+
+      Plus SuSE has these additional packages available which you should _not_
+      install.  Remove them if they're on your system (using YaST or rpm):
+
+            db-40
+            db42
+
+      Xastir will normally try to use /usr/include/db.h as the header file,
+      and /usr/lib/libdb.so as the library it will link to (which is usually
+      a symlink to something else, like /usr/lib/libdb-4.1.so).  If the
+      header file and the library file don't match, a segfault often occurs.
+      The easiest way to avoid problems is to keep one and only one version
+      of the Berkeley DB library on your system.
+
+      Here's how to test what version of include file and library file you're
+      using:  Find the db.h file.  It's usually in /usr/include/db.h.
+
+            grep DB_VERSION db.h
+
+      Mine shows this:
+
+        #define DB_VERSION_MAJOR        4
+        #define DB_VERSION_MINOR        1
+        #define DB_VERSION_PATCH        25
+        #define DB_VERSION_STRING       "Sleepycat Software: Berkeley DB 4.1.25: (October  2, 2003)"
+
+      Now do this:
+
+        ldd /usr/local/bin/xastir | grep libdb
+
+      Mine shows this:
+
+        libdb-4.1.so => /usr/lib/libdb-4.1.so (0x40680000)
+
+      In this case, version 4.1 of the include file matches 4.1 of the library
+      file, so it works fine.  A mismatch in the first two numbers can cause
+      segfaults when Xastir tries to do map caching.
+
+      If you install the Berkeley DB library in an unusual place (something
+      other than /usr/lib and /usr/include), you should still be able to tell
+      configure where to find it.  This comes courtesy of Tom Russo:
+
+      > > Someone installed Berkeley DB Library here:
+      > > 
+      > >     /user/local/BerkeleyDB.4.3/include/db.h
+      > > 
+      > > Perhaps I can assume that the library would be located here:
+      > > 
+      > >     /usr/local/BerkeleyDB.4.3/lib/libdb.so
+      > > 
+      > > How does one go about specifying the location of the db.h file and
+      > > the libdb.so file so that configure/compile/loading of Xastir work
+      > > properly?
+
+      > --with-bdb-libdir=/usr/local/BerkeleyDB.4.3/lib
+      > and
+      > --with-bdb-incdir=/usr/local/BerkeleyDB4.3/include
+
+   11. OPTIONAL:  Compile db2APRS and install MySQL and Meteo to
+      allow Davis weather station support.
+
+      Install MySQL and Meteo. 
+
+        "cd Davis"
+        "./bootstrap.sh"
+        "./configure"
+        "make"
+
+      This should build db2APRS in the "src" directory.  Start up db2APRS.
+      Xastir should be able to connect to the db2APRS server in order to get
+      the Davis weather station data.  See further instructions in the Davis
+      directory.
+
+   12. OPTIONAL: Experimental.  Add GIS database support.  
+
+      Note: Database support is experimental and any aspect may change at
+      any time, including database structures.  Scripts to create database
+      tables for MySQL and Postgres/Postgis are in the scripts directory
+      as db_gis_postgis.sql and db_gis_mysql.sql.
+
+      Warning: If you are connected to internet feeds for APRS data, it
+      is possible to accumulate several million station records per day
+      which could amount to around 300 MB of database records per day.  
+
+      Postgres + Postgis:
+      Install Postgres.  Include development packages (libpq).
+      Add Postgis spatial object support to Postgres.
+
+      Compile xastir with --with-postgis
+
+      After building xastir:
+      Create a database named xastir and a user with create rights on 
+      that database.
+      Edit db_gis_postgis.sql to set username and password for an xastir
+      user with select access to the xastir database.
+      Default values are database=xastir, user=xastir_user
+      You may also need to set permissions in pg_hba.conf.
+      Run the queries in db_gis_postgis.sql.
+      Run xastir and add a SQL Database interface, start with the postgis
+      defaults, add the username and password of the xastir user. 
+
+      Other GIS applications (e.g. QGIS, Mapserver, GRASS) can access and
+      display station data directly from the postgresql/postgis database.  
+
+      You can configure the database interface to read station from the 
+      database on startup and to save stations as they are heard to the
+      database.  This provides persistance of station data between
+      xastir sessions.
+
+      MySQL:
+      Install MySQL.  Include development packages (libmysqlclient).
+
+      Compile xastir with --with-mysql
+
+      After building xastir:
+      Create a database named xastir and a user with create rights on 
+      that database.
+      Edit db_gis_mysql.sql to set username and password for an xastir
+      user with select access to the xastir database.
+      Default values are database=xastir, user=xastir_user
+      Run the queries in db_gis_mysql.sql
+         mysql xastir -p < db_gis_mysql.sql
+      Run xastir and add a SQL Database interface, start with the MySQL
+      defaults, add the username and password of the xastir user. 
+
+      You can configure the database interface to read station from the 
+      database on startup and to save stations as they are heard to the
+      database.  This provides persistance of station data between
+      xastir sessions.
+
+      If you have one or more spatial database interfaces set to activate on 
+      startup, and this produces a situation that won't let you start xastir
+      normally [e.g. Station data with unusual characters could concevable 
+      cause xastir to segfault when retrieved from the database, and 
+      interactions between multiple databases that are both writing are 
+      reading station data at the same time from each other could potentally 
+      be unstable], you should be able to start xastir by editing the 
+      device configuration in ~/.xastir/config/xastir.cnf
+      Look for DEVICEn_TYPE:14 lines (where n is the interface number, between 0
+      and 14, TYPE:14 devices are sql database interfaces), and edit the
+      device to set both query on startup and on startup values to 0.
+      DEVICEn_QUERY_ON_STARTUP:0
+      DEVICEn_ONSTARTUP:0
+      If the cause is problematic data in your database, you may need to
+      run a delete query to eliminate the problematic row(s).  
+     
+ 
+   13. Building XASTIR:  Note that you'll need autoconf 2.53 or newer and
+      automake 1.6.3 or newer in order to run the "./bootstrap.sh" script.
+    
+        "./bootstrap.sh" (This step needed only for those using CVS)
+        "./configure"
+        "make" ("gmake" for Solaris or *BSD)
+
+     This builds XASTIR, You should not get any error or warning messages.
+
+     If you get the message from Xastir's configure script saying:
+
+       "**** NO MOTIF HEADERS FOUND **** install Motif development headers or
+         use --with-motif-includes to specify location of Xm/Xm.h" 
+
+     even though you've got the Motif libraries and headers installed in the
+     proper places, you might need to add this to the configure line:
+
+        "--x-includes=/usr/X11R6/include"
+
+     If that option does not help, then Motif is installed somewhere other 
+     than with the standard X includes.  You must locate the file "Xm.h," 
+     which should be in a subdirectory called "Xm" somewhere.  Once located
+     (let's say in /usr/include/Motif/Xm/Xm.h), use the configure option:
+
+       "--with-motif-includes=/usr/include/Motif"
+
+     If you get the message:
+
+       "**** MOTIF LIBRARIES NOT FOUND **** Install Motif development 
+        headers/libraries or use --with-motif-libraries to specify path 
+        to libXm.a"
+
+     then your Motif libraries are not installed in the same directory as your
+     other X libraries, and you must find the file libXm.a, libXm.so, 
+     or libXm.sl.  Once found (say in /usr/lib/Motif, for example), tell 
+     configure where to find it with:
+
+        "--with-motif-libraries=/usr/lib/Motif"
+
+     If you wish to install Xastir in a location other than the default
+     ("/usr/local/bin" and "/usr/local/share/xastir" directories), you may
+     add the "--prefix=<path>" flag to configure before compiling.  i.e.
+
+     "./configure --prefix=/home/apps/xastir"
+
+     Which will cause executables to be installed in "/home/apps/xastir/bin/"
+     and the rest of Xastir to be installed under the
+     "/home/apps/xastir/xastir/" directory.
+ 
+     This is useful if you don't have root access on a machine, but still
+     wish to install and use Xastir from your home directory.  There are
+     probably many other uses as well.
+
+     If you want to disable optional "dbfawk" support (see README.MAPS) then
+     add "--without-dbfawk" to your "./configure", i.e.
+
+     "./configure --without-dbfawk"
+
+     Most people will want the capability though.
+
+     You'll need the "pcre" package installed in order to compile in
+     dbfawk support.
+
+     To enable spatial indexing of shapefiles you can also add "--with-rtree" 
+     to your configure command line.  Using spatial indices can speed up access
+     of shapefiles that cover large areas if you're only viewing a smaller
+     area, but at the cost of some additional RAM to store the spatial
+     index.  This feature is still in the experimental phase, but some users
+     have observed a noticeable speed-up in map redraws, especially
+     with very large shapefiles.  The spatial indexing library used is based
+     on public domain code obtained from Melinda Green,
+     http://www.superliminal.com, but this code is included in xastir
+     so you don't need to download anything to use it.
+
+     If you see some errors, they might be because you are missing
+     GNU msgfmt or GNU gettext/xgettext?  These packages are required
+     to compile the latest Xastir sources.  Beware of packages with the
+     same names installed into /usr/openwin/bin, these are probably NOT
+     the GNU flavor of the executables and will not work for compiling
+     Xastir.  For SuSE Linux:  Install "development/gettext" using YaST.
+
+     If you do see some errors/warnings read the FAQ. If this doesn't help,
+     or you think you have a different problem, dump the errors/warnings to
+     a file, and send the file and the following information to the
+     developers:
+
+        System type (cpu), speed, memory,
+        Linux Distribution,
+        Linux Version,
+        X Window manager (KDE, GNOME, FVWM, etc..)
+
+
+     To install, type (as root)
+        "make install" (or make install-strip to remove debugging information)
+
+     If you later install additional libraries and just can't get
+     ./configure to see them, remove the config.cache file via this
+     command:  "rm config.cache", and then re-run configure.  Also
+     see the notes above about /sbin/ldconfig.
+
+
+   14. Kernel AX.25 Interfaces
+
+     NOTE:  Xastir is designed by amateur radio operators, for amateur
+     radio operators.  It is intended to be used only by them.  If there's
+     a way for unlicensed users to operate the amateur radio equipment
+     (this usually includes sending messages through it which key up the
+     transmitter), it is a violation of the rules and your license (and
+     more) may be at risk.  The same goes for igating:  Be aware of the
+     rules for your country with respect to gating traffic from the 'net
+     onto RF.  If there's any question, don't do it.
+
+     Please read this entire section before typing anything, as there are
+     serious security implications for some of this!
+
+     Option 1)
+     If you compiled support for AX.25 in and wish to use Kernel-mode
+     AX-25 interfaces, you _may_ need to type this as root:
+
+       chmod 4555 /usr/local/bin/xastir
+
+     This command makes Xastir run as user "root", no matter who actually
+     started it.  This allows Xastir to talk to the kernel AX.25 networking.
+     Note however that the above chmod command will prevent you from creating
+     a core file in case Xastir of a major program fault.  This core file aids
+     in debugging to trace what went wrong.
+
+     GENERAL SECURITY WARNING:
+     Beware that Xastir has not been audited for security, and makes limited
+     effort to drop extra privileges. Use this in a multi-user environment
+     at your own risk!  The developers have worked hard to fix remote buffer
+     overflows in the code to make Xastir safer to use, but there are _MANY_
+     potential security risks remaining in the code.  User beware!  We will
+     attempt to plug known security holes in future releases.
+
+     Also be aware that turning on the Interface->Server ports (TCP and UDP)
+     will allow other users who authenticate properly to send packets.  In
+     the case of TCP they can only get routed to other TCP ports and to the
+     internet.  UDP packets may also get routed to your RF ports (as
+     third-party packets).
+
+     LINUX-SPECIFIC SECURITY WARNING:  If you're using Linux AX.25 kernel
+     networking, you'll need to either make Xastir SUID-root, or use a shim
+     (which itself is set to SUID-root) between Xastir and the AX.25 ports.
+     See Option #2 below for the (possibly safer) shim method.  If you're the
+     paranoid type (and you should be if you're running a system with multiple
+     users), you may wish to skip SUID-root mode/kernel AX.25 interfaces and
+     use standard serial port TNC interfaces instead.  Any program is safer if
+     run as a normal user (not safe, but safer).  It is currently impossible
+     to use kernel-mode AX.25 interfaces without the program running with
+     root privileges.
+
+     Option 2)
+     A more security-conscious option is to use a shim program written by
+     Henk de Groot, PE1DNN.  This program runs in SUID-root mode but is
+     much smaller and so is easier to audit for security, and provides a
+     new port that Xastir can connect to.  The new port can be read/written
+     without having to be the root user.  The program is called aprs_tty
+     and can be obtained here:
+
+     http://wetnet.net/~we7u/xastir/aprs_tty.0.0.2.tgz
+
+     It actually responds to some TNC commands. The code is straight forward
+     and works well.  Run the program, telling it what port to use, and then
+     in XASTIR set up the TNC to point to the new TTY at 19200. It
+     transmits/receives UI frames, and sets the correct unproto path.  In
+     this case DO NOT perform the chmod 4555 command on the Xastir executable.
+
+     Note again that the same SUID-root warnings that were giving in option
+     #1 above also apply to aprs_tty.  Buyer beware!  As far as we know,
+     aprs_tty has not been audited for security, and makes no effort to drop
+     extra privileges. Use this in a multi-user environment at your own risk!
+
+
+   15. Serially-Connected TNC's
+
+     NOTE:  Xastir is designed by amateur radio operators, for amateur
+     radio operators.  It is intended to be used only by them.  If there's
+     a way for unlicensed users to operate the amateur radio equipment
+     (this usually includes sending messages through it which key up the
+     transmitter), it is a violation of the rules and your license (and
+     more) may be at risk.  The same goes for igating:  Be aware of the
+     rules for your country with respect to gating traffic from the 'net
+     onto RF.  If there's any question, don't do it.
+
+     Please read this entire section before typing anything, as there are
+     serious security implications for some of this!
+
+     If you're using a serial TNC, configure your TNC startup files in the
+     /usr/local/share/xastir/config directory:
+
+     tnc-startup.sys is used to set up your TNC for Xastir and tnc-stop.sys
+     is to change the TNC back to your normal settings. There are several
+     example TNC startup files in the directory.  Choose the one that best
+     suits your TNC and edit to taste.  See the note below about where to
+     edit the files.  You might be unpleasantly surprised if after you type
+     "make install" next, all your custom changes to the startup files are
+     lost.  As always, keep a backup.
+
+     Some people have had trouble getting Xastir to decode packets.  While
+     packets were scrolling quite nicely in the View->Incoming Packet Data
+     dialog, stations weren't showing up on the Xastir screen at all. The
+     cause was incorrect settings in the tnc-startup files for that specific
+     TNC. If you change these files in the xastir source directories make sure
+     to do a "make install" to install them into the
+     /usr/local/share/xastir/config/ directory. Another option would be to
+     edit the files in /usr/local/share/xastir/config/ directly. Keep a copy
+     of them in a safe place in any case.  You don't want to lose your custom
+     mods you worked so hard to create.
+
+     Some systems don't allow normal users to access the serial ports.  It's
+     a permissions thing, but is actually the _correct_ way to configure the
+     serial ports.  You can fix this in several ways:
+
+     1) Add the Xastir user to the group owning the serial ports.
+     2) Make Xastir run SGID-uucp (or whatever group owns the port).
+     3) Change the permissions of the device so that any user can access it.
+     4) Make Xastir run SUID-root.
+
+     Solutions 3 and 4 are highly discouraged.  It can be a security nightmare
+     to start opening up files or devices to read/write access by all users,
+     and the same for SUID-root programs.  Don't do either of these.
+
+     Exception:  If you're going to be running AX.25 kernel networking, you
+     may need to be running Xastir SUID-root anyway, or else you need to
+     install a shim program between the port and Xastir.  In the latter case
+     the shim is running SUID-root, not Xastir.  See the section above
+     regarding AX.25 kernel networking.
+
+     Here are what the default permissions usually look like for the
+     two serial ports on a Linux box:
+
+     crw-rw----    1 root     uucp       4,  64 Oct 19 08:15 ttyS0
+     crw-rw----    1 root     uucp       4,  65 Apr 14  2001 ttyS1
+
+     (NOTE:  For a Windows/Cygwin installation, a few details are different,
+     but the ttyS0 and ttyS1 keywords are the same.  Verify that the
+     permissions of these ports are set appropriately for a normal user to read
+     and write to these devices.)
+
+     Solution #1:  The root user would run the commands necessary to add
+     the Xastir user to the "uucp" group, which would then give the user
+     the necessary permissions to use the port.  Usually this involves
+     editing the /etc/group file, but SysAdmin tools usually exist for
+     doing this more easily.
+
+     Solution #2:  As root user, type these commands:
+
+        chgrp uucp /usr/local/bin/xastir
+        chmod 2555 /usr/local/bin/xastir
+
+     If you want to restrict Xastir so that only one user can run it,
+     (in this case "user1") type:
+
+        chown user1 /usr/local/bin/xastir
+        chmod 2500 /usr/local/bin/xastir
+        chgrp uucp /usr/local/bin/xastir
+
+     Solution #3:
+     You can change the permissions of the serial port to allow use by all
+     users, but this is highly discouraged.
+     Here's what Jack Twilley had to say with regards to "chmod uog+rw" (same
+     as chmod 555) for serial ports:
+
+     > This is not necessary, and opens up the possibility of abuse.  Not all
+     > Xastir installations are Linux boxes used by a single person with a
+     > single purpose -- I know of several instances that are multi-user
+     > machines with access to the Internet by multiple parties, some of whom
+     > are not licensed amateurs, and another couple of instances where the
+     > serial port is not always used by a TNC but also by other devices such
+     > as Palm HotSync cradles and GPS receivers.
+     > 
+     > Here are two more secure solutions:
+     > 
+     >  * use non-root users
+     >    One way to use the setuid facilities in Unix would be to set
+     >    the xastir binary's user ID to match the user that owns the serial
+     >    port.  Under Solaris, the default ownership of /dev/cua/a is
+     >    uucp:tty, with a default permission of 0600.  The command 'chown
+     >    uucp /usr/local/bin/xastir' followed by the command 'chmod 4555
+     >    /usr/local/bin/xastir' will allow xastir to run properly without
+     >    changing the serial port's permissions or ownership, thus
+     >    minimizing any impact on other applications that use the serial
+     >    port.
+
+Note from Curt:  This chmod command will prevent creation of "core"
+file that are useful for debugging in case Xastir crashes.
+
+     > 
+     >  * use groups
+     >    A better way to use the setuid facilities in Unix is to set the
+     >    xastir binary's *group* ID to match a group that already has the
+     >    privilege to mess with the serial port.  Under FreeBSD, the default
+     >    ownership of /dev/cuaa0 is uucp:dialer, with a default permission
+     >    of 0660.  The command 'chgrp dialer /usr/local/bin/xastir' followed
+     >    by the command 'chmod 2555 /usr/local/bin/xastir' will change
+     >    Xastir's group to the serial port's group, and then add the setgid
+     >    privilege to the binary.  Now when xastir starts up, it will have
+     >    the minimum privilege necessary to do what it needs to do, without
+     >    being yet another root exploit-in-waiting.
+
+
+   16. Serially-Connected Garmin RINO Radio/GPS
+
+     If you have a Garmin RINO attached to a serial port, have GPSMan
+     installed, and have support for GPSMan compiled into Xastir, then Xastir
+     has the capability to periodically download waypoints from the RINO unit
+     and create APRS(tm) Objects out of them.  Any RINO waypoints that begin with
+     "APRS" will be automatically created, placed on the map, and transmitted
+     as your own Xastir APRS(tm) objects.  If you wish to see them but not transmit
+     them, turn off Object/Item transmit or global transmit in the interface
+     menu.  Another option is to turn off the transmit enable per interface.
+
+     Please note that Xastir cannot cause the attached RINO to poll the other
+     RINO units on the air.  Xastir can only download the waypoints that the
+     attached RINO has collected from the other RINO units that it is passively
+     monitoring.
+
+     Here's a blurb from Wes Johnston about the RINO's:
+
+     "Lets say I have three RINO radios... two in the hands of the SAR teams on
+     the ground, and a third radio in a plane circling above.  It is preferred
+     that the radio in the hands of the SAR teams be the nicer rino120 since it
+     does mapping.  The radio in the plane can be the lowly rino110 since it
+     does not do mapping but you will have a copy of xastir with maps on the
+     laptop with you anyway.
+
+     If I set two of my rino radios to APRSSAR1 and APRSSAR2, and connect a
+     third rino radio to xastir with serial in the plane, xastir will query
+     rino radio #3 at any one minute interval between 0 and 30 minutes, get the
+     APRS* waypoints, lop off the first four characters and publish the shorter
+     named waypoints as SAR1 and SAR2 as APRS(tm) objects on to your TNC.  The
+     hitch to this is that the rino radio cannot automatically poll the RINO
+     users' locations on the ground.  You have to manually (on the radio)
+     select a menu item called POLL and poll the users that way.  The reason
+     the first four characters of the rino callsign have to be "APRS" is that
+     when you send a query, rino only asks about the first 4 chars... so any
+     station with the first four that match will answer... ie all of them in
+     your group.  The other method is to simply fly the plane overhead and
+     listen (eavesdrop) on the channel and passively pickup the locations of the
+     groups as they converse with one another.  The rino will send it's
+     location just as you un-key the PTT if it has been >30 sec since the last
+     time you sent your position.  It would be practical to simply ask each
+     team for an update... they just need to squeeze their PTT for a moment
+     (ie kerchunk) to send a position."
+
+
+   17. Start up XASTIR and read the help files to configure it. If you have 
+     problems, please consult the FAQ file.
+
+     You can now start XASTIR. On most systems that the path is set up in
+     FHS format just type "xastir". On other systems type
+     "/usr/local/bin/xastir" to start the program.
+
+     If you see errors at this point that say something like "Can't load
+     xxx library" this means you forgot to either update /etc/ld.so.conf (or
+     /etc/ld.so.conf.d directory on some systems) and run /sbin/ldconfig, or
+     add the LD_LIBRARY_PATH variable for your shell, and the "ld" loader
+     can't link the libraries with the Xastir executable to get it running in
+     memory.  Note that if you're running Xastir as SUID root, the
+     LD_LIBRARY_PATH variable is ignored.
+
+     To set a new language or change the language current choice, use
+     this command line:
+
+     xastir -l <language>
+
+     Current choices are:
+
+            Dutch English French German Italian Portuguese Spanish
+            ElmerFudd MuppetsChef OldeEnglish PigLatin PirateEnglish
+
+     This option will be stored in the users config file for the next time
+     Xastir is run. On new installs Xastir will default to English unless
+     you use this command line option.
+
+
+   CONNECTING TO AN INTERNET SERVER:
+
+   Here are some lists of Internet servers:
+
+        http://members.aol.com/wa8lmf3/miscinfo/APRServe.txt
+        http://www.wa6oft.com/APRServe.txt
+        http://www.aprs-is.net/aprsservers.htm
+        http://www.aprs-is.net/APRSServers.htm
+
+
+   Filter port syntax (for those ports that allow user-selectable
+   filtering):
+
+        http://www.aprs-is.net/javaprssrvr/javaprsfilter.htm
+
+
+   The procedure to connect to one of them is this:
+
+    *) Select Interface->Properties.
+    *) Click Add.
+    *) Select Internet Server, click Add.
+    *) Fill in the "Host" and "Port" boxes.
+    *) Enter the Pass-code found by running "callpass" with your callsign
+       in an xterm window.
+    *) Set the togglebuttons and filter parameters per your preferences.  The
+       "filter" keyword is added by Xastir, so you don't need to add that word
+       to the box.  If the box has anything in it, "filter" is prepended to the
+       text when Xastir sends the string to the server
+    *) Optionally put in a comment.  That shows up in the Interface and
+       Properties dialogs to remind you of the details for that connection.
+    *) Click OK.
+
+   A short list of the first-tier servers (you may want to connect to the
+   second-tier servers or regional/local servers instead):
+
+     first.aprs.net ports 10151 (history) or 10152 (no history)
+     second.aprs.net ports 10151 (history) or 10152 (no history)
+     third.aprs.net ports 10151 (history) or 10152 (no history)
+     fourth.aprs.net ports 10151 (history) or 10152 (no history)
+
+
+   FESTIVAL NOTE:  From: J. Lance Cotton:
+   One thing that I found that I had to do to finally get festival to work was
+   to get rid of the 'only localhost can connect to the server' pref in the
+   festival configuration. I don't know if that's the default on a source
+   install (I installed festival from RPM's), but it might be.
+   
+   I don't know why it doesn't let localhost connect, even though it's the
+   only one specifically allowed.
+   
+   Here's what to do:  Open the 'festival.scm' file (I found mine in
+   /usr/share/festival/' and look for the line that starts like:
+   
+       (defvar server_access_list ...
+   
+   Make it look like:
+   
+       (defvar server_access_list nil
+   
+   Then restart the festival server.
+   -Lance KJ5O
+
+   Additional note from Alan Crosswell:  If you run the festival_server
+   script instead of festival -server, then the permissions for localhost
+   get set up for you.
+
+
+You probably want to download some maps and additional data files. The
+instructions for this are in the README.MAPS.
+
+-----------------------------------------------------------------------
+
+NOTES FOR DEVELOPERS:
+---------------------
+
+Profiling:
+----------
+1) "./configure --with-profiling"
+
+This will add "-pg" to the CFLAGS section of the Makefiles, which
+turns on the collection of profiling data while the executable is
+running (on Linux anyway).
+
+2) "make clean"
+
+3) "make install" (Don't do "make install-strip" here, as that will
+strip off the symbol table information that gprof requires)
+
+4) "xastir &"
+
+5) Let Xastir run for some period of time.
+
+6) Close Xastir
+
+7) "gprof /usr/local/bin/xastir | tee profile.txt"
+
+Gprof will use the Xastir binary and the gmon.out file created from
+running Xastir to give you the profile listing.
+
+Add the "-l" flag to the gprof line to give you a line-by-line
+profile listing, but be prepared for a long run-time and a lot of
+CPU to be used by gprof to generate it:
+
+    "gprof -l /usr/local/bin/xastir | tee profile.txt"
+
+Also see this link, which talks about how to profile multi-threaded
+applications:
+
+    http://sam.zoy.org/writings/programming/gprof.html
+
+With the method described, you compile/install their library code,
+then invoke Xastir like this:
+
+    LD_PRELOAD=xastir/src/gprof-helper.so xastir &
+
+
+    mv gmon.out gmon.old; gprof /usr/local/bin/xastir gmon.old \
+    | tee profile.txt; gprof -l /usr/local/bin/xastir gmon.old \
+    | tee profile2.txt
+
+
+Checking for Memory Leaks:
+--------------------------
+
+A simple method for just checking malloc's/free's is to set
+MALLOC_CHECK to a 1 or a 2, at least on Linux.  See the malloc man
+page for more info.
+
+For more thorough checks, use libgc:
+
+1) Install libgc, the conservative garbage collector for C and C++.
+Find it at:
+
+    http://www.hpl.hp.com/personal/Hans_Boehm/gc
+
+Configure/install libgc like this:
+
+    ./configure --enable-threads=posix
+
+Make sure that "-DGC_LINUX_THREADS" and "-D_REENTRANT" are defined
+in the Makefile if you're compiling it on Linux.
+
+Optional:  Change Makefile to add "-DSAVE_CALL_CHAIN" on the DEFS
+line.  This will provide more of a stack trace each time a leak is
+found.  This is sometimes useful but much more verbose.
+
+    make
+    make check
+    su
+    make install
+    exit (from root)
+
+2) Now, back in the xastir directory:
+
+    ./configure --with-libgc
+
+Make sure that "-fomit_frame_pointer" is _NOT_ in the Makefiles.
+This will mess up the optional stack trace if present.
+
+    make clean
+    make install
+    xastir &
+
+Let Xastir run for some period of time.
+
+Libgc will dump messages to the xterm as memory leaks are found.
+Any Xastir memory leaks should have a filename and a line number
+listed.  Memory leaks from lower-level libraries will be missing the
+detailed information, so they are easy to spot (and mostly useless
+for the purpose of finding and patching memory leaks).
+
+Note also that libgc will take Xastir's memory usage up quite a bit,
+so don't be surprised if Xastir uses two or three times the normal
+amount of memory while you're debugging memory leaks with libgc.
+
+
+
+  ------------------------------------------------------------------------
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 1999 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7e48ee7
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,1775 @@
+
+$Id: LICENSE,v 1.15 2012/11/01 18:57:18 we7u Exp $
+
+
+*) The majority of the Xastir source code is under the GPL license.
+See the file named "COPYING" for details.
+
+
+-------------------------------
+-------------------------------
+
+
+*) Some of the programs in the scripts directory may contain other
+licensing information.  See the individual files for details.
+
+
+-------------------------------
+-------------------------------
+
+
+*) datum.h and datum.c were derived from public domain source code.
+The name and copyright are listed in that file.
+
+
+-------------------------------
+-------------------------------
+
+
+*) rotated.h and rotated.c are available under the following license:
+
+/* xvertext 5.0, Copyright (c) 1993 Alan Richardson (mppa3 at uk.ac.sussex.syma)
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both the
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  All work developed as a consequence of the use of
+ * this program should duly acknowledge such use. No representations are
+ * made about the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+
+-------------------------------
+-------------------------------
+
+
+*) festival.h and festival.c are available under the following license:
+
+/*************************************************************************/
+/*                                                                       */
+/*                Centre for Speech Technology Research                  */
+/*                     University of Edinburgh, UK                       */
+/*                        Copyright (c) 1999                             */
+/*                        All Rights Reserved.                           */
+/*                                                                       */
+/*  Permission is hereby granted, free of charge, to use and distribute  */
+/*  this software and its documentation without restriction, including   */
+/*  without limitation the rights to use, copy, modify, merge, publish,  */
+/*  distribute, sublicense, and/or sell copies of this work, and to      */
+/*  permit persons to whom this work is furnished to do so, subject to   */
+/*  the following conditions:                                            */
+/*   1. The code must retain the above copyright notice, this list of    */
+/*      conditions and the following disclaimer.                         */
+/*   2. Any modifications must be clearly marked as such.                */
+/*   3. Original authors' names are not deleted.                         */
+/*   4. The authors' names are not used to endorse or promote products   */
+/*      derived from this software without specific prior written        */
+/*      permission.                                                      */
+/*                                                                       */
+/*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK        */
+/*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
+/*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
+/*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE     */
+/*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
+/*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
+/*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
+/*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
+/*  THIS SOFTWARE.                                                       */
+/*                                                                       */
+/*************************************************************************/
+
+
+-------------------------------
+-------------------------------
+
+
+*) "Free Standards Group, FSG, Linux Standard Base, LSB, Free
+Standards Certified, LSB Certified and the Free Standards Certified
+logo are trademarks, service marks and certification marks, as
+appropriate, of Free Standards Group in the United States and in
+other countries."
+
+We are in no way representing that Xastir has been certified by the
+FSG.  To do so costs real money.  We do intend some Xastir binaries
+to install and run properly on LSB-3.0 compliant x86 Linux systems
+though...
+
+
+-------------------------------
+-------------------------------
+
+
+*) libcurl (<http://curl.haxx.se/> is available under the following
+license.  Note that this license is only applicable to a distributed
+Xastir BINARY which includes this library:
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2006, Daniel Stenberg, <daniel at haxx.se>.
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software for
+any purpose with or without fee is hereby granted, provided that the
+above copyright notice and this permission notice appear in all
+copies.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS
+OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in this Software without prior written
+authorization of the copyright holder.
+
+
+-------------------------------
+-------------------------------
+
+
+*) libdb (<http://www.sleepycat.com>) is available under the
+following license.  Note that this license is only applicable to a
+distributed Xastir BINARY which includes this library:
+
+The following is the license that applies to this copy of the
+Berkeley DB software.  For a license to use the Berkeley DB software
+under conditions other than those described here, or to purchase
+support for this software, please contact Sleepycat Software by
+email at info at sleepycat.com, or on the Web at
+http://www.sleepycat.com.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*
+ * Copyright (c) 1990-2005
+ *      Sleepycat Software.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Redistributions in any form must be accompanied by information on
+ *    how to obtain complete source code for the DB software and any
+ *    accompanying software that uses the DB software.  The source code
+ *    must either be included in the distribution or be available for no
+ *    more than the cost of distribution plus a nominal fee, and must be
+ *    freely redistributable under reasonable conditions.  For an
+ *    executable file, complete source code means the source code for all
+ *    modules it contains.  It does not include source code for modules or
+ *    files that typically accompany the major components of the operating
+ *    system on which the executable file runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SLEEPYCAT SOFTWARE ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT, ARE DISCLAIMED.  IN NO EVENT SHALL SLEEPYCAT SOFTWARE
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1995, 1996
+ *      The President and Fellows of Harvard University.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+-------------------------------
+-------------------------------
+
+
+*) GraphicsMagick (<http://www.graphicsmagick.org/>) is available
+under the following license.  Note that this license is only
+applicable to a distributed Xastir BINARY which includes this
+library:
+
+This file is part of the GraphicsMagick software distributed by the
+GraphicsMagick Group.
+
+[ Please note that the legal community considers 15 or more total lines
+of code or text (not necessarily contiguous) to be significant for the
+purposes of copyright. Repeated changes such as renaming a symbol has
+similar significance to changing one line of code. ]
+
+The licences which components of this software fall under are as follows.
+
+1)
+  In November 2002, the GraphicsMagick Group created GraphicsMagick
+  from ImageMagick Studio's ImageMagick and applied this license:
+
+  Copyright (C) 2002 GraphicsMagick Group, an organization dedicated
+  to making software imaging solutions freely available.
+
+  Permission is hereby granted, free of charge, to any person obtaining
+  a copy of this software and associated documentation files
+  ("GraphicsMagick"), to deal in GraphicsMagick without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of GraphicsMagick,
+  and to permit persons to whom GraphicsMagick is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of GraphicsMagick.
+
+  The software is provided "as is", without warranty of any kind, express
+  or implied, including but not limited to the warranties of
+  merchantability, fitness for a particular purpose and noninfringement.
+  In no event shall GraphicsMagick Group be liable for any claim,
+  damages or other liability, whether in an action of contract, tort or
+  otherwise, arising from, out of or in connection with GraphicsMagick
+  or the use or other dealings in GraphicsMagick.
+
+  Except as contained in this notice, the name of the GraphicsMagick
+  Group shall not be used in advertising or otherwise to promote the
+  sale, use or other dealings in GraphicsMagick without prior written
+  authorization from the GraphicsMagick Group.
+
+2)
+  In August 1999, ImageMagick Studio assumed the responsibility for the
+  development of ImageMagick and applied a new license:
+
+  Copyright (C) 2002 ImageMagick Studio, a non-profit organization dedicated
+  to making software imaging solutions freely available.
+
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files ("ImageMagick"),
+  to deal in ImageMagick without restriction, including without limitation
+  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of ImageMagick, and to permit persons to whom the
+  ImageMagick is furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of ImageMagick.
+
+  The software is provided "as is", without warranty of any kind, express or
+  implied, including but not limited to the warranties of merchantability,
+  fitness for a particular purpose and noninfringement.  In no event shall
+  ImageMagick Studio be liable for any claim, damages or other liability,
+  whether in an action of contract, tort or otherwise, arising from, out of
+  or in connection with ImageMagick or the use or other dealings in
+  ImageMagick.
+
+  Except as contained in this notice, the name of the ImageMagick Studio
+  shall not be used in advertising or otherwise to promote the sale, use or
+  other dealings in ImageMagick without prior written authorization from the
+  ImageMagick Studio.
+
+3)
+  From 1991 to August 1999, ImageMagick was developed and distributed by
+  E. I. du Pont de Nemours and Company:
+
+  Copyright 1999 E. I. du Pont de Nemours and Company
+
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files
+  ("ImageMagick"), to deal in ImageMagick without restriction, including
+  without limitation the rights to use, copy, modify, merge, publish,
+  distribute, sublicense, and/or sell copies of ImageMagick, and to
+  permit persons to whom the ImageMagick is furnished to do so, subject
+  to the following conditions:
+
+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of ImageMagick.
+
+  The software is provided "as is", without warranty of any kind, express
+  or implied, including but not limited to the warranties of
+  merchantability, fitness for a particular purpose and noninfringement.
+  In no event shall E. I. du Pont de Nemours and Company be liable for
+  any claim, damages or other liability, whether in an action of
+  contract, tort or otherwise, arising from, out of or in connection with
+  ImageMagick or the use or other dealings in ImageMagick.
+
+  Except as contained in this notice, the name of the E. I. du Pont de
+  Nemours and Company shall not be used in advertising or otherwise to
+  promote the sale, use or other dealings in ImageMagick without prior
+  written authorization from the E. I. du Pont de Nemours and Company.
+
+4)
+  This copyright is limited to some code (for locating an installed
+  Ghostscript under Windows) in the file magick/nt_base.c which was
+  incorporated from the gsview package:
+
+  Copyright (C) 2000-2002, Ghostgum Software Pty Ltd.  All rights reserved.
+
+  Permission is hereby granted, free of charge, to any person obtaining
+  a copy of this file ("Software"), to deal in the Software without
+  restriction, including without limitation the rights to use, copy,
+  modify, merge, publish, distribute, sublicense, and/or sell copies of
+  this Software, and to permit persons to whom this file is furnished to
+  do so, subject to the following conditions:
+
+  This Software is distributed with NO WARRANTY OF ANY KIND.  No author
+  or distributor accepts any responsibility for the consequences of using it,
+  or for whether it serves any particular purpose or works at all, unless he
+  or she says so in writing.
+
+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of the Software.
+
+5)
+  The GraphicsMagick Base64Decode() and Base64Encode() functions are
+  based on source code obtained from OpenSSH.
+  This source code is distributed under the following license.
+
+  Copyright (c) 2000 Markus Friedl.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+6)
+  Many of the pattern images in coders/logo.c are derived from XFig,
+  which is distributed under the following license:
+ 
+  FIG : Facility for Interactive Generation of figures
+  Copyright (c) 1985-1988 by Supoj Sutanthavibul
+  Parts Copyright (c) 1989-2000 by Brian V. Smith
+  Parts Copyright (c) 1991 by Paul King
+ 
+  Any party obtaining a copy of these files is granted, free of charge, a
+  full and unrestricted irrevocable, world-wide, paid up, royalty-free,
+  nonexclusive right and license to deal in this software and
+  documentation files (the "Software"), including without limitation the
+  rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of the Software, and to permit persons who receive
+  copies from any such party to do so, with the only requirement being
+  that this copyright notice remain intact.
+
+7)
+  The documentation for the composition operators is copied from the
+  rlecomp manual page, which is authored by Rod Bogart and John W.
+  Peterson. Rlecomp is part of the Utah Raster Toolkit distributed by the
+  University of Michigan and the University of Utah. The copyright for
+  this manual page is as follows:
+
+  Copyright (c) 1986, University of Utah
+  
+  This software is copyrighted as noted below.  It may be freely copied,
+  modified, and redistributed, provided that the copyright notice is 
+  preserved on all copies.
+  
+  There is no warranty or other guarantee of fitness for this software,
+  it is provided solely "as is".  Bug reports or fixes may be sent
+  to the author, who may or may not act on them as he desires.
+  
+  You may not include this software in a program or other software product
+  without supplying the source, or without informing the end-user that the 
+  source is available for no extra charge.
+  
+  If you modify this software, you should include a notice giving the
+  name of the person performing the modification, the date of modification,
+  and the reason for such modification.
+
+8)
+  The C++ API known as "Magick++", and which resides in the Magick++
+  directory, is distributed under the following license:
+
+  Copyright 1999 - 2003 Bob Friesenhahn <bfriesen at simple.dallas.tx.us>
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of the source files and associated documentation
+  files ("Magick++"), to deal in Magick++ without restriction,
+  including without limitation of the rights to use, copy, modify,
+  merge, publish, distribute, sublicense, and/or sell copies of
+  Magick++, and to permit persons to whom the Magick++ is furnished
+  to do so, subject to the following conditions:
+
+  This copyright notice shall be included in all copies or
+  substantial portions of Magick++. The copyright to Magick++ is
+  retained by its author and shall not be subsumed or replaced by any
+  other copyright.
+
+  The software is provided "as is", without warranty of any kind,
+  express or implied, including but not limited to the warranties of
+  merchantability, fitness for a particular purpose and
+  noninfringement. In no event shall Bob Friesenhahn be liable for
+  any claim, damages or other liability, whether in an action of
+  contract, tort or otherwise, arising from, out of or in connection
+  with Magick++ or the use or other dealings in Magick++.
+
+9)
+  GraphicsMagick makes use of third-party "delegate" libraries to
+  support certain optional features. These libraries bear their own
+  copyrights and licenses, which may be more or less restrictive than the
+  GraphicsMagick license. For convenience, when GraphicsMagick is
+  bundled with (or compiled with) "delegate" libraries, a copy of the
+  licenses for these libraries is provided in a "licenses" directory.
+
+
+-------------------------------
+-------------------------------
+
+
+*) Jasper (<http://www.ece.uvic.ca/~mdadams/jasper/>) is available
+under the following license.  Note that this license is only
+applicable to a distributed Xastir BINARY which includes this
+library:
+
+JasPer License Version 2.0
+
+Copyright (c) 1999-2000 Image Power, Inc.
+Copyright (c) 1999-2000 The University of British Columbia
+Copyright (c) 2001-2003 Michael David Adams
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person (the
+"User") obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the
+following conditions:
+
+1.  The above copyright notices and this permission notice (which
+includes the disclaimer below) shall be included in all copies or
+substantial portions of the Software.
+
+2.  The name of a copyright holder shall not be used to endorse or
+promote products derived from the Software without specific prior
+written permission.
+
+THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
+LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
+"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
+PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
+THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
+EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
+BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
+PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
+GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
+ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
+IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
+SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
+AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
+SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
+THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
+PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
+RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
+EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
+
+
+-------------------------------
+-------------------------------
+
+
+*) Jpeg (<http://www.ijg.org/>) is available under the following
+license.  Note that this license is only applicable to a distributed
+Xastir BINARY which includes this library:
+
+In plain English:
+
+1. We don't promise that this software works.  (But if you find any bugs,
+   please let us know!)
+2. You can use this software for whatever you want.  You don't have to pay us.
+3. You may not pretend that you wrote this software.  If you use it in a
+   program, you must acknowledge somewhere in your documentation that
+   you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose.  This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library.  If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it.  This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L.  Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it.  (See the file
+ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh).  Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents owned by IBM, AT&T, and Mitsubishi.  Hence arithmetic coding cannot
+legally be used without obtaining one or more licenses.  For this reason,
+support for arithmetic coding has been removed from the free JPEG software.
+(Since arithmetic coding provides only a marginal gain over the unpatented
+Huffman mode, it is unlikely that very many implementations will support it.)
+So far as we are aware, there are no patent restrictions on the remaining
+code.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs".  This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+    "The Graphics Interchange Format(c) is the Copyright property of
+    CompuServe Incorporated.  GIF(sm) is a Service Mark property of
+    CompuServe Incorporated."
+
+
+-------------------------------
+-------------------------------
+
+
+*) Lesstif (<http://www.lesstif.org/>) is available under the
+following license.  Note that this license is only applicable to a
+distributed Xastir BINARY which includes this library:
+
+The included files COPYING and COPYING.LIB.LESSTIF, as may apply.
+
+-------------------------------
+-------------------------------
+
+
+*) libpng (<http://www.libpng.org/pub/png/libpng.html>) is available
+under the following license.  Note that this license is only
+applicable to a distributed Xastir BINARY which includes this
+library:
+
+This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.14, November 28, 2006, are
+Copyright (c) 2004, 2006 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+   Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your enjoyment of the
+   library or against infringement.  There is no warranty that our
+   efforts or the library will fulfill any of your particular purposes
+   or needs.  This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and effort is with
+   the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+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.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+November 28, 2006
+
+
+-------------------------------
+-------------------------------
+
+
+*) PCRE (<http://www.pcre.org/>) is available under the following
+license.  Note that this license is only applicable to a distributed
+Xastir BINARY which includes this library:
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 6 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+The basic library functions are written in C and are freestanding.  Also
+included in the distribution is a set of C++ wrapper functions.
+
+
+THE BASIC LIBRARY FUNCTIONS
+---------------------------
+
+Written by:       Philip Hazel
+Email local part: ph10
+Email domain:     cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England. Phone: +44 1223 334714.
+
+Copyright (c) 1997-2006 University of Cambridge
+All rights reserved.
+
+
+THE C++ WRAPPER FUNCTIONS
+-------------------------
+
+Contributed by:   Google Inc.
+
+Copyright (c) 2006, Google Inc.
+All rights reserved.
+
+
+THE "BSD" LICENCE
+-----------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+    * Redistributions of source code must retain the above copyright
+    * notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+    * copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the name
+    * of Google
+      Inc. nor the names of their contributors may be used to endorse or
+      promote products derived from this software without specific prior
+      written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+-------------------------------
+-------------------------------
+
+
+*) ZLIB (<http://www.zlib.net/>) is available under the following
+license.  Note that this license is only applicable to a distributed
+Xastir BINARY which includes this library:
+
+ (C) 1995-2004 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 at gzip.org          madler at 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.  Please
+read the FAQ for more information on the distribution of modified source
+versions.
+
+
+-------------------------------
+-------------------------------
+
+
+*) libXt.a (<http://gforge.freestandards.org/scm/?group_id=5>) is
+available under the following license.  Note that this license is
+only applicable to a distributed Xastir BINARY which includes this
+library:
+
+                                  Licenses
+
+                             The XFree86 Project
+
+                                January 2002
+
+1.  XFree86 License
+
+XFree86 code without an explicit copyright is covered by the following copy-
+right/license:
+
+Copyright (C) 1994-2002 The XFree86 Project, Inc.  All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the XFree86 Project shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from the XFree86
+Project.
+
+2.  Other Licenses
+
+Portions of code are covered by the following licenses/copyrights.  See indi-
+vidual files for the copyright dates.
+
+2.1  X/MIT Copyrights
+
+2.1.1  X Consortium
+
+Copyright (C) <date> X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X
+CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+X Window System is a trademark of X Consortium, Inc.
+
+2.1.2  The Open Group
+
+Copyright <date>  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open
+Group.
+
+2.2  Berkeley-based copyrights:
+
+2.2.1  General
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+  1.  Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+  2.  Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  3.  The name of the author may not be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+2.2.2  UCB/LBL
+
+Copyright (c) 1993 The Regents of the University of California.  All rights
+reserved.
+
+This software was developed by the Computer Systems Engineering group at
+Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and contributed to
+Berkeley.
+
+All advertising materials mentioning features or use of this software must
+display the following acknowledgement: This product includes software devel-
+oped by the University of California, Lawrence Berkeley Laboratory.
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+  1.  Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+  2.  Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  3.  All advertising materials mentioning features or use of this software
+      must display the following acknowledgement: This product includes soft-
+      ware developed by the University of California, Berkeley and its con-
+      tributors.
+
+  4.  Neither the name of the University nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS-
+CLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+2.3  NVIDIA Corp
+
+Copyright (c) 1996 NVIDIA, Corp.  All rights reserved.
+
+NOTICE TO USER: The source code is copyrighted under U.S. and international
+laws.  NVIDIA, Corp. of Sunnyvale, California owns the copyright and as
+design patents pending on the design and interface of the NV chips.  Users
+and possessors of this source code are hereby granted a nonexclusive, roy-
+alty-free copyright and design patent license to use this code in individual
+and commercial software.
+
+Any use of this source code must include, in the user documentation and
+internal comments to the code, notices to the end user as follows:
+
+Copyright (c) 1996 NVIDIA, Corp.  NVIDIA design patents pending in the U.S.
+and foreign countries.
+
+NVIDIA, CORP.  MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
+CODE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WAR-
+RANTY OF ANY KIND.  NVIDIA, CORP. DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA, CORP.  BE LIABLE
+FOR ANY SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAM-
+AGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
+
+2.4  GLX Public License
+
+GLX PUBLIC LICENSE (Version 1.0 (2/11/99)) ("License")
+
+Subject to any third party claims, Silicon Graphics, Inc. ("SGI") hereby
+grants permission to Recipient (defined below), under Recipient's copyrights
+in the Original Software (defined below), to use, copy, modify, merge, pub-
+lish, distribute, sublicense and/or sell copies of Subject Software (defined
+below), and to permit persons to whom the Subject Software is furnished in
+accordance with this License to do the same, subject to all of the following
+terms and conditions, which Recipient accepts by engaging in any such use,
+copying, modifying, merging, publishing, distributing, sublicensing or sell-
+ing:
+
+1. Definitions.
+
+     (a) "Original Software" means source code of computer software code
+     which is described in Exhibit A as Original Software.
+
+     (b) "Modifications" means any addition to or deletion from the sub-
+     stance or structure of either the Original Software or any previous
+     Modifications. When Subject Software is released as a series of
+     files, a Modification means (i) any addition to or deletion from
+     the contents of a file containing Original Software or previous
+     Modifications and (ii) any new file that contains any part of the
+     Original Code or previous Modifications.
+
+     (c) "Subject Software" means the Original Software or Modifications
+     or the combination of the Original Software and Modifications, or
+     portions of any of the foregoing.
+
+     (d) "Recipient" means an individual or a legal entity exercising
+     rights under, and complying with all of the terms of, this License.
+     For legal entities, "Recipient" includes any entity which controls,
+     is controlled by, or is under common control with Recipient.  For
+     purposes of this definition, "control" of an entity means (a) the
+     power, direct or indirect, to direct or manage such entity, or (b)
+     ownership of fifty percent (50%) or more of the outstanding shares
+     or beneficial ownership of such entity.
+
+2. Redistribution of Source Code Subject to These Terms.  Redistributions of
+Subject Software in source code form must retain the notice set forth in
+Exhibit A, below, in every file. A copy of this License must be included in
+any documentation for such Subject Software where the recipients' rights
+relating to Subject Software are described. Recipient may distribute the
+source code version of Subject Software under a license of Recipient's
+choice, which may contain terms different from this License, provided that
+(i) Recipient is in compliance with the terms of this License, and (ii) the
+license terms include this Section 2 and Sections 3, 4, 7, 8, 10, 12 and 13
+of this License, which terms may not be modified or superseded by any other
+terms of such license. If Recipient distributes the source code version under
+a different license Recipient must make it absolutely clear that any terms
+which differ from this License are offered by Recipient alone, not by SGI.
+Recipient hereby agrees to indemnify SGI for any liability incurred by SGI as
+a result of any such terms Recipient offers.
+
+3. Redistribution in Executable Form. The notice set forth in Exhibit A must
+be conspicuously included in any notice in an executable version of Subject
+Software, related documentation or collateral in which Recipient describes
+the user's rights relating to the Subject Software. Recipient may distribute
+the executable version of Subject Software under a license of Recipient's
+choice, which may contain terms different from this License, provided that
+(i) Recipient is in compliance with the terms of this License, and (ii) the
+license terms include this Section 3 and Sections 4, 7, 8, 10, 12 and 13 of
+this License, which terms may not be modified or superseded by any other
+terms of such license. If Recipient distributes the executable version under
+a different license Recipient must make it absolutely clear that any terms
+which differ from this License are offered by Recipient alone, not by SGI.
+Recipient hereby agrees to indemnify SGI for any liability incurred by SGI as
+a result of any such terms Recipient offers.
+
+4. Termination. This License and the rights granted hereunder will terminate
+automatically if Recipient fails to comply with terms herein and fails to
+cure such breach within 30 days of the breach. Any sublicense to the Subject
+Software which is properly granted shall survive any termination of this
+License absent termination by the terms of such sublicense.  Provisions which,
+by their nature, must remain in effect beyond the termination of this License
+shall survive.
+
+5. No Trademark Rights. This License does not grant any rights to use any
+trade name, trademark or service mark whatsoever. No trade name, trademark or
+service mark of SGI may be used to endorse or promote products derived from
+the Subject Software without prior written permission of SGI.
+
+6. No Other Rights. This License does not grant any rights with respect to
+the OpenGL API or to any software or hardware implementation thereof or to
+any other software whatsoever, nor shall any other rights or licenses not
+expressly granted hereunder arise by implication, estoppel or otherwise with
+respect to the Subject Software. Title to and ownership of the Original Soft-
+ware at all times remains with SGI. All rights in the Original Software not
+expressly granted under this License are reserved.
+
+7. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+applicable laws and regulations in connection with use and distribution of
+the Subject Software, including but not limited to, all export and import
+control laws and regulations of the U.S. government and other countries.
+Recipient may not distribute Subject Software that (i) in any way infringes
+(directly or contributorily) the rights (including patent, copyright, trade
+secret, trademark or other intellectual property rights of any kind) of any
+other person or entity or (ii) breaches any representation or warranty,
+express, implied or statutory, which under any applicable law it might be
+deemed to have been distributed.
+
+8. Claims of Infringement. If Recipient at any time has knowledge of any one
+or more third party claims that reproduction, modification, use, distribu-
+tion, import or sale of Subject Software (including particular functionality
+or code incorporated in Subject Software) infringes the third party's intel-
+lectual property rights, Recipient must place in a well-identified web page
+bearing the title "LEGAL" a description of each such claim and a description
+of the party making each such claim in sufficient detail that a user of the
+Subject Software will know whom to contact regarding the claim.  Also, upon
+gaining such knowledge of any such claim, Recipient must conspicuously
+include the URL for such web page in the Exhibit A notice required under Sec-
+tions 2 and 3, above, and in the text of any related documentation, license
+agreement or collateral in which Recipient describes end user's rights relat-
+ing to the Subject Software. If Recipient obtains such knowledge after it
+makes Subject Software available to any other person or entity, Recipient
+shall take other steps (such as notifying appropriate mailing lists or news-
+groups) reasonably calculated to inform those who received the Subject Soft-
+ware that new knowledge has been obtained.
+
+9. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MER-
+CHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON- INFRINGING. SGI ASSUMES NO
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE
+PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY SER-
+VICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED
+HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THE-
+ORY, WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIA-
+BILITY), CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR
+ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
+STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
+THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY
+TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SGI's NEGLIGENCE TO
+THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO
+NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES,
+SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO RECIPIENT.
+
+11. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this License.
+Recipient will defend, indemnify and hold harmless Silicon Graphics, Inc.
+from and against any loss, liability, damages, costs or expenses (including
+the payment of reasonable attorneys fees) arising out of Recipient's use,
+modification, reproduction and distribution of the Subject Software or out of
+any representation or warranty made by Recipient.
+
+12. U.S. Government End Users. The Subject Software is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S.  Government End
+Users acquire only the rights set forth in this License and are subject to
+the terms of this License.
+
+13. Miscellaneous. This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be unen-
+forceable, such provision shall be reformed so as to achieve as nearly as
+possible the same economic effect as the original provision and the remainder
+of this License will remain in effect. This License shall be governed by and
+construed in accordance with the laws of the United States and the State of
+California as applied to agreements entered into and to be performed entirely
+within California between California residents. Any litigation relating to
+this License shall be subject to the exclusive jurisdiction of the Federal
+Courts of the Northern District of California (or, absent subject matter
+jurisdiction in such courts, the courts of the State of California), with
+venue lying exclusively in Santa Clara County, California, with the losing
+party responsible for costs, including without limitation, court costs and
+reasonable attorneys fees and expenses. The application of the United Nations
+Convention on Contracts for the International Sale of Goods is expressly
+excluded. Any law or regulation which provides that the language of a con-
+tract shall be construed against the drafter shall not apply to this License.
+
+Exhibit A
+
+The contents of this file are subject to Sections 2, 3, 4, 7, 8, 10, 12 and
+13 of the GLX Public License Version 1.0 (the "License"). You may not use
+this file except in compliance with those sections of the License.  You may
+obtain a copy of the License at Silicon Graphics, Inc., attn: Legal Services,
+2011 N. Shoreline Blvd., Mountain View, CA 94043 or at
+http://www.sgi.com/software/opensource/glx/license.html.
+
+Software distributed under the License is distributed on an "AS IS" basis.
+ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON-
+INFRINGEMENT. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Software is GLX version 1.2 source code, released February,
+1999. The developer of the Original Software is Silicon Graphics, Inc.  Those
+portions of the Subject Software created by Silicon Graphics, Inc.  are Copy-
+right (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+
+2.5  CID Font Code Public License
+
+CID FONT CODE PUBLIC LICENSE (Version 1.0 (3/31/99))("License")
+
+Subject to any applicable third party claims, Silicon Graphics, Inc.  ("SGI")
+hereby grants permission to Recipient (defined below), under SGI's copyrights
+in the Original Software (defined below), to use, copy, modify, merge, pub-
+lish, distribute, sublicense and/or sell copies of Subject Software (defined
+below) in both source code and executable form, and to permit persons to whom
+the Subject Software is furnished in accordance with this License to do the
+same, subject to all of the following terms and conditions, which Recipient
+accepts by engaging in any such use, copying, modifying, merging, publica-
+tion, distributing, sublicensing or selling:
+
+1. Definitions.
+
+     a. "Original Software" means source code of computer software code
+     that is described in Exhibit A as Original Software.
+
+     b. "Modifications" means any addition to or deletion from the sub-
+     stance or structure of either the Original Software or any previous
+     Modifications. When Subject Software is released as a series of
+     files, a Modification means (i) any addition to or deletion from
+     the contents of a file containing Original Software or previous
+     Modifications and (ii) any new file that contains any part of the
+     Original Code or previous Modifications.
+
+     c. "Subject Software" means the Original Software or Modifications
+     or the combination of the Original Software and Modifications, or
+     portions of any of the foregoing.
+
+     d. "Recipient" means an individual or a legal entity exercising
+     rights under the terms of this License. For legal entities, "Recip-
+     ient" includes any entity that controls, is controlled by, or is
+     under common control with Recipient. For purposes of this defini-
+     tion, "control" of an entity means (i) the power, direct or indi-
+     rect, to direct or manage such entity, or (ii) ownership of fifty
+     percent (50%) or more of the outstanding shares or beneficial own-
+     ership of such entity.
+
+     e. "Required Notice" means the notice set forth in Exhibit A to
+     this License.
+
+     f. "Accompanying Technology" means any software or other technology
+     that is not a Modification and that is distributed or made publicly
+     available by Recipient with the Subject Software.  Separate soft-
+     ware files that do not contain any Original Software or any previ-
+     ous Modification shall not be deemed a Modification, even if such
+     software files are aggregated as part of a product, or in any
+     medium of storage, with any file that does contain Original Soft-
+     ware or any previous Modification.
+
+2. License Terms. All distribution of the Subject Software must be made sub-
+ject to the terms of this License. A copy of this License and the Required
+Notice must be included in any documentation for Subject Software where
+Recipient's rights relating to Subject Software and/or any Accompanying Tech-
+nology are described. Distributions of Subject Software in source code form
+must also include the Required Notice in every file distributed. In addition,
+a ReadMe file entitled "Important Legal Notice" must be distributed with each
+distribution of one or more files that incorporate Subject Software.  That
+file must be included with distributions made in both source code and exe-
+cutable form. A copy of the License and the Required Notice must be included
+in that file.  Recipient may distribute Accompanying Technology under a
+license of Recipient's choice, which may contain terms different from this
+License, provided that (i) Recipient is in compliance with the terms of this
+License, (ii) such other license terms do not modify or supersede the terms
+of this License as applicable to the Subject Software, (iii) Recipient hereby
+indemnifies SGI for any liability incurred by SGI as a result of the distri-
+bution of Accompanying Technology or the use of other license terms.
+
+3. Termination. This License and the rights granted hereunder will terminate
+automatically if Recipient fails to comply with terms herein and fails to
+cure such breach within 30 days of the breach. Any sublicense to the Subject
+Software that is properly granted shall survive any termination of this
+License absent termination by the terms of such sublicense.  Provisions which,
+by their nature, must remain in effect beyond the termination of this License
+shall survive.
+
+4. Trademark Rights. This License does not grant any rights to use any trade
+name, trademark or service mark whatsoever. No trade name, trademark or ser-
+vice mark of SGI may be used to endorse or promote products derived from or
+incorporating any Subject Software without prior written permission of SGI.
+
+5. No Other Rights. No rights or licenses not expressly granted hereunder
+shall arise by implication, estoppel or otherwise. Title to and ownership of
+the Original Software at all times remains with SGI. All rights in the Origi-
+nal Software not expressly granted under this License are reserved.
+
+6. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+applicable laws and regulations in connection with use and distribution of
+the Subject Software, including but not limited to, all export and import
+control laws and regulations of the U.S. government and other countries.
+Recipient may not distribute Subject Software that (i) in any way infringes
+(directly or contributorily) the rights (including patent, copyright, trade
+secret, trademark or other intellectual property rights of any kind) of any
+other person or entity, or (ii) breaches any representation or warranty,
+express, implied or statutory, which under any applicable law it might be
+deemed to have been distributed.
+
+7. Claims of Infringement. If Recipient at any time has knowledge of any one
+or more third party claims that reproduction, modification, use, distribu-
+tion, import or sale of Subject Software (including particular functionality
+or code incorporated in Subject Software) infringes the third party's intel-
+lectual property rights, Recipient must place in a well-identified web page
+bearing the title "LEGAL" a description of each such claim and a description
+of the party making each such claim in sufficient detail that a user of the
+Subject Software will know whom to contact regarding the claim.  Also, upon
+gaining such knowledge of any such claim, Recipient must conspicuously
+include the URL for such web page in the Required Notice, and in the text of
+any related documentation, license agreement or collateral in which Recipient
+describes end user's rights relating to the Subject Software. If Recipient
+obtains such knowledge after it makes Subject Software available to any other
+person or entity, Recipient shall take other steps (such as notifying appro-
+priate mailing lists or newsgroups) reasonably calculated to provide such
+knowledge to those who received the Subject Software.
+
+8. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MER-
+CHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. SGI ASSUMES NO
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE
+PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY SER-
+VICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED
+HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
+WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY),
+CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SUBJECT SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SUBJECT SOFTWARE. SOME JURISDICTIONS DO NOT
+ALLOW THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES, SO THIS EXCLUSION AND
+LIMITATION MAY NOT APPLY TO RECIPIENT TO THE EXTENT SO DISALLOWED.
+
+10. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this License.
+Recipient will defend, indemnify and hold SGI and its successors and assigns
+harmless from and against any loss, liability, damages, costs or expenses
+(including the payment of reasonable attorneys fees) arising out of (Recipi-
+ent's use, modification, reproduction and distribution of the Subject Soft-
+ware or out of any representation or warranty made by Recipient.
+
+11. U.S. Government End Users. The Subject Software is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S. Government End Users
+acquire only the rights set forth in this License and are subject to the
+terms of this License.
+
+12. Miscellaneous. This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be unen-
+forceable by any judicial or administrative authority having proper jurisdic-
+tion with respect thereto, such provision shall be reformed so as to achieve
+as nearly as possible the same economic effect as the original provision and
+the remainder of this License will remain in effect. This License shall be
+governed by and construed in accordance with the laws of the United States
+and the State of California as applied to agreements entered into and to be
+performed entirely within California between California residents.  Any liti-
+gation relating to this License shall be subject to the exclusive jurisdic-
+tion of the Federal Courts of the Northern District of California (or, absent
+subject matter jurisdiction in such courts, the courts of the State of Cali-
+fornia), with venue lying exclusively in Santa Clara County, California, with
+the losing party responsible for costs, including without limitation, court
+costs and reasonable attorneys fees and expenses. The application of the
+United Nations Convention on Contracts for the International Sale of Goods is
+expressly excluded. Any law or regulation that provides that the language of
+a contract shall be construed against the drafter shall not apply to this
+License.
+
+Exhibit A
+
+Copyright (c) 1994-1999 Silicon Graphics, Inc.
+
+The contents of this file are subject to the CID Font Code Public License
+Version 1.0 (the "License"). You may not use this file except in compliance
+with the License. You may obtain a copy of the License at Silicon Graphics,
+Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+or at http://www.sgi.com/software/opensource/cid/license.html
+
+Software distributed under the License is distributed on an "AS IS" basis.
+ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON-
+INFRINGEMENT. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Software (as defined in the License) is CID font code that was
+developed by Silicon Graphics, Inc. Those portions of the Subject Software
+(as defined in the License) that were created by Silicon Graphics, Inc. are
+Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved.
+
+[NOTE: When using this text in connection with Subject Software delivered
+solely in object code form, Recipient may replace the words "this file" with
+"this software" in both the first and second sentences.]
+
+********************************************************************************
+
+XFree86's LICENSE document does not appear to be completely comprehensive.
+
+Many files appear to be licensed under the "SGI FREE SOFTWARE
+LICENSE B (Version 1.1 [02/22/2000])":
+
+SGI FREE SOFTWARE LICENSE B (Version 1.1 [02/22/2000])
+
+1. Definitions.
+
+    1.1. "Additional Notice Provisions" means such additional provisions as
+    appear in the Notice in Original Code under the heading "Additional
+    Notice Provisions."
+
+    1.2. "Covered Code" means the Original Code or Modifications, or any
+    combination thereof.
+
+    1.3. "Hardware" means any physical device that accepts input, processes
+    input, stores the results of processing, and/or provides output.
+
+    1.4. "Larger Work" means a work that combines Covered Code or portions
+    thereof with code not governed by the terms of this License.
+
+    1.5. "Licensable" means having the right to grant, to the maximum
+    extent possible, whether at the time of the initial grant or
+    subsequently acquired, any and all of the rights conveyed herein.
+
+    1.6. "License" means this document.
+
+    1.7. "Licensed Patents" means patent claims Licensable by SGI that are
+    infringed by the use or sale of Original Code or any Modifications
+    provided by SGI, or any combination thereof.
+
+    1.8. "Modifications" means any addition to or deletion from the
+    substance or structure of the Original Code or any previous
+    Modifications. When Covered Code is released as a series of files, a
+    Modification is:
+
+        A. Any addition to the contents of a file containing Original Code
+        and/or addition to or deletion from the contents of a file
+        containing previous Modifications.
+
+        B. Any new file that contains any part of the Original Code or
+        previous Modifications.
+
+    1.9. "Notice" means any notice in Original Code or Covered Code, as
+    required by and in compliance with this License.
+
+    1.10. "Original Code" means source code of computer software code that
+    is described in the source code Notice required by Exhibit A as
+    Original Code, and updates and error corrections specifically thereto.
+
+    1.11. "Recipient" means an individual or a legal entity exercising
+    rights under, and complying with all of the terms of, this License or a
+    future version of this License issued under Section 8.  For legal
+    entities, "Recipient" includes any entity that controls, is controlled
+    by, or is under common control with Recipient. For purposes of this
+    definition, "control" of an entity means (a) the power, direct or
+    indirect, to direct or manage such entity, or (b) ownership of fifty
+    percent (50%) or more of the outstanding shares or beneficial ownership
+    of such entity.
+
+    1.12. "Recipient Patents" means patent claims Licensable by a Recipient
+    that are infringed by the use or sale of Original Code or any
+    Modifications provided by SGI, or any combination thereof.
+
+    1.13. "SGI" means Silicon Graphics, Inc.
+
+    1.14. "SGI Patents" means patent claims Licensable by SGI other than
+    the Licensed Patents.
+
+2. License Grant and Restrictions.
+
+    2.1. SGI License Grant. Subject to the terms of this License and any
+    third party intellectual property claims, for the duration of
+    intellectual property protections inherent in the Original Code, SGI
+    hereby grants Recipient a worldwide, royalty-free, non-exclusive
+    license, to do the following: (i) under copyrights Licensable by SGI,
+    to reproduce, distribute, create derivative works from, and, to the
+    extent applicable, display and perform the Original Code and/or any
+    Modifications provided by SGI alone and/or as part of a Larger Work;
+    and (ii) under any Licensable Patents, to make, have made, use, sell,
+    offer for sale, import and/or otherwise transfer the Original Code
+    and/or any Modifications provided by SGI. Recipient accepts the terms
+    and conditions of this License by undertaking any of the aforementioned
+    actions. The patent license shall apply to the Covered Code if, at the
+    time any related Modification is added, such addition of the
+    Modification causes such combination to be covered by the Licensed
+    Patents. The patent license in Section 2.1(ii) shall not apply to any
+    other combinations that include the Modification.  No patent license is
+    provided under SGI Patents for infringements of SGI Patents by
+    Modifications not provided by SGI or combinations of Original Code and
+    Modifications not provided by SGI.
+
+    2.2. Recipient License Grant. Subject to the terms of this License and
+    any third party intellectual property claims, Recipient hereby grants
+    SGI and any other Recipients a worldwide, royalty-free, non-exclusive
+    license, under any Recipient Patents, to make, have made, use, sell,
+    offer for sale, import and/or otherwise transfer the Original Code
+    and/or any Modifications provided by SGI.
+
+    2.3. No License For Hardware Implementations. The licenses granted in
+    Section 2.1 and 2.2 are not applicable to implementation in Hardware of
+    the algorithms embodied in the Original Code or any Modifications
+    provided by SGI .
+
+3. Redistributions.
+
+    3.1. Retention of Notice/Copy of License. The Notice set forth in
+    Exhibit A, below, must be conspicuously retained or included in any and
+    all redistributions of Covered Code. For distributions of the Covered
+    Code in source code form, the Notice must appear in every file that can
+    include a text comments field; in executable form, the Notice and a
+    copy of this License must appear in related documentation or collateral
+    where the Recipient's rights relating to Covered Code are described.
+    Any Additional Notice Provisions which actually appears in the Original
+    Code must also be retained or included in any and all redistributions
+    of Covered Code.
+
+    3.2. Alternative License. Provided that Recipient is in compliance with
+    the terms of this License, Recipient may, so long as without derogation
+    of any of SGI's rights in and to the Original Code, distribute the
+    source code and/or executable version(s) of Covered Code under (1) this
+    License; (2) a license identical to this License but for only such
+    changes as are necessary in order to clarify Recipient's role as
+    licensor of Modifications; and/or (3) a license of Recipient's
+    choosing, containing terms different from this License, provided that
+    the license terms include this Section 3 and Sections 4, 6, 7, 10, 12,
+    and 13, which terms may not be modified or superseded by any other
+    terms of such license. If Recipient elects to use any license other
+    than this License, Recipient must make it absolutely clear that any of
+    its terms which differ from this License are offered by Recipient
+    alone, and not by SGI. It is emphasized that this License is a limited
+    license, and, regardless of the license form employed by Recipient in
+    accordance with this Section 3.2, Recipient may relicense only such
+    rights, in Original Code and Modifications by SGI, as it has actually
+    been granted by SGI in this License.
+
+    3.3. Indemnity. Recipient hereby agrees to indemnify SGI for any
+    liability incurred by SGI as a result of any such alternative license
+    terms Recipient offers.
+
+4. Termination. This License and the rights granted hereunder will
+terminate automatically if Recipient breaches any term herein and fails to
+cure such breach within 30 days thereof. Any sublicense to the Covered Code
+that is properly granted shall survive any termination of this License,
+absent termination by the terms of such sublicense. Provisions that, by
+their nature, must remain in effect beyond the termination of this License,
+shall survive.
+
+5. No Trademark Or Other Rights. This License does not grant any rights to:
+(i) any software apart from the Covered Code, nor shall any other rights or
+licenses not expressly granted hereunder arise by implication, estoppel or
+otherwise with respect to the Covered Code; (ii) any trade name, trademark
+or service mark whatsoever, including without limitation any related right
+for purposes of endorsement or promotion of products derived from the
+Covered Code, without prior written permission of SGI; or (iii) any title
+to or ownership of the Original Code, which shall at all times remains with
+SGI. All rights in the Original Code not expressly granted under this
+License are reserved.
+
+6. Compliance with Laws; Non-Infringement. There are various worldwide
+laws, regulations, and executive orders applicable to dispositions of
+Covered Code, including without limitation export, re-export, and import
+control laws, regulations, and executive orders, of the U.S.  government and
+other countries, and Recipient is reminded it is obliged to obey such laws,
+regulations, and executive orders. Recipient may not distribute Covered
+Code that (i) in any way infringes (directly or contributorily) any
+intellectual property rights of any kind of any other person or entity or
+(ii) breaches any representation or warranty, express, implied or
+statutory, to which, under any applicable law, it might be deemed to have
+been subject.
+
+7. Claims of Infringement. If Recipient learns of any third party claim
+that any disposition of Covered Code and/or functionality wholly or
+partially infringes the third party's intellectual property rights,
+Recipient will promptly notify SGI of such claim.
+
+8. Versions of the License. SGI may publish revised and/or new versions of
+the License from time to time, each with a distinguishing version number.
+Once Covered Code has been published under a particular version of the
+License, Recipient may, for the duration of the license, continue to use it
+under the terms of that version, or choose to use such Covered Code under
+the terms of any subsequent version published by SGI. Subject to the
+provisions of Sections 3 and 4 of this License, only SGI may modify the
+terms applicable to Covered Code created under this License.
+
+9. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED "AS IS." ALL EXPRESS
+AND IMPLIED WARRANTIES AND CONDITIONS ARE DISCLAIMED, INCLUDING, WITHOUT
+LIMITATION, ANY IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY,
+SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT. SGI ASSUMES NO RISK AS TO THE QUALITY AND PERFORMANCE OF
+THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, SGI
+ASSUMES NO COST OR LIABILITY FOR SERVICING, REPAIR OR CORRECTION.  THIS
+DISCLAIMER OF WARRANTY IS AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY
+COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT SUBJECT TO THIS
+DISCLAIMER.
+
+10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES NOR LEGAL THEORY,
+WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT
+LIABILITY), CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE
+FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF
+ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+WORK STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND
+ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY
+SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM
+SGI's NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION.
+SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL
+OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO
+RECIPIENT.
+
+11. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this
+License. Recipient will defend, indemnify and hold harmless Silicon
+Graphics, Inc. from and against any loss, liability, damages, costs or
+expenses (including the payment of reasonable attorneys fees) arising out
+of Recipient's use, modification, reproduction and distribution of the
+Covered Code or out of any representation or warranty made by
+Recipient.
+
+12. U.S. Government End Users. The Covered Code is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S. Government End
+Users acquire only the rights set forth in this License and are subject to
+the terms of this License.
+
+13. Miscellaneous. This License represents the complete agreement
+concerning the its subject matter. If any provision of this License is held
+to be unenforceable, such provision shall be reformed so as to achieve as
+nearly as possible the same legal and economic effect as the original
+provision and the remainder of this License will remain in effect.  This
+License shall be governed by and construed in accordance with the laws of
+the United States and the State of California as applied to agreements
+entered into and to be performed entirely within California between
+California residents. Any litigation relating to this License shall be
+subject to the exclusive jurisdiction of the Federal Courts of the Northern
+District of California (or, absent subject matter jurisdiction in such
+courts, the courts of the State of California), with venue lying
+exclusively in Santa Clara County, California, with the losing party
+responsible for costs, including without limitation, court costs and
+reasonable attorneys fees and expenses. The application of the United
+Nations Convention on Contracts for the International Sale of Goods is
+expressly excluded. Any law or regulation that provides that the language
+of a contract shall be construed against the drafter shall not apply to
+this License.
+
+Exhibit A
+
+License Applicability. Except to the extent portions of this file are made
+subject to an alternative license as permitted in the SGI Free Software
+License B, Version 1.1 (the "License"), the contents of this file are
+subject only to the provisions of the License. You may not use this file
+except in compliance with the License. You may obtain a copy of the License
+at Silicon Graphics, Inc., attn: Legal Services, 1600 Amphitheatre Parkway,
+Mountain View, CA 94043-1351, or at: http://oss.sgi.com/projects/FreeB
+
+Note that, as provided in the License, the Software is distributed on an
+"AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+
+Original Code. The Original Code is: [name of software, version number, and
+release date], developed by Silicon Graphics, Inc. The Original Code is
+Copyright (c) [dates of first publication, as appearing in the Notice in
+the Original Code] Silicon Graphics, Inc. Copyright in any portions created
+by third parties is as indicated elsewhere herein. All Rights Reserved.
+Additional Notice Provisions: [such additional provisions, if any, as
+appear in the Notice in the Original Code under the heading "Additional
+Notice Provisions"]
+
+
+-------------------------------
+-------------------------------
+
+
+*) GDAL (<http://gdal.org/>).  Not currently included in any Xastir
+binaries.  This is a placeholder that we may use later.
+
+
+-------------------------------
+-------------------------------
+
+
+*) GV (<http://wwwthep.physik.uni-mainz.de/~plass/gv/>).  Not
+currently included in any Xastir binaries.  This is a placeholder
+that we may use later.
+
+
+-------------------------------
+-------------------------------
+ 
+
+To maintain compliance with the above licenses:  Hear ye, hear ye!
+Be it known that the sources for each of the optional libraries
+listed may be obtained from their normal download sites on the
+internet.
+
+
+
+The file you're looking at (LICENSE) is
+Copyright (C) 2000-2012  The Xastir Group
+
diff --git a/LaCrosse/.cvsignore b/LaCrosse/.cvsignore
new file mode 100644
index 0000000..cfb964c
--- /dev/null
+++ b/LaCrosse/.cvsignore
@@ -0,0 +1,16 @@
+configure
+Makefile.in
+Makefile
+make.log
+stamp-h.in
+config.h
+config.log
+aclocal.m4
+autom4te.cache
+config.h.in
+config.status
+stamp-h1
+mkinstalldirs
+depcomp
+install-sh
+missing
diff --git a/LaCrosse/AUTHORS b/LaCrosse/AUTHORS
new file mode 100644
index 0000000..ea32601
--- /dev/null
+++ b/LaCrosse/AUTHORS
@@ -0,0 +1,26 @@
+
+$Id: AUTHORS,v 1.2 2010/01/31 02:12:23 we7u Exp $
+
+
+                        Developers and Contributions
+    _________________________________________________________________
+
+    First, thanks go out to the great folks at the xastir team - a
+    wonderful APRS application set and helpful folks!
+
+    Thanks also to Andreas Muller, author of meteo and a great
+    resource for information and help.
+    
+    Elements of this software are taken from wx200d ver 1.2
+    by Tim Witham, and it is modeled after that application.
+			
+    Finally, thanks to the MySQL folks for the key element - the
+    database.
+
+    N0VH	Jim Chandler	    jim at n0vh.org
+    KB8ROP      Bruce Bennett       bruts at adelphia.net
+    _________________________________________________________________
+
+    Copyright (C) 2003-2004 Bruce Bennett KB8ROP
+    Copyright (C) 2005 Jim Chandler N0VH 
+
diff --git a/LaCrosse/COPYING b/LaCrosse/COPYING
new file mode 100644
index 0000000..60549be
--- /dev/null
+++ b/LaCrosse/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, 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 software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, 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 show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, 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 redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 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 Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, 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 executable.  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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+  5. 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 Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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.
+
+  7. 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 Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  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 program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/LaCrosse/CVS/Entries b/LaCrosse/CVS/Entries
new file mode 100644
index 0000000..5ede153
--- /dev/null
+++ b/LaCrosse/CVS/Entries
@@ -0,0 +1,12 @@
+/.cvsignore/1.2/Thu Jan 26 19:06:14 2006//
+/AUTHORS/1.2/Sun Jan 31 02:12:23 2010//
+/COPYING/1.1/Wed Jan 25 19:36:27 2006//
+/ChangeLog/1.1/Wed Jan 25 19:36:27 2006//
+/INSTALL/1.1/Wed Jan 25 19:36:27 2006//
+/Makefile.am/1.8/Thu Nov  1 18:57:18 2012//
+/NEWS/1.1/Wed Jan 25 19:36:27 2006//
+/README/1.8/Thu Nov  1 18:57:18 2012//
+/bootstrap.sh/1.9/Thu Nov  1 18:57:18 2012//
+/configure.ac/1.7/Thu Nov  1 18:57:18 2012//
+/weatherdump.sql/1.2/Wed Jul 25 00:17:35 2012//
+D
diff --git a/LaCrosse/CVS/Entries.Log b/LaCrosse/CVS/Entries.Log
new file mode 100644
index 0000000..40b1f89
--- /dev/null
+++ b/LaCrosse/CVS/Entries.Log
@@ -0,0 +1,2 @@
+A D/autom4te.cache////
+A D/src////
diff --git a/LaCrosse/CVS/Repository b/LaCrosse/CVS/Repository
new file mode 100644
index 0000000..cce1e32
--- /dev/null
+++ b/LaCrosse/CVS/Repository
@@ -0,0 +1 @@
+xastir/LaCrosse
diff --git a/LaCrosse/CVS/Root b/LaCrosse/CVS/Root
new file mode 100644
index 0000000..6a998ee
--- /dev/null
+++ b/LaCrosse/CVS/Root
@@ -0,0 +1 @@
+:ext:we7u at xastir.cvs.sourceforge.net:/cvsroot/xastir
diff --git a/LaCrosse/ChangeLog b/LaCrosse/ChangeLog
new file mode 100644
index 0000000..e3478e0
--- /dev/null
+++ b/LaCrosse/ChangeLog
@@ -0,0 +1,3 @@
+
+# $Id: ChangeLog,v 1.1 2006/01/25 19:36:27 n0vh Exp $
+
diff --git a/LaCrosse/INSTALL b/LaCrosse/INSTALL
new file mode 100644
index 0000000..0027478
--- /dev/null
+++ b/LaCrosse/INSTALL
@@ -0,0 +1,232 @@
+
+$Id: INSTALL,v 1.1 2006/01/25 19:36:27 n0vh Exp $
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/LaCrosse/Makefile.am b/LaCrosse/Makefile.am
new file mode 100644
index 0000000..bdccfa4
--- /dev/null
+++ b/LaCrosse/Makefile.am
@@ -0,0 +1,43 @@
+
+# $Id: Makefile.am,v 1.8 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+
+AUTOMAKE_OPTIONS = gnu dist-bzip2
+ACLOCAL_AMFLAGS = -I m4
+
+D=      `date +%G%m%d.%H%M%S`
+
+SUBDIRS = src
+
+
+#if DAVIS
+#MyWX = davis
+#else
+#MyWX =
+#endif
+#noinst_PROGRAMS = $(MyWX)
+
+
+# Remove this file here (it is created via configure), not from within intl.
+# DISTCLEANFILES =
+
+EXTRA_DIST = aclocal.m4 AUTHORS bootstrap.sh ChangeLog config.h.in \
+        config.status configure.ac COPYING INSTALL NEWS \
+        README bootstrap.sh
+
+MAINTAINERCLEANFILES = configure config.status aclocal.m4 \
+        Makefile.in Makefile config.guess config.sub install-sh \
+        missing mkinstalldirs
+
+#docdir=${pkgdatadir}/doc
+#doc_DATA=AUTHORS FAQ ChangeLog LICENSE README README.CVS \
+#        README.MAPS README.win32 COPYING INSTALL UPGRADE
+
+#mandir=${prefix}/man
+#man_MANS=xastir.1
+
+ChangeLog::
+
+
diff --git a/LaCrosse/NEWS b/LaCrosse/NEWS
new file mode 100644
index 0000000..14262f5
--- /dev/null
+++ b/LaCrosse/NEWS
@@ -0,0 +1,3 @@
+
+$Id: NEWS,v 1.1 2006/01/25 19:36:27 n0vh Exp $
+
diff --git a/LaCrosse/README b/LaCrosse/README
new file mode 100644
index 0000000..295fb6f
--- /dev/null
+++ b/LaCrosse/README
@@ -0,0 +1,202 @@
+
+$Id: README,v 1.8 2012/11/01 18:57:18 we7u Exp $
+
+Copyright (C) 2006 Jim Chandler <jim at n0vh.org>
+Portions Copyright (C) 2004 Bruce Bennett <bruts at adelphia.net>
+Portions Copyright (C) 2004-2012  The Xastir Group
+(Modified for the Xastir project under GPL license)
+
+
+LaCrosse WS-23xx Weather Station support for Xastir - open2300db2APRS
+
+
+OVERVIEW
+--------
+
+This is a bridge utility between "open2300", a LaCrosse Weather Station 
+data storage & display application by Kenneth Lavrsen (see 
+http://www.lavrsen.dk/twiki/bin/view/Open2300/WebHome) and "Xastir", 
+the APRS package for Linux (see http://www.xastir.org). It allows your 
+LaCrosse WS-23xx weather data to be used by Xastir for local station data.
+
+You will need to obtain and install Xastir, mysql and open2300 as 
+outlined in the following sections. After Xastir and open2300 are
+in working order, this utility can be run as a daemon to provide 
+weather data to Xastir (or any other APRS-format application).
+
+"open2300db2APRS" watches for new weather data in the database, retrieves
+the new data, formats it in APRS "position less" ASCII format and
+makes it available on a TCP port of your choosing. Xastir is 
+capable of reading this data (see note under Xastir installation).
+
+
+INSTALLATION
+------------
+
+Steps in order:
+
+1) Install mysql - initial tested version mysql-3.23.58
+   although version 4 is released and has some significant 
+   improvements - and version 4 *should* work (to be tested yet). 
+   If you use an RPM or DPK binary-image version, be sure to add 
+   the mysql-devel headers. For the latest image-version, see 
+   http://www.mysql.com and follow the links to the downloads. 
+   I used mysql-3.23.58-pc-linux-i686.tar.gz from that site.   
+
+2) Install open2300 - tested version open2300-1.10 
+   See the instructions for installing & then setting 
+   up open2300 that come with the tar ball. Obtain the latest open2300 
+   at http://www.lavrsen.dk/twiki/bin/view/Open2300/WebHome - the setup 
+   is rather involved but worth the efort. Some SQL/XML skills can help 
+   here, but are not absolutely required...
+
+   The table setup for the mySQL portion of the open2300 database can be 
+   found in the weatherdump.sql file.  My database is setup for degree F, 
+   inches of Mercury, inches of rain, and windspeed in knots.
+
+3) Install or update your installation for Xastir to the latest
+   version (http://www.sourceforge.net, project Xastir) 
+
+4) Install open2300db2APRS 
+   See instructions below.
+
+
+SETTINGS & STARTUP
+------------------
+
+1) mysql - it is recommended by mysql to set up passwords, but for
+   this usage it doesn't matter. In fact, it's a bit of a pain.
+   TODO - open2300db2APRS has the annoying fault of clearly displaying 
+   the password used for the mysql database for anyone to see via 
+   'ps -ef'. Start mysqld before open2300db2APRS, meteo and Xastir in your 
+   boot-time initializations.
+
+2) open2300 - my testing used a five minute data accumulation rate. 
+   Thirty seconds would more closely match Xastir, but the 
+   database growth rate would be twelve as fast (about 600  
+   Mbytes/year at 30 sec rate).  I run a cronjob every five minutes that
+   calls mysql2300 to populate the data.  See the open2300 documentation.
+
+3) open2300db2APRS - see "open2300db2APRS RUN OPTIONS" below. Start this daemon 
+   after mysqld and before Xastir.  I start it with the command 
+   "open2300db2APRS -r --password <db2passwd>
+
+4) xastir - start this last, if you are auto-opening the WX port.
+   Set the weather port as a network weather station on 
+   "localhost", port number as chosen in "db2APRS RUN OPTIONS" 
+   (default is 1313). Make sure your station is set to one of the
+   "w/weather data" and your Icon is set to a weather Icon.
+
+
+open2300db2APRS RUN OPTIONS
+-------------------
+
+The open2300db2APRS utility takes standard short & long command line 
+options, which can be displayed by "open2300db2APRS -?". Here's the list:
+
+  -h	--help	
+
+      Show help info and exit.
+
+  -v    --verbose
+
+      Useful with the -n switch, for trouble-shooting, not for 
+      normal operation. Tells you more than you really wanted to  
+      know, but I recommend that you use this switch while you 
+      try to initially set up db2APRS.
+
+  -c	--cport [port#]
+
+      Choose which TCP/IP port data comes out from. If not used,
+      port number 1313 is the default. HINT: "telnet localhost 
+      [port#]" is a handy way to verify db2APRS operation.
+
+  -u 	--user [database user]	
+
+      Username for mysql database connection. If unspecfied 
+      defaults to "meteo" (which is per the meteo setup intended
+      to be a read-only account for meteo).
+
+  -p 	--password [db passwd]	
+
+      Password for mysql connection. If unspecfied, no password  
+      is supplied. NOTE: this password is unfortunately visible 
+      to anyone on your system running 'ps -ef'. TO BE FIXED.
+
+  -b 	--database [database]	
+
+      Database name for mysql connection. If not supplied the 
+      default is "meteo".
+
+  -n	--nodaemon
+
+      Run in the fore-ground as a program. Useful for debugging
+      or initial setup, when used with -v.
+
+  -r	--repeat
+      
+      Keep going till killed - if not specified, one pass is 
+      performed and then db2APRS exits. The only case where this  
+      switch is *not* used is during initial setup/debug.
+
+Typical example: "./open2300db2APRS -r -u open2300 -p mysql2300" for normal use
+or "./open2300db2APRS -r -n -v -u test -p password" for debugging.
+
+
+OPERATIONAL DETAILS
+-------------------
+
+open2300db2APRS connects to the specified mysql database, extracts the 
+latest timestamp and compares it to the last timestamp it read. 
+If newer, the outdoor weather data (extception: air pressure is
+taken as indoor=outdoor) bearing this timestamp is extracted 
+and formatted in the APRS "position less" string format with a  
+Davis and X-APRS tag on the end. Any connecting client is given 
+this string at 25 second intervals, after new database entries 
+are checked for.
+
+This daemon could run on any networked Linux machine instead of 
+the machine hosting Xastir, if desired (it's a good way around 
+lack of processing power, disk space or serial ports!).
+
+Note that the open2300db2APRS daemon keeps providing data to Xastir even 
+when no new entries in the database have been made. This could 
+lead to errors in the timestamp on the data that Xastir is 
+transmitting.
+
+
+BUILD open2300db2APRS
+-------------
+
+It's the usual:
+
+$ cd xastir/LaCrosse
+$ ./bootstrap.sh
+$ ./configure
+$ make
+$ su -c 'make install'
+
+
+ACKNOWLEGEMENTS & AUTHORS
+-------------------------
+
+A large portion of this work taken from db2APRS (thanks Bruce!!)
+
+db2APRS is the product of Bruce Bennett, callsign KB8ROP 
+<bruts at adelphia.net> It is freely available at no charge 
+under the GNU GENERAL PUBLIC LICENSE (see "COPYING" document)
+NO WARRANTY, expressed or implied, use at your own risk.
+
+Please feel free to contact me with test results & comments 
+at the above EMAIL address
+
+Code portions and style taken from wx200d by Tim Witham 
+<twitham at quiknet.com>, et. al.
+
+mysql is the product of MySQL - see http://www.mysql.com for
+team details.
+
+and finally, Xastir is the brain child of Frank Giannandrea et. 
+al. (see http://www.xastir.org for current EMAIL addresses)
+
+
diff --git a/LaCrosse/autom4te.cache/CVS/Entries b/LaCrosse/autom4te.cache/CVS/Entries
new file mode 100644
index 0000000..1784810
--- /dev/null
+++ b/LaCrosse/autom4te.cache/CVS/Entries
@@ -0,0 +1 @@
+D
diff --git a/LaCrosse/autom4te.cache/CVS/Repository b/LaCrosse/autom4te.cache/CVS/Repository
new file mode 100644
index 0000000..8168667
--- /dev/null
+++ b/LaCrosse/autom4te.cache/CVS/Repository
@@ -0,0 +1 @@
+xastir/LaCrosse/autom4te.cache
diff --git a/LaCrosse/autom4te.cache/CVS/Root b/LaCrosse/autom4te.cache/CVS/Root
new file mode 100644
index 0000000..6a998ee
--- /dev/null
+++ b/LaCrosse/autom4te.cache/CVS/Root
@@ -0,0 +1 @@
+:ext:we7u at xastir.cvs.sourceforge.net:/cvsroot/xastir
diff --git a/LaCrosse/bootstrap.sh b/LaCrosse/bootstrap.sh
new file mode 100755
index 0000000..43677b6
--- /dev/null
+++ b/LaCrosse/bootstrap.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# $Id: bootstrap.sh,v 1.9 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+#
+
+../bootstrap.sh
+
diff --git a/LaCrosse/configure.ac b/LaCrosse/configure.ac
new file mode 100755
index 0000000..a7ae58e
--- /dev/null
+++ b/LaCrosse/configure.ac
@@ -0,0 +1,68 @@
+#
+# $Id: configure.ac,v 1.7 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2004 Bruce Bennett <bruts at adelphia.net>
+# Portions Copyright (C) 2004-2012  The Xastir Group
+# (Modified for the Xastir project under GPL license)
+#
+#
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.53)
+AC_INIT(open2300db2APRS, 0.1.0, jim at n0vh.org)
+AM_INIT_AUTOMAKE(open2300db2APRS, 0.1.0)
+AC_CONFIG_SRCDIR([src/open2300db2APRS.c])
+AM_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_PROG_INSTALL
+AC_PROG_CC
+
+# Checks for libraries.
+# Use MySQL's script for library config, if available
+MYSQL_CONFIG=mysql_config
+AC_MSG_CHECKING(for a fully installed MySQL)
+if ${MYSQL_CONFIG} --libs > /dev/null 2>&1
+then
+    MYSQL_VERSION=`${MYSQL_CONFIG} --version`
+    MYSQL_LIBS=`${MYSQL_CONFIG} --libs`
+    LIBS=`${MYSQL_CONFIG} --libs`
+    MYSQL_CFLAGS=`${MYSQL_CONFIG} --cflags`
+    CFLAGS="$CFLAGS $MYSQL_CFLAGS"
+    AC_SUBST(MYSQL_LIBS)
+    AC_SUBST(MYSQL_CFLAGS)
+    AC_MSG_RESULT(...found ${MYSQL_VERSION})
+else
+    AC_MSG_RESULT(MySQL is not fully installed)
+    AC_MSG_CHECKING(if there at least are the needed MySQL client libs)
+    AC_CHECK_LIB(mysqlclient,mysql_close)
+    if test $ac_cv_lib_mysqlclient_mysql_close = no; then
+    
+        AC_MSG_ERROR(*** No MySQL client library found - See README ***)
+    else
+        AC_MSG_RESULT(found a usable libmysqlclient)
+    fi
+fi
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h syslog.h unistd.h])
+if ${MYSQL_CONFIG} --libs > /dev/null 2>&1
+then
+    AC_MSG_RESULT(mysql.h path defined in CFLAGS)
+else
+    AC_CHECK_HEADERS([mysql.h],MYSQL_INC="yes",AC_MSG_ERROR(*** MySQL include file mysql.h not found - See README ***))
+fi
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_FUNC_STRTOD
+AC_CHECK_FUNCS([memset select socket strrchr strtol])
+AC_CONFIG_FILES([Makefile \
+    src/Makefile])
+AC_OUTPUT
diff --git a/LaCrosse/src/.cvsignore b/LaCrosse/src/.cvsignore
new file mode 100644
index 0000000..e8ea731
--- /dev/null
+++ b/LaCrosse/src/.cvsignore
@@ -0,0 +1,4 @@
+.deps
+Makefile
+Makefile.in
+open2300db2APRS
diff --git a/LaCrosse/src/CVS/Entries b/LaCrosse/src/CVS/Entries
new file mode 100644
index 0000000..309e53c
--- /dev/null
+++ b/LaCrosse/src/CVS/Entries
@@ -0,0 +1,5 @@
+/.cvsignore/1.1/Thu Jan 26 15:42:22 2006//
+/Makefile.am/1.7/Thu Nov  1 18:57:18 2012//
+/defs.h/1.6/Thu Nov  1 18:57:18 2012//
+/open2300db2APRS.c/1.11/Thu Nov  1 18:57:18 2012//
+D
diff --git a/LaCrosse/src/CVS/Repository b/LaCrosse/src/CVS/Repository
new file mode 100644
index 0000000..185c93b
--- /dev/null
+++ b/LaCrosse/src/CVS/Repository
@@ -0,0 +1 @@
+xastir/LaCrosse/src
diff --git a/LaCrosse/src/CVS/Root b/LaCrosse/src/CVS/Root
new file mode 100644
index 0000000..6a998ee
--- /dev/null
+++ b/LaCrosse/src/CVS/Root
@@ -0,0 +1 @@
+:ext:we7u at xastir.cvs.sourceforge.net:/cvsroot/xastir
diff --git a/LaCrosse/src/Makefile.am b/LaCrosse/src/Makefile.am
new file mode 100644
index 0000000..9380c94
--- /dev/null
+++ b/LaCrosse/src/Makefile.am
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile.am,v 1.7 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+
+bin_PROGRAMS = open2300db2APRS
+noinst_PROGRAMS = 
+
+open2300db2APRS_SOURCES = \
+    open2300db2APRS.c defs.h
+
+
+open2300db2APRS_LINK=$(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+
diff --git a/LaCrosse/src/defs.h b/LaCrosse/src/defs.h
new file mode 100644
index 0000000..d27615a
--- /dev/null
+++ b/LaCrosse/src/defs.h
@@ -0,0 +1,15 @@
+//
+// $Id: defs.h,v 1.6 2012/11/01 18:57:18 we7u Exp $
+//
+// Copyright (C) 2005 Jim Chandler <jim at n0vh.org>
+// Portions Copyright (C) 2004-2012 The Xastir Group
+//
+//
+// Dummy info here for now...
+//
+
+
+#define VERSION "0.1.0"
+#define PORT	1313
+#define CONNECTIONS	20
+#define NOFILE		20
diff --git a/LaCrosse/src/open2300db2APRS.c b/LaCrosse/src/open2300db2APRS.c
new file mode 100644
index 0000000..e42de77
--- /dev/null
+++ b/LaCrosse/src/open2300db2APRS.c
@@ -0,0 +1,912 @@
+/******************************************************************
+ *
+ * $Id: open2300db2APRS.c,v 1.11 2012/11/01 18:57:18 we7u Exp $
+ *
+ * Copyright (C) 2005 Jim Chandler <jim at n0vh.org>
+ * Portions Copyright (C) 2004-2012 The Xastir Group
+ *
+ * Portions copied from Bruce Bennett's excellent Davis WX work
+ *
+ * (see the files README and COPYING for more details)
+ *
+ * This file implements all of the database to APRS daemon.
+ *
+ *
+    
+        LaCrosse/Data Base Weather --> APRS Weather
+
+        Intended use: 
+		
+        Create & provide APRS style packet string
+        without position information from MySQL database
+        weather information stored there by open2300
+        (See http://open2300.sourceforge.net/ for source) to
+        xastir-1.2.1 (See http://www.xastir.org for source)
+
+        Note:  Open2300 is a weather data accumulator
+        aimed at LaCrosse weather stations, which stores weather
+        data in a mysql database.  
+
+        Output is to the ip hostname:port required in the 
+        command line.
+
+    ACKNOWLEGEMENTS:
+
+        Elements of this software are taken from wx200d ver 1.2
+        by Tim Witham <twitham at quiknet.com>, and it is modeled
+        after that application and from db2APRS by 
+	Bruce Bennett <bruts at adelphia.net>. 
+
+*******************************************************************/
+#include <config.h>
+#include <defs.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <syslog.h>
+#include <errno.h>
+#include <getopt.h>
+#include <mysql.h>
+
+#define MAXARGS 20      /* maximum CGI args to parse */
+#define TMPLEN 128      /* max length of CGI */
+#define BUFLEN 32       /* max length of hostname:port */
+
+#define VALID_WINDDIR   0x01
+#define VALID_WINDSPD   0x02
+#define VALID_WINDGST   0x04
+#define VALID_TEMP      0x08
+#define VALID_RAIN1HR   0x10
+#define VALID_RAIN24H   0x20
+#define VALID_HUMIDITY  0x40
+#define VALID_AIRPRESS  0x80
+#define VALID_RAINTOT   0x100
+
+#define MTPS2MPH        2.2369
+#define DEGC2DEGF       1.8
+#define MM2IN100TH      3.937
+#define INHG2HPA10TH    338.638
+
+#define OUTDOOR_SENSOR  1
+
+    //---From the static table "mfield", which really should be dynamically read here---
+    //			(but then I couldn't use a switch statement)
+
+#define TEMPERATURE         0
+#define TEMPERATURE_MIN     1
+#define TEMPERATURE_MAX     2
+#define HUMIDITY            10
+#define HUMIDITY_MIN        11
+#define HUMIDITY_MAX        12
+#define WETNESS             20
+#define WETNESS_MIN         21
+#define WETNESS_MAX         22
+#define AIR_PRESSURE        30
+#define AIR_PRESSURE_MIN    31
+#define AIR_PRESSURE_MAX    32
+#define SOLAR               40
+#define UV                  41
+#define RAIN                50
+    // note: "51" is really rain total
+#define RAIN_PER_DAY        51
+#define RAIN_PER_HOUR       52
+#define WIND_SPEED          60
+#define WIND_DIRECTION      61
+#define WIND_GUST           62
+#define WIND_X              63
+#define WIND_Y              64
+#define MOISTURE            70
+#define WATERLEVEL          71
+#define WATERLEVEL_MIN      72
+#define WATERLEVEL_MAX      73
+#define BATTERY             110
+#define TRANSMITTER         111
+#define DURATION            120
+#define SAMPLES             121
+
+struct dbinfo {
+    char user[30];
+    char pswrd[15];
+    char name[30];
+} db;
+	
+char *progname;
+char *query;
+int *current = 0;
+
+int opt;
+
+MYSQL       mysql;    // Yeah, globals...
+MYSQL_RES   *result;
+MYSQL_ROW   row;
+
+char last_timestamp[20];
+
+int debug_level;
+
+char wxAPRShost[BUFLEN];
+int wxAPRSport = PORT;
+int outdoor_instr = OUTDOOR_SENSOR;
+
+/******************************************************************
+1/4/2003
+            Usage brief
+
+*******************************************************************/
+void usage(int ret)
+{
+    if (query)
+        printf("Content-type: text/plain\nStatus: 200\n\n");
+	printf("usage: %s [options] \n",progname);
+	printf("VERSION: %s\n",VERSION);
+    printf("  -h    --help                      show this help and exit\n");
+    printf("  -v    --verbose                   debugging info --> stderr\n");
+    printf("  -c    --cport [port#]             IP port for data output\n");
+    printf("  -u    --user [database user]      username for mysql - default meteo\n");
+    printf("  -p    --password [db passwd]      password for mysql - default none\n");
+    printf("  -b    --database [database]       database name - default meteo\n");
+    printf("  -n    --nodaemon                  do not run as daemon\n");
+    printf("  -r    --repeat                    keep running\n");
+    printf("options may be uniquely abbreviated; units are as defined in APRS\n"); 
+    printf("Specification 1.0.1 for positionless weather data (English/hPa).\n");
+    exit(ret);
+}
+
+
+
+
+
+/******************************************************************
+1/2/2003
+            Make an APRS string out of WX data
+
+*******************************************************************/
+
+int APRS_str(char *APRS_buf, 
+            double winddir,
+            double windspeed,				
+            double windgust,
+            double temp,
+            double rain1hr,
+            double rain24h,
+            double raintot,
+            double humidity,
+            double airpressure,
+            unsigned int valid_data_flgs,
+            int Metric_Data)
+{
+
+    int intval;
+    char pbuf[10];
+
+    if (APRS_buf == NULL) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Null string buffer for APRS string.\n");
+        return 0;  //  Ooo!!  *****Nasty Bad Exit Point Here****
+
+    }
+    if(valid_data_flgs & VALID_WINDDIR) {
+        intval = (winddir + 0.5); // rounding to whole degrees
+        if (intval > 360) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind direction > 360\n");
+            sprintf(APRS_buf, "c...");
+        } 
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind direction negative\n");
+            sprintf(APRS_buf, "c...");
+
+        } 
+        else {
+            sprintf(APRS_buf, "c%0.3d", intval);
+        }
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Wind direction flagged as invalid\n");
+        sprintf(APRS_buf, "c...");
+
+    }
+
+    if(valid_data_flgs & VALID_WINDSPD) {
+        if (Metric_Data)
+            intval = (windspeed*MTPS2MPH + 0.5); // converting & rounding to whole MPH 
+        else
+            intval = (windspeed + 0.5); // rounding to whole MPH
+        if (intval > 600) { // Let's be reasonable here - center of a tornado??
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind speed > 600 MPH\n");
+            sprintf(pbuf, "s...");
+
+        } 
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind speed negative\n");
+            sprintf(pbuf, "s...");
+
+		} 
+        else {
+				sprintf(pbuf, "s%0.3d", intval);
+        }
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Wind speed flagged as invalid\n");
+        sprintf(pbuf, "s...");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_WINDGST) {
+        if (Metric_Data)
+            intval = (windgust*MTPS2MPH + 0.5); // converting & rounding to whole MPH
+        else
+            intval = (windgust + 0.5); // rounding to whole MPH
+        if (intval > 600) { // Let's be reasonable here - center of a tornado??
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind gust > 600 MPH\n");
+            sprintf(pbuf, "g...");
+
+        } 
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Wind speed negative\n");
+            sprintf(pbuf, "g...");
+
+        } 
+        else {
+            sprintf(pbuf, "g%0.3d", intval);
+        }
+
+    } 
+    else {
+	    if (debug_level & 1)
+            fprintf(stderr,"info: Wind gust flagged as invalid\n");
+        sprintf(pbuf, "g...");
+
+    }
+	strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_TEMP) {
+        if (Metric_Data)
+            intval = ((temp)*DEGC2DEGF + 0.5)+32; // converting & rounding to whole Deg F
+        else
+            intval = (temp + 0.5); // rounding to whole Deg F
+        if (intval > 200) { // Let's be reasonable here - boiling?
+            if (debug_level & 1)
+                fprintf(stderr,"err: Temperature > 200 Deg F\n");
+            sprintf(pbuf, "t...");
+
+        } 
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Temperature < -99 Deg F\n");
+            sprintf(pbuf, "t...");
+
+        } 
+        else {
+            if (intval < 0) sprintf(pbuf,"t%0.2d",intval);
+            else sprintf(pbuf, "t%0.3d", intval);
+        }
+
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Temperature flagged as invalid\n");
+        sprintf(pbuf, "t...");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_RAIN1HR) {
+        if (Metric_Data)
+            intval = ((rain1hr)*MM2IN100TH + 0.5); // converting & rounding to whole 1/100 inch
+        else
+            intval = (rain1hr*100.0 + 0.5); // rounding to whole 1/100 inch
+        if (intval > 999) { // 10 in/hr? Garden Hose -> rain gauge?
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/Hr > 9.99 inch\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/Hr negative\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else {
+            sprintf(pbuf, "r%0.3d", intval);
+        }
+    } 
+    else {
+	
+        if (debug_level & 1)
+            fprintf(stderr,"info: Rainfall/Hr flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_RAIN24H) {
+        if (Metric_Data)
+            intval = ((rain24h)*MM2IN100TH + 0.5); // converting & rounding to whole 1/100 inch
+        else
+            intval = (rain24h*100.0 + 0.5); // rounding to whole 1/100 inch
+        if (intval > 999) { // Can't handle greater than 9.99 inches of rain in 24 hours
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/24Hr > 9.99 inch - reporting 9.99 inches\n");
+            sprintf(pbuf, "p999");
+
+        } 
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Rainfall/Hr negative\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else {
+            sprintf(pbuf, "p%0.3d", intval);
+        }
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Rainfall/24Hr flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+
+    if(valid_data_flgs & VALID_HUMIDITY) {
+        intval = (humidity + 0.5); // rounding to whole percent
+        if (intval > 100) { // Unlike the space shuttle engines, 100 % is max
+            if (debug_level & 1)
+                fprintf(stderr,"err: Humidity reported > 100%\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+		} 
+        else if (intval < 1) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Humidity reported < 1%\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else {
+            if (intval == 100) intval = 0;  // Report 100% as 'h00'
+            sprintf(pbuf, "h%0.2d", intval);
+        }
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Humidity flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    if(valid_data_flgs & VALID_AIRPRESS) {
+        if (Metric_Data)
+            intval = (airpressure*10.0 + 0.5); //  rounding to whole tenth of a hPa
+        else
+            intval = (airpressure*INHG2HPA10TH + 0.5); // convering In-Hg to 1/10 hPa and rounding
+        if (intval > 20000) { //two atmospheres - about 29 PSIA
+            if (debug_level & 1)
+                fprintf(stderr,"err: Air Pressure reported > 2 Atmospheres%\n");
+                sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else if (intval < 0) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: Air Pressure reported negative%\n");
+            sprintf(pbuf, "\0\0\0\0");
+
+        } 
+        else {
+            sprintf(pbuf, "b%0.5d", intval);
+		}
+	} else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: Air Pressure flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    // NOW THIS MAKES THE STRING NO LONGER A VALID APRS WX REPORT, but
+    // we don't care:  Xastir does NOT just transmit this string, it parses it
+    // and re-recreates the correct string to transmit.  We do this because
+    // APRS doesn't have a "total rain" string in its weather report, but
+    // Xastir likes to have that value around.
+    if(valid_data_flgs & VALID_RAINTOT) {
+        if (Metric_Data)
+            intval = ((raintot)*MM2IN100TH + 0.5); // converting & rounding to whole 1/100 inch
+        else
+            intval = (raintot*100.0 + 0.5); // rounding to whole 1/100 inch
+
+        // Can't handle greater than 99.99 inches of total rain 
+        if (intval > 9999) { 
+            if (debug_level & 1)
+                fprintf(stderr,"err: total Rainfall  > 99.99 inch - reporting 9.99 inches\n");
+            sprintf(pbuf, "T9999");
+
+        } 
+        else if (intval < -99) {
+            if (debug_level & 1)
+                fprintf(stderr,"err: total Rainfall negative\n");
+            sprintf(pbuf, "\0\0\0\0\0");
+
+        } 
+        else {
+            sprintf(pbuf, "T%0.4d", intval);
+        }
+    } 
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"info: total Rainfall flagged as invalid\n");
+        sprintf(pbuf, "\0\0\0\0\0");
+
+    }
+    strcat(APRS_buf,pbuf);
+
+    strcat(APRS_buf,"xDvs\n");  // add X aprs and LaCrosse WX station ID's and <lf>
+
+    if (debug_level & 1)
+        fprintf(stderr,"\ninfo: APRS Version of WX - %s\n\n",APRS_buf);
+    return strlen(APRS_buf);
+}
+
+
+
+
+
+/******************************************************************
+1/2/2003
+            Get the latest set of Weather Data from the Data Base
+
+*******************************************************************/
+
+int Get_Latest_WX( double *winddir,
+                double *windspeed,				
+                double *windgust,
+                double *temp,
+                double *rain1hr,
+                double *rain24h,
+                double *raintot,
+                double *humidity,
+                double *airpressure,
+                unsigned int *valid_data_flgs,
+                int *Metric_Data)
+
+{
+
+    char latest_timestamp[20];
+    char query_buffer[160];
+    int nrows, row_cnt, item_count;
+    int nfields;
+
+		
+    // Find latest, see if it's new to us
+    // --new to us is a simple timestamp follower, so upon startup
+    // it will always read one set of data, assuming any exists
+
+    if (mysql_query(&mysql, "SELECT MAX(timestamp) from weather")) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Latest timestamp query failed - exiting: %s\n", mysql_error(&mysql));
+        return 0;
+    }
+	
+    if (!(result = mysql_store_result(&mysql))) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Latest timestamp query failed - exiting: %s\n", mysql_error(&mysql));
+        return 0;
+    }
+	
+    if (mysql_num_rows(result) != 1 ) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Latest timestamp query failed - exiting: number of results %d\n",
+                mysql_num_rows(result));
+         // release query buffer
+         mysql_free_result(result);
+        return 0;
+    }
+	
+    row = mysql_fetch_row(result);
+	
+    if( row[0] == NULL ) {
+        if(debug_level & 1)
+            fprintf(stderr,"err: NULL result for timestamp query\n");
+        // release query buffer
+        mysql_free_result(result);
+        return 0;
+    }
+    // if no new data. exit with negative status
+		
+    if (!strncmp(last_timestamp, row[0], 14)) {
+        if (debug_level & 1)
+            fprintf(stderr,"info: No new weather data recorded - exiting: negative data\n");
+        // release query buffer
+        mysql_free_result(result);
+        return -1;
+    }
+    strcpy(last_timestamp, row[0]);	  // For next pass & following query
+
+    if( debug_level & 1) fprintf(stdout,"Timestamp: %s\n",last_timestamp);
+	
+    // release query buffer
+    mysql_free_result(result);
+
+    sprintf(query_buffer,"SELECT wind_angle, windspeed, temp_out, rain_1h, rain_24h, rel_hum_out, rel_pressure, rain_total FROM weather WHERE timestamp = %s", last_timestamp);
+
+    if (mysql_query(&mysql, query_buffer)) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Latest Weather Data query failed - exiting: %s\n\t --Query: %s\n",
+                mysql_error(&mysql), query_buffer);
+        return 0;
+    }
+
+    if (!(result = mysql_store_result(&mysql))) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Latest Weather Data query failed - exiting: %s\n", mysql_error(&mysql));
+        return 0;
+    }
+    if ((nrows=mysql_num_rows(result)) < 1 ) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Latest Weather Data query failed - exiting: number of results %d\n",nrows);
+        // release query buffer
+        mysql_free_result(result);
+        return 0;
+    }
+    else {
+        nfields=mysql_num_fields(result);
+        row=mysql_fetch_row(result);
+        if (debug_level & 1)
+            fprintf(stderr,"info: Latest Weather Data query: number of types of readings %d\n",nfields);
+    }
+
+    *valid_data_flgs = 0;
+    item_count = 0;
+
+    //WIND_DIRECTION :
+    *winddir = strtod(row[0],NULL);
+    *valid_data_flgs |= VALID_WINDDIR;  
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"wind direction %f\n ",*winddir);
+    //case WIND_SPEED :
+    *windspeed = strtod(row[1],NULL);
+    *windspeed = *windspeed * 1.15077945; // Convert from knots to mph
+    *valid_data_flgs |= VALID_WINDSPD;  
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"wind speed %f\n ",*windspeed);
+    //case WIND_GUST :
+    *windgust = strtod("0",NULL);
+    //*valid_data_flgs |= VALID_WINDGST;  No gust information from open2300
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"wind gust speed %f\n ",*windgust);
+    //case TEMPERATURE :
+    *temp = strtod(row[2],NULL);
+    *valid_data_flgs |= VALID_TEMP;
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"temperature %f\n ",*temp);
+    //case RAIN_PER_HOUR :
+    *rain1hr = strtod(row[3],NULL);
+    *valid_data_flgs |= VALID_RAIN1HR;  
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"rainfall for 1 hr %f\n ",*rain1hr);
+    //case RAIN_PER_DAY :
+    *rain24h = strtod(row[4],NULL);
+    *valid_data_flgs |= VALID_RAIN24H;  
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"rainfall for 24 hrs %f\n ",*rain24h);
+    //case HUMIDITY :
+    *humidity = strtod(row[5],NULL);
+    *valid_data_flgs |= VALID_HUMIDITY;
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"humidity %f\n ",*humidity);
+    //case AIR_PRESSURE :
+    *airpressure = strtod(row[6],NULL);
+    *valid_data_flgs |= VALID_AIRPRESS;
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"air pressure %f\n ",*airpressure);
+    //case  RAIN_TOTAL
+    *raintot = strtod(row[7],NULL);
+    *valid_data_flgs |= VALID_RAINTOT;  
+    item_count++;
+    if(debug_level & 1)
+         fprintf(stderr,"rainfall since reset %f\n ",*raintot);
+
+    *Metric_Data = 0;  // My station reports F, knots and inHG
+    // release query buffer	& close connection
+    mysql_free_result(result);
+
+    if (debug_level & 1)
+        fprintf(stderr,"info: success - Weather Data number of reading types %d\n",
+             item_count);
+
+    return item_count;
+}				
+
+
+/******************************************************************
+1/5/2003
+            SIGPIPE signal handler
+
+*******************************************************************/
+void pipe_handler(int sig)		/*  */
+{
+    signal(SIGPIPE, SIG_IGN);
+    if (sig == SIGPIPE) {		// client went bye-bye
+        shutdown(*current, 2); 
+        close(*current);
+        *current = -1;
+        if (debug_level & 1)
+            fprintf(stderr, "info: %s - TCP client timed out", progname); 
+    }
+}
+
+
+
+
+
+/******************************************************************
+1/5/2003
+            SIGTERM signal handler
+
+*******************************************************************/
+void term_handler(int sig)		/*  */
+{
+    if (debug_level & 1)
+        fprintf(stderr, "info: %s - ordered to DIE, complying", progname);
+
+    // release query buffer	& close connection
+    mysql_free_result(result);
+
+    mysql_close(&mysql);
+
+    exit( 0 );
+}
+
+
+
+
+
+/******************************************************************
+1/2/2003
+        Coordinating MAIN point
+
+*******************************************************************/
+int main(int argc, char **argv)
+{
+    const char *flags = "Hhvnc:u:p:d:s:r";
+    char WX_APRS[120];
+    int data_len = 0 ;
+    double winddir;
+    double windspeed;				
+    double windgust;
+    double temp;
+    double rain1hr;
+    double rain24h;
+    double raintot;
+    double humidity;
+    double airpressure;
+    unsigned int valid_data_flgs;
+    int Metric_Data = 0, dsts = 0;
+    int  pid, s;
+    socklen_t clen = sizeof(struct sockaddr_in);
+    int fd[CONNECTIONS];
+    int *max = 0,  c, dly_cnt = 1;
+    int not_a_daemon = 0, repetitive = 0, tcp_wx_port = PORT;
+    int  i, index = 0;
+    struct sockaddr_in server, client;
+    struct in_addr bind_address;
+    fd_set rfds;
+    struct timeval tv;
+
+    struct option longopt[] = {
+        {"help", 0, 0, 'h'},
+        {"refresh", 0, 0, 'r'},
+        {"verbose", 0, 0, 'v'},
+        {"user", 1, 0, 'u'},
+        {"password", 1, 0, 'p'},
+        {"database", 1, 0, 'd'},
+        {"cport", 1, 0, 'c'},
+        {"nodaemon", 0, 0, 'n'},
+        {0, 0, 0, 0}
+    };
+
+    debug_level = 0;
+
+    strcpy(db.user,"open2300");	 // set default values for database access
+    strcpy(db.name,"open2300");
+    memset(db.pswrd,0,15);
+
+    mysql_init(&mysql);
+
+
+    progname = strrchr(argv[0], '/');
+    if (progname == NULL)
+        progname = argv[0];
+    else
+        progname++;
+
+    while ((opt = getopt_long(argc, argv, flags, longopt, &index)) != EOF) { 
+        switch (opt) {		/* parse command-line or CGI options */
+            case 'r':
+                repetitive = 1;
+                break;
+            case 'v':
+                fprintf(stdout,"Verbose mode set:\n");
+                debug_level = 1;
+                break;
+            case 'u':	 // mysql username 
+                strncpy(db.user,(char *)optarg,30);
+                break;
+            case 'p':	 // mysql password 
+                strncpy(db.pswrd,(char *)optarg,15);
+                break;
+            case 'd':	 // mysql database name
+                strncpy(db.name,(char *)optarg,30);
+                break;
+            case 'n':			/* do not fork and become a daemon */
+                not_a_daemon = 1;
+                break;
+            case 'c':			/* port to use */
+                tcp_wx_port = strtol(optarg, NULL, 0);
+                break;
+ 
+            case '?':
+            case 'h':
+            case 'H':
+                usage(0);
+                break;
+            default :
+                usage(1);
+        }
+    }
+    if (debug_level & 1) {
+        fprintf(stdout,"Starting...");
+        if (repetitive) fprintf(stdout, " forever ");
+        else fprintf(stdout, " one pass only ");
+        fprintf(stdout," with  database user=%s, password=%s, for database=%s\n",
+            db.user, db.pswrd, db.name);
+        if(not_a_daemon) fprintf(stdout," as a program ");
+        else fprintf(stdout," as a daemon ");
+        fprintf(stdout, " using TCP port %d\n",tcp_wx_port);
+    }
+
+        // Data base connection
+	
+	
+    if (!(mysql_real_connect(&mysql, "localhost", db.user, db.pswrd, db.name, 0, NULL, 0))) {
+        if (debug_level & 1)
+            fprintf(stderr,"err: Data Base connect for user:%s to database:%s failed - exiting: \n\t%s\n",
+                db.user, db.name, mysql_error(&mysql));
+        exit(9);
+    }
+	                                                                        
+    server.sin_family = AF_INET;
+    bind_address.s_addr = htonl(INADDR_ANY);
+    server.sin_addr = bind_address;
+    server.sin_port = htons(tcp_wx_port);
+
+    if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+        if (debug_level & 1)
+            fprintf(stderr, "err: %s - no socket", progname);
+        exit(10);
+    }
+    /* <dirkx at covalent.net> / April 2001 Minor change to allow quick
+     * (re)start of deamon or client while there are pending
+     * conncections during the quit. To avoid addresss/port in use
+     * error.  */
+    i = 1;
+    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) == -1) {
+    if (debug_level & 1)
+        fprintf(stderr, "err: %s - setsockopt", progname);
+    }
+    if (bind(s, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1) {
+        if (debug_level & 1)
+            fprintf(stderr, "err: %s - cannot bind to socket", progname);
+        exit(11);
+    }
+    if (listen(s, CONNECTIONS) == -1) {
+        if (debug_level & 1)
+            fprintf(stderr, "err: %s - listen", progname);
+        exit(12);
+    }
+
+    if (debug_level & 1)
+        fprintf(stdout,"Sockets UP.\n");
+
+    umask(0022);
+    for (i = 0; i < CONNECTIONS; i++) fd[i] = -1;
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+
+    if (!not_a_daemon) {			/* setup has worked; now become a daemon? */
+
+        if ((pid = fork()) == -1) {
+            syslog(LOG_ERR, "can't fork() to become daemon: %m"); 
+        exit(20);
+        } 
+        else if (pid)
+            exit (0);
+
+        setsid();
+        for (i = 0; i < NOFILE; i++) if ( i != s) close(i);
+    }
+
+    /* catch signals to close the database connection */
+    signal( SIGTERM, term_handler );/* termination */
+#if defined(SIGPWR) /* SIGPWR is linux centric */
+    signal( SIGPWR, term_handler ); /* power failure */
+#endif
+
+    if (debug_level & 1) fprintf(stdout,"Main Loop...\n");
+    dly_cnt = 1;  //N0VH, change back to 1
+    do {	
+        if(!(dly_cnt--)) {	 
+            dly_cnt = 25;		// Every 'dly_cnt' passes check for WX data update
+            if((dsts = Get_Latest_WX(&winddir,&windspeed,&windgust,
+                                     &temp,&rain1hr,&rain24h,&raintot,
+                                     &humidity,&airpressure,
+                                     &valid_data_flgs,&Metric_Data)) !=0 ) {
+                if ( dsts > 0 ) {
+                    data_len = APRS_str(WX_APRS, winddir,windspeed,windgust,
+                                        temp, rain1hr, rain24h, raintot, 
+                                        humidity, airpressure,
+                                        valid_data_flgs, Metric_Data);
+
+                    if (!data_len) {
+                        if (debug_level & 1)
+                            fprintf(stderr, "err: WX info formatting problem!");                    
+                        exit(13);
+                    }
+                }
+            } 
+            else {
+                exit(dsts);
+            }
+        }
+        FD_ZERO(&rfds);
+        FD_SET(s, &rfds);
+        if (select(s + 1, &rfds, NULL, NULL, &tv) > 0) {
+            for (current = fd; (*current > 0) && (current < fd + CONNECTIONS - 1); current++);
+            if (current > max) max = current;
+            if ((*current = accept(s, (struct sockaddr *)&client, &clen)) != -1)
+                write(*current, WX_APRS, data_len);
+        }
+        if (dly_cnt == 25) {
+            if (debug_level & 1) fprintf(stdout,"Updating clients:");
+            for (current = fd; current <=max; current++)
+            if (*current > 0) {   // active socket
+                if (debug_level & 1) fprintf(stdout," #");
+                signal(SIGPIPE, pipe_handler);
+                write(*current, WX_APRS, data_len);
+        }
+        if (debug_level & 1) fprintf(stdout," done\n");
+    }
+    sleep(1);	 // 	   
+    } while (repetitive);
+
+    mysql_close(&mysql);
+
+    if (debug_level & 1) fprintf(stdout,"Exiting normally.\n");
+    exit(0);
+}
+
diff --git a/LaCrosse/weatherdump.sql b/LaCrosse/weatherdump.sql
new file mode 100644
index 0000000..bce633f
--- /dev/null
+++ b/LaCrosse/weatherdump.sql
@@ -0,0 +1,32 @@
+-- MySQL dump 8.23
+--
+-- Host: localhost    Database: open2300
+---------------------------------------------------------
+-- Server version	3.23.58-log
+
+--
+-- Table structure for table `weather`
+--
+
+CREATE TABLE weather (
+  timestamp bigint(14) NOT NULL default '0',
+  rec_date date NOT NULL default '0000-00-00',
+  rec_time time NOT NULL default '00:00:00',
+  temp_in decimal(4,1) NOT NULL default '0.0',
+  temp_out decimal(4,1) NOT NULL default '0.0',
+  dewpoint decimal(4,1) NOT NULL default '0.0',
+  rel_hum_in tinyint(3) NOT NULL default '0',
+  rel_hum_out tinyint(3) NOT NULL default '0',
+  windspeed decimal(4,1) NOT NULL default '0.0',
+  wind_angle decimal(4,1) NOT NULL default '0.0',
+  wind_direction char(3) NOT NULL default '',
+  wind_chill decimal(4,1) NOT NULL default '0.0',
+  rain_1h decimal(4,2) NOT NULL default '0.00',
+  rain_24h decimal(4,2) NOT NULL default '0.00',
+  rain_total decimal(5,2) NOT NULL default '0.00',
+  rel_pressure decimal(4,2) NOT NULL default '0.00',
+  tendency varchar(7) NOT NULL default '',
+  forecast varchar(6) NOT NULL default '',
+  UNIQUE KEY timestamp (timestamp)
+) TYPE=MyISAM;
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..6b83bc7
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,153 @@
+
+# $Id: Makefile.am,v 1.60 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+AUTOMAKE_OPTIONS = gnu dist-bzip2
+ACLOCAL_AMFLAGS = -I m4
+
+D=      `date +%G%m%d.%H%M%S`
+
+SUBDIRS = src m4 config help scripts symbols callpass
+
+# Remove this file here (it is created via configure), not from within intl.
+# DISTCLEANFILES = intl/libintl.h
+
+EXTRA_DIST = xastir.spec.in xastir.spec xastir-min.spec.in xastir-min.spec config.guess config.sub install-sh \
+        missing mkinstalldirs placeholder FAQ LICENSE README README.CVS \
+        README.CYGWIN README.Getting-Started README.Contributing \
+        README.MAPS README.win32 README.OSM_maps testdbfawk.1 \
+        DEBUG_LEVELS bootstrap.sh INSTALL UPGRADE callpass.1 xastir.1 xastir_udp_client.1 terraserver.geo \
+        terraserver-reflectivity.geo terraserver-urban.geo worldhi.map \
+        terraserver-topo.geo USRadar.geo CanadaTopo250k.geo \
+        CanadaTopo50k.geo TXRadar.geo WMSRadar.geo Davis LaCrosse \
+        OSM_template \
+        CC_OpenStreetMap_logo.png CC_OpenStreetMap_txt.png \
+        COPYING COPYING.LIB.LESSTIF AUTHORS
+
+MAINTAINERCLEANFILES = configure aclocal.m4 Makefile.in Makefile \
+        config.guess config.sub install-sh missing mkinstalldirs \
+        xastir.spec xastir-min.spec
+
+countydir=${pkgdatadir}/Counties
+county_DATA=placeholder
+
+fccdir=${pkgdatadir}/fcc
+fcc_DATA=placeholder
+
+gnisdir=${pkgdatadir}/GNIS
+gnis_DATA=placeholder
+
+mapdir=${pkgdatadir}/maps
+map_DATA=worldhi.map CC_OpenStreetMap_logo.png CC_OpenStreetMap_txt.png
+
+onlinedir=${pkgdatadir}/maps/Online
+online_DATA=terraserver.geo terraserver-topo.geo \
+        terraserver-reflectivity.geo terraserver-urban.geo \
+        USRadar.geo CanadaTopo250k.geo CanadaTopo50k.geo \
+        TXRadar.geo WMSRadar.geo \
+        OSM_cloudmade_1.geo OSM_cloudmade_2.geo \
+        OSM_cloudmade_5.geo OSM_cloudmade_998.geo \
+        OSM_cloudmade_999.geo OSM_tiled_cycle.geo OSM_tiled_mapnik.geo \
+        OSM_tiled_osmarender.geo OSM_tiled_skiing.geo \
+        OSM_tiled_topOSM_0_relief.geo \
+        OSM_tiled_topOSM_1_contour.geo  OSM_tiled_topOSM_2_features.geo
+
+gpsdir=${pkgdatadir}/maps/GPS
+gps_DATA=placeholder
+
+sounddir=${pkgdatadir}/sounds
+sound_DATA=placeholder
+
+docdir=${prefix}/share/doc/xastir
+doc_DATA=AUTHORS FAQ ChangeLog LICENSE README README.CVS README.CYGWIN \
+        README.MAPS README.win32 COPYING INSTALL UPGRADE \
+        README.Getting-Started README.Contributing README.OSM_maps\
+        COPYING.LIB.LESSTIF
+
+# It'd be nice to remove the directory and contents at
+# "${pkgdatadir}/doc" then install a symlink called "doc" there pointing
+# to "${prefix}/share/doc/xastir/".  The new location for the
+# documentation is FHS compliant.
+
+install-exec-hook:
+	-rm -rf $(DESTDIR)${pkgdatadir}/doc
+
+install-data-hook:
+	cd $(DESTDIR)$(mapdir) && \
+	rm -f CC_OpenStreetMap.png && \
+	$(LN_S) CC_OpenStreetMap_logo.png CC_OpenStreetMap.png
+ 
+mandir=${prefix}/share/man
+man_MANS=xastir.1 callpass.1 xastir_udp_client.1 testdbfawk.1
+
+# Tiles from cloudmade require an access code, so use the static map.
+OSM_cloudmade_1.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_1/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_2.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_2/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_5.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_5/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_998.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_998/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_999.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_999/' < $(top_srcdir)/OSM_template >$@
+
+# Use tiles for these maps
+OSM_tiled_cycle.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile.opencyclemap.org/cycle/!' \
+	    -e 's/-STYLE/-cycle/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_mapnik.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile.openstreetmap.org/!' \
+	    -e 's/-STYLE/-mapnik/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_osmarender.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tah.openstreetmap.org/Tiles/tile/!' \
+	    -e 's/-STYLE/-osmarender/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_skiing.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tiles.openpistemap.org/contours/!' \
+	    -e 's/-STYLE/-skiing/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_topOSM_0_relief.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile1.toposm.com/usw/color-relief/!' \
+	    -e 's/-STYLE/-topOSMr/' \
+	    -e 's/#TILE_EXT png/TILE_EXT jpg/' \
+	    -e 's/#ZOOM_LEVEL_MIN 0/ZOOM_LEVEL_MIN 5/' \
+	    -e 's/#ZOOM_LEVEL_MAX 18/ZOOM_LEVEL_MAX 15/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_topOSM_1_contour.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile1.toposm.com/usw/contours/!' \
+	    -e 's/-STYLE/-topOSMc/' \
+	    -e 's/#ZOOM_LEVEL_MIN 0/ZOOM_LEVEL_MIN 5/' \
+	    -e 's/#ZOOM_LEVEL_MAX 18/ZOOM_LEVEL_MAX 15/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_topOSM_2_features.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile1.toposm.com/usw/features/!' \
+	    -e 's/-STYLE/-topOSMf/' \
+	    -e 's/#ZOOM_LEVEL_MIN 0/ZOOM_LEVEL_MIN 5/' \
+	    -e 's/#ZOOM_LEVEL_MAX 18/ZOOM_LEVEL_MAX 15/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+ChangeLog::
+
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..8ce5853
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,1129 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.60 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
+	$(srcdir)/xastir-lsb.spec.in $(srcdir)/xastir-min.spec.in \
+	$(srcdir)/xastir.spec.in $(top_srcdir)/configure ABOUT-NLS \
+	AUTHORS COPYING ChangeLog INSTALL NEWS config.guess config.sub \
+	depcomp install-sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = xastir.spec xastir-min.spec xastir-lsb.spec
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+man1dir = $(mandir)/man1
+am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(countydir)" \
+	"$(DESTDIR)$(docdir)" "$(DESTDIR)$(fccdir)" \
+	"$(DESTDIR)$(gnisdir)" "$(DESTDIR)$(gpsdir)" \
+	"$(DESTDIR)$(mapdir)" "$(DESTDIR)$(onlinedir)" \
+	"$(DESTDIR)$(sounddir)"
+NROFF = nroff
+MANS = $(man_MANS)
+DATA = $(county_DATA) $(doc_DATA) $(fcc_DATA) $(gnis_DATA) $(gps_DATA) \
+	$(map_DATA) $(online_DATA) $(sound_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d "$(distdir)" \
+    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr "$(distdir)"; }; }
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = ${prefix}/share/doc/xastir
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = ${prefix}/share/man
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+AUTOMAKE_OPTIONS = gnu dist-bzip2
+ACLOCAL_AMFLAGS = -I m4
+D = `date +%G%m%d.%H%M%S`
+SUBDIRS = src m4 config help scripts symbols callpass
+
+# Remove this file here (it is created via configure), not from within intl.
+# DISTCLEANFILES = intl/libintl.h
+EXTRA_DIST = xastir.spec.in xastir.spec xastir-min.spec.in xastir-min.spec config.guess config.sub install-sh \
+        missing mkinstalldirs placeholder FAQ LICENSE README README.CVS \
+        README.CYGWIN README.Getting-Started README.Contributing \
+        README.MAPS README.win32 README.OSM_maps testdbfawk.1 \
+        DEBUG_LEVELS bootstrap.sh INSTALL UPGRADE callpass.1 xastir.1 xastir_udp_client.1 terraserver.geo \
+        terraserver-reflectivity.geo terraserver-urban.geo worldhi.map \
+        terraserver-topo.geo USRadar.geo CanadaTopo250k.geo \
+        CanadaTopo50k.geo TXRadar.geo WMSRadar.geo Davis LaCrosse \
+        OSM_template \
+        CC_OpenStreetMap_logo.png CC_OpenStreetMap_txt.png \
+        COPYING COPYING.LIB.LESSTIF AUTHORS
+
+MAINTAINERCLEANFILES = configure aclocal.m4 Makefile.in Makefile \
+        config.guess config.sub install-sh missing mkinstalldirs \
+        xastir.spec xastir-min.spec
+
+countydir = ${pkgdatadir}/Counties
+county_DATA = placeholder
+fccdir = ${pkgdatadir}/fcc
+fcc_DATA = placeholder
+gnisdir = ${pkgdatadir}/GNIS
+gnis_DATA = placeholder
+mapdir = ${pkgdatadir}/maps
+map_DATA = worldhi.map CC_OpenStreetMap_logo.png CC_OpenStreetMap_txt.png
+onlinedir = ${pkgdatadir}/maps/Online
+online_DATA = terraserver.geo terraserver-topo.geo \
+        terraserver-reflectivity.geo terraserver-urban.geo \
+        USRadar.geo CanadaTopo250k.geo CanadaTopo50k.geo \
+        TXRadar.geo WMSRadar.geo \
+        OSM_cloudmade_1.geo OSM_cloudmade_2.geo \
+        OSM_cloudmade_5.geo OSM_cloudmade_998.geo \
+        OSM_cloudmade_999.geo OSM_tiled_cycle.geo OSM_tiled_mapnik.geo \
+        OSM_tiled_osmarender.geo OSM_tiled_skiing.geo \
+        OSM_tiled_topOSM_0_relief.geo \
+        OSM_tiled_topOSM_1_contour.geo  OSM_tiled_topOSM_2_features.geo
+
+gpsdir = ${pkgdatadir}/maps/GPS
+gps_DATA = placeholder
+sounddir = ${pkgdatadir}/sounds
+sound_DATA = placeholder
+doc_DATA = AUTHORS FAQ ChangeLog LICENSE README README.CVS README.CYGWIN \
+        README.MAPS README.win32 COPYING INSTALL UPGRADE \
+        README.Getting-Started README.Contributing README.OSM_maps\
+        COPYING.LIB.LESSTIF
+
+man_MANS = xastir.1 callpass.1 xastir_udp_client.1 testdbfawk.1
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+xastir.spec: $(top_builddir)/config.status $(srcdir)/xastir.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+xastir-min.spec: $(top_builddir)/config.status $(srcdir)/xastir-min.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+xastir-lsb.spec: $(top_builddir)/config.status $(srcdir)/xastir-lsb.spec.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+install-man1: $(man_MANS)
+	@$(NORMAL_INSTALL)
+	test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
+	@list=''; test -n "$(man1dir)" || exit 0; \
+	{ for i in $$list; do echo "$$i"; done; \
+	l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.1[a-z]*$$/p'; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man1:
+	@$(NORMAL_UNINSTALL)
+	@list=''; test -n "$(man1dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+	  sed -n '/\.1[a-z]*$$/p'; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	test -z "$$files" || { \
+	  echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
+	  cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
+install-countyDATA: $(county_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(countydir)" || $(MKDIR_P) "$(DESTDIR)$(countydir)"
+	@list='$(county_DATA)'; test -n "$(countydir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(countydir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(countydir)" || exit $$?; \
+	done
+
+uninstall-countyDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(county_DATA)'; test -n "$(countydir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(countydir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(countydir)" && rm -f $$files
+install-docDATA: $(doc_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)"
+	@list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
+	done
+
+uninstall-docDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(docdir)" && rm -f $$files
+install-fccDATA: $(fcc_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(fccdir)" || $(MKDIR_P) "$(DESTDIR)$(fccdir)"
+	@list='$(fcc_DATA)'; test -n "$(fccdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(fccdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(fccdir)" || exit $$?; \
+	done
+
+uninstall-fccDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(fcc_DATA)'; test -n "$(fccdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(fccdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(fccdir)" && rm -f $$files
+install-gnisDATA: $(gnis_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(gnisdir)" || $(MKDIR_P) "$(DESTDIR)$(gnisdir)"
+	@list='$(gnis_DATA)'; test -n "$(gnisdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(gnisdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(gnisdir)" || exit $$?; \
+	done
+
+uninstall-gnisDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(gnis_DATA)'; test -n "$(gnisdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(gnisdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(gnisdir)" && rm -f $$files
+install-gpsDATA: $(gps_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(gpsdir)" || $(MKDIR_P) "$(DESTDIR)$(gpsdir)"
+	@list='$(gps_DATA)'; test -n "$(gpsdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(gpsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(gpsdir)" || exit $$?; \
+	done
+
+uninstall-gpsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(gps_DATA)'; test -n "$(gpsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(gpsdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(gpsdir)" && rm -f $$files
+install-mapDATA: $(map_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(mapdir)" || $(MKDIR_P) "$(DESTDIR)$(mapdir)"
+	@list='$(map_DATA)'; test -n "$(mapdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(mapdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(mapdir)" || exit $$?; \
+	done
+
+uninstall-mapDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(map_DATA)'; test -n "$(mapdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(mapdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(mapdir)" && rm -f $$files
+install-onlineDATA: $(online_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(onlinedir)" || $(MKDIR_P) "$(DESTDIR)$(onlinedir)"
+	@list='$(online_DATA)'; test -n "$(onlinedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(onlinedir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(onlinedir)" || exit $$?; \
+	done
+
+uninstall-onlineDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(online_DATA)'; test -n "$(onlinedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(onlinedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(onlinedir)" && rm -f $$files
+install-soundDATA: $(sound_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(sounddir)" || $(MKDIR_P) "$(DESTDIR)$(sounddir)"
+	@list='$(sound_DATA)'; test -n "$(sounddir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sounddir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(sounddir)" || exit $$?; \
+	done
+
+uninstall-soundDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(sound_DATA)'; test -n "$(sounddir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(sounddir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(sounddir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@list='$(MANS)'; if test -n "$$list"; then \
+	  list=`for p in $$list; do \
+	    if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	    if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+	  if test -n "$$list" && \
+	    grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+	    echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+	    grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/         /' >&2; \
+	    echo "       to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+	    echo "       typically \`make maintainer-clean' will remove them" >&2; \
+	    exit 1; \
+	  else :; fi; \
+	else :; fi
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-lzma: distdir
+	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+	$(am__remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lzma*) \
+	  lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@$(am__cd) '$(distuninstallcheck_dir)' \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(MANS) $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(countydir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(fccdir)" "$(DESTDIR)$(gnisdir)" "$(DESTDIR)$(gpsdir)" "$(DESTDIR)$(mapdir)" "$(DESTDIR)$(onlinedir)" "$(DESTDIR)$(sounddir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-countyDATA install-docDATA install-fccDATA \
+	install-gnisDATA install-gpsDATA install-man install-mapDATA \
+	install-onlineDATA install-soundDATA
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-countyDATA uninstall-docDATA uninstall-fccDATA \
+	uninstall-gnisDATA uninstall-gpsDATA uninstall-man \
+	uninstall-mapDATA uninstall-onlineDATA uninstall-soundDATA
+
+uninstall-man: uninstall-man1
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+	ctags-recursive install-am install-data-am install-exec-am \
+	install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am am--refresh check check-am clean clean-generic \
+	ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
+	dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
+	distclean distclean-generic distclean-hdr distclean-tags \
+	distcleancheck distdir distuninstallcheck dvi dvi-am html \
+	html-am info info-am install install-am install-countyDATA \
+	install-data install-data-am install-data-hook install-docDATA \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-exec-hook install-fccDATA install-gnisDATA \
+	install-gpsDATA install-html install-html-am install-info \
+	install-info-am install-man install-man1 install-mapDATA \
+	install-onlineDATA install-pdf install-pdf-am install-ps \
+	install-ps-am install-soundDATA install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+	uninstall-countyDATA uninstall-docDATA uninstall-fccDATA \
+	uninstall-gnisDATA uninstall-gpsDATA uninstall-man \
+	uninstall-man1 uninstall-mapDATA uninstall-onlineDATA \
+	uninstall-soundDATA
+
+
+# It'd be nice to remove the directory and contents at
+# "${pkgdatadir}/doc" then install a symlink called "doc" there pointing
+# to "${prefix}/share/doc/xastir/".  The new location for the
+# documentation is FHS compliant.
+
+install-exec-hook:
+	-rm -rf $(DESTDIR)${pkgdatadir}/doc
+
+install-data-hook:
+	cd $(DESTDIR)$(mapdir) && \
+	rm -f CC_OpenStreetMap.png && \
+	$(LN_S) CC_OpenStreetMap_logo.png CC_OpenStreetMap.png
+
+# Tiles from cloudmade require an access code, so use the static map.
+OSM_cloudmade_1.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_1/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_2.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_2/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_5.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_5/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_998.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_998/' -e's/^#OSMSTATICMAP/OSMSTATICMAP/' < $(top_srcdir)/OSM_template >$@
+
+OSM_cloudmade_999.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/-STYLE/-layer=cloudmade_999/' < $(top_srcdir)/OSM_template >$@
+
+# Use tiles for these maps
+OSM_tiled_cycle.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile.opencyclemap.org/cycle/!' \
+	    -e 's/-STYLE/-cycle/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_mapnik.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile.openstreetmap.org/!' \
+	    -e 's/-STYLE/-mapnik/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_osmarender.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tah.openstreetmap.org/Tiles/tile/!' \
+	    -e 's/-STYLE/-osmarender/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_skiing.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tiles.openpistemap.org/contours/!' \
+	    -e 's/-STYLE/-skiing/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_topOSM_0_relief.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile1.toposm.com/usw/color-relief/!' \
+	    -e 's/-STYLE/-topOSMr/' \
+	    -e 's/#TILE_EXT png/TILE_EXT jpg/' \
+	    -e 's/#ZOOM_LEVEL_MIN 0/ZOOM_LEVEL_MIN 5/' \
+	    -e 's/#ZOOM_LEVEL_MAX 18/ZOOM_LEVEL_MAX 15/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_topOSM_1_contour.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile1.toposm.com/usw/contours/!' \
+	    -e 's/-STYLE/-topOSMc/' \
+	    -e 's/#ZOOM_LEVEL_MIN 0/ZOOM_LEVEL_MIN 5/' \
+	    -e 's/#ZOOM_LEVEL_MAX 18/ZOOM_LEVEL_MAX 15/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+OSM_tiled_topOSM_2_features.geo: OSM_template
+	sed -e '/THIS IS A TEMPLATE FILE/d' -e's/^#OSM_TILED_MAP/OSM_TILED_MAP/' \
+	    -e's!^#URL tileURL!URL http://tile1.toposm.com/usw/features/!' \
+	    -e 's/-STYLE/-topOSMf/' \
+	    -e 's/#ZOOM_LEVEL_MIN 0/ZOOM_LEVEL_MIN 5/' \
+	    -e 's/#ZOOM_LEVEL_MAX 18/ZOOM_LEVEL_MAX 15/' \
+	    < $(top_srcdir)/OSM_template >$@
+
+ChangeLog::
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..ec41cdb
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,39 @@
+
+$Id: NEWS,v 1.12 2012/11/01 18:57:18 we7u Exp $
+
+News - Updated 29 April 2001
+  ------------------------------------------------------------------------
+
+Whats new, first read the following documents:
+
+     INSTALL
+     README
+     ChangeLog
+
+All of these documents combined will fill you in on the latest changes to
+xastir in version 0.4.x.
+
+A lot of things have changed in this version so at a minimum read the
+ChangeLog text file. ChangeLog shows whats been added and fixed along the
+way.
+
+This version includes a "first try" at using the GNU Autotools for
+configuration.  These scripts have not been throughly tested on all
+platforms.  Any feedback is actively solicited.
+
+This version also includes several additional directories added in
+preparation for the implementation of GNU internationalization
+routines.
+
+
+CAUTION:
+
+     1. Before you start Xastir for the first time BACKUP your
+     data files if this is an upgrade from a previous version.
+
+     2. DON'T USE YOUR OLD CONFIG FILE.. MAKE A NEW ONE.........
+
+
+
+Copyright (C) 2000-2012  The Xastir Group
+
diff --git a/OSM_template b/OSM_template
new file mode 100644
index 0000000..d86ee49
--- /dev/null
+++ b/OSM_template
@@ -0,0 +1,52 @@
+#
+# $Id: OSM_template,v 1.3 2010/08/14 21:32:43 jedunmire Exp $
+#
+# THIS IS A TEMPLATE FILE
+#
+# Map data Copyright OpenStreetMap Contributors, CC-BY-SA
+# See www.openstreetmap.org and http://creativecommons.org/licenses/by-sa/2.0/
+#
+# The string following OSMSTATICMAP-, is appended to the URL
+# The string is typically expected to select a layer, and possibly style
+# options. If not set it defaults to:
+#   layer=osmarander
+#
+# The string following OSM_TILED_MAP-, is the name of a sub-directory in
+# the tile cache. It can be empty (delete the '-' too), though that is a
+# bad idea if multiple map styles are using the same TILE_DIR.
+#
+# Select only one of the two map types: OSMSTATICMAP or OSM_TILED_MAP
+#
+#
+#OSMSTATICMAP-STYLE
+#  or
+#OSM_TILED_MAP-STYLE
+#
+# The url for tiled maps defaults to http://tile.openstreetmap.org/. For
+# static maps it defaults to http://ojw.dev.openstreetmap.org/StaticMap/
+#URL tileURL
+
+# Tile extension defaults to png
+#TILE_EXT png
+
+#ZOOM_LEVEL_MIN 0
+#ZOOM_LEVEL_MAX 18
+
+# The tile cache can be changed from the default (~/.xastir/OSMtiles) by
+# setting the following variable. If path does not begin with a '/' then
+# it will be relative to ~/.xastir/.
+#
+#TILE_DIR OSMtiles
+
+
+# When defined:
+# OSM_OPTIMIZE_KEY will change the map scaling to the nearest OSM zoom level.
+# OSM_REPORT_SCALE_KEY will report the present, scale_x, scale_y,
+#   and OSM zoom level, but only for debug level 512 (-v 512)
+#
+# The values are X KeySym values.
+# 65473 = F4
+# 65474 = F5
+OSM_OPTIMIZE_KEY 65473
+OSM_REPORT_SCALE_KEY 65474
+
diff --git a/README b/README
new file mode 100644
index 0000000..0ac951c
--- /dev/null
+++ b/README
@@ -0,0 +1,629 @@
+
+$Id: README,v 1.41 2012/11/01 18:57:18 we7u Exp $
+
+README
+  ------------------------------------------------------------------------
+
+     Please at least SKIM this document before asking questions. In fact,
+     READ IT if you've never successfully set up Xastir before. PLEASE!
+     READ IT! If you haven't read this file, and ask for help
+     expect to be told to READ the README file first! or RTFM :)
+
+     Contents
+
+     0    Important notice
+     1    What is Xastir?
+     2    How do I get Xastir
+     2a   CVS usage
+     3    Quick startup
+     4    Upgrading
+     5    Identification notes
+     6    OS-specific notes
+     7    Gating weather alerts
+     8    Boring legal stuff
+     9    Mailing list
+    10    Documentation
+    11    Obtaining help
+
+  ------------------------------------------------------------------------
+
+     (0) NOTICE
+
+          Please read this file carefully before trying to set up Xastir.
+          This software was developed to be used by licensed amateur radio
+          operators.  You are responsible for any information transmitted
+          or propagated on any network.
+
+     (1) WHAT IS XASTIR?
+
+          Xastir is an open-source project to create a free X11 graphical
+          APRS(tm) client. APRS(tm) use amateur radio and Internet services to
+          convey GPS mapping, weather, and positional data in a graphical
+          application.  It has been developed by and for amateur radio
+          enthusiasts to provide real-time data in an easy to use package.
+
+          Xastir currently runs under several flavors of Linux and BSD Unix.
+          A few people are running Xastir on Solaris Unix, FreeBSD, Lindows
+          and Mac OS X, but there may be small changes necessary in order to
+          get Xastir to configure/compile on some systems.  There are a few
+          notes below which may help in this task.  Most of the developers use
+          Linux which makes it the best supported platform at the moment.
+
+          Xastir is an open-source project: Most sources, documentation, and
+          binaries are available under the GPL license, with a few modules
+          available under other open-source or public domain licenses.
+
+          More information on Xastir can be found at:
+
+            http://www.xastir.org
+            http://xastir.sourceforge.net
+            http://sourceforge.net/projects/xastir/
+
+          including the latest releases, the anonymous CVS access (lets you
+          download the latest developers' code), and information on how to join
+          Xastir mailing lists.  Note that you must be subscribed in order to
+          post to the mailing lists.
+
+          SmartBeaconing(tm) was invented by Tony Arnerich (KD7TA) and Steve
+          Bragg (KA9MVA) for the HamHUD project.  They offer the algorithm to
+          other authors as long as proper credit is given and the term
+          SmartBeaconing(tm) is used.  Thanks to Tony and Steve for that
+          contribution!
+
+             -- The Xastir Group.
+
+     (2) HOW TO GET XASTIR
+
+          Xastir is currently developed at
+          <http://sourceforge.net/projects/xastir/>
+          You can get the latest version of Xastir from there.
+
+          You might try www.xastir.org for help and information.
+          The web site is:
+          <http://xastir.sourceforge.net>.
+
+
+     (2a) CVS USAGE
+
+          You might obtain the *very latest* version of Xastir that
+          is still under development by using CVS. 
+          
+          See the file README.CVS for more details.
+
+     (3) QUICK STARTUP
+
+           INCLUDED IN 'INSTALL'
+           WINDOWS USERS:  Please refer to the "README.win32" file for specific
+           instructions.
+
+     (4) UPGRADING
+
+           INCLUDED IN 'UPGRADE'
+
+     (5) IDENTIFICATION NOTES
+          Packet radio modes, by their very nature, typically identify
+          themselves with every transmission. Xastir has a few features
+          targeted to people who used Xastir in demonstrations and other
+          broadcasts where Xastir itself is used over radio.
+
+          Xastir can auto-ID via voice if Festival is compiled in and/or via a
+          message splashed across the screen. It does this identification
+          every 9.5 minutes if enabled. These identification modes were
+          designed for broadcasting Xastir across fast-scan television (for
+          events perhaps). Set the "ATV_SCREEN_ID" variable to 1 to enable the
+          screen message, and "SPEAK_ID" variable to 1 to enable festival to
+          speak the message. These variables are in the
+          ~/.xastir/config/xastir.cnf file.
+
+
+     (6) OS SPECIFIC NOTES
+      ----------------------------------------------------------------------
+      MAC OSX NOTES:
+
+     No changes necessary now for Mac OS X!
+
+     If you intend to run with GDAL installed, you may find that geotiff
+     projection doesn't work. To avoid this, install libtiff, libproj,
+     and libgeotiff first, then configure GDAL with 
+     --with-libtiff=/path/to/libtiff --with-geotiff=/path/to/geotiff
+     It's important to not choose "yes" or "internal". You may also want
+     --with-libz=yes
+
+     If you have trouble building GDAL you may need this patch:
+     --- GDALmake.opt.in     7 Jan 2004 20:52:29 -0000       1.130
+     +++ GDALmake.opt.in     30 Jan 2004 22:08:58 -0000
+     @@ -78,8 +78,8 @@
+      endif
+ 
+      CPPFLAGS       = @CPPFLAGS@ -I$(GDAL_ROOT)/port
+     -CFLAGS         = @C_WFLAGS@ @C_PIC@ $(C_ODFLAGS) @EXTRA_INCLUDES@ $(USER_DEFS)
+     -CXXFLAGS       = @CXX_WFLAGS@ @CXX_PIC@ $(CXX_ODFLAGS) \
+     +CFLAGS         = @C_WFLAGS@ @C_PIC@ $(GDAL_INCLUDE) $(C_ODFLAGS) @EXTRA_INCLUDES@ $(USER_DEFS)
+     +CXXFLAGS       = @CXX_WFLAGS@ @CXX_PIC@ $(GDAL_INCLUDE) $(CXX_ODFLAGS) \
+                       @EXTRA_INCLUDES@ $(USER_DEFS)
+ 
+      RANLIB         =       @RANLIB@
+
+
+     You may want to install everything to /sw though, so that the normal
+     user can find it easily and add maps.  To do this, run this instead:
+
+        ./configure --prefix=/sw
+
+     That will cause Xastir to be installed in /sw/xastir/* directories, and
+     the executable will go into /sw/bin/xastir.
+
+     Ports have been contributed to DarwinPorts. This will be updated with
+     instructions when those are committed.
+
+     Here's a web page which has specific instructions for installing on OSX,
+     including a binary version of Xastir (no compiling necessary):
+
+          http://n1ofz.connares.org/software/Xastir
+
+       END OF MAC OSX NOTES.
+     -----------------------------------------------------------------------
+
+
+     -----------------------------------------------------------------------
+       FreeBSD NOTES:
+
+     There are both a binary package and a port available as part of the
+     official FreeBSD ports system.  Most FreeBSD users can either type
+     "pkg_add -r xastir" which will fetch the relevant binary for their
+     release, or preferably update their ports tree and use the port to get
+     the latest version.
+
+     Other options:
+
+     The FreeBSD port of xastir uses a development snapshot, and not
+     necessarily the latest snapshot, depending on how busy the port
+     maintainer is.  If you wish to be on the bleeding edge you can build
+     xastir yourself from the latest development snapshot or from CVS,
+     without much more difficulty than Linux users have.  There are a few
+     caveats, though.
+
+     The version of autoconf used to generate configuration files for
+     Xastir is 2.57 or later.  If you have autoconf 2.13 installed,
+     there will be difficulties if you try to run "bootstrap.sh."  It
+     is best to install recent, matching versions of autoconf and automake
+     directly from sources into a separate binary directory other than
+     /usr/local/bin, without relying on the FreeBSD ports system.  The 
+     ports system installs autoconf and automake with odd suffixes that
+     can interfere with the xastir build process.
+
+     Contact Jack Twilley <jmt at twilley.org> or Tom Russo <russo at bogodyn.org> 
+     for more help in getting Xastir configured and built under FreeBSD.
+
+       END OF FreeBSD NOTES.
+     -----------------------------------------------------------------------
+
+
+     -----------------------------------------------------------------------
+       SOLARIS NOTES:
+
+     Changes required for Solaris 2.5 -> 7.0.  Other versions may require
+     slightly different changes.
+
+     After running "configure", edit src/Makefile and make these changes:
+
+       Solaris 2.5 -> 2.6:
+         NOTE: Solaris 2.5 -> 2.6 do not install Xpm.  If you've installed it
+         you'll need to delete "-DNO_XPM" from src/Makefile, make sure the
+         headers are in the search path, and add "-lXpm" to the LIBS or
+         LDFLAGS line in src/Makefile.
+
+       Solaris 7.0 notes from Chris Bell:
+       ----------------------------------
+         Date: Fri, 11 Jan 2002 16:38:57 -0800
+         From: Chris Bell <cbell at junknet.com>
+         To: "Curt Mills, WE7U" <hacker at tc.fluke.com>
+         Cc: xastir-dev
+         Subject: Re: [Xastir-Dev] Autoconf fixes for various OS's 
+
+         YAY!!! Xpm is properly detected for solaris7!!!!  On my system, (with
+         geotiff and ImageMagick) I still have to tweak the geotiff detection
+         to avoid the system libtiff: 
+
+         ===================================================================
+         RCS file: /usr/local/cvs/xastir/configure,v
+         retrieving revision 1.51
+         diff -c -r1.51 configure
+         *** configure   2002/01/11 21:33:54     1.51
+         --- configure   2002/01/12 00:28:01
+         ***************
+         *** 4986,4992 ****
+             echo $ac_n "(cached) $ac_c" 1>&6
+           else
+             ac_save_LIBS="$LIBS"
+         ! LIBS="-lgeotiff  $LIBS"
+           cat > conftest.$ac_ext <<EOF
+           #line 4992 "configure"
+           #include "confdefs.h"
+         --- 4986,4992 ----
+             echo $ac_n "(cached) $ac_c" 1>&6
+           else
+             ac_save_LIBS="$LIBS"
+         ! LIBS="-L/usr/local/lib -R/usr/local/lib -lgeotiff -ltiff $LIBS"
+           cat > conftest.$ac_ext <<EOF
+           #line 4992 "configure"
+           #include "confdefs.h"
+ 
+         Also, the generated Makefile needs the -L/usr/local/lib
+         -R/usr/local/lib added, and -lposix4 added to the link lib line.
+ 
+         It is compiling now, I will let you know if there are any runtime
+         problems.  
+ 
+         I also installed the latest patches for the OS... the latest
+         Openwindows patch finally fixes the X header warnings, so we don't
+         have to fear turning -Wall back on.  (patch # 108376-33) Probably a
+         good tidbit for the README...
+ 
+         I am trying to get enough parts to build more systems for testing
+         solaris 8.   I tried it on my brother's system over the holidays, and
+         it worked just like 7.  
+       -----------------------------------------------------------------------
+
+     Note that Solaris 2.5 doesn't have support for snprintf().  The code
+     has been tweaked to switch to sprintf() for these calls in this case,
+     which allows more places for buffer overflow problems (this is a
+     security issue as well as a stability issue).  Solaris 2.6 and later
+     has support for snprintf().
+
+     Solaris 7.0 has Xpm support built into Motif, so you'll be able to
+     use Xpm map files within Xastir.
+
+     You need BSD-make installed on your system in order to compile Xastir.
+     Type "gmake" instead of "make" to build Xastir, and substitute "gmake"
+     for "make" in the following instructions.
+
+     ---
+     From: Chris Bell
+
+     A note to add, the auto* tools from sunfreeware (precompiled packages)
+     need the environment variable M4 set to gnu m4 (M4=/usr/local/bin/m4)
+     to work.  I also set LDFLAGS to '-L/usr/local/lib -R/usr/local/lib' (to
+     avoid the ancient libtiff in /usr/openwin/lib) before running configure,
+     then the tests (and final link) work properly.
+
+     Chris.
+
+     ---
+     Solaris 9/AEA PK232MBX notes from Alan Shackelford:
+
+     Thanks to the advice of several of you both on the list and in private 
+     email, the NG3B Xastir install is up and running. For future reference, 
+     here are the steps I took, based on your advice combined with my 
+     knowledge of Solaris and the AEA PK232MBX.
+
+     First, use admintool to set up the serial port at 8N1 9600.
+
+     Have a look at the /etc/uucp/Devices file and ensure you have the 
+     following in there someplace (like at the very bottom):
+
+        ACU cua/b - Any hayes
+        Direct cua/b - Any direct
+
+
+     Then use 'cu' (solaris-ese for call unix) to send a '*' to the TNC.
+     You will receive a response from the TNC with copyright info, etc.
+
+     Close the 'cu' session and start Xastir from a terminal window.
+
+     Set the Interface to 9600 8N1 in the configuration screen. Start the 
+     interface using the Interface Start/Stop window. The data will begin to
+     flow.
+
+     Alan NG3B
+     ---
+
+
+        END OF SOLARIS NOTES.
+      ----------------------------------------------------------------------- 
+
+
+      -----------------------------------------------------------------------
+        MANDRAKE LINUX NOTES:
+
+      With Mandrake Linux 8.x? you may get linker errors when it tries to
+      link in the "Xp" library.  To fix this, edit xastir/src/Makefile,
+      adding "-lXp" to the LIBS line, then type "make" again.
+
+        END OF MANDRAKE LINUX NOTES.
+      -----------------------------------------------------------------------
+
+
+      -----------------------------------------------------------------------
+        OpenSuSE LINUX 10.0/10.1 NOTES:
+
+        Bring up YaST2 and add more download sites via:
+
+            Software->Installation Source
+
+        For OpenSuSE 10.0:
+
+        ftp://suse.mirrors.tds.net/pub/opensuse/distribution/SL-10.0-OSS/inst-source/suse
+        ftp://ftp.suse.com/pub/projects/ham/10.0-i386
+
+        For OpenSuSE 10.1:
+
+        ftp://suse.mirrors.tds.net/pub/opensuse/distribution/SL-10.1/inst-source/suse
+        http://dg7gt.osth.de/suse-10.1-ham/
+
+        For OpenSuSE 11.x (Use the one that matches your installation):
+
+        http://download.opensuse.org/repositories/hamradio/openSUSE_11.0/
+        http://download.opensuse.org/repositories/hamradio/openSUSE_11.1/
+        http://download.opensuse.org/repositories/hamradio/openSUSE_11.2/
+        http://download.opensuse.org/repositories/hamradio/openSUSE_11.3/
+
+        Adding these sites will allow you to find and install the ax25
+        libraries/devel headers, the OpenMotif development headers, and the
+        libcurl headers.
+
+        You'll see this warning if you run ./bootstrap.sh:
+
+            4... Running aclocal
+            /usr/share/aclocal/pstoedit.m4:7: warning: underquoted definition of
+            AM_PATH_PSTOEDIT
+              run info '(automake)Extending aclocal'
+              or see
+            http://sources.redhat.com/automake/automake.html#Extending-aclocal
+
+        You may safely ignore this warning.
+
+        I've found that I need to do this when configuring for OpenSUSE in
+        order to pick up the libgeotiff include files:
+
+            ./configure CPPFLAGS="-I/usr/include/libgeotiff"
+
+        I just put it into a script called "configure.suse" so that I don't
+        have to remember it each time.  Here are the complete contents of
+        the script:
+
+            #!/bin/sh
+            ./configure CPPFLAGS="-I/usr/include/libgeotiff"
+
+        then do "chmod 755 configure.suse", and run it like this:
+
+            ./configure.suse
+
+        You'll may also see these when compiling the code:
+
+        map_tif.c: In function `my_GTIFProj4FromLatLong':
+        map_tif.c:391: warning: implicit declaration of function `CSLTokenizeStringComplex'
+        map_tif.c:391: warning: assignment makes pointer from integer without a cast
+        map_tif.c:394: warning: implicit declaration of function `CSLCount'
+        map_tif.c:396: warning: implicit declaration of function `CSLDestroy'
+        x_spider.c: In function `UDP_Server':
+        x_spider.c:1203: warning: pointer targets in passing argument 6 of `recvfrom' differ in signedness
+
+        You may safely ignore them as well.
+
+        Optional but highly recommended:  Install the colorgcc package, then go
+        into /usr/share/doc/packages/colorgcc and "cp colorgccrc ~/.colorgccrc"
+        This will cause any GCC warnings or errors to show up in a different
+        color in your Xterm window.  VERY handy.
+
+        Please note that the AX.25 kernel support in SuSE 10.0 doesn't work.
+        There are patches being discussed on the linux-hams list, but these
+        patches are not currently part of SuSE.  Use the Serial KISS TNC
+        interface in Xastir instead if you're using a KISS TNC with this
+        version of SuSE.
+
+        Note that you may see this warning when running bootstrap.sh:
+            "warning: underquoted definition of AM_PATH_PSTOEDIT"
+        but it is totally harmless.  It bothered me enough during my software
+        development that I figured out how to get rid of it, but please note
+        that the following step is totally unnecessary:  Remove the "pstoedit"
+        and "pstoedit-devel" packages plus packages that depend on them, like
+        inkscape.  Remove via YaST2 or by typing:
+            "rpm -e pstoedit pstoedit-devel inkscape" as root.
+
+        END OF OpenSuSE LINUX 10.0 NOTES.
+      -----------------------------------------------------------------------
+
+
+      -----------------------------------------------------------------------
+        HP/UX NOTES:
+
+      - Installed various needed packages and libraries downloaded from:
+
+      http://hpux.cs.utah.edu/
+
+      I'm not sure all of the following are needed, and, this leaves out a few
+      like ImageMagick, but here's a list of the HPUX depot files I've
+      collected:
+
+        X11R6incs-4.3.0-sd-11.11.depot
+        XR6built-6.11-sd-9.03.tar
+        autoconf-2.59-sd-11.11.depot
+        automake-1.9-sd-11.11.depot
+        bash-3.0-sd-11.00.depot
+        bison-1.875-sd-11.11.depot
+        cvs-1.11.17-sd-11.11.depot
+        db-4.2.52-sd-11.11.depot
+        flex-2.5.4a-sd-11.11.depot
+        gawk-3.1.4-sd-11.11.depot
+        lesstif-0.93.94-sd-11.11.depot
+        libiconv-1.9.2-sd-11.11.depot
+        lsof-4.72-sd-11.11.depot
+        m4-1.4.2-sd-11.11.depot
+        make-3.80-sd-11.11.depot
+        perl-5.8.5-sd-11.11.depot
+        sudo-1.6.7p5-sd-11.00.depot
+        tusc-7.7-sd-11.11.depot
+        wget-1.9.1-sd-11.11.depot
+
+      - Installed HP's version of binutils and gcc off of:
+
+      http://h21007.www2.hp.com/dspp/tech/tech_TechDocumentDetailPage_IDX/1,1701,4682,00.html
+
+        binutils_2.15a_hppa-hp-hpux11.11_depot
+        gcc_3.4.2_hppa-hp-hpux11.11_depot
+
+      HPUX 11.11 doesn't seem to have seteuid and setegid calls so:
+
+      - Installed and linked against HP's Linux libraries:
+
+      http://devrsrc1.external.hp.com/LPK/
+
+      - Changed a couple #include <strings.h>  to:
+
+        #ifdef HAVE_STRING_H
+        #  include <string.h>
+        #else
+        #  include <strings.h>
+        #endif
+
+      - added  #include <sys/modem.h> to interface.h
+
+
+      Current status:  It runs, but it seg-faults when connected to an APRS(tm)
+      IS server.
+
+        END OF HP/UX NOTES.
+      -----------------------------------------------------------------------
+
+
+
+     (7) GATING WEATHER ALERTS, STATIONS, OBJECTS/ITEMS TO RF
+
+      Gating NWS Weather Alerts to RF:
+      --------------------------------
+      If you wish to gate NWS weather alerts from the Internet onto RF, you'll
+      need to create a text file in the users directory as 
+      ~/.xastir/data/nws-stations.txt
+      List each NWS station that you would like to transmit via RF. Wildcards
+      are implied for lengths of 3 or greater. Here's what an example file
+      looks like:
+
+      ------------- Cut Here -------------
+      #
+      # Seattle, WA
+      SEANPW
+      #
+      # Portland, OR (any alert type)
+      PDX
+      #
+      # Pendleton, OR
+      PDTNPW
+      #
+      # Medford, OR
+      MFRNPW
+      #
+      ------------- Cut Here -------------
+
+      All text should start at the beginning of the line.
+
+      Once that file is in place, you'll need to hook up to at least one
+      Internet server that is feeding you the weather alerts. You'll also need
+      to have at least one RF interface up and running with transmit enabled on
+      that interface. Make sure that "Interfaces->Disable Transmit: All" is not
+      selected.  You should now be gating NWS weather messages to RF.
+
+      Turn on igate logging and look at that log file to view what you're
+      sending out via RF. Don't forget to turn off logging or set up
+      auto-rollover of the log files, else your hard drive might fill up with
+      logging info. Auto-rollover of log files is typically accomplished via
+      CRON.
+
+      Gating Stations, Objects/Items to RF:
+      -------------------------------------
+      The latest code also allows gating packets from specific stations to RF
+      using the above method (except object/item packets).  You can also gate
+      objects/items to RF by name.  The same wildcarding rules apply as listed
+      above.  Callsigns or object/item names listed in this file are
+      case-insensitive, so they'll match any case in received packets.
+
+      Bob Bruninga, WB4APR, recommends gating these calls to RF:
+        
+        SCOUTS, SATERN, KIDS, REDCROSS, FOUR-H, YOUTH, GUARD, MARS, JOTA
+
+      See his link: "Generic Callsigns for National Events" off this web page
+      for his current list of recommended callsigns:
+
+        http://www.ew.usna.edu/~bruninga/aprs.html
+
+
+     (8) BORING LEGAL STUFF
+
+          Xastir is Copyright � by Frank Giannandrea. Xastir is
+          distributed according to the GNU General Public
+          License. There should be a copy of this license in the
+          file COPYING. If not, write to the Free Software
+          Foundation, Inc., 675 Mass Ave, Cambridge, MA
+          02139, USA.
+
+          As of Xastir 0.4.0 all changes made by the Xastir
+          development team to the Xastir source code and any related
+          files are Copyright � 2001-2012 by The Xastir Group. The source
+          code will still be distributed according to the GNU General
+          Public License as Frank Giannandrea did in the past.
+
+          There is no warranty, implied or whatever. You use this
+          software at your own risk, no matter what purpose you put
+          it to.
+
+          You didn't pay for it, so don't expect magic.
+
+
+     (9) MAILING LIST
+
+          There are currently a couple of mailing lists about Xastir.
+          xastir at xastir.org is the one relevant for posts about
+          Xastir 0.4.0 and up (and bug fixes, and suggestions, etc).
+          You must be subscribed to the list in order to post messages.
+
+          To subscribe to the Xastir mailing list, send email to:
+          xastir-request at xastir.org In the body of the message,
+          put "subscribe xastir"; or go to
+          http://www.xastir.org and click on "User List" or
+          "Developer List" links on the left to subscribe.
+
+               ### DO NOT SEND FRANK EMAIL ABOUT XASTIR ###
+
+          Frank is no longer developing the Xastir code (although
+          he does put a word in every now and then) so don't bother
+          e-mailing him. If you have a serious problem, email the
+          Xastir mailing list and it will get to the coders.
+
+          Please, before posting to this list, see what things are
+          like, and when you do post, read over your post for
+          readability, spelling, and grammar mistakes. Obviously,
+          we're all human (or are we?) and we all make mistakes (heck,
+          look at this document! ;).
+
+          Open discussion and debate is integral to change and
+          progress. Don't flame others over mere form (grammar and
+          spelling), or even substantive issues either for that
+          matter. Please read and follow the mailing list rules.
+
+          The xastir at xastir.org mail-list is dedicated to Bug
+          reports, technical questions, your thoughts or
+          suggestions on new features being added to Xastir, things
+          that should be removed or fixed, amazing problems that even
+          stump the guru's, etc... are what we want to see here.  You
+          must be subscribed to the list in order to post messages.
+
+     (10) DOCUMENTATION
+
+          We're trying to keep the documentation up to date. If you
+          feel that anything is missing here, or that anything should
+          be added etc, please email xastir at xastir.org about it,
+          thank you.
+
+     (11) OBTAINING HELP
+
+          Please read the file FAQ, and make sure you've followed any relevant
+          instructions in INSTALL. If the problem still exists, feel free to
+          ask on the Xastir mailing-list, as described above.
+
+
+  ------------------------------------------------------------------------
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 1999 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
diff --git a/README.CVS b/README.CVS
new file mode 100644
index 0000000..6cc6359
--- /dev/null
+++ b/README.CVS
@@ -0,0 +1,414 @@
+
+$Id: README.CVS,v 1.29 2012/11/16 03:22:40 we7u Exp $
+
+
+CVS Instructions:
+-----------------
+     For those who think CVS might be a bit too complicated to deal with,
+     here are (I think) the minimal commands.  See the "SUDO" section
+     below though for ideas on how to make updating Xastir even simpler.
+
+     Initial CVS Checkout:
+     ---------------------
+     1) Create a ".cvsrc" file in your home directory containing the
+        following lines.  Use whatever Unix-type editor you're
+        comfortable with.  Choices might be pico, vi, emacs, others:
+
+         ##cvs -z3
+         update -P -d
+         status -v
+         diff -u
+
+        These are just some of the CVS options that I prefer, and make some
+        things easier.  They are not required.
+
+        The "cvs -z3" option isn't accepted by SourceForge currently.  Comment
+        it out by adding a couple of '#' marks in front of the line.  You can
+        test it at a later date by removing the '#' marks and trying a cvs
+        command.
+
+     2) Start up a shell window of some type, perhaps an xterm or an rxvt.
+        Type the following commands into this one shell.  You'll be setting
+        an environment variable which will then allow you check out the full
+        sources for the first time.  After that, the environment variable
+        won't be needed anymore and all shells you use will be able to
+        work with the remote CVS repository.  The checked-out sources contain
+        administration info which the CVS commands use to know which remote
+        server to talk to, and which account/encrypted password to use from
+        your ~/.cvspass file.
+
+     3) Follow the instructions listed under "Anonymous CVS Access".  Go to:
+        <http://sourceforge.net/projects/xastir/>, then click on "CVS" to
+        find the instructions.
+
+        For those that are Internet-challenged, here are the two commands,
+        customized for the Xastir project:
+
+          cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir login
+
+        Press the <ENTER> key when it asks you for a password.  That creates
+        a ".cvspass" file in your home directory with the anonymous login
+        information inside it.
+
+          cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co xastir
+
+        That creates a subdirectory called "xastir" that has all the latest
+        sources in it.
+
+     You may want to use this instead, to get the sources corresponding to the
+     latest release:
+
+       cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co -r RELEASE xastir
+
+     or use this line to get the latest version deemed "stable" by the developers
+     (generally newer than the RELEASE version):
+
+       cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co -r STABLE xastir
+
+     All done!  You now have the latest development sources on your computer.
+     Now you can forget about all of the previous instructions unless you
+     delete the entire tree and want to start over from scratch.
+
+     Note that if you choose the "RELEASE" or "STABLE" tags, those tags will
+     become sticky, so that "cvs update" commands will update to the latest
+     versions of files containing those tags.  If you wish to remove this
+     sticky option so that you can synchronize to a different tag or the latest
+     developer's CVS, see the "cvs update -A" command below.
+
+
+     CVS Commands for Maintaining the Current Development Sources:
+     -------------------------------------------------------------
+     Once all this is in place, just cd into the "xastir" directory at any
+     time, type "cvs update", then type "make install" and you'll have the
+     latest development stuff installed on your system.
+
+     Here are the commands to do if you want a clean build of the latest
+     sources, and want configure to recheck all the libraries and header
+     files that Xastir needs:
+
+         cd xastir
+         cvs update (snag all the latest changes)
+         ./bootstrap.sh
+         ./configure
+         (make clean;make -j3 2>&1) | tee make.log
+         su
+         make install (make install-strip can be used after the first time,
+                       it removes debugging info from executable)
+         chmod 4555 /usr/local/bin/xastir (only needed if using kernel AX.25)
+         exit (from root)
+         xastir
+
+     Note that you'll need autoconf 2.53 or newer and automake 1.6.3 or newer
+     in order to run the "./bootstrap.sh" script.
+
+     For the "cvs update" line, you can also choose which version to update to,
+     just like the "cvs co" lines shown above:
+
+       cvs update -r RELEASE
+     or
+       cvs update -r STABLE
+
+     Once you specify a revision tag (RELEASE or STABLE), that option becomes
+     "sticky" for future checkouts and updates.  That means you only need to
+     type "cvs update" in order to update your code to the latest sources
+     containing that tag.
+
+       cvs update -A
+
+     will make the cvs update command track to the most recently submitted
+     versions again (will make the RELEASE or STABLE options un-sticky).  To
+     review:
+
+       cvs update -A            # To get to developers sources.
+       cvs update -r STABLE     # To get to latest stable sources.
+       cvs update -r RELEASE    # To get to latest released sources.
+
+
+     Even more CVS commands (most people won't need these):
+     ------------------------------------------------------
+     I use these aliases the most (defined in my bash shell startup files):
+
+       alias cvsdiff='cvs diff -w -r HEAD'
+       alias cvsstat2='cvs -n -q update'
+       alias cvsstat3='(cvs status 2>&1) | grep -E "Status: | Examining" | grep -v Up-to-date | grep -v Makefile.in'
+
+     to see if anything has changed.  cvsstat3 is the most useful one
+     for me as a developer.  If anything has, I can use this alias to
+     see the details on a particular file:
+
+         alias cvsdiff='cvs diff -w -r HEAD'
+
+     As in:
+
+         cvsdiff main.c
+
+         -or- (not using the alias)
+
+         cvs diff -w -r HEAD main.c
+
+     Then perhaps do an update on that file alone:
+
+         cvs update main.c
+
+
+    Checking out a branch (for anonymous-CVS users):
+    ------------------------------------------------
+
+        Go to a new directory structure (not CVS controlled) and type this:
+
+            export CVS_RSH=ssh
+            mkdir <branchname>
+            cd <branchname>
+            cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir login
+
+        Press the <ENTER> key when it asks for your password, then:
+
+            cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co -r BRANCH_<branchname> xastir
+
+        The above command will create a directory "xastir" in the <branchname>
+        directory containing the latest sources from that branch.
+
+        A complete example (Using an imaginary branch "xastir99"):
+
+            export CVS_RSH=ssh
+            cd ~/src
+            mkdir xastir99
+            cd xastir99
+            cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir login
+            Hit <ENTER> when asked for passwd.
+            cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co -r BRANCH_xastir99 xastir
+
+        will fetch the BRANCH_xastir99 code branch and deposit it into:
+
+            /home/<user>/src/xastir99/xastir/
+
+
+    There are many more CVS commands and options.  Many of them are more of
+    use to the developers.  Some of those are listed below.  The above should
+    be enough for most people to keep their copies in sync with the latest CVS
+    development sources.
+
+
+SUDO Instructions:
+------------------
+
+    "sudo" is a command that can make your life much simpler.  After you set
+    it up that is!  By adding a couple of lines to your /etc/sudoers file
+    (using the "visudo" command to edit this file), you'll be able to run a few
+    commands as root without having to type the root password each time.
+    Another thing you can do at that point is automate the entire
+    "cvs update;./configure;su;make install" process via a script.  Here's how
+    to set all of this up:
+
+    Type "su" to become the root user, then type "visudo".  This will bring up
+    the "vi" editor on the /etc/sudoers file.  If you'd like to learn more
+    about what I'm going to describe, type "man sudoers" in another window and
+    read about this file.  Another man-page that is useful here is the "man
+    sudo" page.
+
+    Back to the editing:  There's a section in there for user alias.  Mine is
+    labeled "# User alias specification".  Add a line there that reads like
+    this:
+
+        User_Alias XASTIR = username1, username2, username3
+
+    where username1, etc, are valid usernames that you wish to be able to do
+    Xastir installs.  For instance you might have:
+
+        User_Alias XASTIR = mikey
+
+    Next, add a line near the bottom that reads like this:
+
+        XASTIR ALL = NOPASSWD: /bin/chmod, /usr/bin/make
+
+    Now write out and close the file.  At this point the "mikey" user will have
+    root permissions when he/she runs the commands "/bin/chmod" or
+    "/usr/bin/make".  Make sure the paths to those programs are correct for
+    your system.
+
+    Exit from "su" so that you're a regular (non-root) user again.
+
+    Now, in the "xastir" source directory (mine is in "~/src/xastir"), create a
+    script that reads like this.  I named my script  "update-xastir" but nearly
+    any name for the script will do:
+ 
+    -----------------cut here--------------------
+        #! /bin/sh
+
+        cvs update
+        ./bootstrap.sh
+        ./configure
+        sudo make clean
+        sudo make install
+        sudo chmod 4755 /usr/local/bin/xastir
+    -----------------cut here--------------------
+
+    Now type "chmod u+rwx update-xastir" to make that script executable.
+
+    Actually, we've just created a script for Xastir that implements the above
+    and called it "update-xastir".  Do a "cvs update" to get it.
+
+    Try out the script.  Type:
+
+        ./update-xastir
+
+    It should run through the entire update/configure/make/install process for
+    Xastir.  Remember to either change to the proper xastir directory before
+    running it, or add a "cd" command at the beginning of the script so that it
+    will run in the proper directory in all cases.  If you add the proper "cd"
+    command you can copy the script to /usr/local/bin and then run it as
+    "update-xastir" from anywhere.
+
+    Windows users:  You may need to remove the "sudo" keyword on each line to
+    have it work properly for you.
+
+    A note from Gerry Creager as to another way to set up the sudoers file:
+
+      "I now consider it a good idea to add the "gifted" users to the 'wheel'
+      group and then solely enable wheel in /etc/sudoers; I've seen a recent
+      article also supporting this."
+
+
+Developer's CVS Instructions:
+-----------------------------
+
+    Read this doc first.  Why did they have to put spaces in the URL???:
+
+        http://sourceforge.net/apps/trac/sourceforge/wiki/CVS%20client%20instructions
+
+    For branching/merging, read these as well:
+
+        http://www.drdobbs.com/programmers-toolchest/184404280  # Recommended by Tom Russo
+        http://ioctl.org/unix/cvs/branches/
+        http://www.astro.princeton.edu/~rhl/cvs-branches.html
+        http://users.csc.calpoly.edu/~jdalbey/205/Resources/cvsBranchMerge.html
+
+
+    A suggested organization (directory names), to keep branches separate from trunk:
+
+        /home/<user>/src/xastir/head/           # Trunk (or HEAD), mainline development
+        /home/<user>/src/xastir/branchname1/    # branchname1 development
+        /home/<user>/src/xastir/branchname2/    # branchname2 development
+
+
+    Checking out HEAD (Also known as "trunk", default, or main branch):
+    -------------------------------------------------------------------
+
+    These commands will create a directory "xastir" in your current directory which
+    contains the latest Xastir sources from the "trunk" branch.  Replace "<devel>"
+    with your Sourceforge developer's login name.  To keep the trunk code from
+    getting confused with any branches, consider putting it into a subdirectory
+    labeled "trunk" or "head", something like "/home/<user>/src/xastir/head/".
+    These commands will create just such a directory and populate it with the
+    latest development sources (HEAD branch):
+
+        export CVS_RSH=ssh
+        cd ~src/xastir
+        mkdir head
+        cd head
+        cvs -z3 -d:ext:<devel>@xastir.cvs.sourceforge.net:/cvsroot/xastir co xastir
+
+
+    Checking out a branch:
+    ----------------------
+
+    To check out a branch to a fresh directory:
+
+        cd ~/src/xastir
+        mkdir <my_branchdir>  # /home/<user>/src/xastir/<my_branchdir>/
+        cd <my_branchdir>
+        cvs -z3 -d:ext:<devel>@xastir.cvs.sourceforge.net:/cvsroot/xastir co -r BRANCH_<branchname> xastir
+
+    Replace "<devel>" above with your Sourceforge developer's login name, and
+    "<branchname>" with the name of the branch you wish to check out.  "my_branchdir" can
+    be any directory name you like, but naming it the same as <branchname> may be less
+    confusing.
+
+    The above command will create a directory "xastir" under <my_branchdir> containing
+    the sources from the branch you specified.  The selected branch will remain "sticky"
+    in your checked-out working directory unless/until you override it via additional CVS
+    commands.  Any cvs commits done there will commit to the new branch instead of the
+    trunk.  Commits done to a working copy of "trunk" won't appear on your new branch.
+    Pay attention to your directory structure from that point on, whether you're working
+    on a checked-out copy of a branch or a checked-out copy of the trunk, and commit
+    responsibly.
+
+    With the fictitional "xastir99" branch we used before, example commands would be:
+
+        cd ~/src/xastir
+        mkdir xastir99  # /home/<user>/src/xastir/xastir99/
+        cd xastir99
+        cvs -z3 -d:ext:<devel>@xastir.cvs.sourceforge.net:/cvsroot/xastir co -r BRANCH_xastir99 xastir
+
+    NOTE:  The trunk has version numbers like "dd.dd", while branches have version numbers
+    like "dd.dd.dd.dd".
+
+    You can run the "cvs status <filename>" command and look at the "Sticky Tag" near the
+    top of the listing to see which branch you're working with:
+
+        cvs status README.CVS | head -15
+
+
+    Creating a branch:
+    ------------------
+
+    NOTE:  This is a special operation.  Do _not_ attempt unless you are familiar with
+    CVS tagging, branches, and merging.  We plan to do development on the trunk for
+    the mainline (trunk) code and use branches only for a few special development bits:
+    Experimental code that we're not sure will make it to production, or porting to
+    a new widget set for instance...  Something that might lead to a dead-end, a major
+    refactor, or any code that might not see the light of day for some time.
+
+    NOTE:  We've adopted the convention that all branch tags begin with
+    "TAG_BRANCH_" and all branches begin with "BRANCH_".  This makes it easy
+    to see where branches diverge or merge back with "trunk" and to determine
+    which tags are related to branching/merging.
+
+    In a checked-out CVS copy of Xastir, make sure your working copy is up-to-date
+    ("cvs -nq update") if you wish all current development changes to this point to
+    make it to the new branch you're creating:
+    
+        cvs update
+
+    Then:
+
+        # Create a tag called "TAG_BRANCH_<branchname>"
+        cvs rtag TAG_BRANCH_<branchname> xastir
+
+        # Create branch "BRANCH_<branchname>" starting at the tag you created above
+        cvs rtag -b -r TAG_BRANCH_<branchname> BRANCH_<branchname> xastir
+
+    Replace "branchname" with a name of your choosing.  For instance to create
+    a branch called "xastir99":
+
+        cvs rtag TAG_BRANCH_xastir99 xastir
+        cvs rtag -b -r TAG_BRANCH_xastir99 BRANCH_xastir99 xastir
+
+    Follow the "Checking out a branch" section above to create a NEW directory area to
+    work on the new branch.  It's important to keep your directories separate, because
+    commits made on a branch will apply only to that branch;  Commits made to trunk
+    will apply only to the trunk.
+
+
+    Listing the tags on a file:
+    ---------------------------
+    
+        cvs log -t README.CVS
+
+
+    Merging between trunk and a branch:
+    -----------------------------------
+    TBD.
+
+    A note from Tom regarding merges:  Use the "-kk" option on all merges, otherwise every
+    file that has "$Revision: 1.29 $" or "$Date: 2012/11/16 03:22:40 $" in it will get
+    flagged as a change -- possibly even a conflict -- even if that's the only difference
+    between branch and head.  "-kk" on a cvs update doesn't do substitution on those tags,
+    and so only files with real changes will get updated.
+
+
+
+  ------------------------------------------------------------------------
+Copyright (C) 1999 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
diff --git a/README.CYGWIN b/README.CYGWIN
new file mode 100644
index 0000000..893a499
--- /dev/null
+++ b/README.CYGWIN
@@ -0,0 +1,857 @@
+
+$Id: README.CYGWIN,v 1.2 2012/11/01 18:57:18 we7u Exp $
+
+
+---------------------------------------------------------------------
+Note that there are other options to get Xastir running on Win32.
+The method described below in this document is for getting Xastir
+running under Cygwin which can be problematic.  Other methods exist
+on the Xastir Wiki pages which are typically easier and more robust:
+
+    http://www.xastir.org/wiki/index.php/Installation_Notes
+---------------------------------------------------------------------
+
+  In the past, two companies have created simpler installs of 
+  Cygwin/Xastir than described in this document.  Contact one of 
+  these folks for more info.  Remember to replace the "at" below 
+  with the "@" symbol to arrive at the correct e-mail addresses.  
+  We have to do that to prevent large amounts of spam from going to 
+  addresses harvested from web pages:
+
+
+    Lintronix:
+      Internet install of Xastir available for free, CD-ROM available
+      for a nominal fee.  Everything needed to install Cygwin/Xastir
+      online (Internet install) or off-line (CD-ROM).  Walks you
+      through an automated install:
+
+        http://www.lintronix.com/winxastir/
+        E-mail:  winxastir at lintronix.com
+
+
+    Inuit Nunaani Wireless Inc:
+      CD-ROM available for a nominal fee.  Everything needed to
+      install Cygwin/Xastir off-line.  Walks you through an
+      automated install.  This install is verified to work on WinXP
+      and Win98 (known _not_ to work on Win95/WinME).  Contact:
+
+        E-mail:  Tom Tessier <ttessier at trtdigital.ca>
+
+
+
+------------------------------------
+Installing Xastir on Windows/Cygwin:
+------------------------------------
+
+These directions assume that you installed Cygwin after the new version
+was released in January of 2010.  If you had Cygwin installed before
+then, it is simpler to delete the Cygwin directory and the Start Menu
+entries than to upgrade your existing install to the new version.
+
+System Requirements:
+
+CPU: at least 1Ghz
+Memory: at least 512Meg with at least 1Gig of swap space
+OS: Windows 2000 or later
+Time: At least 6 hours if not using the get-maptools.sh script
+      24 to 48 hours if using the script
+
+
+Please Note:  It's beneficial to actually log in to your Windows
+computer rather than skipping that step of the Windows login process
+(Don't hit escape just to get rid of the dialog!).  If you log into
+Windows properly, Cygwin will be able to figure out where to put your
+home directory.  If you don't do this, you'll be referred to as
+"unknown" and you won't have a home directory in Cygwin.  This means
+there won't be a good place to put your Xastir startup files.  Of
+course, log in as the same user each time in order for Cygwin to use
+the proper home directory for you.
+
+CAN'T REPLACE FILES:  Every once in a while Windows will refuse to
+allow you to delete/rename one of the files.  The only way I've
+found to get around this problem is to reboot.  Also, Windows
+typically won't allow you to replace a file that Windows currently
+has open.  If you're going to be recompiling/reinstalling Xastir, or
+updating Cygwin, make sure that these applications are shut down
+before doing so.  You can get VERY strange results if only some
+files get updated.
+
+SPACES IN USERNAMES:  Cygwin specifically, and Unix boxes in
+general, don't much like spaces in filenames, directories, or login
+names.  Any of these may cause you headaches while playing with
+Cygwin.  Create a new login that doesn't have spaces and log in as
+that user before installing Cygwin, and whenever you intend to run
+Cygwin/Xastir.  It's very likely that Xastir won't work for you if
+you use a login that has spaces embedded in it.  For additional
+info, see this link:
+
+    http://cygwin.com/faq/faq_2.html#SEC17
+
+Explanation of this login box for those that don't see it:  If you
+have the option of running networking, you'll have a login box show
+up when you first start up Windows.  It'll ask for you user name and
+password, then let you in.  If you escape out of that dialog, Windows
+may start right up but networking will be disabled.
+
+If you don't see that box, there are two options that I know about,
+either you or someone else set it up to auto-login with your user/
+password combo, or you don't have networking installed at all.
+
+The following steps direct you through installing Cygwin, Xastir, and
+a few optional map libraries that Xastir can use.  Note that in most
+of the places below where the directions state to type commands, this
+must be done from within a Cygwin BASH shell, not a DOS window.
+Where you are asked to edit files, it's best to use Wordpad instead
+of Notepad, as Notepad doesn't do nice things to Unix-format files.
+
+Cygwin now allows you to have Xwindows apps and Windows apps all on
+the screen and visible at the same time!  The instructions here set
+it up in that manner, so you can have Xastir as just another app on
+your Windows desktop.
+
+Please subscribe to the "xastir" mailing list at
+"http://www.xastir.org".  There are lots of helpful people there
+that can aid you in installing/running Xastir.  You must be subscribed
+in order to post messages there.
+
+
+[ ] Step 1)  Install Cygwin, a free download.
+
+
+[ ] Step 1a) Go to http://www.cygwin.com with your web browser.
+Look for the black and green Cygwin icon, then click on "Install
+now!".
+
+This will load the Cygwin network installer program onto your
+computer.  Remember where you decide to put this program.  I put
+mine in "c:\<login>\cygwin\setup.exe", (for instance
+"c:\hacker\cygwin\setup.exe").  This program will allow you to do a
+network install of Cygwin.  After you install Cygwin (see the steps
+below for details) you'll have a package directory (in my case
+"c:\hacker\cygwin\") and a Cygwin directory (in my case
+"c:\cygwin").  The un-installed packages go into the package
+directory as they are downloaded from the 'net.
+
+It will be beneficial to re-run the Cygwin network installer from
+time to time in order to keep Cygwin up to date.  Each time you run
+it you'll update any packages that have been changed since you last
+ran it.
+
+[ ] Step 1b)  Find the "setup.exe" program and execute it either by:
+
+  a) Clicking on it with File Explorer, or
+  b) Start->Run->path to executable, or
+  c) Opening a DOS window and typing the name.
+
+This will start installing Cygwin over the network.  Answers to
+provide to the program:
+
+    Install from Internet (*)
+    "C:\cygwin"
+    Install For All Users
+    Default Text File Type Unix (*)
+    Local Package Directory "C:\hacker\cygwin"
+    Select Your Internet Connection (choose one)
+    Choose A Download Site (choose one nearby if you can determine that)
+
+Note:  Responses above listed with a "(*)" are required.  Others are
+up to the individual user to answer as they wish.  You'll get to a
+"Progress" page where "setup.bz2" is downloaded from the 'net.  If
+it hangs at this step, you may wish to "Cancel" and try another
+server until you obtain this file and are presented with a list of
+packages to install.
+
+
+[ ] Step 1c)  Select Packages:  Leave the packages selected that
+were selected by default, plus select the additional packages listed
+below.  Note that enabling some of these packages causes others to
+be selected as well, that's OK and necessary.
+
+[ ] Press the "View" button until it says "Full" next to it.  All
+packages are now in alphanumeric sorted order.
+
+Selecting a package involves clicking on the little circle symbol
+until the option you want is displayed.  You can choose older
+versions of a package, choose to keep the package you have installed
+already, or choose to remove or install a package in this manner.
+If you're running Cygwin install again and see "Keep" as an option,
+that means you've already installed that package.  We're only
+concerned with the "bin" packages here (stands for "binary") and not
+the "src" packages (source code).
+
+It's suggested that you keep whatever was selected by default, and
+just add the below packages to the selection.  As you select
+packages, other packages may be selected for you that are also
+required:
+
+[ ] autoconf
+[ ] automake
+[ ] binutils
+[ ] bzip2
+[ ] curl
+[ ] cvs
+[ ] db4.x (pick the highest number listed for x)
+[ ] diffutils
+[ ] font-adobe-* (pick all of them)
+[ ] font-bitstream-* (pick all of them)
+[ ] font-util
+[ ] font-xfree86-type1
+[ ] gcc4
+
+[ ] gcc4-fortran (if you are going to use the get-maptools script)
+[ ] gcc4-objc (if you are going to use the get-maptools script)
+
+[ ] GraphicsMagick
+[ ] gv
+[ ] gzip
+[ ] jasper
+[ ] jbigkit
+[ ] lcms
+[ ] less
+[ ] lesstif
+[ ] libbz2-devel
+[ ] libcurl-devel
+[ ] libjasper-devel
+[ ] liblcms-devel
+[ ] libdb4.x (pick the same x as db2.x above)
+[ ] libdb4.x-devel (pick the same x as db2.x above)
+[ ] libfontconfig-devel
+
+[ ] libgeotiff (if you are NOT going to use the get-maptools script)
+[ ] libgeotiff-devel (if you are NOT going to use the get-maptools script)
+[ ] libgeotiff1 (if you are NOT going to use the get-maptools script)
+
+[ ] libGraphicsMagick-devel
+[ ] libGraphicsMagick3
+[ ] libjbig-devel
+[ ] libpcrecpp-devel
+[ ] libpng*-devel (pick the number that matches the already selected libpng* library)
+
+[ ] libproj-devel (if you are NOT going to use the get-maptools script)
+[ ] libproj1 (if you are NOT going to use the get-maptools script)
+
+[ ] libtiff-devel
+[ ] libtool
+[ ] libwmf-devel
+[ ] libX11-devel
+[ ] libXext-devel
+[ ] libXm-devel
+[ ] libxml2-devel
+[ ] m4
+[ ] make
+[ ] nano (a windows-style text editor, optional)
+[ ] patch
+[ ] pcre
+[ ] perl
+
+[ ] proj (if you are NOT going to use the get-maptools script)
+
+[ ] python
+[ ] rcs
+[ ] tcltk
+[ ] tiff 
+[ ] unzip
+[ ] vim (a Unix-style text editor, optional)
+[ ] wget (Optional: Can use libcurl instead)
+[ ] X-start-menu-icons (may take a minute to respond because it turns on many others)
+[ ] xextproto
+
+[ ] zip
+
+Clicking on the small circle with the two arrows will run you
+through the various select/de-select options for each package.
+
+
+[ ] Step 1d)  Click Next and the packages will get downloaded and
+installed.  Repeat the above if you have network difficulties, until
+the install succeeds completely.
+
+Some servers fail to download some files and require the user to
+press enter between downloads when it fails on these files.  If this
+happens, back up and select another server.
+
+
+[ ] Step 1e)  At the end of the install it'll ask you if you wish to
+create desktop icons and menu entries.  Definitely select these!  It
+doesn't mean that Cygwin will start automatically each time you
+reboot your computer or login (it doesn't start automatically).  It
+_does_ mean that you'll have an icon to click on manually to get
+things going.
+
+This will create a Black/Green Cygwin icon on the desktop and a menu
+entry so that you can start Cygwin through the menu system as well.
+
+[ ] Step 1f) Click "Finish".  Cygwin is now installed.  One more
+pop-up informs you Cygwin has been installed.  Sometimes this last
+dialog gets hidden behind other windows, and it does seem to need OK
+clicked to complete the installation.  Click the OK button on that
+last dialog to _really_ complete the installation.
+
+The Black/Green Cygwin icon will start up a BASH window, without
+starting up Xwindows.  Think of it as being similar to a DOS window,
+but with a lot more power.  It understands Unix commands though, not
+DOS commands.
+
+[ ] Note:  I've had the Cygwin network install fail before during
+the downloading stage without informing me in any recognizable
+manner.  You might which to re-do step 1 to make sure nothing
+further gets downloaded/installed.  Once you get to that point, Step
+1 is complete.
+
+[ ] Step 2) Reboot.  Yes, I know that "modern Windows" doesn't always
+require this but you just installed a lot of stuff including a DLL.
+
+[ ] Step 3)  (optional) Create shortcut for starting X:
+
+Click on START / Programs (or All Programs) / Cywgin-X
+
+Right-click on XWin-Server and then click on Send-to / Desktop
+(create Shortcut) to copy that Start Menu entry to a icon
+on your Desktop
+
+[ ] Step 4)  Test Cygwin and create startup shortcuts:
+
+Double-click on the shortcut you just made.  You should get a shell
+window that looks very much like a DOS window.  It's a BASH shell
+window and understands Unix commands instead of DOS commands.
+
+You should see an 'X' in your system tray.  That's the
+X-server running.  
+
+Once you've gotten to this stage, you now have Cygwin and Xwindows
+installed and operational.  Next we go after Xastir itself.
+
+[ ] Step 5)  Create a file at C:\cygwin\home\<user>\ called
+".cvsrc", where the "<user>" part is your Windows login name.  Don't
+forget the leading period in the filename as it's important.  For
+instance, I created a file:  "C:\cygwin\home\hacker\.cvsrc".  The
+file should contain the following lines:
+
+    cvs -z3
+    update -P -d
+    status -v
+    diff -u
+
+The '#' marks comment out the first line.  "cvs -z3" invokes
+compression, and the SourceForge site isn't performing compression
+currently.
+
+PLEASE NOTE:  this file must be created in Unix format, not DOS
+format.  DO NOT USE Notepad or other Windows tools to create the
+file, as CVS will not recognize the contents.  Thanks to Kirk
+Mefford <kc2elo at softhome.net> for noticing this.  The editor "nano"
+can be invoked from a Cygwin window to create this file, or for
+those of you who know "vi" or have Windows editors available that
+can save in Unix format, use those.  If you don't, the "cvs update"
+commands won't work for you, at least until you recreate the file in
+Unix format.  You've been warned!
+
+The "." in ".cvsrc" makes it a Unix hidden file, and it won't appear
+in most Unix listings.  Unix files don't need a file extension, so
+don't create a file that has one (or else rename it to ".cvsrc" when
+done).
+
+Another option is to create the file using a Windows editor, then
+run a dos2unix program on it to convert it to the proper format.
+
+
+[ ] Step 5)  Download Xastir sources.  Start up Xwindows using your
+shortcut.  Type the six lines below into the shell exactly as shown.
+Hit <ENTER> when asked for a password after typing line four (the
+"login" command):
+
+  cd ~
+  touch .cvspass
+  mkdir src
+  cd src
+  cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir login 
+  cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co xastir 
+
+NOTE:  The "login" command must complete without errors in order to
+create a dummy blank password in your .cvspass file.  Without this
+password you'll have trouble with later CVS commands.  If you see
+"EOF", "connection reset by peer", "connection refused", or "timed
+out", it means that the anonymous CVS server at SourceForge is
+overloaded (too many users).  Keep trying the failed commands until
+they succeed!  Notice that up-arrow (on the keyboard) and then
+<ENTER> will repeat the last command, saving you some typing.
+
+The end result when it succeeds  will be a new directory
+"C:\cygwin\home\<user>\src\xastir\" which contains all of the Xastir
+source code.  You can type "ls xastir" (that's lower-case LS) to see
+the file listing.
+
+Side Note:  Here's the coolest thing about CVS:  Once you've done
+this initial source-code download, you'll never have to do the whole
+Xastir download again.  You'll just go into the "src/xastir"
+directory and type "cvs update", which will snag just the _changes_
+to the files since you last updated, and is very fast.  Compile and
+install at that point and you'll be running the latest developer's
+version in just a few minutes!  It's very easy to keep up with the
+developers this way.
+
+
+[ ] Step 6)  Configure/compile/install Xastir.  Type these commands
+into the BASH shell, waiting until each one completes before typing
+the next command:
+
+    cd ~/src/xastir
+    ./bootstrap.sh
+    ./configure
+    make
+    make install
+
+NOTE:  You'll probably want to run the configure step from an xterm
+window with the X11 server running of course.  If you do this from a
+non-X11 window then the configure test for "gv" will fail, as "gv"
+requires an X11 server even when asking it for it's version number.
+Without "gv" support you won't be able to print from Xastir.
+ 
+NOTE:  The "make" step can be extremely memory hungry.  If you don't
+have much free memory, that step might take a long time to run.  One
+Win2k machine with only 20MB of free RAM (128MB total RAM) couldn't
+complete this step, but adding another 128MB of RAM to that machine
+caused it to succeed.  Another machine running Win2k with 64MB free
+(128MB total RAM) took six hours (but keep reading!).  Free up
+memory if you're having trouble completing that step.  This behavior
+is only seen on Windows/Cygwin, not on the Unix-based systems.  On a
+typical Linux box that step takes under two seconds.  Hopefully
+Cygwin linking will improve over time to alleviate this issue.
+We've added a new link-stage parameter to reduce the memory usage
+for that step, but it doesn't totally resolve the problem.  The
+machine that took six hours originally now takes 60 seconds to
+complete that step.
+
+Ignore the "PACKAGE_* redefined" warnings.  They won't break
+anything and are just an annoyance.
+
+Once you get through the above commands, Xastir is compiled and
+installed on your system, with minimal map support.  Later sections
+of this document detail adding additional map libraries in order to
+give you access to the full mapping capability of Xastir.
+
+NOTE:  If you get the below errors during the compile it means that
+Cygwin has changed one of their packages to be incompatible with the
+rest (and needs to change a lot more of their packages to
+correspond).  It also means that you probably had Cygwin installed
+previous to January 2010 and upgraded rather than replaced your
+installation.
+
+---------------------------------------------------------------------
+/usr/include/Xm/Print.h:28:34: X11/extensions/Print.h: No such file or directory
+In file included from /usr/include/Xm/XmAll.h:79,
+                 from alert.c:308:
+/usr/include/Xm/Print.h:40: error: parse error before "XPContext"
+/usr/include/Xm/Print.h:43: error: parse error before '}' token
+/usr/include/Xm/Print.h:61: error: parse error before "XPFinishProc"
+make[3]: *** [alert.o] Error 1
+---------------------------------------------------------------------
+A temporary fix for the above errors (until Cygwin gets their act
+together) is to do the following:
+---------------------------------------------------------------------
+    Launch the Cygwin setup program
+    When you get to the list of packages change the list to FULL mode
+    Uncheck "Hide Obsolete Packages"
+    Scroll down the list until you find xorg-x11-devel
+    Click on the word "keep" until it changes to a 6.x version of the file
+    Click Next and finish the setup
+    Unfortunately you'll have to perform the same fix each time you
+      use the Cygwin setup program or it will "upgrade" to the
+      broken package again.
+---------------------------------------------------------------------
+
+[ ] Step 8)  Actually run the darn thing:
+
+Let's start from scratch to make sure it all works.  Close any
+Cygwin/BASH windows you may have.
+
+Click on the shortcut you created to start Xwindows.
+
+From the resulting BASH window, type "LANG=C xastir &".  Xastir should
+start up shortly.
+
+Note:  Xastir has support for PocketAPRS, DosAPRS, WinAPRS, MacAPRS
+and GNIS maps by default.  For additional types of maps, you'll need
+to install some libraries, then recompile Xastir so that it knows to
+use them.  See the instructions below.
+
+The README.MAPS file has instructions for where to get maps and where
+to put them under the Xastir hierarchy.
+
+If you have any WinAPRS, DosAPRS, or PocketAPRS maps, now is a good
+time to place them in the /cygwin/usr/local/share/xastir/maps folder
+(or a subdirectory of it).  You can also use "*.geo" files and the
+associated image files with Xastir.  You may place them in this
+directory (or a subdirectory of it) as well, though most of the .geo
+files won't work for you until you install the ImageMagick library.
+
+What Xastir paths look like from within Windows (in case you're
+moving maps around with Explorer):  Just prefix them all with
+"cygwin/".  For instance, maps go into
+/cygwin/usr/local/share/xastir/maps instead of
+/usr/local/share/xastir/maps.  Xastir will continue to see them as
+"/usr/local/share/xastir/maps" though from inside Cygwin.  It kind
+of looks like a miniature Unix box from inside Cygwin.
+
+Run Windows in 15-bit color or better (32768 colors or more) or
+you'll get lots of warnings about Xastir not being able to allocate
+colors when it starts up, and the display will be rather stark
+looking.
+
+To set a new language or change the language current choice, use
+this command line instead from inside an Xterm:
+
+     xastir -l <language>
+
+Current choices are:
+
+    Dutch English French German Italian Portuguese Spanish
+    ElmerFudd MuppetsChef OldeEnglish PigLatin PirateEnglish
+
+This option will be stored in the users config file for the next
+time Xastir is run. On new installs Xastir will default to English
+until you use this command line option once.
+
+Another difference with Cygwin as opposed to Unix-like operating
+systems:  You can't do the make install portion if Xastir is up and
+running.  You have to kill Xastir first before you do "make install"
+or "make install-strip".  Otherwise the newly compiled Xastir won't
+replace the old one.
+
+Note that one user running Cygwin on XP had it crash every time his
+screen-saver kicked in.  Disabling the screen-server fixed that
+problem.
+
+Another interesting "feature" of Cygwin/Xwindows is that some of the
+modifier keys like ScrollLock/CapsLock/NumLock must be pressed while
+that X-window is the active foreground window.  If not, the event
+can be missed, and Xwindows can get out of sync with the actual
+state of the key.  This doesn't appear to be an Xastir-specific
+problem, but a Cygwin/Xwindow problem.  With just a BASH shell under
+Cygwin (not involving Xwindows), the problem doesn't appear to
+happen.  Just inside Xwindows on Cygwin.
+
+Some users have experienced problems with their Windows box running
+the NTFS "convert.exe" program instead of the ImageMagick
+"convert.exe" program, usually when enabling snapshots in Xastir.
+If you experience this, check your path settings and make sure that
+ImageMagick's path is first.
+
+When specifying serial ports to use with Xastir,
+
+    "COM1" is called "/dev/ttyS0" in Cygwin (and Linux)
+    "COM2" is called "/dev/ttyS1" in Cygwin (and Linux)
+
+Note the capital 'S'.
+
+
+[ ] Step 9)  Document & Back Up the Configuration
+
+One user had a problem where after Cygwin/Xastir was installed, he
+installed another program, in this case Java, and it wiped out some
+of the environment variables that Cygwin set.  $HOME was one
+variable that got changed.
+
+To guard against such changes, go to My Computer and right-click on
+properties.  Write down the Advanced System Variables and keep the
+note in a safe place.
+
+
+Optional
+
+
+Please see the INSTALL file and the Help menu in Xastir itself
+for additional information not mentioned in this document.
+
+Additional info can be found on the cygwin web-site:
+
+    http://www.cygwin.com
+
+or the Cygwin/XFree86 web-site:
+
+    http://cygwin.com/xfree/
+
+
+[ ] Step 10)  Keeping up-to-date:
+
+Once a week or once a month, run the Cygwin network installer
+program (step 1b above).  After it finishes, open a Cygwin window
+and type these commands to update the Xastir source code:
+
+    cd ~/src/xastir
+    cvs update
+
+If you see "EOF" or "connection reset by peer" it means that the
+anonymous CVS server at SourceForge is overloaded (too many users).
+Keep trying the failed commands until they succeed!  Notice that
+up-arrow (on the keyboard) and then <ENTER> will repeat the last
+command, saving you some typing.
+
+Every once in a while Windows will refuse to allow you to
+delete/rename one of the files.  The only way I've found to get
+around this problem is to reboot.  I sometimes see this when trying
+to do a CVS update, and Windows won't allow one or more files to get
+updated.
+
+Repeat step 6) above to recompile/reinstall the latest Xastir.
+
+A very good option is to read the SUDO instructions in the
+README.CVS file, setting up the /etc/sudoers file and creating an
+update-xastir script as shown.  Then you can type "./update-xastir"
+at any time to snag down the latest Xastir changes, compile, and
+install it.  We've just included an update-xastir script with
+Xastir, so you don't have to create it anymore.  You may however
+need to remove the "sudo" keyword from each line for it to work
+properly on Cygwin.
+
+
+-----
+
+-------------------------------------------
+OPTIONAL:  ADDING ADDITIONAL MAP LIBRARIES:
+-------------------------------------------
+
+These additional Xastir libraries have been tested on Cygwin:
+
+    ImageMagick
+    Shapelib
+    libtiff
+    libproj
+    libgeotiff
+    Festival
+    GDAL/OGR (broken as of January 2010 - kd7myc)
+
+Anyone testing additional libraries is encouraged to share their
+findings on the Xastir mailing lists (you must be subscribed in
+order to post messages there).  The libraries which have _not_ been
+made to work yet on Cygwin are:
+
+    AX25
+    GPSMan/gpsmanshp
+
+The AX25 libraries will probably never work, as they are for Linux
+only.  GPSMan/gpsmanshp may work on Cygwin at some point if enough
+work is done to figure out and document the process.
+
+
+RECOMMENDED:  Adding maptools:
+------------------------------------------------------------
+
+*******************************NOTE**************************************
+As of 10 November 2006, xastir's source tree contains a copy of shapelib
+1.2.10, and automatically builds shapelib if you don't have it installed.
+************************************************************************
+
+
+[ ] From a BASH shell, type:
+
+    cd ~/src/xastir/scripts
+    ./get-maptools.sh
+    come back in six to 48 hours
+    
+The last thing the script tries to do is compile GDAL.  This is currently
+broken.  Don't worry.  The rest should have been installed just fine.
+
+[ ] Now you should be ready to configure and compile Xastir with
+Shapelib support.  Type these commands:
+
+    cd ~/src/xastir
+    cvs update
+    ./bootstrap.sh
+    ./configure
+    make
+    make install
+
+
+See the README.MAPS file for where to get the maps.
+
+
+OPTIONAL:  Install Festival support:
+------------------------------------
+Allows using a synthesized voice from within Xastir for alerts,
+reading messages to you, and other cool things.  Tom Russo did the
+initial work on this, Henk de Groot optimized it:
+
+1) Start BASH shell in Cygwin
+
+2) Make ~/festival download directory and
+    /usr/local/festival installation directory
+
+3) Download festival components from festvox.org into ~/festival, in
+   the Windows environment the corresponding path is:
+
+     C:\Cygwin\home\%USERNAME%\festival
+
+    get the following files:
+
+     speech_tools-1.2.95-beta.tar.gz
+     festival-1.95-beta.tar.gz
+     festlex-CMU.tar.gz
+     festlex-POSLEX.tar.gz
+     festvox-kallpc16k.tar.gz
+
+4) Build festival and company:
+
+    cd /usr/local/festival
+    tar xzf ~/festival/speech_tools-1.2.95-beta.tar.gz
+    tar xzf ~/festival/festival-1.95-beta.tar.gz
+    tar xzf ~/festival/festlex_CMU.tar.gz
+    tar xzf ~/festival/festlex_POSLEX.tar.gz
+    tar xzf ~/festival/festvox_kallpc16k.tar.gz
+
+    cd speech_tools
+    ./configure && make
+    cd ../festival
+    ./configure && make
+
+   These packages are build and used where they are compiled.
+
+5) Test festival:
+
+    cd /usr/local/festival/festival/examples
+    sh saytime
+
+   Festival should say the time if everything went fine
+
+6) Add /festival/festival/bin to PATH in .profile and .bashrc. For
+   me both files look like this:
+
+    .profile and .bashrc:
+    -------------------
+    export PATH=$PATH:/lib:/usr/lib:/usr/X11R6/lib:/usr/local/lib:/usr/local/bin:/usr/local/festival/festival/bin:~/bin:.
+
+    -------------------
+
+7) Configure and build xastir.  Configure should report that
+   festival is found.
+
+8) Start the festival server:
+
+    festival --server &
+
+   To do this automatically I added the following lines to my
+   .bash_profile:
+
+    -------------------
+    if  [ `ps -ef | grep festival | wc -l` -eq 0 ]
+    then
+      festival --server &
+      sleep 1
+    fi
+    -------------------
+
+9) Run xastir, do File->Configure->Speech, add things to say, and
+   listen.
+
+
+
+How to make Sound Alerts work under Cygwin
+------------------------------------------
+(from Kirk Mefford, kc2elo)
+"I figured I'd share exactly what I did to make the sound alerts work in
+xastir under Cygwin. Sound support seems to be just one of the many quirks
+of trying to use *nix native software under Microsoft OS's. Hope this helps
+someone else.
+
+FYI: This was tested under Win2000
+
+Sound alert support under Cygwin using Network Audio Server (NAS)
+
+I downloaded http://nas.intra-links.net/files/nas-1.6-win-binary.zip and
+decompressed the archive with winzip (any zip utility should work fine) into
+a temporary folder.
+
+I deleted the "cygwin1.dll" and "README.txt" files that came in the package
+since they aren't needed and the extra cygwin1.dll can cause problems.
+
+
+  Note from James Cour, K1ZC:
+  ---------------------------
+  "The procedure he (Kirk) outlines there works fine EXCEPT that
+  there is a valuable piece of information in that Readme.txt file...
+  The user must have a folder named /DEV under the Cygwin folder in
+  order for NASD to work.  NASD will not create it automatically, and
+  NASD will not run without it.  The default set-up instructions for
+  Xastir and Cygwin do not create this folder, so the user needs to
+  manually create the folder from Windows."
+
+
+  Note from Tim Baggett, AA5DF:
+  -----------------------------
+  "I recommend running the script (create_devices.sh) found attached
+  to the email located at the URL below to create the /dev directory,
+  and all supported devices under Cygwin."
+
+  "http://cygwin.com/ml/cygwin-xfree/2004-01/msg00353.html"
+
+
+Then copy the remaining files from the package into the /bin directory under
+cygwin.
+
+All that is needed to make nas available to xastir is to load the server
+before running xastir.
+
+To load NAS for xastir to use simply type "nasd -local -b" from cygwin. This
+command will load the NAS server in the background and will only allow local
+users to access it.  For more command options type "nasd -help" from within
+cygwin.  Some people have trouble with the "-local" option, so try
+it without that option as well ("nasd -b").
+
+After NAS is loaded you can load xastir as you normally would.
+
+Once xastir is running, to play sound alerts you need to change the default
+configuration to use "auplay"
+
+From within xastir click on File>Configure>Audio Alarms.
+The "Audio Play Command" box should be changed to "auplay"
+Then ensure the audio files listed to play are located in
+"/usr/local/share/xastir/sounds" directory.
+
+Click OK to accept the changes and be sure to save your config before
+exiting xastir or sound will not work the next time it is loaded.
+
+Turn up the volume on your PC speakers and enjoy the noise xastir makes."
+
+
+OPTIONAL:  Install GDAL/OGR support:
+------------------------------------
+One user has been successful in compiling GDAL/OGR support into
+Xastir.  One thing he mentioned:
+
+"Now the word of warning.  If you try to compile GDAL under Cygwin
+and the compile blows up, you are better rm -rvf'ing the entire
+directory and re-untaring the source again than trying to recompile
+in that blown directory.  Make Clean doesn't do a thing and the old
+settings and mistakes stick around no matter what you try."
+
+Make sure you've got Shapelib installed on your system else Xastir
+won't find GDAL (the private Xastir copy of Shapelib is fine).  Both
+are needed.
+
+Download "gdal-1.2.0b.tar.gz".  In a cygwin window, type the
+following:
+
+
+    tar xzvf gdal-1.2.0b.tar.gz
+    cd gdal-1.2.0b
+    ./configure --with-jpeg=internal --with-libtiff=internal
+    make
+    make install
+
+
+The GDAL/OGR library should now be installed on your system.  Return
+to the xastir directory and start with the ./configure command.  It
+should pick up the fact that GDAL/OGR has been installed and compile
+support for it into Xastir.  Follow with the rest of the commands to
+make/install Xastir.
+
+One user required the below GDAL configure line as otherwise it
+complained about not finding libproj:
+
+    ./configure --with-jpeg=internal --with-libtiff=internal --with-static-proj4
+
+
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 2003-2012 The Xastir Group
+
diff --git a/README.Contributing b/README.Contributing
new file mode 100644
index 0000000..134dfcc
--- /dev/null
+++ b/README.Contributing
@@ -0,0 +1,327 @@
+
+$Id: README.Contributing,v 1.21 2012/11/01 18:57:18 we7u Exp $
+
+
+Hello possible new developer, and welcome to the Xastir project!
+
+In order to get contributed patches accepted more easily by the
+Xastir developers:
+
+*) Read "Developer Guidelines and Notes" in the "HowTos" section of
+Xastir's Wiki (http://www.xastir.org).  Make sure to follow the
+formatting and indentation rules, and in particular the tab format
+(spaces, not tabs).  If you don't like some of the formatting rules,
+abide by them anyway for consistency (Hey, I don't like some of them
+either, but consistency is more important than ideas I might have of
+coding style!  --we7u).
+
+*) Check the Xastir pages at Sourceforge.  There are sections for bug
+reports and feature requests.  Anyone can log new bugs or feature requests,
+whether or not they are logged into Sourceforge.  This is one of the best
+places to see what needs to be worked on, and to see if anyone else has
+had a similar idea. 
+
+*) Check with the Xastir-Dev list first to see if anyone else is
+working on that particular idea or section of code.
+
+*) Verify on the Xastir-Dev list that your idea has some merit and
+chance of being accepted before you put your valuable time into the
+patch.
+
+*) Make sure you're willing to abide by the GPL license with respect
+to your patch.
+
+*) Use as generic C as possible, and comment what you've done, in
+English please!
+
+*) Keep in mind that Xastir runs on multiple operating systems, so
+code for that.  Some #ifdef's may be required in order to make it
+work for the various operating systems.
+
+*) Xastir can be run in multiple languages, so code for that.  If
+any user text is added, make sure to add language strings for them
+to the language files.  If you don't know a particular language, add
+it to all of the language files in English.  It will be translated
+by others later.
+
+*) Put your patches into either "context diff" or "unified diff"
+format.  Don't submit complete files.  Make sure your diff is
+against the latest CVS sources, as that is the version that the
+developers work from.  Create the diff file against the directories
+recursively if more than one file has been changed:
+
+    diff -ur xastir-1.7.0 xastir-modified-directory > mypatch
+
+Here's a shorthand method if you're doing all this against the CVS
+version.  Do this from the top-level Xastir directory:
+
+    cvs diff -u > mypatch
+
+*) By compressing the patch and attaching it to an e-mail you
+preserve the lines exactly so that the "patch" program will have no
+trouble with it:
+
+    gzip mypatch
+
+This creates mypatch.gz, which you can attach to an e-mail or put up
+on an ftp or http site for download.
+
+*) Contribute patches either directly to one of the active
+developers or to the Xastir-Dev mailing list (you must be subscribed
+in order to post messages there).
+
+*) To apply a patch I typically do this:
+
+    gzip -d mypatch.gz
+
+Check the path listed inside the patch:
+
+    head mypatch
+
+Based on the paths listed inside the patch and the directory at
+which you're currently sitting, adjust the "p" number below so that
+the proper number of directories are stripped from the patch.  This
+example strips off the first two directories:
+
+    patch -p2 <mypatch
+
+
+
+DEBUGGING HINTS:
+----------------
+Xastir is a multi-threaded and multi-process application.  It uses
+both threads and forks to do it's work.  You must have a debugger
+that is capable of following these kinds of twists and turns in a
+program.  Many older versions cannot.
+
+Notes from Tom Russo:
+---------------------
+According to everything I can find about GDB, debugging of
+multithreaded apps has been supported in gdb for some time, and are
+certainly supported in gdb 6.x.  For the last couple days I've been
+running xastir inside gdb instead of at the command prompt ---
+perhaps I won't keep forgetting to start it with -t now, and when it
+crashes I'll be where I need to be.
+
+Jim --- this is possibly an option for you, too, if you're seeing
+segfaults frequently enough and can't solve the core file question.
+Try this:
+
+  gdb /usr/local/bin/xastir
+  > run -t
+
+When it crashes, it'll pop you right out into the debugger, whether
+a core file was created or not.  You could then view the active
+threads:
+  > info threads
+
+and get a stack trace of where the crash happened:
+  > where
+
+You could also probably list the code near where the crash happened:
+  > list
+
+If you send the output of those three commands to the xastir-dev
+list then it might help us narrow down the causes.
+
+
+Notes from Curt:
+----------------
+Note that the meaning of the "-t" command-line flag has been
+reversed.  "xastir -?" should show the change once you compile it.
+This means that we'll do core dumps by default upon segfault instead
+of using the internal Xastir segfault handler.  We've also
+re-enabled the "-g" compile option for GCC so that debugging
+information will remain embedded in the executable (unless you strip
+it).  This should aid the development team to debug problems.
+
+> Also, I cannot find anything in man bash that talks about core
+> dumps nor segmentation faults.
+
+Seems like some stuff we're just supposed to know.  _How_ we're
+supposed to know I don't know either...  ;-)
+
+Perhaps that last bit about SUID/SGID might be a clue:  There are
+often exceptions to the rules for SUID/SGID programs.  Try _not_
+setting Xastir SUID (if you're not using AX.25 kernel networking
+ports that is) to see if you get a core file.  Can you send a
+SIGSEGV to the running process and make it dump?  I just tried this
+and I'm not getting a core file either.
+
+Ah, I see in the "man bash" page:
+
+  ulimit
+        -a  All current limits are reported
+
+This gives me:
+
+  core file size        (blocks, -c) 0
+  data seg size         (kbytes, -d) unlimited
+  file size             (blocks, -f) unlimited
+  max locked memory     (kbytes, -l) 32
+  max memory size       (kbytes, -m) unlimited
+  open files                    (-n) 1024
+  pipe size          (512 bytes, -p) 8
+  stack size            (kbytes, -s) unlimited
+  cpu time             (seconds, -t) unlimited
+  max user processes            (-u) 6139
+  virtual memory        (kbytes, -v) unlimited
+
+So...  Looks like I need to set "ulimit -c" and try again:
+
+  ulimit -c unlimited
+
+Now when I do "kill -11 <pid>" I get this:
+
+  [1]+  Segmentation fault      (core dumped) xastir
+
+and this:
+
+  -rw-------   1 archer users 12320768 2006-02-02 09:31 core.7586
+
+I just added "ulimit -c unlimited" to my .profile.  For what it's
+worth, if Xastir has SUID permission bit set (4755) I don't get a
+core dump, but if it is reset I do (0755).
+
+I can invoke ddd like this (it uses gdb under the hood):
+
+    ddd /usr/local/bin/xastir core.7586 &
+
+or gdb like this:
+
+    gdb -c core.7586 /usr/local/bin/xastir
+
+Once you have the program and core file loaded into the debugger you
+can display a backtrace to see where the program died.  In the case
+of ddd, it's Status->Backtrace, then you click on one of the entries
+to make the source code window display the exact location.
+
+Another good debugger to try is "UPS".
+
+Another note about core files:  Sometimes they get written where you
+don't expect.  I just had one appear in ~/.xastir/tmp, so if you
+think you should have a core file and can't find it, try:
+
+    find . -type f | grep core
+
+The core file may be written to a directory that Xastir is currently
+in, instead of where you started Xastir from.
+
+Customized debugging builds
+---------------------------
+
+Sometimes it is helpful to build xastir with specialized compiler
+options to aid in debugging.  For example, if you're trying to hunt
+down elusive segfaults, and you're using GCC, it might be wise to
+build with "-O -g -fno-inline" to prevent the compiler from optimizing
+quite so vigorously; aggressive optimization can sometimes lead to the
+debugger saying the code died on one line when in fact it's happening
+somewhere else.
+
+To build with custom CFLAGS like this, just tell configure what you
+want CFLAGS to be:
+ ./configure CFLAGS="-O -g -fno-inline"
+
+Naturally, unless you're using build directories separate from the
+source directory (see below under "Segregating specialized builds"),
+you need to build every file after changing configure like this, so do
+a make clean before building:
+
+  make clean
+  make 
+  make install
+
+Remember not to "make install-strip" when trying to do debugging
+builds, or your core files will not have debugging symbols in them and
+it will be harder to get useful information out of the debugger.
+
+Segregating specialized builds
+------------------------------
+
+The automake/autoconf setup of xastir makes it easy to maintain several
+different builds of the code without having to clean out the directory and
+rebuild every time.  One does this with "build directories" and executable
+suffixes.
+
+To use this capability, make sure you're starting with a completely
+clean source directory.  In the directory where you normally do your
+"cvs update", do a make distclean.  This will remove anything that
+configure created as well as anything that make created.  From this
+point forward, you don't build xastir in the source code directory
+anymore.
+
+Make an empty directory somewhere --- this will be your build directory.  
+I put my build directories in parallel with the source code directory.  So
+my tree looks like this:
+
+   XASTIR-DEV
+    |
+    +----/xastir (source directory)
+    |
+    +---/build-normal
+    |
+    +---/build-debug
+and so on.
+
+So I would do:
+  cd XASTIR-DEV
+  mkdir build-normal
+
+In the build directory, you run configure using the path to the configure 
+script:
+
+  cd build-normal
+  ../xastir/configure
+  make
+  make install
+
+The configure script uses the path that you gave when you ran it to figure 
+out where to find the source code.
+
+The beauty of this is you can make a second build without doing a make clean:
+  cd XASTIR-DEV
+  mkdir build-debug
+  cd build-debug
+  ../xastir/configure --program-suffix="-debug" CFLAGS="-O -g -fno-inline"
+  make && sudo  make install
+
+This will build a second binary called "xastir-debug" and install it,
+but because you've done the buil in a separate directory, your normal
+compile is untouched.
+
+  cd ~/XASTIR-DEV/xastir
+  cvs update
+  cd ../build-normal
+  make && sudo make install
+  cd ../build-debug
+  make && sudo make install
+
+will update both of your builds.
+
+I also use this technique to share a single xastir source tree over
+NFS, building the code for multiple operating systems in separate
+build directories. 
+  (log in to CYGWIN machine, mount NFS directory)
+  cd /mounted/directory/XASTIR-DEV
+  mkdir build-cygnus
+  ../xastir/configure
+  make && make install
+
+It can also be used to maintain specialized configurations, for
+example a build with "rtree" disabled, a build with map caching
+disabled, etc.  This is a good development trick to keep yourself
+honest --- make sure you can still build all your custom builds when
+you've done a large hacking run, and want to check if you have broken
+things inside ifdefs.  Doing that without build directories requires a
+huge number of configure/make/make distclean cycles.
+
+More?
+-----
+Anything else?  Let's hear about what's still confusing or needs to
+be expanded in this document.  Thanks!
+
+
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 2006-2012 The Xastir Group
+
diff --git a/README.Getting-Started b/README.Getting-Started
new file mode 100644
index 0000000..843252d
--- /dev/null
+++ b/README.Getting-Started
@@ -0,0 +1,902 @@
+
+$Id: README.Getting-Started,v 1.45 2012/08/26 18:34:34 tvrusso Exp $
+
+
+Hello new user, and welcome to Xastir!
+
+
+This document will take you through the steps necessary to get
+Xastir up and running in one of the following configurations:
+
+
+1) Minimal install, which will get you up and running quickly.  It's
+   recommended that you try this configuration first then add to it.
+
+2) Typical install including maps, weather alerts, geo-coding files,
+   etc. so that full regular operation is achieved.
+
+3) Maximum install with all configure options enabled and most of
+   the useful maps loaded/enabled.  All the bells and whistles.
+
+
+Note that you can start with either of the first two options and add
+only the options you wish in order to come up with your own custom
+configuration of Xastir.
+
+These instructions are written for Linux users.  Windows users
+should refer to the README.win32 document instead.
+MacOSX/Solaris/FreeBSD users should refer to the README document
+first, then the INSTALL document and the below instructions for
+further notes.
+
+One question you might ask is whether you can just find a binary on
+the 'net somewhere and install it instead of compiling Xastir from
+sources.  Yes, this is possible.  Xastir changes so often (bug fixes
+and of course adding new features) that you're really limiting
+yourself by using pre-compiled binaries.  Binaries are typically not
+updated all that often, if at all, so you'll forever be behind the
+curve.
+
+Another reason to compile from sources is to customize it to use all
+of the features you have available on your system.  As you add more
+libraries that Xastir can use, you can do a quick
+configure/compile/install and Xastir will be able to take advantage
+of them.
+
+For those that really must have the latest-latest:  Download the
+Xastir sources using CVS instead, then issue the command "cvs
+update" periodically in order to snag the latest changes.  If
+anything comes down the pipe, just configure/make/install and then
+use the latest version.  This avoids large file downloads (after the
+initial download) as it just grabs _changes_ to the sources off the
+'net each time you issue the "cvs update" command.  This is the
+power-user's method of keeping Xastir up-to-date.  See README.CVS
+for details.
+
+After the three configuration sections there's a section on
+operating, which simply talks you through the initial configuration
+settings and how things work.  After that you can refer to the Help
+menu option in Xastir itself, plus the INSTALL and README.* text
+files for additional information.  Please note that the non-English
+help files lag severely behind the English help file.
+
+First of all, NEVER RUN XASTIR AS THE ROOT USER!  You're risking the
+security of your system by attempting it.  Create another regular
+user on your system and use that user for all of your normal
+activity.  This goes for any other normal activity on the system as
+well.  Only use the "root" account for maintenance activities, not
+for regular user activities.  You'll thank me later!
+
+Before we begin, consider subscribing to the Xastir mailing list.
+That's where everyone is kept up-to-date on the latest features,
+plus lots of questions are asked/answered there on a weekly or
+sometimes daily basis.  It's a great way to learn and to stay
+connected with the other Xastir users.  See the mailing links on the
+left of the Xastir home page:  http://www.xastir.org
+You must be subscribed in order to post messages there.
+
+So...  Let's get started!
+
+
+--------------------------------------------------------------------
+--------------------------------------------------------------------
+
+
+Latest info:
+
+*) Xastir starts up with a default world map the first time you run
+it plus pops up a dialog where you can enter your callsign.  Enter
+a callsign, then close/restart Xastir or save the configuration via
+"File->Configure->Save Config Now!".  Either of these methods saves
+the callsign to disk.
+
+*) Xastir includes "Shapefile" map capability by default.  Run the
+script:
+
+    "/usr/local/share/xastir/scripts/get-NWSdata"
+
+as root to download/install NOAA Shapefile maps using the "wget"
+utility.  You'll of course need wget installed in order to fetch the
+files using this method.  Installing the NWS files enables weather
+alert support in Xastir.  Verify that "Map->Enable Weather Alerts" is
+selected and that "Map->Disable All Maps" is _not_ selected, else
+you won't see weather alerts on your screen.
+
+
+--------------------------------------------------------------------
+--------------------------------------------------------------------
+
+
+Sources of help you may find useful:
+
+*) "FAQ" file
+
+*) "INSTALL" file:  Non-Windows instructions for installing Xastir
+   and optional map libraries may be found here.
+
+*) "README" file:  General info and some OS-specific notes.
+
+*) "README.Contributing" file:  Info on how to contribute to the
+   Xastir project.
+
+*) "README.CVS" file:  Info on a more advanced way to keep up-to-date
+   on the latest Xastir sources.
+
+*) "README.Getting-Started" file:  The file you're reading.
+
+*) "README.MAPS" file:  Much of the info about maps and where to get
+   them may be found here.  Also see the Xastir Documentation
+   section, the Wiki pages, at <http://www.xastir.org>
+
+*) "README.win32" file:  For Windows/Cygwin users.
+
+*) "UPGRADE" file:  Useful info for updating some old versions of
+   Xastir.
+
+*) Xastir Web-based documentation, including a set of Wiki pages,
+   found at <http://www.xastir.org>
+
+*) Xastir man page, accessed by typing "man xastir" on a Unix or
+   Unix-like system.  This page is a bit out-of-date.
+
+*) "Help->Help Index" in the Xastir program itself.  Note that only
+   the English language variation of this is somewhat up-to-date.
+
+*) Mailing lists at <http://www.xastir.org>
+
+*) User forums at <http://www.xastir.org>
+
+
+--------------------------------------------------------------------
+--------------------------------------------------------------------
+
+
+Minimal Install:
+----------------
+
+First, let's describe it:  This will get Xastir up and running with
+a few built-in map types.  You'll be on the air or on the 'net
+quickly, then can build upon this working base to add more map
+libraries and other cool features later.
+
+
+Getting the package:
+--------------------
+*) Option 1:  Download one of stable or development snapshots from
+http://www.xastir.org.  There are links from that page or you can go
+to the SourceForge page and click on Files to see the entire set
+that is available.
+
+Once you have the file, create a subdirectory for it to reside.  I
+usually do this:
+
+    cd                      # Go to my home directory
+    mkdir src               # Make a "src" subdirectory
+    cd src                  # Change to it
+    mkdir xastir            # Make an "xastir" subdirectory
+    cd xastir               # Change to it
+    cp /path/filename .     # Copy the downloaded file here
+    tar xzvf filename       # Un-archive the sources
+
+That last step will create yet another xastir directory underneath
+the first one but will have the version number in it, so your full
+path might be something like (starting at your home directory):
+~/src/xastir/xastir-1.7.0
+
+The path just listed is where you'll go in order to run the
+configure and make commands listed below.
+
+    cd  ~/src/xastir/xastir-1.7.0
+
+from an xterm window should take you there.
+
+*) Option 2:  An alternative is to use CVS to snag the sources for
+you.  Using this method you can periodically update to the latest
+released version, the latest "stable" version, or the latest
+development sources.  See README.CVS for info about that option.
+One of the advantages of CVS is that you only pull down the changes
+since you last updated, instead of doing very large file downloads
+each time.  Another advantage is that you can keep up with the
+latest features on a daily basis if you wish, nearly effortlessly.
+
+
+Configure:
+----------
+In order to complete the configure/compile/install of Xastir, you'll
+need some of the development tools and headers installed.  Here's a
+list of a few items you'll need to have installed.  Look for them in
+the development tools sections on your Linux distribution:
+
+
+    bash
+    binutils
+    gcc
+    gcc development headers
+    cpp
+    glibc
+    glibc development headers?
+    freetype2
+    freetype2 development headers
+    openmotif (or Lesstiff or Motif)
+    openmotif development headers (or Lesstiff or Motif)
+    XFree86
+    XFree86 development headers
+    XFree86 fonts
+    XFree86 libraries
+    make (GNU flavor, not BSD flavor)
+    gzip
+    m4
+    grep
+
+
+Note:  Only install one of the Motif packages and the corresponding
+development package to go with it.  Recommendation:  OpenMotif.
+
+If you'd like to install additional packages at this point that may
+be needed later, install these as well:
+
+
+    patch
+    diffutils
+    perl
+    autoconf
+    automake
+    less
+    bzip2
+    curl
+    curl development headers
+    cvs
+    rcs
+    tar
+    liblcms
+    liblcms development headers
+    libtiff
+    less
+    pcre
+    pcre development headers
+    tcl
+    tcl development headers
+    tk
+    zip
+    unzip
+    wget
+    ax25-apps
+    ax25-doc
+    ax25-tools
+    libax25
+    festival
+    festival development headers
+    gawk
+    ghostscript-x11
+    ghostscript-fonts
+    ghostview
+    gv
+    ImageMagick
+    ImageMagick development headers
+
+
+Note that some packages may have dependencies on yet more packages.
+Hopefully your package installation tool will take care of those for
+you.  It's also common for at least one of these packages to forget
+to list some of it's dependencies (ImageMagick is known for that).
+In that case you may have to rely on the compiler to tell you what
+is missing, then go back and re-install a package or two.
+
+When you run the "./configure" step from the "xastir" directory, the
+script will attempt to figure out what facilities are available that
+Xastir can take advantage of.  Sometimes the script guesses wrong
+and you must disable an option and try again.  The correct way to do
+this is (Festival speech synthesizer is used as an example, not that
+I'm picking on Festival or anything):
+
+    ./configure --without-festival
+
+That will guarantee that configure will skip Festival entirely,
+which will set up the Makefiles to skip it, and the Xastir binary
+will be created without any support for it.  Other configure options
+are:
+
+    --without-ax25
+    --without-festival
+    --without-gpsman
+    --without-shapelib
+    --without-imagemagick
+    --without-libproj
+    --without-geotiff
+    --without-gdal
+    --without-pcre
+    --without-dbfawk
+    --without-map-cache
+    --with-errorpopups
+    --with-rtree
+
+
+That said, you probably won't have to use any of these!  Type
+"./configure" all by itself and the script should eventually give
+you a summary of the packages that it will try to compile support
+into Xastir for.  The only time you may want to add some of the
+above options is if the compile hangs up because of one of them.
+You can then add the option to configure, re-create the Makefiles to
+skip that feature, and get Xastir compiled without it.  Once you get
+the problem solved, you can reconfigure and recompile to add that
+feature back in.
+
+At this point, if some things don't appear in the summary that you'd
+like/expect to appear, as long as you get to the "Type 'make' to
+build Xastir" message, you're doing fine.  You can work on getting
+more things in there later.
+
+This is what you'd like to see at the end of the "./configure" run
+(minimum, there may be more "yes" answers):
+
+  AX25.......... : no
+  Festival...... : no
+  GPSMan........ : no
+  ImageMagick... : no
+  libproj....... : no
+  GeoTiff....... : no
+  GDAL/OGR...... : no
+  ShapeLib...... : no
+  pcre.......... : no
+  dbfawk........ : no
+  libgc (Debug). : no
+
+In other words, Xastir should build/compile with NO optional
+libraries installed!  This will still give you USGS GNIS maps,
+APRSdos maps, WinAPRS maps, and PocketAPRS maps, plus audio alerts
+if you have a suitable audio player installed on your system.
+You'll also be able to attach a TNC either in command-line or KISS
+mode and connect it to Xastir.  Mobile support will work with an
+attached serial GPS.  Attached weather stations should work fine
+too.  You won't get online maps or weather alerts with this
+configuration though.  Worry about that stuff later once you get the
+minimal configuration working.
+
+
+Make:
+-----
+Type "make".  That stage should complete with no errors.  You may
+have a warning or two show up, depending on your compiler version
+and your operating system.
+
+
+Make install:
+-------------
+For this stage you need to have root privileges.  "root" is the
+user on a Unix/Linux box that has the ultimate authority over
+everything.  Follow these steps:
+
+    su
+    make install
+    chmod 4755 /usr/local/bin/xastir (optional, see below)
+    exit
+
+The first step takes you to root user privileges.  You'll need to
+type in the root password when it asks for it.  The "make install"
+step installs all of the pieces of Xastir in the appropriate places
+on your system.
+
+The "chmod" step sets up the Xastir executable so that it can assume
+root privileges at the points where it needs to, usually when it
+needs to access serial ports or AX.25 kernel networking ports.  Note
+that if you don't need the above chmod command, don't use it.  It
+will prevent creation of "core" files in case Xastir crashes, which
+makes debugging to figure out the root cause much more difficult.
+There are also some security risks in doing "chmod 4755", as it
+makes Xastir run as the root user at times.  We've tried to minimize
+the risk by giving up root permissions when we don't absolutely
+require them, so the risks are smaller.
+
+At this point you have a minimal Xastir installed.  Jump down to the
+"Operating Xastir" step below.
+
+
+--------------------------------------------------------------------
+--------------------------------------------------------------------
+
+
+Typical Install:
+----------------
+
+First, let's describe it:  This will give you a working Xastir with
+local Shapefile maps, online street/topo/satellite-image maps,
+weather alerts, and audio alerts.  Optionally you can add
+synthesized speech to the mix.
+
+You'll need to run /usr/local/share/xastir/scripts/get-NWSdata as root
+after you do the install in order to get the NOAA data files you'll
+need for the weather alerts.  "get-NWSdata" requires "wget" in order
+to work.
+
+This is what you'd like to see at the end of the "./configure" run
+(minimum, there may be more "yes" answers):
+
+
+-------------------------------------------------------------------
+  MINIMUM OPTIONS:
+    ShapeLib (Vector maps) ................. : yes
+
+  RECOMMENDED OPTIONS:
+    GraphicsMagick/ImageMagick (Raster maps) : yes (GraphicsMagick)
+    pcre (Shapefile customization) ......... : yes
+    dbfawk (Shapefile customization) ....... : yes 
+    rtree indexing (Shapefile speedups) .... : no
+    map caching (Raster map speedups) ...... : no
+    internet map retrieval ................. : yes (libcurl)
+
+  FOR THE ADVENTUROUS:
+    AX25 (Linux Kernel I/O Drivers) ........ : no
+    libproj (USGS Topos & Aerial Photos) ... : no
+    GeoTiff (USGS Topos & Aerial Photos) ... : no
+    Festival (Text-to-speech) .............. : no
+    GDAL/OGR (Obtuse map formats) .......... : no
+    GPSMan/gpsmanshp (GPS downloads) ....... : no 
+-------------------------------------------------------------------
+
+
+Note:  You may see "ImageMagick" instead of "GraphicsMagick" and/or
+"wget" instead of "libcurl" for your installation of Xastir.  Those
+are alternative packages that give similar functionality.  You may
+also see "(internal)" at the end of the Shapelib line, which is fine
+also.
+
+
+TBD
+
+
+--------------------------------------------------------------------
+--------------------------------------------------------------------
+
+
+Maximum Install:
+----------------
+
+First, let's describe it:  This will give you a working Xastir with
+all of the non-debug "configure" options enabled, local maps, online
+street/topo/satellite-image maps, weather alerts, audio alerts,
+synthesized speech, Garmin RINO support, GPS download support,
+search for street address capability, FCC/RAC callsign lookups, and
+all of the supported map types.
+
+This is what you'd like to see at the end of the "./configure" run:
+
+
+-------------------------------------------------------------------
+  MINIMUM OPTIONS:
+    ShapeLib (Vector maps) ................. : yes
+
+  RECOMMENDED OPTIONS:
+    GraphicsMagick/ImageMagick (Raster maps) : yes (GraphicsMagick)
+    pcre (Shapefile customization) ......... : yes
+    dbfawk (Shapefile customization) ....... : yes
+    rtree indexing (Shapefile speedups) .... : yes
+    map caching (Raster map speedups) ...... : yes
+    internet map retrieval ................. : yes (libcurl)
+
+  FOR THE ADVENTUROUS:
+    AX25 (Linux Kernel I/O Drivers) ........ : yes
+    libproj (USGS Topos & Aerial Photos) ... : yes
+    GeoTiff (USGS Topos & Aerial Photos) ... : yes
+    Festival (Text-to-speech) .............. : yes
+    GDAL/OGR (Obtuse map formats) .......... : yes
+    GPSMan/gpsmanshp (GPS downloads) ....... : yes
+-------------------------------------------------------------------
+
+
+Note:  You may see "ImageMagick" instead of "GraphicsMagick" and/or
+"wget" instead of "libcurl" for your installation of Xastir.  Those
+are alternative packages that give similar functionality.  You may
+also see "(internal)" at the end of the Shapelib line, which is fine
+also.
+
+
+TBD
+
+
+--------------------------------------------------------------------
+--------------------------------------------------------------------
+
+
+Operating Xastir:
+-----------------
+
+Again, NEVER RUN XASTIR AS THE ROOT USER!  You're risking the
+security of your system by attempting it.  Create another regular
+user on your system and use that user for all of your normal
+activity.  This goes for any other normal activity on the system as
+well.  Only use the "root" account for maintenance activities, not
+for regular user activities.  You'll thank me later!
+
+Assuming you want to start Xastir up in the English language, you
+can type (from an xterm window):
+
+    xastir
+
+which will start up the program without giving you back a
+command-prompt in your xterm window (until Xastir exits), or you can
+type (from an xterm window):
+
+     xastir &
+
+which will start Xastir in the background, giving you back your
+xterm for more commands.  The typical way to start it is with
+"xastir &".  Of course you can get fancier and attach it to your
+window manager's menus or create an icon on your desktop which
+starts it.  Those are operating system/window manager-specific, so
+we won't cover how to do that here.
+
+The first time you start Xastir it will show a default map of the
+world plus pop up the File->Configure->Station dialog.  Enter a
+callsign on that dialog and press the OK button.
+
+
+Changing the Language:
+
+If you want to start Xastir using some other language, you do that
+with command-line switches when you start Xastir.  Once you use one
+of these switches, that language option becomes "sticky", meaning
+you won't have to enter that command-line switch again unless you
+wish to change languages.
+
+There are some command-line switches that you can 
+If you type "xastir -?", which is an invalid command-line option,
+you'll see this:
+
+  xastir: invalid option -- h
+
+  Xastir Command line Options
+
+  -c /path/dir       Xastir config dir
+  -f callsign        Track callsign
+  -i                 Install private Colormap
+  -geometry WxH+X+Y  Set Window Geometry
+  -l Dutch           Set the language to Dutch
+  -l English         Set the language to English
+  -l French          Set the language to French
+  -l German          Set the language to German
+  -l Italian         Set the language to Italian
+  -l Portuguese      Set the language to Portuguese
+  -l Spanish         Set the language to Spanish
+  -l ElmerFudd       Set the language to ElmerFudd
+  -l MuppetsChef     Set the language to MuppetsChef
+  -l OldeEnglish     Set the language to OldeEnglish
+  -l PigLatin        Set the language to PigLatin
+  -l PirateEnglish   Set the language to PirateEnglish
+  -m                 Deselect Maps
+  -p                 Disable popups
+  -t                 Internal SIGSEGV handler enabled
+  -v level           Set the debug level
+
+
+Ignore those for now unless you need to change the Language.
+
+OK, Xastir should show up on your screen at this point.  We're
+assuming that you're already running X-Windows graphical environment
+at this point.  If you're in command-line Linux/Unix only, Xastir
+won't run.
+
+If you've configured in ShapeLib capability, you'll need to run
+/usr/local/share/xastir/scripts/get-NWSdata as the root user in order
+to get the NOAA data files you'll need for the weather alerts.  The
+script requires "wget" in order to work.  Run this script periodically
+(once every six months perhaps?) to keep your weather alert maps
+up-to-date.  If you're not in the U.S. or one of it's possessions then
+you can safely ignore this download.
+
+
+Various ways to manipulate Xastir:
+
+
+Context-Dependent Operations:
+-----------------------------
+                Normal      Draw-CAD    Measure     Move
+                ------      --------    -------     ----
+Cursor          Arrow       Pencil      Crosshairs  Crosshairs
+LeftClick                                           SelectObject
+LeftDrag        ZoomToArea  ZoomToArea  MeasureArea MoveObject
+MiddleClick     ZoomOut     SetCADPoint ZoomOut     ZoomOut
+
+Alt-F, Alt-V, etc to bring up main menus via the keyboard.  Use
+arrow keys to navigate menus and/or single letters corresponding to
+the "hot" letter (underlined lettter) for each menu item.
+
+"ESC" to back out of the menu system.
+
+
+Global Operations:
+------------------
+LeftClick       Select Menu or GUI Item (when in menus or dialogs)
+LeftDblClick    FetchAlertText (when in View->Wx Alerts dialog)
+RightClick      OptionsMenu
+Home            Center the map on your home station
+PageUp          ZoomOut
+PageDown        ZoomIn
+ArrowUp         PanUp
+ArrowDown       PanDown
+ArrowLeft       PanLeft
+ArrowRight      PanRight
+"="             GridSize++
+"+"             GridSize++
+"Num+"          GridSize++
+"-"             GridSize--
+"Num-"          GridSize--
+"Space"         Activate current widget
+"Tab"           Rotate among widgets
+"Back-Tab"      Rotate among widgets backwards
+
+
+Other Possible External Stimuli:
+--------------------------------
+Send a SIGUSR1 to cause a snapshot to be taken.
+Send a SIGHUP to cause Xastir to save/quit/restart.
+Send a SIGINT, SIGQUIT, or SIGTERM to cause Xastir to quit.
+Connect to TCP port 2023 if Server Port is enabled to send/receive packets.
+Send to UDP port 2023 via the xastir_udp_client program to inject packets.
+
+
+Note that you can also tweak a define/recompile to reverse the
+left/right button functions.
+
+
+
+Configuring Xastir:
+-------------------
+*) Note that the menu's have a dashed line near the top.  If you
+click on that dashed line it acts like a cut-line for the menu and
+detaches that menu from the main menu.  You can then move that menu
+off to another area of your screen.  You might try that with the
+File->Configure menu at this time.
+
+*) Go to File->Configure->Station and set your callsign.  Set up
+other parameters/comment fields on this dialog that may need
+setting.
+
+*) Go to File->Configure->Defaults and set parameters there.
+
+You have the main parameters set now.  Next is to enable some
+interfaces so that you can see some packets come across.  Easiest
+might be the Internet interfaces, assuming the computer you're on
+has Internet access and is hooked up to it currently.
+
+*) Run "callpass" in another Xterm window in order to generate your
+Pass-code number.  Save that number as you'll need it for each
+Interface dialog where you might need to authenticate your callsign.
+Of course you can always run callpass again if you forget it!
+
+*) Go to Interface->Properties then click on "Add".  Click "Internet
+Server".  Another dialog will come up that allows you to enter the
+Host, and the Port.  Enter your Pass-code number here.  People often
+check the "Activate on Startup?" and the "Reconnect on NET failure?"
+options on this box.  You may also assign a comment to this
+interface which describes the interface better for you.  Click "OK"
+to create the interface.  If you checked "Activate on Startup?" then
+the interface will start as well and you'll be receiving packets.
+
+Browse "http://www.aprs2.net/" to find a reasonable set of servers
+to start with.  Another possibility is to use "rotate.aprs2.net"
+port 14580, which theoretically should rotate among the available
+second-tier servers.  See "http://www.aprs2.net" for more info.
+You'll need to put in a filter string, such as "r/35/-106/500" which
+shows you stations that are within 500km of 35dN/106dW (Thanks for
+that one Tom!).  For additional filter settings check out:
+
+    http://www.aprs-is.net/javaprssrvr/javaprsfilter.htm
+
+*) Start that interface from the Interface->Start/Stop dialog if
+it's not started already.  You'll see icons in the lower right
+toggling and see callsigns in the lower left status box if packets
+are coming in.
+
+One thing about configuration:  Most things don't get written to
+Xastir's config file until you choose either "File->Configure->Save
+Config Now!" or you exit Xastir.  Map Selections however are
+immediate.
+
+*) Creating/starting interfaces for other types of devices is
+similar.  If you're wanting to create AX.25 kernel networking ports
+you'll have to refer to the HAM HOWTO documents and perhaps the
+linux-hams mailing list for help.  For AGWPE connections refer to
+that AGWPE docs and mailing list.
+
+It's recommended that if you run a local TNC, you run it in KISS
+mode.  You can do that via the Serial KISS TNC interface, or via
+AX.25 Kernel Networking ports.
+
+Some of the more esoteric types of interfaces may require some
+questions on the Xastir list.  Don't be afraid to ask them as we've
+all been there before.
+
+
+A Note About Paths:
+-------------------
+New path methods were discussed early April, 2005, and are being
+implemented world-wide:
+
+    "WIDE2-2" for fixed stations, balloons, aeronautical-mobile
+    "WIDE1-1,WIDE2-1" for mobiles/portables
+
+With this system, "WIDE1-1" has replaced "RELAY".  Never use
+"WIDE1-1" in anything but the first path slot.  "RELAY", "WIDE",
+"TRACE", and "TRACEn-N" are deprecated and should not be used
+anymore.
+
+If you want to insert a single hop callsign later in the path use
+"WIDE2-1" instead, for example:  "WIDE1-1,WIDE2-1" will go exactly
+two hops and use _either_ home fill-in digi's or mountaintop digi's
+for the first hop, mountaintop digi's only for the second hop.
+
+Home fill-in digi's (only where absolutely needed) should be set up
+to respond to "WIDE1-1" instead of "RELAY".
+
+
+A Note About the Map Directory:
+-------------------------------
+The map directory (/usr/local/share/xastir/maps/) is free-form,
+meaning you can have links in there, subdirectories, etc.  Organize
+it in any way that makes sense to you.  From within the Map Chooser
+you can select a directory name, which will select every map
+underneath that directory, so keep that in mind while organizing
+your maps.
+
+
+Enabling Weather Alerts:
+------------------------
+You must have Shapelib compiled into Xastir.  Xastir now comes with
+Shapelib support built-in.  PRCE/dbfawk are optional.  Install NOAA
+shapefile maps as specified in README.MAPS.  These files must be
+installed into the /usr/local/share/xastir/Counties/ directory.  You
+may use this script to download/install them for you:
+    
+    "/usr/local/share/xastir/scripts/get-NWSdata"
+
+which must be run as the root user, and requires "wget" to work.
+
+A neat trick:  You can copy some of these maps into the
+/usr/local/share/xastir/maps directory somewhere (a new subdirectory
+under there is always fine), then you can select some of these maps
+as regular Xastir maps as well.
+
+
+Enabling FCC/RAC Callsign Lookup:
+---------------------------------
+
+Run the /usr/local/share/xastir/scripts/get-fcc-rac.pl script as root,
+which will download and install the proper databases into the
+/usr/local/share/xastir/fcc/ directory.  At that point the callsign
+lookup features in the Station Info dialog and in the "Station->Find
+Station" menu option should be functional.
+
+
+Enabling Map Feature Lookup:
+----------------------------
+Install USGS GNIS files into the /usr/local/share/xastir/GNIS/
+directory.  Call out the proper file when invoking the "Map->Locate
+Map Feature" menu option.  Note that if you also link a subdirectory
+name under the maps directory back to the
+/usr/local/share/xastir/GNIS/ directory, you'll be able to use the
+GNIS files as maps under the Map Chooser as well.  See README.MAPS
+for how to do this.
+
+
+Enabling Street Address Lookup:
+-------------------------------
+Download the USA.geocode file and install it into the
+/usr/local/share/xastir/GNIS/ directory.  This will enable the
+"Map->Find Address" menu option to work.  Xastir will place a big
+"X" on the map at the street address it finds for you.  This file is
+sometimes available at http://www.dementia.org/geocoder/tgr2003/
+As an alternative you can download the individual state files that
+are located there.
+
+
+Enabling Audio Alarms:
+----------------------
+Download and install sample audio files from Xastir's SourceForge
+download site.  Install the audio files in
+/usr/local/share/xastir/sounds/ directory.
+
+Install a command-line audio player.  Call out the path/name of that
+player in the File->Configure->Audio Alarms dialog.  Common ones are
+vplay and auplay, but there are many others.  Enable the types of
+alarms you desire in that same dialog.
+
+You should be able to test it manually from a shell by typing the
+command in something like this:  vplay filename
+
+Once you find a command that works, type it into Xastir's Audio
+Alarms dialog exactly the same except omit the filename.
+
+
+Enabling Synthesized Speech:
+----------------------------
+*) MacOSX
+    TBD
+
+*) Windows
+    TBD
+
+*) Linux/FreeBSD/Solaris
+Install the Festival Speech Synthesizer.  Configure/compile support
+for it into Xastir.  Start up the Festival server before starting
+Xastir.  Xastir should start up and connect to the server.  Use the
+options in File->Configure->Speech to decide which things you'd like
+Xastir to speak to you about.
+
+Note that the Proximity Alert option in the File->Configure->Speech
+dialog uses the distances set in the File->Configure->Audio Alarms
+dialog.
+
+
+Enabling GPS Waypoint/Track/Route Download Support:
+---------------------------------------------------
+Install GPSMan and gpsmanshp.  Configure/compile support for it in
+Xastir.  Start up GPSMan separately and configure it for your GPS
+and serial port.  You'll see download options for each type on the
+Interface menu.
+
+Note that Xastir requires a version of gpsman at least as recent as 6.1.  Older
+versions of gpsman may not work.
+
+
+Enabling Garmin RINO Support:
+-----------------------------
+Install GPSMan (and gpsmanshp if you wish normal GPS download
+support as well).  Configure/compile support for it in Xastir.
+Start up GPSMan separately and configure it for your GPS and serial
+port.  In the "File->Configure->Timing" dialog you'll see an option
+for "RINO -> Objects Interval".  That sets the interval at which
+Xastir will download waypoints from an attached RINO unit.  Any
+waypoints that begin with "APRS" will have the "APRS" chopped off,
+and the remaining name will be used to create APRS(tm) Objects.  Those
+objects will be plotted on the map and transmitted as well if
+transmit for objects/items is enabled.
+TBD
+
+
+Transmit Enable/Disable Options:
+--------------------------------
+Each interface has a separate transmit enable.  The Interface menu
+also has a few global transmit enables.  All of these must be
+enabled for a particular interface to transmit.  Also, for Internet
+servers, you typically need to authenticate with the server using
+your callsign/pass-code before you're allowed to inject packets into
+the Internet stream which may get gated out to RF.  If you just want
+to talk to other Internet users, you don't need a pass-code to
+authenticate to the servers.
+
+
+Igating Options:
+----------------
+There are igating options on each local TNC interface.  There are
+other global igating options on the File->Configure->Defaults
+dialog.  The global option sets restrictions on all igating.
+
+
+Where stuff is kept:
+-------------------- 
+
+Per-user configurations are kept in each user's ~/.xastir directory, by
+default.  In particular the ~/.xastir/config/xastir.cnf file is where most
+of the configs are kept.  This directory can be optionally specified using
+the -c /path/dir command line option.  Make sure you specify a directory,
+not a file!  Xastir will create the directory and several subdirectories if
+they do not exist when you start up. 
+
+A few executables are installed in /usr/local/bin/.
+
+Scripts are installed in /usr/local/share/xastir/scripts.
+
+Maps are installed in /usr/local/share/xastir/maps/.  Lots of other
+directories are under /usr/local/share/xastir/.
+
+
+More?
+-----
+Anything else?  Let's hear about what's still confusing or needs to
+be expanded in this document.  Thanks!
+
+
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 2005-2012 The Xastir Group
+
diff --git a/README.MAPS b/README.MAPS
new file mode 100644
index 0000000..6337229
--- /dev/null
+++ b/README.MAPS
@@ -0,0 +1,1518 @@
+
+$Id: README.MAPS,v 1.106 2012/03/02 20:28:17 we7u Exp $
+
+
+Recommended Configurations for:
+
+  U.S. Users:
+  -----------
+
+    Minimum:  Shapelib, pcre
+    --------
+      Allows use of all built-in map types plus 2003 (and later) Tigermap data,
+      shapefile weather alerts, and local ESRI Shapefile format
+      maps, including U.S. satellite/image/topo maps via Internet.
+
+    Medium:  Shapelib, pcre, lcms, ImageMagick, libcurl/wget,
+    -------
+
+      Allows use of all the above plus Internet maps and local image
+      maps.
+
+    Maximum:  Shapelib, pcre, lcms, ImageMagick, libcurl/wget,
+    --------  libtif, libproj, libgeotiff
+
+      Allows use of all the above plus USGS topo maps.
+
+    Bleeding edge:  GDAL/OGR
+    --------------
+      Adds more map types, but they're not fully supported yet.  You
+      can certainly get some use out of them though, like overlaying
+      SDTS contour vectors on top of terraserver satellite images.
+
+  Rest of World:
+  --------------
+
+    Minimum:  lcms, ImageMagick, libcurl/wget
+    --------
+      Allows use of all built-in map types plus local and Internet
+      image maps, including Canadian topo maps via Internet.
+
+    Medium:  lcms, ImageMagick, libcurl/wget, Shapelib, pcre,
+    -------
+
+      Allows use of all the above plus ESRI Shapefile maps.
+
+    Maximum:  libproj/libtiff/libgeotiff/GDAL/OGR
+    --------
+      Adds more map types.  Some of these may not be useful in your
+      part of the world.  GDAL/OGR stuff is not fully supported yet.
+
+
+Map Type:           Libraries Required/Notes:
+---------------     -------------------------
+DosAPRS             Built-in.
+WinAPRS             Built-in.
+X-APRS              Built-in.
+MacAPRS             Built-in.
+PocketAPRS          Built-in.
+USGS GNIS           Built-in.  Can split into county-sized chunks
+                    using xastir/scripts/split_gnis.pl to speed
+                    things up.
+Address Lookup      Built-in.
+Weather Alerts      Shapelib
+pre-2003 Tigermaps  Shapelib
+post-2003 Tigermaps Shapelib, pcre
+ESRI Shapefiles     Shapelib
+Image Maps          ImageMagick.  Often need lcms library and others
+                    as well (whatever it takes to make ImageMagick
+                    happy).  Can also use the XPM library for some
+                    image types without installing ImageMagick.
+Internet Maps       ImageMagick plus wget or libcurl.  Often need
+                    lcms library and others as well (whatever it
+                    takes to make ImageMagick happy).
+UI-View Maps        Convert from .INF to .GEO format using
+                    xastir/scripts/inf2geo.pl
+OziExplorer Maps    Convert some maps to .GEO format using
+                    xastir/scripts/ozi2geo.pl
+USGS DRG Topo       libtiff, libtiff-devel, libproj, libgeotiff
+USGS SDTS           GDAL/OGR.  Preliminary.
+MapInfo             GDAL/OGR.  Preliminary.
+Tiger/Line Raw      GDAL/OGR.  Preliminary.
+Microstation DGN    GDAL/OGR.  Preliminary.
+S57                 GDAL/OGR.  Preliminary.
+APRS Overlays       Convert to Shapefile maps with scripts/pos2shp.pl
+
+
+The default map, "worldhi.map", is used with permission of its creator, Keith Sproul, WU2Z.
+
+
+How to Use APRS Overlay Maps (*.POS files) within Xastir:
+---------------------------------------------------------
+    Use the "xastir/scripts/pos2shp.pl" script to convert the
+    overlay files to ESRI Shapefile maps:
+
+        # ./pos2shp.pl test.pos testmap
+        # cp testmap* /usr/local/share/xastir/maps/.
+
+    Xastir:  Map->Configure->Index: Add New Maps
+             Map Chooser:  Select the "testmap" map
+
+
+Getting Maps and other Data Files for Xastir:
+---------------------------------------------
+
+      NOTE:  Set map FILES to permissions 644 ("rw-r--r--"), map
+      DIRECTORIES to 755 ("rwxr-xr-x") using the "chmod" command.
+      These permissions will allow anyone on the box to read the map
+      files, and access the map directories. Type these
+      commands exactly as shown in order to set the map directory's
+      permissions properly.  Do this as the root user:
+
+      cd /usr/local/share/xastir/maps
+      find . -type d -exec chmod 755 {} \;
+      find . -type f -exec chmod 644 {} \;
+
+      You can repeat these commands at anytime, to fix up errant map
+      permissions that are created by downloading/installing new
+      maps.
+
+      Currently the maps/GPS directory needs to be writable by normal users
+      in order to support downloading GPS data using GPSMan.  This will be
+      changed at some future date, moving this directory into the user's
+      home directory instead.
+
+      cd /usr/local/share/xastir/maps
+      chmod 777 GPS
+      find GPS -type d -exec chmod 777 {} \;
+      find GPS -type f -exec chmod 777 {} \;
+
+
+
+    Download some maps:
+
+      If you compiled with ImageMagick and have wget or libcurl installed,
+      you can skip this step and use the online Tiger/Terraserver maps
+      exclusively. However, having maps on your computer is often faster
+      than transferring images over a modem, and is not subject to the
+      failures of your Internet connection.  See the section below on map
+      caching for an exciting feature that works with most online maps to
+      really speed things up!
+
+      You can have any number of maps in the /usr/local/share/xastir/maps
+      directory.  You can organize the maps however you like. You can also
+      use symbolic links to link to files/directories on other disks. Map
+      files are loaded in the order that they appear in the chooser unless
+      you adjust the layering priorities in the "Properties" dialog (it's
+      recommended that you use these now instead of a directory hierarchy to
+      choose the layering).
+
+      There are many methods for organizing many maps. Create a map
+      hierarchy using something that makes sense to you. The old method of
+      creating transparent/filled or raster/vector directories has been
+      superceded by the new map layering features in the Map
+      Chooser->Properties dialog. It's now suggested that the map layering
+      be done there, and the directory layout designed to make it easiest
+      for the user to select maps. Perhaps a good start would be:
+
+           World/
+           Canada/
+           Canada/Province/
+           USA/
+           USA/State/WA/
+           USA/State/WA/County/
+           ...
+           GNIS/
+           Overlay/
+
+      Please note that the map directories are entirely up to the user
+      now. Use the map layering facilities (Map Chooser->Properties) to
+      determine the order in which they will be drawn, and to determine
+      which will draw filled areas.  Note that raster maps will always draw
+      filled, not matter what the setting suggests.  For vector maps, you
+      have a choice of:
+
+            Fill = No       Polygons will never be filled
+            Fill = Yes      Polygons will always be filled
+            Fill = Auto     Polygon fill is determined by map (or if it's a
+                            Shapefile, by any associated dbfawk file).
+
+      Map types available by extension:
+
+      Vector Format:
+      .shp/.shx/.dbf  Shapefile vector map (need all three files)
+      .pdb            PocketAPRS vector map
+      .map            APRSdos/WinAPRS/MacAPRS vector map
+      .gnis           GNIS labels file (actually points instead of vectors)
+      .geo            Vector map or Internet vector map.  Note that for
+                      http/ftp-based maps Xastir requires an IMAGESIZE line.
+
+      Raster Format:
+      .tif/.fgd       geoTIFF raster image map
+      .geo            Raster image map or Internet raster image map.  Note that
+                      for http/ftp-based maps Xastir requires an IMAGESIZE line.
+
+      Note:  .geo is listed twice because it can fit in both categories,
+      depending on the base format of the map file that the .geo file
+      points to.  .geo files are handled by the XPM library or by
+      ImageMagick, so most anything that can be handled by those installed
+      libraries can by handled by Xastir.
+
+      A few maps of various types are available from:
+
+        http://wetnet.net/~we7u/xastir/maps/
+
+      Here's a page that we'll try to keep up-to-date which will have lots of
+      links to download-able maps on it:
+
+        http://www.xastir.org/wiki/index.php/Xastir_Maps
+
+     Dos/Win/MacAPRS style vector/fill maps:
+
+      http://www.winaprs.com/Maps.htm
+      http://www.cnunix.com/ftp/hamradio/rutgers.mirror/maps/maps2/
+      ftp://ftp.tapr.org/aprssig/maps/
+
+       WORLDHI.MAP is suggested as a basic view of the world map.
+
+      You can use any of the other maps available from this site. Many of
+      them were created from Tiger/Line maps, but they are several years out of
+      date. It is suggested that you don't use these as your primary
+      street-level maps; the newer shapefile-based maps are usually preferable.
+      In cases where you cannot compile shapefile support, these maps suffice.
+
+      
+     PocketAPRS vector maps:
+
+      The WinAPRS 2.51 distribution included the full collection of 
+      PocketAPRS vector maps for the USA. The download is about 60MB, from the
+      TAPR ftp site.
+
+        ftp://ftp.tapr.org/aprssig/winstuff/WinAPRS/waprs251.zip
+
+   
+     Raster Maps:
+
+      For Canada there is a country wide set of topographic map images available 
+      from the "Department of Natural Resources Geomatics Canada". Running 
+      /scripts/toporama250k.pl will pull down 430mb of 1:250k map images 
+      from that departments site. If thats not enough data, running
+      /scripts/toporama50k.pl will pull down around 10gigs
+
+**** Note that recent changes at the "Department of Natural Resources Geomatics 
+Canada" have made these scripts fail.  Changes to the scripts are being coded 
+and tested.  CVS well be updated once the scripts are proven to work again. ****
+
+
+     For Ireland, EI8IC (http://www.mapability.com) has produced a set of overlay 
+     maps that show the County Borders, Main Towns and Roads.  John, EI7IG, has 
+     created a set of ".geo" files to go with them and they are all available in one 
+     tarball from [http://ireland.aprs2.net/xastir/IrelandMaps/Ireland.tar.gz 
+     ireland.aprs2.net] They are free for non-commercial use.
+
+     Also available are a map of the 
+     [http://ireland.aprs2.net/xastir/IrelandMaps/Ireland1600x2000.bmp country], with 
+     an associated [http://ireland.aprs2.net/xastir/IrelandMapsIreland1600x2000.geo 
+     geo] file, the [http://ireland.aprs2.net/xastir/IrelandMaps/Ireland1600x2000.bmp 
+     South East], it's associated  
+     [http://ireland.aprs2.net/xastir/IrelandMapsIreland1600x2000.geo geo] and a 
+     [http://ireland.aprs2.net/xastir/IrelandMaps/IrishMET.geo Weather Radar] .geo file.
+
+
+     Shapefile format maps (Requires shapefile support):
+
+      Shapefile format maps are slowly becoming the standard vector format of
+      maps used with Xastir. Xastir 1.3.2 and above by default enable dbfawk
+      support for parsing shapefile metadata, see below.
+
+      A nice world map is available at http://aprsworld.net/gisdata/world/
+      thanks to James Jefferson, TerraSpace, Russia, and the Digital Chart
+      of the World (for Antarctica).  Note that this file is currently
+      available only in uncompressed or in tar/bzip2 format.  To decompress
+      the latter file, you'd type "bunzip2 filename" and then
+      "tar xvf filename".
+   
+      TIGER/Line Shapefiles:
+
+      Tiger/Line 2006 Second Edition data converted to shapefile format is 
+      available from ftp://aprs.tamu.edu/. Look in the "pub/TIGER_2006_SE" 
+      directory.  These maps only work with dbfawk support
+
+      Unpack the zipfiles in your maps directory.  I recommend creating
+      a "TIGER_2006_SE" subdirectory or something similar, and unpacking
+      the zipfile there.  When unpacked, each state zipfile will produce
+      a directory with the state's postal abbreviation as its name, and
+      two subdirectories, "Polylines" and "Polygons."  These directories
+      each contain shapefiles with different information in them --- Polylines
+      are linear features such as roads and streams, Polygons are area features
+      such as parks and airports.  You need both, even though they have the
+      same names (the name of the county they cover).
+
+      You can also create your own TIGER/Line shapefiles from the raw
+      data at the Census web site,
+      http://www.census.gov/geo/www/tiger/index.html.  
+      The process requires two conversions: converting the linear
+      features, and assembling the polygon features.  The TIGER/Line data is
+      a topological format, and polygons are not stored in a simple manner;
+      this second step is time consuming.
+
+      To convert the polylines: 
+      Download the county files you want. Then unzip each one into its
+      own directory (call it "in_directory"). Then cd to in_directory and
+      run the following command:
+
+            ogr2ogr -f "ESRI Shapefile" -t_srs EPSG:4326 foo .
+
+      This will create a subdirectory of in_directory called "foo" which
+      will contain a number of shapefiles and auxiliary data. The files
+      called "CompleteChain.*" are the ones you want; they are the polylines
+      corresponding to roads and other linear features. Copy these to your
+      xastir maps directory and rename them to the name of the county they
+      represent. Then install tgr2shp.dbfawk in your share/xastir/config
+      directory and reindex maps. Ta da. See above: tgr2shp.dbfawk is now
+      part of the xastir distribution..."
+
+      Note that you'll need dbfawk support compiled into Xastir to make
+      these Tiger/Line maps look nice.  For the 2003 TIGER/Line data,
+      Derrick Breshear created scripts to process all of the Tiger/Line raw
+      data into Shapefiles, then they were put on a download site made
+      available by Kevin Glueck, "http://xastir.tamu.edu/".  The 2006 Second
+      Edition data were processed by Jason Winningham and made available on
+      the ftp://aprs.tamu.edu/ site by Gerry Creager.  Thanks go to Tom,
+      Derrick, Kevin, Jason and Gerry for making these maps so accessible to
+      the rest of us.
+
+      The second step to rolling your own TIGER/Line shapefiles is to
+      assemble the polygons.  This requires GDAL/OGR configured with python
+      support, and requires that you have the Python language installed.
+      Use the script Xastir_tigerpoly.py included in the "scripts" directory
+      of Xastir's source tree.
+
+      As an example, if you have un-zipped the file TGR35001.zip (the
+      TIGER/Line file for Bernalillo County, NM) into a directory called
+      TGR35001, then
+   
+            Xastir_tigerpoly.py TGR35001 Bernalillo_County_NM_Polys.shp
+
+      would create a shapefile of TIGER polygons (water bodies, political
+      boundaries, parks, wilderness areas) that you can install in your maps
+      directory and read directly using normal shapefile support.
+      
+      Viewing these shapefiles as filled polygons requires dbfawk support,
+      and the rules for displaying them are contained in the file
+      tgr2shppoly.dbfawk.
+
+
+      Tiger/Line 2000 map data is available from:
+      http://www.esri.com/data/download/census2000_tigerline/index.html
+      but requires free registration.  A example of these types of files can
+      be found at "http://wetnet.net/~we7u/xastir/maps/shapefile/USA/WA/".
+      You'll need to run "tar xzvf <filename>" on each one of the files
+      from that last site after downloading.  Some layers that may be of
+      interest:
+
+
+        CMSA/MSA Polygons 2000              tgr*msa00.shp
+        PMSA Polygons 2000                  tgr*pms00.shp
+        Consolidated Cities                 tgr*city.shp
+        County - Current                    tgr*cty.shp
+        County 2000                         tgr*cty00.shp
+        Designated Places 2000              tgr*plc00.shp
+        Designated Places Current           tgr*plccu.shp
+        Key Geographic Locations            tgr*kgl.shp
+        Landmark Points                     tgr*lpt.shp
+        Landmark Polygons                   tgr*lpy.shp
+        Line Features - Hydrography         tgr*lkH.shp
+        Line Features - Landmarks           tgr*lkD.shp
+        Line Features - Misc. Transport     tgr*lkC.shp
+        Line Features - Non-visible         tgr*lkF.shp
+        Line Features - Physical            tgr*lkE.shp
+        Line Features - Rails               tgr*lkB.shp
+        Line Features - Roads               tgr*lkA.shp
+        Line Features - Unknown             tgr*lkX.shp
+        School Districts - Elementary       tgr*elm.shp
+        School Districts - Middle           tgr*mid.shp
+        School Districts - Secondary        tgr*sec.shp
+        School Districts - Unified          tgr*uni.shp
+        Traffic Analysis Zones              tgr*taz.shp
+        Urban Areas                         tgr*urb.shp
+        Water Polygons                      tgr*wat.shp
+        Alternate Feature Names             tgr*alt.shp
+        Address Matching Info               tgr*add2.shp
+        ZIP+4 Left and Right Info           tgr*zip.shp
+        Key Geographic Location Addresses   tgr*add.shp
+        Landmark Polygon Names              tgr*lpy2.shp
+        Landmark Polygons Multi-Landmark    tgr*lpy3.shp
+        Water Polygons Multi-Names          tgr*wat2.shp
+
+      Older Tiger97 maps converted to shapefile download-able from:
+      http://www.mapshots.com
+
+      Some other shapefile format maps are available at:
+      http://www.nws.noaa.gov/geodata/
+
+      Still other shapefiles are available from esri.com, geographynetwork.com
+      and gisdatadepot.com (from their "free data" link).  Lot's of useful
+      stuff at these sites, just look around.  You can also check
+      with your County GIS office for shapefiles of your county.  You can
+      convert them from State Plane to Lat/Long projection using
+      instructions later in this document.
+
+      Canada street maps in Shapefile format are available at
+      http://www.geobase.ca
+
+      If you also use GeoTIFF images, get the handy usgs_24kgrid.zip file from
+      http://data.geocomm.com/quadindex/.  This file provides a grid of all of
+      the 7.5' maps and their names for the U.S.
+
+      A nice world map is available at http://aprsworld.net/gisdata/world/
+      thanks to James Jefferson, TerraSpace, Russia, and the Digital Chart
+      of the World (for Antarctica).  Note that this file is currently
+      available only in uncompressed or in tar/bzip2 format.  To decompress
+      the latter file, you'd type "bunzip2 filename" and then
+      "tar xvf filename".
+
+      www.bts.gov has the "National Transportation Atlas" that you can download
+      pieces of (at least for the larger layers) or ask for (free) CD-ROM's to be
+      mailed to you.
+
+      -----
+      Re-projecting shapefiles (or: why doesn't my shapefile show up?)
+
+      A shapefile is pretty much just a collection of points and lines
+      between points.  Xastir expects that those points are expressed in
+      degrees of longitude and latitude with positive values indicating N
+      and E and negative values indicating S and W.
+
+      One often comes across shapefiles with data in some other format, such
+      as UTM or state-plane projections with units in meters or feet.  You
+      must re-project these sorts of shapefiles in order to use them in
+      Xastir.  You must either know what the current format is of the
+      shapefile you wish to re-project, or have the .prj file that some
+      shapefiles come with.
+
+      Fortunately, the shapelib-1.2.10 distribution (which you probably
+      compiled and installed to enable shapefile maps in Xastir) includes a
+      tool for performing this re-projection.
+
+      First make the shpproj utility by:
+
+      1. change to directory: <shapelib source directory>/contrib
+      2. type 'make' to compile the contrib files
+      3. Optionally install shpproj by copying it to /usr/local/bin
+
+      shpproj takes 4 arguments:
+
+          shpproj shp_file new_shp -i="in_params" -o="out_params"
+
+      shp_file is the name of your existing shapefile triad (without the
+      extension).
+
+      new_shp is the name of your new shapefile triad (which doesn't exist
+      yet).
+
+      -i="in_params" are the parameters describing the existing shapefile.
+
+      -o="out_params" are the parameters describing the new shapefile.  We
+      want this to be "geographic".
+
+      Examples:
+
+      Convert shapefile triad from US State-plane, South Central Texas region
+      (FIPS code 4204), in feet to geographic:
+
+        shpproj stateplane_shapefile geographic_shapefile \
+             -i="init=nad83:4204 units=us-ft" -o=geographic
+
+      Convert UTM zone 15 to geographic:
+
+        shpproj utm_shapefile geographic_shapefile \
+             -i="proj=utm zone=15 units=m" -o=geographic
+
+      To get a listing of the FIPS codes, you need to have proj installed
+      (see elsewhere in this file for more information).  Look in the
+      "<proj source directory>/nad/nad.lst" file.
+
+      For more detailed documentation, see the shpproj.txt file in the
+      "<shapelib source directory>/contrib/doc" directory.
+
+      There's a resource for looking up the FIPS codes for a particular
+      area:
+
+            http://www.aprs.net/fips/
+
+      An important note about using shpproj to re-project maps 
+
+      The shpproj program cannot be used to convert shapefiles unless they're
+      already using the NAD83 or WGS84 datum.  shpproj will do the conversion
+      if you ask it to, but it will do it incorrectly.
+
+      A simple program to convert shapefiles between various projections
+      that does do datum conversions correctly is "shpcs2cs," available
+      from
+          <http://www.swcp.com/~russo/shape_web/>
+      That program requires libproj to be installed properly, and uses a 
+      command line format similar to the "cs2cs" program that comes with 
+      libproj.
+
+      If you already have GDAL installed, you should have the "ogr2ogr" 
+      program available to you.  ogr2ogr will not only convert projections
+      and geodetic datum correctly, but will also convert format (ArcView
+      binary format to shapefile, TIGER/Line files to shapefile, etc.).
+      Some detailed instructions for using ogr2ogr to do this conversion
+      are available at 
+          <http://www.swcp.com/~russo/shape_web/>
+
+      -----
+
+      Using "dbfawk" to interpret shapefile DBF data:  Each shapefile
+      map (*.shp, *.shx) comes with a DBase data file (*.dbf) in which
+      each shape in the .shp file has a corresponding set of descriptive
+      data about that shape in the .dbf file.  While shapefiles are all
+      a standard format and will most always draw (possibly after having
+      been re-projected with shpproj), the corresponding .dbf data varies
+      widely depending on the data source.  For example, US Census
+      Tiger/Line files contain 20 attributes for each shape including such
+      values as the name of the shape (i.e. street name), and a "Census
+      Feature Class Code" (CFCC) which indicates whether a shape is a
+      dirt road or a superhighway, for example.   
+
+      In "pre-dbfawk" Xastir, knowledge of the various sources of
+      shape files was built into the program and it was necessary to
+      add code to support new shapefile sources (such as those
+      produced by local government agencies, non-US, etc.).  Xastir
+      with dbfawk moves this logic into metadata files named *.dbfawk.
+      These files are linked to the .shp/.dbf files they belong with in
+      one of two ways:
+        1. "Signature" recognition.  .dbfawk files located in the config/
+           directory are read to find the "dbfinfo" signature, which is
+           simply the ordered list of attribute names found in the .dbf file.
+           If you browse config/*.dbfawk you will see dbfawk's for the most
+           well know shapefile types.  For example, tgrlk.dbfawk matches
+           all the "tgr*lk?.dbf" US Census Tiger/Line files.  When a shapefile
+           map is displayed, it's .dbf signature is matched up with one of
+           the config/*.dbfawk files.
+        2. "Tied" to a file.  If you installed a .dbfawk file in the same
+            directory as the .shp and .dbf files (e.g. sample.shp, sample.dbf
+            get a corresponding sample.dbfawk) then that file is used instead
+            of signature matching.
+      The first method allows a single .dbfawk file to be automatically
+      used for hundreds of standard shapefile maps.  The later allows you
+      to customize how your particular shapefile map displays.
+
+      What's in a .dbfawk file?  The best documentation of these files
+      is found by looking at the commented examples in config/*.dbfawk.  
+      dbfawk is modeled after the "awk" pattern scanning and processing 
+      language -- but, it is *not* exactly awk:
+        - Regular expression syntax is that used by Perl (the pcre library
+          is used) rather than pure awk.
+        - Action statements are much more limited than full-blown awk.
+        - The concept of records and fields is used since a .dbf record
+          is structured of usually several fields (name, feature type, etc.).
+      That said, what dbfawk does is allow a great degree of control of
+      how and when shapes and their names are displayed.  This is done by
+      setting the values of several "builtin" variables [Technically, these 
+      are only built-in to shapefile support.  Potentially the awk-like 
+      code can be extended to other uses.]:
+        dbfinfo:   the "signature" to match against.
+        dbffields: which fields to read from the .dbf file.
+        color:     what color code to display the shape with.
+        lanes:     width of the shape.
+        name:      name of the shape.
+        key:       search key (used for WX alerts to find the shape)
+        symbol:	   symbol for landmarks, etc.
+        filled:	   draw polygons filled.  Filled="Yes" or "No" in the Map
+                   Properties dialog will override this option.  Set to "Auto"
+                   in that dialog to have the dbfawk file control this.
+        fill_style: style of fill (0=solid, 1=FillTiled, 2=FillStippled, etc.)
+        fill_color: color of fill
+        fill_stipple: stipple pattern if fill_style=2 ("FillStipple")
+                      0=13 percent, 1=25 percent, 2=50 percent.
+        pattern:   solid or dashed lines.
+        display_level: at what zoom level to begin displaying the shape
+        label_level: at what zoom level to begin displaying labels
+        label_color: color to use for labels
+      
+      Execution of a dbfawk file:  Just like awk, the file consists of
+      patterns that are matched against input data and actions to take
+      when the pattern matches.  There are four special patterns in dbfawk:
+        BEGIN_RECORD: action is executed just before parsing a record.
+        BEGIN: action is executed just before parsing a field.
+        END: action is executed just after parsing the field.
+        END_RECORD: action is executed just after parsing a record.
+      All other patterns are regular expressions that are matched against
+      a data value of <fieldname>=<value>.  For example:
+        FENAME=Main
+
+      Actions in dbfawk files consist of setting variables and two special
+      actions:
+        next: skips to the next field in the record.
+        skip: skips to the next record.
+      If neither next nor skip is given in the action, then processing falls
+      through to the next pattern/action pair in the dbfawk file.
+      
+      The special dbffields variable is used to list which fields of the
+      record to be processed and in what order.  The order is significant
+      since it may take several DBF fields to build up a complete name.
+      For example, in Tiger/Line, the street name is actually the 
+      concatenation of FEDIRP, FENAME, TYPE, FEDIRS.  Here's an excerpt
+      from tgrlk.dbfawk to demonstrate:
+        BEGIN {dbffields="TLID:FEDIRP:FENAME:FETYPE:FEDIRS:CFCC"}
+        ...
+	/^FEDIRP=(.+)$/ {name="$1 ";next}
+	/^FENAME=United States Highway (.*)$/ {name="$(name)US $1"; next}
+	/^FENAME=State Highway (.*)$/ {name="$(name)State $1";next}
+	/^FENAME=State Route (.*)$/ {name="$(name)SR $1";next}
+	/^FENAME=(.*)$/ {name="$(name)$1; next}
+	/^FETYPE=(.+)$/ {name="$(name) $1"; next}
+	/^FEDIRS=(.+)$/ {name="$(name) $1"; next}
+      
+      Creating and testing dbfawk files:  You can test an existing dbfawk
+      file by setting debug level 16 in Xastir (this will generate a huge
+      amount of map rendering debug output, including dbfawk info):
+       "./xastir -v 16 2>/tmp/log"
+      Or, use "testdbfawk" which reads a .dbf file (or single field assignments
+      on the command line).  For example:
+	testdbfawk -D . -d tgr36119lkA.dbf 2>&1|less
+	20 Columns,  42427 Records in file
+	sig: TLID:FNODE:TNODE:LENGTH:FEDIRP:FENAME:FETYPE:FEDIRS:CFCC:FRADDL:TOADDL:FRADDR:TOADDR:ZIPL:ZIPR:CENSUS1:CENSUS2:CFCC1:CFCC2:SOURCE
+	DBF Signatures match!
+	name=Hancock Ave, key=80309984, symbol=, color=40, lanes=1, filled=0, pattern=1,display_level=96,label_level=16
+
+      testdbfawk takes the following command line syntax:
+        testdbfawk --help
+          Prints command line usage
+        testdbfawk -D directory -d file.dbf
+          Scans directory for dbfawk files with signatures matching file.dbf,
+          runs the dbfawk program that matches if it's found.
+        testdbfawk -f file.dbfawk -d file.dbf
+          runs the dbfawk file "file.dbfawk" over the dbf file "file.dbf"
+
+      So in the example above, testdbfawk scans the current directory
+      for dbfawk files with signatures that match tgr36119lkA.dbf's
+      signature.  testdbfawk dumps its output to standard error, so in
+      the example standard error is redirected to standard out and
+      piped into "less" for paging.
+
+      To create a .dbfawk file, you need to understand the layout and contents
+      of your .dbf file.  Use "dbfinfo" and "dbfdump" which are in the shapelib
+      contrib directory.  Dbfinfo will list the field names and dbfdump will
+      dump out all fields of all records.  Take the field names from dbfinfo,
+      and concatenate them together in order, separated by ":" to make the
+      dbfinfo= signature variable assignment.
+
+      Your best bet is to start with an existing .dbfawk file as an example.
+
+      Dbfawk hints and kinks:  You have to think like an awk programmer and
+      realize that the order that rules are listed matters, that it's important
+      to use "next" as soon as it makes sense so other rules aren't looked at
+      unnecessarily and, to use "skip" when you want to fix bad dbf data.
+      For example, my county's Tiger/Line maps have several coding errors
+      where a segment of a main highway is incorrectly labeled as a local 
+      street.  This rule overrides one of those incorrect records:
+	# This Furnace Dock Rd segment is really Rt 9!
+	/^TLID=139773160$/ {name="Briarcliff-Peekskill Pky"; display_level=8192; label_level=512; color=4; lanes=4; skip;}
+      TLID is the Tiger/Line ID which is the unique identifier for this 
+      segment.
+      -----
+
+    Rolling your own shapefile maps:
+
+    It is relatively easy to create your own shapefile maps (for example,
+    if you want to highlight a walk-a-thon course).  There are several
+    methods available with Xastir:
+
+    1. Use GPSMan to download a GPS track to a shapefile.
+
+    2. Save a station tracklog of an actual station or an object that
+       you manually move along the course.  When you select Station Info,
+       you are presented with the option to save the track, which gets
+       put in 
+       .xastir/tracklogs/<datestamp>_<callsign>_APRS_Trail_<color>.*
+       You can move the .shp, .shx, and .dbf files to your maps directory.
+       Use DBFAWK to make a map-specific .dbfawk file.  For example:
+	BEGIN {dbfinfo="Credits:DateTime";dbffields="Credits:"}
+	BEGIN_RECORD {key=""; lanes=4; color=12; name=""; filled=0; 
+           pattern=1; display_level=8192; label_level=32; symbol=""}
+       This makes the track width 4 and red (12).
+
+    3. You can use xastir's "object" capability to generate shapefile maps.
+       a) Turn off object transmission using 
+          Interface->Disable Transmit:Objects
+       b) Put objects where you want.  Set the display symbol as you like it.
+       c) run the "object2shp.pl" script in the scripts directory
+           (/usr/local/share/xastir/scripts/object2shp.pl in most installations)
+          to generate a shapefile:
+            /usr/local/share/xastir/scripts/object2shp.pl ~/.xastir/object.log myshape
+          This requires the four shapelib utilities "dbfcreate", "shpcreate",
+          "shpadd" and "dbfadd" as described below.
+       d) EXIT XASTIR
+       e) REMOVE ~/.xastir/config/object.log
+       f) move "myshape.shp," "myshape.shx," and "myshape.dbf" to your maps
+          directory.
+       g) restart xastir.  
+       h) select your newmap in the map chooser.
+      Creating maps in this way is basically just a scripted version of the
+      manual map generation technique in (4) below.
+
+    4. You can also use the shapelib tools (shpproj was presented earlier)
+       to manually create a shapefile.  For example, the following 
+       marks out the mile-posts for a marathon, using tgrlpt.dbfawk
+       (US Census Tiger/Line landmark points with an APRS(tm) symbol extension) 
+       for the metadata:
+       #!/bin/sh
+       # turn mileposts into a Tiger landmark shapefile
+
+       rm -f posts.shp posts.dbf
+       shpcreate posts point
+       dbfcreate posts -n ID 8 0 -s CFCC 3 -s NAME 30
+       shpadd posts -74.0570 40.6025
+       dbfadd posts 1 'X\m ' Start
+       shpadd posts -74.0443 40.6065
+       dbfadd posts 2 'X\m ' 1M
+       shpadd posts -74.0353 40.6093
+       dbfadd posts 3 'X\m ' 2M
+       shpadd posts -74.0268 40.6260
+       dbfadd posts 4 'X\m ' 3R
+       shpadd posts -74.0200 40.6277
+       dbfadd posts 5 'X\m ' 3G
+       shpadd posts -74.0270 40.6252
+       dbfadd posts 6 'X\m ' 3B
+       shpadd posts -74.0197 40.6395
+       dbfadd posts 7 'X\m ' 4R
+       shpadd posts -74.0203 40.6388
+       dbfadd posts 8 'X\m ' 4BG
+       shpadd posts -74.0077 40.6508
+       dbfadd posts 9 'X\m ' 5R
+       shpadd posts -74.0083 40.6503
+       dbfadd posts 10 'X\m ' 5BG
+       shpadd posts -73.9957 40.6623
+       dbfadd posts 11 'X\m ' 6R
+       shpadd posts -73.9962 40.6617
+       dbfadd posts 12 'X\m ' 6BG
+       shpadd posts -73.9850 40.6743
+       dbfadd posts 13 'X\m ' 7R
+       shpadd posts -73.9858 40.6738
+       dbfadd posts 14 'X\m ' 7BG
+       shpadd posts -73.9782 40.6865
+       dbfadd posts 15 'X\m ' 8M
+       shpadd posts -73.9597 40.6890
+       dbfadd posts 16 'X\m ' 9M
+       shpadd posts -73.9573 40.7007
+       dbfadd posts 17 'X\m ' 10M
+       shpadd posts -73.9622 40.7122
+       dbfadd posts 18 'X\m ' 11M
+       shpadd posts -73.9515 40.7230
+       dbfadd posts 19 'X\m ' 12M
+       shpadd posts -73.9520 40.7345
+       dbfadd posts 20 'X\m ' 13M
+       shpadd posts -73.9525 40.7465
+       dbfadd posts 22 'X\m ' 14M
+       shpadd posts -73.9403 40.7503
+       dbfadd posts 23 'X\m ' 15M
+       shpadd posts -73.9578 40.7587
+       dbfadd posts 24 'X\m ' 16M
+       shpadd posts -73.9556 40.7675
+       dbfadd posts 25 'X\m ' 17M
+       shpadd posts -73.9465 40.7808
+       dbfadd posts 26 'X\m ' 18M
+       shpadd posts -73.9372 40.7935
+       dbfadd posts 27 'X\m ' 19M
+       shpadd posts -73.9272 40.8047
+       dbfadd posts 28 'X\m ' 20M
+       shpadd posts -73.9343 40.8142
+       dbfadd posts 29 'X\m ' 21M
+       shpadd posts -73.9453 40.8050
+       dbfadd posts 30 'X\m ' 22M
+       shpadd posts -73.9525 40.7923
+       dbfadd posts 31 'X\m ' 23M
+       shpadd posts -73.9630 40.7810
+       dbfadd posts 32 'X\m ' 24M
+       shpadd posts -73.9720 40.7696
+       dbfadd posts 33 'X\m ' 25M
+       shpadd posts -73.9811 40.7683
+       dbfadd posts 34 'X\m ' 26M
+       shpadd posts -73.9763 40.7720
+       dbfadd posts 35 'X\m ' Finish
+    ---------
+
+    Splitting large Shapefile maps into regularly-sized tiles:
+
+      Look for "shp2tile" at http://imaptools.com/tools/, it does
+      exactly that.  This can speed up Xastir tremendously if you're
+      zoomed in quite a bit on a large Shapefile map (or maps).  If
+      it is broken into tiles Xastir only has to load the tiles of
+      interest instead of slogging through the entire large file
+      each time.
+
+
+    GeoTIFF Map files (requires GeoTIFF):
+
+      If you compiled in geoTIFF support, you can use USGS DRG topographic
+      maps. These are primarily useful to U.S. users. DRG topo maps can be
+      found for free for most states, and can be purchased for others.
+
+        http://www.bianifc.org/gis_gps/gps/drgfree.html
+        http://www.gisdatadepot.com
+
+      or try a google search with "free drg maps" as the search query.
+
+      If you have no luck finding free DRG maps, go to
+      http://www.geocomm.com/ and check out the "DRG Data Bundles"
+      they have available.  You can purchase a DVD containing all the
+      DRGs for an entire state in three scales, all of them usable in
+      xastir, for a relatively low price.  Be warned, however, that
+      parts of the US have DRGs that are produced by an agency other
+      than the United States Geological Survey, and these DRGs are not
+      necessarily in correct GeoTIFF format.  The areas covered by the
+      Tennessee Valley Authority appear to be among those, as one
+      xastir user discovered when purchasing a DVD of DRGs for North
+      Carolina.  It is still possible to use these DRG files, but they
+      need preprocessing.  See the section below entitled "Defective
+      GeoTIFF files need even more special processing."
+
+      Many useful US maps can be downloaded from the National Map Viewer: 
+      http://nmviewogc.cr.usgs.gov/viewer.htm
+
+      Free FAA sectional charts can be downloaded from
+        http://aviationtoolbox.org/raw_data/FAA_sectionals/current/
+      This site was set up by someone who had a subscription to the FAA
+      DVD collection and made them available on the web (this is legal per
+      FAA's terms of use).  They are no longer being updated as of mid 2005.
+      These charts are in Lambert Conformal Conic projection, though, and
+      need to be converted with gdalwarp to be usable in xastir (see below).
+
+      Current, valid-for-navigation FAA sectional charts may be purchased
+      from the FAA at
+ 	https://naco.faa.gov/ecomp/Catalog.aspx?a=AERO+NOS+DIGITAL
+      for about $1.50US each.  These files are also in GeoTIFF and are the
+      same type as those that are available on aviationtoolbox, but these are
+      updated every 6 months and are kept current.  You will have to process
+      them before viewing in xastir.
+
+      The 7.5' topo maps work the best so far.  Be sure to install the .tif AND
+      the .fgd files side-by-side into the map directories. Without the .fgd
+      file Xastir won't be able to crop the white border from the map.  Xastir
+      currently knows how to handle NAD27, NAD83, and WGS84 geoTIFF files.
+      GeoTIFF files created in other datums will be displayed at an incorrect
+      location with Xastir. The .tfw files included with most geoTIFF images
+      are not used by Xastir.
+
+      If you must make FGD files by hand, the included script mapfgd.pl can
+      create them for you from the USGS geoTIFF files. The format Xastir is
+      looking for is the following:
+
+        1.5.1.1  WEST BOUNDING COORDINATE:  -122.000000
+        1.5.1.2  EAST BOUNDING COORDINATE:  -120.000000  
+        1.5.1.3  NORTH BOUNDING COORDINATE:  48.000000 
+        1.5.1.4  SOUTH BOUNDING COORDINATE:  47.000000 
+
+     -or-
+
+        1.5.1.1  West_Bounding_Coordinate:  -122.000000
+        1.5.1.2  East_Bounding_Coordinate:  -120.000000  
+        1.5.1.3  North_Bounding_Coordinate:  48.000000 
+        1.5.1.4  South_Bounding_Coordinate:  47.000000 
+
+      Notes about DRG-Enhanced (DRG-E) files:
+      * The DRG-E files will draw over the correct spots if you remove
+      the .fgd file, but will overflow their boundaries and
+
+      * The DRG-E files will draw over the correct spots with decent
+      boundary trimming (as far as I can tell, which isn't very far:
+      correct me!) if you use a .fgd file taken from 'real' DRG files
+      from USGS.
+
+      Basically: get rid of the .fgd file from the DRG-E!!
+
+    Highly Compressed MrSID image files:
+
+      Be wary of DRG-E or DOQQ files that are compressed with MrSID
+      compression.  That is a proprietary compression format for
+      which we do not have access to the decoding algorithm.  We
+      cannot use those from within Xastir.  There's possible good news
+      lurking on the horizon though:  LizardTech has mentioned on the
+      gdal-dev mailing list that they might be supporting open-source
+      with a driver for gdal sometime soon.  
+
+      It is also possible to decompress these files with a free tool
+      from LizardTech called "mrsiddecode", available at 
+        http://www.lizardtech.com/download/dl_options.php?page=tools
+
+      mrsiddecode can produce GeoTIFF output with the right command line
+      options.  There is a Linux version of mrsiddecode, but one user
+      has observed that the Windows version running under Wine is a little 
+      more robust.  Your milage may vary.
+
+      Be warned that MrSID is a very effective compression algorithm, and
+      compressed MrSID files of size 5MB could easily decompress into 50MB
+      GeoTIFFs.  
+
+      Note also that many GIS departments take perfectly usable
+      GeoTIFF files with all projection and datum tags and use ESRI products
+      to compress them down into MrSID files, thereby losing all the
+      GeoTIFF tags.  See below.
+
+    GeoTIFF files in certain projections need special processing:
+
+      Not all geotiff files available on the net are usable directly in 
+      xastir.  Some of them are in projections that xastir can't use 
+      properly, and others are missing all of the metadata information that
+      is needed to work out how to convert them to Lat/Lon unprojected rasters.
+      If you encounter a geotiff file that has the correct tags, but is
+      in some projection other than UTM, you can convert that file to a  
+      lat/lon raster if you have gdal installed.  Simply run the following
+      command:
+        gdalwarp -t_srs EPSG:4326 original_raster.tif usable_raster.tif
+
+      This will warp the geotiff file "original raster.tif" from
+      whatever projection it was in into an unprojected lat/lon raster
+      "usable_raster.tif" that can be directly read into xastir.
+      Depending on the source projection, you might get a map that
+      doesn't tile well with other maps due to the inclusion of opaque
+      border material, but it can sometimes be the only way to import
+      a map you need to use.
+
+    Defective GeoTIFF files need even more special processing:
+
+      It is unfortunately the case that the ESRI software in use by many
+      GIS departments produces GeoTIFF files that have NO information about
+      the coordinate system that applies to them --- they'll have just
+      enough information to know what the numerical coordinates of each 
+      pixel are, but no information to tell you whether those coordinates are
+      UTM, Lat/Lon, State Plane, or anything else.  For such maps you will
+      need to determine the coordinate system by finding external files
+      called "metadata" that are associated with the images.  US
+      Federal datasources have a standardized file format (".fgd") that
+      provides this information, but many state or university GIS departments
+      just make some other format up for themselves.  Most sources of
+      map data should have such metadata available, but sometimes it is a bit 
+      of a chore to find it.
+
+      You can determine whether a .tif file has coordinate system information
+      in it using the "gdalinfo" command from the GDAL suite or "listgeo" from
+      the libgeotiff distribution.  If gdalinfo shows something like this:
+
+        Driver: GTiff/GeoTIFF
+        Size is 5364, 7620
+        Coordinate System is `'
+        Origin = (588067.750000,5331248.500000)
+
+      you're the lucky owner of a file that has no coordinate system info
+      (because the only thing after "Coordinate System is" is a pair of
+      quotation marks).   Another dead givaway would be:
+         Metadata:
+           TIFFTAG_SOFTWARE=Arc/Info
+      which tells you that the image was processed with a piece of software
+      that fails to put in all the right tags.
+
+      If you get maps whose metadata say are in UTM projection but for which
+      gdal indicates missing geoTIFF tags like it does in the example above, 
+      xastir won't be able to display them unless you fix them up.
+      Fortunately, the GDAL library tool "gdal_translate" can do the
+      job.  For example, if you have a source map with metadata that
+      says it's in UTM Zone 10, NAD83 datum, to make it suitable for
+      Xastir to read you can do something like this:
+
+      gdal_translate -a_srs EPSG:26910 original.tif georeferenced.tif
+
+      The inclusion of the "-a_srs" option to gdal_translate
+      forces the new tiff file to have the correct geotiff tags to
+      indicate that coordinate system.  
+
+      The EPSG number to use for images in UTM projection with NAD83
+      datum is 26900 plus the UTM zone number.  The EPSG number for UTM in
+      NAD27 is 26700 plus the zone number.  The above command
+      will allow Xastir to read in the image and reference it
+      properly.  If you do the gdalwarp option above instead, you can end up
+      with solid color areas between the edges of the original image
+      and the lat/long rectangle that the image will be warped to; these 
+      extra pixels represent "no data" areas due to the difference in shape
+      between the original rectangular image and the warped image.   The 
+      color of this area depends on the colors present in the original
+      image; GDAL attempts to use a color that is different from any in the
+      source image.  If those areas don't matter to you, then either
+      method will work for you.  If you're planning to tile multiple
+      UTM images together, then the gdal_translate option is best.
+
+      If your maps are NOT in UTM, you must also gdalwarp, because xastir
+      cannot properly display geotiffs that are in projections other than
+      UTM or "unprojected" lat/lon.  
+
+      EPSG numbers for odd-ball coordinate systems can be found at 
+      http://www.remotesensing.org/geotiff/proj_list/Wkt_adam.zip
+
+      Maps that require gdalwarp include the FAA sectionals mentioned above,
+      and some topo maps in obscure state plane coordinates from various state
+      GIS departments.
+
+    XASTIR can only use GeoTIFF files that are 8-bit per pixel with one band
+
+      Some geotiff files contain multiple bands or multiple bytes per pixel.
+      Xastir currently uses only BYTE format, so you may need to convert the
+      geotiff file with gdal_translate.  The number of bands, bytes per 
+      pixel and other information about geotiff files can be obtained using
+      gdalinfo.  
+
+      One-band, 16- or 32-bit-per-pixel:
+       The command "gdal_translate -ot BYTE original.tif new.tif" 
+       can convert 16 and 32 bit per pixel geotiffs to ones that can be used
+       by xastir
+   
+      Multiple band, 8-bit-per-pixel:
+
+      The command "gdal_translate -ot BYTE -b 1 old.tif new.tif" 
+      can extract a single band as a grey scale layer from a multi-band 
+      geotiff file, but this is probably not what you really want.
+      The command 
+            rgb2pct.py old.tif new.tif
+      can create a single band palette based geotiff from a three band rgb 
+      tif by dithering the colors down to a small pallette.  This last
+      tool requires gdal built with Python support.  See the gdal 
+      documentation for these tools for further information.
+
+    More manipulations of GeoTIFF files:
+
+      gdal also provides several additional tools that can be used to 
+      tile maps or chop them up into smaller pieces, but explaining the
+      details of that process is probably beyond the scope of this document. 
+      See the man pages for "gdal_translate" and "gdal_merge.py" for 
+      an explanation of how those tools could be used to accomplish this.
+
+    .geo files/online maps & graphics:
+
+      If you have ImageMagick and wget or libcurl installed, .geo files
+      for NWS radars are available from one of these sites:
+
+          ftp://gcpoolz.com/geos/Srb_geos.zip
+          http://wetnet.net/~we7u/xastir/maps/radar-geos.tgz
+
+      You'll probably want to add an IMAGESIZE line to each one to speed up
+      loading when some radars are offscreen: (bash syntax, modify for your
+      shell...)
+
+          for a in srb_*; do echo "IMAGESIZE 620 620" >> $a; done
+
+      NOTE:  For .geo files with an ftp or http address for fetching the image,
+      IMAGESIZE is currently a REQUIRED parameter in the .geo file.  For .geo
+      files where the image is resident on your hard drive, the IMAGESIZE tag
+      is optional.
+
+      Please also note that the coordinates in the .GEO files are expressed
+      in decimal degrees, and are listed with longitude first then latitude
+      on the TIEPOINT lines.
+
+      Tiger maps of the USA are available through the map menu under 
+      "Enable/configure Tigermap". These maps are generated by the census
+      bureau web-server.
+
+      A .geo with only the word "TERRASERVER-SATELLITE" in it will retrieve a
+      satellite photo of the area from terraserver.  You need "wget" or libcurl,
+      plus ImageMagick installed, and support for them compiled into Xastir.  No
+      additional map downloads are needed if these are the only maps that you
+      want to use.
+
+      A .geo with only the word "TERRASERVER-TOPO" in it will retrieve a
+      topographic map of the area from terraserver.  You need "wget" or
+      libcurl, plus ImageMagick installed, and support for them compiled into
+      Xastir.  No additional map downloads are needed if these are the only
+      maps that you want to use.  Other interesting keywords are
+      "TERRASERVER-URBAN" and "TERRASERVER-REFLECTIVITY".
+
+      Other tags you can put in a .geo file: 
+      DATUM: (not used, yet...)
+      PROJECTION: Currently only supports "TM" for transverse Mercator.
+      REFRESH: number of seconds to reload the maps.  Multiple maps
+          with different values pick the smallest value.
+      TRANSPARENT:  Color to remove from the background (make it transparent).
+          Use a number, 0=black.  Color-mapped images use the map value, so 
+          white is usually 0xffff.  Value can be decimal or hex if preceeded 
+          by "0x".  Multiple TRANSPARENT lines can be used in a file to make
+          multiple colors transparent.
+      CROP: removes borders.  Values are [left top right bottom] with
+          (0,0) at the upper left.  A good value for the NWS radar
+          images above is "CROP 35 20 616 600"
+      GAMMA, CONTRAST, NEGATE, EQUALIZE, NORMALIZE, LEVEL, MODULATE:  These 
+          are all ImageMagick options, and are documented there, and
+          briefly in the xastir help file.
+
+     
+     "Find Address" feature (US only):
+
+      The "Find Address" feature is based on the open source geo-coder by
+      Dan Egnor and as such uses the same format for the data. You can
+      download preprocessed data based on Census Tiger 2003 data at:
+      http://www.dementia.org/geocoder/tgr2003/
+
+      Reprocessed geocoding files from the 2006 Second Edition TIGER/Line 
+      data were produced by Jason Winningham in June of 2007 and made 
+      available on the TAMU FTP server by Gerry Creager.  They are much
+      better than the 2003 data, and it is recommended that they be used
+      instead.  Download them from 
+         ftp://aprs.tamu.edu/pub/geocode/
+
+     Geographic Names Information System Labels:
+
+      These aren't maps, but are collections of name labels for locations.
+      These display at various zoom levels like Dos/WinAPRS map labels, but are
+      also searchable from the Maps menu.
+
+         http://geonames.usgs.gov/
+
+      Click the link "Download GNIS Data: State and Topical Gazetteers" on
+      the left.
+
+      These files should be renamed in the form "<ST>.gnis" after download,
+      where <ST> is the abbreviation for the state that they cover, and
+      should be placed in the /usr/local/share/xastir/GNIS/ directory. To
+      make sure that maps are layered correctly with GNIS labels on the top
+      of the map stack, plus searchable, it is suggested that you link
+      /usr/local/share/xastir/maps/z to this GNIS directory.
+
+      Type this as root to create the link and directories:
+       cd /usr/local/share/xastir/maps
+       ln -s ../GNIS z
+
+      The map files must end in ".gnis" to be used by Xastir, and must be in
+      pipe delimited format.  These are readily available from the above link
+      with such filenames as "AZ_DECI.TXT". The files must be renamed to
+      <ST>.gnis, and the trailing whitespace should be removed for speed. This
+      can be accomplished in one step with the following command. (bash
+      style...)
+
+   for a in *deci; do sed -e 's/[ ]*$//g' < $a > `basename $a _deci`.gnis; done
+
+      Individual files can have whitespace removed as follows:
+        sed -e 's/[ ]*$//g' < inputfile > outputfile
+
+      Populated places GNIS file can be had at:
+
+          http://geonames.usgs.gov/stategaz/POP_PLACES_DECI.zip
+
+      A note from Jason Winningham, kg4wsv:
+
+      "The file has over 181k records in it.  You can use the following command
+      to weed out all places with populations less than 1000, and get it down
+      to just under 14k records, which is really fast to load: 
+
+        awk -F\| '{if ($17 > 1000) print $0}' \
+            /usr/local/share/xastir/GNIS/0pop_places.gnis \
+            >/usr/local/share/xastir/GNIS/0pop_places_over_1k.gnis
+
+      I stuck a zero at the beginning of the filename so this would
+      show up in the GNIS directory before any of the state files."
+
+
+     County weather Warning maps (requires shapefile support):
+      
+       The latest shapefile format weather maps may be found here:
+         http://www.nws.noaa.gov/geodata/
+
+       or more easily found here (but not guaranteed to be the most
+       current:
+         http://wetnet.net/~we7u/xastir/Counties/
+
+       We now have a script in the xastir/scripts directory called
+       "get-NWSdata" which fetches the files you need and plops them
+       into the correct directory and unzips them.  Run that script
+       as root.  It requires "wget" to work.  You may then try the
+       NWS-TEST.log test shown below to verify proper operation.
+
+        --------------------------
+        The files of interest are:
+        --------------------------
+
+        NWSI Libraries:
+        ---------------
+        County Warning Area Boundaries (c_*.zip)
+        Public Zone Boundaries (z_*.zip)
+        Coastal and Offshore Marine Zones (mz*.zip, oz*.zip, hz*.zip)
+        Fire Weather Zone Boundaries (fz*.zip)
+
+        County Libraries:
+        -----------------
+        AWIPS Counties (w_*.zip)
+
+      Unzip those files in the /usr/local/share/xastir/Counties/ directory and
+      Xastir should find them and use them for weather alerts. Be sure to
+      include the .shp, .shx, .and dbf.
+           
+       Note that you can also use the county file as the background polygon
+       filled map for drawing county lands and borders.  Either make a link
+       to these files from your maps directory, or copy the files there so
+       that they show up in the Map Chooser.
+
+      To test whether the weather alerts are working (whether weather?), copy
+      the NWS-TEST.log file to your ~/.xastir/logs/ directory and then bring it
+      in to Xastir using the File->Open Log File option.  Zoom in to the
+      WA/OR/ID area (Pacific Northwest) and you should see a picture that looks
+      like this:  <http://www.eskimo.com/~archer/xastir/xastir-wx-alerts.png>
+      Note that you may have to change the dates embedded in the file if Xastir
+      thinks they are expired.  See the notes at the top of that file.  If the
+      alerts are still active they should appear in the View->Weather Alerts
+      dialog.
+
+	Australian rules Weather Alerts
+
+		http://wxsvr.aprs.net.au/implementation.html
+
+     Raw Tiger/Line format maps (requires GDAL/OGR):
+
+      If you have GDAL/OGR library added to Xastir, you should (very soon)
+      be able to use Tiger/Line maps.  The developers are working to add
+      this capability.
+
+      2002 map data can be found here:
+
+        http://www.census.gov/geo/www/tiger/tiger2002/tgr2002.html
+
+      2003 map data can be found here:
+
+        http://www.census.gov/geo/www/tiger/tiger2003/tgr2003.html
+
+     SDTS format maps (requires GDAL/OGR):
+
+        http://edc.usgs.gov/geodata/
+
+      The "hypsography" maps contain topo lines.  They look very nice overlaid
+      on top of terraserver satellite images.  Note that for some types of maps
+      you also need to download a data dictionary file to go with them.
+
+      Also note that the various datasets appear to reuse filenames.  You may
+      need to separate each one into its own subdirectory in order to keep all
+      of the files from getting overwritten by new maps.
+
+     MapInfo TAB/MID/MIF format maps (requires GDAL/OGR):
+
+      http://www.mapinfo.com
+      http://research.umbc.edu/~roswell/mipage.html
+
+
+     Download audio files:
+
+       To play the wav files you will need a program such as vplay to play the
+       audio file through your sound card.
+
+       Grab xastir-sounds.tgz at the ftp site you downloaded Xastir, or at
+        ftp://ftp.tapr.org/software_lib/Linux/xastir/xastir-sounds.tgz
+
+       Un-tar the file.  Put the sounds files into the
+       /usr/local/share/xastir/sounds directory where Xastir can find them.
+       (FIXME: thunder.wav is missing?).
+
+     Download FCC and/or RAC Database files:
+
+       If the FCC database is installed, a Search FCC Database button will
+       appear in the station info box. If the RAC (Radio Amateurs of Canada)
+       database is installed, a Search RAC Database button will appear for
+       callsigns beginning with "VE" or "VA".
+
+       The download and installation of these is automated in the get-fcc-rac.pl
+       script included with Xastir, but you may install them by hand
+       individually if you wish as described here:
+
+       To use the FCC lookup:
+       ----------------------
+
+         Download:
+         http://wireless.fcc.gov/uls/data/complete/l_amat.zip
+
+         (The only file needed from this 87 Meg zip is the EN.dat file)
+
+         **** NOTE To use the data base file it must be sorted first!!! ****
+     
+         unzip l_amat.zip
+
+         To sort the file, make sure you have plenty of disk space for this as
+         the file is BIG!
+
+         cat EN.dat | /usr/bin/perl -pe 's/\r\r\n//g' | sort +4 -t \| > EN.dat.sorted
+
+         Install it in the xastir/fcc directory:
+
+         su
+         mv EN.dat.sorted /usr/local/share/xastir/fcc/EN.dat
+
+
+       To use the RAC lookup:
+       ----------------------
+
+         Download:
+         http://205.236.99.41/%7Eindicatif/download/amateur.zip
+
+         unzip amateur.zip
+         mv AMATEUR.RPT /usr/local/share/xastir/fcc/AMACALL.LST
+
+
+       Hiking trails from National Geographic's Topo or mapXchange:
+       ------------------------------------------------------------
+
+        For those of you who may be familiar with National Geographic's Topo!
+        program, there's a way to use the user-saved data (but not topo maps
+        themselves) from within Xastir.  Many users create TPG and/or TPO
+        files in TOPO from GPS data and/or hand-drawn routes.  They can then
+        upload them to the mapXchange site, and in fact there are many hiking
+        trails that one can download for free from that site.  Okay, how to use
+        them?
+
+        Go to <http://www.gpsbabel.org>.  Go to the Project page and then the
+        CVS page and follow the instructions for grabbing the CVS gpsbabel
+        sources.  Only CVS has the Topo version 3.x support, which was just
+        recently added (May 2006).  Follow their instructions for building/
+        installing/using the program.  It's a command-line program where you
+        specify the input and output formats and filenames.  Using this program
+        you can snag the interesting data out of the files and convert it to
+        GPX format.  Once you have that, you can use the "gpx2shape" script to
+        convert them to Shapefiles.  Xastir can then use them as map files.
+
+
+
+WHERE TO FIND MORE INFO ON MAP DATUMS, ETC:
+
+    Geodesy:
+    http://oceanservice.noaa.gov/education/geodesy/welcome.html
+
+    "Geodesy for the Layman"
+    http://www.ngs.noaa.gov/PUBS_LIB/Geodesy4Layman/toc.htm
+    
+
+
+MAP CACHING (WORKS WITH MOST ONLINE MAPS):
+
+    Map caching works in conjunction with the map download routines,
+    which fetch maps from http or ftp addresses.  The map caching features
+    use functions found in Berkeley DB 4.0 library, AKA libdb (version 4.0
+    or better), to create and manage a cache directory and a persistent
+    database of information about the files in the cache directory.  This
+    directory defaults to ~/.xastir/map_cache.  The files under this
+    directory can be cleaned up or removed by hand at any time - the
+    caching routines will simply download the maps and put new entries
+    into the .db file.
+
+    Map files are saved with filenames that include the number of seconds
+    since the Unix epoch.  This allows the caching routines to easily
+    determine the age of maps so that older cached maps can be deleted.
+    This is currently (Dec 2004) controlled with a compile time maximum
+    age setting.  See map_cache.h for specifics and for brief
+    documentation about all of the map_cache functions. 
+
+
+
+DRAWING YOUR OWN MAPS USING XASTIR ITSELF:
+
+    The final result here will be ESRI Shapefile vector maps that
+    you can then use within Xastir.  You'll need Shapelib compiled
+    into Xastir to make use of this feature (the private copy of
+    Shapelib is fine for this).
+
+    Turn off Object Transmit first (Interface menu).
+
+    Place an object or item at the start location of your route.
+
+    Click on the "Move" button to active move mode, then move that
+    object around the map.  Once you're done you'll have a bunch of
+    straight lines that depict the course.
+
+    Now bring up Station Info on that object and click on the Store
+    Track button.  If you've got Shapelib compiled in, you'll get a
+    shapefile created with the track you just drew.
+
+    After you're done you can delete the object and then turn on the
+    Object Transmit toggle again.  You'll end up transmitting the
+    deleted final position of the object for a few hours unless you
+    kill/restart Xastir, but that's ok.  Nobody will see it on their
+    maps 'cuz it's a deleted object.
+ 
+    Look in ~/.xastir/tracklogs/ for the Shapefile.  Copy it to your
+    maps directory, changing the name on the three files as you
+    like, then create a dbfawk file for it if you want to change how
+    it is drawn in Xastir.
+
+    Another way would be to drive the course with a GPS and then
+    download the track via Xastir/GPSman to create a Shapefile map.
+
+    Yet another way would be to drive it with an APRS rig and then
+    Store Track as described above.  You could also drive with
+    GPS/Xastir (without APRS) to get a very detailed track and then
+    save your own track.
+
+
+
+DRAWING SAR SEARCH SEGMENTS IN XASTIR:
+
+    Turn on "Draw" mode (togglebutton at the top of the main
+    window).  The cursor should change to the Measure/Draw symbol.
+
+    Using the middle mouse button, click on each vertice until you
+    are almost done describing a polygon (don't close it yet).  If
+    you don't have a middle mouse button, clicking on BOTH mouse
+    buttons at once will do it if you have "emulate third mouse
+    button" enabled in your X-Windows configuration.
+
+    Go to Map->Draw CAD Objects->Close Polygon.  The polygon will
+    get completed, the area enclosed will be computed, and a dialog
+    will pop up asking you for more information.  You do not have to
+    enter any information in this dialog, but a name of some type is
+    helpful in order to be able to identify each segment when
+    modifying/deleting/viewing these segments.
+
+    Note that these CAD Objects get saved in a file and reloaded
+    each time you start Xastir, but they cannot currently be written
+    out as a map file and used as a general map.
+
+    Note also that these CAD Objects don't get transmitted.  They
+    are currently for local display only.
+
+    The display of various kinds of data related to these segments
+    can be modified in the Map->Draw CAD Objects menu.  Modifying
+    parameters for any segment is done in the
+    Map->Draw CAD Objects->CAD Polygons dialog.
+
+    Click on the dashed line in the menus in order to separate that
+    menu from the rest and allow you to keep the menu on the screen.
+    This is very useful when drawing CAD Objects or changing
+    display/filtering options.
+
+    Turn off "Draw" mode when you're done.  The cursor should return
+    to normal.
+
+
+
+SUMMARY OF DISTANCE/AREA/ANGLE CALCULATIONS:
+
+
+    DISTANCE:
+    ---------
+    *) Haversine formula (2-parameter atan version) for computing
+    distance between two points, for our general distance routines:
+
+        calc_distance()
+        calc_distance_course()
+        distance_from_my_station()
+
+    *) Haversine formula (2-parameter atan version) in "Measure" for
+    both the X/Y offsets and the total distance.
+
+    Haversine formula is more accurate for shorter distances than
+    spherical trigonometry calculations.  Both methods are equivalent
+    for longer distances.  Both are Great-Circle calculations (as
+    opposed to Rhumb-line or planar geometry).  See the GIS FAQ for info
+    on these methods.  Dr. Math website mentions both of these and refers
+    people to the same GIS FAQ.
+
+    Also note that the Haversine formula is ill-conditioned if the
+    two points are antipodal (on opposite sides of the Earth).  From the
+    GIS FAQ: "but the error, perhaps as large as 2km (1 mi), is in the
+    context of a distance near 20,000km (12,000 mi)."  For our purposes
+    that's just fine.
+
+
+    AREA:
+    -----
+    *) Area of a spherical rectangle from Dr. Math's website for the
+    "Measure" function.  There are errors in their last two derived
+    formulas.  They have been notified of it.  Our implemented code
+    is correct.
+
+    *) The area calculation for CAD Object Polygons is probably not
+    spherical, but closer to planar.  It might take some doing to calculate
+    the area of irregular polygons on a spherical surface.  We use Greene's
+    Theorem to compute the area based on the vectors.  The lengths of each
+    vector are computed via the Haversine formula, so it's not strictly a
+    planar area calculation either.  Somewhere in-between planar and spherical?
+    This should be plenty good enough for areas that are less than 12 miles on
+    a side (that's about where planar geometry starts to diverge from spherical
+    trigonometry), perhaps also for somewhat larger areas than this due to the
+    advantage of computing the vector lengths with the Haversine formula.
+
+
+    ANGLE:
+    ------
+    *) Great Circle departure angle for the "Measure" function.
+
+    *) Great Circle departure angle for the calc_distance_course()
+    function.
+
+    *) Dead-reckoning angle is essentially a Rhumb-line calculation
+    (constant heading), with a few caveats:
+
+        We compute the next point along a constant angle based on the last
+        position transmitted, the time elapsed, and the course desired.
+        This then gets corrupted a bit either by the standard APRS grid that
+        it has to snap to (and the position snapped to for the previous
+        position) and/or by the relatively course angle available for Base-91
+        compressed positions.
+
+        Standard APRS positions give 1-degree angular resolution but 60-foot or
+        so grid points.  Base-91 Compressed positions give something like 1 to
+        3-foot grid points but less angular resolution (+/- 2 degrees.  We
+        can't win!
+
+        The end result is that we start off like a drunk sailer due to our
+        short transmit times and the above limitations, then the angle smooths
+        out as the time increases between the transmits.  You can see this
+        easily at zoom level 1 when you place an object, when you make a change
+        to an object, or move an object (transmit rate goes up for any of these
+        conditions).
+
+    Dead-reckoning effectively does a Rhumb-Line calculation as it is
+    trying to do a constant heading.  That means it is not the shortest
+    distance between the points.  I'm still trying to get my head around
+    that last concept as it is counter-intuitive to someone versed in
+    compass/maps on land and with shorter distances.
+
+    A Great-Circle route is the shortest distance between two points on
+    a sphere, whereas a Rhumb-line is what you get if you move along a
+    constant compass heading and is a bit longer.
+
+    We probably do not need to go to ellipsoid calculations for Xastir.
+    Spherical calculations should be easily accurate enough for what we do.
+ 
+
+
+  ------------------------------------------------------------------------
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 1999 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
diff --git a/README.OSM_maps b/README.OSM_maps
new file mode 100644
index 0000000..c18df20
--- /dev/null
+++ b/README.OSM_maps
@@ -0,0 +1,216 @@
+$Id: README.OSM_maps,v 1.4 2012/11/01 18:57:18 we7u Exp $
+
+Copyright (C) 2012  The Xastir Group
+
+
+  Using OpenStreetMap in Xastir
+  ------------------------------------------------------------------------
+  CONTENTS
+     Introduction
+     Map Types
+     Map Sources and Renderings (Styles)
+     Map Cache
+     Sharing Tiles
+     Map Definition Files
+     Copyrights and Licenses
+
+
+  Introduction
+  ------------
+    What, you may ask is 'OpenStreetMap' (OSM)? From the web site,
+    www.openstreetmap.org, we read that
+
+        "OpenStreetMap is a free editable map of the whole world.
+         It is made by people like you".
+
+    The tag line for the map is "The Free Wiki World Map".
+
+    Xastir will display bitmap versions of the OSM. There are multiple
+    renderings of the OSM to choose from and, by default, nine (9)
+    are available in Xastir.
+
+  Map Types
+  ---------
+    Xastir can use two different map types based on OSM; static and
+    tiled. Static maps are bitmaps that are least as large as the Xastir
+    window. Tiled maps are built up from 256x256 pixel images.
+
+    Static maps are also assembled from tiles, but the assembly occurs
+    at the server and the full size image is downloaded to Xastir. There
+    is a major disadvantage to static maps- even slight changes in map
+    position requires a new map download.
+
+    Tiles have become the standard for bitmap map images. Their small
+    size allows for short download times and easy reuse. Tiles are the
+    basis of the 'slippy map' implementations on web sites,
+    applications, and portable devices. Note that Xastir is not a
+    'slippy map' application and map motions and refresh times are not
+    as smooth or quick as you can find in other applications (Xastir's
+    strengths lie in other areas).
+
+    Bitmap images, whether static or tiled, are available for only a
+    limited number of zoom levels. There are 18 possible zoom levels.
+    It takes 2^zoom tiles to represent 360 degrees. Since the tiles are
+    256 pixel squares, there are 2^(zoom + 8) pixels in 360 degrees.
+
+    When the Xastir scale does not equate to one of the 18 OSM zoom
+    levels, the bitmap image is scaled. However, scaled bitmaps tend to
+    look ugly. The scaled bitmap can have jagged lines, unequal pixel
+    sizes, and/or missing information. At best a scaled bitmap looks
+    blurred, but more typically some pixels will be enlarged into visible
+    blocks or compressed invisibility.
+
+    You can use the F4 key to adjust the Xastir scale to approximate the
+    OSM zoom level and refresh the display. (The key can be changed by
+    modifying a variable in the OSM definition (GEO) files.
+
+
+  Map Sources and Renderings (Styles)
+  -----------------------------------
+    The OSM data is rendered into tiles using different styles. The
+    easiest place to view and compare the styles is at
+    http://ojw.dev.openstreetmap.org/StaticMap/?mode=Style&
+
+    Tiles can be retreived from a number of servers. The supplied map
+    definitions will download tiles from:
+        http://tile.openstreetmap.org/
+        http://tah.openstreetmap.org/Tiles/tile/
+        http://tiles.openpistemap.org/tiles/contours/
+        http://andy.sandbox.cloudmade.com/tiles/cycle/
+
+    The CloudMade tiles are also available, but a user account and a key
+    are required. Register at http://www.cloudmade.com/ and then create
+    new OSM map definition files (GEO) by copying an existing file and
+    changing the URL variable. The CloudMade tile URLs have this form:
+
+        http://tile.cloudmade.com/<key>/<style#>/256/
+
+
+  Map Cache
+  ---------
+    Static maps are cached with other bitmap map images in the
+    ~/.xastir/map_cache/ directory.
+
+    Tiles are cached separately to make it possible to share them
+    with other applications. By default tiles are cached in
+    ~/.xastir/map_cache/OSMtiles/, but that location can be changed on a
+    by-style basis. The tiles are organized directories by style, zoom
+    level, and longitude:
+    
+      ~/.xastir/map_cache/OSMtiles/
+                             + <style1>/
+                             |    + <zoom>/
+                             |         <longitude>/
+                             |            + [0 ... (2^zoom - 1)].png
+                             + <style2>/
+                             ...
+     
+     Note that 'longitude' is a tile number between 0 and (2^zoom -1).
+
+     Xastir downloads tiles as needed. If Xastir is compiled with
+     libcurl support, then it will check for updates to tiles that have
+     been cached for 7 days or more.
+     See http://wiki.openstreetmap.org/wiki/Tile_usage_policy
+
+     If a tile can not be downloaded for any reason or if the downloaded
+     file is not usable image, then the downloaded file (if any) will be
+     deleted and a red area will be shown in it's place on the display. 
+
+     NOTE: Run Xastir at debug level 512 (-v 512) for more information
+           on download issues. At debug level 512, corrupt tile files
+           will not be deleted. Examining the contents of the corrupt
+           files can be informative.
+
+           If Xastir is compiled with libcurl support, then debug level
+           8192 will enable verbose output from libcurl.
+
+     WARNING: Corrupt tile files will not be deleted when running at
+              debug level 512. If you do not delete them manually before
+              restarting Xastir, then the first time Xastir displays the
+              tile it will be shown in red and then deleted from the
+              cache.
+
+
+  Sharing Tiles
+  -------------
+     The directory structure used to cache tiles is common to other
+     programs, though the style names are typically different. An
+     example of a program that can share tiles with Xastir is TangoGPS
+     (http://www.tangogps.org).
+
+     Here are some examples of how you can share tiles with TangoGPS
+     (the setup for other programs would be similar):
+
+       1) Setup a symlink at the style level of the caches
+           $ cd ~/.xastir/OSMmaps/
+           $ ln ~/Maps/<tangoStyleName>/ <xastirStyleName>
+
+       2) Change the Xastir map definition file to specify the TangoGPS
+          cache by changing the following variables (see the next
+          section for more information):
+             OSM_TILED_MAP-<tangoStyleName>
+             TILE_DIR /home/<user>/Maps
+
+       3) Share all styles and tiles by creating a symlink at the top
+          level of the cache. This also requires changing the Xastir
+          map definition files to specify the style names used by
+          TangoGPS:
+             $ cd ~/.xastir
+             $ rm -rf OSMmaps/
+             $ ln -s ../Maps OSMmaps
+
+
+  Map Definition Files
+  --------------------
+    OSM map type, style, server, cache directory, and function keys are
+    specified in Xastir GEO files. By default the files are located in
+    the /usr/local/share/xastir/maps/Online/ directory. The supplied
+    definition files have filenames of this form:
+
+       OSM_<name>.geo        - static maps
+       OSM_tiled_<name>.geo  - tiled maps
+
+    Where <name> is replaced with the style name. Note that <name> could
+    be any unique string and is not required to be the style.
+
+    Read the comments in the supplied definition files for more
+    information.
+
+
+  Copyrights and Licenses
+  -----------------------
+    Maps and tiles from the OpenStreetMap project are
+    Copyright OpenStreetMap and contributors, CC-BY-SA
+
+       http://www.openstreetmap.org/
+       http://creativecommons.org/licenses/by-sa/2.0/
+
+    in addition, tiles from CloudMade are
+    Copyright CloudMade, CC-BY-SA
+
+        http://www.cloudmade.com/
+        http://cloudmade.com/about/api-terms-and-conditions
+        http://cloudmade.com/terms_conditions
+
+    TopOSM tiles are a composite of CC-BY-SA and public domain data,
+    including MassGIS data. See
+    http://wiki.openstreetmap.org/wiki/TopOSM for more information.
+
+  Changing the Displayed Attribution
+  ----------------------------------
+
+    The licenses from OpenStreetMap and CloudMade require attribution
+    that is met, in part, by a label shown at the top left corner of the
+    map. Two label images have been provided, one shows icons and the
+    other shows black text on a white background.
+
+    You can change between the two label styles by changing a symlink:
+
+       $ cd /usr/local/share/xastir/maps/   # your installing may differ!
+       $ rm CC_OpenStreetMap.png
+       $ ln -s CC_OpenStreetMap_txt.png CC_OpenStreetMap.png
+          or
+       $ ln -S CC_OpenStreetMap_logo.png CC_OpenStreetMap.png
+
+
+  ------------------------------------------------------------------------
diff --git a/README.win32 b/README.win32
new file mode 100644
index 0000000..a2ad5d5
--- /dev/null
+++ b/README.win32
@@ -0,0 +1,1357 @@
+
+$Id: README.win32,v 1.151 2012/11/01 18:57:18 we7u Exp $
+
+---------------------------------------------------------------------
+Note that there are other options to get Xastir running on Win32.
+The method described below in this document is for getting Xastir
+running under Cygwin which can be problematic.  Other methods exist
+on the Xastir Wiki pages which are typically easier and more robust:
+
+    http://www.xastir.org/wiki/index.php/Installation_Notes
+---------------------------------------------------------------------
+
+  Two companies have created simpler installs of Cygwin/Xastir than
+  described in this document.  Contact one of these folks for more
+  info.  Remember to replace the "at" below with the "@" symbol to
+  arrive at the correct e-mail addresses.  We have to do that to
+  prevent large amounts of spam from going to addresses harvested
+  from web pages:
+
+
+    Lintronix:
+      Internet install of Xastir available for free, CD-ROM available
+      for a nominal fee.  Everything needed to install Cygwin/Xastir
+      online (Internet install) or off-line (CD-ROM).  Walks you
+      through an automated install:
+
+        http://www.lintronix.com/winxastir/
+        E-mail:  winxastir at lintronix.com
+
+
+    Inuit Nunaani Wireless Inc:
+      CD-ROM available for a nominal fee.  Everything needed to
+      install Cygwin/Xastir off-line.  Walks you through an
+      automated install.  This install is verified to work on WinXP
+      and Win98 (known _not_ to work on Win95/WinME).  Contact:
+
+        E-mail:  Tom Tessier <ttessier at trtdigital.ca>
+
+
+
+------------------------------------
+Installing Xastir on Windows/Cygwin:
+------------------------------------
+
+Please Note:  It's beneficial to actually log in to your Windows
+computer rather than skipping that step of the Windows login process
+(Don't hit escape just to get rid of the dialog!).  If you log into
+Windows properly, Cygwin will be able to figure out where to put your
+home directory.  If you don't do this, you'll be referred to as
+"unknown" and you won't have a home directory in Cygwin.  This means
+there won't be a good place to put your Xastir startup files.  Of
+course, log in as the same user each time in order for Cygwin to use
+the proper home directory for you.
+
+CAN'T REPLACE FILES:  Every once in a while Windows will refuse to
+allow you to delete/rename one of the files.  The only way I've
+found to get around this problem is to reboot.  Also, Windows
+typically won't allow you to replace a file that Windows currently
+has open.  If you're going to be recompiling/reinstalling Xastir, or
+updating Cygwin, make sure that these applications are shut down
+before doing so.  You can get VERY strange results if only some
+files get updated.
+
+SPACES IN USERNAMES:  Cygwin specifically, and Unix boxes in
+general, don't much like spaces in filenames, directories, or login
+names.  Any of these may cause you headaches while playing with
+Cygwin.  Create a new login that doesn't have spaces and log in as
+that user before installing Cygwin, and whenever you intend to run
+Cygwin/Xastir.  It's very likely that Xastir won't work for you if
+you use a login that has spaces embedded in it.  For additional
+info, see this link:
+
+    http://cygwin.com/faq/faq_2.html#SEC17
+
+Explanation of this login box for those that don't see it:  If you
+have the option of running networking, you'll have a login box show
+up when you first start up Windows.  It'll ask for you user name and
+password, then let you in.  If you escape out of that dialog, Windows
+may start right up but networking will be disabled.
+
+If you don't see that box, there are two options that I know about,
+either you or someone else set it up to auto-login with your user/
+password combo, or you don't have networking installed at all.
+
+The following steps direct you through installing Cygwin, Xastir, and
+a few optional map libraries that Xastir can use.  Note that in most
+of the places below where the directions state to type commands, this
+must be done from within a Cygwin BASH shell, not a DOS window.
+Where you are asked to edit files, it's best to use Wordpad instead
+of Notepad, as Notepad doesn't do nice things to Unix-format files.
+
+Cygwin now allows you to have Xwindows apps and Windows apps all on
+the screen and visible at the same time!  The instructions here set
+it up in that manner, so you can have Xastir as just another app on
+your Windows desktop.
+
+Please subscribe to the "xastir" mailing list at
+"http://www.xastir.org".  There are lots of helpful people there
+that can aid you in installing/running Xastir.  You must be subscribed
+in order to post messages there.
+
+
+[ ] Step 1)  Install Cygwin, a free download.
+
+
+[ ] Step 1a) Go to http://www.cygwin.com with your web browser.
+Look for the black and green Cygwin icon, then click on "Install
+now!".
+
+This will load the Cygwin network installer program onto your
+computer.  Remember where you decide to put this program.  I put
+mine in "c:\<login>\cygwin\setup.exe", (for instance
+"c:\hacker\cygwin\setup.exe").  This program will allow you to do a
+network install of Cygwin.  After you install Cygwin (see the steps
+below for details) you'll have a package directory (in my case
+"c:\hacker\cygwin\") and a Cygwin directory (in my case
+"c:\cygwin").  The un-installed packages go into the package
+directory as they are downloaded from the 'net.
+
+It will be beneficial to re-run the Cygwin network installer from
+time to time in order to keep Cygwin up to date.  Each time you run
+it you'll update any packages that have been changed since you last
+ran it.
+
+[ ] Step 1b)  Find the "setup.exe" program and execute it either by:
+
+  a) Clicking on it with File Explorer, or
+  b) Start->Run->path to executable, or
+  c) Opening a DOS window and typing the name.
+
+This will start installing Cygwin over the network.  Answers to
+provide to the program:
+
+    Install from Internet (*)
+    "C:\cygwin"
+    Install For All Users
+    Default Text File Type Unix (*)
+    Local Package Directory "C:\hacker\cygwin"
+    Select Your Internet Connection (choose one)
+    Choose A Download Site (choose one nearby if you can determine that)
+
+Note:  Responses above listed with a "(*)" are required.  Others are
+up to the individual user to answer as they wish.  You'll get to a
+"Progress" page where "setup.bz2" is downloaded from the 'net.  If
+it hangs at this step, you may wish to "Cancel" and try another
+server until you obtain this file and are presented with a list of
+packages to install.
+
+
+[ ] Step 1c)  Select Packages:  Leave the packages selected that
+were selected by default, plus select the additional packages listed
+below.  Note that enabling some of these packages causes others to
+be selected as well, that's OK and necessary.
+
+[ ] Press the "View" button until it says "Full" next to it.  All
+packages are now in alphanumeric sorted order.
+
+Selecting a package involves clicking on the little circle symbol
+until the option you want is displayed.  You can choose older
+versions of a package, choose to keep the package you have installed
+already, or choose to remove or install a package in this manner.
+If you're running Cygwin install again and see "Keep" as an option,
+that means you've already installed that package.  We're only
+concerned with the "bin" packages here (stands for "binary") and not
+the "src" packages (source code).
+
+It's suggested that you keep whatever was selected by default, and
+just add the below packages to the selection.  As you select
+packages, other packages may be selected for you that are also
+required:
+
+[ ] autoconf
+[ ] automake
+[ ] binutils
+[ ] bzip2
+[ ] curl
+[ ] curl-devel
+[ ] cvs
+[ ] db4.2
+[ ] diffutils
+[ ] gcc
+[ ] gv
+[ ] gzip
+[ ] ImageMagick  (See notes under "Adding ImageMagick" below 
+                  --- there are problems with the Cygwin package)
+[ ] lcms
+[ ] less
+[ ] lesstif
+[ ] libdb4.2
+[ ] libdb4.2-devel
+[ ] libgeotiff
+[ ] libgeotiff-devel
+[ ] libgeotiff1
+[ ] libMagick-devel
+[ ] libMagick6
+[ ] libproj-devel
+[ ] libproj0
+[ ] libtool
+[ ] libxml2-devel
+[ ] m4
+[ ] make
+[ ] nano (a windows-style text editor, optional)
+[ ] patch
+[ ] pcre
+[ ] pcre-devel
+[ ] perl
+[ ] proj
+[ ] python
+[ ] rcs
+[ ] tcltk
+[ ] tiff (install sources for this one too? TBD)
+[ ] unzip
+[ ] vim (a Unix-style text editor, optional)
+[ ] wget (Optional: Can use libcurl instead)
+[ ] X-start-menu-icons
+[ ] X-startup-scripts
+[ ] xfree86-lib-compat
+[ ] xorg-x11-bin
+[ ] xorg-x11-devel: Headers
+[ ] xorg-x11-f100:  100 dpi fonts
+[ ] zip
+
+Clicking on the small circle with the two arrows will run you
+through the various select/de-select options for each package.
+
+Note regarding Perl:  On some Windows systems, Perl 5.8 can cause
+page faults when compiling Xastir.  If this happens to you, start up
+the Cygwin install program again and install Perl 5.6.1 instead.
+Retry the compile.  If this works for you, every time you update
+Cygwin you'll have to check the Perl version to make sure that it
+doesn't update you to 5.8.
+
+Note regarding KDE:  One user reported that the KDE package on
+Cygwin messes up XmStrings in Lesstif.  It caused a bunch of
+headaches.  You've been warned.  Note that KDE is not one of the
+packages listed above (I didn't load it).
+
+
+[ ] Step 1d)  Click Next and the packages will get downloaded and
+installed.  Repeat the above if you have network difficulties, until
+the install succeeds completely.
+
+Some servers fail to download some files and require the user to
+press enter between downloads when it fails on these files.  If this
+happens, back up and select another server.
+
+
+[ ] Step 1e)  At the end of the install it'll ask you if you wish to
+create desktop icons and menu entries.  Definitely select these!  It
+doesn't mean that Cygwin will start automatically each time you
+reboot your computer or login (it doesn't start automatically).  It
+_does_ mean that you'll have an icon to click on manually to get
+things going.
+
+This will create a Black/Green Cygwin icon on the desktop and a menu
+entry so that you can start Cygwin through the menu system as well.
+
+[ ] Step 1f) Click "Finish".  Cygwin is now installed.  One more
+pop-up informs you Cygwin has been installed.  Sometimes this last
+dialog gets hidden behind other windows, and it does seem to need OK
+clicked to complete the installation.  Click the OK button on that
+last dialog to _really_ complete the installation.
+
+The Black/Green Cygwin icon will start up a BASH window, without
+starting up Xwindows.  Think of it as being similar to a DOS window,
+but with a lot more power.  It understands Unix commands though, not
+DOS commands.
+
+[ ] Note:  I've had the Cygwin network install fail before during
+the downloading stage without informing me in any recognizable
+manner.  You might which to re-do step 1 to make sure nothing
+further gets downloaded/installed.  Once you get to that point, Step
+1 is complete.
+
+
+[ ] Step 2)  Create shortcut for starting X:
+
+Create a shortcut to C:\cygwin\usr\X11r6\bin\startxwin.bat from your
+desktop.  This shortcut is the method you'll use to start up
+Xwindows.  The usual method is to use File Explorer to find the
+file, the right click and drag it to your desktop, at which point
+you let go of the right mouse button and you'll be presented with a
+small menu.  Select "Create Shortcut(s) Here".  You can then rename
+the shortcut if you wish.  I named mine "Xwindows".
+
+Change the properties on the shortcut so that it runs it from your
+home directory on Cygwin, something like "c:\cygwin\home\<user>\".
+Right-click on the new shortcut, then go to the Properties menu to
+change this.  You may need to create the home and the user directory
+before you can change the properties on the shortcut.
+
+
+[ ] Step 3)  Test Cygwin and create startup shortcuts:
+
+Note:  With Win2000, I had to do a reboot before I could proceed
+further.
+
+Double-click on the shortcut you just made.  You should get a shell
+window that looks very much like a DOS window.  It's a BASH shell
+window and understands Unix commands instead of DOS commands.
+
+When running this shortcut for the first time from WinXP, several
+errors may occur.  Repeat as necessary until the BASH window appears
+without incident.
+
+Type "exit" and then press <Enter> to make the BASH window
+disappear.
+
+You should still see an 'X' in your system tray.  That's the
+X-server running.  You can right-click on that and then select the
+menu entry to cause it to exit.
+
+Once you've gotten to this stage, you now have Cygwin and Xwindows
+installed and operational.  Next we go after Xastir itself.
+
+[ ] Edit or create your .profile file in your home directory.
+
+NOTE:  Your "home" directory would be at "C:\cygwin\<user>\" if you
+installed Cygwin in the default location.  From inside a BASH shell
+you can get to your home directory just by typing "cd" and then
+pressing <Enter>.  When you see things like "~/.profile" it is
+really referring to the file ".profile" in your home directory (~).
+This is a different file than the ".bash_profile" file.
+
+It appears that Cygwin uses the PATH variable to look for both
+binaries and libraries.  Add this line to the file (create the
+"~/.profile" file if the file doesn't exist):
+
+ export PATH=$PATH:/lib:/usr/lib:/usr/X11R6/lib:/usr/local/lib:/bin:/usr/local/bin:.
+
+If the line already exists in your .profile, add any missing pieces
+to it from the line above.  Directories should be separated by a ':'
+character.  Edit it with "nano" or "vim" (again, the more
+user-friendly editor is "nano").
+
+Once you have saved the file, execute the following commands to copy
+file to where it will be automatically executed when you open a
+shell and then read it for this session so you don't have to close
+and then reopen the shell.
+
+     cp .profile .bashrc
+     source .bashrc
+
+[ ] Step 4)  Create a file at C:\cygwin\home\<user>\ called
+".cvsrc", where the "<user>" part is your Windows login name.  Don't
+forget the leading period in the filename as it's important.  For
+instance, I created a file:  "C:\cygwin\home\hacker\.cvsrc".  The
+file should contain the following lines:
+
+    ##cvs -z3
+    update -P -d
+    status -v
+    diff -u
+
+The '#' marks comment out the first line.  "cvs -z3" invokes
+compression, and the SourceForge site isn't performing compression
+currently.
+
+PLEASE NOTE:  this file must be created in Unix format, not DOS
+format.  DO NOT USE Notepad or other Windows tools to create the
+file, as CVS will not recognize the contents.  Thanks to Kirk
+Mefford <kc2elo at softhome.net> for noticing this.  The editor "nano"
+can be invoked from a Cygwin window to create this file, or for
+those of you who know "vi" or have Windows editors available that
+can save in Unix format, use those.  If you don't, the "cvs update"
+commands won't work for you, at least until you recreate the file in
+Unix format.  You've been warned!
+
+The "." in ".cvsrc" makes it a Unix hidden file, and it won't appear
+in most Unix listings.  Unix files don't need a file extension, so
+don't create a file that has one (or else rename it to ".cvsrc" when
+done).
+
+Another option is to create the file using a Windows editor, then
+run a dos2unix program on it to convert it to the proper format.
+
+
+[ ] Step 5)  Download Xastir sources.  Start up Xwindows using your
+shortcut.  Type the six lines below into the shell exactly as shown.
+Hit <ENTER> when asked for a password after typing line four (the
+"login" command):
+
+  cd ~
+  touch .cvspass
+  mkdir src
+  cd src
+  cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir login 
+  cvs -d:pserver:anonymous at xastir.cvs.sourceforge.net:/cvsroot/xastir co xastir 
+
+NOTE:  The "login" command must complete without errors in order to
+create a dummy blank password in your .cvspass file.  Without this
+password you'll have trouble with later CVS commands.  If you see
+"EOF", "connection reset by peer", "connection refused", or "timed
+out", it means that the anonymous CVS server at SourceForge is
+overloaded (too many users).  Keep trying the failed commands until
+they succeed!  Notice that up-arrow (on the keyboard) and then
+<ENTER> will repeat the last command, saving you some typing.
+
+The end result when it succeeds  will be a new directory
+"C:\cygwin\home\<user>\src\xastir\" which contains all of the Xastir
+source code.  You can type "ls xastir" (that's lower-case LS) to see
+the file listing.
+
+Side Note:  Here's the coolest thing about CVS:  Once you've done
+this initial source-code download, you'll never have to do the whole
+Xastir download again.  You'll just go into the "src/xastir"
+directory and type "cvs update", which will snag just the _changes_
+to the files since you last updated, and is very fast.  Compile and
+install at that point and you'll be running the latest developer's
+version in just a few minutes!  It's very easy to keep up with the
+developers this way.
+
+
+[ ] Step 6)  Configure/compile/install Xastir.  Type these commands
+into the BASH shell, waiting until each one completes before typing
+the next command:
+
+    cd ~/src/xastir
+    ./bootstrap.sh
+    ./configure
+    make
+    make install
+
+NOTE:  You'll probably want to run the configure step from an xterm
+window with the X11 server running of course.  If you do this from a
+non-X11 window then the configure test for "gv" will fail, as "gv"
+requires an X11 server even when asking it for it's version number.
+Without "gv" support you won't be able to print from Xastir.
+ 
+NOTE:  The "make" step can be extremely memory hungry.  If you don't
+have much free memory, that step might take a long time to run.  One
+Win2k machine with only 20MB of free RAM (128MB total RAM) couldn't
+complete this step, but adding another 128MB of RAM to that machine
+caused it to succeed.  Another machine running Win2k with 64MB free
+(128MB total RAM) took six hours (but keep reading!).  Free up
+memory if you're having trouble completing that step.  This behavior
+is only seen on Windows/Cygwin, not on the Unix-based systems.  On a
+typical Linux box that step takes under two seconds.  Hopefully
+Cygwin linking will improve over time to alleviate this issue.
+We've added a new link-stage parameter to reduce the memory usage
+for that step, but it doesn't totally resolve the problem.  The
+machine that took six hours originally now takes 60 seconds to
+complete that step.
+
+Ignore the "PACKAGE_* redefined" warnings.  They won't break
+anything and are just an annoyance.
+
+Once you get through the above commands, Xastir is compiled and
+installed on your system, with minimal map support.  Later sections
+of this document detail adding additional map libraries in order to
+give you access to the full mapping capability of Xastir.
+
+NOTE:  If you get the below errors during the compile it means that
+Cygwin has changed one of their packages to be incompatible with the
+rest (and needs to change a lot more of their packages to
+correspond):
+---------------------------------------------------------------------
+/usr/include/Xm/Print.h:28:34: X11/extensions/Print.h: No such file or directory
+In file included from /usr/include/Xm/XmAll.h:79,
+                 from alert.c:308:
+/usr/include/Xm/Print.h:40: error: parse error before "XPContext"
+/usr/include/Xm/Print.h:43: error: parse error before '}' token
+/usr/include/Xm/Print.h:61: error: parse error before "XPFinishProc"
+make[3]: *** [alert.o] Error 1
+---------------------------------------------------------------------
+A temporary fix for the above errors (until Cygwin gets their act
+together) is to do the following:
+---------------------------------------------------------------------
+    Launch the Cygwin setup program
+    When you get to the list of packages change the list to FULL mode
+    Uncheck "Hide Obsolete Packages"
+    Scroll down the list until you find xorg-x11-devel
+    Click on the word "keep" until it changes to a 6.x version of the file
+    Click Next and finish the setup
+    Unfortunately you'll have to perform the same fix each time you
+      use the Cygwin setup program or it will "upgrade" to the
+      broken package again.
+---------------------------------------------------------------------
+
+[ ] Step 7)  Create a link to the Xastir executable.  Type the
+following commands into the BASH shell:
+
+    cd ~
+    ln -s /usr/local/bin/xastir xastir
+
+That will create a symbolic link from your home directory to the
+Xastir executable, to make it easier to run Xastir without typing
+the long path each time.
+
+
+[ ] Step 8)  Actually run the darn thing:
+
+Let's start from scratch to make sure it all works.  Close any
+Cygwin/BASH windows you may have.
+
+Click on the shortcut you created to start Xwindows.
+
+From the resulting BASH window, type "xastir &".  Xastir should
+start up shortly.
+
+Note:  Xastir has support for PocketAPRS, DosAPRS, WinAPRS, MacAPRS
+and GNIS maps by default.  For additional types of maps, you'll need
+to install some libraries, then recompile Xastir so that it knows to
+use them.  See the instructions below.
+
+The README.MAPS file has instructions for where to get maps and where
+to put them under the Xastir hierarchy.
+
+If you have any WinAPRS, DosAPRS, or PocketAPRS maps, now is a good
+time to place them in the /cygwin/usr/local/share/xastir/maps folder
+(or a subdirectory of it).  You can also use "*.geo" files and the
+associated image files with Xastir.  You may place them in this
+directory (or a subdirectory of it) as well, though most of the .geo
+files won't work for you until you install the ImageMagick library.
+
+What Xastir paths look like from within Windows (in case you're
+moving maps around with Explorer):  Just prefix them all with
+"cygwin/".  For instance, maps go into
+/cygwin/usr/local/share/xastir/maps instead of
+/usr/local/share/xastir/maps.  Xastir will continue to see them as
+"/usr/local/share/xastir/maps" though from inside Cygwin.  It kind
+of looks like a miniature Unix box from inside Cygwin.
+
+Run Windows in 15-bit color or better (32768 colors or more) or
+you'll get lots of warnings about Xastir not being able to allocate
+colors when it starts up, and the display will be rather stark
+looking.
+
+To set a new language or change the language current choice, use
+this command line instead from inside an Xterm:
+
+     xastir -l <language>
+
+Current choices are:
+
+    Dutch English French German Italian Portuguese Spanish
+    ElmerFudd MuppetsChef OldeEnglish PigLatin PirateEnglish
+
+This option will be stored in the users config file for the next
+time Xastir is run. On new installs Xastir will default to English
+until you use this command line option once.
+
+Another difference with Cygwin as opposed to Unix-like operating
+systems:  You can't do the make install portion if Xastir is up and
+running.  You have to kill Xastir first before you do "make install"
+or "make install-strip".  Otherwise the newly compiled Xastir won't
+replace the old one.
+
+Note that one user running Cygwin on XP had it crash every time his
+screen-saver kicked in.  Disabling the screen-server fixed that
+problem.
+
+Another interesting "feature" of Cygwin/Xwindows is that some of the
+modifier keys like ScrollLock/CapsLock/NumLock must be pressed while
+that X-window is the active foreground window.  If not, the event
+can be missed, and Xwindows can get out of sync with the actual
+state of the key.  This doesn't appear to be an Xastir-specific
+problem, but a Cygwin/Xwindow problem.  With just a BASH shell under
+Cygwin (not involving Xwindows), the problem doesn't appear to
+happen.  Just inside Xwindows on Cygwin.
+
+Some users have experienced problems with their Windows box running
+the NTFS "convert.exe" program instead of the ImageMagick
+"convert.exe" program, usually when enabling snapshots in Xastir.
+If you experience this, check your path settings and make sure that
+ImageMagick's path is first.
+
+When specifying serial ports to use with Xastir,
+
+    "COM1" is called "/dev/ttyS0" in Cygwin (and Linux)
+    "COM2" is called "/dev/ttyS1" in Cygwin (and Linux)
+
+Note the capital 'S'.
+
+
+[ ] Step 9)  Document & Back Up the Configuration
+
+One user had a problem where after Cygwin/Xastir was installed, he
+installed another program, in this case Java, and it wiped out some
+of the environment variables that Cygwin set.  $HOME was one
+variable that got changed.
+
+To guard against such changes, go to My Computer and right-click on
+properties.  Write down the Advanced System Variables and keep the
+note in a safe place.
+
+
+Optional
+
+To shorten the Xastir sequence or to automate the startup process of
+Xastir in Windows environment, the following may prove useful.
+
+  1. Locate startwin.bat, it will be located at: Cygwin install
+     drive, eg; C:\cygwin\usr\X11r6\bin\ Please make a backup copy
+     in case something goes wrong!  Save it as a new name such as
+     startwin.bak or startwin.orig.
+
+  2. Open startwin.bat with notepad or another ASCII text editor.
+
+  3. Find the line:
+
+     run xterm -sl 1000 -sb -rightbar -ms red -fg yellow -bg black -e /usr/bin/bash
+
+  4. Copy and paste the line into the startwin.bat file directly
+     under the line you just copied.
+
+  5. Cut /usr/bin/bash -l from the end of the line then enter
+     /usr/local/bin/xastir where you just cut. You will end up with
+     entries such as this:
+
+     run xterm -sl 1000 -sb -rightbar -ms red -fg yellow -bg black -e /usr/bin/bash -l
+     run xterm -sl 1000 -sb -rightbar -ms red -fg yellow -bg black -e /usr/local/bin/xastir
+
+  6. Save startwin.bat
+
+Now when you click the XWindow shortcut, Xastir will start without
+the need to wait for the BASH shell and typing Xastir &. In
+addition, a BASH shell window will open to allow you to monitor any
+error messages or other information generated by Xastir put out to
+STDERR and shown in the shell.
+
+In addition, you can add a shortcut to the startup directory to
+automatically start Xastir when you start Windows..
+
+
+
+Please see the INSTALL file and the Help menu in Xastir itself
+for additional information not mentioned in this document.
+
+Additional info can be found on the cygwin web-site:
+
+    http://www.cygwin.com
+
+or the Cygwin/XFree86 web-site:
+
+    http://cygwin.com/xfree/
+
+
+[ ] Step 10)  Keeping up-to-date:
+
+Once a week or once a month, run the Cygwin network installer
+program (step 1b above).  After it finishes, open a Cygwin window
+and type these commands to update the Xastir source code:
+
+    cd ~/src/xastir
+    cvs update
+
+If you see "EOF" or "connection reset by peer" it means that the
+anonymous CVS server at SourceForge is overloaded (too many users).
+Keep trying the failed commands until they succeed!  Notice that
+up-arrow (on the keyboard) and then <ENTER> will repeat the last
+command, saving you some typing.
+
+Every once in a while Windows will refuse to allow you to
+delete/rename one of the files.  The only way I've found to get
+around this problem is to reboot.  I sometimes see this when trying
+to do a CVS update, and Windows won't allow one or more files to get
+updated.
+
+Repeat step 6) above to recompile/reinstall the latest Xastir.
+
+A very good option is to read the SUDO instructions in the
+README.CVS file, setting up the /etc/sudoers file and creating an
+update-xastir script as shown.  Then you can type "./update-xastir"
+at any time to snag down the latest Xastir changes, compile, and
+install it.  We've just included an update-xastir script with
+Xastir, so you don't have to create it anymore.  You may however
+need to remove the "sudo" keyword from each line for it to work
+properly on Cygwin.
+
+
+-----
+Notes from Henk de Groot:
+
+1) On Windows ME I had to configure the shortcut to start Xwindows,
+it ran out of environment memory. Selecting an "Initial Environment"
+of 4096 bytes in tab "Memory" (I hope that is correct, I have a
+Dutch language version...) fixed it.
+
+2) My keyboard layout was a mess in the xterm, I had to add
+"setxkbmap us" to c:\cygwin\usr\X11R6\bin\startxwin.bat (just below
+"run XWin....").
+
+
+-------------------------------------------
+OPTIONAL:  ADDING ADDITIONAL MAP LIBRARIES:
+-------------------------------------------
+
+These additional Xastir libraries have been tested on Cygwin:
+
+    ImageMagick
+    Shapelib
+    libtiff
+    libproj
+    libgeotiff
+    Festival
+    GDAL/OGR
+
+Anyone testing additional libraries is encouraged to share their
+findings on the Xastir mailing lists (you must be subscribed in
+order to post messages there).  The libraries which have _not_ been
+made to work yet on Cygwin are:
+
+    AX25
+    GPSMan/gpsmanshp
+
+The AX25 libraries will probably never work, as they are for Linux
+only.  GPSMan/gpsmanshp may work on Cygwin at some point if enough
+work is done to figure out and document the process.
+
+
+RECOMMENDED:  Adding Shapelib (tested with shapelib-1.2.10):
+------------------------------------------------------------
+
+*******************************NOTE**************************************
+As of 10 November 2006, xastir's source tree contains a copy of shapelib
+1.2.10, and automatically builds shapelib if you don't have it installed.
+At this point, the only reason to follow the "Adding Shapelib" instructions
+below is if you need the shapelib shared libraries to work in other cygwin
+software.  So unless you do, just skip this section and xastir's build process
+will automatically build and use its own "internal" shapelib support.  Since
+the instructions below contain some "gotchas" that you have to work around,
+just using internal support is far easier if you don't need shapelib for
+other projects.
+************************************************************************
+
+Allows using many sources of online polygon, polyline, and point
+maps, including ones from NOAA.  This is the only format used for
+weather alert maps.
+
+NOTE:  A private copy of the Shapelib library is now included with
+Xastir.  If you need Shapelib only for use with the Xastir program
+you can rely on this private copy to be installed and statically
+linked with Xastir.  If you need Shapelib for any other program,
+it's recommended that you install it as shown below instead, so that
+Xastir and the other programs will use a shared library.
+
+[ ] From a BASH shell, type:
+
+    cd ~/src
+    mkdir shapelib
+    
+[ ] Fetch "shapelib-1.2.10.tar.gz" from one of these sites:
+
+    http://shapelib.maptools.org/
+or  http://wetnet.net/~we7u/xastir/shapelib/
+
+[ ] Put it in the C:\cygwin\home\<user>\src\shapelib directory.
+
+[ ] Untar it from the BASH shell:
+
+    cd ~/src/shapelib
+    tar xzvf shapelib-1.2.10.tar.gz
+
+[ ] Essential: Edit Shapelib's Makefile to remove the space after the "-h" on
+the line that looks like this:
+
+    /usr/bin/ld -G -h libshp.so.1 -o .libs/libshp.so.$(LIBSHP_VERSION) shpopen.lo shptree.lo dbfopen.lo -lc
+
+Change it to this (one space missing and 'c' changed to "cygwin"):
+
+    /usr/bin/ld -G -hlibshp.so.1 -o .libs/libshp.so.$(LIBSHP_VERSION) shpopen.lo shptree.lo dbfopen.lo -lcygwin
+
+I've had another report that says having the space is OK now.  The
+"-lcygwin" is important to bypass the "__getreent" bug below.
+
+Here are the commands to bring up an editor on the file:
+
+    cd ~/src/shapelib/shapelib-1.2.10
+    nano Makefile
+ 
+
+[ ] Save the edited file, then type:
+
+    make lib
+
+[ ] You may get the "undefined reference impure_ptr" messages.  If
+so, edit the file /usr/include/sys/reent.h to remove the word
+"extern" from this line:
+
+    extern struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
+
+then try "make lib" again.
+
+[ ] Type:
+
+    make lib_install
+
+If you get "cp: cannot stat `.libs/libshp.la': No such file or
+directory", then you forgot to edit the Makefile.  BZZZT!  Please
+start again at step 1) above.  Thank you for playing!
+
+If you get something like: "Makefile:121:  *** Missing separator.
+Stop.", then it's likely that while editing the Makefile you ended
+up with line-wrap on a line (one line broken into two or more lines
+because the editor thought it was too long).  Combine the line into
+one line again and retry.  Make sure not to delete any spaces that
+are there between items on the line, else you'll get different
+errors.
+
+[ ] Now you should be ready to configure and compile Xastir with
+Shapelib support.  Type these commands:
+
+    cd ~/src/xastir
+    ./configure
+    make
+    make install
+
+The installed copy of Xastir should now have Shapelib support.  You
+can download NOAA weather alert maps and many other sorts of maps,
+and Xastir will recognize and use them.  Note that weather alert
+shapefiles must go into the /usr/local/share/xastir/Counties
+directory.  All other shapefiles must go into the
+/cygwin/user/local/share/xastir/maps directory (and subdirectories
+below that of your choosing).
+
+See the README.MAPS file for where to get the maps, and a script to
+automate the download/install for you.
+
+
+Note from Gale Wilkinson, kc4pl:
+> >
+> > How do you get shapelib to "make" properly under cygwin?  I
+> > have installed the latest cygwin (packages per the win32
+> > install notes) and then downloaded and unpacked the latest
+> > shapelib source package for compiling.  But when trying to do
+> > the "make lib" it errors out part way through the process.
+> > The error seems to be:
+> >
+> >  dbfopen.lo: In function 'DBFReadAttribute':
+> > /home/gwilkinson/src/shapelib-1.2.10/dbfopen.c:724:undefined
+> > reference to '__getreent'
+> > /home/gwilkinson/src/shapelib-1.2.10/dbfopen.c:716:undefined
+> > reference to '__getreent'
+> > make: *** [lib] Error 1
+
+Dan Brown, n8ysz, responded:
+>
+> I wrote this to get/make shapelib:
+>
+> http://brauhaus.org/xastir/get_shapelib.sh
+> or
+> http://brauhaus.org/xastir/get_shapelib.sh.txt
+
+This script is now also in the Xastir sources as
+"xastir/scripts/get_shapelib.sh".
+
+
+
+OPTIONAL:  Adding ImageMagick:
+--------------------------------------------------------------
+Note: Recent Cygwin installations include ImageMagick 6.0.4.
+Unfortunately, this install is linked against some X11 DLLs that no
+longer get installed by the most recent X11 package.  See
+   http://comments.gmane.org/gmane.os.cygwin.xfree/16493 for a
+work-around.  NOTE: It appears this problem may have been fixed in the
+latest-latest (as of 13 November 2006) ImageMagick/Cygwin package.
+
+The ideal solution to the problem mentioned above is to rebuild
+ImageMagick from source code instead of using the (now-unmaintained)
+Cygwin ImageMagick package.  The instructions below walk you through a
+build of a much older version of ImageMagick, and should still be
+fairly accurate for a more recent vintage (as of this writing,
+ImageMagick versions are up over 6.2, meaning that both the version in
+Cygwin and the version mentione below are very old).
+
+Allows using more than 68 different graphics format files as maps,
+by creating an associated .geo file for each with tie-points.  This
+support also allows use of online Tiger and Terraserver maps with
+Xastir, and NOAA weather radar images.  Other people are working on
+integrating even more online mapping sources.  This will also allow
+you to use any GIF/JPG/XPM/BMP/... image as an Xastir map.
+
+Note: The much older Cygwin binary for ImageMagick-5.5.5 has a problem
+in it's Magick-config script which makes it impossible to use for our
+purposes.  Don't try to use that version.  Some people reported a
+similar problem with 5.5.7.
+
+Note that Xastir's "./configure" stage may fail trying to compile in
+ImageMagick support.  If this happens, make sure you have the
+ImageMagick development package installed if using RPM packages, or
+have installed the ImageMagick header files.  If it still fails,
+check the "config.log" file _very_ carefully.  Often ImageMagick
+tests fail due to some other library that ImageMagick depends upon
+being absent, such as liblcms, libbz2, or others.
+
+Until the RPM packagers for ImageMagick include all of the dependent
+libraries in their RPM dependency list, the best way to assure that
+ImageMagick is installed properly is to install it from sources.
+
+
+ImageMagick:
+        http://www.imagemagick.org/
+
+    cd ~/src
+    mkdir imagemagick
+
+[ ] Download the ImageMagick cygwin binary from www.imagemagick.org
+or one of it's mirrors.  If you can't find the version you need, try
+here:
+
+    http://wetnet.net/~we7u/xastir/ImageMagick/cygwin/
+
+[ ] Put it in the ~/src/imagemagick directory.
+
+[ ] Extract the files:
+
+    cd ~/src/imagemagick
+    tar xzvf filename
+
+[ ] Copy the files/directories into the /usr tree:
+
+    cd ImageMagick-5.5.3
+    cp -R * /usr
+
+[ ] Reconfigure Xastir to use this library:
+
+    cd ~/src/xastir
+    ./configure
+
+[ ] If "configure" did not find ImageMagick properly, edit the
+resulting config.h file and change this line:
+
+    /* #undef HAVE_IMAGEMAGICK */
+
+to this:
+
+    #define HAVE_IMAGEMAGICK 1
+
+
+[ ] Finish the Xastir build and install:
+
+    make
+    make install
+
+[ ] Add this to your ~/.profile file (note this is a different file
+than the .bash_profile file):
+
+    export MAGICK_HOME=/usr
+
+Now on-line Tigermaps should work for you.  Unfortunately it looks
+like the ".profile" file doesn't automatically get run if you start
+up the X-server from a windows shortcut.  If you don't set the
+MAGICK_HOME variable in your shell that you start Xastir from, then
+ImageMagick will fail to display images and you'll get messages like
+"No decode delegate for this image format" in the xterm you started
+Xastir from.  If that happens, you can close Xastir, type
+
+    .  ./.profile
+
+and then type "xastir &" again to make it work.  Another option is
+to start X from within a standard Cygwin window.  After starting X
+you can close the original Cygwin window.  Yet another option is to
+create a script for starting Xastir so that you can set the
+MAGICK_HOME variable just before you start it.  It could look
+something like this:
+
+    #!/bin/sh
+    export MAGICK_HOME=/usr
+    xastir &
+
+Perhaps name it "aprs".  Issue this command to turn it into an
+executable file:
+
+    chmod 755 aprs
+
+
+Start it by typing "./aprs".
+
+--------------------------------------------------------------------
+Note from Kirk Mefford, KC2ELO:
+
+Also one more way to work around the "MAGICK_HOME" issues with
+running from the startxwin.bat file is to add "SET MAGICK_HOME=/usr"
+to the bat file before it gets to loading things. [remember DOS? ;)
+]
+
+I have Xastir loading directly from "startxwin.bat" with "run 
+/usr/local/bin/xastir" and ImageMagick works fine with "SET 
+MAGICK_HOME=/usr" at the top of the bat file.
+--------------------------------------------------------------------
+
+
+HIGHLY RECOMMENDED:  If you create a file called "terraserver.geo"
+in the /usr/local/share/xastir/maps directory, containing the single line
+"TERRASERVER-SATELLITE", and select it with the Map Chooser, you should
+see satellite images on the map screen.  This is assuming that you have
+an Internet connection up and running of course.  It fetches the
+images from the Microsoft Terraserver.
+
+Also create a "terraserver-topo.geo" file in the same area somewhere.
+Inside that file put the keyword "TERRASERVER-TOPO".  Selecting this map
+will fetch topo maps from the Microsoft Terraserver.  More interesting
+keywords that can be used in other files are "TERRASERVER-REFLECTIVITY"
+and "TERRASERVER-URBAN".  There should be files for all four Terraserver
+options installed in your /usr/local/share/xastir/maps/Online directory
+once you install Xastir.
+
+This means if you're online, you can have access to street maps
+(Tigermap server), satellite images (Terraserver), and topo maps
+(again Terraserver)!
+
+
+
+OPTIONAL:  Install GeoTIFF support:
+-----------------------------------
+Note: Recent Cygwin installations include GeoTIFF support, and if you
+installed everything in the list in step 1, you already have it..  You
+only need to manually install libgeotiff if you did not have the 3
+libgeotiff choices, the 2 libproj choices, and the proj choice
+available when installing cygwin, or if Xastir doesn't find libgeotiff.
+
+Allows using USGS DRG topo maps or other types of GeoTIFF
+maps/images and has the ability to tile smaller maps into a larger
+contiguous map of an area:
+
+[NOTE: when checked on 30 Oct 2004, it is now possible to install
+libproj and libgeotiff directly from cygwin setup.  Since at least one
+user has had considerable trouble installing xastir with geotiff using
+the instructions below, it is recommended that these libraries be
+installed through cygwin setup instead.  Be sure to install the
+"-devel" versions that will include headers and libraries needed to
+compile xastir.]
+
+For GeoTIFF support (such as USGS DRG topo maps) you need one each
+of libproj, proj-nad27, and libgeotiff:
+
+
+    libproj (tested with proj-4.4.7):
+    ---------------------------------
+        http://www.remotesensing.org/proj/
+or      http://wetnet.net/~we7u/xastir/libproj/
+
+
+    Datum translations (tested with proj-nad27-1.1):
+    ------------------------------------------------
+        ftp://ftp.remotesensing.org/pub/proj/
+or      http://wetnet.net/~we7u/xastir/libproj/
+
+
+    libgeotiff (tested with libgeotiff-1.2.0):
+    ------------------------------------------
+        http://www.remotesensing.org/geotiff/geotiff.html
+or      ftp://ftp.remotesensing.org/pub/geotiff/libgeotiff/
+or      http://wetnet.net/~we7u/xastir/libgeotiff/
+
+
+Please note that the order of installation for these libraries is
+critical.  If not installing from cygwin setup, please be sure to
+follow the instructions below carefully.
+
+
+Adding libproj to Cygwin (tested with proj-4.4.7):
+--------------------------------------------------
+
+Again, if you installed everything suggested in step 1, you already
+have this and building libproj from source is unnecessary.
+
+NOTE: You must install libproj BEFORE compiling libgeotiff, because
+libgeotiff uses libproj to do the datum translations. If you install
+libgeotiff first, datum translations won't work.
+
+[ ] Type:
+
+    cd ~/src
+    mkdir libproj
+
+[ ] Download the libproj and proj-nad27 files and place them in the
+~/src/libproj directory.
+
+The proj-nad27-1.1.tar.gz must be decompressed in the nad
+subdirectory of the proj distribution directory before you run
+configure.
+
+[ ] Type:
+    
+    cd ~/src/libproj    
+    tar xzvf proj-4.4.7.tar.gz
+    cd proj-4.4.7/nad
+    tar xzvf ../../proj-nad27-1.1.tar.gz
+    cd ..
+    ./configure
+    make
+    make install
+
+
+[ ] These next few commands are required for now, but once
+libgeotiff is fixed so that it finds libproj properly on Cygwin,
+they'll be removed from the libproj instructions:
+
+    cd /usr/lib
+    ln -s /usr/local/lib/libproj.a
+    ln -s /usr/local/lib/libproj.la
+
+
+
+Adding libgeotiff (tested with libgeotiff-1.2.0):
+-------------------------------------------------
+
+[ ] Type:
+
+    cd ~/src
+    mkdir libgeotiff
+
+[ ] Download libgeotiff-1.2.0 and place it in the libgeotiff
+subdirectory.
+
+    cd ~/src/libgeotiff
+    tar xzvf libgeotiff-1.2.0.tar.gz
+    cd libgeotiff-1.2.0
+    ./configure
+    make
+    make install
+
+If you must re-run "configure" for any of these libraries, remember
+to delete "config.status" and "config.cache" files first.
+
+[ ] You may get the "undefined reference impure_ptr" messages (just
+like with Shapelib above).  If so, edit the file
+/usr/include/sys/reent.h to remove the word "extern" from this line:
+
+    extern struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
+
+then try "make" and "make install" again.
+
+I've had it compile all the way through, but I've also had it bomb
+out when it gets to the "ld -shared" step.  At that point it writes
+a lot of "undefined reference" messages.  The line at which the
+compile might fail:
+
+
+    ld -shared xtiff.o geo_free.o geo_get.o geo_names.o geo_new.o
+    geo_print.o geo_set.o geo_tiffp.o geo_write.o geo_trans.o
+    geo_normalize.o geotiff_proj4.o geo_extra.o cpl_serv.o cpl_csv.o -lproj
+    -ltiff -ljpeg -lz -lm -L/usr/local/lib -o libgeotiff.so.1.1.5
+
+
+To fix this, edit the Makefile to add "-lc" to the end of the LIBS
+line and run "make" again, then "make install".
+
+
+[ ] TEMPORARY:  It looks like we need to switch to a newer version
+of the libtiff DLL in order to work with libgeotiff.  Some Cygwin
+installations end up with this "cygtiff3.dll.new" file installed in
+/bin, some do not.  If the images appear to load but always come up
+black, you need to get a different cygtiff3.dll file that works on
+your system.  Below are the instructions for fixing this problem if
+that file is already present:
+
+    cd /bin
+    mv cygtiff3.dll cygtiff3.dll.old
+    cp cygtiff3.dll.new cygtiff3.dll
+
+
+[ ] Set up Xastir to use the new geotiff libraries:
+
+    cd ~/src/xastir
+    ./configure
+    make
+    make install
+
+It should find libtiff/libproj/libgeotiff at the configure stage and
+compile in support for geotiff maps.  You should now be able to use
+USGS GeoTIFF topo maps, and see them tiled together in the map
+window into a continuous map.
+
+
+
+OPTIONAL:  Install Festival support:
+------------------------------------
+Allows using a synthesized voice from within Xastir for alerts,
+reading messages to you, and other cool things.  Tom Russo did the
+initial work on this, Henk de Groot optimized it:
+
+1) Start BASH shell in Cygwin
+
+2) Make ~/festival download directory and
+    /usr/local/festival installation directory
+
+3) Download festival components from festvox.org into ~/festival, in
+   the Windows environment the corresponding path is:
+
+     C:\Cygwin\home\%USERNAME%\festival
+
+    get the following files:
+
+     speech_tools-1.2.95-beta.tar.gz
+     festival-1.95-beta.tar.gz
+     festlex-CMU.tar.gz
+     festlex-POSLEX.tar.gz
+     festvox-kallpc16k.tar.gz
+
+4) Build festival and company:
+
+    cd /usr/local/festival
+    tar xzf ~/festival/speech_tools-1.2.95-beta.tar.gz
+    tar xzf ~/festival/festival-1.95-beta.tar.gz
+    tar xzf ~/festival/festlex_CMU.tar.gz
+    tar xzf ~/festival/festlex_POSLEX.tar.gz
+    tar xzf ~/festival/festvox_kallpc16k.tar.gz
+
+    cd speech_tools
+    ./configure && make
+    cd ../festival
+    ./configure && make
+
+   These packages are build and used where they are compiled.
+
+5) Test festival:
+
+    cd /usr/local/festival/festival/examples
+    sh saytime
+
+   Festival should say the time if everything went fine
+
+6) Add /festival/festival/bin to PATH in .profile and .bashrc. For
+   me both files look like this:
+
+    .profile and .bashrc:
+    -------------------
+    export PATH=$PATH:/lib:/usr/lib:/usr/X11R6/lib:/usr/local/lib:/usr/local/bin:/usr/local/festival/festival/bin:~/bin:.
+
+    -------------------
+
+7) Configure and build xastir.  Configure should report that
+   festival is found.
+
+8) Start the festival server:
+
+    festival --server &
+
+   To do this automatically I added the following lines to my
+   .bash_profile:
+
+    -------------------
+    if  [ `ps -ef | grep festival | wc -l` -eq 0 ]
+    then
+      festival --server &
+      sleep 1
+    fi
+    -------------------
+
+9) Run xastir, do File->Configure->Speech, add things to say, and
+   listen.
+
+
+
+How to make Sound Alerts work under Cygwin
+------------------------------------------
+(from Kirk Mefford, kc2elo)
+"I figured I'd share exactly what I did to make the sound alerts work in
+xastir under Cygwin. Sound support seems to be just one of the many quirks
+of trying to use *nix native software under Microsoft OS's. Hope this helps
+someone else.
+
+FYI: This was tested under Win2000
+
+Sound alert support under Cygwin using Network Audio Server (NAS)
+
+I downloaded http://nas.intra-links.net/files/nas-1.6-win-binary.zip and
+decompressed the archive with winzip (any zip utility should work fine) into
+a temporary folder.
+
+I deleted the "cygwin1.dll" and "README.txt" files that came in the package
+since they aren't needed and the extra cygwin1.dll can cause problems.
+
+
+  Note from James Cour, K1ZC:
+  ---------------------------
+  "The procedure he (Kirk) outlines there works fine EXCEPT that
+  there is a valuable piece of information in that Readme.txt file...
+  The user must have a folder named /DEV under the Cygwin folder in
+  order for NASD to work.  NASD will not create it automatically, and
+  NASD will not run without it.  The default set-up instructions for
+  Xastir and Cygwin do not create this folder, so the user needs to
+  manually create the folder from Windows."
+
+
+  Note from Tim Baggett, AA5DF:
+  -----------------------------
+  "I recommend running the script (create_devices.sh) found attached
+  to the email located at the URL below to create the /dev directory,
+  and all supported devices under Cygwin."
+
+  "http://cygwin.com/ml/cygwin-xfree/2004-01/msg00353.html"
+
+
+Then copy the remaining files from the package into the /bin directory under
+cygwin.
+
+All that is needed to make nas available to xastir is to load the server
+before running xastir.
+
+To load NAS for xastir to use simply type "nasd -local -b" from cygwin. This
+command will load the NAS server in the background and will only allow local
+users to access it.  For more command options type "nasd -help" from within
+cygwin.  Some people have trouble with the "-local" option, so try
+it without that option as well ("nasd -b").
+
+After NAS is loaded you can load xastir as you normally would.
+
+Once xastir is running, to play sound alerts you need to change the default
+configuration to use "auplay"
+
+From within xastir click on File>Configure>Audio Alarms.
+The "Audio Play Command" box should be changed to "auplay"
+Then ensure the audio files listed to play are located in
+"/usr/local/share/xastir/sounds" directory.
+
+Click OK to accept the changes and be sure to save your config before
+exiting xastir or sound will not work the next time it is loaded.
+
+Turn up the volume on your PC speakers and enjoy the noise xastir makes."
+
+
+OPTIONAL:  Install GDAL/OGR support:
+------------------------------------
+One user has been successful in compiling GDAL/OGR support into
+Xastir.  One thing he mentioned:
+
+"Now the word of warning.  If you try to compile GDAL under Cygwin
+and the compile blows up, you are better rm -rvf'ing the entire
+directory and re-untaring the source again than trying to recompile
+in that blown directory.  Make Clean doesn't do a thing and the old
+settings and mistakes stick around no matter what you try."
+
+Make sure you've got Shapelib installed on your system else Xastir
+won't find GDAL (the private Xastir copy of Shapelib is fine).  Both
+are needed.
+
+Download "gdal-1.2.0b.tar.gz".  In a cygwin window, type the
+following:
+
+
+    tar xzvf gdal-1.2.0b.tar.gz
+    cd gdal-1.2.0b
+    ./configure --with-jpeg=internal --with-libtiff=internal
+    make
+    make install
+
+
+The GDAL/OGR library should now be installed on your system.  Return
+to the xastir directory and start with the ./configure command.  It
+should pick up the fact that GDAL/OGR has been installed and compile
+support for it into Xastir.  Follow with the rest of the commands to
+make/install Xastir.
+
+One user required the below GDAL configure line as otherwise it
+complained about not finding libproj:
+
+    ./configure --with-jpeg=internal --with-libtiff=internal --with-static-proj4
+
+
+APRS(tm) is a Trademark of Bob Bruninga
+
+Copyright (C) 2003-2012 The Xastir Group
+
diff --git a/TXRadar.geo b/TXRadar.geo
new file mode 100644
index 0000000..d795090
--- /dev/null
+++ b/TXRadar.geo
@@ -0,0 +1,23 @@
+#
+# $Id: TXRadar.geo,v 1.1 2004/10/05 15:54:25 we7u Exp $
+#
+#US Composite Radar image (Unidata/LDM/Gempak) n5jxs 2003 08 25
+URL     http://mesonet.tamu.edu/gemdata/images/radar/01_mesonet.png
+#                       X               Y               Long			Lat
+TIEPOINT                200             200             -104.80000		35.50000
+TIEPOINT                1130            1090            -95.50000		26.60000
+# Image extents: Lat: 24.6N to 37.5N, Lon: 93.5W to 106.8W (-93.5 to -106.8) # Image size extents: X: 1330 pixels, Y: 1290 pixels (.01 deg/pixel)
+IMAGESIZE 1330 1290
+#
+# REFRESH tells your program just how often to retrieve the radar
+# image.  Images are recreated on the server every 6 minutes (720 sec).
+REFRESH 720
+# Transparent tells the program and image handling software what color
+#is to be considered transparent.  In this case, it's white and valid
+# for a 24-bit color map.
+#TRANSPARENT 0xffffff
+# The following should work for a 16-bit color map.
+#TRANSPARENT 0x0ffff
+# The following should work for all color maps, now.
+TRANSPARENT 0x0ffffffff
+
diff --git a/UPGRADE b/UPGRADE
new file mode 100644
index 0000000..814f431
--- /dev/null
+++ b/UPGRADE
@@ -0,0 +1,95 @@
+
+$Id: UPGRADE,v 1.18 2012/11/01 18:57:18 we7u Exp $
+
+
+Previous Install Notes:
+-----------------------
+     Backup all previous installed data!
+
+  Xastir 0.1.0 users (if there are any of you still around!):
+
+     For Xastir version 0.1.0 and below there are new file locations:
+     All map data, TNC config data, and support files now go under the
+     /usr/local/xastir directory. All personal config data, logs, etc are
+     user the (user home dir)/.xastir directory (which will be created after
+     xastir starts). You can copy (after your first xastir startup) your
+     xastir.cnf file to your (user home dir)/.xastir/config directory. MAKE
+     SURE YOU DELETE all lines referencing Files! Xastir may not run properly
+     if you don't!
+
+     If you have Xastir version 0.1.1 then your files are in the right place,
+     just follow the typical build instructions.
+
+  Xastir 0.2.0 users:
+
+     Xastir 0.2.0 and newer have new device controls so you will need to
+     setup your devices again with 0.2.0.
+     Look at File->Configure->Interfaces and File->Configure->Defaults
+
+  Xastir 0.3.x, 0.9.x, 1.0.x, 1.1.0:
+
+     Versions above 1.1 drop privileges if they are run as root. If any of the
+     Xastir files are owned by root, on only readable by root, they will cause
+     problems. Fix these files by "chmod 644 filename" where filename is the
+     problem file.
+
+  Xastir 1.2.1 or later CVS:
+
+     On or about July 3rd, 2003, the locations of the Xastir system directories
+     were changed.  Existing users must go through this procedure in order to
+     convert to the new directory structure.  Note that if you've installed
+     Xastir from RPM's or other packages, the migration scripts
+     (xastir-migrate.sh and xastir-fixcfg.sh) may not work properly for you.
+     These scripts are designed to move Xastir's system directories only from
+     /usr/local/xastir to the new locations.  If your Xastir files are
+     installed elsewhere (/usr/share/xastir, /usr/lib/xastir, /usr/bin), you
+     may need to perform the alternate procedure listed below under ALTERNATE.
+
+        cd src/xastir
+        cvs update
+        ./bootstrap.sh
+        ./configure
+        make
+        Shut down any running Xastir instances
+        cd scripts
+        su
+        ./xastir-migrate.sh (this will move the Xastir system directories)
+        make install (or make install-strip)
+        chmod 4555 /usr/local/bin/xastir (only if required)
+        exit (from root)
+        ./xastir-fixcfg.sh (run this for each user that has ever run Xastir)
+
+
+     ALTERNATE PROCEDURE (see note above):
+
+        Remove the installed Xastir using the system tools for doing so (apt,
+        rpm, etc).  You'll probably wish to keep your maps directories and
+        your ~/.xastir/config/xastir.cnf files.  Make sure to delete any
+        "callpass" or "xastir" binaries as well.
+
+        Remove your ~/.xastir directory, subdirectories, and all contents
+        (remember to save your xastir.cnf file if some of the settings are
+        important to you).
+
+        Move your maps directory to "/usr/local/share/xastir/maps"
+
+        Configure/compile/install the new Xastir.
+
+        When you start up the new Xastir, it will create a new xastir.cnf file
+        with the proper directory paths defined in order to find the maps.
+        
+     After you start the new Xastir, you'll need to re-index all maps.  The
+     Xastir binary should be in /usr/local/bin/xastir if you installed from
+     sources.  Xastir files are now installed in:
+
+        /usr/local/bin/
+        /usr/local/lib/xastir/
+        /usr/local/man/
+        /usr/local/share/xastir/*
+ 
+        
+ 
+  ------------------------------------------------------------------------
+Copyright (C) 1999 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
diff --git a/USRadar.geo b/USRadar.geo
new file mode 100644
index 0000000..523e927
--- /dev/null
+++ b/USRadar.geo
@@ -0,0 +1,37 @@
+#
+# $Id: USRadar.geo,v 1.5 2006/12/01 21:47:11 we7u Exp $
+#
+#US Composite Radar image (Unidata/LDM/Gempak) n5jxs 2003 08 25
+# Modified for accuracy, comments:  n5jxs 2004 03 15 1400UTC
+#
+# If you want to get a different image-type, change the selection
+# below by removing the '#' from the front of the URL, and placing
+# a '#' before all URLs for image-types you don't want.
+# I don't know what will happen if you have multiple URLs selected.
+URL     http://mesonet.tamu.edu/gemdata/images/radar/01_USrad.png
+#URL     http://mesonet.tamu.edu/gemdata/images/radar/01_USrad.gif
+#URL     http://mesonet.tamu.edu/gemdata/images/radar/01_USrad.jpg
+#URL     http://mesonet.tamu.edu/gemdata/images/radar/01_USrad.tif
+#
+#
+#           X       Y       Long        Lat
+TIEPOINT    200     200     -123.00000  48.00000
+TIEPOINT    5999    2499    -65.00000   23.00000
+# Image extents: Lat: 23.0N to 50.0N, Lon: 65.0W to 125.0W (-65.0 to -125.0)
+# Image size extents: X: 6000 pixels, Y: 2650 pixels (.01 deg/pixel)
+IMAGESIZE 6000 2500
+#
+# REFRESH tells your program just how often to retrieve the radar
+# image.  Images are recreated on the server every 6 minutes (720
+# sec).
+REFRESH 720
+# Transparent tells the program and image handling software what
+# color is to be considered transparent.  In this case, it's white
+# and valid for a 24-bit color map.
+#TRANSPARENT 0xffffff
+# The following should work for a 16-bit color map.
+#TRANSPARENT 0x0ffff
+# The following should work for all color maps, now.
+#TRANSPARENT 0x0ffffffff
+TRANSPARENT 0x000000000
+
diff --git a/WMSRadar.geo b/WMSRadar.geo
new file mode 100644
index 0000000..05f7def
--- /dev/null
+++ b/WMSRadar.geo
@@ -0,0 +1,17 @@
+WMSSERVER
+#URL http://mesonet.tamu.edu/cgi-bin/CONUSradar?SERVICE=WMS&LAYERS=radar,nwscounties
+URL http://mesonet.tamu.edu/cgi-bin/CONUSradar?SERVICE=WMS&LAYERS=radar&FORMAT=image/png&TRANSPARENT=TRUE&CRS=CRS:84&BGCOLOR=0x000000&VERSION=1.1.0
+#
+#
+# REFRESH tells your program just how often to retrieve the radar
+# image.  Images are recreated on the server every 6 minutes (720
+# sec).
+REFRESH 720
+#
+#
+# Black
+TRANSPARENT 0x010101
+TRANSPARENT 0x000000
+# White
+TRANSPARENT 0xffffff
+
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..6e8a31d
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,1106 @@
+# acinclude.m4 for Xastir
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# $Id: acinclude.m4,v 1.88 2012/11/01 18:57:18 we7u Exp $
+
+# test for devices.  Avoid the tests on Cygwin as they hang on some
+# WinXP boxes.
+#
+AC_DEFUN([XASTIR_DETECT_DEVICES],
+[
+AC_MSG_CHECKING([for devices])
+if test -d /proc/registry ; then
+ac_tnc_port=/dev/ttyS0
+ac_gps_port=/dev/ttyS1
+elif test -c /dev/cuaa0 ; then
+ac_tnc_port=/dev/cuaa0
+ac_gps_port=/dev/cuaa1
+elif test -c /dev/ttyS0 ; then
+ac_tnc_port=/dev/ttyS0
+ac_gps_port=/dev/ttyS1
+elif test -c /dev/cua/a ; then
+ac_tnc_port=/dev/cua/a
+ac_gps_port=/dev/cua/b
+else
+ac_tnc_port=none
+ac_gps_port=none
+fi
+
+AC_DEFINE_UNQUOTED([TNC_PORT], "$ac_tnc_port", [Default TNC port.])
+AC_DEFINE_UNQUOTED([GPS_PORT], "$ac_gps_port", [Default GPS port.])
+AC_MSG_RESULT(found $ac_tnc_port and $ac_gps_port)
+])
+
+# add search paths
+AC_DEFUN([XASTIR_ADD_SEARCH_PATHS],
+[
+AC_MSG_CHECKING([for search paths])
+
+test -d /usr/local/include && CPPFLAGS="-I/usr/local/include $CPPFLAGS"
+test -d /usr/local/lib && LDFLAGS="-L/usr/local/lib $LDFLAGS"
+
+for d in /sw /opt /opt/local /usr/dt/share /usr/sfw /opt/sfw; do
+test -d $d/include && CPPFLAGS="$CPPFLAGS -I$d/include"
+test -d $d/lib && LDFLAGS="$LDFLAGS -L$d/lib"
+done
+
+AC_MSG_RESULT([done])
+])
+
+# add compiler flags
+AC_DEFUN([XASTIR_COMPILER_FLAGS],
+[
+# notes -- gcc only! HPUX doesn't work for this so no "-Ae +O2"
+
+
+# everybody likes "-g -O2", right?
+# TVR: Not only does "everybody" not like "-g -O2", but the code below
+# is unnecessary for GCC, which does like "-g -O2".  The autoconf macros that 
+# probe for the C  compiler will put "-g -O2" into CFLAGS if the compiler is
+# GCC and the user has not specified any CFLAGS, and leaves CFLAGS alone
+# if the user has set it him/herself.  The "##" commented code
+# below forces -g -O2 into CFLAGS even if the user has specified something
+# else.
+##for f in -g -O2; do
+## eventually write a test for these
+## gcc already checks for -g earlier!
+##echo $CFLAGS | grep -- $f > /dev/null || CFLAGS="$CFLAGS $f"
+##done
+
+# brutal!
+# check for sed maybe?
+if test "$ac_cv_prog_ac_ct_CC" = "gcc"; then
+gcc --help | sed -e "/^[^ ]/d" -e "/^ [^ ]/d" -e "/^  [^-]/d" -e "s/  //" -e "s/ .*//" > gccflags
+
+# I need a test for -Wno-return-type and -DFUNCPROTO=15
+# before adding them
+
+for f in -no-cpp-precomp -pipe; do
+grep -- $f gccflags > /dev/null && CFLAGS="$CFLAGS $f"
+done
+
+# delete temporary file
+rm -f gccflags
+
+# add any other flags that aren't added earlier
+# Can't add "-Wno-unused-parameter" as older compilers don't like
+# it.  
+#
+for f in -W -Wall -Wpointer-arith -Wstrict-prototypes; do
+echo $CFLAGS | grep -- $f > /dev/null || CFLAGS="$CFLAGS $f"
+done
+
+# Now check whether to use -Wno-unused-parameter (gcc 3) or -Wno-unused
+AC_MSG_CHECKING([whether compiler accepts -Wno-unused-parameter])
+save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS -Wno-unused-parameter"
+AC_TRY_COMPILE([] ,[int i;],[AC_MSG_RESULT([yes])] ,
+[AC_MSG_RESULT([no, using -Wno-unused]); CFLAGS="$save_CFLAGS -Wno-unused"])
+
+# end gcc-specific checks
+fi
+
+# add any pthread flags now
+CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+AC_MSG_CHECKING([for compiler flags])
+AC_MSG_RESULT(using $CFLAGS)
+])
+
+# set XASTIR_SYSTEM
+# JMT - is this really necessary?
+AC_DEFUN([XASTIR_SET_SYSTEM],
+[
+AC_MSG_CHECKING([for system])
+
+case "$host_os" in
+cygwin*)
+  system=Cygnus
+;;
+darwin*)
+  system=Darwin
+  LDFLAGS="-L/sw/lib -L/opt/local/lib $LDFLAGS"
+  CPPFLAGS="-I/sw/include -I/opt/local/include $CPPFLAGS"
+  EXTRA_BIN_PATH=":/opt/local/bin:/sw/bin"
+;;
+freebsd*)
+  system=FreeBSD
+;;
+hpux*)
+  system=HP/UX
+;;
+linux*)
+  system=Linux
+#
+#
+# Useful for testing MacOSX paths on a Linux development box:
+#  EXTRA_BIN_PATH=":/opt/local/bin:/sw/bin"
+#
+#
+;;
+netbsd*)
+  system=NetBSD
+;;
+openbsd*)
+  system=OpenBSD
+;;
+solaris*)
+  system=Solaris
+;;
+*)
+  system=unknown
+;;
+esac
+
+AC_DEFINE_UNQUOTED([XASTIR_SYSTEM], "$system", [Define system type.])
+AC_MSG_RESULT($system)
+])
+
+AC_DEFUN([XASTIR_DETECT_BINARIES],
+[
+BINPATH=$PATH
+
+for d in / /usr /usr/local /usr/X11 /usr/X11R6 /usr/sfw /opt/sfw /opt/local /sw; do
+test -d $d/bin && echo $BINPATH | grep -- $d/bin > /dev/null || BINPATH="$BINPATH:$d/bin"
+done
+
+# it would be much nicer to do this in a for loop
+
+if test "$use_lsb" = "yes"; then
+  AC_DEFINE_UNQUOTED(HAVE_CONVERT, 1, [Define if you have gm or convert]) 
+  AC_DEFINE_UNQUOTED(CONVERT_PATH, "/opt/Xastir/bin/gm convert", [Path to gm or convert]) 
+else
+  AC_PATH_PROG(gm, [gm version], no, $BINPATH)
+  AC_CHECK_FILE(/usr/bin/gm.exe, gm="/usr/bin/gm")
+  if test "$gm" != "no"; then
+    AC_DEFINE_UNQUOTED(HAVE_CONVERT, 1, [Define if you have gm or convert]) 
+    AC_DEFINE_UNQUOTED(CONVERT_PATH, "${gm} convert", [Path to gm or convert])
+  else 
+    AC_PATH_PROG(convert, [convert --version], no, $BINPATH)
+    AC_CHECK_FILE(/usr/bin/convert.exe, convert="/usr/bin/convert")
+    if test "$convert" != "no"; then
+      AC_DEFINE_UNQUOTED(HAVE_CONVERT, 1, [Define if you have convert]) 
+      AC_DEFINE_UNQUOTED(CONVERT_PATH, "${convert}", [Path to convert]) 
+    fi
+  fi
+fi
+ 
+AC_PATH_PROG(lpr, [lpr /dev/null], no, $BINPATH)
+if test "$lpr" != "no"; then
+  AC_DEFINE_UNQUOTED(HAVE_LPR, 1, [Define if you have lpr]) 
+  AC_DEFINE_UNQUOTED(LPR_PATH, "${lpr}", [Path to lpr]) 
+fi
+
+#Find gv executable
+AC_PATH_PROG(gv, [gv], no, $BINPATH)
+
+if test "$gv" != "no"; then
+  # Test gv version
+  AC_MSG_CHECKING([gv version])
+  gv_new="no";
+  gv_version=`gv --version 2>&1`
+  gv_test=`echo $gv_version | cut -d ' ' -f 1`
+  if test "$gv_test" != "gv"; then
+    gv_version=`gv -v 2>&1`
+  fi
+  gv_test=`echo $gv_version | cut -d ' ' -f 1`
+  if test "$gv_test" != "gv"; then
+    # No gv found.  Put an AC_PATH_PROG here so the "then" clause has
+    # something to do and so that we get proper output to the user.
+    AC_MSG_RESULT([gv version test likely exited with error, this is what it said: $gv_version])
+  else
+    gv_short_version=`echo $gv_version | cut -d ' ' -f 2`
+    gv_major=`echo $gv_short_version | cut -d '.' -f 1`
+    gv_minor=`echo $gv_short_version | cut -d '.' -f 2`
+    gv_tiny=`echo $gv_short_version | cut -d '.' -f 3`
+    if test "$gv_major" -gt 3; then
+      gv_new="yes";
+    elif test "$gv_major" -ge 3 -a "$gv_minor" -gt 6; then
+      gv_new="yes";
+    elif test "$gv_major" -ge 3 -a "$gv_minor" -ge 6 -a "$gv_tiny" -ge 1; then
+      gv_new="yes";
+    fi
+    if test "$gv_new" != "no"; then
+      AC_MSG_RESULT([new, >= 3.6.1])
+      AC_DEFINE_UNQUOTED(HAVE_GV, 1, [Define if you have gv])
+      AC_DEFINE_UNQUOTED(HAVE_NEW_GV, 1, [Define if you have old gv])
+      AC_DEFINE_UNQUOTED(GV_PATH, "${gv}", [Path to gv])
+    else
+      AC_MSG_RESULT([old, pre 3.6.1])
+      AC_DEFINE_UNQUOTED(HAVE_GV, 1, [Define if you have gv])
+      AC_DEFINE_UNQUOTED(HAVE_OLD_GV, 1, [Define if you have old gv])
+      AC_DEFINE_UNQUOTED(GV_PATH, "${gv}", [Path to gv])
+    fi
+  fi
+fi
+
+if test "$use_festival" != "no"; then 
+ AC_PATH_PROG(festival, [festival], no, $BINPATH)
+ if test "$festival" != "no"; then
+   AC_DEFINE_UNQUOTED(HAVE_FESTIVAL, 1, [Define if you have festival])
+ fi
+fi
+
+if test "$use_gpsman" != "no"; then
+ AC_PATH_PROG(gpsman, [gpsman haslib gpsmanshp], no, $BINPATH)
+ if test "$gpsman" != "no"; then
+   AC_DEFINE_UNQUOTED(HAVE_GPSMAN, 1, [Define if you have gpsman])
+   AC_DEFINE_UNQUOTED(GPSMAN_PATH, "${gpsman}", [Path to gpsman])
+ fi
+fi
+
+if test "$use_err_popups" != "no"; then
+ AC_DEFINE_UNQUOTED(HAVE_ERROR_POPUPS, 1, [Define if you have error popups enabled])
+fi
+
+if test "$use_lsb" != "no"; then
+ AC_DEFINE_UNQUOTED(__LSB__, 1, [Define if you're compiling for Linux Standard Base])
+fi
+
+
+
+])
+
+
+
+
+
+# TVR - I don't think this is quite as evil as Jack thinks CHECK_IMAGEMAGICK is
+# It assumes that gdal-config is in the user's path, and doesn't try to
+# explore alternate paths.
+AC_DEFUN([XASTIR_CHECK_GDAL],
+[
+use_gdal=no
+#
+# Important: DO NOT use "use_gdal" as the variable here, because AC_CHECK_PROG
+# will do nothing if the variable is already set!
+#
+AC_CHECK_PROG(found_gdal_config, [gdal-config], yes, no)
+if test "${found_gdal_config}" = "yes"; then
+   save_cppflags="$CPPFLAGS" 
+   save_libs="$LIBS" 
+   save_ldflags="$LDFLAGS" 
+
+   GDAL_BIN="gdal-config"
+   CPPFLAGS="$CPPFLAGS `${GDAL_BIN} --cflags`" 
+#
+# This is an annoyance: gdal-config --libs outputs both LDFLAGS and LIBS 
+# stuff.  AC_CHECK_LIB puts the -l in if it works, and we only want the LDFLAGS
+#   LIBS="$LIBS `${GDAL_BIN} --libs`"
+# Remove the -lgdal from what gdal-config --libs returns, because AC_CHECK_LIB
+# will put it into LIBS for us.
+#
+   LDFLAGS="$LDFLAGS `${GDAL_BIN} --libs | sed -e 's/-lgdal[^ ]*//'`"
+   AC_CHECK_HEADERS(gdal.h, [AC_CHECK_LIB(gdal, GDALAllRegister,
+                    [use_gdal="yes"
+                     LIBS="$LIBS -lgdal"
+                     AC_DEFINE(HAVE_LIBGDAL, , 
+                      [Define to 1 if you have the `gdal' library (-lgdal).])],
+                    [CPPFLAGS=${save_cppflags}
+                     LDFLAGS=${save_ldflags}
+                     LIBS=${save_libs}])])
+else
+   AC_MSG_WARN([*** Cannot find gdal-config:  Checking standard locations ***])
+   AC_CHECK_HEADERS(gdal.h, [AC_CHECK_LIB(gdal, GDALAllRegister,
+                    [use_gdal="yes"
+                     LIBS="$LIBS -lgdal"
+                     AC_DEFINE(HAVE_LIBGDAL, , 
+                      [Define to 1 if you have the `gdal' library (-lgdal).])],)])
+fi
+]
+)
+
+
+
+AC_DEFUN([XASTIR_CHECK_POSTGIS],
+[
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+# test for postgresql
+if test "${with_postgis+set}" = set; then
+  PG_CONFIG="pg_config"
+  if test "$with_postgis" != "yes"; then 
+    # get path if provided
+    pg_path="$with_postgis"
+    PG_CONFIG_PATH="${pg_path}/bin"
+    BINPATH="${BINPATH}:${PG_CONFIG_PATH}"
+    POSTGIS_LIB_DIR="-L${pg_path}/lib"
+    AC_PATH_PROG(PG_CONFIG, [pg_config], no, $PG_CONFIG_PATH)
+  else 
+    AC_PATH_PROG(PG_CONFIG, [pg_config], no)
+  fi
+  if test "$PG_CONFIG" != "no"; then
+    # Check for postgis spatial extensions.
+    # Look for lwpostgis.sql script in default location.
+    # If found, is likely a postgis installation.
+    # Need more definitive test for postgis, as this may fail to detect postgres 
+    # installations where this script was removed, and will incorrectly 
+    # detect postgres without postgis where this script has been installed but not run.
+    AC_PATH_PROG(LWPOSTGIS, [lwpostgis.sql], no, "${pg_path}/share")
+    if test "LWPOSTGIS" != "no"; then 
+       #postgres with postgis enabled
+       use_postgis=yes
+       use_spatial_db=yes
+       save_cppflags="$CPPFLAGS" 
+       save_cxxflags="$CXXFLAGS" 
+       save_libs="$LIBS" 
+       save_ldflags="$LDFLAGS" 
+       CPPFLAGS="$CPPFLAGS -I`${PG_CONFIG} --includedir` `${PG_CONFIG} --cppflags`" 
+       CXXFLAGS="$CXXFLAGS `${PG_CONFIG} --cflags`" 
+       LDFLAGS="$LDFLAGS `${PG_CONFIG} --ldflags`" 
+       LIBS="${POSTGIS_LIB_DIR} `${PG_CONFIG} --libs` -lpq $LIBS" 
+       AC_DEFINE(HAVE_POSTGIS, 1, Postgresql with postgis is present. )
+    else
+       AC_MSG_WARN(*** Cannot find lwpostgis.sql:  Building w/o Postgresql/Postgis support. ***)
+       AC_MSG_WARN(*** Postgresql was found, but does not appear to have Postgis added.     ***)
+       AC_MSG_WARN(*** Install and enable postgis and leave the lwpostgis.sql script in     ***)
+       AC_MSG_WARN(*** ${pg_path}/share                                                     ***)
+    fi
+  else
+    use_postgis=no
+    AC_MSG_WARN(*** Cannot find pg_config:  Building w/o Postgresql/Postgis support. ***)
+    AC_MSG_WARN(*** Specify the path to the posgresql installation directory         ***)
+    AC_MSG_WARN(*** For example: --with-postgis=/usr/local/pgsql                     ***)
+  fi
+fi
+
+])
+
+AC_DEFUN([XASTIR_CHECK_MYSQL],
+[
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+
+# test for MySQL
+if test "${with_mysql+set}" = set; then
+  MYSQL_CONFIG="mysql_config"
+  if test "$with_mysql" != "yes"; then 
+    # get path to mysql_config if provided
+    mysql_path="$with_mysql"
+    BINPATH="${BINPATH}:${mysql_path}"
+    AC_PATH_PROG(MYSQL_CONFIG, [mysql_config], no, $mysql_path)
+  else 
+    AC_PATH_PROG(MYSQL_CONFIG, [mysql_config], no)
+  fi
+  use_mysql_spatial=no
+  use_mysql_any=no
+  if test "$MYSQL_CONFIG" != "no"; then
+  
+    # check for mysql version with spatial support 
+    # look for mysql 4.1.2 or greater for spatial support 
+    # and standardized prepared statements
+    # 4.1.0 and 4.1.1 have spatial support, but only early versions
+    # of prepared statement functions that changed in 4.1.2
+    AC_MSG_CHECKING([mysql version >= 4.1.2])
+    mysqlversion=`$MYSQL_CONFIG --version`
+    mysqlversionmajor=`echo ${mysqlversion} | cut -d '.' -f 1`
+    mysqlversionminor=`echo ${mysqlversion} | cut -d '.' -f 2`
+    mysqlversiontiny=`echo ${mysqlversion} | cut -d '.' -f 3`
+    if test "$mysqlversionmajor" -gt 4 ; then
+      mysql_has_spatial="yes"
+    elif test "$mysqlversionmajor" -ge 4 -a "$mysqlversionminor" -gt 1 ; then
+      mysql_has_spatial="yes"
+    elif test "$mysqlversionmajor" -ge 4 -a "$mysqlversionminor" -ge 1 -a "$mysqlversiontiny" -ge 2 ; then
+      mysql_has_spatial="yes"
+    else
+      mysql_has_spatial="no"
+    fi
+    AC_MSG_RESULT($mysql_has_spatial)
+    # if mysql version < 4.1, mysql present but no spatial support 
+    if test "$mysql_has_spatial" = "yes"; then
+       # mysql with spatial support
+       use_mysql_spatial=yes
+       use_spatial_db=yes
+       AC_DEFINE(HAVE_MYSQL_SPATIAL, 1, MySQL with spatial support is present.)
+    else 
+       AC_MSG_WARN(*** MySQL version $mysqlversion detected is < 4.1.2         ***)
+       AC_MSG_WARN(*** Spatial support enabled only for MySQL 4.1.2 and higher ***)
+       AC_MSG_WARN(*** MySQL support for Lat/Long fields is available but      ***)
+       AC_MSG_WARN(*** not for Points Polygons or other spatial objects.       ***)
+    fi
+    save_cppflags="$CPPFLAGS" 
+    save_cxxflags="$CXXFLAGS" 
+    save_libs="$LIBS" 
+    CPPFLAGS="$CPPFLAGS `${MYSQL_CONFIG} --cflags`" 
+    CXXFLAGS="$CXXFLAGS `${MYSQL_CONFIG} --cflags`" 
+    LIBS=" `${MYSQL_CONFIG} --libs` $LIBS" 
+    use_mysql_any=yes
+    AC_DEFINE(HAVE_MYSQL, 1, MySQL is present.)
+  else
+    AC_MSG_WARN(*** Cannot find mysql_config:  Building w/o MySQL support. ***)
+    AC_MSG_WARN(*** Specify the path to mysql_config                       ***)
+    AC_MSG_WARN(*** For example: --with-mysql=/var/lib/mysql               ***)
+  fi
+
+fi
+#AC_MSG_RESULT($use_mysql_spatial)
+])
+
+
+
+AC_DEFUN([XASTIR_CHECK_IMAGEMAGICK],
+[
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+
+# Check for ImageMagick 
+# 
+# First look for the needed Magick-config script, which tells us all
+# of the build options we need.
+#
+# Important: DO NOT use "use_imagemagick" as the variable here,
+# because AC_CHECK_PROG will do nothing if the variable is already set!
+#
+use_imagemagick=no
+AC_PATH_PROG(MAGIC_BIN, [Magick-config], no, $BINPATH)
+if test "$MAGIC_BIN" != "no"; then
+  use_imagemagick=yes
+#else
+#  AC_MSG_WARN(*** Cannot find Magick-config:  Building w/o ImageMagick support. ***)
+fi
+
+if test "${use_imagemagick}" = "yes"; then
+#  #
+#  # Compute the ImageMagick revision number
+#  #
+#  magickversion=`${MAGIC_BIN} --version` 
+#  magickmajor=`echo $magickversion | cut -d '.' -f 1` 
+#  magickminor=`echo $magickversion | cut -d '.' -f 2` 
+#  magicktiny=`echo $magickversion | cut -d '.' -f 3` 
+#  if test "$magickmajor" -lt 5; then 
+#    magickold="yes"; 
+#  elif test "$magickmajor" -eq 5 -a "$magickminor" -lt 4; then 
+#    magickold="yes"; 
+#  elif test "$magickmajor" -eq 5 -a "$magickminor" -eq 4 -a "$magicktiny" -lt 9; then 
+#    magickold="yes"; 
+#  fi
+  #
+  save_cppflags="$CPPFLAGS" 
+  save_cxxflags="$CXXFLAGS" 
+  save_libs="$LIBS" 
+  save_ldflags="$LDFLAGS" 
+  #
+  # Figure out the build options using the Magick-config script
+  #
+  CPPFLAGS="$CPPFLAGS `${MAGIC_BIN} --cppflags`" 
+  CXXFLAGS="$CXXFLAGS `${MAGIC_BIN} --cflags`" 
+  LDFLAGS="$LDFLAGS `${MAGIC_BIN} --ldflags`" 
+  LIBS="${MAGIC_LIB_DIR} `${MAGIC_BIN} --libs` $LIBS" 
+  # 
+  AC_CHECK_HEADER(magick/api.h, use_imagemagick="yes", use_imagemagick="no")
+  if test "${use_imagemagick}" = "no"; then
+    AC_MSG_WARN(*** Cannot find ImageMagick include files:  Building w/o ImageMagick support. ***)
+  else
+    AC_SEARCH_LIBS([WriteImage],[Magick MagickCore], AC_DEFINE(HAVE_IMAGEMAGICK, 1, [Imagemagick image library]), use_imagemagick="no")
+    if test "${use_imagemagick}" = "no"; then
+      AC_MSG_WARN(*** Cannot find ImageMagick library files:  Building w/o ImageMagick support. ***)
+    fi
+  fi
+  #
+  if test "${use_imagemagick}" = "no"; then
+    #
+    # No ImageMagick found.  Restore variables.
+    #
+    CPPFLAGS=$save_cppflags 
+    CXXFLAGS=$save_cxxflags 
+    LIBS=$save_libs 
+    LDFLAGS=$save_ldflags 
+  fi 
+#
+#  if test "${magickold}" = "yes"; then 
+# This used to be important, as some versions didn't support the
+# Tigermap intensity slider.
+#    AC_MSG_WARN(*********************************************************)
+#    AC_MSG_WARN(***     Old ImageMagick version ($magickversion) found.        ***)
+#    AC_MSG_WARN(*** Upgrade to 5.4.9 or newer for full functionality. ***)
+#    AC_MSG_WARN(*********************************************************) 
+#  fi 
+fi
+# End of ImageMagick checks 
+
+])
+
+
+
+
+
+AC_DEFUN([XASTIR_CHECK_GRAPHICSMAGICK],
+[
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+
+# Check for GraphicsMagick 
+# 
+# First look for the needed GraphicsMagick-config script, which tells us all
+# of the build options we need.
+#
+# Important: DO NOT use "use_graphicsmagick" as the variable here,
+# because AC_CHECK_PROG will do nothing if the variable is already set!
+#
+use_graphicsmagick=no
+AC_PATH_PROG(GMAGIC_BIN, [GraphicsMagick-config], no, $BINPATH)
+if test "$GMAGIC_BIN" != "no"; then
+  use_graphicsmagick=yes
+#else
+#  AC_MSG_WARN(*** Cannot find GraphicsMagick-config:  Building w/o GraphicsMagick support. ***)
+fi
+#
+if test "${use_graphicsmagick}" = "yes"; then
+  save_cppflags="$CPPFLAGS" 
+  save_cxxflags="$CXXFLAGS" 
+  save_libs="$LIBS" 
+  save_ldflags="$LDFLAGS" 
+  #
+  # Figure out the build options using the GraphicsMagick-config script
+  #
+  CPPFLAGS="`${GMAGIC_BIN} --cppflags` $CPPFLAGS" 
+  CXXFLAGS="`${GMAGIC_BIN} --cflags` $CXXFLAGS" 
+  LDFLAGS="`${GMAGIC_BIN} --ldflags` $LDFLAGS" 
+  LIBS="${MAGIC_LIB_DIR} `${GMAGIC_BIN} --libs` $LIBS" 
+  # 
+  AC_CHECK_HEADER(GraphicsMagick/magick/api.h, use_graphicsmagick="yes", use_graphicsmagick="no")
+  if test "${use_graphicsmagick}" = "no"; then
+    AC_MSG_WARN(*** Cannot find GraphicsMagick include files: Building w/o GraphicsMagick support. ***)
+  else
+    AC_CHECK_LIB([GraphicsMagick], [WriteImage], AC_DEFINE(HAVE_GRAPHICSMAGICK, 1, [GraphicsMagick image library]), use_graphicsmagick="no")
+    if test "${use_graphicsmagick}" = "no"; then
+      AC_MSG_WARN(*** Cannot find GraphicsMagick library files: Building w/o GraphicsMagick support. ***)
+    fi
+  fi
+  #
+  if test "${use_graphicsmagick}" = "no"; then
+    #
+    # No GraphicsMagick found.  Restore variables.
+    #
+    CPPFLAGS=$save_cppflags 
+    CXXFLAGS=$save_cxxflags 
+    LIBS=$save_libs 
+    LDFLAGS=$save_ldflags 
+  fi
+fi 
+# 
+# End of GraphicsMagick checks 
+
+])
+
+
+
+
+
+# things grabbed elsewhere
+
+# this is from Squeak-3.2-4's acinclude.m4
+AC_DEFUN([AC_CHECK_GMTOFF],
+[AC_CACHE_CHECK([for gmtoff in struct tm], ac_cv_tm_gmtoff,
+  AC_TRY_COMPILE([#include <time.h>],[struct tm tm; tm.tm_gmtoff;],
+    ac_cv_tm_gmtoff="yes", ac_cv_tm_gmtoff="no"))
+test "$ac_cv_tm_gmtoff" != "no" && AC_DEFINE(HAVE_TM_GMTOFF,,X)])
+
+dnl Available from the GNU Autoconf Macro Archive at:
+dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
+dnl
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthread or
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: threads are created detached by default
+        # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
+        AC_MSG_CHECKING([for joinable pthread attribute])
+        AC_TRY_LINK([#include <pthread.h>],
+                    [int attr=PTHREAD_CREATE_JOINABLE;],
+                    ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
+        if test x"$ok" = xunknown; then
+                AC_TRY_LINK([#include <pthread.h>],
+                            [int attr=PTHREAD_CREATE_UNDETACHED;],
+                            ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
+        fi
+        if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
+                AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
+                          [Define to the necessary symbol if this constant
+                           uses a non-standard name on your system.])
+        fi
+        AC_MSG_RESULT(${ok})
+        if test x"$ok" = xunknown; then
+                AC_MSG_WARN([we do not know how to create joinable pthreads])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+                *-aix* | *-freebsd*)     flag="-D_THREAD_SAFE";;
+                *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+                PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with cc_r
+        AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
+
+
+#
+AC_DEFUN([XASTIR_PATH_MOTIF], [
+# New stuff to check for Motif/Lesstif.  Shamelessly borrowed from
+# the opendx project. Opendx in turn snarfed their test from AC_PATH_X.
+
+# Allow "--with-motif-includes" and "--with-motif-libs" so user can 
+# force a specific set of includes.
+AC_ARG_WITH(motif-includes, [  --with-motif-includes     Set path for motif includes (default none)],[with_motif_includes=$withval], [with_motif_includes=])
+if test "$with_motif_includes" != "yes" && test -z "$with_motif_includes"
+then
+        with_motif_includes=
+fi
+
+AC_ARG_WITH(motif-libs, [  --with-motif-libs         Set path for motif libraries (default none)],[with_motif_libs=$withval], [with_motif_libs=])
+if test "$with_motif_libs" != "yes" && test -z "$with_motif_libs"
+then
+  with_motif_libs=
+fi
+
+  # Guess where to find include files, by looking for this one Xm .h file.
+  test -z "$xm_direct_test_include" && xm_direct_test_include=Xm/Xm.h
+
+  # First, try using that file with no special directory specified.
+AC_MSG_CHECKING([for Motif headers])
+AC_PREPROC_IFELSE(
+ [AC_LANG_SOURCE([[#include <$xm_direct_test_include>]])],
+ [
+  # We can compile using X headers with no special include directory.
+  xm_includes=
+  AC_MSG_RESULT([in default path])
+ ],[
+# that test didn't work, we need to hunt a little
+# 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 \
+    "$with_motif_includes"    \
+    ; \
+  do
+    if test -r "$ac_dir/$xm_direct_test_include"; then
+      xm_includes=$ac_dir
+      AC_MSG_RESULT([in $xm_includes])
+      break
+    fi
+  done
+  if test "x$xm_includes" = "x"; then
+    AC_MSG_ERROR([**** NO MOTIF HEADERS FOUND **** install Motif  development headers or use --with-motif-includes to specify location of Xm/Xm.h ])
+  fi
+])
+  # Check for the libraries.
+
+  AC_MSG_CHECKING([for Motif libraries])
+  test -z "$xm_direct_test_library" && xm_direct_test_library=Xm
+  test -z "$xm_direct_test_function" && xm_direct_test_function=XmGetDestination
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$xm_direct_test_library $LIBS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[${xm_direct_test_function}()]])],
+ [
+  LIBS="$ac_save_LIBS"
+  # We can link Motif programs with no special library path.
+  xm_libraries=
+  AC_MSG_RESULT([in default path])
+ ],[
+ 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 "$xm_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 \
+    "$with_motif_libs"     \
+    ; \
+do
+dnl Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/lib${xm_direct_test_library}.$ac_extension; then
+      xm_libraries=$ac_dir
+      AC_MSG_RESULT([in $xm_libraries])
+      break 2
+    fi
+  done
+done
+if test "x$xm_libraries" = "x"; then
+ AC_MSG_ERROR([**** MOTIF LIBRARIES NOT FOUND **** Install Motif development headers/libraries or use --with-motif-libraries to specify path to libXm.a ])
+fi
+])
+])
+
+# From Cyrus imap distribution (KB3EGH)
+
+dnl These are the Cyrus Berkeley DB macros.  In an ideal world these would be
+dnl identical to the above.
+
+dnl They are here so that they can be shared between Cyrus IMAPd
+dnl and Cyrus SASL with relative ease.
+
+dnl The big difference between this and the ones above is that we don't assume
+dnl that we know the name of the library, and we try a lot of permutations
+dnl instead.  We also assume that DB4 is acceptable.
+
+dnl When we're done, there will be a BDB_LIBADD and a BDB_INCADD which should
+dnl be used when necessary.  We should probably be smarter about our RPATH
+dnl handling.
+
+dnl Call these with XASTIR_BERKELEY_DB_CHK.
+
+dnl We will also set $dblib to "berkeley" if we are successful, "no" otherwise.
+
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named and where the db-3 header file is located.  arg.
+AC_DEFUN([XASTIR_BERKELEY_DB_CHK_LIB],
+[
+
+
+# We need to add the following algorithm here:
+#
+#   Find the db.h file, grep for DB_VERSION_MAJOR and
+#     DB_VERSION_MINOR.  In my case I get this:
+#
+#       #define DB_VERSION_MAJOR        4
+#       #define DB_VERSION_MINOR        1
+#
+#   Find the libdb.so file that Xastir would link to.  Find the
+#     version via the target of the symlink?  In my case I have
+#     this:
+#
+#       > ls -al libdb.so
+#       lrwxrwxrwx 1 root root 12 2004-01-07 11:29 libdb.so -> libdb-4.
+#
+#   Compare the major/minor numbers.  If they match, we're good to
+#   go.  If not, don't compile in libdb support.  Perhaps we could
+#   just run ldd on the test code to get the version number of the
+#   linked library instead?
+#
+# Another possible way to do it would be to create test code and
+# compile/run it which would open/write/read/close/delete a
+# database.  That should help to prove that Xastir would run ok if
+# the library were used.
+
+
+
+	BDB_SAVE_LDFLAGS=$LDFLAGS
+
+	if test -d $with_bdb_lib; then
+	    LDFLAGS="-L$with_bdb_lib $LDFLAGS"
+	    BDB_LIBADD="-L$with_bdb_lib $BDB_LIBADD"
+	else
+	    BDB_LIBADD=""
+	fi
+
+	saved_LIBS=$LIBS
+# Removed db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 
+# from the probe.  The map_cache.c code explicitly bombs if it doesn't have
+# version 4 or above, so why probe for version 3?
+
+# it would be nice if this could be done with AC_SEARCH_LIBS but that doesn't
+# work as it appears that there is some C++-type name mangling going on,
+# and just probing for a library that contains "db_create" fails.  One needs
+# to specify the function call with the full prototype for it to be found.
+        BDB_LIB_FOUND="none"
+        AC_MSG_CHECKING([for a library containing db_create])
+        for dbname in db-4.9 db4.9 db49 db-4.8 db4.8 db48 db-4.7 db4.7 db47 db-4.6 db4.6 db46 db-4.5 db4.5 db45 db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db
+          do
+	    LIBS="$saved_LIBS -l$dbname"
+	    AC_TRY_LINK(
+            [#include <db.h>],
+	    [db_create(NULL, NULL, 0);],
+	    [BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; 
+                BDB_LIB_FOUND="-l$dbname"],
+            dblib="no")
+#         STOP if we find one.  Otherwise we'll keep stepping through the 
+#         list and resetting dblib to "no" over and over.
+          if test $dblib = "berkeley" ; then
+            break;
+          fi
+          done
+        AC_MSG_RESULT([$BDB_LIB_FOUND])
+
+# Commented out because the map_cache code is not actually set up to use
+# db_open instead of db_create.  Probing in this way could actually be 
+# dangerous.
+#        if test "$dblib" = "no"; then
+#	    LIBS="$saved_LIBS -ldb"
+#	    AC_TRY_LINK([#include <db.h>],
+#	    [db_open(NULL, 0, 0, 0, NULL, NULL, NULL);],
+#	    BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db,
+#            dblib="no")
+#        fi
+	LIBS=$saved_LIBS
+
+	LDFLAGS=$BDB_SAVE_LDFLAGS
+])
+
+AC_DEFUN([XASTIR_BERKELEY_DB_OPTS],
+[
+AC_ARG_WITH(bdb-libdir,
+	[  --with-bdb-libdir=DIR     Berkeley DB lib files are in DIR],
+	with_bdb_lib=$withval,
+	[ test "${with_bdb_lib+set}" = set || with_bdb_lib=none])
+AC_ARG_WITH(bdb-incdir,
+	[  --with-bdb-incdir=DIR     Berkeley DB include files are in DIR],
+	with_bdb_inc=$withval,
+	[ test "${with_bdb_inc+set}" = set || with_bdb_inc=none ])
+])
+
+AC_DEFUN([XASTIR_BERKELEY_DB_CHK],
+[
+	AC_REQUIRE([XASTIR_BERKELEY_DB_OPTS])
+
+	xastir_save_CPPFLAGS=$CPPFLAGS
+
+	if test -d $with_bdb_inc; then
+	    CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+	    BDB_INCADD="-I$with_bdb_inc"
+	else
+	    BDB_INCADD=""
+	fi
+
+	dnl Note that FreeBSD puts it in a weird place 
+        dnl (/usr/local/include/db42)
+        dnl (but they should use with-bdb-incdir)
+# Commented out because it doesn't distinguish between versions of db.h
+# that can work with xastir and versions that can't.  It is possible to 
+# have multiple versions of db installed in different places, pick up the 
+# header for one and the library for another.  Bleah.
+#        AC_CHECK_HEADER(db.h,
+#                        [XASTIR_BERKELEY_DB_CHK_LIB()],
+#                        dblib="no")
+#
+# Do this instead --- check to see if the db.h we find first in the search
+# path will actually pass the test we do in map_cache.c.  Don't even bother
+# looking for a library if not.  
+        AC_MSG_CHECKING([if db.h is exists and is usable])
+        AC_TRY_COMPILE([#include <db.h>],
+                       [#if (DB_VERSION_MAJOR < 4 )
+                        #error DB_VERSION_MAJOR < 4
+                        #endif],
+                        [AC_MSG_RESULT([yes])
+                        XASTIR_BERKELEY_DB_CHK_LIB()],
+                        [AC_MSG_RESULT([no]); dblib="no"])
+	CPPFLAGS=$xastir_save_CPPFLAGS
+
+    use_map_cache="no"
+    if test "${dblib}" = "berkeley"; then
+        LIBS="$BDB_LIBADD $LIBS"
+	CPPFLAGS="$CPPFLAGS $BDB_INCADD"
+        AC_DEFINE(USE_MAP_CACHE, 1, [Berkeley DB Map Caching])
+        use_map_cache="yes"
+    fi
+ 
+])
+
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..bf5bfb0
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,964 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],,
+[m4_warning([this file was generated for autoconf 2.68.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES(CC)],
+		  [define([AC_PROG_CC],
+			  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES(CXX)],
+		  [define([AC_PROG_CXX],
+			  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES(OBJC)],
+		  [define([AC_PROG_OBJC],
+			  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..0e9066d
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# $Id: bootstrap.sh,v 1.23 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+#
+# This simple routine will run autostuff in the appropriate
+# order to generate the needed configure/makefiles
+#
+
+echo "    7) Removing autom4te.cache directory..."
+rm -rf autom4te.cache
+
+echo "    6) Running aclocal..."
+aclocal
+
+echo "    5) Running autoheader..."
+autoheader
+
+echo "    4) Running autoconf..."
+autoconf
+
+# Cygwin needs these parameters to be separate.
+echo "    3) Running automake..."
+automake -a -c
+
+# Automake-1.9 on SuSE 10 doesn't copy over "mkinstalldirs" if
+# missing.  Check whether it is missing and copy it over ourselves
+# if so.
+if test -x "mkinstalldirs"
+then
+  echo "    2) Checking for 'mkinstalldirs'... Found!"
+else
+  echo "    2) Checking for 'mkinstalldirs'... Not Found"
+  echo "       Attempting to copy it from system directories'"
+  (cp /usr/local/share/automake*/mkinstalldirs . 2>/dev/null)
+  # Did we succeed?
+  if [ $? ]
+  then
+    # Failed the copy above, try in another directory.
+    (cp /usr/share/automake*/mkinstalldirs . 2>/dev/null)
+  fi
+  # Check whether we have the file now in our current directory and
+  # that it is executable.
+  if test -x "mkinstalldirs"
+  then
+    echo "       Checking for 'mkinstalldirs'... Found!"
+  else
+    echo "***ERROR: Couldn't copy the file***"
+  fi
+fi
+
+# Generate derived language files
+echo -n "    1) Generating derived language files"
+(cd config; ../scripts/langPigLatin.pl -split <language-English.sys >language-PigLatin.sys) 
+echo -n "."
+(cd config; ../scripts/langElmerFudd.pl -split <language-English.sys >language-ElmerFudd.sys) 
+echo -n "."
+(cd config; ../scripts/langMuppetsChef.pl -split <language-English.sys >language-MuppetsChef.sys) 
+echo -n "."
+(cd config; ../scripts/langOldeEnglish.pl -split <language-English.sys >language-OldeEnglish.sys) 
+echo -n "."
+(cd config; ../scripts/langPirateEnglish.pl -split <language-English.sys >language-PirateEnglish.sys) 
+echo "."
+
+echo "Bootstrap complete."
+
+
diff --git a/callpass.1 b/callpass.1
new file mode 100644
index 0000000..8ff63d1
--- /dev/null
+++ b/callpass.1
@@ -0,0 +1,29 @@
+.TH callpass 1 2009-12-22 "The Xastir Group"
+
+.SH NAME
+callpass \- generate Pass-code associated with your callsign for authentication via xastir to APRS(tm) network.
+
+.SH SYNOPSIS
+.B callpass
+.I <callsign>
+
+.SH DESCRIPTION
+Generate passcode for use in xastir authentication to APRS network for traffic delivery to cooperating systems.
+.SH EXAMPLES
+
+callpass nocall
+	outputs 'Passcode for nocall is 12960'
+
+.SH NOTES
+There is no error or consistency check for callsign. This utility will generate a passcode for any string.
+.SH SEE ALSO
+xastir help file
+.br
+.PP
+.B APRS[tm]
+is a Trademark of Bob Bruninga, his home page is at "http://www.aprs.org/aprs.html"
+
+.SH COPYING
+Copyright (C) 1999,2000 Frank Giannandrea KC2GJS
+.br
+Copyright (C) 2000-2012 The Xastir Group
diff --git a/callpass/Makefile.am b/callpass/Makefile.am
new file mode 100644
index 0000000..ae87f02
--- /dev/null
+++ b/callpass/Makefile.am
@@ -0,0 +1,13 @@
+# $Id: Makefile.am,v 1.10 2012/11/01 18:57:18 we7u Exp $
+
+# Copyright (C) 2000-2012  The Xastir Group
+
+
+MAINTAINERCLEANFILES=Makefile.in
+
+bin_PROGRAMS = callpass
+
+callpass_SOURCES = callpass.c
+
+callpass_LINK=$(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+
diff --git a/callpass/Makefile.in b/callpass/Makefile.in
new file mode 100644
index 0000000..4ce5f94
--- /dev/null
+++ b/callpass/Makefile.in
@@ -0,0 +1,501 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.10 2012/11/01 18:57:18 we7u Exp $
+
+# Copyright (C) 2000-2012  The Xastir Group
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = callpass$(EXEEXT)
+subdir = callpass
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_callpass_OBJECTS = callpass.$(OBJEXT)
+callpass_OBJECTS = $(am_callpass_OBJECTS)
+callpass_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(callpass_SOURCES)
+DIST_SOURCES = $(callpass_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+MAINTAINERCLEANFILES = Makefile.in
+callpass_SOURCES = callpass.c
+callpass_LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu callpass/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu callpass/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	      echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	      $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+callpass$(EXEEXT): $(callpass_OBJECTS) $(callpass_DEPENDENCIES) 
+	@rm -f callpass$(EXEEXT)
+	$(callpass_LINK) $(callpass_OBJECTS) $(callpass_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/callpass.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-binPROGRAMS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/callpass/callpass.c b/callpass/callpass.c
new file mode 100644
index 0000000..1517821
--- /dev/null
+++ b/callpass/callpass.c
@@ -0,0 +1,81 @@
+/*
+ * $Id: callpass.c,v 1.11 2012/11/01 18:57:18 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#define kKey 0x73e2 // This is the seed for the key
+#define true 1
+
+
+
+static short doHash(char *theCall) {
+    char rootCall[10]; // need to copy call to remove ssid from parse
+    char *p1 = rootCall;
+    short hash;
+    short i,len;
+    char *ptr = rootCall;
+
+    while ((*theCall != '-') && (*theCall != '\0')) *p1++ = toupper((int)(*theCall++));
+        *p1 = '\0';
+
+    hash = kKey; // Initialize with the key value
+    i = 0;
+    len = (short)strlen(rootCall);
+
+    while (i<len) {// Loop through the string two bytes at a time
+        hash ^= (unsigned char)(*ptr++)<<8; // xor high byte with accumulated hash
+        hash ^= (*ptr++); // xor low byte with accumulated hash
+        i += 2;
+    }
+    return (short)(hash & 0x7fff); // mask off the high bit so number is always positive
+}
+
+
+
+short checkHash(char *theCall, short theHash) {
+    return (short)(doHash(theCall) == theHash);
+}
+
+
+
+int main(int argc, char *argv[]) {
+    char temp[100];
+
+    if (argc>1) {
+
+        strncpy(temp,argv[1],100);
+
+        temp[99] = '\0';    // Forced termination
+
+        if (strlen(temp)>0)
+            printf("Passcode for %s is %d\n",temp,doHash(temp));
+
+    } else
+        printf("Usage:callpass <callsign>\n");
+
+    return(0);
+}
+
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..666c5ad
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1511 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, 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.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches at gnu.org> and include a ChangeLog
+# entry.
+#
+# 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.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+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
+
+case "${UNAME_MACHINE}" in
+    i?86)
+	test -z "$VENDOR" && VENDOR=pc
+	;;
+    *)
+	test -z "$VENDOR" && VENDOR=unknown
+	;;
+esac
+test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-${VENDOR}-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-${VENDOR}-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-${VENDOR}-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-${VENDOR}-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    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 ;;
+    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 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-${VENDOR}-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${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 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????: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 ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	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 ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | 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=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	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_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-${VENDOR}-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-${VENDOR}-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-${VENDOR}-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-${VENDOR}-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-${VENDOR}-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-${VENDOR}-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-${VENDOR}-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-${VENDOR}-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-${VENDOR}-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-${VENDOR}-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-${VENDOR}-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-${VENDOR}-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-${VENDOR}-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-${VENDOR}-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-${VENDOR}-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-${VENDOR}-linux-gnu ;;
+	  PA8*) echo hppa2.0-${VENDOR}-linux-gnu ;;
+	  *)    echo hppa-${VENDOR}-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-${VENDOR}-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-${VENDOR}-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-${VENDOR}-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# 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.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-${VENDOR}-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-${VENDOR}-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-${VENDOR}-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    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-${VENDOR}-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-${VENDOR}-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-${VENDOR}-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-${VENDOR}-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-${VENDOR}-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *: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 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-${VENDOR}-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-${VENDOR}-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-${VENDOR}-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-${VENDOR}-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-${VENDOR}-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-${VENDOR}-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR}-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+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\n"); 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`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# 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_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# 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 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..7dc7cd5
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,661 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Path to convert */
+#undef CONVERT_PATH
+
+/* 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 to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to 1 if the `getpgrp' function requires zero arguments. */
+#undef GETPGRP_VOID
+
+/* Path to gpsman */
+#undef GPSMAN_PATH
+
+/* Default GPS port. */
+#undef GPS_PORT
+
+/* Path to gv */
+#undef GV_PATH
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define if you have convert */
+#undef HAVE_CONVERT
+
+/* Database support available */
+#undef HAVE_DB
+
+/* Define to 1 if your `shp' library has DBFGetFieldIndex. */
+#undef HAVE_DBFGETFIELDINDEX
+
+/* Define to 1 if you have the `dcgettext' function. */
+#undef HAVE_DCGETTEXT
+
+/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
+   */
+#undef HAVE_DECL_TZNAME
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define if you have error popups enabled */
+#undef HAVE_ERROR_POPUPS
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have festival */
+#undef HAVE_FESTIVAL
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the <gc.h> header file. */
+#undef HAVE_GC_H
+
+/* Define to 1 if you have the <gdal.h> header file. */
+#undef HAVE_GDAL_H
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* Define if you have gpsman */
+#undef HAVE_GPSMAN
+
+/* GraphicsMagick image library */
+#undef HAVE_GRAPHICSMAGICK
+
+/* Define if you have gv */
+#undef HAVE_GV
+
+/* Imagemagick image library */
+#undef HAVE_IMAGEMAGICK
+
+/* Define to 1 if you have the `inet_ntoa' function. */
+#undef HAVE_INET_NTOA
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `ax25' library (-lax25). */
+#undef HAVE_LIBAX25
+
+/* Define to 1 if your `curl' library has curl_global_init. */
+#undef HAVE_LIBCURL
+
+/* Define to 1 if you have the `gc' library (-lgc). */
+#undef HAVE_LIBGC
+
+/* Define to 1 if you have the `gdal' library (-lgdaal). */
+#undef HAVE_LIBGDAL
+
+/* Define to 1 if you have the `geotiff' library (-lgeotiff). */
+#undef HAVE_LIBGEOTIFF
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `pcre' library (-lpcre). */
+#undef HAVE_LIBPCRE
+
+/* Define to 1 if you have the `shp' library (-lshp). */
+#undef HAVE_LIBSHP
+
+/* Define to 1 if you have the <libshp/shapefil.h> header file. */
+#undef HAVE_LIBSHP_SHAPEFIL_H
+
+/* Define to 1 if you have the `Xext' library (-lXext). */
+#undef HAVE_LIBXEXT
+
+/* Define to 1 if you have the `Xm' library (-lXm). */
+#undef HAVE_LIBXM
+
+/* Define to 1 if you have the `Xp' library (-lXp). */
+#undef HAVE_LIBXP
+
+/* Define to 1 if you have the `Xpm' library (-lXpm). */
+#undef HAVE_LIBXPM
+
+/* Define to 1 if the `Xm' library (-lXm) is used for Xpm. */
+#undef HAVE_LIBXPM_IN_XM
+
+/* Define to 1 if you have the `Xt' library (-lXt). */
+#undef HAVE_LIBXT
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have lpr */
+#undef HAVE_LPR
+
+/* GraphicsMagick or ImageMagick library */
+#undef HAVE_MAGICK
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mempcpy' function. */
+#undef HAVE_MEMPCPY
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have mv */
+#undef HAVE_MV
+
+/* MySQL is present. */
+#undef HAVE_MYSQL
+
+/* MySQL with spatial support is present. */
+#undef HAVE_MYSQL_SPATIAL
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netax25/ax25.h> header file. */
+#undef HAVE_NETAX25_AX25_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define if you have old gv */
+#undef HAVE_NEW_GV
+
+/* Define to 1 if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have old gv */
+#undef HAVE_OLD_GV
+
+/* Define to 1 if you have the <pcre.h> header file. */
+#undef HAVE_PCRE_H
+
+/* Define to 1 if you have the <pcre/pcre.h> header file. */
+#undef HAVE_PCRE_PCRE_H
+
+/* Postgresql with postgis is present. */
+#undef HAVE_POSTGIS
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to 1 if you have the `libproj' library (-lproj). */
+#undef HAVE_PROJ
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the `pthread_mutexattr_setkind_np' function. */
+#undef HAVE_PTHREAD_MUTEXATTR_SETKIND_NP
+
+/* Define to 1 if you have the `pthread_mutexattr_settype' function. */
+#undef HAVE_PTHREAD_MUTEXATTR_SETTYPE
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the `roundf' function. */
+#undef HAVE_ROUNDF
+
+/* Define if you have sed */
+#undef HAVE_SED
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the `settimeofday' function. */
+#undef HAVE_SETTIMEOFDAY
+
+/* Define to 1 if you have the `shapefil.h' header. */
+#undef HAVE_SHAPEFIL_H
+
+/* Define to 1 if the system has the type `sighandler_t'. */
+#undef HAVE_SIGHANDLER_T
+
+/* Define to 1 if you have the `sigignore' function. */
+#undef HAVE_SIGIGNORE
+
+/* Define to 1 if the system has the type `sigjmp_buf'. */
+#undef HAVE_SIGJMP_BUF
+
+/* Define to 1 if you have the `signal' function. */
+#undef HAVE_SIGNAL
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if the system has the type `sig_t'. */
+#undef HAVE_SIG_T
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if the system has the type `socklen_t'. */
+#undef HAVE_SOCKLEN_T
+
+/* Spatial database support available */
+#undef HAVE_SPATIAL_DB
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+   zero-length file name argument. */
+#undef HAVE_STAT_EMPTY_STRING_BUG
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `stpcpy' function. */
+#undef HAVE_STPCPY
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
+/* Define to 1 if you have the `strpbrk' function. */
+#undef HAVE_STRPBRK
+
+/* Define to 1 if you have the `strptime' function. */
+#undef HAVE_STRPTIME
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the `strtof' function. */
+#undef HAVE_STRTOF
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Define to 1 if `tm_zone' is a member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the 'tiff' library (-ltiff) */
+#undef HAVE_TIFF
+
+/* X */
+#undef HAVE_TM_GMTOFF
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+   `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+   `tzname'. */
+#undef HAVE_TZNAME
+
+/* Define to 1 if you have the `tzset' function. */
+#undef HAVE_TZSET
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define if you have wget */
+#undef HAVE_WGET
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to 1 if you have 'X11/xpm.h' */
+#undef HAVE_X11_XPM_H
+
+/* Define if you have xfontsel */
+#undef HAVE_XFONTSEL
+
+/* Define to 1 if you have the <Xm/XpmI.h> header file. */
+#undef HAVE_XM_XPMI_H
+
+/* Define to 1 if you have the `__argz_count' function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define to 1 if you have the `__argz_next' function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define to 1 if you have the `__argz_stringify' function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Path to lpr */
+#undef LPR_PATH
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+   slash. */
+#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
+
+/* Path to mv */
+#undef MV_PATH
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Path to sed */
+#undef SED_PATH
+
+/* 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 runtime.
+	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 to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Legacy stuff, use crowbar and lets keep going */
+#undef STIPPLE
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Default TNC port. */
+#undef TNC_PORT
+
+/* Berkeley DB Map Caching */
+#undef USE_MAP_CACHE
+
+/* RTree spatial indexing */
+#undef USE_RTREE
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Path to wget */
+#undef WGET_PATH
+
+/* Define to 1 to use dbfawk features. */
+#undef WITH_DBFAWK
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Path to installed Xastir binaries. */
+#undef XASTIR_BIN_PATH
+
+/* Defines the installed libs */
+#undef XASTIR_INSTALLED_LIBS
+
+/* Path to installed Xastir files. */
+#undef XASTIR_PATH
+
+/* Define system type. */
+#undef XASTIR_SYSTEM
+
+/* Defines the version tocall */
+#undef XASTIR_TOCALL
+
+/* Define if you need to work with the broken Xorg server 1.7.5 */
+#undef XASTIR_XORG_SERVER_175_BUG
+
+/* Path to xfontsel */
+#undef XFONTSEL_PATH
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define if you're compiling for Linux Standard Base */
+#undef __LSB__
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
+
+#ifndef HAVE_SOCKLEN_T
+#define socklen_t int
+#endif
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..2a55a50
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1705 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, 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.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# 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.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# 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.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+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
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    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 | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-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/'`
+		;;
+	-sco5v6*)
+		# 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/'`
+		;;
+	-udk*)
+		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
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+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.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-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*86 | x86_64)
+	  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.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	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 | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	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
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-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
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	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
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	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
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-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/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	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
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	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
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	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.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		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.
+        -auroraux)
+	        os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-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|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-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
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	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
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		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
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/24kgrid.dbfawk b/config/24kgrid.dbfawk
new file mode 100644
index 0000000..05a411d
--- /dev/null
+++ b/config/24kgrid.dbfawk
@@ -0,0 +1,42 @@
+# $Id: 24kgrid.dbfawk,v 1.9 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map USGS 24k grid shapefiles, which contains bounding
+# rectangles for USGS 1:24000 quadrangles. 
+# The shapefile itself can be had from 
+#   http://data.geocomm.com/quadindex/
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="NAME:STATE:LAT:LONG:MRC";
+# dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="NAME:STATE";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=65535; label_level=512; label_color=2; font_size=1; symbol=""}
+
+# per-field rules are applied to the dbffields that are read from each record.
+/^NAME=(.*)$/ {name="$1; next}
+/^STATE=(.*)$/ {name="$(name),$1; next}
diff --git a/config/Makefile.am b/config/Makefile.am
new file mode 100644
index 0000000..5b29af0
--- /dev/null
+++ b/config/Makefile.am
@@ -0,0 +1,130 @@
+# $Id: Makefile.am,v 1.52 2012/12/04 19:29:25 tvrusso Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+configdir = ${pkgdatadir}/config
+
+EXTRA_DIST = \
+    language-Dutch.sys \
+    language-English.sys \
+    language-French.sys \
+    language-German.sys \
+    language-Italian.sys \
+    language-Portuguese.sys \
+    language-Spanish.sys \
+    language-ElmerFudd.sys \
+    language-MuppetsChef.sys \
+    language-OldeEnglish.sys \
+    language-PigLatin.sys \
+    language-PirateEnglish.sys \
+    xastir.rgb \
+    gps_wpt.dbfawk \
+    24kgrid.dbfawk \
+    stored_track.dbfawk \
+    tgr2shp.dbfawk \
+    tgr2shppoly.dbfawk \
+    tgr2shppoly_2006.dbfawk \
+    tgrcty.dbfawk \
+    tgrkgl.dbfawk \
+    tgrlk.dbfawk \
+    tgrlpt.dbfawk \
+    tgrlpy.dbfawk \
+    tgrplc00.dbfawk \
+    tgrwat.dbfawk \
+    nwsc_ddmmyy.dbfawk \
+    nwsc_ddmmyy_09.dbfawk \
+    nwsc_ddmmyy_09b.dbfawk \
+    nwsc_ddmmyy_10.dbfawk \
+    nwsc_ddmmyy_10a.dbfawk \
+    nwsmzddmmyy.dbfawk \
+    nwsmzddmmyy_09.dbfawk \
+    nwsmzddmmyy_11.dbfawk \
+    nwsmzoddmmyy.dbfawk \
+    nwsozddmmyy.dbfawk \
+    nwsozddmmyy_09.dbfawk \
+    nwsozddap12.dbfawk \
+    nwsw_ddmmyy.dbfawk \
+    nwsw_ddmmyy_09.dbfawk \
+    nwsw_ddmmyy_10.dbfawk \
+    nwsw_ddjn12.dbfawk \
+    nwsz_ddmmyy.dbfawk \
+    nwsz_ddmmyy_09.dbfawk \
+    nwsz_ddmmyy_10.dbfawk \
+    nwsz_ddmmyy_10b.dbfawk \
+    nwsz_ddmmyy_10c.dbfawk \
+    nwsz_ddmmyy_11.dbfawk \
+    nwsz1ddmmyy.dbfawk \
+    nwszoddmmyy.dbfawk \
+    nwshzddmmyy.dbfawk \
+    OSM_Cloudmade_administrative.dbfawk \
+    OSM_Cloudmade_highway.dbfawk \
+    OSM_Cloudmade_natural.dbfawk \
+    OSM_Cloudmade_poi.dbfawk \
+    OSM_Cloudmade_water_and_coastline.dbfawk \
+    predefined_EVENT.sys \
+    predefined_SAR.sys \
+    tl_2009_aiannh.dbfawk \
+    tl_2009_aits.dbfawk \
+    tl_2009_arealm.dbfawk \
+    tl_2009_areawater.dbfawk \
+    tl_2009_county.dbfawk \
+    tl_2009_cousub.dbfawk \
+    tl_2009_edges.dbfawk \
+    tl_2009_mil.dbfawk \
+    tl_2009_nn_county.dbfawk \
+    tl_2009_pointlm.dbfawk \
+    tl_2009_zcta5.dbfawk \
+    tnc-startup.aea \
+    tnc-startup.d700 \
+    tnc-startup.d72_d710 \
+    tnc-startup.kam \
+    tnc-startup.kpc2 \
+    tnc-startup.kpc3 \
+    tnc-startup.null \
+    tnc-startup.paccomm \
+    tnc-startup.pico \
+    tnc-startup.sys \
+    tnc-startup.thd7 \
+    tnc-startup.tnc2 \
+    tnc-startup.tnc2-ui \
+    tnc-stop.d700 \
+    tnc-stop.d72_d710 \
+    tnc-stop.sys \
+    tnc-stop.thd7 \
+    tnc-stop.tnc2-ui \
+    areawater.dbfawk \
+    arealm.dbfawk \
+    tabblock.dbfawk \
+    cousub.dbfawk \
+    cousub00.dbfawk \
+    edge.dbfawk \
+    featnames.dbfawk \
+    pointlm.dbfawk \
+    gfe_public_weather.dbfawk \
+    gfe_metro_areas.dbfawk \
+    gfe_fire_weather.dbfawk \
+    gfe_coastal_waters_warnings.dbfawk \
+    gfe_coastal_waters.dbfawk
+
+
+config_DATA = ${EXTRA_DIST}
+
+install-exec-hook:
+	-rm -f $(DESTDIR)$(configdir)/nwsfz_ddmmyy.dbfawk
+
+language-ElmerFudd.sys: language-English.sys
+	$(top_srcdir)/scripts/langElmerFudd.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-MuppetsChef.sys: language-English.sys
+	$(top_srcdir)/scripts/langMuppetsChef.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-OldeEnglish.sys: language-English.sys
+	$(top_srcdir)/scripts/langOldeEnglish.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-PigLatin.sys: language-English.sys
+	$(top_srcdir)/scripts/langPigLatin.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-PirateEnglish.sys: language-English.sys
+	$(top_srcdir)/scripts/langPirateEnglish.pl -split >$@ <$(srcdir)/language-English.sys
+
diff --git a/config/Makefile.in b/config/Makefile.in
new file mode 100644
index 0000000..e7c9803
--- /dev/null
+++ b/config/Makefile.in
@@ -0,0 +1,534 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.52 2012/12/04 19:29:25 tvrusso Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = config
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(configdir)"
+DATA = $(config_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+configdir = ${pkgdatadir}/config
+EXTRA_DIST = \
+    language-Dutch.sys \
+    language-English.sys \
+    language-French.sys \
+    language-German.sys \
+    language-Italian.sys \
+    language-Portuguese.sys \
+    language-Spanish.sys \
+    language-ElmerFudd.sys \
+    language-MuppetsChef.sys \
+    language-OldeEnglish.sys \
+    language-PigLatin.sys \
+    language-PirateEnglish.sys \
+    xastir.rgb \
+    gps_wpt.dbfawk \
+    24kgrid.dbfawk \
+    stored_track.dbfawk \
+    tgr2shp.dbfawk \
+    tgr2shppoly.dbfawk \
+    tgr2shppoly_2006.dbfawk \
+    tgrcty.dbfawk \
+    tgrkgl.dbfawk \
+    tgrlk.dbfawk \
+    tgrlpt.dbfawk \
+    tgrlpy.dbfawk \
+    tgrplc00.dbfawk \
+    tgrwat.dbfawk \
+    nwsc_ddmmyy.dbfawk \
+    nwsc_ddmmyy_09.dbfawk \
+    nwsc_ddmmyy_09b.dbfawk \
+    nwsc_ddmmyy_10.dbfawk \
+    nwsc_ddmmyy_10a.dbfawk \
+    nwsmzddmmyy.dbfawk \
+    nwsmzddmmyy_09.dbfawk \
+    nwsmzddmmyy_11.dbfawk \
+    nwsmzoddmmyy.dbfawk \
+    nwsozddmmyy.dbfawk \
+    nwsozddmmyy_09.dbfawk \
+    nwsozddap12.dbfawk \
+    nwsw_ddmmyy.dbfawk \
+    nwsw_ddmmyy_09.dbfawk \
+    nwsw_ddmmyy_10.dbfawk \
+    nwsw_ddjn12.dbfawk \
+    nwsz_ddmmyy.dbfawk \
+    nwsz_ddmmyy_09.dbfawk \
+    nwsz_ddmmyy_10.dbfawk \
+    nwsz_ddmmyy_10b.dbfawk \
+    nwsz_ddmmyy_10c.dbfawk \
+    nwsz_ddmmyy_11.dbfawk \
+    nwsz1ddmmyy.dbfawk \
+    nwszoddmmyy.dbfawk \
+    nwshzddmmyy.dbfawk \
+    OSM_Cloudmade_administrative.dbfawk \
+    OSM_Cloudmade_highway.dbfawk \
+    OSM_Cloudmade_natural.dbfawk \
+    OSM_Cloudmade_poi.dbfawk \
+    OSM_Cloudmade_water_and_coastline.dbfawk \
+    predefined_EVENT.sys \
+    predefined_SAR.sys \
+    tl_2009_aiannh.dbfawk \
+    tl_2009_aits.dbfawk \
+    tl_2009_arealm.dbfawk \
+    tl_2009_areawater.dbfawk \
+    tl_2009_county.dbfawk \
+    tl_2009_cousub.dbfawk \
+    tl_2009_edges.dbfawk \
+    tl_2009_mil.dbfawk \
+    tl_2009_nn_county.dbfawk \
+    tl_2009_pointlm.dbfawk \
+    tl_2009_zcta5.dbfawk \
+    tnc-startup.aea \
+    tnc-startup.d700 \
+    tnc-startup.d72_d710 \
+    tnc-startup.kam \
+    tnc-startup.kpc2 \
+    tnc-startup.kpc3 \
+    tnc-startup.null \
+    tnc-startup.paccomm \
+    tnc-startup.pico \
+    tnc-startup.sys \
+    tnc-startup.thd7 \
+    tnc-startup.tnc2 \
+    tnc-startup.tnc2-ui \
+    tnc-stop.d700 \
+    tnc-stop.d72_d710 \
+    tnc-stop.sys \
+    tnc-stop.thd7 \
+    tnc-stop.tnc2-ui \
+    areawater.dbfawk \
+    arealm.dbfawk \
+    tabblock.dbfawk \
+    cousub.dbfawk \
+    cousub00.dbfawk \
+    edge.dbfawk \
+    featnames.dbfawk \
+    pointlm.dbfawk \
+    gfe_public_weather.dbfawk \
+    gfe_metro_areas.dbfawk \
+    gfe_fire_weather.dbfawk \
+    gfe_coastal_waters_warnings.dbfawk \
+    gfe_coastal_waters.dbfawk
+
+config_DATA = ${EXTRA_DIST}
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu config/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu config/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-configDATA: $(config_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(configdir)" || $(MKDIR_P) "$(DESTDIR)$(configdir)"
+	@list='$(config_DATA)'; test -n "$(configdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \
+	done
+
+uninstall-configDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(config_DATA)'; test -n "$(configdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(configdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(configdir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(configdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-configDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-configDATA
+
+.MAKE: install-am install-exec-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-configDATA install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-exec-hook install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am uninstall uninstall-am uninstall-configDATA
+
+
+install-exec-hook:
+	-rm -f $(DESTDIR)$(configdir)/nwsfz_ddmmyy.dbfawk
+
+language-ElmerFudd.sys: language-English.sys
+	$(top_srcdir)/scripts/langElmerFudd.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-MuppetsChef.sys: language-English.sys
+	$(top_srcdir)/scripts/langMuppetsChef.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-OldeEnglish.sys: language-English.sys
+	$(top_srcdir)/scripts/langOldeEnglish.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-PigLatin.sys: language-English.sys
+	$(top_srcdir)/scripts/langPigLatin.pl -split >$@ <$(srcdir)/language-English.sys
+
+language-PirateEnglish.sys: language-English.sys
+	$(top_srcdir)/scripts/langPirateEnglish.pl -split >$@ <$(srcdir)/language-English.sys
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/config/OSM_Cloudmade_administrative.dbfawk b/config/OSM_Cloudmade_administrative.dbfawk
new file mode 100644
index 0000000..ee8d887
--- /dev/null
+++ b/config/OSM_Cloudmade_administrative.dbfawk
@@ -0,0 +1,59 @@
+# $Id: OSM_Cloudmade_administrative.dbfawk,v 1.2 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that
+# accompanies a shapefile into Xastir canonical values of:
+#
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near
+# awk compatible.
+#
+# This file is used to map OSM shapefiles by "Cloudmade" which are
+# named "*_administrative.dbf".
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column
+# names in order. dbfinfo should match the dbf file that we say this
+# dbfawk file goes with.
+dbfinfo="NAME:ADMIN_LEVE";
+
+# dbffields is which of the above fields we actually want to look
+# at.  No point reading dbffields that are not looked at further.
+dbffields="NAME:ADMIN_LEVE";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple
+# fields. Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=105; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0;}
+
+# per-field rules are applied to the dbffields that are read from
+# each record.
+
+# select the name given in the record
+/^NAME=(.+)$/ {name="$1";next}
+
+/^ADMIN_LEVE=2/ {lanes=4; color=105;                   label_level=65536; font_size=1; next}
+/^ADMIN_LEVE=4/ {lanes=3; color=105; display_level=64; label_level=512;   font_size=1; next}
+/^ADMIN_LEVE=6/ {lanes=2; color=105; display_level=64; label_level=512;   font_size=1; next}
+/^ADMIN_LEVE=8/ {lanes=1; color=105; display_level=64; label_level=512;   font_size=1; next}
+
+# key: set the search key to be the Tiger/Line ID.  Not currently
+# used.
+#/^TLID=(.*)$/ {key=$1; next}
+
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/OSM_Cloudmade_highway.dbfawk b/config/OSM_Cloudmade_highway.dbfawk
new file mode 100644
index 0000000..85b4899
--- /dev/null
+++ b/config/OSM_Cloudmade_highway.dbfawk
@@ -0,0 +1,106 @@
+# $Id: OSM_Cloudmade_highway.dbfawk,v 1.2 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that
+# accompanies a shapefile into Xastir canonical values of:
+#
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near
+# awk compatible.
+#
+# This file is used to map OSM shapefiles by "Cloudmade" which are
+# named "*_highway.dbf".
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column
+# names in order. dbfinfo should match the dbf file that we say this
+# dbfawk file goes with.
+dbfinfo="TYPE:NAME:ONEWAY:LANES";
+
+# dbffields is which of the above fields we actually want to look
+# at.  No point reading dbffields that are not looked at further.
+dbffields="TYPE:NAME:ONEWAY:LANES";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple
+# fields. Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0;}
+
+# per-field rules are applied to the dbffields that are read from
+# each record.
+
+# select the name given in the record
+/^NAME=United States Highway (.*)$/ {name="$(name)US $1"; next}
+/^NAME=State Highway (.*)$/ {name="$(name)Hwy $1"; next}
+/^NAME=State Route (.*)$/ {name="$(name)SR-$1"; next}
+/^NAME=United States Highway (.*)$/ {name="$(name)US $1"; next}
+/^NAME=United States Highway (.*)$/ {name="$(name)US $1"; next}
+/^NAME=Interstate (.*) Northbound$/ {name="$(name)I-$1 N"; next}
+/^NAME=Interstate (.*) Southbound$/ {name="$(name)I-$1 S"; next}
+/^NAME=Interstate (.*) Eastbound$/ {name="$(name)I-$1 E"; next}
+/^NAME=Interstate (.*) Westbound$/ {name="$(name)I-$1 W"; next}
+/^NAME=Interstate (.*)$/ {name="$(name)I-$1"; next}
+/^NAME=Washington Highway (.*)$/ {name="$(name)Hwy $1"; next}
+/^NAME=(.+)$/ {name="$1";next}
+
+#/^LANES=(.+)$/ {lanes="$1";}
+
+# TYPE:
+/^TYPE=abandoned/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=bridleway/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=construction/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=crossing/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=cycleway/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=driveway/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=footway/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=ford/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=living_street/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+# Note:  No display_level or label_level
+/^TYPE=motorway/ {lanes=4; color=4; label_level=65536; font_size=3; next}
+# Note:  No display_level
+/^TYPE=motorway_link/ {lanes=3; color=2; label_level=16; font_size=1; next}
+/^TYPE=path/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=pedestrian/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=platform/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=primary/ {lanes=2; color=8; display_level=512; label_level=128; font_size=1; next}
+/^TYPE=primary_link/ {lanes=2; color=8; display_level=512; label_level=128; font_size=1; next}
+/^TYPE=raceway/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=ramp/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=residential/ {lanes=1; color=44; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=road/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=secondary/ {lanes=2; color=8; display_level=256; label_level=64; font_size=1; next}
+/^TYPE=secondary_link/ {lanes=1; color=8; display_level=256; label_level=64; font_size=1; next}
+/^TYPE=service/ {lanes=1; color=8; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=service; residential/ {lanes=7; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=steps/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=tertiary/ {lanes=1; color=8; display_level=256; label_level=64; font_size=1; next}
+/^TYPE=tertiary_link/ {lanes=1; color=8; display_level=256; label_level=64; font_size=1; next}
+/^TYPE=t/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=track/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=trail/ {lanes=1; color=66; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=tr/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=trunk/ {lanes=3; color=8; display_level=128; label_level=16; font_size=3; next}
+/^TYPE=trunk_link/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=unclassified/ {lanes=1; color=4; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=unsurfaced/ {lanes=1; color=105; display_level=64; label_level=16; font_size=1; next}
+
+# key: set the search key to be the Tiger/Line ID.  Not currently
+# used.
+#/^TLID=(.*)$/ {key=$1; next}
+
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/OSM_Cloudmade_natural.dbfawk b/config/OSM_Cloudmade_natural.dbfawk
new file mode 100644
index 0000000..cf462d4
--- /dev/null
+++ b/config/OSM_Cloudmade_natural.dbfawk
@@ -0,0 +1,58 @@
+# $Id: OSM_Cloudmade_natural.dbfawk,v 1.2 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that
+# accompanies a shapefile into Xastir canonical values of:
+#
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near
+# awk compatible.
+#
+# This file is used to map OSM shapefiles by "Cloudmade" which are
+# named "*_natural.dbf".
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column
+# names in order. dbfinfo should match the dbf file that we say this
+# dbfawk file goes with.
+dbfinfo="NAME:TYPE";
+
+# dbffields is which of the above fields we actually want to look
+# at.  No point reading dbffields that are not looked at further.
+dbffields="NAME:TYPE:";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple
+# fields. Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=4; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0;}
+
+# per-field rules are applied to the dbffields that are read from
+# each record.
+
+# select the name given in the record
+/^NAME=(.+)$/ {name="$1";next}
+
+# TYPE:
+/^TYPE=water/ {lanes=1; color=9; display_level=64; label_level=16; font_size=1; next}
+/^TYPE=forest/ {lanes=1; color=10; fill-color=10; display_level=64; label_level=16; font_size=1; next}
+
+# key: set the search key to be the Tiger/Line ID.  Not currently
+# used.
+#/^TLID=(.*)$/ {key=$1; next}
+
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/OSM_Cloudmade_poi.dbfawk b/config/OSM_Cloudmade_poi.dbfawk
new file mode 100644
index 0000000..9ef2758
--- /dev/null
+++ b/config/OSM_Cloudmade_poi.dbfawk
@@ -0,0 +1,62 @@
+# $Id: OSM_Cloudmade_poi.dbfawk,v 1.2 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that
+# accompanies a shapefile into Xastir canonical values of:
+#
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near
+# awk compatible.
+#
+# This file is used to map OSM shapefiles by "Cloudmade" which are
+# named "*_poi.dbf".
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column
+# names in order. dbfinfo should match the dbf file that we say this
+# dbfawk file goes with.
+dbfinfo="CATEGORY:NAME";
+
+# dbffields is which of the above fields we actually want to look
+# at.  No point reading dbffields that are not looked at further.
+dbffields="CATEGORY:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple
+# fields. Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=16; label_level=16; label_color=8; font_size=0; symbol=""; fill_style=0;}
+
+# per-field rules are applied to the dbffields that are read from
+# each record.
+
+/^NAME=(.+)$/ {name="$1";next}
+/^CATEGORY=Automotive/ {color=4; font_size=1; next}
+/^CATEGORY=Eating&Drinking/ {color=4; font_size=1; next}
+/^CATEGORY=Government and Public Services/ {color=4; font_size=1; next}
+/^CATEGORY=Health care/ {color=4; font_size=1; next}
+/^CATEGORY=Leisure/ {color=4; font_size=1; next}
+/^CATEGORY=Lodging/ {color=4; font_size=1; next}
+/^CATEGORY=Night Life and Business/ {color=4; font_size=1; next}
+/^CATEGORY=Sports/ {color=4; font_size=1; next}
+/^CATEGORY=Tourism/ {color=4; font_size=1; next}
+
+# key: set the search key to be the Tiger/Line ID.  Not currently
+# used.
+#/^TLID=(.*)$/ {key=$1; next}
+
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/OSM_Cloudmade_water_and_coastline.dbfawk b/config/OSM_Cloudmade_water_and_coastline.dbfawk
new file mode 100644
index 0000000..133a1b6
--- /dev/null
+++ b/config/OSM_Cloudmade_water_and_coastline.dbfawk
@@ -0,0 +1,59 @@
+# $Id: OSM_Cloudmade_water_and_coastline.dbfawk,v 1.2 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that
+# accompanies a shapefile into Xastir canonical values of:
+#
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near
+# awk compatible.
+#
+# This file is used to map OSM shapefiles by "Cloudmade" which are
+# named "*_water.dbf" and "*_coastline.dbf".  Unfortunately both
+# DBF files have the same signature, so we need to have this dbfawk
+# file match both of them.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column
+# names in order. dbfinfo should match the dbf file that we say this
+# dbfawk file goes with.
+dbfinfo="NATURAL:NAME";
+
+# dbffields is which of the above fields we actually want to look
+# at.  No point reading dbffields that are not looked at further.
+dbffields="NATURAL:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple
+# fields. Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=34; fill_color=26; name=""; filled=1; pattern=0; display_level=8192; label_level=32; label_color=15; font_size=0; symbol=""; fill_style=0;}
+
+# per-field rules are applied to the dbffields that are read from
+# each record.
+
+/^NAME=(.+)$/ {name="$1";next}
+/^NATURAL=shoreline/ {lanes=1; display_level=65536; label_level=1; font_size=1; next}
+/^NATURAL=water/ {lanes=1; display_level=65536; label_level=16; font_size=1; next}
+
+# key: set the search key to be the Tiger/Line ID.  Not currently
+# used.
+#/^TLID=(.*)$/ {key=$1; next}
+
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
+
diff --git a/config/arealm.dbfawk b/config/arealm.dbfawk
new file mode 100644
index 0000000..2a53c7a
--- /dev/null
+++ b/config/arealm.dbfawk
@@ -0,0 +1,53 @@
+# $Id: arealm.dbfawk,v 1.4 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for AREALM
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATEFP:COUNTYFP:ANSICODE:AREAID:FULLNAME:MTFCC";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="FULLNAME:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=6; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+# buildings
+/^MTFCC=K/ {display_level=256; filled=1 color=2; fill_color=2; label_level=128; next}
+# PLCC
+/^MTFCC=L/ {display_level=0; next}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/areawater.dbfawk b/config/areawater.dbfawk
new file mode 100644
index 0000000..6629f92
--- /dev/null
+++ b/config/areawater.dbfawk
@@ -0,0 +1,52 @@
+# $Id: areawater.dbfawk,v 1.4 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for AREAWATER
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATEFP:COUNTYFP:ANSICODE:HYDROID:FULLNAME:MTFCC";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="FULLNAME:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=26; fill_color=26; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=26; font_size=0; symbol=""; fill_style=0 }
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+# water
+/^MTFCC=H20/ {filled=1; color=97; fill_color=97; label_color=26; display_level=1024;next}
+/^MTFCC=H30/ {filled=1; color=97; fill_color=97; label_color=26; display_level=1024;skip}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/cousub.dbfawk b/config/cousub.dbfawk
new file mode 100644
index 0000000..2c2c90f
--- /dev/null
+++ b/config/cousub.dbfawk
@@ -0,0 +1,52 @@
+# $Id: cousub.dbfawk,v 1.4 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for COUSUB
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+# 2007FE = dbfinfo="STATEFP:COUNTYFP:COUSUBFP:COUSUBNS:COSBIDFP:NAME:NAMELSAD:LSAD:CLASSFP:MTFCC:UR:FUNCSTAT";
+dbfinfo ="STATEFP:COUNTYFP:COUSUBFP:COUSUBNS:COSBIDFP:NAME:NAMELSAD:LSAD:CLASSFP:MTFCC:CNECTAFP:NECTAFP:NCTADVFP:FUNCSTAT";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="NAME:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=6; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+/^NAME=(.*)$/ {name="$1";next}
+# item locations
+/^MTFCC=G/ {display_level=512;color=11; next}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/cousub00.dbfawk b/config/cousub00.dbfawk
new file mode 100644
index 0000000..ecd7f10
--- /dev/null
+++ b/config/cousub00.dbfawk
@@ -0,0 +1,51 @@
+# $Id: cousub00.dbfawk,v 1.4 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for COUSUB00
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATEFP00:COUNTYFP00:COUSUBFP00:COSBIDFP00:NAME00:NAMELSAD00:LSAD00:CLASSFP00:MTFCC00:UR00:FUNCSTAT00";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="NAME00:MTFCC00";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=6; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+/^NAME00=(.*)$/ {name="$1";next}
+# item locations
+/^MTFCC00=G/ {display_level=512;color=11; next}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/edge.dbfawk b/config/edge.dbfawk
new file mode 100644
index 0000000..b466f42
--- /dev/null
+++ b/config/edge.dbfawk
@@ -0,0 +1,87 @@
+# $Id: edge.dbfawk,v 1.4 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for EDGES
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+# dbfinfo="STATEFP:COUNTYFP:COUNTYNS:TLID:TFIDL:TFIDR:MTFCC:FULLNAME:SMID:LFROMADD:LTOADD:RFROMADD:RTOADD:ZIPL:ZIPR:FEATCAT:HYDROFLG:RAILFLG:ROADFLG:OLFFLG:PASSFLG:DIVROAD:EXTTYP:TTYP:DECKEDROAD:ARTPATH";
+dbfinfo="STATEFP:COUNTYFP:TLID:TFIDL:TFIDR:MTFCC:FULLNAME:SMID:LFROMADD:LTOADD:RFROMADD:RTOADD:ZIPL:ZIPR:FEATCAT:HYDROFLG:RAILFLG:ROADFLG:OLFFLG:PASSFLG:DIVROAD:EXTTYP:TTYP:DECKEDROAD:ARTPATH:PERSIST:GCSEFLG:OFFSETL:OFFSETR:TNIDF:TNIDT";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="MTFCC:FULLNAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=6; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+# item locations
+/^MTFCC=C3/ {display_level=0; next}
+# water
+/^MTFCC=H20/ {filled=1; fill_style=2; fill_stipple=2; color=117; fill_color=117; label_color=26; display_level=1024;next}
+/^MTFCC=H30/ {filled=1; fill_style=2; fill_stipple=2; color=117; fill_color=117; label_color=26; display_level=1024;next}
+# buildings
+/^MTFCC=K/ {display_level=128; next}
+# PLCC
+/^MTFCC=L/ {display_level=1024; next}
+# legal / statistical boundary
+/^MTFCC=P0001/ {display_level=0; next}
+# water shoreline
+/^MTFCC=P0002/ {display_level=1240; color=9; fill_color=9; next}
+# water intermittent shoreline
+/^MTFCC=P0003/ {display_level=1240; color=9; fill_color=9; next}
+# non-visible boundary
+/^MTFCC=P0004/ {display_level=0; next}
+# railroad
+/^MTFCC=R/ {lanes=2; color=8; pattern=1; display_level=128; next}
+# Limited access road
+/^MTFCC=S11/ {lanes=4; color=11; display_level=1024; label_level=512; font_size=3; next}
+# secondary road
+/^MTFCC=S12/ {display_level=512; lanes=3; color=8; label_level=256; font_size=2; next}
+# local road
+/^MTFCC=S14/ {display_level=128; label_level=16; color=48; lanes=1; next}
+# 4WD off-road trail
+/^MTFCC=S15/ {lanes=1; color=4; display_level=64; font_size=1; next}
+# Freeway access / service drive
+/^MTFCC=S16/ {color=11; display_level=64; next}
+# walkway / stairway
+/^MTFCC=S17[12]/ {lanes=1; color=12; pattern=2; display_level=64; next}
+# alley / private road
+/^MTFCC=S17[34]/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# bike / bridle path
+/^MTFCC=S18/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# road median
+/^MTFCC=S20/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/featnames.dbfawk b/config/featnames.dbfawk
new file mode 100644
index 0000000..7890b62
--- /dev/null
+++ b/config/featnames.dbfawk
@@ -0,0 +1,87 @@
+# $Id: featnames.dbfawk,v 1.4 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for FEATNAMES
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+# 2007FE = dbfinfo="TLID:FULLNAME:NAME:PREDIRABRV:PRETYPABRV:PREQUALABR:SUFDIRABRV:SUFTYPABRV:SUFQUALABR:PREDIR:PRETYP:PREQUAL:SUFDIR:SUFTYP:SUFQUAL:LINEARID:MTFCC:PAFLAG";
+dbfinfo="TLID:FULLNAME:NAME:PREDIRABRV:PRETYPABRV:PREQUALABR:SUFDIRABRV:SUFTYPABRV:SUFQUALABR:PREDIR:PRETYP:PREQUAL:SUFDIR:SUFTYP:SUFQUAL:LINEARID:MTFCC:PAFLAG";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="FULLNAME:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=26; fill_color=26; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=26; font_size=0; symbol=""; fill_style=0 }
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+# item locations
+#/^MTFCC=C3/ {display_level=0; next}
+# water
+/^MTFCC=H20/ {filled=1; fill_style=2; fill_stipple=2; color=117; fill_color=117; label_color=26; display_level=1024;next}
+/^MTFCC=H30/ {filled=1; fill_style=2; fill_stipple=2; color=117; fill_color=117; label_color=26; display_level=1024;next}
+# buildings
+#/^MTFCC=K/ {display_level=256; color=25; next}
+# PLCC
+/^MTFCC=L/ {display_level=0; next}
+# legal / statistical boundary
+/^MTFCC=P0001/ {display_level=0; next}
+# water shoreline
+/^MTFCC=P0002/ {display_level=1240; color=9; fill_color=9; next}
+# water intermittent shoreline
+/^MTFCC=P0003/ {display_level=1240; color=9; fill_color=9; next}
+# non-visible boundary
+/^MTFCC=P0004/ {display_level=0; next}
+# railroad
+/^MTFCC=R/ {lanes=2; color=8; pattern=1; display_level=128; next}
+# Limited access road
+/^MTFCC=S11/ {display_level=2048; lanes=4; color=11; label_level=512; font_size=3; next}
+# secondary road
+/^MTFCC=S12/ {display_level=128; lanes=3; color=8; label_level=128; font_size=2; next}
+# local road
+/^MTFCC=S14/ {display_level=128; label_level=16; color=20; lanes=1; next}
+# 4WD off-road trail
+/^MTFCC=S15/ {lanes=1; color=69; display_level=64; font_size=1; next}
+# Freeway access / service drive
+/^MTFCC=S16/ {color=11; display_level=64; next}
+# walkway / stairway
+/^MTFCC=S17[12]/ {lanes=1; color=12; pattern=2; display_level=64; next}
+# alley / private road
+/^MTFCC=S17[34]/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# bike / bridle path
+/^MTFCC=S18/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# road median
+/^MTFCC=S20/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/gfe_coastal_waters.dbfawk b/config/gfe_coastal_waters.dbfawk
new file mode 100644
index 0000000..8e60de5
--- /dev/null
+++ b/config/gfe_coastal_waters.dbfawk
@@ -0,0 +1,42 @@
+# $Id: gfe_coastal_waters.dbfawk,v 1.1 2012/03/02 20:26:50 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canonical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OFFICE:DIST_NAME:STATE_CODE:STATE_NAME:TIME_ZONE:AAC:DIST_NO:PT_1_NAME:PT_2_NAME:PART_STATE:DISP_ORDER:AREA_TYPE:NARR_FLAG:LEVEL:AAC_PARENT:RPT_SEAS:RPT_SWELL:ELEVATION";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="DIST_NAME:AAC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^AAC=(.*)$/ {key="$1"; next}
+/^DIST_NAME=(.*)$/ {name="$1"; next}
diff --git a/config/gfe_coastal_waters_warnings.dbfawk b/config/gfe_coastal_waters_warnings.dbfawk
new file mode 100644
index 0000000..1cf4f1c
--- /dev/null
+++ b/config/gfe_coastal_waters_warnings.dbfawk
@@ -0,0 +1,42 @@
+# $Id: gfe_coastal_waters_warnings.dbfawk,v 1.1 2012/03/02 20:26:50 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OFFICE:DIST_NAME:STATE_CODE:STATE_NAME:TIME_ZONE:AAC:SEG:AAC_MW:PT_1_NAME:PT_2_NAME:PART_STATE:DISP_ORDER:AREA_TYPE:NARR_FLAG:LEVEL:AAC_PARENT:RPT_SEAS:RPT_SWELL:DESC_TEXT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="DIST_NAME:AAC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^AAC=(.*)$/ {key="$1"; next}
+/^DIST_NAME=(.*)$/ {name="$1"; next}
diff --git a/config/gfe_fire_weather.dbfawk b/config/gfe_fire_weather.dbfawk
new file mode 100644
index 0000000..58e8e91
--- /dev/null
+++ b/config/gfe_fire_weather.dbfawk
@@ -0,0 +1,42 @@
+# $Id: gfe_fire_weather.dbfawk,v 1.1 2012/03/02 20:26:50 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OFFICE:DIST_NO:DIST_NAME:STATE_CODE:STATE_NAME:TIME_ZONE:AAC:SOURCE:FIREBAN_TH:BAN_FLAG:DISP_ORDER:NARR_FLAG:LEVEL:USE_GFDR:USE_FFDR:USE_SFDR:USE_HI_FDR:PW_AACS";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="DIST_NAME:AAC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^AAC=(.*)$/ {key="$1"; next}
+/^DIST_NAME=(.*)$/ {name="$1"; next}
diff --git a/config/gfe_metro_areas.dbfawk b/config/gfe_metro_areas.dbfawk
new file mode 100644
index 0000000..d10afa0
--- /dev/null
+++ b/config/gfe_metro_areas.dbfawk
@@ -0,0 +1,42 @@
+# $Id: gfe_metro_areas.dbfawk,v 1.1 2012/03/02 20:26:50 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OFFICE:DIST_NO:DIST_NAME:STATE_CODE:STATE_NAME:TIME_ZONE:AAC:DISP_ORDER:NARR_FLAG:AAC_PARENT:SUB_FLAG:DESCRIPTN:SURF_FLAG:ROAD_FLAG";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="DIST_NAME:AAC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^AAC=(.*)$/ {key="$1"; next}
+/^DIST_NAME=(.*)$/ {name="$1"; next}
diff --git a/config/gfe_public_weather.dbfawk b/config/gfe_public_weather.dbfawk
new file mode 100644
index 0000000..4b85f77
--- /dev/null
+++ b/config/gfe_public_weather.dbfawk
@@ -0,0 +1,42 @@
+# $Id: gfe_public_weather.dbfawk,v 1.1 2012/03/02 20:26:50 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OFFICE:DIST_NO:DIST_NAME:STATE_CODE:STATE_NAME:TIME_ZONE:AAC:DISP_ORDER:NARR_FLAG:LEVEL:USE_GFDR:USE_FFDR:USE_SFDR:USE_HI_FDR:ALP_FLAG:SURF_FLAG:MW_AACS";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="DIST_NAME:AAC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^AAC=(.*)$/ {key="$1"; next}
+/^DIST_NAME=(.*)$/ {name="$1"; next}
diff --git a/config/gps_wpt.dbfawk b/config/gps_wpt.dbfawk
new file mode 100644
index 0000000..e72cf5f
--- /dev/null
+++ b/config/gps_wpt.dbfawk
@@ -0,0 +1,20 @@
+# $Id: gps_wpt.dbfawk,v 1.8 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map dbf data that accompanies a shapefile created
+# by the "Fetch GPS Waypoints" option of Xastir.
+#
+# It simply attaches the name of the waypoint to the displayed waypoint.
+#
+BEGIN{
+# identifies the signature we want to recognize
+  dbfinfo="name:commt:date";
+# and the fields we actually care about
+  dbffields="name";
+}
+# Executed at beginning of each record, reset defaults
+BEGIN_RECORD {key=""; lanes=1; color=3; name=""; filled=0; pattern=0; display_level=256; label_level=128; label_color=8; symbol="/. "}
+# Find the name, make sure it gets displayed along with the data.
+/^name=(.*)$/ {name="$1";}
+
diff --git a/config/language-Dutch.sys b/config/language-Dutch.sys
new file mode 100644
index 0000000..ecf1740
--- /dev/null
+++ b/config/language-Dutch.sys
@@ -0,0 +1,1372 @@
+# $Id: language-Dutch.sys,v 1.240 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the Dutch Language file used for all the prompts in xastir
+#
+# Creator        : Henk de Groot <pe1dnn at amsat.org >
+# Maintained by  : The Xastir Group <xastir at xastir.org>
+# Last Modified  : Apr 28 2001, Henk de Groot <pe1dnn at amsat.org>
+# Modified 1.0.3 : Oct 19 2001, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.0.4 : Nov 22 2001, Henk de Groot <pe1dnn at amsat.org>
+# Modified 1.0.4 : Nov 25 2001, Henk de Groot <pe1dnn at amsat.org>
+# Modified 1.0.6 : Dec 16 2001, Henk de Groot <pe1dnn at amsat.org>
+# Modified 1.0.7 : Aug 27 2002, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.1.4 : Apr 15 2003, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.1.4 : May 20 2003, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.3.2 : Jun 08 2004, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.3.x : Sept 1 2004, Han Sytsma <h.l.sytsma at hetnet.nl> / # Henk de Groot <pe1dnn at amsat.org>
+# Modified 1.4.2 : Feb 14 2005, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.7.0 : Oct 15 2005, Han Sytsma <h.l.sytsma at hetnet.nl>
+# Modified 1.8.0 : Jan  9 2006, Han Sytsma <h.l.sytsma at hetnet.nl>
+#
+# comment lines with pound signs in front are ignored
+# File format as follows:
+# Id (10 chars alpha numeric)|(String associated with id)|QuickKeys|#comment
+#
+# WARNING:
+# Some strings contain formatting commands like %s and %d, you should not
+# change these. Wrong format strings could produce a segfault!
+#
+# Main Menu
+MENUTB0001|Bestand|B|
+MENUTB0002|Schermen|S|
+MENUTB0004|Kaarten|K|
+MENUTB0005|Beeld|l|
+MENUTB0006|Berichten|r|
+MENUTB0010|Interfaces|f|
+MENUTB0009|Help|H|
+#
+# Menu "File"
+PULDNFI001|Instelling|I|
+PULDNFI002|Open Log Bestand|O|
+PULDNFI003|Test||
+PULDNFI004|Sluiten|S|
+PULDNFI007|Verander Debug Level|D|
+PULDNFI010|TNC Loggen|T|
+PULDNFI011|Net Loggen|N|
+PULDNFI012|IGate Loggen|G|
+PULDNFI013|WX Loggen|W|
+PULDNFI014|Activeer PNG Snapshots|A|
+PULDNFI015|Kaart Afdrukken|K|
+PULDNFI016|KML Snapshots||
+#
+# Menu "View"
+PULDNVI001|Bulletins|B|
+PULDNVI002|Ontvangen Packets|P|
+PULDNVI003|Mobiele Stations|M|
+PULDNVI004|Alle Stations|A|
+PULDNVI009|Lokale Stations|S|
+PULDNVI012|Laatste Stations|L|
+PULDNVI005|Weerstations|W|
+PULDNVI008|Eigen Weer Gegevens|E|
+PULDNVI007|Weer Waarschuwingen|W|
+PULDNVI011|Berichten Verkeer|V|
+PULDNVI013|Tijdsduur Aktief|U|
+PULDNVI014|Tijdsduur Programma Beschikbaar||
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statistieken||
+#
+# Menu "Configure"
+PULDNCF004|Station|t|
+PULDNCF001|Standaard|S|
+PULDNCF003|Tijdsinstelling|m|
+PULDNCF002|Coordinaten Aanduiding|C|
+PULDNCF006|Audio Alarm|A|
+PULDNCF007|Spraak|p|
+PULDNCF008|Instellingen nu bewaren!|I|
+# (Units see PULDNDP006)
+#
+# Menu "Maps"
+PULDNMP001|Kaart Kiezer|K|
+PULDNMP012|Ga naar Lokatie|G|
+PULDNMP014|Lokaliseer Kaart Functie|L|
+PULDNMP016|Disable Fast Zoom/Pan/Home||
+PULDNMP013|Zet alle kaarten uit|Z|
+PULDNMP002|Automatische Kaart Keuze|A|
+PULDNMP003|Kaart Graadlijnen|G|
+PULDNMP004|Kaart Niveaus||
+PULDNMP010|Kaartlabels||
+PULDNMP009|Kleur Gevulde Gebieden|K|
+PULDNMP007|Kaart WX Waarschuwing|W|
+PULDNMP005|Achtergrond Kleur|c|
+PULDNMP006|Station Tekst Stijl|S|
+PULDNMP026|Icon Omranding Stijl|O|
+PULDNMP011|Muis Menu|M|
+PULDNMP008|Kaart Intensiteit|I|
+PULDNMP020|Configureren Tigermap||
+PULDNMP021|Automatische Kaartkeuze - Zet Raster Kaarten Uit||
+PULDNMP022|Indexeer Kaarten bij het Starten||
+PULDNMP023|Index: Voeg nieuwe kaarten toe|n|
+PULDNMP024|Index: Herindexeer ALLE kaarten|H|
+PULDNMP025|Fonts||
+PULDNMP015|Xfont selectie||
+PULDNMP027|Download Kaarten opnieuw (niet uit cache)||
+PULDNMP028|Leeg de gehele kaarten cache!||
+PULDNMP029|Zoek Adres||
+PULDNMP030|Configureer USGS DRG||
+PULDNMP031|Zet kaart begrenzing aan||
+#
+#
+# PopUp "Configure Tigermap"
+MPUPTGR001|Raster|
+MPUPTGR002|Provincies||
+MPUPTGR003|Stads Labels||
+MPUPTGR004|Bevolkte Gebieden||
+MPUPTGR005|Grote wegen||
+MPUPTGR006|Straten||
+MPUPTGR007|Spoorwegen||
+MPUPTGR008|Staat Labels||
+MPUPTGR009|Snelwegen Labels||
+MPUPTGR010|VS Hoofdwegen Labels||
+MPUPTGR011|Hoofd wegen Labels||
+MPUPTGR012|Selecteer weer te geven items:||
+MPUPTGR013|Rivieren||
+MPUPTGR014|Meren||
+MPUPTGR015|Vliegvelden, Parken, enz||
+MPUPTGR016|Kaart Intensiteit||
+MPUPTGR017|Internet Kaarten Timeout (sec)||
+MPUPTGR018|Zet Tiger Kaarten aan||
+#
+# PopUp "Configureer USGS DRG"
+MPUPDRG001|Selecteer weer te geven items:||
+MPUPDRG002|Kleur onderliggende kaart (XOR)||
+MPUPDRG003|Zwart||
+MPUPDRG004|Wit||
+MPUPDRG005|Blauw||
+MPUPDRG006|Rood||
+MPUPDRG007|Bruin||
+MPUPDRG008|Groen||
+MPUPDRG009|Paars||
+MPUPDRG010|Geel||
+MPUPDRG011|Licht Blauw||
+MPUPDRG012|Licht Rood||
+MPUPDRG013|Licht Paars||
+MPUPDRG014|Licht Grijs||
+MPUPDRG015|Licht Bruin||
+#
+# PopUp "Kaart kiezer"
+WPUPMCP001|Kaart Kiezer||
+PULDNMMC01|Wis|N|
+PULDNMMC02|Vector|V|
+PULDNMMC03|250k Topogr.|2|
+PULDNMMC04|100k Topogr.|1|
+PULDNMMC05|24k Topogr.|4|
+PULDNMMC06|Vouw Dirs Uit|||
+PULDNMMC07|Dirs/Kaarten Geselecteerd:||
+PULDNMMC08|Maak Directories leeg|C|
+PULDNMMC09|Selecteer Alles|S|
+#
+# PullDown "Map Background Color"
+PULDNMBC01|Grijs||
+PULDNMBC02|Mistig Roze||
+PULDNMBC03|Marine Blauw||
+PULDNMBC04|Staal Blauw||
+PULDNMBC05|Zee Groen||
+PULDNMBC06|Pastel Groen||
+PULDNMBC07|Pastel Geel||
+PULDNMBC08|Goud Geel||
+PULDNMBC09|Roze Bruin||
+PULDNMBC10|Vuur Rood||
+PULDNMBC11|Wit||
+PULDNMBC12|Zwart||
+#
+# PullDown "Station text Style"
+PULDNMSL01|Zwarte Rand||
+PULDNMSL02|Zwarte Schaduw en gevulde achtergrond||
+PULDNMSL03|Tekst op Zwarte achtergond|T|
+#
+# PullDown "Icon Outline Style"
+PULDNMIO01|Geen Omranding|G|
+PULDNMIO02|Zwarte Omranding|Z|
+PULDNMIO03|Grijze Omranding|G|
+PULDNMIO04|Witte Omranding|W|
+#
+# Switches
+PULDNOT001|Aan||
+PULDNOT002|Uit||
+PULDNOT003|Kort||
+#
+# Menu "Display"
+PULDNDP014|Zoek station|Z|
+PULDNDP001|Volg station|V|
+PULDNDP022|Spoor downloaden|p|
+PULDNDP032|Filter gegevens||
+PULDNDP040|Deselecteer alles||
+PULDNDP041|Selecteer mijn||
+PULDNDP042|Selecteer TNC||
+PULDNDP027|- Selecteer directe stations||
+PULDNDP043|- Selecteer via digi||
+PULDNDP034|Selecteer net||
+PULDNDP019|Geef verlopen gegevens weer||
+PULDNDP044|Selecteer stations||
+PULDNDP028|- Selecteer vaste stations||
+PULDNDP029|- Selecteer bewegende stations||
+PULDNDP030|- Selecteer weer stations||
+PULDNDP053|- Selecteer CWOP WX stations||
+PULDNDP045|Selecteer Objecten/Items||
+PULDNDP026|- Selecteer  weer Objecten/Items||
+PULDNDP039|- Selecteer  water Hoogte Objecten/Items||
+PULDNDP031|- Selecteer  andere Objecten/Items||
+PULDNDP033|Filter weergave||
+PULDNDP010|Roepnaam|R|
+PULDNDP012|Symbolen|y|
+PULDNDP011|- Draai symbolen|D|
+PULDNDP007|Station spoor|t|
+PULDNDP003|Koers|K|
+PULDNDP004|Snelheid|S|
+PULDNDP017|- Geef snelheid kort traject weer||
+PULDNDP002|Hoogte|H|
+PULDNDP009|Weer informatie|W|
+PULDNDP046|- Weer tekst||
+PULDNDP018|-- Geef alleen temperatuur weer||
+PULDNDP047|- Wind indicator||
+PULDNDP054|Geef Aloha cirkels weer||
+PULDNDP013|Zet stations nadering aan||
+PULDNDP008|Stations Vermogen/Winst|V|
+PULDNDP021|- Activeer standaard vermogen/winst||
+PULDNDP020|- Activeer mobiel vermogen/winst||
+PULDNDP023|Geef DF cirkels weer||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearing||
+PULDNDP035|Activeer berekening op geschatte waarden||
+PULDNDP036|- Geef boogsegment weer||
+PULDNDP037|- Geef richting weer||
+PULDNDP038|- Geef symbool weer||
+PULDNDP005|Afst/koers|A|
+PULDNDP024|Geeft tijd laatste rapport||
+PULDNDP015|Wis alle stations|W|
+PULDNDP016|Wis Alle sporen|S|
+PULDNDP025|Wis Object/Item geschiedenis||
+PULDNDP048|Herlaad Object/Item geschiedenis||
+PULDNDP049|Wis alle gemarkeerde bijnamen||
+PULDNDP050|Wis gemarkeerde bijnamen geschiedenis||
+PULDNDP051|Selecteer alleen gemarkeerde bijnamen||
+PULDNDP052|- Label route punten||
+PULDNDP055|Export all|E|
+PULDNDP056|Export to KML File||
+#
+# Units
+PULDNUT001|Engels||
+PULDNUT002|Metrisch||
+#
+# Menu "Messages"
+PULDNMG001|Zend Bericht Naar|Z|
+PULDNMG002|Open Groeps Bericht|O|
+PULDNMG003|Wis alle uitgaande berichten|W|
+PULDQUS001|Algemene Stations Aanvraag|G|
+PULDQUS002|IGate Stations Aanvraag|I|
+PULDQUS003|WX Stations Aanvraag|t|
+PULDNMG004|Automatisch Antwoord Bericht|A|
+PULDNMG005|Automatisch Beantwoorden|B|
+PULDNMG006|Sateliet Bevestigings Mode|M|
+PULDNMG007|Show Pending Messages|P|
+#
+# Menu "Interfaces"
+PULDNTNT04|Interface besturing||
+PULDNTNT03|Zet verzenden van alle data uit||
+PULDNTNT05|Zet verzenden positie uit||
+PULDNTNT06|Zet verzenden van objecten uit||
+PULDNTNT11|Zet server poort aan||
+PULDNTNT01|Zend nu!|Z|
+PULDNTNT07|Volg GPS spoor|F|
+PULDNTNT08|Volg GPS routes|R|
+PULDNTNT09|Volg GPS routepunten|W|
+PULDNTNT10|Laad Garmin RINO routepunten|G|
+#
+# Menu "Help"
+PULDNHEL01|Informatie|A|
+PULDNHEL02|Help Onderwerpen|I|
+PULDNHEL03|NOOD BAKEN BAKEN MODUS INSCHAKELEN|E|
+PULDNHEL04|!!! NOOD BAKEN MODUS !!!||
+PULDNHEL05|Over Xastir||
+#
+# Mouse Menu Popup
+POPUPMA001|Opties||
+POPUPMA00c|Centreer|C|
+POPUPMA015|Stations informatie|S|
+POPUPMA002|Zoom in|i|
+POPUPMA003|Zoom uit|u|
+POPUPMA004|Zoom niveau|n|
+POPUPMA005|Niveau 1|1|
+POPUPMA006|Niveau 16|6|
+POPUPMA007|Niveau 64|4|
+POPUPMA008|Niveau 256|2|
+POPUPMA009|Niveau 1024|0|
+POPUPMA010|Niveau 8192|8|
+POPUPMA017|Hele Wereld|H|
+POPUPMA016|Vorige pos/zoom|p|
+POPUPMA018|Plaats een Object|O|
+POPUPMA019|Verander een Object|V|
+POPUPMA025|Verplaats mijn station naar dit punt|H|
+POPUPMA011|Schuif Omhoog|c|
+POPUPMA012|Schuif Omlaag|h|
+POPUPMA013|Schuif naar Links|l|
+POPUPMA014|Schuif naar Rechts|r|
+POPUPMA020|Afstand meten||
+POPUPMA021|Verplaatsen||
+POPUPMA022|Volg me||
+POPUPMA023|Functie toetsen actief!||
+POPUPMA024|Schakel CapsLock/NumLock/ScrollLock/andere Toetsen UIT||
+POPUPMA026|Centreer & zoom||
+POPUPMA027|Breedtegraden||
+POPUPMA028| Lengtegraden||
+POPUPMA029|Teken CAD objecten||
+POPUPMA030|Draw||
+POPUPMA031|Sluit polygoon||
+POPUPMA032|Wis CAD polygonen||
+POPUPMA033|**NIET GEBRUIKT**||
+POPUPMA034|Handmatig Zoom Niveau||
+POPUPMA035|10% uit||
+POPUPMA036|10% in||
+POPUPMA037|Gebied||
+POPUPMA038|Vierkant||
+POPUPMA039|Vierkante voet||
+POPUPMA040|Vierkante meters||
+POPUPMA041|Richting||
+POPUPMA042|Graden||
+POPUPMA043|Pas meerduidige positie aan||# origineel ambigious mag ook meervoudige zijn?
+POPUPMA044|Positie meerduidigheid is aan, uw nieuwe positie kan verspringen.||# idem
+POPUPMA045|Voor gedefinierde objecten||
+POPUPMA046|CAD polygonen||
+POPUPMA047|Zet CAD objecten aan||
+POPUPMA048|Zet CAD labels aan||
+POPUPMA049|Zet CAD opemerkingen aan||
+POPUPMA050|Zet CAD waarschijnlijkheid aan||
+POPUPMA051|Zet CAD omgevingsgrootte aan||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|meters||
+POPUPMA055|mi|
+#
+# Status line labels
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Tr||
+BBARSTH001|%d/%d Stations||
+BBARSTA000|%-9s Nieuw Object!||
+BBARSTA001|%-9s  Nieuw station!||
+BBARSTA002|%-9s||# Nieuwe Gegevens (geeft alleen roepnaam weer)
+BBARSTA003|Kaarten Laden||
+BBARSTA004|Kaarten Geladen||
+BBARSTA005|Kaart Graadlijnen Aan||
+BBARSTA006|Kaart Graadlijnen Uit||
+BBARSTA007|Auto. Kaartkeuze is nu AAN||
+BBARSTA008|Auto. Kaartkeuze is nu UIT||
+BBARSTA009|Auto. Niveaukeuze is nu AAN||
+BBARSTA010|Auto. Niveaukeuze is nu UIT||
+BBARSTA011|Auto. Beantwoorden is UIT!||
+BBARSTA012|Bestand Gereed||
+BBARSTA013|GPS Poort Openen||
+BBARSTA014|GPS Poort Sluiten||
+BBARSTA015|Kreeg GPS RMC tekst||
+BBARSTA016|Kreeg GPS GGA tekst||
+BBARSTA017|Net verbinding naar host verbroken||
+BBARSTA018|Verbindingstijd netwerk verstreken!||
+BBARSTA019|Zoeken naar host %s||
+BBARSTA020|Verbonden met %s||
+BBARSTA021|Net verbinding mislukt!||
+BBARSTA022|Kon socket niet binden!||
+BBARSTA023|Geen IP voor host!||
+BBARSTA024|Geen host gespecificeerd||
+BBARSTA025|Host gevonden, Verbinding maken met %d||
+BBARSTA026|Wachten op GPS gegevens via HSP..||
+BBARSTA027|HSP vrijmaken, TNC gegevens ophalen..||
+BBARSTA028|%s wordt geladen||
+BBARSTA029|WX poort openen||
+BBARSTA030|WX poort sluiten||
+BBARSTA031|Zoeken naar hostnaam %d||
+BBARSTA032|WX gegevens gedecodeerd||
+BBARSTA033|Echo van de digipeater||
+BBARSTA034|Weer waarschuwings kaarten laden||
+BBARSTA035|Wachten op GPS gegevens via AUX..||
+BBARSTA036|HSP vrijmaken, TNC gegevens ophalen..||
+BBARSTA037|GPS tekst gedecodeerd||
+BBARSTA038|Positie verandering bij mijn station||
+BBARSTA039|Bezig met indexeren van: %s||
+BBARSTA040|Amateur APRS(tm) station %s||
+BBARSTA041|Wacht op GPS gegevens..||
+BBARSTA042|Uitzenden van objecten/items||
+BBARSTA043|Log bijwerken||
+BBARSTA044|ALOHA afstand is %d%s||
+BBARSTA045|Symbolen laden...||
+BBARSTA046|Opnieuw laden van symbolen...||
+BBARSTA047|Initialiseer mijn station...||
+BBARSTA048|Start interfaces...||
+BBARSTA049|Reading tiles...||
+BBARSTA050|Downloading tiles...||
+BBARSTA051|Downloading tile %li of %li||
+#
+# PopUp "View - Incoming Packet Data"
+WPUPDPD001|Ontvangen packets bekijken||
+WPUPDPD002|Alleen TNC gegevens||
+WPUPDPD003|Alleen Net gegevens||
+WPUPDPD004|TNC en Net gegevens||
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Station Capabilities||
+WPUPDPD008|Mine Only||
+#
+# PopUp "View - Find Station"
+WPUPLSP001|Lokaliseer station||
+WPUPLSP002|Lokaliseer roepnaam||
+WPUPLSP003|Hoofdlettergevoelig||
+WPUPLSP004|Zoek exact||
+WPUPLSP005|Lokaliseer nu!||
+WPUPLSP006|Spoed lokaliseren!||
+WPUPLSP007|FCC/RAC lokalisatie||
+#
+# PopUp "Configure - Defaults"
+WPUPCFD001|Standaardinstellingen aanpassen||
+WPUPCFD002|Na hoeveel tijd moet een station als oud beschouwd worden?||
+WPUPCFD003|15 Minuten||
+WPUPCFD004|30 Minuten||
+WPUPCFD005|45 Minuten||
+WPUPCFD006|1 Uur||
+WPUPCFD007|90 Minuten||
+WPUPCFD008|2 Uur||
+WPUPCFD009|Na hoeveel tijd moet een station van het scherm verwijderd worden?||
+WPUPCFD010|6 Uur||
+WPUPCFD011|12 Uur||
+WPUPCFD012|1 Dag||
+WPUPCFD013|2 Dagen||
+WPUPCFD014|1 Week||
+WPUPCFD015|Station Zend Opties||
+WPUPCFD016|Vast Station||
+WPUPCFD017|Mobiel Station m/lokale tijd||
+WPUPCFD018|Mobiel Station m/Zulu datum-tijd||
+WPUPCFD019|Mobiel Station m/Zulu tijd-secondes||
+WPUPCFD021|Stations Positie m/weer||
+WPUPCFD022|Stations Positie, Zulu datum-tijd en weer||
+WPUPCFD023|Verzend ruwe WX gegevens?||
+WPUPCFD024|Comprimeer Object/Item gegevens bij uitzenden?||
+WPUPCFD025|Activeer alternatief net?||
+WPUPCFD026|Met welk interval positie gegevens verzenden?||
+WPUPCFD027|Nieuwe berichten weergeven||
+WPUPCFD028|Waarschuw als speciale functie toetsen aanstaan||
+WPUPCFD029|Geef bulletins zonder afstand weer||
+WPUPCFD030|Zet positie duplicaat controle uit||
+WPUPCFD031|Laad voor gedefinierde objecten uit bestand||
+WPUPCFD032|My trails in one color||
+WPUPCFD033|ALTNET:||
+#
+# PopUp "Configure - Timing"
+WPUPCFTM01|Configureer tijdsinstelling|||
+WPUPCFTM02|Interval verzenden positie (min)||
+WPUPCFTM03|Tijd tot vervagen station (min)||
+WPUPCFTM04|Max interval verzenden Object/Item (min)||
+WPUPCFTM05|Tijd tot verdwijnen van kaart (uren)||
+WPUPCFTM06|GPS status controle interval (sec)||
+WPUPCFTM07|Tijd tot wissen station (dagen)||
+WPUPCFTM08|Timeout berekening geschatte waarden (min)||
+WPUPCFTM09|Seriele Inter-Char vertraging (ms)||
+WPUPCFTM10|Nieuwe volg tijd (min)||
+WPUPCFTM11|Nieuw volg Interval (graden)||
+WPUPCFTM12|RINO -> Objecten Interval (min), 0 = Uitgeschakeld||
+WPUPCFTM13|Snapshot Interval (min)||
+#
+# PopUp "Configure Coordinate System"
+WPUPCFC001|Configureer coordinaten stelsel||
+WPUPCFC002|Selecteer coordinaten weergave||
+WPUPCFC003|dd.dddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM w/speciale zones||
+#
+# PopUp "Configure GPS"
+WPUPCFG001|GPS Instelling||
+WPUPCFG003|Eigen GPS poort||
+WPUPCFG002|Gebruik GPS positie?||
+WPUPCFG004|GPS opties||
+WPUPCFG005|Losse GPS||
+WPUPCFG006|Via TNC verbonden GPS (HSP Kabel)||
+WPUPCFG007|Via TNC verbonden GPS met gebruik van CTL-E||
+WPUPCFG008|GPS tijd (Lees elke)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 minuut||
+WPUPCFG013|2 minuten||
+WPUPCFG014|5 minuten||
+WPUPCFG015|10 minuten||
+WPUPCFG016|Via netwerk verbonden GPS||
+WPUPCFG017|GPSD Host||
+WPUPCFG018|GPSD Poort||
+WPUPCFG019|Netwerk GPS via GPSD||
+WPUPCFG020|Opnieuw verbinden na een fout?||
+WPUPCFG021|Via netwerk verbonden WX||
+WPUPCFG022|WX Host||
+WPUPCFG023|WX Poort||
+#
+# Configure TNC (baud/style are also for WX)
+WPUPCFT001|TNC instelling||
+WPUPCFT002|Gebruik TNC?||
+WPUPCFT003|TNC poort||
+WPUPCFT004|Poort instelling||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|UnProto paden||
+WPUPCFT012|Pad 1: %s via ||
+WPUPCFT013|Pad 2: %s via ||
+WPUPCFT014|Pad 3: %s via ||
+WPUPCFT015|Poort stijl||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|TNC instelling m/HSP GPS||
+WPUPCFT024|Data type||
+WPUPCFT025|Auto detectie||
+WPUPCFT026|Binair type||
+WPUPCFT027|ASCII type||
+WPUPCFT028|TNC instelling m/HSP GPS||
+WPUPCFT029|TNC instelling m/AUX GPS||
+WPUPCFT030|Configureer KISS TNC||
+WPUPCFT031|TNC configuratie bestanden||
+WPUPCFT032|Bestandsnaam activeren TNC||
+WPUPCFT033|Bestandsnaam deactiveren TNC||
+WPUPCFT034|KISS parameters||
+WPUPCFT035|TXDelay (10 ms stappen)||
+WPUPCFT036|Persistence (0 tot 255)||
+WPUPCFT037|SlotTime (10 ms stappen)||
+WPUPCFT038|TxTail (10 ms stappen)||
+WPUPCFT039|Vol Duplex||
+WPUPCFT040|Configureer Multi-Port KISS TNC||
+WPUPCFT041|Radio poort||
+WPUPCFT042|Twijfelachtige UNPROTO route!||
+WPUPCFT043|Gebruik liever een kortere route zoals WIDE2-2 of WIDE1-1,WIDE2-2||
+WPUPCFT044|Twijfelachtige IGATE route!||
+WPUPCFT045|Uitzenden met twijfelachtige UNPROTO route!||
+WPUPCFT046|Uitzenden met twijfelachtige IGATE route!||
+WPUPCFT047|Initialisser KISS-modus bij opstarten||
+#
+# PopUp "Configure WX Port"
+WPUPCFWX01|WX Poort instelling||
+WPUPCFWX02|Weerstation apparaat||
+WPUPCFWX03|Regenmeter correctie (globale instelling)||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|Geen correctie||
+#
+# PopUp "Configure - Station"
+WPUPCFS001|Stations Instelling||
+WPUPCFS002|Roepnaam||
+WPUPCFS003|Breedte graden||
+WPUPCFS004|gra||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|Lengte graden||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Station Symbool||
+WPUPCFS010|Groep/overlay||
+WPUPCFS011|Symbool||
+WPUPCFS028|Selecteer||
+WPUPCFS012|Vermogenswinst||
+WPUPCFS013|PHG uitschakelen||
+WPUPCFS014|Antenne winst||
+WPUPCFS015|Antenne versterking||
+WPUPCFS016|Omni||
+WPUPCFS017|Commentaar:||
+WPUPCFS018|Positie onzekerheid||
+WPUPCFS019|Geen||
+WPUPCFS020|.11 mijl omtrek||
+WPUPCFS021|1.15 mijl omtrek||
+WPUPCFS022|11.51 mijl omtrek||
+WPUPCFS023|69.09 mijl omtrek||
+WPUPCFS024|.18 kilometer omtrek||
+WPUPCFS025|1.85 kilometer omtrek||
+WPUPCFS026|18.53 kilometer omtrek||
+WPUPCFS027|111.19 kilometer omtrek||
+WPUPCFS029|Verstuur gecomprimeerde positie|C|
+#
+# PopUp "Object/Item"
+POPUPOB001|Object/Item||
+POPUPOB002|Naam||
+POPUPOB003|Plaats object||
+POPUPOB004|Verwijder object||
+POPUPOB005|Verander object||
+POPUPOB006|Maak een nieuw object||
+POPUPOB007|Oppervlakte object||
+POPUPOB008|Activeer oppervlakte object||
+POPUPOB009|Heldere kleur||
+POPUPOB010|Kleur-Vulling||
+POPUPOB011|Cirkel||
+POPUPOB012|Rechtse lijn '/'||
+POPUPOB013|Linkse lijn '\'||
+POPUPOB014|Driehoek||
+POPUPOB015|Rechthoek||
+POPUPOB016|Zwart||
+POPUPOB017|Blauw||
+POPUPOB018|Groen||
+POPUPOB019|Cyaan||
+POPUPOB020|Rood||
+POPUPOB021|Violet||
+POPUPOB022|Geel||
+POPUPOB023|Grijs||
+POPUPOB024|Offset omhoog:||
+POPUPOB025|Offset links (behalve '/'):||
+POPUPOB026|Doorgang:||
+POPUPOB027|Algemene Opties||
+POPUPOB028|Lokatie||
+POPUPOB029|Activeer markering||
+POPUPOB030|Gegevens:||
+POPUPOB031|Gemarkeerd object||
+POPUPOB032|Activeer compressie||
+POPUPOB033|Verwijder item||
+POPUPOB034|Wijzig item||
+POPUPOB035|Hoogte (voet):||
+POPUPOB036|Snelheid (knopen):||
+POPUPOB037|Richting:||
+POPUPOB038|DF object||
+POPUPOB039|Signaal - Hoogte(HAAT) - Versterking - Richting||
+POPUPOB040|Straal breedte - Richting||
+POPUPOB041|Rondstraler||
+POPUPOB042|Richtantenne||
+POPUPOB043|Onbruikbaar||
+POPUPOB044|Neem object over||
+POPUPOB045|Neem item over||
+POPUPOB046|DF richting:||
+POPUPOB047|Waarschijnlijkheids ringen||
+POPUPOB048|Kaartbeeld Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+# PopUp "Configure Internet"
+WPUPCFI001|Internet Instelling||
+WPUPCFI002|Host ||
+WPUPCFI003|Poort ||
+WPUPCFI004|(Alternatieve hosts)||
+WPUPCFI005|Host1||
+WPUPCFI006|Poort1||
+WPUPCFI007|Host2||
+WPUPCFI008|Poort2||
+WPUPCFI009|Wachtwoord||
+WPUPCFI010|(Bij Geen Blanco Laten)||
+WPUPCFI011|Verbinding herstellen bij NET fout?||
+WPUPCFI012|Laten Werken als I-Gate?||
+WPUPCFI013|Bij I-Gate berichten verspreiden via TNC?||
+WPUPCFI014|I-Gate transacties loggen?|||
+WPUPCFI015|Filter parameters||
+#
+# PopUp "Configure Database"
+WPUPCFID01|Database Instelling (TBD)||
+WPUPCFID02|Host ||
+WPUPCFID03|Poort ||
+WPUPCFID04|(Alternatieve hosts)||
+WPUPCFID05|Host1||
+WPUPCFID06|Poort1||
+WPUPCFID07|Host2||
+WPUPCFID08|Poort2||
+WPUPCFID09|Wachtwoord||
+WPUPCFID10|(Bij Geen Blanco Laten)||
+WPUPCFID11|Verbinding herstellen bij NET fout?||
+WPUPCFID12|Laten werken als I-Gate?||
+WPUPCFID13|Bij I-Gate berichten verspreiden via TNC?||
+WPUPCFID14|I-Gate transacties loggen?|||
+WPUPCFID15|Filter parameters||
+#
+# PopUp "Configure AGWPE"
+WPUPCFIA01|Configureer AGWPE||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Poort ||
+WPUPCFIA04|(Alternatieve hosts)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Poort1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Poort2||
+WPUPCFIA09|Wachtwoord||
+WPUPCFIA10|(Bij geen blanco laten)||
+WPUPCFIA11|Verbinding herstellen bij NET fout?||
+WPUPCFIA12|Laten werken als I-Gate?||
+WPUPCFIA13|Bij I-Gate berichten verspreiden via TNC?||
+WPUPCFIA14|I-Gate transacties loggen?||
+WPUPCFIA15|Zend op radio poort||
+#
+# PopUp "Configure Audio Alarms"
+WPUPCFA001|Audio alarm instellen||
+WPUPCFA002|Audio afspeel commando||
+WPUPCFA003|Alarm bij||
+WPUPCFA004|Audio bestand om af te spelen||
+WPUPCFA005|Nieuw Station||
+WPUPCFA006|Nieuw Bericht||
+WPUPCFA007|Nadering||
+WPUPCFA008|Band opening||
+WPUPCFA009|Minimale afstand||
+WPUPCFA010|Maximale afstand||
+WPUPCFA011|Weer waarschuwing||
+#
+# PopUp "Configure Speech"
+WPUPCFSP01|Spraak instellen||
+WPUPCFSP02|Uitvoer spraak bij:||
+WPUPCFSP03|Nieuw station||
+WPUPCFSP04|Waarschuwing nieuw bericht||
+WPUPCFSP05|Nieuwe bericht inhoud||
+WPUPCFSP06|Naderings waarschuwing||
+WPUPCFSP07|Band opening||
+WPUPCFSP08|Nieuwe weer waarschuwing||
+WPUPCFSP09|Naderings waarschuwing van gevolgd station||
+#
+# PopUp "Track Station"
+WPUPTSP001|Volg station||
+WPUPTSP002|Volg roepnaam||
+WPUPTSP003|Hoofdlettergevoelig||
+WPUPTSP004|Exact dit station||
+WPUPTSP005|Volg nu!||
+WPUPTSP006|Stop met volgen||
+WPUPTSP007|Download spoor||
+WPUPTSP008|Roepnaam||
+WPUPTSP009|Begin volgen (uren geleden)||
+WPUPTSP010|Volgduur (uren)||
+#
+# PopUp "Messages"
+WPUPMSB001|Stuur bericht, venster %d||
+WPUPMSB002|Stuur groeps bericht, venster %d||
+WPUPMSB003|Stations roepnaam:||
+WPUPMSB004|Groeps roepnaam:||
+WPUPMSB005|Nieuwe/Refresh roepnaam||
+WPUPMSB006|Nieuwe groep||
+WPUPMSB007|Wis bericht geschiedenis||
+WPUPMSB008|Bericht:||
+WPUPMSB009|Stuur nu!||
+WPUPMSB010|Pad:||
+WPUPMSB011|Breek alle openstaande berichten af||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Zend uit||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*AFGEBROKEN*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Path||
+WPUPMSB020|Use Default Path(s)||
+WPUPMSB021|Direct (No path)||
+WPUPMSB022|Reverse Path (Hint):||
+#
+# PopUp "Auto Reply"
+WPUPARM001|Automatich antwoord bericht||
+WPUPARM002|Antwoord:||
+#
+# PopUp "Help Index"
+WPUPHPI001|Help inhoud||
+WPUPHPI002|Bekijken||
+#
+# PopUp "Station Info"
+WPUPSTI000|Object van: %s||
+WPUPSTI001|Stations informatie||
+WPUPSTI002|Stuur bericht||
+WPUPSTI003|Doorzoek FCC databank||
+WPUPSTI004|Doorzoek RAC databank||
+WPUPSTI005|Packets ontvangen: %d     Laatst Gehoord: ||
+WPUPSTI006|Gehoord via de TNC aan device %d, ||
+WPUPSTI007|Gehoord ||
+WPUPSTI008|laatste via lokaal||
+WPUPSTI009|laatste via TNC op device %d||
+WPUPSTI010|laatste via internet op device %d||
+WPUPSTI011|laatste via bestand||
+WPUPSTI012|laatste via onbekend||
+WPUPSTI013|, en is van positie veranderd||
+WPUPSTI014|Huidig Vermogen en Winst:||
+WPUPSTI016|Hoogte: %.0f%s ||
+WPUPSTI017|Richting: %s� ||
+WPUPSTI018|Snelheid: %.1fkm/h||
+WPUPSTI019|Snelheid: %.1fmph||
+WPUPSTI020|%0.1f Mijl||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Afstand vanaf mijn station %s, Koers vanaf mijn station %s||
+WPUPSTI023|Laatste positie ||
+WPUPSTI024|Weer Gegevens %c:%s||
+WPUPSTI025|Wind Richting: %s Snelheid: %03d km/h||
+WPUPSTI026|Wind Richting: %s Snelheid: %s mph||
+WPUPSTI027| Piek: %03d km/h||
+WPUPSTI028| Piek: %s mph||
+WPUPSTI029|Temperatuur: %02.1f�C   ||
+WPUPSTI030|Temperatuur: %s�F   ||
+WPUPSTI031|Vochigheid: %s%%   ||
+WPUPSTI032|Gevoels temperatuur: %02.1f�C  ||
+WPUPSTI033|Baro: %s hPa||
+WPUPSTI034|Sneeuw: %0.1f (cm/24h)||
+WPUPSTI035|Sneeuw: %0.0f (inch/24h)||
+WPUPSTI036|Regen: ||
+WPUPSTI037|%0.2f (mm/h)   ||
+WPUPSTI038|%0.2f (inch/h)   ||
+WPUPSTI039|%0.2f (mm/dag)  ||
+WPUPSTI040|%0.2f (inch/dag)  ||
+WPUPSTI041|%0.2f (mm/sinds middernacht)||
+WPUPSTI042|%0.2f (inch/sinds middernacht)||
+WPUPSTI043|Data pad: %s||
+WPUPSTI044|Commentaar %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Wis spoor||
+WPUPSTI046|Totaal regen: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (inch)||
+WPUPSTI049|Vraag trace||
+WPUPSTI050|Vraag uitstaande berichten||
+WPUPSTI051|Vraag direkte stations||
+WPUPSTI052|Vraag versie||
+WPUPSTI053|Verander object||
+WPUPSTI054|Sla spoor op||
+WPUPSTI055|Echo vanaf:||
+WPUPSTI056|Zet automatisch bijwerken aan||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|DF richting: %s||
+WPUPSTI059|Status %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Ontbrandings temp: %02.1f�C  ||
+WPUPSTI061|Ontbrandings temp: %s�F   ||
+WPUPSTI062|Vochtigheids gehalte in brandstof: %s%%   ||
+WPUPSTI063|Baro: %0.2f in Hg||
+WPUPSTI064|Vraag NWS waarschuwing||
+WPUPSTI065|Gemarkeerde bijnaam: %s||
+WPUPSTI066|Geef station een bijnaam||
+WPUPSTI067|Huidig bereik: %d miles||
+WPUPSTI068|geen||
+WPUPSTI069|default||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|bereik||
+WPUPSTI073|SLECHTE PHG||
+WPUPSTI074|SLECHTE SHG||
+WPUPSTI075|DF bereik||
+WPUPSTI076|Geen signaal gedetecteerd||
+WPUPSTI077|Detecteerbaar signaal (Wellicht)||
+WPUPSTI078|Detecteerbaar signaal maar niet bruikbaar)||
+WPUPSTI079|Zwak signaal, nauwelijks leesbaar||
+WPUPSTI080|Verruist maar bruikbaar signaal||
+WPUPSTI081|Enige ruis, goed bruikbaar signaal||
+WPUPSTI082|Goed signaal met enig waarneembare ruis||
+WPUPSTI083|Bijna ruisvrij siganal||
+WPUPSTI084|Volledig ruisvrij signaal||
+WPUPSTI085|Extreem sterk & volledig ruisvrij signaal||
+WPUPSTI086|VERKEERDE RICHTING||
+WPUPSTI087|SLECHTE NRQ||
+WPUPSTI088|DF openingshoek||
+WPUPSTI089|DF Lengte||
+WPUPSTI090|Ongeldig||
+WPUPSTI091|Verander volgspoor kleur||
+WPUPSTI092|Clear DF Bearing||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|ALOHA omtrek: %d %s||
+WPUPALO002|Stations binnen ALOHA omtrek: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiel (bewegend):   %d||
+WPUPALO005| Mobiel (anders):     %d||
+WPUPALO006| WX stations:         %d||
+WPUPALO007| Vaste stations:      %d||
+WPUPALO008|Laatst berekening %d %s %d %s geleden.||
+WPUPALO666|ALOHA omtrek nog niet berekend||
+#
+#
+# FCC-RAC Call Look up
+STIFCC0001|FCC databank doorzoeken||
+STIFCC0002|RAC databank doorzoeken||
+STIFCC0003|Naam:||
+STIFCC0004|Straat:||
+STIFCC0005|Plaats:||
+STIFCC0006|Staat:||
+STIFCC0007|Postcode:||
+STIFCC0008|Basis ||
+STIFCC0009|Geavanceerd ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+#
+#
+# FCC-RAC Call Look up
+STIFCC0100|FCC index is oud, bezig met herindexeren||
+STIFCC0101|Zoeken roepnaam||
+STIFCC0102|Roepnaam niet gevonden!||
+STIFCC0103|RAC index is oud, bezig met herindexeren||
+#
+#
+# Band open message
+UMBNDO0001|op een afstand van||
+#
+# Universal Options
+UNIOP00001|OK||
+UNIOP00002|Annuleren||
+UNIOP00003|Sluiten||
+UNIOP00004|Mijlen||
+UNIOP00005|Km||
+UNIOP00006|Device||
+UNIOP00007|Toevoegen||
+UNIOP00008|Wissen||
+UNIOP00009|Eigenschappen||
+UNIOP00010|Uitzenden toestaan?||
+UNIOP00011|Activeren bij opstarten?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|C||
+UNIOP00015|F||
+UNIOP00016|mm||
+UNIOP00017|inch||
+UNIOP00018|mm/dag||
+UNIOP00019|inch/dag||
+UNIOP00020|mm/uur||
+UNIOP00021|inch/uur||
+UNIOP00022|mm/mid||
+UNIOP00023|inch/mid||
+UNIOP00024|graden||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|in Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Stel de systeem klok in vanuit GPS?||
+UNIOP00030|Digipeat?||
+UNIOP00031|m||
+UNIOP00032|Toepassen|||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|day||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# PopUp "Station Chooser"
+STCHO00001|Station Kiezer||
+#
+# DISPLAY WX ALERT
+WPUPWXA001|Wx Waarschuwing||
+WPUPWXA002|Wx Waarschuwingen lijst||
+#
+# PopUp "Configure - Interfaces"
+WPUPCIF001|Geinstalleerde interfaces||
+WPUPCIF002|Kies interface type||
+#
+# PopUp "Configure AX.25 TNC"
+WPUPCAX001|Configureer AX.25 TNC||
+WPUPCAX002|AX.25 device naam||
+#
+# Interface device names
+IFDNL00000|Geen||
+IFDNL00001|Serieele TNC||
+IFDNL00002|Serieele TNC met GPS op een HSP kabel||
+IFDNL00003|Serieele GPS||
+IFDNL00004|Serieele WX||
+IFDNL00005|Internet server||
+IFDNL00006|AX25 TNC||
+IFDNL00007|Netwerk GPS (via gpsd)||
+IFDNL00008|Netwerk WX||
+IFDNL00009|Serieele TNC met GPS op een AUX kabel||
+IFDNL00010|Serieele KISS TNC||
+IFDNL00011|Database via netwerk (nog niet geimplementeerd)||
+IFDNL00012|AGWPE via Netwerk||
+IFDNL00013|Serieele Multi-Port KISS TNC||
+IFDNL00014|SQL Database (Experimental)||
+#
+# Interface device info
+IFDIN00000|%s %2d %s via serieel device %s   %s||
+IFDIN00001|%s %2d %s verbonden met %s:%d   %s||
+IFDIN00002|%s %2d %s gebruikt device genaamd %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006|INACTIEF ||
+IFDIN00007| ACTIEF  ||
+IFDIN00008|  FOUT   ||
+IFDIN00009|ONBEKENDE||
+#
+# PopUp "Interface control"
+IFPUPCT000|Interface Besturing||
+IFPUPCT001|Start||
+IFPUPCT002|Stop||
+IFPUPCT003|Start Alle||
+IFPUPCT004|Stop Alle||
+#
+# IGate control
+IGPUPCF000|IGate Opties||
+IGPUPCF001|Schakel al het IGate verkeer uit||
+IGPUPCF002|Sta ALLEEN RF naar Inet verkeer toe||
+IGPUPCF003|Sta RF->Inet en Inet->RF verkeer toe||
+IGPUPCF004|IGate -> RF Path   ||
+#
+# WX Station
+WXPUPSI000|WX station||
+WXPUPSI001|WX station type||
+WXPUPSI002|Huidige gegevens||
+WXPUPSI003|Wind koers||
+WXPUPSI004|Wind snelheid||
+WXPUPSI005|Wind piek||
+WXPUPSI006|Temp||
+WXPUPSI007|Regen totaal||
+WXPUPSI008|Regen dag totaal||
+WXPUPSI009|Baro||
+WXPUPSI010|Vochtigheid||
+WXPUPSI011|Peet Bros ULTIMETER 2000 Type (in gegevens logmode)||
+WXPUPSI012|Peet Bros ULTIMETER II Type||
+WXPUPSI013|Peet Bros ULTIMETER 2000 Type (in packet mode)||
+WXPUPSI014|Regen huidig uur tot.||
+WXPUPSI015|Regen laatste 24uur tot.||
+WXPUPSI016|Qualimetrics Q-Net||
+WXPUPSI017|Peet Bros ULTIMETER 2000 Type (complete mode)||
+WXPUPSI018|Dauw punt||
+WXPUPSI019|Wind piek||
+WXPUPSI020|Wind koude gevoel||
+WXPUPSI021|Warmte index||
+WXPUPSI022|3-Uur Baro||
+WXPUPSI023|Max Temp.||
+WXPUPSI024|Min Temp.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Station Lists
+LHPUPNI000|Alle stations||
+LHPUPNI001|Mobiele stations||
+LHPUPNI002|Weer stations||
+LHPUPNI003|Lokale stations (via TNC)||
+LHPUPNI004|Laatste stations||
+LHPUPNI005|Objecten & Items||
+LHPUPNI006|Eigen Objecten & Items||
+LHPUPNI010|#||
+LHPUPNI011|Roepnaam||
+LHPUPNI012|#Comprimeer||
+LHPUPNI013|Pos Tijd||
+LHPUPNI014|Pad||
+LHPUPNI015|PHG||
+LHPUPNI016|Commentaar||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Breedte gr||
+LHPUPNI104|Lengte gr||
+LHPUPNI105|#Comprimeer||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Breedte/Lengte of UTM||
+#
+# Maps WX Alert styles
+PULDNMAT01|Waarschuwings kaarten boven de andere||
+PULDNMAT02|Waarschuwings kaarten onder de andere||
+#
+# Error/popup messages
+POPEM00001|Lokaliseer fout!||
+POPEM00002|Station %s is niet gevonden!||
+POPEM00003|Spoor-volg fout!||
+POPEM00004|Interface fout!||
+POPEM00005|Ongeldige AX.25 poort naam %s||
+POPEM00006|Ongeldige AX.25 poort naam %s||
+POPEM00007|Ongeldige roepnaam %s||
+POPEM00008|Ongeldige AX.25 doeladres roepnaam of digipeater||
+POPEM00009|Kan AX.25 socket niet openen, %s||
+POPEM00010|Kan AX.25 socket niet binden, %s||
+POPEM00011|Kan geen verbinding met AX.25 roepnaam maken, %s||
+POPEM00012|AX.25 fout bij uitvoer van UI||
+POPEM00013|AX.25 probleem met axports bestand||
+POPEM00014|AX.25 ongeldige poort naam %s||
+POPEM00015|Fout bij het openen van interface %d hardware Fout||
+POPEM00016|Fout bij het openen interface %d Time Out||
+POPEM00017|Geen interfaces meer beschikbaar!||
+POPEM00018|Gegevens Aanvraag - Enkele Bericht Regel||
+POPEM00019|Verzenden is uit voor poort %d||
+POPEM00020|Database Fout!||
+POPEM00021|AX.25 ondersteunig is niet mee gecompileerd in deze Xastir Versie!||
+POPEM00022|Invoer Fout!||
+POPEM00023|Geen lokatie naam gegeven!||
+POPEM00024|Gegeven lokatie naam is in gebruik!||
+POPEM00025|Niet gevonden!||
+POPEM00026|Volgen begint op het moment van verschijnen||
+POPEM00027|Incorrecte gegevens.  Zijn er velden leeg?||
+POPEM00028|Kan bestand niet openen||
+POPEM00029|Gevonden!||
+POPEM00030|Weer station symbool||
+POPEM00031|Veranderd in WX symbool '/_', andere opties:  '\_'  '/W'  and  '\W'||
+POPEM00032|Waarschuwing: gebruik nationaal weer service symbool!||
+POPEM00033|Geen GPS gegevens!||
+POPEM00034|Zet Mijn Positie TX uit totdat geldige GPS gegevens beschikbaar zijn!||
+POPEM00035|Waarschuwing||
+POPEM00036|Let op||
+POPEM00037|HSP interface aanwezig: GPS timing is verhoogd||
+POPEM00038|Naam komt overeen met bestaand Object/Item/Station||
+POPEM00039|Niet toegestane tekens gevonden, deze worden door punten vervangen||
+POPEM00040|Handmatig ingestelde uitgaande route is verloren gegaan||
+POPEM00041|Bezig met een ander bestand te bewerken.  Wacht even en probeer opnieuw||
+POPEM00042|Niet een eigen object! Probeer het object eerst over te nemen.||
+POPEM00043|Geen Object/Item!||
+POPEM00044|Opzoeken in Findu database: Mislukt||
+POPEM00045|Opzoeken in Findu database: Gereed||
+POPEM00046|Berkeley DB headers en gedeelde bibliotheek komen niet overeen! Kaart cache uitgeschakeld.||
+POPEM00047|Global transmit is DISABLED. Emergency beacons are NOT going out!||
+POPEM00048|Emergency Beacon Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmitting every 60 seconds!||
+POPEM00050|Interfaces or posits/transmits DISABLED.  Emergency beacons are NOT going out!||
+POPEM00051|Altnet is enabled (Configure->Defaults dialog)||
+POPEM00052|Callsign is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We're trying to talk to ourselves!||
+#
+# Jump Location
+JMLPO00001|Kaart lokatie||
+JMLPO00002|GA!||
+JMLPO00003|Nieuwe lokatie naam:||
+#
+# Bulletins
+BULMW00001|Bulletins||
+BULMW00002|Beperk reikwijdte tot (0, is geen limiet)||
+BULMW00003|Verander reikwijdte||
+#
+# All Message Traffic
+AMTMW00001|Alle berichten verkeer||
+AMTMW00002|Beperk reikwijdte tot (0, is geen limiet)||
+#
+# Speech Strings
+SPCHSTR001|kilometers||
+SPCHSTR002|meters||
+SPCHSTR003|mijl||
+SPCHSTR004|yards||
+SPCHSTR005|%s, afstand is %d %s.||
+SPCHSTR006|%s, afstand is %.1f %s.||
+SPCHSTR007|%s, afstand is %d %s %s %s.||
+SPCHSTR008|%s, afstand is %.1f %s %s %s.||
+SPCHSTR009|Nieuwe weer waarschuwing||
+SPCHSTR010|Nieuwe roepnaam||
+SPCHSTR011|Gehoord, D X, %s, op een afstand van %.1f %s||
+#
+#
+SPCHDIRN00|ten noorden van||
+SPCHDIRS00|ten zuiden van||
+SPCHDIRE00|ten oosten van||
+SPCHDIRW00|ten westen van||
+SPCHDIRNE0|ten noordoosten van||
+SPCHDIRNW0|ten noordwesten van||
+SPCHDIRSE0|ten zuidoosten van||
+SPCHDIRSW0|ten zuidwesten van||
+#
+# Symbol Selection Dialog
+SYMSEL0001|Selecteer symbool||
+SYMSEL0002|Primaire symbolen Databank||
+SYMSEL0003|Secondaire symbolen Databank||
+#
+# Print Properties Dialog
+PRINT0001|Print eigenschappen||
+PRINT0002|Papier formaat||
+PRINT0003|Draai beeld automatisch||
+PRINT0004|Draai beeld 90. CCW||
+PRINT0005|Pas schaal beeld automatisch aan||
+PRINT0006|Schaal:||
+PRINT0007|Forceer standaard witte achtergrondkleur||
+PRINT0008|Print in Zwart/Wit||
+PRINT0016|Inverteer kleuren||
+PRINT0009|Postscript resolutie:||
+PRINT0010|Voorbeeld||
+PRINT0011|Print naar bestand||
+PRINT0012|Bezig met printen naar bestand...||
+PRINT0013|Converteren naar postscript...||
+PRINT0014|Gereed met aanmaken print bestand||
+PRINT0015|Printer status||
+#
+# Print Properties Dialog
+PRINT1001|Direct to:||
+PRINT1002|Via Previewer:||
+#
+# Locate Feature Dialog
+FEATURE001|Naam:||
+FEATURE002|Provincie:||
+FEATURE003|Land:||
+FEATURE004|Kaart quadrant:||
+FEATURE005|Type:||
+FEATURE006|GNIS Bestand:||
+FEATURE007|Adres:||
+FEATURE008|City:||
+FEATURE009|Mark Destination||
+FEATURE010|Zip Code:||
+FEATURE011|Geocoding Bestand||
+#
+# Coordinate Calculator Dialog
+COORD001|Coordinaten berekening||
+COORD002|Bereken||
+COORD003|Bereken||
+COORD004|Wis||
+COORD005|UTM||
+COORD006|Breedtegraden of||
+COORD007|Lengtegraden of||
+COORD008|Zone||
+COORD009|UTM Oostelijk||
+COORD010|UTM Noordelijk||
+COORD011|               Decimale graden:  ||
+COORD012|       Graden/Decimale minuten:  ||
+COORD013|  Graden/Minuten/Dec. seconden:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|    Militair Referentie raster:  ||
+COORD016|     Maidenhead lokatie raster:  ||
+COORD017| **         Sorry, uw invoer is niet herkend!          **||
+COORD018| **   Gebruik een van onderstaande invoer formaten:    **||
+#
+#
+# Smart Beaconing Dialog
+SMARTB001|Smart Beaconing||
+SMARTB002|Hoge Waarde (secs):||
+SMARTB003|Hoge Snelheid (mph):||
+SMARTB004|Hoge Snelheid (kph):||
+SMARTB005|Lage Waarde (mins):||
+SMARTB006|Lage Snelheid (mph):||
+SMARTB007|Lage Snelheid (kph):||
+SMARTB008|Minimale Draaiing (deg):||
+SMARTB009|Draai Hoek:||
+SMARTB010|Wacht Tijd (secs):||
+SMARTB011|Schakel SmartBeaconing in(tm)||
+#
+#
+#
+# Gamma Adjust Dialog
+GAMMA001|Stel Gamma Correctie bij||
+GAMMA002|Gamma Correctie||
+#
+#
+# 
+# Map labels font Dialog
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Font Miniem||
+MAPFONT004|Map Font Klein||
+MAPFONT005|Map Font Gemiddeld||
+MAPFONT006|Map Font Groot||
+MAPFONT007|Map Font Enorm||
+MAPFONT008|Map Font Border||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV Font ID||
+#
+#
+#
+# Distance/Bearing on status line
+PULDNDB001|Afst/Richting Status||
+#
+#
+# GPS Transfer Operations
+GPS001|GPS overdracht||
+GPS002|Bestandsnaam||
+GPS003|Selecteer kleur||
+GPS004|Rood||
+GPS005|Groen||
+GPS006|Zwart||
+GPS007|Wit||
+GPS008|Oranje||
+GPS009|Blauw||
+GPS010|Geel||
+GPS011|Violet||
+#
+#
+# Map Properties Dialog
+MAPP001|Kaart eigenschappen||
+MAPP002|Max   Min   Kaart  Teken USGS Auto||
+MAPP003|Zoom  Zoom  Laag Vulling DRG  Kaart Path/Bestandsnaam||
+MAPP004|Verander Laag->||
+MAPP005|Vulling->||
+MAPP006|Ja||
+MAPP007|Nee||
+MAPP008|AutoKaart->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+#
+# Time Strings
+TIME001|Dag||
+TIME002|Dagen||
+TIME003|Uur||
+TIME004|Uren||
+TIME005|Minuut||
+TIME006|Minuten||
+TIME007|Seconde||
+TIME008|Secondes||
+#
+#
+# Map Caching
+CACHE001|Kaart in cache||
+CACHE002|Kaart uit cache laden||
+CACHE003|Kaart niet in cache gevonden...||
+#
+#
+# Map Screen Misc
+RANGE001|BEREIK SCHAAL||
+#
+#
+# GPS Status
+GPSS001|WAAS of PPS||
+GPSS002|DGPS||
+GPSS003|Geldig SPS||
+GPSS004|Ongeldig||
+GPSS005|Sats/beeld||
+GPSS006|Repareer||
+GPSS007|!GPS data is ouder dan 30 seconden!||
+GPSS008|Simulatie||
+GPSS009|Handmatig||
+GPSS010|Ingeschat op||
+GPSS011|Float RTK||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data
+CADPUD001|Area Object||
+CADPUD002|Area Label:||
+CADPUD003|Opmerking:||
+CADPUD004|Waarschijnlijkheid (%):||
+CADPUD005|OK||
+CADPUD006|CAD Dialog||
+CADPUD007|Toon/Bewerk details||
+CADPUD008|Afbreken||
+CADPUD009|Wis CAD objecten?||
+CADPUD010|Wis alles||
+CADPUD011|Wis selectie||
+CADPUD012|Solid||
+CADPUD013|Dashed||
+CADPUD014|Double Dash||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|XASTIR Map of %s (upper left) to %s (lower right).  UTM %d m grid, %s datum. ||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA002|XASTIR Map of %s (upper left) to %s %s (lower right).  Lat/Long grid, %s datum.||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA003|XASTIR Map of %s (upper left) to %s (lower right).  UTM zones, %s datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST002|Postgreql with Postgis||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Xastir Simple Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA02|Xastir CAD Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA03|Xastir full Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/language-ElmerFudd.sys b/config/language-ElmerFudd.sys
new file mode 100644
index 0000000..33470db
--- /dev/null
+++ b/config/language-ElmerFudd.sys
@@ -0,0 +1,1143 @@
+# language-ElmerFudd.sys, translated from language-English.sys
+# Please do not edit this derived file.
+MENUTB0001|Fiwe|F|
+MENUTB0002|View|V|
+MENUTB0004|Map|M|
+MENUTB0005|Station|S|
+MENUTB0006|Message|e|
+MENUTB0010|Intewface|I|
+MENUTB0009|Hewp|H|
+PULDNFI001|Configuwe|C|
+PULDNFI002|Open Wog Fiwe|O|
+PULDNFI003|Test|T|
+PULDNFI004|Exit|x|
+PULDNFI007|Change Debug Wevew|D|
+PULDNFI010|TNC Wogging||
+PULDNFI011|Net Wogging||
+PULDNFI012|IGate Wogging||
+PULDNFI013|WX Wogging||
+PULDNFI014|PNG Snapshots||
+PULDNFI015|Pwint|P|
+PULDNFI016|KMW Snapshots||
+PULDNVI001|Buwwetins|B|
+PULDNVI002|Incoming Data|I|
+PULDNVI003|Mobiwe Stations|M|
+PULDNVI004|Aww Stations|A|
+PULDNVI009|Wocaw Stations|S|
+PULDNVI012|Wast Stations|L|
+PULDNVI005|Weadew Stations|W|
+PULDNVI008|Own Weadew Data|D|
+PULDNVI007|Weadew Awewts|e|
+PULDNVI011|Message Twaffic|T|
+PULDNVI013|Uptime|U|
+PULDNVI014|Pwogwam Uptime||
+PULDNVI015|GPS Status||
+PULDNVI016|AWOHA Statistics||
+PULDNCF004|Station|S|
+PULDNCF001|Defauwts|D|
+PULDNCF003|Timing|T|
+PULDNCF002|Coowdinate System|o|
+PULDNCF006|Audio Awawms|A|
+PULDNCF007|Speech|p|
+PULDNCF008|Save Config Now!|C|
+PULDNMP001|Map Choosew|M|
+PULDNMP012|Map Dispway Bookmawks|B|
+PULDNMP014|Wocate Map Featuwe|F|
+PULDNMP016|Disabwe Fast Zoom/Pan/Home||
+PULDNMP013|Disabwe Aww Maps||
+PULDNMP002|Enabwe Auto Maps||
+PULDNMP003|Enabwe Map Gwid||
+PULDNMP004|Enabwe Map Wevews||
+PULDNMP010|Enabwe Map Wabews||
+PULDNMP009|Enabwe Awea Cowow Fiwws||
+PULDNMP007|Enabwe Weadew Awewts||
+PULDNMP005|Backgwound Cowow|C|
+PULDNMP006|Station Text Stywe|T|
+PULDNMP026|Icon Outwine Stywe|O|
+PULDNMP011|Mouse Pointew Menu|P|
+PULDNMP008|Map Intensity|I|
+PULDNMP020|Configuwe Tigewmap||
+PULDNMP021|Auto Map - Disabwe Wastew Maps||
+PULDNMP022|Index New Maps on Stawtup||
+PULDNMP023|Index: Add New Maps|N|
+PULDNMP024|Index: Weindex AWW Maps!|R|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsew||
+PULDNMP027|We-downwoad Maps (Not fwom cache)||
+PULDNMP028|Fwush Entiwe Map Cache!||
+PULDNMP029|Find Addwess||
+PULDNMP030|Configuwe USGS DWG||
+PULDNMP031|Enabwe Map Bowdew||
+MPUPTGR001|Gwid||
+MPUPTGR002|Counties||
+MPUPTGR003|City Wabews||
+MPUPTGR004|Uwban Aweas||
+MPUPTGR005|Majow Woads||
+MPUPTGR006|Stweets||
+MPUPTGR007|Waiwwoads||
+MPUPTGR008|State Wabews||
+MPUPTGR009|Intewstate Wabews||
+MPUPTGR010|US Hwy Wabews||
+MPUPTGR011|State Hwy Wabews||
+MPUPTGR012|Sewect items to be dispwayed:||
+MPUPTGR013|Wivews||
+MPUPTGR014|Wakes||
+MPUPTGR015|Aiwpowts, Pawks, etc||
+MPUPTGR016|Map Intensity||
+MPUPTGR017|Intewnet Map Timeout (sec)||
+MPUPTGR018|Enabwe Tigew Maps||
+MPUPDRG001|Sewect items to be dispwayed:||
+MPUPDRG002|Tint Undewwying Map (XOW)||
+MPUPDRG003|Bwack||
+MPUPDRG004|White||
+MPUPDRG005|Bwue||
+MPUPDRG006|Wed||
+MPUPDRG007|Bwown||
+MPUPDRG008|Gween||
+MPUPDRG009|Puwpwe||
+MPUPDRG010|Yewwow||
+MPUPDRG011|Wight Bwue||
+MPUPDRG012|Wight Wed||
+MPUPDRG013|Wight Puwpwe||
+MPUPDRG014|Wight Gway||
+MPUPDRG015|Wight Bwown||
+WPUPMCP001|Map Choosew||
+PULDNMMC01|Cweaw|C|
+PULDNMMC02|Vectow|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Expand Diws||
+PULDNMMC07|Diws/Maps Sewected:||
+PULDNMMC08|Cweaw Diws|C
+PULDNMMC09|Sewect Aww|S|
+PULDNMBC01|Gway||
+PULDNMBC02|Misty Wose||
+PULDNMBC03|Navy Bwue||
+PULDNMBC04|Steew Bwue||
+PULDNMBC05|Med. Sea Gween||
+PULDNMBC06|Pawe Gween||
+PULDNMBC07|Pawe Gowdenwod||
+PULDNMBC08|Gowdenwod Yewwow||
+PULDNMBC09|Wosy Bwown||
+PULDNMBC10|Fiwe bwick Wed||
+PULDNMBC11|White||
+PULDNMBC12|Bwack||
+PULDNMSL01|Bwack Bowdew|B|
+PULDNMSL02|Bwack Shadow|S|
+PULDNMSL03|Text on Bwack|T|
+PULDNMIO01|No Outwine|N|
+PULDNMIO02|Bwack Outwine|B|
+PULDNMIO03|Gwey Outwine|G|
+PULDNMIO04|White Outwine|W|
+PULDNOT001|On||
+PULDNOT002|Off||
+PULDNOT003|Showt||
+PULDNDP014|Find Station|F|
+PULDNDP001|Twack Station|T|
+PULDNDP022|Fetch Findu Twaiw|u|
+PULDNDP032|Fiwtew Data||
+PULDNDP040|Sewect None||
+PULDNDP041|Sewect Mine||
+PULDNDP042|Sewect TNC||
+PULDNDP027|- Sewect Diwect||
+PULDNDP043|- Sewect Via Digi||
+PULDNDP034|Sewect Net||
+PULDNDP019|Incwude Expiwed Data||
+PULDNDP044|Sewect Stations||
+PULDNDP028|- Sewect Fixed Stations||
+PULDNDP029|- Sewect Moving Stations||
+PULDNDP030|- Sewect WX Stations||
+PULDNDP053|  - Sewect CWOP WX Stations||
+PULDNDP045|Sewect Objects/Items||
+PULDNDP026|- Sewect WX Objects/Items||
+PULDNDP039|- Sewect Watew Gauge Objects/Items||
+PULDNDP031|- Sewect Odew Objects/Items||
+PULDNDP033|Fiwtew Dispway||
+PULDNDP010|Dispway Cawwsign||
+PULDNDP012|Dispway Symbow||
+PULDNDP011|- Wotate Symbow||
+PULDNDP007|Dispway Twaiw||
+PULDNDP003|Dispway Couwse||
+PULDNDP004|Dispway Speed|S|
+PULDNDP017|- Dispway Showt Speed||
+PULDNDP002|Dispway Awtitude||
+PULDNDP009|Dispway Weadew Info||
+PULDNDP046|- Dispway Weadew Text||
+PULDNDP018|-- Tempewatuwe Onwy||
+PULDNDP047|- Dispway Wind Bawb||
+PULDNDP054|Dispway Awoha Ciwcwe||
+PULDNDP013|Dispway Position Ambiguity||
+PULDNDP008|Dispway Powew/Gain||
+PULDNDP021|- Use Defauwt Powew/Gain||
+PULDNDP020|- Dispway Mobiwe Powew/Gain||
+PULDNDP023|Dispway DF Attwibutes||
+PULDNDP123|Dispway DF Beamwidf||
+PULDNDP223|Dispway DF Beawing||
+PULDNDP035|Enabwe Dead-Weckoning||
+PULDNDP036|- Dispway Awc||
+PULDNDP037|- Dispway Couwse||
+PULDNDP038|- Dispway Symbow||
+PULDNDP005|Dispway Dist/Beawing||
+PULDNDP024|Dispway Wast Wepowt Age||
+PULDNDP015|Cweaw Aww Stations!!!|A|
+PULDNDP016|Cweaw Aww Twaiws!!!|C|
+PULDNDP025|Cweaw Object/Item Histowy||
+PULDNDP048|Wewoad Object/Item Histowy||
+PULDNDP049|Cweaw Aww Tacticaw Cawws||
+PULDNDP050|Cweaw Tacticaw Caww Histowy||
+PULDNDP051|Sewect Tacticaw Cawws Onwy||
+PULDNDP052|- Wabew Twaiwpoints||
+PULDNDP055|Expowt aww|E|
+PULDNDP056|Expowt to KMW Fiwe||
+PULDNUT001|Enabwe Engwish Units|E|
+PULDNUT002|Metwic|M|
+PULDNMG001|Send Message To|S|
+PULDNMG002|Open Gwoup Messages|O|
+PULDNMG003|Cweaw Aww Outgoing Messages|C|
+PULDQUS001|Genewaw Stations Qwewy|G|
+PULDQUS002|IGate Stations Qwewy|I|
+PULDQUS003|WX Stations Qwewy|W|
+PULDNMG004|Modify Auto Wepwy Message|A|
+PULDNMG005|Enabwe Auto Wepwy Message||
+PULDNMG006|Satewwite Ack Mode|M|
+PULDNMG007|Show Pending Messages|P|
+PULDNTNT04|Intewface Contwow|C|
+PULDNTNT03|Disabwe Twansmit: AWW||
+PULDNTNT05|Disabwe Twansmit: My Position||
+PULDNTNT06|Disabwe Twansmit: Objects/Items||
+PULDNTNT11|Enabwe Sewvew Powts|P|
+PULDNTNT01|Twansmit Now!|T|
+PULDNTNT07|Fetch GPS Twack|F|
+PULDNTNT08|Fetch GPS Woutes|R|
+PULDNTNT09|Fetch GPS Waypoints|W|
+PULDNTNT10|Fetch Gawmin WINO Waypoints|G|
+PULDNHEL01|About|A|
+PULDNHEL02|Hewp Index|I|
+PULDNHEL03|EMEWGENCY BEACON MODE ENABWE|E|
+PULDNHEL04|!!! EMEWGENCY BEACON MODE !!!||
+PULDNHEL05|About Xastiw||
+POPUPMA001|Options||
+POPUPMA00c|Centew|C|
+POPUPMA015|Station Info|S|
+POPUPMA002|In|I|
+POPUPMA003|Out|O|
+POPUPMA004|Zoom Wevew|L|
+POPUPMA005|Wevew 1|1|
+POPUPMA006|Wevew 16|6|
+POPUPMA007|Wevew 64|4|
+POPUPMA008|Wevew 256|2|
+POPUPMA009|Wevew 1024|0|
+POPUPMA010|Wevew 8192|8|
+POPUPMA017|Entiwe Wowwd|E|
+POPUPMA016|Wast Map Pos/Zoom|P|
+POPUPMA018|Object/Item->Cweate|b|
+POPUPMA019|Object/Item->Modify|M|
+POPUPMA025|Move My Station Hewe|H|
+POPUPMA011|Pan up|u|
+POPUPMA012|Pan down|d|
+POPUPMA013|Pan weft|l|
+POPUPMA014|Pan wight|r|
+POPUPMA020|Measuwe||
+POPUPMA021|Move||
+POPUPMA022|TwackMe||
+POPUPMA023|Modifiews Found!||
+POPUPMA024|Pwease tuwn OFF CapsWock/NumWock/ScwowwWock/odew modifiews||
+POPUPMA026|Centew & Zoom||
+POPUPMA027|  Watitude||
+POPUPMA028| Wongitude||
+POPUPMA029|Dwaw CAD Objects||
+POPUPMA030|Dwaw||
+POPUPMA031|Cwose Powygon||
+POPUPMA032|Ewase CAD Powygons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Wevew||
+POPUPMA035|10% out||
+POPUPMA036|10% in||
+POPUPMA037|Awea||
+POPUPMA038|sqwawe||
+POPUPMA039|sqwawe feet||
+POPUPMA040|sqwawe metews||
+POPUPMA041|Beawing||
+POPUPMA042|degwees||
+POPUPMA043|Modify ambiguous position||
+POPUPMA044|Position ambiguity is on, youw new position may appeaw to jump.||
+POPUPMA045|Pwedefined Objects||
+POPUPMA046|CAD Powygons||
+POPUPMA047|Enabwe CAD objects||
+POPUPMA048|Enabwe CAD wabews||
+POPUPMA049|Enabwe CAD comments||
+POPUPMA050|Enabwe CAD pwobabiwity||
+POPUPMA051|Enabwe CAD awea size||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|metews||
+POPUPMA055|mi|
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Tw||
+BBARSTH001|%d/%d Stations||
+BBARSTA000|%-9s New object!||
+BBARSTA001|%-9s New station!||
+BBARSTA002|%-9s||# new data (only display the call)
+BBARSTA003|Woading Maps...||
+BBARSTA004|Maps Woaded||
+BBARSTA005|Map Wat/Wong Gwid On|O|
+BBARSTA006|Map Wat/Wong Gwid Off|f|
+BBARSTA007|De use of Auto Maps, is now ON||
+BBARSTA008|De use of Auto Maps, is now OFF||
+BBARSTA009|De use of Map Wevews is now ON||
+BBARSTA010|De use of Map Wevews is now OFF||
+BBARSTA011|Auto Wepwy Message OFF!||
+BBARSTA012|Fiwe done..||
+BBARSTA013|Opening GPS Powt||
+BBARSTA014|Cwosing GPS Powt||
+BBARSTA015|Got GPS WMC Stwing||
+BBARSTA016|Got GPS GGA Stwing||
+BBARSTA017|Net disconnected fwom host||
+BBARSTA018|Net connection timed out!||
+BBARSTA019|Wooking up host %s||
+BBARSTA020|Connected to %s||
+BBARSTA021|Net Connection Faiwed!||
+BBARSTA022|Couwd not bind socket!||
+BBARSTA023|No IP fow Host!||
+BBARSTA024|No Host Specified||
+BBARSTA025|Host found, Connecting %d||
+BBARSTA026|Waiting fow GPS data via HSP..||
+BBARSTA027|Cweawing HSP getting TNC data..||
+BBARSTA028|Woading %s||
+BBARSTA029|Opening WX Powt||
+BBARSTA030|Cwosing WX Powt||
+BBARSTA031|Wooking up hostname %d||
+BBARSTA032|Decoded WX Data||
+BBARSTA033|Echo fwom digipeatew||
+BBARSTA034|Woading Weadew Awewt Maps||
+BBARSTA035|Waiting fow GPS data via AUX..||
+BBARSTA036|Cweawing AUX getting TNC data..||
+BBARSTA037|GPS Data Compwete||
+BBARSTA038|Position change on my station||
+BBARSTA039|Indexing %s||
+BBARSTA040|Amateuw APWS(tm) Station %s||
+BBARSTA041|Waiting fow GPS data..||
+BBARSTA042|Twansmitting objects/items||
+BBARSTA043|Wogging||
+BBARSTA044|AWOHA distance is %d%s||
+BBARSTA045|Woading symbows...||
+BBARSTA046|Wewoading symbows...||
+BBARSTA047|Initiawize my station, uh-hah-hah-hah...||
+BBARSTA048|Stawt intewfaces...||
+BBARSTA049|Weading tiwes...||
+BBARSTA050|Downwoading tiwes...||
+BBARSTA051|Downwoading tiwe %wi of %wi||
+WPUPDPD001|Dispway Packet Data||
+WPUPDPD002|TNC Data onwy|T|
+WPUPDPD003|Net Data onwy|N|
+WPUPDPD004|TNC and Net Data|a|
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Station Capabiwities||
+WPUPDPD008|Mine Onwy||
+WPUPLSP001|Wocate Station||
+WPUPLSP002|Wocate Cawwsign||
+WPUPLSP003|Match Case|C|
+WPUPLSP004|Match Exact|E|
+WPUPLSP005|Wocate Now!|N|
+WPUPLSP006|Emewgency Wocate!||
+WPUPLSP007|FCC/WAC Wookup||
+WPUPCFD001|Configuwe Defauwts||
+WPUPCFD002|Aftew what intewvaw of time wiww a station be considewed owd?||
+WPUPCFD003|15 min|1|
+WPUPCFD004|30 min|3|
+WPUPCFD005|45 min|4|
+WPUPCFD006|1 hw|H|
+WPUPCFD007|90 min|9|
+WPUPCFD008|2 hws|2|
+WPUPCFD009|Aftew what intewvaw of time wiww a station not be dispwayed?||
+WPUPCFD010|6 hws|6|
+WPUPCFD011|12 hws|o|
+WPUPCFD012|1 Day|D|
+WPUPCFD013|2 Days|y|
+WPUPCFD014|1 Week|W|
+WPUPCFD015|Twansmit Station Option||
+WPUPCFD016|Fixed Station|F|
+WPUPCFD017|Mobiwe Station w/wocaw time|l|
+WPUPCFD018|Mobiwe Station w/Zuwu date-time|Z|
+WPUPCFD019|Mobiwe Station w/Zuwu time-seconds|u|
+WPUPCFD021|Station Position w/weadew|S|
+WPUPCFD022|Station Position, Zuwu date-time, and weadew|t|
+WPUPCFD023|Twansmit Waw WX data?|R|
+WPUPCFD024|Twansmit compwessed objects/items?|C|
+WPUPCFD025|Activate Awtewnate net?|A|
+WPUPCFD026|Send position wepowts at what intewvaws?||
+WPUPCFD027|Pop up new buwwetins||
+WPUPCFD028|Wawn if Modifiew Keys||
+WPUPCFD029|View zewo-distance buwwetins||
+WPUPCFD030|Disabwe Posit Dupe-Checks||
+WPUPCFD031|Woad pwedefined objects fwom fiwe||
+WPUPCFD032|My twaiws in one cowow||
+WPUPCFD033|AWTNET:||
+WPUPCFTM01|Configuwe Timing||
+WPUPCFTM02|Posit TX Intewvaw (min)||
+WPUPCFTM03|Station Ghosting Time (min)||
+WPUPCFTM04|Object/Item Max TX Intewvaw (min)||
+WPUPCFTM05|Station Cweaw Time (houws)||
+WPUPCFTM06|GPS Check Intewvaw (sec)||
+WPUPCFTM07|Station Dewete Time (days)||
+WPUPCFTM08|Dead-Weckoning Timeout (min)||
+WPUPCFTM09|Sewiaw Intew-Chaw Deway (ms)||
+WPUPCFTM10|New Twack Time (min)||
+WPUPCFTM11|New Twack Intewvaw (degwees)||
+WPUPCFTM12|WINO -> Objects Intewvaw (min), 0 = Disabwed||
+WPUPCFTM13|Snapshot Intewvaw (min)||
+WPUPCFC001|Configuwe Coowdinate System||
+WPUPCFC002|Sewect Coowdinate System||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGWS2||
+WPUPCFC008|UTM w/speciaw zones||
+WPUPCFG001|Configuwe GPS||
+WPUPCFG003|Stand awone GPS powt||
+WPUPCFG002|Use GPS Position?||
+WPUPCFG004|GPS Options||
+WPUPCFG005|Stand-awone GPS||
+WPUPCFG006|TNC Connected GPS (HSP Cabwe)||
+WPUPCFG007|TNC Connected GPS using CTW-E||
+WPUPCFG008|GPS Time (Sampwe evewy)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 min||
+WPUPCFG013|2 min||
+WPUPCFG014|5 min||
+WPUPCFG015|10 min||
+WPUPCFG016|Netwowk Connected GPS||
+WPUPCFG017|GPSD Host||
+WPUPCFG018|GPSD Powt||
+WPUPCFG019|Netwowk GPS via GPSD||
+WPUPCFG020|Weconnect on faiwuwe?||
+WPUPCFG021|Netwowk Connected WX||
+WPUPCFG022|WX Host||
+WPUPCFG023|WX Powt||
+WPUPCFT001|Configuwe TNC||
+WPUPCFT002|Use TNC?||
+WPUPCFT003|TNC Powt||
+WPUPCFT004|Powt Settings||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|UnPwoto Pads||
+WPUPCFT012|Paf 1: %s via ||
+WPUPCFT013|Paf 2: %s via ||
+WPUPCFT014|Paf 3: %s via ||
+WPUPCFT015|Powt Stywe||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Configuwe TNC w/HSP GPS||
+WPUPCFT024|Data Type||
+WPUPCFT025|Auto detect||
+WPUPCFT026|Binawy Type||
+WPUPCFT027|ASCII Type||
+WPUPCFT028|Configuwe TNC w/AUX GPS||
+WPUPCFT029|Configuwe TNC w/INVAWID ENUM||
+WPUPCFT030|Configuwe KISS TNC||
+WPUPCFT031|TNC Configuwation Fiwes||
+WPUPCFT032|TNC Setup Fiwename|| 
+WPUPCFT033|TNC Shutdown Fiwename||
+WPUPCFT034|KISS Pawametews||
+WPUPCFT035|TXDeway (10 ms units)||
+WPUPCFT036|Pewsistence (0 to 255)||
+WPUPCFT037|SwotTime (10 ms units)||
+WPUPCFT038|TxTaiw (10 ms units)||
+WPUPCFT039|Fuww Dupwex||
+WPUPCFT040|Configuwe Muwti-Powt KISS TNC||
+WPUPCFT041|Wadio Powt||
+WPUPCFT042|Intewface Pwopewties: Dubious UNPWOTO Paf!||
+WPUPCFT043|Pwease considew a showtew paf such as WIDE2-2 ow WIDE1-1,WIDE2-2||
+WPUPCFT044|Intewface Pwopewties: Dubious IGATE Paf!||
+WPUPCFT045|Twansmitting w/Dubious UNPWOTO Paf!||
+WPUPCFT046|Twansmitting w/Dubious IGATE Paf!||
+WPUPCFT047|Init KISS-mode on stawtup||
+WPUPCFWX01|Configuwe WX Powt||
+WPUPCFWX02|Weadew Station device||
+WPUPCFWX03|Wain Gauge Cowwection (Gwobaw Setting)||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|No Cowwection||
+WPUPCFS001|Configuwe Station||
+WPUPCFS002|Cawwsign||
+WPUPCFS003|WAT||
+WPUPCFS004|deg||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|WONG||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Station Symbow||
+WPUPCFS010|Gwoup/ovewway||
+WPUPCFS011|Symbow||
+WPUPCFS028|Sewect||
+WPUPCFS012|Powew - Height (HAAT) - Gain - Diwectivity||
+WPUPCFS013|Disabwe PHG||
+WPUPCFS014|Antenna Height||
+WPUPCFS015|Antenna Gain||
+WPUPCFS016|Omni||
+WPUPCFS017|Comment:||
+WPUPCFS018|Position Ambiguity||
+WPUPCFS019|None||
+WPUPCFS020|.11 miwes||
+WPUPCFS021|1.15 miwes||
+WPUPCFS022|11.51 miwes||
+WPUPCFS023|69.09 miwes||
+WPUPCFS024|.18 kiwometwes||
+WPUPCFS025|1.85 kiwometwes||
+WPUPCFS026|18.53 kiwometwes||
+WPUPCFS027|111.19 kiwometwes||
+WPUPCFS029|Send compwessed posits|C|
+POPUPOB001|Object/Item||
+POPUPOB002|Name:||
+POPUPOB003|Cweate New Object||
+POPUPOB004|Dewete Object||
+POPUPOB005|Modify Object||
+POPUPOB006|Cweate New Item||
+POPUPOB007|Awea Object||
+POPUPOB008|Awea Object||
+POPUPOB009|Bwight Cowow||
+POPUPOB010|Cowow-Fiww||
+POPUPOB011|Ciwcwe||
+POPUPOB012|Wine-Wight '/'||
+POPUPOB013|Wine-Weft '\'||
+POPUPOB014|Twiangwe||
+POPUPOB015|Wectangwe||
+POPUPOB016|Bwack||
+POPUPOB017|Bwue||
+POPUPOB018|Gween||
+POPUPOB019|Cyan||
+POPUPOB020|Wed||
+POPUPOB021|Viowet||
+POPUPOB022|Yewwow||
+POPUPOB023|Gwey||
+POPUPOB024|Offset Up:||
+POPUPOB025|Offset Weft (Except '/'):||
+POPUPOB026|Cowwidow:||
+POPUPOB027|Genewic Options||
+POPUPOB028|Wocation||
+POPUPOB029|Signpost||
+POPUPOB030|Signpost Text||
+POPUPOB031|Signpost Object||
+POPUPOB032|Enabwe Compwession||
+POPUPOB033|Dewete Item||
+POPUPOB034|Modify Item||
+POPUPOB035|Awtitude (ft):||
+POPUPOB036|Speed (knots):||
+POPUPOB037|Couwse:||
+POPUPOB038|DF Object||
+POPUPOB039|Signaw - Height(HAAT) - Gain - Diwectivity||
+POPUPOB040|Beam Widf - Beawing||
+POPUPOB041|Omni Antenna||
+POPUPOB042|Beam Antenna||
+POPUPOB043|Usewess||
+POPUPOB044|Adopt Object||
+POPUPOB045|Adopt Item||
+POPUPOB046|DF Beawing:||
+POPUPOB047|Pwobabiwity Ciwcwes||
+POPUPOB048|Map View Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+WPUPCFI001|Configuwe Intewnet||
+WPUPCFI002|Host ||
+WPUPCFI003|Powt ||
+WPUPCFI004|(Secondawy hosts)||
+WPUPCFI005|Host1||
+WPUPCFI006|Powt1||
+WPUPCFI007|Host2||
+WPUPCFI008|Powt2||
+WPUPCFI009|Pass-code||
+WPUPCFI010|(Weave Bwank if None)||
+WPUPCFI011|Weconnect on NET faiwuwe?||
+WPUPCFI012|Wun as an I-Gate?||
+WPUPCFI013|Bwoadcast messages via TNC when an I-Gate?||
+WPUPCFI014|Wog I-Gate Twansactions?||
+WPUPCFI015|Fiwtew Pawametews||
+WPUPCFID01|Configuwe Database (TBD)||
+WPUPCFID02|Host ||
+WPUPCFID03|Powt ||
+WPUPCFID04|(Secondawy hosts)||
+WPUPCFID05|Host1||
+WPUPCFID06|Powt1||
+WPUPCFID07|Host2||
+WPUPCFID08|Powt2||
+WPUPCFID09|Pass-code||
+WPUPCFID10|(Weave Bwank if None)||
+WPUPCFID11|Weconnect on NET faiwuwe?||
+WPUPCFID12|Wun as an I-Gate?||
+WPUPCFID13|Bwoadcast messages via TNC when an I-Gate?||
+WPUPCFID14|Wog I-Gate Twansactions?||
+WPUPCFID15|Fiwtew Pawametews||
+WPUPCFIA01|Configuwe AGWPE||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Powt ||
+WPUPCFIA04|(Secondawy hosts)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Powt1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Powt2||
+WPUPCFIA09|Pass-code||
+WPUPCFIA10|(Weave Bwank if None)||
+WPUPCFIA11|Weconnect on NET faiwuwe?||
+WPUPCFIA12|Wun as an I-Gate?||
+WPUPCFIA13|Bwoadcast messages via TNC when an I-Gate?||
+WPUPCFIA14|Wog I-Gate Twansactions?||
+WPUPCFIA15|Twansmit WadioPowt||
+WPUPCFA001|Configuwe Audio Awawms||
+WPUPCFA002|Audio Pway Command||
+WPUPCFA003|Awawm on||
+WPUPCFA004|Audio fiwe to Pway||
+WPUPCFA005|New Station||
+WPUPCFA006|New Message||
+WPUPCFA007|Pwoximity||
+WPUPCFA008|Band Opening||
+WPUPCFA009|Minimum Distance||
+WPUPCFA010|Maximum Distance||
+WPUPCFA011|Weadew Awewt||
+WPUPCFSP01|Configuwe Speech||
+WPUPCFSP02|Speech Output on:||
+WPUPCFSP03|New Station||
+WPUPCFSP04|New Message Awewt||
+WPUPCFSP05|New Message Body||
+WPUPCFSP06|Pwoximity Awewt||
+WPUPCFSP07|Band Opening||
+WPUPCFSP08|New Weadew Awewt||
+WPUPCFSP09|Twacked Station Pwoximity Awewt||
+WPUPTSP001|Twack Station|| 
+WPUPTSP002|Twack Cawwsign|| 
+WPUPTSP003|Match Case|| 
+WPUPTSP004|Match Exact|| 
+WPUPTSP005|Twack Now!|| 
+WPUPTSP006|Cweaw Twacking|| 
+WPUPTSP007|Downwoad Twaiw||
+WPUPTSP008|Cawwsign||
+WPUPTSP009|Stawt Twaiw (hws ago)||
+WPUPTSP010|Twaiw Wengf (hws)||
+WPUPMSB001|Send Message Box %d||
+WPUPMSB002|Send Gwoup Message Box %d||
+WPUPMSB003|Station's Caww:||
+WPUPMSB004|Gwoup's Caww:||
+WPUPMSB005|New/Wefwesh Caww||
+WPUPMSB006|New Gwoup||
+WPUPMSB007|Cweaw Msg Histowy||
+WPUPMSB008|Message:||
+WPUPMSB009|Send Now!||
+WPUPMSB010|Paf:||
+WPUPMSB011|Cancew Pending Msgs||
+WPUPMSB012|Kick Timew||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Bwoadcast||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCEWWED*||
+WPUPMSB018|*WEJECTED*||
+WPUPMSB019|Change Paf||
+WPUPMSB020|Use Defauwt Paf(s)||
+WPUPMSB021|Diwect (No paf)||
+WPUPMSB022|Wevewse Paf (Hint):||
+WPUPARM001|Change Auto Wepwy||
+WPUPARM002|Wepwy:||
+WPUPHPI001|Hewp Index||
+WPUPHPI002|View||
+WPUPSTI000|Object fwom: %s||
+WPUPSTI001|Station Info||
+WPUPSTI002|Send Message||
+WPUPSTI003|Seawch FCC Database||
+WPUPSTI004|Seawch WAC Database||
+WPUPSTI005|Packets weceived: %d     Wast Heawd: ||
+WPUPSTI006|Heawd via de TNC on device %d, ||
+WPUPSTI007|Heawd ||
+WPUPSTI008|wast via Wocaw||
+WPUPSTI009|wast via TNC on device %d||
+WPUPSTI010|wast via Intewnet on device %d||
+WPUPSTI011|wast via Fiwe||
+WPUPSTI012|wast via Unknown||
+WPUPSTI013|, and has moved||
+WPUPSTI014|Cuwwent Powew Gain:||
+WPUPSTI016|Awtitude: %.0f%s ||
+WPUPSTI017|Couwse: %s� ||
+WPUPSTI018|Speed: %.1f km/h||
+WPUPSTI019|Speed: %.1f mph||
+WPUPSTI020|%0.1f miwes||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distance fwom my station: %s  Beawing fwom my station: %s||
+WPUPSTI023|Wast Position: ||
+WPUPSTI024|Weadew Data %c:%s||
+WPUPSTI025|Wind Couwse: %s�    Speed: %03d km/h||
+WPUPSTI026|Wind Couwse: %s�    Speed: %s mph||
+WPUPSTI027|   Gust: %03d km/h||
+WPUPSTI028|   Gust: %s mph||
+WPUPSTI029|Tempewatuwe: %02.1f�C  ||
+WPUPSTI030|Tempewatuwe: %s�F   ||
+WPUPSTI031|Humidity: %s%%   ||
+WPUPSTI032| Humidex: %02.1f�C  ||
+WPUPSTI033|Bawo: %s hPa||
+WPUPSTI034|Snow: %0.1f (cm/24h)||
+WPUPSTI035|Snow: %0.0f (inch/24h)||
+WPUPSTI036|Wain: ||
+WPUPSTI037|%0.2f (mm/h)    ||
+WPUPSTI038|%0.2f (inch/h)  ||
+WPUPSTI039|%0.2f (mm/day)     ||
+WPUPSTI040|%0.2f (inch/day)  ||
+WPUPSTI041|%0.2f (mm/since midnight)||
+WPUPSTI042|%0.2f (inch/since midnight)||
+WPUPSTI043|Data paf: %s||
+WPUPSTI044|Comment %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Cweaw Twack||
+WPUPSTI046|Totaw Wain: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (inch)||
+WPUPSTI049|Twace Qwewy||
+WPUPSTI050|Un-Acked Messages Qwewy||
+WPUPSTI051|Diwect Stations Qwewy||
+WPUPSTI052|Station Vewsion Qwewy||
+WPUPSTI053|Modify Object/Item||
+WPUPSTI054|Stowe Twack||
+WPUPSTI055|Echoed fwom:||
+WPUPSTI056|Enabwe Automatic Updates||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|DF Beawing: %s||
+WPUPSTI059|Status  %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Fuew Temp: %02.1f�C  ||
+WPUPSTI061|Fuew Temp: %s�F   ||
+WPUPSTI062|Fuew Moistuwe: %s%%   ||
+WPUPSTI063|Bawo: %0.2f in Hg||
+WPUPSTI064|Fetch NWS Awewt||
+WPUPSTI065|Tacticaw Caww: %s||
+WPUPSTI066|Assign Tacticaw Caww||
+WPUPSTI067|Cuwwent Wange: %d miwes||
+WPUPSTI068|none||
+WPUPSTI069|defauwt||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|wange||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Wange||
+WPUPSTI076|No signaw detected||
+WPUPSTI077|Detectibwe signaw (Maybe)||
+WPUPSTI078|Detectibwe signaw but not copyabwe)||
+WPUPSTI079|Weak signaw, mawginawwy weadabwe||
+WPUPSTI080|Noisy but copyabwe signaw||
+WPUPSTI081|Some noise, easy to copy signaw||
+WPUPSTI082|Good signaw w/detectibwe noise||
+WPUPSTI083|Neaw fuww-qwieting signaw||
+WPUPSTI084|Fuww-qwieting signaw||
+WPUPSTI085|Extwemewy stwong & fuww-qwieting signaw||
+WPUPSTI086|BAD BEAWING||
+WPUPSTI087|BAD NWQ||
+WPUPSTI088|DF Beamwidf||
+WPUPSTI089|DF Wengf||
+WPUPSTI090|Not Vawid||
+WPUPSTI091|Change Twaiw Cowow||
+WPUPSTI092|Cweaw DF Beawing||
+WPUPALO001|AWOHA wadius: %d %s||
+WPUPALO002|Stations inside AWOHA ciwcwe: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiwes (in motion): %d||
+WPUPALO005| Mobiwes (odew):     %d||
+WPUPALO006| WX stations:         %d||
+WPUPALO007| Home stations:       %d||
+WPUPALO008|Wast cawcuwated %d %s %d %s ago.||
+WPUPALO666|AWOHA wadius not cawcuwated yet||
+STIFCC0001|FCC Database Wookup||
+STIFCC0002|WAC Database Wookup||
+STIFCC0003|Name:||
+STIFCC0004|Stweet:||
+STIFCC0005|City:||
+STIFCC0006|State:||
+STIFCC0007|Zip:||
+STIFCC0008|Basic ||
+STIFCC0009|Advanced ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+STIFCC0100|FCC index owd, webuiwding||
+STIFCC0101|Cawwsign Seawch||
+STIFCC0102|Cawwsign Not Found!||
+STIFCC0103|WAC index owd, webuiwding||
+UMBNDO0001|at distance of||
+UNIOP00001|OK||
+UNIOP00002|Cancew||
+UNIOP00003|Cwose||
+UNIOP00004|miwes||
+UNIOP00005|km||
+UNIOP00006|Device||
+UNIOP00007|Add||
+UNIOP00008|Dewete||
+UNIOP00009|Pwopewties||
+UNIOP00010|Awwow Twansmitting?||
+UNIOP00011|Activate on Stawtup?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|inch||
+UNIOP00018|mm/day||
+UNIOP00019|inch/day||
+UNIOP00020|mm/hw||
+UNIOP00021|inch/hw||
+UNIOP00022|mm/mid||
+UNIOP00023|inch/mid||
+UNIOP00024|deg||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|in Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Set System Cwock fwom GPS Data?||
+UNIOP00030|Digipeat?||
+UNIOP00031|m||
+UNIOP00032|Appwy||
+UNIOP00033|Weset||
+UNIOP00034|min||
+UNIOP00035|hw||
+UNIOP00036|day||
+UNIOP00037|Send Contwow-E to get GPS data?||
+UNIOP00038|Add Deway||
+STCHO00001|Station Choosew||
+WPUPWXA001|Wx Awewts||
+WPUPWXA002|Wx Awewt Wist||
+WPUPCIF001|Instawwed Intewfaces||
+WPUPCIF002|Choose Intewface Type||
+WPUPCAX001|Configuwe AX.25 TNC||
+WPUPCAX002|AX.25 Device name||
+IFDNL00000|None||
+IFDNL00001|Sewiaw TNC||
+IFDNL00002|Sewiaw TNC w/GPS on a HSP cabwe||
+IFDNL00003|Sewiaw GPS||
+IFDNL00004|Sewiaw WX||
+IFDNL00005|Intewnet Sewvew||
+IFDNL00006|AX25 TNC||
+IFDNL00007|Netwowked GPS (via gpsd)||
+IFDNL00008|Netwowked WX||
+IFDNL00009|Sewiaw TNC w/GPS on AUX powt||
+IFDNL00010|Sewiaw KISS TNC||
+IFDNL00011|Netwowked Database (Not Impwemented Yet)||
+IFDNL00012|Netwowked AGWPE||
+IFDNL00013|Sewiaw Muwti-Powt KISS TNC||
+IFDNL00014|SQW Database (Expewimentaw)||
+IFDIN00000|%s %2d %s %s   %s||
+IFDIN00001|%s %2d %s %s:%d   %s||
+IFDIN00002|%s %2d %s device %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006| DOWN ||
+IFDIN00007|  UP  ||
+IFDIN00008|EWWOW ||
+IFDIN00009|UNKNWN||
+IFPUPCT000|Intewface Contwow||
+IFPUPCT001|Stawt||
+IFPUPCT002|Stop||
+IFPUPCT003|Stawt Aww||
+IFPUPCT004|Stop Aww||
+IGPUPCF000|IGate Options||
+IGPUPCF001|Disabwe aww IGate twaffic||
+IGPUPCF002|Awwow WF to Inet twaffic ONWY||
+IGPUPCF003|Awwow WF->Inet and Inet->WF twaffic||
+IGPUPCF004|Igate -> WF Paf   ||
+WXPUPSI000|WX Station||
+WXPUPSI001|WX Station Type||
+WXPUPSI002|Cuwwent Data||
+WXPUPSI003|Wind Couwse||
+WXPUPSI004|Wind Speed||
+WXPUPSI005|Wind Gust||
+WXPUPSI006|Temp||
+WXPUPSI007|Totaw Wain||
+WXPUPSI008|Today's Wain Totaw||
+WXPUPSI009|Bawo||
+WXPUPSI010|Humidity||
+WXPUPSI011|Peet Bwos UWTIMETEW 2000 Type (Data Wogging Mode)||
+WXPUPSI012|Peet Bwos UWTIMETEW II Type||
+WXPUPSI013|Peet Bwos UWTIMETEW 2000 Type (Packet Mode)||
+WXPUPSI014|Cuwwent HW Wain Tot.||
+WXPUPSI015|Wast 24 Wain Totaw||
+WXPUPSI016|Qwawimetwics Q-Net||
+WXPUPSI017|Peet Bwos UWTIMETEW 2000 Type (Compwete Mode)||
+WXPUPSI018|Dew Point||
+WXPUPSI019|High Wind||
+WXPUPSI020|Wind Chiww||
+WXPUPSI021|Heat Index||
+WXPUPSI022|3-Hw Bawo||
+WXPUPSI023|High Temp.||
+WXPUPSI024|Wow Temp.||
+WXPUPSI025|Wadio Shack WX-200/Owegon Scientific WM-918||
+WXPUPSI026|Davis Weadew Monitow II/Wizawd III/Vantage Pwo||
+WXPUPSI027|WaCwosse WX-23xx||
+WXPUPSI028|Davis APWS Data Woggew||
+LHPUPNI000|Aww Stations||
+LHPUPNI001|Mobiwe Stations||
+LHPUPNI002|Weadew Stations||
+LHPUPNI003|Wocaw Stations (via TNC)||
+LHPUPNI004|Wast Stations||
+LHPUPNI005|Objects & Items||
+LHPUPNI006|Own Objects & Items||
+LHPUPNI010|#||
+LHPUPNI011|Caww Sign||
+LHPUPNI012|#Pack||
+LHPUPNI013|Pos Time||
+LHPUPNI014|Paf||
+LHPUPNI015|PHG||
+LHPUPNI016|Comments||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|AWT.||
+LHPUPNI103|Wat||
+LHPUPNI104|Wong||
+LHPUPNI105|#Pack||
+LHPUPNI106|WSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Bawo||
+LHPUPNI206|WN-H||
+LHPUPNI207|WNSM||
+LHPUPNI208|WN24||
+LHPUPNI209|Wat/Won ow UTM||
+PULDNMAT01|Show Awewt maps above odew maps||
+PULDNMAT02|Show Awewt maps undew odew maps||
+POPEM00001|Wocate Ewwow!||
+POPEM00002|Station %s was not found!||
+POPEM00003|Twacking Ewwow!||
+POPEM00004|Intewface Ewwow!||
+POPEM00005|Invawid AX.25 powt name %s||
+POPEM00006|Invawid AX.25 powt name %s||
+POPEM00007|Invawid cawwsign %s||
+POPEM00008|Invawid AX.25 destination cawwsign ow digipeatew||
+POPEM00009|Cannot open AX.25 socket, %s||
+POPEM00010|Cannot bind AX.25 socket, %s||
+POPEM00011|Cannot connect to AX.25 cawwsign, %s||
+POPEM00012|AX.25 ewwow on output of UI||
+POPEM00013|AX.25 pwobwem wif axpowts fiwe||
+POPEM00014|AX.25 invawid powt name %s||
+POPEM00015|Ewwow opening intewface %d Hawd Faiw||
+POPEM00016|Ewwow opening intewface %d Time Out||
+POPEM00017|No mowe intewfaces Avaiwabwe!||
+POPEM00018|Data Qwewy - Singwe Message Wine||
+POPEM00019|Powt twansmitting is off fow powt %d||
+POPEM00020|Database Ewwow!||
+POPEM00021|AX.25 suppowt not compiwed into Xastiw!||
+POPEM00022|Input Ewwow!||
+POPEM00023|No wocation name specified!||
+POPEM00024|Wocation name specified is in use!||
+POPEM00025|Not Found!||
+POPEM00026|Twacking wiww commence when it appeaws||
+POPEM00027|Impwopew info.  Some fiewds empty?||
+POPEM00028|Can't open fiwe||
+POPEM00029|Found It!||
+POPEM00030|Weadew Station Symbow||
+POPEM00031|Changed to WX symbow '/_', odew options:  '\_'  '/W'  and  '\W'||
+POPEM00032|Wawning: Using Nationaw Weadew Sewvice Symbow!||
+POPEM00033|No GPS Data!||
+POPEM00034|Disabwing My Position TX Untiw Vawid GPS Data!||
+POPEM00035|Wawning||
+POPEM00036|Notice||
+POPEM00037|HSP intewface pwesent: GPS timing has been incweased||
+POPEM00038|Name Confwicts Wif Existing Object/Item/Station||
+POPEM00039|Iwwegaw chawactews found, substituting pewiods in deiw pwace||
+POPEM00040|Custom outgoing paf was wost||
+POPEM00041|Pwocessing anodew fiwe.  Wait a bit, den twy again||
+POPEM00042|Object not owned by me! Twy adopting de object fiwst.||
+POPEM00043|Not an Object/Item!||
+POPEM00044|Fetch Findu Twaiw: Faiwed||
+POPEM00045|Fetch Findu Twaiw: Compwete||
+POPEM00046|Bewkewey DB headew/shawed wibwawy do NOT match! Disabwing map cache.||
+POPEM00047|Gwobaw twansmit is DISABWED. Emewgency beacons awe NOT going out!||
+POPEM00048|Emewgency Beacon Mode!||
+POPEM00049|EMEWGENCY BEACON MODE, twansmitting evewy 60 seconds!||
+POPEM00050|Intewfaces ow posits/twansmits DISABWED.  Emewgency beacons awe NOT going out!||
+POPEM00051|Awtnet is enabwed (Configuwe->Defauwts diawog)||
+POPEM00052|Cawwsign is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We'we twying to tawk to ouwsewves!||
+JMLPO00001|Map Dispway Bookmawks||
+JMLPO00002|Activate!||
+JMLPO00003|New Name:||
+BULMW00001|Buwwetins||
+BULMW00002|Wimit Wange to (0, is no wimit)||
+BULMW00003|Change Wange||
+AMTMW00001|Aww Message Twaffic||
+AMTMW00002|Wimit Wange to (0, is no wimit)||
+SPCHSTR001|kiwometews||
+SPCHSTR002|metews||
+SPCHSTR003|miwes||
+SPCHSTR004|yawds||
+SPCHSTR005|%s, distance is %d %s.||
+SPCHSTR006|%s, distance is %.1f %s.||
+SPCHSTR007|%s, distance is %d %s %s %s.||
+SPCHSTR008|%s, distance is %.1f %s %s %s.||
+SPCHSTR009|New Weadew Awewt||
+SPCHSTR010|New Station||
+SPCHSTR011|Heawd, D X, %s, at distance of %.1f %s||
+SPCHDIRN00|nowf of||
+SPCHDIRS00|souf of||
+SPCHDIRE00|east of||
+SPCHDIRW00|west of||
+SPCHDIRNE0|nowdeast of||
+SPCHDIRNW0|nowdwest of||
+SPCHDIRSE0|soudeast of||
+SPCHDIRSW0|soudwest of||
+SYMSEL0001|Sewect Symbow||
+SYMSEL0002|Pwimawy Symbow Tabwe||
+SYMSEL0003|Secondawy Symbow Tabwe||
+PRINT0001|Pwint Pwopewties||
+PRINT0002|Papew Size||
+PRINT0003|Auto-Wotate Image||
+PRINT0004|Wotate Image 90� CCW||
+PRINT0005|Auto-Scawe Image||
+PRINT0006|Scawe:||
+PRINT0007|Fowce defauwt backgwound cowow to white||
+PRINT0008|Pwint in Bwack and White||
+PRINT0016|Wevewse Cowows||
+PRINT0009|Postscwipt Wesowution:||
+PRINT0010|Pweview||
+PRINT0011|Pwint to Fiwe||
+PRINT0012|Dumping image to fiwe...||
+PRINT0013|Convewting to Postscwipt...||
+PRINT0014|Finished cweating pwint fiwe||
+PRINT0015|Pwint Status||
+PRINT1001|Diwect to:||
+PRINT1002|Via Pweviewew:||
+FEATURE001|Name:||
+FEATURE002|State/Pwovince:||
+FEATURE003|County:||
+FEATURE004|Map Qwad:||
+FEATURE005|Type:||
+FEATURE006|GNIS Fiwe:||
+FEATURE007|Addwess:||
+FEATURE008|City:||
+FEATURE009|Mawk Destination||
+FEATURE010|Zip Code:||
+FEATURE011|Geocoding Fiwe||
+COORD001|Coowdinate Cawcuwatow||
+COORD002|Cawc||
+COORD003|Cawcuwate||
+COORD004|Cweaw||
+COORD005|UTM||
+COORD006|Watitude ow||
+COORD007|Wongitude ow||
+COORD008|Zone||
+COORD009|UTM Easting||
+COORD010|UTM Nowding||
+COORD011|               Decimaw Degwees:  ||
+COORD012|       Degwees/Decimaw Minutes:  ||
+COORD013|  Degwees/Minutes/Dec. Seconds:  ||
+COORD014| Univewsaw Twansvewse Mewcatow:  ||
+COORD015|Miwitawy Gwid Wefewence System:  ||
+COORD016|       Maidenhead Gwid Wocatow:  ||
+COORD017| **       Sowwy, youw input was not wecognized!        **||
+COORD018| **   Pwease use one of de fowwowing input fowmats:   **||
+SMARTB001|Smawt Beaconing||
+SMARTB002|High Wate (secs):||
+SMARTB003|High Speed (mph):||
+SMARTB004|High Speed (kph):||
+SMARTB005|Wow Wate (mins):||
+SMARTB006|Wow Speed (mph):||
+SMARTB007|Wow Speed (kph):||
+SMARTB008|Minimum Tuwn (deg):||
+SMARTB009|Tuwn Swope:||
+SMARTB010|Wait Time (secs):||
+SMARTB011|Enabwe SmawtBeaconing(tm)||
+GAMMA001|Adjust Gamma Cowwection||
+GAMMA002|Gamma Cowwection||
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Font Tiny||
+MAPFONT004|Map Font Smaww||
+MAPFONT005|Map Font Medium||
+MAPFONT006|Map Font Wawge||
+MAPFONT007|Map Font Huge||
+MAPFONT008|Map Font Bowdew||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV ID Font||
+PULDNDB001|Dist/Beawing Status||
+GPS001|GPS Twansfew||
+GPS002|Fiwename||
+GPS003|Sewect Cowow||
+GPS004|Wed||
+GPS005|Gween||
+GPS006|Bwack||
+GPS007|White||
+GPS008|Owange||
+GPS009|Bwue||
+GPS010|Yewwow||
+GPS011|Viowet||
+MAPP001|Map Pwopewties||
+MAPP002|Max   Min    Map         USGS  Auto||
+MAPP003|Zoom  Zoom  Wayew  Fiww  DWG   Map   Paf/Fiwename||
+MAPP004|Change Wayew->||
+MAPP005|Fiwwed->||
+MAPP006|Yes||
+MAPP007|No||
+MAPP008|Automaps->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DWG->||
+TIME001|Day||
+TIME002|Days||
+TIME003|Houw||
+TIME004|Houws||
+TIME005|Minute||
+TIME006|Minutes||
+TIME007|Second||
+TIME008|Seconds||
+CACHE001|Map now cached||
+CACHE002|Woading Cached Map||
+CACHE003|Map not found in cache...||
+RANGE001|WANGE SCAWE||
+GPSS001|WAAS ow PPS||
+GPSS002|DGPS||
+GPSS003|Vawid SPS||
+GPSS004|Invawid||
+GPSS005|Sats/View||
+GPSS006|Fix||
+GPSS007|!GPS data is owdew dan 30 seconds!||
+GPSS008|Simuwation||
+GPSS009|Manuaw||
+GPSS010|Estimated||
+GPSS011|Fwoat WTK||
+GPSS012|WTK||
+CADPUD001|Awea Object||
+CADPUD002|Awea Wabew:||
+CADPUD003|Comment:||
+CADPUD004|Pwobabiwity (%):||
+CADPUD005|OK||
+CADPUD006|CAD Diawog||
+CADPUD007|Show/Edit Detaiws||
+CADPUD008|Cancew||
+CADPUD009|Dewete CAD objects?||
+CADPUD010|Dewete Aww||
+CADPUD011|Dewete Sewected||
+CADPUD012|Sowid||
+CADPUD013|Dashed||
+CADPUD014|Doubwe Dash||
+MDATA001|XASTIW Map of %s (uppew weft) to %s (wowew wight).  UTM %d m gwid, %s datum. ||
+MDATA002|XASTIW Map of %s (uppew weft) to %s %s (wowew wight).  Wat/Wong gwid, %s datum.||
+MDATA003|XASTIW Map of %s (uppew weft) to %s (wowew wight).  UTM zones, %s datum.||
+XADBMST001|MySQW (wat/wong)||
+XADBMST002|Postgweqw wif Postgis||
+XADBMST003|MySQW (spatiaw)||
+XASCHEMA01|Xastiw Simpwe Schema||
+XASCHEMA02|Xastiw CAD Schema||
+XASCHEMA03|Xastiw fuww Schema||
+XASCHEMA04|APWSWowwd Schema||
diff --git a/config/language-English.sys b/config/language-English.sys
new file mode 100644
index 0000000..b7b3d5c
--- /dev/null
+++ b/config/language-English.sys
@@ -0,0 +1,1352 @@
+# $Id: language-English.sys,v 1.228 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the English Language file used for all the prompts in xastir
+# 
+# Creator        : Frank Giannandrea <fgiannan at eazy.net >
+# Maintained by  : The Xastir Group <xastir at xastir.org>
+#
+# comment lines with pound signs in front are ignored
+# File format as follows:
+# ID (10 chars alpha+numeric)|(String associated with id)|QuickKeys|#comment
+# The ID is a unique uppercase char string for each block followed by a nummer
+#
+# WARNING:
+# Some strings contain formatting commands like %s and %d, you should not
+# change these. Wrong format strings could produce a segfault!
+#
+# Main Menu
+MENUTB0001|File|F|
+MENUTB0002|View|V|
+MENUTB0004|Map|M|
+MENUTB0005|Station|S|
+MENUTB0006|Message|e|
+MENUTB0010|Interface|I|
+MENUTB0009|Help|H|
+#
+# Menu "File"
+PULDNFI001|Configure|C|
+PULDNFI002|Open Log File|O|
+PULDNFI003|Test|T|
+PULDNFI004|Exit|x|
+PULDNFI007|Change Debug Level|D|
+PULDNFI010|TNC Logging||
+PULDNFI011|Net Logging||
+PULDNFI012|IGate Logging||
+PULDNFI013|WX Logging||
+PULDNFI014|PNG Snapshots||
+PULDNFI015|Print|P|
+PULDNFI016|KML Snapshots||
+#
+# Menu "View"
+PULDNVI001|Bulletins|B|
+PULDNVI002|Incoming Data|I|
+PULDNVI003|Mobile Stations|M|
+PULDNVI004|All Stations|A|
+PULDNVI009|Local Stations|S|
+PULDNVI012|Last Stations|L|
+PULDNVI005|Weather Stations|W|
+PULDNVI008|Own Weather Data|D|
+PULDNVI007|Weather Alerts|e|
+PULDNVI011|Message Traffic|T|
+PULDNVI013|Uptime|U|
+PULDNVI014|Program Uptime||
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statistics||
+#
+# Menu "Configure"
+PULDNCF004|Station|S|
+PULDNCF001|Defaults|D|
+PULDNCF003|Timing|T|
+PULDNCF002|Coordinate System|o|
+PULDNCF006|Audio Alarms|A|
+PULDNCF007|Speech|p|
+PULDNCF008|Save Config Now!|C|
+# (Units see PULDNDP006)
+#
+# Menu "Maps"
+PULDNMP001|Map Chooser|M|
+PULDNMP012|Map Display Bookmarks|B|
+PULDNMP014|Locate Map Feature|F|
+PULDNMP016|Disable Fast Zoom/Pan/Home||
+PULDNMP013|Disable All Maps||
+PULDNMP002|Enable Auto Maps||
+PULDNMP003|Enable Map Grid||
+PULDNMP004|Enable Map Levels||
+PULDNMP010|Enable Map Labels||
+PULDNMP009|Enable Area Color Fills||
+PULDNMP007|Enable Weather Alerts||
+PULDNMP005|Background Color|C|
+PULDNMP006|Station Text Style|T|
+PULDNMP026|Icon Outline Style|O|
+PULDNMP011|Mouse Pointer Menu|P|
+PULDNMP008|Map Intensity|I|
+PULDNMP020|Configure Tigermap||
+PULDNMP021|Auto Map - Disable Raster Maps||
+PULDNMP022|Index New Maps on Startup||
+PULDNMP023|Index: Add New Maps|N|
+PULDNMP024|Index: Reindex ALL Maps!|R|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsel||
+PULDNMP027|Re-download Maps (Not from cache)||
+PULDNMP028|Flush Entire Map Cache!||
+PULDNMP029|Find Address||
+PULDNMP030|Configure USGS DRG||
+PULDNMP031|Enable Map Border||
+#
+# PopUp "Configure Tigermap"
+MPUPTGR001|Grid||
+MPUPTGR002|Counties||
+MPUPTGR003|City Labels||
+MPUPTGR004|Urban Areas||
+MPUPTGR005|Major Roads||
+MPUPTGR006|Streets||
+MPUPTGR007|Railroads||
+MPUPTGR008|State Labels||
+MPUPTGR009|Interstate Labels||
+MPUPTGR010|US Hwy Labels||
+MPUPTGR011|State Hwy Labels||
+MPUPTGR012|Select items to be displayed:||
+MPUPTGR013|Rivers||
+MPUPTGR014|Lakes||
+MPUPTGR015|Airports, Parks, etc||
+MPUPTGR016|Map Intensity||
+MPUPTGR017|Internet Map Timeout (sec)||
+MPUPTGR018|Enable Tiger Maps||
+#
+# PopUp "Configure USGS DRG"
+MPUPDRG001|Select items to be displayed:||
+MPUPDRG002|Tint Underlying Map (XOR)||
+MPUPDRG003|Black||
+MPUPDRG004|White||
+MPUPDRG005|Blue||
+MPUPDRG006|Red||
+MPUPDRG007|Brown||
+MPUPDRG008|Green||
+MPUPDRG009|Purple||
+MPUPDRG010|Yellow||
+MPUPDRG011|Light Blue||
+MPUPDRG012|Light Red||
+MPUPDRG013|Light Purple||
+MPUPDRG014|Light Gray||
+MPUPDRG015|Light Brown||
+#
+# PopUp "Map Chooser"
+WPUPMCP001|Map Chooser||
+PULDNMMC01|Clear|C|
+PULDNMMC02|Vector|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Expand Dirs||
+PULDNMMC07|Dirs/Maps Selected:||
+PULDNMMC08|Clear Dirs|C
+PULDNMMC09|Select All|S|
+#
+# PullDown "Map Background Color"
+PULDNMBC01|Gray||
+PULDNMBC02|Misty Rose||
+PULDNMBC03|Navy Blue||
+PULDNMBC04|Steel Blue||
+PULDNMBC05|Med. Sea Green||
+PULDNMBC06|Pale Green||
+PULDNMBC07|Pale Goldenrod||
+PULDNMBC08|Goldenrod Yellow||
+PULDNMBC09|Rosy Brown||
+PULDNMBC10|Fire brick Red||
+PULDNMBC11|White||
+PULDNMBC12|Black||
+#
+# PullDown "Station text Style"
+PULDNMSL01|Black Border|B|
+PULDNMSL02|Black Shadow|S|
+PULDNMSL03|Text on Black|T|
+#
+# PullDown "Icon Outline Style"
+PULDNMIO01|No Outline|N|
+PULDNMIO02|Black Outline|B|
+PULDNMIO03|Grey Outline|G|
+PULDNMIO04|White Outline|W|
+#
+# Switches
+PULDNOT001|On||
+PULDNOT002|Off||
+PULDNOT003|Short||
+#
+# Menu "Stations"
+PULDNDP014|Find Station|F|
+PULDNDP001|Track Station|T|
+PULDNDP022|Fetch Findu Trail|u|
+PULDNDP032|Filter Data||
+PULDNDP040|Select None||
+PULDNDP041|Select Mine||
+PULDNDP042|Select TNC||
+PULDNDP027|- Select Direct||
+PULDNDP043|- Select Via Digi||
+PULDNDP034|Select Net||
+PULDNDP019|Include Expired Data||
+PULDNDP044|Select Stations||
+PULDNDP028|- Select Fixed Stations||
+PULDNDP029|- Select Moving Stations||
+PULDNDP030|- Select WX Stations||
+PULDNDP053|  - Select CWOP WX Stations||
+PULDNDP045|Select Objects/Items||
+PULDNDP026|- Select WX Objects/Items||
+PULDNDP039|- Select Water Gauge Objects/Items||
+PULDNDP031|- Select Other Objects/Items||
+PULDNDP033|Filter Display||
+PULDNDP010|Display Callsign||
+PULDNDP012|Display Symbol||
+PULDNDP011|- Rotate Symbol||
+PULDNDP007|Display Trail||
+PULDNDP003|Display Course||
+PULDNDP004|Display Speed|S|
+PULDNDP017|- Display Short Speed||
+PULDNDP002|Display Altitude||
+PULDNDP009|Display Weather Info||
+PULDNDP046|- Display Weather Text||
+PULDNDP018|-- Temperature Only||
+PULDNDP047|- Display Wind Barb||
+PULDNDP054|Display Aloha Circle||
+PULDNDP013|Display Position Ambiguity||
+PULDNDP008|Display Power/Gain||
+PULDNDP021|- Use Default Power/Gain||
+PULDNDP020|- Display Mobile Power/Gain||
+PULDNDP023|Display DF Attributes||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearing||
+PULDNDP035|Enable Dead-Reckoning||
+PULDNDP036|- Display Arc||
+PULDNDP037|- Display Course||
+PULDNDP038|- Display Symbol||
+PULDNDP005|Display Dist/Bearing||
+PULDNDP024|Display Last Report Age||
+PULDNDP015|Clear All Stations!!!|A|
+PULDNDP016|Clear All Trails!!!|C|
+PULDNDP025|Clear Object/Item History||
+PULDNDP048|Reload Object/Item History||
+PULDNDP049|Clear All Tactical Calls||
+PULDNDP050|Clear Tactical Call History||
+PULDNDP051|Select Tactical Calls Only||
+PULDNDP052|- Label Trailpoints||
+PULDNDP055|Export all|E|
+PULDNDP056|Export to KML File||
+#
+# Units
+PULDNUT001|Enable English Units|E|
+PULDNUT002|Metric|M|
+#
+# Menu "Messages"
+PULDNMG001|Send Message To|S|
+PULDNMG002|Open Group Messages|O|
+PULDNMG003|Clear All Outgoing Messages|C|
+PULDQUS001|General Stations Query|G|
+PULDQUS002|IGate Stations Query|I|
+PULDQUS003|WX Stations Query|W|
+PULDNMG004|Modify Auto Reply Message|A|
+PULDNMG005|Enable Auto Reply Message||
+PULDNMG006|Satellite Ack Mode|M|
+PULDNMG007|Show Pending Messages|P|
+#
+# Menu "Interfaces"
+PULDNTNT04|Interface Control|C|
+PULDNTNT03|Disable Transmit: ALL||
+PULDNTNT05|Disable Transmit: My Position||
+PULDNTNT06|Disable Transmit: Objects/Items||
+PULDNTNT11|Enable Server Ports|P|
+PULDNTNT01|Transmit Now!|T|
+PULDNTNT07|Fetch GPS Track|F|
+PULDNTNT08|Fetch GPS Routes|R|
+PULDNTNT09|Fetch GPS Waypoints|W|
+PULDNTNT10|Fetch Garmin RINO Waypoints|G|
+#
+# Menu "Help"
+PULDNHEL01|About|A|
+PULDNHEL02|Help Index|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|About Xastir||
+#
+#
+# Mouse Menu Popup
+POPUPMA001|Options||
+POPUPMA00c|Center|C|
+POPUPMA015|Station Info|S|
+POPUPMA002|In|I|
+POPUPMA003|Out|O|
+POPUPMA004|Zoom Level|L|
+POPUPMA005|Level 1|1|
+POPUPMA006|Level 16|6|
+POPUPMA007|Level 64|4|
+POPUPMA008|Level 256|2|
+POPUPMA009|Level 1024|0|
+POPUPMA010|Level 8192|8|
+POPUPMA017|Entire World|E|
+POPUPMA016|Last Map Pos/Zoom|P|
+POPUPMA018|Object/Item->Create|b|
+POPUPMA019|Object/Item->Modify|M|
+POPUPMA025|Move My Station Here|H|
+POPUPMA011|Pan up|u|
+POPUPMA012|Pan down|d|
+POPUPMA013|Pan left|l|
+POPUPMA014|Pan right|r|
+POPUPMA020|Measure||
+POPUPMA021|Move||
+POPUPMA022|TrackMe||
+POPUPMA023|Modifiers Found!||
+POPUPMA024|Please turn OFF CapsLock/NumLock/ScrollLock/other modifiers||
+POPUPMA026|Center & Zoom||
+POPUPMA027|  Latitude||
+POPUPMA028| Longitude||
+POPUPMA029|Draw CAD Objects||
+POPUPMA030|Draw||
+POPUPMA031|Close Polygon||
+POPUPMA032|Erase CAD Polygons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Level||
+POPUPMA035|10% out||
+POPUPMA036|10% in||
+POPUPMA037|Area||
+POPUPMA038|square||
+POPUPMA039|square feet||
+POPUPMA040|square meters||
+POPUPMA041|Bearing||
+POPUPMA042|degrees||
+POPUPMA043|Modify ambiguous position||
+POPUPMA044|Position ambiguity is on, your new position may appear to jump.||
+POPUPMA045|Predefined Objects||
+POPUPMA046|CAD Polygons||
+POPUPMA047|Enable CAD objects||
+POPUPMA048|Enable CAD labels||
+POPUPMA049|Enable CAD comments||
+POPUPMA050|Enable CAD probability||
+POPUPMA051|Enable CAD area size||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|meters||
+POPUPMA055|mi|
+#
+#
+# Status line labels
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Tr||
+BBARSTH001|%d/%d Stations||
+BBARSTA000|%-9s New object!||
+BBARSTA001|%-9s New station!||
+BBARSTA002|%-9s||# new data (only display the call)
+BBARSTA003|Loading Maps...||
+BBARSTA004|Maps Loaded||
+BBARSTA005|Map Lat/Long Grid On|O|
+BBARSTA006|Map Lat/Long Grid Off|f|
+BBARSTA007|The use of Auto Maps, is now ON||
+BBARSTA008|The use of Auto Maps, is now OFF||
+BBARSTA009|The use of Map Levels is now ON||
+BBARSTA010|The use of Map Levels is now OFF||
+BBARSTA011|Auto Reply Message OFF!||
+BBARSTA012|File done..||
+BBARSTA013|Opening GPS Port||
+BBARSTA014|Closing GPS Port||
+BBARSTA015|Got GPS RMC String||
+BBARSTA016|Got GPS GGA String||
+BBARSTA017|Net disconnected from host||
+BBARSTA018|Net connection timed out!||
+BBARSTA019|Looking up host %s||
+BBARSTA020|Connected to %s||
+BBARSTA021|Net Connection Failed!||
+BBARSTA022|Could not bind socket!||
+BBARSTA023|No IP for Host!||
+BBARSTA024|No Host Specified||
+BBARSTA025|Host found, Connecting %d||
+BBARSTA026|Waiting for GPS data via HSP..||
+BBARSTA027|Clearing HSP getting TNC data..||
+BBARSTA028|Loading %s||
+BBARSTA029|Opening WX Port||
+BBARSTA030|Closing WX Port||
+BBARSTA031|Looking up hostname %d||
+BBARSTA032|Decoded WX Data||
+BBARSTA033|Echo from digipeater||
+BBARSTA034|Loading Weather Alert Maps||
+BBARSTA035|Waiting for GPS data via AUX..||
+BBARSTA036|Clearing AUX getting TNC data..||
+BBARSTA037|GPS Data Complete||
+BBARSTA038|Position change on my station||
+BBARSTA039|Indexing %s||
+BBARSTA040|Amateur APRS(tm) Station %s||
+BBARSTA041|Waiting for GPS data..||
+BBARSTA042|Transmitting objects/items||
+BBARSTA043|Logging||
+BBARSTA044|ALOHA distance is %d%s||
+BBARSTA045|Loading symbols...||
+BBARSTA046|Reloading symbols...||
+BBARSTA047|Initialize my station...||
+BBARSTA048|Start interfaces...||
+BBARSTA049|Reading tiles...||
+BBARSTA050|Downloading tiles...||
+BBARSTA051|Downloading tile %li of %li||
+#
+#
+# PopUp "View - Incoming Packet Data"
+WPUPDPD001|Display Packet Data||
+WPUPDPD002|TNC Data only|T|
+WPUPDPD003|Net Data only|N|
+WPUPDPD004|TNC and Net Data|a|
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Station Capabilities||
+WPUPDPD008|Mine Only||
+#
+# PopUp "View - Find Station"
+WPUPLSP001|Locate Station||
+WPUPLSP002|Locate Callsign||
+WPUPLSP003|Match Case|C|
+WPUPLSP004|Match Exact|E|
+WPUPLSP005|Locate Now!|N|
+WPUPLSP006|Emergency Locate!||
+WPUPLSP007|FCC/RAC Lookup||
+#
+# PopUp "Configure - Defaults"
+WPUPCFD001|Configure Defaults||
+WPUPCFD002|After what interval of time will a station be considered old?||
+WPUPCFD003|15 min|1|
+WPUPCFD004|30 min|3|
+WPUPCFD005|45 min|4|
+WPUPCFD006|1 hr|H|
+WPUPCFD007|90 min|9|
+WPUPCFD008|2 hrs|2|
+WPUPCFD009|After what interval of time will a station not be displayed?||
+WPUPCFD010|6 hrs|6|
+WPUPCFD011|12 hrs|o|
+WPUPCFD012|1 Day|D|
+WPUPCFD013|2 Days|y|
+WPUPCFD014|1 Week|W|
+WPUPCFD015|Transmit Station Option||
+WPUPCFD016|Fixed Station|F|
+WPUPCFD017|Mobile Station w/local time|l|
+WPUPCFD018|Mobile Station w/Zulu date-time|Z|
+WPUPCFD019|Mobile Station w/Zulu time-seconds|u|
+WPUPCFD021|Station Position w/weather|S|
+WPUPCFD022|Station Position, Zulu date-time, and weather|t|
+WPUPCFD023|Transmit Raw WX data?|R|
+WPUPCFD024|Transmit compressed objects/items?|C|
+WPUPCFD025|Activate Alternate net?|A|
+WPUPCFD026|Send position reports at what intervals?||
+WPUPCFD027|Pop up new bulletins||
+WPUPCFD028|Warn if Modifier Keys||
+WPUPCFD029|View zero-distance bulletins||
+WPUPCFD030|Disable Posit Dupe-Checks||
+WPUPCFD031|Load predefined objects from file||
+WPUPCFD032|My trails in one color||
+WPUPCFD033|ALTNET:||
+#
+# PopUp "Configure - Timing"
+WPUPCFTM01|Configure Timing||
+WPUPCFTM02|Posit TX Interval (min)||
+WPUPCFTM03|Station Ghosting Time (min)||
+WPUPCFTM04|Object/Item Max TX Interval (min)||
+WPUPCFTM05|Station Clear Time (hours)||
+WPUPCFTM06|GPS Check Interval (sec)||
+WPUPCFTM07|Station Delete Time (days)||
+WPUPCFTM08|Dead-Reckoning Timeout (min)||
+WPUPCFTM09|Serial Inter-Char Delay (ms)||
+WPUPCFTM10|New Track Time (min)||
+WPUPCFTM11|New Track Interval (degrees)||
+WPUPCFTM12|RINO -> Objects Interval (min), 0 = Disabled||
+WPUPCFTM13|Snapshot Interval (min)||
+#
+# PopUp "Configure Coordinate System"
+WPUPCFC001|Configure Coordinate System||
+WPUPCFC002|Select Coordinate System||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM w/special zones||
+#
+# PopUp "Configure GPS"
+WPUPCFG001|Configure GPS||
+WPUPCFG003|Stand alone GPS port||
+WPUPCFG002|Use GPS Position?||
+WPUPCFG004|GPS Options||
+WPUPCFG005|Stand-alone GPS||
+WPUPCFG006|TNC Connected GPS (HSP Cable)||
+WPUPCFG007|TNC Connected GPS using CTL-E||
+WPUPCFG008|GPS Time (Sample every)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 min||
+WPUPCFG013|2 min||
+WPUPCFG014|5 min||
+WPUPCFG015|10 min||
+WPUPCFG016|Network Connected GPS||
+WPUPCFG017|GPSD Host||
+WPUPCFG018|GPSD Port||
+WPUPCFG019|Network GPS via GPSD||
+WPUPCFG020|Reconnect on failure?||
+WPUPCFG021|Network Connected WX||
+WPUPCFG022|WX Host||
+WPUPCFG023|WX Port||
+#
+# Configure TNC (baud/style are also for WX)
+WPUPCFT001|Configure TNC||
+WPUPCFT002|Use TNC?||
+WPUPCFT003|TNC Port||
+WPUPCFT004|Port Settings||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|UnProto Paths||
+WPUPCFT012|Path 1: %s via ||
+WPUPCFT013|Path 2: %s via ||
+WPUPCFT014|Path 3: %s via ||
+WPUPCFT015|Port Style||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Configure TNC w/HSP GPS||
+WPUPCFT024|Data Type||
+WPUPCFT025|Auto detect||
+WPUPCFT026|Binary Type||
+WPUPCFT027|ASCII Type||
+WPUPCFT028|Configure TNC w/AUX GPS||
+WPUPCFT029|Configure TNC w/INVALID ENUM||
+WPUPCFT030|Configure KISS TNC||
+WPUPCFT031|TNC Configuration Files||
+WPUPCFT032|TNC Setup Filename|| 
+WPUPCFT033|TNC Shutdown Filename||
+WPUPCFT034|KISS Parameters||
+WPUPCFT035|TXDelay (10 ms units)||
+WPUPCFT036|Persistence (0 to 255)||
+WPUPCFT037|SlotTime (10 ms units)||
+WPUPCFT038|TxTail (10 ms units)||
+WPUPCFT039|Full Duplex||
+WPUPCFT040|Configure Multi-Port KISS TNC||
+WPUPCFT041|Radio Port||
+WPUPCFT042|Interface Properties: Dubious UNPROTO Path!||
+WPUPCFT043|Please consider a shorter path such as WIDE2-2 or WIDE1-1,WIDE2-2||
+WPUPCFT044|Interface Properties: Dubious IGATE Path!||
+WPUPCFT045|Transmitting w/Dubious UNPROTO Path!||
+WPUPCFT046|Transmitting w/Dubious IGATE Path!||
+WPUPCFT047|Init KISS-mode on startup||
+#
+#
+# PopUp "Configure WX Port"
+WPUPCFWX01|Configure WX Port||
+WPUPCFWX02|Weather Station device||
+WPUPCFWX03|Rain Gauge Correction (Global Setting)||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|No Correction||
+#
+# PopUp "Configure - Station"
+WPUPCFS001|Configure Station||
+WPUPCFS002|Callsign||
+WPUPCFS003|LAT||
+WPUPCFS004|deg||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Station Symbol||
+WPUPCFS010|Group/overlay||
+WPUPCFS011|Symbol||
+WPUPCFS028|Select||
+WPUPCFS012|Power - Height (HAAT) - Gain - Directivity||
+WPUPCFS013|Disable PHG||
+WPUPCFS014|Antenna Height||
+WPUPCFS015|Antenna Gain||
+WPUPCFS016|Omni||
+WPUPCFS017|Comment:||
+WPUPCFS018|Position Ambiguity||
+WPUPCFS019|None||
+WPUPCFS020|.11 miles||
+WPUPCFS021|1.15 miles||
+WPUPCFS022|11.51 miles||
+WPUPCFS023|69.09 miles||
+WPUPCFS024|.18 kilometres||
+WPUPCFS025|1.85 kilometres||
+WPUPCFS026|18.53 kilometres||
+WPUPCFS027|111.19 kilometres||
+WPUPCFS029|Send compressed posits|C|
+#
+# PopUp "Object/Item"
+POPUPOB001|Object/Item||
+POPUPOB002|Name:||
+POPUPOB003|Create New Object||
+POPUPOB004|Delete Object||
+POPUPOB005|Modify Object||
+POPUPOB006|Create New Item||
+POPUPOB007|Area Object||
+POPUPOB008|Area Object||
+POPUPOB009|Bright Color||
+POPUPOB010|Color-Fill||
+POPUPOB011|Circle||
+POPUPOB012|Line-Right '/'||
+POPUPOB013|Line-Left '\'||
+POPUPOB014|Triangle||
+POPUPOB015|Rectangle||
+POPUPOB016|Black||
+POPUPOB017|Blue||
+POPUPOB018|Green||
+POPUPOB019|Cyan||
+POPUPOB020|Red||
+POPUPOB021|Violet||
+POPUPOB022|Yellow||
+POPUPOB023|Grey||
+POPUPOB024|Offset Up:||
+POPUPOB025|Offset Left (Except '/'):||
+POPUPOB026|Corridor:||
+POPUPOB027|Generic Options||
+POPUPOB028|Location||
+POPUPOB029|Signpost||
+POPUPOB030|Signpost Text||
+POPUPOB031|Signpost Object||
+POPUPOB032|Enable Compression||
+POPUPOB033|Delete Item||
+POPUPOB034|Modify Item||
+POPUPOB035|Altitude (ft):||
+POPUPOB036|Speed (knots):||
+POPUPOB037|Course:||
+POPUPOB038|DF Object||
+POPUPOB039|Signal - Height(HAAT) - Gain - Directivity||
+POPUPOB040|Beam Width - Bearing||
+POPUPOB041|Omni Antenna||
+POPUPOB042|Beam Antenna||
+POPUPOB043|Useless||
+POPUPOB044|Adopt Object||
+POPUPOB045|Adopt Item||
+POPUPOB046|DF Bearing:||
+POPUPOB047|Probability Circles||
+POPUPOB048|Map View Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+# PopUp "Configure Internet"
+WPUPCFI001|Configure Internet||
+WPUPCFI002|Host ||
+WPUPCFI003|Port ||
+WPUPCFI004|(Secondary hosts)||
+WPUPCFI005|Host1||
+WPUPCFI006|Port1||
+WPUPCFI007|Host2||
+WPUPCFI008|Port2||
+WPUPCFI009|Pass-code||
+WPUPCFI010|(Leave Blank if None)||
+WPUPCFI011|Reconnect on NET failure?||
+WPUPCFI012|Run as an I-Gate?||
+WPUPCFI013|Broadcast messages via TNC when an I-Gate?||
+WPUPCFI014|Log I-Gate Transactions?||
+WPUPCFI015|Filter Parameters||
+#
+# PopUp "Configure Database"
+WPUPCFID01|Configure Database (TBD)||
+WPUPCFID02|Host ||
+WPUPCFID03|Port ||
+WPUPCFID04|(Secondary hosts)||
+WPUPCFID05|Host1||
+WPUPCFID06|Port1||
+WPUPCFID07|Host2||
+WPUPCFID08|Port2||
+WPUPCFID09|Pass-code||
+WPUPCFID10|(Leave Blank if None)||
+WPUPCFID11|Reconnect on NET failure?||
+WPUPCFID12|Run as an I-Gate?||
+WPUPCFID13|Broadcast messages via TNC when an I-Gate?||
+WPUPCFID14|Log I-Gate Transactions?||
+WPUPCFID15|Filter Parameters||
+#
+# PopUp "Configure AGWPE"
+WPUPCFIA01|Configure AGWPE||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Port ||
+WPUPCFIA04|(Secondary hosts)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Port1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Port2||
+WPUPCFIA09|Pass-code||
+WPUPCFIA10|(Leave Blank if None)||
+WPUPCFIA11|Reconnect on NET failure?||
+WPUPCFIA12|Run as an I-Gate?||
+WPUPCFIA13|Broadcast messages via TNC when an I-Gate?||
+WPUPCFIA14|Log I-Gate Transactions?||
+WPUPCFIA15|Transmit RadioPort||
+#
+# PopUp "Configure Audio Alarms"
+WPUPCFA001|Configure Audio Alarms||
+WPUPCFA002|Audio Play Command||
+WPUPCFA003|Alarm on||
+WPUPCFA004|Audio file to Play||
+WPUPCFA005|New Station||
+WPUPCFA006|New Message||
+WPUPCFA007|Proximity||
+WPUPCFA008|Band Opening||
+WPUPCFA009|Minimum Distance||
+WPUPCFA010|Maximum Distance||
+WPUPCFA011|Weather Alert||
+#
+# PopUp "Configure Speech"
+WPUPCFSP01|Configure Speech||
+WPUPCFSP02|Speech Output on:||
+WPUPCFSP03|New Station||
+WPUPCFSP04|New Message Alert||
+WPUPCFSP05|New Message Body||
+WPUPCFSP06|Proximity Alert||
+WPUPCFSP07|Band Opening||
+WPUPCFSP08|New Weather Alert||
+WPUPCFSP09|Tracked Station Proximity Alert||
+#
+# PopUp "Track Station"
+WPUPTSP001|Track Station|| 
+WPUPTSP002|Track Callsign|| 
+WPUPTSP003|Match Case|| 
+WPUPTSP004|Match Exact|| 
+WPUPTSP005|Track Now!|| 
+WPUPTSP006|Clear Tracking|| 
+WPUPTSP007|Download Trail||
+WPUPTSP008|Callsign||
+WPUPTSP009|Start Trail (hrs ago)||
+WPUPTSP010|Trail Length (hrs)||
+#
+# PopUp "Messages..."
+WPUPMSB001|Send Message Box %d||
+WPUPMSB002|Send Group Message Box %d||
+WPUPMSB003|Station's Call:||
+WPUPMSB004|Group's Call:||
+WPUPMSB005|New/Refresh Call||
+WPUPMSB006|New Group||
+WPUPMSB007|Clear Msg History||
+WPUPMSB008|Message:||
+WPUPMSB009|Send Now!||
+WPUPMSB010|Path:||
+WPUPMSB011|Cancel Pending Msgs||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Broadcast||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Path||
+WPUPMSB020|Use Default Path(s)||
+WPUPMSB021|Direct (No path)||
+WPUPMSB022|Reverse Path (Hint):||
+#
+# PopUp "Auto Reply"
+WPUPARM001|Change Auto Reply||
+WPUPARM002|Reply:||
+#
+# PopUp "Help Index"
+WPUPHPI001|Help Index||
+WPUPHPI002|View||
+#
+# PopUp "Station Info"
+WPUPSTI000|Object from: %s||
+WPUPSTI001|Station Info||
+WPUPSTI002|Send Message||
+WPUPSTI003|Search FCC Database||
+WPUPSTI004|Search RAC Database||
+WPUPSTI005|Packets received: %d     Last Heard: ||
+WPUPSTI006|Heard via the TNC on device %d, ||
+WPUPSTI007|Heard ||
+WPUPSTI008|last via Local||
+WPUPSTI009|last via TNC on device %d||
+WPUPSTI010|last via Internet on device %d||
+WPUPSTI011|last via File||
+WPUPSTI012|last via Unknown||
+WPUPSTI013|, and has moved||
+WPUPSTI014|Current Power Gain:||
+WPUPSTI016|Altitude: %.0f%s ||
+WPUPSTI017|Course: %s� ||
+WPUPSTI018|Speed: %.1f km/h||
+WPUPSTI019|Speed: %.1f mph||
+WPUPSTI020|%0.1f miles||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distance from my station: %s  Bearing from my station: %s||
+WPUPSTI023|Last Position: ||
+WPUPSTI024|Weather Data %c:%s||
+WPUPSTI025|Wind Course: %s�    Speed: %03d km/h||
+WPUPSTI026|Wind Course: %s�    Speed: %s mph||
+WPUPSTI027|   Gust: %03d km/h||
+WPUPSTI028|   Gust: %s mph||
+WPUPSTI029|Temperature: %02.1f�C  ||
+WPUPSTI030|Temperature: %s�F   ||
+WPUPSTI031|Humidity: %s%%   ||
+WPUPSTI032| Humidex: %02.1f�C  ||
+WPUPSTI033|Baro: %s hPa||
+WPUPSTI034|Snow: %0.1f (cm/24h)||
+WPUPSTI035|Snow: %0.0f (inch/24h)||
+WPUPSTI036|Rain: ||
+WPUPSTI037|%0.2f (mm/h)    ||
+WPUPSTI038|%0.2f (inch/h)  ||
+WPUPSTI039|%0.2f (mm/day)     ||
+WPUPSTI040|%0.2f (inch/day)  ||
+WPUPSTI041|%0.2f (mm/since midnight)||
+WPUPSTI042|%0.2f (inch/since midnight)||
+WPUPSTI043|Data path: %s||
+WPUPSTI044|Comment %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Clear Track||
+WPUPSTI046|Total Rain: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (inch)||
+WPUPSTI049|Trace Query||
+WPUPSTI050|Un-Acked Messages Query||
+WPUPSTI051|Direct Stations Query||
+WPUPSTI052|Station Version Query||
+WPUPSTI053|Modify Object/Item||
+WPUPSTI054|Store Track||
+WPUPSTI055|Echoed from:||
+WPUPSTI056|Enable Automatic Updates||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|DF Bearing: %s||
+WPUPSTI059|Status  %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Fuel Temp: %02.1f�C  ||
+WPUPSTI061|Fuel Temp: %s�F   ||
+WPUPSTI062|Fuel Moisture: %s%%   ||
+WPUPSTI063|Baro: %0.2f in Hg||
+WPUPSTI064|Fetch NWS Alert||
+WPUPSTI065|Tactical Call: %s||
+WPUPSTI066|Assign Tactical Call||
+WPUPSTI067|Current Range: %d miles||
+WPUPSTI068|none||
+WPUPSTI069|default||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|range||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Range||
+WPUPSTI076|No signal detected||
+WPUPSTI077|Detectible signal (Maybe)||
+WPUPSTI078|Detectible signal but not copyable)||
+WPUPSTI079|Weak signal, marginally readable||
+WPUPSTI080|Noisy but copyable signal||
+WPUPSTI081|Some noise, easy to copy signal||
+WPUPSTI082|Good signal w/detectible noise||
+WPUPSTI083|Near full-quieting signal||
+WPUPSTI084|Full-quieting signal||
+WPUPSTI085|Extremely strong & full-quieting signal||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF Beamwidth||
+WPUPSTI089|DF Length||
+WPUPSTI090|Not Valid||
+WPUPSTI091|Change Trail Color||
+WPUPSTI092|Clear DF Bearing||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|ALOHA radius: %d %s||
+WPUPALO002|Stations inside ALOHA circle: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiles (in motion): %d||
+WPUPALO005| Mobiles (other):     %d||
+WPUPALO006| WX stations:         %d||
+WPUPALO007| Home stations:       %d||
+WPUPALO008|Last calculated %d %s %d %s ago.||
+WPUPALO666|ALOHA radius not calculated yet||
+#
+#
+# FCC-RAC Call Look up
+STIFCC0001|FCC Database Lookup||
+STIFCC0002|RAC Database Lookup||
+STIFCC0003|Name:||
+STIFCC0004|Street:||
+STIFCC0005|City:||
+STIFCC0006|State:||
+STIFCC0007|Zip:||
+STIFCC0008|Basic ||
+STIFCC0009|Advanced ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+#
+#
+# FCC-RAC indexing/searching
+STIFCC0100|FCC index old, rebuilding||
+STIFCC0101|Callsign Search||
+STIFCC0102|Callsign Not Found!||
+STIFCC0103|RAC index old, rebuilding||
+#
+#
+# Band open message 
+UMBNDO0001|at distance of||
+#
+#
+# Universal Options
+UNIOP00001|OK||
+UNIOP00002|Cancel||
+UNIOP00003|Close||
+UNIOP00004|miles||
+UNIOP00005|km||
+UNIOP00006|Device||
+UNIOP00007|Add||
+UNIOP00008|Delete||
+UNIOP00009|Properties||
+UNIOP00010|Allow Transmitting?||
+UNIOP00011|Activate on Startup?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|inch||
+UNIOP00018|mm/day||
+UNIOP00019|inch/day||
+UNIOP00020|mm/hr||
+UNIOP00021|inch/hr||
+UNIOP00022|mm/mid||
+UNIOP00023|inch/mid||
+UNIOP00024|deg||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|in Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Set System Clock from GPS Data?||
+UNIOP00030|Digipeat?||
+UNIOP00031|m||
+UNIOP00032|Apply||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|day||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# PopUp "Station Chooser"
+STCHO00001|Station Chooser||
+#
+# DISPLAY WX ALERT 
+WPUPWXA001|Wx Alerts||
+WPUPWXA002|Wx Alert List||
+#
+# PopUp "Configure - Interfaces"
+WPUPCIF001|Installed Interfaces||
+WPUPCIF002|Choose Interface Type||
+#
+# PopUp "Configure AX.25 TNC"
+WPUPCAX001|Configure AX.25 TNC||
+WPUPCAX002|AX.25 Device name||
+#
+# Interface device names 
+IFDNL00000|None||
+IFDNL00001|Serial TNC||
+IFDNL00002|Serial TNC w/GPS on a HSP cable||
+IFDNL00003|Serial GPS||
+IFDNL00004|Serial WX||
+IFDNL00005|Internet Server||
+IFDNL00006|AX25 TNC||
+IFDNL00007|Networked GPS (via gpsd)||
+IFDNL00008|Networked WX||
+IFDNL00009|Serial TNC w/GPS on AUX port||
+IFDNL00010|Serial KISS TNC||
+IFDNL00011|Networked Database (Not Implemented Yet)||
+IFDNL00012|Networked AGWPE||
+IFDNL00013|Serial Multi-Port KISS TNC||
+IFDNL00014|SQL Database (Experimental)||
+#
+# Interface device info 
+IFDIN00000|%s %2d %s %s   %s||
+IFDIN00001|%s %2d %s %s:%d   %s||
+IFDIN00002|%s %2d %s device %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006| DOWN ||
+IFDIN00007|  UP  ||
+IFDIN00008|ERROR ||
+IFDIN00009|UNKNWN||
+#
+# PopUp "Interface control"
+IFPUPCT000|Interface Control||
+IFPUPCT001|Start||
+IFPUPCT002|Stop||
+IFPUPCT003|Start All||
+IFPUPCT004|Stop All||
+#
+# IGate control
+IGPUPCF000|IGate Options||
+IGPUPCF001|Disable all IGate traffic||
+IGPUPCF002|Allow RF to Inet traffic ONLY||
+IGPUPCF003|Allow RF->Inet and Inet->RF traffic||
+IGPUPCF004|Igate -> RF Path   ||
+#
+# WX Station
+WXPUPSI000|WX Station||
+WXPUPSI001|WX Station Type||
+WXPUPSI002|Current Data||
+WXPUPSI003|Wind Course||
+WXPUPSI004|Wind Speed||
+WXPUPSI005|Wind Gust||
+WXPUPSI006|Temp||
+WXPUPSI007|Total Rain||
+WXPUPSI008|Today's Rain Total||
+WXPUPSI009|Baro||
+WXPUPSI010|Humidity||
+WXPUPSI011|Peet Bros ULTIMETER 2000 Type (Data Logging Mode)||
+WXPUPSI012|Peet Bros ULTIMETER II Type||
+WXPUPSI013|Peet Bros ULTIMETER 2000 Type (Packet Mode)||
+WXPUPSI014|Current HR Rain Tot.||
+WXPUPSI015|Last 24 Rain Total||
+WXPUPSI016|Qualimetrics Q-Net||
+WXPUPSI017|Peet Bros ULTIMETER 2000 Type (Complete Mode)||
+WXPUPSI018|Dew Point||
+WXPUPSI019|High Wind||
+WXPUPSI020|Wind Chill||
+WXPUPSI021|Heat Index||
+WXPUPSI022|3-Hr Baro||
+WXPUPSI023|High Temp.||
+WXPUPSI024|Low Temp.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Station Lists
+LHPUPNI000|All Stations||
+LHPUPNI001|Mobile Stations||
+LHPUPNI002|Weather Stations||
+LHPUPNI003|Local Stations (via TNC)||
+LHPUPNI004|Last Stations||
+LHPUPNI005|Objects & Items||
+LHPUPNI006|Own Objects & Items||
+LHPUPNI010|#||
+LHPUPNI011|Call Sign||
+LHPUPNI012|#Pack||
+LHPUPNI013|Pos Time||
+LHPUPNI014|Path||
+LHPUPNI015|PHG||
+LHPUPNI016|Comments||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Lat||
+LHPUPNI104|Long||
+LHPUPNI105|#Pack||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Lat/Lon or UTM||
+#
+# Maps WX Alert styles
+PULDNMAT01|Show Alert maps above other maps||
+PULDNMAT02|Show Alert maps under other maps||
+#
+# Error/popup messages 
+POPEM00001|Locate Error!||
+POPEM00002|Station %s was not found!||
+POPEM00003|Tracking Error!||
+POPEM00004|Interface Error!||
+POPEM00005|Invalid AX.25 port name %s||
+POPEM00006|Invalid AX.25 port name %s||
+POPEM00007|Invalid callsign %s||
+POPEM00008|Invalid AX.25 destination callsign or digipeater||
+POPEM00009|Cannot open AX.25 socket, %s||
+POPEM00010|Cannot bind AX.25 socket, %s||
+POPEM00011|Cannot connect to AX.25 callsign, %s||
+POPEM00012|AX.25 error on output of UI||
+POPEM00013|AX.25 problem with axports file||
+POPEM00014|AX.25 invalid port name %s||
+POPEM00015|Error opening interface %d Hard Fail||
+POPEM00016|Error opening interface %d Time Out||
+POPEM00017|No more interfaces Available!||
+POPEM00018|Data Query - Single Message Line||
+POPEM00019|Port transmitting is off for port %d||
+POPEM00020|Database Error!||
+POPEM00021|AX.25 support not compiled into Xastir!||
+POPEM00022|Input Error!||
+POPEM00023|No location name specified!||
+POPEM00024|Location name specified is in use!||
+POPEM00025|Not Found!||
+POPEM00026|Tracking will commence when it appears||
+POPEM00027|Improper info.  Some fields empty?||
+POPEM00028|Can't open file||
+POPEM00029|Found It!||
+POPEM00030|Weather Station Symbol||
+POPEM00031|Changed to WX symbol '/_', other options:  '\_'  '/W'  and  '\W'||
+POPEM00032|Warning: Using National Weather Service Symbol!||
+POPEM00033|No GPS Data!||
+POPEM00034|Disabling My Position TX Until Valid GPS Data!||
+POPEM00035|Warning||
+POPEM00036|Notice||
+POPEM00037|HSP interface present: GPS timing has been increased||
+POPEM00038|Name Conflicts With Existing Object/Item/Station||
+POPEM00039|Illegal characters found, substituting periods in their place||
+POPEM00040|Custom outgoing path was lost||
+POPEM00041|Processing another file.  Wait a bit, then try again||
+POPEM00042|Object not owned by me! Try adopting the object first.||
+POPEM00043|Not an Object/Item!||
+POPEM00044|Fetch Findu Trail: Failed||
+POPEM00045|Fetch Findu Trail: Complete||
+POPEM00046|Berkeley DB header/shared library do NOT match! Disabling map cache.||
+POPEM00047|Global transmit is DISABLED. Emergency beacons are NOT going out!||
+POPEM00048|Emergency Beacon Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmitting every 60 seconds!||
+POPEM00050|Interfaces or posits/transmits DISABLED.  Emergency beacons are NOT going out!||
+POPEM00051|Altnet is enabled (Configure->Defaults dialog)||
+POPEM00052|Callsign is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We're trying to talk to ourselves!||
+#
+# Jump Location 
+JMLPO00001|Map Display Bookmarks||
+JMLPO00002|Activate!||
+JMLPO00003|New Name:||
+#
+# Bulletins
+BULMW00001|Bulletins||
+BULMW00002|Limit Range to (0, is no limit)||
+BULMW00003|Change Range||
+#
+# All Message Traffic
+AMTMW00001|All Message Traffic||
+AMTMW00002|Limit Range to (0, is no limit)||
+#
+# Speech Strings
+SPCHSTR001|kilometers||
+SPCHSTR002|meters||
+SPCHSTR003|miles||
+SPCHSTR004|yards||
+SPCHSTR005|%s, distance is %d %s.||
+SPCHSTR006|%s, distance is %.1f %s.||
+SPCHSTR007|%s, distance is %d %s %s %s.||
+SPCHSTR008|%s, distance is %.1f %s %s %s.||
+SPCHSTR009|New Weather Alert||
+SPCHSTR010|New Station||
+SPCHSTR011|Heard, D X, %s, at distance of %.1f %s||
+#
+#
+SPCHDIRN00|north of||
+SPCHDIRS00|south of||
+SPCHDIRE00|east of||
+SPCHDIRW00|west of||
+SPCHDIRNE0|northeast of||
+SPCHDIRNW0|northwest of||
+SPCHDIRSE0|southeast of||
+SPCHDIRSW0|southwest of||
+#
+# Symbol Selection Dialog
+SYMSEL0001|Select Symbol||
+SYMSEL0002|Primary Symbol Table||
+SYMSEL0003|Secondary Symbol Table||
+#
+# Print Properties Dialog
+PRINT0001|Print Properties||
+PRINT0002|Paper Size||
+PRINT0003|Auto-Rotate Image||
+PRINT0004|Rotate Image 90� CCW||
+PRINT0005|Auto-Scale Image||
+PRINT0006|Scale:||
+PRINT0007|Force default background color to white||
+PRINT0008|Print in Black and White||
+PRINT0016|Reverse Colors||
+PRINT0009|Postscript Resolution:||
+PRINT0010|Preview||
+PRINT0011|Print to File||
+PRINT0012|Dumping image to file...||
+PRINT0013|Converting to Postscript...||
+PRINT0014|Finished creating print file||
+PRINT0015|Print Status||
+#
+# Print Dialog
+PRINT1001|Direct to:||
+PRINT1002|Via Previewer:||
+#
+# Locate Feature and Find Address Dialogs
+FEATURE001|Name:||
+FEATURE002|State/Province:||
+FEATURE003|County:||
+FEATURE004|Map Quad:||
+FEATURE005|Type:||
+FEATURE006|GNIS File:||
+FEATURE007|Address:||
+FEATURE008|City:||
+FEATURE009|Mark Destination||
+FEATURE010|Zip Code:||
+FEATURE011|Geocoding File||
+#
+# Coordinate Calculator Dialog
+COORD001|Coordinate Calculator||
+COORD002|Calc||
+COORD003|Calculate||
+COORD004|Clear||
+COORD005|UTM||
+COORD006|Latitude or||
+COORD007|Longitude or||
+COORD008|Zone||
+COORD009|UTM Easting||
+COORD010|UTM Northing||
+COORD011|               Decimal Degrees:  ||
+COORD012|       Degrees/Decimal Minutes:  ||
+COORD013|  Degrees/Minutes/Dec. Seconds:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|Military Grid Reference System:  ||
+COORD016|       Maidenhead Grid Locator:  ||
+COORD017| **       Sorry, your input was not recognized!        **||
+COORD018| **   Please use one of the following input formats:   **||
+#
+#
+# Smart Beaconing Dialog
+SMARTB001|Smart Beaconing||
+SMARTB002|High Rate (secs):||
+SMARTB003|High Speed (mph):||
+SMARTB004|High Speed (kph):||
+SMARTB005|Low Rate (mins):||
+SMARTB006|Low Speed (mph):||
+SMARTB007|Low Speed (kph):||
+SMARTB008|Minimum Turn (deg):||
+SMARTB009|Turn Slope:||
+SMARTB010|Wait Time (secs):||
+SMARTB011|Enable SmartBeaconing(tm)||
+#
+#
+#
+# Gamma Adjust Dialog
+GAMMA001|Adjust Gamma Correction||
+GAMMA002|Gamma Correction||
+#
+#
+# 
+# Map labels font Dialog
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Font Tiny||
+MAPFONT004|Map Font Small||
+MAPFONT005|Map Font Medium||
+MAPFONT006|Map Font Large||
+MAPFONT007|Map Font Huge||
+MAPFONT008|Map Font Border||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV ID Font||
+#
+#
+#
+# Distance/Bearing on status line
+PULDNDB001|Dist/Bearing Status||
+#
+#
+# GPS Transfer Operations
+GPS001|GPS Transfer||
+GPS002|Filename||
+GPS003|Select Color||
+GPS004|Red||
+GPS005|Green||
+GPS006|Black||
+GPS007|White||
+GPS008|Orange||
+GPS009|Blue||
+GPS010|Yellow||
+GPS011|Violet||
+#
+#
+# Map Properties Dialog
+MAPP001|Map Properties||
+MAPP002|Max   Min    Map         USGS  Auto||
+MAPP003|Zoom  Zoom  Layer  Fill  DRG   Map   Path/Filename||
+MAPP004|Change Layer->||
+MAPP005|Filled->||
+MAPP006|Yes||
+MAPP007|No||
+MAPP008|Automaps->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+#
+# Time Strings
+TIME001|Day||
+TIME002|Days||
+TIME003|Hour||
+TIME004|Hours||
+TIME005|Minute||
+TIME006|Minutes||
+TIME007|Second||
+TIME008|Seconds||
+#
+#
+# Map Caching
+CACHE001|Map now cached||
+CACHE002|Loading Cached Map||
+CACHE003|Map not found in cache...||
+#
+#
+# Map Screen Misc
+RANGE001|RANGE SCALE||
+#
+#
+# GPS Status
+GPSS001|WAAS or PPS||
+GPSS002|DGPS||
+GPSS003|Valid SPS||
+GPSS004|Invalid||
+GPSS005|Sats/View||
+GPSS006|Fix||
+GPSS007|!GPS data is older than 30 seconds!||
+GPSS008|Simulation||
+GPSS009|Manual||
+GPSS010|Estimated||
+GPSS011|Float RTK||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data and other CAD dialogs
+CADPUD001|Area Object||
+CADPUD002|Area Label:||
+CADPUD003|Comment:||
+CADPUD004|Probability (%):||
+CADPUD005|OK||
+CADPUD006|CAD Dialog||
+CADPUD007|Show/Edit Details||
+CADPUD008|Cancel||
+CADPUD009|Delete CAD objects?||
+CADPUD010|Delete All||
+CADPUD011|Delete Selected||
+CADPUD012|Solid||
+CADPUD013|Dashed||
+CADPUD014|Double Dash||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|XASTIR Map of %s (upper left) to %s (lower right).  UTM %d m grid, %s datum. ||
+#"XASTIR Map of <lat/long> (upper left) to <lat/long> (lower right).  Lat/Long grid, <wgs84> datum. ",
+MDATA002|XASTIR Map of %s (upper left) to %s %s (lower right).  Lat/Long grid, %s datum.||
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM zones, <wgs84> datum. ",
+MDATA003|XASTIR Map of %s (upper left) to %s (lower right).  UTM zones, %s datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+# DB_POSTGIS 
+XADBMST002|Postgreql with Postgis||
+# DB_MYSQL_SPATIAL
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Xastir Simple Schema||
+#XASTIR_SCHEMA_CAD
+XASCHEMA02|Xastir CAD Schema||
+#XASTIR_SCHEMA_COMPLEX
+XASCHEMA03|Xastir full Schema||
+#XASTIR_SCHEMA_APRSWORLD
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/language-French.sys b/config/language-French.sys
new file mode 100644
index 0000000..96f2a8f
--- /dev/null
+++ b/config/language-French.sys
@@ -0,0 +1,1366 @@
+# $Id: language-French.sys,v 1.231 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the French Language file used for all the prompts in xastir
+#
+# Creator        : Richard VE2DJE ve2dje at amsat.org
+# Maintained by  : The Xastir Group <xastir at xastir.org>
+# Merci �        : Jacques Chion, F6CWO, qui a contribu� une grande part des
+#                  traductions r�centes. (N7TAP)
+#
+# comment lines with pound signs in front are ignored
+# File format as follows:
+# ID (10 chars alpha+numeric)|(String associated with id)|QuickKeys|#comment
+# The ID is a unique uppercase char string for each block followed by a nummer
+#
+# WARNING:
+# Some strings contain formatting commands like %s and %d, you should not
+# change these. Wrong format strings could produce a segfault!
+#
+# Main Menu
+MENUTB0001|Fichier|F|
+MENUTB0002|Examiner|E|
+MENUTB0004|Cartes|a|
+MENUTB0005|Stations|S|
+MENUTB0006|Messages|M|
+MENUTB0010|Interfaces|I|
+MENUTB0009|Aide|A|
+#
+# Menu "File"
+PULDNFI001|Configurer|C|
+PULDNFI002|Ouvrir le journal|O|
+PULDNFI003|Test|e|
+PULDNFI004|Quitter|Q|
+PULDNFI007|Changer niveau de d�bogage|d|
+PULDNFI010|Activer archivage TNC|T|
+PULDNFI011|Activer archivage r�seau|r|
+PULDNFI012|Activer archivage IGate|I|
+PULDNFI013|Activer archivage m�t�o|m|
+PULDNFI014|Activer copie d'�cran PNG||
+PULDNFI015|Imprimer carte|p|
+PULDNFI016|Instantan� KML||
+#
+# Menu "View"
+PULDNVI001|Bulletins|B|
+PULDNVI002|Donn�es entrantes|D|
+PULDNVI003|Stations mobiles|m|
+PULDNVI004|Toutes stations|T|
+PULDNVI009|Stations locales|l|
+PULDNVI012|Stations r�centes|r|
+PULDNVI005|Stations m�t�o|m|
+PULDNVI008|Mes donn�es m�t�o|o|
+PULDNVI007|Alertes m�t�o|A|
+PULDNVI011|Trafic des messages|i|
+PULDNVI013|Dur�e de fonctionnement|f|
+PULDNVI014|Dur�e de fonctionnement du logiciel||
+PULDNVI015|Etat du GPS||
+PULDNVI016|Statistiques ALOHA||
+#
+# Menu "Configure"
+PULDNCF004|Station|S|
+PULDNCF001|D�fauts|D|
+PULDNCF003|Temporisations|T|
+PULDNCF002|Syst�me des coordonn�es|C|
+PULDNCF006|Alertes sonores|A|
+PULDNCF007|Parole|P|
+PULDNCF008|Sauvegarder la configuration maintenant !|a|
+# (Units see PULDNDP006)
+#
+# Menu "Maps"
+PULDNMP001|Choix des cartes|C|
+PULDNMP012|Aller �|l|
+PULDNMP014|Localiser �l�ment cartographique|F|
+PULDNMP016|D�sactiver Zoom/Pan/Accueil rapide||
+PULDNMP013|D�sactiver toutes cartes|D|
+PULDNMP002|Activer cartographie automatique|A|
+PULDNMP003|Activer quadrillage|q|
+PULDNMP004|Activer niveaux de cartes|n|
+PULDNMP010|Activer annotation des cartes|n|
+PULDNMP009|Activer remplissage de zones|r|
+PULDNMP007|Activer alertes m�t�o|M|
+PULDNMP005|Couleur de fond|f|
+PULDNMP006|Style du texte de station|S|
+PULDNMP026|Style du contour d'ic�ne|O|
+PULDNMP011|Menu souris|e|
+PULDNMP008|Intensit� des cartes|I|
+PULDNMP020|Configurer Tigermap||
+PULDNMP021|Cartographie automatique - d�sactiver cartes tram�es||
+PULDNMP022|Indexer nouvelles cartes au d�marrage||
+PULDNMP023|Index: Ajouter nouvelles cartes|R|
+PULDNMP024|Index: Re-indexer toutes cartes|A|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsel||
+PULDNMP027|Re-t�l�charger les cartes (pas � partir du cache)||
+PULDNMP028|Vider le cache des cartes||
+PULDNMP029|Trouver l'adresse||
+PULDNMP030|Configurer USGS DRG||
+PULDNMP031|Activer bordure des cartes||
+#
+# PopUp "Configure Tigermap"
+MPUPTGR001|Quadrillage||
+MPUPTGR002|Comt�s||
+MPUPTGR003|Nom des villes||
+MPUPTGR004|R�gions urbaines||
+MPUPTGR005|Routes principales||
+MPUPTGR006|Rues||
+MPUPTGR007|Voies ferr�es||
+MPUPTGR008|Nom des �tats||
+MPUPTGR009|Nom des autoroutes||
+MPUPTGR010|Nom des routes US||
+MPUPTGR011|Nom des routes d'�tats||
+MPUPTGR012|Choisir les articles � afficher:||
+MPUPTGR013|Rivi�res||
+MPUPTGR014|Lacs||
+MPUPTGR015|A�roports, parcs, etc||
+MPUPTGR016|Intensit� de la carte||
+MPUPTGR017|Temporisation de carte Internet (sec)||
+MPUPTGR018|Activer cartes Tiger||
+#
+# PopUp "Configure USGS DRG"
+MPUPDRG001|S�lectionner ce qui doit �tre affich� :||
+MPUPDRG002|Colorer la carte sous-ja�ante (XOR)||
+MPUPDRG003|Noir||
+MPUPDRG004|Blanc||
+MPUPDRG005|Bleu||
+MPUPDRG006|Rouge||
+MPUPDRG007|Marron||
+MPUPDRG008|Vert||
+MPUPDRG009|Pourpre||
+MPUPDRG010|Jaune||
+MPUPDRG011|Bleu clair||
+MPUPDRG012|Rouge clair||
+MPUPDRG013|Pourpre clair||
+MPUPDRG014|Gris clair||
+MPUPDRG015|Marron clair||
+#
+# PopUp "Map Chooser"
+WPUPMCP001|Choix de cartes||
+PULDNMMC01|Effacer|A|
+PULDNMMC02|Vectorielles|V|
+PULDNMMC03|Topogr. 250k|2|
+PULDNMMC04|Topogr. 100k|1|
+PULDNMMC05|Topogr. 24k|4|
+PULDNMMC06|Agrandir r�pertoires|||
+PULDNMMC07|R�ps/cartes choisies:||
+PULDNMMC08|D�selct. r�ps|C|
+PULDNMMC09|Choisir tout|S|
+#
+# PullDown "Map Background Color"
+PULDNMBC01|Gris||
+PULDNMBC02|Rose||
+PULDNMBC03|Bleu marine||
+PULDNMBC04|Bleu acier ||
+PULDNMBC05|Vert moyen||
+PULDNMBC06|Vert p�le||
+PULDNMBC07|Jaune p�le||
+PULDNMBC08|Blanc cr�me||
+PULDNMBC09|Brun ros�||
+PULDNMBC10|Rouge brique||
+PULDNMBC11|Blanc||
+PULDNMBC12|Noir||
+#
+# PullDown "Station text Style"
+PULDNMSL01|Bordure noire|n|
+PULDNMSL02|Ombr� avec toile de fond|O|
+PULDNMSL03|Blanc sur noir|B|
+#
+# PullDown "Icon Outline Style"
+PULDNMIO01|Pas de contour|N|
+PULDNMIO02|Contour noir|B|
+PULDNMIO03|Contour gris|G|
+PULDNMIO04|Contour blanc|W|
+#
+# Switches
+PULDNOT001|Ouvrir||
+PULDNOT002|Fermer||
+PULDNOT003|Court||
+#
+# Menu "Stations"
+PULDNDP014|Localiser une station|L|
+PULDNDP001|Suivre une station|S|
+PULDNDP022|R�cup�rer piste Findu||
+PULDNDP032|Filtrer donn�es||
+PULDNDP040|Ne rien afficher||
+PULDNDP041|Ma station||
+PULDNDP042|Choisir TNC||
+PULDNDP027|- Stations en direct||
+PULDNDP043|- Stations via digi||
+PULDNDP034|Stations via le net||
+PULDNDP019|Inclure donn�es p�rim�es||
+PULDNDP044|Afficher les stations||
+PULDNDP028|- Stations fixes||
+PULDNDP029|- Stations mobiles||
+PULDNDP030|- Stations m�t�o||
+PULDNDP053|  - Stations m�t�o CWOP||
+PULDNDP045|Objets/articles||
+PULDNDP026|- Objets/articles m�t�o||
+PULDNDP039|- Objets/articles indicateurs d'eau||#'
+PULDNDP031|- Autres objets/articles||
+PULDNDP033|Filtrer affichage||
+PULDNDP010|Afficher indicatif|n|
+PULDNDP012|Afficher symbole|c|
+PULDNDP011|- Pivoter symbole|o|
+PULDNDP007|Afficher piste|p|
+PULDNDP003|Afficher cap|r|
+PULDNDP004|Afficher vitesse|v|
+PULDNDP017|- Afficher vitesse abr�g�e||
+PULDNDP002|Afficher altitude|A|
+PULDNDP009|Afficher info m�t�o|I|
+PULDNDP046|- Afficher texte m�t�o||
+PULDNDP018|-- Seulement la temp�rature||
+PULDNDP047|- Indicateur de vent||
+PULDNDP054|Afficher cercle Aloha||
+PULDNDP013|Afficher ambigu�t� de position|b|
+PULDNDP008|Afficher puissance/gain|g|
+PULDNDP021|- Activer puissance/gain d�faut||
+PULDNDP020|- Activer puissance/gain mobile||
+PULDNDP023|Afficher attributs DF||
+PULDNDP123|Afficher largeur faiseau recherche auto (DF)||
+PULDNDP223|Afficher relev� recherche auto (DF)||
+PULDNDP035|Activer point estim�||
+PULDNDP036|- Afficher arc||
+PULDNDP037|- Afficher cap||
+PULDNDP038|- Afficher symbole||
+PULDNDP005|Afficher distance/rel�vement|d|
+PULDNDP024|Afficher �ge du dernier rapport||
+PULDNDP015|Effacer toutes stations !!!|E|
+PULDNDP016|Effacer toutes pistes !!!|f|
+PULDNDP025|Effacer histoire des objets/articles||
+PULDNDP048|Recharger histoire des objets/articles||
+PULDNDP049|Effacer indicatifs tactiques||
+PULDNDP050|Effacer historique des indicatifs tactiques||
+PULDNDP051|Choisir seulement les indicatifs tactiques||
+PULDNDP052|- Annoter les points de piste||
+PULDNDP055|Exporter tout|E|
+PULDNDP056|Exporter vers fichier KML||
+#
+# Units
+PULDNUT001|Activer mesures anglaises||
+PULDNUT002|M�tres||
+#
+# Menu "Messages"
+PULDNMG001|Composer un message �|C|
+PULDNMG002|Ouvrir les messages de groupe|g|
+PULDNMG003|Effacer tout message � exp�dier|E|
+PULDQUS001|Int�rroger toutes les stations|I|
+PULDQUS002|Int�rroger les stations IGate|n|
+PULDQUS003|Int�rroger les stations m�t�o|m|
+PULDNMG004|Configurer la r�ponse automatique|o|
+PULDNMG005|Activer la r�ponse automatique|R|
+PULDNMG006|Mode "Satellite Ack"|M|
+PULDNMG007|Voir les messages en attente|V|
+#
+# Menu "Interfaces"
+PULDNTNT04|Contr�le de l'interface|C|
+PULDNTNT03|D�sactiver transmission: Tout||
+PULDNTNT05|D�sactiver transmission: Ma position||
+PULDNTNT06|D�sactiver transmission: Objets/Articles||
+PULDNTNT11|Activer serveur sur port 2023||
+PULDNTNT01|Transmettre maintenant !|T|
+PULDNTNT07|Extraire piste GPS|F|
+PULDNTNT08|Extraire routes GPS|R|
+PULDNTNT09|Extraire points de cheminement GPS|W|
+PULDNTNT10|Extraire points de cheminement Garmin RINO|G|
+#
+# Menu "Help"
+PULDNHEL01|Information|I|
+PULDNHEL02|Index de l'Aide|A|#'
+PULDNHEL03|ACTIVER MODE BALISE DE DETRESSE|E|
+PULDNHEL04|!!! MODE BALISE DE DETRESSE !!!||
+PULDNHEL05|� propos de Xastir||
+#
+#
+# Mouse Menu Popup
+POPUPMA001|Options|O|
+POPUPMA00c|Centrer|C|
+POPUPMA015|Information sur la station||
+POPUPMA002|Zoom +|s|
+POPUPMA003|Zoom -|i|
+POPUPMA004|Niveau de zoom|N|
+POPUPMA005|Niveau 1|1|
+POPUPMA006|Niveau 16|6|
+POPUPMA007|Niveau 64|4|
+POPUPMA008|Niveau 256|2|
+POPUPMA009|Niveau 1024|0|
+POPUPMA010|Niveau 8192|8|
+POPUPMA017|Monde entier|M|
+POPUPMA016|Pos/zoom pr�c�dent||
+POPUPMA018|Objet/Article->Cr�er||
+POPUPMA019|Objet/Article->Modifier||
+POPUPMA025|D�placer ma station ici|H|
+POPUPMA011|Nord||
+POPUPMA012|Sud||
+POPUPMA013|Ouest||
+POPUPMA014|Est||
+POPUPMA020|Mesurer||
+POPUPMA021|D�placer||
+POPUPMA022|Me suivre||
+POPUPMA023|Modificateurs trouv�s !||
+POPUPMA024|SVP d�sactiver CapsLock/NumLock/ScrollLock/autres||
+POPUPMA026|Centre & zoom||
+POPUPMA027|  Latitude||
+POPUPMA028| Longitude||
+POPUPMA029|Dessiner objets CAD||
+POPUPMA030|Dessiner||
+POPUPMA031|Fermer polygone||
+POPUPMA032|Effacer polygones CAD||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Changer niveau de zoom||
+POPUPMA035|10% arri�re||
+POPUPMA036|10% avant||
+POPUPMA037|Aire||
+POPUPMA038|carr�||
+POPUPMA039|pieds carr�s||
+POPUPMA040|m�tres carr�s||
+POPUPMA041|Rel�vement||
+POPUPMA042|degr�s||
+POPUPMA043|Modifier ambigu�t� de position||
+POPUPMA044|Ambigu�t� de position est active, votre nouvelle position pourra sauter.||
+POPUPMA045|Objets pr�d�finis||
+POPUPMA046|Polygones CAD||
+POPUPMA047|Activer les objets CAD||
+POPUPMA048|Activer les �tiquettes CAD||
+POPUPMA049|Activer les commentaires CAD||
+POPUPMA050|Activer la probabilit� CAD||
+POPUPMA051|Activer la taille de la surface CAD||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|m�tres||
+POPUPMA055|mi|
+#
+#
+# Status line labels
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Sv||
+BBARSTH001|%d/%d stations||
+BBARSTA000|%-9s Nouvel objet !||
+BBARSTA001|%-9s Nouvelle station !||
+BBARSTA002|%-9s||
+BBARSTA003|Chargement de cartes...||
+BBARSTA004|Cartes charg�es||
+BBARSTA005|Quadrillage de carte Lat/Long activ�||
+BBARSTA006|Quadrillage de carte Lat/Long d�sactiv�||
+BBARSTA007|Carte automatique activ�e||
+BBARSTA008|Carte automatique d�sactiv�e||
+BBARSTA009|Niveau de cartes activ�||
+BBARSTA010|Niveau de cartes d�sactiv�||
+BBARSTA011|R�ponse automatique d�sactiv�e||
+BBARSTA012|Fichier termin�...||
+BBARSTA013|Ouverture du port GPS||
+BBARSTA014|Fermeture du port GPS||
+BBARSTA015|R�ception de message GPS RMC||
+BBARSTA016|R�ception de message GPS GGA||
+BBARSTA017|R�seau d�connect� de l'h�te||
+BBARSTA018|Connexion r�seau d�passement de temps !||
+BBARSTA019|Recherche de l'h�te %s||#'
+BBARSTA020|Connect� � %s||
+BBARSTA021|�chec de la connexion !||
+BBARSTA022|Incapable de relier le socket !||
+BBARSTA023|H�te inconnu !||
+BBARSTA024|Serveur non sp�cifi�||#'
+BBARSTA025|H�te trouv�, connexion en cours %d||
+BBARSTA026|Attente de donn�es du GPS par HSP||
+BBARSTA027|Fermeture port HSP r�ception donn�e TNC..||
+BBARSTA028|Chargement de %s||
+BBARSTA029|Ouverture port m�t�o||
+BBARSTA030|Fermeture port m�t�o||
+BBARSTA031|Recherche d'h�te %d||#'
+BBARSTA032|Donn�es m�t�o d�cod�es||
+BBARSTA033|�cho de digipeater||
+BBARSTA034|Chargement de cartes alertes m�t�o||
+BBARSTA035|Attente de don�es du GPS par AUX||
+BBARSTA036|Fermeture port GPS r�ception donn�e TNC..||
+BBARSTA037|GPS m�t�o d�cod�es||
+BBARSTA038|Placez le changement sur ma station||
+BBARSTA039|Cr�ation de l'index de %s||
+BBARSTA040|Station d'amateur APRS(tm) %s||#'
+BBARSTA041|Attente de donn�es GPS..||
+BBARSTA042|Transmission objets/articles||
+BBARSTA043|Journalisation||
+BBARSTA044|Le rayon ALOHA est de %d%s||
+BBARSTA045|Chargement de symboles...||
+BBARSTA046|Rechargement des symboles...||
+BBARSTA047|Initialisation de ma station...||
+BBARSTA048|D�marrer interfaces...||
+BBARSTA049|Lit les dalles...||
+BBARSTA050|T�l�charge les dalles...||
+BBARSTA051|T�l�charge dalle %li de %li||
+#
+#
+# PopUp "View - Incoming Packet Data"
+WPUPDPD001|Affichage de donn�es paquet||
+WPUPDPD002|Donn�es du TNC seulement||
+WPUPDPD003|Donn�es du r�seau seulement||
+WPUPDPD004|Donn�es du TNC et du r�seau||
+WPUPDPD005|TNC||
+WPUPDPD006|R�seau||
+WPUPDPD007|Capacit� Station||
+WPUPDPD008|Seulement les miens||
+#
+# PopUp "View - Find Station"
+WPUPLSP001|Localiser une station||
+WPUPLSP002|Localiser l'indicatif||#'
+WPUPLSP003|Casse exacte|C|
+WPUPLSP004|Correspondance exacte|E|
+WPUPLSP005|Localiser maintenant !|L|
+WPUPLSP006|Localiser d�tresse !||
+WPUPLSP007|Recherche indicatif FCC/RAC||
+#
+# PopUp "Configure - Defaults"
+WPUPCFD001|Configurer d�fauts||
+WPUPCFD002|Au bout de combien de temps une station sera-t-elle consid�r�e �g�e ?||
+WPUPCFD003|15 min|1|
+WPUPCFD004|30 min|3|
+WPUPCFD005|45 min|4|
+WPUPCFD006|1 heure|h|
+WPUPCFD007|90 min|9|
+WPUPCFD008|2 heures|2|
+WPUPCFD009|Au bout de combien de temps une station ne sera-t-elle plus affich�e ?||
+WPUPCFD010|6 heures|6|
+WPUPCFD011|12 heures|e|
+WPUPCFD012|1 jour|j|
+WPUPCFD013|2 jours|o|
+WPUPCFD014|1 semaine|s|
+WPUPCFD015|Option de transmission||
+WPUPCFD016|Station fixe||
+WPUPCFD017|Station mobile + heure locale||
+WPUPCFD018|Station mobile + date/heure Zulu||
+WPUPCFD019|Station mobile + heure/secondes Zulu||
+WPUPCFD021|Position de station + m�t�o||
+WPUPCFD022|Position de station + date/heure Zulu + m�t�o||
+WPUPCFD023|Transmettre les donn�es m�t�o non trait�es ?||
+WPUPCFD024|Transmettre les objets/articles sous forme compr�ss�s ?||
+WPUPCFD025|Activer r�seau alterne ?|A|
+WPUPCFD026|Transmettre position � quel intervalle ?||
+WPUPCFD027|Afficher bulletins nouveaux||
+WPUPCFD028|Alerter si cl�s modificatrices (Verr.Num.)||
+WPUPCFD029|Voir bulletins avec distance z�ro||
+WPUPCFD030|D�sactiver identif. de duplic. posit.||
+WPUPCFD031|Charger des objets pr�d�finis � partir d'un fichier||
+WPUPCFD032|Mon parcour en une seule couleur||
+WPUPCFD033|ALTNET:||
+#
+# PopUp "Configure - Timing"
+WPUPCFTM01|Configurer temporisation||
+WPUPCFTM02|Intervalle transmission de position (min)||
+WPUPCFTM03|D�lai d'affichage faible d'une station (min)||
+WPUPCFTM04|Intervalle maximum de transmission des objets/articles (min)||#'
+WPUPCFTM05|D�lai de suppression d'affichage d'une station (heures)||
+WPUPCFTM06|Intervalle de lecture GPS (sec)||
+WPUPCFTM07|D�lai de suppression d'une station (jours)||
+WPUPCFTM08|Expiration de point estim� (min)||
+WPUPCFTM09|D�lai inter-char port s�rie (ms)||
+WPUPCFTM10|D�lai nouvelle piste (min)||
+WPUPCFTM11|Espace nouvelle piste (degr�s)||
+WPUPCFTM12|RINO -> Intervalle d'objets (min), 0 = D�sactiv�||
+WPUPCFTM13|Intervalle de capture instantan� (min)||
+#
+# PopUp "Configure Coordinate System"
+WPUPCFC001|Configurer syst�me de coordonn�es||
+WPUPCFC002|Choisir syst�me de coordonn�es||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM avec zones sp�ciales||
+#
+# PopUp "Configure GPS"
+WPUPCFG001|Configurer GPS||
+WPUPCFG003|Port GPS seulement||
+WPUPCFG002|Utiliser la position GPS ?||
+WPUPCFG004|Options du GPS||
+WPUPCFG005|GPS seul||
+WPUPCFG006|TNC branch� au GPS (C�ble HSP)||
+WPUPCFG007|TNC branch� au GPS avec CTL-E||
+WPUPCFG008|Intervalle de temps GPS||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 min||
+WPUPCFG013|2 min||
+WPUPCFG014|5 min||
+WPUPCFG015|10 min||
+WPUPCFG016|GPS branch� r�seau||
+WPUPCFG017|H�te GPSD||
+WPUPCFG018|Port GPSD||
+WPUPCFG019|GPS r�seau via GPSD||
+WPUPCFG020|Reconnexion sur �chec ?||
+WPUPCFG021|Connexion m�t�o r�seau||
+WPUPCFG022|H�te m�t�o||
+WPUPCFG023|Port m�t�o||
+#
+# Configure TNC (baud/style are also for WX)
+WPUPCFT001|Configurer le TNC||
+WPUPCFT002|Utiliser le TNC ?||
+WPUPCFT003|Port TNC||
+WPUPCFT004|Configuration du port||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|Voies UnProto||
+WPUPCFT012|Voie 1: %s via ||
+WPUPCFT013|Voie 2: %s via ||
+WPUPCFT014|Voie 3: %s via ||
+WPUPCFT015|Type de port||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Configurer TNC +HSP GPS||
+WPUPCFT024|Type de donn�es||
+WPUPCFT025|Auto detection||
+WPUPCFT026|Type binaire||
+WPUPCFT027|Type ASCII||
+WPUPCFT028|Configurer TNC +AUX GPS||
+WPUPCFT029|COnfigurer TNC +INVALID ENUM||
+WPUPCFT030|Configurer TNC KISS||
+WPUPCFT031|Fichiers de configuration du TNC||
+WPUPCFT032|Nom du fichier de d�marrage du TNC||
+WPUPCFT033|Nom du fichier d'arr�t du TNC||#'
+WPUPCFT034|Param�tres KISS||
+WPUPCFT035|TXDelay (unit� 10 ms)||
+WPUPCFT036|Persistance (0 � 255)||
+WPUPCFT037|SlotTime (unit� 10 ms)||
+WPUPCFT038|TxTail (unit� 10 ms)||
+WPUPCFT039|Full duplex||
+WPUPCFT040|Configurer TNC Multi-Port KISS||
+WPUPCFT041|Port radio||
+WPUPCFT042|Propri�t�s d'interface: Chemin UNPROTO douteux !||
+WPUPCFT043|SVP choisissez un chemin plus court tel que WIDE2-2 or WIDE1-1,WIDE2-2||
+WPUPCFT044|Propri�t�s d'interface: Chemin IGATE douteux !||
+WPUPCFT045|Transmission avec chemin UNPROTO douteux !||
+WPUPCFT046|Transmission avec chemin IGATE douteux !||
+WPUPCFT047|Initialiser mode KISS au d�marrage||
+#
+#
+# PopUp "Configure WX Port"
+WPUPCFWX01|Configurer port m�t�o||
+WPUPCFWX02|Port m�t�o||
+WPUPCFWX03|Correction globale de pluviom�tre||
+WPUPCFWX04|.1 pouce/2.5mm||
+WPUPCFWX05|.01 pouce/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|Pas de correction||
+#
+# PopUp "Configure - Station"
+WPUPCFS001|Configurer la station||
+WPUPCFS002|Indicatif||
+WPUPCFS003|LAT||
+WPUPCFS004|deg||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(E/O)||
+WPUPCFS009|Symbole de station||
+WPUPCFS010|Groupe/superposition||
+WPUPCFS011|Symbole||
+WPUPCFS028|Choisir||
+WPUPCFS012|Puissance - Hauteur (HAAT) - Gain - Directivit�||
+WPUPCFS013|D�sactiver PHG||
+WPUPCFS014|Hauteur de l'antenne||#'
+WPUPCFS015|Gain de l'antenne||#'
+WPUPCFS016|Omni||
+WPUPCFS017|Commentaire:||
+WPUPCFS018|Ambigu�t� de position||
+WPUPCFS019|Rien||
+WPUPCFS020|.11 milles||
+WPUPCFS021|1.15 milles||
+WPUPCFS022|11.51 milles||
+WPUPCFS023|69.09 milles||
+WPUPCFS024|.18 kilom�tres||
+WPUPCFS025|1.85 kilom�tres||
+WPUPCFS026|18.53 kilom�tres||
+WPUPCFS027|111.19 kilom�tres||
+WPUPCFS029|Transmettre positions compress�es|C|
+#
+# PopUp "Object/Item"
+POPUPOB001|Objet/Article||
+POPUPOB002|Nom||
+POPUPOB003|Cr�er nouvel objet||
+POPUPOB004|Supprimer objet||
+POPUPOB005|Modifier objet||
+POPUPOB006|Cr�er nouvel article||
+POPUPOB007|Objet polygonal||
+POPUPOB008|Objet polygonal||
+POPUPOB009|Couleur vive||
+POPUPOB010|Remplis de couleur||
+POPUPOB011|Cercle||
+POPUPOB012|Ligne-droite '/'||
+POPUPOB013|Ligne-gauche '\'||#'
+POPUPOB014|Triangle||
+POPUPOB015|Rectangle||
+POPUPOB016|Noir||
+POPUPOB017|Bleu||
+POPUPOB018|Vert||
+POPUPOB019|Cyan||
+POPUPOB020|Rouge||
+POPUPOB021|Violet||
+POPUPOB022|Jaune||
+POPUPOB023|Gris||
+POPUPOB024|D�calage haut:||
+POPUPOB025|D�calage gauche (sauf '/'):||
+POPUPOB026|Couloir:||
+POPUPOB027|Options g�n�riques||
+POPUPOB028|Placement||
+POPUPOB029|Activer panneau||
+POPUPOB030|Texte sur le panneau||#'
+POPUPOB031|Panneau||
+POPUPOB032|Activer compression||
+POPUPOB033|Supprimer article||
+POPUPOB034|Modifier article||
+POPUPOB035|Altitude (pieds):||
+POPUPOB036|Vitesse (noeuds):||
+POPUPOB037|Cap:||
+POPUPOB038|Objet DF||
+POPUPOB039|Signal - Hauteur (HAAT) - Gain - Directivit�||
+POPUPOB040|Largeur de faisceau - Rel�vement||
+POPUPOB041|Antenne omni||
+POPUPOB042|Antenne dirig�e||
+POPUPOB043|Inutile||
+POPUPOB044|Adopter objet||
+POPUPOB045|Adopter article||
+POPUPOB046|Rel�vement DF:||
+POPUPOB047|Cercles de probabilit�||
+POPUPOB048|Objet Map View||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+# PopUp "Configure Internet"
+WPUPCFI001|Configurer Internet||
+WPUPCFI002|H�te ||
+WPUPCFI003|Port ||
+WPUPCFI004|(H�te secondaire)||
+WPUPCFI005|H�te1||
+WPUPCFI006|Port1||
+WPUPCFI007|H�te2||
+WPUPCFI008|Port2||
+WPUPCFI009|Code d'acc�s||#'
+WPUPCFI010|(Laisser vide si nul)||
+WPUPCFI011|Reconnexion sur erreur r�seau ?||
+WPUPCFI012|Fonction IGate ?||
+WPUPCFI013|Diffusion de messages par le TNC lorsqu'en IGate ?||#'
+WPUPCFI014|Archivage des transactions IGate ?|||
+WPUPCFI015|Param�tres du filtre||
+#
+# PopUp "Configure Database"
+WPUPCFID01|Configurer base de donn�es (TBD)||
+WPUPCFID02|H�te ||
+WPUPCFID03|Port ||
+WPUPCFID04|(H�te secondaire)||
+WPUPCFID05|H�te1||
+WPUPCFID06|Port1||
+WPUPCFID07|H�te2||
+WPUPCFID08|Port2||
+WPUPCFID09|Code d'acc�s||#'
+WPUPCFID10|(Laisser vide si nul)||
+WPUPCFID11|Reconnexion sur erreur r�seau ?||
+WPUPCFID12|Fonction IGate ?||
+WPUPCFID13|Diffusion de messages par le TNC lorsqu'en IGate ?||#'
+WPUPCFID14|Archivage des transactions IGate ?|||
+WPUPCFID15|Param�tres du filtre||
+#
+# PopUp "Configure AGWPE"
+WPUPCFIA01|Configurer AGWPE||
+WPUPCFIA02|H�te ||
+WPUPCFIA03|Port ||
+WPUPCFIA04|(H�te secondaire)||
+WPUPCFIA05|H�te1||
+WPUPCFIA06|Port1||
+WPUPCFIA07|H�te2||
+WPUPCFIA08|Port2||
+WPUPCFIA09|Code d'acc�s||#'
+WPUPCFIA10|(Laisser vide si nul)||
+WPUPCFIA11|Reconnexion sur erreur r�seau ?||
+WPUPCFIA12|Fonction IGate ?||
+WPUPCFIA13|Diffusion de messages par le TNC lorsqu'en IGate ?||#'
+WPUPCFIA14|Archivage des transactions IGate ?|||
+WPUPCFIA15|RadioPort de transmission||
+#
+# PopUp "Configure Audio Alarms"
+WPUPCFA001|Configurer alarmes sonores||
+WPUPCFA002|Commande audio � utiliser||
+WPUPCFA003|Alarme pour:||
+WPUPCFA004|Fichier sonore||
+WPUPCFA005|Nouvelle station||
+WPUPCFA006|Nouveau message||
+WPUPCFA007|Proximit�||
+WPUPCFA008|Ouverture de bande||
+WPUPCFA009|Distance minimum||
+WPUPCFA010|Distance maximum||
+WPUPCFA011|Alerte m�t�o||
+#
+# PopUp "Configure Speech"
+WPUPCFSP01|Configurer parole||
+WPUPCFSP02|Parole pour:||
+WPUPCFSP03|Nouvelle station||
+WPUPCFSP04|Alerte nouveau message||
+WPUPCFSP05|Texte nouveau message||
+WPUPCFSP06|Proximit�||
+WPUPCFSP07|Ouverture de bande||
+WPUPCFSP08|Alerte m�t�o||
+WPUPCFSP09|Station suivie � proximit�||#'
+#
+# PopUp "Track Station"
+WPUPTSP001|Suivre station||
+WPUPTSP002|Suivre l'indicatif||#'
+WPUPTSP003|Casse exacte||
+WPUPTSP004|Correspondance exacte||
+WPUPTSP005|Suivre maintenant !||
+WPUPTSP006|Annuler suivi||
+WPUPTSP007|T�l�charger piste||
+WPUPTSP008|Indicatif||
+WPUPTSP009|D�but de piste (depuis .. heures)||
+WPUPTSP010|Longueur de piste (heures)||
+#
+# PopUp "Messages..."
+WPUPMSB001|Boite d'envoi %d||#'
+WPUPMSB002|Boite d'envoi au groupe %d||#'
+WPUPMSB003|Indicatif de station:||
+WPUPMSB004|Ident. du groupe:||
+WPUPMSB005|Nouvel/Refresh indicatif||
+WPUPMSB006|Nouveau groupe||
+WPUPMSB007|Effacer histoire de messages||
+WPUPMSB008|Message:||
+WPUPMSB009|Transmettre maintenant !||
+WPUPMSB010|Voie:||
+WPUPMSB011|Annuler messages en suspens||
+WPUPMSB012|RAZ minuterie Temporisateur||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Broadcast||
+WPUPMSB016|*EXPIRATION*||
+WPUPMSB017|*ANNULE*||
+WPUPMSB018|*REJETE*||
+WPUPMSB019|Changer chemin||
+WPUPMSB020|Utiliser chemin(s) par d�faut||
+WPUPMSB021|Direct (pas de chemin)||
+WPUPMSB022|Chemin inverse (pour info):||
+#
+# PopUp "Auto Reply"
+WPUPARM001|Modifier r�ponse automatique||
+WPUPARM002|R�ponse:||
+#
+# PopUp "Help Index"
+WPUPHPI001|Index d'Aide||#'
+WPUPHPI002|Lire||
+#
+# PopUp "Station Info"
+WPUPSTI000|Objet de: %s||
+WPUPSTI001|Information de station||
+WPUPSTI002|Composer un message||
+WPUPSTI003|Chercher dans la base FCC||
+WPUPSTI004|Chercher dans la base RAC||
+WPUPSTI005|Paquets recu: %d     Derni�re transmission: ||
+WPUPSTI006|Entendu sur le TNC %d, ||
+WPUPSTI007|Entendu ||
+WPUPSTI008|derni�rement sur port local||
+WPUPSTI009|derni�rement sur TNC %d||
+WPUPSTI010|derni�rement sur Internet %d||
+WPUPSTI011|derni�rement dans fichier||
+WPUPSTI012|derni�rement sur inconnu||
+WPUPSTI013|, et a boug�||
+WPUPSTI014|Puissance/gain/etc.:||
+WPUPSTI016|Altitude: %.0f%s ||
+WPUPSTI017|Cap: %s� ||
+WPUPSTI018|Vitesse: %.1f km/h||
+WPUPSTI019|Vitesse: %.1f milles/h||
+WPUPSTI020|%0.1f milles||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distance de ma station: %s  Rel�vement de ma station: %s||
+WPUPSTI023|Derni�re position : ||
+WPUPSTI024|Donn�es m�t�o %c:%s||
+WPUPSTI025|Cap des vents: %s� Vitesse: %03d km/h||
+WPUPSTI026|Cap des vents: %s� Vitesse: %s milles/h||
+WPUPSTI027|   Rafales: %03d km/h||
+WPUPSTI028|   Rafales: %s milles/h||
+WPUPSTI029|Temp�rature: %02.1f�C  ||
+WPUPSTI030|Temp�rature: %s�F   ||
+WPUPSTI031|Humidit�: %s%%   ||
+WPUPSTI032| Humidex: %02.1f�C  ||
+WPUPSTI033|Baro: %s hPa||
+WPUPSTI034|Neige: %0.1f (cm/24h||
+WPUPSTI035|Neige: %0.0f (pouces/24h)||
+WPUPSTI036|Pluie: ||
+WPUPSTI037|%0.2f (mm/h)   ||
+WPUPSTI038|%0.2f (pouces/h)   ||
+WPUPSTI039|%0.2f (mm/jour)  ||
+WPUPSTI040|%0.2f (pouces/jour)  ||
+WPUPSTI041|%0.2f (mm/depuis minuit)||
+WPUPSTI042|%0.2f (pouces/depuis minuit)||
+WPUPSTI043|Route des donn�es: %s||
+WPUPSTI044|Commentaire %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Effacer la piste||
+WPUPSTI046|Pluie Totale: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (pouces)||
+WPUPSTI049|Informations suivi||
+WPUPSTI050|Messages non confirm�s||
+WPUPSTI051|Info station en direct||
+WPUPSTI052|Info station version||
+WPUPSTI053|Modifier objet/article||
+WPUPSTI054|Sauver piste||
+WPUPSTI055|Echo de:||
+WPUPSTI056|Activer actualisation automatique||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|Rel�vement DF: %s||
+WPUPSTI059|Etat %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Temp combustible: %02.1f�C  ||
+WPUPSTI061|Temp combustible: %s�F   ||
+WPUPSTI062|Humidit� combustible: %s%%   ||
+WPUPSTI063|Baro: %0.2f in Hg||
+WPUPSTI064|Chercher alerte NWS||
+WPUPSTI065|Indicatif tactique: %s||
+WPUPSTI066|Assigner un indicatif tactique||
+WPUPSTI067|Port�e actuelle : %d milles||
+WPUPSTI068|nul||
+WPUPSTI069|d�faut||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|port�e||
+WPUPSTI073|Mauvais PHG||
+WPUPSTI074|Mauvais SHG||
+WPUPSTI075|Port�e DF||
+WPUPSTI076|Pas de signal d�tect�||
+WPUPSTI077|Signal d�tect� (peut-�tre))||
+WPUPSTI078|Signal d�tect� non d�codable||
+WPUPSTI079|Signal faible, parfois d�codable||
+WPUPSTI080|Signal brouill� mais copiable||
+WPUPSTI081|Un peu de bruit, avec un signal facilement d�codable||
+WPUPSTI082|Bon signal avec un peu de bruit||
+WPUPSTI083|Signal presque sans bruit||
+WPUPSTI084|Signal sans bruit||
+WPUPSTI085|Signal tr�s fort sans bruit||
+WPUPSTI086|MAUVAIS RELEVEMENT||
+WPUPSTI087|MAUVAIS NRQ||
+WPUPSTI088|Largeur de faisceau DF||
+WPUPSTI089|Longueur DF||
+WPUPSTI090|Invalide||
+WPUPSTI091|Changer la couleur de la piste||
+WPUPSTI092|Effacer rel�vements DF||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|Rayon ALOHA: %d %s||
+WPUPALO002|Stations dans le cercle ALOHA: %d||
+WPUPALO003| Digis:                  %d||
+WPUPALO004| Mobiles (en mouvement): %d||
+WPUPALO005| Mobiles (autres):       %d||
+WPUPALO006| Stations m�t�o:         %d||
+WPUPALO007| Stations fixes:         %d||
+WPUPALO008|Dernier calcul il y a %d %s %d %s.||
+WPUPALO666|Rayon ALOHA pas encore calcul�||
+#
+#
+# FCC-RAC Call Look up
+STIFCC0001|Recherche base de donn�es FCC||
+STIFCC0002|Recherche base de donn�es RAC||
+STIFCC0003|Nom:||
+STIFCC0004|Adresse:||
+STIFCC0005|Ville:||
+STIFCC0006|Etat:||
+STIFCC0007|Code postal:||
+STIFCC0008|License de base ||
+STIFCC0009|License avanc�e ||
+STIFCC0010|5 mots/min ||
+STIFCC0011|12 mots/min ||
+#
+#
+# FCC-RAC Call Look up
+STIFCC0100|Index FCC ancien, restauration||
+STIFCC0101|Recherche d'indicatif||
+STIFCC0102|Indicatif non trouv� !||
+STIFCC0103|Index RAC ancien, restauration||
+#
+#
+# Band open message
+UMBNDO0001|� une distance de||
+#
+#
+# Universal Options
+UNIOP00001|OK||
+UNIOP00002|Annuler||
+UNIOP00003|Fermer||
+UNIOP00004|milles||
+UNIOP00005|km||
+UNIOP00006|P�riph�rique||
+UNIOP00007|Ajouter||
+UNIOP00008|Supprimer||
+UNIOP00009|Propri�t�s||
+UNIOP00010|Permettre transmission ?||
+UNIOP00011|Activer au d�marrage ?||
+UNIOP00012|km/h||
+UNIOP00013|milles/h||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|pouces||
+UNIOP00018|mm/jour||
+UNIOP00019|pouces/jour||
+UNIOP00020|mm/h||
+UNIOP00021|pouces/h||
+UNIOP00022|mm/minuit||
+UNIOP00023|pouces/minuit||
+UNIOP00024|deg||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|pouces Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|R�gler l'horloge syst�me sur celle du GPS ?||
+UNIOP00030|R�p�teur digi ?||
+UNIOP00031|m||
+UNIOP00032|Appliquer|||
+UNIOP00033|Annuler||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|jour||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# PopUp "Station Chooser"
+STCHO00001|Choix de station||
+#
+# DISPLAY WX ALERT
+WPUPWXA001|Alerte m�t�o||
+WPUPWXA002|Liste d'alertes m�t�o||
+#
+# PopUp "Configure - Interfaces"
+WPUPCIF001|Interfaces install�es||
+WPUPCIF002|Choix du type d'interface||
+#
+# PopUp "Configure AX.25 TNC"
+WPUPCAX001|Configurer TNC AX.25||
+WPUPCAX002|Nom de l'interface AX.25||#'
+#
+# Interface device names
+IFDNL00000|Aucune||
+IFDNL00001|TNC port s�rie||
+IFDNL00002|TNC s�rie + GPS sur c�ble HSP||
+IFDNL00003|GPS port s�rie||
+IFDNL00004|M�t�o port s�rie||
+IFDNL00005|Serveur Internet||
+IFDNL00006|TNC AX25||
+IFDNL00007|GPS r�seau (par gpsd)||
+IFDNL00008|M�t�o par r�seau||
+IFDNL00009|TNC s�rie + GPS sur c�ble AUX||
+IFDNL00010|TNC KISS s�rie||
+IFDNL00011|Base de donn�es par r�seau (pas encore impl�ment�)||
+IFDNL00012|AGWPE par r�seau||
+IFDNL00013|TNC Multi-Port KISS s�rie||
+IFDNL00014|Base de donn�es SQL (Experimental)||
+#
+# Interface device info
+IFDIN00000|%s %2d %s sur port s�rie %s   %s||
+IFDIN00001|%s %2d %s connect� � %s:%d   %s||
+IFDIN00002|%s %2d %s avec interface nomm�e %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006|INACTIF||
+IFDIN00007| ACTIF ||
+IFDIN00008|ERREUR ||
+IFDIN00009|INCONNU||
+#
+# PopUp "Interface control"
+IFPUPCT000|Contr�le d'interface||#'
+IFPUPCT001|D�marrer||
+IFPUPCT002|Arr�ter||
+IFPUPCT003|D�marrer toutes||
+IFPUPCT004|Arr�ter toutes||
+#
+# IGate control
+IGPUPCF000|Options IGate||
+IGPUPCF001|Arr�ter traffic Internet||
+IGPUPCF002|Autoriser RF vers Internet seulement||
+IGPUPCF003|Autoriser RF->Inet et Inet->RF||
+IGPUPCF004|Voie Igate -> RF   ||
+#
+# WX Station
+WXPUPSI000|Station m�t�o||
+WXPUPSI001|Type de station m�t�o||
+WXPUPSI002|Donn�es courantes||
+WXPUPSI003|Cap des vents||
+WXPUPSI004|Vitesse des vents||
+WXPUPSI005|Rafales||
+WXPUPSI006|Temp�rature||
+WXPUPSI007|Pr�cipitation totale||
+WXPUPSI008|Pr�cipitation totale journali�re||
+WXPUPSI009|Barom�tre||
+WXPUPSI010|Humidit�||
+WXPUPSI011|Peet Bros ULTIMETER 2000 (mode acquisition de donn�es)||
+WXPUPSI012|Peet Bros ULTIMETER II||
+WXPUPSI013|Peet Bros ULTIMETER 2000 (mode paquet)||
+WXPUPSI014|Pr�cipitation horaire totale||
+WXPUPSI015|Total pr�cipitation 24 hrs||
+WXPUPSI016|Qualimetrics Q-Net||
+WXPUPSI017|Peet Bros ULTIMETER 2000 (mode complet)||
+WXPUPSI018|Point de ros�e||
+WXPUPSI019|Vents max.||
+WXPUPSI020|Facteur �olien||
+WXPUPSI021|Facteur humidex||
+WXPUPSI022|Baro 3 heures||
+WXPUPSI023|Temp�rature max.||
+WXPUPSI024|Temp�rature min.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Station Lists
+LHPUPNI000|Toutes stations||
+LHPUPNI001|Stations mobiles||
+LHPUPNI002|Stations m�t�o||
+LHPUPNI003|Stations locales (via TNC)||
+LHPUPNI004|Derni�res stations||
+LHPUPNI005|Objets et articles||
+LHPUPNI006|Mes objets et articles||
+LHPUPNI010|No.||
+LHPUPNI011|Indicatif||
+LHPUPNI012|#Paq||
+LHPUPNI013|Heure derni�re pos.||
+LHPUPNI014|Chemin||
+LHPUPNI015|PHG||
+LHPUPNI016|Commentaires||
+LHPUPNI100|Cap||
+LHPUPNI101|Vit.||
+LHPUPNI102|Alt.||
+LHPUPNI103|Lat||
+LHPUPNI104|Long||
+LHPUPNI105|#Paq||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|Cap||
+LHPUPNI201|Vit||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Lat/Lon ou UTM||
+#
+# Maps WX Alert styles
+PULDNMAT01|Voir cartes alertes au dessus des autres cartes||
+PULDNMAT02|Voir cartes alertes en desous des autres cartes||
+#
+# Error/popup messages
+POPEM00001|Erreur localisation !||
+POPEM00002|Station %s non trouv�e !||
+POPEM00003|Erreur de suivi !||
+POPEM00004|Erreur d'interface !||#'
+POPEM00005|Nom de port AX.25 invalide %s||
+POPEM00006|Nom de port AX.25 invalide %s||
+POPEM00007|Indicatif invalide %s||
+POPEM00008|Destination AX25 indicatif ou relais digi invalide||
+POPEM00009|Erreur ouverture socket AX.25, %s||
+POPEM00010|Erreur liaison socket AX.25, %s||
+POPEM00011|Pas de connection � l'indicatif AX.25 %s||#'
+POPEM00012|Erreur AX.25 sur sortie UI||
+POPEM00013|Probl�me avec fichier axports||
+POPEM00014|Nom de port AX.25 invalide %s||
+POPEM00015|Erreur ouverture d'interface %d Erreur majeure||#'
+POPEM00016|Erreur ouverture d'interface %d D�passement de temps||#'
+POPEM00017|Plus d'interfaces disponible !||#'
+POPEM00018|Demande de donn�e - Message � une ligne||
+POPEM00019|Transmission hors service port %d||
+POPEM00020|Erreur base de donn�es !||
+POPEM00021|Support AX.25 non compil� dans Xastir !||#'
+POPEM00022|Erreur d'entr�e !||#'
+POPEM00023|Aucun nom de lieu sp�cifi� !||
+POPEM00024|Le nom de lieu sp�cifi� est en cours d'utilisation !||#'
+POPEM00025|Pas trouv� !||
+POPEM00026|Suivi commencera quand elle appara�tra||
+POPEM00027|Mauvaise info.  Certains champs vides ?||
+POPEM00028|Ne peut ouvrir fichier||
+POPEM00029|Trouv� !||
+POPEM00030|Symbole de station m�t�o||
+POPEM00031|Chang� en symbole m�t�o '/_', autres possibilit�s:  '\_'  '/W'  et  '\W'||
+POPEM00032|Attention: utilise symbole du "National Weather Service" !||
+POPEM00033|Pas de donn�es GPS !||
+POPEM00034|TX de ma position d�sactiv� jusqu'a r�ception de bonnes donn�es GPS !||#'
+POPEM00035|Avertissement||
+POPEM00036|Avis||
+POPEM00037|Interface HSP pr�sente: temporisation GPS augment�e||
+POPEM00038|Conflit de nom avec un Objet/Item/Station d�j� existant||
+POPEM00039|Caract�re ill�gal, remplac� par un point||
+POPEM00040|Le chemin de sortie personnalis� a �t� perdu||
+POPEM00041|Traitement d'un autre fichier en cours. Attendez, puis r�essayez||
+POPEM00042|L'object ne m'appartient pas ! Essayez d'adopter l'objet d'abord.||
+POPEM00043|Ce n'est pas un objet ou article !||
+POPEM00044|R�cup�ration de piste Findu : �chec||
+POPEM00045|R�cup�ration de piste Findu : Termin�||
+POPEM00046|La biblioth�que Berkeley DB ne correspond pas ! D�sactivation du cache des cartes.||
+POPEM00047|Toutes les transmissions sont DESACTIVEES. Les balises d'urgences ne seront PAS envoy�es!||
+POPEM00048|Mode balise d'URGENCE!||
+POPEM00049|MODE BALISE D'URGENCE, transmission toutes les 60 secondes!||
+POPEM00050|Interfaces ou trans.position DESACTIVEES.  Les balises d'urgences ne seront PAS envoy�es!||
+POPEM00051|R�seau alternatif (ALTNET) activ� (Menu Fichier->Configurer->Defauts)||
+POPEM00052|Indicatif est VIDE!||
+POPEM00053|Message est VIDE!||
+POPEM00054|Vous essayez de communiquer avec vous m�me!||
+#
+# Jump Location
+JMLPO00001|Afficher Cartes Favorites||
+JMLPO00002|Aller !||
+JMLPO00003|Nouveau nom de lieu:||
+#
+# Bulletins
+BULMW00001|Bulletins||
+BULMW00002|Limiter la port�e � (0, aucune limite)||
+BULMW00003|Changer port�e||
+#
+# All Message Traffic
+AMTMW00001|Tout trafic des messages||
+AMTMW00002|Limiter la port�e � (0, aucune limite)||
+#
+# Speech Strings
+SPCHSTR001|kilom�tres||
+SPCHSTR002|m�tres||
+SPCHSTR003|milles||
+SPCHSTR004|yards||
+SPCHSTR005|%s, distance est %d %s.||
+SPCHSTR006|%s, distance est %.1f %s.||
+SPCHSTR007|%s, distance est %d %s %s %s.||
+SPCHSTR008|%s, distance est %.1f %s %s %s.||
+SPCHSTR009|Nouvelle alerte m�t�o||
+SPCHSTR010|Nouvel indicatif||
+SPCHSTR011|Re�u, D X, %s, � une distance de %.1f %s||
+#
+#
+SPCHDIRN00|au nord de||
+SPCHDIRS00|au sud de||
+SPCHDIRE00|� l'est de||
+SPCHDIRW00|� l'ouest de||
+SPCHDIRNE0|au nord-est de||
+SPCHDIRNW0|au nord-ouest de||
+SPCHDIRSE0|au sud-est de||
+SPCHDIRSW0|au sud-ouest de||
+#
+# Symbol Selection Dialog
+SYMSEL0001|Choisir symbole||
+SYMSEL0002|Table de symboles primaire||
+SYMSEL0003|Table de symboles secondaire||
+#
+# Print Properties Dialog
+PRINT0001|Propri�t�s d'impression||
+PRINT0002|Taille du papier||
+PRINT0003|Rotation automatique d'image||
+PRINT0004|Tourner image 90� � gauche||
+PRINT0005|Proportion automatique d'image||
+PRINT0006|�chelle:||
+PRINT0007|Forcer le fond � �tre blanc||
+PRINT0008|Imprimer en noir et blanc||
+PRINT0016|Inverser couleurs||
+PRINT0009|R�solution Postscript:||
+PRINT0010|Pr�visualiser||
+PRINT0011|Imprimer dans un fichier||
+PRINT0012|Sauvegarde de l'image dans un fichier...||
+PRINT0013|Conversion Postscript...||
+PRINT0014|Cr�ation du fichier d'impression finie||
+PRINT0015|Etat d'impression||
+#
+# Print Properties Dialog
+PRINT1001|Directement �:||
+PRINT1002|Via Previewer:||
+#
+# Locate Feature Dialog
+FEATURE001|Nom:||
+FEATURE002|Etat/Province:||
+FEATURE003|Comt�:||
+FEATURE004|Quadrant de carte:||
+FEATURE005|Type :||
+FEATURE006|Fichier GNIS :||
+FEATURE007|Adresse :||
+FEATURE008|Ville :||
+FEATURE009|Marquer la destination||
+FEATURE010|Code postal :||
+FEATURE011|Fichier Geocoding||
+#
+# Coordinate Calculator Dialog
+COORD001|Calculatrice de coordon�es||
+COORD002|Calc||
+COORD003|Calculer||
+COORD004|Effacer||
+COORD005|UTM||
+COORD006|Latitude ou||
+COORD007|Longitude ou||
+COORD008|Zone||
+COORD009|UTM vers l'est||
+COORD010|UTM vers le nord||
+COORD011|               Degr�s d�cimaux:  ||
+COORD012|      Degr�s/Minutes d�cimales:  ||
+COORD013|  Degr�s/Minutes/secondes d�c.:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|Syst. de r�f. grille militaire:  ||
+COORD016|     Grille Locator Maidenhead:  ||
+COORD017| **         D�sol�, entr�e non reconnue !          **||
+COORD018| **   SVP utilisez l'un de ces formats d'entr�e:   **||
+#
+#
+# Smart Beaconing Dialog
+SMARTB001|Balise intelligente (Smart Beaconing)||
+SMARTB002|Intervalle maximal (secs):||
+SMARTB003|Vitesse haute (m/h):||
+SMARTB004|Vitesse haute (k/h):||
+SMARTB005|Intervalle minimal (mins):||
+SMARTB006|Vitesse basse (m/h):||
+SMARTB007|Vitesse basse (k/h):||
+SMARTB008|Virage minimum (deg):||
+SMARTB009|Pente de virage:||
+SMARTB010|Temps d'attente (secs):||#'
+SMARTB011|Activer SmartBeaconing(tm)||
+#
+#
+#
+# Gamma Adjust Dialog
+GAMMA001|Ajuster correction de gamma||
+GAMMA002|Correction de gamma||
+#
+#
+# 
+# Map labels font Dialog
+MAPFONT001|Changer police de carat�res||
+MAPFONT002|Police de carat�res||
+MAPFONT003|Police de carat�re des cartes Minusc||
+MAPFONT004|Police de carat�re des cartes Petite||
+MAPFONT005|Police de carat�re des cartes Moyenne||
+MAPFONT006|Police de carat�re des cartes Large||
+MAPFONT007|Police de carat�re des cartes Enorme||
+MAPFONT008|Police de carat�re des cartes Border||
+MAPFONT009|Police de carat�re des menus||
+MAPFONT010|Police de carat�re des Stations||
+MAPFONT011|Police de carat�re de l'ID ATV||
+#
+#
+#
+# Distance/Bearing on status line
+PULDNDB001|Etat dist/rel�vement||
+#
+#
+# GPS Transfer Operations
+GPS001|Transfert GPS||
+GPS002|Nom de fichier||
+GPS003|Choisir couleur||
+GPS004|Rouge||
+GPS005|Vert||
+GPS006|Noir||
+GPS007|Blanc||
+GPS008|Orange||
+GPS009|Bleu||
+GPS010|Jaune||
+GPS011|Violet||
+#
+#
+# Map Properties Dialog
+MAPP001|Caract�ristiques des cartes||
+MAPP002|Max   Min   Carte  Afficher USGS Auto||
+MAPP003|Zoom  Zoom  Couche Remplie  DRG  Cartes Voie/Fichier||
+MAPP004|Modifier Couche->||
+MAPP005|Remplie->||
+MAPP006|Oui||
+MAPP007|Non||
+MAPP008|AutoCartes->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+#
+# Time Strings
+TIME001|jour||
+TIME002|jours||
+TIME003|heure||
+TIME004|heures||
+TIME005|minute||
+TIME006|minutes||
+TIME007|seconde||
+TIME008|secondes||
+#
+#
+# Map Caching
+CACHE001|La carte se trouve dans le cache||
+CACHE002|Chargement de la carte en m�moire||
+CACHE003|Carte non trouv�e dans le cache...||
+#
+#
+# Map Screen Misc
+RANGE001|�CHELLE||
+#
+#
+# GPS Status
+GPSS001|WAAS ou PPS||
+GPSS002|DGPS||
+GPSS003|SPS valide||
+GPSS004|Invalide||
+GPSS005|Sats/vue||
+GPSS006|Rep�re||
+GPSS007|! Les donn�es GPS ont plus de 30 secondes !||
+GPSS008|Simulation||
+GPSS009|Manuel||
+GPSS010|Estim�||
+GPSS011|RTK flottant||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data
+CADPUD001|Object surface||
+CADPUD002|Etiquette surface:||
+CADPUD003|Commentaire:||
+CADPUD004|Probabilit� (%):||
+CADPUD005|OK||
+CADPUD006|Dialogue CAD||
+CADPUD007|Montrer/�diter les d�tails||
+CADPUD008|Annulerl||
+CADPUD009|Effacer les objets CAD ?||
+CADPUD010|Tout effacer||
+CADPUD011|Effacer la s�lection||
+CADPUD012|Continue||
+CADPUD013|pointilli�s||
+CADPUD014|Double pointilli�s||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|Carte XASTIR de %s (haut gauche) � %s (bas droit).  UTM %d m grid, %s datum. ||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA002|carte XASTIR de %s (haut gauche) � %s %s (bas droit).  Lat/Long grid, %s datum.||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA003|Carte XASTIR Map de %s (haut gauche) � %s (bas droit).  UTM zones, %s datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST002|Postgreql avec Postgis||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Sch�ma simple Xastir||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA02|Sch�ma CAD Xastir||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA03|Sch�ma complet Xastir||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA04|Sch�ma APRSWorld||
diff --git a/config/language-German.sys b/config/language-German.sys
new file mode 100644
index 0000000..5ae4ef2
--- /dev/null
+++ b/config/language-German.sys
@@ -0,0 +1,1363 @@
+# $Id: language-German.sys,v 1.240 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the German Language file used for all the prompts in xastir
+# Dies ist die deutsche Sprachdatei f�r Menus und Textausgaben in Xastir
+#
+# Creator        : Kai Altenfelder, DL3LBA <ka at suse.de>
+# Maintained by  : The Xastir Group <xastir at xastir.org>
+# Modified by    : 08.04.2007, Rolf Bleher, DK7IN <xastir at dk7in.de>
+#
+# comment lines with pound signs in front are ignored
+# File format as follows:
+# ID (10 chars alpha+numeric)|(String associated with id)|QuickKeys|#comment
+# The ID is a unique uppercase char string for each block followed by a nummer
+#
+# WARNING:
+# Some strings contain formatting commands like %s and %d, you should not
+# change these. Wrong format strings could produce a segfault!
+#
+# Warnung:
+# Einige Texte enthalten Formatierungsbefehle wie %s oder %d, diese sollten
+# beibehalten werden. Falsche Formatbefehle k�nnen zu einem Programmabsturz
+# f�hren.
+#
+# Hauptmenu
+MENUTB0001|Datei|D|
+MENUTB0002|Zeige|Z|
+MENUTB0004|Karten|K|
+MENUTB0005|Stationen|S|
+MENUTB0006|Nachrichten|N|
+MENUTB0010|Schnittstellen|i|
+MENUTB0009|Hilfe|H|
+#
+# Menu "Datei"
+PULDNFI001|Einstellungen|E|
+PULDNFI002|Protokolldatei laden|P|
+PULDNFI003|Test|T|
+PULDNFI004|Beenden|B|
+PULDNFI007|Debug Level �ndern|D|
+PULDNFI010|TNC protokollieren||
+PULDNFI011|Netz protokollieren||
+PULDNFI012|IGate protokollieren||
+PULDNFI013|Wetter protokollieren||
+PULDNFI014|PNG-Schnapsch�sse||
+PULDNFI015|Karte drucken|d|
+PULDNFI016|KML Snapshots||
+#
+# Menu "Zeige"
+PULDNVI001|Bekanntmachungen|B|
+PULDNVI002|Packet Radio|P|
+PULDNVI003|Mobilstationen|M|
+PULDNVI004|Alle Stationen|A|
+PULDNVI009|Lokale Stationen|L|
+PULDNVI012|Letzte Stationen|S|
+PULDNVI005|Wetterstationen|W|
+PULDNVI008|Eigene Wetterdaten|d|
+PULDNVI007|Wetterwarnung|e|
+PULDNVI011|Nachrichten|N|
+PULDNVI013|Laufzeit|z|
+PULDNVI014|Programmlaufzeit||
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statistiken||
+#
+# Menu "Einstellungen"
+PULDNCF004|Meine Stationsdaten|M|
+PULDNCF001|Grundeinstellungen|G|
+PULDNCF003|Zeitverhalten|Z|
+PULDNCF002|Koordinatensystem|K|
+PULDNCF006|Audio Alarm|A|
+PULDNCF007|Sprachausgabe|S|
+PULDNCF008|Einstellungen sichern|E|
+# (Einheiten siehe PULDNDP006)
+#
+# Menu "Karten"
+PULDNMP001|Kartenauswahl|K|
+PULDNMP012|Ausschnitte|A|
+PULDNMP014|Objekt in Karte suchen|O|
+PULDNMP016|Disable Fast Zoom/Pan/Home||
+PULDNMP013|Alle Karten verbergen||
+PULDNMP002|Automatische Karten||
+PULDNMP003|Gitter||
+PULDNMP004|Ebenen||
+PULDNMP010|Kartenbeschriftung||
+PULDNMP009|Fl�chen einf�rben||
+PULDNMP007|Wetterwarnung||
+PULDNMP005|Hintergrundfarbe|H|
+PULDNMP006|Textdarstellung|T|
+PULDNMP026|Symbol Umrandung|U|
+PULDNMP011|Mauszeiger-Men�|M|
+PULDNMP008|Intensit�t|I|
+PULDNMP020|Einstellungen Tigermaps||
+PULDNMP021|Autom. Karten - PixelKarten aus||
+PULDNMP022|Neue Karten beim Start indizieren||
+PULDNMP023|Index: Neue Karten hinzuf�gen|N|
+PULDNMP024|Index: ALLE Karten reindizieren|r|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsel||
+PULDNMP027|Karten neu laden (nicht vom Cache)||
+PULDNMP028|L�sche gesamten Karten-Cache!||
+PULDNMP029|Finde Adresse||
+PULDNMP030|Konfiguration USGS DRG||
+PULDNMP031|Kartenrand ein||
+#
+#
+# PopUp "Einstellungen Tigermaps"
+MPUPTGR001|Gitter||
+MPUPTGR002|Counties||
+MPUPTGR003|Orts-Beschr.||
+MPUPTGR004|Urbane Bereiche||
+MPUPTGR005|Hauptstrassen||
+MPUPTGR006|Strassen||
+MPUPTGR007|Eisenbahn||
+MPUPTGR008|State Beschr.||
+MPUPTGR009|Interstate Beschr||
+MPUPTGR010|US Hwy Beschr.||
+MPUPTGR011|State Hwy Beschr.||
+MPUPTGR012|Anzeigen von:||
+MPUPTGR013|Fl�sse||
+MPUPTGR014|Seen||
+MPUPTGR015|Flugh�fen, Parks, etc||
+MPUPTGR016|Karten Intensit�t||
+MPUPTGR017|Internet-Karten Timeout [Sek]||
+MPUPTGR018|Tiger Maps erlauben||
+#
+# PopUp "Configure USGS DRG"
+MPUPDRG001|W�hle darzustellende Objekte:||
+MPUPDRG002|f�rbe Hintergrundkarten (XOR)||
+MPUPDRG003|Schwarz||
+MPUPDRG004|Wei�||
+MPUPDRG005|Blau||
+MPUPDRG006|Rot||
+MPUPDRG007|Braun||
+MPUPDRG008|Gr�n||
+MPUPDRG009|Violett||
+MPUPDRG010|Gelb||
+MPUPDRG011|Hellblau||
+MPUPDRG012|Rosa||
+MPUPDRG013|Violett (hell)||
+MPUPDRG014|Hellgrau||
+MPUPDRG015|Hellbraun||
+#
+#
+# PopUp "Kartenauswahl"
+WPUPMCP001|Kartenauswahl||
+PULDNMMC01|Keine|K|
+PULDNMMC02|Vektor|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Verz. expandieren|e|
+PULDNMMC07|Verz/Karten gew�hlt:||
+PULDNMMC08|Verz. l�schen|l|
+PULDNMMC09|Alles w�hlen|A|
+#
+# Karten - Hintergrundfarbe
+PULDNMBC01|Grau||
+PULDNMBC02|Helles Grau||
+PULDNMBC03|Dunkelblau||
+PULDNMBC04|Hellblau||
+PULDNMBC05|Gr�n||
+PULDNMBC06|Hellgr�n||
+PULDNMBC07|Gelb||
+PULDNMBC08|Zartes Gelb||
+PULDNMBC09|R�tliches Braun||
+PULDNMBC10|Rot||
+PULDNMBC11|Wei�||
+PULDNMBC12|Schwarz||
+#
+# Karten - Stil der Stationstexte
+PULDNMSL01|Schwarze Umrandung|U|
+PULDNMSL02|Schatten|S|
+PULDNMSL03|Schwarzer Hintergrund|H|
+#
+# PullDown "Symbol Umrandung"
+PULDNMIO01|Keine Umrandung|K|
+PULDNMIO02|Schwarze Umrandung|S|
+PULDNMIO03|Graue  Umrandung|G|
+PULDNMIO04|Wei�e Umrandung|W|
+#
+# Schalter
+PULDNOT001|An||
+PULDNOT002|Aus||
+PULDNOT003|Kurz||
+#
+# Menu "Stationen"
+PULDNDP014|Station finden|f|
+PULDNDP001|Verfolge Station|V|
+PULDNDP022|Spur von findu holen|h|
+PULDNDP032|Daten filtern||
+PULDNDP040|Nichts||
+PULDNDP041|Meine Daten||
+PULDNDP042|TNC||
+PULDNDP027|- Direkt||
+PULDNDP043|- �ber Digi||
+PULDNDP034|Netzwerk||
+PULDNDP019|Alte Daten einbeziehen||
+PULDNDP044|Stationen||
+PULDNDP028|- Feste Stationen||
+PULDNDP029|- Bewegte Stationen||
+PULDNDP030|- Wetterstationen||
+PULDNDP053|  - CWOP-Stationen||
+PULDNDP045|Objekte||
+PULDNDP026|- Wetter Objekte||
+PULDNDP039|- Regenmengen Objekte||
+PULDNDP031|- Andere Objekte||
+PULDNDP033|Anzeige filtern||
+PULDNDP010|Rufzeichen||
+PULDNDP012|Symbol||
+PULDNDP011|- Symbol drehen||
+PULDNDP007|Spur||
+PULDNDP003|Kurs||
+PULDNDP004|Geschwindigkeit||
+PULDNDP017|- kurz||
+PULDNDP002|H�he||
+PULDNDP009|Wetterdaten||
+PULDNDP046|- Wetter Text||
+PULDNDP018|-- nur Temperatur||
+PULDNDP047|- Windfahne||
+PULDNDP054|ALOHA Kreis anzeigen||
+PULDNDP013|Positionsverschleierung||
+PULDNDP008|Leistung/Gewinn||
+PULDNDP021|- mit Standardwert||
+PULDNDP020|- bei Mobilstationen||
+PULDNDP023|DF Kreise zeigen||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearing||
+PULDNDP035|Positionsvoraussage||
+PULDNDP036|- Kreis zeigen||
+PULDNDP037|- Kurs zeigen||
+PULDNDP038|- Symbol zeigen||
+PULDNDP005|Entfernung/Richtung||
+PULDNDP024|Alter des letzten Empfangs||
+PULDNDP015|Stationen l�schen|l|
+PULDNDP016|Spuren l�schen|S|
+PULDNDP025|ObjektHistorie l�schen||
+PULDNDP048|ObjektHistorie erneut laden||
+PULDNDP049|L�schen aller taktischen Calls||
+PULDNDP050|L�schen Verlauf taktische Calls||
+PULDNDP051|Nur taktische Calls w�hlen||
+PULDNDP052|- Wegpunkte bezeichnen||
+PULDNDP055|Exportieren|E|
+PULDNDP056|Export in KML-Datei||
+#
+# Ma�einheiten
+PULDNUT001|Englische Ma�e||
+PULDNUT002|Metrisch||
+#
+# Menu "Nachrichten"
+PULDNMG001|Schicke Nachricht an|N|
+PULDNMG002|�ffne Gruppen Nachricht|G|
+PULDNMG003|L�sche alle ausgehenden Nachrichten|L|
+PULDQUS001|Abfrage Stationen allgemein|S|
+PULDQUS002|Abfrage Internet-Gateways|I|
+PULDQUS003|Abfrage Wetterstationen|W|
+PULDNMG004|Setze automatische Antwort|t|
+PULDNMG005|Automatische Antwort|A|
+PULDNMG006|Satelliten ACK Modus|M|
+PULDNMG007|Unerledigte Nachrichten zeigen|U|
+#
+# Menu "Schnittstellen"
+PULDNTNT04|Schnittstellensteuerung||
+PULDNTNT03|Nicht senden: ALLES||
+PULDNTNT05|Nicht senden: Meine Position||
+PULDNTNT06|Nicht senden: Objekte||
+PULDNTNT11|aktiviere Server-Port||
+PULDNTNT01|Sende jetzt!|S|
+PULDNTNT07|Lade GPS Track|T|
+PULDNTNT08|Lade GPS Route|R|
+PULDNTNT09|Lade GPS Wegpunkte|W|
+PULDNTNT10|Garmin RINO Wegpunkte holen|G|
+#
+# Menu "Hilfe"
+PULDNHEL01|Version|V|
+PULDNHEL02|Hilfe Index|I|
+PULDNHEL03|NOTFALL BAKEN MODUS EINSCHALTEN|E|
+PULDNHEL04|!!! NOTFALL BAKEN MODUS !!!||
+PULDNHEL05|�ber Xastir||
+#
+# Mauszeiger PopUp Menu
+POPUPMA001|Mauszeiger-Menu||
+POPUPMA00c|Zentrieren||
+POPUPMA015|Stations-Info||
+POPUPMA002|Zoome hinein||
+POPUPMA003|Zoome heraus||
+POPUPMA004|Zoomebenen||
+POPUPMA005|Ebene 1||
+POPUPMA006|Ebene 16||
+POPUPMA007|Ebene 64||
+POPUPMA008|Ebene 256||
+POPUPMA009|Ebene 1024||
+POPUPMA010|Ebene 8192||
+POPUPMA017|Ganze Welt||
+POPUPMA016|Letzte Ansicht||
+POPUPMA018|Objekt Neu||
+POPUPMA019|Objekt �ndern||
+POPUPMA025|Meine Station hierhin!|h|
+POPUPMA011|nach oben||
+POPUPMA012|nach unten||
+POPUPMA013|nach links||
+POPUPMA014|nach rechts||
+POPUPMA020|Messen||
+POPUPMA021|Bewegen||
+POPUPMA022|Verfolge mich||
+POPUPMA023|Modifikationstasten aktiv!||
+POPUPMA024|Bitte Umschalt/Num/Rollen/andere Modifikationstasten ausschalten||
+POPUPMA026|Zentrieren & Zoom||
+POPUPMA027|    Breite||
+POPUPMA028|     L�nge||
+POPUPMA029|CAD-Objekte zeichnen||
+POPUPMA030|Zeichnen||
+POPUPMA031|Polygon abschlie�en||
+POPUPMA032|CAD-Polygone l�schen||
+POPUPMA033|**NICHT BENUTZT**||
+POPUPMA034|Selbstdefinierter Zoom||
+POPUPMA035|10% verkleinern||
+POPUPMA036|10% vergr��ern||
+POPUPMA037|Bereich||
+POPUPMA038|Quadrat||
+POPUPMA039|Quadratfuss||
+POPUPMA040|Quadratmeter||
+POPUPMA041|Peilung||
+POPUPMA042|Grad||
+POPUPMA043|Bearbeite mehrdeutige Position||
+POPUPMA044|Mehrdeutige Position, Ihre Position kann sich sprunghaft ver�ndern.||
+POPUPMA045|Vordefinierte Objekte||
+POPUPMA046|CAD-Polygone||
+POPUPMA047|CAD-Objekte ein||
+POPUPMA048|CAD-Label ein||
+POPUPMA049|CAD-Kommentare ein||
+POPUPMA050|CAD-Wahrscheinlichkeit ein||
+POPUPMA051|CAD-Fl�chenma� ein||
+POPUPMA052|sq||
+POPUPMA053|Fu�||
+POPUPMA054|Meter||
+POPUPMA055|Meilen|
+#
+# Texte in Statuszeile
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Tr||
+BBARSTH001|%d/%d Stationen||
+BBARSTA000|%-9s Neues Objekt!||
+BBARSTA001|%-9s Neue Station!||
+BBARSTA002|%-9s||# neue Daten (nur Call angezeigt)
+BBARSTA003|Lade Karten...||
+BBARSTA004|Karten geladen||
+BBARSTA005|Kartengitter An||
+BBARSTA006|Kartengitter Aus||
+BBARSTA007|Automatische Karte ist AN||
+BBARSTA008|Automatische Karte ist AUS||
+BBARSTA009|Kartenebenen sind AN||
+BBARSTA010|Kartenebenen sind AUS||
+BBARSTA011|Automatische Antwort AUS!||
+BBARSTA012|Datei beendet..||
+BBARSTA013|�ffne GPS Port||
+BBARSTA014|Schlie�e GPS Port||
+BBARSTA015|GPS RMC String empfangen||
+BBARSTA016|GPS GGA String empfangen||
+BBARSTA017|Netz vom Host getrennt||
+BBARSTA018|Timeout beim Verbindungsaufbau!||
+BBARSTA019|Suche Host %s||
+BBARSTA020|Verbunden mit %s||
+BBARSTA021|Netzverbindung fehlgeschlagen!||
+BBARSTA022|Konnte keinen Socket erstellen!||
+BBARSTA023|Keine IP f�r Host!||
+BBARSTA024|Kein Host angegeben||
+BBARSTA025|Host gefunden, verbinde %d||
+BBARSTA026|Warte auf GPS Daten via HSP..||
+BBARSTA027|Setze HSP auf TNC Daten..||
+BBARSTA028|Laden von %s||
+BBARSTA029|�ffne WX Port||
+BBARSTA030|Schlie�e WX Port||
+BBARSTA031|Pr�fe Hostname %d||
+BBARSTA032|Dekodiere Wetterdaten||
+BBARSTA033|Echo vom Digipeater||
+BBARSTA034|Lade Wetterwarnungs-Karten||
+BBARSTA035|Warte auf GPS Daten via AUX..||
+BBARSTA036|Setze AUX auf TNC Daten..||
+BBARSTA037|Dekodiere GPS Daten||
+BBARSTA038|eigene Position ge�ndert||
+BBARSTA039|Indizieren %s||
+BBARSTA040|APRS(tm) Station %s||
+BBARSTA041|Warten auf GPS Daten..||
+BBARSTA042|Senden von Objekten||
+BBARSTA043|Protokoll||
+BBARSTA044|ALOHA Entfernung betr�gt %d%s||
+BBARSTA045|Lade Symbole...||
+BBARSTA046|Lade Symbole neu...||
+BBARSTA047|Initialisiere meine Station...||
+BBARSTA048|Starte Schnittstellen...||
+BBARSTA049|Lesen der Kacheln...||
+BBARSTA050|Laden der Kacheln...||
+BBARSTA051|Laden Kachel %li von %li||
+#
+# PopUp "Zeige - Packet Radio"
+WPUPDPD001|Packet Radio Daten||
+WPUPDPD002|Nur TNC Daten||
+WPUPDPD003|Nur Internet Daten||
+WPUPDPD004|TNC und Internet Daten||
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Stations-Resourcen||
+WPUPDPD008|Nur meine||
+#
+# PopUp "Station - Station finden"
+WPUPLSP001|Finde Station||
+WPUPLSP002|Rufzeichen||
+WPUPLSP003|Gro�/Klein||# ???
+WPUPLSP004|Exakt||# ???
+WPUPLSP005|Finde jetzt!||
+WPUPLSP006|Notfall-Suche!||
+WPUPLSP007|FCC/RAC Suche||
+#
+# PopUp "Einstellungen - Grundeinstellungen"
+WPUPCFD001|Grundeinstellungen||
+WPUPCFD002|Nach welcher Zeit gilt eine Station als alt?||
+WPUPCFD003|15 Minuten||
+WPUPCFD004|30 Minuten||
+WPUPCFD005|45 Minuten||
+WPUPCFD006|1 Stunde||
+WPUPCFD007|90 Minuten||
+WPUPCFD008|2 Stunden||
+WPUPCFD009|Nach welcher Zeit wird eine Station nicht mehr angezeigt?||
+WPUPCFD010|6 Stunden||
+WPUPCFD011|12 Stunden||
+WPUPCFD012|1 Tag||
+WPUPCFD013|2 Tage||
+WPUPCFD014|1 Woche||
+WPUPCFD015|Sendeformat der Station||
+WPUPCFD016|Feste Station||
+WPUPCFD017|Mobile Station mit lokaler Zeit||
+WPUPCFD018|Mobile Station mit UTC Tag/Zeit||
+WPUPCFD019|Mobile Station mit UTC Zeit/Sekunden||
+WPUPCFD021|Station mit Position und Wetter||
+WPUPCFD022|Station mit UTC Zeit, Position und Wetter||
+WPUPCFD023|Sende Wetter Rohdaten?||
+WPUPCFD024|Komprimiertes Format beim Senden von Objekten?||
+WPUPCFD025|Alternatives Netz?||
+WPUPCFD026|Sende Positionsmeldung in folgenden Intervallen||
+WPUPCFD027|PopUp-Fenster f�r neue Bekanntmachungen||
+WPUPCFD028|Warnung bei Modifikationstasten||
+WPUPCFD029|Anzeige bei Entfernung Null||
+WPUPCFD030|Position Dubletten-Pr�fung aus||
+WPUPCFD031|Vordefinierte Objekte aus Datei laden||
+WPUPCFD032|Meine Spuren in einer Farbe||
+WPUPCFD033|ALTNET:||
+#
+# PopUp "Zeitverhalten"
+WPUPCFTM01|Einstellung des Zeitverhaltens|||
+WPUPCFTM02|SendeIntervall Position [Min]||
+WPUPCFTM03|Station schemenhaft nach [Min]||
+WPUPCFTM04|Max SendeIntervall Objekt [Min]||
+WPUPCFTM05|Alte Station anzeigen f�r [Std]||
+WPUPCFTM06|GPS Abfrage alle [Sek]||
+WPUPCFTM07|Station l�schen nach [Tage]||
+WPUPCFTM08|Timeout Pos-Voraussage [Min]||
+WPUPCFTM09|Abstand zw. seriellen Zeichen (ms)||
+WPUPCFTM10|Neue Spur Zeit (Min)||
+WPUPCFTM11|Neue Spur Intervall (Grad)||
+WPUPCFTM12|RINO -> Objekt Intervall (min), 0 = Aus||
+WPUPCFTM13|Schnapschu�-Intervall (min)||
+#
+# PopUp "Koordinatensystem"
+WPUPCFC001|Koordinatensystem||
+WPUPCFC002|Koordinatensystem w�hlen||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM mit Spezialzonen||
+#
+# PopUp "GPS Einstellungen"
+WPUPCFG001|GPS Einstellungen||
+WPUPCFG003|GPS Port||
+WPUPCFG002|GPS Position benutzen?||
+WPUPCFG004|GPS Optionen||
+WPUPCFG005|Eigenst�ndiger GPS||
+WPUPCFG006|TNC mit GPS verbunden (HSP Kabel)||
+WPUPCFG007|TNC mit GPS verbunden �ber Ctrl-E||
+WPUPCFG008|GPS-Abfrage alle||
+WPUPCFG009|5 Sek||
+WPUPCFG010|15 Sek||
+WPUPCFG011|30 Sek||
+WPUPCFG012|1 Minute||
+WPUPCFG013|2 Minuten||
+WPUPCFG014|5 Minuten||
+WPUPCFG015|10 Minuten||
+WPUPCFG016|GPS �ber Netzwerk verbunden||
+WPUPCFG017|gpsd Host||
+WPUPCFG018|gpsd Port||
+WPUPCFG019|GPS �ber Netz via gpsd||
+WPUPCFG020|Wiederverbinden nach Fehler?||
+WPUPCFG021|Wetter �ber Netzwerk||
+WPUPCFG022|Wetterstation Host||
+WPUPCFG023|Wetterstation Port||
+#
+# TNC Einstellungen
+WPUPCFT001|TNC Einstellungen||
+WPUPCFT002|TNC benutzen?||
+WPUPCFT003|TNC Port||
+WPUPCFT004|Port Geschwindigkeit||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|UnProto Pfade||
+WPUPCFT012|Pfad 1: %s via ||
+WPUPCFT013|Pfad 2: %s via ||
+WPUPCFT014|Pfad 3: %s via ||
+WPUPCFT015|Port Datenbits||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Einstellungen f�r TNC mit GPS �ber HSP-Kabel||
+WPUPCFT024|Datenart||
+WPUPCFT025|Automatisch||
+WPUPCFT026|Bin�r||
+WPUPCFT027|ASCII||
+WPUPCFT028|Einstellungen f�r TNC mit GPS �ber AUX-Kabel||
+WPUPCFT029|Einstellungen f�r TNC mit GPS �ber INVALID ENUM||
+WPUPCFT030|KISS TNC konfigurieren||
+WPUPCFT031|TNC Konfigurationsdateien||
+WPUPCFT032|Datei f�r TNC-Setup|| 
+WPUPCFT033|Datei f�r TNC-Shutdown||
+WPUPCFT034|KISS Parameter||
+WPUPCFT035|TXDelay (in 10 ms Einheiten)||
+WPUPCFT036|Persistence (0 to 255)||
+WPUPCFT037|SlotTime (in 10 ms Einheiten)||
+WPUPCFT038|TxTail (in 10 ms Einheiten)||
+WPUPCFT039|Voll-Duplex||
+WPUPCFT040|Multi-Port KISS TNC konfigurieren||
+WPUPCFT041|Funkger�t Port||
+WPUPCFT042|Unklarer UNPROTO Pfad!||
+WPUPCFT043|Bitte kuerzeren Pfad eingeben, z.B. WIDE2-2 oder RELAY,WIDE2-2||
+WPUPCFT044|Unklarer IGATE Pfad!||
+WPUPCFT045|Senden eines unklaren/fehlerhaften UNPROTO-Pfades!||
+WPUPCFT046|Senden eines unklaren/fehlerhaften IGATE-Pfades!||
+WPUPCFT047|KISS-Modus beim Start aktivieren||
+# 
+# PopUp "Einstellungen Wetterstation"
+WPUPCFWX01|Einstellungen Wetterstation||
+WPUPCFWX02|Device f�r Wetterstation||
+WPUPCFWX03|Regenmesser-Korrektur (globale Einstellung)||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|keine Korrektur||
+#
+# PopUp "Einstellungen - Stationsdaten"
+WPUPCFS001|Stationsdaten||
+WPUPCFS002|Rufzeichen||
+WPUPCFS003|Breite||
+WPUPCFS004|Grad||
+WPUPCFS005|Min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|L�nge||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Stations-Symbol||
+WPUPCFS010|Gruppe/Overlay||
+WPUPCFS011|Symbol||
+WPUPCFS028|Auswahl||
+WPUPCFS012|Leistung - H�he - Gewinn - Richtung||
+WPUPCFS013|Kein PHG||
+WPUPCFS014|Antennen H�he||
+WPUPCFS015|Antennen Gewinn||
+WPUPCFS016|Rundstrahler||
+WPUPCFS017|Kommentar:||
+WPUPCFS018|Positionsverschleierung||
+WPUPCFS019|Keine||
+WPUPCFS020|.11 Meilen Kreis||
+WPUPCFS021|1.15 Meilen Kreis||
+WPUPCFS022|11.51 Meilen Kreis||
+WPUPCFS023|69.09 Meilen Kreis||
+WPUPCFS024|.18 Kilometer Kreis||
+WPUPCFS025|1.85 Kilometer Kreis||
+WPUPCFS026|18.53 Kilometer Kreis||
+WPUPCFS027|111.19 Kilometer Kreis||
+WPUPCFS029|Position in komprimiertem Format senden|k|
+#
+# PopUp "Objekt/Item"
+POPUPOB001|Objekt/Item||
+POPUPOB002|Name||
+POPUPOB003|Objekt setzen||
+POPUPOB004|Objekt l�schen||
+POPUPOB005|Objekt �ndern||
+POPUPOB006|Item setzen||
+POPUPOB007|Fl�chenobjekt||
+POPUPOB008|als Fl�chenobjekt||
+POPUPOB009|Helle Farben||
+POPUPOB010|Fl�chen f�llen||
+POPUPOB011|Kreis||
+POPUPOB012|Linie-Rechts '/'||
+POPUPOB013|Linie-Links '\'||
+POPUPOB014|Dreieck||
+POPUPOB015|Rechteck||
+POPUPOB016|Schwarz||
+POPUPOB017|Blau||
+POPUPOB018|Gr�n||
+POPUPOB019|Cyan||
+POPUPOB020|Rot||
+POPUPOB021|Violett||
+POPUPOB022|Gelb||
+POPUPOB023|Grau||
+POPUPOB024|nach oben:||
+POPUPOB025|nach links (au�er '/'):||
+POPUPOB026|Korridor:||
+POPUPOB027|Allgemeine Optionen||
+POPUPOB028|Position||
+POPUPOB029|als Signpost-Objekt||
+POPUPOB030|Signpost-Text||
+POPUPOB031|Signpost Objekt||
+POPUPOB032|Komprimierung einschalten||
+POPUPOB033|Item l�schen||
+POPUPOB034|Item �ndern||
+POPUPOB035|H�he [ft]:||
+POPUPOB036|Geschwindigkeit [Knoten]:||
+POPUPOB037|Kurs:||
+POPUPOB038|als Peil-Objekt||
+POPUPOB039|Leistung - H�he - Gewinn - Richtung||
+POPUPOB040|�ffnungswinkel - Richtung||
+POPUPOB041|Rundstrahlantenne||
+POPUPOB042|Richtantenne||
+POPUPOB043|unbekannt||
+POPUPOB044|Objekt �bernehmen||
+POPUPOB045|Item �bernehmen||
+POPUPOB046|DF Peilung:||
+POPUPOB047|Wahrscheinlichkeitskreise||
+POPUPOB048|Map View Objekt||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+# PopUp "Internet Einstellungen"
+WPUPCFI001|Internet Einstellungen||
+WPUPCFI002|Host ||
+WPUPCFI003|Port ||
+WPUPCFI004|(Weitere Hosts)||
+WPUPCFI005|Host1||
+WPUPCFI006|Port1||
+WPUPCFI007|Host2||
+WPUPCFI008|Port2||
+WPUPCFI009|Zugangs-Code||
+WPUPCFI010|(freilassen falls keiner)||
+WPUPCFI011|Wiederverbinden bei NET Fehler?||
+WPUPCFI012|Als I-Gate verwenden?||
+WPUPCFI013|Nachrichten aus Internet via TNC aussenden wenn I-Gate?||
+WPUPCFI014|I-Gate Transaktionen protokollieren?|||
+WPUPCFI015|Filter-Parameter||
+#
+# PopUp "Datenbank Einstellungen"
+WPUPCFID01|Datenbank Einstellungen (TBD)||
+WPUPCFID02|Host ||
+WPUPCFID03|Port ||
+WPUPCFID04|(Weitere Hosts)||
+WPUPCFID05|Host1||
+WPUPCFID06|Port1||
+WPUPCFID07|Host2||
+WPUPCFID08|Port2||
+WPUPCFID09|Zugangs-Code||
+WPUPCFID10|(Freilassen falls keines)||
+WPUPCFID11|Wiederverbinden bei NET Fehler?||
+WPUPCFID12|Als I-Gate verwenden?||
+WPUPCFID13|Nachrichten aus Internet via TNC aussenden wenn I-Gate?||
+WPUPCFID14|I-Gate Transaktionen protokollieren?|||
+WPUPCFID15|Filter-Parameter||
+#
+# PopUp "Configure AGWPE"
+WPUPCFIA01|AGWPE konfigurieren||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Port ||
+WPUPCFIA04|(Weitere Hosts)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Port1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Port2||
+WPUPCFIA09|Zugangs-Code||
+WPUPCFIA10|Freilassen falls keines)||
+WPUPCFIA11|Wiederverbinden bei NET Fehler?||
+WPUPCFIA12|Als I-Gate verwenden?||
+WPUPCFIA13|Nachrichten aus Internet via TNC aussenden wenn I-Gate?||
+WPUPCFIA14|I-Gate Transaktionen protokollieren?|||
+WPUPCFIA15|FunkPort Senden||
+#
+# PopUp "Einstellungen f�r Audio Alarm"
+WPUPCFA001|Einstellungen f�r Audio Alarm||
+WPUPCFA002|Audio Abspielkommando||
+WPUPCFA003|Alarm an||
+WPUPCFA004|abzuspielende Audio Datei||
+WPUPCFA005|Neue Station||
+WPUPCFA006|Neue Nachricht||
+WPUPCFA007|Ann�herung||
+WPUPCFA008|Band�ffnung||
+WPUPCFA009|Minimum Entfernung||
+WPUPCFA010|Maximum Entfernung||
+WPUPCFA011|Wetter Warnung||
+#
+# PopUp "Sprachausgabe"
+WPUPCFSP01|Sprachausgabe||
+WPUPCFSP02|Sprachausgabe bei:||
+WPUPCFSP03|Neuer Station||
+WPUPCFSP04|Neuer Nachricht||
+WPUPCFSP05|Neuer Text in Nachricht||
+WPUPCFSP06|Ann�herungswarnung||
+WPUPCFSP07|Band�ffnung||
+WPUPCFSP08|Neuer Wetterwarnung||
+WPUPCFSP09|Ann�herung verfolgter Station||
+#
+# PopUp "Verfolge Station"
+WPUPTSP001|Verfolge Station|| 
+WPUPTSP002|Rufzeichen|| 
+WPUPTSP003|Gro�/Klein|| 
+WPUPTSP004|Exakt|| 
+WPUPTSP005|Verfolge jetzt!|| 
+WPUPTSP006|Verfolgung aufheben|| 
+WPUPTSP007|Spur aus dem Internet||
+WPUPTSP008|Rufzeichen||
+WPUPTSP009|Start der Spur (vor ... Std)||
+WPUPTSP010|L�nge der Spur (Std)||
+#
+# PopUp "Nachrichten..."
+WPUPMSB001|Nachricht Fenster %d||
+WPUPMSB002|Gruppennachricht Fenster %d||
+WPUPMSB003|Stationsrufzeichen:||
+WPUPMSB004|Gruppenrufzeichen:||
+WPUPMSB005|Neues/Refresh Rufzeichen||
+WPUPMSB006|Neue Gruppe||
+WPUPMSB007|L�sche alte Nachrichten||
+WPUPMSB008|Nachricht:||
+WPUPMSB009|Sende jetzt!||
+WPUPMSB010|Pfad:||
+WPUPMSB011|Wartende Nachrichten zur�cknehmen||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|Seq||
+WPUPMSB014|Typ||
+WPUPMSB015|Rundmeldung||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*ABBRUCH*||
+WPUPMSB018|*ZUR�CKGEWIESEN*||
+WPUPMSB019|Pfad �ndern||
+WPUPMSB020|Standard-Pfad(e) benutzen||
+WPUPMSB021|Direkt (kein Pfad)||
+WPUPMSB022|Umgekehrter Pfad (Hinweis):||
+#
+# PopUp "Automatische Antwort"
+WPUPARM001|Automatische Antwort �ndern||
+WPUPARM002|Antwort:||
+#
+# PopUp "Hilfe Index"
+WPUPHPI001|Hilfe Index||
+WPUPHPI002|Anzeigen||
+#
+# PopUp "Stations-Info"
+WPUPSTI000|Objekt von: %s||
+WPUPSTI001|Stations-Info||
+WPUPSTI002|Sende Nachricht||
+WPUPSTI003|Suche in FCC Datenbank||
+WPUPSTI004|Suche in RAC Datenbank||
+WPUPSTI005|Pakete empfangen: %d     Zuletzt geh�rt: ||
+WPUPSTI006|Geh�rt �ber TNC auf Device %d, ||
+WPUPSTI007|Geh�rt ||
+WPUPSTI008|zuletzt �ber Lokal||
+WPUPSTI009|zuletzt �ber TNC auf Device %d||
+WPUPSTI010|zuletzt �ber Internet auf Device %d||
+WPUPSTI011|zuletzt �ber Datei||
+WPUPSTI012|zuletzt �ber Unbekannt||
+WPUPSTI013|, und hat die Position ge�ndert||
+WPUPSTI014|Momentane Leistung/Gewinn:||
+WPUPSTI016|H�he: %.0f %s ||
+WPUPSTI017|Kurs: %s� ||
+WPUPSTI018|Geschwindigkeit: %.1fkm/h||
+WPUPSTI019|Geschwindigkeit: %.1fmph||
+WPUPSTI020|%0.1f Meilen||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Entfernung von meiner Station %s, Richtung von meiner Station %s||
+WPUPSTI023|Letzte Position: ||
+WPUPSTI024|Wetter Daten %c:%s||
+WPUPSTI025|Wind Richtung: %s Geschwindigkeit: %03d km/h||
+WPUPSTI026|Wind Richtung: %s Geschwindigkeit: %s mph||
+WPUPSTI027| B�e: %03d km/h||
+WPUPSTI028| B�e: %s mph||
+WPUPSTI029|Temperatur: %02.1f�C   ||
+WPUPSTI030|Temperatur: %s�F   ||
+WPUPSTI031|Feuchte: %s%%   ||
+WPUPSTI032|rel.Feuchte: %02.1f�C  ||
+WPUPSTI033|Luftdruck: %s hPa||
+WPUPSTI034|Schnee: %0.1f cm/24h||
+WPUPSTI035|Schnee: %0.0f Inch/24h||
+WPUPSTI036|Regen: ||
+WPUPSTI037|%0.2f mm/h   ||
+WPUPSTI038|%0.2f Inch/h   ||
+WPUPSTI039|%0.2f mm/Tag  ||
+WPUPSTI040|%0.2f Inch/Tag  ||
+WPUPSTI041|%0.2f mm/seit 0:00||
+WPUPSTI042|%0.2f Inch/seit 0:00||
+WPUPSTI043|Datenpfad: %s||
+WPUPSTI044|Kommentar %02d/%02d %02d:%02d : %s||
+WPUPSTI045|L�sche Spur||
+WPUPSTI046|Regen gesamt: ||
+WPUPSTI047|%0.2f mm||
+WPUPSTI048|%0.2f Inch||
+WPUPSTI049|Trace Anfrage||
+WPUPSTI050|Unbest. Nachrichten||
+WPUPSTI051|Stationsanfrage||
+WPUPSTI052|Stationsversion||
+WPUPSTI053|Objekt/Item �ndern||
+WPUPSTI054|Spur speichern||
+WPUPSTI055|Echo geh�rt von:||
+WPUPSTI056|Automatische Aktualisierung||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|Peil-Richtung: %s||
+WPUPSTI059|Status %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Brennstofftemp.: %02.1f�C  ||
+WPUPSTI061|Brennstofftemp.: %s�F   ||
+WPUPSTI062|Brennstofffeuchte: %s%%   ||
+WPUPSTI063|Baro: %0.2f in Hg||
+WPUPSTI064|NWS Wetterwarnung holen||
+WPUPSTI065|Taktisches Rufzeichen: %s||
+WPUPSTI066|Taktischen Rufzeichen zuweisen||
+WPUPSTI067|Aktuelle Reichweite: %d Meilen||
+WPUPSTI068|keine||
+WPUPSTI069|Standard||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|Reichweite||
+WPUPSTI073|PHG fehlerhaft||
+WPUPSTI074|SHG fehlerhaft||
+WPUPSTI075|DF Bereich||
+WPUPSTI076|Kein Signal erkannt||
+WPUPSTI077|m�gliches Signal||
+WPUPSTI078|Signal erkannt, nicht lesbar||
+WPUPSTI079|Schwaches Signal, schlecht lesbar||
+WPUPSTI080|Verrauschtes Signal aber lesbar||
+WPUPSTI081|Signal lesbar, etwas Rauschen||
+WPUPSTI082|Gutes Signal mit Restrauschen||
+WPUPSTI083|Sehr gutes Signal||
+WPUPSTI084|Hervorragendes  Signal||
+WPUPSTI085|Au�erordentlich starkes Signal||
+WPUPSTI086|SCHLECHTE PEILUNG||
+WPUPSTI087|NRQ fehlerhaft||
+WPUPSTI088|DF �ffnungswinkel||
+WPUPSTI089|DF L�nge||
+WPUPSTI090|ung�ltig||
+WPUPSTI091|Wegfarbe �ndern||
+WPUPSTI092|Clear DF Bearing||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|ALOHA Radius: %d %s||
+WPUPALO002|Stationen innerhalb des ALOHA Kreises: %d||
+WPUPALO003| Digis                    : %d||
+WPUPALO004| Mobilstationen (in Bew.) : %d||
+WPUPALO005| Mobilstationen (sonstige): %d||
+WPUPALO006| Wetterstationen          : %d||
+WPUPALO007| Feststationen            : %d||
+WPUPALO008|zuletzt berechnet vor %d %s %d %s.||
+WPUPALO666|ALOHA Radius noch nicht berechnet||
+#
+# FCC-RAC Call Look up
+STIFCC0001|FCC Datenbank Abfrage||
+STIFCC0002|RAC Datenbank Abfrage||
+STIFCC0003|Name:||
+STIFCC0004|Stra�e:||
+STIFCC0005|Stadt:||
+STIFCC0006|Staat:||
+STIFCC0007|PLZ:||
+STIFCC0008|Grundeinstellung ||
+STIFCC0009|Erweitert ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+#
+# FCC-RAC Call Look up
+STIFCC0100|FCC-Index zu alt, erstelle neu...||
+STIFCC0101|Rufzeichensuche||
+STIFCC0102|Rufzeichen nicht gefunden!||
+STIFCC0103|RAC-Index zu alt, erstelle neu...||
+#
+#
+# Band open message 
+UMBNDO0001|in Entfernung von||
+#
+#
+# Allgemeine Optionen
+UNIOP00001|Ok||
+UNIOP00002|Abbrechen||
+UNIOP00003|Schlie�en||
+UNIOP00004|Meilen||
+UNIOP00005|km||
+UNIOP00006|Geraet||
+UNIOP00007|Hinzuf�gen||
+UNIOP00008|L�schen||
+UNIOP00009|Eigenschaften||
+UNIOP00010|Senden erlaubt?||
+UNIOP00011|Beim Start aktivieren?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|Inch||
+UNIOP00018|mm/Tag||
+UNIOP00019|Inch/Tag||
+UNIOP00020|mm/h||
+UNIOP00021|Inch/h||
+UNIOP00022|mm ab 0:00||
+UNIOP00023|Inch ab 0:00||
+UNIOP00024|�||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|Inch Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Systemzeit durch GPS einstellen||
+UNIOP00030|Digipeater?||
+UNIOP00031|m||
+UNIOP00032|Anwenden|||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|Tag||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# popUp "Stationsauswahl"
+STCHO00001|Stationsauswahl||
+#
+# "Zeige - Wetterwarnungen"
+WPUPWXA001|Wetterwarnung||
+WPUPWXA002|Liste der Wetterwarnungen||
+#
+# PopUp "Einstellungen - Schnittstellen"
+WPUPCIF001|Installierte Schnittstellen||
+WPUPCIF002|W�hle Schnittstellentyp||
+#
+# PopUp "Einstellungen AX.25 TNC"
+WPUPCAX001|Einstellungen AX.25 TNC||
+WPUPCAX002|AX.25 Ger�tename||
+#
+# Interface device names 
+IFDNL00000|Kein||
+IFDNL00001|Serieller TNC||
+IFDNL00002|Serieller TNC + GPS mit HSP-Kabel||
+IFDNL00003|Serieller GPS||
+IFDNL00004|Serielle Wetterstation||
+IFDNL00005|Internet Server||
+IFDNL00006|AX.25 TNC||
+IFDNL00007|GPS �ber Netzwerk (via gpsd)||
+IFDNL00008|Wetter �ber Netzwerk||
+IFDNL00009|Serieller TNC + GPS mit AUX-Kabel||
+IFDNL00010|Serieller KISS TNC||
+IFDNL00011|Datenbank �ber Netz (Noch nicht implementiert)||
+IFDNL00012|AGWPE �ber Netz||
+IFDNL00013|Serieller Multi-Port KISS TNC||
+IFDNL00014|SQL Datenbank (experimentell)||
+#
+# Interface device info 
+IFDIN00000|%s %2d %s an ser. Schnittstelle %s   %s||
+IFDIN00001|%s %2d %s verbunden mit %s:%d   %s||
+IFDIN00002|%s %2d %s �ber Geraet namens %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006|  INAKTIV  ||
+IFDIN00007|   AKTIV   ||
+IFDIN00008|  FEHLER   ||
+IFDIN00009| UNBEKANNT ||
+#
+# PopUp "Schnittstellen-Steuerung"
+IFPUPCT000|Schnittstellen-Steuerung||
+IFPUPCT001|Start||
+IFPUPCT002|Stop||
+IFPUPCT003|Alle starten||
+IFPUPCT004|Alle stoppen||
+#
+# Internet Gateway Steuerung
+IGPUPCF000|Internet Gateway||
+IGPUPCF001|Alle Weiterleitungen verhindern||
+IGPUPCF002|Weiterleitung NUR von HF nach Internet||
+IGPUPCF003|Weiterleitung HF->Internet UND Internet->HF||
+IGPUPCF004|Igate -> HF Pfad ||
+#
+# Wetterstation
+WXPUPSI000|Wetterstation||
+WXPUPSI001|Wetterstation Typ||
+WXPUPSI002|Aktuelle Werte||
+WXPUPSI003|Windrichtung||
+WXPUPSI004|Windgeschwindigkeit||
+WXPUPSI005|Wind B�en||
+WXPUPSI006|Temperatur||
+WXPUPSI007|Regenmenge||
+WXPUPSI008|Regenmenge heute||
+WXPUPSI009|Druck|
+WXPUPSI010|Luftfeuchtigkeit||
+WXPUPSI011|Peet Bros ULTIMETER 2000 Type (Data Logging Mode)||
+WXPUPSI012|Peet Bros ULTIMETER II Type||
+WXPUPSI013|Peet Bros ULTIMETER 2000 Type (Packet Mode)||
+WXPUPSI014|Regenmenge aktuelle Std.||
+WXPUPSI015|Regenmenge letze 24 Std.||
+WXPUPSI016|Qualimetrics Q-Net||
+WXPUPSI017|Peet Bros ULTIMETER 2000 Type (Complete Mode)||
+WXPUPSI018|Taupunkt||
+WXPUPSI019|Wind Spitze||
+WXPUPSI020|Windauskuehlungsfaktor (Windchill)||
+WXPUPSI021|Gef�hlte Temp.||
+WXPUPSI022|3 Std. Druck||
+WXPUPSI023|H�chsttemp.||
+WXPUPSI024|Tiefsttemp.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Stationslisten
+LHPUPNI000|Stationsliste||
+LHPUPNI001|Mobile Stationen||
+LHPUPNI002|Wetterstationen||
+LHPUPNI003|Lokale Stationen (�ber TNC)||
+LHPUPNI004|Letzte Stationen||
+LHPUPNI005|Objekte & Punkte||
+LHPUPNI006|Eigene Objekte & Punkte||
+LHPUPNI010|#||
+LHPUPNI011|Rufzeichen||
+LHPUPNI012|Pakete||
+LHPUPNI013|Pos Zeit||
+LHPUPNI014|Pfad||
+LHPUPNI015|PHG||
+LHPUPNI016|Kommentar||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|H�he||
+LHPUPNI103|Breite||
+LHPUPNI104|L�nge||
+LHPUPNI105|Pakete||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|B�en||
+LHPUPNI203|Temp||
+LHPUPNI204|Feucht||
+LHPUPNI205|Druck||
+LHPUPNI206|Rn-h||
+LHPUPNI207|Rn-0||
+LHPUPNI208|Rn24||
+LHPUPNI209|Breite/L�nge oder UTM||
+#
+# Stil der Wetterwarnungskarten
+PULDNMAT01|Zeige Warnungen �ber Karten||
+PULDNMAT02|Zeige Warnungen unter Karten||
+#
+# Fehlermeldungen
+POPEM00001|Suchfehler!||
+POPEM00002|Station %s wurde nicht gefunden!||
+POPEM00003|Tracking Fehler!||
+POPEM00004|Schnittstellenfehler!||
+POPEM00005|Ung�ltiger AX.25 Port Name %s||
+POPEM00006|Ung�ltiger AX.25 Port Name %s||
+POPEM00007|Ung�ltiges Rufzeichen %s||
+POPEM00008|AX.25 Ziel-Rufzeichen oder Digipeater ung�ltig||
+POPEM00009|Kann AX.25-Socket nicht �ffnen, %s||
+POPEM00010|Kann AX.25-Socket nicht binden, %s||
+POPEM00011|Kann AX.25-Rufzeichen nicht konnektieren, %s||
+POPEM00012|AX.25-Fehler auf Ausgang des UI||
+POPEM00013|AX.25-Problem mit axports Datei||
+POPEM00014|AX.25 ung�ltiger Port-Name %s||
+POPEM00015|Fehler beim �ffnen des Interface %d Hard Fail||
+POPEM00016|Fehler beim �ffnen des Interface %d Time Out||
+POPEM00017|Keine weiteren Schnittstellen verf�gbar!||
+POPEM00018|Datenanfrage - Single Message Line||
+POPEM00019|Senden abgeschaltet bei Port %d||
+POPEM00020|Datenbankfehler!||
+POPEM00021|AX.25-Unterst�tzung nicht in Xastir kompiliert!||
+POPEM00022|Eingabefehler!||
+POPEM00023|Es wurde kein Name angegeben!||
+POPEM00024|Der angegebene Name ist nicht mehr frei!||
+POPEM00025|Nicht gefunden!||
+POPEM00026|Verfolgung wird bei Erscheinen der Station aufgenommen||
+POPEM00027|Falsche Eingabe.  Einige Felder leer?||
+POPEM00028|Kann Datei nicht �ffnen||
+POPEM00029|Gefunden!||
+POPEM00030|Symbol f�r Wetterstation||
+POPEM00031|Ge�ndert auf Wettersymbol '/_', auch m�glich:  '\_'  '/W'  und  '\W'||
+POPEM00032|Warnung: Symbol des National Weather Service wird benutzt!||
+POPEM00033|Keine GPS Daten!||
+POPEM00034|Position wird nicht gesendet bis g�ltige GPS-Daten!||
+POPEM00035|Warnung||
+POPEM00036|Hinweis||
+POPEM00037|HSP Interface vorhanden: GPS-Abfrageintervalle gr��er||
+POPEM00038|Der Name steht im Konflikt mit einem bereits existierenden Objekt, einer Markierung oder Station||
+POPEM00039|Nicht zul�ssige Zeichen gefunden||
+POPEM00040|Der nutzerspezifische Pfad ging verloren||
+POPEM00041|Erstelle andere Datei. Bitte etwas warten und danach neu versuchen||
+POPEM00042|Kein eigenes Objekt! Versuchen Sie erst das Obkekt zu �bernehmen.||
+POPEM00043|Kein Objekt/Item!||
+POPEM00044|Findu-Wegdaten: fehlgeschlagen||
+POPEM00045|Findu-Wegdaten: fertig||
+POPEM00046|Berkeley DB header/shared library passen nicht! Map-Cache aus.||
+POPEM00047|Senden ist global GESPERRT. Notfall-Baken werden NICHT gesendet!||
+POPEM00048|Notfall-Baken-Modus!||
+POPEM00049|NOTFALL-BAKEN-MODUS, senden alle 60 Sekunden!||
+POPEM00050|Schnittstellen oder Positionen/Senden GESPERRT. Notfall-Baken werden NICHT gesendet!||
+POPEM00051|Altnet ist aktiv (Menu Einstellungen->Grundeinstellungen)||
+POPEM00052|Rufzeichen ist LEER!||
+POPEM00053|Nachricht ist LEER!||
+POPEM00054|Wir versuchen mit uns selbst zu reden!||
+#
+# Karten - Ausschnitt 
+JMLPO00001|Gespeicherte Kartenausschnitte||
+JMLPO00002|Aktivieren!|A|
+JMLPO00003|Neuer Name:||
+#
+# "Zeige - Bekanntmachungen"
+BULMW00001|Bekanntmachungen||
+BULMW00002|Bereich einschr�nken auf (0: unbegrenzt)||
+BULMW00003|neuen Bereich setzen||
+#
+# "Zeige - Nachrichten"
+AMTMW00001|Nachrichtenverkehr||
+AMTMW00002|Bereich einschr�nken auf (0: unbegrenzt)||
+#
+# Texte f�r Sprachsynthese
+SPCHSTR001|kilometer||
+SPCHSTR002|meter||
+SPCHSTR003|meilen||
+SPCHSTR004|yards||
+SPCHSTR005|%s, entfernung ist %d %s.||
+SPCHSTR006|%s, entfernung ist %.1f %s.||
+SPCHSTR007|%s, entfernung ist %d %s %s %s.||
+SPCHSTR008|%s, entfernung ist %.1f %s %s %s.||
+SPCHSTR009|neue wetterwarnung||
+SPCHSTR010|neues rufzeichen||
+SPCHSTR011|D X geh�rt, %s, in einer entfernung von %.1f %s||
+#
+SPCHDIRN00|n�rdlich von||
+SPCHDIRS00|s�dlich von||
+SPCHDIRE00|�stlich von||
+SPCHDIRW00|westlich von||
+SPCHDIRNE0|nord�stlich von||
+SPCHDIRNW0|nordwestlich von||
+SPCHDIRSE0|s�d�stlich von||
+SPCHDIRSW0|s�dwestlich von||
+#
+# Symbolauswahl Dialog
+SYMSEL0001|Symbol-Auswahl||
+SYMSEL0002|Prim�re Symbol-Tabelle||
+SYMSEL0003|Sekund�re Symbol-Tabelle||
+#
+# Druckereinstellungen Dialog
+PRINT0001|Druck Eigenschaften||
+PRINT0002|Papiergr��e||
+PRINT0003|Automatisch drehen
+PRINT0004|90� im Gegenuhrzeigersinn drehen||
+PRINT0005|Automatisch skalieren||
+PRINT0006|Skalierung:||
+PRINT0007|Standardhintergrund durch Wei� ersetzen||
+PRINT0008|Schwarz/Wei�-Druck||
+PRINT0016|Farben invertieren||
+PRINT0009|Postscript Aufl�sung:||
+PRINT0010|Vorschau||
+PRINT0011|In Datei drucken||
+PRINT0012|Gebe Bild auf Datei aus...||
+PRINT0013|Konvertiere in Postscript...||
+PRINT0014|Erstellen der Druckdatei beendet||
+PRINT0015|Druckerstatus||
+#
+# Druckereinstellungen Dialog
+PRINT1001|Direkt an:||
+PRINT1002|�ber Vorschau:||
+#
+# Locate Feature Dialog
+FEATURE001|Name:||
+FEATURE002|Bundesland/Provinz:||
+FEATURE003|County:||
+FEATURE004|Map Quad:||
+FEATURE005|Typ:||
+FEATURE006|GNIS-Datei:||
+FEATURE007|Adresse:||
+FEATURE008|Stadt:||
+FEATURE009|Zielmarkierung:||
+FEATURE010|PLZ:||
+FEATURE011|Geocoding Datei||
+#
+# Koordinatenrechner Dialog
+COORD001|Koordinatenumrechnung||
+COORD002|Umrechnen||
+COORD003|Umrechnen||
+COORD004|L�schen||
+COORD005|UTM||
+COORD006|Breitengrad oder||
+COORD007|L�ngengrad oder||
+COORD008|Zone||
+COORD009|UTM �stlich||
+COORD010|UTM n�rdlich||
+COORD011|                   Dezimal Grad: ||
+COORD012|           Grad/Dezimal Minuten: ||
+COORD013|  Grad/Minuten/Dezimal Sekunden: ||
+COORD014|  Universal Transverse Mercator: ||
+COORD015|Milit�risches Koordinatensystem: ||
+COORD016|        Maidenhead Grid Locator: ||
+COORD017| **             Ihre Eingabe war fehlerhaft !            **||
+COORD018| ** Bitte nutzen Sie eines der folgenden Eingabeformate: **||
+#
+#
+# Smart Beaconing Dialog
+SMARTB001|Smart Beaconing||
+SMARTB002|Hohe Rate [Sek]                ||
+SMARTB003|Hohe Geschwindigkeit [mph]     ||
+SMARTB004|Hohe Geschwindigkeit [km/h]    ||
+SMARTB005|Niedrige Rate [Min]            ||
+SMARTB006|Niedrige Geschwindigkeit [mph] ||
+SMARTB007|Niedrige Geschwindigkeit [km/h]||
+SMARTB008|Kurvenschwellwert [Grad]       ||
+SMARTB009|Kurvenparameter (Turn Slope)   ||
+SMARTB010|Wartezeit [Sek]                ||
+SMARTB011|SmartBeaconing(tm) einschalten||
+#
+#
+#
+# Gamma Adjust Dialog
+GAMMA001|Gammakorrektur einstellen||
+GAMMA002|Gammakorrektur||
+#
+#
+# Map labels font Dialog
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Font Winzig||
+MAPFONT004|Map Font Klein||
+MAPFONT005|Map Font Mittel||
+MAPFONT006|Map Font Gro�||
+MAPFONT007|Map Font Riesig||
+MAPFONT008|Map Font Border||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV ID Font||
+#
+# Entfernung/Richtung auf der Statuszeile
+PULDNDB001|Entf./Richtung in Status||
+#
+#
+# GPS Transfer Operations
+GPS001|GPS-�bertragung||
+GPS002|Dateiname||
+GPS003|Farbe w�hlen||
+GPS004|Rot||
+GPS005|Gr�n||
+GPS006|Schwarz||
+GPS007|Wei�||
+GPS008|Orange||
+GPS009|Blau||
+GPS010|Gelb||
+GPS011|Violett||
+#
+#
+# Karten-Eigenschaften Dialog
+MAPP001|Karten-Eigenschaften||
+MAPP002|Max   Min   Karten gef�llt  USGS automat.||
+MAPP003|Zoom  Zoom  Ebene  zeichnen DRG  Karte Pfad/Dateiname||
+MAPP004|Ebene �ndern->||
+MAPP005|gef�llt->||
+MAPP006|Ja ||
+MAPP007|Nein||
+MAPP008|aut.Karte->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+#
+# Zeit Texte
+TIME001|Tag||
+TIME002|Tage||
+TIME003|Stunde||
+TIME004|Stunden||
+TIME005|Minute||
+TIME006|Minuten||
+TIME007|Sekunde||
+TIME008|Sekunden||
+#
+#
+# Map Caching
+CACHE001|Karte im Cache gespeichert||
+CACHE002|Lade Karte aus dem Cache||
+CACHE003|Karte nicht im Cache gefunden...||
+#
+#
+# Map Screen Misc
+RANGE001|ENTFERNUNGS-SKALIERUNG||
+#
+#
+# GPS Status
+GPSS001|WAAS oder PPS||
+GPSS002|DGPS||
+GPSS003|g�ltig SPS||
+GPSS004|ung�ltig||
+GPSS005|Sats/Anzeige||
+GPSS006|Fix||
+GPSS007|!GPS-Daten sind �lter als 30 Sekunden!||
+GPSS008|Simulation||
+GPSS009|Manuell||
+GPSS010|Sch�tzung||
+GPSS011|FRTK||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data
+CADPUD001|Fl�chenobjekt||
+CADPUD002|Fl�chen-Label:||
+CADPUD003|Kommentar:||
+CADPUD004|Wahrscheinlichkeit (%):||
+CADPUD005|OK||
+CADPUD006|CAD-Dialog||
+CADPUD007|Details zeigen/�ndern||
+CADPUD008|Abbrechen||
+CADPUD009|CAD-Objekte l�schen?||
+CADPUD010|Alle l�schen||
+CADPUD011|Ausgew�hlte l�schen||
+CADPUD012|durchgezogen||
+CADPUD013|gestrichelt||
+CADPUD014|doppelt gestrichelt||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|XASTIR Karte von %s (oben links) to %s (unten rechts).  UTM %d m Gitter, %s Datum. ||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA002|XASTIR Karte von %s (oben links) to %s %s (unten rechts).  Breite/L�nge Gitter, %s Datum.||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA003|XASTIR Karte von %s (oben links) to %s (unten rechts).  UTM Zonen, %s Datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST002|Postgreql with Postgis||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Xastir Simple Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA02|Xastir CAD Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA03|Xastir full Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/language-Italian.sys b/config/language-Italian.sys
new file mode 100644
index 0000000..c500443
--- /dev/null
+++ b/config/language-Italian.sys
@@ -0,0 +1,1354 @@
+# $Id: language-Italian.sys,v 1.230 2012/11/01 18:57:18 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# Xastir Version : 1.0.0
+# Creator        : Alessandro Frigeri, IK0YUP <ik0yup at myrealbox.com>
+# Maintained by  : The Xastir Group <xastir at xastir.org>
+# Last Modified  : Tue 31 Aug 11:00:00 CEST 2004 by IK0YUP
+#
+# comment lines with pound signs in front are ignored
+# Il formato del file � il seguente:
+# ID (10 caratteri alfanum)|(Stringa associata all'ID)|TastiDiSceltaRapida|#commento
+# WARNING:
+# Some strings contain formatting commands like %s and %d, you should not
+# change these. Wrong format strings could produce a segfault!
+#
+#
+# Men� Principale
+MENUTB0001|Dati|D|
+MENUTB0002|Liste|L|
+MENUTB0004|Mappe|M|
+MENUTB0005|Visualizza|V|
+MENUTB0006|Messaggi|e|
+MENUTB0010|Interfacce|I|
+MENUTB0009|Guida|G|
+#
+# Men� Dati
+PULDNFI001|Configura|C|
+PULDNFI002|Apri file di registro|A|
+PULDNFI003|Test||
+PULDNFI004|Esci|x|
+PULDNFI007|Cambia il livello di Debug|D|
+PULDNFI010|Registro TNC|T|
+PULDNFI011|Registro Rete|e|
+PULDNFI012|Accesso al Gateway Internet|G|
+PULDNFI013|Registro dati meteo|G|
+PULDNFI014|Cattura schermo in PNG||
+PULDNFI015|Stampa|P|
+PULDNFI016|KML Snapshots||
+#
+# Men� Visualizza
+PULDNVI001|Bollettini|B|
+PULDNVI002|Dati Packet in arrivo|P|
+PULDNVI003|Stazioni Mobili|M|
+PULDNVI004|Stazioni|S|
+PULDNVI009|Stazioni Locali|o|
+PULDNVI012|Ultime Stazioni|L|
+PULDNVI005|Stazioni Meteo|W|
+PULDNVI008|Stazioni Meteo|t|
+PULDNVI007|Allarmi Meteo|A|
+PULDNVI011|Traffico Messaggi|T|
+PULDNVI013|Tempo trascorso dall'avvio|d|
+PULDNVI014|Uptime del programma||
+PULDNVI015|Stato GPS||
+PULDNVI016|ALOHA Statistics||
+#
+# Menu' di Configurazione
+PULDNCF004|Dati Stazione|S|
+PULDNCF001|Configurazioni originali|D|
+PULDNCF003|Temporizzazione|T|
+PULDNCF002|Sistema di Coordinate|C|
+PULDNCF006|Allarmi Audio|A|
+PULDNCF007|Annunci Vocali|p|
+PULDNCF008|Salva la Configurazione Ora!|C|
+# (per unit� vedere PULDNDP006)
+#
+# Men� Mappe
+PULDNMP001|Scegli mappa|C|
+PULDNMP012|Vai alla posizione...|J|#NUOVA funzione dalla v. 0.3.2
+PULDNMP014|Localizza Elemento Mappa|E|
+PULDNMP016|Disable Fast Zoom/Pan/Home||
+PULDNMP013|Disattiva tutte le mappe|D|
+PULDNMP002|Mappe automatiche|A|
+PULDNMP003|Reticolato|G|
+PULDNMP004|Livelli delle Mappe|L|
+PULDNMP010|Abilita etichette delle mappe|F|
+PULDNMP009|Colora le aree chiuse|F|
+PULDNMP007|Mappe Allarme Meteo|W|
+PULDNMP005|Colore dello sfondo della mappa|B|
+PULDNMP006|Etichette Stazione|S|
+PULDNMP026|Stile Bordo Icone|O|
+PULDNMP011|Men� sul puntatore del mouse|M|
+PULDNMP008|Intensit� Mappa|I|
+PULDNMP020|Configura Tigermap||
+PULDNMP021|Mappe Automatche - Disabilita Mappe Raster||
+PULDNMP022|Indicizza Mappe all' Avvio||
+PULDNMP023|Indice: Aggiungi Nuove Mappe|N|
+PULDNMP024|Indice: Riordina Tutte le Mappe|R|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsel||
+PULDNMP027|Re-download Maps (Not from cache)||
+PULDNMP028|Flush Entire Map Cache!||
+PULDNMP029|Find Address||
+PULDNMP030|Configure USGS DRG||
+PULDNMP031|Enable Map Border||
+#
+#
+# PopUp "Configure Tigermap"
+MPUPTGR001|Griglia||
+MPUPTGR002|Contee||
+MPUPTGR003|Etichette Citt�||
+MPUPTGR004|Aree Urbane||
+MPUPTGR005|Strade Principali||
+MPUPTGR006|Strade||
+MPUPTGR007|Ferrovie||
+MPUPTGR008|Etichette Stato||
+MPUPTGR009|Etichette Strade Statali||
+MPUPTGR010|Etichette Autostrade USA||
+MPUPTGR011|Etichette Autostrade Nazionali||
+MPUPTGR012|Seleziona oggetti da visualizzare:||
+MPUPTGR013|Fiumi||
+MPUPTGR014|Laghi||
+MPUPTGR015|Aereoporti, Parchi, ecc||
+MPUPTGR016|Intensit� Mappa||
+MPUPTGR017|Internet Map Timeout (sec)||
+MPUPTGR018|Abilita Mappe Tiger||
+#
+# PopUp "Configure USGS DRG"
+MPUPDRG001|Select items to be displayed:||
+MPUPDRG002|Tint Underlying Map (XOR)||
+MPUPDRG003|Black||
+MPUPDRG004|White||
+MPUPDRG005|Blue||
+MPUPDRG006|Red||
+MPUPDRG007|Brown||
+MPUPDRG008|Green||
+MPUPDRG009|Purple||
+MPUPDRG010|Yellow||
+MPUPDRG011|Light Blue||
+MPUPDRG012|Light Red||
+MPUPDRG013|Light Purple||
+MPUPDRG014|Light Gray||
+MPUPDRG015|Light Brown||
+#
+#
+# Finestra di dialogo mappe
+WPUPMCP001|Scegli mappa||
+PULDNMMC01|Cancella|N|
+PULDNMMC02|Vettoriali|V|
+PULDNMMC03|Topografiche 250k|2|
+PULDNMMC04|Topografiche 100k|1|
+PULDNMMC05|Topografiche 24k|4|
+PULDNMMC06|Espandi Cartella|||
+PULDNMMC07|Cartella/Mappa Selezionata:||
+PULDNMMC08|Clear Dirs|C|
+PULDNMMC09|Select All|S|
+#
+# Men� Colori dello sfondo delle mappe.
+PULDNMBC01|Grigio||
+PULDNMBC02|Rosa||
+PULDNMBC03|Blu mare||
+PULDNMBC04|Blu acciaio||
+PULDNMBC05|Verde acqua||
+PULDNMBC06|Verde chiaro||
+PULDNMBC07|Oro forte||
+PULDNMBC08|Oro chiaro||
+PULDNMBC09|Marrone||
+PULDNMBC10|Rosso fuoco||
+PULDNMBC11|Bianco||
+PULDNMBC12|Nero||
+#
+# Stili delle etichette delle stazioni
+PULDNMSL01|Bordo nero||
+PULDNMSL02|Ombra nera e sfondo uniforme||
+PULDNMSL03|Testo su sfondo nero|T|
+#
+# PullDown "Stile Bordo Icone"
+PULDNMIO01|Nessun Bordo|N|
+PULDNMIO02|Bordo Nero|B|
+PULDNMIO03|Bordo Grigio|G|
+PULDNMIO04|Bordo Bianco|W|
+#
+# ATTIVO/DISATTIVO
+PULDNOT001|Attiva||
+PULDNOT002|Disattiva||
+PULDNOT003|Breve||
+#
+# Man� Stazioni
+PULDNDP014|Localizza Stazione|L|
+PULDNDP001|Segui Stazione|T|
+PULDNDP022|Scarica il percorso da Findu||
+PULDNDP032|Filtra Dati||
+PULDNDP040|Seleziona Nessuno||
+PULDNDP041|Seleziona Miei||
+PULDNDP042|Seleziona TNC||
+PULDNDP027|- Seleziona Diretta||
+PULDNDP043|- Seleziona Via Digi||
+PULDNDP034|Seleziona Rete||
+PULDNDP019|Visualizza dati scaduti||
+PULDNDP044|Seleziona Stazioni||
+PULDNDP028|- Seleziona Stazioni Fisse||
+PULDNDP029|- Seleziona Stazioni Mobili||
+PULDNDP030|- Seleziona Stazioni Meteo||
+PULDNDP053|  - Seleziona stazioni Meteo CWOP||
+PULDNDP045|- Seleziona Oggetti/Dettagli||
+PULDNDP026|- Seleziona Oggetti/Dettagli Meteo||
+PULDNDP039|- Seleziona Oggetti/Dettagli Misura Acqua||
+PULDNDP031|- Seleziona Altri Oggetti/Dettagli||
+PULDNDP033|Visualizza Filtro||
+PULDNDP010|Nominativo|l|
+PULDNDP012|Simboli|Y|
+PULDNDP011|- Ruota Simboli|R|
+PULDNDP007|Percorsi delle stazioni|i|
+PULDNDP003|Direzione|C|
+PULDNDP004|Velocit�|S|
+PULDNDP017|- Visualizza basse velocit�||
+PULDNDP002|Altitudine||A
+PULDNDP009|Informazioni Meteo|W|
+PULDNDP046|- Visualizza Testo Meteo||
+PULDNDP018|-- Visualizza solo Temperatura||
+PULDNDP047|- Visualizza Vento||
+PULDNDP054|Display Aloha Circle||
+PULDNDP013|Ambiguit� di posizione|
+PULDNDP008|Potenza/Guadagno|P|
+PULDNDP021|- Potenza/Guadagno - default||
+PULDNDP020|- Potenza/Guadagno - stazioni mobili||
+PULDNDP023|Visualizza i cerchi DF||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearing||
+PULDNDP035|Abilita Conteggio||
+PULDNDP036|- Visualizza Arc||
+PULDNDP037|- Visualizza Rotta||
+PULDNDP038|- Visualizza Simbolo||
+PULDNDP005|Distanza/Direzione|D|
+PULDNDP024|Visualizza Et� Ultimo Rapporto||
+PULDNDP015|Elimina tutte le stazioni|C|
+PULDNDP016|Elimina tutti i percorsi|T|
+PULDNDP025|Cancella Storico Oggetti/Dettagli||
+PULDNDP048|Ricarica Storico Oggetti/Dettagli||
+PULDNDP049|Cancella tutte le chiamate tattiche||
+PULDNDP050|Cancella lo storico delle chiamate tattiche||
+PULDNDP051|Seleziona solo chiamate tattiche||
+PULDNDP052|- Etichetta i punti percorso||
+PULDNDP055|Export all|E|
+PULDNDP056|Export to KML File||
+#
+# Sistema di misura
+PULDNUT001|Sistema inglese||
+PULDNUT002|Metrico||
+#
+# Messaggi
+PULDNMG001|Invia messaggio a...|S|
+PULDNMG002|Apri gruppo di messaggi|g|
+PULDNMG003|Elimina tutti i messaggi in uscita|C|
+PULDQUS001|Cerca tutte le stazioni|e|
+PULDQUS002|Cerca le stazioni Gateway|I|
+PULDQUS003|Cerca le stazioni meteo|W|
+PULDNMG004|Imposta risposta automatica ai messaggi in arrivo|S|
+PULDNMG005|Risposta automatica ai messaggi in arrivo|R|
+PULDNMG006|Modalit� Satellite Ack|M|
+PULDNMG007|Show Pending Messages|P|
+#
+# Menu "Interfaces"
+PULDNTNT04|Interface Control||
+PULDNTNT03|Disabilita Trasmissioni: TUTTE||
+PULDNTNT05|Disabilita Trasmissioni: Mia Posizione||
+PULDNTNT06|Disabilita Trasmissioni: Oggetti/Entit�||
+PULDNTNT11|Abilita la porta del Server||
+PULDNTNT01|Trasmetti Ora!|T|
+PULDNTNT07|Carica tracciato GPS|F|
+PULDNTNT08|Carica rotte GPS|R|
+PULDNTNT09|Carica punti GPS|W|
+PULDNTNT10|Ricevi Waypoints Garmin RINO|G|
+#
+# Men� Aiuto
+PULDNHEL01|Versione di Xastir|A|
+PULDNHEL02|Indice Guida|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|About Xastir||
+#
+#Mouse Menu Popup
+POPUPMA001|Opzioni||
+POPUPMA00c|Centra la mappa||
+POPUPMA015|Informazioni stazione||
+POPUPMA002|Zoom avanti||
+POPUPMA003|Zoom indietro||
+POPUPMA004|Livello di Zoom||
+POPUPMA005|Livello 1||
+POPUPMA006|Livello 16|| 
+POPUPMA007|Livello 64|| 
+POPUPMA008|Livello 256|| 
+POPUPMA009|Livello 1024|| 
+POPUPMA010|Livello 8192|| 
+POPUPMA017|Tutto il mondo||
+POPUPMA016|Ultima posizione e zoom||
+POPUPMA018|Oggetto/Entit�->Crea||
+POPUPMA019|Oggetto/Entit�->Modifica||
+POPUPMA025|Muovi La mia Stazione Qu�|H|
+POPUPMA011|Sposta in alto||
+POPUPMA012|Sposta in basso||
+POPUPMA013|Sposta a sinistra||
+POPUPMA014|Sposta a destra||
+POPUPMA020|Misurazione distanze|D|
+POPUPMA021|Muovi||
+POPUPMA022|RintracciaMi||
+POPUPMA023|Trovato Blocco Tastiera!||
+POPUPMA024|Per Favore disabilita Blocco Maiuscole/BlocNum/Scorrimento/||
+POPUPMA026|Center & Zoom||
+POPUPMA027|  Latitudine||
+POPUPMA028| Longitudine||
+POPUPMA029|Disegna oggetti CAD||
+POPUPMA030|Draw||
+POPUPMA031|Chiudi il poligono||
+POPUPMA032|Erase CAD Polygons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Level||
+POPUPMA035|10% out||
+POPUPMA036|10% in||
+POPUPMA037|Area||
+POPUPMA038|square||
+POPUPMA039|square feet||
+POPUPMA040|square meters||
+POPUPMA041|Bearing||
+POPUPMA042|degrees||
+POPUPMA043|Modify ambiguous position||
+POPUPMA044|Position abiguity is on, your new position may appear to jump.||
+POPUPMA045|Predefined Objects||
+POPUPMA046|CAD Polygons||
+POPUPMA047|Enable CAD objects||
+POPUPMA048|Enable CAD labels||
+POPUPMA049|Enable CAD comments||
+POPUPMA050|Enable CAD probability||
+POPUPMA051|Enable CAD area size||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|meters||
+POPUPMA055|mi|
+#
+#Etichette barra di stato
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Tr||
+BBARSTH001|%d/%d Stazioni||
+BBARSTA000|%-9s Nuovo Oggetto!||
+BBARSTA001|Nuova statione! %-9s||
+BBARSTA002|Nuovi dati da %-9s||
+BBARSTA003|Caricamento mappe...||
+BBARSTA004|Mappe caricate||
+BBARSTA005|Reticolato Lat/Long Attivo||
+BBARSTA006|Reticolato Lat/Long Non Attivo||
+BBARSTA007|Caricamento automatico delle mappe attivo||
+BBARSTA008|Caricamento automatico delle mappe non attivo||
+BBARSTA009|Livello mappe automatico attivato||
+BBARSTA010|Livello automatico mappe disattivato||
+BBARSTA011|Risposta automatica ai messaggi in arrivo disattivata!||
+BBARSTA012|File caricato..||
+BBARSTA013|Attivazione porta GPS||
+BBARSTA014|Disattivazione porta GPS||
+BBARSTA015|Ricezione stringa RMC dal GPS||
+BBARSTA016|Ricezione stringa GGA dal GPS||
+BBARSTA017|Disconnessione dall'host in rete||
+BBARSTA018|Connessione con l'host perduta (Time-out)!||
+BBARSTA019|Sto cercando l'host %s||
+BBARSTA020|Connesso a %s||
+BBARSTA021|Connessione fallita!||
+BBARSTA022|Non posso utilizzare la porta di rete!||
+BBARSTA023|Risoluzione IP host fallita!||
+BBARSTA024|Non � stato specificato nessun host||
+BBARSTA025|Host trovato, connessione a %d||
+BBARSTA026|Sto attendendo dati dal GPS via HSP..||
+BBARSTA027|Libero HSP, ricezione dati da TNC..||
+BBARSTA028|Caricamento %s|| #
+BBARSTA029|Apertura porta meteo||#
+BBARSTA030|Chiusura porta meteo||#
+BBARSTA031|Ricerca di %d in corso||#KEEP the %d 
+BBARSTA032|Dati meteo rilevati||#
+BBARSTA033|Eco da digipeater||
+BBARSTA034|Caricamento Mappe Allerta Meteo||
+BBARSTA035|Sto attendendo dati del GPS via AUX..||
+BBARSTA036|Libero AUX, ricezione dati da TNC..||
+BBARSTA037|Dati GPS rilevati||
+BBARSTA038|Posizionare il cambiamento sulla mia stazione||
+BBARSTA039|Indicizzazione %s||
+BBARSTA040|Stazione APRS(tm) %s||
+BBARSTA041|Attendo dati GPS..||
+BBARSTA042|Transmetto oggetti/dettagli||
+BBARSTA043|Registro||
+BBARSTA044|ALOHA distance is %d%s||
+BBARSTA045|Loading symbols...||
+BBARSTA046|Reloading symbols...||
+BBARSTA047|Initialize my station...||
+BBARSTA048|Start interfaces...||
+BBARSTA049|Reading tiles...||
+BBARSTA050|Downloading tiles...||
+BBARSTA051|Downloading tile %li of %li||
+#
+#Visualizzazione dati packet
+WPUPDPD001|Visualizzazione dati packet||
+WPUPDPD002|Solo dati da TNC||
+WPUPDPD003|Solo dati dalla Rete||
+WPUPDPD004|Dati da TNC e Rete||
+WPUPDPD005|TNC||
+WPUPDPD006|RETE||
+WPUPDPD007|Station Capabilities||
+WPUPDPD008|Mine Only||
+#
+#Menu' localizza stazione
+WPUPLSP001|Localizza Stazione||
+WPUPLSP002|Localizza Nominativo||
+WPUPLSP003|Non rispetta Maius/Minus||
+WPUPLSP004|Rispetta Maius/minus ||
+WPUPLSP005|Localizza!||
+WPUPLSP006|Localizzazione di Emergenza!||
+WPUPLSP007|Ricerca su FCC/RAC||
+#
+# Configure defaults popup
+WPUPCFD001|Parametri originali||
+WPUPCFD002|Dopo quanto tempo una stazione � da considerarsi vecchia?||
+WPUPCFD003|15 Minuti||
+WPUPCFD004|30 Minuti||
+WPUPCFD005|45 Minuti||
+WPUPCFD006|1 Ora||
+WPUPCFD007|90 Minuti||
+WPUPCFD008|2 Ore||
+WPUPCFD009|Dopo quanto tempo una stazione verr� cancellata?||
+WPUPCFD010|6 Ore||
+WPUPCFD011|12 Ore||
+WPUPCFD012|1 Giorno||
+WPUPCFD013|2 Giorni||
+WPUPCFD014|1 Settimana||
+WPUPCFD015|Opzione trasmissione dati stazione||
+WPUPCFD016|Stazione fissa||
+WPUPCFD017|Stazione mobile con ora locale||
+WPUPCFD018|Stazione mobile con ora e data UTC||
+WPUPCFD019|Stazione mobile con ora UTC (con secondi)||
+WPUPCFD021|Posizione della Stazione con dati meteo||
+WPUPCFD022|Posizione stazione, Data e ora UTC, dati meteo||
+WPUPCFD023|Devo trasmettere i dati Meteo?||
+WPUPCFD024|Comprimo i dati oggetti/dettagli quando trasmetto?||
+WPUPCFD025|Attivare rete alternativa?|A|
+WPUPCFD026|Intervallo per invio rapporti posizione||
+WPUPCFD027|Apparizione nuovi bollettini||
+WPUPCFD028|Avvisa per utilizzo tasti inadatti||
+WPUPCFD029|Vedi bollettini a distanza zero||
+WPUPCFD030|Disattiva Posit Dupe-Checks||
+WPUPCFD031|Load predefined objects from file||
+WPUPCFD032|My trails in one color||
+WPUPCFD033|ALTNET:||
+#
+# PopUp "Configure - Timing"
+WPUPCFTM01|Configura Temporizzazioni||
+WPUPCFTM02|Intervallo TX posizione (min)||
+WPUPCFTM03|Tempo di Ghosting della stazione (min)||
+WPUPCFTM04|Max Intervallo TX Oggetto/Entit� (min)||
+WPUPCFTM05|Clear Time della stazione (ore)||
+WPUPCFTM06|Intervallo controllo GPS (sec)||
+WPUPCFTM07|Tempo eliminazione stazione (giorni)||
+WPUPCFTM08|Fuori tempo Ricalcolo Assoluto (min)||
+WPUPCFTM09|Serial Inter-Char Delay (ms)||
+WPUPCFTM10|Nuovo tempo della traccia (min)||
+WPUPCFTM11|Nuovo intervallo della traccia (gradi)||
+WPUPCFTM12|RINO -> Intervallo oggetto (min), 0 = Non attivo||
+WPUPCFTM13|Snapshot Interval (min)||
+#
+# PopUp "Configure Coordinate System"
+WPUPCFC001|Configura Sistema Coordinate||
+WPUPCFC002|Seleziona Sistema Coordinate||
+WPUPCFC003|gg.ggggg|d|
+WPUPCFC004|gg mm.mmm|m|
+WPUPCFC005|gg mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM con zone speciali||
+#
+# Configurazione GPS
+WPUPCFG001|Configura GPS||
+WPUPCFG003|GPS collegato ad una porta autonoma||
+WPUPCFG002|Usare la posizione data dal GPS?||
+WPUPCFG004|Opzioni GPS||
+WPUPCFG005|GPS Autonomo||
+WPUPCFG006|GPS Collegato al TNC(con cavo HSP)||
+WPUPCFG007|GPS Collegato al TNC usando CTL-E||
+WPUPCFG008|Ora dal GPS (Rileva ogni)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 minuto||
+WPUPCFG013|2 Minuti||
+WPUPCFG014|5 Minuti||
+WPUPCFG015|10 Minuti||
+WPUPCFG016|GPS collegato ad una rete (gpsd)||
+WPUPCFG017|Host GPSD||
+WPUPCFG018|Porta GPSD||
+WPUPCFG019|GPS in rete con GPSD||
+WPUPCFG020|Riconnetti in caso di errore?||
+WPUPCFG021|Dati Meteo rilevati dalla rete||
+WPUPCFG022|Host Meteo||
+WPUPCFG023|Porta Meteo||
+#
+#Configure TNC (baud/style are also for Meteo)
+WPUPCFT001|Configura TNC||
+WPUPCFT002|Usare TNC?||
+WPUPCFT003|porta TNC||
+WPUPCFT004|Impostazioni porta||
+WPUPCFT005|300 bps|| 
+WPUPCFT006|1200 bps|| 
+WPUPCFT007|2400 bps|| 
+WPUPCFT008|4800 bps|| 
+WPUPCFT009|9600 bps|| 
+WPUPCFT010|19200 bps||
+WPUPCFT011|Percorsi UnProto||
+WPUPCFT012|Percorso 1: %s via ||
+WPUPCFT013|Percorso 2: %s via ||
+WPUPCFT014|Percorso 3: %s via ||
+WPUPCFT015|Stile porta|| 
+WPUPCFT016|8,N,1|| 
+WPUPCFT017|7,E,1|| 
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps|| 
+WPUPCFT023|Configura TNC con cavo HSP per GPS||
+WPUPCFT024|Tipi di dati||
+WPUPCFT025|Riconoscimento automatico||
+WPUPCFT026|Dati binari||
+WPUPCFT027|Dati ASCII||
+WPUPCFT028|Configura TNC con cavo AUX per GPS||
+WPUPCFT029|Configura TNC con INVALID ENUM||
+WPUPCFT030|Configura TNC KISS||
+WPUPCFT031|File di configurazione del TNC||
+WPUPCFT032|Nome File configurazione TNC|| 
+WPUPCFT033|Nome File dello Shutdown TNC||
+WPUPCFT034|Parametri KISS||
+WPUPCFT035|Ritardo TX (unit� di 10 ms)||
+WPUPCFT036|Persistenza (0 to 255)||
+WPUPCFT037|SlotTime (unit� di 10 ms)||
+WPUPCFT038|Coda Tx (unit� di 10 ms)||
+WPUPCFT039|Full Duplex||
+WPUPCFT040|Configura TNC Multi-Port KISS||
+WPUPCFT041|Porta Radio||
+WPUPCFT042|Dubious UNPROTO Path!||
+WPUPCFT043|Please consider a shorter path such as WIDE2-2 or WIDE1-1,WIDE2-2||
+WPUPCFT044|Dubious IGATE Path!||
+WPUPCFT045|Transmitting w/Dubious UNPROTO Path!||
+WPUPCFT046|Transmitting w/Dubious IGATE Path!||
+WPUPCFT047|Init KISS-Mode||
+#
+#Configura Porta Meteo
+WPUPCFWX01|Configura Porta Meteo||
+WPUPCFWX02|Periferica della stazione||
+WPUPCFWX03|Correzione Portata pioggia (Settaggio Globale)||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|Nessuna Correzione||
+#
+#Configure Stazione
+WPUPCFS001|Configura Dati Stazione||
+WPUPCFS002|Nominativo||
+WPUPCFS003|LAT||
+WPUPCFS004|grad||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Simbolo della Stazione||
+WPUPCFS010|Raggruppa/Sovrapponi||
+WPUPCFS011|Simbolo||
+WPUPCFS028|Seleziona||
+WPUPCFS012|Potenza-guadagno||
+WPUPCFS013|Disattiva PHG||
+WPUPCFS014|Altezza antenna||
+WPUPCFS015|Guadagno antenna||
+WPUPCFS016|Omni||
+WPUPCFS017|Commenti:||
+WPUPCFS018|Ambiguit� posizione||
+WPUPCFS019|Nessuna||
+WPUPCFS020|cerchio di.11 miglia||
+WPUPCFS021|cerchio di1.15 miglia||
+WPUPCFS022|cerchio di11.51 miglia||
+WPUPCFS023|cerchio di69.09 miglia||
+WPUPCFS024|cerchio di.18 chilometri||
+WPUPCFS025|cerchio di1.85 chilometri||
+WPUPCFS026|cerchio di18.53 chilometri||
+WPUPCFS027|cerchio di 111.19 chilometri||
+WPUPCFS029|Invia posizioni compresse|C|
+#
+# PopUp "Oggetto/Entit�"
+POPUPOB001|Oggetto/Entit�||
+POPUPOB002|Nome||
+POPUPOB003|Imposta Oggetto||
+POPUPOB004|Elimina Oggetto||
+POPUPOB005|Modifica Oggetto||
+POPUPOB006|Crea Nuova Entit�||
+POPUPOB007|Oggetto Area||
+POPUPOB008|Abilita Oggetto Area||
+POPUPOB009|Colore Brillante||
+POPUPOB010|Riempimento||
+POPUPOB011|Cerchio||
+POPUPOB012|Linea a destra '/'||
+POPUPOB013|Linea a sinistra '\'||
+POPUPOB014|Triangolo||
+POPUPOB015|Rettangolo||
+POPUPOB016|Nero||
+POPUPOB017|Blu||
+POPUPOB018|Verde||
+POPUPOB019|Azzurro||
+POPUPOB020|Rosso||
+POPUPOB021|Viola||
+POPUPOB022|Giallo||
+POPUPOB023|Grigio||
+POPUPOB024|Spostamento lungo lat.:||
+POPUPOB025|Spostamento lungo long.:||
+POPUPOB026|Corridoio:||
+POPUPOB027|Opzioni Generiche||
+POPUPOB028|Posizione||
+POPUPOB029|Abilita simbolo postazione||
+POPUPOB030|Dati:||
+POPUPOB031|Simbolo postazione||
+POPUPOB032|Abilita compressione||
+POPUPOB033|Elimina Entit�||
+POPUPOB034|Modifica Entit�||
+POPUPOB035|Altitudine (piedi):||
+POPUPOB036|Velocit� (nodi):||
+POPUPOB037|Direzione:||
+POPUPOB038|Oggetto DF||
+POPUPOB039|Segnale - Altezza(HAAT) - Guadagno - Direttivit�||
+POPUPOB040|Larghezza fascio - Puntamento||
+POPUPOB041|Antenna Omni||
+POPUPOB042|Antenna Direzionale||
+POPUPOB043|Sconosciuta||
+POPUPOB044|Adotta l'Oggetto||
+POPUPOB045|Adotte l'Item||
+POPUPOB046|DF Bearing:||
+POPUPOB047|Probability Circles||
+POPUPOB048|Map View Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+#Configure Internet
+WPUPCFI001|Configura Rete||
+WPUPCFI002|Host ||
+WPUPCFI003|Porta ||
+WPUPCFI004|(host secondari)||
+WPUPCFI005|Host1||
+WPUPCFI006|Porta 1||
+WPUPCFI007|Host2||
+WPUPCFI008|Porta 2||
+WPUPCFI009|codice||
+WPUPCFI010|(Lascia vuoto se non necessario)||
+WPUPCFI011|Riconnettersi in caso di sconnessione?||
+WPUPCFI012|Funzionare da Gateway?||
+WPUPCFI013|Trasmetto i dati al TNC quando sono collegato ad Internet?||
+WPUPCFI014|Scrivo nel log le trasmissioni dalla Rete al TNC?|||
+WPUPCFI015|Parametri Filtro||
+#
+#Configure Database
+WPUPCFID01|Configura Database (TBD)||
+WPUPCFID02|Host ||
+WPUPCFID03|Porta ||
+WPUPCFID04|(host secondari)||
+WPUPCFID05|Host1||
+WPUPCFID06|Porta 1||
+WPUPCFID07|Host2||
+WPUPCFID08|Porta 2||
+WPUPCFID09|codice||
+WPUPCFID10|(Lascia vuoto se non necessario)||
+WPUPCFID11|Riconnettersi in caso di sconnessione?||
+WPUPCFID12|Funzionare da Gateway?||
+WPUPCFID13|Trasmetto i dati al TNC quando sono collegato ad Internet?||
+WPUPCFID14|Scrivo nel log le trasmissioni dalla Rete al TNC?|||
+WPUPCFID15|Parametri Filtro||
+#
+# PopUp "Configure AGWPE"
+WPUPCFIA01|Configura AGWPE||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Porta ||
+WPUPCFIA04|(Host secondari)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Porta1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Porta2||
+WPUPCFIA09|Codice segreto||
+WPUPCFIA10|((Lascia in Bianco se Nessuno)||
+WPUPCFIA11|Riconnetti su errore NET?||
+WPUPCFIA12|Opera come I-Gate?||
+WPUPCFIA13|Manda messaggi Broadcast via TNC durante operazione I-Gate?||
+WPUPCFIA14|Registra su Log I-Gate Transactions?||
+WPUPCFIA15|Porta radio di trasmissione||
+#
+#Configure Audio Alarms
+WPUPCFA001|Configura Suoni||
+WPUPCFA002|Comando esecuzione audio||
+WPUPCFA003|Allarme attivo||
+WPUPCFA004|File audio da eseguire||
+WPUPCFA005|Nuova stazione||
+WPUPCFA006|Nuovo messaggio||
+WPUPCFA007|Vicinanza||
+WPUPCFA008|Apertura banda||
+WPUPCFA009|Distanza minima||
+WPUPCFA010|Distanza massima||
+WPUPCFA011|Allarme meteo||
+#
+# PopUp "Configure Speech"
+WPUPCFSP01|Configura Annuncio||
+WPUPCFSP02|Annuncio su:||
+WPUPCFSP03|Nuova stazione||
+WPUPCFSP04|Nuovo Messaggio||
+WPUPCFSP05|Nuovo corpo del messaggio||
+WPUPCFSP06|Allarme di vicinanza||
+WPUPCFSP07|Apertura di banda||
+WPUPCFSP08|Allarme Meteo||
+WPUPCFSP09|Avviso Prossimit� Stazione Tracciata||
+#
+# Track Stazione
+WPUPTSP001|Segui Stazione||
+WPUPTSP002|Segui Nominativo||
+WPUPTSP003|Corrispondenza a caso||
+WPUPTSP004|Corrispondenza Esatta||
+WPUPTSP005|Segui ora!||
+WPUPTSP006|Annulla operazione||
+WPUPTSP007|Scarica tracciato||
+WPUPTSP008|Nominativo||
+WPUPTSP009|Percorso iniziato (ore fa)||
+WPUPTSP010|Durata percorso (ore)||
+#
+#Messages
+WPUPMSB001|Casella messaggi %d||
+WPUPMSB002|Casella messaggi a gruppo %d||
+WPUPMSB003|Nominativi stazioni:||
+WPUPMSB004|Nominativo gruppo:||
+WPUPMSB005|Nuovo/Refresh nominativo||
+WPUPMSB006|Nuovo gruppo||
+WPUPMSB007|Cancella storico Msg||
+WPUPMSB008|Messaggio:||
+WPUPMSB009|Invia ora!||
+WPUPMSB010|Percorso:||
+WPUPMSB011|Cancella Msg in attesa||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Broadcast||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Path||
+WPUPMSB020|Use Default Path(s)||
+WPUPMSB021|Direct (No path)||
+WPUPMSB022|Reverse Path (Hint):||
+#
+#Auto Reply
+WPUPARM001|Cambia risposta automatica||
+WPUPARM002|Risposta:||
+#
+#Help Index
+WPUPHPI001|Indice guida||
+WPUPHPI002|Visualizza||
+#
+#Stazione Info popup
+WPUPSTI000|Oggetto Inserito da: %s||
+WPUPSTI001|Informazioni stazione||
+WPUPSTI002|Invia messaggio||
+WPUPSTI003|Cerca nel Database FCC||
+WPUPSTI004|Cerca nel Database RFC||
+WPUPSTI005|Pacchetti recevuti: %d     Ultima stazione ascoltata: ||
+WPUPSTI006|Ascoltata dal TNC sulla periferica %d, ||
+WPUPSTI007|Ascoltata ||
+WPUPSTI008|Ascoltata l'ultima volta in locale||
+WPUPSTI009|Ascoltata l'ultima volta dal TNC, periferica %d||
+WPUPSTI010|Ascoltata l'ultima volta da Internet sulla periferica %d||
+WPUPSTI011|ultima via File||
+WPUPSTI012|Ascoltata l'ultima volta via Unknown||
+WPUPSTI013|, e ha cambiato posizione||
+WPUPSTI014|Potenza attuale:||
+WPUPSTI016|Altitudine: %.0f%s||
+WPUPSTI017| Direzione: %s� ||
+WPUPSTI018| Velocit�: %.1f km/ora||
+WPUPSTI019| Velocit�: %.1f miglia/ora||
+WPUPSTI020|%0.1f Miglia||
+WPUPSTI021|%0.1f chilometri||
+WPUPSTI022|Distanza dalla mia Stazione: %s, direzione rispetto alla mia stazione: %s||
+WPUPSTI023|Ultima posizione: ||
+WPUPSTI024|Dati meteorologici %c:%s||
+WPUPSTI025|Direzione del vento: %s�, Velocit�: %03d km/ora||
+WPUPSTI026|Direzione del vento: %s�, Velocit�: %s miglia/ora||
+WPUPSTI027| Picco: %03d km/ora||
+WPUPSTI028| Picco: %s MPH||
+WPUPSTI029|Temperatura: %02.1f�C ||
+WPUPSTI030|Temperatura: %s�F ||
+WPUPSTI031|Umidit�: %s%%  ||
+WPUPSTI032|Humidex: %02.1f�C ||
+WPUPSTI033|Pressione: %s mb ||
+WPUPSTI034|Neve: %0.1f (cm/24ora) ||
+WPUPSTI035|Neve: %0.0f (inch/24ora) ||
+WPUPSTI036|Pioggia: ||
+WPUPSTI037|%0.2f (mm/ora)   ||
+WPUPSTI038|%0.2f (pollici/ora)   ||
+WPUPSTI039|%0.2f (mm/Giorno)  ||
+WPUPSTI040|%0.2f (pollici/Giorno)  ||
+WPUPSTI041|%0.2f (mm/da mezzanotte)||
+WPUPSTI042|%0.2f (pollici/da mezzanotte)||
+WPUPSTI043|Percorso dei dati: %s||
+WPUPSTI044|Commenti %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Elimina traccia||
+WPUPSTI046|Pioggia totale: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (pollici)||
+WPUPSTI049|Richiesta traccia||
+WPUPSTI050|Richiesta Messaggi non Riconosciuti||
+WPUPSTI051|Richiesta Stazioni Dirette||
+WPUPSTI052|Richiesta Versione Stazione||
+WPUPSTI053|Modifica Oggetto/Entit�||
+WPUPSTI054|Registra Tracciato||
+WPUPSTI055|Ripetuto da:||
+WPUPSTI056|Abilita Aggiornamento Automatico||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|Puntamento DF: %s||
+WPUPSTI059|Stato %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Temp Carburante: %02.1f�C  ||
+WPUPSTI061|Temp Carburante: %s�F   ||
+WPUPSTI062|Umidit� Carburante: %s%%   ||
+WPUPSTI063|Pressione: %0.2f in Hg||
+WPUPSTI064|Ricevi avvisi NWS||
+WPUPSTI065|Chiamata tattica: %s||
+WPUPSTI066|Assign Tactical Call||
+WPUPSTI067|Current Range: %d miles||
+WPUPSTI068|none||
+WPUPSTI069|default||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|range||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Range||
+WPUPSTI076|No signal detected||
+WPUPSTI077|Detectible signal (Maybe)||
+WPUPSTI078|Detectible signal but not copyable)||
+WPUPSTI079|Weak signal, marginally readable||
+WPUPSTI080|Noisy but copyable signal||
+WPUPSTI081|Some noise, easy to copy signal||
+WPUPSTI082|Good signal w/detectible noise||
+WPUPSTI083|Near full-quieting signal||
+WPUPSTI084|Full-quieting signal||
+WPUPSTI085|Extremely strong & full-quieting signal||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF Beamwidth||
+WPUPSTI089|DF Length||
+WPUPSTI090|Not Valid||
+WPUPSTI091|Change Trail Color||
+WPUPSTI092|Clear DF Bearing||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|ALOHA radius: %d %s||
+WPUPALO002|Stations inside ALOHA circle: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiles (in motion): %d||
+WPUPALO005| Mobiles (other):     %d||
+WPUPALO006| WX stations:         %d||
+WPUPALO007| Home stations:       %d||
+WPUPALO008|Last calculated %d %s %d %s ago.||
+WPUPALO666|ALOHA radius not calculated yet||
+#
+# FCC-RAC Call Look up
+STIFCC0001|Ricerca nel database FCC||
+STIFCC0002|Ricerca nel database RAC||
+STIFCC0003|Nome:||
+STIFCC0004|Indirizzo:||
+STIFCC0005|Citt�:||
+STIFCC0006|Stato:||
+STIFCC0007|Codice Postale:||
+STIFCC0008|Informazioni base||
+STIFCC0009|Informazioni avanzate ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+#
+# FCC-RAC Call Look up
+STIFCC0100|FCC index old, rebuilding||
+STIFCC0101|Callsign Search||
+STIFCC0102|Callsign Not Found!||
+STIFCC0103|RAC index old, rebuilding||
+#
+#
+#Band open message
+UMBNDO0001|ad una distanza di||
+#
+#Universal Options
+UNIOP00001|OK||
+UNIOP00002|Annulla||
+UNIOP00003|Chiudi||
+UNIOP00004|Miglia||
+UNIOP00005|Chilometri||
+UNIOP00006|Periferica||
+UNIOP00007|Aggiungi||
+UNIOP00008|Cancella||
+UNIOP00009|Propriet�||
+UNIOP00010|Consenti la trasmissione?||
+UNIOP00011|Attiva all'avvio?||
+UNIOP00012|km/ora||
+UNIOP00013|miglia/ora||
+UNIOP00014|C||
+UNIOP00015|F||
+UNIOP00016|mm||
+UNIOP00017|pollici||
+UNIOP00018|mm/Giorno||
+UNIOP00019|pollici/Giorno||
+UNIOP00020|mm/ora||
+UNIOP00021|pollici/ora||
+UNIOP00022|mm da mezzanotte||
+UNIOP00023|pollici da mezzanotte||
+UNIOP00024|gradi||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|in Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Regolare il tempo del sistema dal GPS||
+UNIOP00030|Ripeti?||
+UNIOP00031|m||
+UNIOP00032|Apply|||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|day||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# PopUp "Station Chooser"
+STCHO00001|Scelta Stazione||
+#
+#DISPLAY Meteo ALERT 
+WPUPWXA001|Allarmi Meteo||
+WPUPWXA002|Lista allarmi meteo||
+#
+# Configure Interfaces 
+WPUPCIF001|Interfacce installate||
+WPUPCIF002|Scelta tipo di interfaccia||
+#
+#Configure AX.25 
+WPUPCAX001|Configura TNC AX.25||
+WPUPCAX002|Periferica TNC AX.25||
+#
+#Interface device names 
+IFDNL00000|Nessuna||
+IFDNL00001|TNC Seriale||
+IFDNL00002|TNC Seriale con GPS connesso con cavo HSP||
+IFDNL00003|GPS Seriale||
+IFDNL00004|Meteo Seriale||
+IFDNL00005|Server Internet||
+IFDNL00006|TNC AX.25||
+IFDNL00007|GPS in rete (via gpsd)||
+IFDNL00008|Meteo in rete||
+IFDNL00009|TNC Seriale con GPS connesso con cavo AUX||
+IFDNL00010|TNC Seriale in KISS||
+IFDNL00011|Database su Rete (Non ancora Implementato)||
+IFDNL00012|AGWPE Via Rete||
+IFDNL00013|TNC Seriale in Multi-Port KISS||
+IFDNL00014|SQL Database (Experimental)||
+#
+#Interface device info 
+IFDIN00000|%s %2d %s sulla seriale %s   %s|| 
+IFDIN00001|%s %2d %s connettendo %s:%d   %s|| 
+IFDIN00002|%s %2d %s usa la porta %s   %s|| 
+IFDIN00003|%s %2d  %s  %s %s   %s|| 
+IFDIN00004|%s %2d  %s  %s %s:%d   %s|| 
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006| Disattiva ||
+IFDIN00007|  Attiva   ||
+IFDIN00008|  ERRORE   ||
+IFDIN00009|SCONOSCIUTO||
+#
+#Interface control
+IFPUPCT000|Controllo interfaccia||
+IFPUPCT001|Avvia||
+IFPUPCT002|Ferma||
+IFPUPCT003|Avvia Tutte||
+IFPUPCT004|Ferma Tutte||
+#
+#IGate control
+IGPUPCF000|Opzioni Gateway||
+IGPUPCF001|Disabilita tutto il traffico per il gateway||
+IGPUPCF002|Permetti solo il traffico verso il Gateway||
+IGPUPCF003|Permetti il traffico Radio->Rete e Rete->Radio||
+IGPUPCF004|Igate -> RF Path   ||
+#
+#Stazione Meteo
+WXPUPSI000|Stazione Meteo||
+WXPUPSI001|Tipo di Stazione meteo||
+WXPUPSI002|Dati correnti||
+WXPUPSI003|Direzione del vento||
+WXPUPSI004|Velocit� del vento||
+WXPUPSI005|Raffiche||
+WXPUPSI006|Temperatura||
+WXPUPSI007|Pioggia totale||
+WXPUPSI008|Pioggia totale odierna||
+WXPUPSI009|Pressione||
+WXPUPSI010|Umidit�||
+WXPUPSI011|Peet Bros ULTIMETER 2000 (Modalit� Data Logging)||
+WXPUPSI012|Peet Bros ULTIMETER II ||
+WXPUPSI013|Peet Bros ULTIMETER 2000 (Modalit� Packet)||
+WXPUPSI014|Pioggia (ultima ora)||
+WXPUPSI015|Pioggia (24 ore)||
+WXPUPSI016|Qualimetrics Q-Net||
+WXPUPSI017|Peet Bros ULTIMETER 2000 Type (Complete Mode)||
+WXPUPSI018|Temp.rugiada||
+WXPUPSI019|Velocit� massima vento||
+WXPUPSI020|Vento Freddo||
+WXPUPSI021|Indice Termico||
+WXPUPSI022|Pressione ultime 3 Ore||
+WXPUPSI023|Temp. Massima||
+WXPUPSI024|Temp. Minima||
+WXPUPSI025|Radio Shack Meteo-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Stn Lists
+LHPUPNI000|Lista stazioni||
+LHPUPNI001|Lista stazioni mobili||
+LHPUPNI002|Lista stazioni meteo||
+LHPUPNI003|Lista stazioni locali||
+LHPUPNI004|Lista ultime stazioni||
+LHPUPNI005|Oggetti e Dettagli||
+LHPUPNI006|Oggetti e Dettagli personali||
+LHPUPNI010|#||
+LHPUPNI011|Sigla||
+LHPUPNI012|#Pack||
+LHPUPNI013|Data e Ora||
+LHPUPNI014|Percorso||
+LHPUPNI015|PHG||
+LHPUPNI016|Commenti||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Latitudine||
+LHPUPNI104|Longitudine||
+LHPUPNI105|#Pack||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temperatura||
+LHPUPNI204|Umidit�||
+LHPUPNI205|Pressione||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Lat/Lon or UTM||
+#
+# Maps Meteo Alert styles
+PULDNMAT01|Mostra allarmi sopra altre mappe||
+PULDNMAT02|Mostra allarmi sotto altre mappe||
+#
+# Error/popup messages 
+POPEM00001|Localizza errore!||
+POPEM00002|Stazione %s non trovata!||
+POPEM00003|Errore nell'inseguimento!||
+POPEM00004|Errore dell'interfaccia!||
+POPEM00005|Nome della porta %s non valido||
+POPEM00006|Nome della porta AX.25 %s non valido||
+POPEM00007|Nominativo %s non valido||
+POPEM00008|Destinazione AX.25, Nominativo o digipeater errati||
+POPEM00009|Impossibile aprire la porta AX.25, %s||
+POPEM00010|Non posso collegare la porta AX.25, %s||
+POPEM00011|Connessione al nominativo AX.25 non riuscita, %s||
+POPEM00012|AX.25 errore sull'uscita di UI||
+POPEM00013|AX.25: problema nel file axports||
+POPEM00014|AX.25:  %s||
+POPEM00015|Errore nell'apertura dell'interfaccia %d (Fallito)||
+POPEM00016|Errore nell'apertura dell'interfaccia %d (Tempo scaduto)||
+POPEM00017|Non sono disponibili altre interfacce!||
+POPEM00018|Richiesta dati - Messaggio su linea singola|
+POPEM00019|La trasmissione dalla porta %d � disattivata|
+POPEM00020|Errore del Database!|
+POPEM00021|Supporto AX.25 non compilato in Xastir!||
+POPEM00022|Errore di input!|
+POPEM00023|Non e' stato specificato alcun nome per questo punto!|
+POPEM00024|Il nome assegnato al punto � gi� in uso!|
+POPEM00025|Non trovato!||
+POPEM00026|Il tracciamento verr� visualizzato quando appare||
+POPEM00027|Informazione non completa. Campi vuoti?||
+POPEM00028|Non � possibile aprire il file||
+POPEM00029|Trovato!||
+POPEM00030|Simbolo Stazione Meteo||
+POPEM00031|Cambiato al simbolo Meteo '/_', altre opzioni:  '\_'  '/W'  e  '\W'||
+POPEM00032|Attenzione: Stai usando il simbolo Meteo del Servizio Nazionale!||
+POPEM00033|Nessun dato GPS!||
+POPEM00034|Disabilito TX Mia Posizione fino all'arrivo dei dati GPS!||
+POPEM00035|Attenzione||
+POPEM00036|Nota||
+POPEM00037|presente interfaccia HSP: l'intervallo di lettura del GPS viene aumentato||
+POPEM00038|Name Conflicts With Existing Object/Item/Station||
+POPEM00039|Illegal characters found, substituting periods in their place||
+POPEM00040|Custom outgoing path was lost||
+POPEM00041|Processing another file.  Wait a bit, then try again||
+POPEM00042|Object not owned by me! Try adopting the object first.||
+POPEM00043|Not an Object/Item!||
+POPEM00044|Fetch Findu Trail: Failed||
+POPEM00045|Fetch Findu Trail: Complete||
+POPEM00046|Berkeley DB header/shared library do NOT match! Disabling map cache.||
+POPEM00047|Global transmit is DISABLED. Emergency beacons are NOT going out!||
+POPEM00048|Emergency Beacon Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmitting every 60 seconds!||
+POPEM00050|Interfaces or posits/transmits DISABLED.  Emergency beacons are NOT going out!||
+POPEM00051|Altnet is enabled (Configure->Defaults dialog)||
+POPEM00052|Callsign is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We're trying to talk to ourselves!||
+# 
+# Jump Location 
+JMLPO00001|Posizione Mappa||
+JMLPO00002|Vai!||
+JMLPO00003|Nome del nuovo punto:||
+#
+# Bollettini
+BULMW00001|Bollettini||
+BULMW00002|Raggio (0, senza limite)||
+BULMW00003|Cambia raggio||
+#
+# All Message Traffic
+AMTMW00001|Traffico di tutti i messaggi||
+AMTMW00002|Raggio (0, senza limite)||
+#
+# Speech Strings
+SPCHSTR001|chilometri||
+SPCHSTR002|metri||
+SPCHSTR003|miglia||
+SPCHSTR004|yards||
+SPCHSTR005|%s, distanza � %d %s.||
+SPCHSTR006|%s, distanza � %.1f %s.||
+SPCHSTR007|%s, distanza � %d %s %s %s.||
+SPCHSTR008|%s, distanza � %.1f %s %s %s.||
+SPCHSTR009|Nuovo Allarme Meteo||
+SPCHSTR010|Nuovo Nominativo||
+SPCHSTR011|Ascoltato, D X, %s, alla distanza di %.1f %s||
+#
+SPCHDIRN00|nord di||
+SPCHDIRS00|sud di||
+SPCHDIRE00|est di||
+SPCHDIRW00|ovest di||
+SPCHDIRNE0|nordest di||
+SPCHDIRNW0|nordovest di||
+SPCHDIRSE0|sudest di||
+SPCHDIRSW0|sudovest di||
+#
+# Symbol Selection Dialog
+SYMSEL0001|Selezione simbolo||
+SYMSEL0002|Tabella Primaria||
+SYMSEL0003|Tabella Secondaria||
+#
+# Finestra di dialogo proprieta di stampa
+PRINT0001|Propriet� di Stampa||
+PRINT0002|Formato Carta||
+PRINT0003|Ruota Immagine automaticamente
+PRINT0004|Ruota Immagine di 90� in senso antiorario||
+PRINT0005|Ridimensiona immagine||
+PRINT0006|Scala:||
+PRINT0007|Sfondo bianco||
+PRINT0008|Stampa in bianco e nero||
+PRINT0016|Inverti i colori||
+PRINT0009|Risoluzione del file Postscript:||
+PRINT0010|Anteprima||
+PRINT0011|Stampa su file||
+PRINT0012|Elaborazione immagine su file...||
+PRINT0013|Conversione in Postscript...||
+PRINT0014|Fine elaborazione file.||
+PRINT0015|Stato del processo di stampa||
+#
+# Finestra di dialogo proprieta di stampa
+PRINT1001|Direct to:||
+PRINT1002|Via Previewer:||
+#
+# Finestra di dialogo localizza elemento mappa
+FEATURE001|Nome:||
+FEATURE002|Stato/Provincia:||
+FEATURE003|Contea:||
+FEATURE004|Quadrante:||
+FEATURE005|Tipo:||
+FEATURE006|File GNIS:||
+FEATURE007|Address:||
+FEATURE008|City:||
+FEATURE009|Mark Destination||
+FEATURE010|Zip Code:||
+FEATURE011|Geocoding File||
+#
+# Coordinate Calculator Dialog
+COORD001|Calcolo Coordinate||
+COORD002|Calc||
+COORD003|Calcola||
+COORD004|Cancella||
+COORD005|UTM||
+COORD006|Latitudine o||
+COORD007|Longitudine o||
+COORD008|Zona||
+COORD009|UTM Est||
+COORD010|UTM Nord||
+COORD011|               Decimal Degrees:  ||
+COORD012|       Degrees/Decimal Minutes:  ||
+COORD013|  Degrees/Minutes/Dec. Seconds:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|Military Grid Reference System:  ||
+COORD016|       Maidenhead Grid Locator:  ||
+COORD017| **       Sorry, your input was not recognized!        **||
+COORD018| **   Please use one of the following input formats:   **||
+#
+#
+# Smart Beaconing Dialog
+SMARTB001|SmartBeaconing||
+SMARTB002|Tasso Alto (secs):||
+SMARTB003|Alta Velocit� (mph):||
+SMARTB004|Alta Velocit� (kmh):||
+SMARTB005|Tasso Basso (mins):||
+SMARTB006|Bassa Velocit� (mph):||
+SMARTB007|Bassa Velocit� (kmh):||
+SMARTB008|Giro Minimo (gradi):||
+SMARTB009|Inclinazione Giro:||
+SMARTB010|Tempo di Attesa (secondi):||
+SMARTB011|Abilita SmartBeaconing(tm)||
+#
+#
+#
+# Gamma Adjust Dialog
+GAMMA001|Impostazione Correzione Gamma||
+GAMMA002|Correzione Gamma||
+#
+#
+# Map labels font Dialog
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Font Minuscolo||
+MAPFONT004|Map Font Piccolo||
+MAPFONT005|Map Font Medio||
+MAPFONT006|Map Font Grande||
+MAPFONT007|Map Font Enorme||
+MAPFONT008|Map Font Border||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV ID Font||
+#
+# Distance/Bearing on status line
+PULDNDB001|Stato Distanza/Puntamento||
+#
+#
+# GPS Transfer Operations
+GPS001|Trasferimento GPS||
+GPS002|Nome File||
+GPS003|Seleziona Colore||
+GPS004|Rosso||
+GPS005|Verde||
+GPS006|Nero||
+GPS007|Bianco||
+GPS008|Arancione||
+GPS009|Blu||
+GPS010|Giallo||
+GPS011|Viola||
+#
+#
+# Map Properties Dialog
+MAPP001|Propriet� Mappa||
+MAPP002|Max   Min  Disegna Mappa USGS Auto||
+MAPP003|Zoom  Zoom Livello Riempi DRG Map  Percorso/Nome File||
+MAPP004|Cambia Livello->||
+MAPP005|Riempito->||
+MAPP006|Si||
+MAPP007|No||
+MAPP008|Automappe->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+#
+# Time Strings
+TIME001|Giorno||
+TIME002|Giorni||
+TIME003|Ora||
+TIME004|Ore||
+TIME005|Minuto||
+TIME006|Minuti||
+TIME007|Secondo||
+TIME008|Secondi||
+#
+#
+# Map Caching
+CACHE001|Map now cached||
+CACHE002|Loading Cached Map||
+CACHE003|Map not found in cache...||
+#
+#
+# Map Screen Misc
+RANGE001|RANGE SCALE||
+#
+#
+# GPS Status
+GPSS001|WAAS or PPS||
+GPSS002|DGPS||
+GPSS003|Valid SPS||
+GPSS004|Invalid||
+GPSS005|Sats/View||
+GPSS006|Fix||
+GPSS007|!GPS data is older than 30 seconds!||
+GPSS008|Simulation||
+GPSS009|Manual||
+GPSS010|Estimated||
+GPSS011|Float RTK||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data
+CADPUD001|Area Object||
+CADPUD002|Area Label:||
+CADPUD003|Comment:||
+CADPUD004|Probability (%):||
+CADPUD005|OK||
+CADPUD006|CAD Dialog||
+CADPUD007|Show/Edit Details||
+CADPUD008|Cancel||
+CADPUD009|Delete CAD objects?||
+CADPUD010|Delete All||
+CADPUD011|Delete Selected||
+CADPUD012|Solid||
+CADPUD013|Dashed||
+CADPUD014|Double Dash||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|XASTIR Map of %s (upper left) to %s (lower right).  UTM %d m grid, %s datum. ||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA002|XASTIR Map of %s (upper left) to %s %s (lower right).  Lat/Long grid, %s datum.||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA003|XASTIR Map of %s (upper left) to %s (lower right).  UTM zones, %s datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST002|Postgreql with Postgis||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Xastir Simple Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA02|Xastir CAD Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA03|Xastir full Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/language-MuppetsChef.sys b/config/language-MuppetsChef.sys
new file mode 100644
index 0000000..64e34a3
--- /dev/null
+++ b/config/language-MuppetsChef.sys
@@ -0,0 +1,1143 @@
+# language-MuppetsChef.sys, translated from language-English.sys
+# Please do not edit this derived file.
+MENUTB0001|Feele|F|
+MENUTB0002|Feeuo|V|
+MENUTB0004|Mep|M|
+MENUTB0005|Steteeun|S|
+MENUTB0006|Messege|e|
+MENUTB0010|Interffece|I|
+MENUTB0009|Help|H|
+PULDNFI001|Cunffeeguore|C|
+PULDNFI002|Oupee-a Lug Feele|O|
+PULDNFI003|Test|T|
+PULDNFI004|Ixeet|x|
+PULDNFI007|Chuonge-a Debuog Leffel|D|
+PULDNFI010|TNC Luggeeng||
+PULDNFI011|Net Luggeeng||
+PULDNFI012|IGete-a Luggeeng||
+PULDNFI013|VX Luggeeng||
+PULDNFI014|PNG Snepshuts||
+PULDNFI015|Preent|P|
+PULDNFI016|KML Snepshuts||
+PULDNVI001|Buolleteens|B|
+PULDNVI002|Incumeeng Dete|I|
+PULDNVI003|Mubeele-a Steteeuns|M|
+PULDNVI004|Ell Steteeuns|A|
+PULDNVI009|Lucel Steteeuns|S|
+PULDNVI012|Lest Steteeuns|L|
+PULDNVI005|Veezeer Steteeuns|W|
+PULDNVI008|Ouon Veezeer Dete|D|
+PULDNVI007|Veezeer Ilerts|e|
+PULDNVI011|Messege-a Treffeec|T|
+PULDNVI013|Oupteeme|U|
+PULDNVI014|Prugrem Ouopteeme||
+PULDNVI015|GPS Stetuos||
+PULDNVI016|ELOHE Steteestics||
+PULDNCF004|Steteeun|S|
+PULDNCF001|Deffuolts|D|
+PULDNCF003|Teemeeng|T|
+PULDNCF002|Cuordeenete-a System|o|
+PULDNCF006|Ouodeeu Ilerms|A|
+PULDNCF007|Speech|p|
+PULDNCF008|Seffe-a Cunffeeg Nuo!|C|
+PULDNMP001|Mep Chuoser|M|
+PULDNMP012|Mep DEEspley Buokmerks|B|
+PULDNMP014|Lucete-a Mep Feetuore|F|
+PULDNMP016|DEEseble-a Fest Zuom/Puon/Hume||
+PULDNMP013|DEEseble-a Ill Meps||
+PULDNMP002|Ineble-a Ououtu Meps||
+PULDNMP003|Ineble-a Mep Greed||
+PULDNMP004|Ineble-a Mep Leffels||
+PULDNMP010|Ineble-a Mep Lebels||
+PULDNMP009|Ineble-a Iree-a Culur Feells||
+PULDNMP007|Ineble-a Veezeer Ilerts||
+PULDNMP005|Beckgruound Culur|C|
+PULDNMP006|Stetiun Text Style|T|
+PULDNMP026|Icun Ououotleene-a Style|O|
+PULDNMP011|Muouse-a Puinter Menuo|P|
+PULDNMP008|Mep Intenseety|I|
+PULDNMP020|Cunffeeguore-a Teegermep||
+PULDNMP021|Ouotu Mep - DEEseble-a Rester Meps||
+PULDNMP022|Index Nuo Meps ouon Stertuop||
+PULDNMP023|Index: Idd Nuo Meps|N|
+PULDNMP024|Index: Reendex ILL Meps!|R|
+PULDNMP025|Funts||
+PULDNMP015|Xffuntsel||
+PULDNMP027|Re-a-duonlued Meps (Nut ffrum ceche-a)||
+PULDNMP028|Fluosh Inture-a Mep Ceche-a!||
+PULDNMP029|FEEnd Iddress||
+PULDNMP030|Cunffeeguore-a OuoSGS DRG||
+PULDNMP031|Ineble-a Mep Burder||
+MPUPTGR001|Greed||
+MPUPTGR002|Cuountees||
+MPUPTGR003|CEEty Lebels||
+MPUPTGR004|Ourbuon Irees||
+MPUPTGR005|Mejur Rueds||
+MPUPTGR006|Streets||
+MPUPTGR007|Reelrueds||
+MPUPTGR008|Stete-a Lebels||
+MPUPTGR009|Interstete-a Lebels||
+MPUPTGR010|OuS Hvy Lebels||
+MPUPTGR011|Stete-a Hvy Lebels||
+MPUPTGR012|Select items tu be-a deespleyed:||
+MPUPTGR013|Reeffers||
+MPUPTGR014|Lekes||
+MPUPTGR015|Eurpurts, Perks, ietc||
+MPUPTGR016|Mep Intenseety||
+MPUPTGR017|Internet Mep Timeuout (sec)||
+MPUPTGR018|Ineble-a Tiger Meps||
+MPUPDRG001|Select items tu be-a deespleyed:||
+MPUPDRG002|Tint Ouonderlying Mep (XOR)||
+MPUPDRG003|Bleck||
+MPUPDRG004|Vheete||
+MPUPDRG005|Bluoe||
+MPUPDRG006|Red||
+MPUPDRG007|Bruon||
+MPUPDRG008|Gree||
+MPUPDRG009|Puorple||
+MPUPDRG010|Yelluo||
+MPUPDRG011|LEEght Bluoe||
+MPUPDRG012|LEEght Red||
+MPUPDRG013|LEEght Puorple||
+MPUPDRG014|LEEght Grey||
+MPUPDRG015|LEEght Bruon||
+WPUPMCP001|Mep Chuoser||
+PULDNMMC01|Cleer|C|
+PULDNMMC02|Fectur|V|
+PULDNMMC03|250k Tupu|2|
+PULDNMMC04|100k Tupu|1|
+PULDNMMC05|24k Tupu|4|
+PULDNMMC06|Ixpuond Deers||
+PULDNMMC07|Durs/Meps Selected:||
+PULDNMMC08|Cleer Deers|C
+PULDNMMC09|Select Ill|S|
+PULDNMBC01|Grey||
+PULDNMBC02|MEEsty Ruse||
+PULDNMBC03|Neffy Bluoe||
+PULDNMBC04|Steel Bluoe||
+PULDNMBC05|Med..  Burk Burk Burk! See-a Gree||
+PULDNMBC06|Pele-a Gree||
+PULDNMBC07|Pele-a Guldenrud||
+PULDNMBC08|Guldenrud Yelluo||
+PULDNMBC09|Rusy Bruon||
+PULDNMBC10|Fure-a brick Red||
+PULDNMBC11|Vheete||
+PULDNMBC12|Bleck||
+PULDNMSL01|Bleck Burder|B|
+PULDNMSL02|Bleck Sheduo|S|
+PULDNMSL03|Text ouon Bleck|T|
+PULDNMIO01|Nu Ououotleene|N|
+PULDNMIO02|Bleck Ououotleene|B|
+PULDNMIO03|Grey Ououotleene|G|
+PULDNMIO04|Vheete-a Ououotleene|W|
+PULDNOT001|Oun||
+PULDNOT002|Ouff||
+PULDNOT003|Shurt||
+PULDNDP014|FEEnd Steteeun|F|
+PULDNDP001|Treck Steteeun|T|
+PULDNDP022|Fetch FEEnduo Treel|u|
+PULDNDP032|FEElter Dete||
+PULDNDP040|Select Nune||
+PULDNDP041|Select Meene||
+PULDNDP042|Select TNC||
+PULDNDP027|- Select Deerect||
+PULDNDP043|- Select FEEe-a Deegee||
+PULDNDP034|Select Net||
+PULDNDP019|Incluode-a Ixpured Dete||
+PULDNDP044|Select Steteeuns||
+PULDNDP028|- Select FEExed Steteeuns||
+PULDNDP029|- Select Muffeeng Steteeuns||
+PULDNDP030|- Select VX Steteeuns||
+PULDNDP053|  - Select CVOP VX Steteeuns||
+PULDNDP045|Select Ouobjects/Items||
+PULDNDP026|- Select VX Ouobjects/Items||
+PULDNDP039|- Select Veter Guoge-a Ouobjects/Items||
+PULDNDP031|- Select Ouozeer Ouobjects/Items||
+PULDNDP033|FEElter Deespley||
+PULDNDP010|DEEspley Cellseegn||
+PULDNDP012|DEEspley Symbul||
+PULDNDP011|- Rutete-a Symbul||
+PULDNDP007|DEEspley Treel||
+PULDNDP003|DEEspley Cuourse||
+PULDNDP004|DEEspley Speed|S|
+PULDNDP017|- DEEspley Shurt Speed||
+PULDNDP002|DEEspley Ilteetuode||
+PULDNDP009|DEEspley Veezeer Inffu||
+PULDNDP046|- DEEspley Veezeer Text||
+PULDNDP018|-- Temperetuore-a Ouonly||
+PULDNDP047|- DEEspley Vind Berb||
+PULDNDP054|DEEspley Iluhe-a Ceercle||
+PULDNDP013|DEEspley Pusitiun Imbeeguoity||
+PULDNDP008|DEEspley Puoer/Geen||
+PULDNDP021|- Ouose-a Deffuolt Puoer/Geen||
+PULDNDP020|- DEEspley Mubeele-a Puoer/Geen||
+PULDNDP023|DEEspley DF Ittreebuotes||
+PULDNDP123|DEEspley DF Beemveedt||
+PULDNDP223|DEEspley DF Beereeng||
+PULDNDP035|Ineble-a Deed-Reckuneeng||
+PULDNDP036|- DEEspley Irc||
+PULDNDP037|- DEEspley Cuourse||
+PULDNDP038|- DEEspley Symbul||
+PULDNDP005|DEEspley DEEst/Beereeng||
+PULDNDP024|DEEspley Lest Repurt Ige||
+PULDNDP015|Cleer Ill Stetiuns!!!|A|
+PULDNDP016|Cleer Ill Treels!!!|C|
+PULDNDP025|Cleer Ouobject/Item Heestury||
+PULDNDP048|Relued Ouobject/Item Heestury||
+PULDNDP049|Cleer Ill Tecticel Cells||
+PULDNDP050|Cleer Tecticel Cell Heestury||
+PULDNDP051|Select Tecticel Cells Ouonly||
+PULDNDP052|- Lebel Treelpuints||
+PULDNDP055|Ixpurt ill|E|
+PULDNDP056|Ixpurt tu KML Feele||
+PULDNUT001|Ineble-a Ingleesh Ouoneets|E|
+PULDNUT002|Metreec|M|
+PULDNMG001|Send Messege-a Tu|S|
+PULDNMG002|Oupee-a Gruoup Messeges|O|
+PULDNMG003|Cleer Ill Ououotguing Messeges|C|
+PULDQUS001|Generel Stetiuns Quoery|G|
+PULDQUS002|IGete-a Stetiuns Quoery|I|
+PULDQUS003|VX Stetiuns Quoery|W|
+PULDNMG004|Mudeeffy Ououtu Reply Messege|A|
+PULDNMG005|Ineble-a Ououtu Reply Messege||
+PULDNMG006|Setelleete-a Ick Mude|M|
+PULDNMG007|Shuo Pendeeng Messeges|P|
+PULDNTNT04|Interffece-a Cuntrul|C|
+PULDNTNT03|DEEseble-a Truonsmeet: ILL||
+PULDNTNT05|DEEseble-a Truonsmeet: My Puseetiun||
+PULDNTNT06|DEEseble-a Truonsmeet: Ouobjects/Items||
+PULDNTNT11|Ineble-a Serffer Purts|P|
+PULDNTNT01|Truonsmeet Nuo!|T|
+PULDNTNT07|Fetch GPS Treck|F|
+PULDNTNT08|Fetch GPS Ruoutes|R|
+PULDNTNT09|Fetch GPS Veypueents|W|
+PULDNTNT10|Fetch Germeen RINO Veypueents|G|
+PULDNHEL01|Ebuout|A|
+PULDNHEL02|Help Index|I|
+PULDNHEL03|IMERGENCY BEECON MODE INEBLE|E|
+PULDNHEL04|!!! IMERGENCY BEECON MODE !!!||
+PULDNHEL05|Ebuout Xesteer||
+POPUPMA001|Oupteeuns||
+POPUPMA00c|Center|C|
+POPUPMA015|Stetiun Inffu|S|
+POPUPMA002|In|I|
+POPUPMA003|Ouout|O|
+POPUPMA004|Zuom Leffel|L|
+POPUPMA005|Leffel 1|1|
+POPUPMA006|Leffel 16|6|
+POPUPMA007|Leffel 64|4|
+POPUPMA008|Leffel 256|2|
+POPUPMA009|Leffel 1024|0|
+POPUPMA010|Leffel 8192|8|
+POPUPMA017|Inture-a Vurld|E|
+POPUPMA016|Lest Mep Pus/Zuom|P|
+POPUPMA018|Oubject/Item->Creete|b|
+POPUPMA019|Oubject/Item->Mudeeffy|M|
+POPUPMA025|Muffe-a My Stetiun Here|H|
+POPUPMA011|Puon ouop|u|
+POPUPMA012|Puon duon|d|
+POPUPMA013|Puon lefft|l|
+POPUPMA014|Puon reeght|r|
+POPUPMA020|Meesuore||
+POPUPMA021|Muffe||
+POPUPMA022|TreckMe||
+POPUPMA023|Mudeeffeers Fuound!||
+POPUPMA024|Pleese-a tuorn OuoFF CepsLuck/NuomLuck/ScrullLuck/ouozeer mudeeffeers||
+POPUPMA026|Center & Zuom||
+POPUPMA027|  Leteetuode||
+POPUPMA028| Lungeetuode||
+POPUPMA029|Drev CED Ouobjects||
+POPUPMA030|Drev||
+POPUPMA031|Cluse-a Pulygun||
+POPUPMA032|Irese-a CED Pulyguns||
+POPUPMA033|**NOT OuoSED**||
+POPUPMA034|Cuostum Zuom Leffel||
+POPUPMA035|10% ououot||
+POPUPMA036|10% ien||
+POPUPMA037|Eree||
+POPUPMA038|squoere||
+POPUPMA039|squoere-a ffeet||
+POPUPMA040|squoere-a meters||
+POPUPMA041|Beereeng||
+POPUPMA042|degrees||
+POPUPMA043|Mudeeffy imbeeguouous puseetiun||
+POPUPMA044|Pusitiun imbeeguoity is ouon, yuour nuo pusitiun mey ippeer tu juomp..  Burk Burk Burk!||
+POPUPMA045|Predeffeened Ouobjects||
+POPUPMA046|CED Pulyguns||
+POPUPMA047|Ineble-a CED ouobjects||
+POPUPMA048|Ineble-a CED lebels||
+POPUPMA049|Ineble-a CED cumments||
+POPUPMA050|Ineble-a CED prubebeeleety||
+POPUPMA051|Ineble-a CED iree-a seeze||
+POPUPMA052|sq||
+POPUPMA053|fft||
+POPUPMA054|meters||
+POPUPMA055|mee|
+BBARZM0001|Zuom %s||
+BBARZM0002|Zuom %s Tr||
+BBARSTH001|%d/%d Steteeuns||
+BBARSTA000|%-9s Nuo ouobject!||
+BBARSTA001|%-9s Nuo stetiun!||
+BBARSTA002|%-9s||# new data (only display the call)
+BBARSTA003|Luedeeng Meps..  Burk Burk Burk!..||
+BBARSTA004|Meps Lueded||
+BBARSTA005|Mep Let/Lung Grid Ouon|O|
+BBARSTA006|Mep Let/Lung Grid Ouoff|f|
+BBARSTA007|Zee-a ouose-a ouoff Ououtu Meps, is nuo OuoN||
+BBARSTA008|Zee-a ouose-a ouoff Ououtu Meps, is nuo OuoFF||
+BBARSTA009|Zee-a ouose-a ouoff Mep Leffels is nuo OuoN||
+BBARSTA010|Zee-a ouose-a ouoff Mep Leffels is nuo OuoFF||
+BBARSTA011|Ouotu Reply Messege-a OuoFF!||
+BBARSTA012|FEEle-a dune-a..  Burk Burk Burk!.||
+BBARSTA013|Oupening GPS Purt||
+BBARSTA014|Clusing GPS Purt||
+BBARSTA015|Gut GPS RMC Streeng||
+BBARSTA016|Gut GPS GGE Streeng||
+BBARSTA017|Net deescunnected ffrum hust||
+BBARSTA018|Net cunnectiun timed ououot!||
+BBARSTA019|Luokeeng ouop hust %s||
+BBARSTA020|Cunnected tu %s||
+BBARSTA021|Net Cunnectiun Feeled!||
+BBARSTA022|Cuould nut beend sucket!||
+BBARSTA023|Nu IP ffur Hust!||
+BBARSTA024|Nu Hust Speceeffeed||
+BBARSTA025|Hust ffuound, Cunnecting %d||
+BBARSTA026|Veeting ffur GPS dete-a fee-a HSP..||
+BBARSTA027|Cleering HSP getting TNC dete-a..  Burk Burk Burk!.||
+BBARSTA028|Luedeeng %s||
+BBARSTA029|Oupening VX Purt||
+BBARSTA030|Clusing VX Purt||
+BBARSTA031|Luokeeng ouop hustneme-a %d||
+BBARSTA032|Decuded VX Dete||
+BBARSTA033|Ichu ffrum deegeepeeter||
+BBARSTA034|Luedeeng Veezeer Ilert Meps||
+BBARSTA035|Veeting ffur GPS dete-a fee-a IOuX..||
+BBARSTA036|Cleering IOuX getting TNC dete-a..  Burk Burk Burk!.||
+BBARSTA037|GPS Dete-a Cumplete||
+BBARSTA038|Pusitiun chuonge-a ouon my steteeun||
+BBARSTA039|Indexing %s||
+BBARSTA040|Emeteuor IPRS(tm) Stetiun %s||
+BBARSTA041|Veeting ffur GPS dete-a..  Burk Burk Burk!.||
+BBARSTA042|Truonsmeetting ouobjects/ietems||
+BBARSTA043|Luggeeng||
+BBARSTA044|ELOHE deestuonce-a is %d%s||
+BBARSTA045|Luedeeng symbuls..  Burk Burk Burk!..||
+BBARSTA046|Reluedeeng symbuls..  Burk Burk Burk!..||
+BBARSTA047|Initieleeze-a my stetiun..  Burk Burk Burk!..||
+BBARSTA048|Stert interffeces..  Burk Burk Burk!..||
+BBARSTA049|Reedeeng tiles..  Burk Burk Burk!..||
+BBARSTA050|Duonluedeeng tiles..  Burk Burk Burk!..||
+BBARSTA051|Duonluedeeng tile-a %lee ouoff %lee||
+WPUPDPD001|DEEspley Pecket Dete||
+WPUPDPD002|TNC Dete-a ouonly|T|
+WPUPDPD003|Net Dete-a ouonly|N|
+WPUPDPD004|TNC ouond Net Dete|a|
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Stetiun Cepebeeleeties||
+WPUPDPD008|MEEne-a Ouonly||
+WPUPLSP001|Lucete-a Steteeun||
+WPUPLSP002|Lucete-a Cellseegn||
+WPUPLSP003|Metch Cese|C|
+WPUPLSP004|Metch Ixect|E|
+WPUPLSP005|Lucete-a Nuo!|N|
+WPUPLSP006|Imergency Lucete-a!||
+WPUPLSP007|FCC/REC Luokuop||
+WPUPCFD001|Cunffeeguore-a Deffuolts||
+WPUPCFD002|Effter vhet interffel ouoff time-a vill i-a stetiun be-a cunsidered ouold?||
+WPUPCFD003|15 meen|1|
+WPUPCFD004|30 meen|3|
+WPUPCFD005|45 meen|4|
+WPUPCFD006|1 hr|H|
+WPUPCFD007|90 meen|9|
+WPUPCFD008|2 hrs|2|
+WPUPCFD009|Effter vhet interffel ouoff time-a vill i-a stetiun nut be-a deespleyed?||
+WPUPCFD010|6 hrs|6|
+WPUPCFD011|12 hrs|o|
+WPUPCFD012|1 Dey|D|
+WPUPCFD013|2 Deys|y|
+WPUPCFD014|1 Veek|W|
+WPUPCFD015|Truonsmeet Stetiun Ouopteeun||
+WPUPCFD016|FEExed Steteeun|F|
+WPUPCFD017|Mubeele-a Stetiun v/lucel teeme|l|
+WPUPCFD018|Mubeele-a Stetiun v/Zuoluo dete-a-teeme|Z|
+WPUPCFD019|Mubeele-a Stetiun v/Zuoluo time-a-secunds|u|
+WPUPCFD021|Stetiun Pusitiun v/veezeer|S|
+WPUPCFD022|Stetiun Pusitiun, Zuoluo dete-a-time-a, ouond veezeer|t|
+WPUPCFD023|Truonsmeet Rev VX dete-a?|R|
+WPUPCFD024|Truonsmeet cumpressed ouobjects/items?|C|
+WPUPCFD025|Ectiffete-a Ilternete-a net?|A|
+WPUPCFD026|Send pusitiun repurts it vhet interffels?||
+WPUPCFD027|Pup ouop nuo buolleteens||
+WPUPCFD028|Vern iff Mudeeffeer Keys||
+WPUPCFD029|FEEuo zeru-deestuonce-a buolleteens||
+WPUPCFD030|DEEseble-a Pusit Duope-a-Checks||
+WPUPCFD031|Lued predeffeened ouobjects ffrum ffeele||
+WPUPCFD032|My treels in ouone-a culur||
+WPUPCFD033|ELTNET:||
+WPUPCFTM01|Cunffeeguore-a Teemeeng||
+WPUPCFTM02|Pusit TX Interffel (meen)||
+WPUPCFTM03|Stetiun Ghusting Time-a (meen)||
+WPUPCFTM04|Oubject/Item Mex TX Interffel (meen)||
+WPUPCFTM05|Stetiun Cleer Time-a (huours)||
+WPUPCFTM06|GPS Check Interffel (sec)||
+WPUPCFTM07|Stetiun Delete-a Time-a (deys)||
+WPUPCFTM08|Deed-Reckuning Timeuout (meen)||
+WPUPCFTM09|Seriel Inter-Cher Deley (ms)||
+WPUPCFTM10|Nuo Treck Time-a (meen)||
+WPUPCFTM11|Nuo Treck Interffel (degrees)||
+WPUPCFTM12|RINO -> Ouobjects Interffel (meen), 0 = Deesebled||
+WPUPCFTM13|Snepshut Interffel (meen)||
+WPUPCFC001|Cunffeeguore-a Cuordeenete-a System||
+WPUPCFC002|Select Cuordeenete-a System||
+WPUPCFC003|dd..  Burk Burk Burk!ddddd|d|
+WPUPCFC004|dd mm..  Burk Burk Burk!mmm|m|
+WPUPCFC005|dd mm ss..  Burk Burk Burk!s|s|
+WPUPCFC006|OuTM|U|
+WPUPCFC007|OuSNG/MGRS2||
+WPUPCFC008|OuTM v/speceel zunes||
+WPUPCFG001|Cunffeeguore-a GPS||
+WPUPCFG003|Stuond ilune-a GPS purt||
+WPUPCFG002|Ouse-a GPS Pusitiun?||
+WPUPCFG004|GPS Ouopteeuns||
+WPUPCFG005|Stuond-ilune-a GPS||
+WPUPCFG006|TNC Cunnected GPS (HSP Ceble-a)||
+WPUPCFG007|TNC Cunnected GPS ouosing CTL-I||
+WPUPCFG008|GPS Time-a (Semple-a iffery)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 meen||
+WPUPCFG013|2 meen||
+WPUPCFG014|5 meen||
+WPUPCFG015|10 meen||
+WPUPCFG016|Netvurk Cunnected GPS||
+WPUPCFG017|GPSD Hust||
+WPUPCFG018|GPSD Purt||
+WPUPCFG019|Netvurk GPS fee-a GPSD||
+WPUPCFG020|Recunnect ouon ffeeluore-a?||
+WPUPCFG021|Netvurk Cunnected VX||
+WPUPCFG022|VX Hust||
+WPUPCFG023|VX Purt||
+WPUPCFT001|Cunffeeguore-a TNC||
+WPUPCFT002|Ouse-a TNC?||
+WPUPCFT003|TNC Purt||
+WPUPCFT004|Purt Setteengs||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|OunPrutu Peths||
+WPUPCFT012|Pet 1: %s fee-a ||
+WPUPCFT013|Pet 2: %s fee-a ||
+WPUPCFT014|Pet 3: %s fee-a ||
+WPUPCFT015|Purt Style||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,I,1||
+WPUPCFT018|7,Ouo,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Cunffeeguore-a TNC v/HSP GPS||
+WPUPCFT024|Dete-a Type||
+WPUPCFT025|Ouotu detect||
+WPUPCFT026|BEEnery Type||
+WPUPCFT027|ESCII Type||
+WPUPCFT028|Cunffeeguore-a TNC v/IOuX GPS||
+WPUPCFT029|Cunffeeguore-a TNC v/INFELID INOuM||
+WPUPCFT030|Cunffeeguore-a KISS TNC||
+WPUPCFT031|TNC Cunffeeguoretiun Feeles||
+WPUPCFT032|TNC Setuop Feeleneme|| 
+WPUPCFT033|TNC Shuotduon Feeleneme||
+WPUPCFT034|KISS Peremeters||
+WPUPCFT035|TXDeley (10 ms ouonits)||
+WPUPCFT036|Persistence-a (0 tu 255)||
+WPUPCFT037|SlutTime-a (10 ms ouonits)||
+WPUPCFT038|TxTeel (10 ms ouonits)||
+WPUPCFT039|Fuoll Duoplex||
+WPUPCFT040|Cunffeeguore-a Muolti-Purt KISS TNC||
+WPUPCFT041|Redeeu Purt||
+WPUPCFT042|Interffece-a Pruperties: Duobeeuous OuoNPROTO Pet!||
+WPUPCFT043|Pleese-a cunsider i-a shurter pet suoch is VIDE2-2 ouor VIDE1-1,VIDE2-2||
+WPUPCFT044|Interffece-a Pruperties: Duobeeuous IGETE Pet!||
+WPUPCFT045|Truonsmeetting v/Duobeeuous OuoNPROTO Pet!||
+WPUPCFT046|Truonsmeetting v/Duobeeuous IGETE Pet!||
+WPUPCFT047|Init KISS-mude-a ouon stertuop||
+WPUPCFWX01|Cunffeeguore-a VX Purt||
+WPUPCFWX02|Veezeer Stetiun deffeece||
+WPUPCFWX03|Reen Guoge-a Currectiun (Glubel Setting)||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|Nu Currecteeun||
+WPUPCFS001|Cunffeeguore-a Steteeun||
+WPUPCFS002|Cellseegn||
+WPUPCFS003|LET||
+WPUPCFS004|deg||
+WPUPCFS005|meen||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(I/V)||
+WPUPCFS009|Stetiun Symbul||
+WPUPCFS010|Gruoup/ouofferley||
+WPUPCFS011|Symbul||
+WPUPCFS028|Select||
+WPUPCFS012|Puoer - Heeght (HEAT) - Geen - Deerectiffeety||
+WPUPCFS013|DEEseble-a PHG||
+WPUPCFS014|Ountenne-a Heeght||
+WPUPCFS015|Ountenne-a Geen||
+WPUPCFS016|Oumnee||
+WPUPCFS017|Cumment:||
+WPUPCFS018|Pusitiun Imbeeguoity||
+WPUPCFS019|Nune||
+WPUPCFS020|.11 meeles||
+WPUPCFS021|1.15 meeles||
+WPUPCFS022|11.51 meeles||
+WPUPCFS023|69.09 meeles||
+WPUPCFS024|.18 keelumetres||
+WPUPCFS025|1.85 keelumetres||
+WPUPCFS026|18.53 keelumetres||
+WPUPCFS027|111.19 keelumetres||
+WPUPCFS029|Send cumpressed puseets|C|
+POPUPOB001|Oubject/Item||
+POPUPOB002|Neme-a:||
+POPUPOB003|Creete-a Nuo Ouobject||
+POPUPOB004|Delete-a Ouobject||
+POPUPOB005|Mudeeffy Ouobject||
+POPUPOB006|Creete-a Nuo Item||
+POPUPOB007|Eree-a Ouobject||
+POPUPOB008|Eree-a Ouobject||
+POPUPOB009|Bright Culur||
+POPUPOB010|Culur-Feell||
+POPUPOB011|Ceercle||
+POPUPOB012|LEEne-a-Right '/'||
+POPUPOB013|LEEne-a-Lefft '\'||
+POPUPOB014|Treeuongle||
+POPUPOB015|Rectuongle||
+POPUPOB016|Bleck||
+POPUPOB017|Bluoe||
+POPUPOB018|Gree||
+POPUPOB019|Cyuon||
+POPUPOB020|Red||
+POPUPOB021|Feeulet||
+POPUPOB022|Yelluo||
+POPUPOB023|Grey||
+POPUPOB024|Ouffset Ouop:||
+POPUPOB025|Ouffset Lefft (Ixcept '/'):||
+POPUPOB026|Curridur:||
+POPUPOB027|Generic Ouopteeuns||
+POPUPOB028|Luceteeun||
+POPUPOB029|Seegnpust||
+POPUPOB030|Signpust Text||
+POPUPOB031|Signpust Ouobject||
+POPUPOB032|Ineble-a Cumpresseeun||
+POPUPOB033|Delete-a Item||
+POPUPOB034|Mudeeffy Item||
+POPUPOB035|Eltituode-a (fft):||
+POPUPOB036|Speed (knuts):||
+POPUPOB037|Cuourse-a:||
+POPUPOB038|DF Ouobject||
+POPUPOB039|Signel - Heeght(HEAT) - Geen - Deerectiffeety||
+POPUPOB040|Beem Vidt - Beereeng||
+POPUPOB041|Oumni Ouontenne||
+POPUPOB042|Beem Ouontenne||
+POPUPOB043|Ouseless||
+POPUPOB044|Edupt Ouobject||
+POPUPOB045|Edupt Item||
+POPUPOB046|DF Beering:||
+POPUPOB047|Prubebeeleety Ceercles||
+POPUPOB048|Mep FEEuo Ouobject||
+POPUPOB049|MEEn (mee):||
+POPUPOB050|Mex (mee):||
+WPUPCFI001|Cunffeeguore-a Internet||
+WPUPCFI002|Hust ||
+WPUPCFI003|Purt ||
+WPUPCFI004|(Secundery husts)||
+WPUPCFI005|Hust1||
+WPUPCFI006|Purt1||
+WPUPCFI007|Hust2||
+WPUPCFI008|Purt2||
+WPUPCFI009|Pess-cude||
+WPUPCFI010|(Leeffe-a Bluonk iff Nune-a)||
+WPUPCFI011|Recunnect ouon NET ffeeluore-a?||
+WPUPCFI012|Ruon is ouon I-Gete-a?||
+WPUPCFI013|Bruedcest messeges fee-a TNC vhee-a ouon I-Gete-a?||
+WPUPCFI014|Lug I-Gete-a Truonsectiuns?||
+WPUPCFI015|FEElter Peremeters||
+WPUPCFID01|Cunffeeguore-a Detebese-a (TBD)||
+WPUPCFID02|Hust ||
+WPUPCFID03|Purt ||
+WPUPCFID04|(Secundery husts)||
+WPUPCFID05|Hust1||
+WPUPCFID06|Purt1||
+WPUPCFID07|Hust2||
+WPUPCFID08|Purt2||
+WPUPCFID09|Pess-cude||
+WPUPCFID10|(Leeffe-a Bluonk iff Nune-a)||
+WPUPCFID11|Recunnect ouon NET ffeeluore-a?||
+WPUPCFID12|Ruon is ouon I-Gete-a?||
+WPUPCFID13|Bruedcest messeges fee-a TNC vhee-a ouon I-Gete-a?||
+WPUPCFID14|Lug I-Gete-a Truonsectiuns?||
+WPUPCFID15|FEElter Peremeters||
+WPUPCFIA01|Cunffeeguore-a IGVPE||
+WPUPCFIA02|Hust ||
+WPUPCFIA03|Purt ||
+WPUPCFIA04|(Secundery husts)||
+WPUPCFIA05|Hust1||
+WPUPCFIA06|Purt1||
+WPUPCFIA07|Hust2||
+WPUPCFIA08|Purt2||
+WPUPCFIA09|Pess-cude||
+WPUPCFIA10|(Leeffe-a Bluonk iff Nune-a)||
+WPUPCFIA11|Recunnect ouon NET ffeeluore-a?||
+WPUPCFIA12|Ruon is ouon I-Gete-a?||
+WPUPCFIA13|Bruedcest messeges fee-a TNC vhee-a ouon I-Gete-a?||
+WPUPCFIA14|Lug I-Gete-a Truonsectiuns?||
+WPUPCFIA15|Truonsmeet RedeeuPurt||
+WPUPCFA001|Cunffeeguore-a Ououdeeu Ilerms||
+WPUPCFA002|Ouodeeu Pley Cummuond||
+WPUPCFA003|Elerm ouon||
+WPUPCFA004|Ouodeeu ffeele-a tu Pley||
+WPUPCFA005|Nuo Steteeun||
+WPUPCFA006|Nuo Messege||
+WPUPCFA007|Pruxeemeety||
+WPUPCFA008|Buond Ouopeneeng||
+WPUPCFA009|MEEnimuom Deestuonce||
+WPUPCFA010|Meximuom Deestuonce||
+WPUPCFA011|Veezeer Ilert||
+WPUPCFSP01|Cunffeeguore-a Speech||
+WPUPCFSP02|Speech Ououotpuot ouon:||
+WPUPCFSP03|Nuo Steteeun||
+WPUPCFSP04|Nuo Messege-a Ilert||
+WPUPCFSP05|Nuo Messege-a Budy||
+WPUPCFSP06|Pruximeety Ilert||
+WPUPCFSP07|Buond Ouopeneeng||
+WPUPCFSP08|Nuo Veezeer Ilert||
+WPUPCFSP09|Trecked Stetiun Pruximeety Ilert||
+WPUPTSP001|Treck Steteeun|| 
+WPUPTSP002|Treck Cellseegn|| 
+WPUPTSP003|Metch Cese|| 
+WPUPTSP004|Metch Ixect|| 
+WPUPTSP005|Treck Nuo!|| 
+WPUPTSP006|Cleer Treckeeng|| 
+WPUPTSP007|Duonlued Treel||
+WPUPTSP008|Cellseegn||
+WPUPTSP009|Stert Treel (hrs igu)||
+WPUPTSP010|Treel Lengt (hrs)||
+WPUPMSB001|Send Messege-a Bux %d||
+WPUPMSB002|Send Gruoup Messege-a Bux %d||
+WPUPMSB003|Stetiun's Cell:||
+WPUPMSB004|Gruoup's Cell:||
+WPUPMSB005|Nuo/Reffresh Cell||
+WPUPMSB006|Nuo Gruoup||
+WPUPMSB007|Cleer Msg Heestury||
+WPUPMSB008|Messege-a:||
+WPUPMSB009|Send Nuo!||
+WPUPMSB010|Pet:||
+WPUPMSB011|Cuoncel Pendeeng Msgs||
+WPUPMSB012|KEEck Teemer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Bruedcest||
+WPUPMSB016|*TIMEOOuT*||
+WPUPMSB017|*CENCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Chuonge-a Pet||
+WPUPMSB020|Ouse-a Deffuolt Pet(s)||
+WPUPMSB021|Durect (Nu pet)||
+WPUPMSB022|Refferse-a Pet (HEEnt):||
+WPUPARM001|Chuonge-a Ououtu Reply||
+WPUPARM002|Reply:||
+WPUPHPI001|Help Index||
+WPUPHPI002|Feeuo||
+WPUPSTI000|Oubject ffrum: %s||
+WPUPSTI001|Stetiun Inffu||
+WPUPSTI002|Send Messege||
+WPUPSTI003|Seerch FCC Detebese||
+WPUPSTI004|Seerch REC Detebese||
+WPUPSTI005|Peckets receeffed: %d     Lest Heerd: ||
+WPUPSTI006|Heerd fee-a zee-a TNC ouon deffeece-a %d, ||
+WPUPSTI007|Heerd ||
+WPUPSTI008|lest fee-a Lucel||
+WPUPSTI009|lest fee-a TNC ouon deffeece-a %d||
+WPUPSTI010|lest fee-a Internet ouon deffeece-a %d||
+WPUPSTI011|lest fee-a Feele||
+WPUPSTI012|lest fee-a Ouonknuon||
+WPUPSTI013|, ouond hes muffed||
+WPUPSTI014|Cuorrent Puoer Geen:||
+WPUPSTI016|Eltituode-a: %.0ff%s ||
+WPUPSTI017|Cuourse-a: %s� ||
+WPUPSTI018|Speed: %.1ff km/h||
+WPUPSTI019|Speed: %.1ff mph||
+WPUPSTI020|%0.1ff meeles||
+WPUPSTI021|%0.1ff km||
+WPUPSTI022|DEEstuonce-a ffrum my stetiun: %s  Beering ffrum my stetiun: %s||
+WPUPSTI023|Lest Pusitiun: ||
+WPUPSTI024|Veezeer Dete-a %c:%s||
+WPUPSTI025|Vind Cuourse-a: %s�    Speed: %03d km/h||
+WPUPSTI026|Vind Cuourse-a: %s�    Speed: %s mph||
+WPUPSTI027|   Guost: %03d km/h||
+WPUPSTI028|   Guost: %s mph||
+WPUPSTI029|Temperetuore-a: %02.1ff�C  ||
+WPUPSTI030|Temperetuore-a: %s�F   ||
+WPUPSTI031|Huomeedeety: %s%%   ||
+WPUPSTI032| Huomeedex: %02.1ff�C  ||
+WPUPSTI033|Beru: %s hPe||
+WPUPSTI034|Snuo: %0.1ff (cm/24h)||
+WPUPSTI035|Snuo: %0.0ff (inch/24h)||
+WPUPSTI036|Reen: ||
+WPUPSTI037|%0.2ff (mm/h)    ||
+WPUPSTI038|%0.2ff (inch/h)  ||
+WPUPSTI039|%0.2ff (mm/dey)     ||
+WPUPSTI040|%0.2ff (inch/dey)  ||
+WPUPSTI041|%0.2ff (mm/since-a meednight)||
+WPUPSTI042|%0.2ff (inch/since-a meednight)||
+WPUPSTI043|Dete-a pet: %s||
+WPUPSTI044|Cumment %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Cleer Treck||
+WPUPSTI046|Tutel Reen: ||
+WPUPSTI047|%0.2ff (mm)||
+WPUPSTI048|%0.2ff (inch)||
+WPUPSTI049|Trece-a Quoery||
+WPUPSTI050|Oun-Icked Messeges Quoery||
+WPUPSTI051|Durect Stetiuns Quoery||
+WPUPSTI052|Stetiun Fersiun Quoery||
+WPUPSTI053|Mudeeffy Ouobject/Item||
+WPUPSTI054|Sture-a Treck||
+WPUPSTI055|Ichued ffrum:||
+WPUPSTI056|Ineble-a Ououtumetic Ouopdetes||
+WPUPSTI057|Oumni-DF: %s||
+WPUPSTI058|DF Beering: %s||
+WPUPSTI059|Stetuos  %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Fuoel Temp: %02.1ff�C  ||
+WPUPSTI061|Fuoel Temp: %s�F   ||
+WPUPSTI062|Fuoel Muistuore-a: %s%%   ||
+WPUPSTI063|Beru: %0.2ff in Hg||
+WPUPSTI064|Fetch NVS Ilert||
+WPUPSTI065|Tecticel Cell: %s||
+WPUPSTI066|Essign Tecticel Cell||
+WPUPSTI067|Cuorrent Ruonge-a: %d meeles||
+WPUPSTI068|nune||
+WPUPSTI069|deffuolt||
+WPUPSTI070|HEAT||
+WPUPSTI071|oumnee||
+WPUPSTI072|ruonge||
+WPUPSTI073|BED PHG||
+WPUPSTI074|BED SHG||
+WPUPSTI075|DF Ruonge||
+WPUPSTI076|Nu signel detected||
+WPUPSTI077|Detectible-a signel (Meybe-a)||
+WPUPSTI078|Detectible-a signel buot nut cupyeble-a)||
+WPUPSTI079|Veek signel, mergeenelly reedeble||
+WPUPSTI080|Nuisy buot cupyeble-a seegnel||
+WPUPSTI081|Sume-a nuise-a, iesy tu cupy seegnel||
+WPUPSTI082|Guod signel v/detectible-a nueese||
+WPUPSTI083|Neer ffuoll-quoieting seegnel||
+WPUPSTI084|Fuoll-quoieting seegnel||
+WPUPSTI085|Ixtremely strung & ffuoll-quoieting seegnel||
+WPUPSTI086|BED BEERING||
+WPUPSTI087|BED NRQ||
+WPUPSTI088|DF Beemveedt||
+WPUPSTI089|DF Lengt||
+WPUPSTI090|Nut Feleed||
+WPUPSTI091|Chuonge-a Treel Culur||
+WPUPSTI092|Cleer DF Beereeng||
+WPUPALO001|ELOHE redeeuos: %d %s||
+WPUPALO002|Stetiuns inside-a ILOHE curcle-a: %d||
+WPUPALO003| DEEgees:               %d||
+WPUPALO004| Mubeeles (in mutiun): %d||
+WPUPALO005| Mubeeles (ouozeer):     %d||
+WPUPALO006| VX stetiuns:         %d||
+WPUPALO007| Hume-a stetiuns:       %d||
+WPUPALO008|Lest celcuoleted %d %s %d %s igu..  Burk Burk Burk!||
+WPUPALO666|ELOHE redeeuos nut celcuoleted yet||
+STIFCC0001|FCC Detebese-a Luokuop||
+STIFCC0002|REC Detebese-a Luokuop||
+STIFCC0003|Neme-a:||
+STIFCC0004|Street:||
+STIFCC0005|CEEty:||
+STIFCC0006|Stete-a:||
+STIFCC0007|Zip:||
+STIFCC0008|Besic ||
+STIFCC0009|Edffuonced ||
+STIFCC0010|5 vpm ||
+STIFCC0011|12 vpm ||
+STIFCC0100|FCC index ouold, rebuoeeldeeng||
+STIFCC0101|Cellsign Seerch||
+STIFCC0102|Cellsign Nut Fuound!||
+STIFCC0103|REC index ouold, rebuoeeldeeng||
+UMBNDO0001|et deestuonce-a ouoff||
+UNIOP00001|OuK||
+UNIOP00002|Cuoncel||
+UNIOP00003|Cluse||
+UNIOP00004|meeles||
+UNIOP00005|km||
+UNIOP00006|Deffeece||
+UNIOP00007|Edd||
+UNIOP00008|Delete||
+UNIOP00009|Prupertees||
+UNIOP00010|Elluo Truonsmeetting?||
+UNIOP00011|Ectiffete-a ouon Stertuop?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|eench||
+UNIOP00018|mm/dey||
+UNIOP00019|inch/dey||
+UNIOP00020|mm/hr||
+UNIOP00021|inch/hr||
+UNIOP00022|mm/meed||
+UNIOP00023|inch/meed||
+UNIOP00024|deg||
+UNIOP00025|hPe||
+UNIOP00026|%||
+UNIOP00027|in Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Set System Cluck ffrum GPS Dete-a?||
+UNIOP00030|DEEgeepeet?||
+UNIOP00031|m||
+UNIOP00032|Epply||
+UNIOP00033|Reset||
+UNIOP00034|meen||
+UNIOP00035|hr||
+UNIOP00036|dey||
+UNIOP00037|Send Cuntrul-I tu get GPS dete-a?||
+UNIOP00038|Edd Deley||
+STCHO00001|Stetiun Chuoser||
+WPUPWXA001|Vx Ilerts||
+WPUPWXA002|Vx Ilert Leest||
+WPUPCIF001|Instelled Interffeces||
+WPUPCIF002|Chuose-a Interffece-a Type||
+WPUPCAX001|Cunffeeguore-a IX.25 TNC||
+WPUPCAX002|EX.25 Deffeece-a neme||
+IFDNL00000|Nune||
+IFDNL00001|Seriel TNC||
+IFDNL00002|Seriel TNC v/GPS ouon i-a HSP ceble||
+IFDNL00003|Seriel GPS||
+IFDNL00004|Seriel VX||
+IFDNL00005|Internet Serffer||
+IFDNL00006|EX25 TNC||
+IFDNL00007|Netvurked GPS (fee-a gpsd)||
+IFDNL00008|Netvurked VX||
+IFDNL00009|Seriel TNC v/GPS ouon IOuX purt||
+IFDNL00010|Seriel KISS TNC||
+IFDNL00011|Netvurked Detebese-a (Nut Implemented Yet)||
+IFDNL00012|Netvurked IGVPE||
+IFDNL00013|Seriel Muolti-Purt KISS TNC||
+IFDNL00014|SQL Detebese-a (Ixperimentel)||
+IFDIN00000|%s %2d %s %s   %s||
+IFDIN00001|%s %2d %s %s:%d   %s||
+IFDIN00002|%s %2d %s deffeece-a %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006| DOVN ||
+IFDIN00007|  OuoP  ||
+IFDIN00008|IRROR ||
+IFDIN00009|OuNKNVN||
+IFPUPCT000|Interffece-a Cuntrul||
+IFPUPCT001|Stert||
+IFPUPCT002|Stup||
+IFPUPCT003|Stert Ill||
+IFPUPCT004|Stup Ill||
+IGPUPCF000|IGete-a Ouopteeuns||
+IGPUPCF001|DEEseble-a ill IGete-a treffeec||
+IGPUPCF002|Elluo RF tu Inet treffeec OuoNLY||
+IGPUPCF003|Elluo RF->Inet ouond Inet->RF treffeec||
+IGPUPCF004|Igete-a -> RF Pet   ||
+WXPUPSI000|VX Steteeun||
+WXPUPSI001|VX Stetiun Type||
+WXPUPSI002|Cuorrent Dete||
+WXPUPSI003|Vind Cuourse||
+WXPUPSI004|Vind Speed||
+WXPUPSI005|Vind Guost||
+WXPUPSI006|Temp||
+WXPUPSI007|Tutel Reen||
+WXPUPSI008|Tudey's Reen Tutel||
+WXPUPSI009|Beru||
+WXPUPSI010|Huomeedeety||
+WXPUPSI011|Peet Brus OuoLTIMETER 2000 Type-a (Dete-a Luggeeng Mude-a)||
+WXPUPSI012|Peet Brus OuoLTIMETER II Type||
+WXPUPSI013|Peet Brus OuoLTIMETER 2000 Type-a (Pecket Mude-a)||
+WXPUPSI014|Cuorrent HR Reen Tut..  Burk Burk Burk!||
+WXPUPSI015|Lest 24 Reen Tutel||
+WXPUPSI016|Quoeleemetrics Q-Net||
+WXPUPSI017|Peet Brus OuoLTIMETER 2000 Type-a (Cumplete-a Mude-a)||
+WXPUPSI018|Duo Pueent||
+WXPUPSI019|HEEgh Veend||
+WXPUPSI020|Vind Cheell||
+WXPUPSI021|Heet Index||
+WXPUPSI022|3-Hr Beru||
+WXPUPSI023|HEEgh Temp..  Burk Burk Burk!||
+WXPUPSI024|Luo Temp..  Burk Burk Burk!||
+WXPUPSI025|Redeeu Sheck VX-200/Ouoregun Sceentiffeec VM-918||
+WXPUPSI026|Deffees Veezeer Munitur II/Vizerd III/Fuontege-a Pru||
+WXPUPSI027|LeCrusse-a VX-23xx||
+WXPUPSI028|Deffees IPRS Dete-a Lugger||
+LHPUPNI000|Ell Steteeuns||
+LHPUPNI001|Mubeele-a Steteeuns||
+LHPUPNI002|Veezeer Steteeuns||
+LHPUPNI003|Lucel Stetiuns (fee-a TNC)||
+LHPUPNI004|Lest Steteeuns||
+LHPUPNI005|Oubjects & Items||
+LHPUPNI006|Ouon Ouobjects & Items||
+LHPUPNI010|#||
+LHPUPNI011|Cell Seegn||
+LHPUPNI012|#Peck||
+LHPUPNI013|Pus Teeme||
+LHPUPNI014|Pet||
+LHPUPNI015|PHG||
+LHPUPNI016|Cumments||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ELT.||
+LHPUPNI103|Let||
+LHPUPNI104|Lung||
+LHPUPNI105|#Peck||
+LHPUPNI106|LSF||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Huom||
+LHPUPNI205|Beru||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Let/Lun ouor OuoTM||
+PULDNMAT01|Shuo Ilert meps ibuffe-a ouozeer meps||
+PULDNMAT02|Shuo Ilert meps ouonder ouozeer meps||
+POPEM00001|Lucete-a Irrur!||
+POPEM00002|Stetiun %s ves nut ffuound!||
+POPEM00003|Treckeeng Irrur!||
+POPEM00004|Interffece-a Irrur!||
+POPEM00005|Inffeleed IX.25 purt neme-a %s||
+POPEM00006|Inffeleed IX.25 purt neme-a %s||
+POPEM00007|Inffeleed cellsign %s||
+POPEM00008|Inffeleed IX.25 destinetiun cellsign ouor deegeepeeter||
+POPEM00009|Cuonnut ouopee-a IX.25 sucket, %s||
+POPEM00010|Cuonnut beend IX.25 sucket, %s||
+POPEM00011|Cuonnut cunnect tu IX.25 cellsign, %s||
+POPEM00012|EX.25 ouorrur ouon ououotpuot ouoff OuoI||
+POPEM00013|EX.25 prublem vit ixpurts ffeele||
+POPEM00014|EX.25 inffeleed purt neme-a %s||
+POPEM00015|Irrur ouopening interffece-a %d Herd Feel||
+POPEM00016|Irrur ouopening interffece-a %d Time-a Ououot||
+POPEM00017|Nu mure-a interffeces Iffeeleble-a!||
+POPEM00018|Dete-a Quoery - Single-a Messege-a Leene||
+POPEM00019|Purt truonsmeetting is ouoff ffur purt %d||
+POPEM00020|Detebese-a Irrur!||
+POPEM00021|EX.25 suoppurt nut cumpiled intu Xestur!||
+POPEM00022|Inpuot Irrur!||
+POPEM00023|Nu lucetiun neme-a speceeffeed!||
+POPEM00024|Lucetiun neme-a speceeffeed is in ouose-a!||
+POPEM00025|Nut Fuound!||
+POPEM00026|Treckeeng vill cummence-a vhee-a it ippeers||
+POPEM00027|Impruper inffu..  Burk Burk Burk!  Sume-a ffeelds impty?||
+POPEM00028|Cuon't ouopee-a ffeele||
+POPEM00029|Fuound It!||
+POPEM00030|Veezeer Stetiun Symbul||
+POPEM00031|Chuonged tu VX symbul '/_', ouozeer ouoptiuns:  '\_'  '/V'  ouond  '\V'||
+POPEM00032|Verning: Ouosing Netiunel Veezeer Serffeece-a Symbul!||
+POPEM00033|Nu GPS Dete-a!||
+POPEM00034|DEEsebleeng My Pusitiun TX Ouontil Feleed GPS Dete-a!||
+POPEM00035|Verneeng||
+POPEM00036|Nuteece||
+POPEM00037|HSP interffece-a present: GPS timeeng hes bee-a iencreesed||
+POPEM00038|Neme-a Cunffleects Vit Ixisting Ouobject/Item/Steteeun||
+POPEM00039|Illegel cherecters ffuound, suobstituoting periuds in zeeur plece||
+POPEM00040|Cuostum ououotguing pet ves lust||
+POPEM00041|Prucessing ouonuzeer ffeele-a..  Burk Burk Burk!  Veet i-a beet, zee-a try igeen||
+POPEM00042|Oubject nut ououned by me-a! Try idupting zee-a ouobject ffurst..  Burk Burk Burk!||
+POPEM00043|Nut ouon Ouobject/Item!||
+POPEM00044|Fetch FEEnduo Treel: Feeled||
+POPEM00045|Fetch FEEnduo Treel: Cumplete||
+POPEM00046|Berkeley DB heeder/shered leebrery du NOT metch! DEEsebleeng mep ceche-a..  Burk Burk Burk!||
+POPEM00047|Glubel truonsmeet is DISEBLED. Imergency beecuns ire-a NOT guing ououot!||
+POPEM00048|Imergency Beecun Mude-a!||
+POPEM00049|IMERGENCY BEECON MODE, truonsmeetting iffery 60 secunds!||
+POPEM00050|Interffeces ouor pusits/truonsmeets DISEBLED.  Imergency beecuns ire-a NOT guing ououot!||
+POPEM00051|Eltnet is inebled (Cunffeeguore-a->Deffuolts deelug)||
+POPEM00052|Cellsign is IMPTY!||
+POPEM00053|Messege-a is IMPTY!||
+POPEM00054|Ve-a're-a trying tu telk tu ououorselffes!||
+JMLPO00001|Mep DEEspley Buokmerks||
+JMLPO00002|Ectiffete-a!||
+JMLPO00003|Nuo Neme-a:||
+BULMW00001|Buolleteens||
+BULMW00002|LEEmeet Ruonge-a tu (0, is nu leemeet)||
+BULMW00003|Chuonge-a Ruonge||
+AMTMW00001|Ell Messege-a Treffeec||
+AMTMW00002|LEEmeet Ruonge-a tu (0, is nu leemeet)||
+SPCHSTR001|keelumeters||
+SPCHSTR002|meters||
+SPCHSTR003|meeles||
+SPCHSTR004|yerds||
+SPCHSTR005|%s, deestuonce-a is %d %s..  Burk Burk Burk!||
+SPCHSTR006|%s, deestuonce-a is %.1ff %s..  Burk Burk Burk!||
+SPCHSTR007|%s, deestuonce-a is %d %s %s %s..  Burk Burk Burk!||
+SPCHSTR008|%s, deestuonce-a is %.1ff %s %s %s..  Burk Burk Burk!||
+SPCHSTR009|Nuo Veezeer Ilert||
+SPCHSTR010|Nuo Steteeun||
+SPCHSTR011|Heerd, D X, %s, it deestuonce-a ouoff %.1ff %s||
+SPCHDIRN00|nurt ouoff||
+SPCHDIRS00|suout ouoff||
+SPCHDIRE00|iest ouoff||
+SPCHDIRW00|vest ouoff||
+SPCHDIRNE0|nurzeest ouoff||
+SPCHDIRNW0|nurthvest ouoff||
+SPCHDIRSE0|suouzeest ouoff||
+SPCHDIRSW0|suouthvest ouoff||
+SYMSEL0001|Select Symbul||
+SYMSEL0002|Primery Symbul Teble||
+SYMSEL0003|Secundery Symbul Teble||
+PRINT0001|Print Prupertees||
+PRINT0002|Peper Seeze||
+PRINT0003|Ouotu-Rutete-a Imege||
+PRINT0004|Rutete-a Imege-a 90� CCV||
+PRINT0005|Ouotu-Scele-a Imege||
+PRINT0006|Scele-a:||
+PRINT0007|Furce-a deffuolt beckgruound culur tu vheete||
+PRINT0008|Print in Bleck ouond Vheete||
+PRINT0016|Refferse-a Culurs||
+PRINT0009|Pustscript Resuluotiun:||
+PRINT0010|Preffeeuo||
+PRINT0011|Print tu Feele||
+PRINT0012|Duomping imege-a tu ffeele-a..  Burk Burk Burk!..||
+PRINT0013|Cunfferting tu Pustscript..  Burk Burk Burk!..||
+PRINT0014|FEEnished creeting print ffeele||
+PRINT0015|Print Stetuos||
+PRINT1001|Durect tu:||
+PRINT1002|FEEe-a Preffeeuoer:||
+FEATURE001|Neme-a:||
+FEATURE002|Stete-a/Pruffeence-a:||
+FEATURE003|Cuounty:||
+FEATURE004|Mep Quoed:||
+FEATURE005|Type-a:||
+FEATURE006|GNIS FEEle-a:||
+FEATURE007|Eddress:||
+FEATURE008|CEEty:||
+FEATURE009|Merk Desteenetiun||
+FEATURE010|Zip Cude-a:||
+FEATURE011|Geucudeeng Feele||
+COORD001|Cuordeenete-a Celcuoletur||
+COORD002|Celc||
+COORD003|Celcuolete||
+COORD004|Cleer||
+COORD005|OuTM||
+COORD006|Letituode-a ouor||
+COORD007|Lungeetuode-a ouor||
+COORD008|Zune||
+COORD009|OuTM Iesteeng||
+COORD010|OuTM Nurzeeng||
+COORD011|               Deceemel Degrees:  ||
+COORD012|       Degrees/Deceemel MEEnuotes:  ||
+COORD013|  Degrees/MEEnuotes/Dec..  Burk Burk Burk! Secunds:  ||
+COORD014| Ouoniffersel Truonsfferse-a Mercetur:  ||
+COORD015|MEEleetery Grid Refference-a System:  ||
+COORD016|       Meedenheed Grid Lucetur:  ||
+COORD017| **       Surry, yuour inpuot ves nut recugnized!        **||
+COORD018| **   Pleese-a ouose-a ouone-a ouoff zee-a ffulluoing inpuot ffurmets:   **||
+SMARTB001|Smert Beecuneeng||
+SMARTB002|HEEgh Rete-a (secs):||
+SMARTB003|HEEgh Speed (mph):||
+SMARTB004|HEEgh Speed (kph):||
+SMARTB005|Luo Rete-a (meens):||
+SMARTB006|Luo Speed (mph):||
+SMARTB007|Luo Speed (kph):||
+SMARTB008|MEEnimuom Tuorn (deg):||
+SMARTB009|Tuorn Slupe-a:||
+SMARTB010|Veet Time-a (secs):||
+SMARTB011|Ineble-a SmertBeecuning(tm)||
+GAMMA001|Edjuost Gemme-a Currecteeun||
+GAMMA002|Gemme-a Currecteeun||
+MAPFONT001|Chuonge-a Funts||
+MAPFONT002|Funts||
+MAPFONT003|Mep Funt Teeny||
+MAPFONT004|Mep Funt Smell||
+MAPFONT005|Mep Funt Medeeuom||
+MAPFONT006|Mep Funt Lerge||
+MAPFONT007|Mep Funt Huoge||
+MAPFONT008|Mep Funt Burder||
+MAPFONT009|Menuo Funt||
+MAPFONT010|Stetiun Funt||
+MAPFONT011|ETF ID Funt||
+PULDNDB001|DEEst/Beering Stetuos||
+GPS001|GPS Truonsffer||
+GPS002|Feeleneme||
+GPS003|Select Culur||
+GPS004|Red||
+GPS005|Gree||
+GPS006|Bleck||
+GPS007|Vheete||
+GPS008|Ouruonge||
+GPS009|Bluoe||
+GPS010|Yelluo||
+GPS011|Feeulet||
+MAPP001|Mep Prupertees||
+MAPP002|Mex   MEEn    Mep         OuoSGS  Ououtu||
+MAPP003|Zuom  Zuom  Leyer  FEEll  DRG   Mep   Pet/Feeleneme||
+MAPP004|Chuonge-a Leyer->||
+MAPP005|FEElled->||
+MAPP006|Yes||
+MAPP007|Nu||
+MAPP008|Ouotumeps->||
+MAPP009|Mex Zuom->||
+MAPP010|MEEn Zuom->||
+MAPP011|Ouotu||
+MAPP012|OuSGS DRG->||
+TIME001|Dey||
+TIME002|Deys||
+TIME003|Huour||
+TIME004|Huours||
+TIME005|Meenuote||
+TIME006|Meenuotes||
+TIME007|Secund||
+TIME008|Secunds||
+CACHE001|Mep nuo ceched||
+CACHE002|Luedeeng Ceched Mep||
+CACHE003|Mep nut ffuound in ceche-a..  Burk Burk Burk!..||
+RANGE001|RENGE SCELE||
+GPSS001|VEAS ouor PPS||
+GPSS002|DGPS||
+GPSS003|Feleed SPS||
+GPSS004|Inffeleed||
+GPSS005|Sets/Feeuo||
+GPSS006|Feex||
+GPSS007|!GPS dete-a is ouolder thuon 30 secunds!||
+GPSS008|Seemuoletiun||
+GPSS009|Muonuoel||
+GPSS010|Isteemeted||
+GPSS011|Fluet RTK||
+GPSS012|RTK||
+CADPUD001|Eree-a Ouobject||
+CADPUD002|Eree-a Lebel:||
+CADPUD003|Cumment:||
+CADPUD004|Prubebeeleety (%):||
+CADPUD005|OuK||
+CADPUD006|CED Deelug||
+CADPUD007|Shuo/Ideet Deteels||
+CADPUD008|Cuoncel||
+CADPUD009|Delete-a CED ouobjects?||
+CADPUD010|Delete-a Ill||
+CADPUD011|Delete-a Selected||
+CADPUD012|Suleed||
+CADPUD013|Deshed||
+CADPUD014|Duouble-a Desh||
+MDATA001|XESTIR Mep ouoff %s (ouopper lefft) tu %s (luoer right).  OuoTM %d m grid, %s detuom..  Burk Burk Burk! ||
+MDATA002|XESTIR Mep ouoff %s (ouopper lefft) tu %s %s (luoer right).  Let/Lung grid, %s detuom..  Burk Burk Burk!||
+MDATA003|XESTIR Mep ouoff %s (ouopper lefft) tu %s (luoer right).  OuoTM zunes, %s detuom..  Burk Burk Burk!||
+XADBMST001|MySQL (let/lung)||
+XADBMST002|Pustgreql vit Pustgees||
+XADBMST003|MySQL (spetiel)||
+XASCHEMA01|Xestur Simple-a Scheme||
+XASCHEMA02|Xestur CED Scheme||
+XASCHEMA03|Xestur ffuoll Scheme||
+XASCHEMA04|EPRSVurld Scheme||
diff --git a/config/language-OldeEnglish.sys b/config/language-OldeEnglish.sys
new file mode 100644
index 0000000..59c66f5
--- /dev/null
+++ b/config/language-OldeEnglish.sys
@@ -0,0 +1,1143 @@
+# language-OldeEnglish.sys, translated from language-English.sys
+# Please do not edit this derived file.
+MENUTB0001|Fyl|F|
+MENUTB0002|Viewe|V|
+MENUTB0004|Mape|M|
+MENUTB0005|Stacioonne|S|
+MENUTB0006|Message|e|
+MENUTB0010|Intreface|I|
+MENUTB0009|Helpe|H|
+PULDNFI001|Configurre|C|
+PULDNFI002|Openne Log Fyl|O|
+PULDNFI003|Teste|T|
+PULDNFI004|Exitte|x|
+PULDNFI007|Change Debug Level|D|
+PULDNFI010|TNC Logging||
+PULDNFI011|Nette Logging||
+PULDNFI012|IGate Logging||
+PULDNFI013|WX Logging||
+PULDNFI014|PNG Snapshots||
+PULDNFI015|Printte|P|
+PULDNFI016|KML Snapshots||
+PULDNVI001|Bulletins|B|
+PULDNVI002|Incoming Data|I|
+PULDNVI003|Mobeel Stations|M|
+PULDNVI004|Al Stations|A|
+PULDNVI009|Local Stations|S|
+PULDNVI012|Lastte Stations|L|
+PULDNVI005|Wetehre Stations|W|
+PULDNVI008|Ownne Wetehre Data|D|
+PULDNVI007|Wetehre Alrets|e|
+PULDNVI011|Message Traffick|T|
+PULDNVI013|Upteem|U|
+PULDNVI014|Program Upteem||
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statisticc||
+PULDNCF004|Stacioonne|S|
+PULDNCF001|Defaults|D|
+PULDNCF003|Timing|T|
+PULDNCF002|Coordinate System|o|
+PULDNCF006|Audio Alarms|A|
+PULDNCF007|Speceh|p|
+PULDNCF008|Savethe Config Nou!|C|
+PULDNMP001|Mape Choosre|M|
+PULDNMP012|Mape Displye Bookmarks|B|
+PULDNMP014|Locate Mape Feteurre|F|
+PULDNMP016|Disable Fastte Zoom/Panne/Home||
+PULDNMP013|Disable Al Maps||
+PULDNMP002|Enable Auto Maps||
+PULDNMP003|Enable Mape Gride||
+PULDNMP004|Enable Mape Levels||
+PULDNMP010|Enable Mape Labels||
+PULDNMP009|Enable Aree Colorre Fills||
+PULDNMP007|Enable Wetehre Alrets||
+PULDNMP005|Backgrounde Colorre|C|
+PULDNMP006|Stacioonne Textte Steele|T|
+PULDNMP026|Iconne Outleenne Steele|O|
+PULDNMP011|Moue Pointre Menu|P|
+PULDNMP008|Mape Intensitee|I|
+PULDNMP020|Configurre Tyggremape||
+PULDNMP021|Auto Mape - Disable Rastre Maps||
+PULDNMP022|Index Newe Maps onne Startupe||
+PULDNMP023|Index: Adde Newe Maps|N|
+PULDNMP024|Index: Reindex ALL Maps!|R|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsel||
+PULDNMP027|Re-dounloode Maps (Notte fro cache)||
+PULDNMP028|Flush Enteerre Mape Cache!||
+PULDNMP029|Finde Addresse||
+PULDNMP030|Configurre USGS DRG||
+PULDNMP031|Enable Mape Bordre||
+MPUPTGR001|Gride||
+MPUPTGR002|Counties||
+MPUPTGR003|Citee Labels||
+MPUPTGR004|Urbanne Aree||
+MPUPTGR005|Majorre Roods||
+MPUPTGR006|Stretes||
+MPUPTGR007|Reylroods||
+MPUPTGR008|State Labels||
+MPUPTGR009|Intrestate Labels||
+MPUPTGR010|US Hwee Labels||
+MPUPTGR011|State Hwee Labels||
+MPUPTGR012|Selectte yttems to be displeyede:||
+MPUPTGR013|Ryvvres||
+MPUPTGR014|Lakes||
+MPUPTGR015|Airports, Parks, etc||
+MPUPTGR016|Mape Intensitee||
+MPUPTGR017|Intrenette Mape Tymmeoutte (sec)||
+MPUPTGR018|Enable Tyggre Maps||
+MPUPDRG001|Selectte yttems to be displeyede:||
+MPUPDRG002|Tintte Undreleeing Mape (XOR)||
+MPUPDRG003|Black||
+MPUPDRG004|Wheette||
+MPUPDRG005|Ble||
+MPUPDRG006|Rede||
+MPUPDRG007|Broonne||
+MPUPDRG008|Grene||
+MPUPDRG009|Purple||
+MPUPDRG010|Yellou||
+MPUPDRG011|Lightte Ble||
+MPUPDRG012|Lightte Rede||
+MPUPDRG013|Lightte Purple||
+MPUPDRG014|Lightte Grye||
+MPUPDRG015|Lightte Broonne||
+WPUPMCP001|Mape Choosre||
+PULDNMMC01|Clree|C|
+PULDNMMC02|Vectorre|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Expande Dirs||
+PULDNMMC07|Dirs/Maps Selectede:||
+PULDNMMC08|Clree Dirs|C
+PULDNMMC09|Selectte Al|S|
+PULDNMBC01|Grye||
+PULDNMBC02|Mistee Roe||
+PULDNMBC03|Navee Ble||
+PULDNMBC04|Stele Ble||
+PULDNMBC05|Mede. See Grene||
+PULDNMBC06|Pale Grene||
+PULDNMBC07|Pale Goldenrode||
+PULDNMBC08|Goldenrode Yellou||
+PULDNMBC09|Rosee Broonne||
+PULDNMBC10|Fyrre breek Rede||
+PULDNMBC11|Wheette||
+PULDNMBC12|Black||
+PULDNMSL01|Black Bordre|B|
+PULDNMSL02|Black Shadou|S|
+PULDNMSL03|Textte onne Black|T|
+PULDNMIO01|No Outleenne|N|
+PULDNMIO02|Black Outleenne|B|
+PULDNMIO03|Greye Outleenne|G|
+PULDNMIO04|Wheette Outleenne|W|
+PULDNOT001|Onne||
+PULDNOT002|Off||
+PULDNOT003|Shortte||
+PULDNDP014|Finde Stacioonne|F|
+PULDNDP001|Track Stacioonne|T|
+PULDNDP022|Fetche Findu Treyl|u|
+PULDNDP032|Filtre Data||
+PULDNDP040|Selectte None||
+PULDNDP041|Selectte Mynne||
+PULDNDP042|Selectte TNC||
+PULDNDP027|- Selectte Dyrrectte||
+PULDNDP043|- Selectte Via Digi||
+PULDNDP034|Selectte Nette||
+PULDNDP019|Include Expeerrede Data||
+PULDNDP044|Selectte Stations||
+PULDNDP028|- Selectte Fyxxede Stations||
+PULDNDP029|- Selectte Moving Stations||
+PULDNDP030|- Selectte WX Stations||
+PULDNDP053|  - Selectte CWOP WX Stations||
+PULDNDP045|Selectte Objects/Items||
+PULDNDP026|- Selectte WX Objects/Items||
+PULDNDP039|- Selectte Watre Gauge Objects/Items||
+PULDNDP031|- Selectte Othre Objects/Items||
+PULDNDP033|Filtre Displye||
+PULDNDP010|Displye Callsignne||
+PULDNDP012|Displye Symbol||
+PULDNDP011|- Rotate Symbol||
+PULDNDP007|Displye Treyl||
+PULDNDP003|Displye Coure||
+PULDNDP004|Displye Spede|S|
+PULDNDP017|- Displye Shortte Spede||
+PULDNDP002|Displye Altitude||
+PULDNDP009|Displye Wetehre Info||
+PULDNDP046|- Displye Wetehre Textte||
+PULDNDP018|-- Tempreeturre Onlee||
+PULDNDP047|- Displye Winde Barbe||
+PULDNDP054|Displye Aloha Circle||
+PULDNDP013|Displye Posicioonne Ambiguitee||
+PULDNDP008|Displye Poure/Geynne||
+PULDNDP021|- Ue Defaultte Poure/Geynne||
+PULDNDP020|- Displye Mobeel Poure/Geynne||
+PULDNDP023|Displye DF Attributes||
+PULDNDP123|Displye DF Bemewidthe||
+PULDNDP223|Displye DF Bereing||
+PULDNDP035|Enable Dede-Reckoning||
+PULDNDP036|- Displye Arc||
+PULDNDP037|- Displye Coure||
+PULDNDP038|- Displye Symbol||
+PULDNDP005|Displye Distte/Bereing||
+PULDNDP024|Displye Lastte Reportte Age||
+PULDNDP015|Clree Al Stations!!!|A|
+PULDNDP016|Clree Al Treyls!!!|C|
+PULDNDP025|Clree Objectte/Item Historee||
+PULDNDP048|Reloode Objectte/Item Historee||
+PULDNDP049|Clree Al Tactick Calls||
+PULDNDP050|Clree Tactick Cal Historee||
+PULDNDP051|Selectte Tactick Calls Onlee||
+PULDNDP052|- Label Treylpoints||
+PULDNDP055|Exportte al|E|
+PULDNDP056|Exportte to KML Fyl||
+PULDNUT001|Enable English Units|E|
+PULDNUT002|Metrick|M|
+PULDNMG001|Sende Message To|S|
+PULDNMG002|Openne Groupe Messages|O|
+PULDNMG003|Clree Al Outgoing Messages|C|
+PULDQUS001|Genreel Stations Qeree|G|
+PULDQUS002|IGate Stations Qeree|I|
+PULDQUS003|WX Stations Qeree|W|
+PULDNMG004|Modifee Auto Replee Message|A|
+PULDNMG005|Enable Auto Replee Message||
+PULDNMG006|Satelleette Ack Mode|M|
+PULDNMG007|Shou Pending Messages|P|
+PULDNTNT04|Intreface Control|C|
+PULDNTNT03|Disable Transmitte: ALL||
+PULDNTNT05|Disable Transmitte: Mye Posicioonne||
+PULDNTNT06|Disable Transmitte: Objects/Items||
+PULDNTNT11|Enable Servre Ports|P|
+PULDNTNT01|Transmitte Nou!|T|
+PULDNTNT07|Fetche GPS Track|F|
+PULDNTNT08|Fetche GPS Routes|R|
+PULDNTNT09|Fetche GPS Weypoints|W|
+PULDNTNT10|Fetche Garminne RINO Weypoints|G|
+PULDNHEL01|Aboutte|A|
+PULDNHEL02|Helpe Index|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|Aboutte Xastirre||
+POPUPMA001|Options||
+POPUPMA00c|Centre|C|
+POPUPMA015|Stacioonne Info|S|
+POPUPMA002|Inne|I|
+POPUPMA003|Outte|O|
+POPUPMA004|Zoom Level|L|
+POPUPMA005|Level 1|1|
+POPUPMA006|Level 16|6|
+POPUPMA007|Level 64|4|
+POPUPMA008|Level 256|2|
+POPUPMA009|Level 1024|0|
+POPUPMA010|Level 8192|8|
+POPUPMA017|Enteerre Worlde|E|
+POPUPMA016|Lastte Mape Pos/Zoom|P|
+POPUPMA018|Objectte/Item->Cretee|b|
+POPUPMA019|Objectte/Item->Modifee|M|
+POPUPMA025|Movethe Mye Stacioonne Herre|H|
+POPUPMA011|Panne upe|u|
+POPUPMA012|Panne doonne|d|
+POPUPMA013|Panne leftte|l|
+POPUPMA014|Panne rightte|r|
+POPUPMA020|Meseurre||
+POPUPMA021|Movethe||
+POPUPMA022|TrackMe||
+POPUPMA023|Modifiers Founde!||
+POPUPMA024|Plesee turnne OFF CapsLock/NumLock/ScrollLock/othre modifiers||
+POPUPMA026|Centre & Zoom||
+POPUPMA027|  Latitude||
+POPUPMA028| Longitude||
+POPUPMA029|Drawe CAD Objects||
+POPUPMA030|Drawe||
+POPUPMA031|Cloe Poleegonne||
+POPUPMA032|Erae CAD Poleegons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Level||
+POPUPMA035|10% outte||
+POPUPMA036|10% inne||
+POPUPMA037|Aree||
+POPUPMA038|squarre||
+POPUPMA039|squarre fete||
+POPUPMA040|squarre metres||
+POPUPMA041|Bereing||
+POPUPMA042|degree||
+POPUPMA043|Modifee ambiguous posicioonne||
+POPUPMA044|Posicioonne ambiguitee is onne, yourre newe posicioonne mye appree to jumpe.||
+POPUPMA045|Predefeennede Objects||
+POPUPMA046|CAD Poleegons||
+POPUPMA047|Enable CAD objects||
+POPUPMA048|Enable CAD labels||
+POPUPMA049|Enable CAD comments||
+POPUPMA050|Enable CAD probabilitee||
+POPUPMA051|Enable CAD aree seez||
+POPUPMA052|sq||
+POPUPMA053|ftte||
+POPUPMA054|metres||
+POPUPMA055|mi|
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Trre||
+BBARSTH001|%de/%de Stations||
+BBARSTA000|%-9s Newe objectte!||
+BBARSTA001|%-9s Newe stacioonne!||
+BBARSTA002|%-9s||# new data (only display the call)
+BBARSTA003|Looding Maps...||
+BBARSTA004|Maps Loodede||
+BBARSTA005|Mape Latte/Long Gride Onne|O|
+BBARSTA006|Mape Latte/Long Gride Off|f|
+BBARSTA007|The ue of Auto Maps, is nou ON||
+BBARSTA008|The ue of Auto Maps, is nou OFF||
+BBARSTA009|The ue of Mape Levels is nou ON||
+BBARSTA010|The ue of Mape Levels is nou OFF||
+BBARSTA011|Auto Replee Message OFF!||
+BBARSTA012|Fyl done..||
+BBARSTA013|Opening GPS Portte||
+BBARSTA014|Closing GPS Portte||
+BBARSTA015|Gotte GPS RMC String||
+BBARSTA016|Gotte GPS GGA String||
+BBARSTA017|Nette disconnectede fro hostte||
+BBARSTA018|Nette conneccioonne teemmede outte!||
+BBARSTA019|Looking upe hostte %s||
+BBARSTA020|Connectede to %s||
+BBARSTA021|Nette Conneccioonne Feyllede!||
+BBARSTA022|Colde notte binde sockette!||
+BBARSTA023|No IP forre Hostte!||
+BBARSTA024|No Hostte Specifiede||
+BBARSTA025|Hostte founde, Connecting %de||
+BBARSTA026|Weyting forre GPS data via HSP..||
+BBARSTA027|Clreeing HSP getting TNC data..||
+BBARSTA028|Looding %s||
+BBARSTA029|Opening WX Portte||
+BBARSTA030|Closing WX Portte||
+BBARSTA031|Looking upe hostname %de||
+BBARSTA032|Decodede WX Data||
+BBARSTA033|Echo fro digeeppeteerre||
+BBARSTA034|Looding Wetehre Alrette Maps||
+BBARSTA035|Weyting forre GPS data via AUX..||
+BBARSTA036|Clreeing AUX getting TNC data..||
+BBARSTA037|GPS Data Complete||
+BBARSTA038|Posicioonne change onne mee stacioonne||
+BBARSTA039|Indexing %s||
+BBARSTA040|Amateurre APRS(tm) Stacioonne %s||
+BBARSTA041|Weyting forre GPS data..||
+BBARSTA042|Transmitting objects/yttems||
+BBARSTA043|Logging||
+BBARSTA044|ALOHA distance is %de%s||
+BBARSTA045|Looding seembols...||
+BBARSTA046|Relooding seembols...||
+BBARSTA047|Initeleyz mee stacioonne...||
+BBARSTA048|Startte intrefaces...||
+BBARSTA049|Redeing teelles...||
+BBARSTA050|Dounlooding teelles...||
+BBARSTA051|Dounlooding teel %li of %li||
+WPUPDPD001|Displye Packette Data||
+WPUPDPD002|TNC Data onlee|T|
+WPUPDPD003|Nette Data onlee|N|
+WPUPDPD004|TNC ande Nette Data|a|
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Stacioonne Capabilities||
+WPUPDPD008|Mynne Onlee||
+WPUPLSP001|Locate Stacioonne||
+WPUPLSP002|Locate Callsignne||
+WPUPLSP003|Matche Cae|C|
+WPUPLSP004|Matche Exactte|E|
+WPUPLSP005|Locate Nou!|N|
+WPUPLSP006|Emregencee Locate!||
+WPUPLSP007|FCC/RAC Lookupe||
+WPUPCFD001|Configurre Defaults||
+WPUPCFD002|Aftre whatte intreval of teem wil a stacioonne be conseeddreede olde?||
+WPUPCFD003|15 minne|1|
+WPUPCFD004|30 minne|3|
+WPUPCFD005|45 minne|4|
+WPUPCFD006|1 hrre|H|
+WPUPCFD007|90 minne|9|
+WPUPCFD008|2 hrs|2|
+WPUPCFD009|Aftre whatte intreval of teem wil a stacioonne notte be displeyede?||
+WPUPCFD010|6 hrs|6|
+WPUPCFD011|12 hrs|o|
+WPUPCFD012|1 Dye|D|
+WPUPCFD013|2 Deys|y|
+WPUPCFD014|1 Weke|W|
+WPUPCFD015|Transmitte Stacioonne Opcioonne||
+WPUPCFD016|Fyxxede Stacioonne|F|
+WPUPCFD017|Mobeel Stacioonne we/local teem|l|
+WPUPCFD018|Mobeel Stacioonne we/Zulu date-teem|Z|
+WPUPCFD019|Mobeel Stacioonne we/Zulu teem-seconds|u|
+WPUPCFD021|Stacioonne Posicioonne we/wetehre|S|
+WPUPCFD022|Stacioonne Posicioonne, Zulu date-teem, ande wetehre|t|
+WPUPCFD023|Transmitte Rawe WX data?|R|
+WPUPCFD024|Transmitte compressede objects/yttems?|C|
+WPUPCFD025|Activate Altrenate nette?|A|
+WPUPCFD026|Sende posicioonne reports atte whatte intrevals?||
+WPUPCFD027|Pope upe newe bulletins||
+WPUPCFD028|Warnne if Modifierre Keys||
+WPUPCFD029|Viewe zreo-distance bulletins||
+WPUPCFD030|Disable Positte Dupe-Checks||
+WPUPCFD031|Loode predefeennede objects fro feel||
+WPUPCFD032|Mye treyls inne one colorre||
+WPUPCFD033|ALTNET:||
+WPUPCFTM01|Configurre Timing||
+WPUPCFTM02|Positte TX Intreval (minne)||
+WPUPCFTM03|Stacioonne Ghosting Tym (minne)||
+WPUPCFTM04|Objectte/Item Max TX Intreval (minne)||
+WPUPCFTM05|Stacioonne Clree Tym (hours)||
+WPUPCFTM06|GPS Check Intreval (sec)||
+WPUPCFTM07|Stacioonne Delete Tym (deys)||
+WPUPCFTM08|Dede-Reckoning Tymmeoutte (minne)||
+WPUPCFTM09|Serele Intre-Charre Delye (ms)||
+WPUPCFTM10|Newe Track Tym (minne)||
+WPUPCFTM11|Newe Track Intreval (degree)||
+WPUPCFTM12|RINO -> Objects Intreval (minne), 0 = Disablede||
+WPUPCFTM13|Snapshotte Intreval (minne)||
+WPUPCFC001|Configurre Coordinate System||
+WPUPCFC002|Selectte Coordinate System||
+WPUPCFC003|dde.ddddde|d|
+WPUPCFC004|dde mm.mmm|m|
+WPUPCFC005|dde mm sse.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM we/specele zones||
+WPUPCFG001|Configurre GPS||
+WPUPCFG003|Stande alone GPS portte||
+WPUPCFG002|Ue GPS Posicioonne?||
+WPUPCFG004|GPS Options||
+WPUPCFG005|Stande-alone GPS||
+WPUPCFG006|TNC Connectede GPS (HSP Cable)||
+WPUPCFG007|TNC Connectede GPS using CTL-E||
+WPUPCFG008|GPS Tym (Sample evreee)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 minne||
+WPUPCFG013|2 minne||
+WPUPCFG014|5 minne||
+WPUPCFG015|10 minne||
+WPUPCFG016|Network Connectede GPS||
+WPUPCFG017|GPSD Hostte||
+WPUPCFG018|GPSD Portte||
+WPUPCFG019|Network GPS via GPSD||
+WPUPCFG020|Reconnectte onne feylurre?||
+WPUPCFG021|Network Connectede WX||
+WPUPCFG022|WX Hostte||
+WPUPCFG023|WX Portte||
+WPUPCFT001|Configurre TNC||
+WPUPCFT002|Ue TNC?||
+WPUPCFT003|TNC Portte||
+WPUPCFT004|Portte Settings||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|UnProto Paths||
+WPUPCFT012|Pathe 1: %s via ||
+WPUPCFT013|Pathe 2: %s via ||
+WPUPCFT014|Pathe 3: %s via ||
+WPUPCFT015|Portte Steele||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Configurre TNC we/HSP GPS||
+WPUPCFT024|Data Type||
+WPUPCFT025|Auto detectte||
+WPUPCFT026|Binaree Type||
+WPUPCFT027|ASCII Type||
+WPUPCFT028|Configurre TNC we/AUX GPS||
+WPUPCFT029|Configurre TNC we/INVALID ENUM||
+WPUPCFT030|Configurre KISS TNC||
+WPUPCFT031|TNC Configuracioonne Fylles||
+WPUPCFT032|TNC Setupe Fyllename|| 
+WPUPCFT033|TNC Shutdoonne Fyllename||
+WPUPCFT034|KISS Parametres||
+WPUPCFT035|TXDelye (10 ms units)||
+WPUPCFT036|Persistence (0 to 255)||
+WPUPCFT037|SlotTym (10 ms units)||
+WPUPCFT038|TxTeyl (10 ms units)||
+WPUPCFT039|Ful Duplex||
+WPUPCFT040|Configurre Multi-Portte KISS TNC||
+WPUPCFT041|Radio Portte||
+WPUPCFT042|Intreface Propreties: Dubious UNPROTO Pathe!||
+WPUPCFT043|Plesee conseeddre a shortre pathe suche as WIDE2-2 orre WIDE1-1,WIDE2-2||
+WPUPCFT044|Intreface Propreties: Dubious IGATE Pathe!||
+WPUPCFT045|Transmitting we/Dubious UNPROTO Pathe!||
+WPUPCFT046|Transmitting we/Dubious IGATE Pathe!||
+WPUPCFT047|Initte KISS-mode onne startupe||
+WPUPCFWX01|Configurre WX Portte||
+WPUPCFWX02|Wetehre Stacioonne deveec||
+WPUPCFWX03|Reynne Gauge Correccioonne (Global Setting)||
+WPUPCFWX04|.1 inche/2.5mm||
+WPUPCFWX05|.01 inche/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|No Correccioonne||
+WPUPCFS001|Configurre Stacioonne||
+WPUPCFS002|Callsignne||
+WPUPCFS003|LAT||
+WPUPCFS004|deg||
+WPUPCFS005|minne||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Stacioonne Symbol||
+WPUPCFS010|Groupe/ovrelye||
+WPUPCFS011|Symbol||
+WPUPCFS028|Selectte||
+WPUPCFS012|Poure - Heightte (HAAT) - Geynne - Dyrrectivitee||
+WPUPCFS013|Disable PHG||
+WPUPCFS014|Antenna Heightte||
+WPUPCFS015|Antenna Geynne||
+WPUPCFS016|Omni||
+WPUPCFS017|Commentte:||
+WPUPCFS018|Posicioonne Ambiguitee||
+WPUPCFS019|None||
+WPUPCFS020|.11 meelles||
+WPUPCFS021|1.15 meelles||
+WPUPCFS022|11.51 meelles||
+WPUPCFS023|69.09 meelles||
+WPUPCFS024|.18 kilometres||
+WPUPCFS025|1.85 kilometres||
+WPUPCFS026|18.53 kilometres||
+WPUPCFS027|111.19 kilometres||
+WPUPCFS029|Sende compressede posits|C|
+POPUPOB001|Objectte/Item||
+POPUPOB002|Name:||
+POPUPOB003|Cretee Newe Objectte||
+POPUPOB004|Delete Objectte||
+POPUPOB005|Modifee Objectte||
+POPUPOB006|Cretee Newe Item||
+POPUPOB007|Aree Objectte||
+POPUPOB008|Aree Objectte||
+POPUPOB009|Brightte Colorre||
+POPUPOB010|Colorre-Fil||
+POPUPOB011|Circle||
+POPUPOB012|Lynne-Rightte '/'||
+POPUPOB013|Lynne-Leftte '\'||
+POPUPOB014|Trenegle||
+POPUPOB015|Rectangle||
+POPUPOB016|Black||
+POPUPOB017|Ble||
+POPUPOB018|Grene||
+POPUPOB019|Cyanne||
+POPUPOB020|Rede||
+POPUPOB021|Violette||
+POPUPOB022|Yellou||
+POPUPOB023|Greye||
+POPUPOB024|Offsette Upe:||
+POPUPOB025|Offsette Leftte (Excepte '/'):||
+POPUPOB026|Corridorre:||
+POPUPOB027|Genreick Options||
+POPUPOB028|Locacioonne||
+POPUPOB029|Signpostte||
+POPUPOB030|Signpostte Textte||
+POPUPOB031|Signpostte Objectte||
+POPUPOB032|Enable Compressioonne||
+POPUPOB033|Delete Item||
+POPUPOB034|Modifee Item||
+POPUPOB035|Altitude (ftte):||
+POPUPOB036|Spede (knots):||
+POPUPOB037|Coure:||
+POPUPOB038|DF Objectte||
+POPUPOB039|Signal - Heightte(HAAT) - Geynne - Dyrrectivitee||
+POPUPOB040|Beme Widthe - Bereing||
+POPUPOB041|Omni Antenna||
+POPUPOB042|Beme Antenna||
+POPUPOB043|Uselesse||
+POPUPOB044|Adopte Objectte||
+POPUPOB045|Adopte Item||
+POPUPOB046|DF Bereing:||
+POPUPOB047|Probabilitee Circles||
+POPUPOB048|Mape Viewe Objectte||
+POPUPOB049|Minne (mi):||
+POPUPOB050|Max (mi):||
+WPUPCFI001|Configurre Intrenette||
+WPUPCFI002|Hostte ||
+WPUPCFI003|Portte ||
+WPUPCFI004|(Secondaree hosts)||
+WPUPCFI005|Host1||
+WPUPCFI006|Port1||
+WPUPCFI007|Host2||
+WPUPCFI008|Port2||
+WPUPCFI009|Passe-code||
+WPUPCFI010|(Levee Blank if None)||
+WPUPCFI011|Reconnectte onne NET feylurre?||
+WPUPCFI012|Ronne as anne I-Gate?||
+WPUPCFI013|Broodcastte messages via TNC whanne anne I-Gate?||
+WPUPCFI014|Log I-Gate Transactions?||
+WPUPCFI015|Filtre Parametres||
+WPUPCFID01|Configurre Databae (TBD)||
+WPUPCFID02|Hostte ||
+WPUPCFID03|Portte ||
+WPUPCFID04|(Secondaree hosts)||
+WPUPCFID05|Host1||
+WPUPCFID06|Port1||
+WPUPCFID07|Host2||
+WPUPCFID08|Port2||
+WPUPCFID09|Passe-code||
+WPUPCFID10|(Levee Blank if None)||
+WPUPCFID11|Reconnectte onne NET feylurre?||
+WPUPCFID12|Ronne as anne I-Gate?||
+WPUPCFID13|Broodcastte messages via TNC whanne anne I-Gate?||
+WPUPCFID14|Log I-Gate Transactions?||
+WPUPCFID15|Filtre Parametres||
+WPUPCFIA01|Configurre AGWPE||
+WPUPCFIA02|Hostte ||
+WPUPCFIA03|Portte ||
+WPUPCFIA04|(Secondaree hosts)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Port1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Port2||
+WPUPCFIA09|Passe-code||
+WPUPCFIA10|(Levee Blank if None)||
+WPUPCFIA11|Reconnectte onne NET feylurre?||
+WPUPCFIA12|Ronne as anne I-Gate?||
+WPUPCFIA13|Broodcastte messages via TNC whanne anne I-Gate?||
+WPUPCFIA14|Log I-Gate Transactions?||
+WPUPCFIA15|Transmitte RadioPortte||
+WPUPCFA001|Configurre Audio Alarms||
+WPUPCFA002|Audio Plye Commande||
+WPUPCFA003|Alarm onne||
+WPUPCFA004|Audio feel to Plye||
+WPUPCFA005|Newe Stacioonne||
+WPUPCFA006|Newe Message||
+WPUPCFA007|Proximitee||
+WPUPCFA008|Bande Opening||
+WPUPCFA009|Minimum Distance||
+WPUPCFA010|Maximum Distance||
+WPUPCFA011|Wetehre Alrette||
+WPUPCFSP01|Configurre Speceh||
+WPUPCFSP02|Speceh Outputte onne:||
+WPUPCFSP03|Newe Stacioonne||
+WPUPCFSP04|Newe Message Alrette||
+WPUPCFSP05|Newe Message Bodee||
+WPUPCFSP06|Proximitee Alrette||
+WPUPCFSP07|Bande Opening||
+WPUPCFSP08|Newe Wetehre Alrette||
+WPUPCFSP09|Trackede Stacioonne Proximitee Alrette||
+WPUPTSP001|Track Stacioonne|| 
+WPUPTSP002|Track Callsignne|| 
+WPUPTSP003|Matche Cae|| 
+WPUPTSP004|Matche Exactte|| 
+WPUPTSP005|Track Nou!|| 
+WPUPTSP006|Clree Tracking|| 
+WPUPTSP007|Dounloode Treyl||
+WPUPTSP008|Callsignne||
+WPUPTSP009|Startte Treyl (hrs ago)||
+WPUPTSP010|Treyl Lengthe (hrs)||
+WPUPMSB001|Sende Message Box %de||
+WPUPMSB002|Sende Groupe Message Box %de||
+WPUPMSB003|Staciounes Cal:||
+WPUPMSB004|Groupes Cal:||
+WPUPMSB005|Newe/Refresh Cal||
+WPUPMSB006|Newe Groupe||
+WPUPMSB007|Clree Msg Historee||
+WPUPMSB008|Message:||
+WPUPMSB009|Sende Nou!||
+WPUPMSB010|Pathe:||
+WPUPMSB011|Cancel Pending Msgs||
+WPUPMSB012|Kyk Tymmre||
+WPUPMSB013|seq||
+WPUPMSB014|teepe||
+WPUPMSB015|Broodcastte||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Pathe||
+WPUPMSB020|Ue Defaultte Pathe(s)||
+WPUPMSB021|Dyrrectte (No pathe)||
+WPUPMSB022|Revree Pathe (Hintte):||
+WPUPARM001|Change Auto Replee||
+WPUPARM002|Replee:||
+WPUPHPI001|Helpe Index||
+WPUPHPI002|Viewe||
+WPUPSTI000|Objectte fro: %s||
+WPUPSTI001|Stacioonne Info||
+WPUPSTI002|Sende Message||
+WPUPSTI003|Sereche FCC Databae||
+WPUPSTI004|Sereche RAC Databae||
+WPUPSTI005|Packets receyvvede: %de     Lastte Herede: ||
+WPUPSTI006|Herede via the TNC onne deveec %de, ||
+WPUPSTI007|Herede ||
+WPUPSTI008|lastte via Local||
+WPUPSTI009|lastte via TNC onne deveec %de||
+WPUPSTI010|lastte via Intrenette onne deveec %de||
+WPUPSTI011|lastte via Fyl||
+WPUPSTI012|lastte via Unknoonne||
+WPUPSTI013|, ande has movede||
+WPUPSTI014|Currentte Poure Geynne:||
+WPUPSTI016|Altitude: %.0f%s ||
+WPUPSTI017|Coure: %s� ||
+WPUPSTI018|Spede: %.1f km/h||
+WPUPSTI019|Spede: %.1f mph||
+WPUPSTI020|%0.1f meelles||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distance fro mee stacioonne: %s  Bereing fro mee stacioonne: %s||
+WPUPSTI023|Lastte Posicioonne: ||
+WPUPSTI024|Wetehre Data %c:%s||
+WPUPSTI025|Winde Coure: %s�    Spede: %03de km/h||
+WPUPSTI026|Winde Coure: %s�    Spede: %s mph||
+WPUPSTI027|   Gustte: %03de km/h||
+WPUPSTI028|   Gustte: %s mph||
+WPUPSTI029|Tempreeturre: %02.1f�C  ||
+WPUPSTI030|Tempreeturre: %s�F   ||
+WPUPSTI031|Humiditee: %s%%   ||
+WPUPSTI032| Humeeddex: %02.1f�C  ||
+WPUPSTI033|Baro: %s hPa||
+WPUPSTI034|Snou: %0.1f (cm/24h)||
+WPUPSTI035|Snou: %0.0f (inche/24h)||
+WPUPSTI036|Reynne: ||
+WPUPSTI037|%0.2f (mm/h)    ||
+WPUPSTI038|%0.2f (inche/h)  ||
+WPUPSTI039|%0.2f (mm/dye)     ||
+WPUPSTI040|%0.2f (inche/dye)  ||
+WPUPSTI041|%0.2f (mm/since midnightte)||
+WPUPSTI042|%0.2f (inche/since midnightte)||
+WPUPSTI043|Data pathe: %s||
+WPUPSTI044|Commentte %02de/%02de %02de:%02de : %s||
+WPUPSTI045|Clree Track||
+WPUPSTI046|Total Reynne: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (inche)||
+WPUPSTI049|Trace Qeree||
+WPUPSTI050|Unne-Ackede Messages Qeree||
+WPUPSTI051|Dyrrectte Stations Qeree||
+WPUPSTI052|Stacioonne Versioonne Qeree||
+WPUPSTI053|Modifee Objectte/Item||
+WPUPSTI054|Storre Track||
+WPUPSTI055|Echode fro:||
+WPUPSTI056|Enable Automatick Updates||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|DF Bereing: %s||
+WPUPSTI059|Status  %02de/%02de %02de:%02de : %s||
+WPUPSTI060|Fel Tempe: %02.1f�C  ||
+WPUPSTI061|Fel Tempe: %s�F   ||
+WPUPSTI062|Fel Moisturre: %s%%   ||
+WPUPSTI063|Baro: %0.2f inne Hg||
+WPUPSTI064|Fetche NWS Alrette||
+WPUPSTI065|Tactick Cal: %s||
+WPUPSTI066|Assignne Tactick Cal||
+WPUPSTI067|Currentte Range: %de meelles||
+WPUPSTI068|none||
+WPUPSTI069|defaultte||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|range||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Range||
+WPUPSTI076|No signal detectede||
+WPUPSTI077|Detectible signal (Meybe)||
+WPUPSTI078|Detectible signal butte notte copeeeble)||
+WPUPSTI079|Weke signal, marginallee redeeble||
+WPUPSTI080|Noisee butte copeeeble signal||
+WPUPSTI081|Some noys, eseye to copee signal||
+WPUPSTI082|Goode signal we/detectible noys||
+WPUPSTI083|Nerre ful-quieting signal||
+WPUPSTI084|Ful-quieting signal||
+WPUPSTI085|Extremelee strong & ful-quieting signal||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF Bemewidthe||
+WPUPSTI089|DF Lengthe||
+WPUPSTI090|Notte Valide||
+WPUPSTI091|Change Treyl Colorre||
+WPUPSTI092|Clree DF Bereing||
+WPUPALO001|ALOHA radius: %de %s||
+WPUPALO002|Stations inseede ALOHA circle: %de||
+WPUPALO003| Digis:               %de||
+WPUPALO004| Mobeelles (inne mocioonne): %de||
+WPUPALO005| Mobeelles (othre):     %de||
+WPUPALO006| WX stations:         %de||
+WPUPALO007| Home stations:       %de||
+WPUPALO008|Lastte calculatede %de %s %de %s ago.||
+WPUPALO666|ALOHA radius notte calculatede yette||
+STIFCC0001|FCC Databae Lookupe||
+STIFCC0002|RAC Databae Lookupe||
+STIFCC0003|Name:||
+STIFCC0004|Strete:||
+STIFCC0005|Citee:||
+STIFCC0006|State:||
+STIFCC0007|Zipe:||
+STIFCC0008|Basick ||
+STIFCC0009|Advancede ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+STIFCC0100|FCC index olde, rebuilding||
+STIFCC0101|Callsignne Sereche||
+STIFCC0102|Callsignne Notte Founde!||
+STIFCC0103|RAC index olde, rebuilding||
+UMBNDO0001|atte distance of||
+UNIOP00001|OK||
+UNIOP00002|Cancel||
+UNIOP00003|Cloe||
+UNIOP00004|meelles||
+UNIOP00005|km||
+UNIOP00006|Deveec||
+UNIOP00007|Adde||
+UNIOP00008|Delete||
+UNIOP00009|Propreties||
+UNIOP00010|Allou Transmitting?||
+UNIOP00011|Activate onne Startupe?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|inche||
+UNIOP00018|mm/dye||
+UNIOP00019|inche/dye||
+UNIOP00020|mm/hrre||
+UNIOP00021|inche/hrre||
+UNIOP00022|mm/mide||
+UNIOP00023|inche/mide||
+UNIOP00024|deg||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|inne Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Sette System Clock fro GPS Data?||
+UNIOP00030|Digeeppete?||
+UNIOP00031|m||
+UNIOP00032|Applee||
+UNIOP00033|Resette||
+UNIOP00034|minne||
+UNIOP00035|hrre||
+UNIOP00036|dye||
+UNIOP00037|Sende Control-E to gette GPS data?||
+UNIOP00038|Adde Delye||
+STCHO00001|Stacioonne Choosre||
+WPUPWXA001|Wx Alrets||
+WPUPWXA002|Wx Alrette Listte||
+WPUPCIF001|Installede Intrefaces||
+WPUPCIF002|Chooe Intreface Type||
+WPUPCAX001|Configurre AX.25 TNC||
+WPUPCAX002|AX.25 Deveec name||
+IFDNL00000|None||
+IFDNL00001|Serele TNC||
+IFDNL00002|Serele TNC we/GPS onne a HSP cable||
+IFDNL00003|Serele GPS||
+IFDNL00004|Serele WX||
+IFDNL00005|Intrenette Servre||
+IFDNL00006|AX25 TNC||
+IFDNL00007|Networkede GPS (via gpsde)||
+IFDNL00008|Networkede WX||
+IFDNL00009|Serele TNC we/GPS onne AUX portte||
+IFDNL00010|Serele KISS TNC||
+IFDNL00011|Networkede Databae (Notte Implementede Yette)||
+IFDNL00012|Networkede AGWPE||
+IFDNL00013|Serele Multi-Portte KISS TNC||
+IFDNL00014|SQL Databae (Expreeemmental)||
+IFDIN00000|%s %2de %s %s   %s||
+IFDIN00001|%s %2de %s %s:%de   %s||
+IFDIN00002|%s %2de %s deveec %s   %s||
+IFDIN00003|%s %2de  %s  %s %s   %s||
+IFDIN00004|%s %2de  %s  %s %s:%de   %s||
+IFDIN00005|%s %2de  %s  %s %s   %s||
+IFDIN00006| DOWN ||
+IFDIN00007|  UP  ||
+IFDIN00008|ERROR ||
+IFDIN00009|UNKNWN||
+IFPUPCT000|Intreface Control||
+IFPUPCT001|Startte||
+IFPUPCT002|Stope||
+IFPUPCT003|Startte Al||
+IFPUPCT004|Stope Al||
+IGPUPCF000|IGate Options||
+IGPUPCF001|Disable al IGate traffick||
+IGPUPCF002|Allou RF to Inette traffick ONLY||
+IGPUPCF003|Allou RF->Inette ande Inette->RF traffick||
+IGPUPCF004|Igate -> RF Pathe   ||
+WXPUPSI000|WX Stacioonne||
+WXPUPSI001|WX Stacioonne Type||
+WXPUPSI002|Currentte Data||
+WXPUPSI003|Winde Coure||
+WXPUPSI004|Winde Spede||
+WXPUPSI005|Winde Gustte||
+WXPUPSI006|Tempe||
+WXPUPSI007|Total Reynne||
+WXPUPSI008|Todyes Reynne Total||
+WXPUPSI009|Baro||
+WXPUPSI010|Humiditee||
+WXPUPSI011|Pete Bros ULTIMETER 2000 Type (Data Logging Mode)||
+WXPUPSI012|Pete Bros ULTIMETER II Type||
+WXPUPSI013|Pete Bros ULTIMETER 2000 Type (Packette Mode)||
+WXPUPSI014|Currentte HR Reynne Totte.||
+WXPUPSI015|Lastte 24 Reynne Total||
+WXPUPSI016|Qualeemmetricc Q-Nette||
+WXPUPSI017|Pete Bros ULTIMETER 2000 Type (Complete Mode)||
+WXPUPSI018|Dewe Pointte||
+WXPUPSI019|High Winde||
+WXPUPSI020|Winde Chil||
+WXPUPSI021|Hete Index||
+WXPUPSI022|3-Hrre Baro||
+WXPUPSI023|High Tempe.||
+WXPUPSI024|Lou Tempe.||
+WXPUPSI025|Radio Shack WX-200/Oregonne Scientifick WM-918||
+WXPUPSI026|Davis Wetehre Monitorre II/Wizarde III/Vauntage Pro||
+WXPUPSI027|LaCrose WX-23xx||
+WXPUPSI028|Davis APRS Data Loggre||
+LHPUPNI000|Al Stations||
+LHPUPNI001|Mobeel Stations||
+LHPUPNI002|Wetehre Stations||
+LHPUPNI003|Local Stations (via TNC)||
+LHPUPNI004|Lastte Stations||
+LHPUPNI005|Objects & Items||
+LHPUPNI006|Ownne Objects & Items||
+LHPUPNI010|#||
+LHPUPNI011|Cal Signne||
+LHPUPNI012|#Pack||
+LHPUPNI013|Pos Tym||
+LHPUPNI014|Pathe||
+LHPUPNI015|PHG||
+LHPUPNI016|Comments||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Latte||
+LHPUPNI104|Long||
+LHPUPNI105|#Pack||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Tempe||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Latte/Lonne orre UTM||
+PULDNMAT01|Shou Alrette maps abovethe othre maps||
+PULDNMAT02|Shou Alrette maps undre othre maps||
+POPEM00001|Locate Errorre!||
+POPEM00002|Stacioonne %s was notte founde!||
+POPEM00003|Tracking Errorre!||
+POPEM00004|Intreface Errorre!||
+POPEM00005|Invalide AX.25 portte name %s||
+POPEM00006|Invalide AX.25 portte name %s||
+POPEM00007|Invalide callsignne %s||
+POPEM00008|Invalide AX.25 destinacioonne callsignne orre digeeppeteerre||
+POPEM00009|Cannotte openne AX.25 sockette, %s||
+POPEM00010|Cannotte binde AX.25 sockette, %s||
+POPEM00011|Cannotte connectte to AX.25 callsignne, %s||
+POPEM00012|AX.25 errorre onne outputte of UI||
+POPEM00013|AX.25 problem withe axports feel||
+POPEM00014|AX.25 invalide portte name %s||
+POPEM00015|Errorre opening intreface %de Harde Feyl||
+POPEM00016|Errorre opening intreface %de Tym Outte||
+POPEM00017|No morre intrefaces Aveylable!||
+POPEM00018|Data Qeree - Single Message Lynne||
+POPEM00019|Portte transmitting is off forre portte %de||
+POPEM00020|Databae Errorre!||
+POPEM00021|AX.25 supportte notte compeellede into Xastirre!||
+POPEM00022|Inputte Errorre!||
+POPEM00023|No locacioonne name specifiede!||
+POPEM00024|Locacioonne name specifiede is inne ue!||
+POPEM00025|Notte Founde!||
+POPEM00026|Tracking wil commence whanne itte apprees||
+POPEM00027|Impropre info.  Some fields emptee?||
+POPEM00028|Canne'tte openne feel||
+POPEM00029|Founde Itte!||
+POPEM00030|Wetehre Stacioonne Symbol||
+POPEM00031|Changede to WX seembol '/_', othre options:  '\_'  '/W'  ande  '\W'||
+POPEM00032|Warning: Using National Wetehre Serveec Symbol!||
+POPEM00033|No GPS Data!||
+POPEM00034|Disabling Mye Posicioonne TX Until Valide GPS Data!||
+POPEM00035|Warning||
+POPEM00036|Noteec||
+POPEM00037|HSP intreface presentte: GPS timing has bene increseede||
+POPEM00038|Name Conflicts Withe Existing Objectte/Item/Stacioonne||
+POPEM00039|Illegal charactres founde, substituting preiods inne theirre place||
+POPEM00040|Custom outgoing pathe was lostte||
+POPEM00041|Processing anothre feel.  Weytte a bitte, thenne tree ageynne||
+POPEM00042|Objectte notte ounede bee me! Tree adopting the objectte firstte.||
+POPEM00043|Notte anne Objectte/Item!||
+POPEM00044|Fetche Findu Treyl: Feyllede||
+POPEM00045|Fetche Findu Treyl: Complete||
+POPEM00046|Berkeleye DB hideerre/sharede libraree do NOT matche! Disabling mape cache.||
+POPEM00047|Global transmitte is DISABLED. Emregencee beceons arre NOT going outte!||
+POPEM00048|Emregencee Beceonne Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmitting evreee 60 seconds!||
+POPEM00050|Intrefaces orre posits/transmits DISABLED.  Emregencee beceons arre NOT going outte!||
+POPEM00051|Altnette is enablede (Configurre->Defaults deleog)||
+POPEM00052|Callsignne is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We're treeing to talk to ourselves!||
+JMLPO00001|Mape Displye Bookmarks||
+JMLPO00002|Activate!||
+JMLPO00003|Newe Name:||
+BULMW00001|Bulletins||
+BULMW00002|Limitte Range to (0, is no limitte)||
+BULMW00003|Change Range||
+AMTMW00001|Al Message Traffick||
+AMTMW00002|Limitte Range to (0, is no limitte)||
+SPCHSTR001|kilometres||
+SPCHSTR002|metres||
+SPCHSTR003|meelles||
+SPCHSTR004|yards||
+SPCHSTR005|%s, distance is %de %s.||
+SPCHSTR006|%s, distance is %.1f %s.||
+SPCHSTR007|%s, distance is %de %s %s %s.||
+SPCHSTR008|%s, distance is %.1f %s %s %s.||
+SPCHSTR009|Newe Wetehre Alrette||
+SPCHSTR010|Newe Stacioonne||
+SPCHSTR011|Herede, D X, %s, atte distance of %.1f %s||
+SPCHDIRN00|northe of||
+SPCHDIRS00|southe of||
+SPCHDIRE00|esette of||
+SPCHDIRW00|weste of||
+SPCHDIRNE0|northesette of||
+SPCHDIRNW0|northweste of||
+SPCHDIRSE0|southesette of||
+SPCHDIRSW0|southweste of||
+SYMSEL0001|Selectte Symbol||
+SYMSEL0002|Primaree Symbol Table||
+SYMSEL0003|Secondaree Symbol Table||
+PRINT0001|Printte Propreties||
+PRINT0002|Papre Syz||
+PRINT0003|Auto-Rotate Image||
+PRINT0004|Rotate Image 90� CCW||
+PRINT0005|Auto-Scale Image||
+PRINT0006|Scale:||
+PRINT0007|Force defaultte backgrounde colorre to wheette||
+PRINT0008|Printte inne Black ande Wheette||
+PRINT0016|Revree Colors||
+PRINT0009|Postscripte Resolucioonne:||
+PRINT0010|Previewe||
+PRINT0011|Printte to Fyl||
+PRINT0012|Dumping image to feel...||
+PRINT0013|Convreting to Postscripte...||
+PRINT0014|Finishede creteing printte feel||
+PRINT0015|Printte Status||
+PRINT1001|Dyrrectte to:||
+PRINT1002|Via Previewre:||
+FEATURE001|Name:||
+FEATURE002|State/Province:||
+FEATURE003|Countee:||
+FEATURE004|Mape Quade:||
+FEATURE005|Type:||
+FEATURE006|GNIS Fyl:||
+FEATURE007|Addresse:||
+FEATURE008|Citee:||
+FEATURE009|Mark Destinacioonne||
+FEATURE010|Zipe Code:||
+FEATURE011|Geocoding Fyl||
+COORD001|Coordinate Calculatorre||
+COORD002|Calc||
+COORD003|Calculate||
+COORD004|Clree||
+COORD005|UTM||
+COORD006|Latitude orre||
+COORD007|Longitude orre||
+COORD008|Zone||
+COORD009|UTM Easting||
+COORD010|UTM Northing||
+COORD011|               Decimal Degree:  ||
+COORD012|       Degree/Decimal Minutes:  ||
+COORD013|  Degree/Minutes/Dec. Seconds:  ||
+COORD014| Uneevvresal Transvree Mercatorre:  ||
+COORD015|Militaree Gride Refreence System:  ||
+COORD016|       Meyddenhede Gride Locatorre:  ||
+COORD017| **       Sorree, yourre inputte was notte recogneezzede!        **||
+COORD018| **   Plesee ue one of the follouing inputte formats:   **||
+SMARTB001|Smartte Beceoning||
+SMARTB002|High Rate (secs):||
+SMARTB003|High Spede (mph):||
+SMARTB004|High Spede (kph):||
+SMARTB005|Lou Rate (mins):||
+SMARTB006|Lou Spede (mph):||
+SMARTB007|Lou Spede (kph):||
+SMARTB008|Minimum Turnne (deg):||
+SMARTB009|Turnne Slope:||
+SMARTB010|Weytte Tym (secs):||
+SMARTB011|Enable SmartBeceoning(tm)||
+GAMMA001|Adjustte Gamma Correccioonne||
+GAMMA002|Gamma Correccioonne||
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Mape Fontte Tinee||
+MAPFONT004|Mape Fontte Smal||
+MAPFONT005|Mape Fontte Medium||
+MAPFONT006|Mape Fontte Large||
+MAPFONT007|Mape Fontte Huge||
+MAPFONT008|Mape Fontte Bordre||
+MAPFONT009|Menu Fontte||
+MAPFONT010|Stacioonne Fontte||
+MAPFONT011|ATV ID Fontte||
+PULDNDB001|Distte/Bereing Status||
+GPS001|GPS Transfre||
+GPS002|Fyllename||
+GPS003|Selectte Colorre||
+GPS004|Rede||
+GPS005|Grene||
+GPS006|Black||
+GPS007|Wheette||
+GPS008|Orange||
+GPS009|Ble||
+GPS010|Yellou||
+GPS011|Violette||
+MAPP001|Mape Propreties||
+MAPP002|Max   Minne    Mape         USGS  Auto||
+MAPP003|Zoom  Zoom  Leyre  Fil  DRG   Mape   Pathe/Fyllename||
+MAPP004|Change Leyre->||
+MAPP005|Fillede->||
+MAPP006|Yes||
+MAPP007|No||
+MAPP008|Automaps->||
+MAPP009|Max Zoom->||
+MAPP010|Minne Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+TIME001|Dye||
+TIME002|Deys||
+TIME003|Hourre||
+TIME004|Hours||
+TIME005|Minute||
+TIME006|Minutes||
+TIME007|Seconde||
+TIME008|Seconds||
+CACHE001|Mape nou cachede||
+CACHE002|Looding Cachede Mape||
+CACHE003|Mape notte founde inne cache...||
+RANGE001|RANGE SCALE||
+GPSS001|WAAS orre PPS||
+GPSS002|DGPS||
+GPSS003|Valide SPS||
+GPSS004|Invalide||
+GPSS005|Sats/Viewe||
+GPSS006|Fix||
+GPSS007|!GPS data is oldre thanne 30 seconds!||
+GPSS008|Simulacioonne||
+GPSS009|Manual||
+GPSS010|Estimatede||
+GPSS011|Flootte RTK||
+GPSS012|RTK||
+CADPUD001|Aree Objectte||
+CADPUD002|Aree Label:||
+CADPUD003|Commentte:||
+CADPUD004|Probabilitee (%):||
+CADPUD005|OK||
+CADPUD006|CAD Deleog||
+CADPUD007|Shou/Editte Deteyls||
+CADPUD008|Cancel||
+CADPUD009|Delete CAD objects?||
+CADPUD010|Delete Al||
+CADPUD011|Delete Selectede||
+CADPUD012|Solide||
+CADPUD013|Dashede||
+CADPUD014|Double Dash||
+MDATA001|XASTIR Mape of %s (uppre leftte) to %s (loure rightte).  UTM %de m gride, %s datum. ||
+MDATA002|XASTIR Mape of %s (uppre leftte) to %s %s (loure rightte).  Latte/Long gride, %s datum.||
+MDATA003|XASTIR Mape of %s (uppre leftte) to %s (loure rightte).  UTM zones, %s datum.||
+XADBMST001|MySQL (latte/long)||
+XADBMST002|Postgreql withe Postgis||
+XADBMST003|MySQL (spatele)||
+XASCHEMA01|Xastirre Simple Schema||
+XASCHEMA02|Xastirre CAD Schema||
+XASCHEMA03|Xastirre ful Schema||
+XASCHEMA04|APRSWorlde Schema||
diff --git a/config/language-PigLatin.sys b/config/language-PigLatin.sys
new file mode 100644
index 0000000..9d5d4eb
--- /dev/null
+++ b/config/language-PigLatin.sys
@@ -0,0 +1,1143 @@
+# language-PigLatin.sys, translated from language-English.sys
+# Please do not edit this derived file.
+MENUTB0001|ileFay|F|
+MENUTB0002|iewVay|V|
+MENUTB0004|apMay|M|
+MENUTB0005|ationStay|S|
+MENUTB0006|essageMay|e|
+MENUTB0010|erfaceIntay|I|
+MENUTB0009|elpHay|H|
+PULDNFI001|onfigureCay|C|
+PULDNFI002|enOpay ogLay ileFay|O|
+PULDNFI003|estTay|T|
+PULDNFI004|itExay|x|
+PULDNFI007|angeChay ebugDay evelLay|D|
+PULDNFI010|TNC oggingLay||
+PULDNFI011|etNay oggingLay||
+PULDNFI012|ateIGay oggingLay||
+PULDNFI013|WX oggingLay||
+PULDNFI014|PNG apshotsSnay||
+PULDNFI015|intPray|P|
+PULDNFI016|KML apshotsSnay||
+PULDNVI001|ulletinsBay|B|
+PULDNVI002|omingIncay ataDay|I|
+PULDNVI003|obileMay ationsStay|M|
+PULDNVI004|lAlay ationsStay|A|
+PULDNVI009|ocalLay ationsStay|S|
+PULDNVI012|astLay ationsStay|L|
+PULDNVI005|eatherWay ationsStay|W|
+PULDNVI008|nOway eatherWay ataDay|D|
+PULDNVI007|eatherWay ertsAlay|e|
+PULDNVI011|essageMay afficTray|T|
+PULDNVI013|imeUptay|U|
+PULDNVI014|ogramPray imeUptay||
+PULDNVI015|GPS atusStay||
+PULDNVI016|ALOHA atisticsStay||
+PULDNCF004|ationStay|S|
+PULDNCF001|efaultsDay|D|
+PULDNCF003|imingTay|T|
+PULDNCF002|oordinateCay ystemSay|o|
+PULDNCF006|udioAay armsAlay|A|
+PULDNCF007|eechSpay|p|
+PULDNCF008|aveSay onfigCay owNay!|C|
+PULDNMP001|apMay ooserChay|M|
+PULDNMP012|apMay isplayDay ookmarksBay|B|
+PULDNMP014|ocateLay apMay eatureFay|F|
+PULDNMP016|isableDay astFay oomZay/anPay/omeHay||
+PULDNMP013|isableDay lAlay apsMay||
+PULDNMP002|ableEnay utoAay apsMay||
+PULDNMP003|ableEnay apMay idGray||
+PULDNMP004|ableEnay apMay evelsLay||
+PULDNMP010|ableEnay apMay abelsLay||
+PULDNMP009|ableEnay eaAray olorCay illsFay||
+PULDNMP007|ableEnay eatherWay ertsAlay||
+PULDNMP005|ackgroundBay olorCay|C|
+PULDNMP006|ationStay extTay yleStay|T|
+PULDNMP026|onIcay utlineOay yleStay|O|
+PULDNMP011|ouseMay ointerPay enuMay|P|
+PULDNMP008|apMay ensityIntay|I|
+PULDNMP020|onfigureCay igermapTay||
+PULDNMP021|utoAay apMay - isableDay asterRay apsMay||
+PULDNMP022|exInday ewNay apsMay onway artupStay||
+PULDNMP023|exInday: dAday ewNay apsMay|N|
+PULDNMP024|exInday: eindexRay ALL apsMay!|R|
+PULDNMP025|ontsFay||
+PULDNMP015|ontselXfay||
+PULDNMP027|eRay-ownloadday apsMay (otNay omfray achecay)||
+PULDNMP028|ushFlay ireEntay apMay acheCay!||
+PULDNMP029|indFay essAddray||
+PULDNMP030|onfigureCay USGS DRG||
+PULDNMP031|ableEnay apMay orderBay||
+MPUPTGR001|idGray||
+MPUPTGR002|ountiesCay||
+MPUPTGR003|ityCay abelsLay||
+MPUPTGR004|anUrbay easAray||
+MPUPTGR005|ajorMay oadsRay||
+MPUPTGR006|eetsStray||
+MPUPTGR007|ailroadsRay||
+MPUPTGR008|ateStay abelsLay||
+MPUPTGR009|erstateIntay abelsLay||
+MPUPTGR010|US yHway abelsLay||
+MPUPTGR011|ateStay yHway abelsLay||
+MPUPTGR012|electSay itemsway otay ebay isplayedday:||
+MPUPTGR013|iversRay||
+MPUPTGR014|akesLay||
+MPUPTGR015|irportsAay, arksPay, etcway||
+MPUPTGR016|apMay ensityIntay||
+MPUPTGR017|ernetIntay apMay imeoutTay (ecsay)||
+MPUPTGR018|ableEnay igerTay apsMay||
+MPUPDRG001|electSay itemsway otay ebay isplayedday:||
+MPUPDRG002|intTay erlyingUnday apMay (XOR)||
+MPUPDRG003|ackBlay||
+MPUPDRG004|iteWhay||
+MPUPDRG005|ueBlay||
+MPUPDRG006|edRay||
+MPUPDRG007|ownBray||
+MPUPDRG008|eenGray||
+MPUPDRG009|urplePay||
+MPUPDRG010|ellowYay||
+MPUPDRG011|ightLay ueBlay||
+MPUPDRG012|ightLay edRay||
+MPUPDRG013|ightLay urplePay||
+MPUPDRG014|ightLay ayGray||
+MPUPDRG015|ightLay ownBray||
+WPUPMCP001|apMay ooserChay||
+PULDNMMC01|earClay|C|
+PULDNMMC02|ectorVay|V|
+PULDNMMC03|250k opoTay|2|
+PULDNMMC04|100k opoTay|1|
+PULDNMMC05|24k opoTay|4|
+PULDNMMC06|andExpay irsDay||
+PULDNMMC07|irsDay/apsMay electedSay:||
+PULDNMMC08|earClay irsDay|C
+PULDNMMC09|electSay lAlay|S|
+PULDNMBC01|ayGray||
+PULDNMBC02|istyMay oseRay||
+PULDNMBC03|avyNay ueBlay||
+PULDNMBC04|eelStay ueBlay||
+PULDNMBC05|edMay. eaSay eenGray||
+PULDNMBC06|alePay eenGray||
+PULDNMBC07|alePay oldenrodGay||
+PULDNMBC08|oldenrodGay ellowYay||
+PULDNMBC09|osyRay ownBray||
+PULDNMBC10|ireFay ickbray edRay||
+PULDNMBC11|iteWhay||
+PULDNMBC12|ackBlay||
+PULDNMSL01|ackBlay orderBay|B|
+PULDNMSL02|ackBlay adowShay|S|
+PULDNMSL03|extTay onway ackBlay|T|
+PULDNMIO01|oNay utlineOay|N|
+PULDNMIO02|ackBlay utlineOay|B|
+PULDNMIO03|eyGray utlineOay|G|
+PULDNMIO04|iteWhay utlineOay|W|
+PULDNOT001|nOay||
+PULDNOT002|fOfay||
+PULDNOT003|ortShay||
+PULDNDP014|indFay ationStay|F|
+PULDNDP001|ackTray ationStay|T|
+PULDNDP022|etchFay induFay ailTray|u|
+PULDNDP032|ilterFay ataDay||
+PULDNDP040|electSay oneNay||
+PULDNDP041|electSay ineMay||
+PULDNDP042|electSay TNC||
+PULDNDP027|- electSay irectDay||
+PULDNDP043|- electSay iaVay igiDay||
+PULDNDP034|electSay etNay||
+PULDNDP019|udeInclay iredExpay ataDay||
+PULDNDP044|electSay ationsStay||
+PULDNDP028|- electSay ixedFay ationsStay||
+PULDNDP029|- electSay ovingMay ationsStay||
+PULDNDP030|- electSay WX ationsStay||
+PULDNDP053|  - electSay CWOP WX ationsStay||
+PULDNDP045|electSay ectsObjay/emsItay||
+PULDNDP026|- electSay WX ectsObjay/emsItay||
+PULDNDP039|- electSay aterWay augeGay ectsObjay/emsItay||
+PULDNDP031|- electSay erOthay ectsObjay/emsItay||
+PULDNDP033|ilterFay isplayDay||
+PULDNDP010|isplayDay allsignCay||
+PULDNDP012|isplayDay ymbolSay||
+PULDNDP011|- otateRay ymbolSay||
+PULDNDP007|isplayDay ailTray||
+PULDNDP003|isplayDay ourseCay||
+PULDNDP004|isplayDay eedSpay|S|
+PULDNDP017|- isplayDay ortShay eedSpay||
+PULDNDP002|isplayDay itudeAltay||
+PULDNDP009|isplayDay eatherWay oInfay||
+PULDNDP046|- isplayDay eatherWay extTay||
+PULDNDP018|-- emperatureTay yOnlay||
+PULDNDP047|- isplayDay indWay arbBay||
+PULDNDP054|isplayDay ohaAlay ircleCay||
+PULDNDP013|isplayDay ositionPay iguityAmbay||
+PULDNDP008|isplayDay owerPay/ainGay||
+PULDNDP021|- eUsay efaultDay owerPay/ainGay||
+PULDNDP020|- isplayDay obileMay owerPay/ainGay||
+PULDNDP023|isplayDay DF ibutesAttray||
+PULDNDP123|isplayDay DF eamwidthBay||
+PULDNDP223|isplayDay DF earingBay||
+PULDNDP035|ableEnay eadDay-eckoningRay||
+PULDNDP036|- isplayDay cAray||
+PULDNDP037|- isplayDay ourseCay||
+PULDNDP038|- isplayDay ymbolSay||
+PULDNDP005|isplayDay istDay/earingBay||
+PULDNDP024|isplayDay astLay eportRay eAgay||
+PULDNDP015|earClay lAlay ationsStay!!!|A|
+PULDNDP016|earClay lAlay ailsTray!!!|C|
+PULDNDP025|earClay ectObjay/emItay istoryHay||
+PULDNDP048|eloadRay ectObjay/emItay istoryHay||
+PULDNDP049|earClay lAlay acticalTay allsCay||
+PULDNDP050|earClay acticalTay allCay istoryHay||
+PULDNDP051|electSay acticalTay allsCay yOnlay||
+PULDNDP052|- abelLay ailpointsTray||
+PULDNDP055|ortExpay allway|E|
+PULDNDP056|ortExpay otay KML ileFay||
+PULDNUT001|ableEnay ishEnglay itsUnay|E|
+PULDNUT002|etricMay|M|
+PULDNMG001|endSay essageMay oTay|S|
+PULDNMG002|enOpay oupGray essagesMay|O|
+PULDNMG003|earClay lAlay utgoingOay essagesMay|C|
+PULDQUS001|eneralGay ationsStay ueryQay|G|
+PULDQUS002|ateIGay ationsStay ueryQay|I|
+PULDQUS003|WX ationsStay ueryQay|W|
+PULDNMG004|odifyMay utoAay eplyRay essageMay|A|
+PULDNMG005|ableEnay utoAay eplyRay essageMay||
+PULDNMG006|atelliteSay kAcay odeMay|M|
+PULDNMG007|owShay endingPay essagesMay|P|
+PULDNTNT04|erfaceIntay ontrolCay|C|
+PULDNTNT03|isableDay ansmitTray: ALL||
+PULDNTNT05|isableDay ansmitTray: yMay ositionPay||
+PULDNTNT06|isableDay ansmitTray: ectsObjay/emsItay||
+PULDNTNT11|ableEnay erverSay ortsPay|P|
+PULDNTNT01|ansmitTray owNay!|T|
+PULDNTNT07|etchFay GPS ackTray|F|
+PULDNTNT08|etchFay GPS outesRay|R|
+PULDNTNT09|etchFay GPS aypointsWay|W|
+PULDNTNT10|etchFay arminGay RINO aypointsWay|G|
+PULDNHEL01|outAbay|A|
+PULDNHEL02|elpHay exInday|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|outAbay astirXay||
+POPUPMA001|ionsOptay||
+POPUPMA00c|enterCay|C|
+POPUPMA015|ationStay oInfay|S|
+POPUPMA002|nIay|I|
+POPUPMA003|utOay|O|
+POPUPMA004|oomZay evelLay|L|
+POPUPMA005|evelLay 1|1|
+POPUPMA006|evelLay 16|6|
+POPUPMA007|evelLay 64|4|
+POPUPMA008|evelLay 256|2|
+POPUPMA009|evelLay 1024|0|
+POPUPMA010|evelLay 8192|8|
+POPUPMA017|ireEntay orldWay|E|
+POPUPMA016|astLay apMay osPay/oomZay|P|
+POPUPMA018|ectObjay/emItay->eateCray|b|
+POPUPMA019|ectObjay/emItay->odifyMay|M|
+POPUPMA025|oveMay yMay ationStay ereHay|H|
+POPUPMA011|anPay upway|u|
+POPUPMA012|anPay ownday|d|
+POPUPMA013|anPay eftlay|l|
+POPUPMA014|anPay ightray|r|
+POPUPMA020|easureMay||
+POPUPMA021|oveMay||
+POPUPMA022|ackTrayMe||
+POPUPMA023|odifiersMay oundFay!||
+POPUPMA024|easePlay urntay OFF apsCayLock/umNayLock/ollScrayLock/otherway odifiersmay||
+POPUPMA026|enterCay & oomZay||
+POPUPMA027|  atitudeLay||
+POPUPMA028| ongitudeLay||
+POPUPMA029|awDray CAD ectsObjay||
+POPUPMA030|awDray||
+POPUPMA031|oseClay olygonPay||
+POPUPMA032|aseEray CAD olygonsPay||
+POPUPMA033|**NOT USED**||
+POPUPMA034|ustomCay oomZay evelLay||
+POPUPMA035|10% outway||
+POPUPMA036|10% inway||
+POPUPMA037|eaAray||
+POPUPMA038|uaresqay||
+POPUPMA039|uaresqay eetfay||
+POPUPMA040|uaresqay etersmay||
+POPUPMA041|earingBay||
+POPUPMA042|egreesday||
+POPUPMA043|odifyMay ambiguousway ositionpay||
+POPUPMA044|ositionPay ambiguityway isway onway, ouryay ewnay ositionpay aymay appearway otay umpjay.||
+POPUPMA045|edefinedPray ectsObjay||
+POPUPMA046|CAD olygonsPay||
+POPUPMA047|ableEnay CAD objectsway||
+POPUPMA048|ableEnay CAD abelslay||
+POPUPMA049|ableEnay CAD ommentscay||
+POPUPMA050|ableEnay CAD obabilitypray||
+POPUPMA051|ableEnay CAD areaway izesay||
+POPUPMA052|qsay||
+POPUPMA053|tfay||
+POPUPMA054|etersmay||
+POPUPMA055|imay|
+BBARZM0001|oomZay %sway||
+BBARZM0002|oomZay %sway rTay||
+BBARSTH001|%dway/%dway ationsStay||
+BBARSTA000|%-9s ewNay objectway!||
+BBARSTA001|%-9s ewNay ationstay!||
+BBARSTA002|%-9s||# new data (only display the call)
+BBARSTA003|oadingLay apsMay...||
+BBARSTA004|apsMay oadedLay||
+BBARSTA005|apMay atLay/ongLay idGray nOay|O|
+BBARSTA006|apMay atLay/ongLay idGray fOfay|f|
+BBARSTA007|eThay useway ofway utoAay apsMay, isway ownay ON||
+BBARSTA008|eThay useway ofway utoAay apsMay, isway ownay OFF||
+BBARSTA009|eThay useway ofway apMay evelsLay isway ownay ON||
+BBARSTA010|eThay useway ofway apMay evelsLay isway ownay OFF||
+BBARSTA011|utoAay eplyRay essageMay OFF!||
+BBARSTA012|ileFay oneday..||
+BBARSTA013|eningOpay GPS ortPay||
+BBARSTA014|osingClay GPS ortPay||
+BBARSTA015|otGay GPS RMC ingStray||
+BBARSTA016|otGay GPS GGA ingStray||
+BBARSTA017|etNay isconnectedday omfray osthay||
+BBARSTA018|etNay onnectioncay imedtay outway!||
+BBARSTA019|ookingLay upway osthay %sway||
+BBARSTA020|onnectedCay otay %sway||
+BBARSTA021|etNay onnectionCay ailedFay!||
+BBARSTA022|ouldCay otnay indbay ocketsay!||
+BBARSTA023|oNay IP orfay ostHay!||
+BBARSTA024|oNay ostHay ecifiedSpay||
+BBARSTA025|ostHay oundfay, onnectingCay %dway||
+BBARSTA026|aitingWay orfay GPS ataday iavay HSP..||
+BBARSTA027|earingClay HSP ettinggay TNC ataday..||
+BBARSTA028|oadingLay %sway||
+BBARSTA029|eningOpay WX ortPay||
+BBARSTA030|osingClay WX ortPay||
+BBARSTA031|ookingLay upway ostnamehay %dway||
+BBARSTA032|ecodedDay WX ataDay||
+BBARSTA033|oEchay omfray igipeaterday||
+BBARSTA034|oadingLay eatherWay ertAlay apsMay||
+BBARSTA035|aitingWay orfay GPS ataday iavay AUX..||
+BBARSTA036|earingClay AUX ettinggay TNC ataday..||
+BBARSTA037|GPS ataDay ompleteCay||
+BBARSTA038|ositionPay angechay onway ymay ationstay||
+BBARSTA039|exingInday %sway||
+BBARSTA040|ateurAmay APRS(mtay) ationStay %sway||
+BBARSTA041|aitingWay orfay GPS ataday..||
+BBARSTA042|ansmittingTray objectsway/itemsway||
+BBARSTA043|oggingLay||
+BBARSTA044|ALOHA istanceday isway %dway%sway||
+BBARSTA045|oadingLay ymbolssay...||
+BBARSTA046|eloadingRay ymbolssay...||
+BBARSTA047|itializeInay ymay ationstay...||
+BBARSTA048|artStay interfacesway...||
+BBARSTA049|eadingRay ilestay...||
+BBARSTA050|ownloadingDay ilestay...||
+BBARSTA051|ownloadingDay iletay %ilay ofway %ilay||
+WPUPDPD001|isplayDay acketPay ataDay||
+WPUPDPD002|TNC ataDay onlyway|T|
+WPUPDPD003|etNay ataDay onlyway|N|
+WPUPDPD004|TNC andway etNay ataDay|a|
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|ationStay apabilitiesCay||
+WPUPDPD008|ineMay yOnlay||
+WPUPLSP001|ocateLay ationStay||
+WPUPLSP002|ocateLay allsignCay||
+WPUPLSP003|atchMay aseCay|C|
+WPUPLSP004|atchMay actExay|E|
+WPUPLSP005|ocateLay owNay!|N|
+WPUPLSP006|ergencyEmay ocateLay!||
+WPUPLSP007|FCC/RAC ookupLay||
+WPUPCFD001|onfigureCay efaultsDay||
+WPUPCFD002|erAftay atwhay intervalway ofway imetay illway away ationstay ebay onsideredcay oldway?||
+WPUPCFD003|15 inmay|1|
+WPUPCFD004|30 inmay|3|
+WPUPCFD005|45 inmay|4|
+WPUPCFD006|1 rhay|H|
+WPUPCFD007|90 inmay|9|
+WPUPCFD008|2 shray|2|
+WPUPCFD009|erAftay atwhay intervalway ofway imetay illway away ationstay otnay ebay isplayedday?||
+WPUPCFD010|6 shray|6|
+WPUPCFD011|12 shray|o|
+WPUPCFD012|1 ayDay|D|
+WPUPCFD013|2 aysDay|y|
+WPUPCFD014|1 eekWay|W|
+WPUPCFD015|ansmitTray ationStay ionOptay||
+WPUPCFD016|ixedFay ationStay|F|
+WPUPCFD017|obileMay ationStay wway/ocallay imetay|l|
+WPUPCFD018|obileMay ationStay wway/uluZay ateday-imetay|Z|
+WPUPCFD019|obileMay ationStay wway/uluZay imetay-econdssay|u|
+WPUPCFD021|ationStay ositionPay wway/eatherway|S|
+WPUPCFD022|ationStay ositionPay, uluZay ateday-imetay, andway eatherway|t|
+WPUPCFD023|ansmitTray awRay WX ataday?|R|
+WPUPCFD024|ansmitTray ompressedcay objectsway/itemsway?|C|
+WPUPCFD025|ivateActay ernateAltay etnay?|A|
+WPUPCFD026|endSay ositionpay eportsray atway atwhay intervalsway?||
+WPUPCFD027|opPay upway ewnay ulletinsbay||
+WPUPCFD028|arnWay ifway odifierMay eysKay||
+WPUPCFD029|iewVay erozay-istanceday ulletinsbay||
+WPUPCFD030|isableDay ositPay upeDay-ecksChay||
+WPUPCFD031|oadLay edefinedpray objectsway omfray ilefay||
+WPUPCFD032|yMay ailstray inway oneway olorcay||
+WPUPCFD033|ALTNET:||
+WPUPCFTM01|onfigureCay imingTay||
+WPUPCFTM02|ositPay TX ervalIntay (inmay)||
+WPUPCFTM03|ationStay ostingGhay imeTay (inmay)||
+WPUPCFTM04|ectObjay/emItay axMay TX ervalIntay (inmay)||
+WPUPCFTM05|ationStay earClay imeTay (ourshay)||
+WPUPCFTM06|GPS eckChay ervalIntay (ecsay)||
+WPUPCFTM07|ationStay eleteDay imeTay (aysday)||
+WPUPCFTM08|eadDay-eckoningRay imeoutTay (inmay)||
+WPUPCFTM09|erialSay erIntay-arChay elayDay (smay)||
+WPUPCFTM10|ewNay ackTray imeTay (inmay)||
+WPUPCFTM11|ewNay ackTray ervalIntay (egreesday)||
+WPUPCFTM12|RINO -> ectsObjay ervalIntay (inmay), 0 = isabledDay||
+WPUPCFTM13|apshotSnay ervalIntay (inmay)||
+WPUPCFC001|onfigureCay oordinateCay ystemSay||
+WPUPCFC002|electSay oordinateCay ystemSay||
+WPUPCFC003|dday.ddddday|d|
+WPUPCFC004|dday mmay.mmmay|m|
+WPUPCFC005|dday mmay ssay.sway|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM wway/ecialspay oneszay||
+WPUPCFG001|onfigureCay GPS||
+WPUPCFG003|andStay aloneway GPS ortpay||
+WPUPCFG002|eUsay GPS ositionPay?||
+WPUPCFG004|GPS ionsOptay||
+WPUPCFG005|andStay-aloneway GPS||
+WPUPCFG006|TNC onnectedCay GPS (HSP ableCay)||
+WPUPCFG007|TNC onnectedCay GPS usingway CTL-E||
+WPUPCFG008|GPS imeTay (ampleSay everyway)||
+WPUPCFG009|5 ecsay||
+WPUPCFG010|15 ecsay||
+WPUPCFG011|30 ecsay||
+WPUPCFG012|1 inmay||
+WPUPCFG013|2 inmay||
+WPUPCFG014|5 inmay||
+WPUPCFG015|10 inmay||
+WPUPCFG016|etworkNay onnectedCay GPS||
+WPUPCFG017|GPSD ostHay||
+WPUPCFG018|GPSD ortPay||
+WPUPCFG019|etworkNay GPS iavay GPSD||
+WPUPCFG020|econnectRay onway ailurefay?||
+WPUPCFG021|etworkNay onnectedCay WX||
+WPUPCFG022|WX ostHay||
+WPUPCFG023|WX ortPay||
+WPUPCFT001|onfigureCay TNC||
+WPUPCFT002|eUsay TNC?||
+WPUPCFT003|TNC ortPay||
+WPUPCFT004|ortPay ettingsSay||
+WPUPCFT005|300 sbpay||
+WPUPCFT006|1200 sbpay||
+WPUPCFT007|2400 sbpay||
+WPUPCFT008|4800 sbpay||
+WPUPCFT009|9600 sbpay||
+WPUPCFT010|19200 sbpay||
+WPUPCFT011|otoUnPray athsPay||
+WPUPCFT012|athPay 1: %sway iavay ||
+WPUPCFT013|athPay 2: %sway iavay ||
+WPUPCFT014|athPay 3: %sway iavay ||
+WPUPCFT015|ortPay yleStay||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 sbpay||
+WPUPCFT020|57600 sbpay||
+WPUPCFT021|115200 sbpay||
+WPUPCFT022|230400 sbpay||
+WPUPCFT023|onfigureCay TNC wway/HSP GPS||
+WPUPCFT024|ataDay ypeTay||
+WPUPCFT025|utoAay etectday||
+WPUPCFT026|inaryBay ypeTay||
+WPUPCFT027|ASCII ypeTay||
+WPUPCFT028|onfigureCay TNC wway/AUX GPS||
+WPUPCFT029|onfigureCay TNC wway/INVALID ENUM||
+WPUPCFT030|onfigureCay KISS TNC||
+WPUPCFT031|TNC onfigurationCay ilesFay||
+WPUPCFT032|TNC etupSay ilenameFay|| 
+WPUPCFT033|TNC utdownShay ilenameFay||
+WPUPCFT034|KISS arametersPay||
+WPUPCFT035|elayTXDay (10 smay unitsway)||
+WPUPCFT036|ersistencePay (0 otay 255)||
+WPUPCFT037|otSlayTime (10 smay unitsway)||
+WPUPCFT038|ailTxTay (10 smay unitsway)||
+WPUPCFT039|ullFay uplexDay||
+WPUPCFT040|onfigureCay ultiMay-ortPay KISS TNC||
+WPUPCFT041|adioRay ortPay||
+WPUPCFT042|erfaceIntay opertiesPray: ubiousDay UNPROTO athPay!||
+WPUPCFT043|easePlay onsidercay away ortershay athpay uchsay asway WIDE2-2 orway WIDE1-1,WIDE2-2||
+WPUPCFT044|erfaceIntay opertiesPray: ubiousDay IGATE athPay!||
+WPUPCFT045|ansmittingTray wway/ubiousDay UNPROTO athPay!||
+WPUPCFT046|ansmittingTray wway/ubiousDay IGATE athPay!||
+WPUPCFT047|itInay KISS-odemay onway artupstay||
+WPUPCFWX01|onfigureCay WX ortPay||
+WPUPCFWX02|eatherWay ationStay eviceday||
+WPUPCFWX03|ainRay augeGay orrectionCay (obalGlay ettingSay)||
+WPUPCFWX04|.1 inchway/2.5mm||
+WPUPCFWX05|.01 inchway/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|oNay orrectionCay||
+WPUPCFS001|onfigureCay ationStay||
+WPUPCFS002|allsignCay||
+WPUPCFS003|LAT||
+WPUPCFS004|egday||
+WPUPCFS005|inmay||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(E/W)||
+WPUPCFS009|ationStay ymbolSay||
+WPUPCFS010|oupGray/overlayway||
+WPUPCFS011|ymbolSay||
+WPUPCFS028|electSay||
+WPUPCFS012|owerPay - eightHay (HAAT) - ainGay - irectivityDay||
+WPUPCFS013|isableDay PHG||
+WPUPCFS014|ennaAntay eightHay||
+WPUPCFS015|ennaAntay ainGay||
+WPUPCFS016|iOmnay||
+WPUPCFS017|ommentCay:||
+WPUPCFS018|ositionPay iguityAmbay||
+WPUPCFS019|oneNay||
+WPUPCFS020|.11 ilesmay||
+WPUPCFS021|1.15 ilesmay||
+WPUPCFS022|11.51 ilesmay||
+WPUPCFS023|69.09 ilesmay||
+WPUPCFS024|.18 ilometreskay||
+WPUPCFS025|1.85 ilometreskay||
+WPUPCFS026|18.53 ilometreskay||
+WPUPCFS027|111.19 ilometreskay||
+WPUPCFS029|endSay ompressedcay ositspay|C|
+POPUPOB001|ectObjay/emItay||
+POPUPOB002|ameNay:||
+POPUPOB003|eateCray ewNay ectObjay||
+POPUPOB004|eleteDay ectObjay||
+POPUPOB005|odifyMay ectObjay||
+POPUPOB006|eateCray ewNay emItay||
+POPUPOB007|eaAray ectObjay||
+POPUPOB008|eaAray ectObjay||
+POPUPOB009|ightBray olorCay||
+POPUPOB010|olorCay-illFay||
+POPUPOB011|ircleCay||
+POPUPOB012|ineLay-ightRay '/'||
+POPUPOB013|ineLay-eftLay '\'||
+POPUPOB014|iangleTray||
+POPUPOB015|ectangleRay||
+POPUPOB016|ackBlay||
+POPUPOB017|ueBlay||
+POPUPOB018|eenGray||
+POPUPOB019|yanCay||
+POPUPOB020|edRay||
+POPUPOB021|ioletVay||
+POPUPOB022|ellowYay||
+POPUPOB023|eyGray||
+POPUPOB024|etOffsay pUay:||
+POPUPOB025|etOffsay eftLay (eptExcay '/'):||
+POPUPOB026|orridorCay:||
+POPUPOB027|enericGay ionsOptay||
+POPUPOB028|ocationLay||
+POPUPOB029|ignpostSay||
+POPUPOB030|ignpostSay extTay||
+POPUPOB031|ignpostSay ectObjay||
+POPUPOB032|ableEnay ompressionCay||
+POPUPOB033|eleteDay emItay||
+POPUPOB034|odifyMay emItay||
+POPUPOB035|itudeAltay (tfay):||
+POPUPOB036|eedSpay (otsknay):||
+POPUPOB037|ourseCay:||
+POPUPOB038|DF ectObjay||
+POPUPOB039|ignalSay - eightHay(HAAT) - ainGay - irectivityDay||
+POPUPOB040|eamBay idthWay - earingBay||
+POPUPOB041|iOmnay ennaAntay||
+POPUPOB042|eamBay ennaAntay||
+POPUPOB043|elessUsay||
+POPUPOB044|optAday ectObjay||
+POPUPOB045|optAday emItay||
+POPUPOB046|DF earingBay:||
+POPUPOB047|obabilityPray irclesCay||
+POPUPOB048|apMay iewVay ectObjay||
+POPUPOB049|inMay (imay):||
+POPUPOB050|axMay (imay):||
+WPUPCFI001|onfigureCay ernetIntay||
+WPUPCFI002|ostHay ||
+WPUPCFI003|ortPay ||
+WPUPCFI004|(econdarySay ostshay)||
+WPUPCFI005|ostHay1||
+WPUPCFI006|ortPay1||
+WPUPCFI007|ostHay2||
+WPUPCFI008|ortPay2||
+WPUPCFI009|assPay-odecay||
+WPUPCFI010|(eaveLay ankBlay ifway oneNay)||
+WPUPCFI011|econnectRay onway NET ailurefay?||
+WPUPCFI012|unRay asway anway I-ateGay?||
+WPUPCFI013|oadcastBray essagesmay iavay TNC enwhay anway I-ateGay?||
+WPUPCFI014|ogLay I-ateGay ansactionsTray?||
+WPUPCFI015|ilterFay arametersPay||
+WPUPCFID01|onfigureCay atabaseDay (TBD)||
+WPUPCFID02|ostHay ||
+WPUPCFID03|ortPay ||
+WPUPCFID04|(econdarySay ostshay)||
+WPUPCFID05|ostHay1||
+WPUPCFID06|ortPay1||
+WPUPCFID07|ostHay2||
+WPUPCFID08|ortPay2||
+WPUPCFID09|assPay-odecay||
+WPUPCFID10|(eaveLay ankBlay ifway oneNay)||
+WPUPCFID11|econnectRay onway NET ailurefay?||
+WPUPCFID12|unRay asway anway I-ateGay?||
+WPUPCFID13|oadcastBray essagesmay iavay TNC enwhay anway I-ateGay?||
+WPUPCFID14|ogLay I-ateGay ansactionsTray?||
+WPUPCFID15|ilterFay arametersPay||
+WPUPCFIA01|onfigureCay AGWPE||
+WPUPCFIA02|ostHay ||
+WPUPCFIA03|ortPay ||
+WPUPCFIA04|(econdarySay ostshay)||
+WPUPCFIA05|ostHay1||
+WPUPCFIA06|ortPay1||
+WPUPCFIA07|ostHay2||
+WPUPCFIA08|ortPay2||
+WPUPCFIA09|assPay-odecay||
+WPUPCFIA10|(eaveLay ankBlay ifway oneNay)||
+WPUPCFIA11|econnectRay onway NET ailurefay?||
+WPUPCFIA12|unRay asway anway I-ateGay?||
+WPUPCFIA13|oadcastBray essagesmay iavay TNC enwhay anway I-ateGay?||
+WPUPCFIA14|ogLay I-ateGay ansactionsTray?||
+WPUPCFIA15|ansmitTray adioRayPort||
+WPUPCFA001|onfigureCay udioAay armsAlay||
+WPUPCFA002|udioAay ayPlay ommandCay||
+WPUPCFA003|armAlay onway||
+WPUPCFA004|udioAay ilefay otay ayPlay||
+WPUPCFA005|ewNay ationStay||
+WPUPCFA006|ewNay essageMay||
+WPUPCFA007|oximityPray||
+WPUPCFA008|andBay eningOpay||
+WPUPCFA009|inimumMay istanceDay||
+WPUPCFA010|aximumMay istanceDay||
+WPUPCFA011|eatherWay ertAlay||
+WPUPCFSP01|onfigureCay eechSpay||
+WPUPCFSP02|eechSpay utputOay onway:||
+WPUPCFSP03|ewNay ationStay||
+WPUPCFSP04|ewNay essageMay ertAlay||
+WPUPCFSP05|ewNay essageMay odyBay||
+WPUPCFSP06|oximityPray ertAlay||
+WPUPCFSP07|andBay eningOpay||
+WPUPCFSP08|ewNay eatherWay ertAlay||
+WPUPCFSP09|ackedTray ationStay oximityPray ertAlay||
+WPUPTSP001|ackTray ationStay|| 
+WPUPTSP002|ackTray allsignCay|| 
+WPUPTSP003|atchMay aseCay|| 
+WPUPTSP004|atchMay actExay|| 
+WPUPTSP005|ackTray owNay!|| 
+WPUPTSP006|earClay ackingTray|| 
+WPUPTSP007|ownloadDay ailTray||
+WPUPTSP008|allsignCay||
+WPUPTSP009|artStay ailTray (shray agoway)||
+WPUPTSP010|ailTray engthLay (shray)||
+WPUPMSB001|endSay essageMay oxBay %dway||
+WPUPMSB002|endSay oupGray essageMay oxBay %dway||
+WPUPMSB003|ation'sStay allCay:||
+WPUPMSB004|oup'sGray allCay:||
+WPUPMSB005|ewNay/efreshRay allCay||
+WPUPMSB006|ewNay oupGray||
+WPUPMSB007|earClay gMsay istoryHay||
+WPUPMSB008|essageMay:||
+WPUPMSB009|endSay owNay!||
+WPUPMSB010|athPay:||
+WPUPMSB011|ancelCay endingPay sMsgay||
+WPUPMSB012|ickKay imerTay||
+WPUPMSB013|eqsay||
+WPUPMSB014|ypetay||
+WPUPMSB015|oadcastBray||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|angeChay athPay||
+WPUPMSB020|eUsay efaultDay athPay(sway)||
+WPUPMSB021|irectDay (oNay athpay)||
+WPUPMSB022|everseRay athPay (intHay):||
+WPUPARM001|angeChay utoAay eplyRay||
+WPUPARM002|eplyRay:||
+WPUPHPI001|elpHay exInday||
+WPUPHPI002|iewVay||
+WPUPSTI000|ectObjay omfray: %sway||
+WPUPSTI001|ationStay oInfay||
+WPUPSTI002|endSay essageMay||
+WPUPSTI003|earchSay FCC atabaseDay||
+WPUPSTI004|earchSay RAC atabaseDay||
+WPUPSTI005|acketsPay eceivedray: %dway     astLay eardHay: ||
+WPUPSTI006|eardHay iavay ethay TNC onway eviceday %dway, ||
+WPUPSTI007|eardHay ||
+WPUPSTI008|astlay iavay ocalLay||
+WPUPSTI009|astlay iavay TNC onway eviceday %dway||
+WPUPSTI010|astlay iavay ernetIntay onway eviceday %dway||
+WPUPSTI011|astlay iavay ileFay||
+WPUPSTI012|astlay iavay ownUnknay||
+WPUPSTI013|, andway ashay ovedmay||
+WPUPSTI014|urrentCay owerPay ainGay:||
+WPUPSTI016|itudeAltay: %.0f%sway ||
+WPUPSTI017|ourseCay: %sway� ||
+WPUPSTI018|eedSpay: %.1f mkay/hway||
+WPUPSTI019|eedSpay: %.1f hmpay||
+WPUPSTI020|%0.1f ilesmay||
+WPUPSTI021|%0.1f mkay||
+WPUPSTI022|istanceDay omfray ymay ationstay: %sway  earingBay omfray ymay ationstay: %sway||
+WPUPSTI023|astLay ositionPay: ||
+WPUPSTI024|eatherWay ataDay %cway:%sway||
+WPUPSTI025|indWay ourseCay: %sway�    eedSpay: %03d mkay/hway||
+WPUPSTI026|indWay ourseCay: %sway�    eedSpay: %sway hmpay||
+WPUPSTI027|   ustGay: %03d mkay/hway||
+WPUPSTI028|   ustGay: %sway hmpay||
+WPUPSTI029|emperatureTay: %02.1f�C  ||
+WPUPSTI030|emperatureTay: %sway�F   ||
+WPUPSTI031|umidityHay: %sway%%   ||
+WPUPSTI032| umidexHay: %02.1f�C  ||
+WPUPSTI033|aroBay: %sway ahPay||
+WPUPSTI034|owSnay: %0.1f (mcay/24h)||
+WPUPSTI035|owSnay: %0.0f (inchway/24h)||
+WPUPSTI036|ainRay: ||
+WPUPSTI037|%0.2f (mmay/hway)    ||
+WPUPSTI038|%0.2f (inchway/hway)  ||
+WPUPSTI039|%0.2f (mmay/ayday)     ||
+WPUPSTI040|%0.2f (inchway/ayday)  ||
+WPUPSTI041|%0.2f (mmay/incesay idnightmay)||
+WPUPSTI042|%0.2f (inchway/incesay idnightmay)||
+WPUPSTI043|ataDay athpay: %sway||
+WPUPSTI044|ommentCay %02d/%02d %02d:%02d : %sway||
+WPUPSTI045|earClay ackTray||
+WPUPSTI046|otalTay ainRay: ||
+WPUPSTI047|%0.2f (mmay)||
+WPUPSTI048|%0.2f (inchway)||
+WPUPSTI049|aceTray ueryQay||
+WPUPSTI050|nUay-edAckay essagesMay ueryQay||
+WPUPSTI051|irectDay ationsStay ueryQay||
+WPUPSTI052|ationStay ersionVay ueryQay||
+WPUPSTI053|odifyMay ectObjay/emItay||
+WPUPSTI054|oreStay ackTray||
+WPUPSTI055|oedEchay omfray:||
+WPUPSTI056|ableEnay utomaticAay atesUpday||
+WPUPSTI057|iOmnay-DF: %sway||
+WPUPSTI058|DF earingBay: %sway||
+WPUPSTI059|atusStay  %02d/%02d %02d:%02d : %sway||
+WPUPSTI060|uelFay empTay: %02.1f�C  ||
+WPUPSTI061|uelFay empTay: %sway�F   ||
+WPUPSTI062|uelFay oistureMay: %sway%%   ||
+WPUPSTI063|aroBay: %0.2f inway gHay||
+WPUPSTI064|etchFay NWS ertAlay||
+WPUPSTI065|acticalTay allCay: %sway||
+WPUPSTI066|ignAssay acticalTay allCay||
+WPUPSTI067|urrentCay angeRay: %dway ilesmay||
+WPUPSTI068|onenay||
+WPUPSTI069|efaultday||
+WPUPSTI070|HAAT||
+WPUPSTI071|omniway||
+WPUPSTI072|angeray||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF angeRay||
+WPUPSTI076|oNay ignalsay etectedday||
+WPUPSTI077|etectibleDay ignalsay (aybeMay)||
+WPUPSTI078|etectibleDay ignalsay utbay otnay opyablecay)||
+WPUPSTI079|eakWay ignalsay, arginallymay eadableray||
+WPUPSTI080|oisyNay utbay opyablecay ignalsay||
+WPUPSTI081|omeSay oisenay, easyway otay opycay ignalsay||
+WPUPSTI082|oodGay ignalsay wway/etectibleday oisenay||
+WPUPSTI083|earNay ullfay-ietingquay ignalsay||
+WPUPSTI084|ullFay-ietingquay ignalsay||
+WPUPSTI085|emelyExtray ongstray & ullfay-ietingquay ignalsay||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF eamwidthBay||
+WPUPSTI089|DF engthLay||
+WPUPSTI090|otNay alidVay||
+WPUPSTI091|angeChay ailTray olorCay||
+WPUPSTI092|earClay DF earingBay||
+WPUPALO001|ALOHA adiusray: %dway %sway||
+WPUPALO002|ationsStay insideway ALOHA irclecay: %dway||
+WPUPALO003| igisDay:               %dway||
+WPUPALO004| obilesMay (inway otionmay): %dway||
+WPUPALO005| obilesMay (otherway):     %dway||
+WPUPALO006| WX ationsstay:         %dway||
+WPUPALO007| omeHay ationsstay:       %dway||
+WPUPALO008|astLay alculatedcay %dway %sway %dway %sway agoway.||
+WPUPALO666|ALOHA adiusray otnay alculatedcay etyay||
+STIFCC0001|FCC atabaseDay ookupLay||
+STIFCC0002|RAC atabaseDay ookupLay||
+STIFCC0003|ameNay:||
+STIFCC0004|eetStray:||
+STIFCC0005|ityCay:||
+STIFCC0006|ateStay:||
+STIFCC0007|ipZay:||
+STIFCC0008|asicBay ||
+STIFCC0009|ancedAdvay ||
+STIFCC0010|5 mwpay ||
+STIFCC0011|12 mwpay ||
+STIFCC0100|FCC indexway oldway, ebuildingray||
+STIFCC0101|allsignCay earchSay||
+STIFCC0102|allsignCay otNay oundFay!||
+STIFCC0103|RAC indexway oldway, ebuildingray||
+UMBNDO0001|atway istanceday ofway||
+UNIOP00001|OK||
+UNIOP00002|ancelCay||
+UNIOP00003|oseClay||
+UNIOP00004|ilesmay||
+UNIOP00005|mkay||
+UNIOP00006|eviceDay||
+UNIOP00007|dAday||
+UNIOP00008|eleteDay||
+UNIOP00009|opertiesPray||
+UNIOP00010|owAllay ansmittingTray?||
+UNIOP00011|ivateActay onway artupStay?||
+UNIOP00012|mkay/hway||
+UNIOP00013|hmpay||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mmay||
+UNIOP00017|inchway||
+UNIOP00018|mmay/ayday||
+UNIOP00019|inchway/ayday||
+UNIOP00020|mmay/rhay||
+UNIOP00021|inchway/rhay||
+UNIOP00022|mmay/idmay||
+UNIOP00023|inchway/idmay||
+UNIOP00024|egday||
+UNIOP00025|ahPay||
+UNIOP00026|%||
+UNIOP00027|inway gHay||
+UNIOP00028|mmay gHay||
+UNIOP00029|etSay ystemSay ockClay omfray GPS ataDay?||
+UNIOP00030|igipeatDay?||
+UNIOP00031|mway||
+UNIOP00032|yApplay||
+UNIOP00033|esetRay||
+UNIOP00034|inmay||
+UNIOP00035|rhay||
+UNIOP00036|ayday||
+UNIOP00037|endSay ontrolCay-E otay etgay GPS ataday?||
+UNIOP00038|dAday elayDay||
+STCHO00001|ationStay ooserChay||
+WPUPWXA001|xWay ertsAlay||
+WPUPWXA002|xWay ertAlay istLay||
+WPUPCIF001|alledInstay erfacesIntay||
+WPUPCIF002|ooseChay erfaceIntay ypeTay||
+WPUPCAX001|onfigureCay AX.25 TNC||
+WPUPCAX002|AX.25 eviceDay amenay||
+IFDNL00000|oneNay||
+IFDNL00001|erialSay TNC||
+IFDNL00002|erialSay TNC wway/GPS onway away HSP ablecay||
+IFDNL00003|erialSay GPS||
+IFDNL00004|erialSay WX||
+IFDNL00005|ernetIntay erverSay||
+IFDNL00006|AX25 TNC||
+IFDNL00007|etworkedNay GPS (iavay dgpsay)||
+IFDNL00008|etworkedNay WX||
+IFDNL00009|erialSay TNC wway/GPS onway AUX ortpay||
+IFDNL00010|erialSay KISS TNC||
+IFDNL00011|etworkedNay atabaseDay (otNay ementedImplay etYay)||
+IFDNL00012|etworkedNay AGWPE||
+IFDNL00013|erialSay ultiMay-ortPay KISS TNC||
+IFDNL00014|SQL atabaseDay (erimentalExpay)||
+IFDIN00000|%sway %2d %sway %sway   %sway||
+IFDIN00001|%sway %2d %sway %sway:%dway   %sway||
+IFDIN00002|%sway %2d %sway eviceday %sway   %sway||
+IFDIN00003|%sway %2d  %sway  %sway %sway   %sway||
+IFDIN00004|%sway %2d  %sway  %sway %sway:%dway   %sway||
+IFDIN00005|%sway %2d  %sway  %sway %sway   %sway||
+IFDIN00006| DOWN ||
+IFDIN00007|  UP  ||
+IFDIN00008|ERROR ||
+IFDIN00009|UNKNWN||
+IFPUPCT000|erfaceIntay ontrolCay||
+IFPUPCT001|artStay||
+IFPUPCT002|opStay||
+IFPUPCT003|artStay lAlay||
+IFPUPCT004|opStay lAlay||
+IGPUPCF000|ateIGay ionsOptay||
+IGPUPCF001|isableDay allway ateIGay affictray||
+IGPUPCF002|owAllay RF otay etInay affictray ONLY||
+IGPUPCF003|owAllay RF->etInay andway etInay->RF affictray||
+IGPUPCF004|ateIgay -> RF athPay   ||
+WXPUPSI000|WX ationStay||
+WXPUPSI001|WX ationStay ypeTay||
+WXPUPSI002|urrentCay ataDay||
+WXPUPSI003|indWay ourseCay||
+WXPUPSI004|indWay eedSpay||
+WXPUPSI005|indWay ustGay||
+WXPUPSI006|empTay||
+WXPUPSI007|otalTay ainRay||
+WXPUPSI008|oday'sTay ainRay otalTay||
+WXPUPSI009|aroBay||
+WXPUPSI010|umidityHay||
+WXPUPSI011|eetPay osBray ULTIMETER 2000 ypeTay (ataDay oggingLay odeMay)||
+WXPUPSI012|eetPay osBray ULTIMETER II ypeTay||
+WXPUPSI013|eetPay osBray ULTIMETER 2000 ypeTay (acketPay odeMay)||
+WXPUPSI014|urrentCay HR ainRay otTay.||
+WXPUPSI015|astLay 24 ainRay otalTay||
+WXPUPSI016|ualimetricsQay Q-etNay||
+WXPUPSI017|eetPay osBray ULTIMETER 2000 ypeTay (ompleteCay odeMay)||
+WXPUPSI018|ewDay ointPay||
+WXPUPSI019|ighHay indWay||
+WXPUPSI020|indWay illChay||
+WXPUPSI021|eatHay exInday||
+WXPUPSI022|3-rHay aroBay||
+WXPUPSI023|ighHay empTay.||
+WXPUPSI024|owLay empTay.||
+WXPUPSI025|adioRay ackShay WX-200/egonOray ientificScay WM-918||
+WXPUPSI026|avisDay eatherWay onitorMay II/izardWay III/antageVay oPray||
+WXPUPSI027|aLayCrosse WX-23xx||
+WXPUPSI028|avisDay APRS ataDay oggerLay||
+LHPUPNI000|lAlay ationsStay||
+LHPUPNI001|obileMay ationsStay||
+LHPUPNI002|eatherWay ationsStay||
+LHPUPNI003|ocalLay ationsStay (iavay TNC)||
+LHPUPNI004|astLay ationsStay||
+LHPUPNI005|ectsObjay & emsItay||
+LHPUPNI006|nOway ectsObjay & emsItay||
+LHPUPNI010|#||
+LHPUPNI011|allCay ignSay||
+LHPUPNI012|#ackPay||
+LHPUPNI013|osPay imeTay||
+LHPUPNI014|athPay||
+LHPUPNI015|PHG||
+LHPUPNI016|ommentsCay||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|atLay||
+LHPUPNI104|ongLay||
+LHPUPNI105|#ackPay||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|empTay||
+LHPUPNI204|umHay||
+LHPUPNI205|aroBay||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|atLay/onLay orway UTM||
+PULDNMAT01|owShay ertAlay apsmay aboveway otherway apsmay||
+PULDNMAT02|owShay ertAlay apsmay underway otherway apsmay||
+POPEM00001|ocateLay orErray!||
+POPEM00002|ationStay %sway asway otnay oundfay!||
+POPEM00003|ackingTray orErray!||
+POPEM00004|erfaceIntay orErray!||
+POPEM00005|alidInvay AX.25 ortpay amenay %sway||
+POPEM00006|alidInvay AX.25 ortpay amenay %sway||
+POPEM00007|alidInvay allsigncay %sway||
+POPEM00008|alidInvay AX.25 estinationday allsigncay orway igipeaterday||
+POPEM00009|annotCay openway AX.25 ocketsay, %sway||
+POPEM00010|annotCay indbay AX.25 ocketsay, %sway||
+POPEM00011|annotCay onnectcay otay AX.25 allsigncay, %sway||
+POPEM00012|AX.25 errorway onway outputway ofway UI||
+POPEM00013|AX.25 oblempray ithway axportsway ilefay||
+POPEM00014|AX.25 invalidway ortpay amenay %sway||
+POPEM00015|orErray openingway interfaceway %dway ardHay ailFay||
+POPEM00016|orErray openingway interfaceway %dway imeTay utOay||
+POPEM00017|oNay oremay interfacesway ailableAvay!||
+POPEM00018|ataDay ueryQay - ingleSay essageMay ineLay||
+POPEM00019|ortPay ansmittingtray isway offway orfay ortpay %dway||
+POPEM00020|atabaseDay orErray!||
+POPEM00021|AX.25 upportsay otnay ompiledcay intoway astirXay!||
+POPEM00022|utInpay orErray!||
+POPEM00023|oNay ocationlay amenay ecifiedspay!||
+POPEM00024|ocationLay amenay ecifiedspay isway inway useway!||
+POPEM00025|otNay oundFay!||
+POPEM00026|ackingTray illway ommencecay enwhay itway appearsway||
+POPEM00027|operImpray infoway.  omeSay ieldsfay emptyway?||
+POPEM00028|an'tCay openway ilefay||
+POPEM00029|oundFay tIay!||
+POPEM00030|eatherWay ationStay ymbolSay||
+POPEM00031|angedChay otay WX ymbolsay '/'_ay, otherway optionsway:  '\'_ay  '/'Way  andway  '\'Way||
+POPEM00032|arningWay: ingUsay ationalNay eatherWay erviceSay ymbolSay!||
+POPEM00033|oNay GPS ataDay!||
+POPEM00034|isablingDay yMay ositionPay TX ilUntay alidVay GPS ataDay!||
+POPEM00035|arningWay||
+POPEM00036|oticeNay||
+POPEM00037|HSP interfaceway esentpray: GPS imingtay ashay eenbay increasedway||
+POPEM00038|ameNay onflictsCay ithWay istingExay ectObjay/emItay/ationStay||
+POPEM00039|egalIllay aracterschay oundfay, ubstitutingsay eriodspay inway eirthay aceplay||
+POPEM00040|ustomCay outgoingway athpay asway ostlay||
+POPEM00041|ocessingPray anotherway ilefay.  aitWay away itbay, enthay ytray againway||
+POPEM00042|ectObjay otnay ownedway ybay emay! yTray adoptingway ethay objectway irstfay.||
+POPEM00043|otNay anway ectObjay/emItay!||
+POPEM00044|etchFay induFay ailTray: ailedFay||
+POPEM00045|etchFay induFay ailTray: ompleteCay||
+POPEM00046|erkeleyBay DB eaderhay/aredshay ibrarylay oday NOT atchmay! isablingDay apmay achecay.||
+POPEM00047|obalGlay ansmittray isway DISABLED. ergencyEmay eaconsbay areway NOT oinggay outway!||
+POPEM00048|ergencyEmay eaconBay odeMay!||
+POPEM00049|EMERGENCY BEACON MODE, ansmittingtray everyway 60 econdssay!||
+POPEM00050|erfacesIntay orway ositspay/ansmitstray DISABLED.  ergencyEmay eaconsbay areway NOT oinggay outway!||
+POPEM00051|etAltnay isway enabledway (onfigureCay->efaultsDay ialogday)||
+POPEM00052|allsignCay isway EMPTY!||
+POPEM00053|essageMay isway EMPTY!||
+POPEM00054|e'reWay yingtray otay alktay otay ourselvesway!||
+JMLPO00001|apMay isplayDay ookmarksBay||
+JMLPO00002|ivateActay!||
+JMLPO00003|ewNay ameNay:||
+BULMW00001|ulletinsBay||
+BULMW00002|imitLay angeRay otay (0, isway onay imitlay)||
+BULMW00003|angeChay angeRay||
+AMTMW00001|lAlay essageMay afficTray||
+AMTMW00002|imitLay angeRay otay (0, isway onay imitlay)||
+SPCHSTR001|ilometerskay||
+SPCHSTR002|etersmay||
+SPCHSTR003|ilesmay||
+SPCHSTR004|ardsyay||
+SPCHSTR005|%sway, istanceday isway %dway %sway.||
+SPCHSTR006|%sway, istanceday isway %.1f %sway.||
+SPCHSTR007|%sway, istanceday isway %dway %sway %sway %sway.||
+SPCHSTR008|%sway, istanceday isway %.1f %sway %sway %sway.||
+SPCHSTR009|ewNay eatherWay ertAlay||
+SPCHSTR010|ewNay ationStay||
+SPCHSTR011|eardHay, D X, %sway, atway istanceday ofway %.1f %sway||
+SPCHDIRN00|orthnay ofway||
+SPCHDIRS00|outhsay ofway||
+SPCHDIRE00|eastway ofway||
+SPCHDIRW00|estway ofway||
+SPCHDIRNE0|ortheastnay ofway||
+SPCHDIRNW0|orthwestnay ofway||
+SPCHDIRSE0|outheastsay ofway||
+SPCHDIRSW0|outhwestsay ofway||
+SYMSEL0001|electSay ymbolSay||
+SYMSEL0002|imaryPray ymbolSay ableTay||
+SYMSEL0003|econdarySay ymbolSay ableTay||
+PRINT0001|intPray opertiesPray||
+PRINT0002|aperPay izeSay||
+PRINT0003|utoAay-otateRay ageImay||
+PRINT0004|otateRay ageImay 90� CCW||
+PRINT0005|utoAay-aleScay ageImay||
+PRINT0006|aleScay:||
+PRINT0007|orceFay efaultday ackgroundbay olorcay otay itewhay||
+PRINT0008|intPray inway ackBlay andway iteWhay||
+PRINT0016|everseRay olorsCay||
+PRINT0009|ostscriptPay esolutionRay:||
+PRINT0010|eviewPray||
+PRINT0011|intPray otay ileFay||
+PRINT0012|umpingDay imageway otay ilefay...||
+PRINT0013|onvertingCay otay ostscriptPay...||
+PRINT0014|inishedFay eatingcray intpray ilefay||
+PRINT0015|intPray atusStay||
+PRINT1001|irectDay otay:||
+PRINT1002|iaVay eviewerPray:||
+FEATURE001|ameNay:||
+FEATURE002|ateStay/ovincePray:||
+FEATURE003|ountyCay:||
+FEATURE004|apMay uadQay:||
+FEATURE005|ypeTay:||
+FEATURE006|GNIS ileFay:||
+FEATURE007|essAddray:||
+FEATURE008|ityCay:||
+FEATURE009|arkMay estinationDay||
+FEATURE010|ipZay odeCay:||
+FEATURE011|eocodingGay ileFay||
+COORD001|oordinateCay alculatorCay||
+COORD002|alcCay||
+COORD003|alculateCay||
+COORD004|earClay||
+COORD005|UTM||
+COORD006|atitudeLay orway||
+COORD007|ongitudeLay orway||
+COORD008|oneZay||
+COORD009|UTM astingEay||
+COORD010|UTM orthingNay||
+COORD011|               ecimalDay egreesDay:  ||
+COORD012|       egreesDay/ecimalDay inutesMay:  ||
+COORD013|  egreesDay/inutesMay/ecDay. econdsSay:  ||
+COORD014| iversalUnay ansverseTray ercatorMay:  ||
+COORD015|ilitaryMay idGray eferenceRay ystemSay:  ||
+COORD016|       aidenheadMay idGray ocatorLay:  ||
+COORD017| **       orrySay, ouryay inputway asway otnay ecognizedray!        **||
+COORD018| **   easePlay useway oneway ofway ethay ollowingfay inputway ormatsfay:   **||
+SMARTB001|artSmay eaconingBay||
+SMARTB002|ighHay ateRay (ecssay):||
+SMARTB003|ighHay eedSpay (hmpay):||
+SMARTB004|ighHay eedSpay (hkpay):||
+SMARTB005|owLay ateRay (insmay):||
+SMARTB006|owLay eedSpay (hmpay):||
+SMARTB007|owLay eedSpay (hkpay):||
+SMARTB008|inimumMay urnTay (egday):||
+SMARTB009|urnTay opeSlay:||
+SMARTB010|aitWay imeTay (ecssay):||
+SMARTB011|ableEnay artSmayBeaconing(mtay)||
+GAMMA001|ustAdjay ammaGay orrectionCay||
+GAMMA002|ammaGay orrectionCay||
+MAPFONT001|angeChay ontsFay||
+MAPFONT002|ontsFay||
+MAPFONT003|apMay ontFay inyTay||
+MAPFONT004|apMay ontFay allSmay||
+MAPFONT005|apMay ontFay ediumMay||
+MAPFONT006|apMay ontFay argeLay||
+MAPFONT007|apMay ontFay ugeHay||
+MAPFONT008|apMay ontFay orderBay||
+MAPFONT009|enuMay ontFay||
+MAPFONT010|ationStay ontFay||
+MAPFONT011|ATV ID ontFay||
+PULDNDB001|istDay/earingBay atusStay||
+GPS001|GPS ansferTray||
+GPS002|ilenameFay||
+GPS003|electSay olorCay||
+GPS004|edRay||
+GPS005|eenGray||
+GPS006|ackBlay||
+GPS007|iteWhay||
+GPS008|angeOray||
+GPS009|ueBlay||
+GPS010|ellowYay||
+GPS011|ioletVay||
+MAPP001|apMay opertiesPray||
+MAPP002|axMay   inMay    apMay         USGS  utoAay||
+MAPP003|oomZay  oomZay  ayerLay  illFay  DRG   apMay   athPay/ilenameFay||
+MAPP004|angeChay ayerLay->||
+MAPP005|illedFay->||
+MAPP006|esYay||
+MAPP007|oNay||
+MAPP008|utomapsAay->||
+MAPP009|axMay oomZay->||
+MAPP010|inMay oomZay->||
+MAPP011|utoAay||
+MAPP012|USGS DRG->||
+TIME001|ayDay||
+TIME002|aysDay||
+TIME003|ourHay||
+TIME004|oursHay||
+TIME005|inuteMay||
+TIME006|inutesMay||
+TIME007|econdSay||
+TIME008|econdsSay||
+CACHE001|apMay ownay achedcay||
+CACHE002|oadingLay achedCay apMay||
+CACHE003|apMay otnay oundfay inway achecay...||
+RANGE001|RANGE SCALE||
+GPSS001|WAAS orway PPS||
+GPSS002|DGPS||
+GPSS003|alidVay SPS||
+GPSS004|alidInvay||
+GPSS005|atsSay/iewVay||
+GPSS006|ixFay||
+GPSS007|!GPS ataday isway olderway anthay 30 econdssay!||
+GPSS008|imulationSay||
+GPSS009|anualMay||
+GPSS010|imatedEstay||
+GPSS011|oatFlay RTK||
+GPSS012|RTK||
+CADPUD001|eaAray ectObjay||
+CADPUD002|eaAray abelLay:||
+CADPUD003|ommentCay:||
+CADPUD004|obabilityPray (%):||
+CADPUD005|OK||
+CADPUD006|CAD ialogDay||
+CADPUD007|owShay/itEday etailsDay||
+CADPUD008|ancelCay||
+CADPUD009|eleteDay CAD objectsway?||
+CADPUD010|eleteDay lAlay||
+CADPUD011|eleteDay electedSay||
+CADPUD012|olidSay||
+CADPUD013|ashedDay||
+CADPUD014|oubleDay ashDay||
+MDATA001|XASTIR apMay ofway %sway (upperway eftlay) otay %sway (owerlay ightray).  UTM %dway mway idgray, %sway atumday. ||
+MDATA002|XASTIR apMay ofway %sway (upperway eftlay) otay %sway %sway (owerlay ightray).  atLay/ongLay idgray, %sway atumday.||
+MDATA003|XASTIR apMay ofway %sway (upperway eftlay) otay %sway (owerlay ightray).  UTM oneszay, %sway atumday.||
+XADBMST001|yMaySQL (atlay/onglay)||
+XADBMST002|ostgreqlPay ithway ostgisPay||
+XADBMST003|yMaySQL (atialspay)||
+XASCHEMA01|astirXay impleSay emaSchay||
+XASCHEMA02|astirXay CAD emaSchay||
+XASCHEMA03|astirXay ullfay emaSchay||
+XASCHEMA04|orldAPRSWay emaSchay||
diff --git a/config/language-PirateEnglish.sys b/config/language-PirateEnglish.sys
new file mode 100644
index 0000000..994c289
--- /dev/null
+++ b/config/language-PirateEnglish.sys
@@ -0,0 +1,1143 @@
+# language-PirateEnglish.sys, translated from language-English.sys
+# Please do not edit this derived file.
+MENUTB0001|Scroll|F|
+MENUTB0002|Gander|V|
+MENUTB0004|Treasure Map|M|
+MENUTB0005|Ship|S|
+MENUTB0006|Dispatch|e|
+MENUTB0010|Grapple|I|
+MENUTB0009|Aid|H|
+PULDNFI001|Provision me' ship|C|
+PULDNFI002|Open Scribble Scroll|O|
+PULDNFI003|Test|T|
+PULDNFI004|Run Away!|x|
+PULDNFI007|Change Debug Level|D|
+PULDNFI010|TNC Scribblin'||
+PULDNFI011|Net Scribblin'||
+PULDNFI012|IGate Scribblin'||
+PULDNFI013|WX Scribblin'||
+PULDNFI014|PNG Etchin's||
+PULDNFI015|Affix t' parchment|P|
+PULDNFI016|KML Etchin's||
+PULDNVI001|Bulletins|B|
+PULDNVI002|Incomin' Data|I|
+PULDNVI003|Mobile Ships|M|
+PULDNVI004|All Ships|A|
+PULDNVI009|Local Ships|S|
+PULDNVI012|Last Ships|L|
+PULDNVI005|Weather Ships|W|
+PULDNVI008|Own Weather Data|D|
+PULDNVI007|Weather Alerts|e|
+PULDNVI011|Dispatch Traffic|T|
+PULDNVI013|Uptime|U|
+PULDNVI014|Program Uptime||
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statistics||
+PULDNCF004|Ship|S|
+PULDNCF001|Defaults|D|
+PULDNCF003|Timin'|T|
+PULDNCF002|Coordinate System|o|
+PULDNCF006|Racket Alarms|A|
+PULDNCF007|Parley|p|
+PULDNCF008|Save Config Now!|C|
+PULDNMP001|Treasure Map Chooser|M|
+PULDNMP012|Treasure Map Display Bookmarks|B|
+PULDNMP014|Locate Treasure Map Feature|F|
+PULDNMP016|Disable Fast Zoom/Pan/Haven||
+PULDNMP013|Disable All Treasure Map||
+PULDNMP002|Enable Auto Treasure Map||
+PULDNMP003|Enable Treasure Map Grid||
+PULDNMP004|Enable Treasure Map Levels||
+PULDNMP010|Enable Treasure Map Labels||
+PULDNMP009|Enable Area Color Fills||
+PULDNMP007|Enable Weather Alerts||
+PULDNMP005|Background Color|C|
+PULDNMP006|Ship Text Style|T|
+PULDNMP026|Icon Outline Style|O|
+PULDNMP011|Mouse Pointer Menu|P|
+PULDNMP008|Treasure Map Intensity|I|
+PULDNMP020|Provision me' ship Tigermap||
+PULDNMP021|Auto Treasure Map - Disable Raster Treasure Map||
+PULDNMP022|Index New Treasure Map on Startup||
+PULDNMP023|Index: Add New Treasure Map|N|
+PULDNMP024|Index: Reindex ALL Treasure Map!|R|
+PULDNMP025|Scribbles||
+PULDNMP015|Xfontsel||
+PULDNMP027|Re-plunder Treasure Map (Not from cache)||
+PULDNMP028|Flush Entire Treasure Map Cache!||
+PULDNMP029|Find Address||
+PULDNMP030|Provision me' ship USGS DRG||
+PULDNMP031|Enable Treasure Map Border||
+MPUPTGR001|Grid||
+MPUPTGR002|Counties||
+MPUPTGR003|City Labels||
+MPUPTGR004|Urban Areas||
+MPUPTGR005|Major Roads||
+MPUPTGR006|Streets||
+MPUPTGR007|Railroads||
+MPUPTGR008|State Labels||
+MPUPTGR009|Interstate Labels||
+MPUPTGR010|US Hwy Labels||
+MPUPTGR011|State Hwy Labels||
+MPUPTGR012|Choose 'yer Weapon! items t' be displayed:||
+MPUPTGR013|Rivers||
+MPUPTGR014|Lakes||
+MPUPTGR015|Airports, Parks, etc||
+MPUPTGR016|Treasure Map Intensity||
+MPUPTGR017|Seven Seas Treasure Map Timeout (sec)||
+MPUPTGR018|Enable Tiger Treasure Map||
+MPUPDRG001|Choose 'yer Weapon! items t' be displayed:||
+MPUPDRG002|Tint Underlyin' Treasure Map (XOR)||
+MPUPDRG003|Black||
+MPUPDRG004|White||
+MPUPDRG005|Blue||
+MPUPDRG006|Red||
+MPUPDRG007|Brown||
+MPUPDRG008|Green||
+MPUPDRG009|Purple||
+MPUPDRG010|Yellow||
+MPUPDRG011|Light Blue||
+MPUPDRG012|Light Red||
+MPUPDRG013|Light Purple||
+MPUPDRG014|Light Gray||
+MPUPDRG015|Light Brown||
+WPUPMCP001|Treasure Map Chooser||
+PULDNMMC01|Clear|C|
+PULDNMMC02|Vector|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Expand Dirs||
+PULDNMMC07|Dirs/Treasure Map Choose 'yer Weapon!ed:||
+PULDNMMC08|Clear Dirs|C
+PULDNMMC09|Choose 'yer Weapon! All|S|
+PULDNMBC01|Gray||
+PULDNMBC02|Misty Rose||
+PULDNMBC03|Navy Blue||
+PULDNMBC04|Steel Blue||
+PULDNMBC05|Med. Sea Green||
+PULDNMBC06|Pale Green||
+PULDNMBC07|Pale Goldenrod||
+PULDNMBC08|Goldenrod Yellow||
+PULDNMBC09|Rosy Brown||
+PULDNMBC10|Fire brick Red||
+PULDNMBC11|White||
+PULDNMBC12|Black||
+PULDNMSL01|Black Border|B|
+PULDNMSL02|Black Shadow|S|
+PULDNMSL03|Text on Black|T|
+PULDNMIO01|Nay Outline|N|
+PULDNMIO02|Black Outline|B|
+PULDNMIO03|Grey Outline|G|
+PULDNMIO04|White Outline|W|
+PULDNOT001|On||
+PULDNOT002|Off||
+PULDNOT003|Short||
+PULDNDP014|Find Ship|F|
+PULDNDP001|Track Ship|T|
+PULDNDP022|Fetch Findu Trail|u|
+PULDNDP032|Filter Data||
+PULDNDP040|Choose 'yer Weapon! None||
+PULDNDP041|Choose 'yer Weapon! Mine||
+PULDNDP042|Choose 'yer Weapon! TNC||
+PULDNDP027|- Choose 'yer Weapon! Direct||
+PULDNDP043|- Choose 'yer Weapon! Via Digi||
+PULDNDP034|Choose 'yer Weapon! Net||
+PULDNDP019|Include Expired Data||
+PULDNDP044|Choose 'yer Weapon! Ships||
+PULDNDP028|- Choose 'yer Weapon! Fixed Ships||
+PULDNDP029|- Choose 'yer Weapon! Movin' Ships||
+PULDNDP030|- Choose 'yer Weapon! WX Ships||
+PULDNDP053|  - Choose 'yer Weapon! CWOP WX Ships||
+PULDNDP045|Choose 'yer Weapon! Objects/Items||
+PULDNDP026|- Choose 'yer Weapon! WX Objects/Items||
+PULDNDP039|- Choose 'yer Weapon! Water Gauge Objects/Items||
+PULDNDP031|- Choose 'yer Weapon! Other Objects/Items||
+PULDNDP033|Filter Display||
+PULDNDP010|Display Callsign||
+PULDNDP012|Display Symbol||
+PULDNDP011|- Rotate Symbol||
+PULDNDP007|Display Trail||
+PULDNDP003|Display Course||
+PULDNDP004|Display Speed|S|
+PULDNDP017|- Display Short Speed||
+PULDNDP002|Display Altitude||
+PULDNDP009|Display Weather Info||
+PULDNDP046|- Display Weather Text||
+PULDNDP018|-- Temperature Only||
+PULDNDP047|- Display Wind Barb||
+PULDNDP054|Display Aloha Circle||
+PULDNDP013|Display Positin' Ambiguity||
+PULDNDP008|Display Power/Gain||
+PULDNDP021|- Use Default Power/Gain||
+PULDNDP020|- Display Mobile Power/Gain||
+PULDNDP023|Display DF Attributes||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearin'||
+PULDNDP035|Enable Dead-Reckonin'||
+PULDNDP036|- Display Arc||
+PULDNDP037|- Display Course||
+PULDNDP038|- Display Symbol||
+PULDNDP005|Display Dist/Bearin'||
+PULDNDP024|Display Last Report Age||
+PULDNDP015|Clear All Ships!!!|A|
+PULDNDP016|Clear All Trails!!!|C|
+PULDNDP025|Clear Object/Item History||
+PULDNDP048|Reload Object/Item History||
+PULDNDP049|Clear All Tactical Calls||
+PULDNDP050|Clear Tactical Call History||
+PULDNDP051|Choose 'yer Weapon! Tactical Calls Only||
+PULDNDP052|- Label Trailpoints||
+PULDNDP055|Export all|E|
+PULDNDP056|Export t' KML Scroll||
+PULDNUT001|Enable English Units|E|
+PULDNUT002|Metric|M|
+PULDNMG001|Send Dispatch To|S|
+PULDNMG002|Open Group Dispatchs|O|
+PULDNMG003|Clear All Outgoin' Dispatchs|C|
+PULDQUS001|General Ships Query|G|
+PULDQUS002|IGate Ships Query|I|
+PULDQUS003|WX Ships Query|W|
+PULDNMG004|Modify Auto Reply Dispatch|A|
+PULDNMG005|Enable Auto Reply Dispatch||
+PULDNMG006|Heavenly Body Ack Mode|M|
+PULDNMG007|Show Pendin' Dispatchs|P|
+PULDNTNT04|Grapple Control|C|
+PULDNTNT03|Disable Transmit: ALL||
+PULDNTNT05|Disable Transmit: My Positin'||
+PULDNTNT06|Disable Transmit: Objects/Items||
+PULDNTNT11|Enable Server Ports|P|
+PULDNTNT01|Transmit Now!|T|
+PULDNTNT07|Fetch GPS Track|F|
+PULDNTNT08|Fetch GPS Routes|R|
+PULDNTNT09|Fetch GPS Waypoints|W|
+PULDNTNT10|Fetch Garmin RINO Waypoints|G|
+PULDNHEL01|'bout|A|
+PULDNHEL02|Aid Index|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|'bout HMS Xastir||
+POPUPMA001|Optin's||
+POPUPMA00c|Center|C|
+POPUPMA015|Ship Info|S|
+POPUPMA002|In|I|
+POPUPMA003|Out|O|
+POPUPMA004|Zoom Level|L|
+POPUPMA005|Level 1|1|
+POPUPMA006|Level 16|6|
+POPUPMA007|Level 64|4|
+POPUPMA008|Level 256|2|
+POPUPMA009|Level 1024|0|
+POPUPMA010|Level 8192|8|
+POPUPMA017|Entire World|E|
+POPUPMA016|Last Treasure Map Pos/Zoom|P|
+POPUPMA018|Object/Item->Create|b|
+POPUPMA019|Object/Item->Modify|M|
+POPUPMA025|Move My Ship Here|H|
+POPUPMA011|Pan up|u|
+POPUPMA012|Pan down|d|
+POPUPMA013|Pan left|l|
+POPUPMA014|Pan right|r|
+POPUPMA020|Measure||
+POPUPMA021|Move||
+POPUPMA022|TrackMe||
+POPUPMA023|Modifiers Found!||
+POPUPMA024|Please turn OFF CapsLock/NumLock/ScrollLock/other modifiers||
+POPUPMA026|Center & Zoom||
+POPUPMA027|  Latitude||
+POPUPMA028| Longitude||
+POPUPMA029|Draw CAD Objects||
+POPUPMA030|Draw||
+POPUPMA031|Nay Polygon||
+POPUPMA032|Erase CAD Polygons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Level||
+POPUPMA035|10% out||
+POPUPMA036|10% 'n||
+POPUPMA037|Area||
+POPUPMA038|square||
+POPUPMA039|square feet||
+POPUPMA040|square meters||
+POPUPMA041|Bearin'||
+POPUPMA042|degrees||
+POPUPMA043|Modify ambiguous positin'||
+POPUPMA044|Positin' ambiguity be on, yer new positin' may appear t' jump.||
+POPUPMA045|Predefined Objects||
+POPUPMA046|CAD Polygons||
+POPUPMA047|Enable CAD objects||
+POPUPMA048|Enable CAD labels||
+POPUPMA049|Enable CAD comments||
+POPUPMA050|Enable CAD probability||
+POPUPMA051|Enable CAD area size||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|meters||
+POPUPMA055|mi|
+BBARZM0001|Zoom %s||
+BBARZM0002|Zoom %s Tr||
+BBARSTH001|%d/%d Ships||
+BBARSTA000|%-9s New object!||
+BBARSTA001|%-9s New ship!||
+BBARSTA002|%-9s||# new data (only display the call)
+BBARSTA003|Loadin' Treasure Map...||
+BBARSTA004|Treasure Map Loaded||
+BBARSTA005|Treasure Map Lat/Long Grid On|O|
+BBARSTA006|Treasure Map Lat/Long Grid Off|f|
+BBARSTA007|The use o' Auto Treasure Map, be now ON||
+BBARSTA008|The use o' Auto Treasure Map, be now OFF||
+BBARSTA009|The use o' Treasure Map Levels be now ON||
+BBARSTA010|The use o' Treasure Map Levels be now OFF||
+BBARSTA011|Auto Reply Dispatch OFF!||
+BBARSTA012|Scroll done..||
+BBARSTA013|Openin' GPS Port||
+BBARSTA014|Closin' GPS Port||
+BBARSTA015|Got GPS RMC Strin'||
+BBARSTA016|Got GPS GGA Strin'||
+BBARSTA017|Net disconnected from host||
+BBARSTA018|Net connectin' timed out!||
+BBARSTA019|Lookin' up host %s||
+BBARSTA020|Connected t' %s||
+BBARSTA021|Net Connectin' Failed!||
+BBARSTA022|Could not bind socket!||
+BBARSTA023|Nay IP fer Host!||
+BBARSTA024|Nay Host Specified||
+BBARSTA025|Host found, Connectin' %d||
+BBARSTA026|Waitin' fer GPS data via HSP..||
+BBARSTA027|Clearin' HSP gettin' TNC data..||
+BBARSTA028|Loadin' %s||
+BBARSTA029|Openin' WX Port||
+BBARSTA030|Closin' WX Port||
+BBARSTA031|Lookin' up hostname %d||
+BBARSTA032|Decoded WX Data||
+BBARSTA033|Echo from digipeater||
+BBARSTA034|Loadin' Weather Alert Treasure Map||
+BBARSTA035|Waitin' fer GPS data via AUX..||
+BBARSTA036|Clearin' AUX gettin' TNC data..||
+BBARSTA037|GPS Data Complete||
+BBARSTA038|Positin' change on me ship||
+BBARSTA039|Indexin' %s||
+BBARSTA040|Amateur APRS(tm) Ship %s||
+BBARSTA041|Waitin' fer GPS data..||
+BBARSTA042|Transmittin' objects/items||
+BBARSTA043|Scribblin'||
+BBARSTA044|ALOHA distance be %d%s||
+BBARSTA045|Loadin' symbols...||
+BBARSTA046|Reloadin' symbols...||
+BBARSTA047|Initialize me ship...||
+BBARSTA048|Start grapples...||
+BBARSTA049|Readin' tiles...||
+BBARSTA050|Downloadin' tiles...||
+BBARSTA051|Downloadin' tile %li o' %li||
+WPUPDPD001|Display Packet Data||
+WPUPDPD002|TNC Data only|T|
+WPUPDPD003|Net Data only|N|
+WPUPDPD004|TNC an' Net Data|a|
+WPUPDPD005|TNC||
+WPUPDPD006|NET||
+WPUPDPD007|Ship Capabilities||
+WPUPDPD008|Mine Only||
+WPUPLSP001|Locate Ship||
+WPUPLSP002|Locate Callsign||
+WPUPLSP003|Match Case|C|
+WPUPLSP004|Match Exact|E|
+WPUPLSP005|Locate Now!|N|
+WPUPLSP006|Emergency Locate!||
+WPUPLSP007|FCC/RAC Lookup||
+WPUPCFD001|Provision me' ship Defaults||
+WPUPCFD002|After what interval o' time will a ship be considered auld?||
+WPUPCFD003|15 min|1|
+WPUPCFD004|30 min|3|
+WPUPCFD005|45 min|4|
+WPUPCFD006|1 hr|H|
+WPUPCFD007|90 min|9|
+WPUPCFD008|2 hrs|2|
+WPUPCFD009|After what interval o' time will a ship not be displayed?||
+WPUPCFD010|6 hrs|6|
+WPUPCFD011|12 hrs|o|
+WPUPCFD012|1 Day|D|
+WPUPCFD013|2 Days|y|
+WPUPCFD014|1 Week|W|
+WPUPCFD015|Transmit Ship Optin'||
+WPUPCFD016|Fixed Ship|F|
+WPUPCFD017|Mobile Ship w/local time|l|
+WPUPCFD018|Mobile Ship w/Zulu date-time|Z|
+WPUPCFD019|Mobile Ship w/Zulu time-seconds|u|
+WPUPCFD021|Ship Positin' w/weather|S|
+WPUPCFD022|Ship Positin', Zulu date-time, an' weather|t|
+WPUPCFD023|Transmit Raw WX data?|R|
+WPUPCFD024|Transmit scrawny objects/items?|C|
+WPUPCFD025|Activate Alternate net?|A|
+WPUPCFD026|Send positin' reports at what intervals?||
+WPUPCFD027|Pop up new bulletins||
+WPUPCFD028|Warn if Modifier Keys||
+WPUPCFD029|Gander zero-distance bulletins||
+WPUPCFD030|Disable Posit Dupe-Checks||
+WPUPCFD031|Load predefined objects from scroll||
+WPUPCFD032|My trails 'n one color||
+WPUPCFD033|ALTNET:||
+WPUPCFTM01|Provision me' ship Timin'||
+WPUPCFTM02|Posit TX Interval (min)||
+WPUPCFTM03|Ship Ghostin' Time (min)||
+WPUPCFTM04|Object/Item Max TX Interval (min)||
+WPUPCFTM05|Ship Clear Time (hours)||
+WPUPCFTM06|GPS Check Interval (sec)||
+WPUPCFTM07|Ship Delete Time (days)||
+WPUPCFTM08|Dead-Reckonin' Timeout (min)||
+WPUPCFTM09|Serial Inter-Char Delay (ms)||
+WPUPCFTM10|New Track Time (min)||
+WPUPCFTM11|New Track Interval (degrees)||
+WPUPCFTM12|RINO -> Objects Interval (min), 0 = Disabled||
+WPUPCFTM13|Etchin' Interval (min)||
+WPUPCFC001|Provision me' ship Coordinate System||
+WPUPCFC002|Choose 'yer Weapon! Coordinate System||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM w/special zones||
+WPUPCFG001|Provision me' ship GPS||
+WPUPCFG003|Stand alone GPS port||
+WPUPCFG002|Use GPS Positin'?||
+WPUPCFG004|GPS Optin's||
+WPUPCFG005|Stand-alone GPS||
+WPUPCFG006|TNC Connected GPS (HSP Cable)||
+WPUPCFG007|TNC Connected GPS usin' CTL-E||
+WPUPCFG008|GPS Time (Sample every)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 min||
+WPUPCFG013|2 min||
+WPUPCFG014|5 min||
+WPUPCFG015|10 min||
+WPUPCFG016|Network Connected GPS||
+WPUPCFG017|GPSD Host||
+WPUPCFG018|GPSD Port||
+WPUPCFG019|Network GPS via GPSD||
+WPUPCFG020|Reconnect on failure?||
+WPUPCFG021|Network Connected WX||
+WPUPCFG022|WX Host||
+WPUPCFG023|WX Port||
+WPUPCFT001|Provision me' ship TNC||
+WPUPCFT002|Use TNC?||
+WPUPCFT003|TNC Port||
+WPUPCFT004|Port Settin's||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|UnProto Paths||
+WPUPCFT012|Path 1: %s via ||
+WPUPCFT013|Path 2: %s via ||
+WPUPCFT014|Path 3: %s via ||
+WPUPCFT015|Port Style||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Provision me' ship TNC w/HSP GPS||
+WPUPCFT024|Data Type||
+WPUPCFT025|Auto detect||
+WPUPCFT026|Binary Type||
+WPUPCFT027|ASCII Type||
+WPUPCFT028|Provision me' ship TNC w/AUX GPS||
+WPUPCFT029|Provision me' ship TNC w/INVALID ENUM||
+WPUPCFT030|Provision me' ship KISS TNC||
+WPUPCFT031|TNC Configuratin' Scrolls||
+WPUPCFT032|TNC Setup Scrollname|| 
+WPUPCFT033|TNC Shutdown Scrollname||
+WPUPCFT034|KISS Parameters||
+WPUPCFT035|TXDelay (10 ms units)||
+WPUPCFT036|Persistence (0 t' 255)||
+WPUPCFT037|SlotTime (10 ms units)||
+WPUPCFT038|TxTail (10 ms units)||
+WPUPCFT039|Full Duplex||
+WPUPCFT040|Provision me' ship Multi-Port KISS TNC||
+WPUPCFT041|Radio Port||
+WPUPCFT042|Grapple Properties: Dubious UNPROTO Path!||
+WPUPCFT043|Please consider a shorter path such as WIDE2-2 or WIDE1-1,WIDE2-2||
+WPUPCFT044|Grapple Properties: Dubious IGATE Path!||
+WPUPCFT045|Transmittin' w/Dubious UNPROTO Path!||
+WPUPCFT046|Transmittin' w/Dubious IGATE Path!||
+WPUPCFT047|Init KISS-mode on startup||
+WPUPCFWX01|Provision me' ship WX Port||
+WPUPCFWX02|Weather Ship device||
+WPUPCFWX03|Rain Gauge Correctin' (Global Settin')||
+WPUPCFWX04|.1 inch/2.5mm||
+WPUPCFWX05|.01 inch/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|Nay Correctin'||
+WPUPCFS001|Provision me' ship Ship||
+WPUPCFS002|Callsign||
+WPUPCFS003|LAT||
+WPUPCFS004|deg||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|LONG||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Ship Symbol||
+WPUPCFS010|Group/overlay||
+WPUPCFS011|Symbol||
+WPUPCFS028|Choose 'yer Weapon!||
+WPUPCFS012|Power - Height (HAAT) - Gain - Directivity||
+WPUPCFS013|Disable PHG||
+WPUPCFS014|Antenna Height||
+WPUPCFS015|Antenna Gain||
+WPUPCFS016|Omni||
+WPUPCFS017|Comment:||
+WPUPCFS018|Positin' Ambiguity||
+WPUPCFS019|None||
+WPUPCFS020|.11 miles||
+WPUPCFS021|1.15 miles||
+WPUPCFS022|11.51 miles||
+WPUPCFS023|69.09 miles||
+WPUPCFS024|.18 kilometres||
+WPUPCFS025|1.85 kilometres||
+WPUPCFS026|18.53 kilometres||
+WPUPCFS027|111.19 kilometres||
+WPUPCFS029|Send scrawny posits|C|
+POPUPOB001|Object/Item||
+POPUPOB002|Name:||
+POPUPOB003|Create New Object||
+POPUPOB004|Delete Object||
+POPUPOB005|Modify Object||
+POPUPOB006|Create New Item||
+POPUPOB007|Area Object||
+POPUPOB008|Area Object||
+POPUPOB009|Bright Color||
+POPUPOB010|Color-Fill||
+POPUPOB011|Circle||
+POPUPOB012|Line-Right '/'||
+POPUPOB013|Line-Left '\'||
+POPUPOB014|Triangle||
+POPUPOB015|Rectangle||
+POPUPOB016|Black||
+POPUPOB017|Blue||
+POPUPOB018|Green||
+POPUPOB019|Cyan||
+POPUPOB020|Red||
+POPUPOB021|Violet||
+POPUPOB022|Yellow||
+POPUPOB023|Grey||
+POPUPOB024|Offset Up:||
+POPUPOB025|Offset Left (Except '/'):||
+POPUPOB026|Corridor:||
+POPUPOB027|Generic Optin's||
+POPUPOB028|Locatin'||
+POPUPOB029|Signpost||
+POPUPOB030|Signpost Text||
+POPUPOB031|Signpost Object||
+POPUPOB032|Enable Compression||
+POPUPOB033|Delete Item||
+POPUPOB034|Modify Item||
+POPUPOB035|Altitude (ft):||
+POPUPOB036|Speed (knots):||
+POPUPOB037|Course:||
+POPUPOB038|DF Object||
+POPUPOB039|Signal - Height(HAAT) - Gain - Directivity||
+POPUPOB040|Beam Width - Bearin'||
+POPUPOB041|Omni Antenna||
+POPUPOB042|Beam Antenna||
+POPUPOB043|Useless||
+POPUPOB044|Adopt Object||
+POPUPOB045|Adopt Item||
+POPUPOB046|DF Bearin':||
+POPUPOB047|Probability Circles||
+POPUPOB048|Treasure Map Gander Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+WPUPCFI001|Provision me' ship Seven Seas||
+WPUPCFI002|Host ||
+WPUPCFI003|Port ||
+WPUPCFI004|(Secondary hosts)||
+WPUPCFI005|Host1||
+WPUPCFI006|Port1||
+WPUPCFI007|Host2||
+WPUPCFI008|Port2||
+WPUPCFI009|Pass-code||
+WPUPCFI010|(Leave Blank if None)||
+WPUPCFI011|Reconnect on NET failure?||
+WPUPCFI012|Run as an I-Gate?||
+WPUPCFI013|Broadcast dispatchs via TNC when an I-Gate?||
+WPUPCFI014|Scribble I-Gate Transactin's?||
+WPUPCFI015|Filter Parameters||
+WPUPCFID01|Provision me' ship Database (TBD)||
+WPUPCFID02|Host ||
+WPUPCFID03|Port ||
+WPUPCFID04|(Secondary hosts)||
+WPUPCFID05|Host1||
+WPUPCFID06|Port1||
+WPUPCFID07|Host2||
+WPUPCFID08|Port2||
+WPUPCFID09|Pass-code||
+WPUPCFID10|(Leave Blank if None)||
+WPUPCFID11|Reconnect on NET failure?||
+WPUPCFID12|Run as an I-Gate?||
+WPUPCFID13|Broadcast dispatchs via TNC when an I-Gate?||
+WPUPCFID14|Scribble I-Gate Transactin's?||
+WPUPCFID15|Filter Parameters||
+WPUPCFIA01|Provision me' ship AGWPE||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Port ||
+WPUPCFIA04|(Secondary hosts)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Port1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Port2||
+WPUPCFIA09|Pass-code||
+WPUPCFIA10|(Leave Blank if None)||
+WPUPCFIA11|Reconnect on NET failure?||
+WPUPCFIA12|Run as an I-Gate?||
+WPUPCFIA13|Broadcast dispatchs via TNC when an I-Gate?||
+WPUPCFIA14|Scribble I-Gate Transactin's?||
+WPUPCFIA15|Transmit RadioPort||
+WPUPCFA001|Provision me' ship Racket Alarms||
+WPUPCFA002|Racket Play Command||
+WPUPCFA003|Alarm on||
+WPUPCFA004|Racket scroll t' Play||
+WPUPCFA005|New Ship||
+WPUPCFA006|New Dispatch||
+WPUPCFA007|Proximity||
+WPUPCFA008|Band Openin'||
+WPUPCFA009|Minimum Distance||
+WPUPCFA010|Maximum Distance||
+WPUPCFA011|Weather Alert||
+WPUPCFSP01|Provision me' ship Parley||
+WPUPCFSP02|Parley Output on:||
+WPUPCFSP03|New Ship||
+WPUPCFSP04|New Dispatch Alert||
+WPUPCFSP05|New Dispatch Body||
+WPUPCFSP06|Proximity Alert||
+WPUPCFSP07|Band Openin'||
+WPUPCFSP08|New Weather Alert||
+WPUPCFSP09|Tracked Ship Proximity Alert||
+WPUPTSP001|Track Ship|| 
+WPUPTSP002|Track Callsign|| 
+WPUPTSP003|Match Case|| 
+WPUPTSP004|Match Exact|| 
+WPUPTSP005|Track Now!|| 
+WPUPTSP006|Clear Trackin'|| 
+WPUPTSP007|Plunder Trail||
+WPUPTSP008|Callsign||
+WPUPTSP009|Start Trail (hrs ago)||
+WPUPTSP010|Trail Length (hrs)||
+WPUPMSB001|Send Dispatch Box %d||
+WPUPMSB002|Send Group Dispatch Box %d||
+WPUPMSB003|Ship's Call:||
+WPUPMSB004|Group's Call:||
+WPUPMSB005|New/Refresh Call||
+WPUPMSB006|New Group||
+WPUPMSB007|Clear Msg History||
+WPUPMSB008|Dispatch:||
+WPUPMSB009|Send Now!||
+WPUPMSB010|Path:||
+WPUPMSB011|Nay Pendin' Msgs||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Broadcast||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Path||
+WPUPMSB020|Use Default Path(s)||
+WPUPMSB021|Direct (Nay path)||
+WPUPMSB022|Reverse Path (Hint):||
+WPUPARM001|Change Auto Reply||
+WPUPARM002|Reply:||
+WPUPHPI001|Aid Index||
+WPUPHPI002|Gander||
+WPUPSTI000|Object from: %s||
+WPUPSTI001|Ship Info||
+WPUPSTI002|Send Dispatch||
+WPUPSTI003|Scour FCC Database||
+WPUPSTI004|Scour RAC Database||
+WPUPSTI005|Packets received: %d     Last Heard: ||
+WPUPSTI006|Heard via th' TNC on device %d, ||
+WPUPSTI007|Heard ||
+WPUPSTI008|last via Local||
+WPUPSTI009|last via TNC on device %d||
+WPUPSTI010|last via Seven Seas on device %d||
+WPUPSTI011|last via Scroll||
+WPUPSTI012|last via Unknown||
+WPUPSTI013|, an' has moved||
+WPUPSTI014|Current Power Gain:||
+WPUPSTI016|Altitude: %.0f%s ||
+WPUPSTI017|Course: %s� ||
+WPUPSTI018|Speed: %.1f km/h||
+WPUPSTI019|Speed: %.1f mph||
+WPUPSTI020|%0.1f miles||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distance from me ship: %s  Bearin' from me ship: %s||
+WPUPSTI023|Last Positin': ||
+WPUPSTI024|Weather Data %c:%s||
+WPUPSTI025|Wind Course: %s�    Speed: %03d km/h||
+WPUPSTI026|Wind Course: %s�    Speed: %s mph||
+WPUPSTI027|   Gust: %03d km/h||
+WPUPSTI028|   Gust: %s mph||
+WPUPSTI029|Temperature: %02.1f�C  ||
+WPUPSTI030|Temperature: %s�F   ||
+WPUPSTI031|Humidity: %s%%   ||
+WPUPSTI032| Humidex: %02.1f�C  ||
+WPUPSTI033|Baro: %s hPa||
+WPUPSTI034|Snow: %0.1f (cm/24h)||
+WPUPSTI035|Snow: %0.0f (inch/24h)||
+WPUPSTI036|Rain: ||
+WPUPSTI037|%0.2f (mm/h)    ||
+WPUPSTI038|%0.2f (inch/h)  ||
+WPUPSTI039|%0.2f (mm/day)     ||
+WPUPSTI040|%0.2f (inch/day)  ||
+WPUPSTI041|%0.2f (mm/since midnight)||
+WPUPSTI042|%0.2f (inch/since midnight)||
+WPUPSTI043|Data path: %s||
+WPUPSTI044|Comment %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Clear Track||
+WPUPSTI046|Total Rain: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (inch)||
+WPUPSTI049|Trace Query||
+WPUPSTI050|Un-Acked Dispatchs Query||
+WPUPSTI051|Direct Ships Query||
+WPUPSTI052|Ship Version Query||
+WPUPSTI053|Modify Object/Item||
+WPUPSTI054|Store Track||
+WPUPSTI055|Echoed from:||
+WPUPSTI056|Enable Automatic Updates||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|DF Bearin': %s||
+WPUPSTI059|Status  %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Fuel Temp: %02.1f�C  ||
+WPUPSTI061|Fuel Temp: %s�F   ||
+WPUPSTI062|Fuel Moisture: %s%%   ||
+WPUPSTI063|Baro: %0.2f 'n Hg||
+WPUPSTI064|Fetch NWS Alert||
+WPUPSTI065|Tactical Call: %s||
+WPUPSTI066|Assign Tactical Call||
+WPUPSTI067|Current Range: %d miles||
+WPUPSTI068|none||
+WPUPSTI069|default||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|range||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Range||
+WPUPSTI076|Nay signal detected||
+WPUPSTI077|Detectible signal (Maybe)||
+WPUPSTI078|Detectible signal but not copyable)||
+WPUPSTI079|Weak signal, marginally readable||
+WPUPSTI080|Noisy but copyable signal||
+WPUPSTI081|Some noise, easy t' copy signal||
+WPUPSTI082|Good signal w/detectible noise||
+WPUPSTI083|Near full-quietin' signal||
+WPUPSTI084|Full-quietin' signal||
+WPUPSTI085|Extremely strong & full-quietin' signal||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF Beamwidth||
+WPUPSTI089|DF Length||
+WPUPSTI090|Not Valid||
+WPUPSTI091|Change Trail Color||
+WPUPSTI092|Clear DF Bearin'||
+WPUPALO001|ALOHA radius: %d %s||
+WPUPALO002|Ships inside ALOHA circle: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiles ('n motin'): %d||
+WPUPALO005| Mobiles (other):     %d||
+WPUPALO006| WX ships:         %d||
+WPUPALO007| Haven ships:       %d||
+WPUPALO008|Last calculated %d %s %d %s ago.||
+WPUPALO666|ALOHA radius not calculated yet||
+STIFCC0001|FCC Database Lookup||
+STIFCC0002|RAC Database Lookup||
+STIFCC0003|Name:||
+STIFCC0004|Street:||
+STIFCC0005|City:||
+STIFCC0006|State:||
+STIFCC0007|Zip:||
+STIFCC0008|Basic ||
+STIFCC0009|Advanced ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+STIFCC0100|FCC index auld, rebuildin'||
+STIFCC0101|Callsign Scour||
+STIFCC0102|Callsign Not Found!||
+STIFCC0103|RAC index auld, rebuildin'||
+UMBNDO0001|at distance o'||
+UNIOP00001|Aye||
+UNIOP00002|Nay||
+UNIOP00003|Nay||
+UNIOP00004|miles||
+UNIOP00005|km||
+UNIOP00006|Device||
+UNIOP00007|Add||
+UNIOP00008|Delete||
+UNIOP00009|Properties||
+UNIOP00010|Allow Transmittin'?||
+UNIOP00011|Activate on Startup?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|�C||
+UNIOP00015|�F||
+UNIOP00016|mm||
+UNIOP00017|inch||
+UNIOP00018|mm/day||
+UNIOP00019|inch/day||
+UNIOP00020|mm/hr||
+UNIOP00021|inch/hr||
+UNIOP00022|mm/mid||
+UNIOP00023|inch/mid||
+UNIOP00024|deg||
+UNIOP00025|hPa||
+UNIOP00026|%||
+UNIOP00027|'n Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Set System Clock from GPS Data?||
+UNIOP00030|Digipeat?||
+UNIOP00031|m||
+UNIOP00032|Apply||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|day||
+UNIOP00037|Send Control-E t' get GPS data?||
+UNIOP00038|Add Delay||
+STCHO00001|Ship Chooser||
+WPUPWXA001|Wx Alerts||
+WPUPWXA002|Wx Alert List||
+WPUPCIF001|Installed Grapples||
+WPUPCIF002|Choose Grapple Type||
+WPUPCAX001|Provision me' ship AX.25 TNC||
+WPUPCAX002|AX.25 Device name||
+IFDNL00000|None||
+IFDNL00001|Serial TNC||
+IFDNL00002|Serial TNC w/GPS on a HSP cable||
+IFDNL00003|Serial GPS||
+IFDNL00004|Serial WX||
+IFDNL00005|Seven Seas Server||
+IFDNL00006|AX25 TNC||
+IFDNL00007|Networked GPS (via gpsd)||
+IFDNL00008|Networked WX||
+IFDNL00009|Serial TNC w/GPS on AUX port||
+IFDNL00010|Serial KISS TNC||
+IFDNL00011|Networked Database (Not Implemented Yet)||
+IFDNL00012|Networked AGWPE||
+IFDNL00013|Serial Multi-Port KISS TNC||
+IFDNL00014|SQL Database (Experimental)||
+IFDIN00000|%s %2d %s %s   %s||
+IFDIN00001|%s %2d %s %s:%d   %s||
+IFDIN00002|%s %2d %s device %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006| DOWN ||
+IFDIN00007|  UP  ||
+IFDIN00008|ERROR ||
+IFDIN00009|UNKNWN||
+IFPUPCT000|Grapple Control||
+IFPUPCT001|Start||
+IFPUPCT002|Stop||
+IFPUPCT003|Start All||
+IFPUPCT004|Stop All||
+IGPUPCF000|IGate Optin's||
+IGPUPCF001|Disable all IGate traffic||
+IGPUPCF002|Allow RF t' Inet traffic ONLY||
+IGPUPCF003|Allow RF->Inet an' Inet->RF traffic||
+IGPUPCF004|Igate -> RF Path   ||
+WXPUPSI000|WX Ship||
+WXPUPSI001|WX Ship Type||
+WXPUPSI002|Current Data||
+WXPUPSI003|Wind Course||
+WXPUPSI004|Wind Speed||
+WXPUPSI005|Wind Gust||
+WXPUPSI006|Temp||
+WXPUPSI007|Total Rain||
+WXPUPSI008|Today's Rain Total||
+WXPUPSI009|Baro||
+WXPUPSI010|Humidity||
+WXPUPSI011|Peet Bros ULTIMETER 2000 Type (Data Scribblin' Mode)||
+WXPUPSI012|Peet Bros ULTIMETER II Type||
+WXPUPSI013|Peet Bros ULTIMETER 2000 Type (Packet Mode)||
+WXPUPSI014|Current HR Rain Tot.||
+WXPUPSI015|Last 24 Rain Total||
+WXPUPSI016|Qualimetrics Q-Net||
+WXPUPSI017|Peet Bros ULTIMETER 2000 Type (Complete Mode)||
+WXPUPSI018|Dew Point||
+WXPUPSI019|High Wind||
+WXPUPSI020|Wind Chill||
+WXPUPSI021|Heat Index||
+WXPUPSI022|3-Hr Baro||
+WXPUPSI023|High Temp.||
+WXPUPSI024|Low Temp.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Scribbleger||
+LHPUPNI000|All Ships||
+LHPUPNI001|Mobile Ships||
+LHPUPNI002|Weather Ships||
+LHPUPNI003|Local Ships (via TNC)||
+LHPUPNI004|Last Ships||
+LHPUPNI005|Objects & Items||
+LHPUPNI006|Own Objects & Items||
+LHPUPNI010|#||
+LHPUPNI011|Call Sign||
+LHPUPNI012|#Pack||
+LHPUPNI013|Pos Time||
+LHPUPNI014|Path||
+LHPUPNI015|PHG||
+LHPUPNI016|Comments||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Lat||
+LHPUPNI104|Long||
+LHPUPNI105|#Pack||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Lat/Lon or UTM||
+PULDNMAT01|Show Alert Treasure Map above other Treasure Map||
+PULDNMAT02|Show Alert Treasure Map under other Treasure Map||
+POPEM00001|Locate Error!||
+POPEM00002|Ship %s were bein' not found!||
+POPEM00003|Trackin' Error!||
+POPEM00004|Grapple Error!||
+POPEM00005|Invalid AX.25 port name %s||
+POPEM00006|Invalid AX.25 port name %s||
+POPEM00007|Invalid callsign %s||
+POPEM00008|Invalid AX.25 destinatin' callsign or digipeater||
+POPEM00009|Cannot open AX.25 socket, %s||
+POPEM00010|Cannot bind AX.25 socket, %s||
+POPEM00011|Cannot connect t' AX.25 callsign, %s||
+POPEM00012|AX.25 error on output o' UI||
+POPEM00013|AX.25 problem with axports scroll||
+POPEM00014|AX.25 invalid port name %s||
+POPEM00015|Error openin' grapple %d Hard Fail||
+POPEM00016|Error openin' grapple %d Time Out||
+POPEM00017|Nay more grapples Available!||
+POPEM00018|Data Query - Single Dispatch Line||
+POPEM00019|Port transmittin' be off fer port %d||
+POPEM00020|Database Error!||
+POPEM00021|AX.25 support not compiled into HMS Xastir!||
+POPEM00022|Input Error!||
+POPEM00023|Nay locatin' name specified!||
+POPEM00024|Locatin' name specified be 'n use!||
+POPEM00025|Not Found!||
+POPEM00026|Trackin' will commence when it appears||
+POPEM00027|Improper info.  Some fields empty?||
+POPEM00028|Can't open scroll||
+POPEM00029|Found It!||
+POPEM00030|Weather Ship Symbol||
+POPEM00031|Changed t' WX symbol '/_', other optin's:  '\_'  '/W'  an'  '\W'||
+POPEM00032|Warnin': Usin' National Weather Service Symbol!||
+POPEM00033|Nay GPS Data!||
+POPEM00034|Disablin' My Positin' TX Until Valid GPS Data!||
+POPEM00035|Warnin'||
+POPEM00036|Notice||
+POPEM00037|HSP grapple present: GPS timin' has been increased||
+POPEM00038|Name Conflicts With Existin' Object/Item/Ship||
+POPEM00039|Illegal characters found, substitutin' periods 'n their place||
+POPEM00040|Custom outgoin' path were bein' lost||
+POPEM00041|Processin' another scroll.  Wait a bit, then try again||
+POPEM00042|Object not owned by me! Try adoptin' th' object first.||
+POPEM00043|Not an Object/Item!||
+POPEM00044|Fetch Findu Trail: Failed||
+POPEM00045|Fetch Findu Trail: Complete||
+POPEM00046|Berkeley DB header/shared library do NOT match! Disablin' Treasure Map cache.||
+POPEM00047|Global transmit be DISABLED. Emergency beacons be NOT goin' out!||
+POPEM00048|Emergency Beacon Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmittin' every 60 seconds!||
+POPEM00050|Grapples or posits/transmits DISABLED.  Emergency beacons be NOT goin' out!||
+POPEM00051|Altnet be enabled (Provision me' ship->Defaults dialog)||
+POPEM00052|Callsign be EMPTY!||
+POPEM00053|Dispatch be EMPTY!||
+POPEM00054|We're tryin' t' talk t' ourselves!||
+JMLPO00001|Treasure Map Display Bookmarks||
+JMLPO00002|Activate!||
+JMLPO00003|New Name:||
+BULMW00001|Bulletins||
+BULMW00002|Limit Range t' (0, be nay limit)||
+BULMW00003|Change Range||
+AMTMW00001|All Dispatch Traffic||
+AMTMW00002|Limit Range t' (0, be nay limit)||
+SPCHSTR001|kilometers||
+SPCHSTR002|meters||
+SPCHSTR003|miles||
+SPCHSTR004|yards||
+SPCHSTR005|%s, distance be %d %s.||
+SPCHSTR006|%s, distance be %.1f %s.||
+SPCHSTR007|%s, distance be %d %s %s %s.||
+SPCHSTR008|%s, distance be %.1f %s %s %s.||
+SPCHSTR009|New Weather Alert||
+SPCHSTR010|New Ship||
+SPCHSTR011|Heard, D X, %s, at distance o' %.1f %s||
+SPCHDIRN00|north o'||
+SPCHDIRS00|south o'||
+SPCHDIRE00|east o'||
+SPCHDIRW00|west o'||
+SPCHDIRNE0|northeast o'||
+SPCHDIRNW0|northwest o'||
+SPCHDIRSE0|southeast o'||
+SPCHDIRSW0|southwest o'||
+SYMSEL0001|Choose 'yer Weapon! Symbol||
+SYMSEL0002|Primary Symbol Table||
+SYMSEL0003|Secondary Symbol Table||
+PRINT0001|Affix t' parchment Properties||
+PRINT0002|Paper Size||
+PRINT0003|Auto-Rotate Image||
+PRINT0004|Rotate Image 90� CCW||
+PRINT0005|Auto-Scale Image||
+PRINT0006|Scale:||
+PRINT0007|Force default background color t' white||
+PRINT0008|Affix t' parchment 'n Black an' White||
+PRINT0016|Reverse Colors||
+PRINT0009|Postscript Resolutin':||
+PRINT0010|Preview||
+PRINT0011|Affix t' parchment t' Scroll||
+PRINT0012|Dumpin' image t' scroll...||
+PRINT0013|Convertin' t' Postscript...||
+PRINT0014|Finished creatin' affix t' parchment scroll||
+PRINT0015|Affix t' parchment Status||
+PRINT1001|Direct t':||
+PRINT1002|Via Previewer:||
+FEATURE001|Name:||
+FEATURE002|State/Province:||
+FEATURE003|County:||
+FEATURE004|Treasure Map Quad:||
+FEATURE005|Type:||
+FEATURE006|GNIS Scroll:||
+FEATURE007|Address:||
+FEATURE008|City:||
+FEATURE009|Mark Destinatin'||
+FEATURE010|Zip Code:||
+FEATURE011|Geocodin' Scroll||
+COORD001|Coordinate Calculator||
+COORD002|Calc||
+COORD003|Calculate||
+COORD004|Clear||
+COORD005|UTM||
+COORD006|Latitude or||
+COORD007|Longitude or||
+COORD008|Zone||
+COORD009|UTM Eastin'||
+COORD010|UTM Northin'||
+COORD011|               Decimal Degrees:  ||
+COORD012|       Degrees/Decimal Minutes:  ||
+COORD013|  Degrees/Minutes/Dec. Seconds:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|Military Grid Reference System:  ||
+COORD016|       Maidenhead Grid Locator:  ||
+COORD017| **       Sorry, yer input were bein' not recognized!        **||
+COORD018| **   Please use one o' th' followin' input formats:   **||
+SMARTB001|Smart Beaconin'||
+SMARTB002|High Rate (secs):||
+SMARTB003|High Speed (mph):||
+SMARTB004|High Speed (kph):||
+SMARTB005|Low Rate (mins):||
+SMARTB006|Low Speed (mph):||
+SMARTB007|Low Speed (kph):||
+SMARTB008|Minimum Turn (deg):||
+SMARTB009|Turn Slope:||
+SMARTB010|Wait Time (secs):||
+SMARTB011|Enable SmartBeaconin'(tm)||
+GAMMA001|Adjust Gamma Correctin'||
+GAMMA002|Gamma Correctin'||
+MAPFONT001|Change Scribbles||
+MAPFONT002|Scribbles||
+MAPFONT003|Treasure Map Scribble Tiny||
+MAPFONT004|Treasure Map Scribble Small||
+MAPFONT005|Treasure Map Scribble Medium||
+MAPFONT006|Treasure Map Scribble Large||
+MAPFONT007|Treasure Map Scribble Huge||
+MAPFONT008|Treasure Map Scribble Border||
+MAPFONT009|Menu Scribble||
+MAPFONT010|Ship Scribble||
+MAPFONT011|ATV ID Scribble||
+PULDNDB001|Dist/Bearin' Status||
+GPS001|GPS Transfer||
+GPS002|Scrollname||
+GPS003|Choose 'yer Weapon! Color||
+GPS004|Red||
+GPS005|Green||
+GPS006|Black||
+GPS007|White||
+GPS008|Orange||
+GPS009|Blue||
+GPS010|Yellow||
+GPS011|Violet||
+MAPP001|Treasure Map Properties||
+MAPP002|Max   Min    Treasure Map         USGS  Auto||
+MAPP003|Zoom  Zoom  Layer  Fill  DRG   Treasure Map   Path/Scrollname||
+MAPP004|Change Layer->||
+MAPP005|Filled->||
+MAPP006|Aye||
+MAPP007|Nay||
+MAPP008|Automaps->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+TIME001|Day||
+TIME002|Days||
+TIME003|Hour||
+TIME004|Hours||
+TIME005|Minute||
+TIME006|Minutes||
+TIME007|Second||
+TIME008|Seconds||
+CACHE001|Treasure Map now cached||
+CACHE002|Loadin' Cached Treasure Map||
+CACHE003|Treasure Map not found 'n cache...||
+RANGE001|RANGE SCALE||
+GPSS001|WAAS or PPS||
+GPSS002|DGPS||
+GPSS003|Valid SPS||
+GPSS004|Invalid||
+GPSS005|Sats/Gander||
+GPSS006|Fix||
+GPSS007|!GPS data be older than 30 seconds!||
+GPSS008|Simulatin'||
+GPSS009|Manual||
+GPSS010|Estimated||
+GPSS011|Float RTK||
+GPSS012|RTK||
+CADPUD001|Area Object||
+CADPUD002|Area Label:||
+CADPUD003|Comment:||
+CADPUD004|Probability (%):||
+CADPUD005|Aye||
+CADPUD006|CAD Dialog||
+CADPUD007|Show/Edit Details||
+CADPUD008|Nay||
+CADPUD009|Delete CAD objects?||
+CADPUD010|Delete All||
+CADPUD011|Delete Choose 'yer Weapon!ed||
+CADPUD012|Solid||
+CADPUD013|Dashed||
+CADPUD014|Double Dash||
+MDATA001|HMS XASTIR Treasure Map o' %s (upper left) t' %s (lower right).  UTM %d m grid, %s datum. ||
+MDATA002|HMS XASTIR Treasure Map o' %s (upper left) t' %s %s (lower right).  Lat/Long grid, %s datum.||
+MDATA003|HMS XASTIR Treasure Map o' %s (upper left) t' %s (lower right).  UTM zones, %s datum.||
+XADBMST001|MySQL (lat/long)||
+XADBMST002|Postgreql with Postgis||
+XADBMST003|MySQL (spatial)||
+XASCHEMA01|HMS Xastir Simple Schema||
+XASCHEMA02|HMS Xastir CAD Schema||
+XASCHEMA03|HMS Xastir full Schema||
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/language-Portuguese.sys b/config/language-Portuguese.sys
new file mode 100644
index 0000000..063a0c0
--- /dev/null
+++ b/config/language-Portuguese.sys
@@ -0,0 +1,1353 @@
+# $Id: language-Portuguese.sys,v 1.227 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# Este e o ficheiro da lingua Portuguesa, sem pontuacao, usado para todas as consultas
+# no Xastir.
+#
+# Criador        : por CT1DRB, David Quental
+#
+# Linhas de comentarios com o simbolo de cardinal a frente sao ignorados
+# O formato do ficheiro e como segue:
+# Id (10 caracteres alfa numerico)|(Cadeia associada com id)|TeclaRapida|#comentario
+#
+# AVISO:
+# Algumas cadeias de letras conteem comandos de formato como %s e %d, voce nao
+# deve mudar isso. Cadeias de formatos errados poderao produzir um segfault!
+#
+# Menu principal
+MENUTB0001|Ficheiro|F|
+MENUTB0002|Visualizar|V|
+MENUTB0004|Mapas|M|
+MENUTB0005|Estacoes|s|
+MENUTB0006|Mensagens|g|
+MENUTB0010|Interfaces|I|
+MENUTB0009|Ajuda|j|
+#
+# Menu de ficheiro
+PULDNFI001|Configurar|C|
+PULDNFI002|Abrir o log|B|
+PULDNFI003|Testar|P|
+PULDNFI004|Sair|S|
+PULDNFI007|Muda nivel de debug|D|
+PULDNFI010|Abre o log do TNC|T|
+PULDNFI011|Abre o log da internet|I|
+PULDNFI012|Abre o log da I-Gate|G|
+PULDNFI013|Abre o log do tempo|W|
+PULDNFI014|Activa PNG instantanea||
+PULDNFI015|Imprimir mapa|P|
+PULDNFI016|KML Snapshots||
+#
+# Menu visor
+PULDNVI001|Boletins|B|
+PULDNVI002|Trafego recebido|D|
+PULDNVI003|Estacoes moveis|m|
+PULDNVI004|Todas as estacoes|e|
+PULDNVI009|Estacoes locais|t|
+PULDNVI012|Ultimas estacoes|U|
+PULDNVI005|Estacoes meteorologicas|t|
+PULDNVI008|A sua estacao meteorologica|s|
+PULDNVI007|Alerta de tempo|A|
+PULDNVI011|Trafego de mensagens|f|
+PULDNVI013|Aviso|v|
+PULDNVI014|Programar aviso|r|
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statistics||
+#
+# Menu de configuracao
+PULDNCF004|Esta��o|E|
+PULDNCF001|Pre-definidos|P|
+PULDNCF003|Momento certo|T|
+PULDNCF002|Sistema de coordenadas|S|
+PULDNCF006|Audio dos alarmes|A|
+PULDNCF007|Sintetizador de voz|S|
+PULDNCF008|Guardar configuracao!|G|
+# (Unidades ver PULDNDP006)
+#
+# Menu de mapas
+PULDNMP001|Seleccionar mapas|M|
+PULDNMP012|Saltar para um local do mapa|S|
+PULDNMP014|Localizar faixa no mapa|L|
+PULDNMP016|Disable Fast Zoom/Pan/Home||
+PULDNMP013|Desactivar todos os mapas||
+PULDNMP002|Activar auto mapas||
+PULDNMP003|Activar as coordenadas do mapa||
+PULDNMP004|Niveis dos mapas||
+PULDNMP010|Etiquetas dos mapas||
+PULDNMP009|Activar areas coloridas||
+PULDNMP007|Activar os alertas de WX||
+PULDNMP005|Cor de fundo|C|
+PULDNMP006|Estilo de texto da estacao|E|
+PULDNMP026|Estilo da linha de fora do icon|O|
+PULDNMP011|Menu indicador do rato|r|
+PULDNMP008|Intensidade do mapa|I|
+PULDNMP020|Configurar tigermap||
+PULDNMP021|Auto Map - desactivar raster mapas||
+PULDNMP022|Indexar mapas no comeco||
+PULDNMP023|Index: Acrescentar mapas novos|A|
+PULDNMP024|Index: Reindexar os mapas TODOS|R|
+PULDNMP025|Fonts||
+PULDNMP015|Seleccionar a fonte do X||
+PULDNMP027|Re-download Maps (Not from cache)||
+PULDNMP028|Flush Entire Map Cache!||
+PULDNMP029|Find Address||
+PULDNMP030|Configure USGS DRG||
+PULDNMP031|Enable Map Border||
+#
+# PopUp "Configurar tigermap"
+MPUPTGR001|Grelha||
+MPUPTGR002|Freguesias||
+MPUPTGR003|Etiquetas citadinas||
+MPUPTGR004|Areas urbanas||
+MPUPTGR005|Vias principais||
+MPUPTGR006|Ruas||
+MPUPTGR007|Estradas||
+MPUPTGR008|Etiquetas de provincia||
+MPUPTGR009|Etiquetas inter-provincias||
+MPUPTGR010|Etiquetas Hwy de Portugal||
+MPUPTGR011|Etiquetas Hwy de provincia||
+MPUPTGR012|Seleccionar itens para mostrar:||
+MPUPTGR013|Rios||
+MPUPTGR014|Lagos||
+MPUPTGR015|Aeroportos, parques, etc||
+MPUPTGR016|Intensidade do mapa||
+MPUPTGR017|Internet Map Timeout (sec)||
+MPUPTGR018|Activar Tiger Maps||
+#
+# PopUp "Configure USGS DRG"
+MPUPDRG001|Select items to be displayed:||
+MPUPDRG002|Tint Underlying Map (XOR)||
+MPUPDRG003|Black||
+MPUPDRG004|White||
+MPUPDRG005|Blue||
+MPUPDRG006|Red||
+MPUPDRG007|Brown||
+MPUPDRG008|Green||
+MPUPDRG009|Purple||
+MPUPDRG010|Yellow||
+MPUPDRG011|Light Blue||
+MPUPDRG012|Light Red||
+MPUPDRG013|Light Purple||
+MPUPDRG014|Light Gray||
+MPUPDRG015|Light Brown||
+#
+#
+# Selecao de mapas
+WPUPMCP001|Escolher mapa||
+PULDNMMC01|Limpar|N|
+PULDNMMC02|Vectores|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Direccoes expandidas|||
+PULDNMMC07|Selecionados dirs/mapas:||
+PULDNMMC08|Limpar dirs|C|
+PULDNMMC09|Seleccionar tudo|S|
+#
+# Cores de fundo do mapa
+PULDNMBC01|Cinzento||
+PULDNMBC02|Rosado mistico||
+PULDNMBC03|Azul marinho||
+PULDNMBC04|Azul escuro||
+PULDNMBC05|Med. verde mar||
+PULDNMBC06|Verde palido||
+PULDNMBC07|Dourado palido||
+PULDNMBC08|Dourado amarelado||
+PULDNMBC09|Castanho rosado||
+PULDNMBC10|Vermelho escuro||
+PULDNMBC11|Branco||
+PULDNMBC12|Preto||
+#
+# Mapas de estacoes e estilos das etiquetas
+PULDNMSL01|Fundo negro||
+PULDNMSL02|Fundo cinzento||
+PULDNMSL03|Texto em negro|T|
+#
+# PullDown "Estilo da linha de fora do icon"
+PULDNMIO01|Nao ha limite|N|
+PULDNMIO02|Limite preto|B|
+PULDNMIO03|Limite cinzento|G|
+PULDNMIO04|Limite brando|W|
+#
+# Switches ON/OFF/Curto
+PULDNOT001|On||
+PULDNOT002|Off||
+PULDNOT003|Curto||
+#
+# Menu de mostragem de estacoes
+PULDNDP014|Localizar estacao|L|
+PULDNDP001|Rastrear estacao|R|
+PULDNDP022|Tirar o rasto de Findu|F|
+PULDNDP032|Filtrar dados||
+PULDNDP040|Escolher nada||
+PULDNDP041|Escolher meu||
+PULDNDP042|Escolher TNC||
+PULDNDP027|- Mostrar estacoes direct||
+PULDNDP043|- Escolher via digi||
+PULDNDP034|Mostrar estacoes net||
+PULDNDP019|Mostrar infos expiradas||
+PULDNDP044|Mostrar estacoes||
+PULDNDP028|- Mostrar estacoes fixas||
+PULDNDP029|- Mostrar estacoes moveis||
+PULDNDP030|- Mostrar estacoes de tempo||
+PULDNDP053|  - Seleccionar estacoes CWOP WX||
+PULDNDP045|Mostrar objectos/items||
+PULDNDP026|- Mostrar objectos/items metereologicos||
+PULDNDP039|- Mostrar objectos de medida de agua/Items||
+PULDNDP031|- Mostrar outros objectos/Items||
+PULDNDP033|Filtrar monitor||
+PULDNDP010|Mostrar indicativo|i|
+PULDNDP012|Mostrar simbolos|D|
+PULDNDP011|- Simbolos rodados|S|
+PULDNDP007|Rastos de estacoes|R|
+PULDNDP003|Mostrar curso|c|
+PULDNDP004|Mostrar velocidade|v|
+PULDNDP017|- Mostrar velocidade baixa||
+PULDNDP002|Mostrar altura|a|
+PULDNDP009|Mostrar info do tempo|t|
+PULDNDP046|- Mostrar texto do tempo||
+PULDNDP018|-- Mostrar so a temperatura||
+PULDNDP047|- Mostrar intensidade do vento||
+PULDNDP054|Display Aloha Circle||
+PULDNDP013|Ambiguidade de posicao||
+PULDNDP008|Estacao potencia/ganho|p|
+PULDNDP021|- Activar por defeito pot/ganho||
+PULDNDP020|- Activar movel pot/ganho||
+PULDNDP023|Mostrar circulos DF||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearing||
+PULDNDP035|Activar Dead-Reckoning||
+PULDNDP036|- Activar arco Dead-Reckoning||
+PULDNDP037|- Activar curso Dead-Reckoning||
+PULDNDP038|- Activar simbolo Dead-Reckoning||
+PULDNDP005|Mostrar dist/curso|d|
+PULDNDP024|Mostrar o ultimo reporte horario||
+PULDNDP015|Anular todas as estacoes|A|
+PULDNDP016|Limpar rastos|L|
+PULDNDP025|Limpar historia de objecto/item||
+PULDNDP048|Recarregar objecto/historia de item||
+PULDNDP049|Limpar todos os indicativos tacticos||
+PULDNDP050|Limpar a historia dos indicativos tacticos||
+PULDNDP051|Seleccionar unicamente indicativos tacticos||
+PULDNDP052|- Etiquetas de pontos de pista||
+PULDNDP055|Export all|E|
+PULDNDP056|Export to KML File||
+#
+# Inglesa/metrica
+PULDNUT001|Activar unidades Inglesas||
+PULDNUT002|Metrica||
+#
+# Menu de mensagens
+PULDNMG001|Enviar mensagem a|E|
+PULDNMG002|Abrir mensagens de grupos|g|
+PULDNMG003|Anular todas as mensagens a enviar|A|
+PULDQUS001|Pergunta geral a estacoes|r|
+PULDQUS002|Pergunta a estacoes I-Gate|I|
+PULDQUS003|Pergunta a estacoes WX|W|
+PULDNMG004|Modificar mensagem de resposta automatica|f|
+PULDNMG005|Activar mensagem de resposta automatica|A|
+PULDNMG006|Modo de reconhecimento por satelite|M|
+PULDNMG007|Show Pending Messages|P|
+#
+# Menu de interfaces
+PULDNTNT04|Interface Control||
+PULDNTNT03|Desactivar transmitir: TODOS||
+PULDNTNT05|Desactivar transmitir: A minha posicao||
+PULDNTNT06|Desactivar transmitir: Objectos/Artigos||
+PULDNTNT11|Activar porta de server||
+PULDNTNT01|Transmitir agora..!|T|
+PULDNTNT07|Buscar rastro de GPS|F|
+PULDNTNT08|Buscar rotas de GPS|R|
+PULDNTNT09|Buscar waypoints de GPS|W|
+PULDNTNT10|Buscar pontos da Garmin RINO|G|
+#
+# Menu de ajuda
+PULDNHEL01|Acerca de|A|
+PULDNHEL02|Index de ajuda|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|About Xastir||
+#
+# Menu do rato
+POPUPMA001|Opcoes||
+POPUPMA00c|Centro||
+POPUPMA015|Info da estacao||
+POPUPMA002|Aproximar|A|
+POPUPMA003|Afastar|f|
+POPUPMA004|Nivel de focagem|N|
+POPUPMA005|Nivel 1|1|
+POPUPMA006|Nivel 16|6|
+POPUPMA007|Nivel 64|4|
+POPUPMA008|Nivel 256|2|
+POPUPMA009|Nivel 1024|0|
+POPUPMA010|Nivel 8192|8|
+POPUPMA017|O mundo inteiro|E|
+POPUPMA016|Ultima pos/focagem do mapa|P|
+POPUPMA018|Criar objecto/artigo|C|
+POPUPMA019|Modificar objecto/artigo|M|
+POPUPMA025|Mover aqui a minha estacao|H|
+POPUPMA011|Ir para cima|u|
+POPUPMA012|Ir para baixo|d|
+POPUPMA013|Ir para a esquerda|l|
+POPUPMA014|Ir para a direita|r|
+POPUPMA020|Medida||
+POPUPMA021|Movimento||
+POPUPMA022|Siga-me||
+POPUPMA023|Modificadores encontrados!||
+POPUPMA024|Por favor desligue as teclas CapsLock/NumLock/ScrollLock/outros||
+POPUPMA026|Centro e Zoom||
+POPUPMA027|  Latitude||
+POPUPMA028| Longitude||
+POPUPMA029|Desenhar objectos CAD||
+POPUPMA030|Draw||
+POPUPMA031|Fechar poligono||
+POPUPMA032|Erase CAD Polygons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Level||
+POPUPMA035|10% out||
+POPUPMA036|10% in||
+POPUPMA037|Area||
+POPUPMA038|square||
+POPUPMA039|square feet||
+POPUPMA040|square meters||
+POPUPMA041|Bearing||
+POPUPMA042|degrees||
+POPUPMA043|Modify ambiguous position||
+POPUPMA044|Position abiguity is on, your new position may appear to jump.||
+POPUPMA045|Predefined Objects||
+POPUPMA046|CAD Polygons||
+POPUPMA047|Enable CAD objects||
+POPUPMA048|Enable CAD labels||
+POPUPMA049|Enable CAD comments||
+POPUPMA050|Enable CAD probability||
+POPUPMA051|Enable CAD area size||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|meters||
+POPUPMA055|mi|
+#
+# Menu dos estados das linhas de etiquetas
+BBARZM0001|Foco %s||
+BBARZM0002|Foco %s Tr||
+BBARSTH001|%d/%d estacoes||
+BBARSTA000|%-9s novo objecto!||
+BBARSTA001|%-9s nova estacao!||
+BBARSTA002|%s||
+BBARSTA003|Carregando mapas...||
+BBARSTA004|Mapas carregados...||
+BBARSTA005|Graduacao lat/long esta ON||
+BBARSTA006|Graduacao lat/long esta OFF||
+BBARSTA007|O uso dos auto mapas, esta ON||
+BBARSTA008|O uso dos auto mapas, esta OFF||
+BBARSTA009|Os niveis do mapa estao ON||
+BBARSTA010|Os niveis do mapa estao OFF||
+BBARSTA011|A mensagem de resposta automatica esta OFF!||
+BBARSTA012|Ficheiro criado..||
+BBARSTA013|Abrindo porta GPS||
+BBARSTA014|Fechando porta GPS||
+BBARSTA015|Obtendo a string do GPS RMC||
+BBARSTA016|Obtendo a string do GPS GGA||
+BBARSTA017|Rede desligada do servidor||
+BBARSTA018|Ligacao fechada por excesso de tempo!||
+BBARSTA019|A procurar servidor %s||
+BBARSTA020|Ligado a %s||
+BBARSTA021|Falha na ligacao � rede!||
+BBARSTA022|Pode nao ligar ao socket!||
+BBARSTA023|Nao ha IP para o servidor!||
+BBARSTA024|Nao ha servidor especificado||
+BBARSTA025|Servidor encontrado, a ligar %d||
+BBARSTA026|Esperando por infos do GPS via HSP..||
+BBARSTA027|Limpando as infos de HSP obtidos do TNC..||
+BBARSTA028|Carregando %s||
+BBARSTA029|Abrindo porta WX||
+BBARSTA030|A fechar porta WX||
+BBARSTA031|A procura o servidor %d||
+BBARSTA032|Infos de WX descodificados||
+BBARSTA033|Eco desde o digipeater||
+BBARSTA034|Carregando mapas de alerta WX||
+BBARSTA035|Esperando por dados do GPS via AUX..||
+BBARSTA036|Limpando AUX para obter dados do TNC..||
+BBARSTA037|Dados do GPS completos||
+BBARSTA038|Posicao alterada na minha estacao||
+BBARSTA039|Indexando %s||
+BBARSTA040|Estacao de radioamador de APRS(tm) %s||
+BBARSTA041|Esperando pela data do GPS..||
+BBARSTA042|Transmitindo objectos/items||
+BBARSTA043|Registando||
+BBARSTA044|ALOHA distance is %d%s||
+BBARSTA045|Loading symbols...||
+BBARSTA046|Reloading symbols...||
+BBARSTA047|Initialize my station...||
+BBARSTA048|Start interfaces...||
+BBARSTA049|Reading tiles...||
+BBARSTA050|Downloading tiles...||
+BBARSTA051|Downloading tile %li of %li||
+#
+# Visualiza��o do trafego de packet
+WPUPDPD001|Visualizacao do trafego||
+WPUPDPD002|So dados do TNC||
+WPUPDPD003|So dados da rede||
+WPUPDPD004|Dados do TNC e da rede||
+WPUPDPD005|TNC||
+WPUPDPD006|REDE||
+WPUPDPD007|Station Capabilities||
+WPUPDPD008|Mine Only||
+#
+# Localizar estacao
+WPUPLSP001|Localizar estacao||
+WPUPLSP002|Localizar indicativo||
+WPUPLSP003|Maiscula/minuscula|M|
+WPUPLSP004|Exacta|E|
+WPUPLSP005|Localizar agora!|A|
+WPUPLSP006|Localizar emergencia!||
+WPUPLSP007|FCC/RAC Lookup||
+#
+# Configurar predefinidos
+WPUPCFD001|Configurar valores pre-definidos||
+WPUPCFD002|desde que intervalo de tempo sera considerada uma estacao antiga?||
+WPUPCFD003|15 minutos|1|
+WPUPCFD004|30 minutos|3|
+WPUPCFD005|45 minutos|4|
+WPUPCFD006|1 hora|H|
+WPUPCFD007|90 minutos|9|
+WPUPCFD008|2 horas|2|
+WPUPCFD009|desde que intervalo de tempo a estacao nao sera mostrada?||
+WPUPCFD010|6 horas|6|
+WPUPCFD011|12 horas|o|
+WPUPCFD012|1 Dia|D|
+WPUPCFD013|2 Dias|s|
+WPUPCFD014|1 semana|n|
+WPUPCFD015|Opcao modo de transmissao da estacao||
+WPUPCFD016|Estacao fixa|F|
+WPUPCFD017|Estacao movel c/hora local|l|
+WPUPCFD018|Estacao movel c/data-hora zulu|z|
+WPUPCFD019|Estacao movel c/horas-segundos zulu|u|
+WPUPCFD021|Posicao da estacao c/tempo|t|
+WPUPCFD022|Posicao da estacao, data-hora zulu e tempo|d|
+WPUPCFD023|Transmitir infos WX em Raw?||
+WPUPCFD024|Comprimir objecto/item durante a transmissao?||
+WPUPCFD025|Activar rede alternativa?|A|
+WPUPCFD026|Enviar reportes de posicao em que intervalos?||
+WPUPCFD027|Pop up de novos boletins||
+WPUPCFD028|Avisar se teclas foram modificadas||
+WPUPCFD029|Ver boletins de distancia zero||
+WPUPCFD030|Desactivar dupe-checks de  posit||
+WPUPCFD031|Load predefined objects from file||
+WPUPCFD032|My trails in one color||
+WPUPCFD033|ALTNET:||
+#
+# PopUp "Configurar - momento certo"
+WPUPCFTM01|Configurar momento certo|||
+WPUPCFTM02|Intervalo Posit TX (min)||
+WPUPCFTM03|Tempo de estacao fantasma (min)||
+WPUPCFTM04|Max Intervalo TX objecto/item (min)||
+WPUPCFTM05|Tempo para limpar estacao (horas)||
+WPUPCFTM06|Intervalo para verificar GPS (seg)||
+WPUPCFTM07|Tempo para apagar estacao (dias)||
+WPUPCFTM08|Tempo limite para dead-reckoning (min)||
+WPUPCFTM09|Serie de atraso de inter-char (ms)||
+WPUPCFTM10|Novo tempo de pista (min)||
+WPUPCFTM11|Novo intervado de pista (degrees)||
+WPUPCFTM12|RINO -> Intervalo de objectos (min), 0 = Desactivado||
+WPUPCFTM13|Snapshot Interval (min)||
+#
+# PopUp "Sistema de configuracao de coordenadas"
+WPUPCFC001|Sistema de configuracao de coordenadas||
+WPUPCFC002|Sistema de selecao de coordenadas||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM com zonas especiais||
+#
+# Configurar GPS
+WPUPCFG001|Configurar GPS||
+WPUPCFG003|Porta exclusiva de GPS||
+WPUPCFG002|Usar posicao GPS?||
+WPUPCFG004|opcoes do GPS||
+WPUPCFG005|GPS exclusivo||
+WPUPCFG006|TNC ligado a GPS (cabo HSP)||
+WPUPCFG007|TNC ligado a GPS usando CTL-E||
+WPUPCFG008|GPS tempo (a mostrar cada)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 minuto||
+WPUPCFG013|2 minutos||
+WPUPCFG014|5 minutos||
+WPUPCFG015|10 minutos||
+WPUPCFG016|Rede ligada ao GPS||
+WPUPCFG017|Servidor GPSD||
+WPUPCFG018|Porta GPSD||
+WPUPCFG019|Rede GPS via GPSD||
+WPUPCFG020|Voltar a ligar quando falhar?||
+WPUPCFG021|Rede ligada a WX||
+WPUPCFG022|Servidor WX||
+WPUPCFG023|Porta WX||
+#
+# Configurar TNC (bauds tambem sao para WX)
+WPUPCFT001|Configurar TNC||
+WPUPCFT002|Usar TNC?||
+WPUPCFT003|Porta TNC||
+WPUPCFT004|Velocidade da porta||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|Rota do UnProto||
+WPUPCFT012|Rota 1: %s via ||
+WPUPCFT013|Rota 2: %s via ||
+WPUPCFT014|Rota 3: %s via ||
+WPUPCFT015|Modo da porta||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Configurar o TNC c/HSP GPS||
+WPUPCFT024|Tipo de data||
+WPUPCFT025|Auto deteccao||
+WPUPCFT026|Tipo Binario||
+WPUPCFT027|Tipo ASCII||
+WPUPCFT028|Configurar TNC com GPS AUX||
+WPUPCFT029|Configurar TNC com ENUM INVALIDO||
+WPUPCFT030|Configurar o TNC em KISS||
+WPUPCFT031|Ficheiros de configuracao do TNC||
+WPUPCFT032|Nome do ficheiro de definicoes do TNC||
+WPUPCFT033|Nome do ficheiro de fecho do TNC||
+WPUPCFT034|Parametros do KISS||
+WPUPCFT035|TXDelay (10 unidades de ms)||
+WPUPCFT036|Persistencia (0 a 255)||
+WPUPCFT037|SlotTime (10 unidades de ms)||
+WPUPCFT038|TxTail (10 unidades de ms)||
+WPUPCFT039|Duplex completo (Full Duplex)||
+WPUPCFT040|Configurar o TNC em Multi-Port KISS||
+WPUPCFT041|Porta radio||
+WPUPCFT042|Dubious UNPROTO Path!||
+WPUPCFT043|Please consider a shorter path such as WIDE2-2 or WIDE1-1,WIDE2-2||
+WPUPCFT044|Dubious IGATE Path!||
+WPUPCFT045|Transmitting w/Dubious UNPROTO Path!||
+WPUPCFT046|Transmitting w/Dubious IGATE Path!||
+WPUPCFT047|Init KISS-mode on startup||
+#
+# Configurar a porta da estacao meteorologica
+WPUPCFWX01|Configurar a porta da estacao meteorologica||
+WPUPCFWX02|Dispositivo da estacao meteorologica||
+WPUPCFWX03|Correccao da medida de chuva (Definicoes globais)||
+WPUPCFWX04|.1 polegadas/2.5mm||
+WPUPCFWX05|.01 polegadas/.25mm||
+WPUPCFWX06|.1mm||
+WPUPCFWX07|Nao corrigido||
+#
+# Configurar a estacao
+WPUPCFS001|Configurar a estacao||
+WPUPCFS002|Indicativo||
+WPUPCFS003|Latitude||
+WPUPCFS004|grd||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|Longitude||
+WPUPCFS008|(E/W)||
+WPUPCFS009|Simbolo da estacao||
+WPUPCFS010|Grupo/sobreposto||
+WPUPCFS011|Simbolo||
+WPUPCFS028|Seleccione||
+WPUPCFS012|Potencia - Altura (HAAT) - Ganho e direccao||
+WPUPCFS013|Desactive PHG||
+WPUPCFS014|Altura da antena||
+WPUPCFS015|Ganho da antena||
+WPUPCFS016|Omni||
+WPUPCFS017|Comentarios:||
+WPUPCFS018|Posicao ambigua||
+WPUPCFS019|Nenhuma||
+WPUPCFS020|.11 milha||
+WPUPCFS021|1.15 milhas||
+WPUPCFS022|11.51 milhas||
+WPUPCFS023|69.09 milhas||
+WPUPCFS024|.18 quilometro||
+WPUPCFS025|1.85 quilometros||
+WPUPCFS026|18.53 quilometros||
+WPUPCFS027|111.19 quilometros||
+WPUPCFS029|Enviar posits comprimidas|C|
+#
+# Dialogo de Objeto/Artigo
+POPUPOB001|Objecto/artigo||
+POPUPOB002|Nome:||
+POPUPOB003|Criar novo objecto||
+POPUPOB004|Apagar objeto||
+POPUPOB005|Modificar objecto||
+POPUPOB006|Criar novo artigo||
+POPUPOB007|Area do objeto||
+POPUPOB008|Activar area do objecto||
+POPUPOB009|Cor luminosa||
+POPUPOB010|Area colorida||
+POPUPOB011|Circulo||
+POPUPOB012|Linha-direita '/'||
+POPUPOB013|Linha-esquerda '\'||
+POPUPOB014|Triangulo||
+POPUPOB015|Rectangulo||
+POPUPOB016|Negro||
+POPUPOB017|Azul||
+POPUPOB018|Verde||
+POPUPOB019|Cinzento||
+POPUPOB020|Vermelho||
+POPUPOB021|Violeta||
+POPUPOB022|Amarelo||
+POPUPOB023|Cinzento||
+POPUPOB024|Compensar em cima:||
+POPUPOB025|Compensar a esq.(Excepto '/'):||
+POPUPOB026|Corredor:||
+POPUPOB027|Opcoes gerais||
+POPUPOB028|Situacao||
+POPUPOB029|Activar letreiro||
+POPUPOB030|Data:||
+POPUPOB031|Letreiro objecto||
+POPUPOB032|Activar compressao||
+POPUPOB033|Apagar artigo||
+POPUPOB034|Modificar artigo||
+POPUPOB035|Altitude (Pes):||
+POPUPOB036|Velocidade (nos):||
+POPUPOB037|Curso:||
+POPUPOB038|DF objecto||
+POPUPOB039|Sinal - Altura(HAAT) - Ganho - Direccao||
+POPUPOB040|Dirigindo - Amplitude da direccao||
+POPUPOB041|Antena omni-direcional||
+POPUPOB042|Antena direcional||
+POPUPOB043|Inutil||
+POPUPOB044|Adoptar objecto||
+POPUPOB045|Adoptar item||
+POPUPOB046|DF Bearing:||
+POPUPOB047|Probability Circles||
+POPUPOB048|Map View Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+# Configurar Internet
+WPUPCFI001|Configurar internet||
+WPUPCFI002|Servidor||
+WPUPCFI003|Porta||
+WPUPCFI004|(Servidores secundarios)||
+WPUPCFI005|Servidor1||
+WPUPCFI006|Porta1||
+WPUPCFI007|Servidor2||
+WPUPCFI008|Porta2||
+WPUPCFI009|Senha||
+WPUPCFI010|(Deixar em branco se nao houver nada)||
+WPUPCFI011|Voltar a ligar em caso de falha de rede?||
+WPUPCFI012|Correr como num I-Gate?||
+WPUPCFI013|Difundir mensagens via TNC quando houver um I-Gate?||
+WPUPCFI014|Registo de transacoes do I-Gate?|||
+WPUPCFI015|Parametros filtrados||
+#
+# Configurar Database
+WPUPCFID01|Configurar Database (TBD)||
+WPUPCFID02|Servidor||
+WPUPCFID03|Porta||
+WPUPCFID04|(Servidores secundarios)||
+WPUPCFID05|Servidor1||
+WPUPCFID06|Porta1||
+WPUPCFID07|Servidor2||
+WPUPCFID08|Porta2||
+WPUPCFID09|Senha||
+WPUPCFID10|(Deixar em branco se nao houver nada)||
+WPUPCFID11|Voltar a ligar em caso de falha de rede?||
+WPUPCFID12|Correr como num I-Gate?||
+WPUPCFID13|Difundir mensagens via TNC quando houver um I-Gate?||
+WPUPCFID14|Log de transacoes do I-Gate?|||
+WPUPCFID15|Parametros filtrados||
+#
+# PopUp "Configurar AGWPE"
+WPUPCFIA01|Configurar AGWPE||
+WPUPCFIA02|Host ||
+WPUPCFIA03|Porta ||
+WPUPCFIA04|(Hosts secundarios)||
+WPUPCFIA05|Host1||
+WPUPCFIA06|Porta1||
+WPUPCFIA07|Host2||
+WPUPCFIA08|Porta2||
+WPUPCFIA09|Codigo de passagem||
+WPUPCFIA10|(Deixar em branco se nao ha nada)||
+WPUPCFIA11|Voltar a ligar se houver uma falha da NET?||
+WPUPCFIA12|Funcionar como uma I-Gate?||
+WPUPCFIA13|Divulgar mensagens via TNC quando estiver na I-Gate?||
+WPUPCFIA14|Registo das transacoes I-Gate?||
+WPUPCFIA15|Transmitir RadioPort||
+#
+# Configurar Alarmas de Audio
+WPUPCFA001|Configurar alarme de audio||
+WPUPCFA002|Aplicacao audio||
+WPUPCFA003|Alarme ON||
+WPUPCFA004|Ficheiros de audio||
+WPUPCFA005|Nova estacao||
+WPUPCFA006|Nova mensagem||
+WPUPCFA007|Proximidade||
+WPUPCFA008|Banda aberta||
+WPUPCFA009|Minima distancia||
+WPUPCFA010|Maxima distancia||
+WPUPCFA011|Alerta de tempo||
+#
+# Configurar o festival, o sintetizador de voz
+WPUPCFSP01|Configurar o festival como sintetizador de voz||
+WPUPCFSP02|Fixar em 'ON' as opcoes do sintetizador de voz||
+WPUPCFSP03|<- Anuncia nova estacao||
+WPUPCFSP04|<- Anuncia alerta de nova mensagem||
+WPUPCFSP05|<- Anuncia corpo de nova mensagem||
+WPUPCFSP06|<- Anuncia a proximidade de estacoes||
+WPUPCFSP07|<- Anuncia DX condi��o de banda aberta||
+WPUPCFSP08|<- Anuncia alerta sobre condicoes do tempo||
+WPUPCFSP09|Alerta de proximidade da estacao rastreada||
+#
+# Rastreo da estacao
+WPUPTSP001|Rastrear estacao||
+WPUPTSP002|Rastrear indicativo||
+WPUPTSP003|Maiscula/minuscula||
+WPUPTSP004|Exacto||
+WPUPTSP005|Rastrear agora!||
+WPUPTSP006|Limpar rastro||
+WPUPTSP007|Receber caminho||
+WPUPTSP008|Indicativo||
+WPUPTSP009|Comecar rasto (horas atras)||
+WPUPTSP010|Tamanho do rasto (horas)||
+#
+# Menu de mensagens
+WPUPMSB001|Enviar mensagem %d||
+WPUPMSB002|Enviar mensagem ao grupo %d||
+WPUPMSB003|Indicativo de estacao:||
+WPUPMSB004|Indicativos de grupos:||
+WPUPMSB005|Novo/Refresh indicativo||
+WPUPMSB006|Novo grupo||
+WPUPMSB007|Limpar hist�ria da mensagem||
+WPUPMSB008|Mensagem:||
+WPUPMSB009|Enviar agora!||
+WPUPMSB010|Encaminhamento:||
+WPUPMSB011|Cancelar mensagens pendentes||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Broadcast||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Path||
+WPUPMSB020|Use Default Path(s)||
+WPUPMSB021|Direct (No path)||
+WPUPMSB022|Reverse Path (Hint):||
+#
+# Auto resposta
+WPUPARM001|Mudar resposta automatica||
+WPUPARM002|Reenviar:||
+#
+# Auuda / Indice
+WPUPHPI001|Indice de ajuda|I|
+WPUPHPI002|Visualizar|V|
+#
+# Informacao da estacao
+WPUPSTI000|Objecto criado desde: %s||
+WPUPSTI001|Info estacao||
+WPUPSTI002|Enviar mensagem||
+WPUPSTI003|Procurar infos FCC||
+WPUPSTI004|Procurar infos RAC||
+WPUPSTI005|%d: pacotes recebidos, ultimo recebido na data: ||
+WPUPSTI006|Ouvido via TNC no dispositivo: %d, ||
+WPUPSTI007|Ouvido ||
+WPUPSTI008|Ultima vez via local||
+WPUPSTI009|U�ltima vez via TNC no dispositivo: %d||
+WPUPSTI010|Ultima vez via internet no dispositivo: %d||
+WPUPSTI011|Ultima vez via ficheiro||
+WPUPSTI012|Ultima vez via desconhecida||
+WPUPSTI013|, e mudou de posicao||
+WPUPSTI014|Actual potencia/ganho:||
+WPUPSTI016|Altitude: %.1f%s ||
+WPUPSTI017|Curso: %s� ||
+WPUPSTI018|Velocidade: %.1f km/h||
+WPUPSTI019|Velocidade: %.1f mph||
+WPUPSTI020|%0.1f milhas||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distancia desde a minha estaca�o %s, curso desde a minha estacao %s||
+WPUPSTI023|Ultima posicao: ||
+WPUPSTI024|Dados da estacao meteorologica %c:%s||
+WPUPSTI025|Curso do vento: %s�  Velocidade: %03d km/h||
+WPUPSTI026|Curso do vento: %s�  Velocidade: %s mph||
+WPUPSTI027| Rajada: %03d Km/h||
+WPUPSTI028| Rajada: %s mph||
+WPUPSTI029|Temperatura: %02.1f�C   ||
+WPUPSTI030|Temperatura: %s�F   ||
+WPUPSTI031|Humidade: %s%%   ||
+WPUPSTI032|Indice da humidade: %02.1f�C  ||
+WPUPSTI033|Pressao barometrica: %s mb||
+WPUPSTI034|Neve: %0.1f (cm/24h)||
+WPUPSTI035|Neve: %0.0f (plg/24h)||
+WPUPSTI036|Chuva: ||
+WPUPSTI037|%0.2f (mm/h)  ||
+WPUPSTI038|%0.2f (plg/h)  ||
+WPUPSTI039|%0.2f (mm/dia)  ||
+WPUPSTI040|%0.2f (plg/dia)  ||
+WPUPSTI041|%0.2f (mm/desde a meia noite)||
+WPUPSTI042|%0.2f (mm/desde a meia noite)||
+WPUPSTI043|Rota de dados: %s||
+WPUPSTI044|Comentarios %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Limpar rastro||
+WPUPSTI046|Total de chuva: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (plg)||
+WPUPSTI049|Perguntar rastro||
+WPUPSTI050|Perguntar por mensagens nao-confirmadas||
+WPUPSTI051|Pergunta directa a estacao||
+WPUPSTI052|Pergunta versao a estacao||
+WPUPSTI053|Modificar objeto/artigo||
+WPUPSTI054|Armazenar rastro||
+WPUPSTI055|Repetido desde:||
+WPUPSTI056|Activar actualizacao automatica||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|DF dirigido: %s||
+WPUPSTI059|Estados %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Temp do combustivel: %02.1f�C  ||
+WPUPSTI061|Temp do combustivel: %s�F   ||
+WPUPSTI062|Mistura do combustevel: %s%%   ||
+WPUPSTI063|Baro: %0.2f em Hg||
+WPUPSTI064|Procurar alerta de NWS||
+WPUPSTI065|Indicativo tactico: %s||
+WPUPSTI066|Assign Tactical Call||
+WPUPSTI067|Current Range: %d miles||
+WPUPSTI068|none||
+WPUPSTI069|default||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|range||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Range||
+WPUPSTI076|No signal detected||
+WPUPSTI077|Detectible signal (Maybe)||
+WPUPSTI078|Detectible signal but not copyable)||
+WPUPSTI079|Weak signal, marginally readable||
+WPUPSTI080|Noisy but copyable signal||
+WPUPSTI081|Some noise, easy to copy signal||
+WPUPSTI082|Good signal w/detectible noise||
+WPUPSTI083|Near full-quieting signal||
+WPUPSTI084|Full-quieting signal||
+WPUPSTI085|Extremely strong & full-quieting signal||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF Beamwidth||
+WPUPSTI089|DF Length||
+WPUPSTI090|Not Valid||
+WPUPSTI091|Change Trail Color||
+WPUPSTI092|Clear DF Bearing||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|ALOHA radius: %d %s||
+WPUPALO002|Stations inside ALOHA circle: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiles (in motion): %d||
+WPUPALO005| Mobiles (other):     %d||
+WPUPALO006| WX stations:         %d||
+WPUPALO007| Home stations:       %d||
+WPUPALO008|Last calculated %d %s %d %s ago.||
+WPUPALO666|ALOHA radius not calculated yet||
+#
+# FCC-RAC procurar indicativo
+STIFCC0001|Procurar FCC banco de datos||
+STIFCC0002|Procurar RAC banco de datos||
+STIFCC0003|Nome:||
+STIFCC0004|Rua/Av�:||
+STIFCC0005|Cidade:||
+STIFCC0006|Estado:||
+STIFCC0007|Codigo postal:||
+STIFCC0008|Basica ||
+STIFCC0009|Avancada ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+#
+# FCC-RAC procurar indicativo
+STIFCC0100|FCC index old, rebuilding||
+STIFCC0101|Callsign Search||
+STIFCC0102|Callsign Not Found!||
+STIFCC0103|RAC index old, rebuilding||
+#
+#
+# Mensagem de banda aberta
+UMBNDO0001|a cerca de||
+#
+# Opcoes universais
+UNIOP00001|Aceitar||
+UNIOP00002|Cancelar||
+UNIOP00003|Fechar||
+UNIOP00004|milhas||
+UNIOP00005|km||
+UNIOP00006|Dispositivo||
+UNIOP00007|Acrescentar||
+UNIOP00008|Anular||
+UNIOP00009|Propriedades||
+UNIOP00010|Permitir transmissao?||
+UNIOP00011|Activar no inicio?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|C||
+UNIOP00015|F||
+UNIOP00016|mm||
+UNIOP00017|plg||
+UNIOP00018|mm/dia||
+UNIOP00019|plg/dia||
+UNIOP00020|mm/hora||
+UNIOP00021|plg/hora||
+UNIOP00022|mm/med||
+UNIOP00023|plg/med||
+UNIOP00024|grd||
+UNIOP00025|mb||
+UNIOP00026|%||
+UNIOP00027|inHg||
+UNIOP00028|mm Hg||
+UNIOP00029|Definir o relogio do sistema desde o GPS?||
+UNIOP00030|Digipeater?||
+UNIOP00031|m||
+UNIOP00032|Aplicar|||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|day||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# Seleccionar estacao
+STCHO00001|Seleccionar estacao||
+#
+# Desligar alarme de WX
+WPUPWXA001|Alerta do tempo||
+WPUPWXA002|Lista de alerta do tempo||
+#
+# Configurar interfaces
+WPUPCIF001|Interfaces instalados||
+WPUPCIF002|Escolher tipo de interface||
+#
+# Configurar AX.25 TNC
+WPUPCAX001|Configurar AX.25 TNC||
+WPUPCAX002|AX.25 nome da porta||
+#
+# Nomes dos dispositivos do interface
+IFDNL00000|Nada||
+IFDNL00001|TNC via a porta serie||
+IFDNL00002|Serial TNC c/GPS mais (cabo HSP)||
+IFDNL00003|GPS via porta serie||
+IFDNL00004|Est. meteorologica via porta serie||
+IFDNL00005|Ligacao a um servidor na internet||
+IFDNL00006|AX.25 TNC||
+IFDNL00007|GPS ligado via o servidor gpsd||
+IFDNL00008|Est. meteorologica ligada a uma REDE||
+IFDNL00009|TNC com GPS na porta AUX||
+IFDNL00010|KISS TNC da porta serie||
+IFDNL00011|Base de dados de rede (Nao implementado ainda)||
+IFDNL00012|AGWPE em rede||
+IFDNL00013|Multi-Port KISS TNC da porta serie||
+IFDNL00014|SQL Database (Experimental)||
+#
+# Info dispositivo interface
+IFDIN00000|%s %2d %s sobre serie %s   %s||
+IFDIN00001|%s %2d %s ligado a %s:%d   %s||
+IFDIN00002|%s %2d %s usando dispositivo nomeado %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006| desligado  ||
+IFDIN00007|  ligado    ||
+IFDIN00008|   ERRO     ||
+IFDIN00009|DESCONHECIDO||
+#
+# Controle da interface
+IFPUPCT000|Controle do interface||
+IFPUPCT001|Iniciar||
+IFPUPCT002|Parar||
+IFPUPCT003|Iniciar todos||
+IFPUPCT004|Parar todos||
+#
+# Control de I-Gate
+IGPUPCF000|Opcoes I-Gate||
+IGPUPCF001|Desactiva todo o trafego da IGate||
+IGPUPCF002|So permite trafego de RF para Inet||
+IGPUPCF003|Permite trafego de RF->Inet e Inet->RF||
+IGPUPCF004|Caminho Igate -> RF   ||
+#
+# Esta��o meteorologica
+WXPUPSI000|Estacao meteorologica||
+WXPUPSI001|Tipo de estacao meteorologica||
+WXPUPSI002|Datos actuais||
+WXPUPSI003|Curso do vento||
+WXPUPSI004|Velocidade do vento||
+WXPUPSI005|Rajada do vento||
+WXPUPSI006|Temperatura||
+WXPUPSI007|Total de chuva||
+WXPUPSI008|Total de chuva hoje||
+WXPUPSI009|Pressao barometrica||
+WXPUPSI010|Humidade relativa||
+WXPUPSI011|Peet Bros ULTIMETER 2000 Tipo (Modo dados log)||
+WXPUPSI012|Peet Bros ULTIMETER II Tipo||
+WXPUPSI013|Peet Bros ULTIMETER 2000 Tipo (Modo paquete)||
+WXPUPSI014|Horas totais de chuva||
+WXPUPSI015|Ultimas 24 tot. de chuvas||
+WXPUPSI016|Qualimetricos Q-Net||
+WXPUPSI017|Tipo Peet Bros ULTIMETER 2000 (Modo Completo)||
+WXPUPSI018|Ponto de Rocio||
+WXPUPSI019|Vento alto||
+WXPUPSI020|Vento frio||
+WXPUPSI021|Indice calorifico||
+WXPUPSI022|3-Hr Baro||
+WXPUPSI023|Alta temperat.||
+WXPUPSI024|Baixa temperat.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Listas das estacoes
+LHPUPNI000|Todas as estacoes||
+LHPUPNI001|Estacoes moveis||
+LHPUPNI002|Estacaos meteorologicas||
+LHPUPNI003|Estacoes locais (via TNC)||
+LHPUPNI004|Ultimas estacoes||
+LHPUPNI005|Objectos e items||
+LHPUPNI006|Objectos e items proprios||
+LHPUPNI010| #||
+LHPUPNI011|Indicativo||
+LHPUPNI012|#Pack||
+LHPUPNI013|Ult. posicao||
+LHPUPNI014|Rota||
+LHPUPNI015|PHG||
+LHPUPNI016|Comentarios||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Lat||
+LHPUPNI104|Long||
+LHPUPNI105|#Pack||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Lat/Lon ou UTM||
+#
+# Tracar alertas WX sobre mapas
+PULDNMAT01|Mostra mapa de alarmes sobre outros mapas||
+PULDNMAT02|Mostra mapa de alarmes debaixo de outros mapas||
+#
+# Error/popup mensagens
+POPEM00001|Localiza erro!||
+POPEM00002|A estacao %s nao foi encontrada!||
+POPEM00003|Rastrear erro!||
+POPEM00004|Erro do interface!||
+POPEM00005|Nome invalido da porta AX.25 %s||
+POPEM00006|Nome invalido da porta AX.25 %s||
+POPEM00007|Indicativo invalido %s||
+POPEM00008|Indicativo invalido AX.25 destinado ao digipeater||
+POPEM00009|Nao posso abrir o interface AX.25, %s||
+POPEM00010|Nao posso ligar o interface AX.25, %s||
+POPEM00011|Nao posso ligar ao indicativo AX.25, %s||
+POPEM00012|AX.25 erro na saida de UI||
+POPEM00013|AX.25 problema com o ficheiro /etc/ax25/axports||
+POPEM00014|AX.25 nome invalido da porta %s||
+POPEM00015|Erro abrindo o interface %d, falha grave||
+POPEM00016|Erro abrindo o interface %d tempo esgotado||
+POPEM00017|Nao ha mais interfaces disponiveis!||
+POPEM00018|Dado requerido - Simples linha de mensagem|
+POPEM00019|A porta de transmissao esta "off" para a porta %d|
+POPEM00020|Erro no banco de dados!|
+POPEM00021|AX.25 nao foi compilado no Xastir!||
+POPEM00022|Erro de entrada!|
+POPEM00023|Nome de localizacao nao especificada!|
+POPEM00024|Nome de localizacao especificada em uso!|
+POPEM00025|Nao encontrado!||
+POPEM00026|O rastreamento come�ara quando ele aparecer||
+POPEM00027|Info impropia. Alguns campos vazios?||
+POPEM00028|Nao se pode abrir o ficheiro||
+POPEM00029|Encontrado!||
+POPEM00030|Simbolo da estacao meteorologica||
+POPEM00031|Alterado para simbolo de WX '/_', outras opcoes:  '\_'  '/W'  e  '\W'||
+POPEM00032|Atencao: usando simbolos do servico nacional meteorologico!||
+POPEM00033|Nao ha dados GPS!||
+POPEM00034|Desactivando a TX da minha posicao ate ter dados validos do GPS!||
+POPEM00035|Atencao||
+POPEM00036|Aviso||
+POPEM00037|Interface HSP presente: tempo de GPS foi aumentado||
+POPEM00038|Name Conflicts With Existing Object/Item/Station||
+POPEM00039|Illegal characters found, substituting periods in their place||
+POPEM00040|Custom outgoing path was lost||
+POPEM00041|Processing another file.  Wait a bit, then try again||
+POPEM00042|Object not owned by me! Try adopting the object first.||
+POPEM00043|Not an Object/Item!||
+POPEM00044|Fetch Findu Trail: Failed||
+POPEM00045|Fetch Findu Trail: Complete||
+POPEM00046|Berkeley DB header/shared library do NOT match! Disabling map cache.||
+POPEM00047|Global transmit is DISABLED. Emergency beacons are NOT going out!||
+POPEM00048|Emergency Beacon Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmitting every 60 seconds!||
+POPEM00050|Interfaces or posits/transmits DISABLED.  Emergency beacons are NOT going out!||
+POPEM00051|Altnet is enabled (Configure->Defaults dialog)||
+POPEM00052|Callsign is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We're trying to talk to ourselves!||
+#
+# Salto de localizacao
+JMLPO00001|Localizacao de mapa||
+JMLPO00002|IR!||
+JMLPO00003|Nome da nova localizacao:||
+#
+# Boletins
+BULMW00001|Boletins||
+BULMW00002|Limite de alcance a (0, nao ha limite)||
+BULMW00003|Mudanca de alcance||
+#
+# Trafego de todas as mensagens
+AMTMW00001|Trafego de todas as mensagens||
+AMTMW00002|Limite de alcance a (0, nao ha limite)||
+#
+# Cadeias do sintetizador
+SPCHSTR001|Quilometros||
+SPCHSTR002|metros||
+SPCHSTR003|milhas||
+SPCHSTR004|jardas||
+SPCHSTR005|%s, distancia e %d %s.||
+SPCHSTR006|%s, distancia e %.1f %s.||
+SPCHSTR007|%s, distancia e %d %s %s %s.||
+SPCHSTR008|%s, distancia e %.1f %s %s %s.||
+SPCHSTR009|Novo alerta de tempo||
+SPCHSTR010|Indicativo novo||
+SPCHSTR011|Ouvido, D X, %s, na distancia de %.1f %s||
+#
+SPCHDIRN00|norte of||
+SPCHDIRS00|sul of||
+SPCHDIRE00|este of||
+SPCHDIRW00|oeste of||
+SPCHDIRNE0|nordeste of||
+SPCHDIRNW0|nordoeste of||
+SPCHDIRSE0|sudeste of||
+SPCHDIRSW0|sudoeste of||
+#
+# Dialogo da sele��o do simbolo
+SYMSEL0001|Selecionar simbolo||
+SYMSEL0002|Tabela de simbolo primario||
+SYMSEL0003|Tabela de simbolo secundario||
+#
+# Dialogo das propriedades da impressora
+PRINT0001|Propriedades da impressora||
+PRINT0002|Largura do papel||
+PRINT0003|Auto-rodar imagem
+PRINT0004|Rodar imagem 90� CCW||
+PRINT0005|Auto-balancear imagem||
+PRINT0006|Balanca:||
+PRINT0007|Forcar a pre-definida cor de fundo a branco||
+PRINT0008|Imprimir em branco e preto||
+PRINT0016|Cores invertidas||
+PRINT0009|Resolucao do postscript:||
+PRINT0010|Prevista||
+PRINT0011|Imprimir o ficheiro||
+PRINT0012|Guardar imagem num ficheiro...||
+PRINT0013|Convertendo para postscript...||
+PRINT0014|Criando arquivo de impressao finalizado||
+PRINT0015|Estado da impressora||
+#
+# Dialogo das propriedades da impressora
+PRINT1001|Direct to:||
+PRINT1002|Via Previewer:||
+#
+# Dialogo de localizar forma
+FEATURE001|Nome:||
+FEATURE002|Estado/provincia:||
+FEATURE003|Pas:||
+FEATURE004|Mapa quad:||
+FEATURE005|Tipo:||
+FEATURE006|GNIS arquivo:||
+FEATURE007|Address:||
+FEATURE008|City:||
+FEATURE009|Mark Destination||
+FEATURE010|Zip Code:||
+FEATURE011|Geocoding File||
+#
+# Dialogo do calculo de coordenadas
+COORD001|Calcular coordenadas||
+COORD002|Calc||
+COORD003|Calcular||
+COORD004|Limpar||
+COORD005|UTM||
+COORD006|Latitude ou||
+COORD007|Longitude ou||
+COORD008|Zona||
+COORD009|UTM indo para este||
+COORD010|UTM indo para norte||
+COORD011|               Decimal Degrees:  ||
+COORD012|       Degrees/Decimal Minutes:  ||
+COORD013|  Degrees/Minutes/Dec. Seconds:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|Military Grid Reference System:  ||
+COORD016|       Maidenhead Grid Locator:  ||
+COORD017| **       Sorry, your input was not recognized!        **||
+COORD018| **   Please use one of the following input formats:   **||
+#
+#
+# Dialogo do smart beaconing
+SMARTB001|Beaconing esperto||
+SMARTB002|Racio alto (secs):||
+SMARTB003|Velocidade alta (mph):||
+SMARTB004|Velocidade alta (kph):||
+SMARTB005|Racio baixo (mins):||
+SMARTB006|Velocidade baixa (mph):||
+SMARTB007|Velocidade baixa (kph):||
+SMARTB008|Voltar ao minimo (deg):||
+SMARTB009|Virar encosta:||
+SMARTB010|Tempo de espera (secs):||
+SMARTB011|Activar SmartBeaconing(tm)||
+#
+#
+#
+# Dialogo do gamma adjust
+GAMMA001|Correccao do ajuste gamma||
+GAMMA002|Correccao gamma||
+#
+#
+# Dialogo das fontes de etiquetas dos mapas
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Muito pequeno Font||
+MAPFONT004|Map Font Pequeno||
+MAPFONT005|Map Font Medio||
+MAPFONT006|Map Font Grande||
+MAPFONT007|Map Font Enorme||
+MAPFONT008|Map Font Border||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV ID Font||
+#
+# Distancia/rumo na linha de estados
+PULDNDB001|Estado dist/rumo||
+#
+#
+# Operacoes transferencias de GPS
+GPS001|Transferir GPS||
+GPS002|Ficheiro||
+GPS003|Escolher cor||
+GPS004|Vermelho||
+GPS005|Verde||
+GPS006|Preto||
+GPS007|Branco||
+GPS008|Laranja||
+GPS009|Azul||
+GPS010|Amarelo||
+GPS011|Violeta||
+#
+#
+# Dialogo de propriedades dos mapas
+MAPP001|Propriedades dos mapas||
+MAPP002| Max   Min    Desenhar mapas   USGS||
+MAPP003| Zoom  Zoom  Camada Preenchido DRG   AutoMapa Caminho/Ficheiro||
+MAPP004|Mudar camada->||
+MAPP005|Preenchido->||
+MAPP006|Sim||
+MAPP007|Nao||
+MAPP008|Automapas->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+#
+# Marcas do tempo
+TIME001|Dia||
+TIME002|Dias||
+TIME003|Hora||
+TIME004|Horas||
+TIME005|Minuto||
+TIME006|Minutos||
+TIME007|Segundo||
+TIME008|Segundos||
+#
+#
+# Map Caching
+CACHE001|Map now cached||
+CACHE002|Loading Cached Map||
+CACHE003|Map not found in cache...||
+#
+#
+# Map Screen Misc
+RANGE001|RANGE SCALE||
+#
+#
+# GPS Status
+GPSS001|WAAS or PPS||
+GPSS002|DGPS||
+GPSS003|Valid SPS||
+GPSS004|Invalid||
+GPSS005|Sats/View||
+GPSS006|Fix||
+GPSS007|!GPS data is older than 30 seconds!||
+GPSS008|Simulation||
+GPSS009|Manual||
+GPSS010|Estimated||
+GPSS011|Float RTK||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data
+CADPUD001|Area Object||
+CADPUD002|Area Label:||
+CADPUD003|Comment:||
+CADPUD004|Probability (%):||
+CADPUD005|OK||
+CADPUD006|CAD Dialog||
+CADPUD007|Show/Edit Details||
+CADPUD008|Cancel||
+CADPUD009|Delete CAD objects?||
+CADPUD010|Delete All||
+CADPUD011|Delete Selected||
+CADPUD012|Solid||
+CADPUD013|Dashed||
+CADPUD014|Double Dash||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|XASTIR Map of %s (upper left) to %s (lower right).  UTM %d m grid, %s datum. ||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA002|XASTIR Map of %s (upper left) to %s %s (lower right).  Lat/Long grid, %s datum.||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA003|XASTIR Map of %s (upper left) to %s (lower right).  UTM zones, %s datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST002|Postgreql with Postgis||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Xastir Simple Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA02|Xastir CAD Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA03|Xastir full Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/language-Spanish.sys b/config/language-Spanish.sys
new file mode 100644
index 0000000..9a986ca
--- /dev/null
+++ b/config/language-Spanish.sys
@@ -0,0 +1,1345 @@
+# $Id: language-Spanish.sys,v 1.237 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# Este es el archivo del Lenguaje Espa�ol usado para todas, consultas en Xastir.
+#
+# Creador        : por Jose R. Marte A. <hi8gn at amsat.org>
+# Mantenido por  : El Xastir Grupo <xastir at xastir.org>
+# Ult. Revisi�n  : 05/20/2003, Por Jose R. Marte A. <hi8gn at amsat.org>
+#
+# L�neas de comentarios con un signo de libra en frente son ignorado
+# El formato del archivo es como sigue:
+# Id (10 caract�res alfa num�rico)|(Cadena asociada con id)|TeclaR�pida|#comentario
+#
+# AVISO:
+# Algunas cadenas de letras contienen comando de formato como %s y %d, usted no
+# deber�a cambiar eso. Cadena de formatos errados podr�an producir un segfault!
+#
+# Men� Principal
+MENUTB0001|Archivo|A|
+MENUTB0002|Visualizar|V|
+MENUTB0004|Mapas|M|
+MENUTB0005|Estaciones|S|
+MENUTB0006|Mensajes|e|
+MENUTB0010|Interfaces|I|
+MENUTB0009|Ayuda|y|
+#
+# Men� archivo
+PULDNFI001|Configurar|C|
+PULDNFI002|Abrir Bit�cora|B|
+PULDNFI003|Prueba|P|
+PULDNFI004|Salir|S|
+PULDNFI007|Cambia nivel Depuraci�n|D|
+PULDNFI010|Bit�cora del TNC|T|
+PULDNFI011|Bit�cora de Internet|I|
+PULDNFI012|Bit�cora del I-Gate|G|
+PULDNFI013|Bit�cora del WX|W|
+PULDNFI014|Activa PNG Instant�nea||
+PULDNFI015|Imprimir Mapa|P|
+PULDNFI016|KML Snapshots||
+#
+# Men� visor
+PULDNVI001|Boletines|B|
+PULDNVI002|Datos entrantes|D|
+PULDNVI003|Estaciones M�viles|M|
+PULDNVI004|Todas las Estaciones|T|
+PULDNVI009|Estaciones Locales|L|
+PULDNVI012|�ltimas Estaciones|U|
+PULDNVI005|Estaciones Meteorol�gicas|E|
+PULDNVI008|Su Estaci�n Meteorol�gica|S|
+PULDNVI007|Alerta del tiempo|A|
+PULDNVI011|Tr�ficos de Mensajes|f|
+PULDNVI013|Tiempo de Inicio|I|
+PULDNVI014|Tiempo Transcurrido||
+PULDNVI015|GPS Status||
+PULDNVI016|ALOHA Statistics||
+#
+# Men� de Configuraci�n
+PULDNCF004|Estaci�n|E|
+PULDNCF001|Predefinidos|P|
+PULDNCF003|Cron�metro|t|
+PULDNCF002|Sistema de Coordenada|C|
+PULDNCF006|Alarmas de Audio|A|
+PULDNCF007|Sintetizador de Voz|S|
+PULDNCF008|Guardar Configuraci�n!|G|
+#
+# Men� de Mapas
+PULDNMP001|Seleccionar Mapas|M|
+PULDNMP012|Saltar a una Locaci�n|S|
+PULDNMP014|Localice rasgo del Mapa|L|
+PULDNMP016|Disable Fast Zoom/Pan/Home||
+PULDNMP013|Desactive todos los Mapas||
+PULDNMP002|Activar Auto Mapas||
+PULDNMP003|Rejillas sobre Mapa||
+PULDNMP004|Niveles de Mapas||
+PULDNMP010|Etiquetas de Mapas||
+PULDNMP009|Activar Areas Coloridas||
+PULDNMP007|Alerta Mapa WX||
+PULDNMP005|Color de fondo|C|
+PULDNMP006|Etiquetas de estiones|E|
+PULDNMP026|Icon Outline Style|O|
+PULDNMP011|Men� Indicador del Rat�n|R|
+PULDNMP008|Intensidad del Mapa|I|
+PULDNMP020|Configurar Tigermapa||
+PULDNMP021|Auto Mapa - Desactivar Mapas de Trama||
+PULDNMP022|Indezar Mapas en Inicio||
+PULDNMP023|Indice: Agregar Nuevos Mapas|A|
+PULDNMP024|Indice: Reindezar TODOS los Mapas|T|
+PULDNMP025|Fonts||
+PULDNMP015|Xfontsel||
+PULDNMP027|Re-download Maps (Not from cache)||
+PULDNMP028|Flush Entire Map Cache!||
+PULDNMP029|Find Address||
+PULDNMP030|Configure USGS DRG||
+PULDNMP031|Enable Map Border||
+#
+# Men� "Configurar Tigermapa"
+MPUPTGR001|Rejilla||
+MPUPTGR002|Condados||
+MPUPTGR003|Etiquetas de Ciudades||
+MPUPTGR004|Areas Urbanas||
+MPUPTGR005|Caminos Principales||
+MPUPTGR006|Calles||
+MPUPTGR007|Ferrocarriles||
+MPUPTGR008|Etiquetas de Estados||
+MPUPTGR009|Etiquetas de Inter-estatar||
+MPUPTGR010|Etiquetas de Carretera||
+MPUPTGR011|Etiquetas de Carretera en Estados||
+MPUPTGR012|Seleccionar art�culos a ser desplegado:||
+MPUPTGR013|Rios||
+MPUPTGR014|Lagos||
+MPUPTGR015|Aereopuertos, Parqueos, etc||
+MPUPTGR016|Intensidad de Mapa||
+MPUPTGR017|Internet Map Timeout (segundo)||
+MPUPTGR018|Activar Tiger Mapas||
+#
+# PopUp "Configure USGS DRG"
+MPUPDRG001|Select items to be displayed:||
+MPUPDRG002|Tint Underlying Map (XOR)||
+MPUPDRG003|Black||
+MPUPDRG004|White||
+MPUPDRG005|Blue||
+MPUPDRG006|Red||
+MPUPDRG007|Brown||
+MPUPDRG008|Green||
+MPUPDRG009|Purple||
+MPUPDRG010|Yellow||
+MPUPDRG011|Light Blue||
+MPUPDRG012|Light Red||
+MPUPDRG013|Light Purple||
+MPUPDRG014|Light Gray||
+MPUPDRG015|Light Brown||
+#
+# Seleccion de Mapas
+WPUPMCP001|Selecci�n de Mapa||
+PULDNMMC01|Limpiar|N|
+PULDNMMC02|Vectores|V|
+PULDNMMC03|250k Topo|2|
+PULDNMMC04|100k Topo|1|
+PULDNMMC05|24k Topo|4|
+PULDNMMC06|Expandir Dirs|||
+PULDNMMC07|Dirs/Mapas Seleccionado:||
+PULDNMMC08|Clear Dirs|C|
+PULDNMMC09|Select All|S|
+#
+# Colores de fondo del mapa
+PULDNMBC01|Gris||
+PULDNMBC02|Rosado M�stico||
+PULDNMBC03|Azul Marino||
+PULDNMBC04|Azul acerado||
+PULDNMBC05|Med. Verde mar||
+PULDNMBC06|Verde P�lido||
+PULDNMBC07|Dorado P�lido||
+PULDNMBC08|Dorado Amarillo||
+PULDNMBC09|Marr�n Rosado||
+PULDNMBC10|Rojo ladrillo||
+PULDNMBC11|Blanco||
+PULDNMBC12|Negro||
+#
+# Mapas Estaciones estilos de etiquetas
+PULDNMSL01|Fondo Negro||
+PULDNMSL02|Fondo Gris||
+PULDNMSL03|Texto en Negro|T|
+#
+# PullDown "Icon Outline Style"
+PULDNMIO01|No Outline|N|
+PULDNMIO02|Black Outline|B|
+PULDNMIO03|Grey Outline|G|
+PULDNMIO04|White Outline|W|
+#
+# Switches ON/OFF/Corto
+PULDNOT001|On||
+PULDNOT002|Off||
+PULDNOT003|Corto||
+#
+# Men� de Despliegue de Estaciones
+PULDNDP014|Localizar Estaci�n|L|
+PULDNDP001|Rastreo de Estaci�n|E|
+PULDNDP022|Sacar Rastro de Findu|F|
+PULDNDP032|Filtrar Datos||
+PULDNDP040|- Seleccionar Nada||
+PULDNDP041|- Seleccionar M�o||
+PULDNDP042|- Seleccionar TNC||
+PULDNDP027|- Seleccionar Directo||
+PULDNDP043|- Seleccionar V�a Digi||
+PULDNDP034|- Seleccionar Red||
+PULDNDP019|Incluir Datos Expirados||
+PULDNDP044|- Seleccionar Estaciones||
+PULDNDP028|- Seleccionar Estaciones Fijas||
+PULDNDP029|- Seleccionar Estaciones M�viles||
+PULDNDP030|- Seleccionar Estaciones de WX||
+PULDNDP053|  - Select CWOP WX Stations||
+PULDNDP045|- Seleccionar Objetos/Art�culos||
+PULDNDP026|- Seleccionar Objetos/Art�culos de WX||
+PULDNDP039|- Seleccionar Objetos/Art�culos Medidores de Agua||
+PULDNDP031|- Seleccionar Otros Objetos/Art�culos||
+PULDNDP033|Filtrar Visualizaci�n||
+PULDNDP010|Mostrar Indicativo|I|
+PULDNDP012|Mostrar S�mbolo|D|
+PULDNDP011|- S�mbolo Rotado|S|
+PULDNDP007|Mostrar Rastros|R|
+PULDNDP003|Mostrar Curso|C|
+PULDNDP004|Mostrar Velocidad|V|
+PULDNDP017|- Mostrar Velocidad Corta||
+PULDNDP002|Mostrar Altura|A|
+PULDNDP009|Mostrar Informe del Tiempo|T|
+PULDNDP046|- Mostrar Texto||
+PULDNDP018|- S�lo la Temperatura||
+PULDNDP047|- Mostrar Indicaci�n de Viento||
+PULDNDP054|Display Aloha Circle||
+PULDNDP013|Mostrar Ambig�edad de Posici�n||
+PULDNDP008|Mostrar Potencia/Ganancia|P|
+PULDNDP021|- Usar Pot/Ganancia por Defecto||
+PULDNDP020|- Mostrar Pot/Ganancia M�viles||
+PULDNDP023|Mostrar atributos DF||
+PULDNDP123|Display DF Beamwidth||
+PULDNDP223|Display DF Bearing||
+PULDNDP035|Activar Conteo-Muerto||
+PULDNDP036|- Mostrar Arco||
+PULDNDP037|- Mostrar Curso||
+PULDNDP038|- Mostrar S�mbolo||
+PULDNDP005|Mostrar Orientaci�n/Distancia|D|
+PULDNDP024|Mostrar Tiempo del Ultimo Informe||
+PULDNDP015|Anular Todas las Estaciones|A|
+PULDNDP016|Limpiar Rastros|n|
+PULDNDP025|Limpiar Historia de Objeto/Art�culo||
+PULDNDP048|Recargar Historia de Objeto/Art�culo||
+PULDNDP049|Clear All Tactical Calls||
+PULDNDP050|Clear Tactical Call History||
+PULDNDP051|Select Tactical Calls Only||
+PULDNDP052|- Label Trailpoints||
+PULDNDP055|Export all|E|
+PULDNDP056|Export to KML File||
+#
+# Inglesa/M�trica
+PULDNUT001|Activar Unidades Inglesa||
+PULDNUT002|M�trica||
+#
+# Men� de Mensajes
+PULDNMG001|Enviar Mensaje A|E|
+PULDNMG002|Abrir Mensajes Grupos|G|
+PULDNMG003|Anular todos mensajes saliente|B|
+PULDQUS001|Pregunta General a Estaciones|P|
+PULDQUS002|Pregunta a Estaciones I-Gate|I|
+PULDQUS003|Pregunta a Estaciones WX|W|
+PULDNMG004|Fijar Mensaje en Contestaci�n Autom�tica|F|
+PULDNMG005|Activar Auto contestaci�n de Mensaje|A|
+PULDNMG006|Sat�lite Modo de Reconocimiento|M|
+PULDNMG007|Show Pending Messages|P|
+#
+# Men� de Interfaces
+PULDNTNT04|Interface Control||
+PULDNTNT03|Desactivar Transmitir: TODOS||
+PULDNTNT05|Desactivar Transmitir: Mi Posici�n||
+PULDNTNT06|Desactivar Transmitir: Objetos/Art�culos||
+PULDNTNT11|Enable Server Port||
+PULDNTNT01|Transmitir Ahora..!|T|
+PULDNTNT07|Coger Huella de GPS|F|
+PULDNTNT08|Coger Rutas de GPS|R|
+PULDNTNT09|Coger V�aPuntos de GPS|W|
+PULDNTNT10|Fetch Garmin RINO Waypoints|G|
+#
+# Men� de Ayuda
+PULDNHEL01|Acerca de|A|
+PULDNHEL02|Indice de Ayuda|I|
+PULDNHEL03|EMERGENCY BEACON MODE ENABLE|E|
+PULDNHEL04|!!! EMERGENCY BEACON MODE !!!||
+PULDNHEL05|About Xastir||
+#
+# Men� de Rat�n
+POPUPMA001|Opciones||
+POPUPMA00c|Centro||
+POPUPMA015|Info de estaci�n||
+POPUPMA002|Acercar|A|
+POPUPMA003|Alejar|l|
+POPUPMA004|Nivel de Enfoque|N|
+POPUPMA005|Nivel 1|1|
+POPUPMA006|Nivel 16|6|
+POPUPMA007|Nivel 64|4|
+POPUPMA008|Nivel 256|2|
+POPUPMA009|Nivel 1024|0|
+POPUPMA010|Nivel 8192|8|
+POPUPMA017|El Mundo Entero|E|
+POPUPMA016|Ultima Pos/Enfoque del Mapa|P|
+POPUPMA018|Crear Objeto/Art�culo|C|
+POPUPMA019|Modificar Objeto/Art�culo|M|
+POPUPMA025||Mover Mi  Estaci�n Aqu�|A|
+POPUPMA011|Paneo arriba|u|
+POPUPMA012|Paneo abajo|d|
+POPUPMA013|Paneo izquierda|l|
+POPUPMA014|Paneo derecha|r|
+POPUPMA020|Medida||
+POPUPMA021|Movimiento||
+POPUPMA022|Rastr�eMe||
+POPUPMA023|Modificadores Encontrado!||
+POPUPMA024|Por favor apague OFF CapsLock/NumLock/ScrollLock/otro modificadores||
+POPUPMA026|Centre & Enfoque||
+POPUPMA027|  Latitud||
+POPUPMA028| Longitud||
+POPUPMA029|Dibuje Objetos CAD||
+POPUPMA030|Draw||
+POPUPMA031|Cierre el Pol�gono||
+POPUPMA032|Erase CAD Polygons||
+POPUPMA033|**NOT USED**||
+POPUPMA034|Custom Zoom Level||
+POPUPMA035|10% out||
+POPUPMA036|10% in||
+POPUPMA037|Area||
+POPUPMA038|square||
+POPUPMA039|square feet||
+POPUPMA040|square meters||
+POPUPMA041|Bearing||
+POPUPMA042|degrees||
+POPUPMA043|Modify ambiguous position||
+POPUPMA044|Position abiguity is on, your new position may appear to jump.||
+POPUPMA045|Predefined Objects||
+POPUPMA046|CAD Polygons||
+POPUPMA047|Enable CAD objects||
+POPUPMA048|Enable CAD labels||
+POPUPMA049|Enable CAD comments||
+POPUPMA050|Enable CAD probability||
+POPUPMA051|Enable CAD area size||
+POPUPMA052|sq||
+POPUPMA053|ft||
+POPUPMA054|meters||
+POPUPMA055|mi|
+#
+# Men� de Estados de la l�neas de Etiquetas
+BBARZM0001|Foco %s||
+BBARZM0002|Foco %s Tr||
+BBARSTH001|%d/%d Estaciones||
+BBARSTA000|%-9s Nuevo objeto!||
+BBARSTA001|%-9s Nueva estaci�n!||
+BBARSTA002|%s||
+BBARSTA003|Cargando mapas...||
+BBARSTA004|Mapas cargados...||
+BBARSTA005|Mapa Lat/Long Rejilla es ON||
+BBARSTA006|Mapa Lat/Long Rejilla es OFF||
+BBARSTA007|El uso de Auto Mapas, es ON||
+BBARSTA008|El uso de Auto Mapas, es OFF||
+BBARSTA009|Los Niveles del Mapa est�n ON||
+BBARSTA010|Los Niveles del Mapa est�n OFF||
+BBARSTA011|Auto contestaci�n de Mensaje es OFF!||
+BBARSTA012|Achivo creado..||
+BBARSTA013|Abriendo Puerto GPS||
+BBARSTA014|Cerrando Puerto GPS||
+BBARSTA015|Obtenido GPS RMC Cord�n||
+BBARSTA016|Obtenido GPS GGA Cord�n||
+BBARSTA017|Red desconectada del Servidor||
+BBARSTA018|Conexi�n a Red tiempo vencido!||
+BBARSTA019|Buscando Servidor %s||
+BBARSTA020|Conectado al %s||
+BBARSTA021|Fracaso en conexi�n de la Red!||
+BBARSTA022|Podr�a no atar el s�calo!||
+BBARSTA023|No IP para el Servidor!||
+BBARSTA024|No Servidor Especificado||
+BBARSTA025|Servidor encontrado, Conectando %d||
+BBARSTA026|Esperando por datos del GPS v�a HSP..||
+BBARSTA027|Limpiando el HSP datos obtenido del TNC..||
+BBARSTA028|Cargando %s||
+BBARSTA029|Abriendo Puerto WX||
+BBARSTA030|Cerrando Puerto WX||
+BBARSTA031|Buscando el Servidor %d||
+BBARSTA032|Datos de WX Decodificado||
+BBARSTA033|Eco desde digipeater||
+BBARSTA034|Cargando Mapas de alerta WX||
+BBARSTA035|Esperando por datos del GPS v�a AUX..||
+BBARSTA036|Limpiando el AUX datos obtenido del TNC..||
+BBARSTA037|Datos de GPS Decondificado||
+BBARSTA038|Coloque el cambio en mi estaci�n||
+BBARSTA039|Indezando %s||
+BBARSTA040|Estaci�n de Aficionado APRS(tm) %s||
+BBARSTA041|Esperando por GPS data..||
+BBARSTA042|Transmitiendo objetos/articulos||
+BBARSTA043|Anotando||
+BBARSTA044|ALOHA distance is %d%s||
+BBARSTA045|Loading symbols...||
+BBARSTA046|Reloading symbols...||
+BBARSTA047|Initialize my station...||
+BBARSTA048|Start interfaces...||
+BBARSTA049|Reading tiles...||
+BBARSTA050|Downloading tiles...||
+BBARSTA051|Downloading tile %li of %li||
+#
+# Despliegue Paquete de Datos
+WPUPDPD001|Despligue de Datos||
+WPUPDPD002|s�lo datos del TNC||
+WPUPDPD003|s�lo datos de la Red||
+WPUPDPD004|Datos del TNC y la Red||
+WPUPDPD005|TNC||
+WPUPDPD006|RED||
+WPUPDPD007|Station Capabilities||
+WPUPDPD008|Mine Only||
+#
+# Localizar Estaci�n
+WPUPLSP001|Localizar estaci�n||
+WPUPLSP002|Localizar Indicativo||
+WPUPLSP003|Macheo Sensible|S|
+WPUPLSP004|Macheo Exacto|E|
+WPUPLSP005|Localizar ahora!|A|
+WPUPLSP006|Localizar Emergencia!||
+WPUPLSP007|FCC/RAC Lookup||
+#
+# Configurar predefinidos
+WPUPCFD001|Configurar valores predefinidos||
+WPUPCFD002|desde qu� int�rvalo de tiempo ser� considerada una estaci�n vieja?||
+WPUPCFD003|15 minutos|1|
+WPUPCFD004|30 minutos|3|
+WPUPCFD005|45 minutos|4|
+WPUPCFD006|1 hora|H|
+WPUPCFD007|90 minutos|9|
+WPUPCFD008|2 horas|2|
+WPUPCFD009|desde qu� int�rvalo de tiempo la estaci�n no ser� desplegada?||
+WPUPCFD010|6 horas|6|
+WPUPCFD011|12 horas|o|
+WPUPCFD012|1 D�a|D|
+WPUPCFD013|2 D�as|s|
+WPUPCFD014|1 semana|n|
+WPUPCFD015|Opci�n modo de Transmisi�n de la estaci�n||
+WPUPCFD016|Estaci�n Fija|F|
+WPUPCFD017|Estaci�n M�vil c/Hora local|l|
+WPUPCFD018|Estaci�n M�vil c/Fecha-hora Z�lu|Z|
+WPUPCFD019|Estaci�n M�vil c/Horas-segundos Z�lu|u|
+WPUPCFD021|Posici�n de la estaci�n c/Tiempo|T|
+WPUPCFD022|Posici�n de la estaci�n, fecha-hora Zulu, y Tiempo|f|
+WPUPCFD023|Transmitir datos WX en Raw?||
+WPUPCFD024|Comprimir datos objeto/art�culo cuando transmita?||
+WPUPCFD025|Activar Red Alternada?|A|
+WPUPCFD026|Enviar reportes de posici�n en qu� int�rvalos?||
+WPUPCFD027|Mostrar bulletines Nuevo||
+WPUPCFD028|Avisar si hay teclas Modificadora||
+WPUPCFD029|Ver boletines de zero-distancia||
+WPUPCFD030|Disable Posit Dupe-Checks||
+WPUPCFD031|Load predefined objects from file||
+WPUPCFD032|My trails in one color||
+WPUPCFD033|ALTNET:||
+#
+# Menu "Configurar - Cron�metro"
+WPUPCFTM01|Configurar Cron�metro||
+WPUPCFTM02|TX Posici�n Int�rvalo (minutos)||
+WPUPCFTM03|Desvanecimiento de la Estaci�n (minutos)||
+WPUPCFTM04|Objeto/Art�culo TX Max Int�rvalo (minutos)||
+WPUPCFTM05|Limpiar Tiempo de la Estaci�n (horas)||
+WPUPCFTM06|Chequeo Int�rvalo del GPS (segundos)||
+WPUPCFTM07|Borrar Tiempo de la Estaci�n (d�as)||
+WPUPCFTM08|Descanso Conteo-Muerto (minutos)||
+WPUPCFTM09|Serial Inter-Char Delay (ms)||
+WPUPCFTM10|Nuevo Tiempo Rastro (min)||
+WPUPCFTM11|Nuevo Interval Rastro (grados)||
+WPUPCFTM12|RINO -> Objects Interval (min), 0 = Disabled||
+WPUPCFTM13|Snapshot Interval (min)||
+#
+# Configurar Sistema de Coordenada"
+WPUPCFC001|Configurar Sistema de Coordenada||
+WPUPCFC002|Seleccione Sistema de Coordenada||
+WPUPCFC003|dd.ddddd|d|
+WPUPCFC004|dd mm.mmm|m|
+WPUPCFC005|dd mm ss.s|s|
+WPUPCFC006|UTM|U|
+WPUPCFC007|USNG/MGRS2||
+WPUPCFC008|UTM con zonas especiales||
+#
+# Configurar GPS
+WPUPCFG001|Configurar GPS||
+WPUPCFG003|Puerto exclusivo de GPS||
+WPUPCFG002|Usar Posici�n GPS?||
+WPUPCFG004|opciones del GPS||
+WPUPCFG005|GPS Exclusivo||
+WPUPCFG006|TNC conectado a GPS (Cable HSP)||
+WPUPCFG007|TNC conectado a GPS usando CTL-E||
+WPUPCFG008|GPS tiempo (Muestreo cada)||
+WPUPCFG009|5 sec||
+WPUPCFG010|15 sec||
+WPUPCFG011|30 sec||
+WPUPCFG012|1 minuto||
+WPUPCFG013|2 minutos||
+WPUPCFG014|5 minutos||
+WPUPCFG015|10 minutos||
+WPUPCFG016|Red conectada al GPS||
+WPUPCFG017|Servidor GPSD||
+WPUPCFG018|Puerto GPSD||
+WPUPCFG019|Red GPS v�a GPSD||
+WPUPCFG020|Reconectar en fallo?||
+WPUPCFG021|Red Conectada a WX||
+WPUPCFG022|Servidor WX||
+WPUPCFG023|Puerto WX||
+#
+# Configurar TNC (baudio tambi�n son para WX)
+WPUPCFT001|Configurar TNC||
+WPUPCFT002|Usar TNC?||
+WPUPCFT003|Puerto TNC||
+WPUPCFT004|Velocidad del Puerto||
+WPUPCFT005|300 bps||
+WPUPCFT006|1200 bps||
+WPUPCFT007|2400 bps||
+WPUPCFT008|4800 bps||
+WPUPCFT009|9600 bps||
+WPUPCFT010|19200 bps||
+WPUPCFT011|Rutas del UnProto||
+WPUPCFT012|Ruta 1: %s v�a ||
+WPUPCFT013|Ruta 2: %s v�a ||
+WPUPCFT014|Ruta 3: %s v�a ||
+WPUPCFT015|Modo del Puerto||
+WPUPCFT016|8,N,1||
+WPUPCFT017|7,E,1||
+WPUPCFT018|7,O,1||
+WPUPCFT019|38400 bps||
+WPUPCFT020|57600 bps||
+WPUPCFT021|115200 bps||
+WPUPCFT022|230400 bps||
+WPUPCFT023|Configurar el TNC c/HSP GPS||
+WPUPCFT024|Tipo de Data||
+WPUPCFT025|Auto detecci�n||
+WPUPCFT026|Tipo Binario||
+WPUPCFT027|Tipo ASCII||
+WPUPCFT028|Configurar el TNC c/AUX GPS||
+WPUPCFT029|Configurar el TNC c/MAL ENUM||
+WPUPCFT030|Configurar un KISS TNC||
+WPUPCFT031|Archivos de Configuraci�n del TNC||
+WPUPCFT032|Arreglar Archivo del TNC|| 
+WPUPCFT033|Archivo de apagar TNC||
+WPUPCFT034|Par�metros TNC KISS modo||
+WPUPCFT035|TXDelay (10 ms unidades)||
+WPUPCFT036|Persistence (0 to 255)||
+WPUPCFT037|SlotTime (10 ms unidades)||
+WPUPCFT038|TxTail (10 ms unidades)||
+WPUPCFT039|Full Duplex||
+WPUPCFT040|Configurar un Multi-Port KISS TNC||
+WPUPCFT041|Radio Port||
+WPUPCFT042|Dubious UNPROTO Path!||
+WPUPCFT043|Please consider a shorter path such as WIDE2-2 or WIDE1-1,WIDE2-2||
+WPUPCFT044|Dubious IGATE Path!||
+WPUPCFT045|Transmitting w/Dubious UNPROTO Path!||
+WPUPCFT046|Transmitting w/Dubious IGATE Path!||
+WPUPCFT047|Init KISS-mode on startup||
+#
+# Configurar el Puerto de la Estaci�n Meteorol�gica
+WPUPCFWX01|Configurar el Puerto de la Estaci�n Meteorol�gica||
+WPUPCFWX02|Dispositivo de la Estaci�n Meteorol�gica||
+WPUPCFWX03|Tipo Medida de lluvia (Configuraci�n Global)||
+WPUPCFWX04|0.1 pg / 2.5 mm||
+WPUPCFWX05|0.01 pg / 0.25 mm||
+WPUPCFWX06|0.1 mm||
+WPUPCFWX07|No Correcci�n||
+#
+# Configurar la Estaci�n
+WPUPCFS001|Configurar la estaci�n||
+WPUPCFS002|Indicativo||
+WPUPCFS003|Latitud||
+WPUPCFS004|grd||
+WPUPCFS005|min||
+WPUPCFS006|(N/S)||
+WPUPCFS007|Longitud||
+WPUPCFS008|(E/W)||
+WPUPCFS009|S�mbolo de la estaci�n||
+WPUPCFS010|Grupo/sobrepuesto||
+WPUPCFS011|S�mbolo||
+WPUPCFS028|Seleccione||
+WPUPCFS012|Potencia - Altura (HAAT) - Ganancia y Direcci�n||
+WPUPCFS013|Desactive PHG||
+WPUPCFS014|Altura de la Antena||
+WPUPCFS015|Ganancia de la Antena||
+WPUPCFS016|Omni||
+WPUPCFS017|Comentarios:||
+WPUPCFS018|Posici�n ambig�a||
+WPUPCFS019|Ninguna||
+WPUPCFS020|.11 milla||
+WPUPCFS021|1.15 millas||
+WPUPCFS022|11.51 millas||
+WPUPCFS023|69.09 millas||
+WPUPCFS024|.18 kil�metro||
+WPUPCFS025|1.85 kil�metros||
+WPUPCFS026|18.53 kil�metros||
+WPUPCFS027|111.19 kil�metros||
+WPUPCFS029|Env�o de posici�n comprimida|C|
+#
+# Di�logo de Objeto/Art�culo
+POPUPOB001|Objeto/Ar�culo||
+POPUPOB002|Nombre:||
+POPUPOB003|Crear Nuevo Objeto||
+POPUPOB004|Borrar Objeto||
+POPUPOB005|Modificar Objeto||
+POPUPOB006|Crear Nuevo Art�culo||
+POPUPOB007|Area de Objeto||
+POPUPOB008|Activar Area de Objeto||
+POPUPOB009|Color Luminoso||
+POPUPOB010|Area Colorida||
+POPUPOB011|C�rculo||
+POPUPOB012|L�nea-Derecha '/'||
+POPUPOB013|L�nea-Izquierda '\'||
+POPUPOB014|Tri�ngulo||
+POPUPOB015|Rect�ngulo||
+POPUPOB016|Negro||
+POPUPOB017|Azul||
+POPUPOB018|Verde||
+POPUPOB019|Cian||
+POPUPOB020|Rojo||
+POPUPOB021|Violeta||
+POPUPOB022|Amarillo||
+POPUPOB023|Gris||
+POPUPOB024|Compense Arriba:||
+POPUPOB025|Compense Izq.(Excepto '/'):||
+POPUPOB026|Corridor:||
+POPUPOB027|Opciones Gen�ricas||
+POPUPOB028|Situaci�n||
+POPUPOB029|Activar Letrero||
+POPUPOB030|Data:||
+POPUPOB031|Letrero Objeto||
+POPUPOB032|Activar Compresi�n||
+POPUPOB033|Borrar Art�culo||
+POPUPOB034|Modificar Art�culo||
+POPUPOB035|Altitud (Pies):||
+POPUPOB036|Velocidad (Nudos):||
+POPUPOB037|Curso:||
+POPUPOB038|DF Objeto||
+POPUPOB039|Se�al - Altura(HAAT) - Ganancia - Direcci�n||
+POPUPOB040|Dirigiendo - Ancho de la orientaci�n||
+POPUPOB041|Antena Omni-direccional||
+POPUPOB042|Antena Direccional||
+POPUPOB043|In�til||
+POPUPOB044|Adopt Object||
+POPUPOB045|Adopt Item||
+POPUPOB046|DF Bearing:||
+POPUPOB047|Probability Circles||
+POPUPOB048|Map View Object||
+POPUPOB049|Min (mi):||
+POPUPOB050|Max (mi):||
+#
+# Configurar Internet
+WPUPCFI001|Configurar Internet||
+WPUPCFI002|Servidor||
+WPUPCFI003|Puerto||
+WPUPCFI004|(Servidores Secundarios)||
+WPUPCFI005|Servidor1||
+WPUPCFI006|Puerto1||
+WPUPCFI007|Servidor2||
+WPUPCFI008|Puerto2||
+WPUPCFI009|Palabra de Paso||
+WPUPCFI010|Dejar en blanco si nada||
+WPUPCFI011|Reconectar en fallo de la RED?||
+WPUPCFI012|Correr como un I-Gate?||
+WPUPCFI013|Difundir mensajes v�a TNC cuando un I-Gate?||
+WPUPCFI014|Bit�cora de Transacciones del I-Gate?|||
+WPUPCFI015|Parametros de Filtrado||
+#
+# Configurar Base de datos
+WPUPCFID01|Configurar Base de datos(TBD)||
+WPUPCFID02|Servidor||
+WPUPCFID03|Puerto||
+WPUPCFID04|(Servidores Secundarios)||
+WPUPCFID05|Servidor1||
+WPUPCFID06|Puerto1||
+WPUPCFID07|Servidor2||
+WPUPCFID08|Puerto2||
+WPUPCFID09|Palabra de Paso||
+WPUPCFID10|Dejar en blanco si nada||
+WPUPCFID11|Reconectar en fallo de la RED?||
+WPUPCFID12|Correr como un I-Gate?||
+WPUPCFID13|Difundir mensajes v�a TNC cuando un I-Gate?||
+WPUPCFID14|Bit�cora de Transacciones del I-Gate?|||
+WPUPCFID15|Parametros de Filtrado||
+#
+# Menu "Configurar AGWPE"
+WPUPCFIA01|Configurar AGWPE||
+WPUPCFIA02|Servidor ||
+WPUPCFIA03|Puerto ||
+WPUPCFIA04|(Servidores Secundario)||
+WPUPCFIA05|Servidor1||
+WPUPCFIA06|Puerto1||
+WPUPCFIA07|Servidor2||
+WPUPCFIA08|Puerto2||
+WPUPCFIA09|Codigo de Paso||
+WPUPCFIA10|(dejar en blanco si Nada)||
+WPUPCFIA11|Reconectar en fallo de RED?||
+WPUPCFIA12|Correr como un I-Gate?||
+WPUPCFIA13|Difundir mensajes via TNC cuando un I-Gate?||
+WPUPCFIA14|Bit�cora de Transacciones I-Gate?||
+WPUPCFIA15|Transmitir RadioPuerto||
+#
+# Configurar Alarmas de Audio
+WPUPCFA001|Configurar Alarma de Audio||
+WPUPCFA002|Aplicaci�n Audio||
+WPUPCFA003|Alarma ON||
+WPUPCFA004|Archivos de Audio||
+WPUPCFA005|Nueva estaci�n||
+WPUPCFA006|Nuevo mensaje||
+WPUPCFA007|Proximidad||
+WPUPCFA008|Banda abierta||
+WPUPCFA009|M�nima distancia||
+WPUPCFA010|M�xima distancia||
+WPUPCFA011|Alerta del Tiempo||
+#
+# Configurar a Festival el sintetizador de Voz
+WPUPCFSP01|Configurar a Festival el Sintetizador de Voz||
+WPUPCFSP02|Fijar en 'ON' la opciones del Sintetizador de Voz||
+WPUPCFSP03|<- Anunciar Nueva Estaci�n||
+WPUPCFSP04|<- Anunciar Alerta de Nuevo Mensaje||
+WPUPCFSP05|<- Anunciar Cuerpo de Nuevo Mensaje||
+WPUPCFSP06|<- Anunciar la Proximidad de estaciones||
+WPUPCFSP07|<- Anunciar DX condici�n de Banda Abierta||
+WPUPCFSP08|<- Anunciar Alerta sobre condiciones del Tiempo||
+WPUPCFSP09|<- Estaci�n Rastreada Alerta de Proximidad||
+#
+# Rastreo de Estaci�n
+WPUPTSP001|Rastreo estaci�n|| 
+WPUPTSP002|Rastreo Indicativo|| 
+WPUPTSP003|Macheo Sensible|| 
+WPUPTSP004|Macheo Exacto|| 
+WPUPTSP005|Rastrear Ahora!|| 
+WPUPTSP006|Limpiar Rastro|| 
+WPUPTSP007|Abajar Rastro||
+WPUPTSP008|Indicativo||
+WPUPTSP009|Inicio Del Rastro (hace horas)||
+WPUPTSP010|Longitud del Rastro (horas)||
+#
+# Men� de Mensajes
+WPUPMSB001|Enviar mensaje %d||
+WPUPMSB002|Enviar Mensaje a grupo %d||
+WPUPMSB003|Indicativo de Estaci�n:||
+WPUPMSB004|Indicativos de Grupos:||
+WPUPMSB005|Nuevo/Refresh Indicativo||
+WPUPMSB006|Nuevo grupo||
+WPUPMSB007|Clear Msg History||
+WPUPMSB008|Mensaje:||
+WPUPMSB009|Enviar ahora!||
+WPUPMSB010|Ruta:||
+WPUPMSB011|Cancel Pending Msgs||
+WPUPMSB012|Kick Timer||
+WPUPMSB013|seq||
+WPUPMSB014|type||
+WPUPMSB015|Broadcast||
+WPUPMSB016|*TIMEOUT*||
+WPUPMSB017|*CANCELLED*||
+WPUPMSB018|*REJECTED*||
+WPUPMSB019|Change Path||
+WPUPMSB020|Use Default Path(s)||
+WPUPMSB021|Direct (No path)||
+WPUPMSB022|Reverse Path (Hint):||
+#
+# Auto Contestaci�n
+WPUPARM001|Cambiar auto Contestaci�n||
+WPUPARM002|Reenviar:||
+#
+# Ayuda / Indice
+WPUPHPI001|Indice de Ayuda|I|
+WPUPHPI002|Visualizar|V|
+#
+# Informaci�n de la Estaci�n
+WPUPSTI000|Objeto creado desde: %s||
+WPUPSTI001|Info Estaci�n||
+WPUPSTI002|Enviar mensaje||
+WPUPSTI003|Buscar datos FCC||
+WPUPSTI004|Buscar datos RAC||
+WPUPSTI005|%d: Paquetes recibidos, �ltimo recibido en fecha: ||
+WPUPSTI006|O�do v�a TNC en dispositivo: %d, ||
+WPUPSTI007|O�do ||
+WPUPSTI008|Ultima vez v�a Local||
+WPUPSTI009|Ultima vez v�a TNC en dispositivo: %d||
+WPUPSTI010|Ultima vez v�a Internet en dispositivo: %d||
+WPUPSTI011|Ultima vez v�a Archivo||
+WPUPSTI012|Ultima vez v�a Desconocida||
+WPUPSTI013|, y ha cambiado posici�n||
+WPUPSTI014|Actual Potencia/Ganancia:||
+WPUPSTI016|Altitud: %.1f%s ||
+WPUPSTI017|Curso: %s� ||
+WPUPSTI018|Velocidad: %.1f km/h||
+WPUPSTI019|Velocidad: %.1f mph||
+WPUPSTI020|%0.1f millas||
+WPUPSTI021|%0.1f km||
+WPUPSTI022|Distancia desde mi estaci�n %s, Curso desde mi estaci�n %s||
+WPUPSTI023|Ultima posici�n: ||
+WPUPSTI024|Datos de la estaci�n Meteorol�gica %c:%s||
+WPUPSTI025|Curso del viento: %s�  Velocidad: %03d km/h||
+WPUPSTI026|Curso del viento: %s�  Velocidad: %s mph||
+WPUPSTI027| R�faga: %03d Km/h||
+WPUPSTI028| R�faga: %s mph|| 
+WPUPSTI029|Temperatura: %02.1f�C   ||
+WPUPSTI030|Temperatura: %s�F   ||
+WPUPSTI031| Humedad: %s%%   ||
+WPUPSTI032|Indice de Humedad: %02.1f�C  ||
+WPUPSTI033| Presi�n Barom�trica: %s mb||
+WPUPSTI034|Nieve: %0.1f (cm/24h)||
+WPUPSTI035|Nieve: %0.0f (plg/24h)||
+WPUPSTI036|Lluvia: ||
+WPUPSTI037|%0.2f (mm/h)  ||
+WPUPSTI038|%0.2f (plg/h)  ||
+WPUPSTI039|%0.2f (mm/d�a)  ||
+WPUPSTI040|%0.2f (plg/d�a)  ||
+WPUPSTI041|%0.2f (mm/desde medianoche)||
+WPUPSTI042|%0.2f (mm/desde medianoche)||
+WPUPSTI043|Ruta de Datos: %s||
+WPUPSTI044|Comentarios %02d/%02d %02d:%02d : %s||
+WPUPSTI045|Limpiar Rastro||
+WPUPSTI046|Total lluvia: ||
+WPUPSTI047|%0.2f (mm)||
+WPUPSTI048|%0.2f (plg)||
+WPUPSTI049|Preguntar rastro||
+WPUPSTI050|Pregunta no-conocido Mensaje||
+WPUPSTI051|Pregunta directa a estaci�n||
+WPUPSTI052|Pregunta versi�n a estaci�n||
+WPUPSTI053|Modificar Objeto/Art�culo||
+WPUPSTI054|Almacenar Rastro||
+WPUPSTI055|Repetido desde:||
+WPUPSTI056|Activar Actualizaciones Autom�tica||
+WPUPSTI057|Omni-DF: %s||
+WPUPSTI058|Orientando DF: %s||
+WPUPSTI059|Estados %02d/%02d %02d:%02d : %s||
+WPUPSTI060|Incendio Temp: %02.1f�C  ||
+WPUPSTI061|Incendio Temp: %s�F   ||
+WPUPSTI062|Humedad de Incendio: %s%%  ||
+WPUPSTI063|Baro: %0.2f en Hg||
+WPUPSTI064|Fetch NWS Alert||
+WPUPSTI065|Tactical Call: %s||
+WPUPSTI066|Assign Tactical Call||
+WPUPSTI067|Current Range: %d miles||
+WPUPSTI068|none||
+WPUPSTI069|default||
+WPUPSTI070|HAAT||
+WPUPSTI071|omni||
+WPUPSTI072|range||
+WPUPSTI073|BAD PHG||
+WPUPSTI074|BAD SHG||
+WPUPSTI075|DF Range||
+WPUPSTI076|No signal detected||
+WPUPSTI077|Detectible signal (Maybe)||
+WPUPSTI078|Detectible signal but not copyable)||
+WPUPSTI079|Weak signal, marginally readable||
+WPUPSTI080|Noisy but copyable signal||
+WPUPSTI081|Some noise, easy to copy signal||
+WPUPSTI082|Good signal w/detectible noise||
+WPUPSTI083|Near full-quieting signal||
+WPUPSTI084|Full-quieting signal||
+WPUPSTI085|Extremely strong & full-quieting signal||
+WPUPSTI086|BAD BEARING||
+WPUPSTI087|BAD NRQ||
+WPUPSTI088|DF Beamwidth||
+WPUPSTI089|DF Length||
+WPUPSTI090|Not Valid||
+WPUPSTI091|Change Trail Color||
+WPUPSTI092|Clear DF Bearing||
+#
+#
+# PopUp "ALOHA Statistics"
+WPUPALO001|ALOHA radius: %d %s||
+WPUPALO002|Stations inside ALOHA circle: %d||
+WPUPALO003| Digis:               %d||
+WPUPALO004| Mobiles (in motion): %d||
+WPUPALO005| Mobiles (other):     %d||
+WPUPALO006| WX stations:         %d||
+WPUPALO007| Home stations:       %d||
+WPUPALO008|Last calculated %d %s %d %s ago.||
+WPUPALO666|ALOHA radius not calculated yet||
+#
+# FCC-RAC buscar Indicativo
+STIFCC0001|Buscar en Base de datos FCC||
+STIFCC0002|Buscar en Base de datos RAC||
+STIFCC0003|Nombre:||
+STIFCC0004|Calle:||
+STIFCC0005|Ciudad:||
+STIFCC0006|Estado:||
+STIFCC0007|Zona Postal:||
+STIFCC0008|B�sica ||
+STIFCC0009|Advanzada ||
+STIFCC0010|5 wpm ||
+STIFCC0011|12 wpm ||
+#
+# FCC-RAC buscar Indicativo
+STIFCC0100|FCC index old, rebuilding||
+STIFCC0101|Callsign Search||
+STIFCC0102|Callsign Not Found!||
+STIFCC0103|RAC index old, rebuilding||
+#
+#
+# Mensaje de Banda abierta 
+UMBNDO0001|en distancia de||
+#
+# Opciones Universales
+UNIOP00001|Aceptar||
+UNIOP00002|Cancelar||
+UNIOP00003|Cerrar||
+UNIOP00004|millas||
+UNIOP00005|km||
+UNIOP00006|Dispositivo||
+UNIOP00007|Agregar||
+UNIOP00008|Anular||
+UNIOP00009|Propiedades||
+UNIOP00010|Permitir Transmisi�n?||
+UNIOP00011|Activar en Inicio?||
+UNIOP00012|km/h||
+UNIOP00013|mph||
+UNIOP00014|C||
+UNIOP00015|F||
+UNIOP00016|mm||
+UNIOP00017|pg||
+UNIOP00018|mm/d�a||
+UNIOP00019|pg/d�a||
+UNIOP00020|mm/hora||
+UNIOP00021|pg/hora||
+UNIOP00022|mm/med||
+UNIOP00023|pg/med||
+UNIOP00024|grd||
+UNIOP00025|mb||
+UNIOP00026|%||
+UNIOP00027|pg Hg||
+UNIOP00028|mm Hg||
+UNIOP00029|Fije el tiempo del sistema del GPS||
+UNIOP00030|Digipeat?||
+UNIOP00031|m||
+UNIOP00032|Apply|||
+UNIOP00033|Reset||
+UNIOP00034|min||
+UNIOP00035|hr||
+UNIOP00036|day||
+UNIOP00037|Send Control-E to get GPS data?||
+UNIOP00038|Add Delay||
+#
+# Seleccionar Estaci�n
+STCHO00001|Seleccionar Estaci�n||
+#
+# DESPLIEGUE ALARMA WX
+WPUPWXA001|Alerta del Tiempo||
+WPUPWXA002|Lista de alerta del Tiempo||
+#
+# Configurar Interfaces
+WPUPCIF001|Interfaces Instalados||
+WPUPCIF002|Elegir Tipo de interf�z||
+#
+# Configurar AX.25 TNC
+WPUPCAX001|Configurar AX.25 TNC||
+WPUPCAX002|AX.25 nombre de puerto||
+#
+# Nombres de dispositivos de la Interf�z
+IFDNL00000|Nada||
+IFDNL00001|TNC v�a el Puerto Serial||
+IFDNL00002|Serial TNC c/GPS m�s (cable HSP)||
+IFDNL00003|GPS v�a Puerto Serial||
+IFDNL00004|Est. Meteorol�gica v�a Puerto Serial||
+IFDNL00005|Conexi�n a un Servidor en Internet||
+IFDNL00006|AX.25 TNC||
+IFDNL00007|GPS Enlazado v�a el Servidor gpsd||
+IFDNL00008|Est. Meteorol�gica Enlazada a una RED||
+IFDNL00009|Serial TNC c/GPS m�s (cable AUX)||
+IFDNL00010|Serial KISS TNC||
+IFDNL00011|Red Base de Datos (Aun No Implementada)||
+IFDNL00012|Red AGWPE||
+IFDNL00013|Serial Multi-Port KISS TNC||
+IFDNL00014|SQL Database (Experimental)||
+#
+# Info dispositivo Interf�z
+IFDIN00000|%s %2d %s sobre serial %s   %s||
+IFDIN00001|%s %2d %s conectado a %s:%d   %s||
+IFDIN00002|%s %2d %s usando dispositivo nombrado %s   %s||
+IFDIN00003|%s %2d  %s  %s %s   %s||
+IFDIN00004|%s %2d  %s  %s %s:%d   %s||
+IFDIN00005|%s %2d  %s  %s %s   %s||
+IFDIN00006|  ABAJO    ||
+IFDIN00007|  ARRIBA   ||
+IFDIN00008|  ERROR    ||
+IFDIN00009|DESCONOCIDO||
+#
+# Control de la interf�z
+IFPUPCT000|Control de Interf�z||
+IFPUPCT001|Iniciar||
+IFPUPCT002|Detener||
+IFPUPCT003|Iniciar todos||
+IFPUPCT004|Detener todos||
+#
+# Control de I-Gate
+IGPUPCF000|I-Gate Opciones||
+IGPUPCF001|Desactiva todo el IGate tr�fico||
+IGPUPCF002|S�lo Permite tr�fico de RF->Inet||
+IGPUPCF003|Permite ambos tr�ficos RF<->Inet||
+IGPUPCF004|Igate -> RF Ruta   ||
+#
+# Estaci�n Meteorol�gica
+WXPUPSI000|Estaci�n meteorol�gica||
+WXPUPSI001|Tipo de estaci�n Meteorol�gica||
+WXPUPSI002|Datos Actuales||
+WXPUPSI003|Curso del viento||
+WXPUPSI004|Velocidad del viento||
+WXPUPSI005|R�faga del viento||
+WXPUPSI006|Temperatura||
+WXPUPSI007|Total lluvia||
+WXPUPSI008|Hoy Total lluvia||
+WXPUPSI009|Presi�n Barom�trica||
+WXPUPSI010|Humedad Relativa||
+WXPUPSI011|Peet Bros ULTIMETER 2000 Tipo (Modo Datos Log)||
+WXPUPSI012|Peet Bros ULTIMETER II Tipo||
+WXPUPSI013|Peet Bros ULTIMETER 2000 Tipo (Modo Paquete)||
+WXPUPSI014|Actual Tot. hora lluvia||
+WXPUPSI015|Ultimas 24 Tot. lluvias||
+WXPUPSI016|Cualim�tricos Q-Net||
+WXPUPSI017|Tipo Peet Bros ULTIMETER 2000 (Modo Completo)||
+WXPUPSI018|Punto de Roc�o||
+WXPUPSI019|Viento Alto||
+WXPUPSI020|Viento Fr�o||
+WXPUPSI021|Indice Caluroso||
+WXPUPSI022|3-Hr Baro||
+WXPUPSI023|Alta Temperat.||
+WXPUPSI024|Baja Temperat.||
+WXPUPSI025|Radio Shack WX-200/Oregon Scientific WM-918||
+WXPUPSI026|Davis Weather Monitor II/Wizard III/Vantage Pro||
+WXPUPSI027|LaCrosse WX-23xx||
+WXPUPSI028|Davis APRS Data Logger||
+#
+# Listas de Estaciones
+LHPUPNI000|Todas las estaciones||
+LHPUPNI001|Estaciones m�viles||
+LHPUPNI002|Estaciones Meteorol�gicas||
+LHPUPNI003|Estaciones locales (v�a TNC)||
+LHPUPNI004|Ultimas Estaciones||
+LHPUPNI005|Objetos y Art�culos||
+LHPUPNI006|Objetos y Art�culos Propio||
+LHPUPNI010| #||
+LHPUPNI011|Indicativo||
+LHPUPNI012|#Pack||
+LHPUPNI013|Ult.Posici�n||
+LHPUPNI014|Ruta||
+LHPUPNI015|PHG||
+LHPUPNI016|Comentarios||
+LHPUPNI100|CSE||
+LHPUPNI101|SPD||
+LHPUPNI102|ALT.||
+LHPUPNI103|Lat||
+LHPUPNI104|Long||
+LHPUPNI105|#Pack||
+LHPUPNI106|LSV||
+LHPUPNI107|CFMS||
+LHPUPNI108|DFMS||
+LHPUPNI200|CSE||
+LHPUPNI201|SPD||
+LHPUPNI202|GST||
+LHPUPNI203|Temp||
+LHPUPNI204|Hum||
+LHPUPNI205|Baro||
+LHPUPNI206|RN-H||
+LHPUPNI207|RNSM||
+LHPUPNI208|RN24||
+LHPUPNI209|Lat/Lon o UTM||
+#
+# Traza Alertas WX sobre mapas
+PULDNMAT01|Muestra mapa de alarma sobre otros mapas||
+PULDNMAT02|Muestra mapa de alarma bajo otros mapas||
+#
+# Error/popup mensajes
+POPEM00001|Localiza Error!||
+POPEM00002|La estaci�n %s no fue encontrada!||
+POPEM00003|Rastreo Error!||
+POPEM00004|Interf�z Error!||
+POPEM00005|Inv�lido nombre de puerto AX.25 %s||
+POPEM00006|Inv�lido nombre de puerto AX.25 %s||
+POPEM00007|Inv�lido Indicativo %s||
+POPEM00008|Inv�lido Indicativo AX.25 destinaci�n o digipeater||
+POPEM00009|No puedo abrir el s�calo AX.25, %s||
+POPEM00010|No puedo atar el s�calo AX.25, %s||
+POPEM00011|No puedo conectar al Indicativo AX.25, %s||
+POPEM00012|AX.25 error en la salida de UI||
+POPEM00013|AX.25 problema con el archivo axports||
+POPEM00014|AX.25 inv�lido nombre de puerto %s||
+POPEM00015|Error abriendo la interf�z %d, duro fallo||
+POPEM00016|Error abriendo la interf�z %d Tiempo agotado||
+POPEM00017|No hay mas interf�z disponible!||
+POPEM00018|Dato requerido - Simple L�nea de Mensaje|
+POPEM00019|El Puerto de transmisi�n est� "off" para puerto %d|
+POPEM00020|Error banco de Datos!|
+POPEM00021|El soporte de AX.25 no est� compilado en Xastir!||
+POPEM00022|Error de entrada!|
+POPEM00023|Nombre de locaci�n no especificada!|
+POPEM00024|Nombre de Locaci�n especificada en uso!|
+POPEM00025|No Encontrado!||
+POPEM00026|El Rastreo empezar� cuando el aparezca||
+POPEM00027|Info Impropia. Algunos campos vac�o?||
+POPEM00028|No se puede abrir el archivo||
+POPEM00029|Encontrado!||
+POPEM00030|S�mbolo de Estaci�n Meteorol�gica||
+POPEM00031|Cambiado a s�mbolo WX '/_', otras opciones:  '\_'  '/W'  y  '\W'||
+POPEM00032|Aviso: Usando S�mbolo del National Weather Service!||
+POPEM00033|No GPS Data!||
+POPEM00034|Disactivando TX de Mi Posici�n Hasta ver Data de GPS V�lido!||
+POPEM00035|Warning||
+POPEM00036|Notice||
+POPEM00037|HSP interface present: GPS timing has been increased||
+POPEM00038|Name Conflicts With Existing Object/Item/Station||
+POPEM00039|Illegal characters found, substituting periods in their place||
+POPEM00040|Custom outgoing path was lost||
+POPEM00041|Processing another file.  Wait a bit, then try again||
+POPEM00042|Object not owned by me! Try adopting the object first.||
+POPEM00043|Not an Object/Item!||
+POPEM00044|Fetch Findu Trail: Failed||
+POPEM00045|Fetch Findu Trail: Complete||
+POPEM00046|Berkeley DB header/shared library do NOT match! Disabling map cache.||
+POPEM00047|Global transmit is DISABLED. Emergency beacons are NOT going out!||
+POPEM00048|Emergency Beacon Mode!||
+POPEM00049|EMERGENCY BEACON MODE, transmitting every 60 seconds!||
+POPEM00050|Interfaces or posits/transmits DISABLED.  Emergency beacons are NOT going out!||
+POPEM00051|Altnet is enabled (Configure->Defaults dialog)||
+POPEM00052|Callsign is EMPTY!||
+POPEM00053|Message is EMPTY!||
+POPEM00054|We're trying to talk to ourselves!||
+#
+# Salto de Locaci�n
+JMLPO00001|Localizaci�n de Mapa||
+JMLPO00002|IR!||
+JMLPO00003|Nombre de Nueva Localizaci�n:||
+#
+# Boletines 
+BULMW00001|Boletines||
+BULMW00002|L�mite de Rango a (0, no hay l�mite)||
+BULMW00003|Cambio de Rango||
+#
+# Tr�fico de todo los mensajes
+AMTMW00001|Tr�fico de todos los mensajes||
+AMTMW00002|L�mite de Rango a (0, no hay l�mite)||
+#
+# Cadenas del Sintetizador
+SPCHSTR001|kil�metros||
+SPCHSTR002|metros||
+SPCHSTR003|millas||
+SPCHSTR004|yardas||
+SPCHSTR005|%s, distancia es %d %s.||
+SPCHSTR006|%s, distancia es %.1f %s.||
+SPCHSTR007|%s, distancia es %d %s %s %s.||
+SPCHSTR008|%s, distancia es %.1f %s %s %s.||
+SPCHSTR009|Nueva Alerta de WX||
+SPCHSTR010|Nueva LLamada||
+SPCHSTR011|O�do, D X, %s, en distancia de %.1f %s||
+#
+SPCHDIRN00|norte de||
+SPCHDIRS00|sur de||
+SPCHDIRE00|este de||
+SPCHDIRW00|oeste de||
+SPCHDIRNE0|noreste de||
+SPCHDIRNW0|noroeste de||
+SPCHDIRSE0|sureste de||
+SPCHDIRSW0|suroeste de||
+#
+# Di�logo de seleci�n de S�mbolo
+SYMSEL0001|Seleccione S�mbolo||
+SYMSEL0002|Tabla de S�mbolo primario||
+SYMSEL0003|Tabla de S�mbolo Secundario||
+#
+# Di�logo de la Propiedades de Impresora
+PRINT0001|Propiedades de Impresora||
+PRINT0002|Ancho del Paper||
+PRINT0003|Auto-Rotar Imagen
+PRINT0004|Rotar Imagen 90� CCW||
+PRINT0005|Auto-Balancear Imagen||
+PRINT0006|Balanza:||
+PRINT0007|Forza el predefinido color de fondo a blanco||
+PRINT0008|Imprime en Blanco y Negro||
+PRINT0016|Colores Revertidos||
+PRINT0009|Resoluci�n de Postscript:||
+PRINT0010|Prevista||
+PRINT0011|Imprimir al archivo||
+PRINT0012|Guardar imagen a un archivo...||
+PRINT0013|Convirtiendo a Postscript...||
+PRINT0014|Creando archivo de impresi�n Finalizado||
+PRINT0015|Estado de Impresora||
+#
+# Di�logo de la Propiedades de Impresora
+PRINT1001|Direct to:||
+PRINT1002|Via Previewer:||
+#
+# Di�logo de localizar forma
+FEATURE001|Nombre:||
+FEATURE002|Estado/Provincia:||
+FEATURE003|Pais:||
+FEATURE004|Cuadratura del Mapa:||
+FEATURE005|Tipo:||
+FEATURE006|GNIS Archivo:||
+FEATURE007|Address:||
+FEATURE008|City:||
+FEATURE009|Mark Destination||
+FEATURE010|Zip Code:||
+FEATURE011|Geocoding File||
+#
+# Di�logo de Calcular Coordenada
+COORD001|Calcula Coordenada||
+COORD002|Calc||
+COORD003|Calcular||
+COORD004|Limpiar||
+COORD005|UTM||
+COORD006|Latitud o||
+COORD007|Longitud o||
+COORD008|Zona||
+COORD009|UTM Hacia Este||
+COORD010|UTM Hacia Norte||
+COORD011|               Decimal Degrees:  ||
+COORD012|       Degrees/Decimal Minutes:  ||
+COORD013|  Degrees/Minutes/Dec. Seconds:  ||
+COORD014| Universal Transverse Mercator:  ||
+COORD015|Military Grid Reference System:  ||
+COORD016|       Maidenhead Grid Locator:  ||
+COORD017| **       Sorry, your input was not recognized!        **||
+COORD018| **   Please use one of the following input formats:   **||
+#
+# Di�logo Baliza Inteligente
+SMARTB001|Baliza Inteligente||
+SMARTB002|Alta Proporci�n (secs):||
+SMARTB003|Alta Velocidad (mph):||
+SMARTB004|Alta Velocidad (kph):||
+SMARTB005|Baja Proporci�n (mins):||
+SMARTB006|Baja Velocidad (mph):||
+SMARTB007|Baja Velocidad (kph):||
+SMARTB008|M�nima Vuelta (grados):||
+SMARTB009|Vuelta de declive:||
+SMARTB010|Tiempo de Espera (secs):||
+SMARTB011|Activar Baliza Inteligente(tm)||
+#
+# Di�logo Ajuste de Gamma
+GAMMA001|Ajuste Correcci�n de Gamma||
+GAMMA002|Correcci�n Gamma||
+#
+# Map labels font Dialog
+MAPFONT001|Change Fonts||
+MAPFONT002|Fonts||
+MAPFONT003|Map Font Min�sculo||
+MAPFONT004|Map Font Peque�o||
+MAPFONT005|Map Font Medio||
+MAPFONT006|Map Font Grande||
+MAPFONT007|Map Font Enorme||
+MAPFONT008|Map Font Border||
+MAPFONT009|Menu Font||
+MAPFONT010|Station Font||
+MAPFONT011|ATV ID Font||
+#
+# Distancia/Orientaci�n en l�nea de estado
+PULDNDB001|Estado de Distancia/Orientaci�n||
+#
+# Transferir Operaciones de GPS
+GPS001|Transferir GPS||
+GPS002|Nombre de Archivo||
+GPS003|Seleccionar Color||
+GPS004|Rojo||
+GPS005|Verde||
+GPS006|Negro||
+GPS007|Blanco||
+GPS008|Naranja||
+GPS009|Azul||
+GPS010|Amarillo||
+GPS011|Violeta||
+#
+# Di�logo de Propiedades de Mapa
+MAPP001|Propiedades de Mapa||
+MAPP002|Max   Min  Dibuja   Mapa  USGS  Auto||
+MAPP003|Zoom  Zoom  Capa  Llenado DRG   Mapa Sendero/NombreArchivo||
+MAPP004|Cambie Capa->||
+MAPP005|Llenado->||
+MAPP006|S�||
+MAPP007|No||
+MAPP008|Automapas->||
+MAPP009|Max Zoom->||
+MAPP010|Min Zoom->||
+MAPP011|Auto||
+MAPP012|USGS DRG->||
+#
+# Cadenas del Tiempo
+TIME001|D�a||
+TIME002|D�as||
+TIME003|Hora||
+TIME004|Horas||
+TIME005|Minuto||
+TIME006|Minutos||
+TIME007|Segundo||
+TIME008|Segundos||
+#
+#
+# Map Caching
+CACHE001|Map now cached||
+CACHE002|Loading Cached Map||
+CACHE003|Map not found in cache...||
+#
+#
+# Map Screen Misc
+RANGE001|RANGE SCALE||
+#
+#
+# GPS Status
+GPSS001|WAAS or PPS||
+GPSS002|DGPS||
+GPSS003|Valid SPS||
+GPSS004|Invalid||
+GPSS005|Sats/View||
+GPSS006|Fix||
+GPSS007|!GPS data is older than 30 seconds!||
+GPSS008|Simulation||
+GPSS009|Manual||
+GPSS010|Estimated||
+GPSS011|Float RTK||
+GPSS012|RTK||
+#
+#
+# Popup cad_dialog to obtain CAD object data
+CADPUD001|Area Object||
+CADPUD002|Area Label:||
+CADPUD003|Comment:||
+CADPUD004|Probability (%):||
+CADPUD005|OK||
+CADPUD006|CAD Dialog||
+CADPUD007|Show/Edit Details||
+CADPUD008|Cancel||
+CADPUD009|Delete CAD objects?||
+CADPUD010|Delete All||
+CADPUD011|Delete Selected||
+CADPUD012|Solid||
+CADPUD013|Dashed||
+CADPUD014|Double Dash||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA001|XASTIR Map of %s (upper left) to %s (lower right).  UTM %d m grid, %s datum. ||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA002|XASTIR Map of %s (upper left) to %s %s (lower right).  Lat/Long grid, %s datum.||
+#
+#
+# Format strings for map metadata in top border
+#"XASTIR Map of <utm_coord> (upper left) to <utm_coord> (lower right).  UTM <grid_size> m grid, <wgs84> datum. ",
+MDATA003|XASTIR Map of %s (upper left) to %s (lower right).  UTM zones, %s datum.||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST001|MySQL (lat/long)||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST002|Postgreql with Postgis||
+#
+# Text interpretation of integer values of database type and schema type
+# used for sql database configuration in interface_gui.c
+# DB_MYSQL 
+XADBMST003|MySQL (spatial)||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA01|Xastir Simple Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA02|Xastir CAD Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA03|Xastir full Schema||
+# XASTIR_SCHEMA_SIMPLE]
+XASCHEMA04|APRSWorld Schema||
diff --git a/config/nwsc_ddmmyy.dbfawk b/config/nwsc_ddmmyy.dbfawk
new file mode 100644
index 0000000..a03b8f9
--- /dev/null
+++ b/config/nwsc_ddmmyy.dbfawk
@@ -0,0 +1,55 @@
+# $Id: nwsc_ddmmyy.dbfawk,v 1.23 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   label_color - color for label
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county polygon shapefiles
+# which are named c_ddmmyy.dbf.  These are used for WX alerts but can also
+# be used as a map of all US counties.  For the WX alert feature, the
+# key is set to the concatentation of the STATE and FIPS county code
+# in the same format as the alert->title (e.g. WI_C037).
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATE:CWA:COUNTYNAME:FIPS:TIME_ZONE:FE_AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="COUNTYNAME:STATE:FIPS";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=1; fill_color=7; color=8; name=""; filled=1; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+# name: name is just the county name.
+/^COUNTYNAME=(.*)$/ {name="$1"; font_size=4; next}
+# also append "County" to the name except for Louisiana, use Parish
+# (is this the only state that calls them something other than county?):
+# XXX check this whole LA thing.  I think they call them parishes.
+/^STATE=(LA)$/ {name="$name Parish"; key="$1"; next}
+/^STATE=(..)$/ {name="$name County"; key="$1"; next}
+/^FIPS=..(...)$/ {key="$(key)_C$1"; next}
+
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/nwsc_ddmmyy_09.dbfawk b/config/nwsc_ddmmyy_09.dbfawk
new file mode 100644
index 0000000..b48f6cb
--- /dev/null
+++ b/config/nwsc_ddmmyy_09.dbfawk
@@ -0,0 +1,59 @@
+# $Id: nwsc_ddmmyy_09.dbfawk,v 1.4 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   label_color - color for label
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county polygon shapefiles
+# which are named c_ddmmyy.dbf.  These are used for WX alerts but can also
+# be used as a map of all US counties.  For the WX alert feature, the
+# key is set to the concatentation of the STATE and FIPS county code
+# in the same format as the alert->title (e.g. WI_C037).
+#
+# This DBFAWK file matches the set of county shapefiles that was published
+# by NOAA in 2009, and differs from the earlier format.  Shapefiles from 2008
+# are matched by the file "nwsc_ddmmyy.dbfawk" instead.
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID:SHAPE_LENG:SHAPE_AREA:STATE:CWA:COUNTYNAME:FIPS:TIME_ZONE:FE_AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="COUNTYNAME:STATE:FIPS";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=1; fill_color=7; color=8; name=""; filled=1; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+# name: name is just the county name.
+/^COUNTYNAME=(.*)$/ {name="$1"; font_size=4; next}
+# also append "County" to the name except for Louisiana, use Parish
+# (is this the only state that calls them something other than county?):
+# XXX check this whole LA thing.  I think they call them parishes.
+/^STATE=(LA)$/ {name="$name Parish"; key="$1"; next}
+/^STATE=(..)$/ {name="$name County"; key="$1"; next}
+/^FIPS=..(...)$/ {key="$(key)_C$1"; next}
+
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/nwsc_ddmmyy_09b.dbfawk b/config/nwsc_ddmmyy_09b.dbfawk
new file mode 100644
index 0000000..c9f8d68
--- /dev/null
+++ b/config/nwsc_ddmmyy_09b.dbfawk
@@ -0,0 +1,59 @@
+# $Id: nwsc_ddmmyy_09b.dbfawk,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   label_color - color for label
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county polygon shapefiles
+# which are named c_ddmmyy.dbf.  These are used for WX alerts but can also
+# be used as a map of all US counties.  For the WX alert feature, the
+# key is set to the concatentation of the STATE and FIPS county code
+# in the same format as the alert->title (e.g. WI_C037).
+#
+# This DBFAWK file matches the set of county shapefiles that was published
+# by NOAA in 2009, and differs from the earlier format.  Shapefiles from 2008
+# are matched by the file "nwsc_ddmmyy.dbfawk" instead.
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID_1:OBJECTID:STATE:CWA:COUNTYNAME:FIPS:TIME_ZONE:FE_AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="COUNTYNAME:STATE:FIPS";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=1; fill_color=7; color=8; name=""; filled=1; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+# name: name is just the county name.
+/^COUNTYNAME=(.*)$/ {name="$1"; font_size=4; next}
+# also append "County" to the name except for Louisiana, use Parish
+# (is this the only state that calls them something other than county?):
+# XXX check this whole LA thing.  I think they call them parishes.
+/^STATE=(LA)$/ {name="$name Parish"; key="$1"; next}
+/^STATE=(..)$/ {name="$name County"; key="$1"; next}
+/^FIPS=..(...)$/ {key="$(key)_C$1"; next}
+
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/nwsc_ddmmyy_10.dbfawk b/config/nwsc_ddmmyy_10.dbfawk
new file mode 100644
index 0000000..072b3b1
--- /dev/null
+++ b/config/nwsc_ddmmyy_10.dbfawk
@@ -0,0 +1,59 @@
+# $Id: nwsc_ddmmyy_10.dbfawk,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   label_color - color for label
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county polygon shapefiles
+# which are named c_ddmmyy.dbf.  These are used for WX alerts but can also
+# be used as a map of all US counties.  For the WX alert feature, the
+# key is set to the concatentation of the STATE and FIPS county code
+# in the same format as the alert->title (e.g. WI_C037).
+#
+# This DBFAWK file matches the set of county shapefiles that was published
+# by NOAA in 2009, and differs from the earlier format.  Shapefiles from 2008
+# are matched by the file "nwsc_ddmmyy.dbfawk" instead.
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID_1:OBJECTID_2:OBJECTID:STATE:ZONE:CWA:NAME:STATE_ZONE:TIME_ZONE:FE_AREA:LON:LAT:SHAPE_LENG:SHAPE_LE_1:Shape_Le_2:Shape_Area";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=1; fill_color=7; color=8; name=""; filled=1; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+# name: name is just the county name.
+#/^COUNTYNAME=(.*)$/ {name="$1"; font_size=4; next}
+# also append "County" to the name except for Louisiana, use Parish
+# (is this the only state that calls them something other than county?):
+# XXX check this whole LA thing.  I think they call them parishes.
+#/^STATE=(LA)$/ {name="$name Parish"; key="$1"; next}
+#/^STATE=(..)$/ {name="$name County"; key="$1"; next}
+#/^FIPS=..(...)$/ {key="$(key)_C$1"; next}
+
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/nwsc_ddmmyy_10a.dbfawk b/config/nwsc_ddmmyy_10a.dbfawk
new file mode 100644
index 0000000..c1e0950
--- /dev/null
+++ b/config/nwsc_ddmmyy_10a.dbfawk
@@ -0,0 +1,59 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   label_color - color for label
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county polygon shapefiles
+# which are named c_ddmmyy.dbf.  These are used for WX alerts but can also
+# be used as a map of all US counties.  For the WX alert feature, the
+# key is set to the concatentation of the STATE and FIPS county code
+# in the same format as the alert->title (e.g. WI_C037).
+#
+# This DBFAWK file matches the set of county shapefiles that was published
+# by NOAA in 2009, and differs from the earlier format.  Shapefiles from 2008
+# are matched by the file "nwsc_ddmmyy.dbfawk" instead.
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID:ID:WFO:GL_WFO:SHAPE_LENG:SHAPE_AREA:MZ:AJOIN0:AJOIN1:STATE:CWA:COUNTYNAME:FIPS:TIME_ZONE:FE_AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=1; fill_color=7; color=8; name=""; filled=1; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+# name: name is just the county name.
+#/^COUNTYNAME=(.*)$/ {name="$1"; font_size=4; next}
+# also append "County" to the name except for Louisiana, use Parish
+# (is this the only state that calls them something other than county?):
+# XXX check this whole LA thing.  I think they call them parishes.
+#/^STATE=(LA)$/ {name="$name Parish"; key="$1"; next}
+#/^STATE=(..)$/ {name="$name County"; key="$1"; next}
+#/^FIPS=..(...)$/ {key="$(key)_C$1"; next}
+
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/nwshzddmmyy.dbfawk b/config/nwshzddmmyy.dbfawk
new file mode 100644
index 0000000..de4b393
--- /dev/null
+++ b/config/nwshzddmmyy.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwshzddmmyy.dbfawk,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code reformated
+# to match the alert->title.  For example AN_Z081.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="WFO:NAME:LAT:LON";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+#/^ID=(..)(.*)$/ {key="$1_$2"; next}
+#/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsmzddmmyy.dbfawk b/config/nwsmzddmmyy.dbfawk
new file mode 100644
index 0000000..73d7989
--- /dev/null
+++ b/config/nwsmzddmmyy.dbfawk
@@ -0,0 +1,41 @@
+# $Id: nwsmzddmmyy.dbfawk,v 1.21 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:WFO:NAME:GL_WFO:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(..)(.*)$/ {key="$1_$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsmzddmmyy_09.dbfawk b/config/nwsmzddmmyy_09.dbfawk
new file mode 100644
index 0000000..71ce7ac
--- /dev/null
+++ b/config/nwsmzddmmyy_09.dbfawk
@@ -0,0 +1,41 @@
+# $Id: nwsmzddmmyy_09.dbfawk,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID:ID:WFO:NAME:GL_WFO:LON:LAT:Shape_Leng:Shape_Area";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(..)(.*)$/ {key="$1_$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsmzddmmyy_11.dbfawk b/config/nwsmzddmmyy_11.dbfawk
new file mode 100644
index 0000000..6583fb3
--- /dev/null
+++ b/config/nwsmzddmmyy_11.dbfawk
@@ -0,0 +1,41 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:WFO:GL_WFO:NAME:AJOIN0:AJOIN1:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(..)(.*)$/ {key="$1_$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsmzoddmmyy.dbfawk b/config/nwsmzoddmmyy.dbfawk
new file mode 100644
index 0000000..8e57938
--- /dev/null
+++ b/config/nwsmzoddmmyy.dbfawk
@@ -0,0 +1,41 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:WFO:NAME:WFO_AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(.*)$/ {key="$1"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsozddap12.dbfawk b/config/nwsozddap12.dbfawk
new file mode 100644
index 0000000..44c1ea9
--- /dev/null
+++ b/config/nwsozddap12.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwsozddap12.dbfawk,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code reformated
+# to match the alert->title.  For example AN_Z081.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:WFO:LON:LAT:Location:Name";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(..)(.*)$/ {key="$1_$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsozddmmyy.dbfawk b/config/nwsozddmmyy.dbfawk
new file mode 100644
index 0000000..9a0b147
--- /dev/null
+++ b/config/nwsozddmmyy.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwsozddmmyy.dbfawk,v 1.19 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code reformated
+# to match the alert->title.  For example AN_Z081.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:WFO:NAME:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(..)(.*)$/ {key="$1_$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsozddmmyy_09.dbfawk b/config/nwsozddmmyy_09.dbfawk
new file mode 100644
index 0000000..9dcd349
--- /dev/null
+++ b/config/nwsozddmmyy_09.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwsozddmmyy_09.dbfawk,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS offshore marine zone area polygon shapefiles
+# which are named ozddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the ID code reformated
+# to match the alert->title.  For example AN_Z081.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:WFO:LON:LAT:NAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="ID:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^ID=(..)(.*)$/ {key="$1_$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsw_ddjn12.dbfawk b/config/nwsw_ddjn12.dbfawk
new file mode 100644
index 0000000..aecede2
--- /dev/null
+++ b/config/nwsw_ddjn12.dbfawk
@@ -0,0 +1,41 @@
+# $Id: nwsw_ddjn12.dbfawk,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county warning area polygon shapefiles
+# which are named w_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the CWA code
+# reformated to match alert->title.  For example: CW_ATAE for CWA TAE.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="CWA:WFO:Lon:Lat";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="WFO";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^WFO=(.*)$/ {name="$1"; key="CW_A$1"; next}
diff --git a/config/nwsw_ddmmyy.dbfawk b/config/nwsw_ddmmyy.dbfawk
new file mode 100644
index 0000000..cfbf462
--- /dev/null
+++ b/config/nwsw_ddmmyy.dbfawk
@@ -0,0 +1,41 @@
+# $Id: nwsw_ddmmyy.dbfawk,v 1.19 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county warning area polygon shapefiles
+# which are named w_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the CWA code
+# reformated to match alert->title.  For example: CW_ATAE for CWA TAE.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="WFO:CWA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="WFO";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^WFO=(.*)$/ {name="$1"; key="CW_A$1"; next}
diff --git a/config/nwsw_ddmmyy_09.dbfawk b/config/nwsw_ddmmyy_09.dbfawk
new file mode 100644
index 0000000..82a41af
--- /dev/null
+++ b/config/nwsw_ddmmyy_09.dbfawk
@@ -0,0 +1,41 @@
+# $Id: nwsw_ddmmyy_09.dbfawk,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county warning area polygon shapefiles
+# which are named w_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the CWA code
+# reformated to match alert->title.  For example: CW_ATAE for CWA TAE.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="WFO:CWA:AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="WFO";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^WFO=(.*)$/ {name="$1"; key="CW_A$1"; next}
diff --git a/config/nwsw_ddmmyy_10.dbfawk b/config/nwsw_ddmmyy_10.dbfawk
new file mode 100644
index 0000000..f6b19fb
--- /dev/null
+++ b/config/nwsw_ddmmyy_10.dbfawk
@@ -0,0 +1,41 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS county warning area polygon shapefiles
+# which are named w_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the CWA code
+# reformated to match alert->title.  For example: CW_ATAE for CWA TAE.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="AJOIN0:AJOIN1:WFO:CWA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="WFO";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^WFO=(.*)$/ {name="$1"; key="CW_A$1"; next}
diff --git a/config/nwsz1ddmmyy.dbfawk b/config/nwsz1ddmmyy.dbfawk
new file mode 100644
index 0000000..82b2ca6
--- /dev/null
+++ b/config/nwsz1ddmmyy.dbfawk
@@ -0,0 +1,42 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATE:ZONE:CWA:NAME:STATE_ZONE:TIME_ZONE:FE_AREA:LON:LAT";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsz_ddmmyy.dbfawk b/config/nwsz_ddmmyy.dbfawk
new file mode 100644
index 0000000..58ee742
--- /dev/null
+++ b/config/nwsz_ddmmyy.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwsz_ddmmyy.dbfawk,v 1.25 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATE:ZONE:CWA:NAME:STATE_ZONE:TIME_ZONE:FE_AREA:CEN_LAT:CEN_LON:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsz_ddmmyy_09.dbfawk b/config/nwsz_ddmmyy_09.dbfawk
new file mode 100644
index 0000000..fe3bbb4
--- /dev/null
+++ b/config/nwsz_ddmmyy_09.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwsz_ddmmyy_09.dbfawk,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID:STATE:ZONE:CWA:NAME:STATE_ZONE:TIME_ZONE:FE_AREA:CEN_LAT:CEN_LON:SHAPE_LENG:SHAPE_AREA:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsz_ddmmyy_10.dbfawk b/config/nwsz_ddmmyy_10.dbfawk
new file mode 100644
index 0000000..e81b380
--- /dev/null
+++ b/config/nwsz_ddmmyy_10.dbfawk
@@ -0,0 +1,42 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID:STATE:ZONE:CWA:NAME:STATE_ZONE:TIME_ZONE:FE_AREA:SHAPE_LENG:SHAPE_AREA:FI:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsz_ddmmyy_10b.dbfawk b/config/nwsz_ddmmyy_10b.dbfawk
new file mode 100644
index 0000000..e271c91
--- /dev/null
+++ b/config/nwsz_ddmmyy_10b.dbfawk
@@ -0,0 +1,42 @@
+# $Id: nwsz_ddmmyy_10b.dbfawk,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="OBJECTID:STATE:CWA:TIME_ZONE:FE_AREA:ZONE:NAME:STATE_ZONE:AJOIN0:AJOIN1:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsz_ddmmyy_10c.dbfawk b/config/nwsz_ddmmyy_10c.dbfawk
new file mode 100644
index 0000000..3fd30e2
--- /dev/null
+++ b/config/nwsz_ddmmyy_10c.dbfawk
@@ -0,0 +1,42 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATE:CWA:TIME_ZONE:FE_AREA:ZONE:NAME:STATE_ZONE:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwsz_ddmmyy_11.dbfawk b/config/nwsz_ddmmyy_11.dbfawk
new file mode 100644
index 0000000..2e0e9e2
--- /dev/null
+++ b/config/nwsz_ddmmyy_11.dbfawk
@@ -0,0 +1,43 @@
+# $Id: nwsz_ddmmyy_11.dbfawk,v 1.2 2012/03/02 20:10:35 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+#dbfinfo="OBJECTID:STATE:CWA:TIME_ZONE:FE_AREA:ZONE:NAME:STATE_ZONE:LON:LAT:SHORTNAME:Shape_Leng:Shape_Area";
+dbfinfo="OBJECTID:STATE:CWA:TIME_ZONE:FE_AREA:ZONE:NAME:STATE_ZONE:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/nwszoddmmyy.dbfawk b/config/nwszoddmmyy.dbfawk
new file mode 100644
index 0000000..54b0ff4
--- /dev/null
+++ b/config/nwszoddmmyy.dbfawk
@@ -0,0 +1,42 @@
+# $Id$
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map NWS state zone area polygon shapefiles
+# which are named z_ddmmyy.dbf.  These are used for WX alerts.
+# For the WX alert feature, the key is set to the STATE_ZONE code,
+# reformatted to match alert->title (e.g. KS033 is KS_Z033).
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATE:ZONE:CWA:NAME:STATE_ZONE:TIME_ZONE:FE_AREA:LON:LAT:SHORTNAME";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="STATE_ZONE:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key="BOGUS"; lanes=2; fill_color=7; color=8; name=""; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=512; label_color=20; font_size=2; symbol=""}
+
+/^STATE_ZONE=(..)(.*)$/ {key="$1_Z$2"; next}
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/pointlm.dbfawk b/config/pointlm.dbfawk
new file mode 100644
index 0000000..c7a299e
--- /dev/null
+++ b/config/pointlm.dbfawk
@@ -0,0 +1,63 @@
+# $Id: pointlm.dbfawk,v 1.4 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for POINTLM
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+# 2007FE = dbfinfo="STATEFP:COUNTYFP:COUNTYNS:POINTID:FULLNAME:MTFCC";
+dbfinfo="STATEFP:COUNTYFP:ANSICODE:POINTID:FULLNAME:MTFCC";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="FULLNAME:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=6; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+# item locations
+/^MTFCC=C3/ {display_level=512;color=50; next}
+# Hospitals
+/^MTFCC=K12/ {filled=1; fill_color=12; label_color=12; display_level=256; label_level=128; font_size=12; next}
+# Schools
+/^MTFCC=K25/ {filled=1; fill_color=5; label_color=5; display_level=256; label_level=64; font_size=10; next}
+# Airports
+/^MTFCC=K24/ {filled=1; fill_color=13; label_color=13; display_level=256; label_level=128; font_size=12; next}
+# buildings
+/^MTFCC=K/ {filled=1; fill_color=2; label_color=2; display_level=256; next}
+# PLCC
+/^MTFCC=L/ {display_level=0; next}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
+
diff --git a/config/predefined_EVENT.sys b/config/predefined_EVENT.sys
new file mode 100644
index 0000000..aac68ec
--- /dev/null
+++ b/config/predefined_EVENT.sys
@@ -0,0 +1,109 @@
+#
+# $Id: predefined_EVENT.sys,v 1.7 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2005-2012  The Xastir Group
+#
+# This file contains definitions for the Create SAR objects menu
+#
+# The objects defined here are typical Public Service Event objects. 
+#
+# The objects defined here are ones that might be used in a public
+# service event such as a 5k race.  Customize this file to fit your 
+# needs.
+#
+# Typical modifications include internationalizing the names and menu text 
+# and adding your own custom objects.  
+#
+# To select this file as the source of custom objects in the Create SAR
+# objects menu, use the Load SAR objects menu options in the Configure
+# defaults dialog (File/Configure/Defaults).
+# 
+# Lines begining with # are comments and will be ignored.
+#
+# Each line contains a tab separated variable and value pair.
+# Each set of lines defines an object as specified on the prepared
+# objects menu.  Each set of lines must have variables defined in the
+# following order:
+#
+# NAME  The name of the object.
+#       Maximum length = MAX_CALLSIGN - 1 or - 2, to allow for Name1, Name2
+#       incrementing numbers with multiple objects.
+#       If name ends with a - then the first object will be called Name-1,
+#       the second Name-2, and so on.  If name does not end with a - then
+#       The first object will be called Name, the second Name2.
+# PAGE  The APRS symbol code page, / or \
+#       Maximum length = 1 character.
+# SYMBOL        The APRS symbol specifier.
+        Maximum length = 1 character.
+# DATA  Additional data (such as probability circles) to follow the symbol in
+#       the APRS string for the object
+#       Use DATA NULL if there is no additional data, or omit the DATA line.
+#       Maximum length =  PREDEFINED_OBJECT_DATA_LENGTH = 44
+# MENU  The text to appear on the prepared objects menu for this object.
+#       Maximum length = 25 characters.
+# HIDDENCHILD	NO for entries that appear on the menu.  YES for a second
+# 	object to be created at the same time as the one above it.
+#	This is a workaround to create an IPP and an IPP_ with different
+#  	probability circles in the same place at the same time.
+#       YES is case sensitive.  
+#       HIDDENCHILD must be the last line in each object.
+#
+# NAME, PAGE, SYMBOL, MENU, and HIDDENCHILD are required for each object.
+#
+# Each set of lines specifying an object should be separated by a blank line 
+# for clarity.  Blank lines are ignored.  
+#
+# The maximum number of objects that can be shown on the predefined object
+# menu is defined by the constant MAX_NUMBER_OF_PREDEFINED_OBJECTS.
+
+NAME	ICP
+PAGE	/
+SYMBOL	c
+DATA	NULL
+MENU	ICP: Command Post	
+HIDDENCHILD	NO
+
+NAME	Water
+PAGE	/
+SYMBOL	w
+DATA	NULL
+MENU	Water
+HIDDENCHILD	NO
+
+# FirstAid post
+# "FirstAid" as name will only alow FirstAid1 to FirstAid9
+# due to the default length constraint on object names.
+NAME	Aid
+#NAME	FirstAid
+#NAME	Aid-
+PAGE	/
+# A is blue field with white cross, + is red cross
+SYMBOL	A
+#SYMBOL	+
+DATA	NULL
+MENU	Aid: First Aid
+#MENU	First Aid
+#MENU	Aid-n: First Aid
+HIDDENCHILD	NO
+
+NAME	Staging
+PAGE	S
+SYMBOL	0
+DATA	NULL
+MENU	Staging
+HIDDENCHILD	NO
+
+NAME	Waypt-
+PAGE	\
+SYMBOL	m
+DATA	NULL
+MENU	Waypt-n: Waypoint
+HIDDENCHILD	NO
+
+NAME	Toilets
+PAGE	\
+SYMBOL	r
+DATA	NULL
+MENU	Toilets
+HIDDENCHILD	NO
+
diff --git a/config/predefined_SAR.sys b/config/predefined_SAR.sys
new file mode 100644
index 0000000..f565a81
--- /dev/null
+++ b/config/predefined_SAR.sys
@@ -0,0 +1,135 @@
+#
+# $Id: predefined_SAR.sys,v 1.8 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2005-2012  The Xastir Group
+#
+# This file contains definitions for the Create SAR objects menu
+#
+# The objects defined here are typical Search and Rescue and ICS objects.
+#
+# You may modify this file to produce a custom set of prepared objects.
+# Typical modification would be changing probability circles from 
+# miles to kilometers, placing probability circles around the PLS 
+# instead of the IPP, internationalizing the names and menu text, 
+# and adding your own standard objects.  
+# 
+# To select this file as the source of custom objects in the Create SAR
+# objects menu, use the Load SAR objects menu options in the Configure
+# defaults dialog (File/Configure/Defaults).
+# 
+# Lines begining with # are comments and will be ignored.
+#
+# Each line contains a tab separated variable and value pair.
+# Each set of lines defines an object as specified on the prepared
+# objects menu.  Each set of lines must have variables defined in the
+# following order:
+#
+# NAME	The name of the object.
+#       Maximum length = MAX_CALLSIGN - 1 or - 2, to allow for Name1, Name2
+#       incrementing numbers with multiple objects.
+#       If name ends with a - then the first object will be called Name-1,
+#       the second Name-2, and so on.  If name does not end with a - then
+#       The first object will be called Name, the second Name2.
+# PAGE	The APRS symbol code page, / or \
+#       Maximum length = 1 character.
+# SYMBOL	The APRS symbol specifier.
+        Maximum length = 1 character.
+# DATA	Additional data (such as probability circles) to follow the symbol in 
+#	the APRS string for the object
+#       Use DATA NULL if there is no additional data, or omit the DATA line.
+#       Maximum length =  PREDEFINED_OBJECT_DATA_LENGTH = 44
+# MENU	The text to appear on the prepared objects menu for this object.
+#       Maximum length = 25 characters.
+# HIDDENCHILD	NO for entries that appear on the menu.  YES for a second
+# 	object to be created at the same time as the one above it.
+#	This is a workaround to create an IPP and an IPP_ with different
+#  	probability circles in the same place at the same time.
+#       YES is case sensitive.  
+#       HIDDENCHILD must be the last line in each object.
+#
+# NAME, PAGE, SYMBOL, MENU, and HIDDENCHILD are required for each object.
+#
+# Each set of lines specifying an object should be separated by a blank line 
+# for clarity.  Blank lines are ignored.  
+#
+# The maximum number of objects that can be shown on the predefined object
+# menu is defined by the constant MAX_NUMBER_OF_PREDEFINED_OBJECTS.
+
+NAME	ICP
+PAGE	/
+SYMBOL	c
+DATA	NULL
+MENU	ICP: Command Post	
+HIDDENCHILD	NO
+
+NAME	Staging
+PAGE	S
+SYMBOL	0
+DATA	NULL
+MENU	Staging
+HIDDENCHILD	NO
+
+NAME	IPP
+PAGE	/
+SYMBOL	/
+#circles at .75 and 1 miles
+DATA	Pmin0.75,Pmax1.0
+#circles at 2 and 3 kilometers
+#DATA	Pmin1.24,Pmax1.86
+MENU	IPP: InitialPlanningPoint
+HIDDENCHILD	NO
+
+NAME	IPP_
+PAGE	/
+SYMBOL	/
+# circles at .25 and .5 miles
+DATA	Pmin0.25,Pmax0.5
+# circles at .5 and 1 kilometers
+#DATA	Pmin0.31,Pmax0.62
+MENU	[not shown]
+HIDDENCHILD	YES
+
+NAME	PLS
+PAGE	/
+SYMBOL	/
+DATA	NULL
+MENU	PLS: Point Last Seen
+HIDDENCHILD	NO
+
+NAME	LKP
+PAGE	/
+SYMBOL	.
+DATA	NULL
+MENU	LKP: Last Known Point
+HIDDENCHILD	NO
+
+NAME	Base
+PAGE	B
+SYMBOL	0
+DATA	NULL
+MENU	Base
+HIDDENCHILD	NO
+
+NAME	Helibase
+PAGE	H
+SYMBOL	0
+DATA	NULL
+MENU	Helibase
+HIDDENCHILD	NO
+
+# Using Heli- will produce an object named Heli-1
+# with subsequent objects Heli-2, Heli-3, etc.
+NAME	Heli-
+PAGE	/
+SYMBOL	/
+DATA	NULL
+MENU	Heli-n Helispot
+HIDDENCHILD	NO
+
+NAME	Camp
+PAGE	C
+SYMBOL	0
+DATA	NULL
+MENU	Camp
+HIDDENCHILD	NO
+
diff --git a/config/stored_track.dbfawk b/config/stored_track.dbfawk
new file mode 100644
index 0000000..779f39e
--- /dev/null
+++ b/config/stored_track.dbfawk
@@ -0,0 +1,15 @@
+# $Id: stored_track.dbfawk,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2009-2012  The Xastir Group
+#
+
+
+BEGIN {
+dbfinfo="Credits:DateTime:Label;
+dbffields="Label:DateTime";
+}
+
+BEGIN_RECORD {key=""; lanes=3; color=12; name=""; filled=0; pattern=0; display_level=65536; label_level=256; label_color=12; symbol=""}
+
+/^Label=(.*)$/ {name="$1";}
+/^DateTime=(.*)$/ {name="$name ($1)";}
diff --git a/config/tabblock.dbfawk b/config/tabblock.dbfawk
new file mode 100644
index 0000000..31acf9f
--- /dev/null
+++ b/config/tabblock.dbfawk
@@ -0,0 +1,53 @@
+# $Id: tabblock.dbfawk,v 1.4 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# Census.gov 2008 TigerMaps for TABBLOCK
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March, 2009
+#
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line Shapefiles as available at:
+# http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+# 2007FE = dbfinfo="STATEFP:COUNTYFP:COUNTYNS:STATEFP00:COUNTYFP00:TRACTCE00:BLOCKCE00:SUFFIX1CE:BLKIDFP:NAME:MTFCC:UR00:UACE00:FUNCSTAT";
+dbfinfo="STATEFP:COUNTYFP:COUNTYNS:STATEFP00:COUNTYFP00:TRACTCE00:BLOCKCE00:SUFFIX1CE:BLKIDFP:NAME:MTFCC:UR:UACE:FUNCSTAT";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="UR:NAME:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=11; fill_color=26; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=26; font_size=0; symbol=""; fill_style=0 }
+
+#/^NAME=(.*)$/ {name="$1";next}
+# item locations
+/^MTFCC=G5/ {next}
+/^UR=U/ {display_level=2048;filled=1;color=99;fill_color=99; skip}
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
+
diff --git a/config/tgr2shp.dbfawk b/config/tgr2shp.dbfawk
new file mode 100644
index 0000000..93ae223
--- /dev/null
+++ b/config/tgr2shp.dbfawk
@@ -0,0 +1,263 @@
+# $Id: tgr2shp.dbfawk,v 1.11 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line  shapefiles which are
+# converted to shapefiles using the command:
+#   ogr2ogr -f "ESRI Shapefile" -t_srs "EPSG:4326" out_directory in_directory
+#
+# THis file is identical to the file "tgrlk" except for the "dbfinfo" variable
+# that is used to recognize the signature of the shapefiles.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="MODULE:TLID:SIDE1:SOURCE:FEDIRP:FENAME:FETYPE:FEDIRS:CFCC:FRADDL:TOADDL:FRADDR:TOADDR:FRIADDL:TOIADDL:FRIADDR:TOIADDR:ZIPL:ZIPR:AIANHHFPL:AIANHHFPR:AIHHTLIL:AIHHTLIR:CENSUS1:CENSUS2:STATEL:STATER:COUNTYL:COUNTYR:COUSUBL:COUSUBR:SUBMCDL:SUBMCDR:PLACEL:PLACER:TRACTL:TRACTR:BLOCKL:BLOCKR";
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="TLID:FEDIRP:FENAME:FETYPE:FEDIRS:CFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+# per-field rules are applied to the dbffields that are read from each record.
+# key: set the search key to be the Tiger/Line ID.  Not currently used.
+/^TLID=(.*)$/ {key=$1; next}
+# name: concatenate FEDIRP (direction prefix), FENAME (name), 
+#   FETYPE (type: Rd, Ln, Pky, etc.) and FEDIRS (direction suffix).
+# also abbreviate United States Highway to US, etc.
+/^FEDIRP=(.+)$/ {name="$1 ";next}
+/^FENAME=United States Highway (.*)$/ {name="$(name)US $1"; next}
+/^FENAME=State Highway (.*)$/ {name="$(name)State $1";next}
+/^FENAME=State Route (.*)$/ {name="$(name)SR $1";next}
+/^FENAME=(.*)$/ {name="$(name)$1"; next}
+/^FETYPE=(.+)$/ {name="$(name) $1"; next}
+/^FEDIRS=(.+)$/ {name="$(name) $1"; next}
+# Census Feature Class Codes are used to set lanes, color, display_level, etc.
+# CFCC A..: roads
+# A11 - primary limited access road or interstate highway, unseparated
+# A12 - primary limited access road or interstate highway, unseparated in tunnel
+# A13 - primary limited access road or interstate highway, unseparated, underpassing
+# A14 - primary limited access road or interstate highway, unseparated, with rail line in center
+# A15 - primary limited access road or interstate highway, separated
+# A16 - primary limited access road or interstate highway, separated, in tunnel
+# A17 - primary limited access road or interstate highway, separated, underpassing
+# A18 - primary limited access road or interstate highway, separated, with rail line in center
+# A21 - primary road without limit access, US highways, unseparated
+# A22 -primary road without limit access, US highways, unseparated, in tunnel
+# A23 - primary road without limit access, US highways, underpassing
+# A24 - primary road without limit access, US highways, unseparated, with rail line in center
+# A25 - primary road without limit access, US highways, separated
+# A26 - primary road without limit access, US highways, separated, in tunnel
+# A27 - primary road without limit access, US highways, separated, underpassing
+# A28 - primary road without limit access, US highways, separated, with rail line in center
+# A31 - secondary and connection road, state highways, unseperated
+# A32 - " in tunnel
+# A33 - " underpassing
+# A34 - " with rail line in center
+# A35 - secondary and connection road, state highways, seperated
+# A36 - " in tunnel
+# A37 - " underpassing
+# A38 - " with rail line in center
+# A41 - local, neighborhood and rural road, city street, unseparated
+# A42 - " in tunnel
+# A43 - " underpassing
+# A44 - " with rail line in center
+# A45 - local, neighborhood and rural road, city street, separated
+# A46 - " in tunnel
+# A47 - " underpassing
+# A48 - " with rail line in center
+# A51 - vehicular trail, unseparated
+# A52 - " in tunnel
+# A53 - " underpassing
+# A61 - cul-de-sac
+# A62 - traffic circle
+# A63 - access ramp
+# A64 - service drive
+# A65 - ferry crossing
+# A71 - walkway or trail
+# A72 - stairway
+# A73 - alley
+# A74 - driveway
+# "P" types denote "Provisional" streets that had not been field checked
+# or verified through aerial photography as of the date of preparation of 
+# the TIGER/Line data.  They are otherwise equivalent to "A" types, and
+# we'll just display them the same way.
+/^CFCC=[AP]1/ {lanes=4; color=4; label_level=512; font_size=3; next}
+/^CFCC=[AP]2/ {lanes=3; color=8; label_level=256; font_size=2; next}
+/^CFCC=[AP]3/ {lanes=2; color=8; label_level=128; font_size=1; next}
+/^CFCC=[AP]3[1-6]/ {display_level=256; next}
+/^CFCC=[AP]3[7-8]/ {display_level=128; next}
+/^CFCC=[AP]4/ {display_level=96; label_level=16; color=40; lanes=1; next}
+/^CFCC=[AP]5/ {lanes=2; color=40; display_level=64; font_size=1; next}
+/^CFCC=[AP]65/ {lanes=2; color=8; pattern=2; font_size=1; next}
+/^CFCC=[AP]6[^5]/ {color=40; display_level=64; next}
+/^CFCC=[AP]7[12]/ {lanes=1; color=12; pattern=2; display_level=64; next}
+/^CFCC=[AP]7[03-9]/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# need to implement these:
+# B: railroads
+# B01 - railroad track
+# B02 - " in tunnel
+# B03 - " underpassing
+# B11 - railroad main line
+# B12 - " in tunnel
+# B13 - " underpassing
+# B21 - railroad spur
+# B22 - " in tunnel
+# B23 - " underpassing
+# B31 - railroad yard track
+# B32 - " in tunnel
+# B33 - " underpassing
+# B40 - railroad ferry crossing
+# B50 - other rail line
+# B51 - carline (streetcars, etc.)
+# B52 - cog railroad, incline railway or logging tram
+/^CFCC=B/ {lanes=1; color=8; pattern=1; display_level=128; next}
+# C: transmission lines
+# C00 - misc ground transportation
+# C10 - pipeline
+# C20 - power transmission line
+# C30 - other ground transportation
+# C31 - aerial tramway
+/^CFCC=C/ {display_level=0; next}
+# D: landmarks
+# D00 - unknown
+# D10 - military installation
+# D20 - multihousehold or transient quarters
+# D21 - apartment building or complex
+# D22 - rooming or boarding house
+# D23 - trailer cour or mobile home park
+# D24 - marina
+# D25 - crew-of-vessel area
+# D26 - housing facility for workers
+# D27 - hotel, motel, resort, spa, YMCA, YWCA
+# D28 - campground
+# D29 - shelter or mission
+# D30 - custodial facility
+# D31 - hospital
+# D32 - halfway house
+# D33 - nursing home
+# D34 - county home or poor farm
+# D35 - orphanage
+# D36 - jail 
+# D37 - federal penetentiary, state prison, or prison farm
+# D40 - unknown educational or religious
+# D41 - sorority or fraternity
+# D42 - convent or monastery
+# D43 - educational institution
+# D44 - religious institution
+# D50 - transportation terminal
+# D51 - airport
+# D52 - train station
+# D53 - bus terminal
+# D54 - marine terminal
+# D55 - seaplane anchorage
+# D70 - tower
+# D71 - lookout tower
+# D80 - open space
+# D81 - golf course
+# D82 - cemetery
+# D83 - national park
+# D84 - national forest
+# D85 - state or local park or forest
+# D90 - special purpose landmark
+# D91 - post office box-only ZIP Code location
+# D92 - urbanizacion (Puerto Rico)
+# E: physical featuers
+# E00 - unknown physical feature
+# E10 - fence line
+# E20 - topgraphic feature
+# E21 - ridge line
+# E22 - mountain peak
+# E23 - island
+# F: legal boundaries
+# F00 - nonvisible boundary
+# F10 - jurisdictional boundary
+# F11 - offset boundary
+# F12 - corridor boundary
+# F13 - interpolate boundary across water
+# F14 - superseded boundary
+# F15 - superseded boundary, corrected
+# F20 - data base topology
+# F21 - automated feature extension to lenghten physical feature
+# F22 - irregular feature extension, determined manually
+# F23 - closure extension
+# F24 - separation line
+# F25 - centerline
+# F30 - point-to-point line
+# F40 - property line
+# F50 - Zip Code boundary
+# F60 - map edge
+# F70 - statistical boundardy
+# F71 - 1980 "
+# F72 - 1990 "
+# F73 - internal use
+# F74 - 1990 " ...
+# F80 - other tabulation boundary
+# F81 - internal use
+# F82 - internal use
+/^CFCC=F10$/{color=255; fill_color=255; label_level=32; display_level=512; pattern=0; next}
+/^CFCC=F/{display_level=0; next}
+# (G not used by census;  tig2aprs uses for special maps)
+# H: hydrography
+# H00 - water feature
+# H01 - shoreline of perennial water feature
+# H02 - shoreline of intermittent "
+# H10 - stream
+# H11 - perennial stream
+# H12 - intermittent stream
+# H13 - braided stream or river
+# H20 - canal, ditch or aqueduct
+# H21 - perennial "
+# H22 - intermittent "
+# H30 - lake or pond
+# H31 - perennial "
+# H32 - intermittent "
+# H40 - reservoir
+# H41 - perennial "
+# H42 - intermittent "
+# H50 - bay, estuary, gulf, sound, sea, ocean
+# H51 - bay, estuary, gulf or sound
+# H52 - sea or ocean
+# H60 - gravel pit or quarry filled with water
+# H70 - nonvisibile....
+# H80 - special water features
+# H81 - glacier
+# Don't display hydrology unless zoomed all the way in --- adjust to taste,
+# in NM anything more than this  looks absurd coz every intermittent wash 
+# would show up as a blue line, which is just wrong.
+/^CFCC=H/ {lanes=0; color=26; fill_color=26; label_color=26; display_level=1;}
+/^CFCC=H01/ {pattern=0; display_level=512; lanes=1; next}
+/^CFCC=H02/ {pattern=2; display_level=1; next}
+/^CFCC=H[124]2/ {lanes=1; pattern=2; display_level=128; next}
+# These filled patterns don't actually work: the tiger shapefiles produced
+# by ogr2ogr do not have the polygon features readily accessible!
+/^CFCC=H[34][01]/ {lanes=1; pattern=0; filled=1; fill_style=0; display_level=512; next}
+/^CFCC=H32/ {lanes=1; pattern=1; filled=1; fill_style=1; display_level=512; next}
+/^CFCC=H[1-6][013-9]/ {lanes=1; display_level=512; next}
+/^CFCC=H7/ {display_level=0; label_level=0; next}
+/^CFCC=H8/ {lanes=1; display_level=1}
+/^CFCC=H81/ {color=15; fill_color=15; display_level=256; next}
+# X00 - feature not yet classified
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/tgr2shppoly.dbfawk b/config/tgr2shppoly.dbfawk
new file mode 100644
index 0000000..221dc92
--- /dev/null
+++ b/config/tgr2shppoly.dbfawk
@@ -0,0 +1,262 @@
+# $Id: tgr2shppoly.dbfawk,v 1.15 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line  shapefiles which are
+# converted to shapefiles using the Xastir_tigerpoly.py utility 
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+dbfinfo="MODULE:FILE:CENID:POLYID:STATECU:COUNTYCU:TRACT:BLOCK:BLOCKSUFCU:RS_A1:AIANHHFPCU:AIANHHCU:AIHHTLICU:ANRCCU:AITSCECU:AITSCU:CONCITCU:COUSUBCU:SUBMCDCU:PLACECU:SDELMCU:SDSECCU:SDUNICU:RS_A20:RS_A21:RS_A22:CDCU:ZCTA5CU:ZCTA3CU:RS_A4:RS_A5:RS_A6:RS_A7:RS_A8:RS_A9:CBSACU:CSACU:NECTACU:CNECTACU:METDIVCU:NECTADIVCU:RS_A14:RS_A15:RS_A16:RS_A17:RS_A18:RS_A19:STATE:COUNTY:BLKGRP:AIANHHFP:AIANHH:AIHHTLI:ANRC:AITSCE:AITS:CONCIT:COUSUB:SUBMCD:PLACE:SDELM:SDSEC:SDUNI:MSACMSA:PMSA:NECMA:CD106 [...]
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="WATER:CFCC:LANAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=0; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0; fill_stipple=0 }
+
+# Name -- only features that have landmark records get names
+/^LANAME=None$/ {next}
+/^LANAME=(.*)$/ {name="$1"; next}
+
+#We need this just in case there is no CFCC code to tell us we're a water
+# feature
+#Perennial water
+/^WATER=1$/ {filled=1; fill_style=2; fill_stipple=2; color=117; fill_color=117; label_color=26; display_level=1024;}
+#intermittent water
+/^WATER=2$/ {filled=1; fill_style=2; fill_stipple=0; color=117; fill_color=117; label_color=26; display_level=512;pattern=1;}
+
+# These are *all* the allowed feature classes, even those that aren't
+# polygon types.  We won't actually bother testing for anything other 
+# than the ones we expect to find, lest we spend too much time filtering.
+
+# Census Feature Class Codes are used to set lanes, color, display_level, etc.
+# CFCC A..: roads
+# A11 - primary limited access road or interstate highway, unseparated
+# A12 - primary limited access road or interstate highway, unseparated in tunnel
+# A13 - primary limited access road or interstate highway, unseparated, underpassing
+# A14 - primary limited access road or interstate highway, unseparated, with rail line in center
+# A15 - primary limited access road or interstate highway, separated
+# A16 - primary limited access road or interstate highway, separated, in tunnel
+# A17 - primary limited access road or interstate highway, separated, underpassing
+# A18 - primary limited access road or interstate highway, separated, with rail line in center
+# A21 - primary road without limit access, US highways, unseparated
+# A22 -primary road without limit access, US highways, unseparated, in tunnel
+# A23 - primary road without limit access, US highways, underpassing
+# A24 - primary road without limit access, US highways, unseparated, with rail line in center
+# A25 - primary road without limit access, US highways, separated
+# A26 - primary road without limit access, US highways, separated, in tunnel
+# A27 - primary road without limit access, US highways, separated, underpassing
+# A28 - primary road without limit access, US highways, separated, with rail line in center
+# A31 - secondary and connection road, state highways, unseperated
+# A32 - " in tunnel
+# A33 - " underpassing
+# A34 - " with rail line in center
+# A35 - secondary and connection road, state highways, seperated
+# A36 - " in tunnel
+# A37 - " underpassing
+# A38 - " with rail line in center
+# A41 - local, neighborhood and rural road, city street, unseparated
+# A42 - " in tunnel
+# A43 - " underpassing
+# A44 - " with rail line in center
+# A45 - local, neighborhood and rural road, city street, separated
+# A46 - " in tunnel
+# A47 - " underpassing
+# A48 - " with rail line in center
+# A51 - vehicular trail, unseparated
+# A52 - " in tunnel
+# A53 - " underpassing
+# A61 - cul-de-sac
+# A62 - traffic circle
+# A63 - access ramp
+# A64 - service drive
+# A65 - ferry crossing
+# A71 - walkway or trail
+# A72 - stairway
+# A73 - alley
+# A74 - driveway
+
+#Roads are not going to be polygons, don't even check
+
+# need to implement these:
+# B: railroads
+# B01 - railroad track
+# B02 - " in tunnel
+# B03 - " underpassing
+# B11 - railroad main line
+# B12 - " in tunnel
+# B13 - " underpassing
+# B21 - railroad spur
+# B22 - " in tunnel
+# B23 - " underpassing
+# B31 - railroad yard track
+# B32 - " in tunnel
+# B33 - " underpassing
+# B40 - railroad ferry crossing
+# B50 - other rail line
+# B51 - carline (streetcars, etc.)
+# B52 - cog railroad, incline railway or logging tram
+# /^CFCC=B/ {lanes=1; color=8; pattern=1; display_level=128; next}
+
+# C: transmission lines
+# C00 - misc ground transportation
+# C10 - pipeline
+# C20 - power transmission line
+# C30 - other ground transportation
+# C31 - aerial tramway
+# /^CFCC=C/ {display_level=0; next}
+# D: landmarks
+# D00 - unknown
+# D10 - military installation
+# color is RosyBrown2
+/^CFCC=D1/ { filled=1; color=112; fill_color=112; fill_style=2; fill_stipple=0; display_level=1024; font_size=1; next}
+# D20 - multihousehold or transient quarters
+# D21 - apartment building or complex
+# D22 - rooming or boarding house
+# D23 - trailer cour or mobile home park
+# D24 - marina
+# D25 - crew-of-vessel area
+# D26 - housing facility for workers
+# D27 - hotel, motel, resort, spa, YMCA, YWCA
+# D28 - campground
+# D29 - shelter or mission
+/^CFCC=D2/ {filled=1;  color=14; fill_color=14; fill_style=2; fill_stipple=0; display_level=128; font_size=1; next}
+# D30 - custodial facility
+# D31 - hospital
+# D32 - halfway house
+# D33 - nursing home
+# D34 - county home or poor farm
+# D35 - orphanage
+# D36 - jail 
+# D37 - federal penetentiary, state prison, or prison farm
+/^CFCC=D3/ {filled=1;  color=13; fill_color=13; fill_style=2; fill_stipple=0; display_level=128; font_size=1; next}
+# D40 - unknown educational or religious
+# D41 - sorority or fraternity
+# D42 - convent or monastery
+# D43 - educational institution
+# D44 - religious institution
+/^CFCC=D4/ { filled=1; color=20; fill_color=20; fill_style=2; fill_stipple=0; display_level=64; font_size=1; next}
+# D50 - transportation terminal
+# D51 - airport
+# D52 - train station
+# D53 - bus terminal
+# D54 - marine terminal
+# D55 - seaplane anchorage
+# D57 - Airport
+# color is "gray81"
+/^CFCC=D5/ {filled=1;  color=113; fill_color=113; fill_style=2; fill_stipple=1; display_level=512; font_size=1; next}
+# D60 - Employment center
+# D61 - Shopping center
+# D62 - Industrial Building or Ind. park
+# D63 - Office Building or office park
+# D64 - Amusement Center
+# D65 - Government Center
+# D66 - Other emplyoment center
+/^CFCC=D6/ {filled=1;  color=113; fill_color=113; fill_style=2; fill_stipple=0; display_level=256; font_size=1; next}
+# D70 - tower
+# D71 - lookout tower
+/^CFCC=D7/ {filled=1;  color=113; fill_color=113; fill_style=2; fill_stipple=0; display_level=128; font_size=1; next}
+# D80 - open space
+# D81 - golf course
+# D82 - cemetery
+# Color is "tgr_park_1"
+/^CFCC=D8[01]/ {filled=1;  color=114; fill_color=114; fill_style=2; fill_stipple=0; display_level=512; font_size=1; next}
+# D83 - national park
+# D84 - national forest
+# D85 - state or local park or forest
+# color is "tgr_forest_1"
+/^CFCC=D8[3-5]/ {filled=1;  color=116; fill_color=116; fill_style=2; fill_stipple=0; display_level=1024; font_size=1; next}
+# D90 - special purpose landmark
+# D91 - post office box-only ZIP Code location
+# D92 - urbanizacion (Puerto Rico)
+/^CFCC=D9/ {filled=1;  color=101; fill_color=101; fill_style=2; fill_stipple=0; display_level=256; font_size=1; next}
+
+# E: physical featuers
+# E00 - unknown physical feature
+# E10 - fence line
+# E20 - topgraphic feature
+# E21 - ridge line
+# E22 - mountain peak
+# E23 - island
+# Don't display the E's
+# F: legal boundaries
+# F00 - nonvisible boundary
+# F10 - jurisdictional boundary
+# F11 - offset boundary
+# F12 - corridor boundary
+# F13 - interpolate boundary across water
+# F14 - superseded boundary
+# F15 - superseded boundary, corrected
+# F20 - data base topology
+# F21 - automated feature extension to lenghten physical feature
+# F22 - irregular feature extension, determined manually
+# F23 - closure extension
+# F24 - separation line
+# F25 - centerline
+# F30 - point-to-point line
+# F40 - property line
+# F50 - Zip Code boundary
+# F60 - map edge
+# F70 - statistical boundardy
+# F71 - 1980 "
+# F72 - 1990 "
+# F73 - internal use
+# F74 - 1990 " ...
+# F80 - other tabulation boundary
+# F81 - internal use
+# F82 - internal use
+/^CFCC=F/{filled=1; color=115; fill_color=115; fill_style=0; label_level=32; display_level=512; pattern=0; next}
+#/^CFCC=F/{display_level=0; next}
+# Don't bother with the F's either for now
+# (G not used by census;  tig2aprs uses for special maps)
+# H: hydrography
+# Color is "tgr_water_1"
+/^CFCC=H/ {filled=1; color=117; fill_color=3; label_color=26; display_level=512;}
+# H00 - water feature
+# H01 - shoreline of perennial water feature
+# H02 - shoreline of intermittent "
+/^CFCC=H0/ {filled=1; fill_style=2; fill_stipple=2; display_level=4096; label_level=16; lanes=1}
+/^CFCC=H02/ {filled=1;  fill_stipple=0; pattern=1; next}
+# H10 - stream
+# H11 - perennial stream
+# H12 - intermittent stream
+# H13 - braided stream or river
+# H20 - canal, ditch or aqueduct
+# H21 - perennial "
+# H22 - intermittent "
+# H30 - lake or pond
+# H31 - perennial "
+# H32 - intermittent "
+# H40 - reservoir
+# H41 - perennial "
+# H42 - intermittent "
+# H50 - bay, estuary, gulf, sound, sea, ocean
+# H51 - bay, estuary, gulf or sound
+# H52 - sea or ocean
+/^CFCC=H[1-5]/ {filled=1; fill_style=2; fill_stipple=2;display_level=256; label_level=16; lanes=1}
+/^CFCC=H[1-4]2/ {filled=1; fill_stipple=0; pattern=1; next}
+# H60 - gravel pit or quarry filled with water
+/^CFCC=H6/ {filled=1; fill_style=2; fill_stipple=2;display_level=256; label_level=16; lanes=1}
+# H70 - nonvisibile....
+# H80 - special water features
+# H81 - glacier
+/^CFCC=H81/ {filled=1; color=15; fill_color=15; fill_style=2; fill_stipple=2;display_level=256; label_level=16; lanes=1}
diff --git a/config/tgr2shppoly_2006.dbfawk b/config/tgr2shppoly_2006.dbfawk
new file mode 100644
index 0000000..917c6aa
--- /dev/null
+++ b/config/tgr2shppoly_2006.dbfawk
@@ -0,0 +1,265 @@
+# $Id: tgr2shppoly_2006.dbfawk,v 1.5 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line  shapefiles which are
+# converted to shapefiles using the Xastir_tigerpoly.py utility 
+#
+# It differs from the "tgr2shppoly.dbfawk" file only in the DBF signature,
+# which changed between the 2004 and 2006 TIGER/Line releases.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+dbfinfo="MODULE:FILE:CENID:POLYID:STATECU:COUNTYCU:TRACT:BLOCK:BLOCKSUFCU:RS_A1:AIANHHFPCU:AIANHHCU:AIHHTLICU:ANRCCU:AITSCECU:AITSCU:CONCITCU:COUSUBCU:SUBMCDCU:PLACECU:SDELMCU:SDSECCU:SDUNICU:RS_A20:RS_A21:RS_A22:CDCU:ZCTA5CU:ZCTA3CU:RS_A4:RS_A5:RS_A6:RS_A7:RS_A8:RS_A9:CBSACU:CSACU:NECTACU:CNECTACU:METDIVCU:NECTADIVCU:RS_A14:UACU:URCU:RS_A17:RS_A18:RS_A19:STATE:COUNTY:BLKGRP:AIANHHFP:AIANHH:AIHHTLI:ANRC:AITSCE:AITS:CONCIT:COUSUB:SUBMCD:PLACE:SDELM:SDSEC:SDUNI:MSACMSA:PMSA:NECMA:CD106:CD1 [...]
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="WATER:CFCC:LANAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=0; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0; fill_stipple=0 }
+
+# Name -- only features that have landmark records get names
+/^LANAME=None$/ {next}
+/^LANAME=(.*)$/ {name="$1"; next}
+
+#We need this just in case there is no CFCC code to tell us we're a water
+# feature
+#Perennial water
+/^WATER=1$/ {filled=1; fill_style=2; fill_stipple=2; color=117; fill_color=117; label_color=26; display_level=1024;}
+#intermittent water
+/^WATER=2$/ {filled=1; fill_style=2; fill_stipple=0; color=117; fill_color=117; label_color=26; display_level=512;pattern=1;}
+
+# These are *all* the allowed feature classes, even those that aren't
+# polygon types.  We won't actually bother testing for anything other 
+# than the ones we expect to find, lest we spend too much time filtering.
+
+# Census Feature Class Codes are used to set lanes, color, display_level, etc.
+# CFCC A..: roads
+# A11 - primary limited access road or interstate highway, unseparated
+# A12 - primary limited access road or interstate highway, unseparated in tunnel
+# A13 - primary limited access road or interstate highway, unseparated, underpassing
+# A14 - primary limited access road or interstate highway, unseparated, with rail line in center
+# A15 - primary limited access road or interstate highway, separated
+# A16 - primary limited access road or interstate highway, separated, in tunnel
+# A17 - primary limited access road or interstate highway, separated, underpassing
+# A18 - primary limited access road or interstate highway, separated, with rail line in center
+# A21 - primary road without limit access, US highways, unseparated
+# A22 -primary road without limit access, US highways, unseparated, in tunnel
+# A23 - primary road without limit access, US highways, underpassing
+# A24 - primary road without limit access, US highways, unseparated, with rail line in center
+# A25 - primary road without limit access, US highways, separated
+# A26 - primary road without limit access, US highways, separated, in tunnel
+# A27 - primary road without limit access, US highways, separated, underpassing
+# A28 - primary road without limit access, US highways, separated, with rail line in center
+# A31 - secondary and connection road, state highways, unseperated
+# A32 - " in tunnel
+# A33 - " underpassing
+# A34 - " with rail line in center
+# A35 - secondary and connection road, state highways, seperated
+# A36 - " in tunnel
+# A37 - " underpassing
+# A38 - " with rail line in center
+# A41 - local, neighborhood and rural road, city street, unseparated
+# A42 - " in tunnel
+# A43 - " underpassing
+# A44 - " with rail line in center
+# A45 - local, neighborhood and rural road, city street, separated
+# A46 - " in tunnel
+# A47 - " underpassing
+# A48 - " with rail line in center
+# A51 - vehicular trail, unseparated
+# A52 - " in tunnel
+# A53 - " underpassing
+# A61 - cul-de-sac
+# A62 - traffic circle
+# A63 - access ramp
+# A64 - service drive
+# A65 - ferry crossing
+# A71 - walkway or trail
+# A72 - stairway
+# A73 - alley
+# A74 - driveway
+
+#Roads are not going to be polygons, don't even check
+
+# need to implement these:
+# B: railroads
+# B01 - railroad track
+# B02 - " in tunnel
+# B03 - " underpassing
+# B11 - railroad main line
+# B12 - " in tunnel
+# B13 - " underpassing
+# B21 - railroad spur
+# B22 - " in tunnel
+# B23 - " underpassing
+# B31 - railroad yard track
+# B32 - " in tunnel
+# B33 - " underpassing
+# B40 - railroad ferry crossing
+# B50 - other rail line
+# B51 - carline (streetcars, etc.)
+# B52 - cog railroad, incline railway or logging tram
+# /^CFCC=B/ {lanes=1; color=8; pattern=1; display_level=128; next}
+
+# C: transmission lines
+# C00 - misc ground transportation
+# C10 - pipeline
+# C20 - power transmission line
+# C30 - other ground transportation
+# C31 - aerial tramway
+# /^CFCC=C/ {display_level=0; next}
+# D: landmarks
+# D00 - unknown
+# D10 - military installation
+# color is RosyBrown2
+/^CFCC=D1/ { filled=1; color=112; fill_color=112; fill_style=2; fill_stipple=0; display_level=1024; font_size=1; next}
+# D20 - multihousehold or transient quarters
+# D21 - apartment building or complex
+# D22 - rooming or boarding house
+# D23 - trailer cour or mobile home park
+# D24 - marina
+# D25 - crew-of-vessel area
+# D26 - housing facility for workers
+# D27 - hotel, motel, resort, spa, YMCA, YWCA
+# D28 - campground
+# D29 - shelter or mission
+/^CFCC=D2/ {filled=1;  color=14; fill_color=14; fill_style=2; fill_stipple=0; display_level=128; font_size=1; next}
+# D30 - custodial facility
+# D31 - hospital
+# D32 - halfway house
+# D33 - nursing home
+# D34 - county home or poor farm
+# D35 - orphanage
+# D36 - jail 
+# D37 - federal penetentiary, state prison, or prison farm
+/^CFCC=D3/ {filled=1;  color=13; fill_color=13; fill_style=2; fill_stipple=0; display_level=128; font_size=1; next}
+# D40 - unknown educational or religious
+# D41 - sorority or fraternity
+# D42 - convent or monastery
+# D43 - educational institution
+# D44 - religious institution
+/^CFCC=D4/ { filled=1; color=20; fill_color=20; fill_style=2; fill_stipple=0; display_level=64; font_size=1; next}
+# D50 - transportation terminal
+# D51 - airport
+# D52 - train station
+# D53 - bus terminal
+# D54 - marine terminal
+# D55 - seaplane anchorage
+# D57 - Airport
+# color is "gray81"
+/^CFCC=D5/ {filled=1;  color=113; fill_color=113; fill_style=2; fill_stipple=1; display_level=512; font_size=1; next}
+# D60 - Employment center
+# D61 - Shopping center
+# D62 - Industrial Building or Ind. park
+# D63 - Office Building or office park
+# D64 - Amusement Center
+# D65 - Government Center
+# D66 - Other emplyoment center
+/^CFCC=D6/ {filled=1;  color=113; fill_color=113; fill_style=2; fill_stipple=0; display_level=256; font_size=1; next}
+# D70 - tower
+# D71 - lookout tower
+/^CFCC=D7/ {filled=1;  color=113; fill_color=113; fill_style=2; fill_stipple=0; display_level=128; font_size=1; next}
+# D80 - open space
+# D81 - golf course
+# D82 - cemetery
+# Color is "tgr_park_1"
+/^CFCC=D8[01]/ {filled=1;  color=114; fill_color=114; fill_style=2; fill_stipple=0; display_level=512; font_size=1; next}
+# D83 - national park
+# D84 - national forest
+# D85 - state or local park or forest
+# color is "tgr_forest_1"
+/^CFCC=D8[3-5]/ {filled=1;  color=116; fill_color=116; fill_style=2; fill_stipple=0; display_level=1024; font_size=1; next}
+# D90 - special purpose landmark
+# D91 - post office box-only ZIP Code location
+# D92 - urbanizacion (Puerto Rico)
+/^CFCC=D9/ {filled=1;  color=101; fill_color=101; fill_style=2; fill_stipple=0; display_level=256; font_size=1; next}
+
+# E: physical featuers
+# E00 - unknown physical feature
+# E10 - fence line
+# E20 - topgraphic feature
+# E21 - ridge line
+# E22 - mountain peak
+# E23 - island
+# Don't display the E's
+# F: legal boundaries
+# F00 - nonvisible boundary
+# F10 - jurisdictional boundary
+# F11 - offset boundary
+# F12 - corridor boundary
+# F13 - interpolate boundary across water
+# F14 - superseded boundary
+# F15 - superseded boundary, corrected
+# F20 - data base topology
+# F21 - automated feature extension to lenghten physical feature
+# F22 - irregular feature extension, determined manually
+# F23 - closure extension
+# F24 - separation line
+# F25 - centerline
+# F30 - point-to-point line
+# F40 - property line
+# F50 - Zip Code boundary
+# F60 - map edge
+# F70 - statistical boundardy
+# F71 - 1980 "
+# F72 - 1990 "
+# F73 - internal use
+# F74 - 1990 " ...
+# F80 - other tabulation boundary
+# F81 - internal use
+# F82 - internal use
+/^CFCC=F/{filled=1; color=115; fill_color=115; fill_style=0; label_level=32; display_level=512; pattern=0; next}
+#/^CFCC=F/{display_level=0; next}
+# Don't bother with the F's either for now
+# (G not used by census;  tig2aprs uses for special maps)
+# H: hydrography
+# Color is "tgr_water_1"
+/^CFCC=H/ {filled=1; color=117; fill_color=3; label_color=26; display_level=512;}
+# H00 - water feature
+# H01 - shoreline of perennial water feature
+# H02 - shoreline of intermittent "
+/^CFCC=H0/ {filled=1; fill_style=2; fill_stipple=2; display_level=4096; label_level=16; lanes=1}
+/^CFCC=H02/ {filled=1;  fill_stipple=0; pattern=1; next}
+# H10 - stream
+# H11 - perennial stream
+# H12 - intermittent stream
+# H13 - braided stream or river
+# H20 - canal, ditch or aqueduct
+# H21 - perennial "
+# H22 - intermittent "
+# H30 - lake or pond
+# H31 - perennial "
+# H32 - intermittent "
+# H40 - reservoir
+# H41 - perennial "
+# H42 - intermittent "
+# H50 - bay, estuary, gulf, sound, sea, ocean
+# H51 - bay, estuary, gulf or sound
+# H52 - sea or ocean
+/^CFCC=H[1-5]/ {filled=1; fill_style=2; fill_stipple=2;display_level=256; label_level=16; lanes=1}
+/^CFCC=H[1-4]2/ {filled=1; fill_stipple=0; pattern=1; next}
+# H60 - gravel pit or quarry filled with water
+/^CFCC=H6/ {filled=1; fill_style=2; fill_stipple=2;display_level=256; label_level=16; lanes=1}
+# H70 - nonvisibile....
+# H80 - special water features
+# H81 - glacier
+/^CFCC=H81/ {filled=1; color=15; fill_color=15; fill_style=2; fill_stipple=2;display_level=256; label_level=16; lanes=1}
diff --git a/config/tgrcty.dbfawk b/config/tgrcty.dbfawk
new file mode 100644
index 0000000..a222d39
--- /dev/null
+++ b/config/tgrcty.dbfawk
@@ -0,0 +1,48 @@
+# $Id: tgrcty.dbfawk,v 1.15 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "cty" polygon shapefiles
+# which are named tgrSSCCCcty00.dbf, where SSCCC are the FIPS state and
+# county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:FIPSSTCO:STATE:COUNTY";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="COUNTY:FIPSSTCO";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key=""; lanes=1; fill_color=11; color=8; name=""; filled=0; pattern=0; display_level=8192; label_level=512; label_color=20; font_size=4; symbol=""}
+
+# name: name is just the county name.
+/^COUNTY=(.*)$/ {name="$1"; next}
+# key: set the search key to be the FIPS code.  Not currently used.
+# also append County to the name except for Louisiana, use Parish:
+/^FIPSSTCO=(22.*)$/ {name="$name Parish"; key=$1; next}
+/^FIPSSTCO=(.*)$/ {name="$name County"; key=$1; next}
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/tgrkgl.dbfawk b/config/tgrkgl.dbfawk
new file mode 100644
index 0000000..c36e0cb
--- /dev/null
+++ b/config/tgrkgl.dbfawk
@@ -0,0 +1,66 @@
+# $Id: tgrkgl.dbfawk,v 1.14 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "kgl" (Key Geographic
+# Location) shapefiles which are named tgrSSCCCkgl.dbf, where SSCCC 
+# are the FIPS state and county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:POLYID:COUNTY:CFCC:KGLNAME";
+# dbffields is which of the above fields we actually want to look at.
+dbffields="KGLNAME:CFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key=""; lanes=1; fill_color=255; color=8; name=""; filled=1; pattern=0;
+display_level=0; label_level=0; label_color=8; font_size=2; symbol="/. "}
+
+# name and key are both the KGL name
+/^KGLNAME=(.*)$/ {name=$1; key=$1; next}
+# CFCC=D.. for landmarks.  Use the same code here and for tgrlk.
+#D2: residence?
+#D23: trailer park
+#D28: campground
+/^CFCC=D2/ {symbol="/- "; display_level=64; label_level=32}
+/^CFCC=D23$/ {symbol="/R "; next}
+/^CFCC=D28$/ {symbol="/; "; next}
+/^CFCC=D2/ {next}
+#D31: hospital
+/^CFCC=D31$/ {color=9; symbol="/h "; display_level=128; label_level=64; next}
+#D40: unknown educational or religious
+#D41: sorority or fraternity
+#D42: convent or monastery
+#D43: educational institution
+#D44: religious institution
+/^CFCC=D4/ {color=8; symbol="/K "; display_level=64; label_level=32}
+/^CFCC=D4[03]$/ {color=14; next}
+#D51: airport
+#D54: harbor
+/^CFCC=D51$/ {symbol="/' "; display_level=128; label_level=32; next}
+/^CFCC=D54$/ {symbol="\\s "; display_level=128; label_level=32; next }
+#DB: state forests, etc.
+/^CFCC=D8/ {color=73; display_level=64; label_level=32; next}
+# don't need special end case handling...
+#END_RECORD {}
+#END {}
diff --git a/config/tgrlk.dbfawk b/config/tgrlk.dbfawk
new file mode 100644
index 0000000..cd1c37b
--- /dev/null
+++ b/config/tgrlk.dbfawk
@@ -0,0 +1,247 @@
+# $Id: tgrlk.dbfawk,v 1.16 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "lk" shapefiles which are
+# named tgrSSCCClk[A-H].dbf, where SSCCC are the FIPS state and county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="TLID:FNODE:TNODE:LENGTH:FEDIRP:FENAME:FETYPE:FEDIRS:CFCC:FRADDL:TOADDL:FRADDR:TOADDR:ZIPL:ZIPR:CENSUS1:CENSUS2:CFCC1:CFCC2:SOURCE";
+# dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="TLID:FEDIRP:FENAME:FETYPE:FEDIRS:CFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=8; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""}
+
+# per-field rules are applied to the dbffields that are read from each record.
+# key: set the search key to be the Tiger/Line ID.  Not currently used.
+/^TLID=(.*)$/ {key=$1; next}
+# name: concatenate FEDIRP (direction prefix), FENAME (name), 
+#   FETYPE (type: Rd, Ln, Pky, etc.) and FEDIRS (direction suffix).
+# also abbreviate United States Highway to US, etc.
+/^FEDIRP=(.+)$/ {name="$1 ";next}
+/^FENAME=United States Highway (.*)$/ {name="$(name)US $1"; next}
+/^FENAME=State Highway (.*)$/ {name="$(name)State $1";next}
+/^FENAME=State Route (.*)$/ {name="$(name)SR $1";next}
+/^FENAME=(.*)$/ {name="$(name)$1; next}
+/^FETYPE=(.+)$/ {name="$(name) $1"; next}
+/^FEDIRS=(.+)$/ {name="$(name) $1"; next}
+# Census Feature Class Codes are used to set lanes, color, display_level, etc.
+# CFCC A..: roads
+# A11 - primary limited access road or interstate highway, unseparated
+# A12 - primary limited access road or interstate highway, unseparated in tunnel
+# A13 - primary limited access road or interstate highway, unseparated, underpassing
+# A14 - primary limited access road or interstate highway, unseparated, with rail line in center
+# A15 - primary limited access road or interstate highway, separated
+# A16 - primary limited access road or interstate highway, separated, in tunnel
+# A17 - primary limited access road or interstate highway, separated, underpassing
+# A18 - primary limited access road or interstate highway, separated, with rail line in center
+# A21 - primary road without limit access, US highways, unseparated
+# A22 -primary road without limit access, US highways, unseparated, in tunnel
+# A23 - primary road without limit access, US highways, underpassing
+# A24 - primary road without limit access, US highways, unseparated, with rail line in center
+# A25 - primary road without limit access, US highways, separated
+# A26 - primary road without limit access, US highways, separated, in tunnel
+# A27 - primary road without limit access, US highways, separated, underpassing
+# A28 - primary road without limit access, US highways, separated, with rail line in center
+# A31 - secondary and connection road, state highways, unseperated
+# A32 - " in tunnel
+# A33 - " underpassing
+# A34 - " with rail line in center
+# A35 - secondary and connection road, state highways, seperated
+# A36 - " in tunnel
+# A37 - " underpassing
+# A38 - " with rail line in center
+# A41 - local, neighborhood and rural road, city street, unseparated
+# A42 - " in tunnel
+# A43 - " underpassing
+# A44 - " with rail line in center
+# A45 - local, neighborhood and rural road, city street, separated
+# A46 - " in tunnel
+# A47 - " underpassing
+# A48 - " with rail line in center
+# A51 - vehicular trail, unseparated
+# A52 - " in tunnel
+# A53 - " underpassing
+# A61 - cul-de-sac
+# A62 - traffic circle
+# A63 - access ramp
+# A64 - service drive
+# A65 - ferry crossing
+# A71 - walkway or trail
+# A72 - stairway
+# A73 - alley
+# A74 - driveway
+/^CFCC=A1/ {lanes=4; color=4; label_level=512; font_size=3; next}
+/^CFCC=A2/ {lanes=3; color=8; label_level=256; font_size=2; next}
+/^CFCC=A3/ {lanes=2; color=8; label_level=128; font_size=1; next}
+/^CFCC=A3[1-6]/ {display_level=256; next}
+/^CFCC=A3[7-8]/ {display_level=128; next}
+/^CFCC=A4/ {display_level=96; label_level=16; color=40; lanes=1; next}
+/^CFCC=A5/ {lanes=2; color=40; display_level=64; font_size=1; next}
+/^CFCC=A65/ {lanes=2; color=8; pattern=2; font_size=1; next}
+/^CFCC=A6[^5]/ {color=40; display_level=64; next}
+/^CFCC=A7[12]/ {lanes=1; color=12; pattern=2; display_level=64; next}
+/^CFCC=A7[03-9]/ {lanes=1; color=40; pattern=2; display_level=64; next}
+# need to implement these:
+# B: railroads
+# B01 - railroad track
+# B02 - " in tunnel
+# B03 - " underpassing
+# B11 - railroad main line
+# B12 - " in tunnel
+# B13 - " underpassing
+# B21 - railroad spur
+# B22 - " in tunnel
+# B23 - " underpassing
+# B31 - railroad yard track
+# B32 - " in tunnel
+# B33 - " underpassing
+# B40 - railroad ferry crossing
+# B50 - other rail line
+# B51 - carline (streetcars, etc.)
+# B52 - cog railroad, incline railway or logging tram
+/^CFCC=B/ {lanes=1; color=8; pattern=1; display_level=128; next}
+# C: transmission lines
+# C00 - misc ground transportation
+# C10 - pipeline
+# C20 - power transmission line
+# C30 - other ground transportation
+# C31 - aerial tramway
+/^CFCC=C/ {display_level=0; next}
+# D: landmarks
+# D00 - unknown
+# D10 - military installation
+# D20 - multihousehold or transient quarters
+# D21 - apartment building or complex
+# D22 - rooming or boarding house
+# D23 - trailer cour or mobile home park
+# D24 - marina
+# D25 - crew-of-vessel area
+# D26 - housing facility for workers
+# D27 - hotel, motel, resort, spa, YMCA, YWCA
+# D28 - campground
+# D29 - shelter or mission
+# D30 - custodial facility
+# D31 - hospital
+# D32 - halfway house
+# D33 - nursing home
+# D34 - county home or poor farm
+# D35 - orphanage
+# D36 - jail 
+# D37 - federal penetentiary, state prison, or prison farm
+# D40 - unknown educational or religious
+# D41 - sorority or fraternity
+# D42 - convent or monastery
+# D43 - educational institution
+# D44 - religious institution
+# D50 - transportation terminal
+# D51 - airport
+# D52 - train station
+# D53 - bus terminal
+# D54 - marine terminal
+# D55 - seaplane anchorage
+# D70 - tower
+# D71 - lookout tower
+# D80 - open space
+# D81 - golf course
+# D82 - cemetery
+# D83 - national park
+# D84 - national forest
+# D85 - state or local park or forest
+# D90 - special purpose landmark
+# D91 - post office box-only ZIP Code location
+# D92 - urbanizacion (Puerto Rico)
+# E: physical featuers
+# E00 - unknown physical feature
+# E10 - fence line
+# E20 - topgraphic feature
+# E21 - ridge line
+# E22 - mountain peak
+# E23 - island
+# F: legal boundaries
+# F00 - nonvisible boundary
+# F10 - jurisdictional boundary
+# F11 - offset boundary
+# F12 - corridor boundary
+# F13 - interpolate boundary across water
+# F14 - superseded boundary
+# F15 - superseded boundary, corrected
+# F20 - data base topology
+# F21 - automated feature extension to lenghten physical feature
+# F22 - irregular feature extension, determined manually
+# F23 - closure extension
+# F24 - separation line
+# F25 - centerline
+# F30 - point-to-point line
+# F40 - property line
+# F50 - Zip Code boundary
+# F60 - map edge
+# F70 - statistical boundardy
+# F71 - 1980 "
+# F72 - 1990 "
+# F73 - internal use
+# F74 - 1990 " ...
+# F80 - other tabulation boundary
+# F81 - internal use
+# F82 - internal use
+/^CFCC=F10$/{color=255; fill_color=255; label_level=32; display_level=512; pattern=0; next}
+/^CFCC=F/{display_level=0; next}
+# (G not used by census;  tig2aprs uses for special maps)
+# H: hydrography
+# H00 - water feature
+# H01 - shoreline of perennial water feature
+# H02 - shoreline of intermittent "
+# H10 - stream
+# H11 - perennial stream
+# H12 - intermittent stream
+# H13 - braided stream or river
+# H20 - canal, ditch or aqueduct
+# H21 - perennial "
+# H22 - intermittent "
+# H30 - lake or pond
+# H31 - perennial "
+# H32 - intermittent "
+# H40 - reservoir
+# H41 - perennial "
+# H42 - intermittent "
+# H50 - bay, estuary, gulf, sound, sea, ocean
+# H51 - bay, estuary, gulf or sound
+# H52 - sea or ocean
+# H60 - gravel pit or quarry filled with water
+# H70 - nonvisibile....
+# H80 - special water features
+# H81 - glacier
+/^CFCC=H/ {lanes=0; color=26; fill_color=26; label_color=26}
+/^CFCC=H02/ {pattern=2; next}
+/^CFCC=H[1-6]2/ {lanes=1; pattern=2; next}
+/^CFCC=H[1-6][013-9]/ {lanes=1; next}
+/^CFCC=H7/ {display_level=0; label_level=0; next}
+/^CFCC=H8/ {lanes=1}
+/^CFCC=H81/ {color=15; fill_color=15; next}
+# X00 - feature not yet classified
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/tgrlpt.dbfawk b/config/tgrlpt.dbfawk
new file mode 100644
index 0000000..7ec623b
--- /dev/null
+++ b/config/tgrlpt.dbfawk
@@ -0,0 +1,106 @@
+# $Id: tgrlpt.dbfawk,v 1.15 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "lpt" landmark point shapefiles which are
+# named tgrSSCCClpt.dbf, where SSCCC are the FIPS state and county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:CFCC:NAME";
+# dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="CFCC:NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=2; symbol=""}
+
+# per-field rules are applied to the dbffields that are read from each record.
+# key: set the search key to be the Tiger/Line ID.  Not currently used.
+/^NAME=(.*)$/ {name="$1"; next}
+# Census Feature Class Codes are used to set lanes, color, display_level, etc.
+# D: landmarks
+# D00 - unknown
+# D10 - military installation
+# D20 - multihousehold or transient quarters
+# D21 - apartment building or complex
+# D22 - rooming or boarding house
+# D23 - trailer cour or mobile home park
+# D24 - marina
+# D25 - crew-of-vessel area
+# D26 - housing facility for workers
+# D27 - hotel, motel, resort, spa, YMCA, YWCA
+# D28 - campground
+# D29 - shelter or mission
+# D30 - custodial facility
+# D31 - hospital
+# D32 - halfway house
+# D33 - nursing home
+# D34 - county home or poor farm
+# D35 - orphanage
+# D36 - jail 
+# D37 - federal penetentiary, state prison, or prison farm
+# D40 - unknown educational or religious
+# D41 - sorority or fraternity
+# D42 - convent or monastery
+# D43 - educational institution
+# D44 - religious institution
+# D50 - transportation terminal
+# D51 - airport
+# D52 - train station
+# D53 - bus terminal
+# D54 - marine terminal
+# D55 - seaplane anchorage
+# D70 - tower
+# D71 - lookout tower
+# D80 - open space
+# D81 - golf course
+# D82 - cemetery
+# D83 - national park
+# D84 - national forest
+# D85 - state or local park or forest
+# D90 - special purpose landmark
+# D91 - post office box-only ZIP Code location
+# D92 - urbanizacion (Puerto Rico)
+
+/^CFCC=D28/ {color=10; symbol="/] "; next}
+/^CFCC=D28/ {color=10; symbol="/\; "; next}
+/^CFCC=D31/ {color=9; symbol="/h "; next}
+/^CFCC=D40/ {color=5; next}
+/^CFCC=D41/ {color=2; next}
+/^CFCC=D42/ {color=1; next}
+/^CFCC=D43/ {color=2; symbol="/K "; next}
+/^CFCC=D44/ {color=1; next}
+/^CFCC=D51/ {color=14; symbol="/' "; next}
+/^CFCC=D52/ {color=14; symbol="/= "; next}
+/^CFCC=D53/ {color=14; symbol="/U "; next}
+/^CFCC=D54/ {color=1; symbol="/s "; next}
+/^CFCC=D70/ {color=1; symbol="/r "; next}
+/^CFCC=D8/ {color=2; next}
+
+# X<t><s><o> - APRS extension to get all the various APRS symbols.  
+# Useful for home made maps.  Perhaps I shouldn't overload tiger/line
+# stuff with this and just define a new .dbfawk....
+# <t><s><o> are table, symbol, and overlay,
+
+/^CFCC=X(.*)$/ {symbol="$1"; next}
+
diff --git a/config/tgrlpy.dbfawk b/config/tgrlpy.dbfawk
new file mode 100644
index 0000000..c63d33c
--- /dev/null
+++ b/config/tgrlpy.dbfawk
@@ -0,0 +1,48 @@
+# $Id: tgrlpy.dbfawk,v 1.13 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "lpy" landmark polygon shapefiles which are
+# named tgrSSCCClklpy.dbf, where SSCCC are the FIPS state and county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:POLYID:CENID:COUNTY:CFCC:LANDNAME:LANDPOLY";
+# dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="CFCC:LANDNAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; fill_color=11; color=8; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=2; symbol=""}
+
+# per-field rules are applied to the dbffields that are read from each record.
+# key: set the search key to be the Tiger/Line ID.  Not currently used.
+/^NAME=(.*)$/ {name="$1"; next}
+/^CFCC=H/ {lanes=0; color=26; fill_color=26}
+/^CFCC=H02/ {pattern=2; next}
+/^CFCC=H[1-6]2/ {lanes=1; pattern=2; next}
+/^CFCC=H[1-6][013-9]/ {lanes=1; next}
+/^CFCC=H7/ {display_level=0; label_level=0; next}
+/^CFCC=H8/ {lanes=1}
+/^CFCC=H81/ {color=15; fill_color=15; next}
+
diff --git a/config/tgrplc00.dbfawk b/config/tgrplc00.dbfawk
new file mode 100644
index 0000000..ca8e496
--- /dev/null
+++ b/config/tgrplc00.dbfawk
@@ -0,0 +1,38 @@
+# $Id: tgrplc00.dbfawk,v 1.13 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "plc" shapefiles which are
+# named tgrSSCCCplc00.dbf, where SSCCC are the FIPS state and county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:COUNTY:PLACE:NAME";
+# dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="NAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=3; color=4; fill_color=103; name=""; filled=1; pattern=0; display_level=8192; label_level=256; label_color=8; font_size=2; symbol=""}
+
+/^NAME=(.*)$/ {name="$1"; next}
diff --git a/config/tgrwat.dbfawk b/config/tgrwat.dbfawk
new file mode 100644
index 0000000..a4b9e89
--- /dev/null
+++ b/config/tgrwat.dbfawk
@@ -0,0 +1,49 @@
+# $Id: tgrwat.dbfawk,v 1.15 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc.
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+#
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line "wat" polygon shapefiles
+# which are named tgrSSCCCwat.dbf, where SSCCC are the FIPS state and
+# county codes.
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="ID:COUNTY:CFCC:LANDNAME:LANDPOLY";
+# dbffields is which of the above fields we actually want to look at.
+# Note that the order we list these is important since we are appending the
+# word County or Parish depending on what state the county is in.
+dbffields="CFCC:LANDNAME";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+BEGIN_RECORD {key=""; lanes=1; color=26; fill_color=26; name=""; filled=1; pattern=0; display_level=8192; label_level=512; label_color=8; font_size=2; symbol=""}
+
+# name: name is just the county name.
+/^COUNTY=(.*)$/ {name="$1"; next}
+# key: set the search key to be the FIPS code.  Not currently used.
+# also append County to the name except for Louisiana, use Parish:
+# XXX - find out what the FIPS code is for Louisiana and replace 99 with it:
+/^FIPSSTCO=(99.*)$/ {name="$name Parish"; key=$1; next}
+/^FIPSSTCO=(.*)$/ {name="$name County"; key=$1; next}
+# don't need special end case handling...
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/tl_2009_aiannh.dbfawk b/config/tl_2009_aiannh.dbfawk
new file mode 100644
index 0000000..869dc89
--- /dev/null
+++ b/config/tl_2009_aiannh.dbfawk
@@ -0,0 +1,52 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_aiannh.dbfawk,v 1.2 2010/07/02 07:17:29 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#   see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style			0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+# dbfinfo extracted from tl_2009_27_aiannh.dbf:
+dbfinfo="AIANNHCE:AIANNHNS:AIANNHID:NAME:NAMELSAD:LSAD:CLASSFP:COMPTYP:AIANNHR:MTFCC:FUNCSTAT:ALAND:AWATER:INTPTLAT:INTPTLON:STATEFP:AIANNHFP:PARTFLG";
+dbffields="NAMELSAD:MTFCC";
+}
+/^NAMELSAD=(.*)$/ {name="$1";next}
+
+/^MTFCC=G21/ { 
+display_level=128; color=65;
+label_level=96;   label_color=6;
+next;
+}
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_aits.dbfawk b/config/tl_2009_aits.dbfawk
new file mode 100644
index 0000000..100c079
--- /dev/null
+++ b/config/tl_2009_aits.dbfawk
@@ -0,0 +1,52 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_aits.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style			0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+# dbfinfo extracted from tl_2009_27_aits.dbf:
+dbfinfo="AIANNHCE:TRSUBCE:TRSUBNS:TRSUBID:NAME:NAMELSAD:LSAD:CLASSFP:MTFCC:FUNCSTAT:ALAND:AWATER:INTPTLAT:INTPTLON:STATEFP:TRSUBFP:PARTFLG";
+dbffields="NAMELSAD:MTFCC";
+}
+/^NAMELSAD=(.*)$/ {name="$1";next}
+
+/^MTFCC=G23/ { 
+display_level=128; color=65;
+label_level=96;    label_color=6;
+next;
+}
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_arealm.dbfawk b/config/tl_2009_arealm.dbfawk
new file mode 100644
index 0000000..95acc5d
--- /dev/null
+++ b/config/tl_2009_arealm.dbfawk
@@ -0,0 +1,104 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_arealm.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style (w/ filled=1)      0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="STATEFP:COUNTYFP:ANSICODE:AREAID:FULLNAME:MTFCC:ALAND:AWATER:INTPTLAT:INTPTLON";
+dbffields="FULLNAME:MTFCC";
+}
+
+BEGIN_RECORD {
+  color=11; # color 11 used on things we missed.
+  # Set defaults for other values:
+  name=""; filled=0; pattern=0; key=""; lanes=1; fill_color=40; label_color=48; fill_style=0;
+  display_level=128; label_level=96; font_size=0; symbol=""; fill_stipple=0;
+}
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+
+/^MTFCC=C3023/ { # Island
+color=40; label_color=48; font_size=1; display_level=256; label_level=128; next; }
+/^MTFCC=C3/ { # Other "C3" features not drawn - less than 20 in the whole dataset.
+display_level=0; next; }
+
+# Dwelling areas:
+
+/^MTFCC=K1121/ { # Apartment complex
+display_level=32; label_level=24; next; }
+/^MTFCC=K1228/ { # Campground
+display_level=64; label_level=48; filled=1; color=114 fill_color=114; fill_style=2; fill_stipple=2; label_color=0; font_size=1; next; }
+/^MTFCC=K122/  { # Trailer court, dormitory, hotel/resort, shelter/mission
+display_level=32; label_level=24; next; }
+/^MTFCC=K1231/ { # Hospital/hospice/urgent care facility
+display_level=64; label_level=48; filled=1; fill_color=112; fill_style=2; label_color=12; font_size=1; next; }
+/^MTFCC=K123[349]/ { # Nursing/retirement home, County home/poor farm, religious quarters
+display_level=32; label_level=24; next; }
+/^MTFCC=K123[567]/ { Juvenile Institution/Local Jail or Detention Center/Federal Penitentiary, State Prison
+display_level=32; label_level=24; filled=1; fill_style=2; fill_stipple=1; label_color=67; font_size=1; next; }
+
+# Government facilities:
+
+/^MTFCC=21[046]/ { # Governmental/Community Center/Government Center
+display_level=64; label_level=48; filled=1; fill_color=67; fill_style=2; fill_stipple=2; label_color=15; font_size=1; next; }
+/^MTFCC=K218/ { # Park/NPS land/Nat'l forest or other federal land/State, regional, county or city park
+display_level=64; label_level=32; filled=1; color=114 fill_color=114; fill_style=2; label_color=0; font_size=1; next; }
+
+# Commercial facilities
+
+/^MTFCC=K23/ { # We don't draw "K23" features
+display_level=0; next; }
+
+# Transit
+
+/^MTFCC=K24/ { # Marina/Airport/Train Station/Bus Terminal/Marine Terminal/Seaplane Anchorage/etc
+display_level=128; label_level=64; filled=1; color=115 fill_color=115; fill_style=2; label_color=0; font_size=1; next; }
+
+# Education/recreation/misc
+
+/^MTFCC=K254[03]/ { # University/College/School/Academy
+display_level=64; label_level=48; filled=1; fill_color=103; fill_style=2; font_size=0; next; }
+/^MTFCC=K2561/ { # Golf course
+display_level=64; label_level=48; filled=1; color=114 fill_color=100; fill_style=2; label_color=10; font_size=1; next; }
+/^MTFCC=K2582/ { # Cemetary (don't display - overlap w/ pointlm database)
+display_level=0; next; }
+/^MTFCC=K3544/ { # Place of worship (don't display - overlap w/ pointlm database)
+display_level=0; next; }
+/^MTFCC=K25/ { # All others (Amusement Center, Zoo)
+display_level=128; label_level=64; next; }
+
+#END_RECORD {}
+#END {}
+
diff --git a/config/tl_2009_areawater.dbfawk b/config/tl_2009_areawater.dbfawk
new file mode 100644
index 0000000..f4c63c6
--- /dev/null
+++ b/config/tl_2009_areawater.dbfawk
@@ -0,0 +1,74 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_areawater.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style (w/ filled=1)      0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="STATEFP:COUNTYFP:ANSICODE:HYDROID:FULLNAME:MTFCC:ALAND:AWATER:INTPTLAT:INTPTLON";
+dbffields="FULLNAME:MTFCC";
+}
+
+BEGIN_RECORD {
+  color=11; # color 11 used on things we missed.
+  # defaults for items below
+  name=""; filled=1; pattern=0; key=""; lanes=1;
+  fill_color=42; label_color=3; fill_style=0;
+  display_level=128; label_level=32; font_size=0; symbol="";
+}
+
+/^FULLNAME=(.*)$/ {name="$1";next}
+
+/^MTFCC=H2025/ { # Swamp/marsh
+color=42; fill_style=2; display_level=64; fill_stipple=0; next}
+/^MTFCC=H2030/ { # Lake/Pond, Reservoir, Bay/Estuary/Gulf/Sound, Ocean/Sea
+color=42; fill_style=0; next}
+/^MTFCC=H2040/ { # Reservoir
+color=42; fill_style=2; fill_stipple=2; display_level=64; next}
+/^MTFCC=H20[48]1/ { # Treatment Pond, Glacier
+color=42; fill_style=2; fill_stipple=1; display_level=64; next}
+/^MTFCC=H205/ { # Bay/Estuary/Gulf/Sound, Ocean/Sea
+color=42; fill_style=0; display_level=256; next}
+/^MTFCC=H2060/ { # Quarry filled w/ water
+color=42; fill_style=2; fill_stipple=2; display_level=64; name="$name (Quarry/Pit)"; next}
+/^MTFCC=H3010/ { # Stream/river
+color=42; next}
+/^MTFCC=H3013/ { # Braided stream
+color=42; display_level=64; next}
+/^MTFCC=H302/ { # Canal/ditch/aqueduct
+color=42; display_level=32; next}
+
+#END_RECORD {}
+#END {}
+
diff --git a/config/tl_2009_county.dbfawk b/config/tl_2009_county.dbfawk
new file mode 100644
index 0000000..28a64ca
--- /dev/null
+++ b/config/tl_2009_county.dbfawk
@@ -0,0 +1,55 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_county.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style (w/ filled=1)      0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="STATEFP:COUNTYFP:COUNTYNS:CNTYIDFP:NAME:NAMELSAD:LSAD:CLASSFP:MTFCC:CSAFP:CBSAFP:METDIVFP:FUNCSTAT:ALAND:AWATER:INTPTLAT:INTPTLON";
+dbffields="NAMELSAD:MTFCC";
+}
+
+BEGIN_RECORD {
+  color=11; # color 11 used on things we missed.
+  # Set defaults for other values:
+  name=""; filled=0; pattern=0; key=""; lanes=1; fill_color=20; label_color=20; fill_style=0;
+  display_level=64; label_level=32; font_size=0; symbol=""; fill_stipple=0;
+}
+
+/^NAMELSAD=(.*)$/ {name="$1"}
+/^MTFCC=G/ { # Counties/Parishes
+display_level=5000; color=254; label_level=2048; label_color=254; next}
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_cousub.dbfawk b/config/tl_2009_cousub.dbfawk
new file mode 100644
index 0000000..13af2fb
--- /dev/null
+++ b/config/tl_2009_cousub.dbfawk
@@ -0,0 +1,55 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_cousub.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style (w/ filled=1)      0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo ="STATEFP:COUNTYFP:COUSUBFP:COUSUBNS:COSBIDFP:NAME:NAMELSAD:LSAD:CLASSFP:MTFCC:CNECTAFP:NECTAFP:NCTADVFP:FUNCSTAT:ALAND:AWATER:INTPTLAT:INTPTLON";
+dbffields="NAMELSAD:MTFCC";
+}
+
+BEGIN_RECORD {
+  color=11; # color 11 used on things we missed.
+  # Set defaults for other values:
+  name=""; filled=0; pattern=0; key=""; lanes=1; fill_color=20; label_color=20; fill_style=0;
+  display_level=64; label_level=32; font_size=0; symbol=""; fill_stipple=0;
+}
+
+/^NAMELSAD=(.*)$/ {name="$1";next; }
+/^MTFCC=G/ { # "County Subdivisions" - better known as cities, towns and townships.
+display_level=128; label_level=96; color=115; label_color=115; next}
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_edges.dbfawk b/config/tl_2009_edges.dbfawk
new file mode 100644
index 0000000..82d456f
--- /dev/null
+++ b/config/tl_2009_edges.dbfawk
@@ -0,0 +1,100 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_edges.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style (w/ filled=1)      0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="STATEFP:COUNTYFP:TLID:TFIDL:TFIDR:MTFCC:FULLNAME:SMID:LFROMADD:LTOADD:RFROMADD:RTOADD:ZIPL:ZIPR:FEATCAT:HYDROFLG:RAILFLG:ROADFLG:OLFFLG:PASSFLG:DIVROAD:EXTTYP:TTYP:DECKEDROAD:ARTPATH:PERSIST:GCSEFLG:OFFSETL:OFFSETR:TNIDF:TNIDT";
+dbffields="MTFCC:FULLNAME";
+# level presets
+l_metro=256; l_county=80; l_city=32; l_town=16; l_hood=8;
+}
+
+BEGIN_RECORD {
+  color=11; # color 11 used on things we missed.
+  # Set defaults for other values:
+  name=""; filled=0; pattern=0; key=""; lanes=1; fill_color=20; label_color=20; fill_style=0;
+  display_level=64; label_level=32; font_size=0; symbol=""; fill_stipple=0;
+}
+
+/^FULLNAME=(.*)$/ {name="$1";next; }
+
+# Non-road items:
+
+/^MTFCC=L4031/ { # Ski Lift or Arial Tramway
+display_level=l_city; color=12; pattern=2; name="$name (Ski Lift/Tramway)"; next; }
+/^MTFCC=L4165/ { # Ferry crossing
+lanes=3; pattern=2; color=72; label_color=72; display_level=l_metro; label_level=l_county; next; }
+/^MTFCC=[CHKLP]/ { # Don't draw other non-road items
+display_level=0; next; }
+/^MTFCC=R101/ { # Freight Rail (heavy/freight)
+color=80; label_color=48;  pattern=1; lanes=2; display_level=128; label_level=64; next; }
+/^MTFCC=R105/ { # Passenger Rail (light/mass transit/cog rail)
+color=67; label_color=67; pattern=2; display_level=128; label_level=64; next; }
+
+# Public Roadways
+
+/^MTFCC=S11/ { # Freeways/major highways
+lanes=4; color=102; label_color=102; display_level=1024; label_level=256; font_size=2; next; }
+/^MTFCC=S12/ { # Secondary roads
+display_level=256; lanes=3; color=36; label_color=36; label_level=128; font_size=2; next; }
+/^MTFCC=S14/ { # Local roads, ramps and service drives/frontage roads
+display_level=40; color=44; label_color=44; label_level=16; color=48; lanes=1; next; }
+/^MTFCC=S15/ { # 4WD off-road trail
+color=99; label_color=99; display_level=64; font_size=1; name="$name (OHV/4WD trail)"; next; }
+/^MTFCC=S16/ { # ramps and service roads for Freeways/major highways
+color=102; label_color=102; display_level=32; next; }
+/^MTFCC=S20/ { # road median
+color=44; label_color=44; pattern=1; display_level=16; next; }
+/^MTFCC=S173/ { # alley
+color=44; label_color=44; pattern=1; display_level=32; name="$name (alley)"; next; }
+
+# Non-public roads (and public non-roads)
+
+/^MTFCC=S171/ { # walkway / pedestrian trail
+lanes=1; color=65; label_color=65; pattern=1; display_level=64; label_level=32; name="$name (walkway)"; next; }
+/^MTFCC=S172/ { # stairway
+lanes=1; color=12; label_color=12; pattern=2; display_level=32; label_level=20; name="$name (stairs)"; next; }
+/^MTFCC=S174/ { # private road
+lanes=1; color=23; label_color=23; pattern=2; display_level=32; label_level=20; name="$name (private road)"; next; }
+/^MTFCC=S17/ { # business park / townhome road / parking lane / "internal census use only"
+lanes=1; color=23; label_color=23; pattern=1; display_level=32; label_level=20; name="$name (parking/private)"; next; }
+/^MTFCC=S182/ { # bike path
+lanes=1; color=65; label_color=65; pattern=1; display_level=64; label_level=32; name="$name (bikeway)"; next; }
+/^MTFCC=S183/ { # bridle path
+lanes=1; color=65; label_color=65; pattern=2; display_level=64; label_level=32; name="$name (bridle path)"; next; }
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_mil.dbfawk b/config/tl_2009_mil.dbfawk
new file mode 100644
index 0000000..71aa4ec
--- /dev/null
+++ b/config/tl_2009_mil.dbfawk
@@ -0,0 +1,47 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_mil.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style			0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="ANSICODE:AREAID:FULLNAME:MTFCC:ALAND:AWATER:INTPTLAT:INTPTLON:PARTFLG";
+dbffields="FULLNAME:MTFCC";
+}
+/^FULLNAME=(.*)$/ {name="$1"; next; }
+/^MTFCC=K21/ { # Military installation
+display_level=128; color=116; label_level=64; label_color=116; fill_style=2; fill_stipple=0; fill_color=116; filled=1; next; }
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_nn_county.dbfawk b/config/tl_2009_nn_county.dbfawk
new file mode 100644
index 0000000..3bec460
--- /dev/null
+++ b/config/tl_2009_nn_county.dbfawk
@@ -0,0 +1,56 @@
+# tl_2009_nn_county.dbfawk
+#
+# $Id: tl_2009_nn_county.dbfawk,v 1.2 2012/11/01 18:57:19 we7u Exp $
+# Copyright (C) 2003-2012  The Xastir Group
+# 
+# Census.gov 2009 TigerMaps for state counties or equivalent areas.
+# 
+# Based on work by:
+# Richard Polivka, N6NKO - April, 2008
+# Craig Anderson, N6YXK - May, 2008
+# Dale Seaburg, KG5LT - March 2009
+# Edited for 2009 data by:
+# Peter Gamache, KC0TFB - June, 2010
+#
+# This dbfawk file is used to map arbitrary dbf data that accompanies
+# a shapefile into Xastir canoncical values of:
+#   key     - search key
+#   lanes   - width of feature (usually a road but applies to rivers, etc. too)
+#   color   - color to draw the road
+#   name    - name of the road for labels
+#   filled  - whether a polygon is drawn filled or not
+#   fill_color - color to fill polygon with
+#   pattern - line pattern for road, river, etc. (0 - solid; 1 - dash; 2 - double dash)
+#   display_level - highest zoom level at which to display the feature
+#   label_level - highest zoom level at which to display the label
+#   symbol  - 3 char 'TIO': table, ID, overlay
+# NOTE: This file format is modeled after awk but is nowhere near awk
+#  compatible.
+#
+# This file is used to map US Census Tiger/Line 2009 Shapefiles.
+#
+
+# BEGIN is called once per dbf file which contains multiple records.
+BEGIN {
+# dbfinfo is the "signature" of the dbf file listing the column names in order.
+# dbfinfo should match the dbf file that we say this dbfawk file goes with.
+dbfinfo="STATEFP:COUNTYFP:COUNTYNS:CNTYIDFP:NAME:NAMELSAD:LSAD:CLASSFP:MTFCC:CSAFP:CBSAFP:METDIVFP:FUNCSTAT:ALAND:AWATER:INTPTLAT:INTPTLON";
+
+
+#dbffields is which of the above fields we actually want to look at.
+# No point reading dbffields that are not looked at further.
+dbffields="NAMELSAD:MTFCC";
+}
+
+# BEGIN_RECORD is called once per dbf record which contains multiple fields.
+# Use this rule to re-initialize variables between records.
+# use color 11 to highlight stuff that isn't properly mapped.
+BEGIN_RECORD {key=""; lanes=1; color=6; fill_color=11; name=""; filled=0; pattern=0; display_level=8192; label_level=32; label_color=8; font_size=0; symbol=""; fill_style=0 }
+
+/^NAMELSAD=(.*)$/ {name="$1"}
+# counties
+/^MTFCC=G/ {display_level=6000; filled=0; color=45; label_level=2048; label_color=37; next}
+
+# just a demo of the END_RECORD and END rules:
+#END_RECORD {name="$name ($key)";}
+#END {}
diff --git a/config/tl_2009_pointlm.dbfawk b/config/tl_2009_pointlm.dbfawk
new file mode 100644
index 0000000..9313186
--- /dev/null
+++ b/config/tl_2009_pointlm.dbfawk
@@ -0,0 +1,135 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_pointlm.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style (w/ filled=1)	0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="STATEFP:COUNTYFP:ANSICODE:POINTID:FULLNAME:MTFCC";
+dbffields="FULLNAME:MTFCC";
+# level presets
+l_metro=128; l_county=64; l_city=32; l_town=16; l_hood=8;
+}
+
+BEGIN_RECORD { # Defaults
+key=""; lanes=1; color=70; fill_color=70; name=""; filled=0; pattern=0; display_level=48; label_level=32; label_color=70; font_size=0; symbol=""; fill_style=0;
+}
+
+/^FULLNAME=(.*)$/ {name="$1"; next; }
+
+# Geography
+
+/^MTFCC=3022/ { # Mountain Peak or Summit
+display_level=l_county; next; }
+/^MTFCC=3022/ { # Islands should be in edges.dbf, not here.
+display_level=0; next; }
+/^MTFCC=3026/ { # Quarry
+next; }
+/^MTFCC=3027/ { # Dam should be in areawater, not here.
+display_level=0; next; }
+
+# Road features
+
+/^MTFCC=C306/ { # ignore cul-de-sacs, roundabouts, gates and toll booths
+display_level=0; next; }
+
+# Towers
+
+/^MTFCC=C307[014]/ { # Towers (beacon/observation/lighthouse, antenna and water)
+display_level=l_city; color=50; label_color=50; symbol="\L"; next; }
+/^MTFCC=C3072/ { display_level=l_city; color=50; label_color=50; name="$name (antenna tower)"; symbol="/r"; next; }
+/^MTFCC=C3073/ { display_level=l_city; color=50; label_color=50; name="$name (water tower)"; symbol="/r"; next; }
+/^MTFCC=C307/ { # ignore other towers (tanks, windmills and monuments)
+display_level=0; next; }
+
+# Locality points
+
+/^MTFCC=C308/ { # city names; redundant with cousub.dbf
+display_level=0; next}
+
+# Potential housing (for disaster relief)
+
+/^MTFCC=K1231/ { # Hospitals
+label_color=12; display_level=l_county; symbol="/h"; next}
+/^MTFCC=K12/ { # Don't display other types
+display_level=0; next}
+
+# other gov't items
+
+/^MTFCC=K2110/ { # Military; redundant with mil.dbf
+display_level=0; next; }
+/^MTFCC=K2146/ { # Community center
+display_level=l_city; symbol="/?"; next}
+/^MTFCC=K2165/ { # Gov't center
+display_level=l_city; symbol="/?"; next}
+/^MTFCC=K218/ { # Parks not shown; redundant with arealm.dbf
+display_level=0; next}
+/^MTFCC=K2193/ { # fire dept
+label_color=12; display_level=l_county; symbol="/d"; next}
+/^MTFCC=K2194/ { # police/sheriff station
+label_color=9; display_level=l_county; symbol="/!"; next}
+/^MTFCC=K2196/ { # City hall
+display_level=l_city; symbol="/?"; next}
+/^MTFCC=K219/ { # other buildings not shown
+display_level=0; next}
+
+# Transportation
+
+/^MTFCC=K2400/ { # Transportation terminal?
+display_level=l_city; symbol="/U?"; next}
+/^MTFCC=K245[156]/ { # Airport/airfield, seaplane terminal
+display_level=l_county; symbol="\^@"; next; }
+/^MTFCC=K2452/ { # train/trolley/light rail station
+display_level=l_city; symbol="/=@"; next}
+/^MTFCC=K2453/ { # bus terminal
+display_level=l_city; symbol="/U@"; next}
+/^MTFCC=K2454/ { # marine terminal
+display_level=l_county; symbol="\s@"; next}
+
+# Education/entertainment/misc
+
+/^MTFCC=K254[03]/ { # University/school
+display_level=l_town; symbol="/K"; next}
+/^MTFCC=K2561/ { # golf course; redundant w/ arealm
+display_level=0; next; }
+/^MTFCC=K2582/ { # cemetaries
+display_level=0; next}
+/^MTFCC=K3544/ { # religious
+display_level=0; next}
+
+# catch-all rule:
+/^MTFCC=K/ {display_level=16; label_level=16; next}
+
+#END_RECORD {}
+#END {}
diff --git a/config/tl_2009_zcta5.dbfawk b/config/tl_2009_zcta5.dbfawk
new file mode 100644
index 0000000..0b0a286
--- /dev/null
+++ b/config/tl_2009_zcta5.dbfawk
@@ -0,0 +1,47 @@
+# Written for the Tiger/Line 2009 dataset
+# NB: Colors have been chosen with a black background in mind.
+#
+# $Id: tl_2009_zcta5.dbfawk,v 1.1 2010/07/02 07:12:20 we7u Exp $
+#
+#  Copyright (C) 2010  Peter Gamache, KC0TFB
+#
+#  This program is free software; you can redistribute it and/or
+#  modify
+#  it under the terms of the GNU General Public License as published
+#  by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+#  02111-1307  USA
+#
+#  see file COPYING for details
+#
+# color,label_color,fill_color	sets object colors
+# lanes				sets width of lines drawn (in pixels)
+# name				sets the text that will be used as the label for the feature
+# symbol			"XYZ", where X=group (/ or \), Y=symbol and Z=overlay
+# fill_style			0=solid, 1=tiled, 2=stippled, 3=Opaque Stippled
+# fill_stipple			0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
+# pattern			line pattern: 0=solid, 1=dashed, 2=double dash
+# display_level			maximum zoom level for object display
+# label_level			maximum zoom level for label display
+# font_size			0="Tiny", 4="Huge"
+
+BEGIN {
+dbfinfo="ZCTA5CE:CLASSFP:MTFCC:FUNCSTAT:ALAND:AWATER:INTPTLAT:INTPTLON";
+dbffields="ZCTA5CE:MTFCC";
+}
+/^ZCTA5CE=(.*)$/ {name="$1";next}
+/^MTFCC=G6350/ { # Zip code tabulation area, 5-digit
+display_level=128; color=103; label_level=64; label_color=103; font_size=1; next; }
+
+#END_RECORD {}
+#END {}
diff --git a/config/tnc-startup.aea b/config/tnc-startup.aea
new file mode 100644
index 0000000..9098ae7
--- /dev/null
+++ b/config/tnc-startup.aea
@@ -0,0 +1,47 @@
+# $Id: tnc-startup.aea,v 1.19 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the TNC Startup file for AEA TNC's.
+# lines that begin with a pound sign are comments.
+#
+# This has not been tweaked yet to be specific to AEA's.
+# Please modify it and send the patches to the mailing lists.
+# Thanks.
+#
+HID on
+#CWID off
+EXP on
+ECHO off
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYAlias WIDE1-1
+#
+B E 0
+DIGI on
+FLow off
+FUll off
+HEA off
+#LFadd off
+#LFSup ON
+#AUTOLF off
+#MCOM off
+MFILTER 0
+MON ON
+#
+# Important!  Only monitor PID 0xf0 packets:
+MPROTO OFF
+#
+#MResp OFF
+MRPt on
+MSTamp off
+MXMit off
+NEWmode off
+#PACLen 128
+PASSALL off
+#SCR 0
+# B E 0 must be set to 0 or both APRS and your TNC will send BCNS
+# Which will alternate in everyones L and A lists and fill up
+# their logs.  Do NOT set B E to anything other than 0 while APRS
+# is running.
+
diff --git a/config/tnc-startup.d700 b/config/tnc-startup.d700
new file mode 100644
index 0000000..8b28c6b
--- /dev/null
+++ b/config/tnc-startup.d700
@@ -0,0 +1,69 @@
+# $Id: tnc-startup.d700,v 1.14 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+# TNC Init file for KENWOOD D700.  Also reported to work with the
+# Alinco DR-135TP radio (with the EJ-41U TNC which also uses a Tasco
+# TNC just like the Kenwoods).  Perhaps works with the Alinco DR-635
+# radio (with the EJ-50U TNC) too.
+#
+# NOTE:  TXD on a D700A is fixed at 500ms (1/2 second) in "APRS"
+# mode.  In "packet" mode we can change the txd to other values.
+#
+#
+#Don't send CONTROL-C before this line
+##META <no-ctrl-c>
+TC 1
+##Pause for one second
+##META <delay>
+##META <delay>
+#Put the TNC in packet mode since this is where we want to end up
+# Change the 1 to 0 to go to normal radio mode
+##META <no-ctrl-c>
+TNC 2
+# Pause for two seconds
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+# Enable 4800 baud GPS
+# Change to 2 for 9600 baud GPS
+# Disable both the META line and the GU line for no change
+##META <no-ctrl-c>
+GU 1
+# Pause for two seconds
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+#Turn off Terminal Control
+##META <no-ctrl-c>
+TC 0
+# Pause for two seconds just in case
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+HID off
+#CWID off
+AWlen 8
+BBSMsgs ON
+B E 0
+LOC E 0
+Echo off
+FLow off
+AUTOLF off
+MCOM off
+MON ON
+MRPt on
+PACLen 128
+PASSALL off
+HBAUD 1200
+TXDELAY 25
+HEADERLN off
+# Delete following lines if without GPS
+GBAUD 4800
+GPSTEXT $GPRMC
+LTMH OFF
+LTM 10
+#
diff --git a/config/tnc-startup.d72_d710 b/config/tnc-startup.d72_d710
new file mode 100644
index 0000000..1b93267
--- /dev/null
+++ b/config/tnc-startup.d72_d710
@@ -0,0 +1,47 @@
+# $Id: tnc-startup.d72_d710,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2011-2012  The Xastir Group
+#
+# TNC Init file for KENWOOD TM-D710 or TH-D72 radios.
+# Contributed by Kai Günter, LA3QMA.
+#
+# If using a GPS you must change GBAUD, GPSTEXT, LTMH.
+#
+#
+#Don't send CONTROL-C before this line
+##META <no-ctrl-c>
+#TC 1
+##Pause for one second
+##META <delay>
+##META <delay>
+#Put the TNC in packet mode since this is where we want to end up
+# Change the 1 to 0 to go to normal radio mode
+##META <no-ctrl-c>
+TN 2,0
+# Pause for two seconds
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+HID off
+AWlen 8
+BBSMsgs ON
+B E 0
+LOC E 0
+Echo off
+FLow off
+AUTOLF off
+MCOM off
+MON ON
+MRPt on
+PACLen 128
+PASSALL off
+HBAUD 1200
+TXDELAY 25
+HEADERLN off
+# Delete following lines if without GPS
+#GBAUD 4800
+#GPSTEXT $GPRMC
+#LTMH OFF
+#
+#
diff --git a/config/tnc-startup.kam b/config/tnc-startup.kam
new file mode 100644
index 0000000..f60d417
--- /dev/null
+++ b/config/tnc-startup.kam
@@ -0,0 +1,43 @@
+# $Id: tnc-startup.kam,v 1.19 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the TNC Startup file for a Kantronics KAM TNC. 
+# lines that begin with a pound sign are comments.
+# Edit this file for your tnc!
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#myalias WIDE1-1
+#
+INTF TERM
+#One KAM user reports this command does not exist on his KAM
+#txu on
+xflow off
+MONITOR ON
+MSTAMP OFF
+HEADERLN OFF
+#One KAM user reports this command does not exist on his KAM
+#SCREENLN 0
+AUTOLF OFF
+LFADD OFF
+CD SOFT
+MCOM OFF/OFF
+MCON OFF
+FILT OFF
+AUTOCR 0
+BEACON EVERY 0
+BT %
+BUDL OFF/OFF
+CMS DISC
+CONL OFF
+CT APRS Network no connected messages supported!
+ECHO OFF
+FLOW OFF
+HID OFF/OFF
+#CWID EVERY 0
+MSTAMP OFF
+PASSALL OFF
+#
+# Important!  Monitor only PID 0xf0 packets:
+PID OFF
+
diff --git a/config/tnc-startup.kpc2 b/config/tnc-startup.kpc2
new file mode 100644
index 0000000..c666e18
--- /dev/null
+++ b/config/tnc-startup.kpc2
@@ -0,0 +1,30 @@
+# $Id: tnc-startup.kpc2,v 1.13 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+# This is the TNC Startup file for Kantronics TNC.
+# lines that begin with a pound sign are comments.
+#
+#
+HID off
+#CWID every 0
+B E 0
+DIGI on
+ECho off
+FLow off
+FUll off
+HEA off
+LFadd off
+AUTOLF off
+MCOM off
+MON ON
+MResp OFF
+MRPt on
+MSTamp off
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYAlias WIDE1-1
+#
+NEWmode off
+SCR 0
+#
diff --git a/config/tnc-startup.kpc3 b/config/tnc-startup.kpc3
new file mode 100644
index 0000000..2672cae
--- /dev/null
+++ b/config/tnc-startup.kpc3
@@ -0,0 +1,76 @@
+# $Id: tnc-startup.kpc3,v 1.22 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the TNC Startup file for Kantronics TNC.
+# lines that begin with a pound sign are comments.
+#
+# This configuration sets up Control-E mode for a KPC-3+ (GPS
+# connected to the 2nd serial port).  When Xastir is actively
+# getting GPS fixes, the TNC beacons only what Xastir sends to it.
+# When Xastir stops getting GPS data from the TNC, the TNC will
+# revert to dumb-tracker mode and start sending NMEA strings out all
+# by itself at a 20-minute rate.  If the GPS get disconnected or
+# turned off, the dumb-tracker mode will cease to send out beacons.
+# This last function is done by the "CLEAR" parameter for the BLT
+# commands.
+#
+# Some people prefer to turn off the GPS but still have the TNC
+# beacon their last good GPS position when in dumb-tracker mode.
+# To do this, remove the "CLEAR" parameters from the BLT command
+# lines.
+#
+
+int terminal
+
+# Clear out the LT buffers so we don't have old data in there:
+LT 1
+LT 2
+LT 3
+LT 4
+# Clear out the buffer regularly to prevent stale data:
+BLT 1 00:20:00 CLEAR
+BLT 2 00:20:00 CLEAR
+BLT 3 00:00:00
+BLT 4 00:00:00
+# Set up the NMEA strings to capture:
+GPSHEAD 1 $GPRMC
+GPSHEAD 2 $GPGGA
+#
+GPSPORT 4800 NORMAL CHECKSUM
+LGETCHAR $05
+#
+HID off
+#CWID every 0
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYAlias WIDE1-1
+#
+B E 0
+DIGI on
+ECho off
+FILT off
+FLow off
+FUll off
+HEA off
+LFadd off
+LFSup ON
+AUTOLF off
+MCOM off
+MON ON
+MResp OFF
+MRPt on
+MSTamp off
+MXMit off
+NEWmode off
+#PACLen 128
+PASSALL off
+#
+# Important!  Monitor only PID 0xf0 packets:
+PID off
+#
+SCR 0
+# B E 0 must be set to 0 or both APRS and your TNC will send BCNS
+# Which will alternate in everyones L and A lists and fill up
+# their logs.  Do NOT set B E to anything other than 0 while APRS
+# is running.
diff --git a/config/tnc-startup.null b/config/tnc-startup.null
new file mode 100644
index 0000000..e69de29
diff --git a/config/tnc-startup.paccomm b/config/tnc-startup.paccomm
new file mode 100644
index 0000000..4758b00
--- /dev/null
+++ b/config/tnc-startup.paccomm
@@ -0,0 +1,50 @@
+# $Id: tnc-startup.paccomm,v 1.18 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the TNC Startup file for a Pac-Comm TNC with v5.x firmware.
+# Adapted from Kantronics startup file by Kurt Freiberger, WB5BBW
+
+# lines that begin with a pound sign are comments.
+
+HID off
+#CWID every 0
+MON 0
+ECHO off
+#MYCall WB5BBW
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYAlias WIDE1-1
+#
+#
+#
+#MY1Alias LOCAL
+#MY2Alias REGION
+#MY3Alias WORLD
+#
+# B E 0 must be set to 0 or both APRS and your TNC will send BCNS
+# Which will alternate in everyones L and A lists and fill up
+# their logs.  Do NOT set B E to anything other than 0 while APRS
+# is running.
+B E 0
+# This enables DIGI On and DIGI-SWAP,DIGI-NOT-OWN, DIGI-ONCE enabled.
+DIGI 7
+FLow off
+FUll off
+HEA off
+LFadd off
+AUTOLF off
+MCOM off
+MFILT $00
+MRPt on
+MSTamp off
+NEWmode off
+PASSALL off
+SCR 0
+MON 1
+#
+# Important!  Monitor only PID 0xf0 packets:
+PIDCHECK on
+#
+# End of tnc-startup.pac
+#
diff --git a/config/tnc-startup.pico b/config/tnc-startup.pico
new file mode 100644
index 0000000..364b85c
--- /dev/null
+++ b/config/tnc-startup.pico
@@ -0,0 +1,86 @@
+# $Id: tnc-startup.pico,v 1.22 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the TNC Startup file for a dual-port Paccomm PicoPacket TNC.
+# lines that begin with a pound sign are comments.
+
+ECHO off
+AUTOLF on
+BEACON EVERY 0
+#
+# Clear the GPS buffers
+LTEXT %
+L1TEXT %
+L2TEXT %
+L3TEXT %
+#
+# Set up the NMEA strings we wish to capture:
+#GPSTEXT %
+GPSTEXT $GPRMC
+#
+#LG1TEXT %
+LG1TEXT $GPGGA
+#
+LG2TEXT %
+#LG2TEXT $GPVTG
+#
+LG3TEXT %
+#LG3TEXT $PGRME
+#
+# Digipeat,callsign substitution,
+# no digi of own packets, and digi-once
+DIGIPEAT 7
+ELOC 0
+FLOW off
+FULLDUP off
+GPS off
+HEADERLI off
+HID off
+#CWID every 0
+INTERVAL 0
+LFADD off
+LGETCHAR $05
+LOC E 0
+#
+MALL ON
+MCOM off
+MCON on
+MFILTER 0
+MONITOR 3
+MRPT on
+MSTAMP off
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYALIAS WIDE1-1
+#
+#MY1ALIAS SAR
+#MY2ALIAS ESAR
+#MY3ALIAS ESAR2
+NEWMODE off
+NOMODE on
+#PACLEN 128
+#
+# Only used in KISS mode?
+PERSIST 128
+#
+PASSALL off
+#
+# Important!  Monitor only PID 0xf0 packets:
+PIDCHECK on
+#
+PMS off
+SCREENLN 0
+#
+# Only used in KISS mode?
+SLOTTIME 15
+#
+TXDELAY 30
+XFLOW off
+#
+#
+# BEACON EVERY 0 must be set to 0 or both Xastir and your TNC will send
+# beacons which will alternate in everyones lists and fill up their
+# logs.  Do NOT set BEACON EVERY to anything other than 0 while Xastir
+# is running.
+
diff --git a/config/tnc-startup.sys b/config/tnc-startup.sys
new file mode 100644
index 0000000..1ecef8a
--- /dev/null
+++ b/config/tnc-startup.sys
@@ -0,0 +1,56 @@
+# $Id: tnc-startup.sys,v 1.20 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This is the TNC Startup file for Kantronics TNC.
+# lines that begin with a pound sign are comments.
+
+int terminal
+
+ECHO off
+HID off
+#CWID off
+#CWID every 0
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYAlias WIDE1-1
+#
+B E 0
+DIGI on
+EXP on
+Filt off
+FLow off
+FUll off
+HEA off
+LFadd off
+LFSup on
+AUTOLF off
+MCOM off
+MFILT off
+MON on
+MResp off
+MRPt on
+MSTamp off
+MXMit off
+NEWmode off
+#PACLen 128
+PASSALL off
+#
+#
+# Important!  Monitor only PID 0xf0 packets:
+# *Kantronics*
+PID off
+# *TAPR2*
+MNOAX25 off
+# *Paccomm*
+PIDCHECK on
+# *AEA*
+MPROTO OFF
+# End of monitor only PID 0xf0 packets section
+#
+#
+SCR 0
+# B E 0 must be set to 0 or both APRS and your TNC will send BCNS
+# Which will alternate in everyones L and A lists and fill up
+# their logs.  Do NOT set B E to anything other than 0 while APRS
+# is running.
diff --git a/config/tnc-startup.thd7 b/config/tnc-startup.thd7
new file mode 100644
index 0000000..1ae2808
--- /dev/null
+++ b/config/tnc-startup.thd7
@@ -0,0 +1,79 @@
+# $Id: tnc-startup.thd7,v 1.17 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# TNC Init file for KENWOOD TH-D7
+#
+#--------------------------------------------------
+# Note: Terminal Control commands are send without
+# CONTROL-C before the lines.
+#--------------------------------------------------
+#
+#--------------------------------------------------
+# Turn on Terminal Control
+#
+# This will make the TH-D7 drop out of Packet mode.
+# Once out of Packet mode, the TH-D7 will forget
+# all old TNC settings and even KISS mode, so we
+# can start from a clean situation.
+#--------------------------------------------------
+#
+##META <no-ctrl-c>
+TC 1
+# Pause one second
+##META <delay>
+##META <delay>
+#
+#--------------------------------------------------
+# Turn off Terminal Control
+#
+# This will make the TH-D7 switch to Packet mode.
+#--------------------------------------------------
+#
+##META <no-ctrl-c>
+TC 0
+# Pause for two seconds just in case
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+#
+#--------------------------------------------------
+# Initialize the TNC
+#
+# This will setup the TH-D7 TNC for use with APRS.
+#--------------------------------------------------
+#
+HID off
+#CWID off
+AWlen 8
+BBSMsgs ON
+B E 0
+LOC E 0
+Echo off
+FLow off
+AUTOLF off
+MCOM off
+MON ON
+MRPt on
+PACLen 128
+PASSALL off
+#
+# Enable this line ONLY if you're running 9600 baud packet.  It
+# changes the on-the-air speed from the default 1200 baud.
+#HBAUD 9600
+#
+TXDELAY 25
+#
+#--------------------------------------------------
+# Initialize the GPS
+#
+# Enable the commands if running with GPS.
+# If running without GPS, leave them disabled.
+#--------------------------------------------------
+#
+#GBAUD 4800
+#GPSTEXT $GPRMC
+#LTMH OFF
+#LTM 10
+#
diff --git a/config/tnc-startup.tnc2 b/config/tnc-startup.tnc2
new file mode 100644
index 0000000..0f275db
--- /dev/null
+++ b/config/tnc-startup.tnc2
@@ -0,0 +1,48 @@
+# $Id: tnc-startup.tnc2,v 1.7 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2005-2012  The Xastir Group
+#
+# This is the TNC Startup file for a TAPR TNC2 style of TNC.  This
+# includes many TNC's from TAPR, Paccomm, MFJ, AEA, etc that were
+# based on the original TAPR-2 design.
+
+# lines that begin with a pound sign are comments.
+
+HID off
+#CWID every 0
+MON 0
+ECHO off
+#MYCall WB5BBW
+#
+# Important!  Only uncomment if really needed as a fill-in digi:
+#MYAlias WIDE1-1
+#
+#MY1Alias WIDE
+#MY2Alias REGION
+#MY3Alias WORLD
+# B E 0 must be set to 0 or both APRS and your TNC will send BCNS
+# Which will alternate in everyones L and A lists and fill up
+# their logs.  Do NOT set B E to anything other than 0 while APRS
+# is running.
+B E 0
+# This enables DIGI On and DIGI-SWAP,DIGI-NOT-OWN, DIGI-ONCE enabled.
+DIGI 7
+FLow off
+FUll off
+HEA off
+LFadd off
+AUTOLF off
+MCOM off
+MFILT $00
+MRPt on
+MSTamp off
+NEWmode off
+PASSALL off
+SCR 0
+MON 1
+#
+# Important!  Monitor only PID 0xf0 packets:
+PIDCHECK on
+#
+# End of tnc-startup.tnc2
+#
diff --git a/config/tnc-startup.tnc2-ui b/config/tnc-startup.tnc2-ui
new file mode 100644
index 0000000..ad77a03
--- /dev/null
+++ b/config/tnc-startup.tnc2-ui
@@ -0,0 +1,19 @@
+# $Id: tnc-startup.tnc2-ui,v 1.11 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+# This is the TNC Startup file for the TNC2-UI TNC.
+# lines that begin with a pound sign are comments.
+
+HID off
+#CWID off
+MONITOR OFF
+ECHO OFF
+LF OFF
+BEACON 0
+LTIME 0
+HEADER OFF
+MCOM OFF
+AXLF OFF
+MONITOR ON
+
diff --git a/config/tnc-stop.d700 b/config/tnc-stop.d700
new file mode 100644
index 0000000..c1a1589
--- /dev/null
+++ b/config/tnc-stop.d700
@@ -0,0 +1,48 @@
+# $Id: tnc-stop.d700,v 1.8 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+#TNC STOP FILE
+# Undo any settings make in tnc-startup.sys
+# Edit this file for your tnc!
+UNPROTO CQ
+AUTOLF ON
+ECHO ON
+#Don't send CONTROL-C before this line
+##META <no-ctrl-c>
+TC 1
+##Pause for one second
+##META <delay>
+##META <delay>
+# Turn off AUX port
+##META <no-ctrl-c>
+GU 0
+##META <delay>
+#Put the TNC in internal mode since this is where we want to end up
+# Change the 1 to 0 to go to normal radio mode
+##META <no-ctrl-c>
+TNC 1
+# Pause for two seconds
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+# Enable 4800 baud GPS
+# Change to 2 for 9600 baud GPS
+# Disable both the META line and the GU line for no change
+##META <no-ctrl-c>
+GU 1
+# Pause for two seconds
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+#Turn off Terminal Control
+##META <no-ctrl-c>
+TC 0
+# Pause for two seconds just in case
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+#
diff --git a/config/tnc-stop.d72_d710 b/config/tnc-stop.d72_d710
new file mode 100644
index 0000000..752855f
--- /dev/null
+++ b/config/tnc-stop.d72_d710
@@ -0,0 +1,39 @@
+# $Id: tnc-stop.d72_d710,v 1.2 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2011-2012  The Xastir Group
+#
+# TNC STOP FILE for Kenwood TM-D710 or TH-D72 radios.
+# Contributed by Kai Günter, LA3QMA.
+#
+# Undo any settings make in tnc-startup.sys
+# Edit this file for your tnc!
+#
+#
+UNPROTO CQ
+AUTOLF ON
+ECHO ON
+#Don't send CONTROL-C before this line
+##META <no-ctrl-c>
+TC 1
+##Pause for one second
+##META <delay>
+##META <delay>
+##META <delay>
+#Put the TNC in internal mode since this is where we want to end up
+# Change the 1 to 0 to go to normal radio mode
+##META <no-ctrl-c>
+TN 0,0
+# Pause for two seconds
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+#Turn off Terminal Control
+##META <no-ctrl-c>
+TC 0
+# Pause for two seconds just in case
+##META <delay>
+##META <delay>
+##META <delay>
+##META <delay>
+#
diff --git a/config/tnc-stop.sys b/config/tnc-stop.sys
new file mode 100644
index 0000000..d0cc71b
--- /dev/null
+++ b/config/tnc-stop.sys
@@ -0,0 +1,9 @@
+# $Id: tnc-stop.sys,v 1.9 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+#TNC STOP FILE
+# Undo any settings make in tnc-startup.sys
+# Edit this file for your tnc!
+UNPROTO CQ
+AUTOLF ON
diff --git a/config/tnc-stop.thd7 b/config/tnc-stop.thd7
new file mode 100644
index 0000000..c6c7173
--- /dev/null
+++ b/config/tnc-stop.thd7
@@ -0,0 +1,39 @@
+# $Id: tnc-stop.thd7,v 1.8 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+# TNC Stop file for KENWOOD TH-D7
+#
+#--------------------------------------------------
+# Note: Terminal Control commands are send without
+# CONTROL-C before the lines.
+#--------------------------------------------------
+#
+#--------------------------------------------------
+# Turn on Terminal Control
+#
+# This will make the TH-D7 drop out of Packet mode.
+# Once out of Packet mode, the TH-D7 will forget
+# all TNC settings. No need to restore anything.
+#--------------------------------------------------
+#
+##META <no-ctrl-c>
+TC 1
+# Pause one second
+##META <delay>
+##META <delay>
+#
+#--------------------------------------------------
+# Resume standalone APRS use.
+#
+# GPS en Beacon settings are not changed. Once back
+# in APRS mode, the GPS and Beacon are resumed as
+# they were.
+#--------------------------------------------------
+#
+##META <no-ctrl-c>
+TNC 1
+# Pause one second
+##META <delay>
+##META <delay>
+#
diff --git a/config/tnc-stop.tnc2-ui b/config/tnc-stop.tnc2-ui
new file mode 100644
index 0000000..b1a4738
--- /dev/null
+++ b/config/tnc-stop.tnc2-ui
@@ -0,0 +1,12 @@
+# $Id: tnc-stop.tnc2-ui,v 1.8 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012  The Xastir Group
+#
+# This is the TNC Startup file for the TNC2-UI TNC.
+# lines that begin with a pound sign are comments.
+
+MONITOR OFF
+LF ON
+ECHO ON
+MONITOR ON
+
diff --git a/config/xastir.rgb b/config/xastir.rgb
new file mode 100644
index 0000000..ae14a83
--- /dev/null
+++ b/config/xastir.rgb
@@ -0,0 +1,92 @@
+000 000 000 black
+069 069 069 gray27
+047 079 079 DarkSlateGray
+089 089 089 gray35
+135 135 135 gray53
+169 169 169 darkgray
+186 186 186 gray73
+204 204 204 gray80
+207 207 207 gray81
+211 211 211 lightgray
+219 219 219 gray86
+255 255 255 white
+
+000 000 255 blue
+000 000 238 blue2
+000 000 205 blue3
+000 000 139 blue4
+173 216 230 lightblue
+030 144 255 DodgerBlue
+065 105 225 RoyalBlue
+070 130 180 SteelBlue
+000 191 255 DeepSkyBlue
+000 000 205 MediumBlue
+000 000 128 NavyBlue
+
+000 255 000 green
+000 238 000 green2
+000 205 000 green3
+000 139 000 green4
+152 251 152 PaleGreen
+050 205 050 LimeGreen
+060 179 113 MediumSeaGreen
+034 139 034 ForestGreen
+000 100 000 DarkGreen
+
+000 255 255 cyan
+000 238 238 cyan2
+000 205 205 cyan3
+000 139 139 cyan4
+224 255 255 LightCyan
+
+255 000 000 red
+238 000 000 red2
+205 000 000 red3
+139 000 000 red4
+
+255 000 255 magenta
+238 000 238 magenta2
+205 000 205 magenta3
+139 000 139 magenta4
+
+255 255 000 yellow
+238 238 000 yellow2
+238 238 150 yellow3
+139 139 000 yellow4
+250 250 210 LightGoldenrodYellow
+238 232 170 PaleGoldenrod
+255 248 220 cornsilk
+
+255 165 000 orange
+238 154 000 orange2
+205 133 000 orange3
+205 102 000 DarkOrange3
+255 069 000 OrangeRed
+
+178 034 034 firebrick
+188 143 143 RosyBrown
+255 180 180 RosyBrown2
+
+165 042 042 brown
+255 064 064 brown1
+205 051 051 brown3
+255 130 071 sienna1
+
+064 224 208 turquoise
+186 085 211 mediumorchid
+153 050 204 DarkOrchid
+160 032 240 purple
+127 255 000 chartreuse
+230 230 250 lavender
+221 160 221 plum
+238 174 238 plum2
+250 128 114 salmon
+255 192 203 pink
+255 228 225 MistyRose
+255 174 185 LightPink1
+255 105 180 HotPink
+
+127 255 127 tgr_park_1
+255 247 159 tgr_city_1
+175 215 127 tgr_forest_1
+0   159 255 tgr_water_1
diff --git a/configure b/configure
new file mode 100755
index 0000000..02fb440
--- /dev/null
+++ b/configure
@@ -0,0 +1,14320 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.68 for xastir 2.0.4.
+#
+# Report bugs to <xastir at xastir.org>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	# Preserve -v and -x to the replacement shell.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	case $- in # ((((
+	  *v*x* | *x*v* ) as_opts=-vx ;;
+	  *v* ) as_opts=-v ;;
+	  *x* ) as_opts=-x ;;
+	  * ) as_opts= ;;
+	esac
+	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and xastir at xastir.org
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='xastir'
+PACKAGE_TARNAME='xastir'
+PACKAGE_VERSION='2.0.4'
+PACKAGE_STRING='xastir 2.0.4'
+PACKAGE_BUGREPORT='xastir at xastir.org'
+PACKAGE_URL=''
+
+ac_unique_file="src/xastir.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_header_list=
+ac_func_list=
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+MAGIC_BIN
+GMAGIC_BIN
+DAVIS_FALSE
+DAVIS_TRUE
+LIBRTREE
+SUBRTREE
+found_gdal_config
+MYSQL_CONFIG
+LWPOSTGIS
+PG_CONFIG
+LIBSHP
+CONTSHP
+SUBSHP
+POW_LIB
+LIBOBJS
+ALLOCA
+LIBCOMPAT
+wget
+xfontsel
+mv
+sed
+X_EXTRA_LIBS
+X_LIBS
+X_PRE_LIBS
+X_CFLAGS
+XMKMF
+gpsman
+festival
+gv
+lpr
+convert
+gm
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+RANLIB
+LN_S
+EGREP
+GREP
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+with_festival
+with_gpsman
+with_errorpopups
+with_lsb
+with_xorg_175_workaround
+with_x
+with_libcurl
+with_motif_includes
+with_motif_libs
+with_libproj
+with_internal_shapelib
+with_shapelib
+with_pcre
+with_geotiff
+with_postgis
+with_mysql
+with_ax25
+with_dbfawk
+with_gdal
+with_rtree
+enable_davis
+with_libgc
+with_profiling
+with_map_cache
+with_bdb_libdir
+with_bdb_incdir
+with_graphicsmagick
+with_imagemagick
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+XMKMF'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+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=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -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_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$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 ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$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 | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$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 ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    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 | -n)
+    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 ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$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_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=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 ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# 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 the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  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
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # 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 <<_ACEOF
+\`configure' configures xastir 2.0.4 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/xastir]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --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
+
+X features:
+  --x-includes=DIR    X include files are in DIR
+  --x-libraries=DIR   X library files are in DIR
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of xastir 2.0.4:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-davis          Turn on Davis support
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --without-festival        Disable festival features.
+  --without-gpsman          Disable gpsman features.
+  --with-errorpopups        Send error popups to stderr.
+  --with-lsb                Enable Linux Standard Base.
+  --with-xorg_175_workaround
+                          Employ workaround for broken Xorg 1.7.5 server
+  --with-x                use the X Window System
+  --without-libcurl         Disable libcurl features.
+  --with-motif-includes     Set path for motif includes (default none)
+  --with-motif-libs         Set path for motif libraries (default none)
+  --without-libproj         Disable libproj features.
+  --with-internal-shapelib  Force use of internal shapelib library.
+  --without-shapelib        Disable shapelib features.
+  --without-pcre            Disable pcre features.
+  --without-geotiff         Disable geotiff features.
+  --with-postgis            Enable Postgresql with PostGIS.
+  --with-mysql	            Enable MySQL, with spatial support if available.
+  --without-ax25            Disable ax25 features.
+  --without-dbfawk          Disable dbfawk features.
+  --without-gdal            Disable gdal features.
+  --without-rtree           Disable spatial indexing of shapefiles.
+  --with-libgc              Enable libgc features.
+  --with-profiling          Enable profiling features.
+  --without-map-cache       Disable Map Caching.
+  --with-bdb-libdir=DIR     Berkeley DB lib files are in DIR
+  --with-bdb-incdir=DIR     Berkeley DB include files are in DIR
+  --without-graphicsmagick  Disable graphicsmagick features.
+  --without-imagemagick     Disable imagemagick features.
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  XMKMF       Path to xmkmf, Makefile generator for X Window System
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <xastir at xastir.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+xastir configure 2.0.4
+generated by GNU Autoconf 2.68
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## -------------------------------- ##
+## Report this to xastir at xastir.org ##
+## -------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* 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_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by xastir $as_me 2.0.4, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+as_fn_append ac_header_list " sys/time.h"
+as_fn_append ac_header_list " unistd.h"
+as_fn_append ac_func_list " alarm"
+as_fn_append ac_header_list " stdlib.h"
+as_fn_append ac_header_list " sys/param.h"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+am__api_version='1.11'
+
+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
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# 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
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+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.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&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_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='xastir'
+ VERSION='2.0.4'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+#########################################################################
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+echo ""
+echo "Configuring xastir 2.0.4"
+echo ""
+
+# Take out the dots in order to create the TOCALL
+
+cat >>confdefs.h <<_ACEOF
+#define XASTIR_TOCALL "`echo 2.0.4 | sed -e 's/^/APX/' -e 's/\.//g'`"
+_ACEOF
+
+
+# Check for host type
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+# Define _GNU_SOURCE if appropriate
+# doesn't work with older (heh) autoconfs
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_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 $# != 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
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#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))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+  if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#	  define __EXTENSIONS__ 1
+	  $ac_includes_default
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_safe_to_define___extensions__=yes
+else
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_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 $# != 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
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+for ac_prog in gawk mawk 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+#AC_PROG_YACC
+
+# test for devices
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for devices" >&5
+$as_echo_n "checking for devices... " >&6; }
+if test -d /proc/registry ; then
+ac_tnc_port=/dev/ttyS0
+ac_gps_port=/dev/ttyS1
+elif test -c /dev/cuaa0 ; then
+ac_tnc_port=/dev/cuaa0
+ac_gps_port=/dev/cuaa1
+elif test -c /dev/ttyS0 ; then
+ac_tnc_port=/dev/ttyS0
+ac_gps_port=/dev/ttyS1
+elif test -c /dev/cua/a ; then
+ac_tnc_port=/dev/cua/a
+ac_gps_port=/dev/cua/b
+else
+ac_tnc_port=none
+ac_gps_port=none
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define TNC_PORT "$ac_tnc_port"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GPS_PORT "$ac_gps_port"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found $ac_tnc_port and $ac_gps_port" >&5
+$as_echo "found $ac_tnc_port and $ac_gps_port" >&6; }
+
+
+# add includes and libs
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for search paths" >&5
+$as_echo_n "checking for search paths... " >&6; }
+
+test -d /usr/local/include && CPPFLAGS="-I/usr/local/include $CPPFLAGS"
+test -d /usr/local/lib && LDFLAGS="-L/usr/local/lib $LDFLAGS"
+
+for d in /sw /opt /opt/local /usr/dt/share /usr/sfw /opt/sfw; do
+test -d $d/include && CPPFLAGS="$CPPFLAGS -I$d/include"
+test -d $d/lib && LDFLAGS="$LDFLAGS -L$d/lib"
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+
+
+# check for pthread first
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthread or
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: threads are created detached by default
+        # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr=PTHREAD_CREATE_JOINABLE;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ok=PTHREAD_CREATE_JOINABLE
+else
+  ok=unknown
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        if test x"$ok" = xunknown; then
+                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr=PTHREAD_CREATE_UNDETACHED;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ok=PTHREAD_CREATE_UNDETACHED
+else
+  ok=unknown
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        fi
+        if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
+
+$as_echo "#define PTHREAD_CREATE_JOINABLE \$ok" >>confdefs.h
+
+        fi
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ok}" >&5
+$as_echo "${ok}" >&6; }
+        if test x"$ok" = xunknown; then
+                { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: we do not know how to create joinable pthreads" >&5
+$as_echo "$as_me: WARNING: we do not know how to create joinable pthreads" >&2;}
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+        flag=no
+        case "${host_cpu}-${host_os}" in
+                *-aix* | *-freebsd*)     flag="-D_THREAD_SAFE";;
+                *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+        if test "x$flag" != xno; then
+                PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with cc_r
+        # Extract the first word of "cc_r", so it can be a program name with args.
+set dummy cc_r; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PTHREAD_CC="cc_r"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+else
+        PTHREAD_CC="$CC"
+fi
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+        :
+else
+        acx_pthread_ok=no
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# add compiler flags
+
+# notes -- gcc only! HPUX doesn't work for this so no "-Ae +O2"
+
+
+# everybody likes "-g -O2", right?
+# TVR: Not only does "everybody" not like "-g -O2", but the code below
+# is unnecessary for GCC, which does like "-g -O2".  The autoconf macros that
+# probe for the C  compiler will put "-g -O2" into CFLAGS if the compiler is
+# GCC and the user has not specified any CFLAGS, and leaves CFLAGS alone
+# if the user has set it him/herself.  The "##" commented code
+# below forces -g -O2 into CFLAGS even if the user has specified something
+# else.
+##for f in -g -O2; do
+## eventually write a test for these
+## gcc already checks for -g earlier!
+##echo $CFLAGS | grep -- $f > /dev/null || CFLAGS="$CFLAGS $f"
+##done
+
+# brutal!
+# check for sed maybe?
+if test "$ac_cv_prog_ac_ct_CC" = "gcc"; then
+gcc --help | sed -e "/^^ /d" -e "/^ ^ /d" -e "/^  ^-/d" -e "s/  //" -e "s/ .*//" > gccflags
+
+# I need a test for -Wno-return-type and -DFUNCPROTO=15
+# before adding them
+
+for f in -no-cpp-precomp -pipe; do
+grep -- $f gccflags > /dev/null && CFLAGS="$CFLAGS $f"
+done
+
+# delete temporary file
+rm -f gccflags
+
+# add any other flags that aren't added earlier
+# Can't add "-Wno-unused-parameter" as older compilers don't like
+# it.
+#
+for f in -W -Wall -Wpointer-arith -Wstrict-prototypes; do
+echo $CFLAGS | grep -- $f > /dev/null || CFLAGS="$CFLAGS $f"
+done
+
+# Now check whether to use -Wno-unused-parameter (gcc 3) or -Wno-unused
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler accepts -Wno-unused-parameter" >&5
+$as_echo_n "checking whether compiler accepts -Wno-unused-parameter... " >&6; }
+save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS -Wno-unused-parameter"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using -Wno-unused" >&5
+$as_echo "no, using -Wno-unused" >&6; }; CFLAGS="$save_CFLAGS -Wno-unused"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# end gcc-specific checks
+fi
+
+# add any pthread flags now
+CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compiler flags" >&5
+$as_echo_n "checking for compiler flags... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using $CFLAGS" >&5
+$as_echo "using $CFLAGS" >&6; }
+
+
+# set XASTIR_SYSTEM
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for system" >&5
+$as_echo_n "checking for system... " >&6; }
+
+case "$host_os" in
+cygwin*)
+  system=Cygnus
+;;
+darwin*)
+  system=Darwin
+  LDFLAGS="-L/sw/lib -L/opt/local/lib $LDFLAGS"
+  CPPFLAGS="-I/sw/include -I/opt/local/include $CPPFLAGS"
+  EXTRA_BIN_PATH=":/opt/local/bin:/sw/bin"
+;;
+freebsd*)
+  system=FreeBSD
+;;
+hpux*)
+  system=HP/UX
+;;
+linux*)
+  system=Linux
+#
+#
+# Useful for testing MacOSX paths on a Linux development box:
+#  EXTRA_BIN_PATH=":/opt/local/bin:/sw/bin"
+#
+#
+;;
+netbsd*)
+  system=NetBSD
+;;
+openbsd*)
+  system=OpenBSD
+;;
+solaris*)
+  system=Solaris
+;;
+*)
+  system=unknown
+;;
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define XASTIR_SYSTEM "$system"
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $system" >&5
+$as_echo "$system" >&6; }
+
+
+# Check for binaries
+use_festival=yes
+use_gpsman=yes
+use_err_popups=no
+use_lsb=no
+use_spatial_db=no
+use_postgis=no
+use_mysql_spatial=no
+
+# Check whether --with-festival was given.
+if test "${with_festival+set}" = set; then :
+  withval=$with_festival; use_festival=$withval
+fi
+
+
+
+# Check whether --with-gpsman was given.
+if test "${with_gpsman+set}" = set; then :
+  withval=$with_gpsman; use_gpsman=$withval
+fi
+
+
+
+# Check whether --with-errorpopups was given.
+if test "${with_errorpopups+set}" = set; then :
+  withval=$with_errorpopups; use_err_popups=$withval
+fi
+
+
+
+# Check whether --with-lsb was given.
+if test "${with_lsb+set}" = set; then :
+  withval=$with_lsb; use_lsb=$withval
+fi
+
+
+
+# Check whether --with-xorg_175_workaround was given.
+if test "${with_xorg_175_workaround+set}" = set; then :
+  withval=$with_xorg_175_workaround;
+else
+  with_xorg_175_workaround=no
+fi
+
+if test "x$with_xorg_175_workaround" != xno; then :
+
+$as_echo "#define XASTIR_XORG_SERVER_175_BUG 1" >>confdefs.h
+
+fi
+
+# Now that all the various "use_" variables are set, probe for binaries.
+
+BINPATH=$PATH
+
+for d in / /usr /usr/local /usr/X11 /usr/X11R6 /usr/sfw /opt/sfw /opt/local /sw; do
+test -d $d/bin && echo $BINPATH | grep -- $d/bin > /dev/null || BINPATH="$BINPATH:$d/bin"
+done
+
+# it would be much nicer to do this in a for loop
+
+if test "$use_lsb" = "yes"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CONVERT 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CONVERT_PATH "/opt/Xastir/bin/gm convert"
+_ACEOF
+
+else
+  # Extract the first word of "gm version", so it can be a program name with args.
+set dummy gm version; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_gm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $gm in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_gm="$gm" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_gm="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_gm" && ac_cv_path_gm="no"
+  ;;
+esac
+fi
+gm=$ac_cv_path_gm
+if test -n "$gm"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gm" >&5
+$as_echo "$gm" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /usr/bin/gm.exe" >&5
+$as_echo_n "checking for /usr/bin/gm.exe... " >&6; }
+if ${ac_cv_file__usr_bin_gm_exe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  test "$cross_compiling" = yes &&
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "/usr/bin/gm.exe"; then
+  ac_cv_file__usr_bin_gm_exe=yes
+else
+  ac_cv_file__usr_bin_gm_exe=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__usr_bin_gm_exe" >&5
+$as_echo "$ac_cv_file__usr_bin_gm_exe" >&6; }
+if test "x$ac_cv_file__usr_bin_gm_exe" = xyes; then :
+  gm="/usr/bin/gm"
+fi
+
+  if test "$gm" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CONVERT 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CONVERT_PATH "${gm} convert"
+_ACEOF
+
+  else
+    # Extract the first word of "convert --version", so it can be a program name with args.
+set dummy convert --version; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_convert+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $convert in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_convert="$convert" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_convert="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_convert" && ac_cv_path_convert="no"
+  ;;
+esac
+fi
+convert=$ac_cv_path_convert
+if test -n "$convert"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $convert" >&5
+$as_echo "$convert" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /usr/bin/convert.exe" >&5
+$as_echo_n "checking for /usr/bin/convert.exe... " >&6; }
+if ${ac_cv_file__usr_bin_convert_exe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  test "$cross_compiling" = yes &&
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "/usr/bin/convert.exe"; then
+  ac_cv_file__usr_bin_convert_exe=yes
+else
+  ac_cv_file__usr_bin_convert_exe=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__usr_bin_convert_exe" >&5
+$as_echo "$ac_cv_file__usr_bin_convert_exe" >&6; }
+if test "x$ac_cv_file__usr_bin_convert_exe" = xyes; then :
+  convert="/usr/bin/convert"
+fi
+
+    if test "$convert" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CONVERT 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CONVERT_PATH "${convert}"
+_ACEOF
+
+    fi
+  fi
+fi
+
+# Extract the first word of "lpr /dev/null", so it can be a program name with args.
+set dummy lpr /dev/null; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_lpr+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $lpr in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_lpr="$lpr" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_lpr="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_lpr" && ac_cv_path_lpr="no"
+  ;;
+esac
+fi
+lpr=$ac_cv_path_lpr
+if test -n "$lpr"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lpr" >&5
+$as_echo "$lpr" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$lpr" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LPR 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define LPR_PATH "${lpr}"
+_ACEOF
+
+fi
+
+#Find gv executable
+# Extract the first word of "gv", so it can be a program name with args.
+set dummy gv; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_gv+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $gv in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_gv="$gv" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_gv="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_gv" && ac_cv_path_gv="no"
+  ;;
+esac
+fi
+gv=$ac_cv_path_gv
+if test -n "$gv"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gv" >&5
+$as_echo "$gv" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+if test "$gv" != "no"; then
+  # Test gv version
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking gv version" >&5
+$as_echo_n "checking gv version... " >&6; }
+  gv_new="no";
+  gv_version=`gv --version 2>&1`
+  gv_test=`echo $gv_version | cut -d ' ' -f 1`
+  if test "$gv_test" != "gv"; then
+    gv_version=`gv -v 2>&1`
+  fi
+  gv_test=`echo $gv_version | cut -d ' ' -f 1`
+  if test "$gv_test" != "gv"; then
+    # No gv found.  Put an AC_PATH_PROG here so the "then" clause has
+    # something to do and so that we get proper output to the user.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: gv version test likely exited with error, this is what it said: $gv_version" >&5
+$as_echo "gv version test likely exited with error, this is what it said: $gv_version" >&6; }
+  else
+    gv_short_version=`echo $gv_version | cut -d ' ' -f 2`
+    gv_major=`echo $gv_short_version | cut -d '.' -f 1`
+    gv_minor=`echo $gv_short_version | cut -d '.' -f 2`
+    gv_tiny=`echo $gv_short_version | cut -d '.' -f 3`
+    if test "$gv_major" -gt 3; then
+      gv_new="yes";
+    elif test "$gv_major" -ge 3 -a "$gv_minor" -gt 6; then
+      gv_new="yes";
+    elif test "$gv_major" -ge 3 -a "$gv_minor" -ge 6 -a "$gv_tiny" -ge 1; then
+      gv_new="yes";
+    fi
+    if test "$gv_new" != "no"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: new, >= 3.6.1" >&5
+$as_echo "new, >= 3.6.1" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GV 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_NEW_GV 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GV_PATH "${gv}"
+_ACEOF
+
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: old, pre 3.6.1" >&5
+$as_echo "old, pre 3.6.1" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GV 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_OLD_GV 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GV_PATH "${gv}"
+_ACEOF
+
+    fi
+  fi
+fi
+
+if test "$use_festival" != "no"; then
+ # Extract the first word of "festival", so it can be a program name with args.
+set dummy festival; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_festival+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $festival in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_festival="$festival" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_festival="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_festival" && ac_cv_path_festival="no"
+  ;;
+esac
+fi
+festival=$ac_cv_path_festival
+if test -n "$festival"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $festival" >&5
+$as_echo "$festival" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$festival" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FESTIVAL 1
+_ACEOF
+
+ fi
+fi
+
+if test "$use_gpsman" != "no"; then
+ # Extract the first word of "gpsman haslib gpsmanshp", so it can be a program name with args.
+set dummy gpsman haslib gpsmanshp; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_gpsman+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $gpsman in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_gpsman="$gpsman" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_gpsman="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_gpsman" && ac_cv_path_gpsman="no"
+  ;;
+esac
+fi
+gpsman=$ac_cv_path_gpsman
+if test -n "$gpsman"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gpsman" >&5
+$as_echo "$gpsman" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$gpsman" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GPSMAN 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GPSMAN_PATH "${gpsman}"
+_ACEOF
+
+ fi
+fi
+
+if test "$use_err_popups" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ERROR_POPUPS 1
+_ACEOF
+
+fi
+
+if test "$use_lsb" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define __LSB__ 1
+_ACEOF
+
+fi
+
+
+
+
+
+# if the probes failed, then make sure the "use_" variables are set to no,
+# even if we requested them.
+if test "x${festival}" = "xno"; then
+  use_festival=no
+fi
+if test "x${gpsman}" = "xno"; then
+  use_gpsman=no
+fi
+
+
+# JMT - XXX - what is this and why is it relevant?
+#AC_DEFINE(_REENTRANT, 1, [Use reentrant code if available.])
+
+cat >>confdefs.h <<_ACEOF
+#define STIPPLE 1
+_ACEOF
+
+
+# Checks for libraries.
+#
+#
+# Find the X11 include and library directories.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
+$as_echo_n "checking for X... " >&6; }
+
+
+# Check whether --with-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
+  case $x_includes,$x_libraries in #(
+    *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+    *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
+  $as_echo_n "(cached) " >&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 -f -r conftest.dir
+if mkdir conftest.dir; then
+  cd conftest.dir
+  cat >Imakefile <<'_ACEOF'
+incroot:
+	@echo incroot='${INCROOT}'
+usrlibdir:
+	@echo usrlibdir='${USRLIBDIR}'
+libdir:
+	@echo libdir='${LIBDIR}'
+_ACEOF
+  if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+    for ac_var in incroot usrlibdir libdir; do
+      eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
+    done
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl dylib la dll; 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) ac_x_includes= ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+    esac
+    case $ac_im_usrlibdir in
+	/usr/lib | /usr/lib64 | /lib | /lib64) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+    esac
+  fi
+  cd ..
+  rm -f -r conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R7/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R7
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R7/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R7
+/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'
+
+if test "$ac_x_includes" = no; then
+  # Guess where to find include files, by looking for Xlib.h.
+  # First, try using that file with no special directory specified.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  for ac_dir in $ac_x_header_dirs; do
+  if test -r "$ac_dir/X11/Xlib.h"; then
+    ac_x_includes=$ac_dir
+    break
+  fi
+done
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+  # Check for the libraries.
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS=$LIBS
+  LIBS="-lX11 $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize ()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  LIBS=$ac_save_LIBS
+for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+  # Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl dylib la dll; do
+    if test -r "$ac_dir/libX11.$ac_extension"; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+case $ac_x_includes,$ac_x_libraries in #(
+  no,* | *,no | *\'*)
+    # Didn't find X, or a directory has "'" in its name.
+    ac_cv_have_x="have_x=no";; #(
+  *)
+    # 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'"
+esac
+fi
+;; #(
+    *) have_x=yes;;
+  esac
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
+$as_echo "$have_x" >&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'"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
+$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
+fi
+
+if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+
+$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h
+
+  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 . . . .
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5
+$as_echo_n "checking whether -R must be followed by a space... " >&6; }
+    ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
+    ac_xsave_c_werror_flag=$ac_c_werror_flag
+    ac_c_werror_flag=yes
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+       X_LIBS="$X_LIBS -R$x_libraries"
+else
+  LIBS="$ac_xsave_LIBS -R $x_libraries"
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	  X_LIBS="$X_LIBS -R $x_libraries"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5
+$as_echo "neither works" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    ac_c_werror_flag=$ac_xsave_c_werror_flag
+    LIBS=$ac_xsave_LIBS
+  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 says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And Karl Berry says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XOpenDisplay ();
+int
+main ()
+{
+return XOpenDisplay ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5
+$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; }
+if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dnet_ntoa ();
+int
+main ()
+{
+return dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dnet_dnet_ntoa=yes
+else
+  ac_cv_lib_dnet_dnet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
+$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; }
+if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then :
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5
+$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; }
+if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet_stub  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dnet_ntoa ();
+int
+main ()
+{
+return dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dnet_stub_dnet_ntoa=yes
+else
+  ac_cv_lib_dnet_stub_dnet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
+$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; }
+if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then :
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+fi
+
+    fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LIBS="$ac_xsave_LIBS"
+
+    # msh at cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # Chad R. Larson 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 T.E. Dickey.
+    # The functions gethostbyname, getservbyname, and inet_addr are
+    # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
+    ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
+fi
+
+    if test $ac_cv_func_gethostbyname = no; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+fi
+
+      if test $ac_cv_lib_nsl_gethostbyname = no; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5
+$as_echo_n "checking for gethostbyname in -lbsd... " >&6; }
+if ${ac_cv_lib_bsd_gethostbyname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_bsd_gethostbyname=yes
+else
+  ac_cv_lib_bsd_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5
+$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; }
+if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then :
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
+fi
+
+      fi
+    fi
+
+    # lieder at 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 Leinen: it contains gethostby*
+    # variants that don't use the name server (or something).  -lsocket
+    # must be given before -lnsl if both are needed.  We assume that
+    # if connect needs -lnsl, so does gethostbyname.
+    ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes; then :
+
+fi
+
+    if test $ac_cv_func_connect = no; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
+$as_echo_n "checking for connect in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_connect+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char connect ();
+int
+main ()
+{
+return connect ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_connect=yes
+else
+  ac_cv_lib_socket_connect=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
+$as_echo "$ac_cv_lib_socket_connect" >&6; }
+if test "x$ac_cv_lib_socket_connect" = xyes; then :
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+fi
+
+    fi
+
+    # Guillermo Gomez says -lposix is necessary on A/UX.
+    ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove"
+if test "x$ac_cv_func_remove" = xyes; then :
+
+fi
+
+    if test $ac_cv_func_remove = no; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5
+$as_echo_n "checking for remove in -lposix... " >&6; }
+if ${ac_cv_lib_posix_remove+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lposix  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char remove ();
+int
+main ()
+{
+return remove ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_posix_remove=yes
+else
+  ac_cv_lib_posix_remove=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5
+$as_echo "$ac_cv_lib_posix_remove" >&6; }
+if test "x$ac_cv_lib_posix_remove" = xyes; then :
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat"
+if test "x$ac_cv_func_shmat" = xyes; then :
+
+fi
+
+    if test $ac_cv_func_shmat = no; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5
+$as_echo_n "checking for shmat in -lipc... " >&6; }
+if ${ac_cv_lib_ipc_shmat+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lipc  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shmat ();
+int
+main ()
+{
+return shmat ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ipc_shmat=yes
+else
+  ac_cv_lib_ipc_shmat=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5
+$as_echo "$ac_cv_lib_ipc_shmat" >&6; }
+if test "x$ac_cv_lib_ipc_shmat" = xyes; then :
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+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.
+  # John Interrante, Karl Berry
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5
+$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; }
+if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char IceConnectionNumber ();
+int
+main ()
+{
+return IceConnectionNumber ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ICE_IceConnectionNumber=yes
+else
+  ac_cv_lib_ICE_IceConnectionNumber=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
+$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; }
+if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then :
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+fi
+
+  LDFLAGS=$ac_save_LDFLAGS
+
+fi
+
+if test "$no_x" = "yes"; then
+  as_fn_error $? "*** No X11!  Install X-Windows development headers/libraries! ***" "$LINENO" 5
+fi
+
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+LDFLAGS="$LDFLAGS $X_LIBS"
+LIBS="$LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tan" >&5
+$as_echo_n "checking for library containing tan... " >&6; }
+if ${ac_cv_search_tan+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tan ();
+int
+main ()
+{
+return tan ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' math m; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_tan=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_tan+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_tan+:} false; then :
+
+else
+  ac_cv_search_tan=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tan" >&5
+$as_echo "$ac_cv_search_tan" >&6; }
+ac_res=$ac_cv_search_tan
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XextAddDisplay in -lXext" >&5
+$as_echo_n "checking for XextAddDisplay in -lXext... " >&6; }
+if ${ac_cv_lib_Xext_XextAddDisplay+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXext  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XextAddDisplay ();
+int
+main ()
+{
+return XextAddDisplay ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_Xext_XextAddDisplay=yes
+else
+  ac_cv_lib_Xext_XextAddDisplay=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XextAddDisplay" >&5
+$as_echo "$ac_cv_lib_Xext_XextAddDisplay" >&6; }
+if test "x$ac_cv_lib_Xext_XextAddDisplay" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBXEXT 1
+_ACEOF
+
+  LIBS="-lXext $LIBS"
+
+fi
+
+# It appears that XpGetDocumentData is not used
+# *anywhere* in Xastir, and the fact that this is being probed for has
+# confused at least one user into thinking he needed to install the X Printing
+# Extension development headers when it was completely unnecessary.  But
+# apparently  at least one linux system has a motif library that requires
+# libXp and doesn't link it in dynamically --- so this needs to be enabled?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XpGetDocumentData in -lXp" >&5
+$as_echo_n "checking for XpGetDocumentData in -lXp... " >&6; }
+if ${ac_cv_lib_Xp_XpGetDocumentData+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXp  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XpGetDocumentData ();
+int
+main ()
+{
+return XpGetDocumentData ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_Xp_XpGetDocumentData=yes
+else
+  ac_cv_lib_Xp_XpGetDocumentData=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xp_XpGetDocumentData" >&5
+$as_echo "$ac_cv_lib_Xp_XpGetDocumentData" >&6; }
+if test "x$ac_cv_lib_Xp_XpGetDocumentData" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBXP 1
+_ACEOF
+
+  LIBS="-lXp $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtDisplay in -lXt" >&5
+$as_echo_n "checking for XtDisplay in -lXt... " >&6; }
+if ${ac_cv_lib_Xt_XtDisplay+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XtDisplay ();
+int
+main ()
+{
+return XtDisplay ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_Xt_XtDisplay=yes
+else
+  ac_cv_lib_Xt_XtDisplay=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtDisplay" >&5
+$as_echo "$ac_cv_lib_Xt_XtDisplay" >&6; }
+if test "x$ac_cv_lib_Xt_XtDisplay" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBXT 1
+_ACEOF
+
+  LIBS="-lXt $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XmTextFindString in -lXm" >&5
+$as_echo_n "checking for XmTextFindString in -lXm... " >&6; }
+if ${ac_cv_lib_Xm_XmTextFindString+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XmTextFindString ();
+int
+main ()
+{
+return XmTextFindString ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_Xm_XmTextFindString=yes
+else
+  ac_cv_lib_Xm_XmTextFindString=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xm_XmTextFindString" >&5
+$as_echo "$ac_cv_lib_Xm_XmTextFindString" >&6; }
+if test "x$ac_cv_lib_Xm_XmTextFindString" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBXM 1
+_ACEOF
+
+  LIBS="-lXm $LIBS"
+
+fi
+
+
+
+
+#use_html2text=no
+#AC_PATH_PROG(html2text, [html2text --version], no, $BINPATH)
+#if test "$html2text" != "no"; then
+#  AC_DEFINE_UNQUOTED(HAVE_HTML2TEXT, 1, [Define if you have html2text])
+#  AC_DEFINE_UNQUOTED(HTML2TEXT_PATH, "${html2text}", [Path to html2text])
+#  use_html2text=yes
+#fi
+
+
+
+use_sed=no
+# Extract the first word of "sed --version", so it can be a program name with args.
+set dummy sed --version; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_sed+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $sed in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_sed="$sed" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_sed="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_sed" && ac_cv_path_sed="no"
+  ;;
+esac
+fi
+sed=$ac_cv_path_sed
+if test -n "$sed"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sed" >&5
+$as_echo "$sed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$sed" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SED 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SED_PATH "${sed}"
+_ACEOF
+
+  use_sed=yes
+fi
+
+
+
+use_mv=no
+# Extract the first word of "mv --version", so it can be a program name with args.
+set dummy mv --version; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_mv+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $mv in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_mv="$mv" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_mv="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_mv" && ac_cv_path_mv="no"
+  ;;
+esac
+fi
+mv=$ac_cv_path_mv
+if test -n "$mv"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mv" >&5
+$as_echo "$mv" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$mv" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MV 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define MV_PATH "${mv}"
+_ACEOF
+
+  use_mv=yes
+fi
+
+
+
+use_xfontsel=no
+# Extract the first word of "xfontsel", so it can be a program name with args.
+set dummy xfontsel; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_xfontsel+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $xfontsel in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_xfontsel="$xfontsel" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_xfontsel="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_xfontsel" && ac_cv_path_xfontsel="no"
+  ;;
+esac
+fi
+xfontsel=$ac_cv_path_xfontsel
+if test -n "$xfontsel"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xfontsel" >&5
+$as_echo "$xfontsel" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$xfontsel" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_XFONTSEL 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XFONTSEL_PATH "${xfontsel}"
+_ACEOF
+
+  use_xfontsel=yes
+fi
+
+
+
+use_curl=no
+curl_desired=yes
+# Note: Had to move AC_CHECK_HEADER here instead of inside the first
+# "if" statement:  It corrupted later tests, don't know why.  The
+# only downside is that we check for the libcurl headers even if
+# --without-libcurl was specified on the command-line.
+ac_fn_c_check_header_mongrel "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default"
+if test "x$ac_cv_header_curl_curl_h" = xyes; then :
+  CURL_INC="yes"
+else
+  CURL_INC="no"
+fi
+
+
+
+# Check whether --with-libcurl was given.
+if test "${with_libcurl+set}" = set; then :
+  withval=$with_libcurl; curl_desired=$withval
+fi
+
+if test "${curl_desired}" = "yes"; then
+  if test "${CURL_INC}" = "yes"; then
+    if test "${use_lsb}" = "no"; then
+      # Important: when using the three-argument version of AC_CHECK_LIB, you
+      # must do all of what is normally the default behavior in the third argument,
+      # not just the extra stuff you want to accomplish:
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl_global_init in -lcurl" >&5
+$as_echo_n "checking for curl_global_init in -lcurl... " >&6; }
+if ${ac_cv_lib_curl_curl_global_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char curl_global_init ();
+int
+main ()
+{
+return curl_global_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_curl_curl_global_init=yes
+else
+  ac_cv_lib_curl_curl_global_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curl_curl_global_init" >&5
+$as_echo "$ac_cv_lib_curl_curl_global_init" >&6; }
+if test "x$ac_cv_lib_curl_curl_global_init" = xyes; then :
+  use_curl="yes"
+                    LIBS="${LIBS} -lcurl"
+
+$as_echo "#define HAVE_LIBCURL /**/" >>confdefs.h
+
+
+fi
+
+    else
+
+$as_echo "#define HAVE_LIBCURL /**/" >>confdefs.h
+
+      LIBS="${LIBS} -lcurl"
+      use_curl=yes
+    fi
+  fi
+fi
+# Test for wget only if above libcurl tests fail
+use_wget=no
+if test "${use_curl}" = "no"; then
+  # Extract the first word of "wget --version", so it can be a program name with args.
+set dummy wget --version; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_wget+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $wget in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_wget="$wget" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_wget="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_wget" && ac_cv_path_wget="no"
+  ;;
+esac
+fi
+wget=$ac_cv_path_wget
+if test -n "$wget"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $wget" >&5
+$as_echo "$wget" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  if test "$wget" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_WGET 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define WGET_PATH "${wget}"
+_ACEOF
+
+    use_wget=yes
+  fi
+fi
+
+
+
+use_retrieval=no
+if test "${use_curl}" = "yes"; then
+  use_retrieval="yes (libcurl)"
+else
+  if test "${use_wget}" = "yes"; then
+    use_retrieval="yes (wget)"
+  fi
+fi
+
+
+
+# Test for libgps, used for accessing GPSD daemon
+#use_libgps=no
+#AC_CHECK_HEADER(gps.h, GPS_INC="yes", GPS_INC="no")
+#if test "${GPS_INC}" = "yes"; then
+#  AC_CHECK_LIB([gps], [gps_open],
+#               [use_libgps="yes"
+#                LIBS="${LIBS} -lgps"
+#                AC_DEFINE(HAVE_LIBGPS, ,
+#                          [Define to 1 if your `libgps' library has gps_open.])
+#                ])
+#fi
+
+
+
+# JMT - XXX - why is this here?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lcompat" >&5
+$as_echo_n "checking for main in -lcompat... " >&6; }
+if ${ac_cv_lib_compat_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcompat  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_compat_main=yes
+else
+  ac_cv_lib_compat_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_compat_main" >&5
+$as_echo "$ac_cv_lib_compat_main" >&6; }
+if test "x$ac_cv_lib_compat_main" = xyes; then :
+  LIBCOMPAT="-lcompat"
+
+fi
+
+
+# Check for sched_yield in librt (Needed for Solaris)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sched_yield in -lrt" >&5
+$as_echo_n "checking for sched_yield in -lrt... " >&6; }
+if ${ac_cv_lib_rt_sched_yield+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sched_yield ();
+int
+main ()
+{
+return sched_yield ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_sched_yield=yes
+else
+  ac_cv_lib_rt_sched_yield=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_sched_yield" >&5
+$as_echo "$ac_cv_lib_rt_sched_yield" >&6; }
+if test "x$ac_cv_lib_rt_sched_yield" = xyes; then :
+  LIBS="-lrt $LIBS"
+fi
+
+
+# Check for endian
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+	     #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+
+
+
+# Our old stuff.  Doesn't work in all cases.
+# Checks for header files.
+#AC_CHECK_HEADERS([Xm/Xm.h],MOTIF_INC="yes", AC_MSG_ERROR(*** Cannot find Motif include files:  Please install one of Motif/OpenMotif/Lesstif development packages. ***))
+
+
+# New stuff to check for Motif/Lesstif.  Shamelessly borrowed from
+# the opendx project. Opendx in turn snarfed their test from AC_PATH_X.
+
+# Allow "--with-motif-includes" and "--with-motif-libs" so user can
+# force a specific set of includes.
+
+# Check whether --with-motif-includes was given.
+if test "${with_motif_includes+set}" = set; then :
+  withval=$with_motif_includes; with_motif_includes=$withval
+else
+  with_motif_includes=
+fi
+
+if test "$with_motif_includes" != "yes" && test -z "$with_motif_includes"
+then
+        with_motif_includes=
+fi
+
+
+# Check whether --with-motif-libs was given.
+if test "${with_motif_libs+set}" = set; then :
+  withval=$with_motif_libs; with_motif_libs=$withval
+else
+  with_motif_libs=
+fi
+
+if test "$with_motif_libs" != "yes" && test -z "$with_motif_libs"
+then
+  with_motif_libs=
+fi
+
+  # Guess where to find include files, by looking for this one Xm .h file.
+  test -z "$xm_direct_test_include" && xm_direct_test_include=Xm/Xm.h
+
+  # First, try using that file with no special directory specified.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Motif headers" >&5
+$as_echo_n "checking for Motif headers... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$xm_direct_test_include>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+  # We can compile using X headers with no special include directory.
+  xm_includes=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: in default path" >&5
+$as_echo "in default path" >&6; }
+
+else
+
+# that test didn't work, we need to hunt a little
+# 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 \
+    "$with_motif_includes"    \
+    ; \
+  do
+    if test -r "$ac_dir/$xm_direct_test_include"; then
+      xm_includes=$ac_dir
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: in $xm_includes" >&5
+$as_echo "in $xm_includes" >&6; }
+      break
+    fi
+  done
+  if test "x$xm_includes" = "x"; then
+    as_fn_error $? "**** NO MOTIF HEADERS FOUND **** install Motif  development headers or use --with-motif-includes to specify location of Xm/Xm.h " "$LINENO" 5
+  fi
+
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+  # Check for the libraries.
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Motif libraries" >&5
+$as_echo_n "checking for Motif libraries... " >&6; }
+  test -z "$xm_direct_test_library" && xm_direct_test_library=Xm
+  test -z "$xm_direct_test_function" && xm_direct_test_function=XmGetDestination
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$xm_direct_test_library $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+${xm_direct_test_function}()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  LIBS="$ac_save_LIBS"
+  # We can link Motif programs with no special library path.
+  xm_libraries=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: in default path" >&5
+$as_echo "in default path" >&6; }
+
+else
+
+ 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 "$xm_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 \
+    "$with_motif_libs"     \
+    ; \
+do
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/lib${xm_direct_test_library}.$ac_extension; then
+      xm_libraries=$ac_dir
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: in $xm_libraries" >&5
+$as_echo "in $xm_libraries" >&6; }
+      break 2
+    fi
+  done
+done
+if test "x$xm_libraries" = "x"; then
+ as_fn_error $? "**** MOTIF LIBRARIES NOT FOUND **** Install Motif development headers/libraries or use --with-motif-libraries to specify path to libXm.a " "$LINENO" 5
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+if test "x$xm_includes" != "x" ; then
+    CFLAGS="$CFLAGS -I$xm_includes"
+    CPPFLAGS="$CPPFLAGS -I$xm_includes"
+fi
+if test "x$xm_libraries" != "x" ; then
+    LDFLAGS="-L$xm_libraries $LDFLAGS"
+fi
+
+
+
+
+
+#
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if ${ac_cv_working_alloca_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+			  if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_working_alloca_h=yes
+else
+  ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if ${ac_cv_func_alloca_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+void *alloca (size_t);
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+				    if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_func_alloca_works=yes
+else
+  ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if ${ac_cv_os_cray+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then :
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if ${ac_cv_c_stack_direction+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_c_stack_direction=0
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  return find_stack_direction () < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_stack_direction=1
+else
+  ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_ac_Header=yes"
+else
+  eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_opendir+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_opendir+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#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))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if ${ac_cv_header_sys_wait_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (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;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_sys_wait_h=yes
+else
+  ac_cv_header_sys_wait_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+for ac_header in argz.h arpa/inet.h fcntl.h libintl.h limits.h locale.h malloc.h math.h netdb.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in netinet/in.h nl_types.h stdarg.h stddef.h stdlib.h string.h strings.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h signal.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in termios.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset cs;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* 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";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 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;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if ${ac_cv_type_uid_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uid_t" >/dev/null 2>&1; then :
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" >>confdefs.h
+
+
+$as_echo "#define gid_t int" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+#AC_STRUCT_TM
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if ${ac_cv_type_signal+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_type_signal=int
+else
+  ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if ${ac_cv_struct_tm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm tm;
+				     int *p = &tm.tm_sec;
+				     return !p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_struct_tm=time.h
+else
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+$as_echo "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+
+"
+if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TM_TM_ZONE 1
+_ACEOF
+
+
+fi
+
+if test "$ac_cv_member_struct_tm_tm_zone" = yes; then
+
+$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h
+
+else
+  ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h>
+"
+if test "x$ac_cv_have_decl_tzname" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_TZNAME $ac_have_decl
+_ACEOF
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5
+$as_echo_n "checking for tzname... " >&6; }
+if ${ac_cv_var_tzname+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <time.h>
+#if !HAVE_DECL_TZNAME
+extern char *tzname[];
+#endif
+
+int
+main ()
+{
+return tzname[0][0];
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_var_tzname=yes
+else
+  ac_cv_var_tzname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5
+$as_echo "$ac_cv_var_tzname" >&6; }
+  if test $ac_cv_var_tzname = yes; then
+
+$as_echo "#define HAVE_TZNAME 1" >>confdefs.h
+
+  fi
+fi
+
+
+#Some (Mac?) systems don't define this where it should be, so we kludge
+ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include <sys/types.h>
+#include <sys/socket.h>
+"
+if test "x$ac_cv_type_socklen_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCKLEN_T 1
+_ACEOF
+
+
+fi
+
+
+# some BSD systems do not define sighandler_t, but rather sig_t
+ac_fn_c_check_type "$LINENO" "sighandler_t" "ac_cv_type_sighandler_t" "#include <signal.h>
+"
+if test "x$ac_cv_type_sighandler_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGHANDLER_T 1
+_ACEOF
+
+
+fi
+
+ac_fn_c_check_type "$LINENO" "sig_t" "ac_cv_type_sig_t" "#include <signal.h>
+"
+if test "x$ac_cv_type_sig_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIG_T 1
+_ACEOF
+
+
+fi
+
+
+# some BSD systems do not define sighandler_t, but rather sig_t
+ac_fn_c_check_type "$LINENO" "sigjmp_buf" "ac_cv_type_sigjmp_buf" "#include <setjmp.h>
+"
+if test "x$ac_cv_type_sigjmp_buf" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGJMP_BUF 1
+_ACEOF
+
+
+fi
+
+
+#Force this into config.h.in
+
+
+
+# Check for tm_gmtoff in tm
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmtoff in struct tm" >&5
+$as_echo_n "checking for gmtoff in struct tm... " >&6; }
+if ${ac_cv_tm_gmtoff+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <time.h>
+int
+main ()
+{
+struct tm tm; tm.tm_gmtoff;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_tm_gmtoff="yes"
+else
+  ac_cv_tm_gmtoff="no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tm_gmtoff" >&5
+$as_echo "$ac_cv_tm_gmtoff" >&6; }
+test "$ac_cv_tm_gmtoff" != "no" &&
+$as_echo "#define HAVE_TM_GMTOFF /**/" >>confdefs.h
+
+
+# Checks for library functions.
+#
+for ac_header in vfork.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if ${ac_cv_func_fork_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_fork_works=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	  /* By Ruediger Kuhlmann. */
+	  return fork () < 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_fork_works=yes
+else
+  ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+  ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+  case $host in
+    *-*-amigaos* | *-*-msdosdjgpp*)
+      # Override, as these systems have only a dummy fork() stub
+      ac_cv_func_fork_works=no
+      ;;
+    *)
+      ac_cv_func_fork_works=yes
+      ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if ${ac_cv_func_vfork_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_vfork_works=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Thanks to Paul Eggert for this test.  */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+   argument registers are propagated back to the parent.  The compiler
+   is told about this with #include <vfork.h>, but some compilers
+   (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
+   static variable whose address is put into a register that is
+   clobbered by the vfork.  */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+  static pid_t child;
+  if (!child) {
+    child = vfork ();
+    if (child < 0) {
+      perror ("vfork");
+      _exit(2);
+    }
+    if (!child) {
+      arg = getpid();
+      write(-1, "", 0);
+      _exit (arg);
+    }
+  }
+}
+
+int
+main ()
+{
+  pid_t parent = getpid ();
+  pid_t child;
+
+  sparc_address_test (0);
+
+  child = vfork ();
+
+  if (child == 0) {
+    /* Here is another test for sparc vfork register problems.  This
+       test uses lots of local variables, at least as many local
+       variables as main has allocated so far including compiler
+       temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
+       4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
+       reuse the register of parent for one of the local variables,
+       since it will think that parent can't possibly be used any more
+       in this routine.  Assigning to the local variable will thus
+       munge parent in the parent process.  */
+    pid_t
+      p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+      p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+    /* Convince the compiler that p..p7 are live; otherwise, it might
+       use the same hardware register for all 8 local variables.  */
+    if (p != p1 || p != p2 || p != p3 || p != p4
+	|| p != p5 || p != p6 || p != p7)
+      _exit(1);
+
+    /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+       from child file descriptors.  If the child closes a descriptor
+       before it execs or exits, this munges the parent's descriptor
+       as well.  Test for this by closing stdout in the child.  */
+    _exit(close(fileno(stdout)) != 0);
+  } else {
+    int status;
+    struct stat st;
+
+    while (wait(&status) != child)
+      ;
+    return (
+	 /* Was there some problem with vforking?  */
+	 child < 0
+
+	 /* Did the child fail?  (This shouldn't happen.)  */
+	 || status
+
+	 /* Did the vfork/compiler bug occur?  */
+	 || parent != getpid()
+
+	 /* Did the file descriptor bug occur?  */
+	 || fstat(fileno(stdout), &st) != 0
+	 );
+  }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_vfork_works=yes
+else
+  ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+  ac_cv_func_vfork_works=$ac_cv_func_vfork
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
+$as_echo_n "checking whether $CC needs -traditional... " >&6; }
+if ${ac_cv_prog_gcc_traditional+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5
+$as_echo "$ac_cv_prog_gcc_traditional" >&6; }
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getpgrp requires zero arguments" >&5
+$as_echo_n "checking whether getpgrp requires zero arguments... " >&6; }
+if ${ac_cv_func_getpgrp_void+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # Use it with a single arg.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+getpgrp (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_func_getpgrp_void=no
+else
+  ac_cv_func_getpgrp_void=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpgrp_void" >&5
+$as_echo "$ac_cv_func_getpgrp_void" >&6; }
+if test $ac_cv_func_getpgrp_void = yes; then
+
+$as_echo "#define GETPGRP_VOID 1" >>confdefs.h
+
+fi
+
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  ac_cv_func_malloc_0_nonnull=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
+
+   case " $LIBOBJS " in
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+fi
+
+
+
+
+
+  for ac_header in $ac_header_list
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+  for ac_func in $ac_func_list
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mktime" >&5
+$as_echo_n "checking for working mktime... " >&6; }
+if ${ac_cv_func_working_mktime+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_working_mktime=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Test program from Paul Eggert and Tony Leneis.  */
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#include <limits.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifndef HAVE_ALARM
+# define alarm(X) /* empty */
+#endif
+
+/* Work around redefinition to rpl_putenv by other config tests.  */
+#undef putenv
+
+static time_t time_t_max;
+static time_t time_t_min;
+
+/* Values we'll use to set the TZ environment variable.  */
+static const char *tz_strings[] = {
+  (const char *) 0, "TZ=GMT0", "TZ=JST-9",
+  "TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00"
+};
+#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0]))
+
+/* Return 0 if mktime fails to convert a date in the spring-forward gap.
+   Based on a problem report from Andreas Jaeger.  */
+static int
+spring_forward_gap ()
+{
+  /* glibc (up to about 1998-10-07) failed this test. */
+  struct tm tm;
+
+  /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0"
+     instead of "TZ=America/Vancouver" in order to detect the bug even
+     on systems that don't support the Olson extension, or don't have the
+     full zoneinfo tables installed.  */
+  putenv ((char*) "TZ=PST8PDT,M4.1.0,M10.5.0");
+
+  tm.tm_year = 98;
+  tm.tm_mon = 3;
+  tm.tm_mday = 5;
+  tm.tm_hour = 2;
+  tm.tm_min = 0;
+  tm.tm_sec = 0;
+  tm.tm_isdst = -1;
+  return mktime (&tm) != (time_t) -1;
+}
+
+static int
+mktime_test1 (time_t now)
+{
+  struct tm *lt;
+  return ! (lt = localtime (&now)) || mktime (lt) == now;
+}
+
+static int
+mktime_test (time_t now)
+{
+  return (mktime_test1 (now)
+	  && mktime_test1 ((time_t) (time_t_max - now))
+	  && mktime_test1 ((time_t) (time_t_min + now)));
+}
+
+static int
+irix_6_4_bug ()
+{
+  /* Based on code from Ariel Faigon.  */
+  struct tm tm;
+  tm.tm_year = 96;
+  tm.tm_mon = 3;
+  tm.tm_mday = 0;
+  tm.tm_hour = 0;
+  tm.tm_min = 0;
+  tm.tm_sec = 0;
+  tm.tm_isdst = -1;
+  mktime (&tm);
+  return tm.tm_mon == 2 && tm.tm_mday == 31;
+}
+
+static int
+bigtime_test (int j)
+{
+  struct tm tm;
+  time_t now;
+  tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j;
+  now = mktime (&tm);
+  if (now != (time_t) -1)
+    {
+      struct tm *lt = localtime (&now);
+      if (! (lt
+	     && lt->tm_year == tm.tm_year
+	     && lt->tm_mon == tm.tm_mon
+	     && lt->tm_mday == tm.tm_mday
+	     && lt->tm_hour == tm.tm_hour
+	     && lt->tm_min == tm.tm_min
+	     && lt->tm_sec == tm.tm_sec
+	     && lt->tm_yday == tm.tm_yday
+	     && lt->tm_wday == tm.tm_wday
+	     && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst)
+		  == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst))))
+	return 0;
+    }
+  return 1;
+}
+
+static int
+year_2050_test ()
+{
+  /* The correct answer for 2050-02-01 00:00:00 in Pacific time,
+     ignoring leap seconds.  */
+  unsigned long int answer = 2527315200UL;
+
+  struct tm tm;
+  time_t t;
+  tm.tm_year = 2050 - 1900;
+  tm.tm_mon = 2 - 1;
+  tm.tm_mday = 1;
+  tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+  tm.tm_isdst = -1;
+
+  /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0"
+     instead of "TZ=America/Vancouver" in order to detect the bug even
+     on systems that don't support the Olson extension, or don't have the
+     full zoneinfo tables installed.  */
+  putenv ((char*) "TZ=PST8PDT,M4.1.0,M10.5.0");
+
+  t = mktime (&tm);
+
+  /* Check that the result is either a failure, or close enough
+     to the correct answer that we can assume the discrepancy is
+     due to leap seconds.  */
+  return (t == (time_t) -1
+	  || (0 < t && answer - 120 <= t && t <= answer + 120));
+}
+
+int
+main ()
+{
+  time_t t, delta;
+  int i, j;
+
+  /* This test makes some buggy mktime implementations loop.
+     Give up after 60 seconds; a mktime slower than that
+     isn't worth using anyway.  */
+  alarm (60);
+
+  for (;;)
+    {
+      t = (time_t_max << 1) + 1;
+      if (t <= time_t_max)
+	break;
+      time_t_max = t;
+    }
+  time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max;
+
+  delta = time_t_max / 997; /* a suitable prime number */
+  for (i = 0; i < N_STRINGS; i++)
+    {
+      if (tz_strings[i])
+	putenv ((char*) tz_strings[i]);
+
+      for (t = 0; t <= time_t_max - delta; t += delta)
+	if (! mktime_test (t))
+	  return 1;
+      if (! (mktime_test ((time_t) 1)
+	     && mktime_test ((time_t) (60 * 60))
+	     && mktime_test ((time_t) (60 * 60 * 24))))
+	return 1;
+
+      for (j = 1; ; j <<= 1)
+	if (! bigtime_test (j))
+	  return 1;
+	else if (INT_MAX / 2 < j)
+	  break;
+      if (! bigtime_test (INT_MAX))
+	return 1;
+    }
+  return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ());
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_working_mktime=yes
+else
+  ac_cv_func_working_mktime=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_working_mktime" >&5
+$as_echo "$ac_cv_func_working_mktime" >&6; }
+if test $ac_cv_func_working_mktime = no; then
+  case " $LIBOBJS " in
+  *" mktime.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS mktime.$ac_objext"
+ ;;
+esac
+
+fi
+
+
+
+
+
+
+for ac_func in getpagesize
+do :
+  ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize"
+if test "x$ac_cv_func_getpagesize" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPAGESIZE 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5
+$as_echo_n "checking for working mmap... " >&6; }
+if ${ac_cv_func_mmap_fixed_mapped+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_mmap_fixed_mapped=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+   Here is a matrix of mmap possibilities:
+	mmap private not fixed
+	mmap private fixed at somewhere currently unmapped
+	mmap private fixed at somewhere already mapped
+	mmap shared not fixed
+	mmap shared fixed at somewhere currently unmapped
+	mmap shared fixed at somewhere already mapped
+   For private mappings, we should verify that changes cannot be read()
+   back from the file, nor mmap's back from the file at a different
+   address.  (There have been systems where private was not correctly
+   implemented like the infamous i386 svr4.0, and systems where the
+   VM page cache was not coherent with the file system buffer cache
+   like early versions of FreeBSD and possibly contemporary NetBSD.)
+   For shared mappings, we should conversely verify that changes get
+   propagated back to all the places they're supposed to be.
+
+   Grep wants private fixed already mapped.
+   The main things grep needs to know about mmap are:
+   * does it exist and is it safe to write into the mmap'd area
+   * how to use it (BSD variants)  */
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#ifndef HAVE_GETPAGESIZE
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  ifdef HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192	/* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+  char *data, *data2, *data3;
+  const char *cdata2;
+  int i, pagesize;
+  int fd, fd2;
+
+  pagesize = getpagesize ();
+
+  /* First, make a file with some known garbage in it. */
+  data = (char *) malloc (pagesize);
+  if (!data)
+    return 1;
+  for (i = 0; i < pagesize; ++i)
+    *(data + i) = rand ();
+  umask (0);
+  fd = creat ("conftest.mmap", 0600);
+  if (fd < 0)
+    return 2;
+  if (write (fd, data, pagesize) != pagesize)
+    return 3;
+  close (fd);
+
+  /* Next, check that the tail of a page is zero-filled.  File must have
+     non-zero length, otherwise we risk SIGBUS for entire page.  */
+  fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600);
+  if (fd2 < 0)
+    return 4;
+  cdata2 = "";
+  if (write (fd2, cdata2, 1) != 1)
+    return 5;
+  data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L);
+  if (data2 == MAP_FAILED)
+    return 6;
+  for (i = 0; i < pagesize; ++i)
+    if (*(data2 + i))
+      return 7;
+  close (fd2);
+  if (munmap (data2, pagesize))
+    return 8;
+
+  /* Next, try to mmap the file at a fixed address which already has
+     something else allocated at it.  If we can, also make sure that
+     we see the same garbage.  */
+  fd = open ("conftest.mmap", O_RDWR);
+  if (fd < 0)
+    return 9;
+  if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+		     MAP_PRIVATE | MAP_FIXED, fd, 0L))
+    return 10;
+  for (i = 0; i < pagesize; ++i)
+    if (*(data + i) != *(data2 + i))
+      return 11;
+
+  /* Finally, make sure that changes to the mapped area do not
+     percolate back to the file as seen by read().  (This is a bug on
+     some variants of i386 svr4.0.)  */
+  for (i = 0; i < pagesize; ++i)
+    *(data2 + i) = *(data2 + i) + 1;
+  data3 = (char *) malloc (pagesize);
+  if (!data3)
+    return 12;
+  if (read (fd, data3, pagesize) != pagesize)
+    return 13;
+  for (i = 0; i < pagesize; ++i)
+    if (*(data + i) != *(data3 + i))
+      return 14;
+  close (fd);
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_mmap_fixed_mapped=yes
+else
+  ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5
+$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; }
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+$as_echo "#define HAVE_MMAP 1" >>confdefs.h
+
+fi
+rm -f conftest.mmap conftest.txt
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5
+$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; }
+if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f conftest.sym conftest.file
+echo >conftest.file
+if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_lstat_dereferences_slashed_symlink=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+struct stat sbuf;
+     /* Linux will dereference the symlink and fail, as required by POSIX.
+	That is better in the sense that it means we will not
+	have to compile and use the lstat wrapper.  */
+     return lstat ("conftest.sym/", &sbuf) == 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_lstat_dereferences_slashed_symlink=yes
+else
+  ac_cv_func_lstat_dereferences_slashed_symlink=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
+  # If the `ln -s' command failed, then we probably don't even
+  # have an lstat function.
+  ac_cv_func_lstat_dereferences_slashed_symlink=no
+fi
+rm -f conftest.sym conftest.file
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
+$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; }
+
+test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
+
+cat >>confdefs.h <<_ACEOF
+#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
+_ACEOF
+
+
+if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then
+  case " $LIBOBJS " in
+  *" lstat.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS lstat.$ac_objext"
+ ;;
+esac
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5
+$as_echo_n "checking whether stat accepts an empty string... " >&6; }
+if ${ac_cv_func_stat_empty_string_bug+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_stat_empty_string_bug=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+struct stat sbuf;
+  return stat ("", &sbuf) == 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_stat_empty_string_bug=no
+else
+  ac_cv_func_stat_empty_string_bug=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5
+$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; }
+if test $ac_cv_func_stat_empty_string_bug = yes; then
+  case " $LIBOBJS " in
+  *" stat.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS stat.$ac_objext"
+ ;;
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STAT_EMPTY_STRING_BUG 1
+_ACEOF
+
+fi
+
+for ac_func in strftime
+do :
+  ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
+if test "x$ac_cv_func_strftime" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+else
+  # strftime is in -lintl on SCO UNIX.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5
+$as_echo_n "checking for strftime in -lintl... " >&6; }
+if ${ac_cv_lib_intl_strftime+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strftime ();
+int
+main ()
+{
+return strftime ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_intl_strftime=yes
+else
+  ac_cv_lib_intl_strftime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5
+$as_echo "$ac_cv_lib_intl_strftime" >&6; }
+if test "x$ac_cv_lib_intl_strftime" = xyes; then :
+  $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h
+
+LIBS="-lintl $LIBS"
+fi
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5
+$as_echo_n "checking for working strtod... " >&6; }
+if ${ac_cv_func_strtod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_strtod=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+$ac_includes_default
+#ifndef strtod
+double strtod ();
+#endif
+int
+main()
+{
+  {
+    /* Some versions of Linux strtod mis-parse strings with leading '+'.  */
+    char *string = " +69";
+    char *term;
+    double value;
+    value = strtod (string, &term);
+    if (value != 69 || term != (string + 4))
+      return 1;
+  }
+
+  {
+    /* Under Solaris 2.4, strtod returns the wrong value for the
+       terminating character under some conditions.  */
+    char *string = "NaN";
+    char *term;
+    strtod (string, &term);
+    if (term != string && *(term - 1) == 0)
+      return 1;
+  }
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_strtod=yes
+else
+  ac_cv_func_strtod=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5
+$as_echo "$ac_cv_func_strtod" >&6; }
+if test $ac_cv_func_strtod = no; then
+  case " $LIBOBJS " in
+  *" strtod.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strtod.$ac_objext"
+ ;;
+esac
+
+ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow"
+if test "x$ac_cv_func_pow" = xyes; then :
+
+fi
+
+if test $ac_cv_func_pow = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5
+$as_echo_n "checking for pow in -lm... " >&6; }
+if ${ac_cv_lib_m_pow+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pow ();
+int
+main ()
+{
+return pow ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_pow=yes
+else
+  ac_cv_lib_m_pow=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5
+$as_echo "$ac_cv_lib_m_pow" >&6; }
+if test "x$ac_cv_lib_m_pow" = xyes; then :
+  POW_LIB=-lm
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5
+$as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;}
+fi
+
+fi
+
+fi
+
+for ac_func in __argz_count __argz_next __argz_stringify alarm dcgettext
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getcwd getpgrp gethostbyname gethostname gettimeofday
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getwd inet_ntoa memmove mempcpy memset mkdir munmap pow
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in putenv select setenv setlocale settimeofday signal sigignore
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in snprintf socket sqrt stpcpy strcasecmp strchr strdup
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strerror strncasecmp strpbrk strptime strrchr strstr
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtof strtol strtoul tzset vsnprintf
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Check for deprecated/current pthread functions
+for ac_func in pthread_mutexattr_setkind_np pthread_mutexattr_settype
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# this is a GNU extension and not present on all systems.
+for ac_func in strndup
+do :
+  ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup"
+if test "x$ac_cv_func_strndup" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRNDUP 1
+_ACEOF
+
+fi
+done
+
+
+#this is also a recent extension that should not be counted on
+for ac_func in roundf
+do :
+  ac_fn_c_check_func "$LINENO" "roundf" "ac_cv_func_roundf"
+if test "x$ac_cv_func_roundf" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_ROUNDF 1
+_ACEOF
+
+fi
+done
+
+
+# Check for intl library (Needed for Cygwin)
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in -lintl" >&5
+$as_echo_n "checking for gettext in -lintl... " >&6; }
+if ${ac_cv_lib_intl_gettext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gettext ();
+int
+main ()
+{
+return gettext ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_intl_gettext=yes
+else
+  ac_cv_lib_intl_gettext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_gettext" >&5
+$as_echo "$ac_cv_lib_intl_gettext" >&6; }
+if test "x$ac_cv_lib_intl_gettext" = xyes; then :
+  LIBS="-lintl ${LIBS}"
+fi
+
+
+# Check for libproj (need to do this before test for shapelib, because
+# the shapelib test asks about "use_proj"
+use_proj=yes
+
+# Check whether --with-libproj was given.
+if test "${with_libproj+set}" = set; then :
+  withval=$with_libproj; use_proj=$withval
+fi
+
+if test "${use_proj}" = "yes"; then
+  use_proj=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pj_init in -lproj" >&5
+$as_echo_n "checking for pj_init in -lproj... " >&6; }
+if ${ac_cv_lib_proj_pj_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lproj  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pj_init ();
+int
+main ()
+{
+return pj_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_proj_pj_init=yes
+else
+  ac_cv_lib_proj_pj_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_proj_pj_init" >&5
+$as_echo "$ac_cv_lib_proj_pj_init" >&6; }
+if test "x$ac_cv_lib_proj_pj_init" = xyes; then :
+  use_proj=yes LIBS="$LIBS -lproj"
+
+$as_echo "#define HAVE_PROJ /**/" >>confdefs.h
+
+
+fi
+
+fi
+
+
+# Check for Shapelib
+use_shapelib=yes
+force_internal_shapelib=no
+shapelib_desired=yes
+LIBSHP=""
+SUBSHP=""
+# This symbol will be blank if the proj library hasn't been found, and will
+# have the three programs that need proj if it has
+CONTSHP=""
+
+# Check whether --with-internal-shapelib was given.
+if test "${with_internal_shapelib+set}" = set; then :
+  withval=$with_internal_shapelib; force_internal_shapelib=$withval
+fi
+
+
+# Check whether --with-shapelib was given.
+if test "${with_shapelib+set}" = set; then :
+  withval=$with_shapelib; shapelib_desired=$withval
+fi
+
+if test "${shapelib_desired}" = "no"; then
+  use_shapelib=no
+  force_internal_shapelib=no
+fi
+if test "${force_internal_shapelib}" = "yes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ***************************************************************** " >&5
+$as_echo "$as_me: WARNING: ***************************************************************** " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Internal Shapelib library has been forced.                        " >&5
+$as_echo "$as_me: WARNING: Internal Shapelib library has been forced.                        " >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ***************************************************************** " >&5
+$as_echo "$as_me: WARNING: ***************************************************************** " >&2;}
+  # Temporary setting to get into if block below
+  use_shapelib=no
+fi
+if test "${shapelib_desired}" = "yes" -a "${force_internal_shapelib}" = "no"; then
+  use_shapelib=no
+  for ac_header in shapefil.h libshp/shapefil.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBFOpen in -lshp" >&5
+$as_echo_n "checking for DBFOpen in -lshp... " >&6; }
+if ${ac_cv_lib_shp_DBFOpen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lshp  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char DBFOpen ();
+int
+main ()
+{
+return DBFOpen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_shp_DBFOpen=yes
+else
+  ac_cv_lib_shp_DBFOpen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_shp_DBFOpen" >&5
+$as_echo "$ac_cv_lib_shp_DBFOpen" >&6; }
+if test "x$ac_cv_lib_shp_DBFOpen" = xyes; then :
+  use_shapelib=yes
+    LIBS="$LIBS -lshp"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBFGetFieldIndex in -lshp" >&5
+$as_echo_n "checking for DBFGetFieldIndex in -lshp... " >&6; }
+if ${ac_cv_lib_shp_DBFGetFieldIndex+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lshp  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char DBFGetFieldIndex ();
+int
+main ()
+{
+return DBFGetFieldIndex ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_shp_DBFGetFieldIndex=yes
+else
+  ac_cv_lib_shp_DBFGetFieldIndex=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_shp_DBFGetFieldIndex" >&5
+$as_echo "$ac_cv_lib_shp_DBFGetFieldIndex" >&6; }
+if test "x$ac_cv_lib_shp_DBFGetFieldIndex" = xyes; then :
+
+$as_echo "#define HAVE_DBFGETFIELDINDEX /**/" >>confdefs.h
+
+fi
+
+
+$as_echo "#define HAVE_LIBSHP /**/" >>confdefs.h
+
+    break
+fi
+
+fi
+
+done
+
+fi
+if test "${shapelib_desired}" = "yes" -a "${use_shapelib}" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **************************************************************** " >&5
+$as_echo "$as_me: WARNING: **************************************************************** " >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your system does not have shapelib installed.  Using an internal " >&5
+$as_echo "$as_me: WARNING: Your system does not have shapelib installed.  Using an internal " >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: version.  This may lead to a larger filesize for the executable. " >&5
+$as_echo "$as_me: WARNING: version.  This may lead to a larger filesize for the executable. " >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Install shapelib on your system to eliminate this warning.       " >&5
+$as_echo "$as_me: WARNING: Install shapelib on your system to eliminate this warning.       " >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **************************************************************** " >&5
+$as_echo "$as_me: WARNING: **************************************************************** " >&2;}
+ LIBSHP="-Lshapelib -lshape"
+ CPPFLAGS="-I\$(top_srcdir)/src/shapelib $CPPFLAGS"
+ SUBSHP="shapelib"
+ use_shapelib=yes
+ force_internal_shapelib=yes
+
+$as_echo "#define HAVE_DBFGETFIELDINDEX /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_LIBSHP /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_SHAPEFIL_H /**/" >>confdefs.h
+
+
+ if  test  $use_proj = "yes"
+ then
+   CONTSHP="shpcentrd shpproj shpdata shpwkb"
+ fi
+fi
+
+
+
+
+
+# Check for pcre
+use_pcre=yes
+
+# Check whether --with-pcre was given.
+if test "${with_pcre+set}" = set; then :
+  withval=$with_pcre; use_pcre=$withval
+fi
+
+if test "${use_pcre}" = "yes"; then
+  use_pcre=no
+  for ac_header in pcre.h pcre/pcre.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre" >&5
+$as_echo_n "checking for pcre_compile in -lpcre... " >&6; }
+if ${ac_cv_lib_pcre_pcre_compile+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpcre  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pcre_compile ();
+int
+main ()
+{
+return pcre_compile ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pcre_pcre_compile=yes
+else
+  ac_cv_lib_pcre_pcre_compile=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_compile" >&5
+$as_echo "$ac_cv_lib_pcre_pcre_compile" >&6; }
+if test "x$ac_cv_lib_pcre_pcre_compile" = xyes; then :
+  use_pcre=yes
+  LIBS="$LIBS -lpcre"
+
+$as_echo "#define HAVE_LIBPCRE /**/" >>confdefs.h
+
+  break
+fi
+
+fi
+
+done
+
+fi
+
+
+# Check for XPM
+if test "${use_lsb}" = "no"; then
+  for ac_header in X11/xpm.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "X11/xpm.h" "ac_cv_header_X11_xpm_h" "$ac_includes_default"
+if test "x$ac_cv_header_X11_xpm_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_X11_XPM_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing XpmWriteFileFromPixmap" >&5
+$as_echo_n "checking for library containing XpmWriteFileFromPixmap... " >&6; }
+if ${ac_cv_search_XpmWriteFileFromPixmap+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XpmWriteFileFromPixmap ();
+int
+main ()
+{
+return XpmWriteFileFromPixmap ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' Xpm; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_XpmWriteFileFromPixmap=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_XpmWriteFileFromPixmap+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_XpmWriteFileFromPixmap+:} false; then :
+
+else
+  ac_cv_search_XpmWriteFileFromPixmap=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_XpmWriteFileFromPixmap" >&5
+$as_echo "$ac_cv_search_XpmWriteFileFromPixmap" >&6; }
+ac_res=$ac_cv_search_XpmWriteFileFromPixmap
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_LIBXPM /**/" >>confdefs.h
+
+fi
+
+fi
+
+done
+
+  for ac_header in Xm/XpmI.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "Xm/XpmI.h" "ac_cv_header_Xm_XpmI_h" "$ac_includes_default"
+if test "x$ac_cv_header_Xm_XpmI_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_XM_XPMI_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing XmeXpmWriteFileFromPixmap" >&5
+$as_echo_n "checking for library containing XmeXpmWriteFileFromPixmap... " >&6; }
+if ${ac_cv_search_XmeXpmWriteFileFromPixmap+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XmeXpmWriteFileFromPixmap ();
+int
+main ()
+{
+return XmeXpmWriteFileFromPixmap ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' Xm; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_XmeXpmWriteFileFromPixmap=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_XmeXpmWriteFileFromPixmap+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_XmeXpmWriteFileFromPixmap+:} false; then :
+
+else
+  ac_cv_search_XmeXpmWriteFileFromPixmap=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_XmeXpmWriteFileFromPixmap" >&5
+$as_echo "$ac_cv_search_XmeXpmWriteFileFromPixmap" >&6; }
+ac_res=$ac_cv_search_XmeXpmWriteFileFromPixmap
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_LIBXPM_IN_XM /**/" >>confdefs.h
+
+fi
+
+fi
+
+done
+
+else
+
+$as_echo "#define HAVE_LIBXPM /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_LIBXPM_IN_XM /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_X11_XPM_H /**/" >>confdefs.h
+
+fi
+
+
+#check for libtiff, libgeotiff
+# libjpeg.a and libz.a need to be compiled under LSB
+
+
+use_geotiff=yes
+
+# Check whether --with-geotiff was given.
+if test "${with_geotiff+set}" = set; then :
+  withval=$with_geotiff; use_geotiff=$withval
+fi
+
+if test "${use_geotiff}" = "yes"; then
+    if test "${use_proj}" = "yes" ; then
+        if test "${use_lsb}" = "yes" ; then
+            use_tiff=yes
+            use_geotiff=yes
+            LIBS="$LIBS -lgeotiff -ltiff -ljpeg -lz -lproj"
+
+$as_echo "#define HAVE_TIFF /**/" >>confdefs.h
+
+
+$as_echo "#define HAVE_LIBGEOTIFF /**/" >>confdefs.h
+
+        else
+            ac_fn_c_check_header_mongrel "$LINENO" "xtiffio.h" "ac_cv_header_xtiffio_h" "$ac_includes_default"
+if test "x$ac_cv_header_xtiffio_h" = xyes; then :
+
+else
+  use_geotiff="no"
+fi
+
+
+            if test "${use_geotiff}" = "yes"; then
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFClose in -ltiff" >&5
+$as_echo_n "checking for TIFFClose in -ltiff... " >&6; }
+if ${ac_cv_lib_tiff_TIFFClose+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFClose ();
+int
+main ()
+{
+return TIFFClose ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_tiff_TIFFClose=yes
+else
+  ac_cv_lib_tiff_TIFFClose=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFClose" >&5
+$as_echo "$ac_cv_lib_tiff_TIFFClose" >&6; }
+if test "x$ac_cv_lib_tiff_TIFFClose" = xyes; then :
+  use_tiff=yes
+                LIBS="$LIBS -ltiff"
+
+$as_echo "#define HAVE_TIFF /**/" >>confdefs.h
+
+fi
+
+                if test "${use_tiff}" = "yes"; then
+                    use_geotiff=no
+                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTIFNew in -lgeotiff" >&5
+$as_echo_n "checking for GTIFNew in -lgeotiff... " >&6; }
+if ${ac_cv_lib_geotiff_GTIFNew+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgeotiff  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GTIFNew ();
+int
+main ()
+{
+return GTIFNew ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_geotiff_GTIFNew=yes
+else
+  ac_cv_lib_geotiff_GTIFNew=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_geotiff_GTIFNew" >&5
+$as_echo "$ac_cv_lib_geotiff_GTIFNew" >&6; }
+if test "x$ac_cv_lib_geotiff_GTIFNew" = xyes; then :
+  use_geotiff=yes
+                        LIBS="$LIBS -lgeotiff"
+
+$as_echo "#define HAVE_LIBGEOTIFF /**/" >>confdefs.h
+
+fi
+
+                else
+                    echo "*** Warning: geotiff requires libtiff."
+                    use_geotiff=no
+                fi
+            else
+                echo "*** Warning: geotiff include files not found."
+            fi
+        fi
+    else
+        echo "*** Warning: geotiff requires libproj."
+        use_geotiff=no
+    fi
+fi
+
+# Check for spatial database support
+use_postgis=no
+
+# Check whether --with-postgis was given.
+if test "${with_postgis+set}" = set; then :
+  withval=$with_postgis; use_postgis=$withval
+fi
+
+if test "${use_postgis}" != "no"; then
+
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+# test for postgresql
+if test "${with_postgis+set}" = set; then
+  PG_CONFIG="pg_config"
+  if test "$with_postgis" != "yes"; then
+    # get path if provided
+    pg_path="$with_postgis"
+    PG_CONFIG_PATH="${pg_path}/bin"
+    BINPATH="${BINPATH}:${PG_CONFIG_PATH}"
+    POSTGIS_LIB_DIR="-L${pg_path}/lib"
+    # Extract the first word of "pg_config", so it can be a program name with args.
+set dummy pg_config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PG_CONFIG_PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PG_CONFIG" && ac_cv_path_PG_CONFIG="no"
+  ;;
+esac
+fi
+PG_CONFIG=$ac_cv_path_PG_CONFIG
+if test -n "$PG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5
+$as_echo "$PG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    # Extract the first word of "pg_config", so it can be a program name with args.
+set dummy pg_config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PG_CONFIG" && ac_cv_path_PG_CONFIG="no"
+  ;;
+esac
+fi
+PG_CONFIG=$ac_cv_path_PG_CONFIG
+if test -n "$PG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PG_CONFIG" >&5
+$as_echo "$PG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+  if test "$PG_CONFIG" != "no"; then
+    # Check for postgis spatial extensions.
+    # Look for lwpostgis.sql script in default location.
+    # If found, is likely a postgis installation.
+    # Need more definitive test for postgis, as this may fail to detect postgres
+    # installations where this script was removed, and will incorrectly
+    # detect postgres without postgis where this script has been installed but not run.
+    # Extract the first word of "lwpostgis.sql", so it can be a program name with args.
+set dummy lwpostgis.sql; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_LWPOSTGIS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $LWPOSTGIS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_LWPOSTGIS="$LWPOSTGIS" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in "${pg_path}/share"
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_LWPOSTGIS="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_LWPOSTGIS" && ac_cv_path_LWPOSTGIS="no"
+  ;;
+esac
+fi
+LWPOSTGIS=$ac_cv_path_LWPOSTGIS
+if test -n "$LWPOSTGIS"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LWPOSTGIS" >&5
+$as_echo "$LWPOSTGIS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    if test "LWPOSTGIS" != "no"; then
+       #postgres with postgis enabled
+       use_postgis=yes
+       use_spatial_db=yes
+       save_cppflags="$CPPFLAGS"
+       save_cxxflags="$CXXFLAGS"
+       save_libs="$LIBS"
+       save_ldflags="$LDFLAGS"
+       CPPFLAGS="$CPPFLAGS -I`${PG_CONFIG} --includedir` `${PG_CONFIG} --cppflags`"
+       CXXFLAGS="$CXXFLAGS `${PG_CONFIG} --cflags`"
+       LDFLAGS="$LDFLAGS `${PG_CONFIG} --ldflags`"
+       LIBS="${POSTGIS_LIB_DIR} `${PG_CONFIG} --libs` -lpq $LIBS"
+
+$as_echo "#define HAVE_POSTGIS 1" >>confdefs.h
+
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find lwpostgis.sql:  Building w/o Postgresql/Postgis support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find lwpostgis.sql:  Building w/o Postgresql/Postgis support. ***" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Postgresql was found" >&5
+$as_echo "$as_me: WARNING: *** Postgresql was found" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Install and enable postgis and leave the lwpostgis.sql script in     ***" >&5
+$as_echo "$as_me: WARNING: *** Install and enable postgis and leave the lwpostgis.sql script in     ***" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** ${pg_path}/share                                                     ***" >&5
+$as_echo "$as_me: WARNING: *** ${pg_path}/share                                                     ***" >&2;}
+    fi
+  else
+    use_postgis=no
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find pg_config:  Building w/o Postgresql/Postgis support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find pg_config:  Building w/o Postgresql/Postgis support. ***" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Specify the path to the posgresql installation directory         ***" >&5
+$as_echo "$as_me: WARNING: *** Specify the path to the posgresql installation directory         ***" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** For example: --with-postgis=/usr/local/pgsql                     ***" >&5
+$as_echo "$as_me: WARNING: *** For example: --with-postgis=/usr/local/pgsql                     ***" >&2;}
+  fi
+fi
+
+
+fi
+use_mysql=no
+
+# Check whether --with-mysql was given.
+if test "${with_mysql+set}" = set; then :
+  withval=$with_mysql; use_mysql=$withval
+fi
+
+if test "${use_mysql}" != "no"; then
+
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+
+# test for MySQL
+if test "${with_mysql+set}" = set; then
+  MYSQL_CONFIG="mysql_config"
+  if test "$with_mysql" != "yes"; then
+    # get path to mysql_config if provided
+    mysql_path="$with_mysql"
+    BINPATH="${BINPATH}:${mysql_path}"
+    # Extract the first word of "mysql_config", so it can be a program name with args.
+set dummy mysql_config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MYSQL_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MYSQL_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MYSQL_CONFIG="$MYSQL_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $mysql_path
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MYSQL_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_MYSQL_CONFIG" && ac_cv_path_MYSQL_CONFIG="no"
+  ;;
+esac
+fi
+MYSQL_CONFIG=$ac_cv_path_MYSQL_CONFIG
+if test -n "$MYSQL_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MYSQL_CONFIG" >&5
+$as_echo "$MYSQL_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    # Extract the first word of "mysql_config", so it can be a program name with args.
+set dummy mysql_config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MYSQL_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MYSQL_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MYSQL_CONFIG="$MYSQL_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MYSQL_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_MYSQL_CONFIG" && ac_cv_path_MYSQL_CONFIG="no"
+  ;;
+esac
+fi
+MYSQL_CONFIG=$ac_cv_path_MYSQL_CONFIG
+if test -n "$MYSQL_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MYSQL_CONFIG" >&5
+$as_echo "$MYSQL_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+  use_mysql_spatial=no
+  use_mysql_any=no
+  if test "$MYSQL_CONFIG" != "no"; then
+
+    # check for mysql version with spatial support
+    # look for mysql 4.1.2 or greater for spatial support
+    # and standardized prepared statements
+    # 4.1.0 and 4.1.1 have spatial support, but only early versions
+    # of prepared statement functions that changed in 4.1.2
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking mysql version >= 4.1.2" >&5
+$as_echo_n "checking mysql version >= 4.1.2... " >&6; }
+    mysqlversion=`$MYSQL_CONFIG --version`
+    mysqlversionmajor=`echo ${mysqlversion} | cut -d '.' -f 1`
+    mysqlversionminor=`echo ${mysqlversion} | cut -d '.' -f 2`
+    mysqlversiontiny=`echo ${mysqlversion} | cut -d '.' -f 3`
+    if test "$mysqlversionmajor" -gt 4 ; then
+      mysql_has_spatial="yes"
+    elif test "$mysqlversionmajor" -ge 4 -a "$mysqlversionminor" -gt 1 ; then
+      mysql_has_spatial="yes"
+    elif test "$mysqlversionmajor" -ge 4 -a "$mysqlversionminor" -ge 1 -a "$mysqlversiontiny" -ge 2 ; then
+      mysql_has_spatial="yes"
+    else
+      mysql_has_spatial="no"
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mysql_has_spatial" >&5
+$as_echo "$mysql_has_spatial" >&6; }
+    # if mysql version < 4.1, mysql present but no spatial support
+    if test "$mysql_has_spatial" = "yes"; then
+       # mysql with spatial support
+       use_mysql_spatial=yes
+       use_spatial_db=yes
+
+$as_echo "#define HAVE_MYSQL_SPATIAL 1" >>confdefs.h
+
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** MySQL version $mysqlversion detected is < 4.1.2         ***" >&5
+$as_echo "$as_me: WARNING: *** MySQL version $mysqlversion detected is < 4.1.2         ***" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Spatial support enabled only for MySQL 4.1.2 and higher ***" >&5
+$as_echo "$as_me: WARNING: *** Spatial support enabled only for MySQL 4.1.2 and higher ***" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** MySQL support for Lat/Long fields is available but      ***" >&5
+$as_echo "$as_me: WARNING: *** MySQL support for Lat/Long fields is available but      ***" >&2;}
+       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** not for Points Polygons or other spatial objects.       ***" >&5
+$as_echo "$as_me: WARNING: *** not for Points Polygons or other spatial objects.       ***" >&2;}
+    fi
+    save_cppflags="$CPPFLAGS"
+    save_cxxflags="$CXXFLAGS"
+    save_libs="$LIBS"
+    CPPFLAGS="$CPPFLAGS `${MYSQL_CONFIG} --cflags`"
+    CXXFLAGS="$CXXFLAGS `${MYSQL_CONFIG} --cflags`"
+    LIBS=" `${MYSQL_CONFIG} --libs` $LIBS"
+    use_mysql_any=yes
+
+$as_echo "#define HAVE_MYSQL 1" >>confdefs.h
+
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find mysql_config:  Building w/o MySQL support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find mysql_config:  Building w/o MySQL support. ***" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Specify the path to mysql_config                       ***" >&5
+$as_echo "$as_me: WARNING: *** Specify the path to mysql_config                       ***" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** For example: --with-mysql=/var/lib/mysql               ***" >&5
+$as_echo "$as_me: WARNING: *** For example: --with-mysql=/var/lib/mysql               ***" >&2;}
+  fi
+
+fi
+#AC_MSG_RESULT($use_mysql_spatial)
+
+fi
+
+if test "${use_postgis}" = "yes"; then
+  use_spatial_db=yes
+
+$as_echo "#define HAVE_SPATIAL_DB 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DB 1" >>confdefs.h
+
+fi
+if test "${use_mysql_spatial}" = "yes"; then
+  use_spatial_db=yes
+
+$as_echo "#define HAVE_DB 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_SPATIAL_DB 1" >>confdefs.h
+
+elif test use_mysql_any = "yes"; then
+
+$as_echo "#define HAVE_DB 1" >>confdefs.h
+
+fi
+
+# Check for AX.25 library
+use_ax25=yes
+
+# Check whether --with-ax25 was given.
+if test "${with_ax25+set}" = set; then :
+  withval=$with_ax25; use_ax25=$withval
+fi
+
+if test "${use_ax25}" = "yes"; then
+  use_ax25=no
+  for ac_header in netax25/ax25.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "netax25/ax25.h" "ac_cv_header_netax25_ax25_h" "$ac_includes_default"
+if test "x$ac_cv_header_netax25_ax25_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NETAX25_AX25_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ax25_config_load_ports in -lax25" >&5
+$as_echo_n "checking for ax25_config_load_ports in -lax25... " >&6; }
+if ${ac_cv_lib_ax25_ax25_config_load_ports+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lax25  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ax25_config_load_ports ();
+int
+main ()
+{
+return ax25_config_load_ports ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ax25_ax25_config_load_ports=yes
+else
+  ac_cv_lib_ax25_ax25_config_load_ports=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ax25_ax25_config_load_ports" >&5
+$as_echo "$ac_cv_lib_ax25_ax25_config_load_ports" >&6; }
+if test "x$ac_cv_lib_ax25_ax25_config_load_ports" = xyes; then :
+  use_ax25=yes
+  LIBS="$LIBS -lax25"
+
+$as_echo "#define HAVE_LIBAX25 /**/" >>confdefs.h
+
+  break
+fi
+
+fi
+
+done
+
+fi
+
+
+# use dbfawk
+use_dbfawk=yes
+
+# Check whether --with-dbfawk was given.
+if test "${with_dbfawk+set}" = set; then :
+  withval=$with_dbfawk; use_dbfawk=$withval
+fi
+
+# dbfawk requires shapelib and pcre.  Make sure:
+if test "${use_dbfawk}" = "yes"; then
+  if test "${use_pcre}" = "yes" -a "${use_shapelib}" = "yes"; then
+
+$as_echo "#define WITH_DBFAWK /**/" >>confdefs.h
+
+  else
+    echo "*** Warning: dbfawk requires both pcre and shapelib."
+    use_dbfawk=no
+  fi
+fi
+
+
+# Check for GDAL.  Make sure that the GDAL check is towards the
+# last, as it can mess up shapelib and libgeotiff currently.
+use_gdal=yes
+
+# Check whether --with-gdal was given.
+if test "${with_gdal+set}" = set; then :
+  withval=$with_gdal; use_gdal=$withval
+fi
+
+if test "${use_gdal}" = "yes"; then
+  if test "${use_lsb}" = "no"; then
+
+use_gdal=no
+#
+# Important: DO NOT use "use_gdal" as the variable here, because AC_CHECK_PROG
+# will do nothing if the variable is already set!
+#
+# Extract the first word of "gdal-config", so it can be a program name with args.
+set dummy gdal-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_found_gdal_config+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$found_gdal_config"; then
+  ac_cv_prog_found_gdal_config="$found_gdal_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_found_gdal_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_found_gdal_config" && ac_cv_prog_found_gdal_config="no"
+fi
+fi
+found_gdal_config=$ac_cv_prog_found_gdal_config
+if test -n "$found_gdal_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $found_gdal_config" >&5
+$as_echo "$found_gdal_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "${found_gdal_config}" = "yes"; then
+   save_cppflags="$CPPFLAGS"
+   save_libs="$LIBS"
+   save_ldflags="$LDFLAGS"
+
+   GDAL_BIN="gdal-config"
+   CPPFLAGS="$CPPFLAGS `${GDAL_BIN} --cflags`"
+#
+# This is an annoyance: gdal-config --libs outputs both LDFLAGS and LIBS
+# stuff.  AC_CHECK_LIB puts the -l in if it works, and we only want the LDFLAGS
+#   LIBS="$LIBS `${GDAL_BIN} --libs`"
+# Remove the -lgdal from what gdal-config --libs returns, because AC_CHECK_LIB
+# will put it into LIBS for us.
+#
+   LDFLAGS="$LDFLAGS `${GDAL_BIN} --libs | sed -e 's/-lgdal^ *//'`"
+   for ac_header in gdal.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "gdal.h" "ac_cv_header_gdal_h" "$ac_includes_default"
+if test "x$ac_cv_header_gdal_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GDAL_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GDALAllRegister in -lgdal" >&5
+$as_echo_n "checking for GDALAllRegister in -lgdal... " >&6; }
+if ${ac_cv_lib_gdal_GDALAllRegister+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdal  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GDALAllRegister ();
+int
+main ()
+{
+return GDALAllRegister ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_gdal_GDALAllRegister=yes
+else
+  ac_cv_lib_gdal_GDALAllRegister=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdal_GDALAllRegister" >&5
+$as_echo "$ac_cv_lib_gdal_GDALAllRegister" >&6; }
+if test "x$ac_cv_lib_gdal_GDALAllRegister" = xyes; then :
+  use_gdal="yes"
+                     LIBS="$LIBS -lgdal"
+
+$as_echo "#define HAVE_LIBGDAL /**/" >>confdefs.h
+
+else
+  CPPFLAGS=${save_cppflags}
+                     LDFLAGS=${save_ldflags}
+                     LIBS=${save_libs}
+fi
+
+fi
+
+done
+
+else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find gdal-config:  Checking standard locations ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find gdal-config:  Checking standard locations ***" >&2;}
+   for ac_header in gdal.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "gdal.h" "ac_cv_header_gdal_h" "$ac_includes_default"
+if test "x$ac_cv_header_gdal_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GDAL_H 1
+_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GDALAllRegister in -lgdal" >&5
+$as_echo_n "checking for GDALAllRegister in -lgdal... " >&6; }
+if ${ac_cv_lib_gdal_GDALAllRegister+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdal  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GDALAllRegister ();
+int
+main ()
+{
+return GDALAllRegister ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_gdal_GDALAllRegister=yes
+else
+  ac_cv_lib_gdal_GDALAllRegister=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdal_GDALAllRegister" >&5
+$as_echo "$ac_cv_lib_gdal_GDALAllRegister" >&6; }
+if test "x$ac_cv_lib_gdal_GDALAllRegister" = xyes; then :
+  use_gdal="yes"
+                     LIBS="$LIBS -lgdal"
+
+$as_echo "#define HAVE_LIBGDAL /**/" >>confdefs.h
+
+fi
+
+fi
+
+done
+
+fi
+
+
+  else
+    CPPFLAGS="$CPPFLAGS -I/opt/lsb-tmp/include"
+    LDFLAGS="$LDFLAGS -L/opt/lsb-tmp/lib -lgdal"
+    LIBS="$LIBS -lgdal"
+
+$as_echo "#define HAVE_LIBGDAL /**/" >>confdefs.h
+
+  fi
+fi
+
+use_rtree=yes
+LIBRTREE=""
+SUBRTREE=""
+
+# Check whether --with-rtree was given.
+if test "${with_rtree+set}" = set; then :
+  withval=$with_rtree; use_rtree=$withval
+fi
+
+if test "${use_rtree}" = "yes" ; then
+  if test "${use_shapelib}" = "yes"; then
+
+$as_echo "#define USE_RTREE 1" >>confdefs.h
+
+     LIBRTREE="-Lrtree -lrtree"
+     SUBRTREE="rtree"
+  else
+    echo "*** Warning: rtree requires shapelib."
+    use_rtree=no
+  fi
+fi
+
+
+
+
+
+
+# Check whether --enable-davis was given.
+if test "${enable_davis+set}" = set; then :
+  enableval=$enable_davis; case "${enableval}" in
+    yes) davis=true ;;
+     no) davis=false ;;
+      *) as_fn_error $? "bad value ${enableval} for --enable-davis" "$LINENO" 5 ;;
+  esac
+else
+  davis=false
+fi
+
+ if test x$davis = xtrue; then
+  DAVIS_TRUE=
+  DAVIS_FALSE='#'
+else
+  DAVIS_TRUE='#'
+  DAVIS_FALSE=
+fi
+
+if test "${davis}" = "true"; then
+  davis=yes
+else
+  davis=no
+fi
+
+
+
+
+
+# Check for LIBGC, a Garbage Collection library.  If found, allow
+# linking it with Xastir, but require the "--with-libgc" flag to
+# enable it.
+use_libgc=no
+
+# Check whether --with-libgc was given.
+if test "${with_libgc+set}" = set; then :
+  withval=$with_libgc; use_libgc=$withval
+fi
+
+if test "${use_libgc}" = "yes"; then
+    for ac_header in gc.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "gc.h" "ac_cv_header_gc_h" "$ac_includes_default"
+if test "x$ac_cv_header_gc_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GC_H 1
+_ACEOF
+ LIBGC_INC="yes"
+else
+  use_libgc=no
+fi
+
+done
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GC_init in -lgc" >&5
+$as_echo_n "checking for GC_init in -lgc... " >&6; }
+if ${ac_cv_lib_gc_GC_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgc  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GC_init ();
+int
+main ()
+{
+return GC_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_gc_GC_init=yes
+else
+  ac_cv_lib_gc_GC_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gc_GC_init" >&5
+$as_echo "$ac_cv_lib_gc_GC_init" >&6; }
+if test "x$ac_cv_lib_gc_GC_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGC 1
+_ACEOF
+
+  LIBS="-lgc $LIBS"
+
+else
+  use_libgc=no
+fi
+
+fi
+
+
+
+
+
+# Check whether profiling was requested.  If so, add the "-pg" flag
+# to CFLAGS.  Require "--with-profiling" flag to enable it.
+use_profiling=no
+
+# Check whether --with-profiling was given.
+if test "${with_profiling+set}" = set; then :
+  withval=$with_profiling; use_profiling=$withval
+fi
+
+if test "${use_profiling}" = "yes"; then
+    CFLAGS="$CFLAGS -pg"
+fi
+
+
+
+
+
+# Check for Berkeley DB.
+use_map_cache=yes
+
+# Check whether --with-map_cache was given.
+if test "${with_map_cache+set}" = set; then :
+  withval=$with_map_cache; use_map_cache=$withval
+fi
+
+if test "${use_map_cache}" = "yes"; then
+
+
+# Check whether --with-bdb-libdir was given.
+if test "${with_bdb_libdir+set}" = set; then :
+  withval=$with_bdb_libdir; with_bdb_lib=$withval
+else
+   test "${with_bdb_lib+set}" = set || with_bdb_lib=none
+fi
+
+
+# Check whether --with-bdb-incdir was given.
+if test "${with_bdb_incdir+set}" = set; then :
+  withval=$with_bdb_incdir; with_bdb_inc=$withval
+else
+   test "${with_bdb_inc+set}" = set || with_bdb_inc=none
+fi
+
+
+
+
+
+	xastir_save_CPPFLAGS=$CPPFLAGS
+
+	if test -d $with_bdb_inc; then
+	    CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+	    BDB_INCADD="-I$with_bdb_inc"
+	else
+	    BDB_INCADD=""
+	fi
+
+	                # Commented out because it doesn't distinguish between versions of db.h
+# that can work with xastir and versions that can't.  It is possible to
+# have multiple versions of db installed in different places, pick up the
+# header for one and the library for another.  Bleah.
+#        AC_CHECK_HEADER(db.h,
+#                        [XASTIR_BERKELEY_DB_CHK_LIB()],
+#                        dblib="no")
+#
+# Do this instead --- check to see if the db.h we find first in the search
+# path will actually pass the test we do in map_cache.c.  Don't even bother
+# looking for a library if not.
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if db.h is exists and is usable" >&5
+$as_echo_n "checking if db.h is exists and is usable... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+#if (DB_VERSION_MAJOR < 4 )
+                        #error DB_VERSION_MAJOR < 4
+                        #endif
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+
+# We need to add the following algorithm here:
+#
+#   Find the db.h file, grep for DB_VERSION_MAJOR and
+#     DB_VERSION_MINOR.  In my case I get this:
+#
+#       #define DB_VERSION_MAJOR        4
+#       #define DB_VERSION_MINOR        1
+#
+#   Find the libdb.so file that Xastir would link to.  Find the
+#     version via the target of the symlink?  In my case I have
+#     this:
+#
+#       > ls -al libdb.so
+#       lrwxrwxrwx 1 root root 12 2004-01-07 11:29 libdb.so -> libdb-4.
+#
+#   Compare the major/minor numbers.  If they match, we're good to
+#   go.  If not, don't compile in libdb support.  Perhaps we could
+#   just run ldd on the test code to get the version number of the
+#   linked library instead?
+#
+# Another possible way to do it would be to create test code and
+# compile/run it which would open/write/read/close/delete a
+# database.  That should help to prove that Xastir would run ok if
+# the library were used.
+
+
+
+	BDB_SAVE_LDFLAGS=$LDFLAGS
+
+	if test -d $with_bdb_lib; then
+	    LDFLAGS="-L$with_bdb_lib $LDFLAGS"
+	    BDB_LIBADD="-L$with_bdb_lib $BDB_LIBADD"
+	else
+	    BDB_LIBADD=""
+	fi
+
+	saved_LIBS=$LIBS
+# Removed db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3
+# from the probe.  The map_cache.c code explicitly bombs if it doesn't have
+# version 4 or above, so why probe for version 3?
+
+# it would be nice if this could be done with AC_SEARCH_LIBS but that doesn't
+# work as it appears that there is some C++-type name mangling going on,
+# and just probing for a library that contains "db_create" fails.  One needs
+# to specify the function call with the full prototype for it to be found.
+        BDB_LIB_FOUND="none"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a library containing db_create" >&5
+$as_echo_n "checking for a library containing db_create... " >&6; }
+        for dbname in db-4.9 db4.9 db49 db-4.8 db4.8 db48 db-4.7 db4.7 db47 db-4.6 db4.6 db46 db-4.5 db4.5 db45 db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db
+          do
+	    LIBS="$saved_LIBS -l$dbname"
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_create(NULL, NULL, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley";
+                BDB_LIB_FOUND="-l$dbname"
+else
+  dblib="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+#         STOP if we find one.  Otherwise we'll keep stepping through the
+#         list and resetting dblib to "no" over and over.
+          if test $dblib = "berkeley" ; then
+            break;
+          fi
+          done
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BDB_LIB_FOUND" >&5
+$as_echo "$BDB_LIB_FOUND" >&6; }
+
+# Commented out because the map_cache code is not actually set up to use
+# db_open instead of db_create.  Probing in this way could actually be
+# dangerous.
+#        if test "$dblib" = "no"; then
+#	    LIBS="$saved_LIBS -ldb"
+#	    AC_TRY_LINK([#include <db.h>],
+#	    [db_open(NULL, 0, 0, 0, NULL, NULL, NULL);],
+#	    BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db,
+#            dblib="no")
+#        fi
+	LIBS=$saved_LIBS
+
+	LDFLAGS=$BDB_SAVE_LDFLAGS
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }; dblib="no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	CPPFLAGS=$xastir_save_CPPFLAGS
+
+    use_map_cache="no"
+    if test "${dblib}" = "berkeley"; then
+        LIBS="$BDB_LIBADD $LIBS"
+	CPPFLAGS="$CPPFLAGS $BDB_INCADD"
+
+$as_echo "#define USE_MAP_CACHE 1" >>confdefs.h
+
+        use_map_cache="yes"
+    fi
+
+
+fi
+
+
+
+
+
+# Check for GraphicsMagick.  If not available/desired then check for
+# ImageMagick.  These checks are VERY important to have as the last,
+# as they mess up previous checks if they fail.
+#
+use_graphicsmagick=yes
+use_imagemagick=no
+
+# Check whether --with-graphicsmagick was given.
+if test "${with_graphicsmagick+set}" = set; then :
+  withval=$with_graphicsmagick; use_graphicsmagick=$withval
+fi
+
+if test "${use_graphicsmagick}" = "yes"; then
+  if test "${use_lsb}" = "no"; then
+
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+
+# Check for GraphicsMagick
+#
+# First look for the needed GraphicsMagick-config script, which tells us all
+# of the build options we need.
+#
+# Important: DO NOT use "use_graphicsmagick" as the variable here,
+# because AC_CHECK_PROG will do nothing if the variable is already set!
+#
+use_graphicsmagick=no
+# Extract the first word of "GraphicsMagick-config", so it can be a program name with args.
+set dummy GraphicsMagick-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GMAGIC_BIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $GMAGIC_BIN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GMAGIC_BIN="$GMAGIC_BIN" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GMAGIC_BIN="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_GMAGIC_BIN" && ac_cv_path_GMAGIC_BIN="no"
+  ;;
+esac
+fi
+GMAGIC_BIN=$ac_cv_path_GMAGIC_BIN
+if test -n "$GMAGIC_BIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMAGIC_BIN" >&5
+$as_echo "$GMAGIC_BIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$GMAGIC_BIN" != "no"; then
+  use_graphicsmagick=yes
+#else
+#  AC_MSG_WARN(*** Cannot find GraphicsMagick-config:  Building w/o GraphicsMagick support. ***)
+fi
+#
+if test "${use_graphicsmagick}" = "yes"; then
+  save_cppflags="$CPPFLAGS"
+  save_cxxflags="$CXXFLAGS"
+  save_libs="$LIBS"
+  save_ldflags="$LDFLAGS"
+  #
+  # Figure out the build options using the GraphicsMagick-config script
+  #
+  CPPFLAGS="`${GMAGIC_BIN} --cppflags` $CPPFLAGS"
+  CXXFLAGS="`${GMAGIC_BIN} --cflags` $CXXFLAGS"
+  LDFLAGS="`${GMAGIC_BIN} --ldflags` $LDFLAGS"
+  LIBS="${MAGIC_LIB_DIR} `${GMAGIC_BIN} --libs` $LIBS"
+  #
+  ac_fn_c_check_header_mongrel "$LINENO" "GraphicsMagick/magick/api.h" "ac_cv_header_GraphicsMagick_magick_api_h" "$ac_includes_default"
+if test "x$ac_cv_header_GraphicsMagick_magick_api_h" = xyes; then :
+  use_graphicsmagick="yes"
+else
+  use_graphicsmagick="no"
+fi
+
+
+  if test "${use_graphicsmagick}" = "no"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find GraphicsMagick include files: Building w/o GraphicsMagick support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find GraphicsMagick include files: Building w/o GraphicsMagick support. ***" >&2;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for WriteImage in -lGraphicsMagick" >&5
+$as_echo_n "checking for WriteImage in -lGraphicsMagick... " >&6; }
+if ${ac_cv_lib_GraphicsMagick_WriteImage+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lGraphicsMagick  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char WriteImage ();
+int
+main ()
+{
+return WriteImage ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_GraphicsMagick_WriteImage=yes
+else
+  ac_cv_lib_GraphicsMagick_WriteImage=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GraphicsMagick_WriteImage" >&5
+$as_echo "$ac_cv_lib_GraphicsMagick_WriteImage" >&6; }
+if test "x$ac_cv_lib_GraphicsMagick_WriteImage" = xyes; then :
+
+$as_echo "#define HAVE_GRAPHICSMAGICK 1" >>confdefs.h
+
+else
+  use_graphicsmagick="no"
+fi
+
+    if test "${use_graphicsmagick}" = "no"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find GraphicsMagick library files: Building w/o GraphicsMagick support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find GraphicsMagick library files: Building w/o GraphicsMagick support. ***" >&2;}
+    fi
+  fi
+  #
+  if test "${use_graphicsmagick}" = "no"; then
+    #
+    # No GraphicsMagick found.  Restore variables.
+    #
+    CPPFLAGS=$save_cppflags
+    CXXFLAGS=$save_cxxflags
+    LIBS=$save_libs
+    LDFLAGS=$save_ldflags
+  fi
+fi
+#
+# End of GraphicsMagick checks
+
+
+  else
+    MAGIC_BIN="/opt/lsb-tmp/bin/GraphicsMagick-config"
+    CPPFLAGS="$CPPFLAGS `${MAGIC_BIN} --cppflags`"
+    CXXFLAGS="$CXXFLAGS `${MAGIC_BIN} --cflags`"
+    LDFLAGS="$LDFLAGS `${MAGIC_BIN} --ldflags`"
+    LIBS="${MAGIC_LIB_DIR} `${MAGIC_BIN} --libs` $LIBS"
+
+$as_echo "#define HAVE_GRAPHICSMAGICK 1" >>confdefs.h
+
+  fi
+fi
+#
+# Note: This must be a separate "if" as the use_graphicsmagick
+# variable gets set to "no" if GM is not available above.
+#
+if test "${use_graphicsmagick}" = "no"; then
+  use_imagemagick=yes
+
+# Check whether --with-imagemagick was given.
+if test "${with_imagemagick+set}" = set; then :
+  withval=$with_imagemagick; use_imagemagick=$withval
+fi
+
+  if test "${use_imagemagick}" = "yes"; then
+
+BINPATH="${PATH}${EXTRA_BIN_PATH}"
+
+# Check for ImageMagick
+#
+# First look for the needed Magick-config script, which tells us all
+# of the build options we need.
+#
+# Important: DO NOT use "use_imagemagick" as the variable here,
+# because AC_CHECK_PROG will do nothing if the variable is already set!
+#
+use_imagemagick=no
+# Extract the first word of "Magick-config", so it can be a program name with args.
+set dummy Magick-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MAGIC_BIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_BIN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MAGIC_BIN="$MAGIC_BIN" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $BINPATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MAGIC_BIN="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_MAGIC_BIN" && ac_cv_path_MAGIC_BIN="no"
+  ;;
+esac
+fi
+MAGIC_BIN=$ac_cv_path_MAGIC_BIN
+if test -n "$MAGIC_BIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_BIN" >&5
+$as_echo "$MAGIC_BIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$MAGIC_BIN" != "no"; then
+  use_imagemagick=yes
+#else
+#  AC_MSG_WARN(*** Cannot find Magick-config:  Building w/o ImageMagick support. ***)
+fi
+
+if test "${use_imagemagick}" = "yes"; then
+#  #
+#  # Compute the ImageMagick revision number
+#  #
+#  magickversion=`${MAGIC_BIN} --version`
+#  magickmajor=`echo $magickversion | cut -d '.' -f 1`
+#  magickminor=`echo $magickversion | cut -d '.' -f 2`
+#  magicktiny=`echo $magickversion | cut -d '.' -f 3`
+#  if test "$magickmajor" -lt 5; then
+#    magickold="yes";
+#  elif test "$magickmajor" -eq 5 -a "$magickminor" -lt 4; then
+#    magickold="yes";
+#  elif test "$magickmajor" -eq 5 -a "$magickminor" -eq 4 -a "$magicktiny" -lt 9; then
+#    magickold="yes";
+#  fi
+  #
+  save_cppflags="$CPPFLAGS"
+  save_cxxflags="$CXXFLAGS"
+  save_libs="$LIBS"
+  save_ldflags="$LDFLAGS"
+  #
+  # Figure out the build options using the Magick-config script
+  #
+  CPPFLAGS="$CPPFLAGS `${MAGIC_BIN} --cppflags`"
+  CXXFLAGS="$CXXFLAGS `${MAGIC_BIN} --cflags`"
+  LDFLAGS="$LDFLAGS `${MAGIC_BIN} --ldflags`"
+  LIBS="${MAGIC_LIB_DIR} `${MAGIC_BIN} --libs` $LIBS"
+  #
+  ac_fn_c_check_header_mongrel "$LINENO" "magick/api.h" "ac_cv_header_magick_api_h" "$ac_includes_default"
+if test "x$ac_cv_header_magick_api_h" = xyes; then :
+  use_imagemagick="yes"
+else
+  use_imagemagick="no"
+fi
+
+
+  if test "${use_imagemagick}" = "no"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find ImageMagick include files:  Building w/o ImageMagick support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find ImageMagick include files:  Building w/o ImageMagick support. ***" >&2;}
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing WriteImage" >&5
+$as_echo_n "checking for library containing WriteImage... " >&6; }
+if ${ac_cv_search_WriteImage+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char WriteImage ();
+int
+main ()
+{
+return WriteImage ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' Magick MagickCore; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_WriteImage=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_WriteImage+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_WriteImage+:} false; then :
+
+else
+  ac_cv_search_WriteImage=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_WriteImage" >&5
+$as_echo "$ac_cv_search_WriteImage" >&6; }
+ac_res=$ac_cv_search_WriteImage
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_IMAGEMAGICK 1" >>confdefs.h
+
+else
+  use_imagemagick="no"
+fi
+
+    if test "${use_imagemagick}" = "no"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Cannot find ImageMagick library files:  Building w/o ImageMagick support. ***" >&5
+$as_echo "$as_me: WARNING: *** Cannot find ImageMagick library files:  Building w/o ImageMagick support. ***" >&2;}
+    fi
+  fi
+  #
+  if test "${use_imagemagick}" = "no"; then
+    #
+    # No ImageMagick found.  Restore variables.
+    #
+    CPPFLAGS=$save_cppflags
+    CXXFLAGS=$save_cxxflags
+    LIBS=$save_libs
+    LDFLAGS=$save_ldflags
+  fi
+#
+#  if test "${magickold}" = "yes"; then
+# This used to be important, as some versions didn't support the
+# Tigermap intensity slider.
+#    AC_MSG_WARN(*********************************************************)
+#    AC_MSG_WARN(***     Old ImageMagick version ($magickversion) found.        ***)
+#    AC_MSG_WARN(*** Upgrade to 5.4.9 or newer for full functionality. ***)
+#    AC_MSG_WARN(*********************************************************)
+#  fi
+fi
+# End of ImageMagick checks
+
+
+  fi
+fi
+#
+#
+#
+if test "${use_imagemagick}" = "yes" -o "${use_graphicsmagick}" = "yes"; then
+
+$as_echo "#define HAVE_MAGICK 1" >>confdefs.h
+
+fi
+
+
+
+
+
+# Set XASTIR_DATA_BASE in CPPFLAGS due to Gnu coding standard that requires
+# datadir expansion to be deferred until make time.
+if test "x${datadir}" = "x"; then
+  CPPFLAGS="$CPPFLAGS -DXASTIR_DATA_BASE=\\\"${ac_default_prefix}/share/xastir\\\""
+else
+  CPPFLAGS="$CPPFLAGS -DXASTIR_DATA_BASE=\\\"${datadir}/xastir\\\""
+fi
+
+
+
+# Add a special option that makes Cygwin link much faster (from
+# Henk de Groot)
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="-Wl,--no-keep-memory $LDFLAGS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+/* Stupid useless test for linker flags */
+   exit(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  xa_cv_no_keep_memory=yes
+else
+  xa_cv_no_keep_memory=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test "${xa_cv_no_keep_memory}" = "no"; then
+  LDFLAGS="$save_LDFLAGS"
+fi
+
+#
+# Assure we have this order for these LIBS: "-lXm -lXt -lX11" by
+# adding them to the beginning.  Add spaces around them for the
+# following steps.  Here I'm adding them to the beginning so the
+# dupe-check portion will take out the later ones that might be in
+# the wrong order.  If they're in the wrong order, we can get
+# "Error: Shell widget xastir has zero width and/or height" when
+# Xastir is started up.   Can also get "Error: attempt to add
+# non-widget child "DropSiteManager" to parent", but that can also
+# be caused by other problems with libraries.
+#
+LIBS=" -lXm -lXt -lX11 $LIBS"
+
+#
+# Remove duplicate entries.  Thanks to Paul Lutt, ke7xt, for this!
+#
+# Don't get rid of dupes on the LIBS line.  We may need the same
+# "-Llibdir" called out several times, immediately prior to each
+# "-llibrary" that needs it.
+#
+
+CFLAGS=`echo  "$CFLAGS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+CPPFLAGS=`echo  "$CPPFLAGS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+LDFLAGS=`echo "$LDFLAGS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+#LIBS=`echo "$LIBS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+
+
+
+#
+# Remove "-g" CFLAGS/CPPFLAGS entries.  Note:  This is a _bad_ idea
+# as debuggers won't have a symbol table to work from!
+#
+#changequote(,)
+#CFLAGS=`echo  "$CFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-g") s = s " " $i} print s}'`
+#CPPFLAGS=`echo  "$CPPFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-g") s = s " " $i} print s}'`
+#changequote([,])
+
+
+#
+# Change the compiler optimization if using Windows/Cygwin in order
+# to reduce memory usage and speed up the compile.  Here we change
+# "-O2" to "-O1" or " " in CFLAGS/CPPFLAGS to reduce the level of
+# optimization.
+# We also wish to remove "-no-undefined" from LDFLAGS on Cygwin, as
+# we use GCC for our linking instead of libtool, and GCC doesn't
+# like that flag at the link stage.
+#
+case "$host_os" in
+cygwin*)
+
+  CFLAGS=`echo  "$CFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-O2") s = s " " $i} print s}'`
+  CPPFLAGS=`echo  "$CPPFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-O2") s = s " " $i} print s}'`
+  LDFLAGS=`echo  "$LDFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-no-undefined") s = s " " $i} print s}'`
+
+;;
+esac
+
+
+# Create the ILIBS defined variable.  We add spaces here in the else
+# clauses in order to make the REGRESSION_TESTS format nicely.  We
+# take them back out before we define the variable that Xastir uses
+# for it's Help->About dialog.
+#
+if test "${use_ax25}" = "yes"; then
+  ILIBS="AX25"
+else
+  ILIBS="    "
+fi
+if test "${use_festival}" = "yes"; then
+  ILIBS="$ILIBS Festival"
+else
+  ILIBS="$ILIBS         "
+fi
+if test "${use_gpsman}" = "yes"; then
+  ILIBS="$ILIBS GPSMan"
+else
+  ILIBS="$ILIBS       "
+fi
+if test "${use_graphicsmagick}" = "yes"; then
+    ILIBS="$ILIBS GraphicsMagick"
+else
+  if test "${use_imagemagick}" = "yes"; then
+    ILIBS="$ILIBS ImageMagick   "
+  else
+    ILIBS="$ILIBS               "
+  fi
+fi
+if test "${use_proj}" = "yes"; then
+  ILIBS="$ILIBS libProj"
+else
+  ILIBS="$ILIBS        "
+fi
+if test "${use_geotiff}" = "yes"; then
+  ILIBS="$ILIBS GeoTiff"
+else
+  ILIBS="$ILIBS        "
+fi
+if test "${use_gdal}" = "yes"; then
+  ILIBS="$ILIBS GDAL/OGR"
+else
+  ILIBS="$ILIBS         "
+fi
+if test "${use_shapelib}" = "yes"; then
+  ILIBS="$ILIBS ShapeLib"
+else
+  ILIBS="$ILIBS         "
+fi
+if test "${use_pcre}" = "yes"; then
+  ILIBS="$ILIBS PCRE"
+else
+  ILIBS="$ILIBS     "
+fi
+if test "${use_dbfawk}" = "yes"; then
+  ILIBS="$ILIBS Dbfawk"
+else
+  ILIBS="$ILIBS       "
+fi
+if test "${use_map_cache}" = "yes"; then
+  ILIBS="$ILIBS map_caching"
+else
+  ILIBS="$ILIBS            "
+fi
+if test "${use_err_popups}" = "yes"; then
+  ILIBS="$ILIBS error_popups"
+else
+  ILIBS="$ILIBS             "
+fi
+if test "${use_libgc}" = "yes"; then
+  ILIBS="$ILIBS libgc"
+else
+  ILIBS="$ILIBS      "
+fi
+if test "${use_profiling}" = "yes"; then
+  ILIBS="$ILIBS profiling"
+else
+  ILIBS="$ILIBS          "
+fi
+if test "${use_rtree}" = "yes"; then
+  ILIBS="$ILIBS rtree"
+else
+  ILIBS="$ILIBS      "
+fi
+if test "${use_lsb}" = "yes"; then
+  ILIBS="$ILIBS LSB"
+else
+  ILIBS="$ILIBS    "
+fi
+if test "${use_curl}" = "yes"; then
+  ILIBS="$ILIBS libcurl"
+else
+  if test "${use_wget}" = "yes"; then
+    ILIBS="$ILIBS wget   "
+  else
+    ILIBS="$ILIBS        "
+  fi
+fi
+
+# Write out the library information to "summary.log".  Here we want
+# the spaces for the undefined pieces, so REGRESSION_TESTS formats
+# nicely.
+echo "$ILIBS" >summary.log
+
+
+#
+# Remove extraneous spaces from output variables (asthetic)
+#
+ILIBS=`echo $ILIBS | sed -e 's/  */ /g'`
+X_CFLAGS=`echo $X_CFLAGS | sed -e 's/  */ /g'`
+X_PRE_LIBS=`echo $X_PRE_LIBS | sed -e 's/  */ /g'`
+X_LIBS=`echo $X_LIBS | sed -e 's/  */ /g'`
+X_EXTRA_LIBS=`echo $X_EXTRA_LIBS | sed -e 's/  */ /g'`
+
+CC=`echo $CC | sed -e 's/  */ /g'`
+CFLAGS=`echo $CFLAGS | sed -e 's/  */ /g'`
+CPPFLAGS=`echo $CPPFLAGS | sed -e 's/  */ /g'`
+CXXFLAGS=`echo $CXXFLAGS | sed -e 's/  */ /g'`
+LDFLAGS=`echo $LDFLAGS | sed -e 's/  */ /g'`
+TESTED_LIBS=`echo $LIBS | sed -e 's/  */ /g'`
+MAGICK_DEP_LIBS=`echo $MAGICK_DEP_LIBS | sed -e 's/  */ /g'`
+LIBS=`echo $LIBS | sed -e 's/  */ /g'`
+
+
+# Change the output text for Shapelib if we're using the internal
+# library.  The below will be used for the configure summary and for
+# the Help->About text in Xastir.
+if test "${force_internal_shapelib}" = "yes"; then
+  ILIBS=`echo $ILIBS | sed -e 's/ShapeLib/ShapeLib(internal)/g'`
+  use_shapelib="yes (internal)"
+fi
+
+
+
+tmp_path="$ac_default_prefix"
+tmp_bin_path="$ac_default_prefix"
+if test "x$prefix" != xNONE; then
+  tmp_path="$prefix"
+  tmp_bin_path="$prefix"
+fi
+if test "x$exec_prefix" != xNONE; then
+  tmp_bin_path="$exec_prefix"
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define XASTIR_PATH "`echo $tmp_path`"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XASTIR_BIN_PATH "`echo $tmp_bin_path`"
+_ACEOF
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define XASTIR_INSTALLED_LIBS "`echo $ILIBS`"
+_ACEOF
+
+
+
+
+
+#AC_SUBST(CPPFLAGS)
+
+#AC_SUBST(LDFLAGS)
+#AC_SUBST(X_PRE_LIBS)
+#AC_SUBST(X_LIBS)
+#AC_SUBST(X_EXTRA_LIBS)
+
+ac_config_files="$ac_config_files Makefile callpass/Makefile config/Makefile help/Makefile m4/Makefile scripts/Makefile scripts/values scripts/values.pl src/Makefile src/rtree/Makefile src/shapelib/Makefile src/shapelib/contrib/Makefile symbols/Makefile xastir.spec xastir-min.spec xastir-lsb.spec"
+
+
+cat >confcache <<\_ACEOF
+# 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, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# 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.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${DAVIS_TRUE}" && test -z "${DAVIS_FALSE}"; then
+  as_fn_error $? "conditional \"DAVIS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by xastir $as_me 2.0.4, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <xastir at xastir.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+xastir config.status 2.0.4
+configured by $0, generated by GNU Autoconf 2.68,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "callpass/Makefile") CONFIG_FILES="$CONFIG_FILES callpass/Makefile" ;;
+    "config/Makefile") CONFIG_FILES="$CONFIG_FILES config/Makefile" ;;
+    "help/Makefile") CONFIG_FILES="$CONFIG_FILES help/Makefile" ;;
+    "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;;
+    "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
+    "scripts/values") CONFIG_FILES="$CONFIG_FILES scripts/values" ;;
+    "scripts/values.pl") CONFIG_FILES="$CONFIG_FILES scripts/values.pl" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "src/rtree/Makefile") CONFIG_FILES="$CONFIG_FILES src/rtree/Makefile" ;;
+    "src/shapelib/Makefile") CONFIG_FILES="$CONFIG_FILES src/shapelib/Makefile" ;;
+    "src/shapelib/contrib/Makefile") CONFIG_FILES="$CONFIG_FILES src/shapelib/contrib/Makefile" ;;
+    "symbols/Makefile") CONFIG_FILES="$CONFIG_FILES symbols/Makefile" ;;
+    "xastir.spec") CONFIG_FILES="$CONFIG_FILES xastir.spec" ;;
+    "xastir-min.spec") CONFIG_FILES="$CONFIG_FILES xastir-min.spec" ;;
+    "xastir-lsb.spec") CONFIG_FILES="$CONFIG_FILES xastir-lsb.spec" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #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.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+# Please leave these in as they're very useful for debug when we
+# port to new platforms!  Leave them commented out unless doing
+# debugging on the configure scripts.
+#
+#echo ""
+#echo "        LIBS: $LIBS"
+#echo "     LDFLAGS: $LDFLAGS"
+#echo "      CFLAGS: $CFLAGS"
+#echo "    CPPFLAGS: $CPPFLAGS"
+#echo "      X_LIBS: $X_LIBS"
+#echo "  X_PRE_LIBS: $X_PRE_LIBS"
+#echo "X_EXTRA_LIBS: $X_EXTRA_LIBS"
+
+
+# Write a short summary of the configure tests/results to
+# "summary.log"
+egrep -e "checking |result:|gcc version" config.log >> summary.log
+
+
+echo ===========================================
+echo
+echo xastir 2.0.4 has been configured to use the following
+echo options and external libraries:
+echo
+echo MINIMUM OPTIONS:
+echo "  ShapeLib (Vector maps) ................. : $use_shapelib"
+echo
+echo RECOMMENDED OPTIONS:
+
+echo -n "  GraphicsMagick/ImageMagick (Raster maps) : "
+if test "${use_graphicsmagick}" = "yes"; then
+  echo "yes (GraphicsMagick)"
+else
+  if test "${use_imagemagick}" = "yes"; then
+    echo "yes (ImageMagick)"
+  else
+    echo "no"
+  fi
+fi
+echo "  pcre (Shapefile customization) ......... : $use_pcre"
+echo "  dbfawk (Shapefile customization) ....... : $use_dbfawk"
+echo "  rtree indexing (Shapefile speedups) .... : $use_rtree"
+echo "  map caching (Raster map speedups) ...... : $use_map_cache"
+echo "  internet map retrieval ................. : $use_retrieval"
+echo
+echo FOR THE ADVENTUROUS:
+echo "  AX25 (Linux Kernel I/O Drivers) ........ : $use_ax25"
+echo "  libproj (USGS Topos & Aerial Photos) ... : $use_proj"
+echo "  GeoTiff (USGS Topos & Aerial Photos) ... : $use_geotiff"
+echo "  Festival (Text-to-speech) .............. : $use_festival"
+echo "  GDAL/OGR (Obtuse map formats) .......... : $use_gdal"
+echo "  GPSMan/gpsmanshp (GPS downloads) ....... : $use_gpsman"
+#echo "  GPSD Client (libgps) ................... : $use_libgps"
+
+if test "${use_err_popups}" = "yes" -o "${use_libgc}" = "yes" -o "${use_profiling}" = "yes" -o "${use_lsb}" = "yes" -o "${use_spatial_db}" = "yes" -o "$use_mysql_any" = "yes"; then
+  echo
+  echo DEVELOPER OPTIONS:
+  echo "  ErrorPopups (Old Method) ............... : $use_err_popups"
+  echo "  libgc (Debug memory usage) ............. : $use_libgc"
+  echo "  profiling (Debug code efficiency) ...... : $use_profiling"
+  echo "  Linux Standard Base (LSB) .............. : $use_lsb"
+  echo "  Spatial database support ............... : $use_spatial_db"
+  echo "  Spatial database Postgresql/Postgis .... : $use_postgis"
+  echo "  MySQL .................................. : $use_mysql_any"
+  echo "  MySQL Spatial database support ......... : $use_mysql_spatial"
+fi
+
+#echo   Davis/MySQL............................. : $davis
+echo
+echo xastir will be installed in $prefix/bin.
+if test "x$xastirpath" != "x" ; then
+        echo Warning: You have an old copy of Xastir at $xastirpath.
+fi
+echo "Type 'make' to build Xastir (Use 'gmake' instead on some systems)."
+
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..898f304
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,1003 @@
+# Process this file with autoconf to produce a configure script.
+
+# $Id: configure.ac,v 1.226 2012/12/04 23:35:35 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+
+
+#########################################################################
+# SET VERSION HERE!
+#
+# Note that the most standard OSS method of doing numbering is:
+#       Major.Minor.PatchLevel
+#
+# If we are only doing patches, change the PATCHLEVEL number.
+# If we add new features, change the MINOR number.
+# If we feel we've added enough new features or rewritten enough
+#   code to warrant it, change the MAJOR number.
+#
+# Also:  We adopted the convention of using odd numbers for development
+#   or development releases, even numbers for STABLE releases.
+#
+#
+# AC_INIT():
+# It should look something like this:  (xastir, 2.0.2, xastir at xastir.org)
+# The revision number must contain at least one '.' and two digits.
+# AM_INIT_AUTOMAKE():
+# It should look something like this:  (xastir, 2.0.2)
+# The revision number must contain at least one '.' and two digits.
+#
+AC_INIT([xastir], [2.0.4], [xastir at xastir.org])
+AM_INIT_AUTOMAKE
+#########################################################################
+
+
+AC_PREREQ(2.53)
+
+AC_CONFIG_SRCDIR([src/xastir.h])
+AM_CONFIG_HEADER(config.h)
+
+echo ""
+echo "Configuring AC_PACKAGE_NAME AC_PACKAGE_VERSION"
+echo ""
+
+# Take out the dots in order to create the TOCALL
+AC_DEFINE_UNQUOTED(XASTIR_TOCALL, "`echo AC_PACKAGE_VERSION | sed -e 's/^/APX/' -e 's/\.//g'`", [Defines the version tocall])
+
+# Check for host type
+AC_CANONICAL_HOST
+
+# Define _GNU_SOURCE if appropriate
+# doesn't work with older (heh) autoconfs
+AC_GNU_SOURCE
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_AWK
+AC_PROG_RANLIB
+#AC_PROG_YACC
+
+# test for devices
+XASTIR_DETECT_DEVICES
+
+# add includes and libs
+XASTIR_ADD_SEARCH_PATHS
+
+# check for pthread first
+ACX_PTHREAD
+
+# add compiler flags 
+XASTIR_COMPILER_FLAGS
+
+# set XASTIR_SYSTEM
+XASTIR_SET_SYSTEM
+
+# Check for binaries
+use_festival=yes
+use_gpsman=yes
+use_err_popups=no
+use_lsb=no
+use_spatial_db=no
+use_postgis=no
+use_mysql_spatial=no
+AC_ARG_WITH(festival,[  --without-festival        Disable festival features.],use_festival=$withval)
+
+AC_ARG_WITH(gpsman,[  --without-gpsman          Disable gpsman features.],use_gpsman=$withval)
+
+AC_ARG_WITH(errorpopups,[  --with-errorpopups        Send error popups to stderr.],use_err_popups=$withval)
+
+AC_ARG_WITH(lsb,[  --with-lsb                Enable Linux Standard Base.],use_lsb=$withval)
+
+AC_ARG_WITH([xorg_175_workaround], 
+            [AS_HELP_STRING([--with-xorg_175_workaround],[Employ workaround for broken Xorg 1.7.5 server])],
+            [],
+            [with_xorg_175_workaround=no])
+AS_IF([test "x$with_xorg_175_workaround" != xno],
+             [AC_DEFINE([XASTIR_XORG_SERVER_175_BUG], [1],
+                       [Define if you need to work with the broken Xorg server 1.7.5])])
+
+# Now that all the various "use_" variables are set, probe for binaries.
+XASTIR_DETECT_BINARIES
+
+# if the probes failed, then make sure the "use_" variables are set to no,
+# even if we requested them.
+if test "x${festival}" = "xno"; then
+  use_festival=no
+fi
+if test "x${gpsman}" = "xno"; then
+  use_gpsman=no
+fi
+
+
+# JMT - XXX - what is this and why is it relevant?
+#AC_DEFINE(_REENTRANT, 1, [Use reentrant code if available.]) 
+AC_DEFINE_UNQUOTED(STIPPLE, 1, [Legacy stuff, use crowbar and lets keep going]) 
+
+# Checks for libraries. 
+# 
+# 
+# Find the X11 include and library directories. 
+# 
+AC_PATH_XTRA
+if test "$no_x" = "yes"; then
+  AC_MSG_ERROR(*** No X11!  Install X-Windows development headers/libraries! ***)
+fi
+
+CPPFLAGS="$CPPFLAGS $X_CFLAGS" 
+LDFLAGS="$LDFLAGS $X_LIBS"
+LIBS="$LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+
+AC_SEARCH_LIBS(tan,math m)
+AC_CHECK_LIB([Xext], [XextAddDisplay])
+# It appears that XpGetDocumentData is not used
+# *anywhere* in Xastir, and the fact that this is being probed for has 
+# confused at least one user into thinking he needed to install the X Printing
+# Extension development headers when it was completely unnecessary.  But 
+# apparently  at least one linux system has a motif library that requires 
+# libXp and doesn't link it in dynamically --- so this needs to be enabled?
+AC_CHECK_LIB([Xp], [XpGetDocumentData]) 
+AC_CHECK_LIB([Xt], [XtDisplay]) 
+AC_CHECK_LIB([Xm], [XmTextFindString])
+
+
+
+#use_html2text=no
+#AC_PATH_PROG(html2text, [html2text --version], no, $BINPATH)
+#if test "$html2text" != "no"; then
+#  AC_DEFINE_UNQUOTED(HAVE_HTML2TEXT, 1, [Define if you have html2text]) 
+#  AC_DEFINE_UNQUOTED(HTML2TEXT_PATH, "${html2text}", [Path to html2text]) 
+#  use_html2text=yes
+#fi
+
+
+
+use_sed=no
+AC_PATH_PROG(sed, [sed --version], no, $BINPATH)
+if test "$sed" != "no"; then
+  AC_DEFINE_UNQUOTED(HAVE_SED, 1, [Define if you have sed]) 
+  AC_DEFINE_UNQUOTED(SED_PATH, "${sed}", [Path to sed]) 
+  use_sed=yes
+fi
+
+
+
+use_mv=no
+AC_PATH_PROG(mv, [mv --version], no, $BINPATH)
+if test "$mv" != "no"; then
+  AC_DEFINE_UNQUOTED(HAVE_MV, 1, [Define if you have mv]) 
+  AC_DEFINE_UNQUOTED(MV_PATH, "${mv}", [Path to mv]) 
+  use_mv=yes
+fi
+
+
+
+use_xfontsel=no
+AC_PATH_PROG(xfontsel, xfontsel, no, $BINPATH)
+if test "$xfontsel" != "no"; then
+  AC_DEFINE_UNQUOTED(HAVE_XFONTSEL, 1, [Define if you have xfontsel]) 
+  AC_DEFINE_UNQUOTED(XFONTSEL_PATH, "${xfontsel}", [Path to xfontsel]) 
+  use_xfontsel=yes
+fi
+
+
+
+use_curl=no
+curl_desired=yes
+# Note: Had to move AC_CHECK_HEADER here instead of inside the first
+# "if" statement:  It corrupted later tests, don't know why.  The
+# only downside is that we check for the libcurl headers even if
+# --without-libcurl was specified on the command-line.
+AC_CHECK_HEADER(curl/curl.h, CURL_INC="yes", CURL_INC="no")
+AC_ARG_WITH(libcurl,[  --without-libcurl         Disable libcurl features.],curl_desired=$withval)
+if test "${curl_desired}" = "yes"; then
+  if test "${CURL_INC}" = "yes"; then
+    if test "${use_lsb}" = "no"; then 
+      # Important: when using the three-argument version of AC_CHECK_LIB, you
+      # must do all of what is normally the default behavior in the third argument,
+      # not just the extra stuff you want to accomplish:
+      AC_CHECK_LIB([curl], [curl_global_init], 
+                   [use_curl="yes"
+                    LIBS="${LIBS} -lcurl"
+                    AC_DEFINE(HAVE_LIBCURL, ,
+                              [Define to 1 if your `curl' library has curl_global_init.])
+                    ])
+    else
+      AC_DEFINE(HAVE_LIBCURL, , [Define to 1 if your `curl' library has curl_global_init.] )
+      LIBS="${LIBS} -lcurl"
+      use_curl=yes
+    fi
+  fi
+fi
+# Test for wget only if above libcurl tests fail
+use_wget=no
+if test "${use_curl}" = "no"; then
+  AC_PATH_PROG(wget, [wget --version], no, $BINPATH)
+  if test "$wget" != "no"; then
+    AC_DEFINE_UNQUOTED(HAVE_WGET, 1, [Define if you have wget]) 
+    AC_DEFINE_UNQUOTED(WGET_PATH, "${wget}", [Path to wget]) 
+    use_wget=yes
+  fi
+fi
+
+
+
+use_retrieval=no
+if test "${use_curl}" = "yes"; then
+  use_retrieval="yes (libcurl)"
+else
+  if test "${use_wget}" = "yes"; then
+    use_retrieval="yes (wget)"
+  fi
+fi
+
+
+
+# Test for libgps, used for accessing GPSD daemon
+#use_libgps=no
+#AC_CHECK_HEADER(gps.h, GPS_INC="yes", GPS_INC="no")
+#if test "${GPS_INC}" = "yes"; then
+#  AC_CHECK_LIB([gps], [gps_open],
+#               [use_libgps="yes"
+#                LIBS="${LIBS} -lgps"
+#                AC_DEFINE(HAVE_LIBGPS, ,
+#                          [Define to 1 if your `libgps' library has gps_open.])
+#                ])
+#fi
+
+
+
+# JMT - XXX - why is this here?
+AC_CHECK_LIB(compat, main, 
+    [LIBCOMPAT="-lcompat"
+    AC_SUBST(LIBCOMPAT)])
+ 
+# Check for sched_yield in librt (Needed for Solaris)
+AC_CHECK_LIB(rt, sched_yield, LIBS="-lrt $LIBS")
+ 
+# Check for endian 
+AC_C_BIGENDIAN 
+ 
+
+
+# Our old stuff.  Doesn't work in all cases.
+# Checks for header files. 
+#AC_CHECK_HEADERS([Xm/Xm.h],MOTIF_INC="yes", AC_MSG_ERROR(*** Cannot find Motif include files:  Please install one of Motif/OpenMotif/Lesstif development packages. ***))
+
+XASTIR_PATH_MOTIF
+if test "x$xm_includes" != "x" ; then
+    CFLAGS="$CFLAGS -I$xm_includes"
+    CPPFLAGS="$CPPFLAGS -I$xm_includes"
+fi
+if test "x$xm_libraries" != "x" ; then
+    LDFLAGS="-L$xm_libraries $LDFLAGS"
+fi
+
+AC_SUBST(LDFLAGS) 
+AC_SUBST(LIBS) 
+
+
+#
+AC_FUNC_ALLOCA 
+AC_HEADER_DIRENT 
+AC_HEADER_STDC 
+AC_HEADER_SYS_WAIT 
+AC_CHECK_HEADERS([argz.h arpa/inet.h fcntl.h libintl.h limits.h locale.h malloc.h math.h netdb.h]) 
+AC_CHECK_HEADERS([netinet/in.h nl_types.h stdarg.h stddef.h stdlib.h string.h strings.h])
+AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h signal.h])
+AC_CHECK_HEADERS([termios.h unistd.h]) 
+
+# Checks for typedefs, structures, and compiler characteristics. 
+# 
+AC_C_CONST 
+AC_TYPE_UID_T 
+AC_C_INLINE 
+AC_TYPE_PID_T 
+AC_TYPE_SIZE_T 
+AC_HEADER_TIME 
+#AC_STRUCT_TM 
+AC_TYPE_SIGNAL 
+AC_STRUCT_TIMEZONE
+
+#Some (Mac?) systems don't define this where it should be, so we kludge
+AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h>
+#include <sys/socket.h>])
+
+# some BSD systems do not define sighandler_t, but rather sig_t
+AC_CHECK_TYPES(sighandler_t,,,[#include <signal.h>])
+AC_CHECK_TYPES(sig_t,,,[#include <signal.h>])
+
+# some BSD systems do not define sighandler_t, but rather sig_t
+AC_CHECK_TYPES(sigjmp_buf,,,[#include <setjmp.h>])
+
+#Force this into config.h.in
+AH_BOTTOM([#ifndef HAVE_SOCKLEN_T
+#define socklen_t int
+#endif])
+
+
+# Check for tm_gmtoff in tm
+AC_CHECK_GMTOFF
+ 
+# Checks for library functions. 
+# 
+AC_FUNC_FORK 
+AC_PROG_GCC_TRADITIONAL 
+AC_FUNC_GETPGRP 
+AC_FUNC_MALLOC 
+AC_FUNC_MKTIME 
+AC_FUNC_MMAP 
+AC_FUNC_STAT 
+AC_FUNC_STRFTIME 
+AC_FUNC_STRTOD 
+AC_CHECK_FUNCS([__argz_count __argz_next __argz_stringify alarm dcgettext])
+AC_CHECK_FUNCS([getcwd getpgrp gethostbyname gethostname gettimeofday])
+AC_CHECK_FUNCS([getwd inet_ntoa memmove mempcpy memset mkdir munmap pow])
+AC_CHECK_FUNCS([putenv select setenv setlocale settimeofday signal sigignore])
+AC_CHECK_FUNCS([snprintf socket sqrt stpcpy strcasecmp strchr strdup])
+AC_CHECK_FUNCS([strerror strncasecmp strpbrk strptime strrchr strstr])
+AC_CHECK_FUNCS([strtof strtol strtoul tzset vsnprintf])
+
+# Check for deprecated/current pthread functions
+AC_CHECK_FUNCS([pthread_mutexattr_setkind_np pthread_mutexattr_settype])
+
+# this is a GNU extension and not present on all systems.
+AC_CHECK_FUNCS([strndup])
+
+#this is also a recent extension that should not be counted on
+AC_CHECK_FUNCS([roundf])
+ 
+# Check for intl library (Needed for Cygwin) 
+# 
+AC_CHECK_LIB(intl, gettext, LIBS="-lintl ${LIBS}") 
+
+# Check for libproj (need to do this before test for shapelib, because
+# the shapelib test asks about "use_proj"
+use_proj=yes
+AC_ARG_WITH(libproj,[  --without-libproj         Disable libproj features.],use_proj=$withval)
+if test "${use_proj}" = "yes"; then
+  use_proj=no
+  AC_CHECK_LIB(proj, pj_init, use_proj=yes LIBS="$LIBS -lproj"
+    AC_DEFINE(HAVE_PROJ, , Define to 1 if you have the `libproj' library (-lproj). )
+  )
+fi
+
+
+# Check for Shapelib
+use_shapelib=yes
+force_internal_shapelib=no
+shapelib_desired=yes
+LIBSHP=""
+SUBSHP=""
+# This symbol will be blank if the proj library hasn't been found, and will
+# have the three programs that need proj if it has
+CONTSHP=""
+AC_ARG_WITH(internal-shapelib,[  --with-internal-shapelib  Force use of internal shapelib library.],force_internal_shapelib=$withval)
+AC_ARG_WITH(shapelib,[  --without-shapelib        Disable shapelib features.],shapelib_desired=$withval)
+if test "${shapelib_desired}" = "no"; then
+  use_shapelib=no
+  force_internal_shapelib=no
+fi
+if test "${force_internal_shapelib}" = "yes"; then
+  AC_MSG_WARN([***************************************************************** ])  
+  AC_MSG_WARN([Internal Shapelib library has been forced.                        ])
+  AC_MSG_WARN([***************************************************************** ])
+  # Temporary setting to get into if block below
+  use_shapelib=no
+fi
+if test "${shapelib_desired}" = "yes" -a "${force_internal_shapelib}" = "no"; then
+  use_shapelib=no
+  AC_CHECK_HEADERS(shapefil.h libshp/shapefil.h, [AC_CHECK_LIB(shp, DBFOpen, use_shapelib=yes
+    LIBS="$LIBS -lshp"
+    AC_CHECK_LIB(shp,DBFGetFieldIndex,
+      AC_DEFINE(HAVE_DBFGETFIELDINDEX, , Define to 1 if your `shp' library has DBFGetFieldIndex. ) )
+    AC_DEFINE(HAVE_LIBSHP, , Define to 1 if you have the `shp' library (-lshp). )
+    break)])
+fi
+if test "${shapelib_desired}" = "yes" -a "${use_shapelib}" = "no"; then
+ AC_MSG_WARN([**************************************************************** ])  
+ AC_MSG_WARN([Your system does not have shapelib installed.  Using an internal ])
+ AC_MSG_WARN([version.  This may lead to a larger filesize for the executable. ])
+ AC_MSG_WARN([Install shapelib on your system to eliminate this warning.       ])
+ AC_MSG_WARN([**************************************************************** ])  
+ LIBSHP="-Lshapelib -lshape"
+ CPPFLAGS="-I\$(top_srcdir)/src/shapelib $CPPFLAGS"
+ SUBSHP="shapelib" 
+ use_shapelib=yes
+ force_internal_shapelib=yes
+ AC_DEFINE(HAVE_DBFGETFIELDINDEX, , Define to 1 if your `shp' library has DBFGetFieldIndex. ) 
+ AC_DEFINE(HAVE_LIBSHP, , Define to 1 if you have the `shp' library (-lshp). )
+ AC_DEFINE(HAVE_SHAPEFIL_H, , Define to 1 if you have the `shapefil.h' header. )
+
+ if  test  $use_proj = "yes" 
+ then
+   CONTSHP="shpcentrd shpproj shpdata shpwkb"
+ fi
+fi
+AC_SUBST(SUBSHP)
+AC_SUBST(CONTSHP)
+AC_SUBST(LIBSHP)
+
+
+# Check for pcre
+use_pcre=yes
+AC_ARG_WITH(pcre,[  --without-pcre            Disable pcre features.],use_pcre=$withval)
+if test "${use_pcre}" = "yes"; then
+  use_pcre=no
+  AC_CHECK_HEADERS(pcre.h pcre/pcre.h, [AC_CHECK_LIB(pcre, pcre_compile, use_pcre=yes
+  LIBS="$LIBS -lpcre"
+  AC_DEFINE(HAVE_LIBPCRE, , Define to 1 if you have the `pcre' library (-lpcre). )
+  break)])
+fi
+
+
+# Check for XPM
+if test "${use_lsb}" = "no"; then 
+  AC_CHECK_HEADERS(X11/xpm.h, AC_SEARCH_LIBS(XpmWriteFileFromPixmap, Xpm, AC_DEFINE(HAVE_LIBXPM, , Define to 1 if you have the `Xpm' library (-lXpm). )))
+  AC_CHECK_HEADERS(Xm/XpmI.h, AC_SEARCH_LIBS(XmeXpmWriteFileFromPixmap, Xm, AC_DEFINE(HAVE_LIBXPM_IN_XM, , Define to 1 if the `Xm' library (-lXm) is used for Xpm. )))
+else
+  AC_DEFINE(HAVE_LIBXPM, , Define to 1 if you have the `Xpm' library (-lXpm). )
+  AC_DEFINE(HAVE_LIBXPM_IN_XM, , Define to 1 if the `Xm' library (-lXm) is used for Xpm. )
+  AC_DEFINE(HAVE_X11_XPM_H, , Define to 1 if you have 'X11/xpm.h' )
+fi
+ 
+ 
+#check for libtiff, libgeotiff
+# libjpeg.a and libz.a need to be compiled under LSB
+
+
+use_geotiff=yes
+AC_ARG_WITH(geotiff, [  --without-geotiff         Disable geotiff features.], use_geotiff=$withval)
+if test "${use_geotiff}" = "yes"; then
+    if test "${use_proj}" = "yes" ; then
+        if test "${use_lsb}" = "yes" ; then
+            use_tiff=yes
+            use_geotiff=yes
+            LIBS="$LIBS -lgeotiff -ltiff -ljpeg -lz -lproj"
+            AC_DEFINE(HAVE_TIFF, ,Define to 1 if you have the 'tiff' library (-ltiff))
+            AC_DEFINE(HAVE_LIBGEOTIFF, ,Define to 1 if you have the `geotiff' library (-lgeotiff).)
+        else
+            AC_CHECK_HEADER(xtiffio.h, , use_geotiff="no")
+            if test "${use_geotiff}" = "yes"; then
+                AC_CHECK_LIB(tiff, TIFFClose, use_tiff=yes
+                LIBS="$LIBS -ltiff"
+                AC_DEFINE(HAVE_TIFF, ,Define to 1 if you have the 'tiff' library (-ltiff)))
+                if test "${use_tiff}" = "yes"; then
+                    use_geotiff=no
+                    AC_CHECK_LIB(geotiff, GTIFNew, use_geotiff=yes
+                        LIBS="$LIBS -lgeotiff"
+                        AC_DEFINE(HAVE_LIBGEOTIFF, ,Define to 1 if you have the `geotiff' library (-lgeotiff).))
+                else
+                    echo "*** Warning: geotiff requires libtiff."
+                    use_geotiff=no
+                fi
+            else
+                echo "*** Warning: geotiff include files not found."
+            fi
+        fi
+    else
+        echo "*** Warning: geotiff requires libproj."
+        use_geotiff=no
+    fi
+fi 
+
+# Check for spatial database support
+use_postgis=no
+AC_ARG_WITH(postgis, [  --with-postgis            Enable Postgresql with PostGIS.],use_postgis=$withval)
+if test "${use_postgis}" != "no"; then
+  XASTIR_CHECK_POSTGIS
+fi
+use_mysql=no
+AC_ARG_WITH(mysql, [  --with-mysql	            Enable MySQL, with spatial support if available.],use_mysql=$withval)
+if test "${use_mysql}" != "no"; then
+  XASTIR_CHECK_MYSQL
+fi
+
+if test "${use_postgis}" = "yes"; then
+  use_spatial_db=yes
+  AC_DEFINE(HAVE_SPATIAL_DB, 1, [Spatial database support available] )
+  AC_DEFINE(HAVE_DB, 1, [Database support available] )
+fi
+if test "${use_mysql_spatial}" = "yes"; then
+  use_spatial_db=yes
+  AC_DEFINE(HAVE_DB, 1, [Database support available] )
+  AC_DEFINE(HAVE_SPATIAL_DB, 1, [Spatial database support available] )
+elif test use_mysql_any = "yes"; then
+  AC_DEFINE(HAVE_DB, 1, [Database support available] )
+fi
+
+# Check for AX.25 library 
+use_ax25=yes
+AC_ARG_WITH(ax25,[  --without-ax25            Disable ax25 features.],use_ax25=$withval)
+if test "${use_ax25}" = "yes"; then
+  use_ax25=no
+  AC_CHECK_HEADERS(netax25/ax25.h, [AC_CHECK_LIB(ax25, ax25_config_load_ports, use_ax25=yes
+  LIBS="$LIBS -lax25"
+  AC_DEFINE(HAVE_LIBAX25, , Define to 1 if you have the `ax25' library (-lax25). )
+  break)])
+fi
+
+
+# use dbfawk
+use_dbfawk=yes
+AC_ARG_WITH(dbfawk,[  --without-dbfawk          Disable dbfawk features.],use_dbfawk=$withval)
+# dbfawk requires shapelib and pcre.  Make sure:
+if test "${use_dbfawk}" = "yes"; then
+  if test "${use_pcre}" = "yes" -a "${use_shapelib}" = "yes"; then
+    AC_DEFINE(WITH_DBFAWK, , Define to 1 to use dbfawk features. )
+  else
+    echo "*** Warning: dbfawk requires both pcre and shapelib."
+    use_dbfawk=no
+  fi
+fi
+
+
+# Check for GDAL.  Make sure that the GDAL check is towards the
+# last, as it can mess up shapelib and libgeotiff currently.
+use_gdal=yes
+AC_ARG_WITH(gdal,[  --without-gdal            Disable gdal features.],use_gdal=$withval)
+if test "${use_gdal}" = "yes"; then
+  if test "${use_lsb}" = "no"; then 
+    XASTIR_CHECK_GDAL
+  else
+    CPPFLAGS="$CPPFLAGS -I/opt/lsb-tmp/include"
+    LDFLAGS="$LDFLAGS -L/opt/lsb-tmp/lib -lgdal"
+    LIBS="$LIBS -lgdal"
+    AC_DEFINE(HAVE_LIBGDAL, , [Define to 1 if you have the `gdal' library (-lgdaal).])
+  fi
+fi
+
+use_rtree=yes
+LIBRTREE=""
+SUBRTREE=""
+AC_ARG_WITH(rtree,[  --without-rtree           Disable spatial indexing of shapefiles.],[use_rtree=$withval])
+if test "${use_rtree}" = "yes" ; then
+  if test "${use_shapelib}" = "yes"; then
+    AC_DEFINE([USE_RTREE],1,[RTree spatial indexing])
+     LIBRTREE="-Lrtree -lrtree"
+     SUBRTREE="rtree"
+  else
+    echo "*** Warning: rtree requires shapelib."
+    use_rtree=no
+  fi
+fi
+AC_SUBST(SUBRTREE)
+AC_SUBST(LIBRTREE)
+
+
+
+
+AC_ARG_ENABLE(davis, [  --enable-davis          Turn on Davis support],
+  [case "${enableval}" in
+    yes) davis=true ;;
+     no) davis=false ;;
+      *) AC_MSG_ERROR(bad value ${enableval} for --enable-davis) ;;
+  esac],[davis=false])
+AM_CONDITIONAL(DAVIS, test x$davis = xtrue)
+if test "${davis}" = "true"; then
+  davis=yes
+else
+  davis=no
+fi
+
+
+
+
+
+# Check for LIBGC, a Garbage Collection library.  If found, allow
+# linking it with Xastir, but require the "--with-libgc" flag to
+# enable it.
+use_libgc=no
+AC_ARG_WITH(libgc,[  --with-libgc              Enable libgc features.],use_libgc=$withval)
+if test "${use_libgc}" = "yes"; then
+    AC_CHECK_HEADERS([gc.h], LIBGC_INC="yes", use_libgc=no)
+    AC_CHECK_LIB([gc], [GC_init], , use_libgc=no)
+fi
+
+
+
+
+
+# Check whether profiling was requested.  If so, add the "-pg" flag
+# to CFLAGS.  Require "--with-profiling" flag to enable it.
+use_profiling=no
+AC_ARG_WITH(profiling,[  --with-profiling          Enable profiling features.],use_profiling=$withval)
+if test "${use_profiling}" = "yes"; then
+    CFLAGS="$CFLAGS -pg"
+fi
+
+
+
+
+
+# Check for Berkeley DB.
+use_map_cache=yes
+AC_ARG_WITH(map_cache,[  --without-map-cache       Disable Map Caching.],use_map_cache=$withval)
+if test "${use_map_cache}" = "yes"; then
+  XASTIR_BERKELEY_DB_CHK
+fi
+
+
+
+
+
+# Check for GraphicsMagick.  If not available/desired then check for
+# ImageMagick.  These checks are VERY important to have as the last,
+# as they mess up previous checks if they fail.
+#
+use_graphicsmagick=yes
+use_imagemagick=no
+AC_ARG_WITH(graphicsmagick,[  --without-graphicsmagick  Disable graphicsmagick features.],use_graphicsmagick=$withval)
+if test "${use_graphicsmagick}" = "yes"; then
+  if test "${use_lsb}" = "no"; then
+    XASTIR_CHECK_GRAPHICSMAGICK
+  else
+    MAGIC_BIN="/opt/lsb-tmp/bin/GraphicsMagick-config"
+    CPPFLAGS="$CPPFLAGS `${MAGIC_BIN} --cppflags`"
+    CXXFLAGS="$CXXFLAGS `${MAGIC_BIN} --cflags`"
+    LDFLAGS="$LDFLAGS `${MAGIC_BIN} --ldflags`"
+    LIBS="${MAGIC_LIB_DIR} `${MAGIC_BIN} --libs` $LIBS"
+    AC_DEFINE(HAVE_GRAPHICSMAGICK, 1, [GraphicsMagick image library])
+  fi
+fi
+#
+# Note: This must be a separate "if" as the use_graphicsmagick
+# variable gets set to "no" if GM is not available above.
+#
+if test "${use_graphicsmagick}" = "no"; then
+  use_imagemagick=yes
+  AC_ARG_WITH(imagemagick,[  --without-imagemagick     Disable imagemagick features.],use_imagemagick=$withval)
+  if test "${use_imagemagick}" = "yes"; then
+    XASTIR_CHECK_IMAGEMAGICK
+  fi
+fi
+#
+#
+#
+if test "${use_imagemagick}" = "yes" -o "${use_graphicsmagick}" = "yes"; then
+  AC_DEFINE(HAVE_MAGICK, 1, [GraphicsMagick or ImageMagick library])
+fi
+
+
+
+
+
+# Set XASTIR_DATA_BASE in CPPFLAGS due to Gnu coding standard that requires
+# datadir expansion to be deferred until make time.
+if test "x${datadir}" = "x"; then 
+  CPPFLAGS="$CPPFLAGS -DXASTIR_DATA_BASE=\\\"${ac_default_prefix}/share/xastir\\\""
+else 
+  CPPFLAGS="$CPPFLAGS -DXASTIR_DATA_BASE=\\\"${datadir}/xastir\\\""
+fi 
+ 
+
+
+# Add a special option that makes Cygwin link much faster (from
+# Henk de Groot)
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="-Wl,--no-keep-memory $LDFLAGS"
+AC_TRY_LINK([#include <sys/types.h>],
+  [/* Stupid useless test for linker flags */
+   exit(0);],
+  xa_cv_no_keep_memory=yes,
+  xa_cv_no_keep_memory=no)
+if test "${xa_cv_no_keep_memory}" = "no"; then 
+  LDFLAGS="$save_LDFLAGS"
+fi
+
+# 
+# Assure we have this order for these LIBS: "-lXm -lXt -lX11" by 
+# adding them to the beginning.  Add spaces around them for the 
+# following steps.  Here I'm adding them to the beginning so the   
+# dupe-check portion will take out the later ones that might be in 
+# the wrong order.  If they're in the wrong order, we can get 
+# "Error: Shell widget xastir has zero width and/or height" when 
+# Xastir is started up.   Can also get "Error: attempt to add
+# non-widget child "DropSiteManager" to parent", but that can also
+# be caused by other problems with libraries.
+# 
+LIBS=" -lXm -lXt -lX11 $LIBS" 
+  
+# 
+# Remove duplicate entries.  Thanks to Paul Lutt, ke7xt, for this! 
+#
+# Don't get rid of dupes on the LIBS line.  We may need the same
+# "-Llibdir" called out several times, immediately prior to each
+# "-llibrary" that needs it.
+# 
+changequote(,) 
+CFLAGS=`echo  "$CFLAGS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+CPPFLAGS=`echo  "$CPPFLAGS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+LDFLAGS=`echo "$LDFLAGS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+#LIBS=`echo "$LIBS" | awk '{for(i=1;i<=NF;++i) {if (arg[$i]++ == 0) s = s " " $i} print s}'`
+changequote([,]) 
+
+
+# 
+# Remove "-g" CFLAGS/CPPFLAGS entries.  Note:  This is a _bad_ idea
+# as debuggers won't have a symbol table to work from!
+#
+#changequote(,) 
+#CFLAGS=`echo  "$CFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-g") s = s " " $i} print s}'`
+#CPPFLAGS=`echo  "$CPPFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-g") s = s " " $i} print s}'`
+#changequote([,]) 
+
+
+#
+# Change the compiler optimization if using Windows/Cygwin in order
+# to reduce memory usage and speed up the compile.  Here we change
+# "-O2" to "-O1" or " " in CFLAGS/CPPFLAGS to reduce the level of
+# optimization.
+# We also wish to remove "-no-undefined" from LDFLAGS on Cygwin, as
+# we use GCC for our linking instead of libtool, and GCC doesn't
+# like that flag at the link stage.
+#
+case "$host_os" in
+cygwin*)
+  changequote(,) 
+  CFLAGS=`echo  "$CFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-O2") s = s " " $i} print s}'`
+  CPPFLAGS=`echo  "$CPPFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-O2") s = s " " $i} print s}'`
+  LDFLAGS=`echo  "$LDFLAGS" | awk '{for(i=1;i<=NF;++i) {if ($i != "-no-undefined") s = s " " $i} print s}'`
+  changequote([,]) 
+;;
+esac
+ 
+
+# Create the ILIBS defined variable.  We add spaces here in the else
+# clauses in order to make the REGRESSION_TESTS format nicely.  We
+# take them back out before we define the variable that Xastir uses
+# for it's Help->About dialog.
+#
+if test "${use_ax25}" = "yes"; then
+  ILIBS="AX25"
+else
+  ILIBS="    "
+fi
+if test "${use_festival}" = "yes"; then
+  ILIBS="$ILIBS Festival"
+else
+  ILIBS="$ILIBS         "
+fi
+if test "${use_gpsman}" = "yes"; then
+  ILIBS="$ILIBS GPSMan"
+else
+  ILIBS="$ILIBS       "
+fi
+if test "${use_graphicsmagick}" = "yes"; then
+    ILIBS="$ILIBS GraphicsMagick"
+else
+  if test "${use_imagemagick}" = "yes"; then
+    ILIBS="$ILIBS ImageMagick   "
+  else
+    ILIBS="$ILIBS               "
+  fi 
+fi
+if test "${use_proj}" = "yes"; then
+  ILIBS="$ILIBS libProj"
+else
+  ILIBS="$ILIBS        "
+fi
+if test "${use_geotiff}" = "yes"; then
+  ILIBS="$ILIBS GeoTiff"
+else
+  ILIBS="$ILIBS        "
+fi
+if test "${use_gdal}" = "yes"; then
+  ILIBS="$ILIBS GDAL/OGR"
+else
+  ILIBS="$ILIBS         "
+fi
+if test "${use_shapelib}" = "yes"; then
+  ILIBS="$ILIBS ShapeLib"
+else
+  ILIBS="$ILIBS         "
+fi
+if test "${use_pcre}" = "yes"; then
+  ILIBS="$ILIBS PCRE"
+else
+  ILIBS="$ILIBS     "
+fi
+if test "${use_dbfawk}" = "yes"; then
+  ILIBS="$ILIBS Dbfawk"
+else
+  ILIBS="$ILIBS       "
+fi
+if test "${use_map_cache}" = "yes"; then
+  ILIBS="$ILIBS map_caching"
+else
+  ILIBS="$ILIBS            "
+fi
+if test "${use_err_popups}" = "yes"; then
+  ILIBS="$ILIBS error_popups"
+else
+  ILIBS="$ILIBS             "
+fi
+if test "${use_libgc}" = "yes"; then
+  ILIBS="$ILIBS libgc"
+else
+  ILIBS="$ILIBS      "
+fi
+if test "${use_profiling}" = "yes"; then
+  ILIBS="$ILIBS profiling"
+else
+  ILIBS="$ILIBS          "
+fi
+if test "${use_rtree}" = "yes"; then
+  ILIBS="$ILIBS rtree"
+else
+  ILIBS="$ILIBS      "
+fi
+if test "${use_lsb}" = "yes"; then
+  ILIBS="$ILIBS LSB"
+else
+  ILIBS="$ILIBS    "
+fi
+if test "${use_curl}" = "yes"; then
+  ILIBS="$ILIBS libcurl"
+else
+  if test "${use_wget}" = "yes"; then
+    ILIBS="$ILIBS wget   "
+  else
+    ILIBS="$ILIBS        "
+  fi
+fi
+
+# Write out the library information to "summary.log".  Here we want
+# the spaces for the undefined pieces, so REGRESSION_TESTS formats
+# nicely.
+echo "$ILIBS" >summary.log
+
+
+# 
+# Remove extraneous spaces from output variables (asthetic) 
+# 
+ILIBS=`echo $ILIBS | sed -e 's/  */ /g'` 
+X_CFLAGS=`echo $X_CFLAGS | sed -e 's/  */ /g'` 
+X_PRE_LIBS=`echo $X_PRE_LIBS | sed -e 's/  */ /g'` 
+X_LIBS=`echo $X_LIBS | sed -e 's/  */ /g'` 
+X_EXTRA_LIBS=`echo $X_EXTRA_LIBS | sed -e 's/  */ /g'` 
+ 
+CC=`echo $CC | sed -e 's/  */ /g'` 
+CFLAGS=`echo $CFLAGS | sed -e 's/  */ /g'`
+CPPFLAGS=`echo $CPPFLAGS | sed -e 's/  */ /g'` 
+CXXFLAGS=`echo $CXXFLAGS | sed -e 's/  */ /g'` 
+LDFLAGS=`echo $LDFLAGS | sed -e 's/  */ /g'` 
+TESTED_LIBS=`echo $LIBS | sed -e 's/  */ /g'` 
+MAGICK_DEP_LIBS=`echo $MAGICK_DEP_LIBS | sed -e 's/  */ /g'` 
+LIBS=`echo $LIBS | sed -e 's/  */ /g'` 
+
+
+# Change the output text for Shapelib if we're using the internal
+# library.  The below will be used for the configure summary and for
+# the Help->About text in Xastir.
+if test "${force_internal_shapelib}" = "yes"; then
+  ILIBS=`echo $ILIBS | sed -e 's/ShapeLib/ShapeLib(internal)/g'`
+  use_shapelib="yes (internal)"
+fi
+
+
+
+tmp_path="$ac_default_prefix"
+tmp_bin_path="$ac_default_prefix"
+if test "x$prefix" != xNONE; then
+  tmp_path="$prefix"
+  tmp_bin_path="$prefix"
+fi
+if test "x$exec_prefix" != xNONE; then
+  tmp_bin_path="$exec_prefix"
+fi
+AC_DEFINE_UNQUOTED(XASTIR_PATH, "`echo $tmp_path`", [Path to installed Xastir files.])
+AC_DEFINE_UNQUOTED(XASTIR_BIN_PATH, "`echo $tmp_bin_path`", [Path to installed Xastir binaries.])
+
+
+
+AC_DEFINE_UNQUOTED(XASTIR_INSTALLED_LIBS, "`echo $ILIBS`", [Defines the installed libs])
+
+
+AC_SUBST(LDFLAGS) 
+AC_SUBST(LIBS) 
+#AC_SUBST(CPPFLAGS) 
+AC_SUBST(X_CFLAGS) 
+#AC_SUBST(LDFLAGS) 
+#AC_SUBST(X_PRE_LIBS) 
+#AC_SUBST(X_LIBS) 
+#AC_SUBST(X_EXTRA_LIBS) 
+
+AC_CONFIG_FILES([Makefile \
+    callpass/Makefile \
+    config/Makefile \
+    help/Makefile \
+    m4/Makefile \
+    scripts/Makefile \
+    scripts/values \
+    scripts/values.pl \
+    src/Makefile \
+    src/rtree/Makefile \
+    src/shapelib/Makefile \
+    src/shapelib/contrib/Makefile \
+    symbols/Makefile \
+    xastir.spec \
+    xastir-min.spec \
+    xastir-lsb.spec]) 
+ 
+AC_OUTPUT 
+
+# Please leave these in as they're very useful for debug when we
+# port to new platforms!  Leave them commented out unless doing
+# debugging on the configure scripts.
+#
+#echo "" 
+#echo "        LIBS: $LIBS" 
+#echo "     LDFLAGS: $LDFLAGS" 
+#echo "      CFLAGS: $CFLAGS" 
+#echo "    CPPFLAGS: $CPPFLAGS" 
+#echo "      X_LIBS: $X_LIBS" 
+#echo "  X_PRE_LIBS: $X_PRE_LIBS" 
+#echo "X_EXTRA_LIBS: $X_EXTRA_LIBS" 
+
+
+# Write a short summary of the configure tests/results to
+# "summary.log"
+egrep -e "checking |result:|gcc version" config.log >> summary.log
+
+
+echo ===========================================
+echo
+echo AC_PACKAGE_NAME AC_PACKAGE_VERSION has been configured to use the following
+echo options and external libraries:
+echo
+echo MINIMUM OPTIONS:
+echo "  ShapeLib (Vector maps) ................. : $use_shapelib"
+echo
+echo RECOMMENDED OPTIONS:
+
+echo -n "  GraphicsMagick/ImageMagick (Raster maps) : "
+if test "${use_graphicsmagick}" = "yes"; then 
+  echo "yes (GraphicsMagick)"
+else
+  if test "${use_imagemagick}" = "yes"; then
+    echo "yes (ImageMagick)"
+  else
+    echo "no"
+  fi
+fi
+echo "  pcre (Shapefile customization) ......... : $use_pcre"
+echo "  dbfawk (Shapefile customization) ....... : $use_dbfawk"
+echo "  rtree indexing (Shapefile speedups) .... : $use_rtree"
+echo "  map caching (Raster map speedups) ...... : $use_map_cache"
+echo "  internet map retrieval ................. : $use_retrieval"
+echo
+echo FOR THE ADVENTUROUS:
+echo "  AX25 (Linux Kernel I/O Drivers) ........ : $use_ax25"
+echo "  libproj (USGS Topos & Aerial Photos) ... : $use_proj"
+echo "  GeoTiff (USGS Topos & Aerial Photos) ... : $use_geotiff"
+echo "  Festival (Text-to-speech) .............. : $use_festival"
+echo "  GDAL/OGR (Obtuse map formats) .......... : $use_gdal"
+echo "  GPSMan/gpsmanshp (GPS downloads) ....... : $use_gpsman"
+#echo "  GPSD Client (libgps) ................... : $use_libgps"
+
+if test "${use_err_popups}" = "yes" -o "${use_libgc}" = "yes" -o "${use_profiling}" = "yes" -o "${use_lsb}" = "yes" -o "${use_spatial_db}" = "yes" -o "$use_mysql_any" = "yes"; then
+  echo
+  echo DEVELOPER OPTIONS:
+  echo "  ErrorPopups (Old Method) ............... : $use_err_popups"
+  echo "  libgc (Debug memory usage) ............. : $use_libgc"
+  echo "  profiling (Debug code efficiency) ...... : $use_profiling"
+  echo "  Linux Standard Base (LSB) .............. : $use_lsb"
+  echo "  Spatial database support ............... : $use_spatial_db"
+  echo "  Spatial database Postgresql/Postgis .... : $use_postgis"
+  echo "  MySQL .................................. : $use_mysql_any"
+  echo "  MySQL Spatial database support ......... : $use_mysql_spatial"
+fi
+
+#echo   Davis/MySQL............................. : $davis
+echo 
+echo AC_PACKAGE_NAME will be installed in $prefix/bin. 
+if test "x$xastirpath" != "x" ; then 
+        echo Warning: You have an old copy of Xastir at $xastirpath. 
+fi 
+echo "Type 'make' to build Xastir (Use 'gmake' instead on some systems)." 
+
+
diff --git a/depcomp b/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 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, see <http://www.gnu.org/licenses/>.
+
+# 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.
+
+# Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+	       s/^ *//
+	       s/ \\*$//
+	       s/$/:/
+	       p
+	     }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/help/Makefile.am b/help/Makefile.am
new file mode 100644
index 0000000..4762083
--- /dev/null
+++ b/help/Makefile.am
@@ -0,0 +1,22 @@
+# $Id: Makefile.am,v 1.12 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+helpdir = ${pkgdatadir}/help
+EXTRA_DIST = \
+    help-Dutch.dat \
+    help-English.dat \
+    help-French.dat \
+    help-German.dat \
+    help-Italian.dat \
+    help-Portuguese.dat \
+    help-Spanish.dat
+
+help_DATA = \
+    help-Dutch.dat \
+    help-English.dat \
+    help-French.dat \
+    help-German.dat \
+    help-Italian.dat \
+    help-Portuguese.dat \
+    help-Spanish.dat
diff --git a/help/Makefile.in b/help/Makefile.in
new file mode 100644
index 0000000..8a4dbd1
--- /dev/null
+++ b/help/Makefile.in
@@ -0,0 +1,430 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = help
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(helpdir)"
+DATA = $(help_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+
+# $Id: Makefile.am,v 1.12 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+helpdir = ${pkgdatadir}/help
+EXTRA_DIST = \
+    help-Dutch.dat \
+    help-English.dat \
+    help-French.dat \
+    help-German.dat \
+    help-Italian.dat \
+    help-Portuguese.dat \
+    help-Spanish.dat
+
+help_DATA = \
+    help-Dutch.dat \
+    help-English.dat \
+    help-French.dat \
+    help-German.dat \
+    help-Italian.dat \
+    help-Portuguese.dat \
+    help-Spanish.dat
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu help/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu help/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-helpDATA: $(help_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(helpdir)" || $(MKDIR_P) "$(DESTDIR)$(helpdir)"
+	@list='$(help_DATA)'; test -n "$(helpdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(helpdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(helpdir)" || exit $$?; \
+	done
+
+uninstall-helpDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(help_DATA)'; test -n "$(helpdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(helpdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(helpdir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(helpdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-helpDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-helpDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-helpDATA \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+	uninstall-am uninstall-helpDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/help/help-Dutch.dat b/help/help-Dutch.dat
new file mode 100644
index 0000000..a858ac6
--- /dev/null
+++ b/help/help-Dutch.dat
@@ -0,0 +1,3099 @@
+HELP-INDEX>READ ME FIRST - License
+
+                          READ ME FIRST - License
+
+For the most current information please read the README file in the Xastir
+directory.  Also see the LICENSE and COPYING files for additional information.
+
+Remember this program is intended to be used by the HAM community, in the USA
+the FCC restricts you from transmitting over RF if you are not a licensed HAM.
+Users in countries outside the USA should seek their local government 
+restrictions. 
+
+LICENSE:
+
+XASTIR, Amateur Station Tracking and Information Reporting
+Copyright (C) 1999,2000 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
+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.
+
+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.
+
+More information on the program can be found at:
+
+ http://www.xastir.org
+ http://sourceforge.net/projects/xastir/
+ http://xastir.sourceforge.net
+
+There are some mailing lists available that are Xastir-specific.
+Please subscribe to one or both of them for the latest Xastir
+information.  See http://www.xastir.org to subscribe.
+
+For more information on the GNU License look at:
+http://www.gnu.org
+
+
+HELP-INDEX>Welcome! and Notes from the Authors
+
+                      Welcome! and Notes from the Authors
+
+XASTIR, or X-windows Amateur Station Tracking and Information Reporting.
+
+Xastir is an APRS(tm) program that is Open Source and free to use and 
+pass out to others. Currently this program is in development and should 
+not be seen as a finished product! Your help will be needed to make this
+a better program.  If you have programming skills and/or can write 
+documentation, your help may be needed! We have a lot of ideas but very 
+little time, so if you think you can add something to the effort let us
+know!
+
+
+
+APRS(tm) is a Trademark of Bob Bruninga, his home page is at
+"http://web.usna.navy.mil/~bruninga/aprs.html". A great deal of information
+on APRS(tm) can be found in the APRSdos documentation written by
+Bob Bruninga. An additional source of information is the APRS(tm)
+specification, available from http://www.tapr.org .
+
+HELP-INDEX>What's new in Xastir 2.0.1
+(Changes between 1.7 and 2.0.0 were never recorded here,this block
+describes a few of the changes from 1.9.8 to 2.0.0 that occured right
+before release of 2.0.0, but otherwise documents only changes from 2.0.0 
+to 2.0.1)
+
+Added tiling for OpenStreetMaps (2.0.0).
+Added "setlocale()" calls to assure we aren't confused by user 
+LANG variable settings.
+Improved speed of config file processing.
+Fixes for new One-Wire-Daemon protocol, allowing both old and 
+new to work with Xastir.
+Fixed segfaults that could happen when closing list dialogs.
+Fix OSM code to support 16-bit quanta in Graphics/ImageMagick.
+Fixed broken makefile that was ignoring DESTDIR.
+Fixed broken build so internal shapelib builds correctly when
+proj.4 is not installed.
+Add dbfawk files for several generations of new NWS shapefiles.
+Update get-NWSdata to pull current NWS shapefiles.
+Add start/stop files for Kenwood D72 and D710 radios.
+Added a script to convert GeoPDF files to usable GeoTIFF files.
+Make the command to set a TNC into CONVERSE mode a run-time
+configurable option in the TNC Interface Properties dialog.
+Add support for Australian Bureau of Metrology weather alerts.
+Fixes for Davis APRS Data Logger, Davis Meteo and LaCrosse 
+support so it gets rain totals correct.
+Allow "posit interval" in File->Configure->Timing to go all the
+way to zero, meaning "never send posits on a schedule."
+Add signal support so that Xastir will emit a posit when it 
+receives SIGUSR2.  Combined with zero "posit interval," this
+allows Xastir to emit a posit only when told to by an external
+script.
+Fixed error in logic for band-opening alerts (speech and audio
+alarms) so it does not incorrectly report third party traffic
+as a band opening.
+Add "Send Control-E to get GPS data?" to TNC interface 
+properties for the "Serial TNC w/ GPS on AUX port" interface
+type.  Defaults to enabled, which is correct for KPC-3+ TNCs,
+but should be turned off for any TNC that automatically
+streams GPS NMEA strings, such as Kenwood APRS radios.
+Update GPSMAN support to reflect changes in the gpsman command 
+line.
+Add a small delay between sending the converse-mode command
+and sending data for transmission, because KAM TNCs don't
+work if you send the data immediately.
+Fix a bug in the OSM tile download loop that could prevent
+further downloading of tiles if any one tile download fails.
+Fixed a thread-unsafeness bug that could cause Xastir to start
+using corrupted file names when multiple logging options
+(TNC, NET, WX, IGATE, etc.) selected simultaneously.
+Fixed get-fcc-rac.pl script to reflect changes in RAC download
+site.
+
+
+
+
+HELP-INDEX>What's new in Xastir 1.7
+Added REGRESSION_TESTS in order to test interoperability of the
+configure-time flags.
+Added a replacement for malloc() for those cases where the OS
+provides a faulty one.
+Added more to the summary.log file:  The tests and results from
+config.log.
+GDAL configure probe now uses gdal-config if it's in the user's
+path.
+Tweaked configure so that dependent libraries cause other library
+searches to fail, and to provide more user output.
+Added ASCII-art drawing to INSTALL showing most of the library
+dependencies.
+Updated symbols.dat to more closely correspond to the current spec.
+Implemented EMERGENCY BEACON transmit capability under the Help
+menu.
+Added decoding for "EMERGENCY" anywhere in the packet plus any of
+these in the TO: field:  ALARM, ALERT, WARNING, WXALARM, EM.  Any of
+these will invoke the normal emergency popup dialog.
+Waypoint symbols now have a line drawn between them and the station
+transmitting them, per the spec.
+Now using font metrics to determine size of font.  We use that to
+determine size of black rectangle to draw underneath.
+Fixed the Fetch Findu Trail function so that it matches what Findu
+can provide.
+Fixed track->shapefile function so that it works on Cygwin too.
+Added reset button to Change Debug Levels dialog.
+Enable WX Alerts menu item is now grey'ed out if Shapelib isn't
+installed.
+RINO Download timing slider is now visible but grey'ed out if gpsman
+isn't installed.
+Added a custom zoom option to the right-click zoom levels menu.
+Moved the center & zoom dialog to the map menu.
+Changed a memcpy() to an xastir_snprintf() function in alert.c to
+assure that a string is terminated.
+Free'ing some malloc'ed space for cases where hash inserts fail.
+Added probe for sighandler_t definition.
+Changed includes, added leak_detector.h.
+A few small changes here and there to get rid of compiler warnings.
+Freeing some malloc'ed space for the cases where hash inserts fail.
+Fixed initializers for awk_rule[].
+Changed hash add functions so that they do a delete first instead of
+replacing hash values.
+Moved some wx-alert related code to debug level 2.
+Changed leak detect interval from 5 minutes to 60 seconds.
+Fixed a big memory leak in draw_nice_string() function.
+Changed include files around so memory leak detection stuff is in
+leak_detection.h.
+Added new compiler flags and cleaned up the code to eliminate many
+warnings created.
+Fixed Incoming Data dialog code so that packets transmitted to local
+interfaces would appear there.
+TNC/NET toggles work for those now too.
+Fixed memory leak in font metrics code.
+Simplfied get_long()  and get_int() functions and callouts.
+Tweaks for sighandler_t and sigjmp_buf.
+Added a sign-on message for server connects.
+FCC/RAC lookup or Locate Now buttons don't destroy the dialog
+anymore.
+Fixing up strings.h includes.
+Added a new popup for EMERGENCY packets.
+Changed signal() with SIG_IGN to sigignore for some cases.
+Added a test for sigignore() to configure.ac.
+Changes to allow different versions of "gv" to be used.
+Moved "-lgdal" to end of link line to avoid conflict with other
+libraries.
+Added UDP server and client.
+Added more language strings for previously hard-coded values.
+Changed config file get_int and get_long functions to provide better
+output when config file entries are missing or out-of-range.
+We now allow gating to the internet and to RF for user-defined
+packets and telemetry packets.
+Changing to <CR><LF> for the TCP server signon message.
+Changing to timestamp per packet for log files, with long int
+seconds at the beginning.
+Added icon.
+Added support for -geometry command-line parameter.
+Added fast creation of standard SAR objects via mouse menu,
+including adding digits to the end of the object name if name would
+conflict with pre-existing objects.
+
+
+
+HELP-INDEX>What's new in Xastir 1.6
+Fix for DF lines having incorrect angles at times.
+Configurable display of layers for USGS topo maps.
+Better Map Feature Search:  Shows up to 50 matches, user selects
+which one to center map on.
+Configurable "relay" digipeater calls:  Up to 50 callsigns can be
+specified in the Xastir config file to use for relay digipeating.
+"WIDE1-1" is now the default.
+Added support for Web Map Service (WMS).
+Tweaked the GPGGA and GPRMC GPS sentence decoding.
+Added speed-ups for lat/long geotiff's.
+Added Aloha circle.
+Added new #defines in interface.h for specifying "conv" or 'k'
+command to TNC.
+Added new tnc-startup file for TAPR-2 style TNC's.
+Added transparency capability to WMS.
+Fixed digpeating code for "wide1-1,wide2-1" case.
+Fixed some compile errors that are seen on FC4 and OSX Tiger.
+Added new terraserver .geo file options.
+Changed Map Properties "fill" option to allow NO/YES/AUTO.
+Auto uses dbfawk if present, no/yes force fill to that state.
+Fixed some #ifdefs here and there so that compiles will work if
+some libraries aren't present.
+Added map caching for nearly all internet maps, plus two new toggles
+on the map menu for clearing out current-view maps or all maps from
+the cache.
+Moved Tigermap timeout slider to main timing dialog, renamed it, and
+made it function for ALL internet map fetches.
+Added timestamps to x_spider log messages.
+A fix for the emacs tempfile bug w.r.t. dbfawk files went in, but
+hasn't been verified to have fixed the problem yet.
+More bulletproofing added to the map_cache code.
+Fixed a compile problem that happens if ImageMagick isn't installed.
+Changed stipple style to solid for polygons drawn with dbfawk.
+Another fix so that linking works without map caching. 
+
+
+
+HELP-INDEX>What's new in Xastir 1.5
+Optional Rtree shapefile extent caching
+Optional berkelydb-based internet map caching
+Modifier keys fix
+Improvements to the message GUI
+Tactical call support re-written, hashtable based
+Warnings on crazy paths
+Hashtable weather alert speedups
+Dead-reconing for Objects/items
+Igate of specific stations (in the nws-stations.txt)
+Fixed DF object properties
+Measure function more accurate
+Decoding for "Position with Timestamp no APRS messaging" packets.
+More thorough checking for scanf/sscanf/fscanf function calls
+Fixing 100% humidity for some weather stations, plus added more data for Davis stations
+Changed active internet connection check from 1 min to 5 minutes
+Fixed decoding of compressed DF objects
+Fixes to allow new WHO-IS server to be used from Xastir
+Got rid of extra 0x00 byts between transmitted KISS frames
+Tweak to not start an interface upon changing its properties
+Tweaks to allow use of http proxy servers for online map accesses (.netrc file)
+
+
+
+HELP-INDEX>What's new in Xastir 1.4
+Comment fields for interfaces
+split_gnis and ozi2geo scripts, need to add to section on scripts
+serial mkiss interface
+move objects without confirm
+new timing params w.r.t. trails, need to add to config|timing part
+geo-coder (already in docs)
+exponential/random back-off for almost everything
+dbfawk default, memory leaks fixed
+click+drag zoom boxes
+tactical callsign support
+numerous small memory leaks, uninitialized data uses, and similar bugs fixed. 
+GPS quality info
+RINO waypoints downloading
+label trackpoints
+comment/status timestamps
+listener socket/ability to act like a limited internet server
+
+
+HELP-INDEX>Starting Xastir for the first time
+
+                    Starting Xastir for the first time
+
+When first running Xastir, you should start it from a terminal window so
+that any warning or error messages can be seen. On most systems a path is
+set up to run programs in /usr/local/bin and all you need to do is type
+"xastir &" at the prompt. On systems that do not have this path installed
+type "/usr/local/bin/xastir &" to start the program.  The '&' character
+will cause Xastir to start in the background, leaving the terminal window
+available for other uses.
+
+You may also set the language choice at this time. To set the language or
+change the current language choice, call Xastir with the option '-l':
+
+    xastir -lEnglish
+
+Language options are:
+    xastir -l Dutch
+    xastir -l English
+    xastir -l French
+    xastir -l German
+    xastir -l Italian
+    xastir -l Portuguese
+    xastir -l Spanish
+    xastir -l ElmerFudd
+    xastir -l MuppetsSwedishChef
+    xastir -l OldeEnglish
+    xastir -l PigLatin
+    xastir -l PirateEnglish
+
+The chosen language will be stored in your config file, so it is preserved
+for the next time you call Xastir.  For new installs Xastir will default to
+English until you change the language with this command line option.
+
+The menus on the top may be accessed with the mouse or with keyboard
+shortcuts. The keyboard shortcuts may not work correctly with num-lock on.
+
+You will need to configure interfaces in order to actually use Xastir.
+Interface configuration is detailed under the "Configuring Interfaces" help
+topic and its subtopics.
+
+If you are operating in a situation where a coordinate system other than the
+default DD MM.MMMM system would be helpful, you may select your preferred
+system by going to File|Configure|Coordinate system.  Any of the supported
+coordinate systems my be used as input by using the Coordinate Calculator.
+
+HELP-INDEX>Configure the Station Information
+
+                         Configure the Station Information
+
+Click on File, then Configure, then Station.
+
+Fill in your Amateur Station call sign.
+
+Fill in your station position if you are not using Xastir with a GPS 
+unit. You can locate your general position on the map with Xastir and
+use the position given by the cursor placement over the map. This
+position will be viewable in the box at the bottom of the Xastir screen
+2nd from the left, whenever the mouse is over the drawing area. You can also
+choose "Move My Station Here" from the right-click menu while your mouse is
+over your location. If you have a GPS you can skip this and set up the GPS
+later.
+
+"Send Compressed posits", if selected, will transmit in the newer compressed
+format. This format will reduce the amount of data on the air, thereby
+increasing the capacity of the APRS(tm) network. The maximum precision of the
+transmitted position is also higher. Some older programs, including recent
+versions of WinAPRS, do not decode this format yet. Findu.com might also have
+trouble with it.  We transmit course/speed in this format but not altitude.
+In order to send course/speed AND altitude requires adding nine characters to
+the packet which negates part of the reason to use compressed posits.
+
+To select a symbol to be used for your station you need to specify
+a group and a symbol character. You can manually fill in these fields,
+or press select to graphically choose a symbol. There are two groups
+of symbols available. A text description of each symbol can be found
+in the "symbol table" help topic.
+
+For some symbols of the secondary group you can specify an overlay.
+With that a symbol will be displayed together with an additional
+overlay character, e.g. a car symbol with the number 1 overlay-ed on
+top of the symbol.
+
+For using overlays you need to select a symbol from the secondary symbol
+table and enter the overlay character to be shown in the group/overlay
+field. Only numbers and uppercase characters are allowed as overlay
+characters. According to the APRS(tm) specification not every symbol can
+be overlay-ed, Xastir doesn't enforce this, but some other programs may.
+Note that not all of the symbols have been implemented in the graphics
+chooser yet, and some of them are not per the APRS(tm) spec yet.
+
+Next, enter the data for the power/height/gain of your station. This
+is useful information but is not required; simply select "Disable PHG"
+to disable it. These choices present a granular representation of your
+stations range. Select the combination of values closest to the
+description of your station.  Please use height above average
+terrain (HAAT) for the height value.  Do NOT use average height
+above sea level or height above ground.  All values must be
+specified if you wish to transmit PHG information.
+
+Another option would be to specify the RNG in the comment field in miles
+instead of using PHG. See the APRS(tm) spec for details.
+    
+For Gain use the gain of your antenna in dBi. 
+(FIXME: dBd? spec is unclear, I think it's implying dBi because it says "in
+absence of any data, stations are assumed to be running 10w to a 3dB omni at
+20ft. A typical omni is only 3dBi.....) 
+
+Note: The gain setting is really intended for vertical antennas; the gain
+setting for a beam should be quite a bit below the forward gain of the beam.
+This is because with directivity set, the PHG circle is only offset by 1/3rd
+of its size toward the specified direction. Setting gain higher will enlarge
+the whole circle unrealistically, rather than increasing the directivity.
+There was talk several years ago about amending the specifications to better
+deal with beam antennas, but nothing was changed.
+
+Enter a comment, not required but it will add insight on your station.
+A common thing to enter here is your preferred e-mail address.  It will
+be transmitted along with your posits.
+
+Position ambiguity will allow you control how accurately you transmit your
+position. A setting of none will allow your station to transmit the exact
+position you have entered or received from a GPS. The other choices will
+place you somewhere in the range of the choice you selected.  Note that
+this may throw some non-spec compliant stations for a loop.  Findu.com
+doesn't understand position ambiguity.
+
+Clicking OK will save your changes, Clicking on Cancel will keep the
+previous settings.
+
+HELP-INDEX>Configure Default Operation
+
+                        Configure Default Operation
+
+Click on File, then Configure, then Defaults.
+
+This page sets up some standard defaults for the program operation. 
+
+Transmit Station Option sets the type of packet your station will transmit 
+its data as.
+
+IGate Options will set your station up as an Internet-RF gateway. This option
+should be used with caution; As a ham you are responsible for the data that
+comes in via the Internet and is transmitted via RF. You also will need to
+choose an IGate option on each interface in order for the IGate to function.
+If you want to have your IGate forward NWS weather alerts to RF, you must
+create a ~/.xastir/data/nws-stations.txt file listing each call or NWS station
+(like "PHISVR") that you would like to transmit via RF.  This feature also
+works for gating specific callsigns to RF.  Bob Bruninga, WB4APR, recommends
+gating these calls to RF: SCOUTS, SATERN, KIDS, REDCROSS, FOUR-H, YOUTH, GUARD,
+MARS, JOTA.  See his link: "Generic Callsigns for National Events" off this web
+page for his current list of recommended callsigns:
+
+        http://www.ew.usna.edu/~bruninga/aprs.html
+                     
+"Transmit Compressed objects/items?", if selected, will transmit objects and
+items in the newer compressed format. The maximum precision of the transmitted
+position is higher, and the transmission is shorter, but some older programs do
+not decode this format yet.  Currently this only compresses "standard"
+objects/items with an optional speed/course.  It won't compress area, signpost,
+or DF objects/items, and won't currently represent altitude in "standard"
+objects/items.
+
+"Pop up new Bulletins", if selected, will cause Xastir to bring up the bulletin
+dialog when bulletins within the configured range are received. "View 
+zero-distance bulletins" will cause bulletins with no known location not to
+be displayed or cause pop-ups.
+
+"Warn if Modifier keys" will cause Xastir to print a warning if you attempt to
+use Xastir while num-lock, scroll-lock, or caps-lock is engaged. Some users
+report the screen blanking on them and similar problems when they attempt to
+use Xastir with one of these modifier keys on.
+
+You can also select "Activate alternate net?" and choose an altnet call from
+this dialog. Altnet allows you to have a private APRS(tm) network among the
+stations that also have altnet configured, and have the same altnet call
+entered.
+
+"Disable Posit Dupe-Checks" disables the check for duplicate copies of a
+position. This should only be used when a station might return to exactly the
+same position (within 60' or so for non-compressed positions) and you wish to
+see the duplicate positions and/or tracks displayed on the map.  This option
+is almost never needed in practice, but can be useful for special events like
+search and rescue operations.
+
+"My Trails in one color" shows all trails with your callsign but different 
+ssids in the same color.  With My trails in one color selected, mycall-1 
+and mycall-2 are shown in the same color.  With My trails in one color
+unchecked, mycall-1 and mycall-2 are shown in different colors.  
+
+"Load predefined objects from file" and the pick list which follows it allows 
+you to replace the list of Predefined objects that are accessible from the 
+right click pop-up menu with your own list of objects.  A set of standard
+Search and Rescue objects and a set of typical public event objects are 
+supplied in the predefined_SAR.sys and predefined_EVENT.sys files.  You may
+also use these files as a template to create a predefined_USER.sys file.  
+See the instructions in the predefined_SAR.sys and predefined_EVENT.sys file
+for details on how to define objects for a custom predefined objects menu.
+If both "Load predefined objects from file" is selected and a file that 
+exists in the xastir/config/ directory is selected, then the objects defined
+in that file will be shown on the Predefined objects menu.  The unaltered
+predefined_SAR.sys file defines the same objects as the default menu.   
+
+
+HELP-INDEX>Configure Timing
+
+                            Configure Timing
+
+Click on File, then Configure, then Timing.
+
+Posit TX Interval specifies how often your station's position will be
+transmitted.  For fixed stations a good recommendation is every 30 minutes,
+and definitely no less than 10 minutes.  Mobile stations may wish to use a
+faster rate.  Note that if you're using SmartBeaconing, this slider is
+ignored.
+
+Object/Item Max TX Interval is the maximum interval used for sending out
+objects and items. Try to keep these intervals reasonable, as transmitting
+to a long path every 5 minutes will really take up a lot of the air time.
+A decaying interval algorithm is triggered any time an object is created,
+modified, or killed.  The transmit interval will increase until it hits the
+max interval indicated by the slider.
+
+GPS Check Interval will set the interval of time to look at the GPS for new
+data. This is available for stations using an HSP or shared cable with their
+TNC.
+
+Dead-Reckoning Timeout adjusts how long a position is assumed valid for the
+purpose of estimating its current position.
+
+New Track Time adjusts how many minutes must elapse before a new
+separate track is started.  Caution: setting the new track time to 0 will turn
+off the display of all tracks.
+
+RINO -> Objects Interval adjusts how often waypoints are downloaded from an
+attached Garmin RINO radio/GPS unit.  APRS(tm) Objects are created out of any
+waypoints beginning with "APRS".  The "APRS" prefix is removed when creating
+the Object names.
+
+Station Ghosting Time specifies the ghosting interval. Stations that have not
+been heard in the given period will appear ghosted on screen.
+
+Station Clear Time specifies when a station will be removed from the screen.
+
+Station Delete Time specifies the number of full days before data from a
+station will be entirely removed from the Xastir database.
+
+Serial Inter-Char Delay specifies a wait time in milliseconds between each
+character sent to an attached TNC.
+
+New Track Interval (degrees) specifies distance in lat/long degrees at which
+a new track segment is started.   Caution: setting new track interval to 0
+degreees will turn off the display of all tracks.
+
+Snapshot Interval (minutes) specifies how often snapshot files will be
+written if either File->PNG Snapshots or File->KML Snapshots are selected.
+
+HELP-INDEX>Configure Audio Alarms
+
+                           Configure Audio Alarms
+
+Click on File, then Configure, then Audio Alarms.
+
+To use this option you must have a sound card and a program that will play
+wav files. The Audio Play Command should contain the program you want to
+execute to play the audio file (and any command line options). That of
+course doesn't work if the only sound card in the system is used for a
+soundmodem...
+
+Each type of alert has a check-box to enable it. The fields will contain the
+name of the file to play. Fields under the option will set parameters for the
+option.
+
+The current choices are:
+Play message on hearing a new station.
+Play message on receiving a new message.
+Play message on receiving data from a station within the min/max distance of
+     your proximity settings. 
+Play message on receiving data from a station (via TNC) within the min/max
+     distance of your band opening settings.
+Play message on receiving and displaying a new weather alert.
+
+There is a standard set of sounds available most places where Xastir can be
+obtained, please see the file INSTALL for more information.
+
+HELP-INDEX>Configure Speech
+
+                       Configure Speech Synthesis
+
+To use this option you must have a sound card and the 'festival' speech
+synthesis software installed.  Install Festival and start it in 'server' 
+mode prior to starting up XASTIR.  The normal command for this is 
+"festival_server &".  If you use the "festival --server" option instead (old
+method), you may run into problems with connections getting rejected by the
+server.
+
+Once you have festival installed, Xastir will have the ability to speak using
+the following choices:
+
+New Station       - Announce the call of a new station.
+New Message Alert - Announce the arrival of a new message.
+New Message Body  - Speak the contents of a message.
+Proximity Alert   - Announce when receiving data from a station within the
+    min.max distance of your proximity settings.  This option uses the 
+    proximity settings found in the Audio Alarms menu.
+Tracked station Proximity Alert - Announce when receiving data from a
+    station within the min.max distance of the tracked station. This option
+    uses the proximity settings found in the Audio Alarms menu.
+Band Opening      - Announce when receiving data from a station (via TNC) 
+    within the min/max distance of your band opening settings.  This option 
+    uses the distance settings found in the Audio Alarms menu.
+New Weather Alert - Not implemented yet.
+
+Info on Festival may be obtained from: http://www.speech.cs.cmu.edu/festival/
+
+HELP-INDEX>Configure Smart Beaconing
+
+Click File, then Configure, then Smart Beaconing.
+
+The main "Enable SmartBeaconing(tm)" Will cause Xastir to transmit positions at
+various rates and locations based on the movement of the station. It creates
+more realistic trails and makes dead-reckoning much more accurate. This option
+is only useful in a mobile station with a GPS attached.
+
+There are several options available to customize the operation of
+SmartBeaconing:
+
+High rate
+The interval (in seconds) at which beacons are sent when the speed is above the
+High speed setting.  This parameter is also used to compute a beacon rate based
+on speed when traveling between the high and low speeds.
+
+High speed
+The speed threshold that will cause beacons at the rate specified above.
+
+Low rate
+The interval (in minutes) at which beacons are sent when the speed is below the
+Low speed setting.  Basically consider this to be the stopped beacon rate.
+This parameter is not used at all when traveling at a rate of speed higher than
+"Low speed".
+
+Low speed
+The speed threshold that will cause beacons at the rate specified above.
+
+Minimum Turn
+The minimum degrees that corner pegging can occur at "High speed" or above.
+Lower speeds will require more degrees of turn to trigger a posit, based on
+the value of "Turn Slope" below.
+
+Turn Slope
+Fudge factor for making turns less sensitive at lower speeds.  The parameter
+doesn't have any units. It ends up being non-linear over the speed range the
+way the original SmartBeaconing(tm) algorithm works.
+
+Wait Time
+The time in seconds between corner-pegging beacons, prevents multiple
+beacons in short succession.
+
+HELP-INDEX>Configure Units of Measure
+
+                        Configure Units of Measure
+
+The default selection is for the Metric System: mm, cm, km/h, etc. To select
+English units, inches, feet, MPH, etc. Click on File, then Configure, then
+toggle the "Enable English Units" check-box.
+
+HELP-INDEX>Save Config Now!
+
+                        Save Config Now!
+
+This button will save all of the current configuration to the config file.
+Note that when Xastir is closed, it also saves configuration to the config
+file.
+
+HELP-INDEX>Bottom Status Bar
+
+                         Bottom Status Bar
+
+At the bottom of the window various status messages are available:
+
+In the first box on the left general status messages are displayed for a
+short time.
+
+The second box displays the current lat/long or UTM, and Maidenhead grid
+square position of the mouse over the map. If file|configure|Dist/Bearing
+Status is selected, this box will also contain the course and bearing of
+this position relative to your station.
+
+A third box is used to display how many stations are on screen, and how many
+are in the database.
+
+The fourth box will display the current zoom level and will display "Tr" if
+the station tracking is on.  At some zoom levels the Tr is not
+displayed properly due to the size of the box. 
+
+The fifth box indicates whether logging is enabled.
+
+The last area will display the device status for each interface. Each will
+display in order first to last or 0 to 9. The interface status is separated
+into three areas, top device type, center data flow, and bottom interface
+operational status.
+
+The device type will show what interfaces are configured. The color will
+show what type of device the interface is configured for. Blues are for
+the various TNC devices; Greens will show the GPS devices; Yellow for
+Internet Servers; Orange for WX interfaces.
+
+The center will show data flow in (arrow pointing left) or data flow out
+(arrow pointing right) for that interface.
+
+A green box at the bottom will show if that interface is active. A red
+box will show if the interface is active but in an error condition.
+Otherwise nothing will show if the interface is not active.
+
+HELP-INDEX>Moving the Map and the Options Menu
+
+                    Moving the Map and the Options Menu
+
+Map movement is very simple, ease and quickness of movement is dependent on
+your processor speed and the amount of detail you load. Hint: You can
+disable all maps in the maps menu in order to move around quickly, then
+enable maps again.
+
+Zooming:
+Zooming can be accomplished by right clicking on the map (and holding the 
+button down). This will bring up an options menu, with choices to zoom in or
+out a single level, or to change to one of the preset zoom levels.
+
+All zooming functions from the options menu will zoom in or out at the point
+on the map where you clicked the right mouse button. Zoom levels have a cascade
+menu. Levels 1-64 are for very local areas and levels 256 and above are for
+large areas. The lower number the level, the more local the area.
+
+A quicker zoom in function is to push and hold the left mouse button, drag it
+across the area of interest and let go.  The map will zoom to approximately
+the size of the square you just described with the mouse drag operation. The
+"move" and "measure" toolbar check-boxes must be disabled for this feature to
+work. Clicking the middle button zooms out with a factor of 2, centering
+where you clicked as well.
+
+The map can also be zoomed with the keyboard Page-Up/Page-Down keys, or the "In"
+and "Out" buttons in the toolbar. The zooming in this case keeps the same map
+center (no centering).
+
+Panning/Centering:
+The map can be centered at a specific location by choosing center in the
+right-click options menu.
+
+Panning is also accomplished by using the options menu, or by using the arrow
+buttons on the toolbar. The map position will shift a portion of a screen.
+Enough data from the previous screen should be available to re-orient yourself.
+
+The map can also be panned with the keyboard arrow keys.
+
+More About Options Menu:
+
+Map Display Bookmarks
+See the help topic "Creating and using Map Display Bookmarks"
+
+The "Station Info" selection on the options menu will look for the station
+closest to where you right-clicked the mouse. If more than one station is
+close to that position a "Station chooser" list will appear, then you can
+choose what station's data you want to look at. If only one station is close
+to the mouse pointer then that station's data will display immediately. For
+mobile stations with a lot of track data this could need some time on slow
+computers. Note that expired stations still have their data stored in the
+Xastir database, and if one knows a station's former location, one can still
+view its info in this manner. Use the "Display Expired Data" option
+to display some data that disappears for ghosted stations, like
+speed/altitude, etc.
+
+With "Last Pos/Zoom" you can restore the previous map view by restoring the
+previous values of the map zoom and centering values.
+
+For Object and Item information, please see the help topic "Objects and Items"
+
+Draw CAD objects lets you create polygons on screen, for tactical or
+presentation use. This feature is still under construction.
+
+"Move my Station here" Allows you to move your station to a specified map
+location without editing the station configuration.
+
+HELP-INDEX>Objects and Items
+
+A station could place several different objects on the map, with their
+position transmitted to other stations. The object names are less restrictive
+than the normal station names.
+
+Objects and items are nearly the same things, but their use could differ a bit.
+Objects are generally used for moving or variable things such as thunderstorms,
+while items are generally used for more inanimate things, such as water
+stations. Because items may not be decoded by some flavors of APRS(tm)
+programs, objects are often used for inanimate things, too.
+
+Besides normal objects with a symbol at its position there are some special
+objects available. Area objects are useful for a variety of operations in
+which you want to draw or highlight an area of interest on the map. They can
+also be used to draw trails/roads/boundaries, watch boxes for severe weather,
+runways, perimeter of a search area or of a public service event, areas of
+damage, areas to stay out of, buildings that aren't on the map, checker/chess
+boards for gaming on APRS(tm). :-)  Note that area objects are not
+implemented on all versions of APRS(tm) programs, and some of the details of
+how they are displayed may also be different on other programs.
+For the other three, probability circles, signposts and DF objects, see below.
+
+Objects/Items are retransmitted at a decaying rate up to the max interval
+specified in File|Configure|Timings.  "killed" objects/items are also
+retransmitted in this manner until they expire from the queue (currently 20
+transmits).  Objects/Items are persistent across Xastir sessions, and are
+stored in ~/.xastir/config/object.log. This file may be cleared by selecting
+"Clear Object/Item history" from the Stations menu.
+
+The Object/Item creation option in the right click menu will bring up a dialog
+with the position of your object filled in based on where you clicked the
+mouse. You may fill in the details, and add an object/item from this menu.
+
+The Object/Item modification option brings you the object modification dialog.
+It is similar to the object creation dialog, except the object's current
+information is already filled out, and the object's name and a few of the
+other options can't be changed. You could also delete the object with this
+option.
+
+Objects and items can be moved with the mouse if the "Move" check-box on the
+toolbar is enabled.  
+
+The Predefined Objects option in the right click menu allows you to rapidly
+place standard Search and Rescue objects without having to go through the 
+Object/Item creation dialog.  These objects include standard Incident 
+Command System symbols for ICP, Staging, Base, and Helibase, as well as
+SAR objects for PLS, IPP (with 4 area circles), and LKP If an object of the 
+same name as an object you select off the list allready exists, a new 
+object will be created with a number appended to the end.  For example, 
+the first time you select Staging from the Predefined objects menu, an
+object named Staging will be created.  If you then create an additional 
+Staging object from the Predefined objects menu, it will be named Staging2. 
+Heli- (and user defined objects ending in a "-") will be created as Heli-1,
+Heli-2, Heli-3, etc.  If you have recieved one of these standard objects that 
+was transmitted by another station, your first object will be named with an 
+appended number.  You may wish to assign a tactical call to your object in 
+this situation (for example, replacing ICP2 with a tactical call).  
+
+The Predefined Objects menu is customizable by modifying the files 
+predefined_SAR.sys, predefined_EVENT.sys, and predefined_USER.sys, and then
+selecting one these files through the File/Configuration/Defaults dialog. 
+See the predefined_SAR.sys file for details.  
+
+Description of the entries in the object dialogue:
+
+= Signpost =
+This makes the object a signpost object. These signs can contain one
+to three characters, and currently appear in Xastir as a blank sign.
+Station Info shows the value contained on the sign.
+
+= Area Object =
+This makes the object an area object, and enables the area object controls
+described below.
+
+= DF Object =
+This is a direction-finding report. Enabling it allows you to choose Omni or
+Beam report, and allows you to put in the specifics for each.  See:
+    http://web.usna.navy.mil/~bruninga/dfing.html
+and the APRSdos documentation for details on these useful techniques.
+(FIXME: Separate section on DF'ing techniques?)
+
+= Probability Circles =
+This allows you to define the radius (in miles) of two circles centered on 
+the object or item.  Min is the radius (in miles) of the smaller, inner 
+circle, and Max is the radius (in miles) of the larger, outer circle.  
+These circles are drawn in red.  They can be used to assist in planning 
+Search and Rescue operations.  To create more than two circles, add additional
+probability circle objects to the same location.  Probability circles may not
+be displayed by other client software.
+
+= Name =
+This is the name of the object or item. It may be up to 9 characters long,
+with spaces allowed inside the name. When modifying an object, this may not
+be changed. To rename an object you must delete the original and then create
+a new object. Note that if you select Signpost/Area Object/DF Object that
+this field and perhaps others are cleared. Enter the name AFTER you've
+selected the type of object it will become.
+
+= Station Symbol =
+You may select a symbol for the object. Press select to choose graphically,
+or see the symbol table help section for descriptions of each symbol.  Note
+also that area objects, signpost objects, and DF objects have special fixed
+symbols and therefore can't be selected here.  Those particular symbols get
+automatically assigned when you change to that type of object.
+
+= Location =
+The location of the object is specified here. If you selected "Create 
+Object/Item" from the right-click menu, the location you clicked will be filled
+in. If you moved an object with the mouse, the new location will be in these
+fields.  You can also type in a location, for instance you may be placing an
+object from an over-the-air voice report.
+
+= Generic Options =
+You may specify the speed, direction, and altitude of objects here. Some object
+types cannot have a speed or direction, in which case the fields are grayed
+out.
+
+= Signpost Text =
+If the object is a signpost object, you may specify the 1 to 3 digit
+number that appears on the sign here.  Note that Xastir doesn't display
+signpost objects properly yet.
+
+= Area Object =
+Area Objects are used to highlight specific parts of maps, or to draw extra
+detail onto maps. This will be done with the following entries:
+  = Bright Color =
+    Use the brighter version of the colors allowed.
+  = Color-Fill =
+    The area should be filled, not just outlined. This may be useful to
+    exclude an area from a search or other event.
+  = Object Type =
+    Choose from the geometric shapes allowed.
+  = Object Color =
+    Choose the color in which the object will display. This is also affected
+    by the "Bright Color" option above.
+  = Object Offset Up =
+    In hundredth of a degree latitude.  An unfortunate detail of the spec,
+    and hard to calculate easily.  Suffice it to say that you can change
+    the size of the object once you place it.
+  = Object Offset Left except / =
+    In hundredth of a degree longitude.  See above.
+  = Object corridor =
+    This is the width of a line area object. Useful for runways, weather
+    watch boxes, describing an area of interest or an area of exclusion, etc.
+
+Always delete your objects and items when you are done with them!
+Don't just allow them to expire from your cache, as they may hang
+around on other peoples' screens for an extended period.
+
+
+Description of weather watch boxes:
+
+Watch boxes and "areas of maximum concern" (AOMC) generated by the WXSVR
+(http://wxsvr.net/) are colored as follows:
+
+  Yellow dashed = Severe Thunderstorm Watch  (looks like crime scene tape)
+   Yellow solid = AOMC for Severe Thunderstorm Warning
+     Red dashed = Tornado Watch
+      Red solid = AOMC for Tornado Warning.
+   Green dashed = Mesoscale (larger) discussion area
+    Blue dashed = Test Watch
+     Blue solid = Test Warning
+
+HELP-INDEX>CAD Objects
+
+                     CAD Objects
+
+[CAD object support has moved from the right click menu to 
+Map/Draw CAD Objects]. 
+
+CAD object support is preliminary at this time.  Features and the user 
+interface are subject to change.  
+ 
+CAD objects are arbitrary shapes that you can draw on maps in xastir, but 
+can't transmit by APRS.  
+
+Currently supported CAD objects are:
+Polygons: Closed areas of at least three points.  
+
+To create a CAD object, first press the Draw radio button on the toolbar.
+This will change the cursor to a pencil.  Begin drawing a polygon by 
+clicking with the middle mouse button (or both buttons on a two button mouse,
+for which you will need to have three button mouse emulation enabled).  This 
+places a point on the map.  Now move the cursor somewhere else (the normal
+left click/right click navigation and zoom functions still work normaly) and
+click the middle mouse button again.  This draws a line between the two points
+you have selected.  Middle click again to draw another line segment and keep 
+repeating until you have drawn all except for the closing line segment of your
+polygon.  To close the polygon, select Map/Draw
+CAD Objects/Close Polygon.  This will close your polygon and bring up a dialog
+that will allow you to enter a name, comment, and probability for the polygon.
+
+When you have finished drawing CAD objects, exit the CAD drawing mode by 
+deselecting the Draw radio button on the toolbar.
+
+CAD objects can be edited from the View/CAD Polygons menu and from the 
+Map/Draw CAD Objects/CAD Polygons menu.  CAD objects can be  deleted from the 
+Map/Draw CAD Objects/Erase CAD Polygons menu.
+
+HELP-INDEX>View Menu
+
+                     View Menu Options
+
+The View menu presents various ways to look at data in Xastir.
+
+Bulletins
+This is the APRS(tm) bulletin board, where important announcements are posted.
+If you are connected with the internet interface, it is a good idea to set the
+range field to a few hundred miles, to ignore posts from other portions of the
+world. "0" in the range field means the entire world. Click the "Change range"
+button to make changes to this field effective. Xastir currently does not
+support sending bulletins. Incoming bulletins will open this dialog
+automatically if you select "pop up new bulletins" in the Configure|Defaults
+dialog.  The "View zero-distance bulletins" button enables viewing bulletins
+for which you don't have a range yet (they haven't sent a posit yet, but you
+received a bulletin from them).  If this is unchecked, you must get a position
+from a station, and the station must be within the range selected (or range
+must be set to zero), in order for the bulletin to be viewed.
+ 
+Incoming packet data
+This displays the incoming data on your TNC or internet interface. The radio
+buttons below select if you want to see only TNC data, only internet data, or
+both.
+
+Mobile Stations
+This is a list of stations that are moving. Stations qualify for this list if
+they have moved (more than one position received for them), the symbol of the
+station is not considered. Information shown includes course, speed, altitude,
+position, number of packets received, number of visible GPS satellites, course
+from your station, and distance from your station. 
+
+All Stations
+This option displays a table of all stations sorted alphabetically. It includes
+the number of packets heard, the time the station was last heard, the path that
+the most recent packet took, the PHG, and the comment of the station.
+
+Local stations
+This option displays only stations that are heard via your TNC. It includes
+the number of packets heard, the time the station was last heard, the path that
+the most recent packet took, the PHG, and the comment of the station.
+
+Last Stations
+This option displays a table of all stations sorted from most recently heard
+to least recently heard. It includes the number of packets heard, the time
+the station was last heard, the path that the most recent packet took, the PHG,
+and the comment of the station.
+
+Objects & Items
+This option displays only objects and items. It includes the number of packets
+heard, the time the objects/item was last heard, the path that the most recent
+packet took, the PHG, and the comment of the object/item.
+
+Own Objects & Items
+This option displays only objects and items that you control (i.e.: Have sent
+the most recent update for). It includes the number of packets heard, the time
+the objects/item was last heard, the path that the most recent packet took, the
+PHG, and the comment of the object/item. A ghosted icon indicates that the
+object has been deleted.
+
+Weather Stations
+This option displays a table of all the APRS(tm) weather stations and their
+data. Data includes wind course, wind speed, wind gust speed, temperature,
+humidity, barometric pressure, rain in the past hour, rain since midnight,
+and rain in the last 24 hours.
+
+Own weather data
+Displays your weather data if you have a weather station and have configured
+Xastir to access it.
+
+Weather Alerts
+Displays weather alerts received, including the alert flags, alert source/type,
+alert destination, expiration, message, and effected location. This data
+is used for the alert highlighting. Double-clicking on an alert will request
+further information about it via finger from the online WXSVR. This only
+works if you have internet access; future versions may access this data over
+radio as well.
+
+Message Traffic
+Shows all message traffic while the window is open. It includes the source,
+destination, interface, and message. The range option can limit this display
+to nearby stations, much like the range control on bulletins. A range of 0
+causes all messages to be displayed.
+
+GPS Status
+Shows the status of your GPS unit, including the type of fix and number of
+satellites acquired.
+
+Uptime
+Shows the amount of time elapsed since Xastir was started.
+
+HELP-INDEX>Map Menu and the Map Chooser
+
+                       Map Menu and the Map Chooser
+
+Map Menu:
+
+Map Chooser
+This will present you with a list of map directories and/or files in your
+map directory. Checking the "Expand Dirs" option toggles the expansion of
+directories into individual map files. The properties dialog allows more
+advanced controls, and is described below. Click on map names to highlight
+them, this will cause them to be displayed when you click the OK button. You
+may select any number of maps. Clicking "Clear" will select no maps,
+clicking "Vector" will select only vector maps. The three "topo" options will
+automatically select all GeoTIFF images of the listed size. Clicking the OK
+button will display the selected maps. Cancel will abandon any changes.
+
+  Map Chooser Properties
+  Clicking the Properties button will bring up a dialog where you can specify
+  the layer in which maps appear, and in which zoom levels they appear. Higher
+  layer numbers are displayed on top of lower numbers. The range may be
+  specified from -99999 to 99999; it is suggested that you space your layering
+  numbers widely to allow later insertion of additional map layers. From this
+  dialog you may specify whether a vector map is drawn with color fills. This
+  is a per-map setting; the global disable option on the Maps menu can override
+  this. The Filled setting is ignored for raster maps (images). A setting of
+  "auto" allows a dbfawk file to control this parameter directly (usable only
+  if dbfawk is compiled in and the map in question is a Shapefile). You can
+  also select whether a map is considered by the "Auto maps" feature here.
+  Finally, you can specify the minimum and maximum zoom levels at which a map
+  is displayed. This is useful to prevent very detailed local maps from loading
+  at very wide zoom positions, and visa-versa. A minimum zoom of 10 means a map
+  will be displayed at all zooms including and above 10. Likewise, a maximum
+  zoom of 256 means a map will be displayed at all zooms below and including
+  256.
+
+Map Display Bookmarks
+See the help topic "Creating and using Map Display Bookmarks"
+
+Locate Map Feature
+This option brings up a search dialog where you can search through the labels
+in a GNIS file to find a specific location.  It will center the map on the
+new location if it is found. The "GNIS File:" entry is saved between calls
+and between invocations of Xastir.  You must put GNIS files into the
+xastir/GNIS directory in order to use this feature.
+
+Find Address 
+This option brings up a search dialog where you can enter an address. It will 
+center on the map if the address is found. The path to the geo-coder file is 
+saved between calls. 
+
+Coordinate Calc
+This option opens a simple calculator that can convert between coordinate
+systems. This is useful for converting positions to the various formats used
+by different groups of people. This same calculator can be called up by the
+Calc button on some of the other dialogs. It's useful for entering coordinates
+in other formats.
+
+Configure menu:
+  Background color
+  This option controls the color of the background behind the maps you have
+  displayed. The background color is often entirely hidden by filled maps
+  (see below).
+
+  Map Intensity
+  This controls the brightness of any graphics used as maps. This option only
+  appears if you have compiled with GeoTIFF support.
+
+  Adjust Gamma Correction
+  This allows you to apply gamma connection to all loaded map graphics. Maps
+  can be adjusted individually in their .geo files, see the section on .geos in
+  "Map files and WX Counties". This option only appears if you've compiled with
+  ImageMagick support, and does not apply to geoTIFF maps; see the above
+  option.
+
+  Map labels font
+  This allows you to set the font style and size used for map labels.
+
+  Station Text Style
+  Controls which font and style to use for station text and others.
+
+  Icon Outline Style
+  This allows you to specify an outline that surrounds station icons. This
+  helps improve visibility on various backgrounds.
+
+  Configure Tigermap
+  Turning this option on causes Xastir to download the map from the US census
+  bureau's online tiger mapping server. The dialog that comes up allows one to
+  select which layers are displayed, as well as the brightness of the resulting
+  map. This is only available if you have compiled with ImageMagick support.
+  Tigermaps are always loaded as the bottom layer; they do not have layering
+  settings in the Map Chooser.
+
+Disable All Maps
+This option disables the loading of any maps. It is most useful when doing
+rapid zooming or panning, because it saves the need to load the maps on each
+redraw.  Note that this option is not saved between sessions.
+
+Enable Auto Maps
+When enabled, any map found in the map directory (or any directory under it)
+will be displayed if it falls within the current display region. You can add
+any number of directory levels under the main map directory for your maps. Auto
+maps will go through any that have Auto Maps enabled (in the Map Chooser
+Properties dialog) check them all and find what map (or part) should be
+displayed.  All Maps will be merged into the viewing area. If you have a large
+quantity of maps, very detailed maps or a slower computer this can be quite
+slow. When this option is off, maps selected with the Map Chooser and/or Tiger
+Maps dialog will be displayed.
+
+Auto Maps - disable Raster maps
+This option prevents Auto Maps from loading maps which are graphics (images).
+Only vector maps will be displayed in this case.
+
+Enable Map Grid
+When enabled, this option will display a grid on the map.   If the coordinate
+system is UTM a UTM grid will be displayed.  If the coordinate system is 
+latitude/longitude then a latitude and longitude grid will be displayed.  As you
+zoom in the grid switches to a finer resolution.  The spacing of the latitude 
+and longitude grid may be manually adjusted with the "+" and "-" keys.
+
+Enable Map Border
+When both Enable Map Grid and Enable Map Border are enabled, a narrow white 
+border is drawn around the map and the grid lines are labeled using the 
+selected coordinate system (File/Configure/Coordinate System), and the selected
+border font (Map/Configure/Map Labels font/Border Font).   If the UTM or MGRS 
+coordinate systems are selected, the grid lines will be labeled with easting
+and northing values only at zoom levels smaller than about 2048.  
+
+Enable Map Levels
+When enabled, this option will try to filter out data when the zoom level
+shows large areas. This does not work will all maps but will work with the
+maps generated from Tiger Line maps at the aprs.rutgers.edu site, and with
+ESRI Shapefile maps. This does not decrease the loading times of the maps very
+much, rather it simply reduces screen clutter.
+
+Enable Map Labels
+This option toggles the display of map labels embedded in DosAPRS, WinAPRS,
+GNIS, and ESRI Shapefile format maps.
+
+Enable Area Color Fills
+This option controls the filling of vector maps. In certain cases, you
+may want to eliminate the fill to see maps below the top maps. This is a global
+control, maps may individually have color fill toggled in the properties dialog
+of the Map Chooser.
+
+Enable Weather Alert Counties
+This toggles the display of county warning area maps for severe weather.
+These maps can be obtained and installed according to the directions in the
+README.MAPS file. They are displayed on screen when special weather alert
+messages are received, and expire after a time or can be remotely canceled.
+The weather alert text can be seen under View|Weather Alerts. The
+xastir/Counties directory must be populated with the correct files from NOAA
+and Shapelib support must be compiled into Xastir in order to enable this
+functionality.
+
+Index New Maps on Startup
+This option controls if the map index file is built on startup. Most users
+should leave this enabled. If the timestamp of the map file is newer than
+the map index file, the map will be indexed.
+
+Index: Add New Maps
+This option adds any new maps to the max index.  Same rules as the above
+Index New Maps feature, but a manual method of invoking it.
+
+Index: Reindex ALL Maps
+This option starts over from scratch, indexing every map it recognizes in the
+maps directory. This is useful if the Add New Maps function is skipping some
+maps, perhaps because of old timestamps on the map files.  This function may
+take quite a while to complete if you have a lot of maps.
+
+Mouse pointer menu
+This option brings up the options menu normally available by right clicking.
+
+One note on maps:  Many of the currently available vector maps for the
+U.S. were created in NAD 1927 datum, while Xastir and other APRS(tm) programs
+use WGS 1984 datum.  If zoomed in to a small area on the map the datum
+shift may be very noticeable.  The USGS topographic maps have their datum
+corrected by Xastir as they are displayed, so positions will generally
+be more accurate with those topographic maps.
+
+HELP-INDEX>Map files and WX Counties
+
+                         Map files and WX Counties
+
+Map Types
+Xastir will work with various types of map files. All DosAPRS, Windows/Mac
+APRS(tm) map files are supported, as well as PocketAPRS format maps and GNIS
+(Geographic Names Information System) label files.  Xastir also can be
+compiled to use external libraries to support XPixmap (XPM) images, GeoTIFF
+topographic maps, and ESRI Shapefile maps.  The graphics handling capability
+of Xastir can be greatly extended by compiling with ImageMagick support,
+enabling support for many graphic formats as maps (see
+"http://www.imagemagick.org/www/formats.html").  Xastir supports weather
+alert maps in ESRI Shapefile format, available from NOAA.
+
+Details of locations to obtain many of the above types of maps are found in
+the file README.MAPS
+
+Map Locations
+Any map file should be stored in the /usr/local/share/xastir/maps directory
+on your computer. This location may be different on some systems, depending on
+how Xastir was compiled/installed. You can create any number of directories
+under this directory to help organize and separate your data. The maps will be
+loaded in alphanumerical order unless layering is specified.
+
+Hints on installing and organizing maps are found in README.MAPS. 
+Maps in a pixel graphics format actually need a combination of two files,
+a data file with a graphic pixmap (.xpm) (or other format if you compiled
+with ImageMagick), and a calibration file (.geo). The .xpm file is the
+standard graphic format, available without additional libraries. If you
+want to save storage space you can use gzip to compress those files 
+("gzip map.xpm" will result in "map.xpm.gz"). Xastir detects this
+automatically during map loading. You can use XView/Gimp/ImageMagick and
+other programs to convert gif, jpg, and tif images into this format if
+you don't have support for many image types compiled in (ImageMagick). If
+you have problems with maps in xpm format, try to load and save the
+graphics with Gimp first, to convert all unknown color names into the
+binary representation.
+
+The .geo file is a text data file that will tie the image to a location
+in the world. Here is an example of a .geo file that will cover the entire
+world with the map world1.xpm:
+
+FILENAME   world1.xpm
+#          x          y        lon         lat
+TIEPOINT   0          0        -180        90
+TIEPOINT   639        319      180         -90
+IMAGESIZE  640        320
+
+.geo files can have many elements:
+
+FILENAME <filename>
+This specifies the filename of a map image to be loaded from the local disk.  
+
+URL <http://website>
+This specifies the URL of a map image to be loaded from a web or ftp site. 
+ImageMagick only.
+
+TIEPOINT <x-pixel> <y-pixel> <longitude> <latitude>
+Two tie-points are required, and more than 2 will be ignored.
+these two lines are for connecting an x,y pixel position in the image
+to a lat and long position on the earth. The points should be as close as
+possible to the upper left corner and the lower right corner of the image for
+best accuracy.  The latitude/longitude are specified in decimal degrees.
+
+IMAGESIZE <pixels horizontally> <pixels vertically>
+This specifies the size of the image in pixels. If this is not set, the image
+will be loaded each map redraw, regardless if it is on screen or not.
+IMAGESIZE is a REQUIRED OPTION if a URL is specified.  For local files, it's
+an optional parameter (we use ImageMagick to query the image size for local
+files).
+
+DATUM <datum>
+This feature is not implemented.
+
+PROJECTION <projection>
+This feature is only partially implemented, default is "LatLon", other
+possibility is "TM" to specify that the map is in  Transverse Mercator
+projection.
+
+# <anything>
+Any line with the first character of a '#' will be ignored.
+
+ImageMagick specific image enhancements:
+
+GAMMA
+eg: GAMMA 1.2    or    GAMMA 1.2,2.0,1.2
+The first will change overall gamma for this image, the second will
+lighten green more than red or blue.
+
+CONTRAST
+eg: CONTRAST 0    or    CONTRAST 1
+Doesn't seem to do that much, other values make no difference.
+
+NEGATE
+eg: NEGATE 0    or    NEGATE 1
+0 will negate all colors, 1 just grayscale colors.
+
+EQUALIZE
+No argument.
+
+NORMALIZE
+No argument.
+
+LEVEL <black_point, mid_point, white_point>
+eg: LEVEL 0,1,65535
+These values seem to be the defaults.
+
+MODULATE <brightness, saturation, hue>
+eg: MODULATE 90,150,100
+These are percents, 100,100,100 is the default.
+
+REFRESH <seconds>
+eg: REFRESH 900
+This tag is used for dynamic URLs such as weather radar, where you
+wish Xastir to auto-redraw the map at a specified interval.  By
+adding this tag to weather radar .geos, you can watch the weather
+move across your screen.  Xastir contains only one interval counter,
+so the smallest REFRESH interval loaded takes effect for all selected
+maps.
+
+TRANSPARENT 
+Color to remove from the background (make it transparent).  Use a
+number, 0=black.  Color-mapped images use the map value, so white is
+usually 0xffffffff (32-bits of 1s).  Values must be in hexadecimal,
+and are preceeded by "0x".  The value can be obtained by using debug
+level 16.  The first of the four numbers after "Color allocated is"
+is the colormap index.
+
+CROP <left top right bottom>
+Removes borders (makes them transparent).  Values are in pixels with
+(0,0) at the upper left.  A good value for the 620x620 NWS radar
+images is "CROP 35 20 616 600"
+
+Special/nonstandard .geo files:
+
+TIGERMAP
+A file with just the word "TIGERMAP" will cause Xastir to retrieve an
+online Tiger map of the area on screen. These are not available for every
+place in the world. "tigermap.geo" is automatically installed in the maps
+directory.
+
+TERRASERVER-SATELLITE
+A file with just the word "TERRASERVER-SATELLITE" will cause Xastir to
+retrieve a Terraserver satellite photo of the area on screen. Those
+services are not available for every place in the world. Note that using
+the Terraserver maps at any zoom above 256 will probably take a long time
+to load, won't show much detail, and probably won't display correctly. This
+is a limit of Microsoft's Terraserver, not Xastir.  Also note that
+crossing UTM zone boundaries is not supported by Terraserver.
+"terraserver.geo" is automatically installed in the maps directory.
+
+TERRASERVER-TOPO
+A file with just the word "TERRASERVER-TOPO" will cause Xastir to retrieve a
+topographic map of the area on screen. Those services are not available for
+every place in the world. Note that using the maps at any zoom above 256
+will probably take a long time to load, won't show much detail, and
+probably won't display correctly. This is a limit of Microsoft's
+Terraserver, not Xastir.  Also note that crossing UTM zone boundaries is not
+supported by Terraserver. "terraserver-topo.geo" is automatically
+installed in the maps directory.
+
+TERRASERVER-URBAN
+Same as above but with Terraserver colored urban-area satellite
+images. "terraserver-urban.geo" is automatically installed in the
+maps directory.
+
+TERRASERVER-REFLECTIVITY
+Same as above but with Terraserver reflectivity images.
+"terraserver-reflectivity.geo" is automatically installed in the
+maps directory.
+
+TOPORAMA-250k
+Canadian 1:250k scale topo maps, downloaded from findu.com.
+"CanadaTopo250k.geo" is automatically installed in the maps
+directory.
+
+TOPORAMA-50k
+Canadian 1:50k scale topo maps, downloaded from findu.com.
+"CanadaTopo50k.geo" is automatically installed in the maps
+directory.
+
+WMSSERVER
+Allows use of Web Map Services (WMS). An example "WMSRadar.geo" is
+automatically installed in the maps directory.
+
+
+
+geoTIFF maps are a combination of two files as well: a .tif and a .fgd file.
+The .tif file is the actual map data.  The .fgd file need only contain four
+lines like this (but may contain many other lines):
+
+1.5.1.1   WEST BOUNDING COORDINATE:  -122.000000
+1.5.1.2   EAST BOUNDING COORDINATE:  -120.000000
+1.5.1.3   NORTH BOUNDING COORDINATE:  48.000000
+1.5.1.4   SOUTH BOUNDING COORDINATE:  47.000000
+
+Xastir uses only those four lines in its calculations to determine the corner
+points of a map, to see whether the map fits in the current viewport (so it
+can decide whether to skip it).  If your map data are USGS topographic maps,
+the .fgd file should be readily available to you. If it is not, the mapfgd.pl
+script can create it for you. If you don't have a .fgd file, the map will load
+fine, but the white borders won't be cropped and the size and rotation may be
+off a tad bit. An added feature in Xastir is the ability to do datum
+translations from NAD 1927 to WGS 84 datum, which makes the USGS topographic
+maps much more  accurate on the Xastir screen.
+
+Xastir can use USGS geoTIFF topographic maps directly from the CD drive.
+Manually mount the disk or use auto-mounter to do it for you, and make sure
+you have a sym-link created in your maps directory that points to where you
+mounted your CD-ROM drive.  That's it!
+
+
+ESRI Shapefile maps are also a combination of several files, a .shp file, a
+.dbf file, and a .shx file. You only need to select the .shp file to load the
+map, but the other(s) must be present for the map to load correctly.
+
+
+GNIS (Geographic Names Information System) data is a collection of names of
+locations, or geographic features. These labels behave like map labels in
+Dos/WinAPRS maps.  As you zoom in, more labels will appear, assuming you've
+selected the GNIS file as a map and have enabled Map Labels in the Maps menu.
+If you have some of them in the xastir/GNIS directory, you can also search
+for map labels within Xastir.
+
+
+WX County Maps
+All WX County maps should be stored in the /usr/local/share/xastir/Counties
+and Xastir only supports the ESRI Shapefile standard for these. Installation
+is explained in README.MAPS.  You must have Shapelib compiled in.
+
+As NWS messages are received, different areas will get tinted to designate
+areas of concern.  They are color-coded to specify different types of
+alerts. The colors are: Cyan for advisory, yellow for watch, red for warning,
+orange for canceled alert, royal blue for tests, and green for undetermined
+alert levels. The coloring is done with a pixmap stipple that displays the
+type of alert, if it is able to be determined. These changes were made so that
+the underlying maps may still be seen underneath the weather alert areas, and
+so the alert type may be more easily determined, as sometimes matching the
+alerts on screen and in the weather alerts dialog is difficult. The display
+of weather alerts may be turned on/off via the Map menu.
+
+HELP-INDEX>Stations Menu
+
+                             Stations Menu
+
+These options will allow you to control the data displayed around the stations
+on the map. It will also let you track and find stations, and clear stations
+and trails in the database and from the map.
+
+Find Station
+See the help topic "Locating a Station".
+
+Track Station
+See the help topic "Tracking a Station"
+
+Fetch Findu Trail
+Downloads historic trail data from findu.com. Slider bars control the starting
+point and duration of data downloaded.  For an example, if you wished to see
+the track that happened two days ago, all day long, you might set the first
+slider to 48 hours (start time of two days ago) and the second slider to 24
+hours to snag exactly one day's worth of data, from the start until 24 hours
+later.
+
+
+Export all
+This sub-menu allows saving data for all stations to files [or databases]
+
+    Export to KML file
+      Saves all stations and their trails to a Keyhole Markup Language
+      file in ~/.xastir/tracklogs.  The filename will be the current
+      date and time with a .kml extension, e.g. 20080125-033045.kml
+      KML files can also be written on a regular basis using KML
+      Snapshots on the file menu.
+     
+    Store to open databases [Not yet implemented]
+      [Store to database interfaces is currently only implemented through 
+      individual SQL database interface dialogs]
+
+    To save a png snapshot of the current map, use File->PNG Snapshots
+
+Filter Data
+This sub-menu allows filtering of the displayed symbols:
+
+  Select None
+    Determines if symbols should be drawn on the map. The other options depend
+    on this being enabled.
+
+  Select Mine
+    Determines if your own station is shown on the map.
+
+  Select via TNC
+   Global toggle for displaying data received via a TNC, but may be narrowed:
+
+   Select Direct
+     This option only displays stations heard directly (not digipeated).
+
+   Select via Digi
+     This option displays stations heard indirectly via a digipeater.
+
+  Select Net
+    This option displays stations with data received via the Internet.
+
+  Include Expired Data
+    Causes Xastir to continue to display the station data that normally goes
+    away when the symbol is ghosted.  The expiration time can be adjusted in
+    the File|Configure|Defaults menu.
+
+
+  Select Stations
+    Global toggle for displaying stations, but may be narrowed:
+
+    Select Fixed Stations
+      This option displays stationary stations.
+
+    Select Moving Stations
+      This option displays stations with multiple positions or non-zero speed
+
+    Select WX Stations
+      This option displays Weather Stations.
+
+     Select CWOP WX Stations
+      This option includes the display of citizen weather (non-ham) weather
+      data.
+
+  Select Objects/Items
+    Global toggle for displaying objects/items, but may be narrowed:
+
+    Select WX Objects/Items
+     This option displays weather Objects and Items. This includes tropical
+     storms and remote weather stations.
+
+    Select Water Gauge Objects/Items
+     This option toggles the display of water gauge (/w) objects.
+
+    Select Other Objects/Items
+     This option enables or disables the display of objects other than those
+     listed above.
+
+
+Filter Display
+This sub-menu allows filtering of the displayed data:
+
+  Display Callsign
+  Determines if the callsign is displayed.
+
+    Label Trailpoints
+    This option includes callsigns along trails, to help identify which
+    points belong to which stations.
+
+  Display Symbol
+  Determines if the symbol is shown to the left of the callsign.
+
+    Rotate Symbol
+    Some symbols will change their orientation to show the direction in which
+    they are traveling.
+
+  Display Trail
+  When enabled, any moving station will trail a colored line.  We now display
+  as many locations as we have in our database (old limit was 100).  Long
+  trail segments (over 2 degrees latitude or 2 degrees long), or segments with
+  more than 45 minutes receive delay between the points will not be displayed.
+  Duplicate points are also eliminated from the track (SAR team returning to
+  base:  Last segment may not be displayed due to the starting point appearing
+  twice in the trail list).
+
+  Display Course
+  When enabled, green text will appear below the call sign. This will display
+  the last known course (in degrees) the station was traveling.
+
+  Display Speed
+  When on, red text will appear below the call sign (or course). This will
+  display the last known speed of the station. 
+
+    Display Short Speed
+    This option removes display of the measurement units for speed.
+
+  Display Altitude
+  When enabled, blue text will appear above the call sign. This will display
+  the last known altitude of the station.
+
+
+  Display Weather Info
+  Global toggle for displaying weather information, but may be narrowed:
+
+    Display Weather Text
+    When enabled, the latest weather data (temp,wind speed/course/gust,
+    humidity) is displayed. This may be adjusted with the following option:
+
+      Display Temperature Only
+      Displays only the temperature data for the station.
+
+    Display Wind Barb
+    When enabled, a wind barb showing the direction and speed of the wind is
+    drawn for all displayed stations reporting this information. 
+
+
+  Display Position Ambiguity
+  When enabled, the area in which station using position ambiguity may be
+  located within is shaded, with the relevant station in the center.
+
+  Display Power/Gain
+  When on, Power/Gain Circles will be displayed. Overlapping circles indicate
+  that the stations are theoretically within simplex range of one another.
+  This is only roughly accurate, especially in areas of variable terrain. 
+
+    Use Default Power/Gain
+    Enables a default power/gain setting as specified in the APRS(tm)
+    specification.
+
+    Display Mobile Power/Gain
+    Enables power/gain circles for mobile stations.
+
+
+  Display DF Attributes
+  When enabled, any DF circles/lines will be displayed on the screen.
+
+  Enable Dead-Reckoning
+  When enabled, the positions of stations are estimated based on past course
+  and speed. The recalculation rate should be reasonable, but can be adjusted
+  in the configuration file.
+
+    Display Arc
+    Displays an expanding arc of expected maximum travel distance, location and
+    course given the past course and speed. The arc slowly becomes a circle as
+    the position report gets older.
+
+    Display Course
+    Displays an expected course and distance traveled by the station, assuming
+    the course hasn't changed.
+ 
+    Display Symbols
+    Displays a ghosted version of the stations symbol at the expected position,
+    assuming the station has continued at its current course and speed.
+
+
+  Display Dist/Bearing
+  When enabled, two lines of text will be displayed on the left side of the
+  stations' icon. The top line will contain the distance from your station to
+  this station. The bottom line will contain the course from your station to
+  this station.
+
+  Display Last Report Age
+  Display the time since the station was last heard.
+
+Reload Object/Item History
+This will reload the ~/.xastir/config/objects.log file used for Object and Item
+persistence. This is needed if you edit the file while Xastir is running.
+
+Clear Object/Item History
+This will clear the ~/.xastir/config/objects.log file used for Object and Item
+persistence. It is recommended that you manually select and delete all Objects
+and Items that you own before doing this, otherwise they may remain on the
+screens of other APRS(tm) users.
+
+Clear All Tactical Calls
+Clears all assigned tactical calls. This will take effect the next
+redraw. Note that this will NOT clear tactical calls on other
+peoples' screens if you've published them via a message to
+"TACTICAL" (see the help text for "Send Message").
+
+Clear Tactical Call History
+This removes the tactical call history file, meaning that tactical calls
+assigned will not remain permanent between Xastir restarts.  Note
+that this will NOT clear tactical calls on other peoples' screens if
+you've published them via a message to "TACTICAL" (see the help text
+for "Send Message".
+
+Clear All Trails
+This will wipe all the line tracking data from the station database and
+refresh the screen.  This option is perhaps useful if you're low on memory
+or just want an uncluttered screen.  You may also clear individual stations'
+trails from the Station Info dialog.
+
+Clear All Stations
+This will wipe all the data from the station database except yours.  This
+option is perhaps useful if you're low on memory or just want to unclutter
+your screen.
+
+HELP-INDEX>Messages and the Messages menu
+
+                  Messages and the Messages menu
+
+Send Message to and Open group messages
+
+These are very similar. "Send message to" will send your messages to one
+station and will only receive data from that station. Group messages are more
+general: you can receive any message for the group and you will send out your
+messages to that group name. Group messages code is not fully implemented yet
+and various problems still need to be worked out.  The "groups" file is looked
+for in ~/.xastir/config.  This is where the groups you are a member of are
+stored.  As was said before the "groups" functionality may not be complete yet.
+
+At some point in the near future sending of bulletins should be added to this
+menu as well.  It's not coded yet.
+
+Each of these two screens contains a message box, a call line, a message line,
+and various buttons. You must first enter the call of the group or station you
+want to contact. Once that is done any new message that has come in from that
+station to you will be displayed. If the station is sending you information
+and no message window is up it will automatically pop up a new window (up to
+10) with that station's call sign filled in for you. You can now enter a
+message on the message line. The message can be longer that the message line,
+and will max out at about 250+ characters. Once your message is entered,
+clicking on the "Send Now!" button will send your message. The "Send Now!"
+button will gray out until your message is completely ack'ed. Any message you
+receive will be sorted by the line # and be placed in the message window. If
+you are in a group mode each line will display the call sign from where the
+message was sent followed by the message itself. Currently group messages are
+sorted by call and then line #. When you are done sending messages clicking on
+the exit button will close the window. Other buttons are also available:  The
+"New Call" button will allow you to look at old data a station has sent.  Type
+in the call and click on this button, any old information will be displayed.
+You can also use this button to change the call of the station you're talking
+with. Enter the new call and click the button. The "Clear Msg History" button
+will clear any message displayed in the message window.  "Cancel Pending Msgs"
+will cancel any messages in the transmit queue that haven't been acknowledged
+by the remote station yet.  After canceling the pending messages or receiving
+and acknowledgment packet from the remote station, you may send new messages to
+the remote station.  Xastir will allow you to type ahead, so you can just keep
+typing if you don't want to wait for the acknowledgments.
+
+Messages in reply to previous ones will attempt to use the path of the
+received message to avoid flooding the system with broadcast messages. You
+may adjust the path in the send message dialog, or the default path(s) set
+in the interface control will be used if you leave this blank.  The path
+can be set for each message sent, but once a message is sent the path
+remains fixed for that particular message.
+
+Each outgoing message remains highlighted until it is ack'ed by the remote
+station.  If it times out or if you cancel the pending messages, those
+messages will remain highlighted unless you clear the message history.
+
+To publish TACTICAL calls to other Xastir and APRS+SA stations as
+well as assign those tactical calls locally: Send a message to
+"TACTICAL" with the body of the message containing lines something
+like:
+  
+  callsign-1=TAC1;callsign-2=TAC2;callsign-3=TAC3
+
+To remove these tactical calls later from local AND remote screens,
+assure that the original message(s) assigning them has timed-out or
+been cancelled, then send a message like this and let it retry until
+it times out (assigns blank tactical calls to the original
+callsigns, thereby removing the assignment):
+
+    callsign-1=;callsign-2=;callsign-3=
+
+Clear all outgoing messages
+This will clear all un-ack'ed messages you have sent.
+
+General Stations Query
+This sends an ?APRS? packet, which should cause all local stations to report
+their position and/or status. Most software ignores this query, because
+responding to it would cause massive floods of data.
+
+IGate Stations Query
+This sends an ?IGATE? packet, which should cause all local IGates to respond
+with their capabilities.
+
+WX Stations Query
+This sends an ?WX? packet, which should cause all local weather stations to
+report their position and weather.
+
+Modify Auto reply message
+This will set the message that is sent as an Auto Reply.
+
+Enable Auto Reply Msg
+This will turn on an automatic reply when an incoming message is received.
+
+Satellite Ack Mode
+This mode disables the sending of ack messages in response to received
+messages. Messages are still acknowledged using the reply-ack system. When
+operating over a satellite it is clear that your message made it, because you
+will hear it repeated. The receiving station sending an independent ack only
+adds QRM.
+ 
+HELP-INDEX>Interfaces Menu
+
+                         Interfaces menu
+
+This menu contains interface related options.
+
+Interface Control
+This option displays a window where you can turn on and off your configured
+interfaces, as well as add, delete, or configure interfaces. See the "Configure
+Interfaces" help topic.
+
+Disable Transmit options
+These options disable the transmission of everything, one's position, or one's
+objects. These are global options and affect all interfaces. Most interfaces
+have an option to disable transmission on that specific interface in their
+configuration menus as well.
+
+Enable Server Port
+This enables/disables TCP and UDP listening sockets at port 2023.  You may
+connect other APRS(tm) clients to the TCP port in order to send/receive
+APRS(tm) data.  Once they authenticate, they'll be able to send data to Xastir.
+Without authentication, they'll be able to receive every bit of TNC and INET
+data that Xastir receives.  Note that ANY user with the proper credentials can
+come in on the TCP or UDP ports if they are enabled.  The only one of these two
+ports currently that can send to RF is the UDP Server port.  The TCP
+port cannot.
+
+    "user WE7U-13 pass XXXX vers XASTIR 1.3.3"
+
+Connect another APRS(tm) client to that port and it should authenticate and be
+able to send to any server that Xastir is connected to, as well as receive
+packets from all ports/servers Xastir is hooked to.
+
+You should also have a binary called "xastir_udp_client" which can send packets
+into the UDP listening port.  Invoke it like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> "APRS Packet Goes Here"
+
+Currently that will inject the packet into Xastir's decoding routines and send
+it to any TCP-connected clients. It will also igate it to the INET if you have
+igating enabled.  It will send the packet out the RF ports as third-party
+packets only if you add the "-to_rf" flag after the passcode like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> -to_rf "APRS Packet"
+
+The UDP client is useful for generating and injecting APRS packets from
+external scripts.  It can also be used to fetch the callsign of the remote
+xastir server by using the -identify flag:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> -identify
+
+Transmit now
+Causes all interfaces that have transmit enabled (see configure|interfaces) to
+transmit a position packet.  It will be grayed out if Disable Transmit: ALL
+is selected.
+
+If you have GPSMan installed, you have these additional menu options
+displayed:
+
+Fetch GPS Track
+Download a set of trackpoints from an attached GPS.
+
+Fetch GPS Routes
+Download a set of routes from an attached GPS.
+
+Fetch GPS Waypoints
+Download a set of waypoints from an attached GPS.
+
+Fetch Garmin RINO Waypoints
+Snag waypoints from an attached Garmin RINO, create APRS(tm) Objects out of any
+waypoints which begin with "APRS".
+
+HELP-INDEX>Station info box - FCC and RAC lookup
+
+                  Station info box - FCC and RAC lookup
+
+Station Info will display any data decoded by Xastir.
+
+You can assign (local only) tactical calls to stations from here, by
+clicking the "Assign Tactical Call" button. This will cause the
+station on screen to display as the tactical call instead of its
+callsign. Assigning a blank tactical call clears this feature, and
+it can also be cleared for all stations in the Stations menu.  This
+feature assigns tactical calls to the local Xastir station only, but
+see below to publish them to others.
+
+To publish tactical calls across the air to other Xastir and APRS+SA
+stations (as well as assign them locally), see the "Send Message" help
+section.
+
+"Enable Automatic Updates" will cause the window to refresh frequently with the
+latest information.
+
+The information available may include: Number of packets heard, the time
+last heard, the device the packet came from, station comments, 
+power/height/gain of the station, course/distance from your station,
+weather information, and current and previous positions.
+
+For moving stations a track-log follows with the most recent entries on top.
+A '+' in front indicates that a new track starts at that point (if there was
+a large gap in time or position). A star at the end of a line indicates that
+this station could be heard direct (without a digi) at that specific position.
+Positions are followed by the 6 digit Maidenhead grid square the station was
+located in at that point.
+
+For your own station, there is an "Echoed from" field, listing the
+last six digipeaters that heard you directly. This is useful for setting
+non-generic paths.
+
+Currently two rows of four buttons appear in the Station Info window.  Some
+of the labels on the buttons change based on the type of station that you're
+dealing with.
+
+For objects/items:
+
+Store     Modify    Blank      Close
+Track     Object/
+          Item
+
+Station   Trace     Un-Acked   Direct
+Version   Query     Messages   Stations
+Query               Query      Query
+
+For other stations:
+
+Store     Send      Search     Close
+Track     Message   FCC (RAC)
+                    Database
+
+Station   Trace     Un-Acked   Direct
+Version   Query     Messages   Stations
+Query               Query      Query
+
+"Station Version Query" changes to "Clear Track" for mobile stations.
+The Clear Track button will clear any line tracking for this station that is
+currently stored or on the map display.
+
+"Store Track" will save the track of the station to a file on disk. The 
+format is similar to that used by GPS receivers but its specification
+might be changed (enhanced) in future versions. There is currently no
+way to read that track data back in, but it is planned for the future.
+The goal is to also read and display GPS track-logs in a similar manner.
+These track-log files will be placed in the directory ~/.xastir/tracklogs
+with a name equal to the stations call with ".trk" as extension.  "Store 
+Track" will simultaneously save the station's track as a Keyhole Markup
+Language (.kml) file with a filename equal to the station's call, the
+current date and time and .kml as extension.  If shapefile support has
+been included, the station's track will also be saved as a set of four 
+files (.dbf,.prj,.shp,.shx).  Subsequent presses of Store Track for the
+same station will write additional lines into the .trk file, and create
+new .kml (and shapefile) files (each containing all positions in the 
+station's track.  
+
+"Modify Object/Item" will bring up the Object Modify window.
+
+"Send message" will open up the message window and allow you to send a message
+to this station. It will fill in the call sign for you.
+
+If the FCC (U.S. Federal Communications Commission) or RAC (Radio Amateurs of
+Canada) database is installed and the callsign appears to be a Canadian or
+U.S. callsign, the "Search FCC/RAC Database" button will become active,
+otherwise this button will be inactive.  The FCC and RAC files should be
+placed in the /usr/local/share/xastir/fcc directory, and case is important!
+Pressing this button adds the station's name and address into the Station
+Info box.  Instructions for installing these databases are in the README.MAPS
+file.
+
+Xastir will create index files for each database file upon startup. If a newer
+callsign file is placed there while Xastir is running, it will create or
+rebuild the index on the next lookup.  Special prefixes are NOT handled.
+
+HELP-INDEX>Creating a log
+                              Creating a log
+
+Xastir can log data from the internet or TNC for later playback, or for
+debugging purposes.  WARNING: Logging can fill up your hard drive, so be
+careful using it, or make preparations for rolling over the log files
+automatically via cron. An indication will be shown on the status bar when
+logging is enabled.
+
+All these choices are accessible via the File menu:
+
+Enable TNC Logging
+Logs all TNC data received and transmitted. These logs can be played back using
+the "Open Log File" feature.
+
+Enable Net logging
+Logs all internet data received and transmitted. These logs can be played back
+using the "Open Log File" feature.  If you have no interfaces started but still
+want to log your posits and objects locally, this is the option to enable for
+that as well.
+
+Enable IGate logging
+Logs all data forwarded in both directions, and rejected forwards with reasons
+for rejection. Includes NWS messages forwarded to RF.
+
+Enable WX logging
+Logs all weather data received from your weather station.
+
+
+HELP-INDEX>Replaying a log
+
+                              Replaying a log
+
+Click on "File", then "Open Log File" and a file selector window will display.
+You can use it to browse your hard drive and select any file containing raw
+TNC data like those created by the TNC and Net logging options. Your station
+will still function the same way, receiving and transmitting. If you were
+logging data, the typical place to look for those files would be 
+~/.xastir/logs/
+
+NOTE: This function doesn't read the saved station tracklogs.
+
+HELP-INDEX>Locating a Station
+
+                             Locating a Station
+
+Click on "Stations", then "Find Station". A window will pop up. You can now
+enter a call or part of a call. By default it will search for an exact match
+(full call, not partial) and is not case sensitive. If you are looking for a
+partial match, "Match Exact" should not be selected.
+
+For objects which could contain lower case letters you have to check
+"Match Case"! Opposite to the name, without "Match Case" the search
+text will only be converted to upper case...
+
+Clicking on the "Locate Now!" button will center the first station
+found in the center of your screen at the current zoom level.
+
+Clicking "FCC/RAC Lookup" will look up the user's information if the FCC or RAC
+database, of those databases are installed.
+
+Clicking on "Cancel" will close the window.
+
+This dialog will pop up if a station sends a Mic-e "Emergency!" packet, to
+encourage users to locate and perhaps help the listed station.
+
+HELP-INDEX>Creating and using Map Display Bookmarks
+
+                  Creating and using Map Display Bookmarks
+
+Click on "Maps", then "Map Display Bookmarks" and a window will pop up.
+If this is the first time you have used this then the box will have no
+entries in it. To add a bookmark to the list: Position the main map to
+the area and zoom level you want to use. Enter a unique name in the
+"New Name" area, then click on add. Your entry will be added to the
+list (in alphabetical order).  You can add as many map display bookmarks
+as you want. To use one of the bookmarks mark its name and click
+"Activate!". The main map will then show the stored area and zoom level.
+You can similarly delete a bookmark by clicking on the bookmark name and
+then the "Delete" button.
+
+"Maps->Locate Map Feature" is another method to jump to a location, if
+the name of the location is known and you have GNIS files installed.
+
+HELP-INDEX>Tracking a Station
+
+                        Tracking a Station
+
+Click on "Stations", then "Track Station". Enter the callsign to track (all or
+part) then click on the "Track Now!" button. As the station moves it will
+remain viewable in the main map window. As the stations starts to get close
+to the edge of the map window the window will re-center so that the object is
+always visible. To stop tracking this station click on the "Clear Tracking"
+button. While tracking is active, a "Tr" is shown in the status bar next to
+the zoom level.  If the station is not on the map yet, tracking will begin
+as soon as it shows up.
+
+HELP-INDEX>Printing
+
+                       Printing the Map Screen
+
+Note: Printing has not been set up on Windows/Cygwin.  These instructions
+are for Unix and Unix-like operating systems.
+
+Xastir can print the drawing area in either black & white or color.  It does
+this by first dumping the image to an XPixmap file on disk, then using external
+tools to convert it to postscript, scale it, rotate it, preview it, then print
+it.  You must have your system printing set up to handle postscript (usually
+this requires Ghostscript and a print filter installed, as well as lp or lpr
+print spoolers).  You must also have the following tools installed for this
+capability:  ImageMagick tools (specifically "convert"), "Ghostscript",
+Ghostscript fonts, and "gv".  Once all of these packages are installed and
+functional, you should get a "gv" window popping up shortly after you tell
+Xastir to create a print file.  From there  you can view the printed image, and
+if acceptable, tell "gv" to print it.  Note that sometimes changing to a white
+default background for the maps is recommended, depending on what maps you have
+viewable.  This can save greatly on ink.
+
+HELP-INDEX>Creating Snapshots
+
+                     Creating Automatic Snapshots
+
+Xastir has the capability to create automatic snapshots of the map screen
+on a recurring basis.  The default time period is set at once per five
+minutes.  Assuming that you have "convert" from the ImageMagick tools
+installed, Xastir will create an XPM format file in ~/.xastir/tmp/, then
+convert it to the PNG file ~/.xastir/tmp/snapshot.png. This file is useful for
+embedding in web pages to show a "live" image of what is on your Xastir
+screen.  Enable this feature via the "File->PNG Snapshots" toggle-button. 
+The rate is once every five minutes (configurable from the Configure 
+Timing dialog from "File->Configure->Timing"), or every time the button is 
+toggled from off to on. A .geo is created to allow you to use the snapshot 
+as a map.  A .kml file is also written to allow you to use the snapshot as
+a graphic overlay on terrain in applications capable of reading kml.  See
+kml_snapshot_to_web.sh and kml_snapshot_feed.kml in the scripts directory 
+for more information on using the snapshot.png and snapshot.kml file to
+produce a kml feed using the snapshots.
+
+                    Creating Automatic KML Snapshots
+
+Xastir is capable of writing all current stations and tracks to a kml file
+on a recurring basis.  Enable this feature via the "File->KML Snapshots" 
+toggle button.  The rate at which these snapshots are generated is the same
+as that of PNG snapshots, configured from "File->Configure->Timing" by 
+setting the snapshot time interval.  Each snapshot is written to a .kml
+file in ~/.xastir/tracklogs, with a filename based on the date and time
+of the snapshot, e.g. 20080206-000720.kml  This behavior may change to 
+make KML snapshots write to a single file like PNG snapshots.
+                    
+
+HELP-INDEX>Included Scripts
+
+                        Included Scripts
+
+Xastir includes several Perl scripts and a shell script that may be useful:
+
+get-fcc-rac.pl
+This shell script automates retrieving and installing the FCC and the RAC
+callsign databases. Note that these databases are very large!
+
+icontable.pl
+This script generates an xpm bitmap of all Xastir's primary and secondary
+symbols from the symbols.dat file. The overlays and specials are ignored.
+Output is to STDOUT, so a typical call would be "icontable.pl > symbols.xpm".
+
+inf2geo.pl
+This script creates .geo files from UI-View .inf files. To create a map.geo
+from a map.inf, typical usage would be "inf2geo.pl map".
+
+kiss-off.pl
+This script sends the commands needed to turn off a TNC's KISS mode.
+
+mapblast2geo.pl
+This script creates .geo files for Mapblast pixel maps. It includes usage
+information.
+
+mapfgd.pl
+This script creates minimal .fgd files for GeoTIFF images lacking them, based
+on information found in the GeoTIFF file. The created files allow Xastir to
+crop the white borders and rotate/scale the map properly. Typical usage would
+be "mapfgd.pl mapdir" where mapdir is the directory containing the GeoTIFF
+images.
+
+overlay.pl
+This script creates .log format files from comma-separated overlay files. See
+the script comments for full usage information. 
+
+ozi2geo.pl
+This script creates .geo files from OziExplorer .map files.
+
+permutations.pl
+This script converts between different lat/lon formats. See the script comments
+for further details.
+
+split_gnis.bash
+This will take a GNIS data-point file (typically for a whole state, 8+MB), break
+it down into smaller chunks (typically for a county, 30-200k) it will also
+throw away the trailing spaces and <CR>s at EOL.
+
+split_gnis.pl
+This is a Perl version of the above script.
+
+test_coord.pl
+Tests for the Coordinate.pm Perl module.
+
+track-get.pl
+This script downloads the track-log of a specified object from a Garmin GPS.
+It requires the GPS::Garmin module. It prompts for an object name, and writes
+the track-log to the ~/.xastir/logs directory.
+
+update_langfile.pl
+This script is targeted toward developers. It rebuilds a specified language
+file to contain all the strings of another. It is usually used to regenerate
+the non-English language files when significant changes have been made to the
+English file. When the second language file lacks a string in the main file,
+the untranslated string is inserted. Typical usage would be 
+"update_langfile.pl language-German.sys" . The main language file is
+hard-coded but easily editable.
+
+waypoint-get.pl
+This similar script downloads the waypoints from a Garmin GPS, and creates a
+log in the ~/.xastir/logs directory containing the waypoints as objects. It
+also requires the GPS::Garmin module.
+
+db_gis_mysql.sql  db_gis_postgis.sql
+These will create tables for storing station data in a mysql or postgresql/
+postgis database.  SQL Server database support is experimental.  See the
+"OPTIONAL: Experimental.  Add GIS database support" section in INSTALL
+
+HELP-INDEX>Configuring Interfaces
+
+                           Configuring Interfaces
+
+Click on Interfaces, then Interface Control.
+
+An "Installed Interfaces" box should appear. This box will allow you to add,
+delete, and modify the properties of various devices you may want to use with
+Xastir.
+
+Supported interface types are:
+Serial TNC
+Serial TNC w/GPS on HSP cable
+Serial GPS
+Serial WX
+Internet Server
+AX.25 TNC
+Networked GPS (via gpsd)
+Networked WX
+Serial TNC w/GPS on AUX port
+Serial KISS TNC
+Networked Database (Not Implemented Yet)
+Networked AGWPE
+Serial Multi-Port KISS TNC
+SQL Databases [MySQL,Postgis] (Experimental)
+
+To add a device, click on the add button. A "Choose Interface Type" box will
+appear. Click on the type of device you would like to add. Then click the Add
+button in the "Choose Interface Type" box. Properties for that device will
+appear. Fill out the requested information and click OK.
+
+To delete the device, click on the device you wish to delete and then click
+the delete button.
+
+To modify the properties of a device, click on the device you wish to modify,
+then click the properties button. The properties for that device will appear.
+Change the information you want and click OK.
+
+More specific help is available under the help topics of each interface type.
+
+SQL Databases will only appear as an option if you have MySQL or Postgis 
+support compiled.  
+
+HELP-INDEX>Configure Serial TNC Devices 
+
+                          Configure Serial TNC Devices 
+
+This section covers adding or modifying Serial TNCs or Serial TNCs with a
+GPS on a HSP cable.
+
+If you have a HSP cable, which allows you to share the TNC port with a GPS
+unit you may choose a TNC with GPS (HSP Cable). This is a special cable and may
+not work on all computers/GPS/TNC combinations. If you use this device the TNC
+and the GPS should be set to the same communications parameters. Generally
+4800 bps, 8 data bits, no parity, and 1 stop bit.
+
+TNC Port Options:
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+The TNC Port is the Unix device that the TNC (or TNC and GPS) is hooked to.
+Normally you can use /dev/ttyS0 (com1), /dev/ttyS1 (com2) etc.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your TNC
+and GPS.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices, and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. XASTIR will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1, WIDE2-2 may work better. Or if you know the call of your closest digi you
+may use XXXCALL, WIDE2-2. Most of you will only need one path. If you are in a
+remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths are
+entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+TNC Startup and Shutdown files. These fields specify a filename that is
+located in the /usr/local/share/xastir/config directory. Each file is a
+standard text file containing any commands you would like to send your TNC at
+the time the device is activated (startup file) or shut down.
+
+HELP-INDEX>Configure Serial TNC w/GPS on HSP cable or AUX port
+
+                Configure Serial TNC w/GPS on HSP cable or AUX port
+
+These hybrid interface types implement the options of both serial TNCs and
+GPSs. Please consult the configuration help for both serial TNCs and serial
+Gpsd for further information on the configuration of these devices.
+
+"Send Control-E to get GPS Data?"
+
+This checkbox controls whether Xastir sends a Control-E to the TNC every time
+it needs GPS data.
+
+Some TNCs that support a GPS on an auxilliary port require that Xastir
+send a Control-E to the TNC in order to get the GPS data each time it
+is needed.  Devices in this class include the Kantronics KPC-3+.
+
+Some devices, like Kenwood APRS radios (D700, etc.) do NOT require
+this, and in fact the Control-E interferes with correct operation of
+these devices.
+
+Because Control-E was required by the most common TNCs that had an aux
+port for GPS at the time that this interface type was written, this is
+the default behavior of Xastir.  If you have a Kenwood radio that you are 
+using in this mode, you must DESELECT the "Send Control-E to get GPS data?"
+checkbox in the configuration dialog for this interface type.  
+
+HELP-INDEX>Configure Serial KISS TNC
+
+                     Configure Serial KISS TNC
+
+This section covers adding or modifying Serial KISS TNCs. KISS mode can be done
+by most standard TNCs too, and it eliminates the necessity to set the options
+specially in the startup files, at the expense of slightly higher processor
+usage. And of course this enables the use of purely KISS TNCs, such as the one
+described in the November 2000 issue of QST, without a separate program or
+kernel module.
+
+Options
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+Selecting "RELAY Digipeat?" will tell Xastir to digipeat traffic.  It will do
+this if the first unused digipeater call in the path matches your callsign or a
+callsign listed in your Xastir config file ("RELAY_DIGIPEAT_CALLS" line,
+default is "WIDE1-1"). This option is only recommended for base stations in
+regions where there are few other fill-in digipeaters in the area. Consult with
+a local group about the best setting for your region. You may hand-edit the
+Xastir config file when Xastir is not running in order to change this string to
+match your local recommendations. In the U.S., "WIDE1-1" is the recommended
+setting.
+
+The TNC Port is the Unix serial device that the TNC is hooked to.
+Normally you can use /dev/ttyS0 (com1), /dev/ttyS1 (com2) etc.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Now set the bps rate under port settings.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices, and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. Xastir will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just a WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1,WIDE2-2 may work better. Or if you know the call of your closest digi
+you may use XXXCALL,WIDE2-2. Most of you will only need one path. If you are in
+a remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths
+are entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+Next configure the KISS parameters: TXdelay is the time (in 10ms units) needed
+between the keying of the radio and when it is ready to send data. Persistence
+and slottime are the channel access parameters: Slottime is how often the
+channel access algorithm is executed, and should usually be set to 10.
+Persistence is how aggressively your station tries to grab the channel when
+free, and should be ideally set to 255 divided by the number of stations on the
+channel. Full duplex allows the transmission to begin while there are packets
+being received on the channel, this should be disabled in most cases (set to
+"0").
+
+HELP-INDEX>Configure AX.25 TNC Devices
+
+                        Configure AX.25 TNC Devices
+
+This section covers adding or modifying AX.25 TNC devices. AX.25 devices can
+be any device that uses the Linux AX.25 drivers. This is a kernel level
+driver, and device such as a Baycom or a sound modem can be used as a TNC.
+These devices must be set up and running before Xastir can use them.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+Selecting "RELAY Digipeat?" will tell Xastir to digipeat traffic. It will do
+this if the first unused digipeater call in the path matches your callsign or a
+callsign listed in your Xastir config file ("RELAY_DIGIPEAT_CALLS" line,
+default is "WIDE1-1"). This option is only recommended for base stations in
+regions where there are few other fill-in digipeater stations in the area.
+Consult with a local group about the best setting for your region.  This is
+only needed if you are not using any other software that performs this
+function, such as aprsdigi or DIGI_NED. You may hand-edit the Xastir config
+file when Xastir is not running in order to change this string to match your
+local recommendations. In the U.S., "WIDE1-1" is the recommended setting.
+
+Enter the AX.25 Device name you specified in the axports file for this device.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter in up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. Xastir will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just a WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1,WIDE2-2 may work better. Or if you know the call of your closest digi
+you may use XXXCALL,WIDE2-2. Most of you will only need one path. If you are in
+a remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths
+are entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+NOTE: To use AX.25 devices with Xastir you will need to run the program as
+"root". If you want to run Xastir as another user you may want to set the
+suid bit on the Xastir program file. Please see INSTALL file for more
+information; current Xastir drops the extra privileges but has not been audited
+for exploits. Use in this fashion in a multi-user environment at your own risk!
+
+HELP-INDEX>Configure Serial GPS Devices
+
+                       Configure Serial GPS Devices
+
+Set the serial port device for your GPS unit. Common values of /dev/ttyS0
+(COM1) or /dev/ttyS1 (COM2) can be used.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Set system clock from GPS data" will tell Xastir to try setting the
+system's clock to the highly accurate time signal from the GPS receiver. This
+requires root privileges on most systems.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your GPS.
+Most GPS units will use 4800 bps and 8,n,1.
+
+HELP-INDEX>Configure Networked GPS Devices
+
+                    Configure Networked GPS Devices
+
+If you need to share the GPS data with different programs or machines, this
+option is best. Xastir will work with gpsd which will allow several
+connections to share your GPS data.
+
+Set the host name (or IP address) and the port number for the gpsd host on
+your network.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+Selecting "Set system clock from GPS data" will tell Xastir to try setting the
+system's clock to the highly accurate time signal from the GPS receiver. This
+requires root privileges on most systems.
+
+HELP-INDEX>Configure the Internet Server
+
+                         Configure the Internet Server
+
+Internet Servers allow you to send and receive data for all over the world.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+setup communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing Internet
+data can be sent to this device.
+
+Enter the host name (or IP address) and the port number of the Internet
+Server you want to contact. 
+
+Enter a valid pass-code to validate your connection, this will allow your
+data to be transmitted via an IGate. If you don't have a pass-code, use the 
+included "callpass" program to generate one. Note that passcodes are dependent
+on callsigns.  From the src directory, "make callpass" should create the
+executable if it isn't already compiled.
+
+Enter any filter parameters. This causes a special message to be sent to the
+server requesting that the data be filtered in a certain way. The exact format
+of this field is fully specified, please consult APRSSIG for more information.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+HELP-INDEX>Configure a Serial WX Station
+
+                     Configure a Serial WX Station
+
+Set the serial port device for your WX unit. Common values of /dev/ttyS0
+(COM1) or /dev/ttyS1 (COM2) can be used.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your WX
+unit. The Data Type option will allow you to override what type of serial data
+the program will look for. The auto-detect feature will first look for Weather
+data in a binary type as the Radio Shack WX-200 uses. If no binary data is
+found in the stream, Xastir will look for an ASCII type of WX station (like
+Peet Bros.).
+
+Now set the Rain Gauge correction factor. Xastir requires that the rain gauge
+report in .01 inch increments. If the unit reports in .1 inch or .1 millimeter
+increments, a correction must be specified to obtain accurate measurements.
+
+HELP-INDEX>Configure a Networked WX Station
+
+                   Configure a Networked WX Station
+
+Xastir can use WX data servers such as wx200d. wx200d will allow several
+network connections, thus sharing the Weather data with several programs or
+computers.
+
+Enter the host name (or IP address) and the port number of the WX data server
+you want to contact.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+As before the Data Type will override the auto detection.
+
+Now set the Rain Gauge correction factor. Xastir requires that the rain gauge
+report in .01 inch increments. If the unit reports in .1 inch or .1 millimeter
+increments, a correction must be specified to obtain accurate measurements.
+
+HELP-INDEX>Configure an AGWPE Connection
+
+                   Configure an AGWPE Connection
+
+Xastir can use an AGWPE network interface running on a Windows box
+as a TNC interface. It can also use the login/password security that
+AGWPE has built-in, but you must set up the account in the AGWPE
+application with your callsign for the username, in all capital
+letters.  For instance: "AB7CD".
+
+The other options are described in the sections for Serial TNC and for
+Network interfaces.
+
+HELP-INDEX>Configure a SQL Database Connection
+
+                Configure a SQL Database Connection
+                         [Experimental]
+
+Xastir can experimentally store and retrieve station data from either
+a MySQL database or a Postgresql + Postgis database.  See the 
+"OPTIONAL: Experimental.  Add GIS database support." section in the
+INSTALL file for more information.  Station and object data are stored
+as spatial data, and can be retrieved from other GIS applications, for example
+Xastir can write station locations into a Postgis database from which they
+can also be viewed using QGIS.  SQL database connections also allow for the
+persistence of data between Xastir sessions.  All aspects of spatial database
+support, including database structures, are currently experimental and may 
+change at any time.  You may configure multiple SQL database connections, 
+but you should only have one active at a time.  
+
+Before creating a database connection in Xastir, you will need to create a 
+database to connect to, create an appropriate set of tables 
+(see the db_gis_xxxxx.sql scripts in the scripts directory), and add a user 
+with a password and rights to access the database.  For postgis databases
+you may also need to appropriately configure the user in pg_hba.conf
+
+Configuration options on the SQL database dialog include:
+Database: MySQL (lat/long) for very old MySQL databases, 
+          Postgis for postgresql + postgis, and 
+          MySQL (Spatial) for current MySQL databases.
+With tables for: Currently only the Xastir simple schema - a very basic
+          flat table holding minimal information about stations.
+Host: IP address or hostname for the database server, default is localhost.
+Port: Default is 3306 for MySQL and 5432 for Postgresql.  The database can
+          be on a remote server, but the appropriate port will need to be
+          open in any firewalls.  
+Username: Can be unique to your database, e.g. xastir_user
+Password: Unique to your database.  
+Schema name: Your database name. e.g. xastir
+MySQL Socket: check my.cnf, or mysql --help | grep socket
+          Leave blank for postgis databases.
+Reconnect on Net Failure: [Not yet implemented]
+MySQL defaults and Postgis defaults provided by the buttons may
+or may not be correct for your database.  
+
+Three options control the behavior of the SQL Database interface:
+Activate on Startup:  Try to connect to this database and begin storing heard 
+station data as soon as Xastir starts (if store incoming data is also selected).
+
+Store incoming data: Stores each station (including objects and items) report
+as a record in the database.  All stations heard on all interfaces will be 
+stored to the database - if you are connected to internet feeds and leave 
+xastir running this can easily be a million records per day.
+
+Load data on startup: Retrieve all station data from the database
+when restaring Xastir.  Currently the only way to retrieve persistent 
+data from a database.  Will attempt to connect to database and retrieve data 
+independent of the settings of either activate on startup or store incoming
+data.  Due to rounding and conversion errors, non-mobile stations may move 
+slightly.  
+
+The "Most Recent Error" box may or may not contain an error message to help
+identify connection problems.  When Xastir fails to connect to a database, 
+the interface will show ERROR on the interface list, and the most recent error 
+may be shown here.   Running xastir from the console and observing error 
+messages there, or running xastir from the console with xastir -v1 may help
+identify the cause of connection problems, as may examination of the 
+database's error logs.  
+
+You will only be able to configure a SQL Database interface if you have 
+compiled Xastir with support for that DBMS (--with-mysql or --with-postgis).
+
+HELP-INDEX>Symbol Table
+
+These are the symbols that you can select for your station under the "Station
+Information" configuration menu. The current list can be found in the APRS(tm)
+Reference which you could get from http://www.tapr.org
+
+                             Symbol Table
+
+Symbol     Group /                       Group \
+
+!          Triangle w/!                  Triangle w/!
+"          Rain Cloud                    Rain Cloud
+#          Digi                          DIGI
+$          Phone Symbol                  $ Symbol
+%          DX                            DX
+&          GATE-HF                       GATE
+'          Small Aircraft                Aircraft Crash
+(          Cloud                         Cloud
+)          TBD
+*          SNOW Flake                    SNOW Flake
++          Red Cross
+,          Reverse L
+-          House w/omni
+.          Small x
+/          Red Dot
+0          0 in a box                    Circle
+1          1 in a box
+2          2 in a box
+3          3 in a box
+4          4 in a box
+5          5 in a box
+6          6 in a box
+7          7 in a box
+8          8 in a box
+9          9 in a box                    GAS
+:          Fire                          ?
+;          Tent                          Tent
+<          Motorcycle                    Pennant
+=          Train Engine
+>          Car                           Car
+?          POS Antenna                   ? in a box
+@          HURRICANE/STORM               HURRICANE/STORM
+A          First Aid                     Box
+B          BBS                           Blowing Snow
+C          Canoe
+D          D in a circle
+E          E in a circle                 Smoke Stack
+F          F in a circle
+G          Grid Square Antenna           ?
+H          Hotel/Bed
+I          TCP/IP                        ?
+J          J in a circle                 Lightening
+K          School House
+L          Light House                   Light House
+M          Mac
+N          NTS                           ?
+O          Balloon
+P          Police car                    Rx
+Q          Circle with in Circles        Circle with in Circles
+R          RV                            Restaurant
+S          Shuttle                       Satellite
+T          Thunderstorm (cloud/bolt)     Thunderstorm (cloud/bolt)
+U          School Bus                    Sun
+V          VOR TAC                       VOR TAC Symbol
+W          National Weather Service      NWS-Digi
+X          Helicopter
+Y          Sail Boat
+Z          Windows
+[          Runner                        WC
+\          DF Triangle
+]          Packet Mail Box
+^          Large Aircraft                Large Aircraft
+_          Weather Station               WS-Digi
+`          Satellite Dish
+a          Ambulance
+b          Bike                          blowing cloud
+c          DX antenna
+d          Fire dept.                    DX Antenna
+e          Horse                         Sleet cloud
+f          Fire Truck                    FC Cloud
+g          glider                        Pennant (2)
+h          Hospital                      HAM
+i          Island                        Island
+j          Jeep                          Jeep
+k          Truck                         Truck
+l          Small dot                     Small Dot
+m          MIC                           Mile Post
+n          N                             Small Triangle
+o          EOC                           Dot with in Circles
+p          Puppy                         Dot with in Circles
+q          GS Antenna                    GS Antenna
+r          Antenna Tower                 Antenna Tower
+s          Boat                          Boat
+t          TS                            ?
+u          18 Wheel Truck
+v          Van                           Dot with in Circles
+w          H20                           Flood
+x          X Windows                     Red Dot
+y          House w/Yagi                  House w/yagi
+z                                        X Windows
+{          FOG                           FOG
+|          Black Line                    Black Line
+}          TCP                           TCP
+~          Sail Boat                     Sail Boat
+
+HELP-INDEX>What was new in Xastir 1.0
+
+Over the past year, Xastir has been under active development, and this new
+release is the culmination of those efforts. Development has been run by
+Chuck Byam, who agreed to take over for Frank Giannandrea. Many other
+individuals have contributed to this project, and are listed in the AUTHORS
+file.
+
+The Xastir package now uses GNU autoconf to build makefiles and select
+features based on the libraries and software one has installed. No more
+editing makefiles as in previous releases!
+
+Starting Xastir 1.0, one probably won't immediately notice any major
+changes. The familiar interface of previous Xastir versions has been retained
+for the most part. The great majority of the changes are improvements in
+efficiency under the hood:
+* Startup time for the program has been improved.
+* Memory usage has greatly improved, with dynamic allocation of separate
+  station, trail, and weather data on an as-needed basis. No longer will
+  memory be wasted on stationary stations for trail data, nor will non-weather
+  stations waste memory for weather information. With these modifications,
+  Xastir can even be connected to the internet link comfortably on a 16MB
+  machine.
+* Improvements have been made to avoid having to reload maps from disk at every
+  minor change; Weather alerts and changes to the display and tracking options
+  no longer cause the maps to reload, rather the trails and symbols are
+  redrawn alone.
+* Improvements have been made to various dialog boxes that re-drew often, to
+  redraw less often, to allow them to be usable on slower systems. This is
+  also true of tracking a station, with the map redrawing only if the station
+  approaches the edge of the screen.
+Thanks to these changes, Xastir is perfectly usable on slower Pentium(tm)
+machines.
+
+Native GeoTIFF support is now included, and will be compiled into one's copy
+of Xastir if they have the GeoTIFF libraries installed on their system. These
+map files are of very high quality, and are especially useful in search and
+rescue operations. Maps on this format are available from the USGS, and
+commercially on CD-ROM. Xastir understands how to convert from the NAD-27
+datum to the new WGS-84 datum, so maps of both format can be read accurately.
+New shortcut buttons have been added to the map selection dialog to enable
+one to pick all maps of a specific type.
+
+Support for the Festival Speech Synthesis System is now available to announce
+new stations and band openings. The old system of alert sounds has been
+retained as well.
+
+Xastir now supports adding and deleting objects. Finally, Xastir users are able
+to manage resources with this useful feature. Objects are helpful for
+coordinating events, directing travelers, and doing search and rescue work.
+
+The County Warning Area maps that display weather alerts are no longer painted
+onto the maps below, but are shaded onto the maps. While this does make the
+colors unpredictable, it is now possible to see the road-maps below the 
+alert! 
+
+A new and useful feature is the change in the orientation of a symbol based on
+the direction in which it is moving. Even without a trail, a quick glance can
+tell you a mobile station's bearing. There are several more new options in the
+display menu, enabling one to decide more precisely what is displayed and what
+isn't.
+
+Panning and control over the map has been enhanced: There are now arrow buttons
+visible at the top of the screen to pan the map. The map can also be panned
+with the arrow keys, and the zoom can be adjusted with the page up and page
+down keys. There are new option in the click menu, to center the map where you
+clicked or to place an object where you clicked. The panning options in this
+menu have been removed in favor of the new controls at the top of the screen.
+
+Support for altnet has been added, enabling one to have a private APRS(tm)
+network for special events, search and rescue, storm chasing, or whenever else
+the user doesn't want to be bothered by the hundreds of APRS(tm) stations
+around.
+
+There are numerous small changes, both visible and invisible to the user. The
+interface control dialog now has a "Start all" and "Stop all" option, to save
+the user the time of performing these actions for each interface. The station
+setup dialog now shows you your symbol, so you don't have to exit the dialog to
+see which symbol you chose. Several buffer overflows that caused unpredictable
+behavior and/or crashes have been fixed. And many minor improvements have been
+made to the source code to ensure that it compiles correctly on various
+systems.
+
+Enjoy the new Xastir!
+
+
+HELP-INDEX>What was new in Xastir 1.1
+
+                    What was new in Xastir 1.1
+
+This new release, Xastir 1.1, adds significant new features and enhancements
+to the user interface. Unlike 1.0, the interface changes will take some getting
+used to, but the flexibility and versatility of the enhanced interface will
+more than make up for the troubles.
+Among the improvements to the user interface:
+* Keyboard shortcuts for menus and dialogs, menu reorganization, and mouse
+  behavior changes.
+* The ability to move objects or measure distance with the mouse, using the
+  appropriate check-boxes in the toolbar.
+* A scale has been added to allow one to judge distance on a map.
+* Map labels for windows-style APRS(tm) maps are rotated to match the marked
+  map features.
+* The user interface for dealing with objects has been entirely redesigned.
+* Station info boxes can be set to automatically update.
+* Tear-off menus.  Allow you to keep a menu on the screen and play with
+  different options. Tear off a menu by clicking on the dashed-line portion.
+
+Map support has been greatly enhanced, with PocketAPRS, ESRI Shapefiles, GNIS
+labels and many graphics formats with ImageMagick. Additionally, support for
+downloading graphical maps from web-servers has been added, allowing Xastir to
+use online radar, Tiger, and Terraserver maps. 
+
+Xastir 1.1 supports much more of the APRS(tm) protocol than its predecessor:
+* It can add, modify, move and view area objects, signpost objects, and items.
+  These features are invaluable for event coordination and search and rescue
+  use. Objects and items are also periodically retransmitted.
+* Support for displaying position ambiguity squares, pre-calculated radio
+  ranges, Maidenhead grid squares, and weather objects. These features aren't
+  extremely common, but do come up occasionally.
+* Support for the APRS(tm) radio direction finding features. These features
+  are useful for anything from tracking jammers to locating lost hikers. Xastir
+  supports both Omni and Beam reports.
+  
+Other notable improvements:
+* Xastir can now search for a specified location or landmark using GNIS data.
+* Track logs can now be exported to file.
+* Maps can be printed if certain tools and libraries are present.
+* Support for retrieving historical track data from findu.com.
+* Xastir now compiles and runs on Mac OS X, Solaris and FreeBSD with only
+  minimal changes; see README for details. 
+* Several major bugs found in 1.0 have been corrected, including the problems
+  loading DOS maps and the problems with the weather reporting. Other minor
+  bugs and memory leaks have been fixed. And several more errors have been
+  corrected in the parsing routines, so Xastir should remain stable no matter
+  what is thrown at it! 
+
+
+HELP-INDEX>What was new in Xastir 1.2
+
+                    What was new in Xastir 1.2
+
+The latest Xastir release adds numerous new capabilities, keeping Xastir a
+benchmark for APRS(tm) programs on any operating system.
+
+Xastir's hardware support has been enhanced, with
+* Support for Serial KISS TNCs
+* Support for Serial TNCs with GPS on the AUX port
+* Support for using AGWPE as a TNC
+* Support for Dallas One-Wire weather station
+  (see http://melhuish.info/simon/projects/oww/)
+* Support for more weather stations via the wx200d daemon (WX-200/WM-918/
+  WMR-918/WMR-968)
+* Support for the different sized rain gauges of the Peet Brothers weather
+  stations.
+
+Additionally, several bugs in the weather reporting code were corrected, and
+support for setting the system clock based on the GPS was added.
+
+There have been many additions and improvements to the Xastir user interface:
+The most notable is the addition of dead-reckoning. This means that stations
+that are moving will continue to move on your screen in the direction and at
+the speed speed that they last reported. The estimated location can be shown
+with any combination of a ghosted icon, a dashed line from the last position,
+or an arc of expected possible distance and angle.
+
+Also very notable are the improvements to the Map Chooser. Maps can now be
+selected a directory at a time, or individually. And the new map properties
+dialog allows individual control of map layering, map color filling, and
+consideration for auto-maps. Additionally, with extent caching under the hood,
+auto-maps regains much of its formal usefulness even with many maps installed!
+
+Bulletins pop up on screen, and emergency beacons cause an alert with the 
+locate station dialog on hand. These changes are helpful in emergencies and
+event coordination.
+
+Xastir can now be set to use one of several coordinate systems, including UTM,
+dd.ddddd, dd mm.mmm, and dd mm ss.s. This is helpful for coordinating with
+other groups using a different system.
+
+The online Tiger maps can now be enabled from the map menu, and options can
+be adjusted to request maps with just the data you want displayed.
+
+The stations menu has been reorganized, allowing more intuitive filtering of
+stations shown and of accompanying data.
+
+Other smaller interface changes include:
+* The density of the grid-lines can be adjusted with the +, =, and - keys.
+* Objects and item lists have been added to the view menu.
+* Station maidenhead grid squares are now shown in station info and the
+  coordinate calculator.
+* There is a check-box "Track me" to enable easily tracking your own station
+* The length of trails downloaded from findu.com can now be specified.
+* Xastir can now ID via voice IDs or Screen IDs, by editing the configuration
+  file. This is intended for configurations when the Xastir screen is seen
+  remotely via fast-scan TV. 
+* Timestamps are written to log files every 30 seconds of operation, to keep a
+  record of when data was heard.
+* The status bar can display the course/distance to your station when
+  enabled in the file|configure menu.
+* Range scales are now shown opposite the map scale. This is an attempt to
+  standardize various APRS(tm) client approaches to zoom levels.
+
+New additions under-the-hood:
+* Tracked proximity alarms.
+* Export waypoints within proximity boundaries.  Your GPS can show
+  you the locations of APRS(tm) stations as waypoints on the GPS map
+  screen.
+* Export trail as ESRI Shapefile.  New feature if you have Shapelib
+  compiled in.  Station Info->Store Track button also creates a
+  Shapefile map of the station's track now.
+
+The weather reporting features have been improved, with the addition of
+optional wind barbs to weather stations and decoding of storm wind radius data.
+Weather alert shading is now done with pixmap stipples showing the type of
+alert. Further information on an alert is available over the internet from
+the WXSVR by simply double-clicking the alert in the weather alerts list.
+Weather alerts now use the newer ESRI Shapefile-format maps.
+
+Xastir's map support has been improved with enhancements to the ESRI Shapefile
+code to handle point-type ESRI Shapefiles. Additionally, speed improvements
+have been made in the ImageMagick graphical map loading, and many
+color-correction features have been added. As mentioned above, the Map Chooser
+has been greatly improved, and weather alerts use ESRI Shapefile-format maps.
+
+Under the hood, Xastir has had several major improvements:
+
+The messaging system has been largely rewritten, and the annoying timed updates
+to dialogs no longer occur. The new messaging system allows multiple messages
+to be queued, and implements reply-ack's for speed. Xastir also attempts to
+specify a reasonable path for the message based on received messages. This
+improves speed and congestion control. The messaging GUI has been largely
+untouched, and remains high on the list of future improvements.
+
+The build process has been significantly improved; Xastir is now able to be
+built on numerous operating systems with few manual interventions.
+
+Xastir now supports GPSMan/gpsmanshp, allowing the importing of waypoints,
+tracks, and routes from several types of GPS receivers.  This allows you to
+create ESRI Shapefile-format maps out of GPS data.
+
+Xastir now implements SmartBeaconing(tm), which greatly improves trail quality
+and reduces unneeded channel usage. See the "Configure SmartBeaconing" help
+topic.
+
+IGating support has also improved, with the ability to configure a specific RF
+path for IGated packets, and the addition of a 29 second anti-dupe queue to
+reduce unnecessary redundancy on the RF channel.
+
+Map extents and filenames are now cached, so maps will not be loaded from disk
+unless they are on screen. This is a major improvement for map types that did
+not specify this information. Additionally, auto-maps uses this information,
+making it usable even with many maps installed.
+
+Objects controlled by Xastir are now stored in a file, so a restart of Xastir
+will not cause them to be lost. Additionally, Xastir now supports the
+compressed format for objects and items, which can help reduce RF channel
+congestion. It also gives you better location accuracy of the placed objects.
+See the help topic "Configure Default Operation".
+
+Xastir now drops root privileges when not needed if run setuid root. Please
+read the information about this in INSTALL; this change provides only
+limited protection.
+
+Xastir now supports using a private colormap with the command-line argument
+"-i". This is recommended for systems running in 8-bit color mode. 
+
+Additionally, several more buffer overruns and other errors were corrected in
+Xastir's data parser, and numerous other bugs have been fixed.
+
+Enjoy the new Xastir!
+
+HELP-INDEX>What's new in Xastir 1.3
+
+                    What's new in Xastir 1.3
+
+This latest Xastir release greatly improves on the efficiency and usability of
+Xastir, and adds many helpful and often-requested new features.
+
+.geo files can now have REFRESH tags, to specify how often the file is
+reloaded. This is useful for weather radars and other dynamic images. .geo
+files can also have a TRANSPARENT tag to make a certain color transparent, and
+a CROP tag to specify a specific region to display.
+
+Some Opentrac packets are now decoded and displayed. See
+http://opentrac.org/ for more details.
+
+The default main Xastir directory is now /usr/local/share/xastir; please see
+the upgrade notes in README for migration information. This more closely
+mirrors the behavior of other applications.  If you're installing
+from a binary package (rpm/deb/etc), the default install location
+may be /usr/share/xastir.
+
+Xastir efficiency has been greatly improved. Changes in data structures and
+timing values have made this Xastir release the most efficient yet.
+Additionally, map redraw sequences are interruptible, so map panning speed
+has been improved.
+
+dbfawk support - Experimental support for configurable shapefile metadata, in
+an awk-like language. See README.MAPS for more details; this must be turned
+on with a specific switch to the configure command.
+
+GDAL/OGR support - Experimental support for GDAL and loading of native Tiger
+data (.RT1 files). This is automatically enabled if the GDAL library is
+found.
+
+Support for UTM w/special zones and MGRS coordinate systems.
+
+Cad drawing mode allows one to draw regions on your screen using the center
+mouse button. This feature is not yet complete, but is functional.
+
+User interface changes:
+* Several of the menus have been reorganized to have a hierarchical design.
+* Additionally, a few colors have been modified for better visibility.
+* The map label font and style are more configurable
+* The cursor changes to let one know if they're in move object or measure mode.
+* If the coordinate system is set to UTM, and "Map Grid" is selected, an UTM
+  grid is displayed. 
+
+Snapshot mode now generates a .geo file, allowing the image to later be used
+as a map.
+
+Tiger maps have been moved back the chooser, as was the pre-1.2 behavior.
+This is more consistent.
+
diff --git a/help/help-English.dat b/help/help-English.dat
new file mode 100644
index 0000000..a858ac6
--- /dev/null
+++ b/help/help-English.dat
@@ -0,0 +1,3099 @@
+HELP-INDEX>READ ME FIRST - License
+
+                          READ ME FIRST - License
+
+For the most current information please read the README file in the Xastir
+directory.  Also see the LICENSE and COPYING files for additional information.
+
+Remember this program is intended to be used by the HAM community, in the USA
+the FCC restricts you from transmitting over RF if you are not a licensed HAM.
+Users in countries outside the USA should seek their local government 
+restrictions. 
+
+LICENSE:
+
+XASTIR, Amateur Station Tracking and Information Reporting
+Copyright (C) 1999,2000 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
+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.
+
+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.
+
+More information on the program can be found at:
+
+ http://www.xastir.org
+ http://sourceforge.net/projects/xastir/
+ http://xastir.sourceforge.net
+
+There are some mailing lists available that are Xastir-specific.
+Please subscribe to one or both of them for the latest Xastir
+information.  See http://www.xastir.org to subscribe.
+
+For more information on the GNU License look at:
+http://www.gnu.org
+
+
+HELP-INDEX>Welcome! and Notes from the Authors
+
+                      Welcome! and Notes from the Authors
+
+XASTIR, or X-windows Amateur Station Tracking and Information Reporting.
+
+Xastir is an APRS(tm) program that is Open Source and free to use and 
+pass out to others. Currently this program is in development and should 
+not be seen as a finished product! Your help will be needed to make this
+a better program.  If you have programming skills and/or can write 
+documentation, your help may be needed! We have a lot of ideas but very 
+little time, so if you think you can add something to the effort let us
+know!
+
+
+
+APRS(tm) is a Trademark of Bob Bruninga, his home page is at
+"http://web.usna.navy.mil/~bruninga/aprs.html". A great deal of information
+on APRS(tm) can be found in the APRSdos documentation written by
+Bob Bruninga. An additional source of information is the APRS(tm)
+specification, available from http://www.tapr.org .
+
+HELP-INDEX>What's new in Xastir 2.0.1
+(Changes between 1.7 and 2.0.0 were never recorded here,this block
+describes a few of the changes from 1.9.8 to 2.0.0 that occured right
+before release of 2.0.0, but otherwise documents only changes from 2.0.0 
+to 2.0.1)
+
+Added tiling for OpenStreetMaps (2.0.0).
+Added "setlocale()" calls to assure we aren't confused by user 
+LANG variable settings.
+Improved speed of config file processing.
+Fixes for new One-Wire-Daemon protocol, allowing both old and 
+new to work with Xastir.
+Fixed segfaults that could happen when closing list dialogs.
+Fix OSM code to support 16-bit quanta in Graphics/ImageMagick.
+Fixed broken makefile that was ignoring DESTDIR.
+Fixed broken build so internal shapelib builds correctly when
+proj.4 is not installed.
+Add dbfawk files for several generations of new NWS shapefiles.
+Update get-NWSdata to pull current NWS shapefiles.
+Add start/stop files for Kenwood D72 and D710 radios.
+Added a script to convert GeoPDF files to usable GeoTIFF files.
+Make the command to set a TNC into CONVERSE mode a run-time
+configurable option in the TNC Interface Properties dialog.
+Add support for Australian Bureau of Metrology weather alerts.
+Fixes for Davis APRS Data Logger, Davis Meteo and LaCrosse 
+support so it gets rain totals correct.
+Allow "posit interval" in File->Configure->Timing to go all the
+way to zero, meaning "never send posits on a schedule."
+Add signal support so that Xastir will emit a posit when it 
+receives SIGUSR2.  Combined with zero "posit interval," this
+allows Xastir to emit a posit only when told to by an external
+script.
+Fixed error in logic for band-opening alerts (speech and audio
+alarms) so it does not incorrectly report third party traffic
+as a band opening.
+Add "Send Control-E to get GPS data?" to TNC interface 
+properties for the "Serial TNC w/ GPS on AUX port" interface
+type.  Defaults to enabled, which is correct for KPC-3+ TNCs,
+but should be turned off for any TNC that automatically
+streams GPS NMEA strings, such as Kenwood APRS radios.
+Update GPSMAN support to reflect changes in the gpsman command 
+line.
+Add a small delay between sending the converse-mode command
+and sending data for transmission, because KAM TNCs don't
+work if you send the data immediately.
+Fix a bug in the OSM tile download loop that could prevent
+further downloading of tiles if any one tile download fails.
+Fixed a thread-unsafeness bug that could cause Xastir to start
+using corrupted file names when multiple logging options
+(TNC, NET, WX, IGATE, etc.) selected simultaneously.
+Fixed get-fcc-rac.pl script to reflect changes in RAC download
+site.
+
+
+
+
+HELP-INDEX>What's new in Xastir 1.7
+Added REGRESSION_TESTS in order to test interoperability of the
+configure-time flags.
+Added a replacement for malloc() for those cases where the OS
+provides a faulty one.
+Added more to the summary.log file:  The tests and results from
+config.log.
+GDAL configure probe now uses gdal-config if it's in the user's
+path.
+Tweaked configure so that dependent libraries cause other library
+searches to fail, and to provide more user output.
+Added ASCII-art drawing to INSTALL showing most of the library
+dependencies.
+Updated symbols.dat to more closely correspond to the current spec.
+Implemented EMERGENCY BEACON transmit capability under the Help
+menu.
+Added decoding for "EMERGENCY" anywhere in the packet plus any of
+these in the TO: field:  ALARM, ALERT, WARNING, WXALARM, EM.  Any of
+these will invoke the normal emergency popup dialog.
+Waypoint symbols now have a line drawn between them and the station
+transmitting them, per the spec.
+Now using font metrics to determine size of font.  We use that to
+determine size of black rectangle to draw underneath.
+Fixed the Fetch Findu Trail function so that it matches what Findu
+can provide.
+Fixed track->shapefile function so that it works on Cygwin too.
+Added reset button to Change Debug Levels dialog.
+Enable WX Alerts menu item is now grey'ed out if Shapelib isn't
+installed.
+RINO Download timing slider is now visible but grey'ed out if gpsman
+isn't installed.
+Added a custom zoom option to the right-click zoom levels menu.
+Moved the center & zoom dialog to the map menu.
+Changed a memcpy() to an xastir_snprintf() function in alert.c to
+assure that a string is terminated.
+Free'ing some malloc'ed space for cases where hash inserts fail.
+Added probe for sighandler_t definition.
+Changed includes, added leak_detector.h.
+A few small changes here and there to get rid of compiler warnings.
+Freeing some malloc'ed space for the cases where hash inserts fail.
+Fixed initializers for awk_rule[].
+Changed hash add functions so that they do a delete first instead of
+replacing hash values.
+Moved some wx-alert related code to debug level 2.
+Changed leak detect interval from 5 minutes to 60 seconds.
+Fixed a big memory leak in draw_nice_string() function.
+Changed include files around so memory leak detection stuff is in
+leak_detection.h.
+Added new compiler flags and cleaned up the code to eliminate many
+warnings created.
+Fixed Incoming Data dialog code so that packets transmitted to local
+interfaces would appear there.
+TNC/NET toggles work for those now too.
+Fixed memory leak in font metrics code.
+Simplfied get_long()  and get_int() functions and callouts.
+Tweaks for sighandler_t and sigjmp_buf.
+Added a sign-on message for server connects.
+FCC/RAC lookup or Locate Now buttons don't destroy the dialog
+anymore.
+Fixing up strings.h includes.
+Added a new popup for EMERGENCY packets.
+Changed signal() with SIG_IGN to sigignore for some cases.
+Added a test for sigignore() to configure.ac.
+Changes to allow different versions of "gv" to be used.
+Moved "-lgdal" to end of link line to avoid conflict with other
+libraries.
+Added UDP server and client.
+Added more language strings for previously hard-coded values.
+Changed config file get_int and get_long functions to provide better
+output when config file entries are missing or out-of-range.
+We now allow gating to the internet and to RF for user-defined
+packets and telemetry packets.
+Changing to <CR><LF> for the TCP server signon message.
+Changing to timestamp per packet for log files, with long int
+seconds at the beginning.
+Added icon.
+Added support for -geometry command-line parameter.
+Added fast creation of standard SAR objects via mouse menu,
+including adding digits to the end of the object name if name would
+conflict with pre-existing objects.
+
+
+
+HELP-INDEX>What's new in Xastir 1.6
+Fix for DF lines having incorrect angles at times.
+Configurable display of layers for USGS topo maps.
+Better Map Feature Search:  Shows up to 50 matches, user selects
+which one to center map on.
+Configurable "relay" digipeater calls:  Up to 50 callsigns can be
+specified in the Xastir config file to use for relay digipeating.
+"WIDE1-1" is now the default.
+Added support for Web Map Service (WMS).
+Tweaked the GPGGA and GPRMC GPS sentence decoding.
+Added speed-ups for lat/long geotiff's.
+Added Aloha circle.
+Added new #defines in interface.h for specifying "conv" or 'k'
+command to TNC.
+Added new tnc-startup file for TAPR-2 style TNC's.
+Added transparency capability to WMS.
+Fixed digpeating code for "wide1-1,wide2-1" case.
+Fixed some compile errors that are seen on FC4 and OSX Tiger.
+Added new terraserver .geo file options.
+Changed Map Properties "fill" option to allow NO/YES/AUTO.
+Auto uses dbfawk if present, no/yes force fill to that state.
+Fixed some #ifdefs here and there so that compiles will work if
+some libraries aren't present.
+Added map caching for nearly all internet maps, plus two new toggles
+on the map menu for clearing out current-view maps or all maps from
+the cache.
+Moved Tigermap timeout slider to main timing dialog, renamed it, and
+made it function for ALL internet map fetches.
+Added timestamps to x_spider log messages.
+A fix for the emacs tempfile bug w.r.t. dbfawk files went in, but
+hasn't been verified to have fixed the problem yet.
+More bulletproofing added to the map_cache code.
+Fixed a compile problem that happens if ImageMagick isn't installed.
+Changed stipple style to solid for polygons drawn with dbfawk.
+Another fix so that linking works without map caching. 
+
+
+
+HELP-INDEX>What's new in Xastir 1.5
+Optional Rtree shapefile extent caching
+Optional berkelydb-based internet map caching
+Modifier keys fix
+Improvements to the message GUI
+Tactical call support re-written, hashtable based
+Warnings on crazy paths
+Hashtable weather alert speedups
+Dead-reconing for Objects/items
+Igate of specific stations (in the nws-stations.txt)
+Fixed DF object properties
+Measure function more accurate
+Decoding for "Position with Timestamp no APRS messaging" packets.
+More thorough checking for scanf/sscanf/fscanf function calls
+Fixing 100% humidity for some weather stations, plus added more data for Davis stations
+Changed active internet connection check from 1 min to 5 minutes
+Fixed decoding of compressed DF objects
+Fixes to allow new WHO-IS server to be used from Xastir
+Got rid of extra 0x00 byts between transmitted KISS frames
+Tweak to not start an interface upon changing its properties
+Tweaks to allow use of http proxy servers for online map accesses (.netrc file)
+
+
+
+HELP-INDEX>What's new in Xastir 1.4
+Comment fields for interfaces
+split_gnis and ozi2geo scripts, need to add to section on scripts
+serial mkiss interface
+move objects without confirm
+new timing params w.r.t. trails, need to add to config|timing part
+geo-coder (already in docs)
+exponential/random back-off for almost everything
+dbfawk default, memory leaks fixed
+click+drag zoom boxes
+tactical callsign support
+numerous small memory leaks, uninitialized data uses, and similar bugs fixed. 
+GPS quality info
+RINO waypoints downloading
+label trackpoints
+comment/status timestamps
+listener socket/ability to act like a limited internet server
+
+
+HELP-INDEX>Starting Xastir for the first time
+
+                    Starting Xastir for the first time
+
+When first running Xastir, you should start it from a terminal window so
+that any warning or error messages can be seen. On most systems a path is
+set up to run programs in /usr/local/bin and all you need to do is type
+"xastir &" at the prompt. On systems that do not have this path installed
+type "/usr/local/bin/xastir &" to start the program.  The '&' character
+will cause Xastir to start in the background, leaving the terminal window
+available for other uses.
+
+You may also set the language choice at this time. To set the language or
+change the current language choice, call Xastir with the option '-l':
+
+    xastir -lEnglish
+
+Language options are:
+    xastir -l Dutch
+    xastir -l English
+    xastir -l French
+    xastir -l German
+    xastir -l Italian
+    xastir -l Portuguese
+    xastir -l Spanish
+    xastir -l ElmerFudd
+    xastir -l MuppetsSwedishChef
+    xastir -l OldeEnglish
+    xastir -l PigLatin
+    xastir -l PirateEnglish
+
+The chosen language will be stored in your config file, so it is preserved
+for the next time you call Xastir.  For new installs Xastir will default to
+English until you change the language with this command line option.
+
+The menus on the top may be accessed with the mouse or with keyboard
+shortcuts. The keyboard shortcuts may not work correctly with num-lock on.
+
+You will need to configure interfaces in order to actually use Xastir.
+Interface configuration is detailed under the "Configuring Interfaces" help
+topic and its subtopics.
+
+If you are operating in a situation where a coordinate system other than the
+default DD MM.MMMM system would be helpful, you may select your preferred
+system by going to File|Configure|Coordinate system.  Any of the supported
+coordinate systems my be used as input by using the Coordinate Calculator.
+
+HELP-INDEX>Configure the Station Information
+
+                         Configure the Station Information
+
+Click on File, then Configure, then Station.
+
+Fill in your Amateur Station call sign.
+
+Fill in your station position if you are not using Xastir with a GPS 
+unit. You can locate your general position on the map with Xastir and
+use the position given by the cursor placement over the map. This
+position will be viewable in the box at the bottom of the Xastir screen
+2nd from the left, whenever the mouse is over the drawing area. You can also
+choose "Move My Station Here" from the right-click menu while your mouse is
+over your location. If you have a GPS you can skip this and set up the GPS
+later.
+
+"Send Compressed posits", if selected, will transmit in the newer compressed
+format. This format will reduce the amount of data on the air, thereby
+increasing the capacity of the APRS(tm) network. The maximum precision of the
+transmitted position is also higher. Some older programs, including recent
+versions of WinAPRS, do not decode this format yet. Findu.com might also have
+trouble with it.  We transmit course/speed in this format but not altitude.
+In order to send course/speed AND altitude requires adding nine characters to
+the packet which negates part of the reason to use compressed posits.
+
+To select a symbol to be used for your station you need to specify
+a group and a symbol character. You can manually fill in these fields,
+or press select to graphically choose a symbol. There are two groups
+of symbols available. A text description of each symbol can be found
+in the "symbol table" help topic.
+
+For some symbols of the secondary group you can specify an overlay.
+With that a symbol will be displayed together with an additional
+overlay character, e.g. a car symbol with the number 1 overlay-ed on
+top of the symbol.
+
+For using overlays you need to select a symbol from the secondary symbol
+table and enter the overlay character to be shown in the group/overlay
+field. Only numbers and uppercase characters are allowed as overlay
+characters. According to the APRS(tm) specification not every symbol can
+be overlay-ed, Xastir doesn't enforce this, but some other programs may.
+Note that not all of the symbols have been implemented in the graphics
+chooser yet, and some of them are not per the APRS(tm) spec yet.
+
+Next, enter the data for the power/height/gain of your station. This
+is useful information but is not required; simply select "Disable PHG"
+to disable it. These choices present a granular representation of your
+stations range. Select the combination of values closest to the
+description of your station.  Please use height above average
+terrain (HAAT) for the height value.  Do NOT use average height
+above sea level or height above ground.  All values must be
+specified if you wish to transmit PHG information.
+
+Another option would be to specify the RNG in the comment field in miles
+instead of using PHG. See the APRS(tm) spec for details.
+    
+For Gain use the gain of your antenna in dBi. 
+(FIXME: dBd? spec is unclear, I think it's implying dBi because it says "in
+absence of any data, stations are assumed to be running 10w to a 3dB omni at
+20ft. A typical omni is only 3dBi.....) 
+
+Note: The gain setting is really intended for vertical antennas; the gain
+setting for a beam should be quite a bit below the forward gain of the beam.
+This is because with directivity set, the PHG circle is only offset by 1/3rd
+of its size toward the specified direction. Setting gain higher will enlarge
+the whole circle unrealistically, rather than increasing the directivity.
+There was talk several years ago about amending the specifications to better
+deal with beam antennas, but nothing was changed.
+
+Enter a comment, not required but it will add insight on your station.
+A common thing to enter here is your preferred e-mail address.  It will
+be transmitted along with your posits.
+
+Position ambiguity will allow you control how accurately you transmit your
+position. A setting of none will allow your station to transmit the exact
+position you have entered or received from a GPS. The other choices will
+place you somewhere in the range of the choice you selected.  Note that
+this may throw some non-spec compliant stations for a loop.  Findu.com
+doesn't understand position ambiguity.
+
+Clicking OK will save your changes, Clicking on Cancel will keep the
+previous settings.
+
+HELP-INDEX>Configure Default Operation
+
+                        Configure Default Operation
+
+Click on File, then Configure, then Defaults.
+
+This page sets up some standard defaults for the program operation. 
+
+Transmit Station Option sets the type of packet your station will transmit 
+its data as.
+
+IGate Options will set your station up as an Internet-RF gateway. This option
+should be used with caution; As a ham you are responsible for the data that
+comes in via the Internet and is transmitted via RF. You also will need to
+choose an IGate option on each interface in order for the IGate to function.
+If you want to have your IGate forward NWS weather alerts to RF, you must
+create a ~/.xastir/data/nws-stations.txt file listing each call or NWS station
+(like "PHISVR") that you would like to transmit via RF.  This feature also
+works for gating specific callsigns to RF.  Bob Bruninga, WB4APR, recommends
+gating these calls to RF: SCOUTS, SATERN, KIDS, REDCROSS, FOUR-H, YOUTH, GUARD,
+MARS, JOTA.  See his link: "Generic Callsigns for National Events" off this web
+page for his current list of recommended callsigns:
+
+        http://www.ew.usna.edu/~bruninga/aprs.html
+                     
+"Transmit Compressed objects/items?", if selected, will transmit objects and
+items in the newer compressed format. The maximum precision of the transmitted
+position is higher, and the transmission is shorter, but some older programs do
+not decode this format yet.  Currently this only compresses "standard"
+objects/items with an optional speed/course.  It won't compress area, signpost,
+or DF objects/items, and won't currently represent altitude in "standard"
+objects/items.
+
+"Pop up new Bulletins", if selected, will cause Xastir to bring up the bulletin
+dialog when bulletins within the configured range are received. "View 
+zero-distance bulletins" will cause bulletins with no known location not to
+be displayed or cause pop-ups.
+
+"Warn if Modifier keys" will cause Xastir to print a warning if you attempt to
+use Xastir while num-lock, scroll-lock, or caps-lock is engaged. Some users
+report the screen blanking on them and similar problems when they attempt to
+use Xastir with one of these modifier keys on.
+
+You can also select "Activate alternate net?" and choose an altnet call from
+this dialog. Altnet allows you to have a private APRS(tm) network among the
+stations that also have altnet configured, and have the same altnet call
+entered.
+
+"Disable Posit Dupe-Checks" disables the check for duplicate copies of a
+position. This should only be used when a station might return to exactly the
+same position (within 60' or so for non-compressed positions) and you wish to
+see the duplicate positions and/or tracks displayed on the map.  This option
+is almost never needed in practice, but can be useful for special events like
+search and rescue operations.
+
+"My Trails in one color" shows all trails with your callsign but different 
+ssids in the same color.  With My trails in one color selected, mycall-1 
+and mycall-2 are shown in the same color.  With My trails in one color
+unchecked, mycall-1 and mycall-2 are shown in different colors.  
+
+"Load predefined objects from file" and the pick list which follows it allows 
+you to replace the list of Predefined objects that are accessible from the 
+right click pop-up menu with your own list of objects.  A set of standard
+Search and Rescue objects and a set of typical public event objects are 
+supplied in the predefined_SAR.sys and predefined_EVENT.sys files.  You may
+also use these files as a template to create a predefined_USER.sys file.  
+See the instructions in the predefined_SAR.sys and predefined_EVENT.sys file
+for details on how to define objects for a custom predefined objects menu.
+If both "Load predefined objects from file" is selected and a file that 
+exists in the xastir/config/ directory is selected, then the objects defined
+in that file will be shown on the Predefined objects menu.  The unaltered
+predefined_SAR.sys file defines the same objects as the default menu.   
+
+
+HELP-INDEX>Configure Timing
+
+                            Configure Timing
+
+Click on File, then Configure, then Timing.
+
+Posit TX Interval specifies how often your station's position will be
+transmitted.  For fixed stations a good recommendation is every 30 minutes,
+and definitely no less than 10 minutes.  Mobile stations may wish to use a
+faster rate.  Note that if you're using SmartBeaconing, this slider is
+ignored.
+
+Object/Item Max TX Interval is the maximum interval used for sending out
+objects and items. Try to keep these intervals reasonable, as transmitting
+to a long path every 5 minutes will really take up a lot of the air time.
+A decaying interval algorithm is triggered any time an object is created,
+modified, or killed.  The transmit interval will increase until it hits the
+max interval indicated by the slider.
+
+GPS Check Interval will set the interval of time to look at the GPS for new
+data. This is available for stations using an HSP or shared cable with their
+TNC.
+
+Dead-Reckoning Timeout adjusts how long a position is assumed valid for the
+purpose of estimating its current position.
+
+New Track Time adjusts how many minutes must elapse before a new
+separate track is started.  Caution: setting the new track time to 0 will turn
+off the display of all tracks.
+
+RINO -> Objects Interval adjusts how often waypoints are downloaded from an
+attached Garmin RINO radio/GPS unit.  APRS(tm) Objects are created out of any
+waypoints beginning with "APRS".  The "APRS" prefix is removed when creating
+the Object names.
+
+Station Ghosting Time specifies the ghosting interval. Stations that have not
+been heard in the given period will appear ghosted on screen.
+
+Station Clear Time specifies when a station will be removed from the screen.
+
+Station Delete Time specifies the number of full days before data from a
+station will be entirely removed from the Xastir database.
+
+Serial Inter-Char Delay specifies a wait time in milliseconds between each
+character sent to an attached TNC.
+
+New Track Interval (degrees) specifies distance in lat/long degrees at which
+a new track segment is started.   Caution: setting new track interval to 0
+degreees will turn off the display of all tracks.
+
+Snapshot Interval (minutes) specifies how often snapshot files will be
+written if either File->PNG Snapshots or File->KML Snapshots are selected.
+
+HELP-INDEX>Configure Audio Alarms
+
+                           Configure Audio Alarms
+
+Click on File, then Configure, then Audio Alarms.
+
+To use this option you must have a sound card and a program that will play
+wav files. The Audio Play Command should contain the program you want to
+execute to play the audio file (and any command line options). That of
+course doesn't work if the only sound card in the system is used for a
+soundmodem...
+
+Each type of alert has a check-box to enable it. The fields will contain the
+name of the file to play. Fields under the option will set parameters for the
+option.
+
+The current choices are:
+Play message on hearing a new station.
+Play message on receiving a new message.
+Play message on receiving data from a station within the min/max distance of
+     your proximity settings. 
+Play message on receiving data from a station (via TNC) within the min/max
+     distance of your band opening settings.
+Play message on receiving and displaying a new weather alert.
+
+There is a standard set of sounds available most places where Xastir can be
+obtained, please see the file INSTALL for more information.
+
+HELP-INDEX>Configure Speech
+
+                       Configure Speech Synthesis
+
+To use this option you must have a sound card and the 'festival' speech
+synthesis software installed.  Install Festival and start it in 'server' 
+mode prior to starting up XASTIR.  The normal command for this is 
+"festival_server &".  If you use the "festival --server" option instead (old
+method), you may run into problems with connections getting rejected by the
+server.
+
+Once you have festival installed, Xastir will have the ability to speak using
+the following choices:
+
+New Station       - Announce the call of a new station.
+New Message Alert - Announce the arrival of a new message.
+New Message Body  - Speak the contents of a message.
+Proximity Alert   - Announce when receiving data from a station within the
+    min.max distance of your proximity settings.  This option uses the 
+    proximity settings found in the Audio Alarms menu.
+Tracked station Proximity Alert - Announce when receiving data from a
+    station within the min.max distance of the tracked station. This option
+    uses the proximity settings found in the Audio Alarms menu.
+Band Opening      - Announce when receiving data from a station (via TNC) 
+    within the min/max distance of your band opening settings.  This option 
+    uses the distance settings found in the Audio Alarms menu.
+New Weather Alert - Not implemented yet.
+
+Info on Festival may be obtained from: http://www.speech.cs.cmu.edu/festival/
+
+HELP-INDEX>Configure Smart Beaconing
+
+Click File, then Configure, then Smart Beaconing.
+
+The main "Enable SmartBeaconing(tm)" Will cause Xastir to transmit positions at
+various rates and locations based on the movement of the station. It creates
+more realistic trails and makes dead-reckoning much more accurate. This option
+is only useful in a mobile station with a GPS attached.
+
+There are several options available to customize the operation of
+SmartBeaconing:
+
+High rate
+The interval (in seconds) at which beacons are sent when the speed is above the
+High speed setting.  This parameter is also used to compute a beacon rate based
+on speed when traveling between the high and low speeds.
+
+High speed
+The speed threshold that will cause beacons at the rate specified above.
+
+Low rate
+The interval (in minutes) at which beacons are sent when the speed is below the
+Low speed setting.  Basically consider this to be the stopped beacon rate.
+This parameter is not used at all when traveling at a rate of speed higher than
+"Low speed".
+
+Low speed
+The speed threshold that will cause beacons at the rate specified above.
+
+Minimum Turn
+The minimum degrees that corner pegging can occur at "High speed" or above.
+Lower speeds will require more degrees of turn to trigger a posit, based on
+the value of "Turn Slope" below.
+
+Turn Slope
+Fudge factor for making turns less sensitive at lower speeds.  The parameter
+doesn't have any units. It ends up being non-linear over the speed range the
+way the original SmartBeaconing(tm) algorithm works.
+
+Wait Time
+The time in seconds between corner-pegging beacons, prevents multiple
+beacons in short succession.
+
+HELP-INDEX>Configure Units of Measure
+
+                        Configure Units of Measure
+
+The default selection is for the Metric System: mm, cm, km/h, etc. To select
+English units, inches, feet, MPH, etc. Click on File, then Configure, then
+toggle the "Enable English Units" check-box.
+
+HELP-INDEX>Save Config Now!
+
+                        Save Config Now!
+
+This button will save all of the current configuration to the config file.
+Note that when Xastir is closed, it also saves configuration to the config
+file.
+
+HELP-INDEX>Bottom Status Bar
+
+                         Bottom Status Bar
+
+At the bottom of the window various status messages are available:
+
+In the first box on the left general status messages are displayed for a
+short time.
+
+The second box displays the current lat/long or UTM, and Maidenhead grid
+square position of the mouse over the map. If file|configure|Dist/Bearing
+Status is selected, this box will also contain the course and bearing of
+this position relative to your station.
+
+A third box is used to display how many stations are on screen, and how many
+are in the database.
+
+The fourth box will display the current zoom level and will display "Tr" if
+the station tracking is on.  At some zoom levels the Tr is not
+displayed properly due to the size of the box. 
+
+The fifth box indicates whether logging is enabled.
+
+The last area will display the device status for each interface. Each will
+display in order first to last or 0 to 9. The interface status is separated
+into three areas, top device type, center data flow, and bottom interface
+operational status.
+
+The device type will show what interfaces are configured. The color will
+show what type of device the interface is configured for. Blues are for
+the various TNC devices; Greens will show the GPS devices; Yellow for
+Internet Servers; Orange for WX interfaces.
+
+The center will show data flow in (arrow pointing left) or data flow out
+(arrow pointing right) for that interface.
+
+A green box at the bottom will show if that interface is active. A red
+box will show if the interface is active but in an error condition.
+Otherwise nothing will show if the interface is not active.
+
+HELP-INDEX>Moving the Map and the Options Menu
+
+                    Moving the Map and the Options Menu
+
+Map movement is very simple, ease and quickness of movement is dependent on
+your processor speed and the amount of detail you load. Hint: You can
+disable all maps in the maps menu in order to move around quickly, then
+enable maps again.
+
+Zooming:
+Zooming can be accomplished by right clicking on the map (and holding the 
+button down). This will bring up an options menu, with choices to zoom in or
+out a single level, or to change to one of the preset zoom levels.
+
+All zooming functions from the options menu will zoom in or out at the point
+on the map where you clicked the right mouse button. Zoom levels have a cascade
+menu. Levels 1-64 are for very local areas and levels 256 and above are for
+large areas. The lower number the level, the more local the area.
+
+A quicker zoom in function is to push and hold the left mouse button, drag it
+across the area of interest and let go.  The map will zoom to approximately
+the size of the square you just described with the mouse drag operation. The
+"move" and "measure" toolbar check-boxes must be disabled for this feature to
+work. Clicking the middle button zooms out with a factor of 2, centering
+where you clicked as well.
+
+The map can also be zoomed with the keyboard Page-Up/Page-Down keys, or the "In"
+and "Out" buttons in the toolbar. The zooming in this case keeps the same map
+center (no centering).
+
+Panning/Centering:
+The map can be centered at a specific location by choosing center in the
+right-click options menu.
+
+Panning is also accomplished by using the options menu, or by using the arrow
+buttons on the toolbar. The map position will shift a portion of a screen.
+Enough data from the previous screen should be available to re-orient yourself.
+
+The map can also be panned with the keyboard arrow keys.
+
+More About Options Menu:
+
+Map Display Bookmarks
+See the help topic "Creating and using Map Display Bookmarks"
+
+The "Station Info" selection on the options menu will look for the station
+closest to where you right-clicked the mouse. If more than one station is
+close to that position a "Station chooser" list will appear, then you can
+choose what station's data you want to look at. If only one station is close
+to the mouse pointer then that station's data will display immediately. For
+mobile stations with a lot of track data this could need some time on slow
+computers. Note that expired stations still have their data stored in the
+Xastir database, and if one knows a station's former location, one can still
+view its info in this manner. Use the "Display Expired Data" option
+to display some data that disappears for ghosted stations, like
+speed/altitude, etc.
+
+With "Last Pos/Zoom" you can restore the previous map view by restoring the
+previous values of the map zoom and centering values.
+
+For Object and Item information, please see the help topic "Objects and Items"
+
+Draw CAD objects lets you create polygons on screen, for tactical or
+presentation use. This feature is still under construction.
+
+"Move my Station here" Allows you to move your station to a specified map
+location without editing the station configuration.
+
+HELP-INDEX>Objects and Items
+
+A station could place several different objects on the map, with their
+position transmitted to other stations. The object names are less restrictive
+than the normal station names.
+
+Objects and items are nearly the same things, but their use could differ a bit.
+Objects are generally used for moving or variable things such as thunderstorms,
+while items are generally used for more inanimate things, such as water
+stations. Because items may not be decoded by some flavors of APRS(tm)
+programs, objects are often used for inanimate things, too.
+
+Besides normal objects with a symbol at its position there are some special
+objects available. Area objects are useful for a variety of operations in
+which you want to draw or highlight an area of interest on the map. They can
+also be used to draw trails/roads/boundaries, watch boxes for severe weather,
+runways, perimeter of a search area or of a public service event, areas of
+damage, areas to stay out of, buildings that aren't on the map, checker/chess
+boards for gaming on APRS(tm). :-)  Note that area objects are not
+implemented on all versions of APRS(tm) programs, and some of the details of
+how they are displayed may also be different on other programs.
+For the other three, probability circles, signposts and DF objects, see below.
+
+Objects/Items are retransmitted at a decaying rate up to the max interval
+specified in File|Configure|Timings.  "killed" objects/items are also
+retransmitted in this manner until they expire from the queue (currently 20
+transmits).  Objects/Items are persistent across Xastir sessions, and are
+stored in ~/.xastir/config/object.log. This file may be cleared by selecting
+"Clear Object/Item history" from the Stations menu.
+
+The Object/Item creation option in the right click menu will bring up a dialog
+with the position of your object filled in based on where you clicked the
+mouse. You may fill in the details, and add an object/item from this menu.
+
+The Object/Item modification option brings you the object modification dialog.
+It is similar to the object creation dialog, except the object's current
+information is already filled out, and the object's name and a few of the
+other options can't be changed. You could also delete the object with this
+option.
+
+Objects and items can be moved with the mouse if the "Move" check-box on the
+toolbar is enabled.  
+
+The Predefined Objects option in the right click menu allows you to rapidly
+place standard Search and Rescue objects without having to go through the 
+Object/Item creation dialog.  These objects include standard Incident 
+Command System symbols for ICP, Staging, Base, and Helibase, as well as
+SAR objects for PLS, IPP (with 4 area circles), and LKP If an object of the 
+same name as an object you select off the list allready exists, a new 
+object will be created with a number appended to the end.  For example, 
+the first time you select Staging from the Predefined objects menu, an
+object named Staging will be created.  If you then create an additional 
+Staging object from the Predefined objects menu, it will be named Staging2. 
+Heli- (and user defined objects ending in a "-") will be created as Heli-1,
+Heli-2, Heli-3, etc.  If you have recieved one of these standard objects that 
+was transmitted by another station, your first object will be named with an 
+appended number.  You may wish to assign a tactical call to your object in 
+this situation (for example, replacing ICP2 with a tactical call).  
+
+The Predefined Objects menu is customizable by modifying the files 
+predefined_SAR.sys, predefined_EVENT.sys, and predefined_USER.sys, and then
+selecting one these files through the File/Configuration/Defaults dialog. 
+See the predefined_SAR.sys file for details.  
+
+Description of the entries in the object dialogue:
+
+= Signpost =
+This makes the object a signpost object. These signs can contain one
+to three characters, and currently appear in Xastir as a blank sign.
+Station Info shows the value contained on the sign.
+
+= Area Object =
+This makes the object an area object, and enables the area object controls
+described below.
+
+= DF Object =
+This is a direction-finding report. Enabling it allows you to choose Omni or
+Beam report, and allows you to put in the specifics for each.  See:
+    http://web.usna.navy.mil/~bruninga/dfing.html
+and the APRSdos documentation for details on these useful techniques.
+(FIXME: Separate section on DF'ing techniques?)
+
+= Probability Circles =
+This allows you to define the radius (in miles) of two circles centered on 
+the object or item.  Min is the radius (in miles) of the smaller, inner 
+circle, and Max is the radius (in miles) of the larger, outer circle.  
+These circles are drawn in red.  They can be used to assist in planning 
+Search and Rescue operations.  To create more than two circles, add additional
+probability circle objects to the same location.  Probability circles may not
+be displayed by other client software.
+
+= Name =
+This is the name of the object or item. It may be up to 9 characters long,
+with spaces allowed inside the name. When modifying an object, this may not
+be changed. To rename an object you must delete the original and then create
+a new object. Note that if you select Signpost/Area Object/DF Object that
+this field and perhaps others are cleared. Enter the name AFTER you've
+selected the type of object it will become.
+
+= Station Symbol =
+You may select a symbol for the object. Press select to choose graphically,
+or see the symbol table help section for descriptions of each symbol.  Note
+also that area objects, signpost objects, and DF objects have special fixed
+symbols and therefore can't be selected here.  Those particular symbols get
+automatically assigned when you change to that type of object.
+
+= Location =
+The location of the object is specified here. If you selected "Create 
+Object/Item" from the right-click menu, the location you clicked will be filled
+in. If you moved an object with the mouse, the new location will be in these
+fields.  You can also type in a location, for instance you may be placing an
+object from an over-the-air voice report.
+
+= Generic Options =
+You may specify the speed, direction, and altitude of objects here. Some object
+types cannot have a speed or direction, in which case the fields are grayed
+out.
+
+= Signpost Text =
+If the object is a signpost object, you may specify the 1 to 3 digit
+number that appears on the sign here.  Note that Xastir doesn't display
+signpost objects properly yet.
+
+= Area Object =
+Area Objects are used to highlight specific parts of maps, or to draw extra
+detail onto maps. This will be done with the following entries:
+  = Bright Color =
+    Use the brighter version of the colors allowed.
+  = Color-Fill =
+    The area should be filled, not just outlined. This may be useful to
+    exclude an area from a search or other event.
+  = Object Type =
+    Choose from the geometric shapes allowed.
+  = Object Color =
+    Choose the color in which the object will display. This is also affected
+    by the "Bright Color" option above.
+  = Object Offset Up =
+    In hundredth of a degree latitude.  An unfortunate detail of the spec,
+    and hard to calculate easily.  Suffice it to say that you can change
+    the size of the object once you place it.
+  = Object Offset Left except / =
+    In hundredth of a degree longitude.  See above.
+  = Object corridor =
+    This is the width of a line area object. Useful for runways, weather
+    watch boxes, describing an area of interest or an area of exclusion, etc.
+
+Always delete your objects and items when you are done with them!
+Don't just allow them to expire from your cache, as they may hang
+around on other peoples' screens for an extended period.
+
+
+Description of weather watch boxes:
+
+Watch boxes and "areas of maximum concern" (AOMC) generated by the WXSVR
+(http://wxsvr.net/) are colored as follows:
+
+  Yellow dashed = Severe Thunderstorm Watch  (looks like crime scene tape)
+   Yellow solid = AOMC for Severe Thunderstorm Warning
+     Red dashed = Tornado Watch
+      Red solid = AOMC for Tornado Warning.
+   Green dashed = Mesoscale (larger) discussion area
+    Blue dashed = Test Watch
+     Blue solid = Test Warning
+
+HELP-INDEX>CAD Objects
+
+                     CAD Objects
+
+[CAD object support has moved from the right click menu to 
+Map/Draw CAD Objects]. 
+
+CAD object support is preliminary at this time.  Features and the user 
+interface are subject to change.  
+ 
+CAD objects are arbitrary shapes that you can draw on maps in xastir, but 
+can't transmit by APRS.  
+
+Currently supported CAD objects are:
+Polygons: Closed areas of at least three points.  
+
+To create a CAD object, first press the Draw radio button on the toolbar.
+This will change the cursor to a pencil.  Begin drawing a polygon by 
+clicking with the middle mouse button (or both buttons on a two button mouse,
+for which you will need to have three button mouse emulation enabled).  This 
+places a point on the map.  Now move the cursor somewhere else (the normal
+left click/right click navigation and zoom functions still work normaly) and
+click the middle mouse button again.  This draws a line between the two points
+you have selected.  Middle click again to draw another line segment and keep 
+repeating until you have drawn all except for the closing line segment of your
+polygon.  To close the polygon, select Map/Draw
+CAD Objects/Close Polygon.  This will close your polygon and bring up a dialog
+that will allow you to enter a name, comment, and probability for the polygon.
+
+When you have finished drawing CAD objects, exit the CAD drawing mode by 
+deselecting the Draw radio button on the toolbar.
+
+CAD objects can be edited from the View/CAD Polygons menu and from the 
+Map/Draw CAD Objects/CAD Polygons menu.  CAD objects can be  deleted from the 
+Map/Draw CAD Objects/Erase CAD Polygons menu.
+
+HELP-INDEX>View Menu
+
+                     View Menu Options
+
+The View menu presents various ways to look at data in Xastir.
+
+Bulletins
+This is the APRS(tm) bulletin board, where important announcements are posted.
+If you are connected with the internet interface, it is a good idea to set the
+range field to a few hundred miles, to ignore posts from other portions of the
+world. "0" in the range field means the entire world. Click the "Change range"
+button to make changes to this field effective. Xastir currently does not
+support sending bulletins. Incoming bulletins will open this dialog
+automatically if you select "pop up new bulletins" in the Configure|Defaults
+dialog.  The "View zero-distance bulletins" button enables viewing bulletins
+for which you don't have a range yet (they haven't sent a posit yet, but you
+received a bulletin from them).  If this is unchecked, you must get a position
+from a station, and the station must be within the range selected (or range
+must be set to zero), in order for the bulletin to be viewed.
+ 
+Incoming packet data
+This displays the incoming data on your TNC or internet interface. The radio
+buttons below select if you want to see only TNC data, only internet data, or
+both.
+
+Mobile Stations
+This is a list of stations that are moving. Stations qualify for this list if
+they have moved (more than one position received for them), the symbol of the
+station is not considered. Information shown includes course, speed, altitude,
+position, number of packets received, number of visible GPS satellites, course
+from your station, and distance from your station. 
+
+All Stations
+This option displays a table of all stations sorted alphabetically. It includes
+the number of packets heard, the time the station was last heard, the path that
+the most recent packet took, the PHG, and the comment of the station.
+
+Local stations
+This option displays only stations that are heard via your TNC. It includes
+the number of packets heard, the time the station was last heard, the path that
+the most recent packet took, the PHG, and the comment of the station.
+
+Last Stations
+This option displays a table of all stations sorted from most recently heard
+to least recently heard. It includes the number of packets heard, the time
+the station was last heard, the path that the most recent packet took, the PHG,
+and the comment of the station.
+
+Objects & Items
+This option displays only objects and items. It includes the number of packets
+heard, the time the objects/item was last heard, the path that the most recent
+packet took, the PHG, and the comment of the object/item.
+
+Own Objects & Items
+This option displays only objects and items that you control (i.e.: Have sent
+the most recent update for). It includes the number of packets heard, the time
+the objects/item was last heard, the path that the most recent packet took, the
+PHG, and the comment of the object/item. A ghosted icon indicates that the
+object has been deleted.
+
+Weather Stations
+This option displays a table of all the APRS(tm) weather stations and their
+data. Data includes wind course, wind speed, wind gust speed, temperature,
+humidity, barometric pressure, rain in the past hour, rain since midnight,
+and rain in the last 24 hours.
+
+Own weather data
+Displays your weather data if you have a weather station and have configured
+Xastir to access it.
+
+Weather Alerts
+Displays weather alerts received, including the alert flags, alert source/type,
+alert destination, expiration, message, and effected location. This data
+is used for the alert highlighting. Double-clicking on an alert will request
+further information about it via finger from the online WXSVR. This only
+works if you have internet access; future versions may access this data over
+radio as well.
+
+Message Traffic
+Shows all message traffic while the window is open. It includes the source,
+destination, interface, and message. The range option can limit this display
+to nearby stations, much like the range control on bulletins. A range of 0
+causes all messages to be displayed.
+
+GPS Status
+Shows the status of your GPS unit, including the type of fix and number of
+satellites acquired.
+
+Uptime
+Shows the amount of time elapsed since Xastir was started.
+
+HELP-INDEX>Map Menu and the Map Chooser
+
+                       Map Menu and the Map Chooser
+
+Map Menu:
+
+Map Chooser
+This will present you with a list of map directories and/or files in your
+map directory. Checking the "Expand Dirs" option toggles the expansion of
+directories into individual map files. The properties dialog allows more
+advanced controls, and is described below. Click on map names to highlight
+them, this will cause them to be displayed when you click the OK button. You
+may select any number of maps. Clicking "Clear" will select no maps,
+clicking "Vector" will select only vector maps. The three "topo" options will
+automatically select all GeoTIFF images of the listed size. Clicking the OK
+button will display the selected maps. Cancel will abandon any changes.
+
+  Map Chooser Properties
+  Clicking the Properties button will bring up a dialog where you can specify
+  the layer in which maps appear, and in which zoom levels they appear. Higher
+  layer numbers are displayed on top of lower numbers. The range may be
+  specified from -99999 to 99999; it is suggested that you space your layering
+  numbers widely to allow later insertion of additional map layers. From this
+  dialog you may specify whether a vector map is drawn with color fills. This
+  is a per-map setting; the global disable option on the Maps menu can override
+  this. The Filled setting is ignored for raster maps (images). A setting of
+  "auto" allows a dbfawk file to control this parameter directly (usable only
+  if dbfawk is compiled in and the map in question is a Shapefile). You can
+  also select whether a map is considered by the "Auto maps" feature here.
+  Finally, you can specify the minimum and maximum zoom levels at which a map
+  is displayed. This is useful to prevent very detailed local maps from loading
+  at very wide zoom positions, and visa-versa. A minimum zoom of 10 means a map
+  will be displayed at all zooms including and above 10. Likewise, a maximum
+  zoom of 256 means a map will be displayed at all zooms below and including
+  256.
+
+Map Display Bookmarks
+See the help topic "Creating and using Map Display Bookmarks"
+
+Locate Map Feature
+This option brings up a search dialog where you can search through the labels
+in a GNIS file to find a specific location.  It will center the map on the
+new location if it is found. The "GNIS File:" entry is saved between calls
+and between invocations of Xastir.  You must put GNIS files into the
+xastir/GNIS directory in order to use this feature.
+
+Find Address 
+This option brings up a search dialog where you can enter an address. It will 
+center on the map if the address is found. The path to the geo-coder file is 
+saved between calls. 
+
+Coordinate Calc
+This option opens a simple calculator that can convert between coordinate
+systems. This is useful for converting positions to the various formats used
+by different groups of people. This same calculator can be called up by the
+Calc button on some of the other dialogs. It's useful for entering coordinates
+in other formats.
+
+Configure menu:
+  Background color
+  This option controls the color of the background behind the maps you have
+  displayed. The background color is often entirely hidden by filled maps
+  (see below).
+
+  Map Intensity
+  This controls the brightness of any graphics used as maps. This option only
+  appears if you have compiled with GeoTIFF support.
+
+  Adjust Gamma Correction
+  This allows you to apply gamma connection to all loaded map graphics. Maps
+  can be adjusted individually in their .geo files, see the section on .geos in
+  "Map files and WX Counties". This option only appears if you've compiled with
+  ImageMagick support, and does not apply to geoTIFF maps; see the above
+  option.
+
+  Map labels font
+  This allows you to set the font style and size used for map labels.
+
+  Station Text Style
+  Controls which font and style to use for station text and others.
+
+  Icon Outline Style
+  This allows you to specify an outline that surrounds station icons. This
+  helps improve visibility on various backgrounds.
+
+  Configure Tigermap
+  Turning this option on causes Xastir to download the map from the US census
+  bureau's online tiger mapping server. The dialog that comes up allows one to
+  select which layers are displayed, as well as the brightness of the resulting
+  map. This is only available if you have compiled with ImageMagick support.
+  Tigermaps are always loaded as the bottom layer; they do not have layering
+  settings in the Map Chooser.
+
+Disable All Maps
+This option disables the loading of any maps. It is most useful when doing
+rapid zooming or panning, because it saves the need to load the maps on each
+redraw.  Note that this option is not saved between sessions.
+
+Enable Auto Maps
+When enabled, any map found in the map directory (or any directory under it)
+will be displayed if it falls within the current display region. You can add
+any number of directory levels under the main map directory for your maps. Auto
+maps will go through any that have Auto Maps enabled (in the Map Chooser
+Properties dialog) check them all and find what map (or part) should be
+displayed.  All Maps will be merged into the viewing area. If you have a large
+quantity of maps, very detailed maps or a slower computer this can be quite
+slow. When this option is off, maps selected with the Map Chooser and/or Tiger
+Maps dialog will be displayed.
+
+Auto Maps - disable Raster maps
+This option prevents Auto Maps from loading maps which are graphics (images).
+Only vector maps will be displayed in this case.
+
+Enable Map Grid
+When enabled, this option will display a grid on the map.   If the coordinate
+system is UTM a UTM grid will be displayed.  If the coordinate system is 
+latitude/longitude then a latitude and longitude grid will be displayed.  As you
+zoom in the grid switches to a finer resolution.  The spacing of the latitude 
+and longitude grid may be manually adjusted with the "+" and "-" keys.
+
+Enable Map Border
+When both Enable Map Grid and Enable Map Border are enabled, a narrow white 
+border is drawn around the map and the grid lines are labeled using the 
+selected coordinate system (File/Configure/Coordinate System), and the selected
+border font (Map/Configure/Map Labels font/Border Font).   If the UTM or MGRS 
+coordinate systems are selected, the grid lines will be labeled with easting
+and northing values only at zoom levels smaller than about 2048.  
+
+Enable Map Levels
+When enabled, this option will try to filter out data when the zoom level
+shows large areas. This does not work will all maps but will work with the
+maps generated from Tiger Line maps at the aprs.rutgers.edu site, and with
+ESRI Shapefile maps. This does not decrease the loading times of the maps very
+much, rather it simply reduces screen clutter.
+
+Enable Map Labels
+This option toggles the display of map labels embedded in DosAPRS, WinAPRS,
+GNIS, and ESRI Shapefile format maps.
+
+Enable Area Color Fills
+This option controls the filling of vector maps. In certain cases, you
+may want to eliminate the fill to see maps below the top maps. This is a global
+control, maps may individually have color fill toggled in the properties dialog
+of the Map Chooser.
+
+Enable Weather Alert Counties
+This toggles the display of county warning area maps for severe weather.
+These maps can be obtained and installed according to the directions in the
+README.MAPS file. They are displayed on screen when special weather alert
+messages are received, and expire after a time or can be remotely canceled.
+The weather alert text can be seen under View|Weather Alerts. The
+xastir/Counties directory must be populated with the correct files from NOAA
+and Shapelib support must be compiled into Xastir in order to enable this
+functionality.
+
+Index New Maps on Startup
+This option controls if the map index file is built on startup. Most users
+should leave this enabled. If the timestamp of the map file is newer than
+the map index file, the map will be indexed.
+
+Index: Add New Maps
+This option adds any new maps to the max index.  Same rules as the above
+Index New Maps feature, but a manual method of invoking it.
+
+Index: Reindex ALL Maps
+This option starts over from scratch, indexing every map it recognizes in the
+maps directory. This is useful if the Add New Maps function is skipping some
+maps, perhaps because of old timestamps on the map files.  This function may
+take quite a while to complete if you have a lot of maps.
+
+Mouse pointer menu
+This option brings up the options menu normally available by right clicking.
+
+One note on maps:  Many of the currently available vector maps for the
+U.S. were created in NAD 1927 datum, while Xastir and other APRS(tm) programs
+use WGS 1984 datum.  If zoomed in to a small area on the map the datum
+shift may be very noticeable.  The USGS topographic maps have their datum
+corrected by Xastir as they are displayed, so positions will generally
+be more accurate with those topographic maps.
+
+HELP-INDEX>Map files and WX Counties
+
+                         Map files and WX Counties
+
+Map Types
+Xastir will work with various types of map files. All DosAPRS, Windows/Mac
+APRS(tm) map files are supported, as well as PocketAPRS format maps and GNIS
+(Geographic Names Information System) label files.  Xastir also can be
+compiled to use external libraries to support XPixmap (XPM) images, GeoTIFF
+topographic maps, and ESRI Shapefile maps.  The graphics handling capability
+of Xastir can be greatly extended by compiling with ImageMagick support,
+enabling support for many graphic formats as maps (see
+"http://www.imagemagick.org/www/formats.html").  Xastir supports weather
+alert maps in ESRI Shapefile format, available from NOAA.
+
+Details of locations to obtain many of the above types of maps are found in
+the file README.MAPS
+
+Map Locations
+Any map file should be stored in the /usr/local/share/xastir/maps directory
+on your computer. This location may be different on some systems, depending on
+how Xastir was compiled/installed. You can create any number of directories
+under this directory to help organize and separate your data. The maps will be
+loaded in alphanumerical order unless layering is specified.
+
+Hints on installing and organizing maps are found in README.MAPS. 
+Maps in a pixel graphics format actually need a combination of two files,
+a data file with a graphic pixmap (.xpm) (or other format if you compiled
+with ImageMagick), and a calibration file (.geo). The .xpm file is the
+standard graphic format, available without additional libraries. If you
+want to save storage space you can use gzip to compress those files 
+("gzip map.xpm" will result in "map.xpm.gz"). Xastir detects this
+automatically during map loading. You can use XView/Gimp/ImageMagick and
+other programs to convert gif, jpg, and tif images into this format if
+you don't have support for many image types compiled in (ImageMagick). If
+you have problems with maps in xpm format, try to load and save the
+graphics with Gimp first, to convert all unknown color names into the
+binary representation.
+
+The .geo file is a text data file that will tie the image to a location
+in the world. Here is an example of a .geo file that will cover the entire
+world with the map world1.xpm:
+
+FILENAME   world1.xpm
+#          x          y        lon         lat
+TIEPOINT   0          0        -180        90
+TIEPOINT   639        319      180         -90
+IMAGESIZE  640        320
+
+.geo files can have many elements:
+
+FILENAME <filename>
+This specifies the filename of a map image to be loaded from the local disk.  
+
+URL <http://website>
+This specifies the URL of a map image to be loaded from a web or ftp site. 
+ImageMagick only.
+
+TIEPOINT <x-pixel> <y-pixel> <longitude> <latitude>
+Two tie-points are required, and more than 2 will be ignored.
+these two lines are for connecting an x,y pixel position in the image
+to a lat and long position on the earth. The points should be as close as
+possible to the upper left corner and the lower right corner of the image for
+best accuracy.  The latitude/longitude are specified in decimal degrees.
+
+IMAGESIZE <pixels horizontally> <pixels vertically>
+This specifies the size of the image in pixels. If this is not set, the image
+will be loaded each map redraw, regardless if it is on screen or not.
+IMAGESIZE is a REQUIRED OPTION if a URL is specified.  For local files, it's
+an optional parameter (we use ImageMagick to query the image size for local
+files).
+
+DATUM <datum>
+This feature is not implemented.
+
+PROJECTION <projection>
+This feature is only partially implemented, default is "LatLon", other
+possibility is "TM" to specify that the map is in  Transverse Mercator
+projection.
+
+# <anything>
+Any line with the first character of a '#' will be ignored.
+
+ImageMagick specific image enhancements:
+
+GAMMA
+eg: GAMMA 1.2    or    GAMMA 1.2,2.0,1.2
+The first will change overall gamma for this image, the second will
+lighten green more than red or blue.
+
+CONTRAST
+eg: CONTRAST 0    or    CONTRAST 1
+Doesn't seem to do that much, other values make no difference.
+
+NEGATE
+eg: NEGATE 0    or    NEGATE 1
+0 will negate all colors, 1 just grayscale colors.
+
+EQUALIZE
+No argument.
+
+NORMALIZE
+No argument.
+
+LEVEL <black_point, mid_point, white_point>
+eg: LEVEL 0,1,65535
+These values seem to be the defaults.
+
+MODULATE <brightness, saturation, hue>
+eg: MODULATE 90,150,100
+These are percents, 100,100,100 is the default.
+
+REFRESH <seconds>
+eg: REFRESH 900
+This tag is used for dynamic URLs such as weather radar, where you
+wish Xastir to auto-redraw the map at a specified interval.  By
+adding this tag to weather radar .geos, you can watch the weather
+move across your screen.  Xastir contains only one interval counter,
+so the smallest REFRESH interval loaded takes effect for all selected
+maps.
+
+TRANSPARENT 
+Color to remove from the background (make it transparent).  Use a
+number, 0=black.  Color-mapped images use the map value, so white is
+usually 0xffffffff (32-bits of 1s).  Values must be in hexadecimal,
+and are preceeded by "0x".  The value can be obtained by using debug
+level 16.  The first of the four numbers after "Color allocated is"
+is the colormap index.
+
+CROP <left top right bottom>
+Removes borders (makes them transparent).  Values are in pixels with
+(0,0) at the upper left.  A good value for the 620x620 NWS radar
+images is "CROP 35 20 616 600"
+
+Special/nonstandard .geo files:
+
+TIGERMAP
+A file with just the word "TIGERMAP" will cause Xastir to retrieve an
+online Tiger map of the area on screen. These are not available for every
+place in the world. "tigermap.geo" is automatically installed in the maps
+directory.
+
+TERRASERVER-SATELLITE
+A file with just the word "TERRASERVER-SATELLITE" will cause Xastir to
+retrieve a Terraserver satellite photo of the area on screen. Those
+services are not available for every place in the world. Note that using
+the Terraserver maps at any zoom above 256 will probably take a long time
+to load, won't show much detail, and probably won't display correctly. This
+is a limit of Microsoft's Terraserver, not Xastir.  Also note that
+crossing UTM zone boundaries is not supported by Terraserver.
+"terraserver.geo" is automatically installed in the maps directory.
+
+TERRASERVER-TOPO
+A file with just the word "TERRASERVER-TOPO" will cause Xastir to retrieve a
+topographic map of the area on screen. Those services are not available for
+every place in the world. Note that using the maps at any zoom above 256
+will probably take a long time to load, won't show much detail, and
+probably won't display correctly. This is a limit of Microsoft's
+Terraserver, not Xastir.  Also note that crossing UTM zone boundaries is not
+supported by Terraserver. "terraserver-topo.geo" is automatically
+installed in the maps directory.
+
+TERRASERVER-URBAN
+Same as above but with Terraserver colored urban-area satellite
+images. "terraserver-urban.geo" is automatically installed in the
+maps directory.
+
+TERRASERVER-REFLECTIVITY
+Same as above but with Terraserver reflectivity images.
+"terraserver-reflectivity.geo" is automatically installed in the
+maps directory.
+
+TOPORAMA-250k
+Canadian 1:250k scale topo maps, downloaded from findu.com.
+"CanadaTopo250k.geo" is automatically installed in the maps
+directory.
+
+TOPORAMA-50k
+Canadian 1:50k scale topo maps, downloaded from findu.com.
+"CanadaTopo50k.geo" is automatically installed in the maps
+directory.
+
+WMSSERVER
+Allows use of Web Map Services (WMS). An example "WMSRadar.geo" is
+automatically installed in the maps directory.
+
+
+
+geoTIFF maps are a combination of two files as well: a .tif and a .fgd file.
+The .tif file is the actual map data.  The .fgd file need only contain four
+lines like this (but may contain many other lines):
+
+1.5.1.1   WEST BOUNDING COORDINATE:  -122.000000
+1.5.1.2   EAST BOUNDING COORDINATE:  -120.000000
+1.5.1.3   NORTH BOUNDING COORDINATE:  48.000000
+1.5.1.4   SOUTH BOUNDING COORDINATE:  47.000000
+
+Xastir uses only those four lines in its calculations to determine the corner
+points of a map, to see whether the map fits in the current viewport (so it
+can decide whether to skip it).  If your map data are USGS topographic maps,
+the .fgd file should be readily available to you. If it is not, the mapfgd.pl
+script can create it for you. If you don't have a .fgd file, the map will load
+fine, but the white borders won't be cropped and the size and rotation may be
+off a tad bit. An added feature in Xastir is the ability to do datum
+translations from NAD 1927 to WGS 84 datum, which makes the USGS topographic
+maps much more  accurate on the Xastir screen.
+
+Xastir can use USGS geoTIFF topographic maps directly from the CD drive.
+Manually mount the disk or use auto-mounter to do it for you, and make sure
+you have a sym-link created in your maps directory that points to where you
+mounted your CD-ROM drive.  That's it!
+
+
+ESRI Shapefile maps are also a combination of several files, a .shp file, a
+.dbf file, and a .shx file. You only need to select the .shp file to load the
+map, but the other(s) must be present for the map to load correctly.
+
+
+GNIS (Geographic Names Information System) data is a collection of names of
+locations, or geographic features. These labels behave like map labels in
+Dos/WinAPRS maps.  As you zoom in, more labels will appear, assuming you've
+selected the GNIS file as a map and have enabled Map Labels in the Maps menu.
+If you have some of them in the xastir/GNIS directory, you can also search
+for map labels within Xastir.
+
+
+WX County Maps
+All WX County maps should be stored in the /usr/local/share/xastir/Counties
+and Xastir only supports the ESRI Shapefile standard for these. Installation
+is explained in README.MAPS.  You must have Shapelib compiled in.
+
+As NWS messages are received, different areas will get tinted to designate
+areas of concern.  They are color-coded to specify different types of
+alerts. The colors are: Cyan for advisory, yellow for watch, red for warning,
+orange for canceled alert, royal blue for tests, and green for undetermined
+alert levels. The coloring is done with a pixmap stipple that displays the
+type of alert, if it is able to be determined. These changes were made so that
+the underlying maps may still be seen underneath the weather alert areas, and
+so the alert type may be more easily determined, as sometimes matching the
+alerts on screen and in the weather alerts dialog is difficult. The display
+of weather alerts may be turned on/off via the Map menu.
+
+HELP-INDEX>Stations Menu
+
+                             Stations Menu
+
+These options will allow you to control the data displayed around the stations
+on the map. It will also let you track and find stations, and clear stations
+and trails in the database and from the map.
+
+Find Station
+See the help topic "Locating a Station".
+
+Track Station
+See the help topic "Tracking a Station"
+
+Fetch Findu Trail
+Downloads historic trail data from findu.com. Slider bars control the starting
+point and duration of data downloaded.  For an example, if you wished to see
+the track that happened two days ago, all day long, you might set the first
+slider to 48 hours (start time of two days ago) and the second slider to 24
+hours to snag exactly one day's worth of data, from the start until 24 hours
+later.
+
+
+Export all
+This sub-menu allows saving data for all stations to files [or databases]
+
+    Export to KML file
+      Saves all stations and their trails to a Keyhole Markup Language
+      file in ~/.xastir/tracklogs.  The filename will be the current
+      date and time with a .kml extension, e.g. 20080125-033045.kml
+      KML files can also be written on a regular basis using KML
+      Snapshots on the file menu.
+     
+    Store to open databases [Not yet implemented]
+      [Store to database interfaces is currently only implemented through 
+      individual SQL database interface dialogs]
+
+    To save a png snapshot of the current map, use File->PNG Snapshots
+
+Filter Data
+This sub-menu allows filtering of the displayed symbols:
+
+  Select None
+    Determines if symbols should be drawn on the map. The other options depend
+    on this being enabled.
+
+  Select Mine
+    Determines if your own station is shown on the map.
+
+  Select via TNC
+   Global toggle for displaying data received via a TNC, but may be narrowed:
+
+   Select Direct
+     This option only displays stations heard directly (not digipeated).
+
+   Select via Digi
+     This option displays stations heard indirectly via a digipeater.
+
+  Select Net
+    This option displays stations with data received via the Internet.
+
+  Include Expired Data
+    Causes Xastir to continue to display the station data that normally goes
+    away when the symbol is ghosted.  The expiration time can be adjusted in
+    the File|Configure|Defaults menu.
+
+
+  Select Stations
+    Global toggle for displaying stations, but may be narrowed:
+
+    Select Fixed Stations
+      This option displays stationary stations.
+
+    Select Moving Stations
+      This option displays stations with multiple positions or non-zero speed
+
+    Select WX Stations
+      This option displays Weather Stations.
+
+     Select CWOP WX Stations
+      This option includes the display of citizen weather (non-ham) weather
+      data.
+
+  Select Objects/Items
+    Global toggle for displaying objects/items, but may be narrowed:
+
+    Select WX Objects/Items
+     This option displays weather Objects and Items. This includes tropical
+     storms and remote weather stations.
+
+    Select Water Gauge Objects/Items
+     This option toggles the display of water gauge (/w) objects.
+
+    Select Other Objects/Items
+     This option enables or disables the display of objects other than those
+     listed above.
+
+
+Filter Display
+This sub-menu allows filtering of the displayed data:
+
+  Display Callsign
+  Determines if the callsign is displayed.
+
+    Label Trailpoints
+    This option includes callsigns along trails, to help identify which
+    points belong to which stations.
+
+  Display Symbol
+  Determines if the symbol is shown to the left of the callsign.
+
+    Rotate Symbol
+    Some symbols will change their orientation to show the direction in which
+    they are traveling.
+
+  Display Trail
+  When enabled, any moving station will trail a colored line.  We now display
+  as many locations as we have in our database (old limit was 100).  Long
+  trail segments (over 2 degrees latitude or 2 degrees long), or segments with
+  more than 45 minutes receive delay between the points will not be displayed.
+  Duplicate points are also eliminated from the track (SAR team returning to
+  base:  Last segment may not be displayed due to the starting point appearing
+  twice in the trail list).
+
+  Display Course
+  When enabled, green text will appear below the call sign. This will display
+  the last known course (in degrees) the station was traveling.
+
+  Display Speed
+  When on, red text will appear below the call sign (or course). This will
+  display the last known speed of the station. 
+
+    Display Short Speed
+    This option removes display of the measurement units for speed.
+
+  Display Altitude
+  When enabled, blue text will appear above the call sign. This will display
+  the last known altitude of the station.
+
+
+  Display Weather Info
+  Global toggle for displaying weather information, but may be narrowed:
+
+    Display Weather Text
+    When enabled, the latest weather data (temp,wind speed/course/gust,
+    humidity) is displayed. This may be adjusted with the following option:
+
+      Display Temperature Only
+      Displays only the temperature data for the station.
+
+    Display Wind Barb
+    When enabled, a wind barb showing the direction and speed of the wind is
+    drawn for all displayed stations reporting this information. 
+
+
+  Display Position Ambiguity
+  When enabled, the area in which station using position ambiguity may be
+  located within is shaded, with the relevant station in the center.
+
+  Display Power/Gain
+  When on, Power/Gain Circles will be displayed. Overlapping circles indicate
+  that the stations are theoretically within simplex range of one another.
+  This is only roughly accurate, especially in areas of variable terrain. 
+
+    Use Default Power/Gain
+    Enables a default power/gain setting as specified in the APRS(tm)
+    specification.
+
+    Display Mobile Power/Gain
+    Enables power/gain circles for mobile stations.
+
+
+  Display DF Attributes
+  When enabled, any DF circles/lines will be displayed on the screen.
+
+  Enable Dead-Reckoning
+  When enabled, the positions of stations are estimated based on past course
+  and speed. The recalculation rate should be reasonable, but can be adjusted
+  in the configuration file.
+
+    Display Arc
+    Displays an expanding arc of expected maximum travel distance, location and
+    course given the past course and speed. The arc slowly becomes a circle as
+    the position report gets older.
+
+    Display Course
+    Displays an expected course and distance traveled by the station, assuming
+    the course hasn't changed.
+ 
+    Display Symbols
+    Displays a ghosted version of the stations symbol at the expected position,
+    assuming the station has continued at its current course and speed.
+
+
+  Display Dist/Bearing
+  When enabled, two lines of text will be displayed on the left side of the
+  stations' icon. The top line will contain the distance from your station to
+  this station. The bottom line will contain the course from your station to
+  this station.
+
+  Display Last Report Age
+  Display the time since the station was last heard.
+
+Reload Object/Item History
+This will reload the ~/.xastir/config/objects.log file used for Object and Item
+persistence. This is needed if you edit the file while Xastir is running.
+
+Clear Object/Item History
+This will clear the ~/.xastir/config/objects.log file used for Object and Item
+persistence. It is recommended that you manually select and delete all Objects
+and Items that you own before doing this, otherwise they may remain on the
+screens of other APRS(tm) users.
+
+Clear All Tactical Calls
+Clears all assigned tactical calls. This will take effect the next
+redraw. Note that this will NOT clear tactical calls on other
+peoples' screens if you've published them via a message to
+"TACTICAL" (see the help text for "Send Message").
+
+Clear Tactical Call History
+This removes the tactical call history file, meaning that tactical calls
+assigned will not remain permanent between Xastir restarts.  Note
+that this will NOT clear tactical calls on other peoples' screens if
+you've published them via a message to "TACTICAL" (see the help text
+for "Send Message".
+
+Clear All Trails
+This will wipe all the line tracking data from the station database and
+refresh the screen.  This option is perhaps useful if you're low on memory
+or just want an uncluttered screen.  You may also clear individual stations'
+trails from the Station Info dialog.
+
+Clear All Stations
+This will wipe all the data from the station database except yours.  This
+option is perhaps useful if you're low on memory or just want to unclutter
+your screen.
+
+HELP-INDEX>Messages and the Messages menu
+
+                  Messages and the Messages menu
+
+Send Message to and Open group messages
+
+These are very similar. "Send message to" will send your messages to one
+station and will only receive data from that station. Group messages are more
+general: you can receive any message for the group and you will send out your
+messages to that group name. Group messages code is not fully implemented yet
+and various problems still need to be worked out.  The "groups" file is looked
+for in ~/.xastir/config.  This is where the groups you are a member of are
+stored.  As was said before the "groups" functionality may not be complete yet.
+
+At some point in the near future sending of bulletins should be added to this
+menu as well.  It's not coded yet.
+
+Each of these two screens contains a message box, a call line, a message line,
+and various buttons. You must first enter the call of the group or station you
+want to contact. Once that is done any new message that has come in from that
+station to you will be displayed. If the station is sending you information
+and no message window is up it will automatically pop up a new window (up to
+10) with that station's call sign filled in for you. You can now enter a
+message on the message line. The message can be longer that the message line,
+and will max out at about 250+ characters. Once your message is entered,
+clicking on the "Send Now!" button will send your message. The "Send Now!"
+button will gray out until your message is completely ack'ed. Any message you
+receive will be sorted by the line # and be placed in the message window. If
+you are in a group mode each line will display the call sign from where the
+message was sent followed by the message itself. Currently group messages are
+sorted by call and then line #. When you are done sending messages clicking on
+the exit button will close the window. Other buttons are also available:  The
+"New Call" button will allow you to look at old data a station has sent.  Type
+in the call and click on this button, any old information will be displayed.
+You can also use this button to change the call of the station you're talking
+with. Enter the new call and click the button. The "Clear Msg History" button
+will clear any message displayed in the message window.  "Cancel Pending Msgs"
+will cancel any messages in the transmit queue that haven't been acknowledged
+by the remote station yet.  After canceling the pending messages or receiving
+and acknowledgment packet from the remote station, you may send new messages to
+the remote station.  Xastir will allow you to type ahead, so you can just keep
+typing if you don't want to wait for the acknowledgments.
+
+Messages in reply to previous ones will attempt to use the path of the
+received message to avoid flooding the system with broadcast messages. You
+may adjust the path in the send message dialog, or the default path(s) set
+in the interface control will be used if you leave this blank.  The path
+can be set for each message sent, but once a message is sent the path
+remains fixed for that particular message.
+
+Each outgoing message remains highlighted until it is ack'ed by the remote
+station.  If it times out or if you cancel the pending messages, those
+messages will remain highlighted unless you clear the message history.
+
+To publish TACTICAL calls to other Xastir and APRS+SA stations as
+well as assign those tactical calls locally: Send a message to
+"TACTICAL" with the body of the message containing lines something
+like:
+  
+  callsign-1=TAC1;callsign-2=TAC2;callsign-3=TAC3
+
+To remove these tactical calls later from local AND remote screens,
+assure that the original message(s) assigning them has timed-out or
+been cancelled, then send a message like this and let it retry until
+it times out (assigns blank tactical calls to the original
+callsigns, thereby removing the assignment):
+
+    callsign-1=;callsign-2=;callsign-3=
+
+Clear all outgoing messages
+This will clear all un-ack'ed messages you have sent.
+
+General Stations Query
+This sends an ?APRS? packet, which should cause all local stations to report
+their position and/or status. Most software ignores this query, because
+responding to it would cause massive floods of data.
+
+IGate Stations Query
+This sends an ?IGATE? packet, which should cause all local IGates to respond
+with their capabilities.
+
+WX Stations Query
+This sends an ?WX? packet, which should cause all local weather stations to
+report their position and weather.
+
+Modify Auto reply message
+This will set the message that is sent as an Auto Reply.
+
+Enable Auto Reply Msg
+This will turn on an automatic reply when an incoming message is received.
+
+Satellite Ack Mode
+This mode disables the sending of ack messages in response to received
+messages. Messages are still acknowledged using the reply-ack system. When
+operating over a satellite it is clear that your message made it, because you
+will hear it repeated. The receiving station sending an independent ack only
+adds QRM.
+ 
+HELP-INDEX>Interfaces Menu
+
+                         Interfaces menu
+
+This menu contains interface related options.
+
+Interface Control
+This option displays a window where you can turn on and off your configured
+interfaces, as well as add, delete, or configure interfaces. See the "Configure
+Interfaces" help topic.
+
+Disable Transmit options
+These options disable the transmission of everything, one's position, or one's
+objects. These are global options and affect all interfaces. Most interfaces
+have an option to disable transmission on that specific interface in their
+configuration menus as well.
+
+Enable Server Port
+This enables/disables TCP and UDP listening sockets at port 2023.  You may
+connect other APRS(tm) clients to the TCP port in order to send/receive
+APRS(tm) data.  Once they authenticate, they'll be able to send data to Xastir.
+Without authentication, they'll be able to receive every bit of TNC and INET
+data that Xastir receives.  Note that ANY user with the proper credentials can
+come in on the TCP or UDP ports if they are enabled.  The only one of these two
+ports currently that can send to RF is the UDP Server port.  The TCP
+port cannot.
+
+    "user WE7U-13 pass XXXX vers XASTIR 1.3.3"
+
+Connect another APRS(tm) client to that port and it should authenticate and be
+able to send to any server that Xastir is connected to, as well as receive
+packets from all ports/servers Xastir is hooked to.
+
+You should also have a binary called "xastir_udp_client" which can send packets
+into the UDP listening port.  Invoke it like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> "APRS Packet Goes Here"
+
+Currently that will inject the packet into Xastir's decoding routines and send
+it to any TCP-connected clients. It will also igate it to the INET if you have
+igating enabled.  It will send the packet out the RF ports as third-party
+packets only if you add the "-to_rf" flag after the passcode like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> -to_rf "APRS Packet"
+
+The UDP client is useful for generating and injecting APRS packets from
+external scripts.  It can also be used to fetch the callsign of the remote
+xastir server by using the -identify flag:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> -identify
+
+Transmit now
+Causes all interfaces that have transmit enabled (see configure|interfaces) to
+transmit a position packet.  It will be grayed out if Disable Transmit: ALL
+is selected.
+
+If you have GPSMan installed, you have these additional menu options
+displayed:
+
+Fetch GPS Track
+Download a set of trackpoints from an attached GPS.
+
+Fetch GPS Routes
+Download a set of routes from an attached GPS.
+
+Fetch GPS Waypoints
+Download a set of waypoints from an attached GPS.
+
+Fetch Garmin RINO Waypoints
+Snag waypoints from an attached Garmin RINO, create APRS(tm) Objects out of any
+waypoints which begin with "APRS".
+
+HELP-INDEX>Station info box - FCC and RAC lookup
+
+                  Station info box - FCC and RAC lookup
+
+Station Info will display any data decoded by Xastir.
+
+You can assign (local only) tactical calls to stations from here, by
+clicking the "Assign Tactical Call" button. This will cause the
+station on screen to display as the tactical call instead of its
+callsign. Assigning a blank tactical call clears this feature, and
+it can also be cleared for all stations in the Stations menu.  This
+feature assigns tactical calls to the local Xastir station only, but
+see below to publish them to others.
+
+To publish tactical calls across the air to other Xastir and APRS+SA
+stations (as well as assign them locally), see the "Send Message" help
+section.
+
+"Enable Automatic Updates" will cause the window to refresh frequently with the
+latest information.
+
+The information available may include: Number of packets heard, the time
+last heard, the device the packet came from, station comments, 
+power/height/gain of the station, course/distance from your station,
+weather information, and current and previous positions.
+
+For moving stations a track-log follows with the most recent entries on top.
+A '+' in front indicates that a new track starts at that point (if there was
+a large gap in time or position). A star at the end of a line indicates that
+this station could be heard direct (without a digi) at that specific position.
+Positions are followed by the 6 digit Maidenhead grid square the station was
+located in at that point.
+
+For your own station, there is an "Echoed from" field, listing the
+last six digipeaters that heard you directly. This is useful for setting
+non-generic paths.
+
+Currently two rows of four buttons appear in the Station Info window.  Some
+of the labels on the buttons change based on the type of station that you're
+dealing with.
+
+For objects/items:
+
+Store     Modify    Blank      Close
+Track     Object/
+          Item
+
+Station   Trace     Un-Acked   Direct
+Version   Query     Messages   Stations
+Query               Query      Query
+
+For other stations:
+
+Store     Send      Search     Close
+Track     Message   FCC (RAC)
+                    Database
+
+Station   Trace     Un-Acked   Direct
+Version   Query     Messages   Stations
+Query               Query      Query
+
+"Station Version Query" changes to "Clear Track" for mobile stations.
+The Clear Track button will clear any line tracking for this station that is
+currently stored or on the map display.
+
+"Store Track" will save the track of the station to a file on disk. The 
+format is similar to that used by GPS receivers but its specification
+might be changed (enhanced) in future versions. There is currently no
+way to read that track data back in, but it is planned for the future.
+The goal is to also read and display GPS track-logs in a similar manner.
+These track-log files will be placed in the directory ~/.xastir/tracklogs
+with a name equal to the stations call with ".trk" as extension.  "Store 
+Track" will simultaneously save the station's track as a Keyhole Markup
+Language (.kml) file with a filename equal to the station's call, the
+current date and time and .kml as extension.  If shapefile support has
+been included, the station's track will also be saved as a set of four 
+files (.dbf,.prj,.shp,.shx).  Subsequent presses of Store Track for the
+same station will write additional lines into the .trk file, and create
+new .kml (and shapefile) files (each containing all positions in the 
+station's track.  
+
+"Modify Object/Item" will bring up the Object Modify window.
+
+"Send message" will open up the message window and allow you to send a message
+to this station. It will fill in the call sign for you.
+
+If the FCC (U.S. Federal Communications Commission) or RAC (Radio Amateurs of
+Canada) database is installed and the callsign appears to be a Canadian or
+U.S. callsign, the "Search FCC/RAC Database" button will become active,
+otherwise this button will be inactive.  The FCC and RAC files should be
+placed in the /usr/local/share/xastir/fcc directory, and case is important!
+Pressing this button adds the station's name and address into the Station
+Info box.  Instructions for installing these databases are in the README.MAPS
+file.
+
+Xastir will create index files for each database file upon startup. If a newer
+callsign file is placed there while Xastir is running, it will create or
+rebuild the index on the next lookup.  Special prefixes are NOT handled.
+
+HELP-INDEX>Creating a log
+                              Creating a log
+
+Xastir can log data from the internet or TNC for later playback, or for
+debugging purposes.  WARNING: Logging can fill up your hard drive, so be
+careful using it, or make preparations for rolling over the log files
+automatically via cron. An indication will be shown on the status bar when
+logging is enabled.
+
+All these choices are accessible via the File menu:
+
+Enable TNC Logging
+Logs all TNC data received and transmitted. These logs can be played back using
+the "Open Log File" feature.
+
+Enable Net logging
+Logs all internet data received and transmitted. These logs can be played back
+using the "Open Log File" feature.  If you have no interfaces started but still
+want to log your posits and objects locally, this is the option to enable for
+that as well.
+
+Enable IGate logging
+Logs all data forwarded in both directions, and rejected forwards with reasons
+for rejection. Includes NWS messages forwarded to RF.
+
+Enable WX logging
+Logs all weather data received from your weather station.
+
+
+HELP-INDEX>Replaying a log
+
+                              Replaying a log
+
+Click on "File", then "Open Log File" and a file selector window will display.
+You can use it to browse your hard drive and select any file containing raw
+TNC data like those created by the TNC and Net logging options. Your station
+will still function the same way, receiving and transmitting. If you were
+logging data, the typical place to look for those files would be 
+~/.xastir/logs/
+
+NOTE: This function doesn't read the saved station tracklogs.
+
+HELP-INDEX>Locating a Station
+
+                             Locating a Station
+
+Click on "Stations", then "Find Station". A window will pop up. You can now
+enter a call or part of a call. By default it will search for an exact match
+(full call, not partial) and is not case sensitive. If you are looking for a
+partial match, "Match Exact" should not be selected.
+
+For objects which could contain lower case letters you have to check
+"Match Case"! Opposite to the name, without "Match Case" the search
+text will only be converted to upper case...
+
+Clicking on the "Locate Now!" button will center the first station
+found in the center of your screen at the current zoom level.
+
+Clicking "FCC/RAC Lookup" will look up the user's information if the FCC or RAC
+database, of those databases are installed.
+
+Clicking on "Cancel" will close the window.
+
+This dialog will pop up if a station sends a Mic-e "Emergency!" packet, to
+encourage users to locate and perhaps help the listed station.
+
+HELP-INDEX>Creating and using Map Display Bookmarks
+
+                  Creating and using Map Display Bookmarks
+
+Click on "Maps", then "Map Display Bookmarks" and a window will pop up.
+If this is the first time you have used this then the box will have no
+entries in it. To add a bookmark to the list: Position the main map to
+the area and zoom level you want to use. Enter a unique name in the
+"New Name" area, then click on add. Your entry will be added to the
+list (in alphabetical order).  You can add as many map display bookmarks
+as you want. To use one of the bookmarks mark its name and click
+"Activate!". The main map will then show the stored area and zoom level.
+You can similarly delete a bookmark by clicking on the bookmark name and
+then the "Delete" button.
+
+"Maps->Locate Map Feature" is another method to jump to a location, if
+the name of the location is known and you have GNIS files installed.
+
+HELP-INDEX>Tracking a Station
+
+                        Tracking a Station
+
+Click on "Stations", then "Track Station". Enter the callsign to track (all or
+part) then click on the "Track Now!" button. As the station moves it will
+remain viewable in the main map window. As the stations starts to get close
+to the edge of the map window the window will re-center so that the object is
+always visible. To stop tracking this station click on the "Clear Tracking"
+button. While tracking is active, a "Tr" is shown in the status bar next to
+the zoom level.  If the station is not on the map yet, tracking will begin
+as soon as it shows up.
+
+HELP-INDEX>Printing
+
+                       Printing the Map Screen
+
+Note: Printing has not been set up on Windows/Cygwin.  These instructions
+are for Unix and Unix-like operating systems.
+
+Xastir can print the drawing area in either black & white or color.  It does
+this by first dumping the image to an XPixmap file on disk, then using external
+tools to convert it to postscript, scale it, rotate it, preview it, then print
+it.  You must have your system printing set up to handle postscript (usually
+this requires Ghostscript and a print filter installed, as well as lp or lpr
+print spoolers).  You must also have the following tools installed for this
+capability:  ImageMagick tools (specifically "convert"), "Ghostscript",
+Ghostscript fonts, and "gv".  Once all of these packages are installed and
+functional, you should get a "gv" window popping up shortly after you tell
+Xastir to create a print file.  From there  you can view the printed image, and
+if acceptable, tell "gv" to print it.  Note that sometimes changing to a white
+default background for the maps is recommended, depending on what maps you have
+viewable.  This can save greatly on ink.
+
+HELP-INDEX>Creating Snapshots
+
+                     Creating Automatic Snapshots
+
+Xastir has the capability to create automatic snapshots of the map screen
+on a recurring basis.  The default time period is set at once per five
+minutes.  Assuming that you have "convert" from the ImageMagick tools
+installed, Xastir will create an XPM format file in ~/.xastir/tmp/, then
+convert it to the PNG file ~/.xastir/tmp/snapshot.png. This file is useful for
+embedding in web pages to show a "live" image of what is on your Xastir
+screen.  Enable this feature via the "File->PNG Snapshots" toggle-button. 
+The rate is once every five minutes (configurable from the Configure 
+Timing dialog from "File->Configure->Timing"), or every time the button is 
+toggled from off to on. A .geo is created to allow you to use the snapshot 
+as a map.  A .kml file is also written to allow you to use the snapshot as
+a graphic overlay on terrain in applications capable of reading kml.  See
+kml_snapshot_to_web.sh and kml_snapshot_feed.kml in the scripts directory 
+for more information on using the snapshot.png and snapshot.kml file to
+produce a kml feed using the snapshots.
+
+                    Creating Automatic KML Snapshots
+
+Xastir is capable of writing all current stations and tracks to a kml file
+on a recurring basis.  Enable this feature via the "File->KML Snapshots" 
+toggle button.  The rate at which these snapshots are generated is the same
+as that of PNG snapshots, configured from "File->Configure->Timing" by 
+setting the snapshot time interval.  Each snapshot is written to a .kml
+file in ~/.xastir/tracklogs, with a filename based on the date and time
+of the snapshot, e.g. 20080206-000720.kml  This behavior may change to 
+make KML snapshots write to a single file like PNG snapshots.
+                    
+
+HELP-INDEX>Included Scripts
+
+                        Included Scripts
+
+Xastir includes several Perl scripts and a shell script that may be useful:
+
+get-fcc-rac.pl
+This shell script automates retrieving and installing the FCC and the RAC
+callsign databases. Note that these databases are very large!
+
+icontable.pl
+This script generates an xpm bitmap of all Xastir's primary and secondary
+symbols from the symbols.dat file. The overlays and specials are ignored.
+Output is to STDOUT, so a typical call would be "icontable.pl > symbols.xpm".
+
+inf2geo.pl
+This script creates .geo files from UI-View .inf files. To create a map.geo
+from a map.inf, typical usage would be "inf2geo.pl map".
+
+kiss-off.pl
+This script sends the commands needed to turn off a TNC's KISS mode.
+
+mapblast2geo.pl
+This script creates .geo files for Mapblast pixel maps. It includes usage
+information.
+
+mapfgd.pl
+This script creates minimal .fgd files for GeoTIFF images lacking them, based
+on information found in the GeoTIFF file. The created files allow Xastir to
+crop the white borders and rotate/scale the map properly. Typical usage would
+be "mapfgd.pl mapdir" where mapdir is the directory containing the GeoTIFF
+images.
+
+overlay.pl
+This script creates .log format files from comma-separated overlay files. See
+the script comments for full usage information. 
+
+ozi2geo.pl
+This script creates .geo files from OziExplorer .map files.
+
+permutations.pl
+This script converts between different lat/lon formats. See the script comments
+for further details.
+
+split_gnis.bash
+This will take a GNIS data-point file (typically for a whole state, 8+MB), break
+it down into smaller chunks (typically for a county, 30-200k) it will also
+throw away the trailing spaces and <CR>s at EOL.
+
+split_gnis.pl
+This is a Perl version of the above script.
+
+test_coord.pl
+Tests for the Coordinate.pm Perl module.
+
+track-get.pl
+This script downloads the track-log of a specified object from a Garmin GPS.
+It requires the GPS::Garmin module. It prompts for an object name, and writes
+the track-log to the ~/.xastir/logs directory.
+
+update_langfile.pl
+This script is targeted toward developers. It rebuilds a specified language
+file to contain all the strings of another. It is usually used to regenerate
+the non-English language files when significant changes have been made to the
+English file. When the second language file lacks a string in the main file,
+the untranslated string is inserted. Typical usage would be 
+"update_langfile.pl language-German.sys" . The main language file is
+hard-coded but easily editable.
+
+waypoint-get.pl
+This similar script downloads the waypoints from a Garmin GPS, and creates a
+log in the ~/.xastir/logs directory containing the waypoints as objects. It
+also requires the GPS::Garmin module.
+
+db_gis_mysql.sql  db_gis_postgis.sql
+These will create tables for storing station data in a mysql or postgresql/
+postgis database.  SQL Server database support is experimental.  See the
+"OPTIONAL: Experimental.  Add GIS database support" section in INSTALL
+
+HELP-INDEX>Configuring Interfaces
+
+                           Configuring Interfaces
+
+Click on Interfaces, then Interface Control.
+
+An "Installed Interfaces" box should appear. This box will allow you to add,
+delete, and modify the properties of various devices you may want to use with
+Xastir.
+
+Supported interface types are:
+Serial TNC
+Serial TNC w/GPS on HSP cable
+Serial GPS
+Serial WX
+Internet Server
+AX.25 TNC
+Networked GPS (via gpsd)
+Networked WX
+Serial TNC w/GPS on AUX port
+Serial KISS TNC
+Networked Database (Not Implemented Yet)
+Networked AGWPE
+Serial Multi-Port KISS TNC
+SQL Databases [MySQL,Postgis] (Experimental)
+
+To add a device, click on the add button. A "Choose Interface Type" box will
+appear. Click on the type of device you would like to add. Then click the Add
+button in the "Choose Interface Type" box. Properties for that device will
+appear. Fill out the requested information and click OK.
+
+To delete the device, click on the device you wish to delete and then click
+the delete button.
+
+To modify the properties of a device, click on the device you wish to modify,
+then click the properties button. The properties for that device will appear.
+Change the information you want and click OK.
+
+More specific help is available under the help topics of each interface type.
+
+SQL Databases will only appear as an option if you have MySQL or Postgis 
+support compiled.  
+
+HELP-INDEX>Configure Serial TNC Devices 
+
+                          Configure Serial TNC Devices 
+
+This section covers adding or modifying Serial TNCs or Serial TNCs with a
+GPS on a HSP cable.
+
+If you have a HSP cable, which allows you to share the TNC port with a GPS
+unit you may choose a TNC with GPS (HSP Cable). This is a special cable and may
+not work on all computers/GPS/TNC combinations. If you use this device the TNC
+and the GPS should be set to the same communications parameters. Generally
+4800 bps, 8 data bits, no parity, and 1 stop bit.
+
+TNC Port Options:
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+The TNC Port is the Unix device that the TNC (or TNC and GPS) is hooked to.
+Normally you can use /dev/ttyS0 (com1), /dev/ttyS1 (com2) etc.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your TNC
+and GPS.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices, and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. XASTIR will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1, WIDE2-2 may work better. Or if you know the call of your closest digi you
+may use XXXCALL, WIDE2-2. Most of you will only need one path. If you are in a
+remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths are
+entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+TNC Startup and Shutdown files. These fields specify a filename that is
+located in the /usr/local/share/xastir/config directory. Each file is a
+standard text file containing any commands you would like to send your TNC at
+the time the device is activated (startup file) or shut down.
+
+HELP-INDEX>Configure Serial TNC w/GPS on HSP cable or AUX port
+
+                Configure Serial TNC w/GPS on HSP cable or AUX port
+
+These hybrid interface types implement the options of both serial TNCs and
+GPSs. Please consult the configuration help for both serial TNCs and serial
+Gpsd for further information on the configuration of these devices.
+
+"Send Control-E to get GPS Data?"
+
+This checkbox controls whether Xastir sends a Control-E to the TNC every time
+it needs GPS data.
+
+Some TNCs that support a GPS on an auxilliary port require that Xastir
+send a Control-E to the TNC in order to get the GPS data each time it
+is needed.  Devices in this class include the Kantronics KPC-3+.
+
+Some devices, like Kenwood APRS radios (D700, etc.) do NOT require
+this, and in fact the Control-E interferes with correct operation of
+these devices.
+
+Because Control-E was required by the most common TNCs that had an aux
+port for GPS at the time that this interface type was written, this is
+the default behavior of Xastir.  If you have a Kenwood radio that you are 
+using in this mode, you must DESELECT the "Send Control-E to get GPS data?"
+checkbox in the configuration dialog for this interface type.  
+
+HELP-INDEX>Configure Serial KISS TNC
+
+                     Configure Serial KISS TNC
+
+This section covers adding or modifying Serial KISS TNCs. KISS mode can be done
+by most standard TNCs too, and it eliminates the necessity to set the options
+specially in the startup files, at the expense of slightly higher processor
+usage. And of course this enables the use of purely KISS TNCs, such as the one
+described in the November 2000 issue of QST, without a separate program or
+kernel module.
+
+Options
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+Selecting "RELAY Digipeat?" will tell Xastir to digipeat traffic.  It will do
+this if the first unused digipeater call in the path matches your callsign or a
+callsign listed in your Xastir config file ("RELAY_DIGIPEAT_CALLS" line,
+default is "WIDE1-1"). This option is only recommended for base stations in
+regions where there are few other fill-in digipeaters in the area. Consult with
+a local group about the best setting for your region. You may hand-edit the
+Xastir config file when Xastir is not running in order to change this string to
+match your local recommendations. In the U.S., "WIDE1-1" is the recommended
+setting.
+
+The TNC Port is the Unix serial device that the TNC is hooked to.
+Normally you can use /dev/ttyS0 (com1), /dev/ttyS1 (com2) etc.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Now set the bps rate under port settings.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices, and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. Xastir will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just a WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1,WIDE2-2 may work better. Or if you know the call of your closest digi
+you may use XXXCALL,WIDE2-2. Most of you will only need one path. If you are in
+a remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths
+are entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+Next configure the KISS parameters: TXdelay is the time (in 10ms units) needed
+between the keying of the radio and when it is ready to send data. Persistence
+and slottime are the channel access parameters: Slottime is how often the
+channel access algorithm is executed, and should usually be set to 10.
+Persistence is how aggressively your station tries to grab the channel when
+free, and should be ideally set to 255 divided by the number of stations on the
+channel. Full duplex allows the transmission to begin while there are packets
+being received on the channel, this should be disabled in most cases (set to
+"0").
+
+HELP-INDEX>Configure AX.25 TNC Devices
+
+                        Configure AX.25 TNC Devices
+
+This section covers adding or modifying AX.25 TNC devices. AX.25 devices can
+be any device that uses the Linux AX.25 drivers. This is a kernel level
+driver, and device such as a Baycom or a sound modem can be used as a TNC.
+These devices must be set up and running before Xastir can use them.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+Selecting "RELAY Digipeat?" will tell Xastir to digipeat traffic. It will do
+this if the first unused digipeater call in the path matches your callsign or a
+callsign listed in your Xastir config file ("RELAY_DIGIPEAT_CALLS" line,
+default is "WIDE1-1"). This option is only recommended for base stations in
+regions where there are few other fill-in digipeater stations in the area.
+Consult with a local group about the best setting for your region.  This is
+only needed if you are not using any other software that performs this
+function, such as aprsdigi or DIGI_NED. You may hand-edit the Xastir config
+file when Xastir is not running in order to change this string to match your
+local recommendations. In the U.S., "WIDE1-1" is the recommended setting.
+
+Enter the AX.25 Device name you specified in the axports file for this device.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter in up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. Xastir will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just a WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1,WIDE2-2 may work better. Or if you know the call of your closest digi
+you may use XXXCALL,WIDE2-2. Most of you will only need one path. If you are in
+a remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths
+are entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+NOTE: To use AX.25 devices with Xastir you will need to run the program as
+"root". If you want to run Xastir as another user you may want to set the
+suid bit on the Xastir program file. Please see INSTALL file for more
+information; current Xastir drops the extra privileges but has not been audited
+for exploits. Use in this fashion in a multi-user environment at your own risk!
+
+HELP-INDEX>Configure Serial GPS Devices
+
+                       Configure Serial GPS Devices
+
+Set the serial port device for your GPS unit. Common values of /dev/ttyS0
+(COM1) or /dev/ttyS1 (COM2) can be used.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Set system clock from GPS data" will tell Xastir to try setting the
+system's clock to the highly accurate time signal from the GPS receiver. This
+requires root privileges on most systems.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your GPS.
+Most GPS units will use 4800 bps and 8,n,1.
+
+HELP-INDEX>Configure Networked GPS Devices
+
+                    Configure Networked GPS Devices
+
+If you need to share the GPS data with different programs or machines, this
+option is best. Xastir will work with gpsd which will allow several
+connections to share your GPS data.
+
+Set the host name (or IP address) and the port number for the gpsd host on
+your network.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+Selecting "Set system clock from GPS data" will tell Xastir to try setting the
+system's clock to the highly accurate time signal from the GPS receiver. This
+requires root privileges on most systems.
+
+HELP-INDEX>Configure the Internet Server
+
+                         Configure the Internet Server
+
+Internet Servers allow you to send and receive data for all over the world.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+setup communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing Internet
+data can be sent to this device.
+
+Enter the host name (or IP address) and the port number of the Internet
+Server you want to contact. 
+
+Enter a valid pass-code to validate your connection, this will allow your
+data to be transmitted via an IGate. If you don't have a pass-code, use the 
+included "callpass" program to generate one. Note that passcodes are dependent
+on callsigns.  From the src directory, "make callpass" should create the
+executable if it isn't already compiled.
+
+Enter any filter parameters. This causes a special message to be sent to the
+server requesting that the data be filtered in a certain way. The exact format
+of this field is fully specified, please consult APRSSIG for more information.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+HELP-INDEX>Configure a Serial WX Station
+
+                     Configure a Serial WX Station
+
+Set the serial port device for your WX unit. Common values of /dev/ttyS0
+(COM1) or /dev/ttyS1 (COM2) can be used.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your WX
+unit. The Data Type option will allow you to override what type of serial data
+the program will look for. The auto-detect feature will first look for Weather
+data in a binary type as the Radio Shack WX-200 uses. If no binary data is
+found in the stream, Xastir will look for an ASCII type of WX station (like
+Peet Bros.).
+
+Now set the Rain Gauge correction factor. Xastir requires that the rain gauge
+report in .01 inch increments. If the unit reports in .1 inch or .1 millimeter
+increments, a correction must be specified to obtain accurate measurements.
+
+HELP-INDEX>Configure a Networked WX Station
+
+                   Configure a Networked WX Station
+
+Xastir can use WX data servers such as wx200d. wx200d will allow several
+network connections, thus sharing the Weather data with several programs or
+computers.
+
+Enter the host name (or IP address) and the port number of the WX data server
+you want to contact.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+As before the Data Type will override the auto detection.
+
+Now set the Rain Gauge correction factor. Xastir requires that the rain gauge
+report in .01 inch increments. If the unit reports in .1 inch or .1 millimeter
+increments, a correction must be specified to obtain accurate measurements.
+
+HELP-INDEX>Configure an AGWPE Connection
+
+                   Configure an AGWPE Connection
+
+Xastir can use an AGWPE network interface running on a Windows box
+as a TNC interface. It can also use the login/password security that
+AGWPE has built-in, but you must set up the account in the AGWPE
+application with your callsign for the username, in all capital
+letters.  For instance: "AB7CD".
+
+The other options are described in the sections for Serial TNC and for
+Network interfaces.
+
+HELP-INDEX>Configure a SQL Database Connection
+
+                Configure a SQL Database Connection
+                         [Experimental]
+
+Xastir can experimentally store and retrieve station data from either
+a MySQL database or a Postgresql + Postgis database.  See the 
+"OPTIONAL: Experimental.  Add GIS database support." section in the
+INSTALL file for more information.  Station and object data are stored
+as spatial data, and can be retrieved from other GIS applications, for example
+Xastir can write station locations into a Postgis database from which they
+can also be viewed using QGIS.  SQL database connections also allow for the
+persistence of data between Xastir sessions.  All aspects of spatial database
+support, including database structures, are currently experimental and may 
+change at any time.  You may configure multiple SQL database connections, 
+but you should only have one active at a time.  
+
+Before creating a database connection in Xastir, you will need to create a 
+database to connect to, create an appropriate set of tables 
+(see the db_gis_xxxxx.sql scripts in the scripts directory), and add a user 
+with a password and rights to access the database.  For postgis databases
+you may also need to appropriately configure the user in pg_hba.conf
+
+Configuration options on the SQL database dialog include:
+Database: MySQL (lat/long) for very old MySQL databases, 
+          Postgis for postgresql + postgis, and 
+          MySQL (Spatial) for current MySQL databases.
+With tables for: Currently only the Xastir simple schema - a very basic
+          flat table holding minimal information about stations.
+Host: IP address or hostname for the database server, default is localhost.
+Port: Default is 3306 for MySQL and 5432 for Postgresql.  The database can
+          be on a remote server, but the appropriate port will need to be
+          open in any firewalls.  
+Username: Can be unique to your database, e.g. xastir_user
+Password: Unique to your database.  
+Schema name: Your database name. e.g. xastir
+MySQL Socket: check my.cnf, or mysql --help | grep socket
+          Leave blank for postgis databases.
+Reconnect on Net Failure: [Not yet implemented]
+MySQL defaults and Postgis defaults provided by the buttons may
+or may not be correct for your database.  
+
+Three options control the behavior of the SQL Database interface:
+Activate on Startup:  Try to connect to this database and begin storing heard 
+station data as soon as Xastir starts (if store incoming data is also selected).
+
+Store incoming data: Stores each station (including objects and items) report
+as a record in the database.  All stations heard on all interfaces will be 
+stored to the database - if you are connected to internet feeds and leave 
+xastir running this can easily be a million records per day.
+
+Load data on startup: Retrieve all station data from the database
+when restaring Xastir.  Currently the only way to retrieve persistent 
+data from a database.  Will attempt to connect to database and retrieve data 
+independent of the settings of either activate on startup or store incoming
+data.  Due to rounding and conversion errors, non-mobile stations may move 
+slightly.  
+
+The "Most Recent Error" box may or may not contain an error message to help
+identify connection problems.  When Xastir fails to connect to a database, 
+the interface will show ERROR on the interface list, and the most recent error 
+may be shown here.   Running xastir from the console and observing error 
+messages there, or running xastir from the console with xastir -v1 may help
+identify the cause of connection problems, as may examination of the 
+database's error logs.  
+
+You will only be able to configure a SQL Database interface if you have 
+compiled Xastir with support for that DBMS (--with-mysql or --with-postgis).
+
+HELP-INDEX>Symbol Table
+
+These are the symbols that you can select for your station under the "Station
+Information" configuration menu. The current list can be found in the APRS(tm)
+Reference which you could get from http://www.tapr.org
+
+                             Symbol Table
+
+Symbol     Group /                       Group \
+
+!          Triangle w/!                  Triangle w/!
+"          Rain Cloud                    Rain Cloud
+#          Digi                          DIGI
+$          Phone Symbol                  $ Symbol
+%          DX                            DX
+&          GATE-HF                       GATE
+'          Small Aircraft                Aircraft Crash
+(          Cloud                         Cloud
+)          TBD
+*          SNOW Flake                    SNOW Flake
++          Red Cross
+,          Reverse L
+-          House w/omni
+.          Small x
+/          Red Dot
+0          0 in a box                    Circle
+1          1 in a box
+2          2 in a box
+3          3 in a box
+4          4 in a box
+5          5 in a box
+6          6 in a box
+7          7 in a box
+8          8 in a box
+9          9 in a box                    GAS
+:          Fire                          ?
+;          Tent                          Tent
+<          Motorcycle                    Pennant
+=          Train Engine
+>          Car                           Car
+?          POS Antenna                   ? in a box
+@          HURRICANE/STORM               HURRICANE/STORM
+A          First Aid                     Box
+B          BBS                           Blowing Snow
+C          Canoe
+D          D in a circle
+E          E in a circle                 Smoke Stack
+F          F in a circle
+G          Grid Square Antenna           ?
+H          Hotel/Bed
+I          TCP/IP                        ?
+J          J in a circle                 Lightening
+K          School House
+L          Light House                   Light House
+M          Mac
+N          NTS                           ?
+O          Balloon
+P          Police car                    Rx
+Q          Circle with in Circles        Circle with in Circles
+R          RV                            Restaurant
+S          Shuttle                       Satellite
+T          Thunderstorm (cloud/bolt)     Thunderstorm (cloud/bolt)
+U          School Bus                    Sun
+V          VOR TAC                       VOR TAC Symbol
+W          National Weather Service      NWS-Digi
+X          Helicopter
+Y          Sail Boat
+Z          Windows
+[          Runner                        WC
+\          DF Triangle
+]          Packet Mail Box
+^          Large Aircraft                Large Aircraft
+_          Weather Station               WS-Digi
+`          Satellite Dish
+a          Ambulance
+b          Bike                          blowing cloud
+c          DX antenna
+d          Fire dept.                    DX Antenna
+e          Horse                         Sleet cloud
+f          Fire Truck                    FC Cloud
+g          glider                        Pennant (2)
+h          Hospital                      HAM
+i          Island                        Island
+j          Jeep                          Jeep
+k          Truck                         Truck
+l          Small dot                     Small Dot
+m          MIC                           Mile Post
+n          N                             Small Triangle
+o          EOC                           Dot with in Circles
+p          Puppy                         Dot with in Circles
+q          GS Antenna                    GS Antenna
+r          Antenna Tower                 Antenna Tower
+s          Boat                          Boat
+t          TS                            ?
+u          18 Wheel Truck
+v          Van                           Dot with in Circles
+w          H20                           Flood
+x          X Windows                     Red Dot
+y          House w/Yagi                  House w/yagi
+z                                        X Windows
+{          FOG                           FOG
+|          Black Line                    Black Line
+}          TCP                           TCP
+~          Sail Boat                     Sail Boat
+
+HELP-INDEX>What was new in Xastir 1.0
+
+Over the past year, Xastir has been under active development, and this new
+release is the culmination of those efforts. Development has been run by
+Chuck Byam, who agreed to take over for Frank Giannandrea. Many other
+individuals have contributed to this project, and are listed in the AUTHORS
+file.
+
+The Xastir package now uses GNU autoconf to build makefiles and select
+features based on the libraries and software one has installed. No more
+editing makefiles as in previous releases!
+
+Starting Xastir 1.0, one probably won't immediately notice any major
+changes. The familiar interface of previous Xastir versions has been retained
+for the most part. The great majority of the changes are improvements in
+efficiency under the hood:
+* Startup time for the program has been improved.
+* Memory usage has greatly improved, with dynamic allocation of separate
+  station, trail, and weather data on an as-needed basis. No longer will
+  memory be wasted on stationary stations for trail data, nor will non-weather
+  stations waste memory for weather information. With these modifications,
+  Xastir can even be connected to the internet link comfortably on a 16MB
+  machine.
+* Improvements have been made to avoid having to reload maps from disk at every
+  minor change; Weather alerts and changes to the display and tracking options
+  no longer cause the maps to reload, rather the trails and symbols are
+  redrawn alone.
+* Improvements have been made to various dialog boxes that re-drew often, to
+  redraw less often, to allow them to be usable on slower systems. This is
+  also true of tracking a station, with the map redrawing only if the station
+  approaches the edge of the screen.
+Thanks to these changes, Xastir is perfectly usable on slower Pentium(tm)
+machines.
+
+Native GeoTIFF support is now included, and will be compiled into one's copy
+of Xastir if they have the GeoTIFF libraries installed on their system. These
+map files are of very high quality, and are especially useful in search and
+rescue operations. Maps on this format are available from the USGS, and
+commercially on CD-ROM. Xastir understands how to convert from the NAD-27
+datum to the new WGS-84 datum, so maps of both format can be read accurately.
+New shortcut buttons have been added to the map selection dialog to enable
+one to pick all maps of a specific type.
+
+Support for the Festival Speech Synthesis System is now available to announce
+new stations and band openings. The old system of alert sounds has been
+retained as well.
+
+Xastir now supports adding and deleting objects. Finally, Xastir users are able
+to manage resources with this useful feature. Objects are helpful for
+coordinating events, directing travelers, and doing search and rescue work.
+
+The County Warning Area maps that display weather alerts are no longer painted
+onto the maps below, but are shaded onto the maps. While this does make the
+colors unpredictable, it is now possible to see the road-maps below the 
+alert! 
+
+A new and useful feature is the change in the orientation of a symbol based on
+the direction in which it is moving. Even without a trail, a quick glance can
+tell you a mobile station's bearing. There are several more new options in the
+display menu, enabling one to decide more precisely what is displayed and what
+isn't.
+
+Panning and control over the map has been enhanced: There are now arrow buttons
+visible at the top of the screen to pan the map. The map can also be panned
+with the arrow keys, and the zoom can be adjusted with the page up and page
+down keys. There are new option in the click menu, to center the map where you
+clicked or to place an object where you clicked. The panning options in this
+menu have been removed in favor of the new controls at the top of the screen.
+
+Support for altnet has been added, enabling one to have a private APRS(tm)
+network for special events, search and rescue, storm chasing, or whenever else
+the user doesn't want to be bothered by the hundreds of APRS(tm) stations
+around.
+
+There are numerous small changes, both visible and invisible to the user. The
+interface control dialog now has a "Start all" and "Stop all" option, to save
+the user the time of performing these actions for each interface. The station
+setup dialog now shows you your symbol, so you don't have to exit the dialog to
+see which symbol you chose. Several buffer overflows that caused unpredictable
+behavior and/or crashes have been fixed. And many minor improvements have been
+made to the source code to ensure that it compiles correctly on various
+systems.
+
+Enjoy the new Xastir!
+
+
+HELP-INDEX>What was new in Xastir 1.1
+
+                    What was new in Xastir 1.1
+
+This new release, Xastir 1.1, adds significant new features and enhancements
+to the user interface. Unlike 1.0, the interface changes will take some getting
+used to, but the flexibility and versatility of the enhanced interface will
+more than make up for the troubles.
+Among the improvements to the user interface:
+* Keyboard shortcuts for menus and dialogs, menu reorganization, and mouse
+  behavior changes.
+* The ability to move objects or measure distance with the mouse, using the
+  appropriate check-boxes in the toolbar.
+* A scale has been added to allow one to judge distance on a map.
+* Map labels for windows-style APRS(tm) maps are rotated to match the marked
+  map features.
+* The user interface for dealing with objects has been entirely redesigned.
+* Station info boxes can be set to automatically update.
+* Tear-off menus.  Allow you to keep a menu on the screen and play with
+  different options. Tear off a menu by clicking on the dashed-line portion.
+
+Map support has been greatly enhanced, with PocketAPRS, ESRI Shapefiles, GNIS
+labels and many graphics formats with ImageMagick. Additionally, support for
+downloading graphical maps from web-servers has been added, allowing Xastir to
+use online radar, Tiger, and Terraserver maps. 
+
+Xastir 1.1 supports much more of the APRS(tm) protocol than its predecessor:
+* It can add, modify, move and view area objects, signpost objects, and items.
+  These features are invaluable for event coordination and search and rescue
+  use. Objects and items are also periodically retransmitted.
+* Support for displaying position ambiguity squares, pre-calculated radio
+  ranges, Maidenhead grid squares, and weather objects. These features aren't
+  extremely common, but do come up occasionally.
+* Support for the APRS(tm) radio direction finding features. These features
+  are useful for anything from tracking jammers to locating lost hikers. Xastir
+  supports both Omni and Beam reports.
+  
+Other notable improvements:
+* Xastir can now search for a specified location or landmark using GNIS data.
+* Track logs can now be exported to file.
+* Maps can be printed if certain tools and libraries are present.
+* Support for retrieving historical track data from findu.com.
+* Xastir now compiles and runs on Mac OS X, Solaris and FreeBSD with only
+  minimal changes; see README for details. 
+* Several major bugs found in 1.0 have been corrected, including the problems
+  loading DOS maps and the problems with the weather reporting. Other minor
+  bugs and memory leaks have been fixed. And several more errors have been
+  corrected in the parsing routines, so Xastir should remain stable no matter
+  what is thrown at it! 
+
+
+HELP-INDEX>What was new in Xastir 1.2
+
+                    What was new in Xastir 1.2
+
+The latest Xastir release adds numerous new capabilities, keeping Xastir a
+benchmark for APRS(tm) programs on any operating system.
+
+Xastir's hardware support has been enhanced, with
+* Support for Serial KISS TNCs
+* Support for Serial TNCs with GPS on the AUX port
+* Support for using AGWPE as a TNC
+* Support for Dallas One-Wire weather station
+  (see http://melhuish.info/simon/projects/oww/)
+* Support for more weather stations via the wx200d daemon (WX-200/WM-918/
+  WMR-918/WMR-968)
+* Support for the different sized rain gauges of the Peet Brothers weather
+  stations.
+
+Additionally, several bugs in the weather reporting code were corrected, and
+support for setting the system clock based on the GPS was added.
+
+There have been many additions and improvements to the Xastir user interface:
+The most notable is the addition of dead-reckoning. This means that stations
+that are moving will continue to move on your screen in the direction and at
+the speed speed that they last reported. The estimated location can be shown
+with any combination of a ghosted icon, a dashed line from the last position,
+or an arc of expected possible distance and angle.
+
+Also very notable are the improvements to the Map Chooser. Maps can now be
+selected a directory at a time, or individually. And the new map properties
+dialog allows individual control of map layering, map color filling, and
+consideration for auto-maps. Additionally, with extent caching under the hood,
+auto-maps regains much of its formal usefulness even with many maps installed!
+
+Bulletins pop up on screen, and emergency beacons cause an alert with the 
+locate station dialog on hand. These changes are helpful in emergencies and
+event coordination.
+
+Xastir can now be set to use one of several coordinate systems, including UTM,
+dd.ddddd, dd mm.mmm, and dd mm ss.s. This is helpful for coordinating with
+other groups using a different system.
+
+The online Tiger maps can now be enabled from the map menu, and options can
+be adjusted to request maps with just the data you want displayed.
+
+The stations menu has been reorganized, allowing more intuitive filtering of
+stations shown and of accompanying data.
+
+Other smaller interface changes include:
+* The density of the grid-lines can be adjusted with the +, =, and - keys.
+* Objects and item lists have been added to the view menu.
+* Station maidenhead grid squares are now shown in station info and the
+  coordinate calculator.
+* There is a check-box "Track me" to enable easily tracking your own station
+* The length of trails downloaded from findu.com can now be specified.
+* Xastir can now ID via voice IDs or Screen IDs, by editing the configuration
+  file. This is intended for configurations when the Xastir screen is seen
+  remotely via fast-scan TV. 
+* Timestamps are written to log files every 30 seconds of operation, to keep a
+  record of when data was heard.
+* The status bar can display the course/distance to your station when
+  enabled in the file|configure menu.
+* Range scales are now shown opposite the map scale. This is an attempt to
+  standardize various APRS(tm) client approaches to zoom levels.
+
+New additions under-the-hood:
+* Tracked proximity alarms.
+* Export waypoints within proximity boundaries.  Your GPS can show
+  you the locations of APRS(tm) stations as waypoints on the GPS map
+  screen.
+* Export trail as ESRI Shapefile.  New feature if you have Shapelib
+  compiled in.  Station Info->Store Track button also creates a
+  Shapefile map of the station's track now.
+
+The weather reporting features have been improved, with the addition of
+optional wind barbs to weather stations and decoding of storm wind radius data.
+Weather alert shading is now done with pixmap stipples showing the type of
+alert. Further information on an alert is available over the internet from
+the WXSVR by simply double-clicking the alert in the weather alerts list.
+Weather alerts now use the newer ESRI Shapefile-format maps.
+
+Xastir's map support has been improved with enhancements to the ESRI Shapefile
+code to handle point-type ESRI Shapefiles. Additionally, speed improvements
+have been made in the ImageMagick graphical map loading, and many
+color-correction features have been added. As mentioned above, the Map Chooser
+has been greatly improved, and weather alerts use ESRI Shapefile-format maps.
+
+Under the hood, Xastir has had several major improvements:
+
+The messaging system has been largely rewritten, and the annoying timed updates
+to dialogs no longer occur. The new messaging system allows multiple messages
+to be queued, and implements reply-ack's for speed. Xastir also attempts to
+specify a reasonable path for the message based on received messages. This
+improves speed and congestion control. The messaging GUI has been largely
+untouched, and remains high on the list of future improvements.
+
+The build process has been significantly improved; Xastir is now able to be
+built on numerous operating systems with few manual interventions.
+
+Xastir now supports GPSMan/gpsmanshp, allowing the importing of waypoints,
+tracks, and routes from several types of GPS receivers.  This allows you to
+create ESRI Shapefile-format maps out of GPS data.
+
+Xastir now implements SmartBeaconing(tm), which greatly improves trail quality
+and reduces unneeded channel usage. See the "Configure SmartBeaconing" help
+topic.
+
+IGating support has also improved, with the ability to configure a specific RF
+path for IGated packets, and the addition of a 29 second anti-dupe queue to
+reduce unnecessary redundancy on the RF channel.
+
+Map extents and filenames are now cached, so maps will not be loaded from disk
+unless they are on screen. This is a major improvement for map types that did
+not specify this information. Additionally, auto-maps uses this information,
+making it usable even with many maps installed.
+
+Objects controlled by Xastir are now stored in a file, so a restart of Xastir
+will not cause them to be lost. Additionally, Xastir now supports the
+compressed format for objects and items, which can help reduce RF channel
+congestion. It also gives you better location accuracy of the placed objects.
+See the help topic "Configure Default Operation".
+
+Xastir now drops root privileges when not needed if run setuid root. Please
+read the information about this in INSTALL; this change provides only
+limited protection.
+
+Xastir now supports using a private colormap with the command-line argument
+"-i". This is recommended for systems running in 8-bit color mode. 
+
+Additionally, several more buffer overruns and other errors were corrected in
+Xastir's data parser, and numerous other bugs have been fixed.
+
+Enjoy the new Xastir!
+
+HELP-INDEX>What's new in Xastir 1.3
+
+                    What's new in Xastir 1.3
+
+This latest Xastir release greatly improves on the efficiency and usability of
+Xastir, and adds many helpful and often-requested new features.
+
+.geo files can now have REFRESH tags, to specify how often the file is
+reloaded. This is useful for weather radars and other dynamic images. .geo
+files can also have a TRANSPARENT tag to make a certain color transparent, and
+a CROP tag to specify a specific region to display.
+
+Some Opentrac packets are now decoded and displayed. See
+http://opentrac.org/ for more details.
+
+The default main Xastir directory is now /usr/local/share/xastir; please see
+the upgrade notes in README for migration information. This more closely
+mirrors the behavior of other applications.  If you're installing
+from a binary package (rpm/deb/etc), the default install location
+may be /usr/share/xastir.
+
+Xastir efficiency has been greatly improved. Changes in data structures and
+timing values have made this Xastir release the most efficient yet.
+Additionally, map redraw sequences are interruptible, so map panning speed
+has been improved.
+
+dbfawk support - Experimental support for configurable shapefile metadata, in
+an awk-like language. See README.MAPS for more details; this must be turned
+on with a specific switch to the configure command.
+
+GDAL/OGR support - Experimental support for GDAL and loading of native Tiger
+data (.RT1 files). This is automatically enabled if the GDAL library is
+found.
+
+Support for UTM w/special zones and MGRS coordinate systems.
+
+Cad drawing mode allows one to draw regions on your screen using the center
+mouse button. This feature is not yet complete, but is functional.
+
+User interface changes:
+* Several of the menus have been reorganized to have a hierarchical design.
+* Additionally, a few colors have been modified for better visibility.
+* The map label font and style are more configurable
+* The cursor changes to let one know if they're in move object or measure mode.
+* If the coordinate system is set to UTM, and "Map Grid" is selected, an UTM
+  grid is displayed. 
+
+Snapshot mode now generates a .geo file, allowing the image to later be used
+as a map.
+
+Tiger maps have been moved back the chooser, as was the pre-1.2 behavior.
+This is more consistent.
+
diff --git a/help/help-French.dat b/help/help-French.dat
new file mode 100644
index 0000000..4abb303
--- /dev/null
+++ b/help/help-French.dat
@@ -0,0 +1,593 @@
+HELP-INDEX>ME LIRE EN PREMIER - License
+
+                        ME LIRE EN PREMIER pour XASTIR
+
+Traduction Francaise par F1SJE F1SJE at F1SJE.FRPA.FRA.EU
+Correction et derniers peaufinages F1IOL at F6KBF.FRPA.FRA.EU
+                        
+!!! NOTE: Ces documentations ne sont peut-�tre pas � jour ou incompl�tes
+
+Les plus r�centes informations sont dans le README.1ST dans le r�pertoire
+Xastir.
+
+Ce programme est destin� a �tre utilis� par des radio-amateurs DANS LE
+CADRE DE LEUR REGLEMENTATION NATIONALE.
+
+LICENSE :
+
+XASTIR, Amateur Station Tracking and Information Reporting
+Copyright (C) 1999  Frank Giannandrea
+Copyright (c) 2000-2012 The Xastir Group
+
+Ce programme est libre; vous pouvez le redistribuer et le modifier
+dans les conditions d�finies dans la "GNU General Public License"
+(version 2 ou sup�rieure) d�finie par la "Free Software Fondation".
+
+mais SANS AUCUNE GARANTIE. Voir la "GNU General Public License" pour
+plus de d�tails.
+
+Vous devriez avoir recu une copie de la "GNU General Public License"
+avec ce programme sinon �crivez �  : the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+Plus d'informations sur ce programme peuvent �tre trouv�e sur sa page Web :
+
+http://www.xastir.org
+http://sourceforge.net/projects/xastir/
+http://xastir.sourceforge.net
+
+Pour plus d'informations sur la License GNU regardez sur :
+http://www.gnu.org
+
+
+HELP-INDEX>Bienvenue! Et notes de l'auteur.
+
+                        Bienvenue dans Xastir
+                        
+XASTIR, ou X-windows Amateur Station Tracking and Information Reporting.
+
+C'est un programme APRS(tm) dont les sources sont ouvertes et libres 
+d'utilisation et de diffusion. Ce programme est en cours de d�veloppement
+et ne devrait pas �tre vu comme un produit fini. J'aurai besoin de votre 
+aide pour le rendre plus fonctionnel. J'ai beaucoup d'id�es mais peu de 
+temps alors si vous pensez pouvoir m'aider n'h�sitez pas et faite moi le 
+savoir!
+
+73s
+Frank Giannandrea
+
+APRS[tm] est une marque d�pos�e de Bob Bruninga, 
+Sa page d'accueil est  "http://web.usna.navy.mil/~bruninga/aprs.html"
+
+HELP-INDEX>D�buter
+                               D�buter
+                               
+Maintenant que Xastir fonctionne il faut le configurer !
+Le menu Configurer va vous permettre de param�trer votre station.
+La plupart de options par d�faut vous permettent d�j� de travailler.
+
+Le sous menu d�faut vous permet de s�lectionner les valeurs des 
+diff�rents intervals de temps, les options de transmission et les
+fonctions du gateway internet.
+
+Le sous menu interfaces vous permet de param�trer vos p�riph�riques
+s�rie, AX25, GPS, Stations m�t�o, Connexions internet etc...
+Vous pouvez �galement modifier les param�tres de ces interfaces avec
+ce menu.
+
+Pour commencer le plus important est de configurer la station; 
+indicatif, Latitude/Longitude (Si vous n'avez pas de GPS), incertitude 
+quant � la position et autres informations.
+
+Alarmes sonores va configurer les sons en fonction des �v�nements.
+
+Mesure vous permettra de choisr entre syst�me m�trique ou mesures 
+anglaises.
+
+NOTE : Dans les menus les options grises sont actives, quand vous 
+s�lectionnez vous faites passer l'option en gris.
+
+HELP-INDEX>Configuration de la station
+
+                                Configuration de la station
+  
+Entrez votre indicatif/SSID.
+
+Le d�faut est NOCALL, si vous ne savez pas ce que ca veut dire peut-etre
+ne devriez vous pas utiliser ce programme.
+
+Ensuite entrez latitude et longitude en degr�s, minutes, centi�mes
+
+N pour Nord, S pour Sud, E pour Est et attention W pour Ouest (Ndt : allez
+on ne va pas modifier les sources pour ca hi ! ) 
+
+Maintenant entrez votre Groupe/Overlay et le symbole de votre station.
+Regardez le listing des tables pour choisir votre symbole.
+Par d�faut le symbole est x pour xwindows/Unix et le groupe est "/".
+Si vous voulez autre chose entrez la lettre ou le chiffre dans la
+fen�tre Groupe/Overlay et prenez un symbole dans le groupe "\".
+
+Ce n'est pas obligatoire mais si vous voulez entrez ensuite la puissance,
+la hauteur et le gain de votre antenne en vous aidant des tableaux ci-dessous :
+
+
+Chiffre a utiliser       0  1  2  3   4   5   6   7   8   9 
+Puissance    (en watts)  0  1  4  9  16  25  36  49  64  81
+
+Exemple : Entrez 6 pour 36 Watts
+
+Idem pour la hauteur, ce n'est pas la hauteur au dessus du sol
+mais la hauteur au dessus du niveau de la mer.
+
+Chiffre a utiliser    0   1   2   3    4    5    6     7     8     9 
+Hauteur              10  20  40  80  160  320  640  1280  2560  5120
+
+Exemple : Entrez 7 pour 1280m
+
+Pour le gain mettez simplement le gain de votre antenne en dB.
+
+Ci dessous en degr�s par rapport au nord 
+
+Chiffre a utiliser   0   1   2    3    4    5    6    7    8     9 
+Direction (deg)      0  45  90  135  180  225  270  315  360  None
+
+Utilisez 0 pour une antenne omnidirectionnelle (Verticale)
+
+Entrez un commentaire, ce n'est pas exig� mais personnalisera votre station.
+
+L'incertitude quant � votre position vous permet de g�rer la pr�cision 
+avec laquelle vous allez transmettre votre position.
+Avec aucune votre station transmettra la position exacte que vous avez
+entr�e ou recue par GPS sinon votre station sera vue quelque part dans 
+les limites choisies. 
+
+
+cliquez sur OK pour sauvegarder vos changements, cliquez sur annuler pour conserver
+les param�tres courants.
+
+HELP-INDEX>Comment utiliser mon GPS avec Xastir
+
+                        Comment utiliser mon GPS avec Xastir
+                        
+Vous avez 3 solutions, un GPS en r�seau , un GPS sur port s�rie ou un GPS
+sur port s�rie avec TNC et c�ble HSP.
+L'int�r�t d'un GPS en r�seau est que vous pouvez le partager avec d'autres 
+programmes. Xastir peut se connecter en r�seau sur un d�mon nomm� GPSD.
+Ce programme envoie des donn�es GPS standards sur le r�seau.
+Certaines versions autorisent une connexion GPS sur internet.
+Une fois install� sur votre machine (ou une autre en r�seau) vous pouvez 
+y connnecter Xastir en cr�ant une interface.
+Cliquez sur Configurer/Interfaces
+Ajouter
+R�seau GPS (avec gpsd)
+Entrez le nom de la machine ou vous avez install� GPSD et le nom du port.
+Validez les 2 autres options selon ce que vous voulez.
+
+GPS s�rie :
+C'est un GPS s�rie standard connect� sur port s�rie qui doit transmettre
+ses donn�es au format NEMA. Proc�dez comme pour gpsd pour l'ajouter,
+mettez le port s�rie utilis�, en principe les param�tres par d�faut pour
+le port s�rie doivent fonctionner sinon ajustez les � l'aide de la doc de
+votre appareil.
+
+HSP TNC/GPS: 
+ Regardez � "Comment utiliser mon TNC avec Xastir?"
+
+
+HELP-INDEX>Comment utiliser mon TNC avec Xastir?
+
+                             Comment utiliser mon TNC avec Xastir?
+                             
+La encore vous avez trois solutions : Un TNC en r�seau (AX25), un TNC sur
+port s�rie  et un TNC avec c�ble HSP et GPS.
+
+AX25 :
+
+C'est simplement un des ports du kernel AX25 de Linux, vous devez avoir
+les librairies AX25 d'install�es et le support AX25 dans le Kernel.
+
+TNC S�rie :
+
+TNC S�rie avec HSP et GPS :
+
+
+HELP-INDEX>Configurer les Defauts
+
+                                Configurer les Defauts
+
+cliquez sur Configurer/Defaut.
+
+S�lectionnez l'intervalle de temps au del� duquel votre station sera
+consid�r�e comme vieille, 2 heures par default. Au bout de cet intervalle
+de temps l'icone de la station deviendra ombr�e ou transparente.
+
+
+Cliquez sur OK pour sauvegarder vos changements, Cliquez sur annuler pour conserver
+les param�tres courants.
+
+HELP-INDEX>Configurer le port GPS
+
+                                Configurer le port GPS
+cliquez sur Configurer/Interfaces
+Ajouter
+S�rie GPS pour un GPS seul, vous utiliserez un port s�rie style ttyS1.
+
+Si vous avez un c�ble HSP qui vous permet de partager le port TNC avec 
+un GPS vous devez s�lectionner S�rie TNC/GPS sur c�ble HSP.
+C'est un c�ble sp�cial qui ne fonctionne pas sur toutes combinaisons
+de machines/GPS/TNC.
+Attention aux param�tres de transmission, soyez sympas avec les autres
+utilisateurs de la fr�quence.
+Pour activer l'utilisation du GPS s�lectionner l'option autorisation de 
+transmettre sinon vous transmettrez les donn�es que vous avez configur�es
+dans le sous menu station. Ces donn�es seront mises a jours automatiquement
+si vous utilisez un GPS.
+Quand vous utilisez GPS vous denenez une station mobile avec vitesse et 
+direction m�me si vous ne bougez pas, les donn�es transmises changent. (Je 
+changerai cela avec une option plus tard)  
+Vous devrez s�lectionnez les intervalles de transmission directement
+avec le GPS, les options par defaut de votre station ne seront plus prises
+en compte. Si vous etes en fixe mettez 10 minutes, sinon choissisez les 
+options selon vos besoins.
+
+Cliquez sur OK pour sauvegarder vos changements, Cliquez sur annuler pour conserver
+les param�tres courants.
+
+HELP-INDEX>Configurer le port TNC
+
+                                Configurer le port TNC
+                                
+cliquez sur Configurer/Interface
+Ajouter
+Choisir votre TNC 
+S�lectionnez activer au d�marrage et autorisation de transmettre
+selon vos besoins.
+Entrez le port et param�trez le.
+
+Entrez le chemin des UNPROTOS.
+Xastir par d�faut a d�j� le chemin VIA XX.
+Vous pouvez en ajouter 3 autres de mani�re a �tre bien entendu
+m�me dans de mauvaises conditions.
+En fonction des champs remplis Xastir commencera un cycle d'envoi vers
+ces destinations, l'une apr�s l'autre a chaque fois qu'il sera l'heure
+de transmettre.
+Si vous �tes en local sans digi mettez WIDE2-2, si vous etes QRP ou loin 
+d'un digi WIDE1-1,WIDE2-2 fonctionnera mieux.
+Si vous �tes pr�s d'un digi vous pouvez mettre INDICATIF,WIDE2-2.
+La plupart d'entre vous n'avez besoin que d'un chemin mais si vous n'etes
+pas bien d�gag� mettez en plusieurs, demandez aux stations qui vous 
+entourent.
+
+Cliquez sur OK pour sauvegarder vos changements, Cliquez sur annuler pour conserver
+les param�tres courants.
+
+HELP-INDEX>Configurer la connexion � Internet
+
+                        Configurer la connexion � Internet
+
+Vous devez conna�tre un serveur et un n� de port, par defaut 
+www.aprs.net port 10151. Un mot de passe valide autorisera votre
+station � transmettre par internet et � �tre retransmise sur l'air.
+Pour obtenir un mot de passe contacter Steve Dimse, K4HG � www.aprs.net
+en lui pr�cisant vos nom, indicatif etc etc... Apr�s v�rification il vous
+donnera votre code. Sans code par d'acc�s sur l'air mais vous �tes quand 
+m�me forward� sur Internet.
+Validez reconnexion sur erreur r�seau pour une reconnexion automatique en
+cas de coupure.
+Dans Configurer/options vous avez la possiblit� de devenir un Gateway vous
+aussi. FAITES TRES ATTENTION � cette option, contactez Steve Dimse et veillez
+� rester en conformit� avec la r�glementation en vigueur.
+Dans interface/fichier journal vous avez une option pour enregistrer 
+tous les �v�nements du Gateway.
+
+Cliquez sur OK pour sauvegarder vos changements, Cliquez sur annuler pour conserver
+les param�tres courants.
+
+APRS[tm] est une marque d�pos�e de Bob Bruninga, 
+Sa page d'accueil est  "http://web.usna.navy.mil/~bruninga/aprs.html"
+
+HELP-INDEX>Configurer alertes sonores
+
+                                Configurer alertes sonores
+                                
+Bien �videment vous devez avoir une carte son ! il vous faudra aussi un
+programme qui joue les .wav, mettez le chemin complet dans la fen�tre 
+commande audio.
+
+Choix disponibles :
+
+Nouvelle station
+
+Nouveau message
+
+Proximit�
+
+Ouverture de bande
+
+Distance Minimum
+
+Distance Maximum
+
+Alerte M�t�o
+
+HELP-INDEX>Configuration des  Unit�s
+
+                         Configuration des  Unit�s
+                         
+Ceci selectionne le syst�me d'unit�s, par defaut m�trique. Sinon
+les mesures anglaises sont disponibles.
+
+HELP-INDEX>Ligne de status inf�rieure
+
+                                Ligne de status inf�rieure
+
+En bas de la fen�tre vous pouvez voir diff�rents messages :
+
+1�re fenetre : messages g�n�raux.
+2�me fen�tre : Latitude/Longitude du pointeur sur la carte.
+3�me fen�tre : Nombre de stations dans la base de donn�e.
+4�me fen�tre : Niveau de Zoom et Tr si le suivi de station est actif.
+
+Les 2 derni�res fen�tres montrent le status du TNC et du r�seau.
+Un ">" pour des donn�es sortantes et un "<" pour des donn�es entrantes.
+
+
+HELP-INDEX>Mouvements de la carte (Zoom et N.S.E.W) et menu options
+
+        Mouvements de la carte (Zoom et N.S.E.W) et menu options
+                
+Les mouvements de la carte sont tr�s simple, la facilit� et la rapidit�
+des mouvements d�pend de la vitesse du processeur et du niveau de d�tail
+des cartes charg�es.
+Il suffit de cliquer sur un point de carte pour voir s'ouvrir un menu 
+qui permet de Zoomer sur ce point, voir + au nord, sud est ou ouest par
+rapport au centre de la carte; plus le zoom est petit plus le grossissement
+est grand.
+Le sous menu information sur la station vous donne les �l�ments de la station
+la plus proche du point ou vous avez cliqu�. S'il y a plusieurs stations non 
+loin un choix vous sera propos�.
+
+HELP-INDEX>Menu Cartes et choix de cartes
+
+                        Menu Cartes et choix de cartes
+                        
+Carte automatique Actif/Inactif
+Si actif toutes les cartes du sous r�pertoire "map" et toutes celle des
+r�pertoires dessous seront affich�es si elles correspondent � la r�gion
+sur laquelle vous travaillez. Ceci peut ralentir consid�rablement le syst�me
+si vous avez beaucoup de cartes et un ordinateur tr�s lent.
+Si inactif seules les cartes choisies dans cartes/choisir une carte seront
+affich�es.
+
+Quadrillage Actif/Inactif
+Active un quadrillage tous les 10�.
+
+Niveau Actif/Inactif
+Active le filtrage des petits d�tails quand le niveau de zoom montre une
+large surface, fonctionne seulement avec le cartes g�n�r�es avec "Tiger
+Line maps" (Site aprs.rutgers.edu).
+
+Choisir une carte
+Cliquez simplement sur les cartes que vous voulez afficher. Vous pouvez
+en prendre autant que vous voulez.
+cliquez sur OK pour afficher vos cartes, cliquez sur annuler pour conserver
+les param�tres courants.
+
+HELP-INDEX>Options Visualisation
+
+                                Options Visualisation
+                                
+Ces options vous permettent d'afficher des donn�es autour des stations
+se trouvant sur la carte.
+
+Altitude Actif/Inactif
+Si actif une ligne bleue de donn�es aparait au dessus de l'indicatif,
+indiquant la derni�re altitude connue de la station.
+  
+Route Actif/Inactif
+Si actif une ligne verte de donn�es aparait au dessous de l'indicatif,
+indiquant le dernier azimut connu de la station.
+
+Vitesse Actif/Inactif
+Si actif une ligne rouge de donn�es aparait au dessous de l'indicatif 
+ou de la trajectoire indiquant la derni�re vitesse connue de la station.
+
+Distance/Orientation Actif/Inactif
+Si actif deux lignes de donn�es aparaissent � gauche de l'indicatif, la
+ligne du dessus indique la distance par rapport � votre station, celle
+du dessous l'azimut.
+
+Trajectoire des stations Actif/Inactif
+Si actif toutes les stations en mouvement traceront une ligne de couleur
+affichant les 100 derni�res positions. Quand la station devient vieille
+et que sont icones est transparente la trajectoire n'est plus en ligne
+continue.
+
+PHG  Actif/Inactif
+Si actif on verra des cercles Puissance/Gain autour de la station.
+
+Suivre une station
+Ouvrira une fen�tre ou vous pourrez entrer un indicatif. cliquez sur
+suivre maintenant et l'affichage ira sur cette station et continuera 
+de la suivre quand elle enverra d'autres donn�es.
+cliquez sur fin de suivi pour arr�ter.
+Cliquez sur Annuler pour quitter sans changement.
+
+Information M�t�o
+Si actif Les derni�res donn�es m�t�o seront affich�es (T�, Vitesse et
+direction du vent, rafales, humidit�)
+
+HELP-INDEX>Messages
+
+                                Messages
+                                
+Composer un message et message de groupe
+C'est a peu pr�t la m�me chose. Composer un message enverra votre
+message � une unique station, inversement vous ne recevrez des 
+messages que de cette station. Message de groupe enverra un message
+a un groupe de personnes et inversement vous recevrez tous les messages
+post�s dans ce groupe. Actuellement les messages de groupe ne 
+fonctionnent pas tout � fait bien.
+Dans chacun de ces �crans il y a une fen�tre Message, une ligne Message,
+une fen�tre ident. de la station et quelques boutons.
+Entrez en premier l'indicatif de la station ou le groupe. Ceci fait vous
+recevrez d�j� tous les messages de la station ou du groupe; une fen�tre
+s'ouvrira s'il n'y en a pas d'ouverte. Vous pouvez maintenant entrer
+un message de 250 caract�res maxi sur la ligne message, cliquez sur 
+transmettre maintenant pour l'envoyer. Le bouton restera gris j'usqu'a
+reception d'un accus� de r�ception. Les messages recus seront tri�s et 
+s'afficheront dans la fen�tre message. En mode groupe vous verrez 
+l'indicatif de l'exp�diteur suivi du message; les messages seront tri�s
+par indicatif. Quand vous avez termin� cliquez sur fermer.
+Le bouton nouvelle identit� vous permet de voir les anciens messages
+qu'une station a envoy�s; tapez son indicatif pour les afficher.
+Bien entendu ce bouton peut servir � changer la station avec qui vous
+parlez. Le bouton effacer tous les messages effacera tous les messages
+de la fen�tre en cours.
+
+Effacer tous les messages sortants
+Efface tous les messages non acquitt�s.
+
+R�ponse automatique
+Active ou d�sactive la r�ponse automatique.
+
+Message de r�ponse automatique
+Configure un message de r�ponse automatique.
+
+
+HELP-INDEX>Effacer toutes les stations
+
+                                Effacer toutes les stations
+                                
+cliquez sur fichier/Effacer toutes les stations enlevera toutes
+les station de votre �cran et de la base de donn�es station.
+
+
+HELP-INDEX>Relire un fichier journal
+
+                                Relire un fichier journal
+                                
+cliquez sur Fichier/ouvrir un fichier journal. Choisissez un
+fichier journal, votre station va se comporter comme si elle
+recevait en �mmettait de nouveau, simulant les �v�nements du 
+fichier journal. Ca peut bien sur cr�er quelques messages d'alerte
+si par exemple vous avez eu une session message, votre station va 
+renvoyer les messages � un fichier journal !
+
+HELP-INDEX>Localiser une Station
+
+                                Localiser une Station
+                                
+Cliquer sur examiner/localiser une station, une fen�tre s'ouvre,
+entrez un indicatif ou une partie. Par d�faut Xastir cherchera
+la correspondance exacte (D'une station ou d'un objet). Case exact
+vous permettra de chercher sans prendre en compte la diff�rence 
+majuscule/minuscule. Cliquez sur trouver maintenant centrera 
+l'�cran sur la premi�re correspondance trouv�e.
+Cliquer sur annuler fermera la fen�tre.
+
+HELP-INDEX>Table des symboles
+
+                                Table des symboles
+                                
+
+
+
+Symbole     Groupe /                      Groupe \
+
+
+!          Triangle w/!                   Triangle w/!
+"          Rain Cloud                    Rain Cloud
+#          Digi                          DIGI         
+$          Phone Symbol                  $ Symbol
+%          DX                            DX 
+&          GATE-HF                       GATE
+'          Small Aircraft                Aircraft Crash
+(          Cloud                         Cloud
+)          TBD                           
+*          SNOW Flake                    SNOW Flake  
++          Red Cross                     
+,          Reverse L                     
+-          House w/omni                  
+.          Small x                       
+/          Red Dot                       
+0          0 in a box                    Circle
+1          1 in a box
+2          2 in a box
+3          3 in a box
+4          4 in a box
+5          5 in a box
+6          6 in a box
+7          7 in a box
+8          8 in a box
+9          9 in a box                    GAS
+:          Fire                          ?
+;          Tent                          Tent
+<          Motorcycle                    Pennant
+=          Train Engine                  
+>          Car                           Car 
+?          POS Antenna                   ? in a box
+@          HURRICANE/STORM               HURRICANE/STORM 
+A          First Aid                     Box
+B          BBS                           Blowing Snow 
+C          Canoe                         
+D          D in a circle                 
+E          E in a circle                 Smoke Stack
+F          F in a circle                 
+G          Grid Square Antenna           ?
+H          Hotel/Bed                     
+I          TCP/IP                        ?
+J          J in a circle                 Lightening
+K          School House                  
+L          Light House                   Light House
+M          Mac                           
+N          NTS                           ?
+O          Balloon                       
+P          Police car                    Rx
+Q          Circle with in Circles        Circle with in Circles
+R          RV                            Restaurant
+S          Shuttle                       Satellite
+T          Thunderstorm (cloud/bolt)     Thunderstorm (cloud/bolt)
+U          School Bus                    Sun
+V          VOR TAC                       VOR TAC Symbol
+W          National Weather Service      NWS-Digi
+X          Helicopter                    
+Y          Sail Boat                     
+Z          Windows
+[          Runner                        WC
+\          DF Triangle                   
+]          Packet Mail Box
+^          Large Aircraft                Large Aircraft
+_          Weather Station               WS-Digi
+`          Satellite Dish              
+a          Ambulance
+b          Bike                          blowing cloud
+c          DX antenna                     
+d          Fire dept.                    DX Antenna
+e          Horse                         Sleet cloud 
+f          Fire Truck                    FC Cloud 
+g          glider                        Pennant (2)
+h          Hospital                      HAM
+i          Island                        Island
+j          Jeep                          Jeep
+k          Truck                         Truck 
+l          Small dot                     Small Dot
+m          MIC                           Mile Post
+n          N                             Small Triangle
+o          EOC                           Dot with in Circles 
+p          Puppy                         Dot with in Circles 
+q          GS Antenna                    GS Antenna
+r          Antenna Tower                 Antenna Tower
+s          Boat                          Boat
+t          TS                            ?
+u          18 Wheel Truck                
+v          Van                           Dot with in Circles 
+w          H20                           Flood
+x          X Windows                     Red Dot
+y          House w/Yagi                  House w/yagi 
+z                                        X Windows
+{          FOG                           FOG
+|          Black Line                    Black Line
+}          TCP                           TCP
+~          Sail Boat                     Sail Boat
+
diff --git a/help/help-German.dat b/help/help-German.dat
new file mode 100644
index 0000000..9e8b591
--- /dev/null
+++ b/help/help-German.dat
@@ -0,0 +1,1957 @@
+HELP-INDEX>Einf�hrende Worte / Lizenzbestimmungen
+
+                  Einf�hrende Worte / Lizenzbestimmungen
+
+F�r die aktuellsten Informationen und genauere Installationshinweise
+lesen sie bitte die README Datei im Xastir Hauptverzeichnis. Beachten
+Sie auch die Dateien LICENCE und COPYING f�r weitere Informationen.
+
+Bitte denken sie daran, da� dieses Programm f�r den Einsatz im
+Amateurfunk bestimmt ist. In Deutschland mu� man im Besitz eines
+Funkzeugnises sein, um auf Amateurfunkfrequenzen senden zu d�rfen.
+Informationen zum Erwerb eines Funkzeugisses findet man beim
+Amateurfunkclub DARC http://www.darc.de. Auch in anderen L�ndern
+gelten �hnliche Bestimmungen, die zu beachten sind.
+
+Die Entwicklung der Software und die Dokumentation erfolgte zun�chst in
+Englisch, so da� im Zweifelsfall die englische Version aktueller sein
+k�nnte. Die vorliegende deutsche Hilfedatei wurde von DK7IN �bersetzt.
+Korrekturen und Anregungen bitte an xastir at dk7in.de
+
+
+LIZENZBESTIMMUNGEN f�r XASTIR:
+
+XASTIR steht unter der GNU Lizenz, im Folgenden der englische
+Wortlaut. Die Details der GNU-Lizenz finden sich in der Datei
+LICENCE.
+
+XASTIR, Amateur Station Tracking and Information Reporting
+Copyright (C) 1999,2000 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
+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.
+
+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
+
+
+Weitere Informationen zum Programm findet man unter:
+  http://www.xastir.org
+  http://sourceforge.net/projects/xastir/
+  http://xastir.sourceforge.net
+
+Es gibt einige Mailinglisten zu XASTIR. Melden sie sich zu einer oder
+beiden unter http://www.xastir.org an, um die neuesten Diskussionen rund
+um XASTIR zu verfolgen.
+
+Weitere Informationen zur GNU Lizenz finden sich auf:
+  http://www.gnu.org
+
+Informationen �ber Freie Software in deutscher Sprache
+finden Sie bei der Free Software Foundation Europe
+  http://fsfeurope.org/index.de.html
+
+
+HELP-INDEX>Willkommen! und Anmerkungen der Autoren
+
+                 Willkommen! und Anmerkungen der Autoren
+
+XASTIR (X-Window Amateur Station Tracking and Information Reporting)
+
+XASTIR ist ein APRS(tm)-Programm, das als Open Source frei benutzt und an
+andere weitergegeben werden darf. Das Programm befindet sich momentan im
+Entwicklungsstadium und sollte nicht als fertiges Produkt angesehen
+werden! Mit ihrer Mitarbeit kann dieses Programm besser werden. Wenn sie
+also Programmiererfahrung haben, oder Dokumentation schreiben k�nnen,
+k�nnen wir ihre Hilfe gebrauchen. Wir haben eine Menge Ideen aber nur
+begrenzte Zeit. Wenn sie also denken, einen Beitrag leisten zu k�nnen,
+lassen sie es uns wissen!
+
+
+APRS[tm] ist ein Warenzeichen von Bob Bruninga, seine Homepage ist
+"http://web.usna.navy.mil/~bruninga/aprs.html"
+Beachten Sie bitte, da� sehr viel Information zu APRS(tm) in
+der von Bob Bruninga geschriebenen Dokumentationen zu APRSdos
+enthalten ist. Eine weitere Informationsquelle ist die von
+http://www.tapr.org als PDF-Dokument erh�ltliche APRS Spezifikation.
+
+HELP-INDEX>Neuheiten in Xastir 1.2
+
+                       Neuheiten in Xastir 1.2
+
+Die aktuellste Xastir Version hat wiederum einige neue F�higkeiten
+hinzubekommen, so da� Xastir ein Benchmark f�r APRS-Programme auf
+allen Betriebssystemen bleibt.
+
+Die Hardware-Unterst�tzung von Xastir wurde erweitert:
+  * Unterst�tzung f�r serielle KISS TNCs
+  * Unterst�tzung f�r serielle TNCs mit GPS an der AUX-Schnittstelle
+  * Unterst�tzung f�r den Einsatz von AGWPE als TNC
+  * Unterst�tzung f�r eine Dallas One-Wire Wetterstation
+  (siehe http://melhuish.info/simon/projects/oww/)
+  * Unterst�tzung f�r weitere Wetterstationen �ber den wx200d Daemon
+    (WX-200 / WM-918 / WMR-918 / WMR-968)
+  * Unterst�tzung f�r verschieden gro�e Regenmesser der Peet Brothers
+    Wetterstationen.
+
+Weiterhin wurden einige Fehler Im Kode der Wetterberichte korrigiert,
+auch l��t sich nun die Systemzeit �ber einen angeschlossenen
+GPS-Empf�nger stellen.
+
+Es gab viele Erg�nzungen und Verbesserungen in der Xastir Benutzer-
+Schnittstelle:
+Die bemerkenswerteste ist die Positionsvoraussage. Dies bedeutet, da� sich
+alle beweglichen Stationen nach dem letzten Empfang auf dem Bildschirm
+weiterbewegt werden, so als w�rden sie sich weiterhin mit der letzten
+Geschwindigkeit in die zuletzt berichtete Richtung bewegen. Die so
+vorausgesagte Position kann mit einer Kombination aus einem schemenhaften
+Symbol, einer gestrichelten Linie von der letzten gesicherten Position und
+einem Kreissegment des erwarteten Bereichs von Entfernung und Richtung
+angegeben werden.
+
+Bemerkenswert ist auch die Verbesserung der Kartenauswahl. Neben der
+individuellen Auswahl einzelner Karten k�nnen nun auch ganze
+Kartenverzeichnisse auf einmal ausgew�hlt werden. Unter "Eigenschaften"
+bei der Kartenauswahl, kann den einzelnen Karten nun eine individuelle
+Ebene zugewiesen werden, um die Reihenfolge der Darstellung zu beeinflussen.
+Ebenso wird dort festgelegt, ob Karten mit Farbe gef�llt werden sollen, oder
+ob sie bei "automatischen Karten" ber�cksichtigt werden sollen.
+Dank erweiterem Caching im Hintergrund erlangen automatische Karten wieder
+ihre Bedeutung, und das auch bei vielen installierten Karten!
+
+Bekanntmachungen erscheinen auf dem Schirm und Notfall-Baken ergeben eine
+Warnung, die gleich die Sucheingabe f�r diese Station mitbringt. Diese
+�nderungen sind hilfreich bei der Koordination von Notf�llen oder Ereignissen.
+
+Xastir kann nun f�r verschiedene Koordinatensystemen eingerichtet werden,
+darunter UTM, dd.ddddd, dd mm.mmm, und dd mm ss.s. Dies ist hilfreich bei
+der Koordination mit anderen Gruppen, die ein abweichendes System benutzen.
+
+Die online Tigermaps k�nnen nun aus dem Kartenmenu heraus eingeschaltet
+und die anzuzeigenden Daten individuell angepa�t werden.
+
+Das Stationen-Menu wurde reorganisiert, um so eine intuitive Filterung der
+darzustellenden Stationen und der dann anzuzeigenden Daten zu erlauben.
+
+Andere kleinere �nderungen beinhalten:
+  * Die Dichte der Gitterlinien kann mit den '+', '=' und '-'-Tasten
+    ge�ndert werden.
+  * Objekte und Items wurden zum Menu "Zeige" hinzugef�gt.
+  * Der Maidenhead Locator wird nun in der Stationsinfo und im
+    Koordinatenrechner angezeigt.
+  * Es gibt einen Schalter "Verfolge mich", um die eigene Station auf
+    einfache Weise immer auf dem Bildschirm zu sehen.
+  * Die L�nge und der Startzeitpunkt der von findu.com herunterzuladenden
+    Spuren k�nnen nun eingestellt werden.
+  * Xastir can now ID via voice ID's or Screen ID's, by editing the
+    configuration file. This is intended for configurations when the Xastir
+    screen is seen remotely via fast-scan TV. 
+  * Zeitstempel werden alle 30 Sekunden in die Protokolldateien geschrieben,
+    um so besser informiert zu sein, wann eine Station geh�rt wurde.
+  * Die Statuszeile kann nun auch die Entfernung und Richtung zur eigenen
+    Station anzeigen, wenn dies im "Datei - Einstellungen" Menu aktiviert
+    wurde.
+  * Eine Bereichsskala erg�nzt nun die L�ngenskala. Dies ist ein Versuch,
+    den Ansatz bez�glich der Zoom-Stufen bei verschiedenen APRS-Programmen
+    zu standardisieren.
+
+Die M�glichkeiten von Wetterberichten wurden verbessert, mit dem
+Hinzuf�gen einer optionalen Windfahne bei Wetterstationen und der
+Dekodierung des Radius von Sturmwinden. Die Markierung von gebieten mit 
+Wetterwarnungen wird nun mit Mustern vorgenommen, die die Art der Warnung
+zeigen. Weitere Informationen zu einer Warnung stehen �ber das Internet
+vom Wetterserver zur Verf�gung und werden durch Doppelklicken auf die
+Warnung in der Wetterwarnungsliste angezeigt. Wetterwarnungne benutzen
+nun Karten mit dem neueren ESRI Shapefile-Format.
+
+Xastir's kartenunterst�tzung wurde verbessert mit Erweiterungen des ESRI
+Shapefile Kodes um Punkt-Typ ESRI Shapefiles handhaben zu k�nnen. Zus�tzlich
+wurden Geschwindigkeitsverbesserungen beim Laden von Kartengrafiken mit
+ImageMagick erzielt und etliche Farbkorreturm�glichkeiten hinzugef�gt.
+Wie oben erw�hnt, wurde die Kartenauswahl deutlich verbessert und Wetterkarten
+benutzen Karten im ESRI Shapefile-Format.
+
+Im Hintergrund hat Xastir einige wichtige Verbesserungen erfahren:
+
+Das Nachrichtensystem wurde gr��tenteils umgeschrieben und die nervenden
+zeitgesteuerten Updates im Nachrichtenfesnter erscheinen nicht mehr.
+Das neue Nachrichtensystem erlaubt es, mehrere Nachrichten in einer
+Warteschlange zu halten und verwendet Reply-ACK's f�r mehr Geschwindigkeit.
+Xastir versucht auch einen vern�nftigen Pfad aufgrund einer empfangenen
+Nachricht vorzugeben. Dies erh�ht die Geschwindigkeit und vermeidet die
+�berflutung von Digipeatern.
+
+Der Build-Proze� wurde signifikant verbessert. Xastir kann nun auf vielen
+Betriebssystemen �bersetzt werden, wobei nur wenige manuelle Eingriffe n�tig
+sind.
+
+Xastir unterst�tzt nun GPSMan/gpsmanshp, um so Wegpunkte, Tracklogs und
+Routen von verschiedenen Arten von GPS-Empf�ngern zu importieren. Hiermit
+k�nnen auch Karten im ESRI Shapefile-Format aus GPS-Daten erzeugt werden.
+
+Xastir hat nun SmartBeaconing(tm) implementiert, das die Spurqualit�t
+deutlich erh�ht und unn�tige Kanalbelegung vermeidet. Siehe hierzu die Hilfe
+"Einstellungen - Smart Beaconing".
+
+Die Unterst�tzung f�r Internet-Gateways wurde verbessert, mit der M�glichkeit
+f�r weitergereichte Pakete einen speziellen Pfad zu definieren, sowie einer
+29 Sekunden Warteschlange zur Aussonderung von Doppeln, um so die unn�tige
+Redundanz auf dem Funkkanal zu reduzieren.
+
+Kartenbereiche und Dateinamen werden nun gecached, so da� Karten nur von der
+Festplatte geladen werden m�ssen, wenn sie auf dem Schirm darstellbar sind.
+Dies ist eine wichtige Verbesserungen f�r Karten, die diese Information nicht
+angeben. Zus�tzlich wird diese Information von "automatischen Karten"
+verwendet, wodurch dies auch bei vielen installierten Karten noch verwendbar
+ist.
+
+Von Xastir kontrollierte Objekte werden nun in einer Datei gespeichert, so
+da� sie bei einem Neustart von Xastir nicht verloren gehen. Au�erdem
+unterst�tzt Xastir nun das komprimierte Format bei Objekten und Items, was 
+dabei helfen kann, die �berf�llung von Funkkan�len zu reduzieren. Dies
+f�hrt auch zu einer h�heren Genauigkeit der platzierten Objekte. Siehe
+hierzu "Datei - Einstellungen - Grundeinstellungen".
+
+Xastir gibt nun root-Privilegien auf, wenn sie nicht ben�tigt werden, wenn
+es mittels setuid gestartet wird. Bitte lesen Sie die Informationen hierzu
+in der datei INSTALL. Diese �nderung bietet einen eingeschr�nkten Schutz.
+
+Xastir unterst�tzt nun die Benutzung einer eigenen Farbtabelle mit dem
+Kommandozeilenparameter "-i". Dies wird empfohlen f�r Systeme, die im
+8-Bit Farbmodus laufen.
+
+Zudem wurden einige weitere Puffer�berl�ufe und andere Fehler im Datenparser
+von Xastir korrigiert und viele ander Fehler wurden beseitigt.
+
+Erfreuen Sie sich am neuen Xastir !
+
+
+HELP-INDEX>Der erste Aufruf von Xastir
+
+                        Der erste Aufruf von Xastir
+
+Beim ersten Start von Xastir sollten sie das Programm aus einem
+Terminalfenster heraus aufrufen, um m�gliche Fehlermeldungen sehen zu
+k�nnen. Da auf den meisten Systemen der Pfad so eingerichtet ist, da�
+Programme in /usr/local/bin gefunden werden, reicht es am Prompt
+"xastir &" einzugeben. Auf anderen Systemen mu� "/usr/local/bin/xastir &"
+eingegeben werden, um das Programm zu starten. Das '&' sorgt daf�r, da�
+Xastir im Hintergrund gestartet wir, so da� das Terminalfenster noch
+anderweitig verwendet werden kann.
+
+Sie k�nnen beim Aufruf auch gleich die Sprache w�hlen. Um die Sprache zu
+�ndern, rufen sie Xastir mit der Option -l auf:
+
+    xastir -lGerman
+
+Weitere M�glichkeiten sind: 
+    xastir -l Dutch 
+    xastir -l English 
+    xastir -l French 
+    xastir -l Italian
+    xastir -l Spanish
+    xastir -l ElmerFudd
+    xastir -l MuppetsSwedishChef
+    xastir -l OldeEnglish
+    xastir -l PigLatin
+    xastir -l PirateEnglish
+
+Die so gew�hlte Sprache wird in der Konfigurationsdatei des Benutzers
+gespeichert und auch beim n�chsten Aufruf ohne diese Option verwendet.
+Bei einem neu installierten Xastir ist die Voreinstellung Englisch
+bis zu einer �nderung mit dieser Option.
+
+Die Menus am oberen Rand k�nnen auch mit Tastenk�rzeln erreicht werden.
+Diese funktionieren gegebenenfalls nicht, wenn NumLock eingeschaltet ist.
+
+Vor der Benutzung mu� Xastir und einige Schnittstellen konfiguriert
+werden. Die Schnittstellenkonfiguration ist detailliert in der Hilfe
+unter "Schnittstellen" beschrieben.
+
+HELP-INDEX>Stationsdaten
+
+                               Stationsdaten        
+
+Klicken sie auf Datei, Einstellungen, dann auf Meine Stationsdaten
+
+Tragen sie ihr Amateurfunk-Rufzeichen ein.
+
+Tragen sie die Position ihrer Station ein, wenn sie Xastir nicht
+zusammen mit einem GPS-Empf�nger einsetzen. Sie k�nnen ihre ungef�hre
+Position auch mit einer Karte in Xastir bestimmen indem sie die Maus
+auf der Karte plazieren und die Position in der Statuszeile ablesen.
+Wenn sie einen GPS-Empf�nger haben k�nnen sie diesen Schritt
+�berspringen und stattdessen sp�ter den GPS-Empf�nger einrichten.
+
+W�hlen sie ein Symbol f�r ihre Station, hierzu ist die Angabe der
+Gruppe und des eigentlichen Symbolzeichens erforderlich. Sie k�nnen
+dies manuell eintragen, oder nach Dr�cken auf Auswahl aus einer
+grafischen Symbol�bersicht ausw�hlen. Es stehen zwei Gruppen von
+Symbolen zur Verf�gung. Eine Beschreibung der Symbolbedeutung findet
+sich im Hilfetext "Symboltabelle". 
+
+F�r einige Symbole der sekund�ren Gruppe kann auch ein Overlay
+spezifiziert werden. Hierbei wird das Symbol zusammen mit dem
+Overlay-Zeichen dargestellt, z.B. ein Autosymbol mit der Zahl 1.
+
+Um Overlays zu nutzen m�ssen sie ein Symbol der sekund�ren Gruppe w�hlen
+und das gew�nschte �berlagerungszeichen in das Feld Gruppe/Overlay
+eintragen. Nur Zahlen und Gro�buchstaben sind als Overlay zul�ssig.
+Nach den APRS-Spezifikationen kann nicht jedes Symbol �berlagert werden,
+aber Xastir erzwingt dies nicht, wie m�glicherweise andere Programme.
+Beachten sie, da� bisher auch nicht alle Symbole belegt sind und manche
+eventuell nicht ganz den APRS-Spezifikationen entsprechen.
+
+Tragen sie als n�chstes die Daten f�r Leistung, H�he, Gewinn und
+Vorzugsrichtung f�r ihre Station ein. Es ist eine sinnvolle Information
+wird aber nicht unbedingt ben�tigt. W�hlen sie einfach "Kein PHG", wenn
+sie diese Daten nicht aussenden wollen. Diese Einstellungen geben eine
+grobe Vorstellung von der Reichweite ihrer Station. W�hlen sie die Werte,
+die den ihren am n�chsten kommen.
+
+Eine andere M�glichkeit w�re es, stattdessen die Reichweite RNG in
+Meilen im Kommentar zu spezifizieren. F�r Details ziehen sie bitte
+die APRS-Spezifikationen zu Rate.
+
+Benutzen sie hier bitte die nicht die H�he �ber dem Boden oder
+Meeresh�he, sondern die H�he gegen�ber dem durchschnittlichen Gel�nde.
+Die Angabe ist in Fu�, Meter m�ssen mit 3,28 multipliziert werden.
+
+Als Gewinn tragen sie den Antennengewinn in dBi ein.
+
+Anmerkung: Die Angabe des Gewinns ist prim�r f�r Vertikalantennen
+gedacht, f�r Beams sollten kleinere Werte eingetragen werden. Die Grund
+hierf�r ist, da� bei gesetzter Vorzugsrichtung, die Ellipse f�r die
+Reichweite nur um ein Drittel in die angegebene Richtung vergr��ert wird.
+Wird der Gewinn eines Beams gr��er angegeben, so wird nur die
+Reichweitenmarkierung unrealistisch gro�, statt da� die deren
+Richtwirkung erh�ht w�rde.
+
+Bei der Angabe einer Vorzugsrichtung ihrer Antenne w�ren z.B. 90� eine
+Antenne, die nach Osten weist.
+
+Geben sie einen Kommentar ein, dies ist nicht notwendig, erlaubt aber
+die �bermittlung sinnvoller Informationen, wie z.B. den Namen und die
+E-Mail-Adresse. Es wird zusammen mit den Positionsmeldungen �bertragen.
+
+Die Positionsverschleierung erlaubt ihnen einszustellen, wie genau ihre
+Position �bermittelt wird. Bei "Keine" werden die exakten eingetragenen
+oder vom GPS empfangenen Daten ausgesendet. Die anderen M�glichkeiten
+setzen die �bermittelte Position irgendwo in den gew�hlten Bereich.
+Einige Stationen, die nicht ganz den Spezifikationen entsprechen,
+verstehen jedoch keine Positionsverschleierung, so z.B. auch findu.com.
+
+Bei einem Klick auf OK werden die �nderungen gesichert, bei Abbrechen
+bleiben die vorherigen Einstellungen erhalten.
+
+HELP-INDEX>Grundeinstellungen
+
+                             Grundeinstellungen
+
+Klicken sie auf Datei, Einstellungen, dann auf Grundeinstellungen
+
+Auf dieser Seite werden einige Standardwerte f�r den Programmablauf
+eingestellt. Alte Stationen werden nach einiger Zeit schemenhaft
+dargestellt und die zugeh�rigen Spuren gestrichelt.
+
+In der ersten Zeile wird festgelegt, nach welcher Zeit eine Station nur
+noch schemenhaft angezeigt wird. In der n�chsten Zeile wird festgelegt,
+nach welcher Zeit eine Station ganz vom Bildschirm verschwindet. Nach
+dem Doppelten dieser Zeit wird die Station dann auch aus den internen
+Datenbanken gel�scht.
+
+Die dritte Zeile legt fest, in welchen Abst�nden die eigene Position
+�bermittelt wird. F�r Feststationen sind 30 Minuten ein guter Wert, es
+sollten auf alle F�lle nicht unter 10 Minuten sein. Bei Mobilstationen
+kann ein k�rzeres Intervall sinnvoll sein. Diese Einstellung wird auch
+verwendet, um Objekte und Items wiederholt zu senden. Versuchen sie hier
+eine sinnvolle Einstellung zu finden, um nicht zu viel unn�tigen Verkehr
+zu produzieren.
+
+GPS Zeit legt das Zeitintervall fest, nach dem nach neuen GPS Daten
+geschaut wird. Diese Option ist f�r Stationen mit gemeinsamen Zugriff
+auf TNC und GPS �ber ein HSP-Kabel.
+
+Mit dem Sendeformat der Station wird festgelegt, welche Art von Paketen
+die Station sendet.
+
+IGate Options erm�glicht die Errichtung einer Br�cke zwischen Internet
+und Funk. Diese Option sollte mit Vorsicht benutzt werden. Als
+Fumkamateur sind sie selbst daf�r verantwortlich, was aus dem Internet
+kommt und �ber ihre Funkanlage ausgesendet wird. Sie m�ssen au�erdem bei
+jeder Schnittstelle eine IGate-Einstellung machen, damit dies
+funktioniert. Wenn sie wollen, da� ihr IGate NWS Wetterwarnungen �ber
+Funk weitergibt, m�ssen sie eine Datei ~/.xastir/data/nws-stations.txt
+anlegen, in der alle Stationen aufgef�hrt sind (wie z.B. "PHISVR"),
+deren Daten sie �ber Funk weiterreichen wollen.
+
+Bei Aktivierung von "Sende komprimierte Position" wird die Position in
+einem neueren, komprimierten Format gesendet. Hierdurch werden die
+gesendeten Pakete k�rzer, so da� die Kapazit�t des APRS(tm) Netzwerks
+steigt. Die maximale Aufl�sung der gesendeten Position ist ebenfalls
+h�her. Allerdings k�nnen einige �ltere Programme, einschlie�lich
+k�rzlich erschienener Versionen von WinAPRS, dieses Format noch nicht
+dekodieren. Auch findu.com kann damit Probleme haben.
+
+Wenn "Sende Wetter Rohdaten" gew�hlt wurde, werden auch Pakete gesendet,
+die unverarbeitete Wetterstationsdaten enthalten. Dies ist n�tzlich f�r
+Wetterstationen mit ASCII-Daten, wie Peet Bros. Wetterstationen.
+
+Sie k�nnen au�erdem Alternatives Netz aktivieren, und dort ein eigenes
+K�rzel eintragen. Alternatives Netz erlaubt ihnen damit, ein privates
+APRS-Netzwerk aufzubauen, mit Stationen, die ebenfalls Alternatives
+Netz aktiviert haben und das gleiche Rufzeichen benutzen.
+
+HELP-INDEX>Audio Alarm
+
+                               Audio Alarm
+
+Klicken sie auf Datei, Einstellungen, dann Audio Alarm.
+
+Um diese Option zu nutzen, ben�tigen sie eine Soundkarte und ein
+Programm, das Audiodateien im WAV-Format abspielt. Tragen sie als
+Kommando dieses Programm ein und eventuell ben�tigte Kommandozeilen-
+parameter. Das ganze funktioniert nat�rlich nicht, wenn die einzige
+Soundkarte im System f�r ein Soundmodem benutzt wird...
+
+F�r verschiedene Ereignisse kann eine Datei eingetragen werden, z.B. eine
+wav-Datei, die abgespielt werden soll. Bei einigen Ereignissen k�nnen
+zus�tzliche Parameter ge�ndert werden. F�r jedes Ereignis kann einzeln
+festgelegt werden, ob eine akustische Meldung erfolgen soll.
+
+Momentan steht zur Verf�gung:
+Abspielen einer Ansage beim Auftauchen einer neuen Station
+Abspielen einer Ansage bei einer neuen Nachricht
+Abspielen einer Ansage, wenn Daten von einer Station empfangen
+     werden, die sich innerhalb einer min/max Entfernung gem�� den
+     Ann�herungs-Einstellungen befindet
+Abspielen einer Ansage, wenn Daten von einer Station �ber TNC
+     empfangen werden, die sich innerhalb einer min/max Entfernung
+     gem�� den Band�ffnungs-Einstellungen befindet
+Abspielen einer Ansage bei einer Wetterwarnung
+
+
+HELP-INDEX>Sprachausgabe
+
+                            Sprachausgabe
+
+Klicken sie auf Datei, Einstellungen, dann Sprachausgabe.
+
+Um diese Option zu nutzen, ben�tigen sie neben einer Soundkarte die
+'Festival' Sprachsynthese Software. Installieren sie Festival und starten
+sie es als Server bevor sie Xastir aufrufen. Das Kommando hierf�r hei�t
+�blicherweise "festival --server &".
+
+Nachdem Festival installiert ist, kann Xastir f�r folgende F�lle eine
+Sprachausgabe vornehmen:
+
+o Ansagen des Rufzeichens einer neuen Station.
+
+o Ansagen, da� eine neue Nachricht eingetroffen ist.
+
+o Den Text einer Nachricht vorlesen.
+
+o Eine Ansage, wenn Daten von einer Station empfangen wurden, die sich
+  innerhalb einer min/max Entfernung gem�� den
+  Ann�herungs-Einstellungen (siehe Audio Alarm) befindet.
+
+o Eine Ansage, wenn Daten von einer Station �ber TNC empfangen werden,
+  die sich innerhalb einer min/max Entfernung
+  gem�� den Band�ffnungs-Einstellungen (siehe Audio Alarm) befindet.
+
+o Die Ansage einer Wetterwarnung ist bisher noch nicht verf�gbar.
+
+Informationen zu Festival erhalten sie �ber:
+  http://www.speech.cs.cmu.edu/festival/
+
+HELP-INDEX>Ma�einheiten
+
+                             Ma�einheiten
+
+Als Standardeinstellung wird das metrische System mit mm, cm, m, km,
+km/h, usw. verwendet. Wenn sie englische Ma�einheiten bevorzugen,
+klicken sie auf Datei, Einstellungen und aktivieren sie Englische Ma�e,
+um Zoll, Fu�, mph, usw. anzuzeigen.
+
+HELP-INDEX>Einstellungen sichern
+
+                         Einstellungen sichern
+
+�ber Datei, Einstellungen, Einstellungen sichern k�nnen alle
+vorgenommenen Einstellungen sofort in der Konfigurationsdatei gespeichert
+werden. Aber auch beim Verlassen des Programms werden die Einstellungen
+gespeichert.
+
+HELP-INDEX>Statuszeile
+
+                                 Statuszeile
+
+Am unteren Rand des Bildschirms werden verschiedene Statusmeldungen
+dargestellt:
+
+Im ersten Feld (links) werden allgemeine Statusmeldungen angezeigt, sie
+werden nach kurzer Zeit wieder gel�scht.
+
+Das zweite Feld zeigt bei Mausbewegungen die aktuelle Position auf der
+Karte unter dem Mauszeiger an.
+
+Ein drittes Feld zeigt die Anzahl der insgesamt empfangenen Stationen in
+der Datenbank an.
+
+Das vierte Feld zeigt den aktuellen Zoomstatus an und ein "Tr", wenn eine
+Station verfolgt wird (Tracking).
+
+Das letzte Feld zeigt mit Symbolen den Status f�r jedes Ger�t an, wobei
+die Schnittstellen von links nach rechts (0 bis 9) gez�hlt werden. Der
+Status wird vertikal in drei Bereiche unterteilt. Oben Art des Ger�ts,
+in der Mitte der Datenflu� und unten der Betriebszustand.
+
+Die Art des Ger�ts kann anhand der Farbe unterschieden werden. Blau steht
+f�r die verschiedenen TNC Ger�te, gr�n sind GPS-Empf�nger, gelb Internet
+Server und orange Wetterstationen.
+
+In der Mitte zeigt ein links weisender Pfeil empfangene Daten an, ein
+rechtsweisender Pfeil steht f�r �ber dieses Ger�t gesendete Daten.
+
+Ein gr�nes Rechteck im unteren Bereich zeigt, da� diese Schnittstelle
+aktiviert ist. Ein rotes Rechteck deutet auf eine aktive Schnittstelle
+hin, bei der aber ein Fehler aufgetreten ist. Anderenfalls wird nichts
+angezeigt, wenn die Schnittstelle nicht aktiv ist.
+
+HELP-INDEX>Verschieben der Karte und Mauszeiger-Menu
+
+                  Verschieben der Karte und Mauszeiger-Menu        
+
+Das Verschieben der Karte ist sehr einfach, die Geschwindigkeit des
+Bildaufbaus h�ngt jedoch von der Rechnerleistung und dem Umfang der zu
+ladenden Kartendaten ab.
+
+Zoomen:
+Man kann in der Karte zoomen, indem man auf der Karte mit der rechten
+Maustaste klickt (und diese gedr�ckt h�lt). Es erscheint ein PopUp-Menu,
+mit der M�glichkeit, hinein oder heraus zu zoomen, oder auf eine der
+vordefinierten Skalierungsfaktoren zu wechseln.
+
+Die Zoom-Funktionen zentrieren die Karte gleichzeitig an dem Punkt, an
+dem die rechte Maustaste gedr�ckt wurde. Bei "Zoomebenen" erh�lt man ein
+Untermenu. Die Skalierungen 1-64 sind f�r die n�here Umgebung, w�hrend
+256 und h�her gr��ere Bereiche darstellen. Je kleiner die Zahl, umso
+lokaler wird der Kartenausschnitt.
+
+Ein schnelleres Hineinzoomen in einen Kartenausschnitt kann mit der Maus
+erreicht werden, wenn man auf mit der linken Maustaste auf eine Ecke des
+gew�nschten Ausschnitts klickt, bei gedr�ckter Maustaste zur
+gegen�berliegeden Ecke f�hrt und dort die Taste losl��t. Die Karte wird
+in der Mitte des gew�hlten Ausschnitts neu zentriert, f�r die Skalierung
+wird nur die H�he des Ausschnitts verwendet, die Breite wird der
+Bildschirmgr��e entsprechend angepa�t. Die Schaltkn�pfe "Messen" und
+"Bewegen" d�rfen hierf�r nicht aktiviert sein.
+
+Weiterhin besteht die M�glichkeit die PgUp und PgDn Tasten zum Zoomen zu
+verwenden. Hierbei bleibt das Zentrum er Karte erhalten.
+
+Verschieben/Zentrieren:
+Die Karte kann bei gleicher Aufl�sung neu zentriert werden, indem man
+mit der linken Maustaste auf das neue Zentrum klickt. Beim Klicken mit
+der mittleren Maustaste wird die Karte neu zentriert, au�erdem wird die
+Aufl�sung durch Herauszoomen auf die H�lfte reduziert.
+
+Ein Verschieben kann �ber das Mauszeiger-Menu oder durch die Pfeile am
+oberen Bildschirmrand erfolgen. Die Karte wird nur um einen Teil der
+Bildschirmgr��e verschoben, so da� gen�gend Daten bestehen bleiben, um
+sich wieder zurechtzufinden. Auch die Cursortasten verschieben die Karte.
+
+Informationen zum Mauszeiger-Menu:
+"Stationsinfo" versucht zun�chst die Station zu finden, die der Stelle,
+an der die rechte Maustaste gedr�ckt wurde, am n�chsten liegt. Befinden
+sich dort mehrere Stationen, so kommt zun�chst ein PopUp-Fenster mit
+einer Stationsliste, aus der man die gew�nschte w�hlen kann. Danach, oder
+wenn nur eine Station direkt in unmittelbarer N�he ist, �ffnet ein
+Fenster mit verschiedenen Daten zu dieser Station. Bei Mobilstationen mit
+vielen Daten kann dies auf langsamen Computern etwas Zeit ben�tigen. Um
+alte Stationen zu sehen, kann vor�bergehend "Alte Daten zeigen" im Menu
+"Ansicht" eingeschaltet werden.
+
+�ber den Menupunkt "Letzte Ansicht" kann der vorherigen Kartenausschnitt
+wieder hergestellt werden.
+
+F�r Informationen zu Objekten siehe den Hilfetext "Objekte und Items"
+
+HELP-INDEX>Objekte und Items
+
+                          Objekte und Items
+
+Eine Station kann verschiedene Objekte auf der Karte setzen, deren
+Position auch �ber Funk an andere Stationen weitergegeben wird. Bei den
+Namen f�r Objekte bestehen nicht so viele Einschr�nkungen wie f�r die
+Stationsnamen.
+
+Objekte und Items sind ziemlich das gleiche, sie werden manchmal f�r
+etwas unterschiedliche Zwecke angewandt. Objekte werden oft f�r
+bewegliche oder ver�nderliche Dinge eingsetzt, wie z.B. Wirbelst�rme,
+w�hrend Items im Allgemeinen f�r unbewegliche Dinge, z.B. eine
+Wasserstation, eingesetzt werden. Da Items von einigen APRS-Programmen
+nicht dekodiert werden k�nnen, werden aber oftmals auch unbewegliche
+Objekte verwendet.
+
+�ber das Mauszeiger-Menu hat man Zugriff zu "Objekt Neu" und "Objekt
+�ndern. Ma�geblich f�r das Objekt ist dabei die Position des Mauszeigers
+bei Aufruf des Mauszeiger-Menus.
+
+Neben normalen Objekten mit einem Symbol an der Position gibt es noch
+spezielle Objekte. Fl�chenobjekte sind geeignet, wenn es darum geht einen
+gr��eren Bereich auf der Karte zu markieren. Man kann damit auch Wege,
+Stra�en oder Grenzen zeichnen, ein Suchgebiet abstecken, oder wenn es
+sein mu� auch ein Schachbrett um �ber APRS zu spielen :-) Beachten sie,
+da� Fl�chenobjekte nicht in allen APRS-Programmen implementiert sind und
+wenn, dann auch teilweise unterschiedlich dargestellt werden. Die anderen
+beiden, Signpost und Peil-Objekte werden weiter unten beschrieben.
+
+Objekte werden in den gleichen Abst�nden wie die eigenen Stationsdaten,
+die in "Datei-Einstellungen-Grundeinstellungen" festgelegt sind,
+wiederholt ausgesendet, insgesamt bis zum Doppelten der ebenfalls dort
+definierten Anzeigezeit f�r Stationen. Auch gel�schte Objekte werden
+wiederholt gesendet, bis sie in der Datenbank auslaufen.
+
+
+Bei "Objekt Neu" wird die Position, an der das Mauszeiger-Menu ge�ffnet
+wurde, als Vorgabe f�r ein neu zu erstellendes Objekt verwendet. Nach
+Eingabe eines Namens kann man ein anderes Symbol f�r das Objekt w�hlen,
+einen Kommentar eintragen und es �ber das Menu ein neues Objekt oder
+Item erstellen.
+
+Bei "Objekt �ndern" erh�lt man einen �hnlichen Dialog, bei dem allerdings
+die Daten des Objekt an der Position des Mauszeigers bereits eingetragen
+sind. Einige Daten, wie z.B. der Objektname, k�nnen nicht ge�ndert
+werden. Hier�ber ist auch das L�schen eines Objekts m�glich.
+
+Objekte und Items k�nnen auch mit der Maus auf der Karte verschoben
+werden, wenn der Schaltknopf "Bewegen" auf der oberen Leiste aktiviert
+ist.
+
+Erl�uterung der einzelnen Eintr�ge im Objekt-Dialog:
+
+= Signpost-Objekt =
+Durch Aktivieren wird aus dem Objekt ein Signpost-Objekt, auf einem
+Hinweisschild k�nnen drei Zeichen dargestellt werden, die sichtbar
+werden, wenn an der betreffenden Position hineingezoomt wird. Hinweis:
+Das funktioniert SO noch nicht...
+
+= Fl�chenobjekt =
+Hierdurch wird das Objekt als ein Fl�chenobjekt definiert, zus�tzlich
+werden die unten erl�uterten Steuerfunktionen f�r Fl�chenobjekte
+eingeschaltet.
+
+= Peil-Objekt =
+Hierbei handelt es sich um eine Peilmeldung, die mit dem DF-Symbol
+markiert wird. Sie k�nnen zwischen einer Meldung mit Rundstrahl- oder
+Richtantenne w�hlen und die spezifischen Daten eintragen. N�here Details
+�ber diese Techniken finden sich unter
+   http://web.usna.navy.mil/~bruninga/dfing.html
+und in der APRSdos Dokumentation.
+
+= Name =
+Dies ist der Name des Objekts, der aus bis zu neun Zeichen bestehen kann,
+wobei auch Leerzeichen innerhalb des Namens zul�ssig sind. Beim �ndern
+eines Objekts kann der Name nicht mehr ge�ndert werden. Falls trotzdem
+erforderlich, mu� das Objekt zun�chst gel�scht und dann mit neuem Namen
+neu erstellt werden. Wenn Sie das Objekt als Fl�chenobjekt, Signpost-
+oder Peil-Objekt definieren, wird der dann unn�tige Name gel�scht.
+
+= Stations-Symbol =
+W�hlen sie ein Symbol f�r das Objekt, hierzu ist die Angabe der
+Gruppe und des eigentlichen Symbolzeichens erforderlich. Sie k�nnen
+dies manuell eintragen, oder nach Dr�cken auf "Auswahl" aus einer
+grafischen Symbol�bersicht ausw�hlen. Es stehen zwei Gruppen von
+Symbolen zur Verf�gung. Eine Beschreibung der Symbolbedeutung findet
+sich im Hilfetext "Symboltabelle". Bei Signpost-, Fl�chen- und
+Peil-Objekten l��t sich das Symbol nicht �ndern.
+
+= Position =
+Hier wird die Position des Objekts eingegeben. Wenn Sie ein neues Objekt
+erstellen, so wurde dort bereits die Position eingetragen, an der Sie
+mit der rechten Maustaste geklickt hatten, um das Mauszeiger-Menu
+aufzurufen. Wenn Sie das Objekt verschoben haben, so steht dort die neue
+Position. Sie k�nnen die Daten aber auch manuell eintragen, z.B. wenn
+Ihnen jemand eine Position �ber Sprechfunk durchgegeben hat.
+
+= Allgemeine Optionen =
+Hier k�nnen Sie die Geschwindigkeit, die Bewegungsrichtung und die H�he
+des Objekts eintragen. Bei einigen Objekten ist die Angabe von
+Geschwindigkeit und Richtung nicht m�glich, die Felder sind dann in Grau
+dargestellt.
+
+= Signpost Text =
+Hier k�nnen Sie f�r ein Signpost-Objekt den Text (ein bis drei Zeichen)
+angeben, der auf dem Hinweisschild erscheinen soll. Beachten Sie, da�
+Xastir Signpost-Objekte momentan noch nicht richtig anzeigt.
+
+= Fl�chenobjekt =
+Fl�chenobjekte werden eingesetzt, um spezielle Teile einer Karte
+herauszuheben oder zus�tzliche Details zu zeichnen. Hierzu dienen die
+folgenden Eintr�ge:
+
+  = Helle Farben =
+    Wenn aktiviert, werden hellere, sonst dunklere Farben f�r die Fl�chen
+    verwendet.
+
+  = Fl�chen f�llen =
+    Wenn markiert, werden die Fl�chen mit Objektfarbe gef�llt, ansonsten
+    wird nur die Umrandung dargestellt.
+
+  = Objekt-Typ =
+    Verschiedene geometrische Grundformen k�nnen hier gew�hlt werden:
+    Kreis/Ellipse, Linie nach rechts, Linie nach links, Dreieck, Rechteck
+
+  = Objektfarbe =
+    Hier wird die Farbe gew�hlt in der das Objekt gezeichnet wird. Dies
+    wird auch durch das Markieren von "Helle Farben" (siehe oben)
+    beeinflu�t. Es stehen zur Verf�gung:
+    Schwarz, Blau, Gr�n, Cyan, Rot, Violett, Gelb, Grau
+
+  = nach oben =
+    Ausdehnung des Fl�chenobjekts nach oben in 1/100 Grad. 
+
+  = nach links =
+    Ausdehnung des Fl�chenobjekts nach links in 1/100 Grad. 
+
+  = Korridor =
+    Gibt die Breite eines Linienobjekts an und wird in Meilen
+    spezifiziert.
+
+Denken Sie daran, Ihre Objekte zu l�schen, wenn sie nicht mehr ben�tigt
+werden. Anderenfalls werden sie wiederholt gesendet und erscheinen auf
+dem Bildschirm anderer Stationen bis sie verfallen.
+
+HELP-INDEX>Listendarstellungen
+
+                         Listendarstellungen
+                         
+�ber den Menupunkt "Zeige" k�nnen verschiedene Daten der Stationen meist
+in Form von Listen dargestellt werden.
+
+= Berichte =
+Berichte (bulletin boards) sind eine M�glichkeit, �ber APRS Nachrichten
+und wichtige Ank�ndigungen an alle zu senden. Wenn Sie mit dem Internet
+verbunden sind, ist es sinnvoll, den Einzugsbereich auf wenige 100km
+einzustellen um so Berichte aus anderen Teilen der Welt zu ignorieren.
+Der Eintrag einer '0' im Feld Bereich bedeutet keinerlei Einschr�nkungen,
+d.h. alle Berichte werden empfangen. Klicken Sie auf "neuen Bereich
+setzen" um den eingegebenen Wert zu �bernehmen.
+Xastir unterst�tzt das Senden von Berichten momentan noch nicht.
+
+= Packet Radio =
+Hier werden die �ber Packet Radio oder das Internet ankommenden Rohdaten
+dargestellt. Es kann gew�hlt werden, ob nur Daten vom TNC, nur
+Daten aus dem Internet, oder beides angezeigt werden soll.
+
+= Mobilstationen =
+Dies ist eine Liste von Stationen, die sich bewegen, typischerweise also
+Mobilstationen. Die Bedeutung des Symbols wird dabei ignoriert, es wird
+nur festgestellt, ob sich die Station bewegt. Die angezeigte Information
+umfa�t neben der letzten bekannten Position auch Geschwindigkeit,
+Bewegungsrichtung, H�he, Anzahl der empfangenen Pakete, Anzahl der
+sichtbaren Satelliten sowie Abstand und Richtung von unserer eigenen
+Station.
+
+= Alle Stationen =
+Hier wird eine Tabelle mit allen Stationen in alphabetischer Reihenfolge
+angezeigt. Es umfa�t auch die Anzahl der geh�rten Pakete, die Zeit zu der
+die Station zuletzt geh�rt wurde, den Pfad, den das letzte Paket genommen
+hatte, PHG und nat�rlich den Kommentar.
+
+= Lokale Stationen =
+Eine �hnliche Tabelle wie zuvor, allerdings werden nur Stationen
+angezeigt, die �ber den eigenen TNC geh�rt wurden.
+
+= Letzte Stationen =
+Eine Liste mit allen Stationen in der Reihenfolge, in der sie geh�rt
+wurden. Die zuletzt geh�rten Stationen stehen oben am Beginn der Liste.
+Angezeigt wird wiederum die Anzahl der geh�rten Pakete, die Zeit zu der
+die Station zuletzt geh�rt wurde, den Pfad, den das letzte Paket genommen
+hatte, PHG und der Kommentar.
+
+= Wetterstationen =
+Diese Liste umfa�t nur APRS Wetterstationen mit deren Daten. Aufgef�hrt
+werden Windgeschwindigkeit- und richtung, Geschwindigkeit von B�en, die
+Temperatur, die Luftfeuchtigkeit, den Druck, Regenmenge w�hrend der
+letzten Stunde, seit Mitternacht und w�hrend der letzten 24 Stunden.
+
+= Eigene Wetterdaten =
+Wenn eine eigene Wetterstation vorhanden ist und in Xastir konfiguriert
+wurde, so werden deren Wetterdaten hier angezeigt.
+
+= Wetterwarnung =
+Zeigt die empfangenen Wetterwarnungen des amerikanischen NWS an.
+
+= Nachrichten =
+Zeigt den Nachrichtenverkehr zwischen den verschiedenen Stationen solange
+das Fenster ge�ffnet ist. Dies beinhaltet Quelle und Ziel, �ber welche
+Schnittstelle sie lif und den Inhalt der Nachricht. �ber "Bereich" kann
+die Anzeige auf Nachrichten von Stationen in der Umgebung beschr�nkt
+werden, bei Eingabe von '0' werden alle Nachrichten angezeigt.
+
+= Laufzeit =
+Zeigt an, seit wie lange Xastir bereits l�uft.
+
+HELP-INDEX>Kartenauswahl und Einstellungen
+
+                       Kartenauswahl und Einstellungen
+
+= Kartenauswahl =
+Hiermit erhalten sie eine Liste aller Dateien im Kartenverzeichnis. Wenn
+sie einen Dateinamen markieren, so wird die Karte beim Klicken auf OK
+geladen und angezeigt, wenn sie in den aktuellen Bildauschnitt f�llt.
+Sie k�nnen mehrere Karten gleichzeitig ausw�hlen. Abbruch verwirft die
+�nderungen in der Kartenauswahl. Es gibt auch Buttons um alle Karten
+gleichzeitig abzuw�hlen oder bestimmte Kartentypen zu laden.
+
+= Ausschnitte =
+Genaueres siehe im Hilfetext zu "Gespeicherte Kartenausschnitten"
+
+= Objekt in Karte suchen =
+Hiermit erhalten Sie einen Dialog zur Suche eines bestimmten Objekts in
+einer GNIS Datei. Falls gefunden wird die Karte an dieser Stelle neu
+zentriert. Die zuletzt befragte GNIS-Datei wird beim n�chsten Aufruf
+wiederum als Vorgabe gew�hlt.
+
+= Alle Karten verbergen =
+Hiermit kann das Laden aller Karten vor�bergehend verhindert werden. Dies
+ist vor allem dann vorteilhaft, wenn man die Karte oft verschiebt oder
+zoomt und der langsame Kartenaufbau dazwischen st�rend wirkt. Bei einem
+Neustart von Xastir ist diese Option immer ausgeschaltet.
+
+= Automatische Karte (An/Aus) =
+Falls eingeschaltet, wird jede Karte im Kartenverzeichnis oder einem
+Unterverzeichnis geladen, die f�r den aktuell dargestellten Ausschnitt
+g�ltig ist. Sie k�nnen beliebig viele Uterverzeichnis-Ebenen unterhalb
+des Kartenverzeichnisses anlegen, die automatisch durchsucht werden. Alle
+Karten werden im dargestellten Ausschnitt �berlagert. Die Reihenfolge
+h�ngt von der alphabetischen Sortierung ab, gegebenenfalls kann man Links
+auf andere Namen anlegen, um die Sortierung flexibler handhaben zu
+k�nnen. Wenn sie viele oder komplexe Karten haben, oder einen langsamen
+Computer, dann kann das Laden der Karten sehr lange dauern. Wenn diese
+Option ausgeschaltet ist, werden die in der Kartenauswahl markierten
+Karten geladen.
+
+= Gitter (An/Aus) =
+Wenn eingeschaltet wird ein Kartengitter mit, je nach Zoomebene, 10 Grad
+bzw. 1 Grad Abstand gezeichnet.
+
+= Ebenen (An/Aus) =
+Falls eingeschaltet, werden Details bei der Darstellung herausgefiltert
+wenn gr��ere Bereiche durch herauszoomen dargestellt werden. Dies
+funktioniert nicht mit allen Karten, es verringert auch nicht die
+Ladezeit, sondern sorgt nur daf�r, da� der Bildschirm lesbar bleibt. Ein
+Beispiel hierf�r sind Karten die aus den Tiger Line Karten von
+aprs.rutgers.edu erzeugt wurden.
+
+= Kartenbeschriftungen =
+Hiermit k�nnen Kartenbeschriftungen ein- oder ausgeschaltet werden, die
+in Karten im dosAPRS, WinAPRS, GNIS und ESRI Shapefile Format enthalten
+sind.
+
+= Fl�chen einf�rben (An/Aus) =
+Diese Option legt das Einf�rben bei Vektorkarten fest. In manchen F�llen
+ist es sinnvoll, die F�llung zu entfernen, um darunterliegende weitere
+Karten sehen zu k�nnen. Die Karten werden in alphabetischer Reihenfolge
+geladen, so da� ein Umbenennen oder ein Link eine weitere M�glichkeit in
+diesem Fall darstellt.
+
+= Wetterwarnung Counties =
+Bei Wetterwarnungen des amerikanischen NWS k�nnen einzelne Counties, f�r
+die eine Wetterwarnung vorliegt, eingef�rbt werden. Dies kann hiermit
+gesteuert werden.
+
+= Hintergrundfarbe (An/Aus) =
+Erm�glicht die Auswahl der bei transparenten Karten durchscheinenden
+Hintergrundfarbe.
+
+= Intensit�t =
+Hiermit kann die Farbs�ttigung der Karte gesteuert werden. Dieser
+Menupunkt erscheint nur, wenn Xastir mit GeoTIFF-Unterst�tzung und/oder
+ImageMagick zusammen kompiliert wurde.
+
+= Textdarstellung =
+Erm�glicht die Auswahl zwischen zwei verschiedenen Arten der
+Schriftdarstellung f�r Stationsinformationen auf der Karte.
+
+= Mauszeiger-Menu =
+�ffnet das Mauszeiger-Menu, das sonst beim Klick mit der rechten
+Maustaste erscheint.
+
+
+Eine Anmerkung zu Karten:
+Viele der zur Zeit erh�ltlichen Vektorkarten f�r die USA sind mit dem
+NAD-27 Datum erstellt worden, w�hrend Xastir und andere APRS Programme
+das aktuelle WGS-84 Datum verwenden. Wenn man sehr weit auf einen kleinen
+Kartenausschnitt herein zoomt werden die Abweichungen durch das falsche
+Kartendatum deutlich. Bei den USGS Topographischen Karten wird die
+Datumsabweichung von Xastir korrigiert, so da� Positionen hiermit im
+Allgemeinen genauer sind als mit anderen topographischen Karten.
+
+HELP-INDEX>Kartendateien und County-Daten f�r Wetterwarnungen
+
+          Kartendateien und County-Daten f�r Wetterwarnungen
+
+Kartentypen
+Xastir kann mit den verschiedensten Kartentypen arbeiten. Alle DosAPRS-,
+WinAPRS- und MacAPRS-Karten werden unterst�tzt. Zus�tzlich unterst�tzt
+Xastir von Haus aus Karten im PocketAPRS-Format, Bezeichnungen aus GNIS-
+Dateien (Geographic Names Information System) und Karten im XPixmap-
+Grafikformat. Xastir kann so kompiliert werden, da� externe Bibliotheken
+eingebunden werden k�nnen, um topographische Karten im GeoTIFF-Format und
+ESRI Shapefiles zu unterst�tzen. Die F�higkeit mit Karten in den
+verschiedensten Grafikformaten umzugehen kann durch das Kompilieren mit
+ImageMagick-Unterst�tzung stark erweitert werden (siehe
+"http://www.imagemagick.org/www/formats.html"). Xastir unterst�tzt die
+Darstellung von Bereichen von Wetterwarnungen auf Karten, hierzu k�nnen
+die Daten im klassischen dosAPRS/WinAPRS-Format vorliegen, die Einbindung
+im neuen ESRI Shapefile-Format wird in K�rze vollst�ndig sein. Einen
+Hinweis auf die Quellen von verschiedenen Kartenformaten finden Sie in
+der Datei README.1ST.
+
+Karten-Verzeichnisse
+Alle Kartendateien sollten unter /usr/local/share/xastir/maps auf Ihrm
+Computer gespeichert werden. Zur besseren Organisation und Trennung der
+Karten k�nnen sie dort auch beliebige Unterverzeichnisse anlegen. Bei der
+Kartenauswahl werden die Karten mit ihrem ralativen Pfad alphabetisch
+sortiert angezeigt. Symbolische Links k�nnen helfen, um die Reihenfolge
+gegebenenfalls zu �ndern.
+
+Hinweise zur Installation und Organisation der Karten finden sich
+ebenfalls in README.1ST.
+
+F�r Karten im Pixelgrafikformat werden immer zwei Dateien ben�tigt, zum
+einen die Grafikdatei im .xpm Format (oder andere Formate bei
+ImageMagick-Unterst�tzung) und eine Kalibrierungsdatei (.geo). Das
+Standardgrafikformat ohne zus�tzliche Bibliotheken ist .xpm, um Platz zu
+sparen k�nnen diese Dateien aber auch mit gzip gepackt werden
+("gzip map.xpm" erzeugt die komprimierte Datei "map.xpm.gz"). Dies wird
+von Xastir automatisch erkannt und beim Laden der Karte ber�cksichtigt.
+Sie k�nnen XView, Gimp, ImageMagick oder andere Programme benutzen, um
+Grafiken zu konvertieren, die als gif, jpg oder tiff-Dateien vorliegen,
+wenn Sie nicht ImageMagick hinzukompilieren wollen. Sollten Sie Probleme
+mit Karten im .xpm-Format haben, versuchen Sie zun�chst, die Grafik in
+Gimp zu laden und wieder abzuspeichern, hierdurch werden alle, evtl.
+unbekannten, Farbnamen in Bin�rdarstellung umgewandelt.
+
+Die .geo-Datei ist eine Textdatei, die Kartenposition in der Welt
+festlegt. Zur Erl�uterung hier die Datei world1.geo:
+
+FILENAME   world1.xpm
+#          x          y        lon         lat
+TIEPOINT   0          0        -180        90
+TIEPOINT   640        320      180         -90
+
+Dieses einfache Beispiel besteht aus vier grundlegenden Komponenten. Die
+erste Zeile (FILENAME) legt die Grafikdatei fest, die f�r diese Karte
+benutzt werden soll. Bei einer komprimierten .xpm-Datei ist die Angabe
+der Endung ".gz" optional. Wenn kein Pfad angegeben wird, wird die
+Grafikdatei im gleichen Verzeichnis wie die .geo-Datei gesucht.
+Unter FILENAME kann auch eine URL angegeben werden, unter der Xastir die
+Kartengrafik mittels wget herunterladen kann. Dies bedeutet, da� so
+ziemlich jedes Bild, da� �ber HTTP oder FTP im Internet verf�gbar ist,
+als Karte dienen kann.
+
+Die zweite Zeile ist eine Kommenarzeile, dies wird durch ein '#' als
+erstes Zeichen einer Zeile festgelegt.
+
+Die letzten beiden Zeilen binden x-y-Positionen in der Grafikdatei an
+Koordinaten (L�ngen- und Breitengrade) in der realen Welt. Zwei solche
+Punkte werden ben�tigt und sie sollten f�r eine hohe Genauigkeit
+m�glichst weit auseinander in den Ecken der Grafikdatei liegen, z.B. oben
+links und unten rechts.
+
+Um eine solche Karte zu verwenden, w�hlen Sie in der Kartenauswahl die
+zugeh�rige .geo-Datei.
+
+Die Gr��e der Grafikdatei kann optional ebenfalls in der .geo-Datei
+angegeben werden:
+
+FILENAME        Agnes_Mountain.xpm.gz
+#
+#               X       Y       Lon             Lat
+#               ----    ----    -------------   -----------
+TIEPOINT        0       0       -121.00120491   48.37481943
+TIEPOINT        1337    1999    -120.87619806   48.24982052
+#
+IMAGESIZE       1338    2000
+
+Mit IMAGESIZE wird die Bildgr��e in Pixel angegeben. Xastir benutzt diese
+Information, um Karten, die nicht in den aktuell dargestellten Ausschnitt
+fallen, m�glichst schnell aussortieren zu k�nnen. Wird dies nicht
+angegeben, mu� Xastir die Grafikdatei zum Berechnen auf alle F�lle immer
+laden.
+
+Wenn Xastir mit Unterst�tzung von ImageMagick kompiliert wurde, so stehen
+au�er .xpm s�mtliche Grafikformate zur Verf�gung, die von ImageMagick
+selbst oder seinen Bibliotheken unterst�tzt werden.
+
+Es gibt verschiedene "spezielle" .geo-Dateien, die von Xastir verwendet
+werden k�nnen:
+
+o Eine Datei, die nur das Wort "TIGERMAP" enth�lt, veranla�t Xastir,
+  Tiger Karten im passenden Ausschnitt aus dem Internet zu laden und auf
+  dem Bildschirm darzustellen.
+
+o Eine Datei, die nur das Wort "TERRASERVER-SATELLITE" enth�lt, veranla�t
+  Xastir, Terraserver Satellitenfotos des gew�hlten Ausschnitts
+  darzustellen.  Dies funktioniert allerdings nicht in allen Gegenden der
+  Welt.  Beachten Sie, da� bei einem Zoom-Faktor gr��er als 256 Terraserver
+  Karten zum Laden vermutlich sehr lange brauchen und m�glicherweise auch
+  nicht korrekt dargestellt werden. Dies ist eine Limitierung von
+  Terraserver, nicht von Xastir.
+
+o Eine Datei mit dem Wort "FINDU" und einer weiteren Zeile
+  "CALL <callsign>" l�dt historische Spurdaten der mit dem Call
+  spezifizierten Station. Dies ist allerdings inzwischen �ber das
+  Stationsmenu einfacher zu bewerkstelligen.
+  
+
+geoTIFF Karten sind ebenfalls eine Kombination aus zwei Dateien, einer
+.tif und einer .fgd Datei. Die .tif-Datei enth�lt die eigentlichen
+Kartendaten, die .fgd-Kalibrierungsdatei ben�tigt nur vier Eintr�ge wie
+im folgenden Fall, kann aber viele Andere Eintr�ge zus�tzlich enhalten:
+
+1.5.1.1   WEST BOUNDING COORDINATE:  -122.000000
+1.5.1.2   EAST BOUNDING COORDINATE:  -120.000000
+1.5.1.3   NORTH BOUNDING COORDINATE:  48.000000
+1.5.1.4   SOUTH BOUNDING COORDINATE:  47.000000
+
+Xastir benutzt diese vier Zeilen, um die Eckpunkte der Karte zu
+berechnen, und um festzustellen, ob die Karte in den gerade angezeigten
+Ausschnitt f�llt. Wenn es sich bei Ihren Daten um topographische 
+USGS-Karten handelt, sollten auch die .fgd-Dateien vorliegen. Xastir
+ist in der Lage das Datum von NAD27 in WGS84 umzurechnen, so da� auch
+USGS-Karten unter Xastir eine h�here Genauigkeit erreichen.
+
+Wenn Sie keine .fgd-Datei haben, wird die Karte problemlos geladen,
+allerdings werden die wei�en R�nder am Kartenrand nicht beschnitten und
+die Karte k�nnte eine leicht falsche Gr��e und Rotation besitzen.
+
+Xastir kann nun USGS geoTIFF topographische Karten direkt von einer CD
+laden. Mounten Sie das CD-ROM manuell oder automatisch durch automounter,
+und achten Sie darauf, da� ein symbolischer Link im Kartenverzeichnis auf
+das gemountete Laufwerk zeigt. Das war es!
+
+
+Auch Shapefiles sind eine Kombination aus mehreren Dateien, .shp, .dbf
+und .shx. Sie m�ssen nur die .shp-Datei ausw�hlen, um die Karte zu laden.
+Die anderen Dateien m�ssen jedoch vorhanden sein, um die Karte
+ordnungsgem�� laden zu k�nnen.
+
+
+GNIS (Geographic Names Information System) Daten bestehen aus einer
+Sammlung von Namen von Orten oder geographischen Objekten mit ihren
+jeweiligen Positionen. Diese Bezeichnungen werden wie die in Dos/WinAPRS
+Karten dargestellt. Je weiter man hineinzoomt, umso mehr detailiertere
+Bezeichnungen erscheinen, unter der Annahme, da� eine GNIS-Datei als
+Karte gew�hlt wurde und die Darstellung von Bezeichnungen im Kartenmenu
+eingeschaltet wurden.
+
+
+County Karten f�r Wetterwarnungen
+Alle County-Karten sollten im Verzeichnis /usr/local/share/xastir/Counties
+gespeichert werden. Es gibt verschiedene Formate f�r diese Karten, aber
+dieses Verzeichnis wird immer Unterverzeichnisse f�r jeden Staat/Marine-
+Bereich haben (Abk�rzung aus zwei Buchstaben).
+Das alte Format benutzt <ST><COUNTYNAME>.map, w�hrend das neue Format
+<ST>Z<NWSZONECODE>.map benutzt. Die Installation wird ausf�hrlicher in
+README.1ST im Abschnitt �ber die Quelle von Karten beschrieben.
+
+Wenn eine NWS Nachricht empfangen wird, so werden die entsprechenden
+Bereiche eingef�rbt, um den Bereich der Warnung zu kennzeichnen. Die
+verschiedenen Farben beschreiben dabei die Art der Warnung.
+Urspr�nglich wurden folgende Farben verwendet:
+Cyan for advisory, yellow for watch, red for warning, orange for
+cancelled alert, royal blue for tests, and green for undetermined
+alert levels.
+Inzwischen k�nnen die Farben davon etwas abweichen, da die Fl�chen nun
+nicht mehr gef�llt werden, sondern nur noch in der Farbe ge�ndert werden,
+so da� man die darunterliegende Karte noch erkennen kann.
+Die Darstellung von Wetterwarnungen kann im Kartenmenu ein- bzw.
+ausgeschaltet werden.
+
+HELP-INDEX>Ansicht
+
+                                Ansicht
+
+Die Optionen in diesem Menu erlauben ihnen festzulegen, welche Daten
+zu den Stationen auf der Karte angezeigt werden sollen. Es erlaubt
+Ihnen auch Stationen zu suchen und zu verfolgen, oder Stationen oder
+deren Spur zu l�schen.
+
+= Station finden =
+  Siehe hierzu unter "Stationen finden".
+
+= Verfolge Station =
+  Siehe hierzu unter "Verfolgen von Stationen".
+
+= Spur von Findu holen =
+  L�dt alte Spurdaten einer Station aus dem Internet von findu.com.
+  Momentan werden die Daten der letzten beiden Wochen geladen.
+
+= Symbole =
+  Hiermit kann festgelegt werden, ob Symbole auf der Karte gezeichnet
+  werden sollen. Die meisten folgenden Optionen h�ngen hiervon ebenfalls
+  ab. Bei alten Stationen wird das Symbol nur noch schememhaft in der
+  Standardausrichtung gezeichnet, die zugeh�rige Spur wird gestrichelt
+  und alle Daten au�er dem Rufzeichen verschwinden vom Bildschirm.
+
+= Symbole drehen =
+  Wenn eingeschaltet, werden einige Symbole auf der Karte gedreht, um
+  so die Richtung, in die sich Mobilstationen bewegen, anzudeuten.
+
+= Rufzeichen =
+  Zeigt das Rufzeichen der Station rechts vom Symbol an.
+
+= Geschwindigkeit =
+  Zeigt die Geschwindigkeit einer Station in roter Schrift unterhalb
+  von Rufzeichen und Richtung an, sofern eine Geschwindigkeit
+  �bermittelt wird.
+= - kurz =
+  Wenn markiert wird die Geschwindigkeit in Kurzform ohne Einheit
+  angezeigt.
+
+= H�he =
+  Zeigt die H�he oberhalb des Rufzeichens in blauer Schrift an,
+  sofern sie �bermittelt wurde.
+
+= Kurs =
+  Zeigt die Richtung, in die sich die Station bewegt, unterhalb des
+  Rufzeichens in gr�ner Schrift an, sofern die Station einen Kurs
+  �bermittelt.
+
+= Entfernung/Richtung =
+  Erm�glicht die Anzeige der Entfernung von der eigenen Station und der
+  Richtung, in der sich die Station von der eigenen Station aus befindet.
+  Diese beiden Werte werden links vom Symbol dargestellt.
+
+= Wetterdaten =
+  Wenn eingeschaltet, werden bei Wetterstationen unterhalb des Symbols
+  die letzten Wetterdaten aufgelistet (Temperatur, Wind- und B�en-
+  geschwindigkeit, Windrichtung und Feuchtigkeit.
+= - nur Temperatur =
+  Wenn markiert wird nur die Temperatur angezeigt.
+
+= Leistung/Gewinn =
+  Wenn PHG-Daten �bermittelt werden, wird ein Kreis um die Station
+  gezeichnet, dessen Radius aus Leistung, H�he und Antennengewinn
+  berechnet wird. Wenn sich zwei Kreise �berschneiden sind die
+  Stationen theoretisch in Reichweite f�r eine Simplexverbindung.
+  In der Praxis is dies aber nur eine sehr grobe N�herung, vor allem
+  in Gegenden mit sich �nderndem Gel�nde.
+= - mit Standardwert =
+  F�r Stationen, die keine PHG-Daten �bermitteln, wird stattdessen
+  ein Standardwert gen�� den APRS-Spezifikationen verwendet.
+= - bei Mobilstationen =
+  Hiermit k�nnen auch f�r Mobilstationen Entfernungskreise gezeichnet
+  werden.
+
+= Positionsverschleierung =
+  Wenn eingeschaltet, wird die Fl�che markiert, in der sich eine Station
+  mit Positionsverschleierung befinden kann. Die betreffende Station
+  wird in der Mitte dieses Bereichs positioniert.
+  
+= Alte Daten zeigen =
+  Xastir zeigt Daten auch noch an, nachdem sie eigentlich bereits als
+  alt deklariert wurden. Diese Zeiten k�nnen unter Datei-Einstellungen-
+  Grundeinstellungen ge�mdert werden.
+
+= DF Kreise zeigen =
+  Wenn eingeschaltet, werden auch alle Kreise f�r Peilungen (Direction
+  Finding) angezeigt.
+  
+= Spuren =
+  Wenn markiert, wird f�r Mobilstationen eine farbige Spur mit den
+  letzten maximal 100 Positionen gezeichnet. Jeder neuen Mobilstation
+  wird hierzu eine neue Farbe aus einer Tabelle zugewiesen.
+
+= Stationen l�schen =
+  Dies l�scht alle Stationsdaten au�er den eigenen. Dies ist
+  z.B. n�tzlich, wenn der Speicher knapp bemessen ist.
+
+= Spuren L�schen =
+  L�schen alle Spuren der Mobilstationen. Dies ist z.B. n�tzlich,
+  wenn der Speicher knapp bemessen ist. Die Spur einzelner Stationen
+  kann auch �ber das StationsInfo Menu gel�scht werden.
+
+HELP-INDEX>Nachrichten
+
+                                Nachrichten
+
+= Schicke Nachricht an =
+  Hiermit k�nnen Nachrichten mit einer einzelnen Station ausgetauscht
+  werden. Dies ist auch �ber das Menu StationsInfo m�glich.
+
+= �ffne Gruppen Nachricht=
+  Dies funktioniert �hnlich, nur da� die Nachrichten an einen
+  Gruppennamen geschickt werden. Die Gruppen werden in der Datei
+  "groups" in ~/.xastir/config definiert. Gruppennachrichten sind noch
+  nicht voll implementiert und einige Probleme m�ssen noch beseitigt
+  werden.
+
+In Zukunft wird es auch m�glich sein, Bulletins zu verschicken, dies ist
+aber momentan noch nicht implementiert.
+
+Im Nachrichtenfenster mu� zun�chst das Rufzeichen der Station eingetragen
+werden, der man eine Nachricht schicken will. Darunter kann man dann eine 
+Zeile des Nachrichtentexts (max. 250 Zeichen) eingeben und mit
+"Sende jetzt!" abschicken. Bis zu einer Best�tigung (ACK) durch die
+Gegenstation bleibt dieser Button inaktiv (grau).
+
+Es stehen maximal zehn Fenster f�r Nachrichten an verschiedene Rufzeichen
+zur Verf�gung.
+
+Beim Empfang einer an die eigene Station gerichteten Nachricht �ffnet
+sich automatisch das Nachrichtenfenster, wobei das Rufzeichen des
+Absenders bereits eingetragen ist.
+
+Im gro�en Fenster sind oben die ausgehenden und unten die eingetroffenen
+Nachrichten sortiert nach ihrer Zeilennummer aufgelistet.
+
+Mit "Beenden" wird das Nachrichtenfenster verlassen.
+Mit "Neues Rufzeichen" kann man nachschauen, welche Nachrichten eine
+Station fr�her gesendet hatte. Sie k�nnen dies auch einsetzen, um mit
+einer anderen Station Nachrichten auszutauschen.
+Mit "L�sche Nachrichten" wird die angezeigte Liste mit Nachrichten
+gel�scht.
+
+= L�sche alle ausgehenden Nachrichten =
+  Hiermit werden alle noch nicht best�tigten gesendeten Nachrichten
+  gel�scht. Anderenfalls wird mehrfach versucht, diese zuzustellen.
+
+= Stationen Allgemein =
+  Dies sendet ein ?APRS? Paket, wodurch alle lokalen Stationen mit
+  ihrer Position und/oder ihrem Status antworten sollten. Viele
+  Programme ignorieren diese Anfrage, da eine Antwort zu einer Flut
+  von Daten f�hren kann.
+
+= IGate Stationen =
+  Dies sendet ein ?IGATE? Paket, wodurch alle IGate-Stationen antworten
+  und ihre M�glichkeiten mitteilen sollten.
+
+= Wetterstationen =
+  Dies sendet ein ?WX? Paket, wodurch alle lokalen Wetterstationen ihre
+  Position und die Wetterdaten senden sollten.
+
+= Setze automatische Antwort =
+  Legt den Text fest, der als automatische Antwort gesendet wird.
+
+= Automatische Antwort =
+  Hiermit kann ein vorbereiteter Standardtext bei jeder ankommenden
+  Nachricht als Antwort versandt werden.
+
+HELP-INDEX>Schnittstellen
+
+                           Schnittstellen
+
+In diesem Menu k�nnen Einstellungen zu den vershiedenen Schnittstellen
+gemacht werden.
+
+= Schnittstellen Ein/Aus =
+  Diese Option �ffnet ein Fenster, in dem Sie alle Ihre konfigurierten
+  Schnittstellen ein- oder ausschalten k�nnen.
+
+= Einstellungen =
+  Eine Liste mit den installierten Schnittstellen erscheint und erlaubt
+  Ihnen deren Einstellungen zu �nden und weitere Schnittstellen
+  hinzuzuf�gen bzw. vorhandene zu l�schen. N�heres finden Sie unter
+  "Schnittstellen Konfiguration"
+
+= Nicht senden: ALLES =
+  Wenn markiert wird �berhaupt NICHT gesendet.
+  F�r diese und die folgenden beiden Optionen gilt, da� es sich um
+  globale Einstellungen handelt, die f�r alle Schnittstellen gelten.
+  Die meisten Schnittstellen bieten auch die M�glichkeit, das Senden
+  �ber diese spezielle Schnittstelle einzeln auszuschalten.
+
+= Nicht senden: Meine Position =
+  Wenn markiert wird die eigene Position nicht gesendet.
+
+= Nicht senden: Objekte =
+  Wenn markiert wird die eigenen Objekte nicht gesendet.
+
+= Sende jetzt! =
+  F�hrt dazu, da� alle eingeschalteten Schnittstellen ein Positions-
+  Paket senden. Es ist nicht funktionsf�hig (grau), wenn das Senden
+  grunds�tzlich ausgeschaltet ist.  
+
+HELP-INDEX>Stations-Info
+
+                           Stations-Info
+
+Das Fenster Stations-Info zeigt alle Daten an, die von Xastir f�r diese
+Station dekodiert wurden.
+
+Es k�nnen die folgenden Informationen angezeigt werden: Die Anzahl der
+geh�rten Pakete, die Uhrzeit, zu der die Station zuletzt geh�rt wurde,
+�ber welche Schnittstelle dies erfolgte, den Kommentar, PHG (aus
+Leistung, H�he und Gewinn), Entfernung und Richtung von meiner Station,
+Wetterdaten und die letzte Position.
+Bei Stationen, die sich bewegen, folgt ein Tracklog mit den neuesten
+Daten ganz oben. Ein '+' vor einer Zeile markiert den Start eines neuen
+Tracks (wenn zuvor eine gro�e Zeit- bzw. Ortsdifferenz vorlag). Ein Stern
+am Ende einer Zeile weist darauf hin, da� die Station an der jeweiligen
+Position auf direktem Weg geh�rt werden konnte (ohne Digipeater).
+
+Nur f�r die eigene Station gibt es ein Feld "Echo von", das die letzten
+sechs Digipeater auff�hrt, die mein Paket als erste weitergegeben haben.
+
+Am unteren Rand des Fensters befinden sich zwei Reihen mit vier Aktions-
+feldern, deren Funktion abh�ngig von der Art der dargestellten Station
+ist.
+
+F�r Objekte/Items:
+
+Track speichern    Objekt �ndern         --leer--           Schlie�en
+? Stationsversion  ? Trace         ? unbest. Nachrichten  Stationsanfrage
+
+
+F�r andere Stationen:
+
+Track speichern    Nachricht senden    FCC/RAC Datenbank       Schlie�en
+? Stationsversion  ? Trace           ? unbest. Nachrichten  Stationsanfrage
+
+Bei sich bewegenden Stationen fehlt die Anfrage nach der Stationsversion,
+stattdessen findet sich dort "Spur l�schen". Hiermit werden alle
+Bewegungsdaten dieser Station in der Datenbank und vom Bildschirm
+gel�scht.
+
+Mit "Spur speichern" wird die Position und falls vorhanden, alle
+Bewegungsdaten in einer Datei auf der Festplatte gespeichert. Das
+derzeit benutzte Format ist dem �hnlich, das bei GPS-Empf�ngern zum
+Einsatz kommt, die Spezifikationen k�nnten sich aber in zuk�nftigen
+Versionen noch �ndern. Es gibt momentan keinen Weg, diese Daten wieder
+einzulesen, dies ist aber f�r die Zukunft geplant. Das Ziel ist es auch
+GPS Tracklog-Dateien in �hnlicher Art laden und darstellen zu k�nnen.
+Diese Tracklog-Dateien werden im Verzeichnis ~/.xastir/tracklogs
+abgelegt, der Dateiname besteht aus dem jeweiligen Rufzeichen mit der
+Erweiterung ".trk".
+
+"Objekt/Item �ndern" �ffnet das Fenster zum �ndern von Objekten.
+
+"Sende Nachricht" �ffnet f�r diese Station ein Nachrichtenfenster und
+erm�glicht an diese Station eine Nachricht zu senden.
+
+Wenn die FCC (U.S. Federal Communications Commission) oder RAC (Radio
+Amateurs of Canada) Datenbank installiert ist und das Rufzeichen aus
+dem US-amerikanischen bzw. kanadischen Kontingent stammt, so ist das
+"FCC/RAC Suche"-Feld vorhanden, sonst nicht. Die FCC- und RAC-Dateien
+sollten sich im Verzeichnis /usr/local/share/xastir/fcc befinden, wobei auf
+Gro�-/Kleinschreibung zu achten ist. Wenn die Suche erfolgreich ist,
+wird Name und Adresse der Station im Stations-Info Fenster angezeigt.
+Anweisungen zur Installation dieser Datenbanken finden sich in der
+Datei README.1ST.
+
+Xastir erzeugt beim Start eine Indexdatei f�r jede dieser Datenbanken.
+Wenn eine Rufzeichendatei aktualisiert wird, w�hrend Xastir l�uft, so
+wird der Index bei der n�chsten Suche erstellt oder neu aufgebaut.
+Spezielle Pr�fixe werden NICHT ber�cksichtigt.
+
+HELP-INDEX>Erstellen von Protokolldateien
+
+                    Erstellen von Protokolldateien
+
+Xastir kann empfangene Daten in Protokolldateien schreiben, so da� sie
+sp�ter wieder eingespielt werden, oder zu Debuggingzwecken analysiert
+werden k�nnen. Alle diese Einstellungen werden im Menu "Datei"
+vorgenommen.
+
+= TNC protokollieren =
+  Protokolliert alle Daten, die �ber den TNC empfangen bzw. gesendet
+  werden. Dieses Protokoll kann �ber "Protokolldatei laden" zu einem
+  sp�teren Zeitpunkt wieder eingelesen werden.
+
+= Netz protokollieren =
+  Protokolliert alle Daten, die �ber das Internet empfangen bzw. gesendet
+  werden. Dieses Protokoll kann �ber "Protokolldatei laden" zu einem
+  sp�teren Zeitpunkt wieder eingelesen werden. Wenn Sie keine
+  Schnittstelle gestartet haben und Ihre Position oder die eigenen
+  Objekte lokal protokollieren wollen, ist dies die geeignete Methode.
+
+= IGate protokollieren =
+  Protokolliert alle weitergereichten Daten in beide Richtungen, bei
+  unterdr�ckten Weiterleitungen auch den Grund hierf�r. Dies beinhaltet
+  auch NWS Nachrichten, die in Richtung Funk weitergeleitet werden
+  (gem�� ~/.xastir/data/nws-stations.txt: eine Textdatei, die alle
+  Rufzeichen bzw. NWS Station wie z.B. "SECIND" angibt, deren Daten
+  �ber Funk weitergegeben werden sollen).
+  
+= Wetter protokollieren =
+  Protokolliert alle Wetterdaten, die von Ihrer Wetterstation empfangen
+  werden.
+
+HELP-INDEX>Wiedergeben einer Protokolldatei
+
+                      Wiedergeben einer Protokolldatei
+
+Klicken sie auf Datei, dann auf "Protokolldatei laden". In einem
+Auswahlfenster k�nnen sie eine Datei ausw�hlen, deren Inhalt von Xastir
+geladen werden soll. Es mu� sich dabei um eine Datei mit TNC Rohdaten
+handeln, wie sie auch von Xastir als Protokolldatei geschrieben werden
+kann. Die Station funktioniert dabei weiterhin wie gewohnt, die
+eingespielten Daten werden aber nicht wieder ausgesendet. Wenn sie Daten
+protokollieren, finden sie diese Dateien �blicherweise in ~/.xastir/logs/ 
+
+HELP-INDEX>Finden einer Station
+
+                            Finden einer Station
+
+Klicken sie auf Ansicht, dann auf "Station finden". Ein Fenster
+erscheint, in dem sie das Rufzeichen der zu suchenden Station eingeben
+k�nnen. In der Standardeinstellung wird nach �bereinstimmung mit dem
+kompletten Rufzeichen (Exact Match) gesucht.
+
+Bei Objekten, die Kleinbuchstaben enthalten, mu� "Match Case" gew�hlt
+werden! Entgegen dem Namen wird ohne "Match Case" der Suchbegriff nur in
+Gro�buchstaben umgesetzt...
+ 
+Mit "Finde jetzt!" wird der Suchvorgang gestarted und bei Erfolg der
+Bildausschnitt so justiert, da� die Station mit einer �bereinstimmung
+in der Mitte zu sehen ist.
+
+HELP-INDEX>Gespeicherte Kartenausschnitte
+
+                     Gespeicherte Kartenausschnitte
+
+Klicken sie auf Karten, dann auf "Ausschnitte" und sie erhalten ein
+PopUp-Fenster mit fr�her gespeicherten Kartenausschnitten. Beim ersten
+Aufruf wird diese Liste noch leer sein. Sie k�nnen den aktuellen
+Kartenausschnitt unter einem Namen speichern. Geben sie diesen Namen
+unter "Neuer Name" ein und w�hlen anschlie�end "Hinzuf�gen".
+
+Nach Markieren eines Namens aus der Liste k�nnen sie den gespeicherten
+Kartenausschnitt durch "Aktivieren!" wieder herstellen.
+
+Durch Markieren und "L�schen" k�nnen Eintr�ge aus der Liste auch wieder
+entfernt werden.
+
+"Karte - Objekt in Karte suchen" ist eine weitere M�glichkeit, um einen
+Kartenausschnitt zu �ndern, indem ein bestimmtes Objekt bei installierten
+GNIS-Dateien gesucht werden kann.
+
+HELP-INDEX>Verfolgen einer Station
+
+                  Verfolgen einer Station (Tracking)
+
+Klicken sie auf Ansicht, dann auf "Verfolge Station". Geben sie das
+Rufzeichen ein und dr�cken sie "Verfolge jetzt!". Die verfolgte Station
+bleibt nun immer auf dem Bildschirm sichtbar. Wenn die Station nahe an
+den Rand des Kartenausschnitts gelangt, wird die Karte nachgef�hrt. Um
+das Tracking wieder aufzuheben klicken sie auf "Verfolgung aufheben".
+
+HELP-INDEX>Schnittstellen Konfiguration
+
+                      Schnittstellen Konfiguration
+ 
+Klicken sie auf Schnittstellen, dann auf Einstellungen
+
+Es erscheint ein Fenster "Installierte Schnittstellen", f�r die
+verschiedenen Ger�te, die sie mit Xastir zusammen benutzen wollen. Dort
+k�nnen sie Schnittstellen hinzuf�gen, l�schen und deren Eigenschaften
+�ndern.
+
+Durch Klick auf "Hinzuf�gen" k�nnen sie ein neues Ger�t anmelden,
+es erscheint ein Fenster zur Auswahl des Schnittstellentyps.
+
+Momentan sind verf�gbar:
+  Serieller TNC
+  Serieller TNC plus GPS mit HSP-Kabel
+  Serieller GPS-Empf�nger
+  Serielle Wetterstation
+  Internet Server
+  AX.25 TNC
+  GPS �ber Netzwerk (via gpsd)
+  Wetterstation �ber Netzwerk
+
+Markieren sie das gew�nschte Ger�t aus der Liste und Klicken auf
+"Hinzuf�gen", es erscheint dann ein Fenster, indem sie die verschiedene
+Eigenschaften f�r dieses Ger�t festlegen k�nnen. Tragen sie die
+ben�tigten Werte ein und best�tigen sie mit OK.
+
+Ein Ger�t kann nach Markierung mit einem Klick auf "L�schen" wieder
+entfernt werden.
+
+Mit "Einstellungen" erhalten sie f�r das markierte Ger�t aus der
+Schnittstellenliste ein Fenster, indem sie verschiedene Parameter �ndern
+k�nnen.
+
+Weiterf�rende Hilfe findet man in den Abschnitten f�r die einzelnen
+Schnittstellentypen.
+
+HELP-INDEX>Serieller TNC
+
+                               Serieller TNC
+
+Dieser Abschnitt behandelt das Hinzuf�gen oder �ndern von seriellen TNCs
+und seriellen TNCs mit einem GPS �ber ein HSP-Kabel.
+
+Wenn sie ein HSP-Kabel besitzen, k�nnen sie diesen Eintrag ausw�hlen und
+dann sowohl den TNC als auch den GPS-Empf�nger �ber die gleiche serielle
+Schnittstelle anschlie�en. Es handelt sich um ein spezielles Kabel, bei
+dem die Empfangsleitung durch den Computer zwischen den beiden Ger�ten
+umgeschaltet werden kann. Es arbeitet m�glicherweise nicht mit allen
+m�glichen Kombinationen von Computer, TNC und GPS. Der TNC und der GPS
+m�ssen auf die gleichen Kommunikationsparameter eingestellt werden,
+�blicherweise also 4800 bps, 8 Datenbits, keine Parit�t und 1 Stopbit.
+
+Optionen f�r die TNC-Schnittstelle:
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+"Senden erlaubt" legt fest, ob �ber diese Schnittstelle �berhaupt Daten
+gesendet werden d�rfen.
+
+Als TNC Port wird das Unix Device eingetragen, mit dem der TNC (oder TNC
+und GPS) verbunden ist. Normalerweise geben sie hier /dev/ttyS0 (COM1),
+/dev/ttyS1 (COM2) etc. an.
+
+Setzen sie nun die Baudrate und die Anzahl der Datenbits. 8N1 steht f�r
+8 Datenbits, keine Parit�t und 1 Stopbit, 7E1 f�r 7 Datenbits, gerade
+Parit�t und 1 Stopbit und 7O1 arbeitet mit ungerader Parit�t. Bei
+Verwendung des HSP-Kabels m�ssen diese Einstellungen f�r TNC und GPS
+identisch sein.
+
+Mit den IGate Optionen k�nnen sie festlegen, in welche Richtung
+Internetverkehr �ber diese Schnittstelle erfolgen kann. Dies kann f�r
+jedes Ger�t getrennt eingestellt werden. Wenn sie kein IGate betreiben,
+lassen sie die Einstellungen auf "Disable".
+
+Tragen sie bis zu drei UNPROTO Pfade ein, Xastir gibt dabei das
+Zielrufzeichen vor. Falls mehrere Pfade (bis zu drei) eingetragen wurden,
+so verwendet Xastir diese abwechselnd bei jeder Aussendung, um so auch in
+schwierigen Situationen geh�rt zu werden. Wenn sie nur lokalen Verkehr
+haben, so gen�gt ein einzelnes WIDE2-2. Bei wenig Leistung oder gr��erer
+Entfernung von einem Digipeater d�rfte "WIDE1-1,WIDE2-2" besser funktionieren.
+Wenn sie das Rufzeichen eines benachbarten Digis kennen, k�nnen sie auch
+alle Pakete �ber diesen schicken, indem sie es an erster Stelle nennen,
+also z.B. "DB0XYZ,WIDE2-2". F�r die meisten Stationen wird ein Pfad gen�gen,
+in abgelegenen Gegenden oder unter schwierigen Bedingungen kann es
+sinnvoll sein, mehrere einzutragen. Am besten l��t es sich mit �rtlichen
+Funkamateuren abkl�ren, welcher Pfad geeignet ist, um einerseits gut
+geh�rt zu werden, andererseits aber die Frequenzen nicht unn�tig zu
+belasten. In Gegenden mit intelligenten Digis, die Wiederholungsschleifen
+weitgehend vermeiden, kann auch z.B. WIDE3-3 oder "WIDE1-1,WIDE3-3"
+verwendet werden.
+
+Die TNC Startup und Shutdown Dateien befinden sich im Verzeichnis
+/usr/local/share/xastir/config und werden beim Starten bzw. Stoppen der
+TNC-Verbindung zur Initialisierung ausgef�hrt. Es handelt sich um
+normale Textdateien mit Kommandos, die an den TNC gesendet werden.
+
+HELP-INDEX>AX.25 TNC Schnittstellen
+
+                         AX.25 TNC Schnittstellen
+
+Als AX.25 TNC Device kann jedes Ger�t verwendet werden, da� �ber ein
+Linux AX.25 Treiber angesprochen werden kann. Hierbei handelt es sich um
+einen Kernel-Treiber, der z.B. auch das Baycom-Modem oder ein Packet
+Radio �ber die Soundkarte unterst�tzt. Diese Ger�te m�ssen vor dem Start
+von Xastir in Linux eingerichtet werden, bevor sie benutzt werden k�nnen.
+
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+"Senden erlaubt" legt fest, ob �ber diese Schnittstelle �berhaupt Daten
+gesendet werden d�rfen.
+
+Mit den IGate Optionen k�nnen sie festlegen, in welche Richtung
+Internetverkehr �ber diese Schnittstelle erfolgen kann. Dies kann f�r
+jedes Ger�t getrennt eingestellt werden. Wenn sie kein IGate betreiben,
+lassen sie die Einstellungen auf "Disable".
+
+Geben sie den f�r das AX.25-Ger�t festgelegten Device-Namen an, wie er
+in der Datei /etc/ax25/axports steht.
+
+Tragen sie bis zu drei UNPROTO Pfade ein, Xastir gibt dabei das
+Zielrufzeichen vor. Falls mehrere Pfade (bis zu drei) eingetragen wurden,
+so verwendet Xastir diese abwechselnd bei jeder Aussendung, um so auch in
+schwierigen Situationen geh�rt zu werden. Wenn sie nur lokalen Verkehr
+haben, so gen�gt ein einzelnes WIDE2-2. Bei wenig Leistung oder gr��erer
+Entfernung von einem Digipeater d�rfte "WIDE1-1,WIDE2-2" besser funktionieren.
+Wenn sie das Rufzeichen eines benachbarten Digis kennen, k�nnen sie auch
+alle Pakete �ber diesen schicken, indem sie es an erster Stelle nennen,
+also z.B. "DB0XYZ,WIDE2-2". F�r die meisten Stationen wird ein Pfad gen�gen,
+in abgelegenen Gegenden oder unter schwierigen Bedingungen kann es
+sinnvoll sein, mehrere einzutragen. Am besten l��t es sich mit �rtlichen
+Funkamateuren abkl�ren, welcher Pfad geeignet ist, um einerseits gut
+geh�rt zu werden, andererseits aber die Frequenzen nicht unn�tig zu
+belasten. In Gegenden mit intelligenten Digis, die Wiederholungsschleifen
+weitgehend vermeiden, kann auch z.B. WIDE3-3 oder "WIDE1-1,WIDE3-3"
+verwendet werden.
+
+Anmerkung: Um die AX.25 Treiber verwenden zu k�nnen, mu� Xastir unter
+"root"-Rechten laufen. Um Xastir als normaler Benutzer zu starten, mu�
+das suid Bit beim Xastir-Programm gesetzt werden. Hierzu dient das
+folgende Kommando (als root): "chmod a+s /usr/local/bin/xastir".
+
+Beachten sie bitte, da� jedes Programm, das auf diese Weise l�uft, als
+Sicherheitsrisiko angesehen werden kann. Es wurde nicht besonders auf
+m�gliche Sicherheitsrisiken hin getestet, benutzen sie es also in einer
+Mehrbenutzer-Umgebung mit Vorsicht und auf eigenes Riskio!
+
+HELP-INDEX>Serieller GPS
+
+                              Serieller GPS
+
+Setzen sie die serielle Schnittstelle f�r den GPS Empf�nger. G�ngige
+Eintr�ge sind hier /dev/ttyS0 (COM1) oder /dev/ttyS1 (COM2).
+
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+Setzen sie nun die Baudrate und die Anzahl der Datenbits. 8N1 steht f�r
+acht Datenbits, keine Parit�t und 1 Stopbit, 7E1 f�r 7 Datenbits, gerade
+Parit�t und 1 Stopbit und 7O1 arbeitet mit ungerader Parit�t. Die Daten
+m�ssen mit denen des GPS-Empf�ngers �bereinstimmen, die meisten Ger�te
+verwenden im ben�tigten NMEA-Modus 4800 bps und 8N1.
+
+HELP-INDEX>GPS �ber Netzwerk
+
+                             GPS �ber Netzwerk
+
+Wenn sie die GPS-Daten f�r verschiedene Programme bzw. Computer
+ben�tigen, ist diese Auswahl die geeignetste. Hierzu mu� vorher der gpsd
+eingerichtet worden sein, von dem Xastir dann, neben anderen Programmen,
+die GPS-Daten beziehen kann.
+
+Tragen sie Namen (oder IP-Adresse) und Port-Nummer f�r den gpsd Rechner
+in ihrem Netzwerk ein.
+
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+Durch Markieren von "Wiederverbinden nach Fehler" versucht Xastir die
+Netzwerkverbindung nach einem Fehler wieder herzustellen.
+
+HELP-INDEX>Internet Server
+
+                              Internet Server
+
+Internet Server erlauben ihnen Daten aus der ganzen Welt zu empfangen und
+lokale Daten ins Internet zu senden.
+
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+"Senden erlaubt" legt fest, ob �ber diese Schnittstelle �berhaupt Daten
+ins Internet gesendet werden d�rfen.
+
+Tragen sie Namen (oder IP-Adresse) und Port-Nummer des Internet Servers
+ein, den sie ansprechen wollen.
+
+Geben sie einen g�ltigen Schl�ssel (Pass-Code) ein um Daten �ber ein
+IGate senden zu k�nnen. Wenn sie keinen Schl�ssel passend zu ihrem
+Rufzeichen haben, k�nnen sie einen mit dem beigef�gten Programm
+"callpass" erzeugen. Wenn es noch nicht bereits kompiliert wurde, geben
+hierzu sie im src Verzeicnis "make callpass" ein.
+
+Durch Markieren von "Wiederverbinden nach Fehler" versucht Xastir die
+Netzwerkverbindung nach einem Fehler wieder herzustellen.
+
+HELP-INDEX>Serielle Wetterstation
+
+                          Serielle Wetterstation
+
+Tragen sie die serielle Schnittstelle f�r die Wetterstation ein. G�ngige
+Eintr�ge sind hier /dev/ttyS0 (COM1) oder /dev/ttyS1 (COM2).
+
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+Setzen sie nun die Baudrate und die Anzahl der Datenbits. 8N1 steht f�r
+acht Datenbits, keine Parit�t und 1 Stopbit, 7E1 f�r 7 Datenbits, gerade
+Parit�t und 1 Stopbit und 7O1 arbeitet mit ungerader Parit�t. Die Daten
+m�ssen mit denen ihrer Wetterstation �bereinstimmen.
+
+Durch die Angabe der "Datenart" kann festgelegt werden, welche Daten das
+Programm �ber die serielle Schnittstelle erwartet. Bei "Automatisch" wird
+zun�chst nach Wetterdaten im Bin�rformat geschaut, wie es die Radio Shack
+WX-200 Wetterstation liefert. Falls keine Bin�rdaten im Datenstrom
+gefunden werden, versucht Xastir eine Wetterstation mit ASCII-Daten zu
+finden (wie Peet Bros.).
+
+HELP-INDEX>Wetterstation �ber Netzwerk
+
+                     Wetterstation �ber Netzwerk
+
+Xastir kann Wetterdaten Server wie den wx200d ansprechen. wx200d erlaubt
+mehrere Netzwerkverbindungen, so da� Wetterdaten gleichzeitig
+verschiednen Programmen oder Computern zur Verf�gung steht.
+
+Tragen sie Namen (oder IP-Adresse) und Port-Nummer des Wetterdaten
+Servers in ihrem Netzwerk ein.
+
+Durch Markieren von "Beim Start aktivieren" wird Xastir bei jedem
+Programmstart versuchen, diese Schnittstelle einzuschalten.
+
+Durch Markieren von "Wiederverbinden nach Fehler" versucht Xastir die
+Netzwerkverbindung nach einem Fehler wieder herzustellen.
+
+Wie im vorigen Abschnitt kann durch Angabe von "Datenart" die
+automatische Auswahl �berschrieben werden.
+
+HELP-INDEX>Ausdrucken des Bildschirms
+
+                      Ausdrucken des Bildschirms
+
+Xastir kann den dargestellten Kartenausschnitt in Schwarz-Wei� oder in
+Farbe ausdrucken. Hierbei wird das Bild zun�chst als XPixmap-Datei
+gespeichert, dann werden externen Zusatzprogramme gestartet, um es ins
+PostScript-Format zu konvertieren, zu skalieren und rotieren, eine
+Vorschau zu erm�glichen und es schlie�lich zu drucken.
+
+Hierf�r mu� Ihr System so eingerichtet sein, da� Sie PostScript-Dateien
+drucken k�nnen, gew�hnlich wird hierf�r ghostscript, installierte
+Druckerfilter sowie ein lp oder lpr Druckerspooler ben�tigt. F�r die
+Erstellung der Ausdrucke m�ssen dann die folgenden Pakete installiert
+sein: ImageMagick (speziell "convert"), Ghostscript nebst Schriften, und
+"gv". Wenn diese Pakete funktionsf�hig sind, so sollte kurz nach dem
+Druckbefehl in Xastir ein "gv"-Fenster aufgehen, in dem man das Druckbild
+zun�chst begutachten kann. Falls das Ergebnis zufriedenstellend ist, kann
+es von gv aus ausgedruckt werden.
+
+Beachten Sie, da� es in Abh�ngigkeit von den dargestellten Karten
+sinnvoll sein kann, den Kartenhintergrund auf wei�e Farbe zu �ndern,
+hierdurch kann gegebenenfalls einiges an Tinte gespart werden.
+
+HELP-INDEX>Erstellen automatischer Schnappsch�sse
+
+                Erstellen automatischer Schnappsch�sse
+
+Xastir hat die F�higkeit, wiederholt automatische Schnappsch�sse des
+dargestellten Kartenausschnitts anzufertigen. Momentan erfolgt dies alle
+f�nf Minuten. Unter der Voraussetzung, da� "convert" aus dem ImageMagick-
+Paket installiert ist, erzeugt Xastir eine XPM-Datei in /var/tmp und
+konvertiert diese dann in die PNG-Datei /var/tmp/xastir_snap.png.
+Hiermit kann das aktuelle Geschehen z.B. auf einer regelm��ig
+aktualisierten Webpage dargestellt werden. Schnappsch�sse werden �ber
+Datei - Schnappsch�sse eingeschaltet.
+
+HELP-INDEX>Symboltabelle
+
+                          Symboltabelle
+
+Dies sind die Definitionen der f�r ihre Station oder f�r Objekte
+w�hlbaren Symbole. Es stehen zwei Gruppen zur Verf�gung, mit teilweise
+unterschiedlichen Symbolen bei gleichem Symbolbuchstaben. Die Grafiken
+aus der alternative Gruppe "\" werden auch herangezogen, wenn ein Overlay
+erfolgen soll. Hierzu wird als Gruppe ein Buchstabe [A-Z] oder eine
+Zahl [0-9] eingegeben, dies erscheint dann �berlagert �ber dem Symbol.
+Die aktuelle Liste findet man in der APRS Reference, die es bei
+http://www.tapr.org gibt.
+
+
+                      Symboltabelle
+
+Symbol     Group /                       Group \
+
+!          Triangle w/!                  Triangle w/!
+"          Rain Cloud                    Rain Cloud
+#          Digi                          DIGI
+$          Phone Symbol                  $ Symbol
+%          DX                            DX
+&          GATE-HF                       GATE
+'          Small Aircraft                Aircraft Crash
+(          Cloud                         Cloud
+)          TBD
+*          SNOW Flake                    SNOW Flake
++          Red Cross
+,          Reverse L
+-          House w/omni
+.          Small x
+/          Red Dot
+0          0 in a box                    Circle
+1          1 in a box
+2          2 in a box
+3          3 in a box
+4          4 in a box
+5          5 in a box
+6          6 in a box
+7          7 in a box
+8          8 in a box
+9          9 in a box                    GAS
+:          Fire                          ?
+;          Tent                          Tent
+<          Motorcycle                    Pennant
+=          Train Engine
+>          Car                           Car
+?          POS Antenna                   ? in a box
+@          HURRICANE/STORM               HURRICANE/STORM
+A          First Aid                     Box
+B          BBS                           Blowing Snow
+C          Canoe
+D          D in a circle
+E          E in a circle                 Smoke Stack
+F          F in a circle
+G          Grid Square Antenna           ?
+H          Hotel/Bed
+I          TCP/IP                        ?
+J          J in a circle                 Lightening
+K          School House
+L          Light House                   Light House
+M          Mac
+N          NTS                           ?
+O          Balloon
+P          Police car                    Rx
+Q          Circle with in Circles        Circle with in Circles
+R          RV                            Restaurant
+S          Shuttle                       Satellite
+T          Thunderstorm (cloud/bolt)     Thunderstorm (cloud/bolt)
+U          School Bus                    Sun
+V          VOR TAC                       VOR TAC Symbol
+W          National Weather Service      NWS-Digi
+X          Helicopter
+Y          Sail Boat
+Z          Windows
+[          Runner                        WC
+\          DF Triangle
+]          Packet Mail Box
+^          Large Aircraft                Large Aircraft
+_          Weather Station               WS-Digi
+`          Satellite Dish
+a          Ambulance
+b          Bike                          blowing cloud
+c          DX antenna
+d          Fire dept.                    DX Antenna
+e          Horse                         Sleet cloud
+f          Fire Truck                    FC Cloud
+g          glider                        Pennant (2)
+h          Hospital                      HAM
+i          Island                        Island
+j          Jeep                          Jeep
+k          Truck                         Truck
+l          Small dot                     Small Dot
+m          MIC                           Mile Post
+n          N                             Small Triangle
+o          EOC                           Dot with in Circles
+p          Puppy                         Dot with in Circles
+q          GS Antenna                    GS Antenna
+r          Antenna Tower                 Antenna Tower
+s          Boat                          Boat
+t          TS                            ?
+u          18 Wheel Truck
+v          Van                           Dot with in Circles
+w          H20                           Flood
+x          X Windows                     Red Dot
+y          House w/Yagi                  House w/yagi
+z                                        X Windows
+{          FOG                           FOG
+|          Black Line                    Black Line
+}          TCP                           TCP
+~          Sail Boat                     Sail Boat
+
+HELP-INDEX>Was war neu in Xastir V1.0
+
+                     Was war neu in Xastir V1.0
+
+W�hrend des vergangenen Jahres wurde Xastir weiterentwickelt und dieses
+Release ist das Ergebnis dieser Bem�hungen. Die Entwicklung wurde von
+Chuck Byam geleitet, der das Projekt mit dem Einverst�ndnis von Frank
+Giannandrea �bernommen hat. Viele andere haben zum Erfolg des Projects
+beigetragen, eine Auflistung findet sich in der Datei AUTHORS.
+
+Das Xastir Paket benutzt nun GNU autoconf um die Makefiles zu erstellen
+und verschiedene Eigenschaften aufgrund der installierten Bibliotheken
+und Software auszuw�hlen.
+
+Beim Start von Xastir V1.0 werden sie wom�glich nicht sofort gr��ere
+�nderungen entdecken. Die bekannte Bedienoberfl�che wurde weitgehend
+beibehalten. Der gr��te Teil der �nderungen bleibt im Verborgenen und
+dient einer Steigerungen der Effizienz:
+
+o Die Startzeit des Programms wurde verbessert
+
+o Der Speicherbedarf wurde durch dynamische Speicherzuweisung f�r
+  Stationen, Spuren und Wetterdaten stark verbessert. D.h. es wird kein
+  Speicher mehr verschwendet f�r nicht vorhandene Spurdaten bei festen
+  Stationen oder Wetterdaten bei den meisten Stationen. Mit diesen
+  �nderungen ist es m�glich, Xastir komfortabel mit dem Internet zu
+  verbinden, auch wenn nur sehr wenig Speicher vorhanden ist.
+
+o Das Laden der Karten wurde verbessert, indem nun nicht mehr bei jeder
+  kleinen �nderung die Karte neu von der Festplatte geladen werden mu�.
+  Wetterwarnungen und �nderungen an den Einstellungen f�r die Darstellung
+  und Tracking Optionen erfordern kein Neuladen der Karten, stattdessen
+  werden nur die Symbole und die Spuren neu gezeichnet.
+
+o Verschiedene Dialog-Fenster, die fr�her h�ufig neu gezeichnet wurden,
+  werden nun nur bei Bedarf aktualisiert und sind damit auch auf
+  langsameren Systemen akzeptabel. Dies gilt auch f�r das Verfolgen einer
+  Station (Tracking), wobei die Karte nun nur neu gezeichnet wird, wenn
+  die Station sich dem Rand des Bildschirms n�hert.
+
+Dank dieser �nderungen kann Xastir problemlos auch auf langsameren
+Pentium(tm) Rechnern eingesetzt werden.  
+  
+Unterst�tzung f�r das GeoTIFF Kartenformat ist nun vorhanden und wird
+in Xastir einkompiliert, wenn die GeoTiff Bibliotheken auf dem System
+installiert sind. Diese Karten sind von hoher Qualit�t und besonders f�r
+Such- und Rettungsoperationen zu gebrauchen. Karten in diesem Format sind
+vom USGS und kommerziell auf CD-ROM erh�ltlich. Xastir wei�, wie das
+Datum von NAD-27 in WGS-84 umzurechnen ist, so da� Karten in beiden
+Formaten ohne Genauigkeitsverlust gelesen werden k�nnen. Zus�tzliche
+Tasten wurden in der Kartenauswahl hinzugef�gt, um schnell alle Karten
+einer bestimmten Art auszuw�hlen.
+
+Das oben gesagte gilt in erster Linie f�r die USA, wo es jede Menge
+Karten gibt. Bei uns gibt es zwar sch�nere topgraphische Karten, daf�r
+gibt es aber so gut wie nichts kostenlos, und damit auch kein
+verbreitetes Standardformat.
+  
+Xastir unterst�tzt nun das Setzen und L�schen von Objekten. Objekte
+k�nnen verwendet werden, um Treffen anzuzeigen, Reisenden Hinweise zu
+geben oder Such- und Rettungseins�tze durchzuf�hren.
+
+Die amerikanischen County Wetterwarnungs-Karten werden nicht mehr direkt
+auf die Karten gezeichnet, sondern mit der Karte �berlagert. Einerseits
+sind die Farben dadurch verf�lscht, aber es ist nun m�glich, die
+Stra�enkarten auch im Warnungsgebiet zu erkennen.
+
+Eine neue und n�tzliche Eigenschaft ist, da� sich die Ausrichtung einiger
+Symbole �ndert, je nachdem in welche Richtung sich z.B. ein Fahrzeug
+bewegt. Auch ohne die zur�ckgelegte Spur kann man die Richtung einer
+Mobilstation mit einem Blick erfassen. Es gibt einige weitere Optionen
+im Menu Darstellung mit denen man genauer festlegen kann, was angezeigt
+werden soll und was nicht.
+
+Das Verschieben und die Kontrolle �ber den Kartenausschnitt wurde
+verbessert: Es gibt nun Pfeile oben rechts im Menu, um die Karte mit der
+Maus zu verschieben. Die Karte kann auch mit den Cursortasten verschoben
+werden und die Vergr��erung kann mit den PgUp und PgDn Tasten eingestellt
+werden. Im PopUp-Menu der linken Maustaste gibt es neue Optionen um die
+Karte an der aktuellen Position zu zentrieren oder dort ein Pbjekt zu
+platzieren. Die Verschiebem�glichkeiten �ber dieses Menu wurden zugunsten
+der oben genannten entfernt.
+
+Unterst�tzung f�r Alternative Netzwerke wurde hinzugef�gt, hiermit wird
+es m�glich, ein privates APRS(tm) Netzwerk einzurichten f�r
+Veranstaltungen, f�r Such- und Rettungseins�tze, Sturmjagd, oder f�r
+alles wo der Benutzer nicht von Hunderten von APRS(tm)-Stationen um ihn
+herum genervt werden will.
+
+Es gibt viele kleine �nderungen, sichtbar oder unsichtbar f�r den
+Benutzer. Die Schnittstellen-Steuerung hat nun eine Option, um alle
+Schnittstellen gleichzeitig zu starten oder zu stoppen, um dem Benutzer
+es zu ersparen, dies f�r jede Schnittstelle einzeln tun zu m�ssen. Die
+Stationseinstellungen zeigen nun das gew�hlte Symbol, so da� man das
+Fenster nicht mehr verlassen mu�, um es zu sehen. Einige Puffer�berl�ufe,
+die unvorhersagbares Verhalten oder Programmabst�rze hervorgerufen
+hatten, wurden beseitigt. Und viele kleinere �nderungen wurden am
+Quelltext vorgenommen, damit Xastir auf verschiedenen Systemen fehlerfrei
+�bersetzt werden kann.
+
+Viel Freude mit dem neuen Xastir!
+
diff --git a/help/help-Italian.dat b/help/help-Italian.dat
new file mode 100644
index 0000000..ea9e6ea
--- /dev/null
+++ b/help/help-Italian.dat
@@ -0,0 +1,1047 @@
+HELP-INDEX>Leggimi - Licenza
+
+                          Leggimi - Licenza
+
+Per informazioni sulla versione corrente del programma leggere README.1ST nella 
+cartella di Xastir.
+
+Questo programma � sviluppato per essere usato all'interno della comunit� 
+radioamatoriale, negli Stati Uniti la FCC non autorizza a trasmettere per radio 
+se non sei radioamatore.
+Gli utenti di altri paesi devono attenersi alle leggi locali in merito.
+
+
+LICENZA:
+
+XASTIR, Amateur Station Tracking and Information Reporting
+Copyright (C) 1999,2000  Frank Giannandrea
+Copyright (c) 2000-2012  The Xastir Group
+
+Questo programma � un software libero; pu�' essere ridistribuito e modificato
+secondo i termini della Licenza GNU GPL, pubblicata dalla Free Software
+Foundation;
+anche la versione 2 della licenza � valida, come anche le versioni seguenti.
+
+ma SENZA ALCUNA GARANZIA; senza la garanzia di COMMERCIABILITA' o ADATTAMENTO
+PER UN PARTICOLARE USO.  Vedere la Licenza GNU GPL per maggiori dettagli.
+
+Dovrebbe essere pervenuta a voi la licenza GNU assieme al programma; se cos�
+non fosse segnalate l'evento alla  Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA  02111-1307, USA.
+
+Ulteriori informazioni sul software possono essere ottenute via:
+Web,
+ http://www.xastir.org
+ http://sourceforge.net/projects/xastir/
+ http://xastir.sourceforge.net
+
+
+Per maggiori informazioni riguardo la licenza pubblica GNU GPL:
+ http://www.gnu.org
+
+
+HELP-INDEX>Benvenuti! e note dell'Autore
+
+                      Benvenuti! - note dell'autore
+
+XASTIR, o X-windows Amateur Station Tracking and Information Reporting.
+
+� un programma APRS(tm) sviluppato liberamente e di libero uso, pu�  essere 
+liberamente distribuito. Attualmente il programma � in fase di sviluppo e non 
+deve essere visto come un prodotto finito! Il tuo aiuto servir� a renderlo 
+migliore.
+Se sai programmare o vuoi scrivere documentazione, il tuo aiuto mi risulter�  
+molto gradito! Ho molte idee ma cos� poco tempo! Quindi se pensi che manchi 
+qualcosa, fammelo sapere.
+
+73,
+Frank Giannandrea
+
+Traduzione della guida a cura di Alessandro Frigeri, IK0YUP.
+
+APRS[tm] � un marchio registrato di Bob Bruninga, 
+la sua pagina � "http://web.usna.navy.mil/~bruninga/aprs.html"
+
+HELP-INDEX>Novit� in Xastir 1.0
+
+                        Novit� in Xastir 1.0
+
+Over the past year, Xastir has been under active development, and this new
+release is the culmination of those efforts. Development has been run by
+Chuck Byam, who agreed to take over for Frank Giannandrea. Many other
+individuals have contributed to this project, and are listed in the AUTHORS
+file.
+
+Nell'ultimo anno, Xastir � passato per una fase di notevole sviluppo, e questa 
+nuova versione � il culmine dell'impegno di questo periodo.  Lo sviluppo � 
+stato coordinato da Chuck Byam, a cui Frank Giannandrea ha passato il 
+testimone.
+Altre persone hanno contribuito allo sviluppo di questo progetto, e sono 
+elencati nel file AUTHORS. 
+
+Il programma Xastir ora utilizza GNU autoconf per la costruzione dei Makefile 
+e la selezione delle caratteristiche in base alle librerie e del software 
+installato nel sistema.  Non sono quindi necessarie modifiche ai Makefile come 
+nelle versioni precedenti.
+
+Avviando Xastir 1.0 probabilmente non si noteranno grandi differenze.  
+L'interfaccia utente gi� buona � stata mantenuta pressoch� inalterata. La 
+maggior parte dei cambiamenti � avvenuta in un miglioramento delle prestazioni 
+complessive:
+* Sono stati migliorati i tempi di avvio del programma.
+* E' stato migliorato l'utilizzo della memoria, con l'allocazione dinamica 
+  dei dati di stazione, tracciati, meteo.  Non verr� utilizzata inutilmente 
+  memoria per dati non aggiornati.  Con questa modifica, Xastir potr� essere 
+  collegato ad un server internet anche in un computer con 16Mb di RAM.
+* E' stata migliorata la modalit� di caricamento delle mappe.  Infatti una
+  mappa non verr� pi� ricaricata per un semplice cambiamento di dat ida una 
+  stazione.  Allarmi meteo e tracciati di stazioni in movimento saranno 
+  disegnati a parte.  
+* Miglioramenti sono stati apportati nella frequenza d visualizzazione di 
+  alcune  finestre di dialogo che nella versione precedente apparivano con 
+  una alta frequenza.  
+
+Grazie a questi cambiamenti Xastir � perfettamente funzionante anche su 
+computer lenti. 
+
+Il supporto per le mappe GeoTIFF ora � incluso nel codice e verr� attivato se 
+nel sistema sono presenti le librerie GeoTIFF.  Questi file contengono mappe 
+di alta qualit�, utili specialmente in operazioni di soccorso.  Questo 
+formato di mappe � disponibile presso l'USGS (United States Geological Survey) 
+oppure commercialmente su CDROM.  Xastir convertir� automaticamente le mappe
+trasferendo il datum NAD-27 al WGS-84.  Sono state abilitate delle 
+scorciatoie tramite tastiera che permettono di caricare tutte le mappe
+disponibili per una particolare area.
+
+E' disponibile il supporto per Festival Speech Synthesis System per l'annuncio 
+vocale  di nuovi dati in arrivo.  Il precedente sistema di avvisi sonori � 
+ancora disponibile.
+
+Xatir ora supporta la possibilit� di aggiungere oggetti alle mappe. Questa 
+possibilit� fornisce all'utente molte possibilit� di utilizzo in coordinazione 
+di eventi e operazioni di soccorso.
+  
+Le mappe di allarme meteo (ndt: solo USA, per ora) sono visualizzate con una 
+trasparenza, permettendo di vedere le mappe geografiche sottostanti.
+
+Una nuova ed utile funzione � il cambiamento della orientazione di un simbolo 
+in base alla direzione del suo movimento.  Anche senza un percorso, � possibile 
+sapere la direzione di una stazione modile..  Ci sono diverse nuove funzioni 
+nel men� di visualizzazione, che permettono all'utente di visualizzare solo le 
+informazioni interressanti al momento. 
+
+Il controllo di visualizzazione delle mappe � stato migliorato:  sono presenti
+dei bottoni a freccia nella parte alta dello schermo.  Le mappe possono essere 
+cos� spostate con i suddetti bottoni, con i tasti freccia della tastiera e 
+lo zoom pu� essere regolato con i tasti Pag-SU e Pag-Gi� della tastiera.  
+Nel men� che appare cliccando sulla mappa � disponibile la nuova funzione che 
+permette di centrare la mappa in un dato punto.  Le funzioni di spostamento
+della mappa sono state rimosse in quanto presenti i bottoni in alto nello 
+schermo.  
+
+E' stato aggiunto il supporto altnet per permettere di avere reti APRS(tm)
+locali per eventi speciali, operazioni di soccorso, allarmi meteo o qualsiasi 
+situazione in cui non � necessario analizzare dati da altre stazioni.
+
+Ci sono numerosi cambiamenti minori, visibili ed invisibili all'utente.  
+Il controllo di interfaccia ha ora il bottone "Avvia tutte" e "Arresta tutte" 
+per permettere all'utente di avviare tutte le interfacce in una sola
+operazione. La finestra di dialogo della configurazione della stazione ora 
+mostra l'icona scelta, cos� non � pi� necessario controllare sulla mappa quale 
+icona � stata scelta.  Sono stati corretti errori nel codice che davano errori 
+di overflow di memoria.  Altre correzioni sono state fatte per rendere il 
+codice compilabile senza problemi su diverse piattaforme con fiversi sistemi.
+
+E ora: Buon divertimento con il nuovo Xastir!   
+
+ 
+  
+HELP-INDEX>Avviare Xastir
+
+                    Avviare Xastir per la prima volta
+
+La prima volta che si lancia Xastir, dovrebbe essere fatto da un terminale in 
+maniera tale che qualsiasi messaggio di errore salti alla vista.  Nella maggior 
+parte dei sistemi il percorso di ricerca dei file eseguibili comprende la 
+cartella  /usr/local/bin e tutto quello che serve per avviare il programma � 
+dare il comando xastir al prompt.  Nei sistemi dove il percorso 
+"/usr/local/bin" non � impostato bisogner� digitare "/usr/local/bin/xastir" per 
+avviare il programma.
+
+Si pu� anche impostare un linguaggio diverso dall'originale.  Per impostare o 
+cambiare il linguaggio usato da xastir bisogna utilizzare la seguente sintassi: 
+
+xastir -l
+
+Attualmente le scelte sono: English Dutch French German Spanish Italian
+                            ElmerFudd MuppetsSwedishChef OldeEnglish PigLatin
+                            PirateEnglish
+
+Questa opzione viene memorizzata nel file di configurazione dell'utente e resa 
+disponibile per i seguenti usi del programma.  Per le nuove installazioni 
+Xastir user� l'inglese a meno che non venga specificato un linguaggio 
+differente con l'opzione -l.
+
+NOTA: Nei menu, le opzioni in grigio sono quelle selezionate, come anche nelle 
+opzioni di on/off, la scelta attivata sar� evidenziata dalla colorazione grigia.
+
+HELP-INDEX>Informazioni sulla configurazione della stazione
+
+                         Informazioni sulla configurazione della stazione
+
+Seleziona Configura la Stazione
+
+Imposta il tuo nominativo nella apposita casella.
+
+Compila le caselle relative alla posizione (Lat,Long) se non si intende usare 
+Xastir con un GPS. Se la posizione non � disponibile � possibile individuare la 
+posizione sulla mappa e copiare i dati. Latitudine e longitudine potranno 
+essere rilevati nella seconda casella partendo da destra, nella parte bassa 
+della finestra principale.
+Se si intende utilizzare un GPS si pu� saltare questa sezione e configurare il 
+GPS in un secondo momento.
+
+Il simbolo o il gruppo della stazione possono essere cambiati in qualsiasi 
+momento, per fare questo si faccia riferimento alla guida ai simboli.
+
+Indicare ora i dati tecnici della stazione: questi dati sono interessanti ma 
+non necessari al corretto funzionamento del programma.
+Utilizzare il seguente codice per indicare la potenza che pi� si avvicina a 
+quella della vostra stazione:
+
+Codice           0  1  2  3   4   5   6   7   8   9
+Potenza (watts)  0  1  4  9  16  25  36  49  64  81
+
+Esempio: Se si sta trasmettendo con 36 watt, indicare "6".
+
+
+Lo stesso discorso vale per l'altezza, ma bisogna indicare l'altitudine e non 
+l'altezza dell'antenna sul terreno.
+
+Codice             0   1   2   3    4    5    6     7     8     9
+Altitudine (piedi)10  20  40  80  160  320  640  1280  2560  5120
+
+Esempio: se l'altitudine della stazione � 1280 piedi, il codice da usare
+         sar�  "7".
+
+
+Per impostare il guadagno scrivere semplicemente il valore dello stesso 
+espresso in dB, nella apposita casella.
+
+La direzione ha bisogno di un codice che esprime la direzione dell'antenna 
+espressa in gradi dal Nord.
+
+Codice           0   1   2    3    4    5    6    7    8        9
+Direzione(gradi) *  45  90  135  180  225  270  315  360  Nessuna
+
+Esempio: Se la vostra antenna � omnidirezionale, impostare "0". Se la 
+         direzionalit� � verso nord, impostare "8".
+
+Inserire un commento, non necessario al programma, ma utile agli altri 
+operatori.
+
+L'ambiguit� della posizione permette di trasmettere quanto � precisa la 
+posizione fornita dalla nostra stazione. Una impostazione con ambiguit� nulla 
+permetter� di comunicare alle altre stazioni esattamente la posizione che 
+abbiamo impostato o che arriva dal GPS.  Le altre scelte posizioneranno la 
+stazione nel raggio indicato dal codice impostato.
+
+Selezionando OK, verranno applicati tutti i cambiamenti effettuati, mentre il 
+tasto Annulla manterr� le opzioni correnti. 
+
+HELP-INDEX>Configurazione delle Unit� di Misura
+
+                        Configurazione delle Unit� di Misura
+
+L'impostazione originale del programma � per il sistema metrico, mm, cm, Km/ora 
+ecc.
+Per selezionare il sistema di misura anglosassone (pollici,piedi,miglia/ora) 
+selezionare Configura, Unit�, quindi il sistema che si vuole usare.  L'opzione 
+attiva � quella marcata dal grigio.
+
+
+HELP-INDEX>Configurazione delle Operazioni Base
+
+                        Configurazione delle Operazioni Base
+
+Selezionare Configura e quindi Predefinito
+
+Questa scheda imposta una configurazione standard. Le vecchie stazioni saranno 
+visualizzate con un'icona fantasma.  Il "tempo lettura GPS" imposter� 
+l'intervallo di tempo per  acquisire nuovi dati dal GPS.  Questa opzione � 
+disponibile per le stazioni dotate di HSP o di un cavo condiviso con il proprio 
+TNC.
+
+L'opzione "Trasmissioni Stazione" imposta con quali packet la stazione 
+trasmetter� i propri dati.    
+
+L'opzione "Trasmetti codici WX", se selezionato, mander� anche un pacchetto di 
+dati provenienti dalla stazione meteo.Questa opzione � utile per i tipi di 
+stazioni meteo che trasmettono i dati gi� in formato ASCII come le Peet Bros. 
+
+Le opzioni Gateway permetteranno di impostare la stazione come un gateway tra 
+internet e la rete radio.  Questa opzione va usata con cautela, come 
+radioamatore ognuno di noi � responsabile per i dati che trasmette, e quindi 
+anche per quelli che provengono da internet e vengono trasmessi per radio in 
+una simile configurazione.
+
+HELP-INDEX>Configurazione Interfacce
+
+                           Configurazione Interfacce
+
+Selezionare Configura e quindi Interfacce.
+
+Dovrebbe apparire una scheda che indica le "Interfacce installate".  Questa 
+scheda vi permetter� di aggiungere, cancellare, e modificare le propriet� 
+delle varie periferiche che possono essere utilizzate con Xastir.
+
+Le opzioni sono:
+TNC Seriale
+TNC Seriale con GPS tramite un cavo HSP
+GPS Seriale
+WX Seriale
+Server Internet
+TNC AX25
+GPS in rete (via gpsd)
+WX in rete
+
+Per aggiungere una periferica, selezionare aggiungi.  Apparir� la scheda
+ "Scegli il tipo di interfaccia".  Seleziona il tipo di interfaccia che vuoi 
+aggiungere.
+Appariranno i parametri di quella periferica.  Fornire le impostazioni 
+richieste e selezionare "ok"
+
+Per eliminare una periferica, selezionarla e in seguito cliccare sul bottone 
+Elimina.
+
+Per modificare le propriet� di una periferica, seleziona la periferica e quindi 
+il bottone "Propriet�".  La scheda con i parametri della periferica appariranno 
+e potranno essere modificati a piacere. Per rendere effettive le impostazioni 
+schiacciare il bottone OK dopo aver fatto le modifiche.
+ 
+HELP-INDEX>Configurazione di TNC Seriali
+
+
+                          Configurazione di TNC Seriali
+
+CONFIGURAZIONE DI UN TNC SERIALE
+
+Questa sezione tratta l'impostazione di un TNC Seriale o di un TNC seriale con 
+un  cavo HSP per il collegamento del GPS.
+
+Se si ha il cavo HSP, che permette di condividere la porta del TNC con quella 
+del GPS, la configurazione da selezionare sar� "TNC con GPS".  Il cavo HSP � un 
+cavo speciale che pu� non essere compatibile con tutte le combinazioni 
+computer/TNC/GPS possibili.  Se si usa questa configurazione, il TNC e il GPS
+devono avere una impostazione dei parametri di comunicazione che in genere 
+prevede: 4800 bps, 8 bit di dati, nessuna parit�, 1 bit di stop.
+
+Opzioni della Porta TNC:
+Selezionando "Attivare all'avvio" si indica a Xastir di caricare questa 
+periferica automaticamente all'avvio del programma.
+
+Selezionando "Permetti la Trasmissione", ordina a Xastir che ogni dato inviato 
+all'interfaccia pu� essere trasmesso.
+
+La porta del TNC � la porta Unix alla quale � collegato il TNC.  In genere sono 
+chiamate /dev/ttyS0 (Dos com1), /dev/ttyS1 (Dos com2)
+
+Ora impostare la velocit� e il tipo di comunicazione in "Impostazioni porta", e 
+i parametri in "Stile porta".  Uno stile di porta 8N1 indica 8 bit di dati, 
+Nessuna parit� e 1 bit di stop. 7E1 indica 7 bit di dati, parit� e 1 bit di 
+stop.  7O1 indica 7 bit di dati, parit� dispari, e 1 bit di stop.  Questi 
+parametri DEVONO essere 
+comuni sia al TNC che al GPS. 
+
+Scegliere ora la corretta impostazione per il Gateway di questa interfaccia. 
+Potresti avere diversi TNC e questa opzione pu� essere diversa per ogni TNC.
+Se non intendi attivare le funzionalit� di gateway lascia l'opzione 
+"Disabilitato".
+
+Inserisci ora fino a tre percorsi UNPROTO. Xastir assume la parte XX VIA del 
+percorso UNPROTO. � possibile impostare tre percorsi differenti in modo da 
+ avere alternative nel caso le condizioni non siano buone.  Se uno dei percorsi 
+� occupato allora Xastir passer� al successivo ad ogni trasmissione e cos� via.
+
+Se sei in una condizione di stazioni locali, semplicemente un WIDE2-2 pu� essere 
+una buona scelta.  Se stai usando poca potenza e/o sei distante dal digipeater 
+allora WIDE1-1,WIDE2-2 potrebbe essere la scelta giusta.  Se conosci il nominativo 
+del tuo pi� vicino digipeater allora si potr� usare NOMINATIVO_DIGI,WIDE2-2.  La 
+maggior parte di voi avr� bisogno di un solo percorso.  Se ci si trova in un 
+area remota e il segnale � difficilmente ascoltabile dalle altre stazioni allora 
+potrebbe essere necessario aggiungere dei percorsi.  Una buona norma � quella
+di chiedere al gruppo di radioamatori locali quale � il miglio percorso per i 
+pacchetti in quella data area. 
+
+File di inizializzazione e di spegnimento del TNC. Questi campi specificano i 
+nomi di file presenti nelle cartella /usr/local/share/xastir/config. Ognuno
+di questi file di test contiene i comandi che si vogliono mandare al TNC
+all'avvio del programma e al termine dello stesso.
+
+CONFIGURAZIONE DEL TNC AX.25
+
+Questa sezione descrive l'aggiunta e la modifica di interfacce TNC AX.25.
+Per interfacce AX.25 si intendono tutte quelle periferiche che usano i driver 
+AX.25 di Linux.  Questo driver � a livello di kernel e periferiche come i 
+Baycom o soundmodem possono essere usati come TNC.  Queste periferiche devono 
+essere rese disponibili (funzionanti) al programma prima del suo avvio.
+
+Selezionando "Attiva all'avvio" si ordiner� a Xastir di caricare questa 
+interfaccia all'avvio.
+
+Selezionando "Permetti la Trasmissione", si permetter� che i dati vengano 
+trasmessi per radio.
+
+Scegliere ora la corretta impostazione per il Gateway di questa interfaccia. 
+Potresti avere diversi TNC AX.25 o TNC Seriali  e questa opzione pu� essere 
+diversa per ogni TNC.
+Se non si intende attivare le funzionalit� di gateway lascia l'opzione 
+"Disabilitato".
+
+Impostare il nome della periferica AX.25 come specificato dal file axports.
+
+Inserisci ora fino a tre percorsi UNPROTO. Xastir assume la parte XX VIA del 
+percorso UNPROTO. � possibile impostare tre percorsi differenti in modo da 
+avere alternative nel caso le condizioni non siano buone.  Se uno dei percorsi �
+occupato allora Xastir passer� al successivo ad ogni trasmissione e cos� via.
+
+Se sei in una condizione di stazioni locali, semplicemente un WIDE2-2 pu� essere 
+una buona scelta.  Se stai usando poca potenza e/o sei distante dal digipeater
+allora WIDE1-1,WIDE2-2 potrebbe essere la scelta giusta.  Se conosci il nominativo 
+del tuo pi� vicino digipeater allora si potr� usare NOMINATIVO_DIGI,WIDE2-2.  La 
+maggior parte di voi avr� bisogno di un solo percorso.  Se ci si trova in 
+un'area remota e il segnale � difficilmente ascoltabile dalle altre stazioni allora 
+potrebbe essere necessario aggiungere dei percorsi.  Una buona norma � quella 
+di chiedere al gruppo di radioamatori locali quale � il miglio percorso per i 
+pacchetti in quella data area. 
+
+NOTA: Per usare le periferiche AX.25 con Xastir bisogna avere i privilegi di 
+root.
+Se si vuole far eseguire Xastir da un utente qualsiasi, bisogner� cambiare il 
+suid del programma Xastir.  Il comando seguente  eseguito da root potr� servire 
+allo scopo:
+
+chmod a+s /usr/local/bin/xastir
+
+
+Come qualsiasi programma che venga eseguito in questa modalit�, questo � da 
+considerarsi un rischio di sicurezza, visto che il programma ancora non � stato 
+sperimentato per reagire a tentativi di intrusione.
+
+Configurazione del GPS
+
+
+                                Configurazione GPS Seriali
+
+Imposta la porta seriale che usata dal vostro GPS.  Valori comuni sono 
+/dev/ttyS0 (dos com1) e /dev/ttyS1 (dos com2).
+
+Selezionando "Attiva all'avvio" si ordiner� a Xastir di caricare questa 
+interfaccia all'avvio.
+
+Ora seleziona la velocit� di trasmissione espressa in bps e i parametri della 
+porta sotto il menu "stile".  Uno stile di porta 8N1 significa 8 but di dati, 
+nessuna parit� e 1 bit di stop. 7E1 indica 7 bits di dati, parit� pari e 1 stop 
+bit. 701 indica 7 bit di dati, parit� dispari e 1 stop bit.  Questi parametri 
+devono essere gli stessi che usa il GPS.  La maggior parte dei GPS usa 4800 bps
+8N1.
+
+HELP-INDEX>Configurare un GPS in rete
+
+                    Configurazione di un GPS in rete.
+
+Questa opzione permette di condividere i dati provenienti dal GPS con pi� 
+programmi, e con pi� computer in rete.  Xastir pu� ottenere i dati dal GPS 
+attraverso il demone gpsd che permette, attraverso diverse connessioni, di 
+condividere i dati del 
+GPS  con altrettante applicazioni. 
+
+Impostare il nome dell'host (o l'indirizzo IP) e il numero della porta che gpsd 
+utilizza per le connessioni (di solito la 5678).
+
+Selezionando "Attiva all'avvio" si ordiner� a Xastir di caricare questa 
+interfaccia  all'avvio.
+
+Selezionando "Riconnetti su Errore", indicher� ad Xastir di riconnettersi una 
+volta che il flusso di dati si � per qualche motivo interrotto.
+
+HELP-INDEX>Configurare il Server Internet
+
+                         Configurazione del Server Internet
+
+I server internet permettono di ricevere ed inviare dati a tutto il mondo 
+attraverso internet.
+
+Selezionando "Attiva all'avvio" si ordiner� a Xastir di caricare questa 
+interfaccia  all'avvio.
+
+Selezionando "Permetti la Trasmissione", indicher� che Xastir potr� trasmettere 
+via radio tutti i dati.
+
+Inserisci il nome dell'host (o l'indirizzo IP) e il numero della porta del 
+server internet che vuoi connettere.
+
+Inserisci un codice di accesso valido per attivare la connessione, che 
+permetter� ai tuoi dati di essere trasmessi attraverso Internet.  Se non hai 
+un codice di accesso puoi spedire un mail a fgiannan at earthlink.net con tutti i 
+tuoi dati e informazioni radio, per ricevere il codice.
+
+Selezionare Riconnetti in caso di errore, che indica a Xastir di riconnettersi 
+nel caso la comunicazione sia interrotta.
+
+HELP-INDEX>Configurare una Stazione Meteo
+
+                           Configurare una stazione meteo
+
+Configurare una stazione meteo Seriale.
+
+Impostare la porta seriale alla quale � connessa l'unit� Meteo.  
+Valori comuni sono /dev/ttyS0 (COM1) o /dev/ttyS1 (COM2).
+
+Selezionando "Attiva all'avvio" si ordiner� a Xastir di caricare questa 
+interfaccia  all'avvio.
+
+Ora bisogna selezionare la velocit� della porta in bps sotto Configurazione 
+della Porta, e i parametri sotto 'Stile di Porta'.  Lo 'Stile della Porta' 8N1 
+indica 8 bit di dati, nessuna parit� e 1 bit di stop.  7E1 indica 7 bit di 
+dati, parit� e 1 bit di stop. 
+7O1 � usato per 7 bit di dati, parit�, un bit di stop.  Questi parametri devono 
+essere gli stessi della porta dell'apparecchio meteo.
+L'opzione 'Tipi di dati permette di aggiornare per quale tipo di comunicazione 
+seriale il programma dovr� cercare.  La funzione di autoriconoscimento 
+(auto-detect) cercher� per primi dei dati in formato binario come quelli della 
+stazione meteo Radio Shack WX-200.
+Nel caso non vengano rilevati dati binari allora Xastir cercher� per dati ASCII 
+(utilizzati dalla stazione Peer Bros.).
+
+
+Configurare una stazione Meteo in Rete
+
+Xastir pu� usare dati meteo reperendoli da server come il wx200d.
+wx200d permette pi� connessioni, permettendo di condividere i dati meteo con 
+pi� programmi o computer.
+
+Inserisci il nome dell'host (o l'indirizzo IP) e il numero della porta del 
+server Meteo che si vuole connettere .
+
+Selezionando "Attiva all'avvio" si ordiner� a Xastir di caricare questa 
+interfaccia  all'avvio.
+
+Selezionando "Riconnetti se sconnesso", indicher� a Xastir di riconnettersi in 
+caso di errore.
+
+Come prima, selezionando il "Tipo di dati" si escluder� l'auto-riconoscimento.
+
+
+
+HELP-INDEX>Configurzione allarmi Audio
+
+                           Configurazione Suoni
+
+Selezionare Configurazione, e quindi Suoni.
+
+Per usare questa opzione bisogna avere una scheda sonora e un programma che 
+esegua i file con estensione .wav.  Il "Comando per eseguire i suoni" � il 
+programma (e relative opzioni) che si vuole usare per ascoltare i suoni che 
+vengono da Xastir.
+
+I campi conterranno il nome del file da eseguire, i campi sotto le opzioni 
+imposteranno i parametri per le opzioni.
+
+Le possibili scelte sono:
+-Esegui un suono quando viene rilevata una nuova stazione.
+-Esegui un suono quando viene ricevuto un nuovo messaggio.
+-Esegui un suono quando arrivano dati da una stazione ad una distanza 
+ Min/Max come segnalato dall'utente.
+-Esegui un suono quando viene rilevata una stazione (via TNC) con una distanza 
+min/max impostata nei limiti di apertura di banda..
+
+HELP-INDEX>Configurazione delle unit� di misura (Inglese/Metrico)
+
+              Configurazione delle unit� di misura (Inglese/Metrico)
+
+Questo seleziona che in che unit� le grandezze verranno visualizzate dal 
+programma.
+Il programma si configura automaticamente sul sistema metrico ma � possibile 
+cambiare questa possibilit�.
+
+HELP-INDEX>Barra di stato inferiore
+
+                         Barra di stato inferiore
+
+Nella parte inferiore della finestra principale sono disponibili diversi 
+messaggi di controllo.
+
+I messaggi di controllo generale sono visualizzati nella paste sinistra.
+
+Nella seconda casella da sinistra � visualizzata la posizione sulla mappa del 
+mouse in lat/lon.
+La terza casella visualizza il numero di stazioni ricevute e presenti nel 
+database.
+La quarta casella visualizza il livello di zoom e visualizzer� Tr se
+sulla stazione selezionata � attivata la funzione di inseguimento.
+L'ultima casella visualizza lo stato di funzionamento delle periferiche, che
+sono visualizzate nell'ordine di inserimento da 0 a 9.
+Il controllo di stato delle interfacce � diviso in tre aree, la parte alta 
+indica il tipo di periferica, in mezzo � indicato lo stato di flusso di dati e 
+nella parte bassa � indicato lo stato operazionale della periferica, blu per i 
+vari TNC, verde per i GPS, giallo per per i servizi Internet, arancio per le 
+periferiche Meteo. 
+Nella parte centrale il flusso di dati entrante � indicato con una freccia a 
+sinistra per dati uscenti e a destra per dati entranti. Nella parte inferiore 
+il verde indica che l'interfaccia � collegata e funziona correttamente, il 
+rosso che l'interfaccia � collegata ma in uno stato di errore, l'assenza di 
+colore indica che l'interfaccia non � collegata.
+
+
+HELP-INDEX>Spostare la mappa e opzioni.
+
+                    Spostare la mappa e Opzioni
+
+Il movimento della mappa � molto semplice e la velocit� di visualizzazione 
+della stessa � dipendente dal tipo di sistema in uso e dalla quantit� di 
+dettagli visualizzata.
+
+Tutti i movimenti e ingrandimenti sono possibili cliccando il tasto sinistro 
+del mouse (tenendolo premuto) sulla mappa.  Questa azione visualizzer� un menu 
+di Opzioni.
+
+Tutte le funzioni di Zoom sono riferite al punto della mappa dove � stato 
+cliccato il bottone sinistro del mouse.  Il menu degli zoom mostrer� ulteriori 
+opzioni: livelli di zoom da 1 a 3 sono per aree locali mentre livelli da 4 a 6 
+sono per aree 
+maggiori, quindi pi� il numero � piccolo e pi� l'area visualizzata � stretta.
+
+Dal menu delle opzioni si pu� anche spostare la vista della mappa con la 
+funzione Pan, che provocher� uno spostamento del centro della mappa.
+
+Le "informazioni della stazione" cerca per la stazione pi� vicina al punto 
+selezionato dal click del mouse.  Se pi� stazioni sono presenti apparir� una 
+finestra di 
+selezione che permetter� di indicare di quale stazione veramente si ha bisogno 
+di 
+informazioni.
+
+HELP-INDEX>Map Options and Map Chooser Opzioni della Mappa e Scelta della Mappa
+
+                       Opzioni della Mappa e Scelta della mappa
+
+Opzioni della Mappa:
+
+Mappe Automatiche (Attiva/Disattiva)
+Quando attivato, qualsiasi mappa trovata nella directory delle mappe verr� 
+visualizzata se nella sua area ricade la visualizzazione corrente.  Questa 
+funzione cercher� in tutte le sottocartelle della directory delle mappe.  Se 
+pi� mappe sono disponibili allora verranno sovrapposte, in questo caso un
+ computer poco veloce pu� produrre una visualizzazione lenta.
+Tuttavia � possibile disattivare questa funzione e selezionare manualmente la 
+mappa da visualizzare.
+
+Griglia (Attiva/Disattiva)
+Quando � attiva, questa funzione visualizza una griglia ogni 10 gradi. Se si 
+effettua uno zoom in avanti la risoluzione della griglia passer� ad 1 grado.
+
+Livelli della Mappa (Attiva/Disattiva)
+Quando attivata, questa funzione permette di filtrare i dati di mappe su 
+grandi aree.
+Questa opzione funziona solo con le mappe Tiger Line maps reperibili presso 
+http://aprs.rutgers.edu.  Ci� non velocizzer� il caricamento delle mappe ma 
+produrr� una visualizzazione di dettagli appropriata alla scala di 
+visualizzazione.
+
+Colore in Aree Chiuse (Attiva/Disattiva)
+Questa opzione controlla il colore di riempimento delle mappe vettoriali. 
+In alcuni casi pu� essere necessario eliminare il riempimento di un'area 
+per permettere la visualizzazione dei livelli sottostanti.  Le mappe sono 
+caricate in ordine alfabetico e quindi i livelli rispetteranno tale ordine. 
+
+Scelta della mappa.
+Questa funzione visualizza tutte le mappe disponibili.  Si potr� selezionare 
+pi� di una mappa e poi premere OK per confermare la selezione.  Il bottone 
+Cancella chiude la finestra di dialogo della scelta delle mappe.
+
+Nota: Xastir utilizza il Datum WGS 1984 per le mappe.
+
+HELP-INDEX>File di mappe, Dos, Windows, Pixmaps e WX Counties
+
+             File di mappe, Dos, Windows, Pixmaps e WX Counties
+
+Tipi di Mappa
+Xastir funziona con vari tipi di mappa.  Tutte le mappe per il programma 
+APRS[TM] Dos,Windows,Mac sono supportate.  Dalla versione 0.3.2 � possibile 
+caricare anche mappe in formato Pixmap.  � possibile anche caricare le mappe di 
+supporto per gli Allarmi Meteo Statunitensi.
+
+Dove posizionare le mappe
+Qualsiasi mappa Dos, Windows/Mac o Pixmap deve essere messa nella directory 
+/usr/local/share/xastir/maps.  Si possono creare sottocartelle per oridare il 
+contenuto. Per esempio si pu� creare una cartella ITALIA per mettere tutte le 
+mappe che comprendono il territorio italiano, oppure si possono dividere le 
+mappe per tipo: Pixmap e Dos.
+
+Esempio
+
+                          /usr/local/share/xastir/maps/
+                                                /italia/nord
+                                                /italia/centro
+                                                /italia/sud
+                                                /dos/italia/
+                                                /dos/germania/
+                                                /pixmaps/italia/
+                                                /pixmaps/germania/
+
+
+
+Le mappe Pixmap sono una combinazione di due file, un file binario grafico 
+pixmap (.xpm) e un file di dati di locazione (.geo).  Il file .xpm grafico � in 
+formato .xpm 
+standard modificabile con qualsiasi programma di grafica che supporti questo 
+formato.  Il 
+file di dati .geo permette di posizionare la mappa nel mondo.
+Ecco un esempio di file .geo: world1.geo
+
+FILENAME   world1.xpm
+#          x          y        lon         lat
+TIEPOINT   0          0        -180        90
+TIEPOINT   640        320      180         -90
+
+
+Questo semplice file  ha 4 componenti. La prima riga indica il file grafico a 
+cui sono riferiti i dati che deve essere nella stessa directory del file di 
+dati.
+La seconda linea imposta un commento alla mappa.  Ogni linea che inizia con un
+ # (cancelletto) indica un commento che non verr� letto dal programma.
+Le ultime due linee connettono un pixel di coordinate x,y ad un punto della 
+terra con coordinate lat/long.  Due punti sono necessari e dovrebbero essere 
+presi in alto a 
+sinistra e in basso a destra dell'immagine.
+Per usare la mappa Pixmap, selezionare la scelta di mappa e in seguito il file 
+.geo
+
+Mappe di Allerta Meteo USA
+Tutte le mappe di Allerta meteo USA dovrebbero essere posizionate in 
+/usr/local/share/xastir/Counties.
+Dovranno poi essere create delle sottocartelle per lo stato USA a cui 
+appartiene la mappa chiamate con l'abbreviazione di due lettere dello stato.
+
+
+               /usr/local/share/xastir/Counties
+                                         /CO/
+                                         /CO/COPARK.map
+                                         /CO/CODOUGLA.map
+                                         /CO/COJEFFER.map
+                                         /CO/COZ001.map
+                                         /CO/COZ002.map
+                                         /CO/COZ003.map
+                                         /NJ/
+                                         /NJ/NJOCEAN.map
+                                         /NJ/NJBERGEN.map
+                                         /NJ/NJMONMOU.map
+                                         /NJ/NJZ001.map
+                                         /NJ/NJZ002.map
+                                         /NJ/NJZ003.map
+
+
+
+Ecco due siti dove � possibile avere questo tipo di mappe:
+ftp://aprs.rutgers.edu/pub/hamradio/APRS/NWSCounties/
+http://home.att.net/~kg5qd1/Maps.html
+
+HELP-INDEX>Informazioni stazione - Ricerca nel database FCC e RAC
+
+                       Informazioni stazione - Ricerca nel database FCC e RAC
+
+Informazioni Stazione mostrer� tutti i dati acquisiti da Xastir per quel 
+determinato nominativo.
+
+Il bottone Annulla Inseguimento toglier� tutti i percorsi che sono stati 
+memorizzati nello schermo.
+
+Il bottone Spedisci Messaggio aprir� una finestra per spedire un messaggio.
+
+Se si � installato il database FCC o RAC si pu� fare una ricerca dei dati della 
+stazione.
+I file di databse RAC e FCC devono essere posizionati in
+/usr/local/share/xastir/fcc.
+
+Questa funzione aggiunger� l'indirizzo della stazione alle informazioni 
+ricevute via radio.
+
+Per usare il database FCC bisogna scaricarlo (40Mb) da:
+ftp://ftp.fcc.gov/pub/XFS_AlphaTest/amateur/appl.zip
+
+o la nuova versione da:
+ftp://ftp.fcc.gov/pub/Bureaus/Wireless/Databases/uls/complete/l_amat.zip
+(The only file needed form this 40Meg zip is the EN.dat file)
+
+**** NOTA: per usare la  nuova versione, il database deve essere prima 
+ordinato!!! ****
+Assicurarsi di avere spazio disco libero (100Mb)
+Per ordinare il file eseguire i seguenti comandi:
+sort +4 -t \| EN.dat >EN.dat.sorted
+rm EN.dat
+mv EN.dat.sorted EN.dat
+
+Il database RAC si pu� scaricare da:
+ftp://ftp.rac.ca/pub/cdncaldb.zip
+
+Xastir creer� degli indici per ogni database, se un nuovo callsign � immesso 
+nel database allora Xastir creer� dei nuovi indici e render� subito disponibile 
+il nuovo 
+callsign.
+
+I prefissi speciali NON sono inclusi nei database.
+
+HELP-INDEX>Opzioni di Visualizzazione
+
+                             Opzioni di visualizzazione
+
+Queste opzioni permettono di visualizzare i dati delle stazioni attorno 
+all'icona che indica la posizione della stazione sulla mappa.
+
+Altitudine (on/off)
+Quando attivo, una linea blu di dati appare sopra al nominativo, ad indicare 
+l'altitudine della stazione nell'ultima posizione ricevuta.
+
+Direzione (on/off)
+Quando attivo, una linea verde di dati apparir� sotto al nominativo. Questa 
+indica la direzione in gradi del movimento della stazione l'ultima volta che � 
+stata ascoltata.
+
+
+Velocit� Speed (on/off)
+Quando attiva, una linea di dati rossi indica la velocit� della stazione 
+l'ultima volta che � stata ricevuta.
+
+Distanza/direzione (on/off)
+Quando attivata, due linee di dati verranno visualizzate alla sinistra
+dell'icona della stazione.
+La linea superiore indica la distanza dalla propria stazione, mentre la linea 
+inferiore la direzione dalla propria stazione.
+
+Tracce della Stazione (on/off)
+Quando attiva, qualsiasi stazione in movimento lascer� una traccia della 
+posizione precedente fino ad un numero di 100 posizioni.  Quando i dati della 
+stazione diventano vecchi e l'icona della stazione diventa trasparente, la 
+traccia � indicata con un tratteggio.
+
+Potenza/Guadagno (on/off)
+Quando attiva, visualizza i cerchi di potenza e guadagno.
+
+Insegui stazione
+Questa funzione visualizza una finestra di dialogo simile a quella di 
+localizzazione.
+Si pu� inserire un nominativo o parte di esso e quindi selezionare "Insegui 
+ora!" per centrare lo schermo su quella stazione e mantenerlo centrato per ogni 
+successivo spostamento.
+
+Selezionando "Elimina Inseguimento" si eliminer� la funzione.
+
+Il bottone "Annulla" nasconder� la finestra senza apportare cambiamenti.
+
+Informazioni Meteo (on/off)
+Quando selezionato, verranno visualizzate le ultime informazioni meteo
+(temperature,velocit� del vento/direzione/gust,umidit�).
+
+
+HELP-INDEX>Messaggi
+
+                                Messaggi
+
+Spedire Messaggi e Apri Gruppo
+
+Queste funzioni sono molto simili. "Spedisci messaggio a" spedir� un messaggio 
+solo ad una stazione.  I messaggi di gruppo sono pi� generali.
+(ndt: la funzione messaggi di gruppo al momento non � completamente funzionante)
+
+Ognuna di queste finestre visualizza una scheda di messaggio, una linea per il 
+nominativo/nome gruppo e vari bottoni.
+
+Una volta inserito il nominativo della stazione, tutti i messaggi ricevuti da
+essa verranno visualizzati.  Se non ci sono messaggi allora una nuova finestra
+permetter� di inserire un nuovo messaggi da spedire.  La lunghezza massima del
+ messaggio � di 250 caratteri. "Spedisci ora!" invier� il messaggio al 
+destinatario.
+Il bottone "Spedisci ora!" rimarr� grigio fino a quando il messaggio non sar�
+correttamente inviato.
+
+Qualsiasi messaggio ricevuto sar� ordinato secondo la linea # e messo nella
+ finestra dei messaggi.  Se si � nella funzione Gruppo, la lista dei messaggi
+ visualizzer� anche il nominativo del mittente.
+
+"Nuovo nominativo" visualizzer� i vecchi messaggi della stazione oppure
+permetter� la comunicazione con un'altra stazione.  Il bottone "Cancella
+ Messaggi" eliminer� tutti i messaggi.
+
+Elimina i messaggi in uscita.
+
+Questo eliminer� tutti i messaggi che sono stati spediti.
+
+Risposta automatica
+
+Questa funzione attiva la risposta automatica ai messaggi in entrata.
+
+Imposta risposta automatica
+
+Render� possibile impostare il messaggio  di risposta automatico.
+
+HELP-INDEX>Eliminare i percorsi dallo schermo
+
+                   Eliminare i percorsi dallo schermo
+
+Selezionare File e quindi "Elimina Percorsi" per eliminare tutti i percorsi 
+delle dallo schermo e dal database interno.
+
+HELP-INDEX>Ripulire lo schermo dai simboli di stazioni
+
+                   Ripulire lo schermo dai simboli di stazioni
+
+Selezionare File e quindi "Elimina tutte le Stazioni". Questo eliminer� tutti 
+dati delle stazioni ricevute fino a quel momento eccetto la vostra.
+
+HELP-INDEX>Rispondere ad un log
+
+                              Rispondere ad un log
+
+Selezionare "Apri file log" e selezionare un file di log creato dal TNC o dalla 
+rete con la funzione sotto le opzioni di rete. La stazione user� il file di log 
+come se 
+fosse direttamente connessa al TNC.
+
+HELP-INDEX>Localizzare una Stazione
+
+                            Localizzare una Stazione
+
+Selezionare Vista e quindi "Localizza Stazione" per fare apparire una finestra 
+di dialogo che permette di inserire un nominativo (completo, non case 
+sensitive). Se si vuole cercare un nominativo parziale allora bisogna 
+deselezionare "Nome esatto".  Selezionando "Maius/Minus Esatti" verranno
+ osservati anche i criteri di Maiuscole/minuscole.
+Selezionando "Localizza Ora!" il Display verr� centrato sulla stazione cercata 
+al livello di zoom corrente.  "Annulla" chiuder� la finestra di dialogo.
+
+
+HELP-INDEX>Creare ed usare i Salti alla Stazione
+
+                     Creare ed usare i Salti alla Stazione
+
+Selezionare Visualizza e quindi  "Vai alla Stazione" per visualizzare una
+finestra di dialogo.
+La prima volta che si usa questa funzione la finestra di dialogo sar� vuota.  
+Si pu� creare una nuova vista selezionando "Nuova posizione", inserire il nome  
+e quindi Aggiungi.
+Per usare le posizioni registrate baster� selezionare la posizione e quindi il 
+tasto "Vai!" per centrare la posizione registrata.  E' possibile eliminare una 
+posizione selezionandola e selezionando "Elimina".
+
+HELP-INDEX>Inseguimento di una stazione
+
+Inseguimento di una stazione
+
+Selezionare Visualizza e quindi Insegui stazione.  Inserire il nominativo da 
+inseguire (tutto o parte di esso) e quindi selezionare "Insegui Ora!".  Appena 
+la stazione si muove, essa viene centrata nello schermo.  Per disattivare 
+questa funzione bisogna selezionare "Annulla Inseguimento".
+
+HELP-INDEX>Tabella dei simboli
+
+                        Tabella dei Simboli
+
+Simbolo    Gruppo /                     Gruppo \
+
+!          Triangolo w/!                Triangolo w/!
+"          Nuvola Nera                  Nuvola da Pioggia
+#          Digi                         DIGI
+$          Telefono                     Simbolo $
+%          DX                           DX
+&          GATEWAY-HF                   GATE
+'          Piccolo Aereo                Incidente Aereo
+(          Nuvola                       Nuvola
+)          TBD
+*          Fiocco di neve               Fiocco di neve
++          Croce rossa
+,          L inversa
+-          Casa con antenna Omnidirezionale
+.          Piccola x
+/          Punto rosso
+0          0 in un quadrato                 Cerchio
+1          1 in un quadrato
+2          2 in un quadrato     
+3          3 in un quadrato
+4          4 in un quadrato     
+5          5 in un quadrato
+6          6 in un quadrato     
+7          7 in un quadrato
+8          8 in un quadrato     
+9          9 in un quadrato                  GAS
+:          Fuoco                         ?
+;          Tenda                         Tenda
+<          Motocicletta                  Banderuola
+=          Locomotiva
+>          Auto                          Auto
+?          POS Antenna                   ? in un quadrato     
+@          URAGANO/TEMPESTA              URAGANO/TEMPESTA
+A          Pronto Soccorso                               Quadrato
+B          BBS                           Neve a vento
+C          Canoa
+D          D in un cerchio
+E          E in un cerchio               Fumogeno
+F          F in un cerchio
+G          Antenna Grid Square           ?
+H          Hotel/Letto
+I          TCP/IP                        ?
+J          J in un cerchio               Fulmine
+K          Scuola Casa
+L          Faro                          Faro
+M          Mac
+N          NTS                           ?
+O          Pallone Aerostatico
+P          Auto Polizia                  Rx
+Q          Cerchio con Cerchietti        Cerchio con Cerchietti
+R          RV                            Ristorante
+S          Shuttle                       Satellite
+T          Temporale (cloud/bolt)        Temporale (cloud/bolt)
+U          Scuolabus                             Sole
+V          VOR TAC                       VOR TAC Symbol
+W          National Weather Service      NWS-Digi
+X          Elicottero
+Y          Barca a vela
+Z          Windows
+[          Corridore                     Bagno
+\          Triangolo DF
+]          Packet Mail Box
+^          Grande Aereo                  Grande Aereo
+_          Stazione meteo                WS-Digi
+`          Antenna parabolica
+a          Ambulanza
+b          Bicicletta                    Nuvola a vento
+c          antenna DX
+d          Caserma Pompieri              Antenna DX
+e          Cavallo                       Nuvola a Cirro
+f          Mezzo Pompieri                FC Cloud
+g          aliante                       Banderuola (2)
+h          Ospedale                      HAM
+i          Isola                         Isola
+j          Jeep                          Jeep
+k          Camion                        Camion
+l          Puntino                       Puntino
+m          MIC                           Pietra Miliare
+n          N                             Small Triangle
+o          EOC                           Punto con cerchietti
+p          Cagnolino                     Punto con cerchietti
+q          GS Antenna                    GS Antenna
+r          Traliccio Antenna             Traliccio
+s          Nave                          Nave
+t          TS                            ?
+u          18 Wheel Truck
+v          Van                           Punto con cerchietti
+w          H20                           Inondazione
+x          X Windows                     Punto Rosso
+y          House w/Yagi                  Casa con Yagi
+z                                        X Windows
+{          NEBBIA                        NEBBIA
+|          Linea Nera                    Linea Nera
+}          TCP                           TCP
+~          Barca a vela                  Barca a vela
+
+
diff --git a/help/help-Portuguese.dat b/help/help-Portuguese.dat
new file mode 100644
index 0000000..a858ac6
--- /dev/null
+++ b/help/help-Portuguese.dat
@@ -0,0 +1,3099 @@
+HELP-INDEX>READ ME FIRST - License
+
+                          READ ME FIRST - License
+
+For the most current information please read the README file in the Xastir
+directory.  Also see the LICENSE and COPYING files for additional information.
+
+Remember this program is intended to be used by the HAM community, in the USA
+the FCC restricts you from transmitting over RF if you are not a licensed HAM.
+Users in countries outside the USA should seek their local government 
+restrictions. 
+
+LICENSE:
+
+XASTIR, Amateur Station Tracking and Information Reporting
+Copyright (C) 1999,2000 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
+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.
+
+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.
+
+More information on the program can be found at:
+
+ http://www.xastir.org
+ http://sourceforge.net/projects/xastir/
+ http://xastir.sourceforge.net
+
+There are some mailing lists available that are Xastir-specific.
+Please subscribe to one or both of them for the latest Xastir
+information.  See http://www.xastir.org to subscribe.
+
+For more information on the GNU License look at:
+http://www.gnu.org
+
+
+HELP-INDEX>Welcome! and Notes from the Authors
+
+                      Welcome! and Notes from the Authors
+
+XASTIR, or X-windows Amateur Station Tracking and Information Reporting.
+
+Xastir is an APRS(tm) program that is Open Source and free to use and 
+pass out to others. Currently this program is in development and should 
+not be seen as a finished product! Your help will be needed to make this
+a better program.  If you have programming skills and/or can write 
+documentation, your help may be needed! We have a lot of ideas but very 
+little time, so if you think you can add something to the effort let us
+know!
+
+
+
+APRS(tm) is a Trademark of Bob Bruninga, his home page is at
+"http://web.usna.navy.mil/~bruninga/aprs.html". A great deal of information
+on APRS(tm) can be found in the APRSdos documentation written by
+Bob Bruninga. An additional source of information is the APRS(tm)
+specification, available from http://www.tapr.org .
+
+HELP-INDEX>What's new in Xastir 2.0.1
+(Changes between 1.7 and 2.0.0 were never recorded here,this block
+describes a few of the changes from 1.9.8 to 2.0.0 that occured right
+before release of 2.0.0, but otherwise documents only changes from 2.0.0 
+to 2.0.1)
+
+Added tiling for OpenStreetMaps (2.0.0).
+Added "setlocale()" calls to assure we aren't confused by user 
+LANG variable settings.
+Improved speed of config file processing.
+Fixes for new One-Wire-Daemon protocol, allowing both old and 
+new to work with Xastir.
+Fixed segfaults that could happen when closing list dialogs.
+Fix OSM code to support 16-bit quanta in Graphics/ImageMagick.
+Fixed broken makefile that was ignoring DESTDIR.
+Fixed broken build so internal shapelib builds correctly when
+proj.4 is not installed.
+Add dbfawk files for several generations of new NWS shapefiles.
+Update get-NWSdata to pull current NWS shapefiles.
+Add start/stop files for Kenwood D72 and D710 radios.
+Added a script to convert GeoPDF files to usable GeoTIFF files.
+Make the command to set a TNC into CONVERSE mode a run-time
+configurable option in the TNC Interface Properties dialog.
+Add support for Australian Bureau of Metrology weather alerts.
+Fixes for Davis APRS Data Logger, Davis Meteo and LaCrosse 
+support so it gets rain totals correct.
+Allow "posit interval" in File->Configure->Timing to go all the
+way to zero, meaning "never send posits on a schedule."
+Add signal support so that Xastir will emit a posit when it 
+receives SIGUSR2.  Combined with zero "posit interval," this
+allows Xastir to emit a posit only when told to by an external
+script.
+Fixed error in logic for band-opening alerts (speech and audio
+alarms) so it does not incorrectly report third party traffic
+as a band opening.
+Add "Send Control-E to get GPS data?" to TNC interface 
+properties for the "Serial TNC w/ GPS on AUX port" interface
+type.  Defaults to enabled, which is correct for KPC-3+ TNCs,
+but should be turned off for any TNC that automatically
+streams GPS NMEA strings, such as Kenwood APRS radios.
+Update GPSMAN support to reflect changes in the gpsman command 
+line.
+Add a small delay between sending the converse-mode command
+and sending data for transmission, because KAM TNCs don't
+work if you send the data immediately.
+Fix a bug in the OSM tile download loop that could prevent
+further downloading of tiles if any one tile download fails.
+Fixed a thread-unsafeness bug that could cause Xastir to start
+using corrupted file names when multiple logging options
+(TNC, NET, WX, IGATE, etc.) selected simultaneously.
+Fixed get-fcc-rac.pl script to reflect changes in RAC download
+site.
+
+
+
+
+HELP-INDEX>What's new in Xastir 1.7
+Added REGRESSION_TESTS in order to test interoperability of the
+configure-time flags.
+Added a replacement for malloc() for those cases where the OS
+provides a faulty one.
+Added more to the summary.log file:  The tests and results from
+config.log.
+GDAL configure probe now uses gdal-config if it's in the user's
+path.
+Tweaked configure so that dependent libraries cause other library
+searches to fail, and to provide more user output.
+Added ASCII-art drawing to INSTALL showing most of the library
+dependencies.
+Updated symbols.dat to more closely correspond to the current spec.
+Implemented EMERGENCY BEACON transmit capability under the Help
+menu.
+Added decoding for "EMERGENCY" anywhere in the packet plus any of
+these in the TO: field:  ALARM, ALERT, WARNING, WXALARM, EM.  Any of
+these will invoke the normal emergency popup dialog.
+Waypoint symbols now have a line drawn between them and the station
+transmitting them, per the spec.
+Now using font metrics to determine size of font.  We use that to
+determine size of black rectangle to draw underneath.
+Fixed the Fetch Findu Trail function so that it matches what Findu
+can provide.
+Fixed track->shapefile function so that it works on Cygwin too.
+Added reset button to Change Debug Levels dialog.
+Enable WX Alerts menu item is now grey'ed out if Shapelib isn't
+installed.
+RINO Download timing slider is now visible but grey'ed out if gpsman
+isn't installed.
+Added a custom zoom option to the right-click zoom levels menu.
+Moved the center & zoom dialog to the map menu.
+Changed a memcpy() to an xastir_snprintf() function in alert.c to
+assure that a string is terminated.
+Free'ing some malloc'ed space for cases where hash inserts fail.
+Added probe for sighandler_t definition.
+Changed includes, added leak_detector.h.
+A few small changes here and there to get rid of compiler warnings.
+Freeing some malloc'ed space for the cases where hash inserts fail.
+Fixed initializers for awk_rule[].
+Changed hash add functions so that they do a delete first instead of
+replacing hash values.
+Moved some wx-alert related code to debug level 2.
+Changed leak detect interval from 5 minutes to 60 seconds.
+Fixed a big memory leak in draw_nice_string() function.
+Changed include files around so memory leak detection stuff is in
+leak_detection.h.
+Added new compiler flags and cleaned up the code to eliminate many
+warnings created.
+Fixed Incoming Data dialog code so that packets transmitted to local
+interfaces would appear there.
+TNC/NET toggles work for those now too.
+Fixed memory leak in font metrics code.
+Simplfied get_long()  and get_int() functions and callouts.
+Tweaks for sighandler_t and sigjmp_buf.
+Added a sign-on message for server connects.
+FCC/RAC lookup or Locate Now buttons don't destroy the dialog
+anymore.
+Fixing up strings.h includes.
+Added a new popup for EMERGENCY packets.
+Changed signal() with SIG_IGN to sigignore for some cases.
+Added a test for sigignore() to configure.ac.
+Changes to allow different versions of "gv" to be used.
+Moved "-lgdal" to end of link line to avoid conflict with other
+libraries.
+Added UDP server and client.
+Added more language strings for previously hard-coded values.
+Changed config file get_int and get_long functions to provide better
+output when config file entries are missing or out-of-range.
+We now allow gating to the internet and to RF for user-defined
+packets and telemetry packets.
+Changing to <CR><LF> for the TCP server signon message.
+Changing to timestamp per packet for log files, with long int
+seconds at the beginning.
+Added icon.
+Added support for -geometry command-line parameter.
+Added fast creation of standard SAR objects via mouse menu,
+including adding digits to the end of the object name if name would
+conflict with pre-existing objects.
+
+
+
+HELP-INDEX>What's new in Xastir 1.6
+Fix for DF lines having incorrect angles at times.
+Configurable display of layers for USGS topo maps.
+Better Map Feature Search:  Shows up to 50 matches, user selects
+which one to center map on.
+Configurable "relay" digipeater calls:  Up to 50 callsigns can be
+specified in the Xastir config file to use for relay digipeating.
+"WIDE1-1" is now the default.
+Added support for Web Map Service (WMS).
+Tweaked the GPGGA and GPRMC GPS sentence decoding.
+Added speed-ups for lat/long geotiff's.
+Added Aloha circle.
+Added new #defines in interface.h for specifying "conv" or 'k'
+command to TNC.
+Added new tnc-startup file for TAPR-2 style TNC's.
+Added transparency capability to WMS.
+Fixed digpeating code for "wide1-1,wide2-1" case.
+Fixed some compile errors that are seen on FC4 and OSX Tiger.
+Added new terraserver .geo file options.
+Changed Map Properties "fill" option to allow NO/YES/AUTO.
+Auto uses dbfawk if present, no/yes force fill to that state.
+Fixed some #ifdefs here and there so that compiles will work if
+some libraries aren't present.
+Added map caching for nearly all internet maps, plus two new toggles
+on the map menu for clearing out current-view maps or all maps from
+the cache.
+Moved Tigermap timeout slider to main timing dialog, renamed it, and
+made it function for ALL internet map fetches.
+Added timestamps to x_spider log messages.
+A fix for the emacs tempfile bug w.r.t. dbfawk files went in, but
+hasn't been verified to have fixed the problem yet.
+More bulletproofing added to the map_cache code.
+Fixed a compile problem that happens if ImageMagick isn't installed.
+Changed stipple style to solid for polygons drawn with dbfawk.
+Another fix so that linking works without map caching. 
+
+
+
+HELP-INDEX>What's new in Xastir 1.5
+Optional Rtree shapefile extent caching
+Optional berkelydb-based internet map caching
+Modifier keys fix
+Improvements to the message GUI
+Tactical call support re-written, hashtable based
+Warnings on crazy paths
+Hashtable weather alert speedups
+Dead-reconing for Objects/items
+Igate of specific stations (in the nws-stations.txt)
+Fixed DF object properties
+Measure function more accurate
+Decoding for "Position with Timestamp no APRS messaging" packets.
+More thorough checking for scanf/sscanf/fscanf function calls
+Fixing 100% humidity for some weather stations, plus added more data for Davis stations
+Changed active internet connection check from 1 min to 5 minutes
+Fixed decoding of compressed DF objects
+Fixes to allow new WHO-IS server to be used from Xastir
+Got rid of extra 0x00 byts between transmitted KISS frames
+Tweak to not start an interface upon changing its properties
+Tweaks to allow use of http proxy servers for online map accesses (.netrc file)
+
+
+
+HELP-INDEX>What's new in Xastir 1.4
+Comment fields for interfaces
+split_gnis and ozi2geo scripts, need to add to section on scripts
+serial mkiss interface
+move objects without confirm
+new timing params w.r.t. trails, need to add to config|timing part
+geo-coder (already in docs)
+exponential/random back-off for almost everything
+dbfawk default, memory leaks fixed
+click+drag zoom boxes
+tactical callsign support
+numerous small memory leaks, uninitialized data uses, and similar bugs fixed. 
+GPS quality info
+RINO waypoints downloading
+label trackpoints
+comment/status timestamps
+listener socket/ability to act like a limited internet server
+
+
+HELP-INDEX>Starting Xastir for the first time
+
+                    Starting Xastir for the first time
+
+When first running Xastir, you should start it from a terminal window so
+that any warning or error messages can be seen. On most systems a path is
+set up to run programs in /usr/local/bin and all you need to do is type
+"xastir &" at the prompt. On systems that do not have this path installed
+type "/usr/local/bin/xastir &" to start the program.  The '&' character
+will cause Xastir to start in the background, leaving the terminal window
+available for other uses.
+
+You may also set the language choice at this time. To set the language or
+change the current language choice, call Xastir with the option '-l':
+
+    xastir -lEnglish
+
+Language options are:
+    xastir -l Dutch
+    xastir -l English
+    xastir -l French
+    xastir -l German
+    xastir -l Italian
+    xastir -l Portuguese
+    xastir -l Spanish
+    xastir -l ElmerFudd
+    xastir -l MuppetsSwedishChef
+    xastir -l OldeEnglish
+    xastir -l PigLatin
+    xastir -l PirateEnglish
+
+The chosen language will be stored in your config file, so it is preserved
+for the next time you call Xastir.  For new installs Xastir will default to
+English until you change the language with this command line option.
+
+The menus on the top may be accessed with the mouse or with keyboard
+shortcuts. The keyboard shortcuts may not work correctly with num-lock on.
+
+You will need to configure interfaces in order to actually use Xastir.
+Interface configuration is detailed under the "Configuring Interfaces" help
+topic and its subtopics.
+
+If you are operating in a situation where a coordinate system other than the
+default DD MM.MMMM system would be helpful, you may select your preferred
+system by going to File|Configure|Coordinate system.  Any of the supported
+coordinate systems my be used as input by using the Coordinate Calculator.
+
+HELP-INDEX>Configure the Station Information
+
+                         Configure the Station Information
+
+Click on File, then Configure, then Station.
+
+Fill in your Amateur Station call sign.
+
+Fill in your station position if you are not using Xastir with a GPS 
+unit. You can locate your general position on the map with Xastir and
+use the position given by the cursor placement over the map. This
+position will be viewable in the box at the bottom of the Xastir screen
+2nd from the left, whenever the mouse is over the drawing area. You can also
+choose "Move My Station Here" from the right-click menu while your mouse is
+over your location. If you have a GPS you can skip this and set up the GPS
+later.
+
+"Send Compressed posits", if selected, will transmit in the newer compressed
+format. This format will reduce the amount of data on the air, thereby
+increasing the capacity of the APRS(tm) network. The maximum precision of the
+transmitted position is also higher. Some older programs, including recent
+versions of WinAPRS, do not decode this format yet. Findu.com might also have
+trouble with it.  We transmit course/speed in this format but not altitude.
+In order to send course/speed AND altitude requires adding nine characters to
+the packet which negates part of the reason to use compressed posits.
+
+To select a symbol to be used for your station you need to specify
+a group and a symbol character. You can manually fill in these fields,
+or press select to graphically choose a symbol. There are two groups
+of symbols available. A text description of each symbol can be found
+in the "symbol table" help topic.
+
+For some symbols of the secondary group you can specify an overlay.
+With that a symbol will be displayed together with an additional
+overlay character, e.g. a car symbol with the number 1 overlay-ed on
+top of the symbol.
+
+For using overlays you need to select a symbol from the secondary symbol
+table and enter the overlay character to be shown in the group/overlay
+field. Only numbers and uppercase characters are allowed as overlay
+characters. According to the APRS(tm) specification not every symbol can
+be overlay-ed, Xastir doesn't enforce this, but some other programs may.
+Note that not all of the symbols have been implemented in the graphics
+chooser yet, and some of them are not per the APRS(tm) spec yet.
+
+Next, enter the data for the power/height/gain of your station. This
+is useful information but is not required; simply select "Disable PHG"
+to disable it. These choices present a granular representation of your
+stations range. Select the combination of values closest to the
+description of your station.  Please use height above average
+terrain (HAAT) for the height value.  Do NOT use average height
+above sea level or height above ground.  All values must be
+specified if you wish to transmit PHG information.
+
+Another option would be to specify the RNG in the comment field in miles
+instead of using PHG. See the APRS(tm) spec for details.
+    
+For Gain use the gain of your antenna in dBi. 
+(FIXME: dBd? spec is unclear, I think it's implying dBi because it says "in
+absence of any data, stations are assumed to be running 10w to a 3dB omni at
+20ft. A typical omni is only 3dBi.....) 
+
+Note: The gain setting is really intended for vertical antennas; the gain
+setting for a beam should be quite a bit below the forward gain of the beam.
+This is because with directivity set, the PHG circle is only offset by 1/3rd
+of its size toward the specified direction. Setting gain higher will enlarge
+the whole circle unrealistically, rather than increasing the directivity.
+There was talk several years ago about amending the specifications to better
+deal with beam antennas, but nothing was changed.
+
+Enter a comment, not required but it will add insight on your station.
+A common thing to enter here is your preferred e-mail address.  It will
+be transmitted along with your posits.
+
+Position ambiguity will allow you control how accurately you transmit your
+position. A setting of none will allow your station to transmit the exact
+position you have entered or received from a GPS. The other choices will
+place you somewhere in the range of the choice you selected.  Note that
+this may throw some non-spec compliant stations for a loop.  Findu.com
+doesn't understand position ambiguity.
+
+Clicking OK will save your changes, Clicking on Cancel will keep the
+previous settings.
+
+HELP-INDEX>Configure Default Operation
+
+                        Configure Default Operation
+
+Click on File, then Configure, then Defaults.
+
+This page sets up some standard defaults for the program operation. 
+
+Transmit Station Option sets the type of packet your station will transmit 
+its data as.
+
+IGate Options will set your station up as an Internet-RF gateway. This option
+should be used with caution; As a ham you are responsible for the data that
+comes in via the Internet and is transmitted via RF. You also will need to
+choose an IGate option on each interface in order for the IGate to function.
+If you want to have your IGate forward NWS weather alerts to RF, you must
+create a ~/.xastir/data/nws-stations.txt file listing each call or NWS station
+(like "PHISVR") that you would like to transmit via RF.  This feature also
+works for gating specific callsigns to RF.  Bob Bruninga, WB4APR, recommends
+gating these calls to RF: SCOUTS, SATERN, KIDS, REDCROSS, FOUR-H, YOUTH, GUARD,
+MARS, JOTA.  See his link: "Generic Callsigns for National Events" off this web
+page for his current list of recommended callsigns:
+
+        http://www.ew.usna.edu/~bruninga/aprs.html
+                     
+"Transmit Compressed objects/items?", if selected, will transmit objects and
+items in the newer compressed format. The maximum precision of the transmitted
+position is higher, and the transmission is shorter, but some older programs do
+not decode this format yet.  Currently this only compresses "standard"
+objects/items with an optional speed/course.  It won't compress area, signpost,
+or DF objects/items, and won't currently represent altitude in "standard"
+objects/items.
+
+"Pop up new Bulletins", if selected, will cause Xastir to bring up the bulletin
+dialog when bulletins within the configured range are received. "View 
+zero-distance bulletins" will cause bulletins with no known location not to
+be displayed or cause pop-ups.
+
+"Warn if Modifier keys" will cause Xastir to print a warning if you attempt to
+use Xastir while num-lock, scroll-lock, or caps-lock is engaged. Some users
+report the screen blanking on them and similar problems when they attempt to
+use Xastir with one of these modifier keys on.
+
+You can also select "Activate alternate net?" and choose an altnet call from
+this dialog. Altnet allows you to have a private APRS(tm) network among the
+stations that also have altnet configured, and have the same altnet call
+entered.
+
+"Disable Posit Dupe-Checks" disables the check for duplicate copies of a
+position. This should only be used when a station might return to exactly the
+same position (within 60' or so for non-compressed positions) and you wish to
+see the duplicate positions and/or tracks displayed on the map.  This option
+is almost never needed in practice, but can be useful for special events like
+search and rescue operations.
+
+"My Trails in one color" shows all trails with your callsign but different 
+ssids in the same color.  With My trails in one color selected, mycall-1 
+and mycall-2 are shown in the same color.  With My trails in one color
+unchecked, mycall-1 and mycall-2 are shown in different colors.  
+
+"Load predefined objects from file" and the pick list which follows it allows 
+you to replace the list of Predefined objects that are accessible from the 
+right click pop-up menu with your own list of objects.  A set of standard
+Search and Rescue objects and a set of typical public event objects are 
+supplied in the predefined_SAR.sys and predefined_EVENT.sys files.  You may
+also use these files as a template to create a predefined_USER.sys file.  
+See the instructions in the predefined_SAR.sys and predefined_EVENT.sys file
+for details on how to define objects for a custom predefined objects menu.
+If both "Load predefined objects from file" is selected and a file that 
+exists in the xastir/config/ directory is selected, then the objects defined
+in that file will be shown on the Predefined objects menu.  The unaltered
+predefined_SAR.sys file defines the same objects as the default menu.   
+
+
+HELP-INDEX>Configure Timing
+
+                            Configure Timing
+
+Click on File, then Configure, then Timing.
+
+Posit TX Interval specifies how often your station's position will be
+transmitted.  For fixed stations a good recommendation is every 30 minutes,
+and definitely no less than 10 minutes.  Mobile stations may wish to use a
+faster rate.  Note that if you're using SmartBeaconing, this slider is
+ignored.
+
+Object/Item Max TX Interval is the maximum interval used for sending out
+objects and items. Try to keep these intervals reasonable, as transmitting
+to a long path every 5 minutes will really take up a lot of the air time.
+A decaying interval algorithm is triggered any time an object is created,
+modified, or killed.  The transmit interval will increase until it hits the
+max interval indicated by the slider.
+
+GPS Check Interval will set the interval of time to look at the GPS for new
+data. This is available for stations using an HSP or shared cable with their
+TNC.
+
+Dead-Reckoning Timeout adjusts how long a position is assumed valid for the
+purpose of estimating its current position.
+
+New Track Time adjusts how many minutes must elapse before a new
+separate track is started.  Caution: setting the new track time to 0 will turn
+off the display of all tracks.
+
+RINO -> Objects Interval adjusts how often waypoints are downloaded from an
+attached Garmin RINO radio/GPS unit.  APRS(tm) Objects are created out of any
+waypoints beginning with "APRS".  The "APRS" prefix is removed when creating
+the Object names.
+
+Station Ghosting Time specifies the ghosting interval. Stations that have not
+been heard in the given period will appear ghosted on screen.
+
+Station Clear Time specifies when a station will be removed from the screen.
+
+Station Delete Time specifies the number of full days before data from a
+station will be entirely removed from the Xastir database.
+
+Serial Inter-Char Delay specifies a wait time in milliseconds between each
+character sent to an attached TNC.
+
+New Track Interval (degrees) specifies distance in lat/long degrees at which
+a new track segment is started.   Caution: setting new track interval to 0
+degreees will turn off the display of all tracks.
+
+Snapshot Interval (minutes) specifies how often snapshot files will be
+written if either File->PNG Snapshots or File->KML Snapshots are selected.
+
+HELP-INDEX>Configure Audio Alarms
+
+                           Configure Audio Alarms
+
+Click on File, then Configure, then Audio Alarms.
+
+To use this option you must have a sound card and a program that will play
+wav files. The Audio Play Command should contain the program you want to
+execute to play the audio file (and any command line options). That of
+course doesn't work if the only sound card in the system is used for a
+soundmodem...
+
+Each type of alert has a check-box to enable it. The fields will contain the
+name of the file to play. Fields under the option will set parameters for the
+option.
+
+The current choices are:
+Play message on hearing a new station.
+Play message on receiving a new message.
+Play message on receiving data from a station within the min/max distance of
+     your proximity settings. 
+Play message on receiving data from a station (via TNC) within the min/max
+     distance of your band opening settings.
+Play message on receiving and displaying a new weather alert.
+
+There is a standard set of sounds available most places where Xastir can be
+obtained, please see the file INSTALL for more information.
+
+HELP-INDEX>Configure Speech
+
+                       Configure Speech Synthesis
+
+To use this option you must have a sound card and the 'festival' speech
+synthesis software installed.  Install Festival and start it in 'server' 
+mode prior to starting up XASTIR.  The normal command for this is 
+"festival_server &".  If you use the "festival --server" option instead (old
+method), you may run into problems with connections getting rejected by the
+server.
+
+Once you have festival installed, Xastir will have the ability to speak using
+the following choices:
+
+New Station       - Announce the call of a new station.
+New Message Alert - Announce the arrival of a new message.
+New Message Body  - Speak the contents of a message.
+Proximity Alert   - Announce when receiving data from a station within the
+    min.max distance of your proximity settings.  This option uses the 
+    proximity settings found in the Audio Alarms menu.
+Tracked station Proximity Alert - Announce when receiving data from a
+    station within the min.max distance of the tracked station. This option
+    uses the proximity settings found in the Audio Alarms menu.
+Band Opening      - Announce when receiving data from a station (via TNC) 
+    within the min/max distance of your band opening settings.  This option 
+    uses the distance settings found in the Audio Alarms menu.
+New Weather Alert - Not implemented yet.
+
+Info on Festival may be obtained from: http://www.speech.cs.cmu.edu/festival/
+
+HELP-INDEX>Configure Smart Beaconing
+
+Click File, then Configure, then Smart Beaconing.
+
+The main "Enable SmartBeaconing(tm)" Will cause Xastir to transmit positions at
+various rates and locations based on the movement of the station. It creates
+more realistic trails and makes dead-reckoning much more accurate. This option
+is only useful in a mobile station with a GPS attached.
+
+There are several options available to customize the operation of
+SmartBeaconing:
+
+High rate
+The interval (in seconds) at which beacons are sent when the speed is above the
+High speed setting.  This parameter is also used to compute a beacon rate based
+on speed when traveling between the high and low speeds.
+
+High speed
+The speed threshold that will cause beacons at the rate specified above.
+
+Low rate
+The interval (in minutes) at which beacons are sent when the speed is below the
+Low speed setting.  Basically consider this to be the stopped beacon rate.
+This parameter is not used at all when traveling at a rate of speed higher than
+"Low speed".
+
+Low speed
+The speed threshold that will cause beacons at the rate specified above.
+
+Minimum Turn
+The minimum degrees that corner pegging can occur at "High speed" or above.
+Lower speeds will require more degrees of turn to trigger a posit, based on
+the value of "Turn Slope" below.
+
+Turn Slope
+Fudge factor for making turns less sensitive at lower speeds.  The parameter
+doesn't have any units. It ends up being non-linear over the speed range the
+way the original SmartBeaconing(tm) algorithm works.
+
+Wait Time
+The time in seconds between corner-pegging beacons, prevents multiple
+beacons in short succession.
+
+HELP-INDEX>Configure Units of Measure
+
+                        Configure Units of Measure
+
+The default selection is for the Metric System: mm, cm, km/h, etc. To select
+English units, inches, feet, MPH, etc. Click on File, then Configure, then
+toggle the "Enable English Units" check-box.
+
+HELP-INDEX>Save Config Now!
+
+                        Save Config Now!
+
+This button will save all of the current configuration to the config file.
+Note that when Xastir is closed, it also saves configuration to the config
+file.
+
+HELP-INDEX>Bottom Status Bar
+
+                         Bottom Status Bar
+
+At the bottom of the window various status messages are available:
+
+In the first box on the left general status messages are displayed for a
+short time.
+
+The second box displays the current lat/long or UTM, and Maidenhead grid
+square position of the mouse over the map. If file|configure|Dist/Bearing
+Status is selected, this box will also contain the course and bearing of
+this position relative to your station.
+
+A third box is used to display how many stations are on screen, and how many
+are in the database.
+
+The fourth box will display the current zoom level and will display "Tr" if
+the station tracking is on.  At some zoom levels the Tr is not
+displayed properly due to the size of the box. 
+
+The fifth box indicates whether logging is enabled.
+
+The last area will display the device status for each interface. Each will
+display in order first to last or 0 to 9. The interface status is separated
+into three areas, top device type, center data flow, and bottom interface
+operational status.
+
+The device type will show what interfaces are configured. The color will
+show what type of device the interface is configured for. Blues are for
+the various TNC devices; Greens will show the GPS devices; Yellow for
+Internet Servers; Orange for WX interfaces.
+
+The center will show data flow in (arrow pointing left) or data flow out
+(arrow pointing right) for that interface.
+
+A green box at the bottom will show if that interface is active. A red
+box will show if the interface is active but in an error condition.
+Otherwise nothing will show if the interface is not active.
+
+HELP-INDEX>Moving the Map and the Options Menu
+
+                    Moving the Map and the Options Menu
+
+Map movement is very simple, ease and quickness of movement is dependent on
+your processor speed and the amount of detail you load. Hint: You can
+disable all maps in the maps menu in order to move around quickly, then
+enable maps again.
+
+Zooming:
+Zooming can be accomplished by right clicking on the map (and holding the 
+button down). This will bring up an options menu, with choices to zoom in or
+out a single level, or to change to one of the preset zoom levels.
+
+All zooming functions from the options menu will zoom in or out at the point
+on the map where you clicked the right mouse button. Zoom levels have a cascade
+menu. Levels 1-64 are for very local areas and levels 256 and above are for
+large areas. The lower number the level, the more local the area.
+
+A quicker zoom in function is to push and hold the left mouse button, drag it
+across the area of interest and let go.  The map will zoom to approximately
+the size of the square you just described with the mouse drag operation. The
+"move" and "measure" toolbar check-boxes must be disabled for this feature to
+work. Clicking the middle button zooms out with a factor of 2, centering
+where you clicked as well.
+
+The map can also be zoomed with the keyboard Page-Up/Page-Down keys, or the "In"
+and "Out" buttons in the toolbar. The zooming in this case keeps the same map
+center (no centering).
+
+Panning/Centering:
+The map can be centered at a specific location by choosing center in the
+right-click options menu.
+
+Panning is also accomplished by using the options menu, or by using the arrow
+buttons on the toolbar. The map position will shift a portion of a screen.
+Enough data from the previous screen should be available to re-orient yourself.
+
+The map can also be panned with the keyboard arrow keys.
+
+More About Options Menu:
+
+Map Display Bookmarks
+See the help topic "Creating and using Map Display Bookmarks"
+
+The "Station Info" selection on the options menu will look for the station
+closest to where you right-clicked the mouse. If more than one station is
+close to that position a "Station chooser" list will appear, then you can
+choose what station's data you want to look at. If only one station is close
+to the mouse pointer then that station's data will display immediately. For
+mobile stations with a lot of track data this could need some time on slow
+computers. Note that expired stations still have their data stored in the
+Xastir database, and if one knows a station's former location, one can still
+view its info in this manner. Use the "Display Expired Data" option
+to display some data that disappears for ghosted stations, like
+speed/altitude, etc.
+
+With "Last Pos/Zoom" you can restore the previous map view by restoring the
+previous values of the map zoom and centering values.
+
+For Object and Item information, please see the help topic "Objects and Items"
+
+Draw CAD objects lets you create polygons on screen, for tactical or
+presentation use. This feature is still under construction.
+
+"Move my Station here" Allows you to move your station to a specified map
+location without editing the station configuration.
+
+HELP-INDEX>Objects and Items
+
+A station could place several different objects on the map, with their
+position transmitted to other stations. The object names are less restrictive
+than the normal station names.
+
+Objects and items are nearly the same things, but their use could differ a bit.
+Objects are generally used for moving or variable things such as thunderstorms,
+while items are generally used for more inanimate things, such as water
+stations. Because items may not be decoded by some flavors of APRS(tm)
+programs, objects are often used for inanimate things, too.
+
+Besides normal objects with a symbol at its position there are some special
+objects available. Area objects are useful for a variety of operations in
+which you want to draw or highlight an area of interest on the map. They can
+also be used to draw trails/roads/boundaries, watch boxes for severe weather,
+runways, perimeter of a search area or of a public service event, areas of
+damage, areas to stay out of, buildings that aren't on the map, checker/chess
+boards for gaming on APRS(tm). :-)  Note that area objects are not
+implemented on all versions of APRS(tm) programs, and some of the details of
+how they are displayed may also be different on other programs.
+For the other three, probability circles, signposts and DF objects, see below.
+
+Objects/Items are retransmitted at a decaying rate up to the max interval
+specified in File|Configure|Timings.  "killed" objects/items are also
+retransmitted in this manner until they expire from the queue (currently 20
+transmits).  Objects/Items are persistent across Xastir sessions, and are
+stored in ~/.xastir/config/object.log. This file may be cleared by selecting
+"Clear Object/Item history" from the Stations menu.
+
+The Object/Item creation option in the right click menu will bring up a dialog
+with the position of your object filled in based on where you clicked the
+mouse. You may fill in the details, and add an object/item from this menu.
+
+The Object/Item modification option brings you the object modification dialog.
+It is similar to the object creation dialog, except the object's current
+information is already filled out, and the object's name and a few of the
+other options can't be changed. You could also delete the object with this
+option.
+
+Objects and items can be moved with the mouse if the "Move" check-box on the
+toolbar is enabled.  
+
+The Predefined Objects option in the right click menu allows you to rapidly
+place standard Search and Rescue objects without having to go through the 
+Object/Item creation dialog.  These objects include standard Incident 
+Command System symbols for ICP, Staging, Base, and Helibase, as well as
+SAR objects for PLS, IPP (with 4 area circles), and LKP If an object of the 
+same name as an object you select off the list allready exists, a new 
+object will be created with a number appended to the end.  For example, 
+the first time you select Staging from the Predefined objects menu, an
+object named Staging will be created.  If you then create an additional 
+Staging object from the Predefined objects menu, it will be named Staging2. 
+Heli- (and user defined objects ending in a "-") will be created as Heli-1,
+Heli-2, Heli-3, etc.  If you have recieved one of these standard objects that 
+was transmitted by another station, your first object will be named with an 
+appended number.  You may wish to assign a tactical call to your object in 
+this situation (for example, replacing ICP2 with a tactical call).  
+
+The Predefined Objects menu is customizable by modifying the files 
+predefined_SAR.sys, predefined_EVENT.sys, and predefined_USER.sys, and then
+selecting one these files through the File/Configuration/Defaults dialog. 
+See the predefined_SAR.sys file for details.  
+
+Description of the entries in the object dialogue:
+
+= Signpost =
+This makes the object a signpost object. These signs can contain one
+to three characters, and currently appear in Xastir as a blank sign.
+Station Info shows the value contained on the sign.
+
+= Area Object =
+This makes the object an area object, and enables the area object controls
+described below.
+
+= DF Object =
+This is a direction-finding report. Enabling it allows you to choose Omni or
+Beam report, and allows you to put in the specifics for each.  See:
+    http://web.usna.navy.mil/~bruninga/dfing.html
+and the APRSdos documentation for details on these useful techniques.
+(FIXME: Separate section on DF'ing techniques?)
+
+= Probability Circles =
+This allows you to define the radius (in miles) of two circles centered on 
+the object or item.  Min is the radius (in miles) of the smaller, inner 
+circle, and Max is the radius (in miles) of the larger, outer circle.  
+These circles are drawn in red.  They can be used to assist in planning 
+Search and Rescue operations.  To create more than two circles, add additional
+probability circle objects to the same location.  Probability circles may not
+be displayed by other client software.
+
+= Name =
+This is the name of the object or item. It may be up to 9 characters long,
+with spaces allowed inside the name. When modifying an object, this may not
+be changed. To rename an object you must delete the original and then create
+a new object. Note that if you select Signpost/Area Object/DF Object that
+this field and perhaps others are cleared. Enter the name AFTER you've
+selected the type of object it will become.
+
+= Station Symbol =
+You may select a symbol for the object. Press select to choose graphically,
+or see the symbol table help section for descriptions of each symbol.  Note
+also that area objects, signpost objects, and DF objects have special fixed
+symbols and therefore can't be selected here.  Those particular symbols get
+automatically assigned when you change to that type of object.
+
+= Location =
+The location of the object is specified here. If you selected "Create 
+Object/Item" from the right-click menu, the location you clicked will be filled
+in. If you moved an object with the mouse, the new location will be in these
+fields.  You can also type in a location, for instance you may be placing an
+object from an over-the-air voice report.
+
+= Generic Options =
+You may specify the speed, direction, and altitude of objects here. Some object
+types cannot have a speed or direction, in which case the fields are grayed
+out.
+
+= Signpost Text =
+If the object is a signpost object, you may specify the 1 to 3 digit
+number that appears on the sign here.  Note that Xastir doesn't display
+signpost objects properly yet.
+
+= Area Object =
+Area Objects are used to highlight specific parts of maps, or to draw extra
+detail onto maps. This will be done with the following entries:
+  = Bright Color =
+    Use the brighter version of the colors allowed.
+  = Color-Fill =
+    The area should be filled, not just outlined. This may be useful to
+    exclude an area from a search or other event.
+  = Object Type =
+    Choose from the geometric shapes allowed.
+  = Object Color =
+    Choose the color in which the object will display. This is also affected
+    by the "Bright Color" option above.
+  = Object Offset Up =
+    In hundredth of a degree latitude.  An unfortunate detail of the spec,
+    and hard to calculate easily.  Suffice it to say that you can change
+    the size of the object once you place it.
+  = Object Offset Left except / =
+    In hundredth of a degree longitude.  See above.
+  = Object corridor =
+    This is the width of a line area object. Useful for runways, weather
+    watch boxes, describing an area of interest or an area of exclusion, etc.
+
+Always delete your objects and items when you are done with them!
+Don't just allow them to expire from your cache, as they may hang
+around on other peoples' screens for an extended period.
+
+
+Description of weather watch boxes:
+
+Watch boxes and "areas of maximum concern" (AOMC) generated by the WXSVR
+(http://wxsvr.net/) are colored as follows:
+
+  Yellow dashed = Severe Thunderstorm Watch  (looks like crime scene tape)
+   Yellow solid = AOMC for Severe Thunderstorm Warning
+     Red dashed = Tornado Watch
+      Red solid = AOMC for Tornado Warning.
+   Green dashed = Mesoscale (larger) discussion area
+    Blue dashed = Test Watch
+     Blue solid = Test Warning
+
+HELP-INDEX>CAD Objects
+
+                     CAD Objects
+
+[CAD object support has moved from the right click menu to 
+Map/Draw CAD Objects]. 
+
+CAD object support is preliminary at this time.  Features and the user 
+interface are subject to change.  
+ 
+CAD objects are arbitrary shapes that you can draw on maps in xastir, but 
+can't transmit by APRS.  
+
+Currently supported CAD objects are:
+Polygons: Closed areas of at least three points.  
+
+To create a CAD object, first press the Draw radio button on the toolbar.
+This will change the cursor to a pencil.  Begin drawing a polygon by 
+clicking with the middle mouse button (or both buttons on a two button mouse,
+for which you will need to have three button mouse emulation enabled).  This 
+places a point on the map.  Now move the cursor somewhere else (the normal
+left click/right click navigation and zoom functions still work normaly) and
+click the middle mouse button again.  This draws a line between the two points
+you have selected.  Middle click again to draw another line segment and keep 
+repeating until you have drawn all except for the closing line segment of your
+polygon.  To close the polygon, select Map/Draw
+CAD Objects/Close Polygon.  This will close your polygon and bring up a dialog
+that will allow you to enter a name, comment, and probability for the polygon.
+
+When you have finished drawing CAD objects, exit the CAD drawing mode by 
+deselecting the Draw radio button on the toolbar.
+
+CAD objects can be edited from the View/CAD Polygons menu and from the 
+Map/Draw CAD Objects/CAD Polygons menu.  CAD objects can be  deleted from the 
+Map/Draw CAD Objects/Erase CAD Polygons menu.
+
+HELP-INDEX>View Menu
+
+                     View Menu Options
+
+The View menu presents various ways to look at data in Xastir.
+
+Bulletins
+This is the APRS(tm) bulletin board, where important announcements are posted.
+If you are connected with the internet interface, it is a good idea to set the
+range field to a few hundred miles, to ignore posts from other portions of the
+world. "0" in the range field means the entire world. Click the "Change range"
+button to make changes to this field effective. Xastir currently does not
+support sending bulletins. Incoming bulletins will open this dialog
+automatically if you select "pop up new bulletins" in the Configure|Defaults
+dialog.  The "View zero-distance bulletins" button enables viewing bulletins
+for which you don't have a range yet (they haven't sent a posit yet, but you
+received a bulletin from them).  If this is unchecked, you must get a position
+from a station, and the station must be within the range selected (or range
+must be set to zero), in order for the bulletin to be viewed.
+ 
+Incoming packet data
+This displays the incoming data on your TNC or internet interface. The radio
+buttons below select if you want to see only TNC data, only internet data, or
+both.
+
+Mobile Stations
+This is a list of stations that are moving. Stations qualify for this list if
+they have moved (more than one position received for them), the symbol of the
+station is not considered. Information shown includes course, speed, altitude,
+position, number of packets received, number of visible GPS satellites, course
+from your station, and distance from your station. 
+
+All Stations
+This option displays a table of all stations sorted alphabetically. It includes
+the number of packets heard, the time the station was last heard, the path that
+the most recent packet took, the PHG, and the comment of the station.
+
+Local stations
+This option displays only stations that are heard via your TNC. It includes
+the number of packets heard, the time the station was last heard, the path that
+the most recent packet took, the PHG, and the comment of the station.
+
+Last Stations
+This option displays a table of all stations sorted from most recently heard
+to least recently heard. It includes the number of packets heard, the time
+the station was last heard, the path that the most recent packet took, the PHG,
+and the comment of the station.
+
+Objects & Items
+This option displays only objects and items. It includes the number of packets
+heard, the time the objects/item was last heard, the path that the most recent
+packet took, the PHG, and the comment of the object/item.
+
+Own Objects & Items
+This option displays only objects and items that you control (i.e.: Have sent
+the most recent update for). It includes the number of packets heard, the time
+the objects/item was last heard, the path that the most recent packet took, the
+PHG, and the comment of the object/item. A ghosted icon indicates that the
+object has been deleted.
+
+Weather Stations
+This option displays a table of all the APRS(tm) weather stations and their
+data. Data includes wind course, wind speed, wind gust speed, temperature,
+humidity, barometric pressure, rain in the past hour, rain since midnight,
+and rain in the last 24 hours.
+
+Own weather data
+Displays your weather data if you have a weather station and have configured
+Xastir to access it.
+
+Weather Alerts
+Displays weather alerts received, including the alert flags, alert source/type,
+alert destination, expiration, message, and effected location. This data
+is used for the alert highlighting. Double-clicking on an alert will request
+further information about it via finger from the online WXSVR. This only
+works if you have internet access; future versions may access this data over
+radio as well.
+
+Message Traffic
+Shows all message traffic while the window is open. It includes the source,
+destination, interface, and message. The range option can limit this display
+to nearby stations, much like the range control on bulletins. A range of 0
+causes all messages to be displayed.
+
+GPS Status
+Shows the status of your GPS unit, including the type of fix and number of
+satellites acquired.
+
+Uptime
+Shows the amount of time elapsed since Xastir was started.
+
+HELP-INDEX>Map Menu and the Map Chooser
+
+                       Map Menu and the Map Chooser
+
+Map Menu:
+
+Map Chooser
+This will present you with a list of map directories and/or files in your
+map directory. Checking the "Expand Dirs" option toggles the expansion of
+directories into individual map files. The properties dialog allows more
+advanced controls, and is described below. Click on map names to highlight
+them, this will cause them to be displayed when you click the OK button. You
+may select any number of maps. Clicking "Clear" will select no maps,
+clicking "Vector" will select only vector maps. The three "topo" options will
+automatically select all GeoTIFF images of the listed size. Clicking the OK
+button will display the selected maps. Cancel will abandon any changes.
+
+  Map Chooser Properties
+  Clicking the Properties button will bring up a dialog where you can specify
+  the layer in which maps appear, and in which zoom levels they appear. Higher
+  layer numbers are displayed on top of lower numbers. The range may be
+  specified from -99999 to 99999; it is suggested that you space your layering
+  numbers widely to allow later insertion of additional map layers. From this
+  dialog you may specify whether a vector map is drawn with color fills. This
+  is a per-map setting; the global disable option on the Maps menu can override
+  this. The Filled setting is ignored for raster maps (images). A setting of
+  "auto" allows a dbfawk file to control this parameter directly (usable only
+  if dbfawk is compiled in and the map in question is a Shapefile). You can
+  also select whether a map is considered by the "Auto maps" feature here.
+  Finally, you can specify the minimum and maximum zoom levels at which a map
+  is displayed. This is useful to prevent very detailed local maps from loading
+  at very wide zoom positions, and visa-versa. A minimum zoom of 10 means a map
+  will be displayed at all zooms including and above 10. Likewise, a maximum
+  zoom of 256 means a map will be displayed at all zooms below and including
+  256.
+
+Map Display Bookmarks
+See the help topic "Creating and using Map Display Bookmarks"
+
+Locate Map Feature
+This option brings up a search dialog where you can search through the labels
+in a GNIS file to find a specific location.  It will center the map on the
+new location if it is found. The "GNIS File:" entry is saved between calls
+and between invocations of Xastir.  You must put GNIS files into the
+xastir/GNIS directory in order to use this feature.
+
+Find Address 
+This option brings up a search dialog where you can enter an address. It will 
+center on the map if the address is found. The path to the geo-coder file is 
+saved between calls. 
+
+Coordinate Calc
+This option opens a simple calculator that can convert between coordinate
+systems. This is useful for converting positions to the various formats used
+by different groups of people. This same calculator can be called up by the
+Calc button on some of the other dialogs. It's useful for entering coordinates
+in other formats.
+
+Configure menu:
+  Background color
+  This option controls the color of the background behind the maps you have
+  displayed. The background color is often entirely hidden by filled maps
+  (see below).
+
+  Map Intensity
+  This controls the brightness of any graphics used as maps. This option only
+  appears if you have compiled with GeoTIFF support.
+
+  Adjust Gamma Correction
+  This allows you to apply gamma connection to all loaded map graphics. Maps
+  can be adjusted individually in their .geo files, see the section on .geos in
+  "Map files and WX Counties". This option only appears if you've compiled with
+  ImageMagick support, and does not apply to geoTIFF maps; see the above
+  option.
+
+  Map labels font
+  This allows you to set the font style and size used for map labels.
+
+  Station Text Style
+  Controls which font and style to use for station text and others.
+
+  Icon Outline Style
+  This allows you to specify an outline that surrounds station icons. This
+  helps improve visibility on various backgrounds.
+
+  Configure Tigermap
+  Turning this option on causes Xastir to download the map from the US census
+  bureau's online tiger mapping server. The dialog that comes up allows one to
+  select which layers are displayed, as well as the brightness of the resulting
+  map. This is only available if you have compiled with ImageMagick support.
+  Tigermaps are always loaded as the bottom layer; they do not have layering
+  settings in the Map Chooser.
+
+Disable All Maps
+This option disables the loading of any maps. It is most useful when doing
+rapid zooming or panning, because it saves the need to load the maps on each
+redraw.  Note that this option is not saved between sessions.
+
+Enable Auto Maps
+When enabled, any map found in the map directory (or any directory under it)
+will be displayed if it falls within the current display region. You can add
+any number of directory levels under the main map directory for your maps. Auto
+maps will go through any that have Auto Maps enabled (in the Map Chooser
+Properties dialog) check them all and find what map (or part) should be
+displayed.  All Maps will be merged into the viewing area. If you have a large
+quantity of maps, very detailed maps or a slower computer this can be quite
+slow. When this option is off, maps selected with the Map Chooser and/or Tiger
+Maps dialog will be displayed.
+
+Auto Maps - disable Raster maps
+This option prevents Auto Maps from loading maps which are graphics (images).
+Only vector maps will be displayed in this case.
+
+Enable Map Grid
+When enabled, this option will display a grid on the map.   If the coordinate
+system is UTM a UTM grid will be displayed.  If the coordinate system is 
+latitude/longitude then a latitude and longitude grid will be displayed.  As you
+zoom in the grid switches to a finer resolution.  The spacing of the latitude 
+and longitude grid may be manually adjusted with the "+" and "-" keys.
+
+Enable Map Border
+When both Enable Map Grid and Enable Map Border are enabled, a narrow white 
+border is drawn around the map and the grid lines are labeled using the 
+selected coordinate system (File/Configure/Coordinate System), and the selected
+border font (Map/Configure/Map Labels font/Border Font).   If the UTM or MGRS 
+coordinate systems are selected, the grid lines will be labeled with easting
+and northing values only at zoom levels smaller than about 2048.  
+
+Enable Map Levels
+When enabled, this option will try to filter out data when the zoom level
+shows large areas. This does not work will all maps but will work with the
+maps generated from Tiger Line maps at the aprs.rutgers.edu site, and with
+ESRI Shapefile maps. This does not decrease the loading times of the maps very
+much, rather it simply reduces screen clutter.
+
+Enable Map Labels
+This option toggles the display of map labels embedded in DosAPRS, WinAPRS,
+GNIS, and ESRI Shapefile format maps.
+
+Enable Area Color Fills
+This option controls the filling of vector maps. In certain cases, you
+may want to eliminate the fill to see maps below the top maps. This is a global
+control, maps may individually have color fill toggled in the properties dialog
+of the Map Chooser.
+
+Enable Weather Alert Counties
+This toggles the display of county warning area maps for severe weather.
+These maps can be obtained and installed according to the directions in the
+README.MAPS file. They are displayed on screen when special weather alert
+messages are received, and expire after a time or can be remotely canceled.
+The weather alert text can be seen under View|Weather Alerts. The
+xastir/Counties directory must be populated with the correct files from NOAA
+and Shapelib support must be compiled into Xastir in order to enable this
+functionality.
+
+Index New Maps on Startup
+This option controls if the map index file is built on startup. Most users
+should leave this enabled. If the timestamp of the map file is newer than
+the map index file, the map will be indexed.
+
+Index: Add New Maps
+This option adds any new maps to the max index.  Same rules as the above
+Index New Maps feature, but a manual method of invoking it.
+
+Index: Reindex ALL Maps
+This option starts over from scratch, indexing every map it recognizes in the
+maps directory. This is useful if the Add New Maps function is skipping some
+maps, perhaps because of old timestamps on the map files.  This function may
+take quite a while to complete if you have a lot of maps.
+
+Mouse pointer menu
+This option brings up the options menu normally available by right clicking.
+
+One note on maps:  Many of the currently available vector maps for the
+U.S. were created in NAD 1927 datum, while Xastir and other APRS(tm) programs
+use WGS 1984 datum.  If zoomed in to a small area on the map the datum
+shift may be very noticeable.  The USGS topographic maps have their datum
+corrected by Xastir as they are displayed, so positions will generally
+be more accurate with those topographic maps.
+
+HELP-INDEX>Map files and WX Counties
+
+                         Map files and WX Counties
+
+Map Types
+Xastir will work with various types of map files. All DosAPRS, Windows/Mac
+APRS(tm) map files are supported, as well as PocketAPRS format maps and GNIS
+(Geographic Names Information System) label files.  Xastir also can be
+compiled to use external libraries to support XPixmap (XPM) images, GeoTIFF
+topographic maps, and ESRI Shapefile maps.  The graphics handling capability
+of Xastir can be greatly extended by compiling with ImageMagick support,
+enabling support for many graphic formats as maps (see
+"http://www.imagemagick.org/www/formats.html").  Xastir supports weather
+alert maps in ESRI Shapefile format, available from NOAA.
+
+Details of locations to obtain many of the above types of maps are found in
+the file README.MAPS
+
+Map Locations
+Any map file should be stored in the /usr/local/share/xastir/maps directory
+on your computer. This location may be different on some systems, depending on
+how Xastir was compiled/installed. You can create any number of directories
+under this directory to help organize and separate your data. The maps will be
+loaded in alphanumerical order unless layering is specified.
+
+Hints on installing and organizing maps are found in README.MAPS. 
+Maps in a pixel graphics format actually need a combination of two files,
+a data file with a graphic pixmap (.xpm) (or other format if you compiled
+with ImageMagick), and a calibration file (.geo). The .xpm file is the
+standard graphic format, available without additional libraries. If you
+want to save storage space you can use gzip to compress those files 
+("gzip map.xpm" will result in "map.xpm.gz"). Xastir detects this
+automatically during map loading. You can use XView/Gimp/ImageMagick and
+other programs to convert gif, jpg, and tif images into this format if
+you don't have support for many image types compiled in (ImageMagick). If
+you have problems with maps in xpm format, try to load and save the
+graphics with Gimp first, to convert all unknown color names into the
+binary representation.
+
+The .geo file is a text data file that will tie the image to a location
+in the world. Here is an example of a .geo file that will cover the entire
+world with the map world1.xpm:
+
+FILENAME   world1.xpm
+#          x          y        lon         lat
+TIEPOINT   0          0        -180        90
+TIEPOINT   639        319      180         -90
+IMAGESIZE  640        320
+
+.geo files can have many elements:
+
+FILENAME <filename>
+This specifies the filename of a map image to be loaded from the local disk.  
+
+URL <http://website>
+This specifies the URL of a map image to be loaded from a web or ftp site. 
+ImageMagick only.
+
+TIEPOINT <x-pixel> <y-pixel> <longitude> <latitude>
+Two tie-points are required, and more than 2 will be ignored.
+these two lines are for connecting an x,y pixel position in the image
+to a lat and long position on the earth. The points should be as close as
+possible to the upper left corner and the lower right corner of the image for
+best accuracy.  The latitude/longitude are specified in decimal degrees.
+
+IMAGESIZE <pixels horizontally> <pixels vertically>
+This specifies the size of the image in pixels. If this is not set, the image
+will be loaded each map redraw, regardless if it is on screen or not.
+IMAGESIZE is a REQUIRED OPTION if a URL is specified.  For local files, it's
+an optional parameter (we use ImageMagick to query the image size for local
+files).
+
+DATUM <datum>
+This feature is not implemented.
+
+PROJECTION <projection>
+This feature is only partially implemented, default is "LatLon", other
+possibility is "TM" to specify that the map is in  Transverse Mercator
+projection.
+
+# <anything>
+Any line with the first character of a '#' will be ignored.
+
+ImageMagick specific image enhancements:
+
+GAMMA
+eg: GAMMA 1.2    or    GAMMA 1.2,2.0,1.2
+The first will change overall gamma for this image, the second will
+lighten green more than red or blue.
+
+CONTRAST
+eg: CONTRAST 0    or    CONTRAST 1
+Doesn't seem to do that much, other values make no difference.
+
+NEGATE
+eg: NEGATE 0    or    NEGATE 1
+0 will negate all colors, 1 just grayscale colors.
+
+EQUALIZE
+No argument.
+
+NORMALIZE
+No argument.
+
+LEVEL <black_point, mid_point, white_point>
+eg: LEVEL 0,1,65535
+These values seem to be the defaults.
+
+MODULATE <brightness, saturation, hue>
+eg: MODULATE 90,150,100
+These are percents, 100,100,100 is the default.
+
+REFRESH <seconds>
+eg: REFRESH 900
+This tag is used for dynamic URLs such as weather radar, where you
+wish Xastir to auto-redraw the map at a specified interval.  By
+adding this tag to weather radar .geos, you can watch the weather
+move across your screen.  Xastir contains only one interval counter,
+so the smallest REFRESH interval loaded takes effect for all selected
+maps.
+
+TRANSPARENT 
+Color to remove from the background (make it transparent).  Use a
+number, 0=black.  Color-mapped images use the map value, so white is
+usually 0xffffffff (32-bits of 1s).  Values must be in hexadecimal,
+and are preceeded by "0x".  The value can be obtained by using debug
+level 16.  The first of the four numbers after "Color allocated is"
+is the colormap index.
+
+CROP <left top right bottom>
+Removes borders (makes them transparent).  Values are in pixels with
+(0,0) at the upper left.  A good value for the 620x620 NWS radar
+images is "CROP 35 20 616 600"
+
+Special/nonstandard .geo files:
+
+TIGERMAP
+A file with just the word "TIGERMAP" will cause Xastir to retrieve an
+online Tiger map of the area on screen. These are not available for every
+place in the world. "tigermap.geo" is automatically installed in the maps
+directory.
+
+TERRASERVER-SATELLITE
+A file with just the word "TERRASERVER-SATELLITE" will cause Xastir to
+retrieve a Terraserver satellite photo of the area on screen. Those
+services are not available for every place in the world. Note that using
+the Terraserver maps at any zoom above 256 will probably take a long time
+to load, won't show much detail, and probably won't display correctly. This
+is a limit of Microsoft's Terraserver, not Xastir.  Also note that
+crossing UTM zone boundaries is not supported by Terraserver.
+"terraserver.geo" is automatically installed in the maps directory.
+
+TERRASERVER-TOPO
+A file with just the word "TERRASERVER-TOPO" will cause Xastir to retrieve a
+topographic map of the area on screen. Those services are not available for
+every place in the world. Note that using the maps at any zoom above 256
+will probably take a long time to load, won't show much detail, and
+probably won't display correctly. This is a limit of Microsoft's
+Terraserver, not Xastir.  Also note that crossing UTM zone boundaries is not
+supported by Terraserver. "terraserver-topo.geo" is automatically
+installed in the maps directory.
+
+TERRASERVER-URBAN
+Same as above but with Terraserver colored urban-area satellite
+images. "terraserver-urban.geo" is automatically installed in the
+maps directory.
+
+TERRASERVER-REFLECTIVITY
+Same as above but with Terraserver reflectivity images.
+"terraserver-reflectivity.geo" is automatically installed in the
+maps directory.
+
+TOPORAMA-250k
+Canadian 1:250k scale topo maps, downloaded from findu.com.
+"CanadaTopo250k.geo" is automatically installed in the maps
+directory.
+
+TOPORAMA-50k
+Canadian 1:50k scale topo maps, downloaded from findu.com.
+"CanadaTopo50k.geo" is automatically installed in the maps
+directory.
+
+WMSSERVER
+Allows use of Web Map Services (WMS). An example "WMSRadar.geo" is
+automatically installed in the maps directory.
+
+
+
+geoTIFF maps are a combination of two files as well: a .tif and a .fgd file.
+The .tif file is the actual map data.  The .fgd file need only contain four
+lines like this (but may contain many other lines):
+
+1.5.1.1   WEST BOUNDING COORDINATE:  -122.000000
+1.5.1.2   EAST BOUNDING COORDINATE:  -120.000000
+1.5.1.3   NORTH BOUNDING COORDINATE:  48.000000
+1.5.1.4   SOUTH BOUNDING COORDINATE:  47.000000
+
+Xastir uses only those four lines in its calculations to determine the corner
+points of a map, to see whether the map fits in the current viewport (so it
+can decide whether to skip it).  If your map data are USGS topographic maps,
+the .fgd file should be readily available to you. If it is not, the mapfgd.pl
+script can create it for you. If you don't have a .fgd file, the map will load
+fine, but the white borders won't be cropped and the size and rotation may be
+off a tad bit. An added feature in Xastir is the ability to do datum
+translations from NAD 1927 to WGS 84 datum, which makes the USGS topographic
+maps much more  accurate on the Xastir screen.
+
+Xastir can use USGS geoTIFF topographic maps directly from the CD drive.
+Manually mount the disk or use auto-mounter to do it for you, and make sure
+you have a sym-link created in your maps directory that points to where you
+mounted your CD-ROM drive.  That's it!
+
+
+ESRI Shapefile maps are also a combination of several files, a .shp file, a
+.dbf file, and a .shx file. You only need to select the .shp file to load the
+map, but the other(s) must be present for the map to load correctly.
+
+
+GNIS (Geographic Names Information System) data is a collection of names of
+locations, or geographic features. These labels behave like map labels in
+Dos/WinAPRS maps.  As you zoom in, more labels will appear, assuming you've
+selected the GNIS file as a map and have enabled Map Labels in the Maps menu.
+If you have some of them in the xastir/GNIS directory, you can also search
+for map labels within Xastir.
+
+
+WX County Maps
+All WX County maps should be stored in the /usr/local/share/xastir/Counties
+and Xastir only supports the ESRI Shapefile standard for these. Installation
+is explained in README.MAPS.  You must have Shapelib compiled in.
+
+As NWS messages are received, different areas will get tinted to designate
+areas of concern.  They are color-coded to specify different types of
+alerts. The colors are: Cyan for advisory, yellow for watch, red for warning,
+orange for canceled alert, royal blue for tests, and green for undetermined
+alert levels. The coloring is done with a pixmap stipple that displays the
+type of alert, if it is able to be determined. These changes were made so that
+the underlying maps may still be seen underneath the weather alert areas, and
+so the alert type may be more easily determined, as sometimes matching the
+alerts on screen and in the weather alerts dialog is difficult. The display
+of weather alerts may be turned on/off via the Map menu.
+
+HELP-INDEX>Stations Menu
+
+                             Stations Menu
+
+These options will allow you to control the data displayed around the stations
+on the map. It will also let you track and find stations, and clear stations
+and trails in the database and from the map.
+
+Find Station
+See the help topic "Locating a Station".
+
+Track Station
+See the help topic "Tracking a Station"
+
+Fetch Findu Trail
+Downloads historic trail data from findu.com. Slider bars control the starting
+point and duration of data downloaded.  For an example, if you wished to see
+the track that happened two days ago, all day long, you might set the first
+slider to 48 hours (start time of two days ago) and the second slider to 24
+hours to snag exactly one day's worth of data, from the start until 24 hours
+later.
+
+
+Export all
+This sub-menu allows saving data for all stations to files [or databases]
+
+    Export to KML file
+      Saves all stations and their trails to a Keyhole Markup Language
+      file in ~/.xastir/tracklogs.  The filename will be the current
+      date and time with a .kml extension, e.g. 20080125-033045.kml
+      KML files can also be written on a regular basis using KML
+      Snapshots on the file menu.
+     
+    Store to open databases [Not yet implemented]
+      [Store to database interfaces is currently only implemented through 
+      individual SQL database interface dialogs]
+
+    To save a png snapshot of the current map, use File->PNG Snapshots
+
+Filter Data
+This sub-menu allows filtering of the displayed symbols:
+
+  Select None
+    Determines if symbols should be drawn on the map. The other options depend
+    on this being enabled.
+
+  Select Mine
+    Determines if your own station is shown on the map.
+
+  Select via TNC
+   Global toggle for displaying data received via a TNC, but may be narrowed:
+
+   Select Direct
+     This option only displays stations heard directly (not digipeated).
+
+   Select via Digi
+     This option displays stations heard indirectly via a digipeater.
+
+  Select Net
+    This option displays stations with data received via the Internet.
+
+  Include Expired Data
+    Causes Xastir to continue to display the station data that normally goes
+    away when the symbol is ghosted.  The expiration time can be adjusted in
+    the File|Configure|Defaults menu.
+
+
+  Select Stations
+    Global toggle for displaying stations, but may be narrowed:
+
+    Select Fixed Stations
+      This option displays stationary stations.
+
+    Select Moving Stations
+      This option displays stations with multiple positions or non-zero speed
+
+    Select WX Stations
+      This option displays Weather Stations.
+
+     Select CWOP WX Stations
+      This option includes the display of citizen weather (non-ham) weather
+      data.
+
+  Select Objects/Items
+    Global toggle for displaying objects/items, but may be narrowed:
+
+    Select WX Objects/Items
+     This option displays weather Objects and Items. This includes tropical
+     storms and remote weather stations.
+
+    Select Water Gauge Objects/Items
+     This option toggles the display of water gauge (/w) objects.
+
+    Select Other Objects/Items
+     This option enables or disables the display of objects other than those
+     listed above.
+
+
+Filter Display
+This sub-menu allows filtering of the displayed data:
+
+  Display Callsign
+  Determines if the callsign is displayed.
+
+    Label Trailpoints
+    This option includes callsigns along trails, to help identify which
+    points belong to which stations.
+
+  Display Symbol
+  Determines if the symbol is shown to the left of the callsign.
+
+    Rotate Symbol
+    Some symbols will change their orientation to show the direction in which
+    they are traveling.
+
+  Display Trail
+  When enabled, any moving station will trail a colored line.  We now display
+  as many locations as we have in our database (old limit was 100).  Long
+  trail segments (over 2 degrees latitude or 2 degrees long), or segments with
+  more than 45 minutes receive delay between the points will not be displayed.
+  Duplicate points are also eliminated from the track (SAR team returning to
+  base:  Last segment may not be displayed due to the starting point appearing
+  twice in the trail list).
+
+  Display Course
+  When enabled, green text will appear below the call sign. This will display
+  the last known course (in degrees) the station was traveling.
+
+  Display Speed
+  When on, red text will appear below the call sign (or course). This will
+  display the last known speed of the station. 
+
+    Display Short Speed
+    This option removes display of the measurement units for speed.
+
+  Display Altitude
+  When enabled, blue text will appear above the call sign. This will display
+  the last known altitude of the station.
+
+
+  Display Weather Info
+  Global toggle for displaying weather information, but may be narrowed:
+
+    Display Weather Text
+    When enabled, the latest weather data (temp,wind speed/course/gust,
+    humidity) is displayed. This may be adjusted with the following option:
+
+      Display Temperature Only
+      Displays only the temperature data for the station.
+
+    Display Wind Barb
+    When enabled, a wind barb showing the direction and speed of the wind is
+    drawn for all displayed stations reporting this information. 
+
+
+  Display Position Ambiguity
+  When enabled, the area in which station using position ambiguity may be
+  located within is shaded, with the relevant station in the center.
+
+  Display Power/Gain
+  When on, Power/Gain Circles will be displayed. Overlapping circles indicate
+  that the stations are theoretically within simplex range of one another.
+  This is only roughly accurate, especially in areas of variable terrain. 
+
+    Use Default Power/Gain
+    Enables a default power/gain setting as specified in the APRS(tm)
+    specification.
+
+    Display Mobile Power/Gain
+    Enables power/gain circles for mobile stations.
+
+
+  Display DF Attributes
+  When enabled, any DF circles/lines will be displayed on the screen.
+
+  Enable Dead-Reckoning
+  When enabled, the positions of stations are estimated based on past course
+  and speed. The recalculation rate should be reasonable, but can be adjusted
+  in the configuration file.
+
+    Display Arc
+    Displays an expanding arc of expected maximum travel distance, location and
+    course given the past course and speed. The arc slowly becomes a circle as
+    the position report gets older.
+
+    Display Course
+    Displays an expected course and distance traveled by the station, assuming
+    the course hasn't changed.
+ 
+    Display Symbols
+    Displays a ghosted version of the stations symbol at the expected position,
+    assuming the station has continued at its current course and speed.
+
+
+  Display Dist/Bearing
+  When enabled, two lines of text will be displayed on the left side of the
+  stations' icon. The top line will contain the distance from your station to
+  this station. The bottom line will contain the course from your station to
+  this station.
+
+  Display Last Report Age
+  Display the time since the station was last heard.
+
+Reload Object/Item History
+This will reload the ~/.xastir/config/objects.log file used for Object and Item
+persistence. This is needed if you edit the file while Xastir is running.
+
+Clear Object/Item History
+This will clear the ~/.xastir/config/objects.log file used for Object and Item
+persistence. It is recommended that you manually select and delete all Objects
+and Items that you own before doing this, otherwise they may remain on the
+screens of other APRS(tm) users.
+
+Clear All Tactical Calls
+Clears all assigned tactical calls. This will take effect the next
+redraw. Note that this will NOT clear tactical calls on other
+peoples' screens if you've published them via a message to
+"TACTICAL" (see the help text for "Send Message").
+
+Clear Tactical Call History
+This removes the tactical call history file, meaning that tactical calls
+assigned will not remain permanent between Xastir restarts.  Note
+that this will NOT clear tactical calls on other peoples' screens if
+you've published them via a message to "TACTICAL" (see the help text
+for "Send Message".
+
+Clear All Trails
+This will wipe all the line tracking data from the station database and
+refresh the screen.  This option is perhaps useful if you're low on memory
+or just want an uncluttered screen.  You may also clear individual stations'
+trails from the Station Info dialog.
+
+Clear All Stations
+This will wipe all the data from the station database except yours.  This
+option is perhaps useful if you're low on memory or just want to unclutter
+your screen.
+
+HELP-INDEX>Messages and the Messages menu
+
+                  Messages and the Messages menu
+
+Send Message to and Open group messages
+
+These are very similar. "Send message to" will send your messages to one
+station and will only receive data from that station. Group messages are more
+general: you can receive any message for the group and you will send out your
+messages to that group name. Group messages code is not fully implemented yet
+and various problems still need to be worked out.  The "groups" file is looked
+for in ~/.xastir/config.  This is where the groups you are a member of are
+stored.  As was said before the "groups" functionality may not be complete yet.
+
+At some point in the near future sending of bulletins should be added to this
+menu as well.  It's not coded yet.
+
+Each of these two screens contains a message box, a call line, a message line,
+and various buttons. You must first enter the call of the group or station you
+want to contact. Once that is done any new message that has come in from that
+station to you will be displayed. If the station is sending you information
+and no message window is up it will automatically pop up a new window (up to
+10) with that station's call sign filled in for you. You can now enter a
+message on the message line. The message can be longer that the message line,
+and will max out at about 250+ characters. Once your message is entered,
+clicking on the "Send Now!" button will send your message. The "Send Now!"
+button will gray out until your message is completely ack'ed. Any message you
+receive will be sorted by the line # and be placed in the message window. If
+you are in a group mode each line will display the call sign from where the
+message was sent followed by the message itself. Currently group messages are
+sorted by call and then line #. When you are done sending messages clicking on
+the exit button will close the window. Other buttons are also available:  The
+"New Call" button will allow you to look at old data a station has sent.  Type
+in the call and click on this button, any old information will be displayed.
+You can also use this button to change the call of the station you're talking
+with. Enter the new call and click the button. The "Clear Msg History" button
+will clear any message displayed in the message window.  "Cancel Pending Msgs"
+will cancel any messages in the transmit queue that haven't been acknowledged
+by the remote station yet.  After canceling the pending messages or receiving
+and acknowledgment packet from the remote station, you may send new messages to
+the remote station.  Xastir will allow you to type ahead, so you can just keep
+typing if you don't want to wait for the acknowledgments.
+
+Messages in reply to previous ones will attempt to use the path of the
+received message to avoid flooding the system with broadcast messages. You
+may adjust the path in the send message dialog, or the default path(s) set
+in the interface control will be used if you leave this blank.  The path
+can be set for each message sent, but once a message is sent the path
+remains fixed for that particular message.
+
+Each outgoing message remains highlighted until it is ack'ed by the remote
+station.  If it times out or if you cancel the pending messages, those
+messages will remain highlighted unless you clear the message history.
+
+To publish TACTICAL calls to other Xastir and APRS+SA stations as
+well as assign those tactical calls locally: Send a message to
+"TACTICAL" with the body of the message containing lines something
+like:
+  
+  callsign-1=TAC1;callsign-2=TAC2;callsign-3=TAC3
+
+To remove these tactical calls later from local AND remote screens,
+assure that the original message(s) assigning them has timed-out or
+been cancelled, then send a message like this and let it retry until
+it times out (assigns blank tactical calls to the original
+callsigns, thereby removing the assignment):
+
+    callsign-1=;callsign-2=;callsign-3=
+
+Clear all outgoing messages
+This will clear all un-ack'ed messages you have sent.
+
+General Stations Query
+This sends an ?APRS? packet, which should cause all local stations to report
+their position and/or status. Most software ignores this query, because
+responding to it would cause massive floods of data.
+
+IGate Stations Query
+This sends an ?IGATE? packet, which should cause all local IGates to respond
+with their capabilities.
+
+WX Stations Query
+This sends an ?WX? packet, which should cause all local weather stations to
+report their position and weather.
+
+Modify Auto reply message
+This will set the message that is sent as an Auto Reply.
+
+Enable Auto Reply Msg
+This will turn on an automatic reply when an incoming message is received.
+
+Satellite Ack Mode
+This mode disables the sending of ack messages in response to received
+messages. Messages are still acknowledged using the reply-ack system. When
+operating over a satellite it is clear that your message made it, because you
+will hear it repeated. The receiving station sending an independent ack only
+adds QRM.
+ 
+HELP-INDEX>Interfaces Menu
+
+                         Interfaces menu
+
+This menu contains interface related options.
+
+Interface Control
+This option displays a window where you can turn on and off your configured
+interfaces, as well as add, delete, or configure interfaces. See the "Configure
+Interfaces" help topic.
+
+Disable Transmit options
+These options disable the transmission of everything, one's position, or one's
+objects. These are global options and affect all interfaces. Most interfaces
+have an option to disable transmission on that specific interface in their
+configuration menus as well.
+
+Enable Server Port
+This enables/disables TCP and UDP listening sockets at port 2023.  You may
+connect other APRS(tm) clients to the TCP port in order to send/receive
+APRS(tm) data.  Once they authenticate, they'll be able to send data to Xastir.
+Without authentication, they'll be able to receive every bit of TNC and INET
+data that Xastir receives.  Note that ANY user with the proper credentials can
+come in on the TCP or UDP ports if they are enabled.  The only one of these two
+ports currently that can send to RF is the UDP Server port.  The TCP
+port cannot.
+
+    "user WE7U-13 pass XXXX vers XASTIR 1.3.3"
+
+Connect another APRS(tm) client to that port and it should authenticate and be
+able to send to any server that Xastir is connected to, as well as receive
+packets from all ports/servers Xastir is hooked to.
+
+You should also have a binary called "xastir_udp_client" which can send packets
+into the UDP listening port.  Invoke it like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> "APRS Packet Goes Here"
+
+Currently that will inject the packet into Xastir's decoding routines and send
+it to any TCP-connected clients. It will also igate it to the INET if you have
+igating enabled.  It will send the packet out the RF ports as third-party
+packets only if you add the "-to_rf" flag after the passcode like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> -to_rf "APRS Packet"
+
+The UDP client is useful for generating and injecting APRS packets from
+external scripts.  It can also be used to fetch the callsign of the remote
+xastir server by using the -identify flag:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> -identify
+
+Transmit now
+Causes all interfaces that have transmit enabled (see configure|interfaces) to
+transmit a position packet.  It will be grayed out if Disable Transmit: ALL
+is selected.
+
+If you have GPSMan installed, you have these additional menu options
+displayed:
+
+Fetch GPS Track
+Download a set of trackpoints from an attached GPS.
+
+Fetch GPS Routes
+Download a set of routes from an attached GPS.
+
+Fetch GPS Waypoints
+Download a set of waypoints from an attached GPS.
+
+Fetch Garmin RINO Waypoints
+Snag waypoints from an attached Garmin RINO, create APRS(tm) Objects out of any
+waypoints which begin with "APRS".
+
+HELP-INDEX>Station info box - FCC and RAC lookup
+
+                  Station info box - FCC and RAC lookup
+
+Station Info will display any data decoded by Xastir.
+
+You can assign (local only) tactical calls to stations from here, by
+clicking the "Assign Tactical Call" button. This will cause the
+station on screen to display as the tactical call instead of its
+callsign. Assigning a blank tactical call clears this feature, and
+it can also be cleared for all stations in the Stations menu.  This
+feature assigns tactical calls to the local Xastir station only, but
+see below to publish them to others.
+
+To publish tactical calls across the air to other Xastir and APRS+SA
+stations (as well as assign them locally), see the "Send Message" help
+section.
+
+"Enable Automatic Updates" will cause the window to refresh frequently with the
+latest information.
+
+The information available may include: Number of packets heard, the time
+last heard, the device the packet came from, station comments, 
+power/height/gain of the station, course/distance from your station,
+weather information, and current and previous positions.
+
+For moving stations a track-log follows with the most recent entries on top.
+A '+' in front indicates that a new track starts at that point (if there was
+a large gap in time or position). A star at the end of a line indicates that
+this station could be heard direct (without a digi) at that specific position.
+Positions are followed by the 6 digit Maidenhead grid square the station was
+located in at that point.
+
+For your own station, there is an "Echoed from" field, listing the
+last six digipeaters that heard you directly. This is useful for setting
+non-generic paths.
+
+Currently two rows of four buttons appear in the Station Info window.  Some
+of the labels on the buttons change based on the type of station that you're
+dealing with.
+
+For objects/items:
+
+Store     Modify    Blank      Close
+Track     Object/
+          Item
+
+Station   Trace     Un-Acked   Direct
+Version   Query     Messages   Stations
+Query               Query      Query
+
+For other stations:
+
+Store     Send      Search     Close
+Track     Message   FCC (RAC)
+                    Database
+
+Station   Trace     Un-Acked   Direct
+Version   Query     Messages   Stations
+Query               Query      Query
+
+"Station Version Query" changes to "Clear Track" for mobile stations.
+The Clear Track button will clear any line tracking for this station that is
+currently stored or on the map display.
+
+"Store Track" will save the track of the station to a file on disk. The 
+format is similar to that used by GPS receivers but its specification
+might be changed (enhanced) in future versions. There is currently no
+way to read that track data back in, but it is planned for the future.
+The goal is to also read and display GPS track-logs in a similar manner.
+These track-log files will be placed in the directory ~/.xastir/tracklogs
+with a name equal to the stations call with ".trk" as extension.  "Store 
+Track" will simultaneously save the station's track as a Keyhole Markup
+Language (.kml) file with a filename equal to the station's call, the
+current date and time and .kml as extension.  If shapefile support has
+been included, the station's track will also be saved as a set of four 
+files (.dbf,.prj,.shp,.shx).  Subsequent presses of Store Track for the
+same station will write additional lines into the .trk file, and create
+new .kml (and shapefile) files (each containing all positions in the 
+station's track.  
+
+"Modify Object/Item" will bring up the Object Modify window.
+
+"Send message" will open up the message window and allow you to send a message
+to this station. It will fill in the call sign for you.
+
+If the FCC (U.S. Federal Communications Commission) or RAC (Radio Amateurs of
+Canada) database is installed and the callsign appears to be a Canadian or
+U.S. callsign, the "Search FCC/RAC Database" button will become active,
+otherwise this button will be inactive.  The FCC and RAC files should be
+placed in the /usr/local/share/xastir/fcc directory, and case is important!
+Pressing this button adds the station's name and address into the Station
+Info box.  Instructions for installing these databases are in the README.MAPS
+file.
+
+Xastir will create index files for each database file upon startup. If a newer
+callsign file is placed there while Xastir is running, it will create or
+rebuild the index on the next lookup.  Special prefixes are NOT handled.
+
+HELP-INDEX>Creating a log
+                              Creating a log
+
+Xastir can log data from the internet or TNC for later playback, or for
+debugging purposes.  WARNING: Logging can fill up your hard drive, so be
+careful using it, or make preparations for rolling over the log files
+automatically via cron. An indication will be shown on the status bar when
+logging is enabled.
+
+All these choices are accessible via the File menu:
+
+Enable TNC Logging
+Logs all TNC data received and transmitted. These logs can be played back using
+the "Open Log File" feature.
+
+Enable Net logging
+Logs all internet data received and transmitted. These logs can be played back
+using the "Open Log File" feature.  If you have no interfaces started but still
+want to log your posits and objects locally, this is the option to enable for
+that as well.
+
+Enable IGate logging
+Logs all data forwarded in both directions, and rejected forwards with reasons
+for rejection. Includes NWS messages forwarded to RF.
+
+Enable WX logging
+Logs all weather data received from your weather station.
+
+
+HELP-INDEX>Replaying a log
+
+                              Replaying a log
+
+Click on "File", then "Open Log File" and a file selector window will display.
+You can use it to browse your hard drive and select any file containing raw
+TNC data like those created by the TNC and Net logging options. Your station
+will still function the same way, receiving and transmitting. If you were
+logging data, the typical place to look for those files would be 
+~/.xastir/logs/
+
+NOTE: This function doesn't read the saved station tracklogs.
+
+HELP-INDEX>Locating a Station
+
+                             Locating a Station
+
+Click on "Stations", then "Find Station". A window will pop up. You can now
+enter a call or part of a call. By default it will search for an exact match
+(full call, not partial) and is not case sensitive. If you are looking for a
+partial match, "Match Exact" should not be selected.
+
+For objects which could contain lower case letters you have to check
+"Match Case"! Opposite to the name, without "Match Case" the search
+text will only be converted to upper case...
+
+Clicking on the "Locate Now!" button will center the first station
+found in the center of your screen at the current zoom level.
+
+Clicking "FCC/RAC Lookup" will look up the user's information if the FCC or RAC
+database, of those databases are installed.
+
+Clicking on "Cancel" will close the window.
+
+This dialog will pop up if a station sends a Mic-e "Emergency!" packet, to
+encourage users to locate and perhaps help the listed station.
+
+HELP-INDEX>Creating and using Map Display Bookmarks
+
+                  Creating and using Map Display Bookmarks
+
+Click on "Maps", then "Map Display Bookmarks" and a window will pop up.
+If this is the first time you have used this then the box will have no
+entries in it. To add a bookmark to the list: Position the main map to
+the area and zoom level you want to use. Enter a unique name in the
+"New Name" area, then click on add. Your entry will be added to the
+list (in alphabetical order).  You can add as many map display bookmarks
+as you want. To use one of the bookmarks mark its name and click
+"Activate!". The main map will then show the stored area and zoom level.
+You can similarly delete a bookmark by clicking on the bookmark name and
+then the "Delete" button.
+
+"Maps->Locate Map Feature" is another method to jump to a location, if
+the name of the location is known and you have GNIS files installed.
+
+HELP-INDEX>Tracking a Station
+
+                        Tracking a Station
+
+Click on "Stations", then "Track Station". Enter the callsign to track (all or
+part) then click on the "Track Now!" button. As the station moves it will
+remain viewable in the main map window. As the stations starts to get close
+to the edge of the map window the window will re-center so that the object is
+always visible. To stop tracking this station click on the "Clear Tracking"
+button. While tracking is active, a "Tr" is shown in the status bar next to
+the zoom level.  If the station is not on the map yet, tracking will begin
+as soon as it shows up.
+
+HELP-INDEX>Printing
+
+                       Printing the Map Screen
+
+Note: Printing has not been set up on Windows/Cygwin.  These instructions
+are for Unix and Unix-like operating systems.
+
+Xastir can print the drawing area in either black & white or color.  It does
+this by first dumping the image to an XPixmap file on disk, then using external
+tools to convert it to postscript, scale it, rotate it, preview it, then print
+it.  You must have your system printing set up to handle postscript (usually
+this requires Ghostscript and a print filter installed, as well as lp or lpr
+print spoolers).  You must also have the following tools installed for this
+capability:  ImageMagick tools (specifically "convert"), "Ghostscript",
+Ghostscript fonts, and "gv".  Once all of these packages are installed and
+functional, you should get a "gv" window popping up shortly after you tell
+Xastir to create a print file.  From there  you can view the printed image, and
+if acceptable, tell "gv" to print it.  Note that sometimes changing to a white
+default background for the maps is recommended, depending on what maps you have
+viewable.  This can save greatly on ink.
+
+HELP-INDEX>Creating Snapshots
+
+                     Creating Automatic Snapshots
+
+Xastir has the capability to create automatic snapshots of the map screen
+on a recurring basis.  The default time period is set at once per five
+minutes.  Assuming that you have "convert" from the ImageMagick tools
+installed, Xastir will create an XPM format file in ~/.xastir/tmp/, then
+convert it to the PNG file ~/.xastir/tmp/snapshot.png. This file is useful for
+embedding in web pages to show a "live" image of what is on your Xastir
+screen.  Enable this feature via the "File->PNG Snapshots" toggle-button. 
+The rate is once every five minutes (configurable from the Configure 
+Timing dialog from "File->Configure->Timing"), or every time the button is 
+toggled from off to on. A .geo is created to allow you to use the snapshot 
+as a map.  A .kml file is also written to allow you to use the snapshot as
+a graphic overlay on terrain in applications capable of reading kml.  See
+kml_snapshot_to_web.sh and kml_snapshot_feed.kml in the scripts directory 
+for more information on using the snapshot.png and snapshot.kml file to
+produce a kml feed using the snapshots.
+
+                    Creating Automatic KML Snapshots
+
+Xastir is capable of writing all current stations and tracks to a kml file
+on a recurring basis.  Enable this feature via the "File->KML Snapshots" 
+toggle button.  The rate at which these snapshots are generated is the same
+as that of PNG snapshots, configured from "File->Configure->Timing" by 
+setting the snapshot time interval.  Each snapshot is written to a .kml
+file in ~/.xastir/tracklogs, with a filename based on the date and time
+of the snapshot, e.g. 20080206-000720.kml  This behavior may change to 
+make KML snapshots write to a single file like PNG snapshots.
+                    
+
+HELP-INDEX>Included Scripts
+
+                        Included Scripts
+
+Xastir includes several Perl scripts and a shell script that may be useful:
+
+get-fcc-rac.pl
+This shell script automates retrieving and installing the FCC and the RAC
+callsign databases. Note that these databases are very large!
+
+icontable.pl
+This script generates an xpm bitmap of all Xastir's primary and secondary
+symbols from the symbols.dat file. The overlays and specials are ignored.
+Output is to STDOUT, so a typical call would be "icontable.pl > symbols.xpm".
+
+inf2geo.pl
+This script creates .geo files from UI-View .inf files. To create a map.geo
+from a map.inf, typical usage would be "inf2geo.pl map".
+
+kiss-off.pl
+This script sends the commands needed to turn off a TNC's KISS mode.
+
+mapblast2geo.pl
+This script creates .geo files for Mapblast pixel maps. It includes usage
+information.
+
+mapfgd.pl
+This script creates minimal .fgd files for GeoTIFF images lacking them, based
+on information found in the GeoTIFF file. The created files allow Xastir to
+crop the white borders and rotate/scale the map properly. Typical usage would
+be "mapfgd.pl mapdir" where mapdir is the directory containing the GeoTIFF
+images.
+
+overlay.pl
+This script creates .log format files from comma-separated overlay files. See
+the script comments for full usage information. 
+
+ozi2geo.pl
+This script creates .geo files from OziExplorer .map files.
+
+permutations.pl
+This script converts between different lat/lon formats. See the script comments
+for further details.
+
+split_gnis.bash
+This will take a GNIS data-point file (typically for a whole state, 8+MB), break
+it down into smaller chunks (typically for a county, 30-200k) it will also
+throw away the trailing spaces and <CR>s at EOL.
+
+split_gnis.pl
+This is a Perl version of the above script.
+
+test_coord.pl
+Tests for the Coordinate.pm Perl module.
+
+track-get.pl
+This script downloads the track-log of a specified object from a Garmin GPS.
+It requires the GPS::Garmin module. It prompts for an object name, and writes
+the track-log to the ~/.xastir/logs directory.
+
+update_langfile.pl
+This script is targeted toward developers. It rebuilds a specified language
+file to contain all the strings of another. It is usually used to regenerate
+the non-English language files when significant changes have been made to the
+English file. When the second language file lacks a string in the main file,
+the untranslated string is inserted. Typical usage would be 
+"update_langfile.pl language-German.sys" . The main language file is
+hard-coded but easily editable.
+
+waypoint-get.pl
+This similar script downloads the waypoints from a Garmin GPS, and creates a
+log in the ~/.xastir/logs directory containing the waypoints as objects. It
+also requires the GPS::Garmin module.
+
+db_gis_mysql.sql  db_gis_postgis.sql
+These will create tables for storing station data in a mysql or postgresql/
+postgis database.  SQL Server database support is experimental.  See the
+"OPTIONAL: Experimental.  Add GIS database support" section in INSTALL
+
+HELP-INDEX>Configuring Interfaces
+
+                           Configuring Interfaces
+
+Click on Interfaces, then Interface Control.
+
+An "Installed Interfaces" box should appear. This box will allow you to add,
+delete, and modify the properties of various devices you may want to use with
+Xastir.
+
+Supported interface types are:
+Serial TNC
+Serial TNC w/GPS on HSP cable
+Serial GPS
+Serial WX
+Internet Server
+AX.25 TNC
+Networked GPS (via gpsd)
+Networked WX
+Serial TNC w/GPS on AUX port
+Serial KISS TNC
+Networked Database (Not Implemented Yet)
+Networked AGWPE
+Serial Multi-Port KISS TNC
+SQL Databases [MySQL,Postgis] (Experimental)
+
+To add a device, click on the add button. A "Choose Interface Type" box will
+appear. Click on the type of device you would like to add. Then click the Add
+button in the "Choose Interface Type" box. Properties for that device will
+appear. Fill out the requested information and click OK.
+
+To delete the device, click on the device you wish to delete and then click
+the delete button.
+
+To modify the properties of a device, click on the device you wish to modify,
+then click the properties button. The properties for that device will appear.
+Change the information you want and click OK.
+
+More specific help is available under the help topics of each interface type.
+
+SQL Databases will only appear as an option if you have MySQL or Postgis 
+support compiled.  
+
+HELP-INDEX>Configure Serial TNC Devices 
+
+                          Configure Serial TNC Devices 
+
+This section covers adding or modifying Serial TNCs or Serial TNCs with a
+GPS on a HSP cable.
+
+If you have a HSP cable, which allows you to share the TNC port with a GPS
+unit you may choose a TNC with GPS (HSP Cable). This is a special cable and may
+not work on all computers/GPS/TNC combinations. If you use this device the TNC
+and the GPS should be set to the same communications parameters. Generally
+4800 bps, 8 data bits, no parity, and 1 stop bit.
+
+TNC Port Options:
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+The TNC Port is the Unix device that the TNC (or TNC and GPS) is hooked to.
+Normally you can use /dev/ttyS0 (com1), /dev/ttyS1 (com2) etc.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your TNC
+and GPS.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices, and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. XASTIR will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1, WIDE2-2 may work better. Or if you know the call of your closest digi you
+may use XXXCALL, WIDE2-2. Most of you will only need one path. If you are in a
+remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths are
+entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+TNC Startup and Shutdown files. These fields specify a filename that is
+located in the /usr/local/share/xastir/config directory. Each file is a
+standard text file containing any commands you would like to send your TNC at
+the time the device is activated (startup file) or shut down.
+
+HELP-INDEX>Configure Serial TNC w/GPS on HSP cable or AUX port
+
+                Configure Serial TNC w/GPS on HSP cable or AUX port
+
+These hybrid interface types implement the options of both serial TNCs and
+GPSs. Please consult the configuration help for both serial TNCs and serial
+Gpsd for further information on the configuration of these devices.
+
+"Send Control-E to get GPS Data?"
+
+This checkbox controls whether Xastir sends a Control-E to the TNC every time
+it needs GPS data.
+
+Some TNCs that support a GPS on an auxilliary port require that Xastir
+send a Control-E to the TNC in order to get the GPS data each time it
+is needed.  Devices in this class include the Kantronics KPC-3+.
+
+Some devices, like Kenwood APRS radios (D700, etc.) do NOT require
+this, and in fact the Control-E interferes with correct operation of
+these devices.
+
+Because Control-E was required by the most common TNCs that had an aux
+port for GPS at the time that this interface type was written, this is
+the default behavior of Xastir.  If you have a Kenwood radio that you are 
+using in this mode, you must DESELECT the "Send Control-E to get GPS data?"
+checkbox in the configuration dialog for this interface type.  
+
+HELP-INDEX>Configure Serial KISS TNC
+
+                     Configure Serial KISS TNC
+
+This section covers adding or modifying Serial KISS TNCs. KISS mode can be done
+by most standard TNCs too, and it eliminates the necessity to set the options
+specially in the startup files, at the expense of slightly higher processor
+usage. And of course this enables the use of purely KISS TNCs, such as the one
+described in the November 2000 issue of QST, without a separate program or
+kernel module.
+
+Options
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+Selecting "RELAY Digipeat?" will tell Xastir to digipeat traffic.  It will do
+this if the first unused digipeater call in the path matches your callsign or a
+callsign listed in your Xastir config file ("RELAY_DIGIPEAT_CALLS" line,
+default is "WIDE1-1"). This option is only recommended for base stations in
+regions where there are few other fill-in digipeaters in the area. Consult with
+a local group about the best setting for your region. You may hand-edit the
+Xastir config file when Xastir is not running in order to change this string to
+match your local recommendations. In the U.S., "WIDE1-1" is the recommended
+setting.
+
+The TNC Port is the Unix serial device that the TNC is hooked to.
+Normally you can use /dev/ttyS0 (com1), /dev/ttyS1 (com2) etc.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Now set the bps rate under port settings.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices, and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. Xastir will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just a WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1,WIDE2-2 may work better. Or if you know the call of your closest digi
+you may use XXXCALL,WIDE2-2. Most of you will only need one path. If you are in
+a remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths
+are entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+Next configure the KISS parameters: TXdelay is the time (in 10ms units) needed
+between the keying of the radio and when it is ready to send data. Persistence
+and slottime are the channel access parameters: Slottime is how often the
+channel access algorithm is executed, and should usually be set to 10.
+Persistence is how aggressively your station tries to grab the channel when
+free, and should be ideally set to 255 divided by the number of stations on the
+channel. Full duplex allows the transmission to begin while there are packets
+being received on the channel, this should be disabled in most cases (set to
+"0").
+
+HELP-INDEX>Configure AX.25 TNC Devices
+
+                        Configure AX.25 TNC Devices
+
+This section covers adding or modifying AX.25 TNC devices. AX.25 devices can
+be any device that uses the Linux AX.25 drivers. This is a kernel level
+driver, and device such as a Baycom or a sound modem can be used as a TNC.
+These devices must be set up and running before Xastir can use them.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing RF data can
+be sent to this device for broadcast.
+
+Selecting "RELAY Digipeat?" will tell Xastir to digipeat traffic. It will do
+this if the first unused digipeater call in the path matches your callsign or a
+callsign listed in your Xastir config file ("RELAY_DIGIPEAT_CALLS" line,
+default is "WIDE1-1"). This option is only recommended for base stations in
+regions where there are few other fill-in digipeater stations in the area.
+Consult with a local group about the best setting for your region.  This is
+only needed if you are not using any other software that performs this
+function, such as aprsdigi or DIGI_NED. You may hand-edit the Xastir config
+file when Xastir is not running in order to change this string to match your
+local recommendations. In the U.S., "WIDE1-1" is the recommended setting.
+
+Enter the AX.25 Device name you specified in the axports file for this device.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Choose the correct IGate operation for this device. You may have several TNC
+devices and this option can be different for each device. If you are not
+running an IGate leave it at the default option of "Disable".
+
+Enter in up to three UNPROTO paths. Xastir will assume the XX VIA part of the
+UNPROTO path. There are three paths allowed so that your signal will be heard
+if conditions are bad. Xastir will cycle through each one that is filled in,
+one per transmission time.  If you are local to a digi, just a WIDE2-2 may be a
+good choice. If you are using low power and/or are distant from a digi then
+WIDE1-1,WIDE2-2 may work better. Or if you know the call of your closest digi
+you may use XXXCALL,WIDE2-2. Most of you will only need one path. If you are in
+a remote area and your signal is difficult to get out you may need more. Check
+with a local group and ask what path may be best for your area.  If no paths
+are entered it will default to WIDE2-2.
+
+If you are IGating to RF, you may enter a specific path to use for the packets
+you send to RF. If you leave this blank, the UNPROTO paths above will be used.
+If the UNPROTO paths are blank, WIDE2-2 will be used.
+
+NOTE: To use AX.25 devices with Xastir you will need to run the program as
+"root". If you want to run Xastir as another user you may want to set the
+suid bit on the Xastir program file. Please see INSTALL file for more
+information; current Xastir drops the extra privileges but has not been audited
+for exploits. Use in this fashion in a multi-user environment at your own risk!
+
+HELP-INDEX>Configure Serial GPS Devices
+
+                       Configure Serial GPS Devices
+
+Set the serial port device for your GPS unit. Common values of /dev/ttyS0
+(COM1) or /dev/ttyS1 (COM2) can be used.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Set system clock from GPS data" will tell Xastir to try setting the
+system's clock to the highly accurate time signal from the GPS receiver. This
+requires root privileges on most systems.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your GPS.
+Most GPS units will use 4800 bps and 8,n,1.
+
+HELP-INDEX>Configure Networked GPS Devices
+
+                    Configure Networked GPS Devices
+
+If you need to share the GPS data with different programs or machines, this
+option is best. Xastir will work with gpsd which will allow several
+connections to share your GPS data.
+
+Set the host name (or IP address) and the port number for the gpsd host on
+your network.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+Selecting "Set system clock from GPS data" will tell Xastir to try setting the
+system's clock to the highly accurate time signal from the GPS receiver. This
+requires root privileges on most systems.
+
+HELP-INDEX>Configure the Internet Server
+
+                         Configure the Internet Server
+
+Internet Servers allow you to send and receive data for all over the world.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+setup communications with it when the program first starts.
+
+Selecting "Allow Transmitting" will tell Xastir that any outgoing Internet
+data can be sent to this device.
+
+Enter the host name (or IP address) and the port number of the Internet
+Server you want to contact. 
+
+Enter a valid pass-code to validate your connection, this will allow your
+data to be transmitted via an IGate. If you don't have a pass-code, use the 
+included "callpass" program to generate one. Note that passcodes are dependent
+on callsigns.  From the src directory, "make callpass" should create the
+executable if it isn't already compiled.
+
+Enter any filter parameters. This causes a special message to be sent to the
+server requesting that the data be filtered in a certain way. The exact format
+of this field is fully specified, please consult APRSSIG for more information.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+HELP-INDEX>Configure a Serial WX Station
+
+                     Configure a Serial WX Station
+
+Set the serial port device for your WX unit. Common values of /dev/ttyS0
+(COM1) or /dev/ttyS1 (COM2) can be used.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Now set the bps rate under port settings, and the parameters under port
+style. Port Style setting 8N1 is used for 8 data bits, No parity and 1 stop
+bit. 7E1 is used for 7 data bits, even parity and 1 stop bit. 7O1 is used for
+7 data bits, odd parity, and 1 stop bit. These parameters must match your WX
+unit. The Data Type option will allow you to override what type of serial data
+the program will look for. The auto-detect feature will first look for Weather
+data in a binary type as the Radio Shack WX-200 uses. If no binary data is
+found in the stream, Xastir will look for an ASCII type of WX station (like
+Peet Bros.).
+
+Now set the Rain Gauge correction factor. Xastir requires that the rain gauge
+report in .01 inch increments. If the unit reports in .1 inch or .1 millimeter
+increments, a correction must be specified to obtain accurate measurements.
+
+HELP-INDEX>Configure a Networked WX Station
+
+                   Configure a Networked WX Station
+
+Xastir can use WX data servers such as wx200d. wx200d will allow several
+network connections, thus sharing the Weather data with several programs or
+computers.
+
+Enter the host name (or IP address) and the port number of the WX data server
+you want to contact.
+
+Comment will allow you to set a friendly name or comment for the port.
+
+Selecting "Activate on start up" will tell Xastir to look for this device and
+set up communications with it when the program first starts.
+
+Selecting "Reconnect on failure" will tell Xastir to try to reconnect when the
+data stream has failed.
+
+As before the Data Type will override the auto detection.
+
+Now set the Rain Gauge correction factor. Xastir requires that the rain gauge
+report in .01 inch increments. If the unit reports in .1 inch or .1 millimeter
+increments, a correction must be specified to obtain accurate measurements.
+
+HELP-INDEX>Configure an AGWPE Connection
+
+                   Configure an AGWPE Connection
+
+Xastir can use an AGWPE network interface running on a Windows box
+as a TNC interface. It can also use the login/password security that
+AGWPE has built-in, but you must set up the account in the AGWPE
+application with your callsign for the username, in all capital
+letters.  For instance: "AB7CD".
+
+The other options are described in the sections for Serial TNC and for
+Network interfaces.
+
+HELP-INDEX>Configure a SQL Database Connection
+
+                Configure a SQL Database Connection
+                         [Experimental]
+
+Xastir can experimentally store and retrieve station data from either
+a MySQL database or a Postgresql + Postgis database.  See the 
+"OPTIONAL: Experimental.  Add GIS database support." section in the
+INSTALL file for more information.  Station and object data are stored
+as spatial data, and can be retrieved from other GIS applications, for example
+Xastir can write station locations into a Postgis database from which they
+can also be viewed using QGIS.  SQL database connections also allow for the
+persistence of data between Xastir sessions.  All aspects of spatial database
+support, including database structures, are currently experimental and may 
+change at any time.  You may configure multiple SQL database connections, 
+but you should only have one active at a time.  
+
+Before creating a database connection in Xastir, you will need to create a 
+database to connect to, create an appropriate set of tables 
+(see the db_gis_xxxxx.sql scripts in the scripts directory), and add a user 
+with a password and rights to access the database.  For postgis databases
+you may also need to appropriately configure the user in pg_hba.conf
+
+Configuration options on the SQL database dialog include:
+Database: MySQL (lat/long) for very old MySQL databases, 
+          Postgis for postgresql + postgis, and 
+          MySQL (Spatial) for current MySQL databases.
+With tables for: Currently only the Xastir simple schema - a very basic
+          flat table holding minimal information about stations.
+Host: IP address or hostname for the database server, default is localhost.
+Port: Default is 3306 for MySQL and 5432 for Postgresql.  The database can
+          be on a remote server, but the appropriate port will need to be
+          open in any firewalls.  
+Username: Can be unique to your database, e.g. xastir_user
+Password: Unique to your database.  
+Schema name: Your database name. e.g. xastir
+MySQL Socket: check my.cnf, or mysql --help | grep socket
+          Leave blank for postgis databases.
+Reconnect on Net Failure: [Not yet implemented]
+MySQL defaults and Postgis defaults provided by the buttons may
+or may not be correct for your database.  
+
+Three options control the behavior of the SQL Database interface:
+Activate on Startup:  Try to connect to this database and begin storing heard 
+station data as soon as Xastir starts (if store incoming data is also selected).
+
+Store incoming data: Stores each station (including objects and items) report
+as a record in the database.  All stations heard on all interfaces will be 
+stored to the database - if you are connected to internet feeds and leave 
+xastir running this can easily be a million records per day.
+
+Load data on startup: Retrieve all station data from the database
+when restaring Xastir.  Currently the only way to retrieve persistent 
+data from a database.  Will attempt to connect to database and retrieve data 
+independent of the settings of either activate on startup or store incoming
+data.  Due to rounding and conversion errors, non-mobile stations may move 
+slightly.  
+
+The "Most Recent Error" box may or may not contain an error message to help
+identify connection problems.  When Xastir fails to connect to a database, 
+the interface will show ERROR on the interface list, and the most recent error 
+may be shown here.   Running xastir from the console and observing error 
+messages there, or running xastir from the console with xastir -v1 may help
+identify the cause of connection problems, as may examination of the 
+database's error logs.  
+
+You will only be able to configure a SQL Database interface if you have 
+compiled Xastir with support for that DBMS (--with-mysql or --with-postgis).
+
+HELP-INDEX>Symbol Table
+
+These are the symbols that you can select for your station under the "Station
+Information" configuration menu. The current list can be found in the APRS(tm)
+Reference which you could get from http://www.tapr.org
+
+                             Symbol Table
+
+Symbol     Group /                       Group \
+
+!          Triangle w/!                  Triangle w/!
+"          Rain Cloud                    Rain Cloud
+#          Digi                          DIGI
+$          Phone Symbol                  $ Symbol
+%          DX                            DX
+&          GATE-HF                       GATE
+'          Small Aircraft                Aircraft Crash
+(          Cloud                         Cloud
+)          TBD
+*          SNOW Flake                    SNOW Flake
++          Red Cross
+,          Reverse L
+-          House w/omni
+.          Small x
+/          Red Dot
+0          0 in a box                    Circle
+1          1 in a box
+2          2 in a box
+3          3 in a box
+4          4 in a box
+5          5 in a box
+6          6 in a box
+7          7 in a box
+8          8 in a box
+9          9 in a box                    GAS
+:          Fire                          ?
+;          Tent                          Tent
+<          Motorcycle                    Pennant
+=          Train Engine
+>          Car                           Car
+?          POS Antenna                   ? in a box
+@          HURRICANE/STORM               HURRICANE/STORM
+A          First Aid                     Box
+B          BBS                           Blowing Snow
+C          Canoe
+D          D in a circle
+E          E in a circle                 Smoke Stack
+F          F in a circle
+G          Grid Square Antenna           ?
+H          Hotel/Bed
+I          TCP/IP                        ?
+J          J in a circle                 Lightening
+K          School House
+L          Light House                   Light House
+M          Mac
+N          NTS                           ?
+O          Balloon
+P          Police car                    Rx
+Q          Circle with in Circles        Circle with in Circles
+R          RV                            Restaurant
+S          Shuttle                       Satellite
+T          Thunderstorm (cloud/bolt)     Thunderstorm (cloud/bolt)
+U          School Bus                    Sun
+V          VOR TAC                       VOR TAC Symbol
+W          National Weather Service      NWS-Digi
+X          Helicopter
+Y          Sail Boat
+Z          Windows
+[          Runner                        WC
+\          DF Triangle
+]          Packet Mail Box
+^          Large Aircraft                Large Aircraft
+_          Weather Station               WS-Digi
+`          Satellite Dish
+a          Ambulance
+b          Bike                          blowing cloud
+c          DX antenna
+d          Fire dept.                    DX Antenna
+e          Horse                         Sleet cloud
+f          Fire Truck                    FC Cloud
+g          glider                        Pennant (2)
+h          Hospital                      HAM
+i          Island                        Island
+j          Jeep                          Jeep
+k          Truck                         Truck
+l          Small dot                     Small Dot
+m          MIC                           Mile Post
+n          N                             Small Triangle
+o          EOC                           Dot with in Circles
+p          Puppy                         Dot with in Circles
+q          GS Antenna                    GS Antenna
+r          Antenna Tower                 Antenna Tower
+s          Boat                          Boat
+t          TS                            ?
+u          18 Wheel Truck
+v          Van                           Dot with in Circles
+w          H20                           Flood
+x          X Windows                     Red Dot
+y          House w/Yagi                  House w/yagi
+z                                        X Windows
+{          FOG                           FOG
+|          Black Line                    Black Line
+}          TCP                           TCP
+~          Sail Boat                     Sail Boat
+
+HELP-INDEX>What was new in Xastir 1.0
+
+Over the past year, Xastir has been under active development, and this new
+release is the culmination of those efforts. Development has been run by
+Chuck Byam, who agreed to take over for Frank Giannandrea. Many other
+individuals have contributed to this project, and are listed in the AUTHORS
+file.
+
+The Xastir package now uses GNU autoconf to build makefiles and select
+features based on the libraries and software one has installed. No more
+editing makefiles as in previous releases!
+
+Starting Xastir 1.0, one probably won't immediately notice any major
+changes. The familiar interface of previous Xastir versions has been retained
+for the most part. The great majority of the changes are improvements in
+efficiency under the hood:
+* Startup time for the program has been improved.
+* Memory usage has greatly improved, with dynamic allocation of separate
+  station, trail, and weather data on an as-needed basis. No longer will
+  memory be wasted on stationary stations for trail data, nor will non-weather
+  stations waste memory for weather information. With these modifications,
+  Xastir can even be connected to the internet link comfortably on a 16MB
+  machine.
+* Improvements have been made to avoid having to reload maps from disk at every
+  minor change; Weather alerts and changes to the display and tracking options
+  no longer cause the maps to reload, rather the trails and symbols are
+  redrawn alone.
+* Improvements have been made to various dialog boxes that re-drew often, to
+  redraw less often, to allow them to be usable on slower systems. This is
+  also true of tracking a station, with the map redrawing only if the station
+  approaches the edge of the screen.
+Thanks to these changes, Xastir is perfectly usable on slower Pentium(tm)
+machines.
+
+Native GeoTIFF support is now included, and will be compiled into one's copy
+of Xastir if they have the GeoTIFF libraries installed on their system. These
+map files are of very high quality, and are especially useful in search and
+rescue operations. Maps on this format are available from the USGS, and
+commercially on CD-ROM. Xastir understands how to convert from the NAD-27
+datum to the new WGS-84 datum, so maps of both format can be read accurately.
+New shortcut buttons have been added to the map selection dialog to enable
+one to pick all maps of a specific type.
+
+Support for the Festival Speech Synthesis System is now available to announce
+new stations and band openings. The old system of alert sounds has been
+retained as well.
+
+Xastir now supports adding and deleting objects. Finally, Xastir users are able
+to manage resources with this useful feature. Objects are helpful for
+coordinating events, directing travelers, and doing search and rescue work.
+
+The County Warning Area maps that display weather alerts are no longer painted
+onto the maps below, but are shaded onto the maps. While this does make the
+colors unpredictable, it is now possible to see the road-maps below the 
+alert! 
+
+A new and useful feature is the change in the orientation of a symbol based on
+the direction in which it is moving. Even without a trail, a quick glance can
+tell you a mobile station's bearing. There are several more new options in the
+display menu, enabling one to decide more precisely what is displayed and what
+isn't.
+
+Panning and control over the map has been enhanced: There are now arrow buttons
+visible at the top of the screen to pan the map. The map can also be panned
+with the arrow keys, and the zoom can be adjusted with the page up and page
+down keys. There are new option in the click menu, to center the map where you
+clicked or to place an object where you clicked. The panning options in this
+menu have been removed in favor of the new controls at the top of the screen.
+
+Support for altnet has been added, enabling one to have a private APRS(tm)
+network for special events, search and rescue, storm chasing, or whenever else
+the user doesn't want to be bothered by the hundreds of APRS(tm) stations
+around.
+
+There are numerous small changes, both visible and invisible to the user. The
+interface control dialog now has a "Start all" and "Stop all" option, to save
+the user the time of performing these actions for each interface. The station
+setup dialog now shows you your symbol, so you don't have to exit the dialog to
+see which symbol you chose. Several buffer overflows that caused unpredictable
+behavior and/or crashes have been fixed. And many minor improvements have been
+made to the source code to ensure that it compiles correctly on various
+systems.
+
+Enjoy the new Xastir!
+
+
+HELP-INDEX>What was new in Xastir 1.1
+
+                    What was new in Xastir 1.1
+
+This new release, Xastir 1.1, adds significant new features and enhancements
+to the user interface. Unlike 1.0, the interface changes will take some getting
+used to, but the flexibility and versatility of the enhanced interface will
+more than make up for the troubles.
+Among the improvements to the user interface:
+* Keyboard shortcuts for menus and dialogs, menu reorganization, and mouse
+  behavior changes.
+* The ability to move objects or measure distance with the mouse, using the
+  appropriate check-boxes in the toolbar.
+* A scale has been added to allow one to judge distance on a map.
+* Map labels for windows-style APRS(tm) maps are rotated to match the marked
+  map features.
+* The user interface for dealing with objects has been entirely redesigned.
+* Station info boxes can be set to automatically update.
+* Tear-off menus.  Allow you to keep a menu on the screen and play with
+  different options. Tear off a menu by clicking on the dashed-line portion.
+
+Map support has been greatly enhanced, with PocketAPRS, ESRI Shapefiles, GNIS
+labels and many graphics formats with ImageMagick. Additionally, support for
+downloading graphical maps from web-servers has been added, allowing Xastir to
+use online radar, Tiger, and Terraserver maps. 
+
+Xastir 1.1 supports much more of the APRS(tm) protocol than its predecessor:
+* It can add, modify, move and view area objects, signpost objects, and items.
+  These features are invaluable for event coordination and search and rescue
+  use. Objects and items are also periodically retransmitted.
+* Support for displaying position ambiguity squares, pre-calculated radio
+  ranges, Maidenhead grid squares, and weather objects. These features aren't
+  extremely common, but do come up occasionally.
+* Support for the APRS(tm) radio direction finding features. These features
+  are useful for anything from tracking jammers to locating lost hikers. Xastir
+  supports both Omni and Beam reports.
+  
+Other notable improvements:
+* Xastir can now search for a specified location or landmark using GNIS data.
+* Track logs can now be exported to file.
+* Maps can be printed if certain tools and libraries are present.
+* Support for retrieving historical track data from findu.com.
+* Xastir now compiles and runs on Mac OS X, Solaris and FreeBSD with only
+  minimal changes; see README for details. 
+* Several major bugs found in 1.0 have been corrected, including the problems
+  loading DOS maps and the problems with the weather reporting. Other minor
+  bugs and memory leaks have been fixed. And several more errors have been
+  corrected in the parsing routines, so Xastir should remain stable no matter
+  what is thrown at it! 
+
+
+HELP-INDEX>What was new in Xastir 1.2
+
+                    What was new in Xastir 1.2
+
+The latest Xastir release adds numerous new capabilities, keeping Xastir a
+benchmark for APRS(tm) programs on any operating system.
+
+Xastir's hardware support has been enhanced, with
+* Support for Serial KISS TNCs
+* Support for Serial TNCs with GPS on the AUX port
+* Support for using AGWPE as a TNC
+* Support for Dallas One-Wire weather station
+  (see http://melhuish.info/simon/projects/oww/)
+* Support for more weather stations via the wx200d daemon (WX-200/WM-918/
+  WMR-918/WMR-968)
+* Support for the different sized rain gauges of the Peet Brothers weather
+  stations.
+
+Additionally, several bugs in the weather reporting code were corrected, and
+support for setting the system clock based on the GPS was added.
+
+There have been many additions and improvements to the Xastir user interface:
+The most notable is the addition of dead-reckoning. This means that stations
+that are moving will continue to move on your screen in the direction and at
+the speed speed that they last reported. The estimated location can be shown
+with any combination of a ghosted icon, a dashed line from the last position,
+or an arc of expected possible distance and angle.
+
+Also very notable are the improvements to the Map Chooser. Maps can now be
+selected a directory at a time, or individually. And the new map properties
+dialog allows individual control of map layering, map color filling, and
+consideration for auto-maps. Additionally, with extent caching under the hood,
+auto-maps regains much of its formal usefulness even with many maps installed!
+
+Bulletins pop up on screen, and emergency beacons cause an alert with the 
+locate station dialog on hand. These changes are helpful in emergencies and
+event coordination.
+
+Xastir can now be set to use one of several coordinate systems, including UTM,
+dd.ddddd, dd mm.mmm, and dd mm ss.s. This is helpful for coordinating with
+other groups using a different system.
+
+The online Tiger maps can now be enabled from the map menu, and options can
+be adjusted to request maps with just the data you want displayed.
+
+The stations menu has been reorganized, allowing more intuitive filtering of
+stations shown and of accompanying data.
+
+Other smaller interface changes include:
+* The density of the grid-lines can be adjusted with the +, =, and - keys.
+* Objects and item lists have been added to the view menu.
+* Station maidenhead grid squares are now shown in station info and the
+  coordinate calculator.
+* There is a check-box "Track me" to enable easily tracking your own station
+* The length of trails downloaded from findu.com can now be specified.
+* Xastir can now ID via voice IDs or Screen IDs, by editing the configuration
+  file. This is intended for configurations when the Xastir screen is seen
+  remotely via fast-scan TV. 
+* Timestamps are written to log files every 30 seconds of operation, to keep a
+  record of when data was heard.
+* The status bar can display the course/distance to your station when
+  enabled in the file|configure menu.
+* Range scales are now shown opposite the map scale. This is an attempt to
+  standardize various APRS(tm) client approaches to zoom levels.
+
+New additions under-the-hood:
+* Tracked proximity alarms.
+* Export waypoints within proximity boundaries.  Your GPS can show
+  you the locations of APRS(tm) stations as waypoints on the GPS map
+  screen.
+* Export trail as ESRI Shapefile.  New feature if you have Shapelib
+  compiled in.  Station Info->Store Track button also creates a
+  Shapefile map of the station's track now.
+
+The weather reporting features have been improved, with the addition of
+optional wind barbs to weather stations and decoding of storm wind radius data.
+Weather alert shading is now done with pixmap stipples showing the type of
+alert. Further information on an alert is available over the internet from
+the WXSVR by simply double-clicking the alert in the weather alerts list.
+Weather alerts now use the newer ESRI Shapefile-format maps.
+
+Xastir's map support has been improved with enhancements to the ESRI Shapefile
+code to handle point-type ESRI Shapefiles. Additionally, speed improvements
+have been made in the ImageMagick graphical map loading, and many
+color-correction features have been added. As mentioned above, the Map Chooser
+has been greatly improved, and weather alerts use ESRI Shapefile-format maps.
+
+Under the hood, Xastir has had several major improvements:
+
+The messaging system has been largely rewritten, and the annoying timed updates
+to dialogs no longer occur. The new messaging system allows multiple messages
+to be queued, and implements reply-ack's for speed. Xastir also attempts to
+specify a reasonable path for the message based on received messages. This
+improves speed and congestion control. The messaging GUI has been largely
+untouched, and remains high on the list of future improvements.
+
+The build process has been significantly improved; Xastir is now able to be
+built on numerous operating systems with few manual interventions.
+
+Xastir now supports GPSMan/gpsmanshp, allowing the importing of waypoints,
+tracks, and routes from several types of GPS receivers.  This allows you to
+create ESRI Shapefile-format maps out of GPS data.
+
+Xastir now implements SmartBeaconing(tm), which greatly improves trail quality
+and reduces unneeded channel usage. See the "Configure SmartBeaconing" help
+topic.
+
+IGating support has also improved, with the ability to configure a specific RF
+path for IGated packets, and the addition of a 29 second anti-dupe queue to
+reduce unnecessary redundancy on the RF channel.
+
+Map extents and filenames are now cached, so maps will not be loaded from disk
+unless they are on screen. This is a major improvement for map types that did
+not specify this information. Additionally, auto-maps uses this information,
+making it usable even with many maps installed.
+
+Objects controlled by Xastir are now stored in a file, so a restart of Xastir
+will not cause them to be lost. Additionally, Xastir now supports the
+compressed format for objects and items, which can help reduce RF channel
+congestion. It also gives you better location accuracy of the placed objects.
+See the help topic "Configure Default Operation".
+
+Xastir now drops root privileges when not needed if run setuid root. Please
+read the information about this in INSTALL; this change provides only
+limited protection.
+
+Xastir now supports using a private colormap with the command-line argument
+"-i". This is recommended for systems running in 8-bit color mode. 
+
+Additionally, several more buffer overruns and other errors were corrected in
+Xastir's data parser, and numerous other bugs have been fixed.
+
+Enjoy the new Xastir!
+
+HELP-INDEX>What's new in Xastir 1.3
+
+                    What's new in Xastir 1.3
+
+This latest Xastir release greatly improves on the efficiency and usability of
+Xastir, and adds many helpful and often-requested new features.
+
+.geo files can now have REFRESH tags, to specify how often the file is
+reloaded. This is useful for weather radars and other dynamic images. .geo
+files can also have a TRANSPARENT tag to make a certain color transparent, and
+a CROP tag to specify a specific region to display.
+
+Some Opentrac packets are now decoded and displayed. See
+http://opentrac.org/ for more details.
+
+The default main Xastir directory is now /usr/local/share/xastir; please see
+the upgrade notes in README for migration information. This more closely
+mirrors the behavior of other applications.  If you're installing
+from a binary package (rpm/deb/etc), the default install location
+may be /usr/share/xastir.
+
+Xastir efficiency has been greatly improved. Changes in data structures and
+timing values have made this Xastir release the most efficient yet.
+Additionally, map redraw sequences are interruptible, so map panning speed
+has been improved.
+
+dbfawk support - Experimental support for configurable shapefile metadata, in
+an awk-like language. See README.MAPS for more details; this must be turned
+on with a specific switch to the configure command.
+
+GDAL/OGR support - Experimental support for GDAL and loading of native Tiger
+data (.RT1 files). This is automatically enabled if the GDAL library is
+found.
+
+Support for UTM w/special zones and MGRS coordinate systems.
+
+Cad drawing mode allows one to draw regions on your screen using the center
+mouse button. This feature is not yet complete, but is functional.
+
+User interface changes:
+* Several of the menus have been reorganized to have a hierarchical design.
+* Additionally, a few colors have been modified for better visibility.
+* The map label font and style are more configurable
+* The cursor changes to let one know if they're in move object or measure mode.
+* If the coordinate system is set to UTM, and "Map Grid" is selected, an UTM
+  grid is displayed. 
+
+Snapshot mode now generates a .geo file, allowing the image to later be used
+as a map.
+
+Tiger maps have been moved back the chooser, as was the pre-1.2 behavior.
+This is more consistent.
+
diff --git a/help/help-Spanish.dat b/help/help-Spanish.dat
new file mode 100644
index 0000000..d4bfe40
--- /dev/null
+++ b/help/help-Spanish.dat
@@ -0,0 +1,1681 @@
+HELP-INDEX>L�AME PRIMERO - Licencia
+
+           L�AME PRIMERO - Licencia
+
+!!! NOTA: �Este Documento se actualiz� en Fecha 04/09/02 !!
+
+Para la informaci�n m�s actualizada por favor
+lea el archivo README.1ST en el directorio de Xastir.
+
+Recuerde que este programa es usado por la comunidad HAM, en los EE.UU
+la FCC le restringe de transmitir sobre RF si usted no es un HAM con licencia.
+Usuarios autorizados en otros pa�ses fuera de los EE.UU.
+Deben buscar sus restricciones gubernamentales locales. 
+
+LICENCIA:
+
+XASTIR, Estaci�n de Aficionado de Rastreo y Reportes de Informaci�n.
+Copyright (C) 1999-2000 Frank Giannandrea
+Copyright (C) 2000-2012 The Xastir Group
+
+Este programa es software libre; usted puedes redistribuirlo y/o
+modificarlo bajo los t�rminos del GNU Licencia P�blica General
+como publicado por la Fundaci�n del Software Libre; cualquier versi�n 2
+de la Licencia, o (a su opci�n) cualquier versi�n m�s atrazada.
+
+pero SIN NINGUNA GARANTIA; a�n sin la garant�a impl�cita de
+COMERCIABILIDAD o APTITUD PARA UN PROPOSITO PARTICULAR.
+Vea el (GNU) Licencia P�blica General para m�s detalles.
+
+Usted debes de haber recibido una copia del GNU Licencia P�blica General
+junto con este programa; si no, escriba al Software Libre
+Fundaci�n, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, EE.UU..
+
+M�s informaci�n sobre el programa puede encontrarse en:
+
+http://www.xastir.org/
+http://sourceforge.net/projects/xastir/
+http://xastir.sourceforge.net
+
+Hay algunos Forum de discusiones disponibles que son espec�ficamente sobre Xastir.
+Usted puedes subscribirse en uno o en ambos de ellos para recibir las �ltimas
+informaciones y novedades sobre el desarrollo de Xastir.
+Visite esta direcci�n para subscribirse en http://www.xastir.org/.
+
+Para m�s informaci�n sobre la Licencia GNU busque en:
+
+http://www.gnu.org/
+
+
+HELP-INDEX>Bienvenido! y Notas de los Autores
+
+                      �Bienvenido! y Notas de los Autores
+
+XASTIR, Significa, X-ventanas Estaci�n de Aficionado de Rastreo y Reportes de Informaci�n.
+
+               El significado en ingl�s es como sigue:
+XASTIR, or (X)windows (A)mateur (S)tation (T)racking and (I)nformation (R)eporting.
+
+Es un APRS(tm) como programa que es Fuente Abierta y libre para usarlo y pasarlo a otros. 
+Actualmente este programa est� en desarrollo y no debe verse 
+como un producto finalizado! Su ayuda ser� necesaria para hacer de este 
+un mejor programa.  
+
+Si usted tienes habilidades programando y/o puede escribir documentaci�n, 
+su ayuda puede ser necesaria! Yo tengo muchas ideas pero el tiempo muy corto. 
+As� que si usted piensas que usted puedes anexar algo al esfuerzo d�jemelo saber!
+
+73,
+Frank Giannandrea
+fgiannan at eazy.net
+
+
+APRS[tm] es una Marca de f�brica de Bob Bruninga, 
+su p�gina est� en "http://web.usna.navy.mil/~bruninga/aprs.html" 
+Por favor note que mucha de la informaci�n sobre APRS(tm) puede encontrarse  
+en la documentaci�n de APRSdos escrita por Bob Bruninga.  Una adicional  
+fuente de informaci�n es el APRS(tm) especificaci�n, disponible en  
+http://www.tapr.org
+
+HELP-INDEX>Que hay de nuevo en Xastir 1.1
+
+            Que hay de nuevo en Xastir 1.1
+
+Esta nueva versi�n, Xastir 1.1, agrega nuevos rasgos significantes y perfeccionamientos  
+a la interface del usuario. Al contrario de 1.0, 
+los cambios de la interface tomar�n algunos uso conseguido, 
+pero la flexibilidad y versatilidad de la interface reforzada ser�  
+mayor, trantando de sacar fuera los problemas.  
+Entre las mejoras a la interf�z de usuario:  
+* Los atajos del teclado para los men�s y di�logos, reorganizaci�n del men�, y rat�n  
+  cambios de conducta.  
+* La habilidad de mover objetos o medida distancia con el rat�n, usando el  
+  apropiado marcado de caja en la barra de herramienta.  
+* Una balanza se ha agregado para permitir a uno a juzgar distancia sobre un mapa.  
+* Las etiquetas del APRS(tm) mapas para el estilo de ventanas son rotado para machar los rasgos  de mapas marcado.  
+* La interf�z del usuario por tratar con objetos que han sido redise�ado completamente.  
+* Pueden ponerse cajas de info de estaci�n para fijar autom�ticamente actualizaci�n.  
+* Rasgar-fuera los men�s. Permitiendole a usted mantener un men� en la pantalla y jugar con  
+  opciones diferentes. Rasgar fuera un men� por pulsar el bot�n del rat�n en la porci�n del golpear-l�nea.  
+  
+El soporte del mapa se ha reforzado grandemente, con PocketAPRS, ESRI Shapefiles, GNIS,  
+etiquetas y muchos gr�ficos estructuran con ImageMagick. Adicionalmente, soporte para  
+bajar graficalmente mapas desde varios webservers han sido agregado, permitiendo a Xastir a  
+use radar en l�nea, Tigre (Tiger), y mapas de Terraserver.   
+  
+Xastir ahora soporta mucho m�s del APRS(tm) protocolo que su precursor:  
+* Puede agregar, modificar y ver �reas de objetos, el poste indicador de objeto, y art�culos. �stos  
+  rasgos son inestimables para la coordinaci�n de evento y b�squeda y uso en rescate.  
+  Los objetos y art�culos tambi�n son peri�dicamente retransmitido.  
+* El soporte para desplegar ambig�edad de posici�n cuadra, rangos de radio precalculado,  
+  Cuadra de rejilla, y objetos de tiempo. Estos rasgos no son  
+  sumamente com�n, pero surge de vez en cuando.  
+* El soporte para el APRS(tm) rasgos de radio-direcci�n-encontrada (RDF). Estos rasgos  
+  son �tilidad para algo, desde rastrear localizar excursionistas perdidos. Xastir  
+  soportas ambas Omni y direccional.  
+    
+Otras mejoras notables:  
+* Xastir puede ahora buscar una localizaci�n especificada o punto en tierra usando el GNIS data.  
+* Pueden exportarse ahora las bit�coras (logs) hacia un archivo.  
+* Pueden imprimirse mapas si ciertas herramientas y bibliotecas est�n presentes.  
+* Soporte para recuperar datos de rastreo hist�ricos desde findu.com.  
+* Se han corregido varios bichos (bugs) mayores encontrados en 1.0, incluso los problemas  
+  cargando mapas de DOS y los problemas con el informe del tiempo. Otro menores   
+  bichos y goteras de memoria han sido reparada. Y algunos m�s errores han sido  
+  corregido en las rutinas de parsing, as� que Xastir debe permanecer estable no importa  
+  �lo que se tire en �l!   
+  
+Y muchas mejoras menores han sido hecha en el c�digo fuente
+para asegurar que compile correctamente en varios sistemas.
+  
+Esperamos que usted disfrute el nuevo Xastir!  
+  
+
+HELP-INDEX>Iniciando a Xastir por primera vez
+
+               Iniciando a Xastir por primera vez
+
+Cuando Xastir se inicie por primera vez, usted debes ejecutarlo en una ventana 
+terminal asi que cualquier mensaje de advertencia o error puedan verse.
+
+En la mayor�a de los sistemas una ruta es configurada para correr el programa 
+en /usr/local/bin y todo lo que usted necesitas hacer es tipear "xastir" 
+en la l�nea de comando.
+
+En sistemas que no tienen este tipo de ruta instalado "/usr/local/bin/xastir" 
+para empezar el programa.
+
+Usted tambi�n puedes poner la opci�n del Idioma en este momento. 
+Para poner el idioma o cambiar el idioma actual, use �sta l�nea:
+
+xastir -l  
+
+
+Los Idomas Actuales son:
+
+Alem�n  (German)
+Espa�ol  (Spanish)
+Franc�s  (French)
+Holand�s  (Dutch)
+Ingl�s  (English)
+Italiano  (Italian)
+ElmerFudd (English)
+MuppetsSwedishChef (English)
+OldeEnglish (English)
+PigLatin (English)
+PirateEnglish (English)
+
+Si Usted quieres correr el Xastir en espa�ol use �sta l�nea:
+
+Ej: xastir -lSpanish o xastir -l Spanish
+
+Esta opci�n ser� guardada en el archivo de  configuraci�n de usuario 
+para que la pr�xima vez que Xastir se ejecute corra con el idioma Espa�ol. 
+
+En nueva instalaci�n xastir tendr� como valor predefinido el idioma ingl�s 
+a menos que usted uses �sta opci�n de l�nea de comando.
+
+NOTA: En men�s, se seleccionan art�culos que son encanecido,
+como en las opciones del ON/OFF, si 'ON' es seleccionado
+se opacar� o se pondr� transparente (encanecido).
+
+HELP-INDEX>Configurando la informaci�n de la Estaci�n
+
+           Configure la Informaci�n de la Estaci�n   
+
+Pulse el bot�n del rat�n en Archivo luego Configurar despu�s en Estaci�n  
+llene la casilla con su Indicativo de Radioaficionado.
+
+llene su posici�n de la estaci�n si usted no est�s usando Xastir con una unidad de GPS. 
+Si usted no la conoce, usted puedes localizar su posici�n general en el mapa 
+con Xastir y puedes usar la posici�n dada por colocar el puntero del rat�n sobre el mapa.
+
+Esta posici�n ser� visible en la barra del fondo de Xastir cuadro 2
+de la izquierda. Si usted tienes un GPS usted puedes saltar esta opci�n.
+
+Los s�mbol/grupo de la estaci�n pueden configurarse aqu�. Pulse seleccionar gr�ficamente y  
+escoja un s�mbolo, o manualmente rellene los campos. Una descripci�n de texto de cada uno  
+de los s�mbolos pueden encontrarse en la "Tabla de s�mbolo" tema de ayuda. Las cubiertas son cumplidas seleccionando un s�mbolo
+ de la tabla alternada, y poniendo el campo de la tabla a  
+el car�cter que usted desea recubrir encima del s�mbolo. Letras may�sculas y  
+los n�meros pueden ser recubierto. El APRS(tm) especificaci�n s�lo permite cubiertas sobre  
+s�mbolos espec�ficos; Xastir no forza esto, pero algunos otros programas pueden.  
+Note que no todos los s�mbolos se han llevado a cabo en el selector gr�fico  
+todav�a, y algunos de ellos no est�n por el APRS(tm) especificaci�n todav�a.  
+
+Luego, entre en los datos para la potencia/altura/ganancia de su estaci�n. Esta es  
+una informaci�n �til pero no se requiere; absolutamente seleccione "Desactive PHG"  
+desactivarlo. Estas opciones presentan una representaci�n granular de su estaci�n.  
+Seleccione la combinaci�n de valores cerca a la descripci�n de su estaci�n.  
+
+Otra opci�n ser�a especificar el RNG en el campo de comentario en millas  
+en lugar de usar PHG. Vea el APRS(tm) especificaci�n para detalles.  
+  
+Por favor use altura sobre el promedio del  terreno para el valor de altura.  No  
+use el promedio de altura sobre el nivel del mar o altura sobre tierra.  
+  
+Para el uso de Ganancia la ganancia de su antena en dBi.   
+�(CORRIGEME:  dBd? la especificaci�n no es clara, 
+yo pienso que est� implicando dBi porque dice "en ausencia de cualquier datos,
+las estaciones son asumida a estar corriendo 10w a un 3dB omni en  20pies.
+Una antena omni t�pica es s�lo 3dBi.....)   
+Para Altura, use el HAAT (altura sobre el promedio del terreno) de su estaci�n,  
+NO la altura sobre el nivel del mar o altura sobre geo-id.  
+
+Nota: La ganancia puesta es realmente pensada para las antenas verticales; la ganancia  
+puesta para una antena direcional deber�a ser por debajo de la ganancia hacia delante de una antena direcional.  
+Esto es porque con la direccionabilidad puesta, el c�rculo de PHG es compensado s�lo a trav�s de 1/3rd  
+de su tama�o hacia la direcci�n especificada. Poniendo la Ganancia m�s alta agrandar�  
+el c�rculo entero no-realisticamente, en lugar del aumentado direccionalmente.  
+Hab�a charla hace varios a�os sobre el enmendando las especificaciones para mejorar  
+trato con antenas direccional, pero nada fue cambiado.  
+  
+Entrar un comentario, no requerido pero agregar� visi�n en su estaci�n.  
+Una cosa com�n para entrar aqu� es su direcci�n de e-mail preferida.  Que  
+ser� transmitido a lo largo con su postula.  
+  
+La ambig�edad de la posici�n permitir� usted controlar que tan exacto usted transmite su  
+posici�n. Si usted no pone nada, xastir permitir� a su estaci�n transmitir la exacta  
+posici�n que usted ha entrado o ha recibido de un GPS. Las otras opciones lo pondr�n  
+en alguna parte en el rango de la opci�n que usted seleccion�.  Note que  
+esto puede tirar estaciones d�ciles a alguna no-especificaci�n para un bucle.  Findu.com  
+no entiende la ambig�edad de posici�n.  
+  
+Pulsando el bot�n "Aceptar" guardar�s sus cambios.
+Pulsando el bot�n en "Cancelar" conservar�s las actuales configuraciones.
+
+HELP-INDEX>Configurar Operaci�n Predefinida
+
+              Configurar Operaci�n Predefinida  
+  
+Pulse el bot�n en Archivo despu�s en Configurar luego en Predefinidos
+  
+Esta p�gina prepara algunos valores por defecto normales para el funcionamiento 
+del programa. Viejas estaciones se desplegar�n con un icono fantasma, 
+y el sendero correspondiente se fragmentar�.  
+
+El primer juego de botones de barra especifica el intervalo de desdoblamiento.  El segundo  
+juego de botones que especifica cuando una estaci�n ser� removida de la pantalla.  
+Las estaciones tambi�n son removida del banco de datos interno en el doble este tiempo,  
+as� si usted lo pusiera durante 6 horas, se anular�n estaciones del banco de datos  
+a las 12 horas.  
+  
+El tercer juego de botones especifica qu� a menudo la identificaci�n de su estaci�n ser�  
+transmitido.  Para las estaciones fijas una recomendaci�n buena es cada 30 minutos,  
+y definitivamente ninguno menos de 10 minutos.  
+Las estaciones m�viles pueden desear una m�s r�pida proporci�n.
+
+Este intervalo tambi�n se usa para mandar objetos y art�culos.  Pruebe  
+mantener este intervalo algo razonable, como transmitir hacia un largo camino,  
+cada 30 segundo realmente subir� mucho el tiempo a�reo.
+
+GPS Tiempo pondr� el intervalo de tiempo mirar el GPS por nuevos datos.  
+Esto es disponible para estaciones que usan un cable compartido HSP con su TNC.  
+  
+La Opci�n Trasmite Estaci�n fija el tipo de paquete que su estaci�n transmitir� sus datos como.
+Transmite datos Raw WX  si seleccionado tambi�n enviar� un paquete que contiene Datos raw
+de una Estaci�n Meteorol�gica. Esto es �til en los tipos de ASCII de estaciones WX, como la Peet Bros.
+
+Estaci�n WX. Las Opciones de IGate preparar�n su estaci�n como un portal de Internet-RF.
+Esta opci�n podr�a ser usada con cuatela, Como un HAM usted es responsable
+por el data que viene v�a el Internet y es transmitido hacia el Puerto de RF. 
+
+Usted tambi�n necesitar�   
+escoger una opci�n del igate en cada interface para que el igate funcione.  
+Si usted quiere tener su igate env�e NWS alarmas WX  hacia el RF, usted debe  
+crear un archivo ~/.xastir/data/nws-stations.txt listando cada llamada o estaci�n de NWS  
+(como "PHISVR") que le gustar�a transmitir v�a RF.
+    
+"Transmitir datos de WX RAW", si seleccionado, tambi�n enviar� un paquete que contiene crudo (raw)  
+Datos de estaci�n meteorol�gica. Esto es �til en los tipos de ASCII de estaciones WX,   
+como la Peet Bros. estaci�n meteorol�gica.
+
+"Los datos de posici�n comprimida pueden ser transmitida"?, si es seleccionado, transmitir� en  
+el m�s nuevo formato comprimido. Este formato reducir� la cantidad de datos en  
+el aire, por eso aumentando la capacidad de la red APRS(tm). La m�xima  
+precisi�n de la posici�n transmitida tambi�n es m�s alta. Algunos programas m�s viejos,  
+incluyendo las recientes versiones de WinAPRS, no decodificar� este formato todav�a.  
+Findu.com tambi�n podr�an tener problema con el.
+
+Activar Red Alternada ?
+esta opci�n se usa para desplegar grupos de estaciones que muestran
+en el unproto en el campo '>To' la versi�n del software como el Xastir
+que muestra la versi�n en el unproto como esto: HI8GN>APX090.
+
+Usted tambi�n puede seleccionar Altnet y puede escoger una llamada del altnet de este di�logo.
+Altnet le permite tener un privado APRS(tm) red entre las estaciones que tambi�n  
+tenga altnet configurado, y tiene la misma llamada del altnet entrada.
+
+Si cambiamos el valor por defecto que es XASTIR por ejemplo por APX110
+desplegar� toda las estaciones que tengan versiones de APX11x
+donde valor de 'x' puede ser desde 0-9.
+
+HELP-INDEX>Configurando las Alarmas de Audio
+
+                         Configurando las alarmas de Audio
+
+Para usar esta opci�n usted debes tener una tarjeta de sonido y un programa que 
+reproduzcan los archivos wav. El programa reproductor de Audio debe tener 
+comando el cual usted quieres ejecutar para tocar el audio archivo (y cualquier 
+opci�n en la l�nea de comando).
+
+Los campos tendr�n el nombre del archivo a reproducir, campos bajo la opci�n 
+pondr� par�metros para la opci�n.
+
+Las opciones Actuales son:
+
+  Reproducir mensaje al encontrar una nueva estaci�n. 
+
+  Reproducir mensaje al recibir un nuevo mensaje.
+
+  Reproducir mensaje de datos recibidos de una estaci�n dentro de la distancia  
+ min/max de su proximidad.
+
+  Reproducir mensaje de datos recibidos de una estaci�n (v�a TNC) con la 
+distancia de min/max de su banda abrierta.
+
+HELP-INDEX>Configurar el Sintetizador de Voz
+
+                         Configurar el Sintetizador de Voz
+
+Para usar esta opci�n del sintetizador de voz usted debes tener una tarjeta de sonido
+configurada para poder reproducir sonido.
+
+Tambi�n usted necesita tener instalado y corriendo al Servidor Festival m�s
+el Speech_tools con su biblioteca de soporte para el Sistema Festival de Voz S�ntetizada
+
+y asi poder escuchar el sintetizador de voz anunciar
+nuevas estaciones y aperturas de banda proximidad de una estaci�n. 
+
+El sistema de alarmas de sonidos ha sido tambi�n retenido.
+
+Con el Sintetizador de Voz adaptado por Curt Mills (we7u) 
+
+ajuste las casillas en las cuales usted quieres ejecutar el sintetizador para las alarmas
+
+(y cualquier opci�n en la l�nea de comando).
+
+Los campos tendr�n el nombre del archivo a reproducir, campos bajo la opci�n 
+pondr� par�metros para la opci�n.
+
+Las opciones Actuales son:
+
+  Anunciar un mensaje al encontrar una nueva estaci�n. 
+  Anunciar un mensaje al recibir un nuevo mensaje.
+  Anunciar un mensaje al recibir el cuerpo un nuevo mensaje.
+  Anunciar un mensaje de datos recibidos de una estaci�n dentro de la distancia  
+  min/max de su proximidad.
+
+  Anunciar un mensaje de datos recibidos de una estaci�n (v�a TNC o INET)
+  con la distancia de min/max de su banda abierta.
+
+  Anunciar un mensaje al recibir una nueva alerta sobre el tiempo climatol�gico.
+
+Info sobre Festival puede ser obtenida desde: http://www.speech.cs.cmu.edu/festival/
+
+HELP-INDEX>Configurando las Unidades de Medida
+
+                    Configure Unidades de Medida  
+  
+La selecci�n predefinida es para el Sistema M�trico, mm, cm, KPH, etc. 
+Seleccionar Ingl�s, pulgadas, pies, MPH, etc. Pulse el bot�n de Configurar, 
+luego en Unidades, despu�s la unidad de medida que usted quieres usar.
+Recuerde encanecida opciones son selecciona actualmente. 
+
+HELP-INDEX>Salvar Configuraci�n Ahora!
+
+                      Salvar Configuraci�n Ahora!
+
+Este bot�n salvar� todas la configuraci�n actual al archivo de configuraci�n.  
+Note que cuando Xastir est� cerrado, tambi�n salva configuraci�n al archivo
+de configuraci�n.
+
+HELP-INDEX>Barra de Estado de fondo
+
+                         Barra de Estado de fondo  
+  
+En el fondo de la ventana varios mensajes de estado est�n disponibles:  
+  
+En la primera parte en la barra de estados general los mensajes son desplegados.
+
+La segunda parte se muestra la posici�n lat/long
+actual moviendo el rat�n sobre el mapa.
+
+En la tercera parte es usada para mostrar
+cu�ntas estaciones est�n en el banco de datos.
+
+La cuarta parte de la barra desplegar� el nivel de enfoque actual y desplegar�
+"Tr" si el rastreo de estaci�n est� encendida (on).   
+  
+El �ltima �rea desplegar� el estado de dispositivo para cada interf�z. Cada una  
+desplegar� en orden primero hasta el �ltimo o de 0 a 9. El estado de la interface est� separado  
+en tres �reas, tipo de dispositivo cima, datos de centro fluyendo, y interface de fondo  
+estado operacional. El tipo de dispositivo mostrar� qu� interfaces se configuraron.  
+El color mostrar� qu� tipo de dispositivo de la interface se configur�. Azul  
+es para los varios dispositivos TNC; Verde mostrar� los dispositivos de GPS; Amarillo para los   
+Servidores de Internet; Naranja para las interfaces de WX. El centro mostrar� que los datos fluyen en rx (flecha que apunta a l
+a izquierda) o los datos fluyen fuera tx (flecha que apunta a la derecha) para eso interface. Una caja verde al fondo mostrar� 
+si esa interface es activa.  
+Una caja roja mostrar� si la interface es activa pero en una condici�n de error.  
+Por otra parte nada mostrar� si la interface no est� activa.  
+
+Las �ltimas dos partes mostrar�n el estado del tnc y de la red. Una "=>" 
+indicar� si el dato est� siendo enviado, y una "<=" si el dato est� entrando 
+desde la interfaz.
+
+  
+HELP-INDEX>Moviendo el Mapa y el Men� de Opciones
+
+                    Moviendo el Mapa y el Men� de Opciones  
+  
+Movimiento en el mapa es muy simple, la facilidad y rapidez de movimiento son dependientes de  
+la velocidad de su procesador y la cantidad de detalle que usted carga.  
+  
+Subiendo verticalmente:  
+Subiendo verticalmente puede ser logrado por pulsar el bot�n derecho de rat�n sobre el mapa (y sosteniendo el bot�n abajo). Est
+o plantear� un men� de opciones, con opciones para hacer subir verticalmente o fuera a un solo nivel, o para cambiar a uno de l
+os niveles del enfoque prefijado.  
+  
+Todas las funciones de enfoque desde el men� de opciones har�n acercarse o alejarse al punto  
+en el mapa donde usted puls� el bot�n del rat�n correcto. El  nivel de enfoque tiene una men� en  cascada. Niveles 1-64 son par
+a las �reas muy locales y niveles 256 y superior es para  
+�reas grandes. El n�mero m�s bajo del nivel, la �rea m�s local.  
+  
+Una funci�n de enfoque m�s r�pida es empujar y sostener el bot�n del rat�n izquierdo, arr�strelo  
+por el �rea de inter�s y permitida vaya.  El mapa har� subir verticalmente aproximadamente a  
+el tama�o del cuadrado usted apenas descrito con el rat�n la funci�n de arrastre.  
+El programa usa el componente vertical para decidir en el nivel de enfoque, y el  
+componentes verticales y horizontales para computar el nuevo centro del mapa.  El "movimiento"  
+y "medida" que deben desactivarse checkboxes de la bara de herramienta de este rasgo para trabajar.  
+  
+El mapa tambi�n puede acercarse con el teclado las llaves de PageUp/PageDown.  El  
+acercar en este caso guarda el mismo centro del mapa.   
+  
+Paneando/Centrando:  
+El mapa puede centrarse a una situaci�n espec�fica por pulsar el bot�n izquierdo del rat�n.  
+Pulsando el bot�n los enfoques del bot�n medio aleja con un factor de 2, centrando donde usted  
+puls� el bot�n.  
+  
+Paneando tambi�n es cumplido usando el men� de opciones, o usando la flecha  
+botones en la tope de la pantalla. La posici�n del mapa cambiar� una porci�n de  
+pantalla. Bastantes datos de pantalla anterior deben estar disponibles reorientarlo  
+.  
+  
+El mapa tambi�n puede ser paneado con las llaves de flecha del teclado.  
+  
+M�s Sobre el Men� de Opciones:  
+La selecci�n de "Estaci�n Info" en el men� de opciones buscar� la estaci�n  
+cerca a donde usted puls� el bot�n derecho del rat�n. Si m�s de una estaci�n est�  
+cerca de esa posici�n un "escogedor de Estaci�n" de lista aparecer�, entonces usted puede  
+escoger los datos de qu� estaci�n que usted quiere ver. Si s�lo una estaci�n es vista entonces el indicador del rat�n es cerrad
+o y los datos de esa estaci�n se desplegar�n inmediatamente. Note  
+que expiradas estaciones todav�a tienen sus datos guardados en el banco de datos de Xastir, y  
+si uno sabe la situaci�n anterior de una estaci�n, uno todav�a puede ver su info de esta  
+manera. Tambi�n es posible desplegar estaciones viejas encendiendo el "el Despliegue  
+de Datos Expirados" opci�n en el men� de las estaciones. CORRIGEME: Si no es completamente verdad.  Esto s�lo despliega algunos
+ de los datos que desaparecen como estaciones fantasma,   
+Velocidad/altitud, etc.,  
+  
+Para informaci�n de Objeto y Art�culo, por favor vea el tema de ayuda "Objetos y Art�culos"  
+
+HELP-INDEX>Objetos y Art�culos
+
+                                Objetos y Art�culos
+
+La opci�n de crear Objeto/Art�culo en el bot�n derecho pulsado el men� traear� un di�logo  
+con la posici�n de basado objeto en donde usted puls� el bot�n del rat�n.  
+Usted puede rellenar los detalles, y agregar un objeto/art�culo desde este men�.  
+  
+La opci�n de modificar Objeto/Art�culo le traer� un di�logo de modificaci�n de objeto.  
+Es similar al di�logo de creaci�n de objeto, excepto por la actual informaci�n de objeto que  
+ya est�n publicada, y el nombre del objeto y unas de las pocas otras opciones que no pueden ser cambiada.  
+  
+Los objetos son retransmitido dentro de la proporci�n de posici�n de la estaci�n reportada, configurada en Archivo|Configurar|P
+redefinidos, y cesar� la retransmisi�n despu�s doblar el  
+tiempo de despliegue de la estaci�n, tambi�n configurada all�. "muerta" los objetos tambi�n son  
+retransmitido de esta manera, hasta que ellos expiren desde la cola.  
+  
+Generalmente se usan los objetos para movimiento o cosas inconstantes como tormentas,  
+mientras que los art�culos generalmente son usando para las cosas m�s inanimadas, como agua,  
+estaciones. Cualquiera puede moverse con el rat�n si el "Movimiento" el checkbox en la  
+barra de botones se habilita.  Note que los art�culos no pueden ser descifrados por uno cuantos  programas APRS(tm) .  
+  
+Las �rea de objetos son �tiles para una variedad de funcionamientos en lo que usted quiere dibujar  
+o resaltar una �rea de inter�s en el mapa. Ellos tambi�n pueden ser personalizados para dibujar  
+rastros/caminos/fronteras, sitios de vijilancia para mal el tiempo, las pistas de aterrizaje, per�metros, de una �rea de b�sque
+da o de un evento de servicio p�blico, �reas de da�o, �reas para quedarse fuera de, edificios que no est�n en el mapa, la tabla
+ checker/chess para juego por dinero en APRS(tm).: -) Note que las �rea de objetos no son llevada a cabo en todas las versiones
+ de programas APRS(tm), y algunos de los detalles de c�mo ellos se despliegan tambi�n pueden  
+ser diferente en otros programas.  
+  
+Nombre  
+�ste es el nombre del objeto o art�culo. Puede depender de hasta 9 car�cteres. Cuando  
+modifica un objeto, este no puede ser cambiado. Para renombrar un objeto usted debe  
+anular el original y entonces crear un nuevo objeto. Note que si usted selecciona  
+Signpost/Area Object/DF Objeto que este campo y quiz�s otros ser�n aclarado.  
+Entre en el nombre DESPU�S que usted ha seleccionado el tipo de objeto que volver�.  
+  
+Poste indicador  
+Este hace al objeto un poste indicador de objeto. Estas se�ales pueden ser 3 car�cteres,  
+visible en un poste indicador a la locaci�n cuando el enfoque es acercado. (CORRIGEME: Nosotros no hacemos el despliegue de los
+ postes indicadores todav�a de esta manera).  
+  
+Objeto del �rea  
+Esto hace un objeto del �rea al objeto, y habilita los mandos de objeto de �rea  
+descrito debajo.  
+  
+Objeto DF  
+�ste es un informe de contrada-direcci�n. Habilit�ndolo le permite escoger reporte Omni o  
+direccional, y le permite poner en el especifico para cada uno.  Vea:  
+    http://web.usna.navy.mil/~bruninga/dfing.html  
+y la documentaci�n de APRSdos para los detalles en estas t�cnicas �tiles.  
+(CORRIGEME: la secci�n Separada en las t�cnicas de DFing?)  
+  
+S�mbolo Estaci�n  
+Usted puede seleccionar un s�mbolo para el objeto. Pulse seleccionar para escoger gr�ficamente,  
+o ver la secci�n tabla de ayuda de s�mbolo para las descripciones de cada s�mbolo. Note  
+que no todos los s�mbolos se han llevado a cabo todav�a en el escogedor de gr�ficos,  
+y algunos no est�n por el APRS(tm) especificaci�n. Tambi�n note esa �rea de objeto, poste indicador de objetos, y los objetos d
+e DF tienen s�mbolos fijos especiales y por consiguiente no pueden ser seleccionado aqu�.  
+  
+Localizaci�n  
+La localizaci�n del objeto se especifica aqu�. Si usted seleccionara "Crear   
+Objeto/Art�culo" pulsando el bot�n derecho del men�, la locaci�n que usted pulsado se llenar�  
+. Si usted moviera un objeto con el rat�n, la nueva posici�n estar� en esos campos.  Usted tambi�n puede teclear en una posici�
+n, por ejemplo usted puede estar poniendo un  
+objeto de un informe de voz sobre el aire.  
+  
+Opciones gen�ricas  
+Usted puede especificar la velocidad, direcci�n, y altitud de objetos aqu�. Algunos tipos de objetos  
+no pueden tener una velocidad o direcci�n en tales casos los campos son desgrisado  
+.  
+  
+Objeto del poste indicador  
+Si el objeto es un objeto de poste indicador, usted puede especificar de 1 a 3 car�cter  
+de mensaje que aparece en la se�al aqu�.  Note que Xastir no despliega los objetos  
+de poste indicador a propiamente todav�a.  
+  
+Objeto �rea  
+Se usan Objetos de �rea para resaltar partes espec�ficas del mapas, o para dibujar excepcionalmente detalle dentro de los mapas
+.  
+  Color luminoso.  
+    Use la versi�n m�s luminosa de los colores permitidos.  
+  Colorido  
+    El �rea debe llenarse, no s�lo perfilado. Esto puede ser �til para  
+    excluir una �rea de una b�squeda u otro evento.  
+  Tipo de objeto  
+    Escoge desde las formas geom�tricas permitidas.  
+  Color del objeto  
+    Escoge el color en el que el objeto se desplegar�. Esto tambi�n es afectado  
+    por el "Color Luminoso" la opci�n anteriormente.  
+  El objeto Compensado  
+    En cent�sima de un grado latitud.  Un detalle infortunado de la especificaci�n,  
+    y duro de calcular f�cilmente.  Basta decir que usted puede cambiar  
+    el tama�o del objeto una vez usted lo ponga.  
+  El Desplazamiento izquierdo del objeto excepto /  
+    En cent�sima de un grado latitud.  Vea anteriormente.  
+  Objeto corredor  
+    �ste es el ancho de una l�nea de �rea de objeto. Util para las pistas de aterrizaje, tiempo  
+    watchboxes, describiendo una �rea de inter�s o una �rea de exclusi�n, etc.,  
+(CORRIGEME: Escriba esta parte! (el �rea objeto) La especificaci�n es incierta a m�, el c�digo,  
+es incierto a m�, pero en el futuro yo lo deducir� todos!)  
+  
+�Siempre anule sus objetos y art�culos cuando usted halla terminado con ellos!  
+No les permita simplemente expirar desde su escondite, como ellos pueden colgarse  
+alrededor de las pantallas de otras personas por un periodo extendido.  
+    
+
+HELP-INDEX>Men� Visualizador
+
+                     Opciones del Men� de Visualizar  
+  
+El men� de Visualizar presenta varias maneras de ver datos en Xastir.  
+  
+Boletines  
+�ste es el APRS(tm) tabla de anuncios, donde importantes anuncios son puesto.  
+Si usted se conecta con la interf�z del internet, es una buena idea para poner el  
+rango del campo a unas cientas millas, para ignorar postes de otras porciones del  
+mundo. "0" es el rango del campo, significa el mundo entero. Pulse el bot�n "Cambio de rango"  
+pulse para hacer cambios a este campo eficaz. Xastir actualmente no soporta el env�o de boletines.  
+  
+Datos de paquete entrantes  
+Esto despliega los datos entrantes en su TNC o interf�z del internet. Los botones radio  
+debajo selecciona si usted quiere ver s�lo datos de TNC, s�lo datos del internet, o  
+ambos.  
+  
+Estaciones m�viles  
+�sta es una lista de estaciones que se est�n moviendo. Las estaciones califican para esta lista si  
+ellas se han movido (m�s de una posici�n recibida para ellas), el s�mbolo de  
+la estaci�n no es considerada. Informaci�n mostrada incluyendo curso, velocidad, altitud,  
+posici�n, n�mero de paquetes recibido, n�mero de sat�lites de GPS visibles, curso,  
+de su estaci�n, y distancia de su estaci�n.   
+  
+Todas las Estaciones  
+Esta opci�n despliega una tabla de todas las estaciones ordenada alfab�ticamente. Incluyendo  
+el n�mero de paquetes o�do, el tiempo que la estaci�n fue o�da �ltima vez, el camino   
+m�s reciente paquete tomado, el PHG, y el comentario de la estaci�n.  
+  
+Estaciones locales  
+Esta opci�n despliega s�lo estaciones que se oyen v�a su TNC. Incluye  
+el n�mero de paquetes o�do, el tiempo que la estaci�n fue o�da �ltima vez, el camino  
+m�s reciente paquete tomado, el PHG, y el comentario de la estaci�n.  
+  
+Ultimas Estaciones  
+Esta opci�n despliega una tabla de todas las estaciones ordenada recientemente o�da  
+a menor recientemente escuchada. Incluye el n�mero de paquetes o�do, el tiempo,  
+la estaci�n fue o�da �ltima vez, el camino que el m�s reciente paquete tom�, el PHG,  
+y el comentario de la estaci�n.  
+  
+Estaci�n WX  
+Esta opci�n despliega una tabla de todo el APRS(tm) estaciones del tiempo y sus datos.  
+El datos incluyen curso del viento, velocidad del viento, velocidad de r�faga dle viento, temperatura, humedad, presi�n barom�t
+rica, lluvia en la �ltima hora, lluvia medianoche subsecuentemente, y lluvia en las �ltimas 24 horas.  
+  
+Estaci�n Meteorol�gica Propia  
+Despliega sus datos del tiempo si usted tiene una estaci�n del tiempo y la ha configurado  
+Xastir para accederla.  
+  
+Alerta del Tiempo  
+Los despliegues alarmas recibidas, incluso las banderas de alertas, la alerta fuente/tipo,  
+destino alerta, expiraci�n, mensaje, y efectuada situaci�n. Esto datos  
+se usa por el resalto de condado, y no es particularmente humanamente-le�ble.  
+Usted generalmente puede deducir el estado y condado para la mayor�a de las alarmas.  
+  
+Tr�fico de mensaje  
+Muestras todo el tr�fico de mensaje mientras la ventana est� abierta. Incluye la fuente,  
+destino, interf�z, y mensaje. La opci�n de rango puede limitar este despliegue  
+a las estaciones cercanas, mucho como el mando del rango en boletines. Un rango de 0  
+causas todos los mensajes a ser desplegados.  
+  
+SobreHora  
+Muestras la cantidad de tiempo pasado subsecuentemente que Xastir fue iniciado.  
+  
+HELP-INDEX>Mapas Opciones y Seleccionar Mapas
+
+              Mapas Opciones y Seleccionar Mapas
+
+Mapas Opciones:
+
+Auto mapas (on/off)
+ Cuando cualquier mapa es encontrado, en el directorio de mapas
+(o cualquier directorio bajo �l) ser� desplegado,
+si el cae dentro de la regi�n de despliegue actual.
+
+Usted puedes agregar cualquier n�mero de niveles de directorios bajo
+el directorio del mapa principal para sus mapas.
+El Auto mapa pasar� por todos ellos y hallar� que mapa (o parte) debe desplegarse.
+
+Todos los Mapas se unir�n en el �rea de visi�n.
+Si usted tienes una cantidad grandes de mapas, mapas muy detallados
+o una computadora muy lenta, esto puede ser mostrado bastante lento.
+
+Cuando esta opci�n est� apagada, se desplegar�n mapas seleccionados
+con el selector de Mapas.
+
+Rejillas sobre Mapa (on/off)
+ Cuando est� en 'ON', esta opci�n desplegar� una l�nea de reja cada 10 grados.
+
+ Niveles de mapas (on/off)
+ Cuando est� en 'ON', esta opci�n intentar� filtrar fuera los datos cuando el 
+nivel de enfoque muesta grandes �reas. Esto no trabajar� con todos los mapas 
+pero trabajar� con los mapas generados de 'Tiger line maps'  en el sitio de 
+aprs.rutgers.edu.
+
+Areas rellena en colores (on/off)
+Esta opcion controla el relleno del vector del mapa. En ciertos casos, usted
+podria querer enliminar el relleno para ver el mapa bajo el tope de mapas.
+Los mapas son cargados en orden alfabertico por tipo, asi que renombrando
+mapas es un segundo pero la via es menos elegante archivar la vista deseada.
+
+Seleccionar Mapas
+Esta se presentar� con una lista de todos los archivos en su directorio de 
+mapas. Cualquier mapa que usted desear�as incluirlo en los datos desplegados, 
+simplemente tiene que pulsar el bot�n del rat�n sobre el nombre.
+Esto resaltar� el nombre del mapa, Usted puedes seleccionar cualquier n�mero de mapas.
+Pulsando en el bot�n "Aceptar"  se desplegar�n los mapas seleccionados.
+Oprimiendo el Bot�n de "Cancelar" abandonar�a cualquier cambio.
+
+Tambien hay botones de atajo para seleccionar todos de un cierto tipo de mapa,
+o de-seleccionar todos los mapas de una vez.
+
+Una nota sobre mapas: Muchos de los actuales mapas de vectores disponibles para
+los EE.UU. fueron creado en NAD 1927 datum, mientras Xastir y otros programas de APRS
+usan el WGS 1984 datum. 
+Si es enfocado hacia una �rea peque�a en el mapa la variaci�n del datum
+puede ser muy notable. Los mapas topo USGS tienen sus datum corregido por Xastir
+como ellos son desplegados,
+asi que la posiciones generalmente ser�n m�s exacta con los mapas topo.
+
+HELP-INDEX>Archivos Mapas, Dos, Windows, Pixmaps, geoTIFF y Condados WX  
+
+             Archivos mapas, Dos, Windows, Pixmaps, geoTIFF y Condados WX  
+
+Tipos de mapas  
+Xastir trabajar� con varios tipos archivos de mapas.
+Todo el Dos, Windows/MacAPRS[TM] son archivos de  Mapas que son soportados.
+
+Un nuevo formato de Pixmap se ha agregado en versi�n 0.3.2.
+Xastir tambi�n soportar� mapas para las Alertas de condados WX.  
+El �ltimo formato de mapa soportado es geoTIFF, tales mapas como son
+USGS DRG topo mapas.
+
+Locaciones de Mapas 
+Cualquier Dos, Windows/Mac o archivo Pixmap y geoTIFF, deben guardarse en el  
+Directorio de /usr/local/share/xastir/maps en su computadora.
+Usted puedes crear cualquier n�meros de directorios bajo este directorio
+para ayudar a separar sus datos.
+Por ejemplo usted puedes querer crear un directorio de USA.
+y despu�s uno por cada estado bajo el Directorio de USA.
+O tiene un directorio separado para DOS o Pixmaps y geoTIFF.
+
+
+                          /usr/local/share/xastir/maps/
+                                                /usa/
+                                                /usa/CO/
+                                                /usa/NJ/
+                                                /dos/CO/
+                                                /dos/NJ/
+                                                /pixmaps/CO/
+                                                /pixmaps/NJ/
+
+
+Pixmaps realmente son una combinaci�n de dos archivos, un archivo de dato con un,  
+pixmap (.xpm), gr�fico y un archivo de locaci�n (.geo).
+El archivo .xpm es una estructura de gr�fico normal,
+con una imagen de cualquier tipo.
+
+Usted puedes usar XView para convertir gif, jpg, y tif im�genes en este formato.
+El archivo geo es un archivo de dato que atar� la imagen a una locaci�n en el mundo.
+Aqu� est� un ejemplo de mi archivo world1.geo
+
+
+ARCHIVO   world1.xpm
+#          x          y        lon         lat
+TIEPOINT   0          0        -180        90
+TIEPOINT   640        320      180         -90
+
+Este es un archivo simple, con 4 componentes b�sicos.
+La primera l�nea especifica este archivo data .geo es usado,
+este archivo debe estar en el mismo directorio como el archivo de .geo.  
+
+La segunda l�nea muestra un comentario;
+cualquier l�nea con el car�cter como un "#" ser� ignorado.  
+  
+Las �ltimas dos l�neas son para conectar un pixel en la posici�n x,y  
+en la imagen a una posici�n lat y long en la mundo. Dos puntos unidos  
+son necesitado y debe estar cerca de la esquina izquierda superior 
+y la esquina derecha m�s abajo de la imagen.  
+  
+Usar archivo pixmap con xastir, use el selector de mapa y seleccione el archivo .geo
+para incluir la imagen en la vista del mapa actual.  
+
+Por razones de velocidad, otras l�neas de opciones pueden ser anexada
+en el archivo .geo.
+Aqu� algunos ejemplos del formato modificado:
+
+ARCHIVO         Agnes_Mountain.xpm.gz
+#
+#               X       Y       Lon             Lat
+#               ----    ----    -------------   -----------
+TIEPOINT        0       0       -121.00120491   48.37481943
+TIEPOINT        1337    1999    -120.87619806   48.24982052
+#
+#EDGES  BOTTOM          TOP             LEFT            RIGHT
+EDGES  48.24982052  48.37481943  -121.00120491  -120.87619806
+
+La l�nea EDGES especifica el min/max bordes del mapa. El mencionado
+mapa arriba es inclinado ligeramente, el cual es el porqu� los n�meros
+no corresponden a la esquina 'tiepoints' exactamente. Xastir usar� esa
+informaci�n saltar el mapa si no encaja en la vista actual.
+
+Mapas geoTIFF son una combinaci�n de dos archivos tambi�n:
+un archivo .tif y un .fgd. El archivo .tif es el actual data mapa.
+El archivo .fgd necesita solamente tener cuatro l�neas como estas:
+
+1.5.1.1   WEST BOUNDING COORDINATE:  -122.000000
+1.5.1.2   EAST BOUNDING COORDINATE:  -120.000000
+1.5.1.3   NORTH BOUNDING COORDINATE:  48.000000
+1.5.1.4   SOUTH BOUNDING COORDINATE:  47.000000
+
+Xastir usa esas cuatro l�neas en su calculaciones para determinar los puntos
+de la esquina del mapa, y si o no el mapa vuelve al actual punto de vista
+(asi que el puede decidir si saltarlo). Si su data mapa es un mapa topo USGS,
+el archivo .fgd podr�a ser le�damente disponible a usted.
+Una forma anexada en Xastir es la abilidad hacer traslaciones datum desde
+NAD 1927 a WGS 84 datum, el cual hace el mapa topo USGS mucho m�s posicionalmente
+exacto sobre la pantalla en Xastir.
+
+Mapas Condado WX  
+Todos los mapas Condado WX deben guardarse en el directorio de
+/usr/local/share/xastir/Counties.  Hay formatos diferentes para los mapas,
+pero de cualquier modo este directorio tendr� directorios (usted podr�as
+necesitar crearlos) bajo este  para cada estado (2 abreviaciones de letras).
+
+               /usr/local/share/xastir/Counties
+                                         /CO/
+                                         /CO/COPARK.map
+                                         /CO/CODOUGLA.map
+                                         /CO/COJEFFER.map
+                                         /CO/COZ001.map
+                                         /CO/COZ002.map
+                                         /CO/COZ003.map
+                                         /NJ/
+                                         /NJ/NJOCEAN.map
+                                         /NJ/NJBERGEN.map
+                                         /NJ/NJMONMOU.map
+                                         /NJ/NJZ001.map
+                                         /NJ/NJZ002.map
+                                         /NJ/NJZ003.map
+
+
+Aqui estan dos lugares en el Internet donde usted puedes obtener esos mapas:
+
+ftp://aprs.rutgers.edu/pub/hamradio/APRS/NWSCounties/
+http://home.att.net/~kg5qd1/Maps.html
+
+Como los mensajes NWS son recibidos, diferentes areas obtendr�n un tintado
+hacia las �reas designadas.
+Ellas son coloreadas para especificar diferentes tipos de alertas. 
+
+Los colores originales fueron:
+
+Cian para el asesor, amarillo para alerta del tiempo,
+rojo para advertencia, naranja para alerta cancelada, azul real para pruebas,
+y verde para niveles de indeterminadas alarmas.
+
+Con la �ltima versi�n de Xastir los colores pueden ser diferentes
+debido a un cambio mayor: 
+Las �reas que ahora son tintadas en lugar de relleno de color,
+y la dependencia en el tintado debajo los colores.
+
+Este cambio fue hecho asi que los mapas estando debajo de esto pueden
+mantenerse visible debajo en las �reas de alertas del tiempo. 
+Las alertas del tiempo podr�an ser fijada en on/off v�a el men� del mapa tambi�n.
+
+
+HELP-INDEX>Configurar Interfaces
+
+                           Configurar Interfaces  
+  
+Pulse el bot�n en Configurar luego en Interfaces  
+  
+Un di�logo de "Interfaces Instalados" debe aparecer. 
+Este di�logo le permitir�s a usted Agregar, Anular, y modificar las Propiedades 
+en varios dispositivos que usted puedes querer usar con Xastir.  
+  
+Las opciones actuales son:  
+TNC v�a el Puerto Serial
+TNC v�a un Puerto Serial con (GPS m�s cable HSP)
+GPS v�a un Puerto Serial
+Estaci�n Meteorol�gica v�a Puerto Serial
+Conexi�n a un Servidor en Internet
+TNC v�a la Uilidades del AX.25
+GPS Enlazado v�a el Servidor gpsd
+Estaci�n Meteorol�gica Enlazada a una RED
+TNC v�a un Puerto Serial con (GPS m�s AUX puerto)
+  
+Para agregar un dispositivo, pulse el bot�n de agregar. 
+Un di�logo "Elegir Tipo de Interfaz" aparecer�. 
+Pulse el bot�n en el tipo de dispositivo que le gustar�a agregar. 
+Luego pulse el bot�n de Agregar en el di�logo "Elegir Tipo de Interfaz". 
+Las propiedades para ese dispositivo aparecer�. 
+
+Rellene la informaci�n pedida y pulse el bot�n en Aceptar, anular el dispositivo, 
+pulse el bot�n en el dispositivo usted deseas anular y entonces pulse el bot�n Anular.
+Para modificar las propiedades de un dispositivo, 
+pulse el bot�n en el dispositivo usted deseas modificar, 
+luego pulse sobre el bot�n de propiedades. 
+
+Las propiedades para ese dispositivo aparecer�.
+Cambie la informaci�n que usted quieres y pulsar el bot�n en Aceptar.
+
+HELP-INDEX>Configurando el Serial sobre un TNC
+
+                 Configurando el Serial sobre un TNC
+
+SERIAL TNC CONFIGURACION
+
+Pulse el bot�n "Configurar" luego en "Interfaces" despu�s en "Agregar"
+despu�s en "Serial TNC" luego "Agregar" y por �ltimo en "Puerto TNC"
+
+Si usted tienes un TNC y planea usarlo con XASTIR seleccione "Puerto TNC".
+El valor por defecto no, es seleccionado.
+
+Ahora entre en el puerto que el TNC est�, es decir /dev/ttyS0 para com1
+
+Seleccione los valores del puerto que se acoplan a su TNCs velocidad del puerto.
+
+Entre en tres rutas de UNPROTO.
+
+Xastir asumir� los XX VIA la parte de la ruta de UNPROTO. Hay tres Rutas 
+permitidas para que su se�al sea escuchada si las condiciones son mala.
+Si cualquiera de �stos es llenado en XASTIR ciclar� a trav�s de uno de ellos
+a cada intervalo de transmision.
+
+Si usted est�s local, s�lo un WIDE2-2 puede ser una buena opci�n.
+Si usted est�s usando baja potencia y/o est�s distante de un digi entonces
+WIDE1-1,WIDE2-2 puede trabajar mejor.
+
+O si usted conoces el indicativo de su digi m�s cercano que usted
+puedes usar XXXCALL,WIDE2-2.
+La mayor�a de ustedes necesitar�n s�lo una ruta.
+
+Si usted est�s en una �rea remota y su se�al es dif�cil de conseguirla
+usted puedes necesitar m�s.
+
+Verifique con un grupo local y preg�ntele que ruta 
+puede ser mejor para su �rea. Algunas areas
+usan el flujo de protocolos m�s eficientes, en tales caso usted podr�a usar
+WIDE3-3 o WIDE1-1,WIDE3-3.
+
+Los archivos de Inicio y Salida del TNC. Estos campos especifican a nombre
+de archivo qie es localizado en el directorio /usr/local/share/xastir/config.
+Cada archivo es un archivo de texto estandar conteniendo algunos comandos que
+usted le gustaria enviarle a su TNC a la vez que el dispositivo es activado
+(Archivo de Inicio - Startup file) o de deshabilitar (shut down).
+
+Pulsando el bot�n "Aceptar" guardar�s sus cambios.
+Pulsando el bot�n en "Cancelar" guardar� la configuracion actual.
+
+HELP-INDEX>Opciones del TNC
+
+                   Opciones del TNC
+
+Permitir Transmisi�n (on/off)
+ Esto controla la transmisi�n de datos a trav�s del TNC. Usted puedes querer
+Simplemente escuchar en RF o si usted no es un HAM y no debes transmitir. Con
+Esta opci�n (el cual est� apagado por defecto) usted puedes controlar 
+transmisi�n de cualquier datos v�a RF. 
+
+Bit�cora (log) del TNC (on/off)
+ Si est� en 'ON', un archivo de log (Bit�cora) se crear� en el directorio logs. 
+El archivo se llamar� tnc.log y se a�adir� con toda la informaci�n o�da v�a RF.
+
+Transmitir Ahora!
+ Este transmitir� su position/info de su estacion cuando usted pulses el bot�n 
+en esta selecci�n. No transmitir� si la opci�n "Serial TNC" no est� seleccionada
+(en la secci�n Configurar/Interfaces/Agregar/Serial TNC/Adregar/Puerto TNC)
+o si la opci�n arriba mencionada permitir transmisi�n est� fijada en off.
+
+HELP-INDEX>Configurar TNC via Serial c/GPS en HSP cable o AUX puerto
+
+            Configurar TNC via Serial c/GPS en HSP cable o AUX puerto
+
+Esos tipos de interfaces h�bridos implementan las opciones de ambos serial TNCs
+y GPSs. Por favor consulte la configuraci�n de ayuda para ambos serial TNCs y
+serial GPSs para m�s detalles de informaci�n sobre la configuraci�n
+de esos dispositivos.
+
+HELP-INDEX>Configurando el AX.25 TNC
+
+                 Configurando el AX.25 TNC
+
+AX.25 TNC CONFIGURACION    
+    
+Esta secci�n cubre agregando o modificando AX.25 TNC dispositivos.
+AX.25 dispositivos pueden sea cualquier dispositivo que use controladores AX.25
+en Linux.
+
+�ste es un controlador de nivel del n�cleo (kernel),
+y el dispositivo como un Baycom o una tarjeta de sonido como m�dem 
+puede usarse como un TNC.
+Estos dispositivos deben ser configurado y correrlo
+ antes de que Xastir pueda usarlos.    
+    
+Seleccionando Activar en Inicio, le dir� a Xastir que busque este dispositivo
+y fije las comunicaciones con �l cuando el programa de su primer inicio.
+    
+Seleccionando Permite Transmitir, le dir� a Xastir que cualquier
+salida de datos de RF puede ser enviado a este dispositivo para la transmisi�n.
+    
+Escoja la operaci�n correcta de IGate para este dispositivo.
+Usted puedes tener varios dispositivos TNC, y esta opci�n puede ser diferente 
+por cada dispositivo. Si usted no est�s ejecutando un IGate 
+usted puedes dejar �sta opci�n predefinida de "Desactivar todo el tr�fico".    
+    
+Entre el nombre del Dispositivo AX.25 
+que usted especific� en el archivo del axports para este dispositivo.
+    
+Entre en tres rutas de UNPROTO. Xastir asumir� el XX VIA parte de la ruta
+del UNPROTO. Hay tres rutas permitidas para que su se�al sea escuchada
+si las condiciones son mala.
+
+Si cualquiera de �sas son llenada en XASTIR ciclar� a trav�s de uno de ellos 
+en cada momento de la transmisi�n. Si usted es local, s�lo un
+WIDE2-2 puede ser una buena opci�n.
+
+Si usted est�s usando baja potencia y/o est�s distante de un digi
+entonces WIDE1-1,WIDE2-2 pueden trabajar mejor.
+O si usted sabes el indicativo de su digi m�s cercano
+a usted puedes usar XXXCALL,WIDE2-2. La mayor�a de ustedes necesitar�n s�lo una ruta.
+
+Si usted est�s en una �rea remota y su se�al es dif�cil de conseguir usted puedes 
+necesitar m�s. Verifique con un grupo local y preg�ntele qu� 
+ruta puede ser mejor para su �rea. Algunas areas
+usan el flujo de protocolos m�s eficientes, en tales caso usted podr�a usar
+WIDE3-3 o WIDE1-1,WIDE3-3.
+
+    
+NOTA: Para usar dispositivos AX.25 con Xastir usted necesitar�s ejecutar el programa como "ra�z" ("root").
+
+Si usted quieres ejecutar Xastir como otro usuario usted necesitar�s
+fijar el suid en ON  en el archivo de programa de xastir.
+El orden siguiente como ra�z debe fijar esto para usted. chmod a+s /usr/local/bin/xastir.
+
+como con cualquier programa que este corriendo de esta forma, por favor note que
+esto puede ser considerado como una seguridad de riesgo, como el programa no ha sido
+probado para explotar. Uselo en este modo en un multi-usuarios en su propio riesgo!
+
+HELP-INDEX>C�mo uso yo mi GPS con Xastir?  
+  
+                             Usando UN GPS con Xastir  
+  
+Para usar una unidad de GPS con Xastir usted tienes tres opciones,
+un GPS Conectado a una red o a un serial GPS,
+o a un serial GPS con un TNC y cable HSP.
+
+                            GPS conectado a una red:   
+  
+La ventaja de usar un GPS conectado a una red
+es que usted puedes compartir el GPS con otros programas.   
+Xastir usa un programa llamado gpsd para hacer una connexi�n a una red.   
+  
+Este programa entrega datos de GPS normales en un s�calo de conexi�n de redes.
+Algunas versiones tambi�n permiten correcci�n de GPS v�a un servidor de Internet.   
+  
+Una vez que usted tengas bajado e Instalado el gpsd en su m�quina
+(u otra m�quina), usted puedes fijar el Xastir
+para conectar a �l creando una interfaz.   
+  
+Pulse el bot�n en "Configurar" y despu�s en "Interfaces".
+Cuando el di�logo de Interfaces aparezca Pulse el bot�n de "Agregar".   
+Un nuevo di�logo aparecer� con los tipos de Interfaces,
+Elegir en "Enlazado GPS (via el gpsd)", y luego pulse el bot�n en Agregar.
+
+Hay 4 opciones a elegir.
+Primero entre el nombre del servidor del programa gpsd que est� ejecutando.   
+Si est� en el mismo computador que Xastir entonces  entre localhost.   
+  
+Luego entre en el puerto que usted puso el programa gpsd para escuchar.
+Si usted seleccionas "Activar en Inicio", Xastir tratar� de conectar
+al programa gpsd tan pronto se inicia y tan pronto usted hagas click
+en el bot�n "Aceptar". La �ltima opci�n, si seleccionado,
+intentar� hacer la reconexi�n al gpsd si un fallo fu� encontrado.  
+  
+Serial GPS: Un serial GPS es cualquier unidad de GPS normal 
+que conecte al puerto serial y transmita datos en el NMEA normal. 
+Permitir a Xastir a usar este tipo de GPS pulse el bot�n
+de "Configurar" luego en "Interfaces". Cuando el di�logo
+de Interfaces aparezca pulse el bot�n de "Agregar".
+
+Un di�logo con los tipos de Interfaces aparecer�,
+Pulse sobre el "Serial GPS" y despu�s en el bot�n Agregar.   
+  
+               Unas pocas opciones para fijar.
+               
+Primero entre el puerto serial en donde el dispositivo
+est� conectado (como "/dev/ttyS1 (COM2)"). 
+Pr�ximo si usted seleccionas "Activar en Inicio",
+Xastir intentar� inicializar el "serial GPS" cuando �l se
+inicie y cuando usted pulses el bot�n "Aceptar".
+Las pr�ximas opciones pondr�n la velocidad del puerto serial y modo.   
+  
+Para la mayor�a de las unidades de GPS los valores predefinidos est�n bien.
+Pero Chequee usted el manual del GPS s�lo en caso de dudas.
+
+HSP TNC/GPS: 
+Mire en "C�mo uso yo mi TNC con Xastir?"  
+
+
+HELP-INDEX>Configurando el Puerto/GPS
+
+              Configurando el Puerto/GPS
+
+Pulse el bot�n en "Configurar" luego en "Interfaces" luego en "Agregar" 
+elija "Serial GPS" luego "Agregar" despu�s ajuste los par�metros del Puerto/GPS.
+
+Para usar una posici�n "Serial GPS" en el puerto serial,
+pulse el bot�n en Posici�n Serial GPS.
+Este puerto puede especificarse en la Posici�n "S�lo el puerto de GPS".
+Usted puedes usar un dispositivo serial como /dev/ttyS1 (COM2).
+
+Si usted tienes un cable de HSP que le permitas compartir el Serial TNC con una 
+unidad GPS usted puedes seleccionar "Serial TNC c/GPS m�s (Cable HSP).
+�ste es un cable especial y el m�o no trabaja en todas las combinaciones
+de computadores/GPS/TNC.
+
+Ahora usted puedes escoger un GPS muestreo y TNC relaci�n, Recuerde usarlo con 
+precauci�n aqui, que sean amigables por sus estaciones cercanas.
+
+�Activar el uso de los datos de GPS seleccione el "Uso Posici�n GPS?" opci�n.
+Con esta selecci�n hecha la unidad de GPS pondr� al d�a su posici�n.
+Si esto no se selecciona la posici�n actual vendr� desde la locaci�n 
+en configuraci�n informaci�n de la Estaci�n.
+
+Cuando active los datos de GPS tambi�n pondr�s al d�a 
+la posici�n en configuraci�n de informaci�n de la Estaci�n.
+
+Cuando use el GPS sus paquetes cambian, usted obtendr�s una estaci�n m�vil con 
+curso y velocidad a�n cuando la suya no est� moviendose (yo puedo cambiar esto 
+despu�s a una opci�n).
+
+El tiempo del GPS le permitir� seleccionar proporciones de la relaci�n
+de muestra  para el GPS y sobre pasar el tiempo del paquete normal 
+por transmitir su estaci�n.
+
+Si usted est�s estacionado entonces use 10 minutos.
+Si usted est�s haciendo alg�n especial/rastreo etc..
+use la selecci�n que encajar�n mejor los datos que usted necesitas.
+Por favor no haga sobre transmisi�n, si usted no lo necesitas hacer. 
+
+
+Pulsando el bot�n "Aceptar" guardar�s sus cambios.
+Pulsando el bot�n en "Cancelar" guardar�s las configuraciones actuales.
+
+HELP-INDEX>C�mo uso yo mi TNC con Xastir?  
+  
+                Usando UN TNC con Xastir  
+  
+Para usar un TNC con Xastir usted tienes tres opciones,
+un "serial TNC" o un "Serial TNC c/GPS m�s (cable HSP)"
+o un TNC Conectado a una red "AX.25 TNC".
+
+AX.25 o un TNC en una red:
+Este tipo de tnc le permitir� compartir el TNC con otros programas.
+Al usarlo usted debes tener la librer�a AX.25 , y el
+HamRadio soporte instalado en el n�cleo (kernel) de su Linux OS.
+
+Ellos son un poco m�s dif�ciles de configurar para usarlo 
+pero hay muy buenas opciones y ventajas en su uso. 
+
+Usando el soporte del "AX.25 TNC", usted tienes varios
+dispositivos que usted puedes usar con Xastir.
+Algunos de ellos son serial TNC que usan AX.25,
+tarjetas de sonidos como TNC's, Baycom, etc.  
+  
+SERIAL TNC: SERIAL TNC con (GPS m�s cable HSP):
+
+HELP-INDEX>Configurando la conexi�n de Internet
+
+             Configurando la conexi�n de Internet
+
+La conexion a los Servicios de Internet le permite a usted enviar
+y recibir datos desde y hacia todo el mundo.
+
+Para configurar el Internet usted necesitar�s conocer un host y un n�mero de 
+puerto. El host predefinido es www.aprs.net y el puerto es 10151. Usted puedes 
+escoger otros pero este debe trabajar. Una Palabra de paso v�lida le permitir�
+a su estaci�n transmitir por el Internet.
+
+Permitir� a su estaci�n salir de una I-Gate y conseguir retransmitir v�a RF.
+Para conseguir un c�digo de paso usted necesitar�s contactar con Frank, 
+email fgiannan at earthlink.net, Enviarle su nombre, Indicativo, etc.
+
+Una vez �l verifique su estado como un HAM �l puede enviarle su c�digo. 
+Usted puedes mantenerse recibiendo y transmitiendo datos v�a el 
+Internet aunque usted no tengas un passcode. Pero sin el c�digo de paso sus 
+datos no ser�n directamente retransmitido v�a RF.
+Cualquiera que est� conectado al Internet directamente conseguir� su mensaje.
+
+Host1 y Host2 son servidores opcionales que ser�n contactado si el servidor 
+primario est� fuera. Cada servidor ser� intentado dos veces, siguiendo al 
+pr�ximo si la conexi�n fracasa.
+
+Si usted quieres que XASTIR reconecte despu�s de una conexi�n perdida
+en el net entonces seleccione la opci�n "Reconecte en fracaso de la RED?"
+en la que por defecto est� en ON.
+
+Las �ltimas opciones son para preparar su estaci�n para ser un IGate. Esto 
+permite a su estaci�n con su c�digo de paso simplemente actuar como una puerta 
+(gateway), pero en lugar de otra banda sus datos atravesar�n el Internet.
+Esta opci�n no debe ser tomada ligeramente.
+
+Primero usted debes coordinar con otros 
+en su �rea para que usted puedas agregar verdadera informaci�n que puede estar 
+perdiendo. Usted tambi�n debes avisar a Steve sobre esto. Esta versi�n puede 
+enviar informaci�n recibida desde su TNC hacia el Internet y transmitir� 
+cualquier mensaje procedente de Internet a trav�s de su estaci�n via RF.
+
+Enviar� s�lo datos v�a RF si usted tienes el opci�n seleccionada de transmisi�n 
+de mensajes. S�lo estaciones que usted has o�do (v�a RF) en las �ltimas horas 
+tendr�n mensajes enviados a ellos en �sta v�a.
+
+Note tambi�n usted es responsable por los datos transmitidos
+por su estaci�n asi que tenga cuidado con esta 
+opci�n (otros pueden enviarle mensajes que usted no quieres transmitir).
+
+Si usted quieres ver que su I-Gate esta haciendo encienda la opci�n Log I-Gate 
+de transacciones. esto construir� un archivo de igate.log en su "logs" los 
+directorios  mostrar�n todos los datos pasados de RF local hacia la red con 
+l�nea que tiene "IGATE-RF->NET": y conteniendo todo los datos.
+
+Tambi�n mostrar� todo el tr�fico entrante desde la red con "NET->RF-IGATE:".
+Note aqu� usted no ver�s la completa salida de paquetes, como su estaci�n y ruta son 
+asumida. Solamente mostrar� el data como un mensaje de tercera persona.
+
+
+Pulsando el bot�n "Aceptar" guardar�s sus cambios.
+Pulsando el bot�n en "Cancelar" guardar�s los cambios actuales.
+
+
+APRS[tm] es una Marca de f�brica de Bob Bruninga, 
+su p�gina est� en "http://web.usna.navy.mil/~bruninga/aprs.html"
+
+
+HELP-INDEX>Opciones de RED
+
+                   Opciones de RED
+
+Permitir Transmisi�n (on/off)
+Esto controla la transmisi�n de datos a trav�s del Internet.
+El valor por defecto es apagado.
+Con esto en (off) apagado ning�n dato ser� enviado al Internet.
+
+Bit�cora de Internet (on/off)
+ Si esto est� en 'ON', un archivo log se crear� en el directorio logs. El archivo
+se llamar� net.log y se a�adir� con toda la informaci�n o�da v�a el Internet.
+
+Transmitir Ahora!
+ Esto transmitir� su position/info de la estaci�n cuando usted pulses el 
+bot�n en esta selecci�n. No transmitir� si la opci�n est� apagada en Permitir 
+transmisi�n.
+
+HELP-INDEX>Configurando una Estaci�n Meteorol�gica sobre un Puerto Serial.
+
+Configurando una Estaci�n Meteorol�gica sobre un Puerto Serial.
+
+Configurar el puerto serial para su estaci�n Meteorol�gica. A los valores 
+comunes de /dev/ttyS0 (COM1) o /dev/ttyS1 (COM2) pueden ser usado.
+
+Seleccionado "Activar en Inicio" le dir�s a Xastir buscar este dispositivo y
+fijar comunicanciones con el cuando el programa se inicie primero.
+
+Ahora fije el bps bajo el puerto de configuraci�n, y los par�metros bajo el
+puerto estilo. El seteo del puerto estilo 8N1, es usado para 8 bitios de datos,
+No paridad y 1 bitio de parada (stop bit). 7E1 es usado para 7 bitios de datos,
+even paridad y 1 bitio de parada. 7O1 es usado para 7 bitios de datos, odd paridad
+y 1 bitio de parada. Esos par�metros deben de machar con su estaci�n Meteorol�gica.
+El tipo de opci�n de data le perimitir� sobrepasar que tipo de serial data el progrma
+ver�. La forma de auto-detecci�n primero buscar� datos del tiempo en un modo binario
+como lo usa el Radio Shack WX-200. Si no dato binario es encontrado,
+Xastir buscar� un tipo ASCII de estaci�n Meteorol�gica (como la Peet Bros.)
+
+HELP-INDEX>Configurando una Estaci�n Meteorl�gica en la RED
+
+Configurando una Estaci�n Meteorl�gica en la RED
+
+Xastir puede usar servicios de dato de una estaci�n Meteorol�gica
+tales como la wx200d. La wx200d le permitir�s varias conexiones de redes,
+asi compartiendo el informe del tiempo con varios programas o computadores.
+
+Entre el nombre del host (o la direcci�n num�rica IP) y el n�mero del puerto
+de la estaci�n Meteorol�gica servidora que usted quieres contactar.
+
+Seleccionado "Activar en Inicio" le dir�s a Xastir buscar este dispositivo y
+fijar comunicanciones con el cuando el programa se inicie primero.
+
+Seleccionado "Reconectar en fallo de la RED" le dir� a Xastir tratar de reconectar cuando
+el data conexi�n haya fracasado.
+Como antes el tipo de data sobrepasar� el auto-detecci�n.
+
+HELP-INDEX>Di�logo info estaci�n - b�squeda FCC y RAC  
+  
+                  Di�logo info estaci�n - b�squeda FCC y RAC  
+  
+Info estaci�n desplegar� cualquier dato descifrado por Xastir.
+Actualmente dos o tres botones aparecen aqu� adem�s del bot�n Cerrar.
+
+Los botones de Anular Rastro anular�n cualquier l�nea de rastro para esa estaci�n 
+que es actualmente guardada o en el despliegue de mapa.
+
+Env�e mensaje abrir� la ventana de mensaje y le permitir� enviar a mensje a esta estaci�n.
+El llenar� en el indicativo por usted. 
+
+Si el banco de datos de FCC se instala,
+un bot�n de B�squeda en el Banco de datos FCC aparecer� en este Di�logo.
+Si el RAC (RadioAficionados de Canad�) banco de datos se instala, 
+un bot�n de b�squeda RAC Banco de datos aparecer� para indicativo 
+que empiezan con una "V".  
+
+El archivo FCC y  RAC deben colocarse en el directorio
+/usr/local/share/xastir/fcc, y el caso es importante!  
+  
+Usted puedes usar este bot�n para agregar los nombres de estaciones
+y dir�jase al Di�logo de Estaci�n Info. 
+
+Para usar la b�squeda de FCC bajelo de aqui:
+ftp://ftp.fcc.gov/pub/XFS_AlphaTest/amateur/appl.zip
+
+ o el Nuevo banco de datos en:
+ftp://ftp.fcc.gov/pub/Bureaus/Wireless/Databases/uls/complete/l_amat.zip  
+  
+(El �nico archivo necesitado forma este 40Meg zip es el archivo EN.dat)  
+  
+* * * * NOTA para usar el NUEVO archivo base de datos debe ordenarse primero!!! * * * *
+
+�Aseg�rese que usted tienes espacio en el disco suficiente 
+para esto como el archivo es GRANDE!  
+
+Para ordenar el archivo: sort +4 -t \ | EN.dat >EN.dat.ordenado  
+rm EN.dat  
+mv EN.dat.ordenado EN.dat  
+  
+Para usar la b�squeda de RAC b�jelo de: ftp://ftp.rac.ca/pub/cdncaldb.zip  
+Xastir crear� archivos �ndice por cada archivo del banco de datos en el inicio.  
+  
+Si un archivo de indicativo es eliminado mientras Xastir est� corriendo,
+crear� o reconstruir� el �ndice en la pr�xima b�squeda. No se manejan prefijos especiales.
+
+HELP-INDEX>Opciones de Despliegue
+
+                        Opciones de Despliegue
+
+Estas opciones le permitir�n desplegar datos sobre la estaci�n alrededor del 
+�cono de las estaciones en el mapa.
+
+Indicativo (on/off)
+ Cuando est� en 'ON', todo los indicativos de las estaciones se desplegar�n.  
+Si este esta en 'OFF' los indicativos no se desplegar�n sobre el mapa.
+
+Para viejas estaciones el s�mbolo es dibujado
+como fantasma y en su orientaci�n estandar.
+
+Corespondiendo al arrastre que son subrayado m�s que s�lido y todo el data
+excepto el indicativo desaparece de la pantalla.
+
+Callsign (on/off)
+Determines if the callsign is displayed on the right side of the symbol.
+
+Altura (on/off)
+ Cuando est� en 'ON', una l�nea azul de datos aparecer�  sobre el indicativo.  
+Este desplegar� la �ltima altitud conocida de la estaci�n.
+
+Curso (on/off)
+ Cuando est� en 'ON', una l�nea verde de dato aparecer� debajo del indicativo. 
+Esto desplegar� el �ltimo curso conocido (en grados) de la estaci�n que est� en 
+movimiento.
+
+Velocidad (on/off)
+ Cuando est� en 'ON', una l�nea roja aparecer� debajo del indicativo (o curso). 
+Esto despliegar� la �ltima velocidad conocida de la estaci�n que est� en 
+movimiento.
+
+Dist/curso (on/off)
+ Cuando est� en 'ON', se desplegar�n dos l�neas de informaci�n en el lado 
+izquierdo del �cono de la estaci�n. La l�nea de arriba tendr� la distancia 
+de su estaci�n hacia esta estaci�n. La l�nea de abajo tendr� el curso desde su 
+estaci�n hacia esta estaci�n. 
+
+Rastros de estaciones (on/off)
+ Cuando est� en 'ON', cualquier estaci�n en movimiento arrastrar� una l�nea 
+coloreada con las �ltimas 100+ localizaciones. Cuando la estaci�n se pone vieja 
+el �cono es opaco la l�nea de rastro se volver� intermitente en lugar de la 
+l�nea cont�nua.
+
+
+Estaci�n Potencia/Ganancia (on/off)
+ Cuando est� en 'ON', se desplegar�n C�rculos de Poder/Ganancia.
+ Sobrepasando los c�rculos indicado que las estaciones est�n te�ricamente
+ con simple rango uno del otro.
+ Esto es aproximandaemnte exacto, especialmente in �reas de terreno variable.
+ 
+Rastreo Estaci�n
+ Traer� una caja abierta similar a la opci�n localizar estaci�n. Usted puedes 
+entrar  todos o parte del indicativo. Al seleccionar "Rastrear Ahora!" El 
+despliegue saltar� a la posici�n de la estaci�n (si es encuentrada). Cuando 
+nuevos datos para esa estaci�n son encuentrados el despliegar� el rastro a lo largo 
+de esa estaci�n.
+
+ El bot�n "Borrar Rastro" limpiar� todo el rastro.
+
+ El bot�n de "Cancelar" terminar� sin cambios realizados.
+
+Informe del Tiempo (on/off)
+Cuando est� en 'ON', los �ltimos datos del tiempo 
+(velocidad/curso/r�faga,Humedad,temperatura,viento) 
+ son desplegados.
+
+S�mbolos (on/off)
+Determina si los s�mbolos podr�an ser dibujado en el mapa.
+
+Rotar S�mbolos (on/off)
+Si 'ON', algunos s�mbolos deber�an cambiar su orientaci�n y mostrar la
+direcci�n en la cual una estaci�n m�vil se est� moviendo.
+
+HELP-INDEX>Mensajes
+
+                        Mensajes
+
+Enviar mensaje a y Mensajes De grupo abierto
+�stos son muy similares. El "Enviar mensaje a" enviar� sus mensajes a una 
+estaci�n y recibir� s�lo forma de datos de la estaci�n. Los mensajes de grupo 
+son m�s en general usted puedes recibir cualquier mensaje para el grupo y usted 
+enviar�s sus mensajes a ese nombre de grupo. Los mensajes de grupo no pueden 
+trabajar mejor por el momento hay varios problemas que necesitan ser 
+solucionado. Sin embargo, volviendo atr�s al
+uso de estas pantallas. 
+
+Cada una de estas pantallas contienen una caja de mensaje, una l�nea de 
+llamada, una l�nea de mensaje, y varios botones. Usted debes primero entrar  la 
+llamada del grupo o estaci�n que usted quieres avisar. Una vez que eso se hace 
+cualquier nuevo mensaje que ha entrado de esa estaci�n hacia usted ser�s 
+desplegado. Si la estaci�n est� envi�ndole informaci�n y ninguna ventana de 
+mensaje est� abierta �l abrir� autom�ticamente a una nueva ventana (hasta 10) 
+con esos indicativos de estaciones para usted. Usted puedes ahora entrar un 
+mensaje en la l�nea de mensaje. El mensaje puede ser m�s largo que la l�nea de 
+mensaje, y la m�xima salida es aproximadamente 250+ car�cteres. Una vez su 
+mensaje es entrado, pulsando el bot�n "Enviar Ahora!" mandar� su mensaje.
+
+El bot�n "Enviar Ahora!" se pondr� opaco hasta que su mensaje sea completamente Reconocido.
+Cualquier mensaje que usted recibas ser� ordenado por la l�nea # y ser� puesto 
+en la ventana de mensaje. Si usted est�s en un modo de grupo cada l�nea 
+desplegar� el indicativo de donde el mensaje se envi� seguido por el propio 
+mensaje. Los mensajes de grupos actuales son ordenados por llamada y despu�s   
+la l�nea #. Cuando usted hayas enviado el mensaje pulsando el bot�n de "Cerrar" 
+cerrar� la ventana.
+
+Dos otros botones son tambi�n disponible. El bot�n "Nuevo Indicativo" 
+le permitir� mirar datos viejos que una estaci�n ha enviado.
+Teclee el indicativo y pulse en este bot�n, cualquier 
+informaci�n vieja ser� desplegada.
+Usted tambi�n puedes usar este bot�n para cambiar el indicativo de la estaci�n
+con la que usted est�s hablando.
+Entre el nuevo indicativo y pulse el bot�n. El bot�n de "Borrar Mensajes"
+limpiar� cualquier mensaje desplegado en la ventana de mensajes.
+
+
+Borrar todos los mensajes salientes
+ Esto limpiar� todo los mensajes no-conocidos que usted has enviado.
+
+Auto Contestaci�n de Msj
+Esto encender� una contestaci�n autom�tica
+cuando un mensaje entrante se recibe.
+
+Fijar Mensaje en  contestaci�n Autom�tica
+ Esto fijar� un mensaje que se enviar� en ausencia autom�ticamente.
+
+HELP-INDEX>Limpiando el despliegue de l�nea de rastros
+
+            Limpiando el despliegue de l�nea de rastros
+
+Pulse el bot�n en "Archivo" y despu�s "Borrar Todo rastro". Esto limpiar� 
+todo el dato de la l�nea de rastreo del banco de datos de la estaci�n y 
+actualiza la pantalla.
+
+HELP-INDEX>Limpiando el despliegue de estaciones
+
+             Limpiando el despliegue de estaciones
+
+Pulse el bot�n en "Archivo" y luego el bot�n "Borrar Toda las Estaciones". Esto 
+limpiar� todo los datos del banco de datos de las estaciones excepto la suya.
+
+HELP-INDEX>Reenviando un log (Bit�cora) 
+
+                     Reenviando una Bit�cora
+
+Pulse el bot�n en "Archivo" y despu�s en "Abrir Bit�cora"
+una ventana de selecci�n de archivo se desplegar�.
+
+Usted puedes usarlo hojear su unidad de disco duro y seleccionar cualquier archivo
+que contenga un TNC datos raw  como aqu�llos creados por el TNC y opciones de red.
+
+Su estaci�n todav�a funcionar� de la misma manera, recibiendo y transmitiendo.
+Y debe haber una palabra de advertencia aqu�, si su dato contiene una sessi�n 
+de mensaje y usted tienes su estaci�n lista para transmitir, responder� al 
+archivo como si el dato fu� recibido sobre el TNC o Internet. 
+
+HELP-INDEX>Localizando una Estaci�n
+
+                  Localizando una Estaci�n
+
+Pulse el bot�n sobre "Visualizador" luego en, "Localizar Estaci�n"
+o sobre el bot�n de "Desplegar" luego en "Estaci�n Rastreo" una ventana se abrir�.
+Usted puedes ahora entrar una estaci�n o parte de una estaci�n. Por 
+defecto buscar� un macheo exacto (llamada completa, no parcial) y no es caso 
+sensible. Si usted est�s buscando un macheo parcial, "Macheo Exacto" podr�a no 
+ser seleccionado.
+
+Realmente usted puedes usar esto para localizar una estaci�n o un objeto. Qu� es
+donde nosotros venimos a la opci�n "Macheo Sensible". Yo he notado que algunos 
+objetos est�n en caso mixto o min�scula. Con "Macheo Sensible" seleccionado, 
+el localizador buscar� may�scula y min�scula cuando usted la entr�. Si
+"Macheo Sensible" no se selecciona, el localizador asumir� cualquier caso que usted 
+teclees es may�scula y investigar� en eso. Pulsando el bot�n "Localizar Ahora!"
+centrar� la primera estaci�n encontrada en el centro de su pantalla
+al nivel del enfoque actual. Pulsando el bot�n "Cancelar" cerrar� la ventana.
+
+HELP-INDEX>Creando y usando Salto a Localizaciones  
+  
+                     Creando y usando Salto a Localizaciones  
+  
+Pulse el bot�n "Visualizador", luego en "Saltar a la posici�n" una ventana aparecer�.
+Si �sta es la primera vez usted has usado este di�logo no tendr�s ninguna entrada en �l.
+Agregar una posici�n en la lista de posici�n vaya al �rea del mapa principal 
+y enfoque el nivel que usted quieres usar.
+
+Entre un �nico nombre en el �rea "Nombre de Nueva localizaci�n",
+luego pulse el bot�n agregar.
+Su entrada se agregar� a la lista (en orden alfab�tico).
+Usted puedes agregar tantas locaci�n de mapas que usted quieras de esta manera.
+
+Para usar uno de la posici�n pulsar el bot�n en el nombre de la posici�n 
+y pulsar el bot�n  "IR!", el mapa principal entonces mostrar� esa posici�n. 
+
+Usted puedes anular una posici�n similarmente pulsando el bot�n 
+sobre el nombre de la posici�n y luego el bot�n "Anular".
+
+HELP-INDEX>Rastreando una Estaci�n  
+  
+Rastreando una Estaci�n  
+  
+Pulse sobre el bot�n de "Desplegar" luego en "Rastreo Estaci�n".
+Entre en el indicativo para rastrear (todos o parte) luego pulse el bot�n "Rastrear Ahora!".
+Como la estaci�n lo mueve ser� centrado en la ventana del mapa principal.
+Dejar de rastrear esta estaci�n pulsar el bot�n  "Anular Rastro".
+
+HELP-INDEX>Tr�fico de mensajes
+  
+    Tr�fico de todos los mensajes
+    
+Pulse sobre la opci�n de "Tr�fico de Mensajes"
+luego un di�logo se abrir� e iniciar� el Monitoreo
+de todas las estaciones alrededor del mundo, en chat o enviando
+mensaje de prueba etc.
+  
+HELP-INDEX>Imprimiendo
+  
+              Imprimiendo la Pantalla del Mapa  
+  
+Xastir puede imprimir el �rea de dibujo en cualquier blanco y negro o color.  Hace  
+esto primero descargando la imagen a un archivo XPixmap en disco, entonces usando una  
+herramienta externa para convertirlo al posdata, balancearlo, rotarlo, prevista, entonces la impresi�n  
+.  Usted debe tener su sistema que configure la impresi�n para manejar posdata (normalmente  
+esto requiere Ghostscript y un filtro de impresi�n instalados, as� como lp o lpr  
+imprime spoolers). Usted tambi�n debe tener las herramientas siguientes instaladas para esta  
+capacidad:  Herramientas de ImageMagick (espec�ficamente "convertido"), "Ghostscript",  
+Conjuntos de caracteres de Ghostscript, y "gv". Una vez todos esos paquetes son instalando y  
+funcional, usted debe una "gv" ventana sobre salte brevemente despu�s que usted le diga a  
+Xastir crear un archivo de impresi�n.  De all� usted puede ver la imagen impresa, y  
+si aceptable, diga a "gv" imprimirlo.  Note que algunas veces cambiando a un blanco  
+el fondo predefinido para los mapas se recomienda, dependiendo de qu� mapas usted tienen  
+visualizable.  Esto puede ahorrar le grandemente la tinta.  
+  
+HELP-INDEX>Creando Captura Instant�nea Autom�ticamente
+
+             Creando Captura Instant�nea Autom�ticamente
+  
+Xastir tiene la capacidad para crear captura instant�nea autom�ticamente en pantalla del mapa  
+recurriendo al algo b�sico.  Este periodo de tiempo es actualmente fijado por cinco  
+minutos.  Asumiendo que usted tiene "convertir" de la herramienta de ImageMagick  
+instalado, Xastir crear� un archivo de formato XPM en /var/tmp, entonces lo converte,  
+al archivo de PNG /var/tmp/xastir_snap.png. Este archivo es �til para ponerlo  
+en p�ginas web para mostrar una imagen viva de lo que est� en su pantalla de Xastir.  Habilite  
+este rasgo v�a el "Archivo->Activar PNG Instant�nea".  
+  
+
+HELP-INDEX>Tabla de S�mbolo
+
+Eso son los s�mbolos que usted puedes selecionar para su estaci�n bajo la
+"Informaci�n de la Estaci�n" men� de configuraci�n.
+
+La lista actual puede ser encontrada en el APRS Referencia en el cual usted
+puedes obtenerlo desde http://www.tapr.org/
+
+                   Tabla de s�mbolo
+
+S�mbolo Grupo/                          Grupo/
+
+!       Tri�ngulo w/!                   Tri�ngulo w/!
+"       Lluvia Nube                     Lluvia Nube
+#       Digi                            DIGI         
+$       S�mbolo  telef�nico             $ S�mbolo
+%       DX                              DX 
+&       GATE-HF                         GATE
+'       Avi�n peque�o                   Avi�n Ca�do
+(       Nube                            nube
+)       TBD                           
+*       NIEVE Hojuela                   NIEVE Hojuela  
++       Cruz roja                     
+,       Inverso  L
+-       w/omni casa                  
+.       X peque�a
+/       Punto rojo                       
+0       0 en una caja                    C�rculo
+1       1 en una caja
+2       2 en una caja
+3       3 en una caja
+4       4 en una caja
+5       5 en una caja
+6       6 en una caja
+7       7 en una caja
+8       8 en una caja
+9       9 en un GAS de la caja
+:       Bombero                         ?
+;       Tienda                          tienda
+<       motocicleta                     Bander�n
+=       M�quina de tren                  
+>       Autom�vil                       autom�vil 
+?       Antena POS                      ? en una caja
+@       HURRICAN/TORMENTA               HURRICAN/TORMENTA 
+A       Primero auxilio                 Caja
+B       BBS                             Blowing Nieve 
+C       Canoa                         
+D       D en un c�rculo                 
+E       E en un circulo                 Pila de Humo
+F       F en un c�rculo                 
+G       Reja Antena Cuadrada            ?
+H       Hotel/Cama                     
+I       TCP/IP                          ?
+J       J en un c�rculo                 descarga
+K       Escuela                  
+L       Casa Iluminada                  Casa Iluminada
+M       Mac                           
+N       NTS                             ?
+O       Globo                       
+P       Carro  de  Patrulla             Rx
+Q       Circle con C�rculos             C�rculo con C�rculos
+R       RV                              Restaurante
+S       Transbordador                   Sat�lite
+T       Tormenta (cloud/bolt)           Tormenta (cloud/bolt)
+U       Autob�s escolar                 Sol
+V       VOR TAC                         VOR TAC S�mbolo
+W       Servicio  del Tiempo Nacional   NWS-Digi
+X       Helic�ptero
+Y       Velero                     
+Z       Windows
+[       corredor                        WC
+\       DF Tri�ngulo
+]       Packet Mail Box
+^       Avi�n grande                    Avi�n Grande
+_       Estaci�n Meteorol�gica          WS-Digi
+`       Plato de sat�lite              
+a       Ambulancia
+b       Bicicleta                       vuela nube
+c       antena de DX                     
+d       depto de bombero.               Antena de DX
+e       Caballo                         Aguanieve nube 
+f       Cami�n de bombero               FC Nube
+g       planeador                       Bander�n (2)
+h       Hospital                        HAM
+i       Isla                            Isla
+j       Jeep                            Jeep
+k       Cami�n                          Cami�n 
+l       Punto peque�o                   Punto peque�o
+m       MIC                             Milla Poste
+n       N                               Tri�ngulo Peque�o
+o       EOC                             Punto en C�rculos 
+p       Cachorro                        Punto en C�rculos 
+q       GS Antena                       Antena de GS
+r       Antena Torre                    Antena Torre
+s       Bote                            Barco
+t       TS                              ?
+u       18 Rueda de Cami�n
+v       Carro de mudanzas               Punto en C�rculos 
+w       H20                             Diluvio
+x       X Windows                       Punto Rojo
+y       Casa w/Yagi                     Casa w/yagi 
+z                                       X Windows
+{       NIEBLA                          NIEBLA
+|       L�nea Negra                     L�nea negra
+}       TCP                             TCP
+~       Velero                          Velero
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# 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.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # 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 $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/m4/Makefile.am b/m4/Makefile.am
new file mode 100644
index 0000000..6503e4a
--- /dev/null
+++ b/m4/Makefile.am
@@ -0,0 +1,5 @@
+# $Id: Makefile.am,v 1.10 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+EXTRA_DIST=     xmhtml.m4
diff --git a/m4/Makefile.in b/m4/Makefile.in
new file mode 100644
index 0000000..dce9d04
--- /dev/null
+++ b/m4/Makefile.in
@@ -0,0 +1,364 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = m4
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+
+# $Id: Makefile.am,v 1.10 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+EXTRA_DIST = xmhtml.m4
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu m4/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/m4/xmhtml.m4 b/m4/xmhtml.m4
new file mode 100644
index 0000000..760508d
--- /dev/null
+++ b/m4/xmhtml.m4
@@ -0,0 +1,215 @@
+dnl
+dnl
+dnl ICE_FIND_XmHTML
+dnl
+dnl Adapted from a macro by Andreas Zeller.
+dnl
+AC_DEFUN([ICE_FIND_XmHTML],
+[
+AC_REQUIRE([AC_PATH_XTRA])
+xmhtml_includes=
+xmhtml_libraries=
+AC_ARG_WITH(XmHTML,
+[  --without-XmHTML         do not use XmHTML widgets])
+dnl Treat --without-XmHTML like
+dnl --without-XmHTML-includes --without-XmHTML-libraries.
+if test "$with_XmHTML" = "no"
+then
+xmhtml_includes=none
+xmhtml_libraries=none
+fi
+AC_ARG_WITH(xmhtml-includes,
+[  --with-xmhtml-includes=DIR    Motif include files are in DIR],
+xmhtml_includes="$withval")
+AC_ARG_WITH(xmhtml-libraries,
+[  --with-xmhtml-libraries=DIR   Motif libraries are in DIR],
+xmhtml_libraries="$withval")
+AC_MSG_CHECKING(for XmHTML)
+#
+#
+# Search the include files.
+#
+if test "$xmhtml_includes" = ""; then
+AC_CACHE_VAL(ice_cv_xmhtml_includes,
+[
+ice_xmhtml_save_LIBS="$LIBS"
+ice_xmhtml_save_CFLAGS="$CFLAGS"
+ice_xmhtml_save_CPPFLAGS="$CPPFLAGS"
+ice_xmhtml_save_LDFLAGS="$LDFLAGS"
+#
+LIBS="$X_PRE_LIBS -lXm -lXt -lX11 $X_EXTRA_LIBS $LIBS"
+CFLAGS="$X_CFLAGS $CFLAGS"
+CPPFLAGS="$X_CFLAGS $CPPFLAGS"
+LDFLAGS="$X_LIBS $LDFLAGS"
+#
+AC_TRY_COMPILE([#include <XmHTML/XmHTML.h>],[int a;],
+[
+# XmHTML/XmHTML.h is in the standard search path.
+ice_cv_xmhtml_includes=
+],
+[
+# XmHTML/XmHTML.h is not in the standard search path.
+# Locate it and put its directory in `xmhtml_includes'
+#
+# /usr/include/Motif* are used on HP-UX (Motif).
+# /usr/include/X11* are used on HP-UX (X and Athena).
+# /usr/dt is used on Solaris (Motif).
+# /usr/openwin is used on Solaris (X and Athena).
+# Other directories are just guesses.
+ice_cv_xmhtml_includes="none"
+for dir in "$x_includes" "${prefix}/include" /usr/include /usr/local/include \
+           /usr/include/Motif2.0 /usr/include/Motif1.2 /usr/include/Motif1.1 \
+           /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 \
+           /usr/dt/include /usr/openwin/include \
+           /usr/dt/*/include /opt/*/include /usr/include/Motif* \
+           /home/XmHTML/include /usr/XmHTML/include /opt/XmHTML/include \
+           /home/XmHTML*/include /usr/XmHTML*/include /opt/XmHTML*/include \
+           "${prefix}"/*/include /usr/*/include /usr/local/*/include \
+           "${prefix}"/include/* /usr/include/* /usr/local/include/*; do
+if test -f "$dir/XmHTML/XmHTML.h"; then
+        ice_cv_xmhtml_includes="$dir"
+        break
+fi
+done
+])
+#
+LIBS="$ice_xmhtml_save_LIBS"
+CFLAGS="$ice_xmhtml_save_CFLAGS"
+CPPFLAGS="$ice_xmhtml_save_CPPFLAGS"
+LDFLAGS="$ice_xmhtml_save_LDFLAGS"
+])
+xmhtml_includes="$ice_cv_xmhtml_includes"
+fi
+#
+#
+# Now for the libraries.
+#
+if test "$xmhtml_libraries" = ""; then
+AC_CACHE_VAL(ice_cv_xmhtml_libraries,
+[
+ice_xmhtml_save_LIBS="$LIBS"
+ice_xmhtml_save_CFLAGS="$CFLAGS"
+ice_xmhtml_save_CPPFLAGS="$CPPFLAGS"
+ice_xmhtml_save_LDFLAGS="$LDFLAGS"
+#
+LIBS="$X_PRE_LIBS -lXmHTML -lXm -lXt -lX11 $X_EXTRA_LIBS $LIBS"
+CFLAGS="$X_CFLAGS $CFLAGS"
+CPPFLAGS="$X_CFLAGS $CPPFLAGS"
+LDFLAGS="$X_LIBS $LDFLAGS"
+#
+AC_TRY_LINK([#include <XmHTML/XmHTML.h>],[XmCreateHTML();],
+[
+# libXm.a is in the standard search path.
+ice_cv_xmhtml_libraries=
+],
+[
+# libXm.a is not in the standard search path.
+# Locate it and put its directory in `xmhtml_libraries'
+#
+# /usr/lib/Motif* are used on HP-UX (Motif).
+# /usr/lib/X11* are used on HP-UX (X and Athena).
+# /usr/dt is used on Solaris (Motif).
+# /usr/lesstif is used on Linux (Lesstif).
+# /usr/openwin is used on Solaris (X and Athena).
+# Other directories are just guesses.
+ice_cv_xmhtml_libraries="none"
+for dir in "$x_libraries" "${prefix}/lib" /usr/lib /usr/local/lib \
+           /usr/lib/Motif2.0 /usr/lib/Motif1.2 /usr/lib/Motif1.1 \
+           /usr/lib/X11R6 /usr/lib/X11R5 /usr/lib/X11R4 /usr/lib/X11 \
+           /usr/dt/lib /usr/openwin/lib \
+           /usr/dt/*/lib /opt/*/lib /usr/lib/Motif* \
+           /usr/lesstif*/lib /usr/lib/Lesstif* \
+           /home/XmHTML/lib /usr/XmHTML/lib /opt/XmHTML/lib \
+           /home/XmHTML*/lib /usr/XmHTML*/lib /opt/XmHTML*/lib \
+           "${prefix}"/*/lib /usr/*/lib /usr/local/*/lib \
+           "${prefix}"/lib/* /usr/lib/* /usr/local/lib/*; do
+if test -d "$dir" && test "`ls $dir/libXmHTML.* 2> /dev/null`" != ""; then
+        ice_cv_xmhtml_libraries="$dir"
+        break
+fi
+done
+])
+#
+LIBS="$ice_xmhtml_save_LIBS"
+CFLAGS="$ice_xmhtml_save_CFLAGS"
+CPPFLAGS="$ice_xmhtml_save_CPPFLAGS"
+LDFLAGS="$ice_xmhtml_save_LDFLAGS"
+])
+#
+xmhtml_libraries="$ice_cv_xmhtml_libraries"
+fi
+#
+# Provide an easier way to link
+#
+# Okay
+#
+# Let's start by making sure that we completely abandon everything related
+# to XmHTML installation if either the library or the includes have not been
+# located, OR if there was a problem locating the Motif libraries, which are
+# required for the use of XmHTML.  The opening three conditions, if true, will
+# bypass all XmHTML config operations; that is to say, if any of these
+# conditions is true, we call with_xmhtml "no", and that's the end of the
+# game.
+#
+if test "$with_xmhtml" = "no" ; then
+        with_xmhtml="no"
+elif test "$xmhtml_includes" = "none" ; then
+        with_xmhtml="no"
+elif test "$xmhtml_libraries" = "none"; then
+        with_xmhtml="no"
+else
+#
+# We now have established that we want to use XmHTML. It's time to set up the
+# basic environment, and do some discrete tests to set up the environment.
+#
+# First, let's set with_xmhtml to "yes" (don't know of this is really
+# necessary, but we'll be conservative here).  We also send HAVE_XmHTML
+# to config.h and the cache file.
+#
+        AC_DEFINE(HAVE_XmHTML_H)
+        with_xmhtml="yes"
+#
+# Then let's see if the includes were NOT in the default path (if they were,
+# we won't be needing an -I to point at the headers, because the compiler
+# will find them by itself).  We've already eliminated the possibility of
+# "none", so anything other than "" will definitely be a path.
+#
+#
+        if test "$xmhtml_includes" != ""; then
+                include_xmhtml="-I$xmhtml_includes"
+        fi
+#
+# Now that that's out of the way, let's deal with libraries.  Here,
+# we check again to see if the variable (xmhtml_libraries this time)
+# is an empty string, but this time we have work to do whether the
+# test is true or false.  We start with the case of an empty
+# string, which means we want to link with XmHTML, but don't need
+# a path to the library.
+#
+# This isn't quite happy yet.  A test for the location of the jpeg
+# and Xext libraries should be added.
+#
+        if test "$xmhtml_libraries" = ""; then
+                link_xmhtml="-lXmHTML -lXext -ljpeg -lpng -lz"
+        else
+                link_xmhtml="-L$xmhtml_libraries -lXmHTML -lXext -ljpeg -lpng -lz"
+        fi
+#
+# We now close the enclosing conditional.
+#
+fi
+#
+AC_SUBST(include_xmhtml)
+AC_SUBST(link_xmhtml)
+#
+#
+#
+xmhtml_libraries_result="$xmhtml_libraries"
+xmhtml_includes_result="$xmhtml_includes"
+test "$xmhtml_libraries_result" = "" && xmhtml_libraries_result="in default path"
+test "$xmhtml_includes_result" = "" && xmhtml_includes_result="in default path"
+test "$xmhtml_libraries_result" = "none" && xmhtml_libraries_result="(none)"
+test "$xmhtml_includes_result" = "none" && xmhtml_includes_result="(none)"
+AC_MSG_RESULT(
+  [libraries $xmhtml_libraries_result, headers $xmhtml_includes_result])
+])dnl
diff --git a/missing b/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# 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.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..4191a45
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,162 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2009-04-28.21; # UTC
+
+# Original author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+IFS=" ""	$nl"
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake at gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  case $file in
+    /*) pathcomp=/ ;;
+    *)  pathcomp= ;;
+  esac
+  oIFS=$IFS
+  IFS=/
+  set fnord $file
+  shift
+  IFS=$oIFS
+
+  for d
+  do
+    test "x$d" = x && continue
+
+    pathcomp=$pathcomp$d
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp=$pathcomp/
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/placeholder b/placeholder
new file mode 100644
index 0000000..371ac01
--- /dev/null
+++ b/placeholder
@@ -0,0 +1,5 @@
+
+This file was needed in order to the directory created.
+
+Delete this file at will.
+
diff --git a/scripts/Coordinate.pm b/scripts/Coordinate.pm
new file mode 100644
index 0000000..1ffc076
--- /dev/null
+++ b/scripts/Coordinate.pm
@@ -0,0 +1,2465 @@
+#!/usr/bin/perl -w
+
+
+#
+# Coordinate.pm:  Perl module for:
+#
+# 1) Creating and manipulating Coordinate objects,
+# 2) Translating coordinates between UTM and Latitude/Longitude,
+# 3) Translating coordinates between ~231 different datums,
+# 4) Formatting coordinates into decimal degrees, degrees/minutes,
+#    and degrees/minutes/seconds.
+#
+# Copyright (C) 2000-2012  Curt Mills, WE7U
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+
+#
+# $Id: Coordinate.pm,v 1.6 2012/11/01 18:57:19 we7u Exp $
+#
+#
+# Reference ellipsoids derived from Peter H. Dana's website- 
+# New:  http://www.Colorado.EDU/geography/gcraft/notes/datum/elist.html
+#
+# Old:  http://www.utexas.edu/depts/grg/gcraft/notes/datum/elist.html
+# Department of Geography, University of Texas at Austin
+# Internet: pdana at mail.utexas.edu
+# 3/22/95
+#
+#
+# Reference datums derived from Peter H. Dana's website-
+# http://www.Colorado.EDU/geography/gcraft/notes/datum/datum.html#GeoDat
+#
+#
+# UTM<->LAT/LON translations were originally written in C++ by
+# Chuck Gantz- chuck.gantz at globalstar.com.  Permission received
+# by Chuck Gantz via e-mail to release it under the GPL license.
+# Re-coded into Perl by Curt Mills.
+#
+# Datum translations were originally written in C by
+# John F. Waers - jfwaers at csn.net.  His code was released to
+# the public domain.  Re-coded into Perl by Curt Mills.
+#
+#
+# TODO:
+# -----
+# Please note that I didn't pay a lot of attention to
+# keeping the "double" notation in the form of higher
+# precision floating point routines.  This means that
+# the Perl5 code won't be as accurate as the original
+# C-code.  It doesn't matter for my purposes.  If
+# anyone converts to Math::BigFloat for higher precision,
+# please send me the changes.  As it is I did a
+# quick check and found a difference of only 1.4 meters
+# between my Perl results and the results from a web-based
+# datum-shift calculator on the 'net.  -- Curt.
+#
+# Should probably add return values for each method.  Check
+# for error conditions and return 0 if problem.
+#
+# Add method to tell distance in meters of datum shift (verbose flag?)
+#
+# Get rid of print statements unless verbose or debug mode.
+#
+# POD documentation.
+#
+
+
+#------------------------------------------------------------------------------------------------
+
+
+package CoordinateFormat;
+
+
+$VERSION = do { my @r=(q$Revision: 1.6 $=~/\d+/g); sprintf "%d."."%02d"x$#r, at r };
+
+
+#
+# Conversions between decimal degrees, degrees/decimal minutes, and
+# degrees/minutes/seconds.  These are methods which all work on
+# "CoordinateFormat" objects.
+#
+# These routines probably need a bit of work yet.  It'd be nice
+# to be able to specify field widths.
+#
+
+
+sub new
+{
+  my $class = shift;			# What class are we constructing?
+  my $self      = { };			# Allocate new memory
+  bless $self, $class;			# Mark it of the right type
+  $self->_init(@_);			# Call _init with remaining args
+  return $self;
+}
+
+
+sub _init
+{
+  my $self = shift;
+  $self->{RAW} = shift if @_;		# Input string
+  $self->{FORMATTED} = shift if @_;	# Output string, formatted
+}
+
+
+sub raw					# Set'er/Get'er for input string
+{
+  my $self = shift;
+  $self->{RAW} = shift if @_;
+  return $self->{RAW};
+}
+
+
+sub formatted				# Set'er/Get'er for formatted string
+{
+  my $self = shift;
+  $self->{FORMATTED} = shift if @_;
+  return $self->{FORMATTED};
+}
+
+
+#
+# Returns the version number (RCS version tag) of this module.
+#
+sub version
+{
+  return $VERSION;
+}
+
+
+
+
+
+#
+# Degrees and Decimal Minutes
+#
+# Fills in the FORMATTED variable in the object and also returns
+# the string.  If unsuccessful, returns an empty string.
+#
+sub degrees_minutes
+{
+  my $self = shift;				# Get the object to work on
+  my $input = $self->raw();
+
+  my ($degrees, $minutes, $seconds);
+
+  if ( $input =~ /\d+\s+\d+\s+\d+\.*\d*/ )	# Input is in "DD MM SS.SS" format
+  {
+    $degrees = $minutes = $seconds = $input;
+    $degrees =~ s/(\d+)\s+\d+\s+\d+\.*\d*/$1/;
+    $minutes =~ s/\d+\s+(\d+)\s+\d+\.*\d*/$1/;
+    $seconds =~ s/\d+\s+\d+\s+(\d+\.*\d*)/$1/;
+    $minutes = $minutes + ($seconds / 60.0);
+    $self->formatted( sprintf( "%02d %02.8f", $degrees, abs($minutes) ) );
+    return( $self->formatted() );
+  }
+  elsif ( $input =~ /\d+\s+\d+\.*\d*/ )		# Input is in "DD MM.MM" format
+  {
+    $self->formatted( $input );			# No translation necessary
+    return( $self->formatted() );
+  }
+  elsif ( $input =~ /\d+\.*\d*/ )		# Input is in "DD.DDDD" format
+  {
+    $degrees = int ($input);
+    $minutes = ($input - $degrees) * 60.0;
+    $self->formatted( sprintf( "%02d %02.8f", $degrees, abs($minutes) ) );
+    return( $self->formatted() );
+  }
+  else
+  {
+    print "degrees_minutes() method: Input format not recognized: $input\n";
+    $self->formatted( "" );
+    return( "" );				# Should I die here instead?
+  }
+}
+
+
+
+
+
+#
+# Degrees/Minutes/Seconds
+#
+# Fills in the FORMATTED variable in the object and also returns
+# the string.  If unsuccessful, returns an empty string.
+#
+sub degrees_minutes_seconds
+{
+  my $self = shift;				# Get the object to work on
+  my $input = $self->raw();
+
+  my ($degrees, $minutes, $seconds);
+
+  if ( $input =~ /\d+\s+\d+\s+\d+\.*\d*/ )	# Input is in "DD MM SS.SS" format
+  {
+    $self->formatted( $input );			# No translation necessary
+    return( $self->formatted() );
+  }
+  elsif ( $input =~ /\d+\s+\d+\.*\d*/ )		# Input is in "DD MM.MM" format
+  {
+    $degrees = $minutes = $input;
+    $degrees =~ s/(\d+)\s+\d+\.*\d*/$1/;
+    $minutes =~ s/\d+\s+(\d+\.*\d*)/$1/;
+    $seconds = $minutes;
+    $minutes = int ($minutes);
+    $seconds = ($seconds - $minutes) * 60.0;
+    $self->formatted( sprintf( "%02d %02d %02.8f", $degrees, abs($minutes), abs($seconds) ) );
+    return( $self->formatted() );
+  }
+  elsif ( $input =~ /\d+\.*\d*/ )		# Input is in "DD.DDDD" format
+  {
+    $degrees = int ($input);
+    $minutes = int ( ($input - $degrees) * 60.0 );
+    $seconds = ( ( ($input - $degrees) * 60.0) - $minutes) * 60.0;
+    $self->formatted( sprintf( "%02d %02d %02.8f", $degrees, abs($minutes), abs($seconds) ) );
+    return( $self->formatted() );
+  }
+  else
+  {
+    print "degrees_minutes_seconds() method: Input format not recognized: $input\n";
+    $self->formatted( "" );
+    return( "" );				# Should I die here instead?
+  }
+}
+
+
+
+
+
+#
+# Decimal Degrees
+#
+# Fills in the FORMATTED variable in the object and also returns
+# the string.  If unsuccessful, returns an empty string.
+#
+sub decimal_degrees
+{
+  my $self = shift;				# Get the object to work on
+  my $input = $self->raw();
+
+  my ($degrees, $minutes, $seconds);
+
+  if ( $input =~ /\d+\s+\d+\s+\d+\.*\d*/ )	# Input is in "DD MM SS.SS" format
+  {
+    $degrees = $minutes = $seconds = $input;
+    $degrees =~ s/(\d+)\s+\d+\s+\d+\.*\d*/$1/;
+    $minutes =~ s/\d+\s+(\d+)\s+\d+\.*\d*/$1/;
+    $seconds =~ s/\d+\s+\d+\s+(\d+\.*\d*)/$1/;
+    $self->formatted( sprintf( "%02.8f", $degrees + ($minutes/60.0) + ($seconds/(60.0 * 60.0) ) ) );
+    return( $self->formatted() );
+  }
+  elsif ( $input =~ /\d+\s+\d+\.*\d*/ )		# Input is in "DD MM.MM" format
+  {
+    $degrees = $minutes = $input;
+    $degrees =~ s/(\d+)\s+\d+\.*\d*/$1/;
+    $minutes =~ s/\d+\s+(\d+\.*\d*)/$1/;
+    $self->formatted( sprintf( "%02.8f", $degrees + ($minutes / 60.0) ) );
+    return( $self->formatted() );
+  }
+  elsif ( $input =~ /\d+\.*\d*/ )		# Input is in "DD.DDDD" format
+  {
+    $self->formatted( $input );			# No translation necessary
+    return( $self->formatted() );
+  }
+  else
+  {
+    print "decimal_degrees() method: Input format not recognized: $input\n";
+    $self->formatted( "" );
+    return( "" );				# Should I die here instead?
+  }
+}
+
+
+#------------------------------------------------------------------------------------------------
+
+
+package Ellipsoid;
+
+
+$VERSION = do { my @r=(q$Revision: 1.6 $=~/\d+/g); sprintf "%d."."%02d"x$#r, at r };
+
+
+#
+# Ellipsoid: Equatorial_Radius is the ellipsoid semimajor axis (a)
+#	     Polar_Radius is the ellipsoid semiminor axis (b).
+#	     First_Ecc_Squared is the first eccentricity squared, defined as:  2f - (f^2)
+#            Inverse_flattening (1/f) is the inverse of ellipsoid flattening 'f'
+#	     Flattening (f) is defined as:  (a-b)/a.
+#
+# This object is used to create the Ellipsoid_Table object below,
+# containing all of the parameters to describe the various
+# ellipsoids that we need for datum and UTM<->Lat/Lon translations.
+#
+# Equatorial_Radius and First_Ecc_Squared are used by the UTM<->Lat/Lon code.
+# Equatorial_Radius and Inverse_flattening are used by the datum_shift code.
+#
+
+
+sub new
+{
+  my $class = shift;		# What class are we constructing?
+  my $self      = { };		# Allocate new memory
+  bless $self, $class;		# Mark it of the right type
+  $self->_init(@_);		# Call _init with remaining args
+  return $self;
+}
+
+
+#
+# Notice that we compute first_ecc_squared, flattening, and polar_radius
+# from the other parameters.
+#
+sub _init
+{
+  my $self = shift;
+  my $f;
+  my $b;
+  my $inverse_f;
+
+  $self->{NAME} = shift if @_;					# Name of ellipsoid
+  $a = $self->{EQUATORIAL_RADIUS} = shift if @_;		# Semi-major axis, meters
+  $inverse_f = $self->{INVERSE_FLATTENING} = shift if @_;	# Inverse of the ellipsoid flattening 'f'
+
+  if ($inverse_f)
+  {
+    $f = 1.0 / $inverse_f;
+    $self->{FLATTENING} = $f;					# Store the flattening value as well
+    $self->{FIRST_ECC_SQUARED}  = (2 * $f) - ($f**2);		# Compute First Eccentricity Squared from 'f'
+
+    if ($a)
+    {
+      # f = (a-b)/a
+      # f = a/a - b/a
+      # f = 1 - b/a
+      # b/a + f = 1
+      # b/a = 1 - f
+      # b = (1-f)a
+      #
+      $b = (1.0 - $f) * $a;
+      $self->{POLAR_RADIUS} = $b;
+    }
+  }
+}
+
+
+#
+# Returns the version number (RCS version tag) of this module.
+#
+sub version
+{
+  return $VERSION;
+}
+
+
+sub name
+{
+  my $self = shift;
+  $self->{NAME} = shift if @_;
+  return $self->{NAME};
+}
+
+
+sub equatorial_radius
+{
+  my $self = shift;
+  $self->{EQUATORIAL_RADIUS} = shift if @_;
+  return $self->{EQUATORIAL_RADIUS};
+}
+
+
+#
+# Note that you can override the computed POLAR_RADIUS value
+# by using this method to store a new value in the hash.
+#
+sub polar_radius
+{
+  my $self = shift;
+  $self->{POLAR_RADIUS} = shift if @_;
+  return $self->{POLAR_RADIUS};
+}
+
+
+#
+# Note that you can override the computed FIRST_ECC_SQUARED value
+# by using this method to store a new value in the hash.
+#
+sub first_ecc_squared
+{
+  my $self = shift;
+  $self->{FIRST_ECC_SQUARED} = shift if @_;
+  return $self->{FIRST_ECC_SQUARED};
+}
+
+
+#
+# Note that you can override the computed FLATTENING value
+# by using this method to store a new value in the hash.
+#
+sub flattening
+{
+  my $self = shift;
+  $self->{FLATTENING} = shift if @_;
+  return $self->{FLATTENING};
+}
+
+
+sub inverse_flattening
+{
+  my $self = shift;
+  $self->{INVERSE_FLATTENING} = shift if @_;
+  return $self->{INVERSE_FLATTENING};
+}
+
+
+#-----------------------------------------------------------------------------------------------
+
+
+package EllipsoidTable;
+
+
+$VERSION = do { my @r=(q$Revision: 1.6 $=~/\d+/g); sprintf "%d."."%02d"x$#r, at r };
+
+
+#
+# I could have created this table as a hash of anonymous arrays, which might have been
+# faster/more efficient.  Oh well.
+#
+# All of the methods here are class methods.  There isn't even a way to make an
+# EllipsoidTable object given here.  This class is merely a large collection
+# of Ellipsoid objects, collected in the %_ellipsoid hash.
+#
+
+
+my %_ellipsoid;		# Class data
+
+
+#
+# Returns the version number (RCS version tag) of this module.
+#
+sub version
+{
+  return $VERSION;
+}
+
+
+# Note that this method is really useless.  The name is the same as the
+# hash key used in the %_ellipsoid hash.  Redundant.
+#
+sub name
+{
+  shift;	# Object reference (don't need it)
+  my $ellipsoid_name = shift;
+
+  return $_ellipsoid{$ellipsoid_name}->name();
+}
+
+
+sub equatorial_radius	# (a)
+{
+  shift;	# Object reference (don't need it)
+  my $ellipsoid_name = shift;
+
+  return $_ellipsoid{$ellipsoid_name}->equatorial_radius();
+}
+
+
+sub polar_radius	# (b)
+{
+  shift;	# Object reference (don't need it)
+  my $ellipsoid_name = shift;
+
+  return $_ellipsoid{$ellipsoid_name}->polar_radius();
+}
+
+
+sub first_ecc_squared	# (ecc)
+{
+  shift;	# Object reference (don't need it)
+  my $ellipsoid_name = shift;
+
+  return $_ellipsoid{$ellipsoid_name}->first_ecc_squared();
+}
+
+
+sub flattening		# (f)
+{
+  shift;	# Object reference (don't need it)
+  my $ellipsoid_name = shift;
+
+  return $_ellipsoid{$ellipsoid_name}->flattening();
+}
+
+
+sub inverse_flattening	# (1/f)
+{
+  shift;	# Object reference (don't need it)
+  my $ellipsoid_name = shift;
+
+  return $_ellipsoid{$ellipsoid_name}->inverse_flattening();
+}
+
+
+#
+# This method allows printing out each defined Ellipsoid.
+#
+sub enumerate
+{
+  my $self = shift;
+
+  print "\nEllipsoid\t\tEquatorial Radius (a)\tPolar Radius (b)\tFirst Eccentricity^2\tFlattening (f)\t\t1/f\n";
+  print   "---------\t\t---------------------\t----------------\t--------------------\t--------------\t\t---\n";
+
+  foreach my $key (sort keys %_ellipsoid)
+  {
+    printf("%23s,\t%s,\t%s,\t%s,\t%s,\t%s\n",
+	$key,
+	$self->equatorial_radius($key),
+	$self->polar_radius($key),
+	$self->first_ecc_squared($key),
+	$self->flattening($key),
+	$self->inverse_flattening($key) );
+  }
+  return(1);
+}
+
+
+
+
+
+#
+# Auto-run code
+#
+# Fill in the hash containing Ellipsoid objects (fill in the Class data)
+#
+# Name, Equatorial_Radius (a), Inverse_Flattening (1/f).
+#
+# Name:				Reference Ellipsoid Name
+# Equatorial_Radius:		(a) = Semi-Major Axis		(WGS-84 value = 6378137.0 meters)
+# Polar_radius:			(b) = Semi-Minor Axis		(WGS-84 value = 6356752.3142 meters)
+# Flattening:			f = (a-b)/a			(WGS-84 value = 0.00335281066475)
+# First_Eccentricity_Squared:	ecc = 2f - (f^2)		(WGS-84 value = 0.00669437999013)
+# Inverse_flattening:		Reciprocal Flattening (1/f)	(WGS-84 value = 298.257223563)
+#
+# We can calculate Polar_Radius (b), Flattening (f), and First_Eccentricity_Squared (ecc)
+# from the values for Equatorial_Radius (a) and Inverse_flattening (1/f), so the table
+# includes only the latter two parameters.
+#
+
+
+#print "Creating ellipsoid data\n";
+#                                                                                   Equatorial
+#            Name                                          Name                     Radius       Inverse_flattening
+$_ellipsoid{"Airy"}			= Ellipsoid->new( "Airy",		    6377563.396, 299.324964600 );
+$_ellipsoid{"Modified Airy"}          	= Ellipsoid->new( "Modified Airy",	    6377340.189, 299.324964600 );
+$_ellipsoid{"Australian National"}	= Ellipsoid->new( "Australian National",    6378160.000, 298.250000000 );
+$_ellipsoid{"Bessel 1841"}		= Ellipsoid->new( "Bessel 1841",	    6377397.155, 299.152812800 );
+$_ellipsoid{"Bessel 1841 (Namibia)"}	= Ellipsoid->new( "Bessel 1841 (Namibia)",  6377483.865, 299.152812800 );
+$_ellipsoid{"Clarke 1866"}		= Ellipsoid->new( "Clarke 1866",	    6378206.400, 294.978698200 );
+$_ellipsoid{"Clarke 1880"}		= Ellipsoid->new( "Clarke 1880",	    6378249.145, 293.465000000 );
+$_ellipsoid{"Everest (India 1830)"}	= Ellipsoid->new( "Everest (India 1830)",   6377276.345, 300.801700000 );
+$_ellipsoid{"Everest (Sabah Sarawak)"}	= Ellipsoid->new( "Everest (Sabah Sarawak)",6377298.556, 300.801700000 ); 
+$_ellipsoid{"Everest (India 1956)"}	= Ellipsoid->new( "Everest (India 1956)",   6377301.243, 300.801700000 );
+$_ellipsoid{"Everest (Malaysia 1969)"}	= Ellipsoid->new( "Everest (Malaysia 1969)",6377295.664, 300.801700000 );
+$_ellipsoid{"Everest (Malay. & Sing)"}	= Ellipsoid->new( "Everest (Malay. & Sing)",6377304.063, 300.801700000 );
+$_ellipsoid{"Everest 1948"}		= Ellipsoid->new( "Everest 1948",           6377304.063, 300.801700000 );
+$_ellipsoid{"Everest (Pakistan)"}	= Ellipsoid->new( "Everest (Pakistan)",	    6377309.613, 300.801700000 );
+$_ellipsoid{"Fischer 1960 (Mercury)"}	= Ellipsoid->new( "Fischer 1960 (Mercury)", 6378166.000, 298.300000000 );
+$_ellipsoid{"Fischer 1968"}		= Ellipsoid->new( "Fischer 1968",	    6378150.000, 298.300000000 );
+$_ellipsoid{"Modified Fischer 1960"}	= Ellipsoid->new( "Modified Fischer 1960",  6378155.000, 298.300000000 );
+$_ellipsoid{"GRS 1967"}			= Ellipsoid->new( "GRS 1967",		    6378160.000, 298.247167427 );
+$_ellipsoid{"GRS 1980"}			= Ellipsoid->new( "GRS 1980",		    6378137.000, 298.257222101 );
+$_ellipsoid{"Helmert 1906"}		= Ellipsoid->new( "Helmert 1906",	    6378200.000, 298.300000000 );
+$_ellipsoid{"Hough 1960"}		= Ellipsoid->new( "Hough 1960",		    6378270.000, 297.000000000 );
+$_ellipsoid{"Indonesian 1974"}		= Ellipsoid->new( "Indonesian 1974",	    6378160.000, 298.247000000 );
+$_ellipsoid{"International 1924"}	= Ellipsoid->new( "International 1924",	    6378388.000, 297.000000000 );
+$_ellipsoid{"Krassovsky 1940"}		= Ellipsoid->new( "Krassovsky 1940",	    6378245.000, 298.300000000 );
+$_ellipsoid{"South American 1969"}	= Ellipsoid->new( "South American 1969",    6378160.000, 298.250000000 );
+$_ellipsoid{"WGS 60"}			= Ellipsoid->new( "WGS 60",		    6378165.000, 298.300000000 );
+$_ellipsoid{"WGS 66"}			= Ellipsoid->new( "WGS 66",		    6378145.000, 298.250000000 );
+$_ellipsoid{"WGS 72"}			= Ellipsoid->new( "WGS 72",		    6378135.000, 298.260000000 );
+$_ellipsoid{"WGS 84"}			= Ellipsoid->new( "WGS 84",		    6378137.000, 298.257223563 );
+
+
+#------------------------------------------------------------------------------------------------
+
+
+package Datum;
+
+
+$VERSION = do { my @r=(q$Revision: 1.6 $=~/\d+/g); sprintf "%d."."%02d"x$#r, at r };
+
+
+#
+# These are the objects and methods used to create the DatumTable in the next package.
+#
+
+
+sub new
+{
+  my $class = shift;		# What class are we constructing?
+  my $self      = { };		# Allocate new memory
+  bless $self, $class;		# Mark it of the right type
+  $self->_init(@_);		# Call _init with remaining args
+  return $self;
+}
+
+
+sub _init
+{
+  my $self = shift;
+  $self->{NAME} = shift if @_;
+  $self->{ELLIPSOID} = shift if @_;
+  $self->{DX} = shift if @_;
+  $self->{DY} = shift if @_;
+  $self->{DZ} = shift if @_;
+}
+
+
+#
+# Returns the version number (RCS version tag) of this module.
+#
+sub version
+{
+  return $VERSION;
+}
+
+
+#
+# This is mostly a useless method.  We store the name here, but it
+# is also present as the hash key in the %_datum hash.  Redundant.
+#
+sub name			# Name of datum
+{
+  my $self = shift;
+  $self->{NAME} = shift if @_;
+  return $self->{NAME};
+}
+
+
+sub ellipsoid			# Name of ellipsoid used in datum
+{
+  my $self = shift;
+  $self->{ELLIPSOID} = shift if @_;
+  return $self->{ELLIPSOID};
+}
+
+
+sub dx				# X-offset from WGS84 ellipsoid center
+{
+  my $self = shift;
+  $self->{DX} = shift if @_;
+  return $self->{DX};
+}
+
+
+sub dy				# Y-offset from WGS84 ellipsoid center
+{
+  my $self = shift;
+  $self->{DY} = shift if @_;
+  return $self->{DY};
+}
+
+
+sub dz				# Z-offset from WGS84 ellipsoid center
+{
+  my $self = shift;
+  $self->{DZ} = shift if @_;
+  return $self->{DZ};
+}
+
+
+#------------------------------------------------------------------------------------------------
+
+
+package DatumTable;
+
+
+$VERSION = do { my @r=(q$Revision: 1.6 $=~/\d+/g); sprintf "%d."."%02d"x$#r, at r };
+
+
+#
+# I could have created this table as a hash of anonymous arrays, which might have been
+# faster/more efficient.  Oh well.
+#
+# All of the methods here are class methods.  There isn't even a way to make a
+# DatumTable object given here.  This class is merely a large collection
+# of Datum objects, collected in the %_datum hash.
+#
+
+my %_datum;			# Class data
+
+
+#
+# Returns the version number (RCS version tag) of this module.
+#
+sub version
+{
+  return $VERSION;
+}
+
+
+sub name				# Name of datum
+{
+  shift;				# Object reference (don't need it)
+  my $datum_name = shift;
+
+  return $_datum{$datum_name}->name();
+}
+
+
+sub ellipsoid				# Name of ellipsoid used in datum
+{
+  shift;				# Object reference (don't need it)
+  my $datum_name = shift;
+
+  return $_datum{$datum_name}->ellipsoid();
+}
+
+
+sub dx					# X-offset from WGS84 ellipsoid center
+{
+  shift;				# Object reference (don't need it)
+  my $datum_name = shift;
+
+  return $_datum{$datum_name}->dx();
+}
+
+
+sub dy					# Y-offset from WGS84 ellipsoid center
+{
+  shift;				# Object reference (don't need it)
+  my $datum_name = shift;
+
+  return $_datum{$datum_name}->dy();
+}
+
+
+sub dz					# Z-offset from WGS84 ellipsoid center
+{
+  shift;				# Object reference (don't need it)
+  my $datum_name = shift;
+
+  return $_datum{$datum_name}->dz();
+}
+
+
+#
+# This method allows printing out each defined Datum.
+#
+sub enumerate
+{
+  my $self = shift;
+
+  print "\nDatum\t\t\t\t\t\t\t\tEllipsoid\tDx\tDy\tDz\n";
+  print   "-----\t\t\t\t\t\t\t\t---------\t--\t--\t--\n";
+
+  foreach my $key (sort keys %_datum)
+  {
+    printf("%s\n\t\t\t\t\t\t%23s,\t%s,\t%s,\t%s\n",
+	$key,
+	$self->ellipsoid($key),
+	$self->dx($key),
+	$self->dy($key),
+	$self->dz($key) );
+  }
+  return(1);
+}
+
+
+
+
+
+#
+# Auto-run code
+#
+# Fill in the Class data.
+#
+# This code fills in the %_datum hash which has entries consisting of Datum objects.
+#
+# From the original C code:
+#
+# "Dx, Dy, Dz: ellipsoid center with respect to WGS 84 ellipsoid center
+#  x axis is the prime meridian
+#  y axis is 90 degrees east longitude
+#  z axis is the axis of rotation of the ellipsoid"
+#
+# Most of the current data is from Peter Dana's website.
+# This increased the number of datums to around 231.  -- Curt.
+#
+#
+# NOTE:  Consider adding a field for "region of use".
+#
+#
+#	 Name	Name	Ellipsoid	Dx	Dy	Dz
+$_datum{"Adindan (Burkina Faso)"}
+	= Datum->new( "Adindan (Burkina Faso)",
+			"Clarke 1880", -118, -14, 218 );
+
+$_datum{"Adindan (Cameroon)"}
+	= Datum->new( "Adindan (Cameroon)",
+			"Clarke 1880", -134, -2, 210 );
+
+$_datum{"Adindan (Ethiopia)"}
+	= Datum->new( "Adindan (Ethiopia)",
+			"Clarke 1880", -165, -11, 206 );
+
+$_datum{"Adindan (Mali)"}
+	= Datum->new( "Adindan (Mali)",
+			"Clarke 1880", -123, -20, 220 );
+
+$_datum{"Adindan (MEAN for Ethiopia/Sudan)"}
+	= Datum->new( "Adindan (MEAN for Ethiopia/Sudan)",
+			"Clarke 1880", -166, -15, 204 );
+
+$_datum{"Adindan (Senegal)"}
+	= Datum->new( "Adindan (Senegal)",
+			"Clarke 1880", -128, -18, 224 );
+
+$_datum{"Adindan (Sudan)"}
+	= Datum->new( "Adindan (Sudan)",
+			"Clarke 1880", -161, -14, 205 );
+
+$_datum{"Afgooye"}
+	= Datum->new( "Afgooye",
+			"Krassovsky 1940", -43, -163, 45 );
+
+$_datum{"Ain el Abd 1970 (Bahrain)"}
+	= Datum->new( "Ain el Abd 1970 (Bahrain)",
+			"International 1924", -150, -250, -1 );
+
+$_datum{"Ain el Abd 1970 (Saudi Arabia)"}
+	= Datum->new( "Ain el Abd 1970 (Saudi Arabia)",
+			"International 1924", -143, -236, 7 );
+
+$_datum{"American Samoa 1962"}
+	= Datum->new( "American Samoa 1962",
+			"Clarke 1866", -115, 118, 426 );
+
+$_datum{"Anna 1 Astro 1965"}
+	= Datum->new( "Anna 1 Astro 1965",
+			"Australian National", -491, -22, 435 );
+
+$_datum{"Antigua Island Astro 1943"}
+	= Datum->new( "Antigua Island Astro 1943",
+			"Clarke 1880", -270, 13, 62 );
+
+$_datum{"Arc 1950 (Botswana)"}
+	= Datum->new( "Arc 1950 (Botswana)",
+			"Clarke 1880", -138, -105, -289 );
+
+$_datum{"Arc 1950 (Burundi)"}
+	= Datum->new( "Arc 1950 (Burundi)",
+			"Clarke 1880", -153, -5, -292 );
+
+$_datum{"Arc 1950 (Lesotho)"}
+	= Datum->new( "Arc 1950 (Lesotho)",
+			"Clarke 1880", -125, -108, -295 );
+
+$_datum{"Arc 1950 (Malawi)"}
+	= Datum->new( "Arc 1950 (Malawi)",
+			"Clarke 1880", -161, -73, -317 );
+
+$_datum{"Arc 1950 (MEAN)"}
+	= Datum->new( "Arc 1950 (MEAN)",
+			"Clarke 1880", -143, -90, -294 );
+
+$_datum{"Arc 1950 (Swaziland)"}
+	= Datum->new( "Arc 1950",
+			"Clarke 1880", -134, -105, -295 );
+
+$_datum{"Arc 1950 (Zaire)"}
+	= Datum->new( "Arc 1950",
+			"Clarke 1880", -169, -19, -278 );
+
+$_datum{"Arc 1950 (Zambia)"}
+	= Datum->new( "Arc 1950",
+			"Clarke 1880", -147, -74, -283 );
+
+$_datum{"Arc 1950 (Zimbabwe)"}
+	= Datum->new( "Arc 1950",
+			"Clarke 1880", -142, -96, -293 );
+
+$_datum{"Arc 1960 (MEAN)"}
+	= Datum->new( "Arc 1960 (MEAN)",
+			"Clarke 1880", -160, -6, -302 );
+
+$_datum{"Arc 1960 (Kenya)"}
+	= Datum->new( "Arc 1960 (Kenya)",
+			"Clarke 1880", -157, -2, -299 );
+
+$_datum{"Arc 1960 (Tanzania)"}
+	= Datum->new( "Arc 1960 (Tanzania)",
+			"Clarke 1880", -175, -23, -303 );
+
+$_datum{"Ascension Island 1958"}
+	= Datum->new( "Ascension Island 1958",
+			"International 1924", -205, 107, 53 );
+
+$_datum{"Astro B4 Sorol Atoll"}
+	= Datum->new( "Astro B4 Sorol Atoll",
+			"International 1924", 114, -116, -333 );
+
+$_datum{"Astro Beacon E 1945"}
+	= Datum->new( "Astro Beacon E 1945",
+			"International 1924", 145, 75, -272 );
+
+$_datum{"Astro DOS 71/4"}
+	= Datum->new( "Astro DOS 71/4",
+			"International 1924", -320, 550, -494 );
+
+$_datum{"Astro Tern Island (FRIG) 1961"}
+	= Datum->new( "Astro Tern Island (FRIG) 1961",
+			"International 1924", 114, -116, -333 );
+
+$_datum{"Astronomical Station 1952"}
+	= Datum->new( "Astronomical Station 1952",
+			"International 1924", 124, -234, -25 );
+
+$_datum{"Australian Geodetic 1966"}
+	= Datum->new( "Australian Geodetic 1966",
+			"Australian National", -133, -48, 148 );
+
+$_datum{"Australian Geodetic 1984"}
+	= Datum->new( "Australian Geodetic 1984",
+			"Australian National", -134, -48, 149 );
+
+$_datum{"Ayabelle Lighthouse"}
+	= Datum->new( "Ayabelle Lighthouse",
+			"Clarke 1880", -79, -129, 145 );
+
+$_datum{"Bellevue (IGN)"}
+	= Datum->new( "Bellevue (IGN)",
+			"International 1924", -127, -769, 472 );
+
+$_datum{"Bermuda 1957"}
+	= Datum->new( "Bermuda 1957",
+			"Clarke 1866", -73, 213, 296 );
+
+$_datum{"Bogota Observatory"}
+	= Datum->new( "Bogota Observatory",
+			"International 1924", 307, 304, -318 );
+
+$_datum{"Bukit Rimpah"}
+	= Datum->new( "Bukit Rimpah",
+			"Bessel 1841", -384, 664, -48 );
+
+$_datum{"Camp Area Astro"}
+	= Datum->new( "Camp Area Astro",
+			"International 1924", -104, -129, 239 );
+
+$_datum{"Campo Inchauspe"}
+	= Datum->new( "Campo Inchauspe",
+			"International 1924", -148, 136, 90 );
+
+$_datum{"Canton Astro 1966"}
+	= Datum->new( "Canton Astro 1966",
+			"International 1924", 298, -304, -375 );
+
+$_datum{"Cape"}
+	= Datum->new( "Cape",
+			"Clarke 1880", -136, -108, -292 );
+
+$_datum{"Cape Canaveral"}
+	= Datum->new( "Cape Canaveral",
+			"Clarke 1866", -2, 151, 181 );
+
+$_datum{"Carthage"}
+	= Datum->new( "Carthage",
+			"Clarke 1880", -263, 6, 431 );
+
+$_datum{"CH-1903"}
+	= Datum->new( "CH-1903",
+			"Bessel 1841", 674, 15, 405);
+
+$_datum{"Chatham Island Astro 1971"}
+	= Datum->new( "Chatham Island Astro 1971",
+			"International 1924", 175, -38, 113);
+
+$_datum{"Chua Astro"}
+	= Datum->new( "Chua Astro",
+			"International 1924", -134, 229, -29 );
+
+$_datum{"Corrego Alegre"}
+	= Datum->new( "Corrego Alegre",
+			"International 1924", -206, 172, -6 );
+
+$_datum{"Dabola"}
+	= Datum->new( "Dabola",
+			"Clarke 1880", -83, 37, 124 );
+
+$_datum{"Deception Island"}
+	= Datum->new( "Deception Island",
+			"Clarke 1880", 260, 12, -147 );
+
+$_datum{"Djakarta (Batavia)"}
+	= Datum->new( "Djakarta (Batavia)",
+			"Bessel 1841", -377, 681, -50 );
+
+$_datum{"DOS 1968"}
+	= Datum->new( "DOS 1968",
+			"International 1924", 230, -199, -752 );
+
+$_datum{"Easter Island 1967"}
+	= Datum->new( "Easter Island 1967",
+			"International 1924", 211, 147, 111 );
+
+$_datum{"Estonia 1937"}
+	= Datum->new( "Estonia 1937",
+			"Bessel 1841", 374, 150, 588 );
+
+$_datum{"European 1950 (Cyprus)"}
+	= Datum->new( "European 1950 (Cyprus)",
+			"International 1924", -104, -101, -140 );
+
+$_datum{"European 1950 (Egypt)"}
+	= Datum->new( "European 1950 (Egypt)",
+			"International 1924", -130, -117, -151 );
+
+$_datum{"European 1950 (England/Channel Is/Scotland/Shetland Is)"}
+	= Datum->new( "European 1950 (England/Channel Is/Scotland/Shetland Is)",
+			"International 1924", -86, -96, -120 );
+
+$_datum{"European 1950 (England/Ireland/Scotland/Shetland Is)"}
+	= Datum->new( "European 1950 (England/Ireland/Scotland/Shetland Is)",
+			"International 1924", -86, -96, -120 );
+
+$_datum{"European 1950 (Finland/Norway)"}
+	= Datum->new( "European 1950 (Finland/Norway)",
+			"International 1924", -87, -95, -120 );
+
+$_datum{"European 1950 (Greece)"}
+	= Datum->new( "European 1950 (Greece)",
+			"International 1924", -84, -95, -130 );
+
+$_datum{"European 1950 (Iran)"}
+	= Datum->new( "European 1950 (Iran)",
+			"International 1924", -117, -132, -164 );
+
+$_datum{"European 1950 (Italy:Sardinia)"}
+	= Datum->new( "European 1950 (Italy:Sardinia)",
+			"International 1924", -97, -103, -120 );
+
+$_datum{"European 1950 (Italy:Sicily)"}
+	= Datum->new( "European 1950 (Italy:Sicily)",
+			"International 1924", -97, -88, -135 );
+
+$_datum{"European 1950 (Malta)"}
+	= Datum->new( "European 1950 (Malta)",
+			"International 1924", -107, -88, -149 );
+
+$_datum{"European 1950 (MEAN for Austria/Belgium/Denmark/Finland/France/W Germany/Gibraltar/Greece/Italy/Luxembourg/Netherlands/Norway/Portugal/Spain/Sweden/Switzerland)"}
+	= Datum->new( "European 1950 (MEAN for Austria/Belgium/Denmark/Finland/France/W Germany/Gibraltar/Greece/Italy/Luxembourg/Netherlands/Norway/Portugal/Spain/Sweden/Switzerland)",
+			"International 1924", -87, -98, -121 );
+
+$_datum{"European 1950 (MEAN for Austria/Denmark/France/W Germany/Netherlands/Switzerland)"}
+	= Datum->new( "European 1950 (MEAN for Austria/Denmark/France/W Germany/Netherlands/Switzerland)",
+			"International 1924", -87, -96, -120 );
+
+$_datum{"European 1950 (MEAN for Iraq/Israel/Jordan/Lebanon/Kuwait/Saudi Arabia/Syria)"}
+	= Datum->new( "European 1950 (MEAN for Iraq/Israel/Jordan/Lebanon/Kuwait/Saudi Arabia/Syria)",
+			"International 1924", -103, -106, -141 );
+
+$_datum{"European 1950 (Portugal/Spain)"}
+	= Datum->new( "European 1950 (Portugal/Spain)",
+			"International 1924", -84, -107, -120 );
+
+$_datum{"European 1950 (Tunisia)"}
+	= Datum->new( "European 1950 (Tunisia)",
+			"International 1924", -112, -77, -145 );
+
+$_datum{"European 1979 (MEAN for Austria/Finland/Netherlands/Norway/Spain/Sweden/Switzerland)"}
+	= Datum->new( "European 1979 (MEAN for Austria/Finland/Netherlands/Norway/Spain/Sweden/Switzerland)",
+			"International 1924",  -86, -98, -119 );
+
+$_datum{"Finland Hayford"}
+	= Datum->new( "Finland Hayford",
+			"International 1924", -78, -231, -97 );
+
+$_datum{"Fort Thomas"}
+	= Datum->new( "Fort Thomas",
+			"Clarke 1880", -7, 215, 225 );
+
+$_datum{"Gandajika Base 1970"}
+	= Datum->new( "Gandajika Base 1970",
+			"International 1924", -133, -321, 50 );
+
+$_datum{"Geodetic Datum 1949"}
+	= Datum->new( "Geodetic Datum 1949",
+			"International 1924", 84, -22, 209 );
+
+$_datum{"Graciosa Base SW 1948"}
+	= Datum->new( "Graciosa Base SW 1948",
+			"International 1924", -104, 167, -38 );
+
+$_datum{"Guam 1963"}
+	= Datum->new( "Guam 1963",
+			"Clarke 1866", -100, -248, 259 );
+
+$_datum{"Gunung Segara"}
+	= Datum->new( "Gunung Segara",
+			"Bessel 1841", -403, 684, 41 );
+
+$_datum{"GUX 1 Astro"}
+	= Datum->new( "GUX 1 Astro",
+			"International 1924", 252, -209, -751 );
+
+$_datum{"Herat North"}
+	= Datum->new( "Herat North",
+			"International 1924", -333, -222, 114 );
+
+$_datum{"Hermannskogel Datum (Namibia)"}
+	= Datum->new( "Hermannskogel Datum (Namibia)",
+			"Bessel 1841", 653, -212, 449 );
+
+$_datum{"Hjorsey 1955"}
+	= Datum->new( "Hjorsey 1955",
+			"International 1924", -73, 46, -86 );
+
+$_datum{"Hong Kong 1963"}
+	= Datum->new( "Hong Kong 1963",
+			"International 1924", -156, -271, -189 );
+
+$_datum{"Hu-Tzu-Shan"}
+	= Datum->new( "Hu-Tzu-Shan",
+			"International 1924", -637, -549, -203 );
+
+$_datum{"Indian (Bangladesh)"}
+	= Datum->new( "Indian (Bangladesh)",
+			"Everest (India 1830)", 282, 726, 254 );
+
+$_datum{"Indian (India/Nepal)"}
+	= Datum->new( "Indian (India/Nepal)",
+			"Everest (India 1956)", 295, 736, 257 );
+
+$_datum{"Indian (Pakistan)"}
+	= Datum->new( "Indian (Pakistan)",
+			"Everest (Pakistan)", 283, 682, 231 );
+
+$_datum{"Indian 1954 (Thailand)"}
+	= Datum->new( "Indian 1954 (Thailand)",
+			"Everest (India 1830)", 217, 823, 299 );
+
+$_datum{"Indian 1960 (Vietnam:Con Son Is)"}
+	= Datum->new( "Indian 1960 (Vietnam:Con Son Is)",
+			"Everest (India 1830)", 182, 915, 344 );
+
+$_datum{"Indian 1960 (Vietnam:Near 160N)"}
+	= Datum->new( "Indian 1960 (Vietnam:Near 160N)",
+			"Everest (India 1830)", 198, 881, 317 );
+
+$_datum{"Indian 1975 (Thailand)"}
+	= Datum->new( "Indian 1975 (Thailand)",
+			"Everest (India 1830)", 210, 814, 289 );
+
+$_datum{"Indonesian 1974"}
+	= Datum->new( "Indonesian 1974)",
+			"Indonesian 1974)", -24, -15, 5 );
+
+$_datum{"Ireland 1965"}
+	= Datum->new( "Ireland 1965",
+			"Modified Airy", 506, -122, 611 );
+
+$_datum{"ISTS 061 Astro 1968"}
+	= Datum->new( "ISTS 061 Astro 1968",
+			"International 1924", -794, 119, -298 );
+
+$_datum{"ISTS 073 Astro 1969"}
+	= Datum->new( "ISTS 073 Astro 1969",
+			"International 1924", 208, -435, -229 );
+
+$_datum{"Johnston Island"}
+	= Datum->new( "Johnston Island",
+			"International 1924", 189, -79, -202 );
+
+$_datum{"Kandawala"}
+	= Datum->new( "Kandawala",
+			"Everest (India 1830)", -97, 787, 86 );
+
+$_datum{"Kerguelen Island 1949"}
+	= Datum->new( "Kerguelen Island 1949",
+			"International 1924", 145, -187, 103 );
+
+$_datum{"Kertau 1948"}
+	= Datum->new( "Kertau 1948",
+			"Everest (Malay. & Sing)", -11, 851, 5 );
+
+$_datum{"Kusaie Astro 1951"}
+	= Datum->new( "Kusaie Astro 1951",
+			"International 1924", 647, 1777, -1124 );
+
+$_datum{"Korean Geodetic System"}
+	= Datum->new( "Korean Geodetic System",
+			"GRS 1980", 0, 0, 0 );
+
+$_datum{"L. C. 5 Astro 1961"}
+	= Datum->new( "L. C. 5 Astro 1961",
+			"Clarke 1866", 42, 124, 147 );
+
+$_datum{"Leigon"}
+	= Datum->new( "Leigon",
+			"Clarke 1880", -130, 29, 364 );
+
+$_datum{"Liberia 1964"}
+	= Datum->new( "Liberia 1964",
+			"Clarke 1880", -90, 40, 88 );
+
+$_datum{"Luzon (Philippines:Except Mindanao)"}
+	= Datum->new( "Luzon (Philippines:Except Mindanao)",
+			"Clarke 1866", -133, -77, -51 );
+
+$_datum{"Luzon (Philippines:Mindanao)"}
+	= Datum->new( "Luzon (Philippines:Mindanao)",
+			"Clarke 1866", -133, -79, -72 );
+
+$_datum{"M\'Poraloko"}
+	= Datum->new( "M\'Poraloko",
+			"Clarke 1880", -74, -130, 42 );
+
+$_datum{"Mahe 1971"}
+	= Datum->new( "Mahe 1971",
+			"Clarke 1880", 41, -220, -134 );
+
+$_datum{"Marco Astro"}
+	= Datum->new( "Marco Astro",
+			"International 1924", -289, -124, 60 );
+
+$_datum{"Massawa"}
+	= Datum->new( "Massawa",
+			"Bessel 1841",  639, 405, 60 );
+
+$_datum{"Merchich"}
+	= Datum->new( "Merchich",
+			"Clarke 1880", 31, 146, 47 );
+
+$_datum{"Midway Astro 1961"}
+	= Datum->new( "Midway Astro 1961",
+			"International 1924", 912, -58, 1227 );
+
+$_datum{"Minna (Cameroon)"}
+	= Datum->new( "Minna (Cameroon)",
+			"Clarke 1880", -81, -84, 115 );
+
+$_datum{"Minna (Nigeria)"}
+	= Datum->new( "Minna (Nigeria)",
+			"Clarke 1880", -92, -93, 122 );
+
+$_datum{"Montserrat Island Astro 1958"}
+	= Datum->new( "Montserrat Island Astro 1958",
+			"Clarke 1880", 174, 359, 365 );
+
+$_datum{"Nahrwan (Oman:Masirah Is)"}
+	= Datum->new( "Nahrwan (Oman:Masirah Is)",
+			"Clarke 1880", -247, -148, 369 );
+
+$_datum{"Nahrwan (Saudi Arabia)"}
+	= Datum->new( "Nahrwan (Saudi Arabia)",
+			"Clarke 1880", -243, -192, 477 );
+
+$_datum{"Nahrwan (United Arab Emirates)"}
+	= Datum->new( "Nahrwan (United Arab Emirates)",
+			"Clarke 1880", -249, -156, 381 );
+
+$_datum{"Naparima BWI"}
+	= Datum->new( "Naparima BWI",
+			"International 1924", -10, 375, 165 );
+
+$_datum{"NAD27 Alaska:Except Aleutian Is"}
+	= Datum->new( "NAD27 Alaska:Except Aleutian Is",
+			"Clarke 1866", -5, 135, 172 );
+
+$_datum{"NAD27 Alaska:Aleutian Is E of 180W"}
+	= Datum->new( "NAD27 Alaska:Aleutian Is E of 180W",
+			"Clarke 1866", -2, 152, 149 );
+
+$_datum{"NAD27 Alaska:Aleutian Is W of 180W"}
+	= Datum->new( "NAD27 Alaska:Aleutian Is W of 180W",
+			"Clarke 1866", 2, 204, 105 );
+
+$_datum{"NAD27 Bahamas:Except San Salvador Is"}
+	= Datum->new( "NAD27 Bahamas:Except San Salvador Is",
+			"Clarke 1866", -4, 154, 178 );
+
+$_datum{"NAD27 Bahamas:San Salvador Is"}
+	= Datum->new( "NAD27 Bahamas:San Salvador Is",
+			"Clarke 1866", 1, 140, 165 );
+
+$_datum{"NAD27 Canada (Alberta/B.C.)"}
+	= Datum->new( "NAD27 Canada (Alberta/B.C.)",
+			"Clarke 1866", -7, 162, 188 );
+
+$_datum{"NAD27 Canada (Manitoba/Ontario)"}
+	= Datum->new( "NAD27 Canada (Manitoba/Ontario)",
+			"Clarke 1866", -9, 157, 184 );
+
+$_datum{"NAD27 Canada MEAN"}
+	= Datum->new( "NAD27 Canada MEAN",
+			"Clarke 1866", -10, 158, 189 );
+
+$_datum{"NAD27 Canada (New Brunswick/Newfoundland/Nova Scotia/Quebec)"}
+	= Datum->new( "NAD27 Canada (New Brunswick/Newfoundland/Nova Scotia/Quebec)",
+			"Clarke 1866", -22, 160, 190 );
+
+$_datum{"NAD27 Canada (Northwest Territories/Saskatchewan)"}
+	= Datum->new( "NAD27 Canada (Northwest Territories/Saskatchewan)",
+			"Clarke 1866", 4, 159, 188 );
+
+$_datum{"NAD27 Canada (Yukon)"}
+	= Datum->new( "NAD27 Canada (Yukon)",
+			"Clarke 1866", -7, 139, 181 );
+
+$_datum{"NAD27 Canal Zone"}
+	= Datum->new( "NAD27 Canal Zone",
+			"Clarke 1866", 0, 125, 201 );
+
+$_datum{"NAD27 Caribbean"}
+	= Datum->new( "NAD27 Caribbean",
+			"Clarke 1866", -7, 152, 178 );
+
+$_datum{"NAD27 MEAN:Antigua/Barbados/Barbuda/Caicos Islands/Cuba/Dominican Republic/Grand Cayman/Jamaica/Turks Islands"}
+	= Datum->new( "NAD27 MEAN:Antigua/Barbados/Barbuda/Caicos Islands/Cuba/Dominican Republic/Grand Cayman/Jamaica/Turks Islands",
+			"Clarke 1866", -3, 142, 183 );
+
+$_datum{"NAD27 MEAN:Belize/Costa Rica/El Salvador/Guatemala/Honduras/Nicaragua"}
+	= Datum->new( "NAD27 MEAN:Belize/Costa Rica/El Salvador/Guatemala/Honduras/Nicaragua",
+			"Clarke 1866", 0, 125, 194 );
+
+$_datum{"NAD27 CONUS MEAN"}
+	= Datum->new( "NAD27 CONUS MEAN",
+			"Clarke 1866", -8, 160, 176 );
+
+  # Added for compatibility reasons.  Same as above.
+$_datum{"NAD27 CONUS"}
+	= Datum->new( "NAD27 CONUS",
+			"Clarke 1866", -8, 160, 176 );
+
+$_datum{"NAD27 CONUS MEAN:E of Mississippi/Louisiana/Missouri/Minnesota"}
+	= Datum->new( "NAD27 CONUS MEAN:E of Mississippi/Louisiana/Missouri/Minnesota",
+			"Clarke 1866", -9, 161, 179 );
+
+$_datum{"NAD27 CONUS MEAN:W of Mississippi/Except Louisiana/Minnesota/Missouri"}
+	= Datum->new( "NAD27 CONUS W of Mississippi/Except Louisiana/Minnesota/Missouri",
+			"Clarke 1866", -8, 159, 175 );
+
+$_datum{"NAD27 Cuba"}
+	= Datum->new( "NAD27 Cuba",
+			"Clarke 1866", -9, 152, 178 );
+
+$_datum{"NAD27 Greenland (Hayes Peninsula)"}
+	= Datum->new( "NAD27 Greenland (Hayes Peninsula)",
+			"Clarke 1866", 11, 114, 195 );
+
+$_datum{"NAD27 Mexico"}
+	= Datum->new( "NAD27 Mexico",
+			"Clarke 1866", -12, 130, 190 );
+
+$_datum{"NAD27 San Salvador"}
+	= Datum->new( "NAD27 San Salvador",
+			"Clarke 1866", 1, 140, 165 );
+
+$_datum{"NAD83 Alaska (Except Aleutian Is)"}
+	= Datum->new( "NAD83 Alaska (Except Aleutian Is)",
+			"GRS 1980", 0, 0, 0 );
+
+$_datum{"NAD83 Aleutian Is"}
+	= Datum->new( "NAD83 Aleutian Is",
+			"GRS 1980", -2, 0, 4 );
+
+$_datum{"NAD83 Canada"}
+	= Datum->new( "NAD83 Canada",
+			"GRS 1980", 0, 0, 0 );
+
+$_datum{"NAD83 CONUS"}
+	= Datum->new( "NAD83 CONUS",
+			"GRS 1980", 0, 0, 0 );
+
+$_datum{"NAD83 Hawaii"}
+	= Datum->new( "NAD83 Hawaii",
+			"GRS 1980", 1, 1, -1 );
+
+$_datum{"NAD83 Mexico/Central America"}
+	= Datum->new( "NAD83 Mexico/Central America",
+			"GRS 1980", 0, 0, 0 );
+
+$_datum{"North Sahara"}
+	= Datum->new( "North Sahara",
+			"Clarke 1880", -186, -93, 310 );
+
+$_datum{"Nahrwn Masirah Ilnd"}
+	= Datum->new( "Nahrwn Masirah Ilnd",
+			"Clarke 1880", -247, -148, 369 );
+
+$_datum{"Nahrwn Saudi Arbia"}
+	= Datum->new( "Nahrwn Saudi Arbia",
+			"Clarke 1880", -231, -196, 482 );
+
+$_datum{"Nahrwn United Arab"}
+	= Datum->new( "Nahrwn United Arab",
+			"Clarke 1880", -249, -156, 381 );
+
+$_datum{"Naparima BWI"}
+	= Datum->new( "Naparima BWI",
+			"International 1924", -2, 374, 172 );
+
+$_datum{"Observatorio Meteorologico 1939"}
+	= Datum->new( "Observatorio Meteorologico 1939",
+			"International 1924", -425, -169, 81 );
+
+$_datum{"Old Egyptian 1907"}
+	= Datum->new( "Old Egyptian 1907",
+			"Helmert 1906", -130, 110, -13 );
+
+$_datum{"Old Hawaiian Hawaii"}
+	= Datum->new( "Old Hawaiian Hawaii",
+			"Clarke 1866", 89, -279, -183 );
+
+$_datum{"Old Hawaiian Kauai"}
+	= Datum->new( "Old Hawaiian Kauai",
+			"Clarke 1866", 45, -290, -172 );
+
+$_datum{"Old Hawaiian Maui"}
+	= Datum->new( "Old Hawaiian Maui",
+			"Clarke 1866", 65, -290, -190 );
+
+$_datum{"Old Hawaiian MEAN"}
+	= Datum->new( "Old Hawaiian MEAN",
+			"Clarke 1866", 61, -285, -181 );
+
+$_datum{"Old Hawaiian Oahu"}
+	= Datum->new( "Old Hawaiian Oahu",
+			"Clarke 1866", 58, -283, -182 );
+
+$_datum{"Oman"}
+	= Datum->new( "Oman",
+			"Clarke 1880", -346, -1, 224 );
+
+$_datum{"Ordnance Survey Great Britain 1936 England"}
+	= Datum->new( "Ordnance Survey Great Britain 1936 England",
+			"Airy 1830", 371, -112, 434 );
+
+$_datum{"Ordnance Survey Great Britain 1936 England/Isle of Man/Wales"}
+	= Datum->new( "Ordnance Survey Great Britain 1936 England/Isle of Man/Wales",
+			"Airy 1830", 371, -111, 434 );
+
+$_datum{"Ordnance Survey Great Britain 1936 MEAN:England/Isle of Man/Scotland/Shetland Is/Wales"}
+	= Datum->new( "Ordnance Survey Great Britain 1936 MEAN:England/Isle of Man/Scotland/Shetland Is/Wales",
+			"Airy 1830", 375, -111, 431 );
+
+$_datum{"Ordnance Survey Great Britain 1936 Scotland/Shetland Is"}
+	= Datum->new( "Ordnance Survey Great Britain 1936 Scotland/Shetland Is",
+			"Airy 1830", 384, -111, 425 );
+
+$_datum{"Ordnance Survey Great Britain 1936 Wales"}
+	= Datum->new( "Ordnance Survey Great Britain 1936 Wales",
+			"Airy 1830", 370, -108, 434 );
+
+$_datum{"Pico De Las Nieves"}
+	= Datum->new( "Pico De Las Nieves",
+			"International 1924", -307, -92, 127 );
+
+$_datum{"Pitcairn Astro 1967"}
+	= Datum->new( "Pitcairn Astro 1967",
+			"International 1924", 185, 165, 42 );
+
+$_datum{"Point 58"}
+	= Datum->new( "Point 58",
+			"Clarke 1880", -106, -129, 165 );
+
+$_datum{"Pointe Noire 1948"}
+	= Datum->new( "Pointe Noire 1948",
+			"Clarke 1880", -148, 51, -291 );
+
+$_datum{"Porto Santo 1936"}
+	= Datum->new( "Porto Santo 1936",
+			"International 1924", -499, -249, 314 );
+
+$_datum{"Provisional South American 1956 Bolivia"}
+	= Datum->new( "Provisional South American 1956 Bolivia",
+			"International 1924", -270, 188, -388 );
+
+$_datum{"Provisional South American 1956 Chile Northern/Near 19S"}
+	= Datum->new( "Provisional South American 1956 Chile Northern/Near 19S",
+			"International 1924", -270, 183, -390 );
+
+$_datum{"Provisional South American 1956 Chile Southern/Near 43S"}
+	= Datum->new( "Provisional South American 1956 Chile Southern/Near 43S",
+			"International 1924", -305, 243, -442 );
+
+$_datum{"Provisional South American 1956 Columbia"}
+	= Datum->new( "Provisional South American 1956 Columbia",
+			"International 1924", -282, 169, -371 );
+
+$_datum{"Provisional South American 1956 Ecuador"}
+	= Datum->new( "Provisional South American 1956 Ecuador",
+			"International 1924", -278, 171, -367 );
+
+$_datum{"Provisional South American 1956 Guyana"}
+	= Datum->new( "Provisional South American 1956 Guyana",
+			"International 1924", -298, 159, -369 );
+
+$_datum{"Provisional South American 1956 MEAN:Bolivia/Chile/Columbia/Ecuador/Guyana/Peru/Venezuela"}
+	= Datum->new( "Provisional South American 1956 MEAN:Bolivia/Chile/Columbia/Ecuador/Guyana/Peru/Venezuela",
+			"International 1924", -288, 175, -376 );
+
+$_datum{"Provisional South American 1956 Peru"}
+	= Datum->new( "Provisional South American 1956 Peru",
+			"International 1924", -279, 175, -379 );
+
+$_datum{"Provisional South American 1956 Venezuela"}
+	= Datum->new( "Provisional South American 1956 Venezuela",
+			"International 1924", -295, 173, -371 );
+
+$_datum{"Provisional South Chilean 1963 Near 53S"}
+	= Datum->new( "Provisional South Chilean 1963 Near 53S",
+			"International 1924", 16, 196, 93 );
+
+$_datum{"Puerto Rico/Virgin Is"}
+	= Datum->new( "Puerto Rico/Virgin Is",
+			"Clarke 1866", 11, 72, -101 );
+
+$_datum{"Pulkovo 1942"}
+	= Datum->new( "Pulkovo 1942",
+			"Krassovsky 1940", 28, -130, -95 );
+
+$_datum{"Qatar National"}
+	= Datum->new( "Qatar National",
+			"International 1924", -128, -283, 22 );
+
+$_datum{"Qornoq"}
+	= Datum->new( "Qornoq",
+			"International 1924", 164, 138, -189 );
+
+$_datum{"Reunion"}
+	= Datum->new( "Reunion",
+			"International 1924", 94, -948, -1262 );
+
+$_datum{"Rome 1940"}
+	= Datum->new( "Rome 1940",
+			"International 1924", -225, -65, 9 );
+
+$_datum{"RT 90"}
+	= Datum->new( "RT 90",
+			"Bessel 1841", 498, -36, 568 );
+
+$_datum{"S-42 (Pulkovo 1942) Hungary"}
+	= Datum->new( "S-42 (Pulkovo 1942) Hungary",
+			"Krassovsky 1940", 28, -121, -77 );
+
+$_datum{"S-42 (Pulkovo 1942) Poland"}
+	= Datum->new( "S-42 (Pulkovo 1942) Poland",
+			"Krassovsky 1940", 23, -124, -82 );
+
+$_datum{"S-42 (Pulkovo 1942) Czechoslavakia"}
+	= Datum->new( "S-42 (Pulkovo 1942) Czechoslavakia",
+			"Krassovsky 1940", 26, -121, -78 );
+
+$_datum{"S-42 (Pulkovo 1942) Latvia"}
+	= Datum->new( "S-42 (Pulkovo 1942) Latvia",
+			"Krassovsky 1940", 24, -124, -82 );
+
+$_datum{"S-42 (Pulkovo 1942) Kazakhstan"}
+	= Datum->new( "S-42 (Pulkovo 1942) Kazakhstan",
+			"Krassovsky 1940", 15, -130, -84 );
+
+$_datum{"S-42 (Pulkovo 1942) Albania"}
+	= Datum->new( "S-42 (Pulkovo 1942) Albania",
+			"Krassovsky 1940", 24, -130, -92 );
+
+$_datum{"S-42 (Pulkovo 1942) Romania"}
+	= Datum->new( "S-42 (Pulkovo 1942) Romania",
+			"Krassovsky 1940", 28, -121, -77 );
+
+$_datum{"S-JTSK Czechoslavakia"}
+	= Datum->new( "S-JTSK Czechoslavakia",
+			"Bessel 1841", 589, 76, 480 );
+
+$_datum{"Santo (DOS) 1965"}
+	= Datum->new( "Santo (DOS) 1965",
+			"International 1924", 170, 42, 84 );
+
+$_datum{"Sao Braz"}
+	= Datum->new( "Sao Braz",
+			"International 1924", -203, 141, 53 );
+
+$_datum{"Sapper Hill 1943"}
+	= Datum->new( "Sapper Hill 1943",
+			"International 1924", -355, 21, 72 );
+
+$_datum{"Schwarzeck"}
+	= Datum->new( "Schwarzeck",
+			"Bessel 1841 (Namibia)", 616, 97, -251 );
+
+$_datum{"Selvagem Grande 1938"}
+	= Datum->new( "Selvagem Grande 1938",
+			"International 1924", -289, -124, 60 );
+
+$_datum{"Sierra Leone 1960"}
+	= Datum->new( "Sierra Leone 1960",
+			"Clarke 1880", -88, 4, 101 );
+
+$_datum{"South American 1969 Argentina"}
+	= Datum->new( "South American 1969 Argentina",
+			"South American 1969", -62, -1, -37 );
+
+$_datum{"South American 1969 Bolivia"}
+	= Datum->new( "South American 1969 Bolivia",
+			"South American 1969", -61, 2, -48 );
+
+$_datum{"South American 1969 Brazil"}
+	= Datum->new( "South American 1969 Brazil",
+			"South American 1969", -60, -2, -41 );
+
+$_datum{"South American 1969 Chile"}
+	= Datum->new( "South American 1969 Chile",
+			"South American 1969", -75, -1, -44 );
+
+$_datum{"South American 1969 Colombia"}
+	= Datum->new( "South American 1969 Colombia",
+			"South American 1969", -44, 6, -36 );
+
+$_datum{"South American 1969 Ecuador"}
+	= Datum->new( "South American 1969 Ecuador",
+			"South American 1969", -48, 3, -44 );
+
+$_datum{"South American 1969 Ecuador:Baltra/Galapagos"}
+	= Datum->new( "South American 1969 Ecuador:Baltra/Galapagos",
+			"South American 1969", -47, 26, -42 );
+
+$_datum{"South American 1969 Guyana"}
+	= Datum->new( "South American 1969 Guyana",
+			"South American 1969", -53, 3, -47 );
+
+$_datum{"South American 1969 MEAN"}
+	= Datum->new( "South American 1969 MEAN",
+			"South American 1969", -57, 1, -41 );
+
+$_datum{"South American 1969 Paraguay"}
+	= Datum->new( "South American 1969 Paraguay",
+			"South American 1969", -61, 2, -33 );
+
+$_datum{"South American 1969 Peru"}
+	= Datum->new( "South American 1969 Peru",
+			"South American 1969", -58, 0, -44 );
+
+$_datum{"South American 1969 Trinidad/Tobago"}
+	= Datum->new( "South American 1969 Trinidad/Tobago",
+			"South American 1969", -45, 12, -33 );
+
+$_datum{"South American 1969 Venezuela"}
+	= Datum->new( "South American 1969 Venezuela",
+			"South American 1969", -45, 8, -33 );
+
+$_datum{"South Asia"}
+	= Datum->new( "South Asia",
+			"Modified Fischer 1960", 7, -10, -26 );
+
+$_datum{"Southeast Base"}
+	= Datum->new( "Southeast Base",
+			"International 1924", -499, -249, 314 );
+
+$_datum{"Southwest Base"}
+	= Datum->new( "Southwest Base",
+			"International 1924", -104, 167, -38 );
+
+$_datum{"Tananarive Observatory 1925"}
+	= Datum->new( "Tananarive Observatory 1925",
+			"International 1924", -189, -242, -91 );
+
+$_datum{"Timbalai 1948"}
+	= Datum->new( "Timbalai 1948",
+			"Everest (Sabah Sarawak)", -679, 669, -48 );
+
+$_datum{"Tokyo Japan"}
+	= Datum->new( "Tokyo Japan",
+			"Bessel 1841", -148, 507, 685 );
+
+$_datum{"Tokyo MEAN"}
+	= Datum->new( "Tokyo MEAN",
+			"Bessel 1841", -148, 507, 685 );
+
+$_datum{"Tokyo Okinawa"}
+	= Datum->new( "Tokyo Okinawa",
+			"Bessel 1841", -158, 507, 676 );
+
+$_datum{"Tokyo South Korea"}
+	= Datum->new( "Tokyo South Korea",
+			"Bessel 1841", -147, 506, 687 );
+
+$_datum{"Tristan Astro 1968"}
+	= Datum->new( "Tristan Astro 1968",
+			"International 1924", -632, 438, -609 );
+
+$_datum{"Viti Levu 1916"}
+	= Datum->new( "Viti Levu 1916",
+			"Clarke 1880", 51, 391, -36 );
+
+$_datum{"Voirol 1960"}
+	= Datum->new( "Voirol 1960",
+			"Clarke 1880", -123, -206, 219 );
+  
+$_datum{"Wake Island Astro 1952"}
+	= Datum->new( "Wake Island Astro 1952",
+			"International 1924", 276, -57, 149 );
+
+$_datum{"Wake-Eniwetok 1960"}
+	= Datum->new( "Wake-Eniwetok 1960",
+			"Hough 1960", 102, 52, -38 );
+
+$_datum{"WGS 72"}
+	= Datum->new( "WGS 72",
+			"WGS 72", 0, 0, 0 );
+
+$_datum{"WGS 84"}
+	= Datum->new( "WGS 84",
+			"WGS 84", 0, 0, 0 );
+
+$_datum{"Yacare"}
+	= Datum->new( "Yacare",
+			"International 1924", -155, 171, 37 );
+
+$_datum{"Zanderij"}
+	= Datum->new( "Zanderij",
+			"International 1924", -265, 120, -358 );
+
+
+#------------------------------------------------------------------------------------------------
+
+
+package Coordinate;
+
+
+#
+# Note that we export NOTHING!  This module strives to be object-oriented,
+# therefore exporting is a bad thing.  You can get to any of the public
+# methods by using normal method calls on an object.
+#
+
+
+$VERSION = do { my @r=(q$Revision: 1.6 $=~/\d+/g); sprintf "%d."."%02d"x$#r, at r };
+
+
+use Math::Trig;
+#use Math::BigFloat;    # Allows arbitrary length floating point operations
+#use strict;
+
+
+
+
+
+#
+# Here is a Coordinate object.  It contains all of the data
+# for describing a single point on the earth and the methods
+# for setting/getting these values.
+#
+
+#
+# This constructor can be used to create and initialize an object
+# with Latitude/Longitude/Datum fields.
+#
+sub new
+{
+  my $class = shift;		# What class are we constructing?
+  my $self      = { };		# Allocate new memory
+  bless $self, $class;		# Mark it of the right type
+  $self->_init(@_);		# Call _init with remaining args
+  return $self;
+}
+
+
+sub _init
+{
+  my $self = shift;
+  $self->{LATITUDE} = shift if @_;
+  $self->{LONGITUDE} = shift if @_;
+  $self->{DATUM} = shift if @_;
+}
+
+
+#
+# This constructor can be used to create and initialize an object
+# with easting/northing/zone/datum fields (UTM grid).
+#
+sub new_utm
+{
+  my $class = shift;            # What class are we constructing?
+  my $self      = { };          # Allocate new memory
+  bless $self, $class;          # Mark it of the right type
+  $self->_init_utm(@_);         # Call _init with remaining args
+  return $self;
+}
+
+
+sub _init_utm
+{
+  my $self = shift;
+  $self->{EASTING} = shift if @_;
+  $self->{NORTHING} = shift if @_;
+  $self->{ZONE} = shift if @_;
+  $self->{DATUM} = shift if @_;
+}
+
+
+#
+# Returns the version number (RCS version tag) of this module.
+#
+sub version
+{
+  return $VERSION;
+}
+
+
+
+sub latitude
+{
+  my $self = shift;
+  $self->{LATITUDE} = shift if @_;
+  return $self->{LATITUDE};
+}
+
+
+
+
+
+sub longitude
+{
+  my $self = shift;
+  $self->{LONGITUDE} = shift if @_;
+  return $self->{LONGITUDE};
+}
+
+
+
+
+
+sub formatted_latitude
+{
+  my $self = shift;
+  $self->{FORMATTED_LATITUDE} = shift if @_;
+  return $self->{FORMATTED_LATITUDE};
+}
+
+
+
+
+
+sub formatted_longitude
+{
+  my $self = shift;
+  $self->{FORMATTED_LONGITUDE} = shift if @_;
+  return $self->{FORMATTED_LONGITUDE};
+}
+
+
+
+
+
+sub easting
+{
+  my $self = shift;
+  $self->{EASTING} = shift if @_;
+  return $self->{EASTING};
+}
+
+
+
+
+
+sub northing
+{
+  my $self = shift;
+  $self->{NORTHING} = shift if @_;
+  return $self->{NORTHING};
+}
+
+
+
+
+
+sub zone
+{
+  my $self = shift;
+  $self->{ZONE} = shift if @_;
+  return $self->{ZONE};
+}
+
+
+
+
+
+sub datum
+{
+  my $self = shift;
+  $self->{DATUM} = shift if @_;
+  return $self->{DATUM};
+}
+
+
+
+
+
+#
+# Converts lat/lon to UTM coordinates.  Equations from USGS Bulletin 1532
+# (According to comments in the original C code).
+#
+# East Longitudes are positive, West are negative. 
+# North latitudes are positive, South are negative.
+# Latitude and longitude are in decimal degrees.
+#
+# This method fills in the Easting/Northing/Zone fields in the object.
+# The Zone field will look something like: "10U" when filled in.
+#
+sub lat_lon_to_utm
+{
+  my $position = shift;			# Snag the pointer to the object.
+
+  my $PI = 3.14159265358979323846;
+  my $deg_2_rad = $PI / 180;
+  my $k0 = 0.9996;
+
+  # First get the datum used in the position from the object:
+  my $datum = $position->datum();
+
+  # Now find out the ellipsoid used by consulting the DatumTable:
+  my $ellipsoid = DatumTable->ellipsoid( $datum );
+  
+  # Do a lookup in the $ellipsoid{} hash to find the Radius value.
+  my $a = EllipsoidTable->equatorial_radius( $ellipsoid );
+
+  # Do a lookup in the $ellipsoid{} hash to find the Ecc value.
+  my $ecc_Squared = EllipsoidTable->first_ecc_squared( $ellipsoid );
+
+  my $Lat = $position->latitude();
+  my $Long = $position->longitude();
+ 	
+  # Make sure the longitude is between -180.00 .. 179.9
+  my $Long_Temp = ($Long+180)-int(($Long+180)/360)*360-180; 	# -180.00 .. 179.9;
+
+  my $Lat_Rad = $Lat * $deg_2_rad;
+  my $Long_Rad = $Long_Temp * $deg_2_rad;
+  my $Zone_Number = int(($Long_Temp + 180)/6) + 1;
+ 
+  if( $Lat >= 56.0 && $Lat < 64.0 && $Long_Temp >= 3.0 && $Long_Temp < 12.0 )
+  {
+    $Zone_Number = 32;
+  }
+
+  # Special zones for Svalbard
+  if( $Lat >= 72.0 && $Lat < 84.0 ) 
+  {
+    if(    $Long_Temp >= 0.0  && $Long_Temp <  9.0 ) { $Zone_Number = 31 }
+    elsif( $Long_Temp >= 9.0  && $Long_Temp < 21.0 ) { $Zone_Number = 33 }
+    elsif( $Long_Temp >= 21.0 && $Long_Temp < 33.0 ) { $Zone_Number = 35 }
+    elsif( $Long_Temp >= 33.0 && $Long_Temp < 42.0 ) { $Zone_Number = 37 };
+  }
+  my $Long_Origin = ($Zone_Number - 1)*6 - 180 + 3;	# +3 puts origin in middle of zone
+  my $Long_Origin_Rad = $Long_Origin * $deg_2_rad;
+
+  # Compute the UTM Zone from the latitude and longitude
+  # NOTE:  Need to check for out-of-range here.
+  #
+  my $Zone_Letter = &_utm_letter_designator($Lat);
+  #printf( "Zone_Number: %d\t\tZone_Letter: %s\n", $Zone_Number, $Zone_Letter );
+  my $UTM_Zone = sprintf( "%d%s", $Zone_Number, $Zone_Letter );
+
+  my $ecc_Prime_Squared = ($ecc_Squared)/(1-$ecc_Squared);
+
+  my $N = $a/sqrt(1-$ecc_Squared*sin($Lat_Rad)*sin($Lat_Rad));
+  my $T = tan($Lat_Rad) * tan($Lat_Rad);
+  my $C = $ecc_Prime_Squared * cos($Lat_Rad) * cos($Lat_Rad);
+  my $A = cos($Lat_Rad) * ($Long_Rad-$Long_Origin_Rad);
+
+  my $M = $a * ((1 - $ecc_Squared/4 - 3 * $ecc_Squared * $ecc_Squared/64 - 5 * $ecc_Squared * $ecc_Squared * $ecc_Squared/256) * $Lat_Rad
+	- (3 * $ecc_Squared/8 + 3 * $ecc_Squared * $ecc_Squared/32 + 45 * $ecc_Squared * $ecc_Squared * $ecc_Squared/1024) * sin(2 * $Lat_Rad)
+	+ (15 * $ecc_Squared * $ecc_Squared/256 + 45 * $ecc_Squared * $ecc_Squared * $ecc_Squared/1024) * sin(4 * $Lat_Rad) 
+	- (35 * $ecc_Squared * $ecc_Squared * $ecc_Squared/3072) * sin(6 * $Lat_Rad));
+	
+  my $UTM_Easting = ($k0 * $N * ($A + (1 - $T + $C) * $A * $A * $A/6
+	+ (5 - 18 * $T + $T * $T + 72 * $C - 58 * $ecc_Prime_Squared) * $A * $A * $A * $A * $A/120)
+	+ 500000.0);
+
+  my $UTM_Northing = ($k0 * ($M + $N * tan($Lat_Rad) * ($A * $A/2 + (5 - $T + 9 * $C + 4 * $C * $C) * $A * $A * $A * $A/24
+	+ (61 - 58 * $T + $T * $T + 600 * $C - 330 * $ecc_Prime_Squared) * $A * $A * $A * $A * $A * $A/720)));
+
+  if($Lat < 0)
+  {
+    $UTM_Northing += 10000000.0;	# 10000000 meter offset for southern hemisphere
+  }
+
+  # Write the results back to our position object
+  $position->easting( $UTM_Easting );
+  $position->northing( $UTM_Northing );
+  $position->zone( $UTM_Zone );
+  return(1);
+}
+
+
+
+
+
+#
+# This routine determines the correct UTM letter designator for the given latitude.
+# Returns 'Z' if latitude is outside the UTM limits of 84N to 80S.
+#
+# Note that this is a normal subroutine, not an object method.  It is to
+# be used inside this module only and is not exported.
+#
+sub _utm_letter_designator
+{
+  my $Lat = shift;
+  my $Letter_Designator;
+
+  if    (( 84 >= $Lat) && ($Lat >=  72)) { $Letter_Designator = 'X' }
+  elsif (( 72  > $Lat) && ($Lat >=  64)) { $Letter_Designator = 'W' }
+  elsif (( 64  > $Lat) && ($Lat >=  56)) { $Letter_Designator = 'V' }
+  elsif (( 56  > $Lat) && ($Lat >=  48)) { $Letter_Designator = 'U' }
+  elsif (( 48  > $Lat) && ($Lat >=  40)) { $Letter_Designator = 'T' }
+  elsif (( 40  > $Lat) && ($Lat >=  32)) { $Letter_Designator = 'S' }
+  elsif (( 32  > $Lat) && ($Lat >=  24)) { $Letter_Designator = 'R' }
+  elsif (( 24  > $Lat) && ($Lat >=  16)) { $Letter_Designator = 'Q' }
+  elsif (( 16  > $Lat) && ($Lat >=   8)) { $Letter_Designator = 'P' }
+  elsif ((  8  > $Lat) && ($Lat >=   0)) { $Letter_Designator = 'N' }
+  elsif ((  0  > $Lat) && ($Lat >=  -8)) { $Letter_Designator = 'M' }
+  elsif (( -8  > $Lat) && ($Lat >= -16)) { $Letter_Designator = 'L' }
+  elsif ((-16  > $Lat) && ($Lat >= -24)) { $Letter_Designator = 'K' }
+  elsif ((-24  > $Lat) && ($Lat >= -32)) { $Letter_Designator = 'J' }
+  elsif ((-32  > $Lat) && ($Lat >= -40)) { $Letter_Designator = 'H' }
+  elsif ((-40  > $Lat) && ($Lat >= -48)) { $Letter_Designator = 'G' }
+  elsif ((-48  > $Lat) && ($Lat >= -56)) { $Letter_Designator = 'F' }
+  elsif ((-56  > $Lat) && ($Lat >= -64)) { $Letter_Designator = 'E' }
+  elsif ((-64  > $Lat) && ($Lat >= -72)) { $Letter_Designator = 'D' }
+  elsif ((-72  > $Lat) && ($Lat >= -80)) { $Letter_Designator = 'C' }
+  else { $Letter_Designator = 'Z' }; # An error flag: Latitude is outside UTM limits
+
+  return $Letter_Designator;
+}
+
+
+
+
+
+#
+# Converts UTM coordinates to lat/lon.  Equations from USGS Bulletin 1532.
+# East longitudes are positive, West are negative. 
+# North latitudes are positive, South are negative.
+# Latitude and longitude are in decimal degrees. 
+# Zone should look something like: "10U" before starting the conversion.
+#
+sub utm_to_lat_lon
+{
+  my $position = shift;		# Input is in the form of a "Coordinate" object
+
+  my $PI = 3.14159265358979323846;
+  my $rad_2_deg = 180.0 / $PI;
+  my $k0 = 0.9996;
+
+  # First get the datum used in the position from the object:
+  my $datum = $position->datum();
+
+  # Now find out the ellipsoid used by consulting the DatumTable:
+  my $ellipsoid = DatumTable->ellipsoid( $datum );
+
+  # Do a lookup in the $ellipsoid{} hash to find the Radius value.
+  my $a = EllipsoidTable->equatorial_radius( $ellipsoid );
+
+  # Do a lookup in the $ellipsoid{} hash to find the Ecc value.
+  my $ecc_Squared = EllipsoidTable->first_ecc_squared( $ellipsoid );
+
+  my $x = $position->easting();
+  my $y = $position->northing();
+  my $Zone_Letter = $position->zone();
+  my $Zone_Number = $Zone_Letter;
+  $Zone_Number =~ s/(\d+).*/$1/;	# Convert to an integer
+
+  my $e1 = (1-sqrt(1-$ecc_Squared))/(1+sqrt(1-$ecc_Squared));
+
+  $Zone_Letter =~ s/\d+(\w)/$1/;	# Convert UTM zone to just a letter
+  #print "$Zone_Letter\n\n";
+
+  my $Northern_Hemisphere;		# 1 for northern hemisphere, 0 for southern
+
+  $x = $x - 500000.0;			# Remove 500,000 meter offset for longitude
+  $y = $y;
+
+  if(($Zone_Letter ge 'N'))
+  {
+    $Northern_Hemisphere = 1;		# 'N' or higher is in the northern hemisphere
+    #print "Northern Hemisphere\n";
+  }
+  else
+  {
+    $Northern_Hemisphere = 0;		# Point is in southern hemisphere
+    $y -= 10000000.0;			# Remove 10,000,000 meter offset used for southern hemisphere
+    #print "Southern Hemisphere\n";
+  }
+
+  #print "Zone_Number: $Zone_Number\n";
+  my $Long_Origin = ($Zone_Number - 1) * 6 - 180 + 3;	# +3 puts origin in middle of zone
+
+  my $ecc_Prime_Squared = ($ecc_Squared)/(1 - $ecc_Squared);
+
+  my $M = $y / $k0;
+  my $mu = $M/($a * (1 - $ecc_Squared/4 - 3 * $ecc_Squared * $ecc_Squared/64 - 5 * $ecc_Squared * $ecc_Squared * $ecc_Squared/256));
+
+  my $phi1_Rad = $mu + (3 * $e1/2 - 27 * $e1 * $e1 * $e1/32) * sin(2 * $mu) 
+	+ (21 * $e1 * $e1/16 - 55 * $e1 * $e1 * $e1 * $e1/32) * sin(4 * $mu)
+	+(151 * $e1 * $e1 * $e1/96) * sin(6 * $mu);
+
+  my $phi1 = $phi1_Rad * $rad_2_deg;
+
+  my $N1 = $a/sqrt(1 - $ecc_Squared * sin($phi1_Rad) * sin($phi1_Rad));
+  my $T1 = tan($phi1_Rad) * tan($phi1_Rad);
+  my $C1 = $ecc_Prime_Squared * cos($phi1_Rad) * cos($phi1_Rad);
+
+  my $R1 = $a * (1 - $ecc_Squared)/(1 - $ecc_Squared * sin($phi1_Rad) * sin($phi1_Rad)**1.5);
+
+  my $D = $x/($N1 * $k0);
+
+  $Lat = $phi1_Rad - ($N1 * tan($phi1_Rad)/$R1) * ($D * $D/2 - (5 + 3 * $T1 + 10 * $C1 - 4 * $C1 * $C1 - 9 * $ecc_Prime_Squared) * $D * $D * $D * $D/24
+	+(61 + 90 * $T1 + 298 * $C1 + 45 * $T1 * $T1 - 252 * $ecc_Prime_Squared - 3 * $C1 * $C1) * $D * $D * $D * $D * $D * $D/720);
+
+  $Lat = $Lat * $rad_2_deg;
+
+  $Long = ($D - (1 + 2 * $T1 + $C1) * $D * $D * $D/6 + (5 - 2 * $C1 + 28 * $T1 - 3 * $C1 * $C1 + 8 * $ecc_Prime_Squared + 24 * $T1 * $T1)
+	*$D * $D * $D * $D * $D/120)/cos($phi1_Rad);
+
+  $Long = $Long_Origin + $Long * $rad_2_deg;
+
+  # Write the results back to our position object
+  $position->latitude( $Lat );
+  $position->longitude( $Long );
+
+  return(1);
+}
+
+
+
+
+
+#
+# Function to convert latitude and longitude in decimal degrees between WGS 84 and
+# another datum. The arguments to this function are a Coordinate object ($position)
+# and a direction flag ($from_WGS84).  The Datum you're translating to/from is
+# stored in the Datum() field of the object (the other Datum is by default WGS 84).
+#
+sub _datum_shift
+{
+  my $position = shift;				# This is our position object
+
+  my $from_WGS84 = shift;			# If 1, then we're converting from WGS 84
+						# to the datum listed in the position object
+						# If 0, we're going the other way.
+
+  my $PI = 3.14159265358979323846;
+  my $rad_2_deg = 180.0 / $PI;
+  my $deg_2_rad = $PI / 180;
+
+  #printf("%s\n", $position->datum() );
+
+  my $datum = $position->datum();		# Snag the parameters from the position object
+						# (Get the "other" datum).
+
+  my $latitude = $position->latitude();
+  my $longitude = $position->longitude();
+
+  # Now find out the ellipsoid used by consulting the DatumTable:
+  my $ellipsoid = DatumTable->ellipsoid( $datum );
+
+  my $dx = DatumTable->dx($datum);		# Grab the parameters for the "other" datum.
+  my $dy = DatumTable->dy($datum);		# Offsets between "other" datum and WGS84
+  my $dz = DatumTable->dz($datum);		# ellipsoid centers.
+
+  #print "$dx\t$dy\t$dz\n";
+
+	
+  my $WGS_a    = EllipsoidTable->equatorial_radius("WGS 84");	# WGS 84 semimajor axis
+  my $WGS_inv_f = EllipsoidTable->inverse_flattening("WGS 84");	# WGS 84 1/f
+
+  my $phi = $latitude * $deg_2_rad;
+  my $lambda = $longitude * $deg_2_rad;
+  my ($a0, $b0, $es0, $f0);			# Reference ellipsoid of input data
+  my ($a1, $b1, $es1, $f1);			# Reference ellipsoid of output data
+  my $psi;					# geocentric latitude 
+  my ($x, $y, $z);				# 3D coordinates with respect to original datum 
+  my $psi1;					# transformed geocentric latitude 
+
+  if ($datum eq "WGS 84")			# do nothing if current datum is WGS 84
+  {
+    return(1);
+  }
+		
+  if ($from_WGS84)				# convert from WGS 84 to new datum 
+  {
+    $a0 = $WGS_a;				# WGS 84 semimajor axis 
+    $f0 = 1.0 / $WGS_inv_f;			# WGS 84 flattening 
+    $a1 = EllipsoidTable->equatorial_radius($ellipsoid);
+    $f1 = 1.0 / EllipsoidTable->inverse_flattening($ellipsoid);
+  }
+  else						# convert from old datum to WGS 84 
+  {
+    $a0 = EllipsoidTable->equatorial_radius($ellipsoid);	# semimajor axis 
+    $f0 = 1.0 / EllipsoidTable->inverse_flattening($ellipsoid);	# flattening 
+    $a1 = $WGS_a;				# WGS 84 semimajor axis 
+    $f1 = 1 / $WGS_inv_f;				# WGS 84 flattening 
+    $dx = -$dx;
+    $dy = -$dy;
+    $dz = -$dz;
+  }
+
+  $b0 = $a0 * (1 - $f0); 			# semiminor axis for input datum 
+  $es0 = 2 * $f0 - $f0*$f0;			# eccentricity^2 
+
+  $b1 = $a1 * (1 - $f1);			# semiminor axis for output datum 
+  $es1 = 2 * $f1 - $f1*$f1;			# eccentricity^2 
+
+  # Convert geodedic latitude to geocentric latitude, psi 
+	
+  if ($latitude == 0.0 || $latitude == 90.0 || $latitude == -90.0)
+  {
+    $psi = $phi;
+  }
+  else
+  {
+    $psi = atan((1 - $es0) * tan($phi));
+  }
+
+  # Calculate x and y axis coordinates with respect to the original ellipsoid 
+	
+  if ($longitude == 90.0 || $longitude == -90.0)
+  {
+    $x = 0.0;
+    $y = abs($a0 * $b0 / sqrt($b0*$b0 + $a0*$a0* ( tan($psi)**2.0) ) );
+  }
+  else
+  {
+    $x = abs(($a0 * $b0) /
+        sqrt( (1 + (tan($lambda)**2.0) ) * ($b0*$b0 + $a0*$a0 * (tan($psi)**2.0) ) ) );
+
+    $y = abs($x * tan($lambda));
+  }
+	
+  if ($longitude < -90.0 || $longitude > 90.0)
+  {
+    $x = -$x;
+  }
+  if ($longitude < 0.0)
+  {
+    $y = -$y;
+  }
+	
+  # Calculate z axis coordinate with respect to the original ellipsoid 
+	
+  if ($latitude == 90.0)
+  {
+    $z = $b0;
+  }
+  elsif ($latitude == -90.0)
+  {
+    $z = -$b0;
+  }
+  else
+  {
+    $z = tan($psi) * sqrt( ($a0*$a0 * $b0*$b0) / ($b0*$b0 + $a0*$a0 * (tan($psi)**2.0) ) );
+  }
+
+  # Calculate the geocentric latitude with respect to the new ellipsoid 
+
+  $psi1 = atan(($z - $dz) / sqrt(($x - $dx)*($x - $dx) + ($y - $dy)*($y - $dy)));
+	
+  # Convert to geocentric latitude and save return value 
+
+  $latitude = atan(tan($psi1) / (1 - $es1)) * $rad_2_deg;
+
+  # Calculate the longitude with respect to the new ellipsoid 
+	
+  $longitude = atan(($y - $dy) / ($x - $dx)) * $rad_2_deg;
+
+  # Correct the resultant for negative x values 
+	
+  if ($x-$dx < 0.0)
+  {
+    if ($y-$dy > 0.0)
+    {
+      $longitude = 180.0 + $longitude;
+    }
+    else
+    {
+      $longitude = -180.0 + $longitude;
+    }
+  }
+
+  # Write the results back to our position object
+  $position->latitude($latitude);
+  $position->longitude($longitude);
+
+  if (! $from_WGS84)			# If we're converting to WGS 84 datum
+  {
+    $position->datum( "WGS 84" );	# Change the datum to correspond to
+					# the new data in the object
+  }
+
+  #print "New one:  $latitude, $longitude\n";
+
+  return(1);
+}
+
+
+
+
+
+#
+# Method to convert latitude and longitude in decimal degrees from another
+# datum to WGS 84.  The only argument to this method is a Coordinate object
+# with the lat/lon/datum fields filled in.
+#
+# This method returns a NEW Coordinate object with lat/lon/datum fields
+# filled in and the other fields empty.  The original object is not changed.
+#
+sub datum_shift_to_wgs84
+{
+  my $old_position = shift;	# This is our original position object
+
+  my $to_WGS84 = 0;
+
+  # Create a new object and fill in a few fields
+  my $new_position = Coordinate->new(   $old_position->latitude(),
+					$old_position->longitude(),
+					$old_position->datum() );
+
+  &_datum_shift( $new_position, $to_WGS84 );
+
+  return( $new_position );	# Return the datum-shifted object
+}
+
+
+
+
+
+#
+# Method to convert latitude and longitude in decimal degrees from WGS 84 to
+# another datum.  The arguments to this method are a Coordinate object
+# with the lat/lon/datum fields filled in (the datum field must be "WGS 84"),
+# AND a datum (string) to shift to.
+#
+# This method returns a NEW Coordinate object with lat/lon/datum fields
+# filled in.  The original object is not changed.
+#
+sub datum_shift_from_wgs84_to
+{
+  my $old_position = shift;			# This is our original position object
+  my $new_datum = shift;			# The datum we wish to shift to
+
+  my $from_WGS84 = 1;
+
+  # Create a new object and fill in a few fields
+  my $new_position = Coordinate->new(	$old_position->latitude(),
+					$old_position->longitude(),
+					$new_datum );
+
+  &_datum_shift( $new_position, $from_WGS84 );
+
+  return( $new_position );	# Return the datum-shifted object
+}
+
+
+
+
+
+#
+# Degrees and Decimal Minutes
+#
+# Fills in the Formatted_latitude and Formatted_longitude variables
+# in the object.
+#
+sub degrees_minutes
+{
+  my $self = shift;						# Get the object to work on
+
+  $temp = CoordinateFormat->new();				# Create temporary object
+
+  $temp->raw( $self->latitude() );				# Fill in with raw data
+  $self->formatted_latitude ( $temp->degrees_minutes() );	# Process it & fill in our finished string
+
+  $temp->raw( $self->longitude() );				# Fill in with raw data
+  $self->formatted_longitude( $temp->degrees_minutes() );	# process it & fill in our finished string
+
+  return(1);
+}
+
+
+
+
+
+#
+# Degrees/Minutes/Seconds
+#
+# Fills in the Formatted_latitude and Formatted_longitude variables
+# in the object.
+#
+sub degrees_minutes_seconds
+{
+  my $self = shift;							# Get the object to work on
+
+  $temp = CoordinateFormat->new();					# Create the temporary object
+
+  $temp->raw( $self->latitude() );					# Fill in with raw data
+  $self->formatted_latitude ( $temp->degrees_minutes_seconds() );	# Process it & fill in our finished string
+
+  $temp->raw( $self->longitude() );					# Fill in with raw data
+  $self->formatted_longitude( $temp->degrees_minutes_seconds() );	# Process it & fill in our finished string
+
+  return(1);
+}
+
+
+
+
+
+#
+# Decimal Degrees
+#
+# Fills in the Formatted_latitude and Formatted_longitude variables
+# in the object.
+#
+sub decimal_degrees
+{
+  my $self = shift;						# Get the object to work on
+
+  $temp = CoordinateFormat->new();				# Create the temporary object
+
+  $temp->raw( $self->latitude() );				# Fill in with raw data
+  $self->formatted_latitude ( $temp->decimal_degrees() );	# Process it & fill in our finished string
+
+  $temp->raw( $self->longitude() );				# Fill in with raw data
+  $self->formatted_longitude( $temp->decimal_degrees() );	# Process it & fill in our finished string
+
+  return(1);
+}
+
+
+#------------------------------------------------------------------------------------------------
+
+
+#
+# Auto-run code
+#
+# This code will get run automatically whenever this file gets "required"
+# or "used" in another Perl program.
+#
+
+  
+1;		# Needed to prevent exception when loading this module
+
+
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
new file mode 100644
index 0000000..948848c
--- /dev/null
+++ b/scripts/Makefile.am
@@ -0,0 +1,52 @@
+# $Id: Makefile.am,v 1.41 2012/11/27 04:41:23 tvrusso Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+scriptsdir=${pkgdatadir}/scripts
+dist_scripts_DATA = \
+    Coordinate.pm \
+    coord-convert.pl \
+    geopdf2gtiff.pl \
+    get-BOMdata \
+    get-fcc-rac.pl \
+    get-gnis \
+    get-pop \
+    get-maptools.sh \
+    get-NWSdata \
+    get_shapelib.sh \
+    gpx2shape \
+    icontable.pl \
+    inf2geo.pl \
+    kiss-off.pl \
+    langElmerFudd.pl \
+    langMuppetsChef.pl \
+    langOldeEnglish.pl \
+    langPigLatin.pl \
+    langPirateEnglish.pl \
+    mapblast2geo.pl \
+    mapfgd.pl \
+    object2shp.pl \
+    overlay.pl \
+    ozi2geo.pl \
+    permutations.pl \
+    pos2shp.pl \
+    ridge_radar.pl \
+    slideshow.pl \
+    split_gnis.bash \
+    split_gnis.pl \
+    test_coord.pl \
+    toporama50k.pl \
+    toporama250k.pl\
+    track-get.pl \
+    update_langfile.pl \
+    values \
+    values.pl \
+    waypoint-get.pl \
+    xastir-fixcfg.sh \
+    xastir-migrate.sh \
+    Xastir_tigerpoly.py
+
+install-data-hook:
+	cd $(DESTDIR)$(scriptsdir) && \
+	chmod a+x *.sh *.pl *.py get-* gpx2* *.bash
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
new file mode 100644
index 0000000..a00c7f4
--- /dev/null
+++ b/scripts/Makefile.in
@@ -0,0 +1,467 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.41 2012/11/27 04:41:23 tvrusso Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = scripts
+DIST_COMMON = $(dist_scripts_DATA) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/values.in \
+	$(srcdir)/values.pl.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = values values.pl
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(scriptsdir)"
+DATA = $(dist_scripts_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+scriptsdir = ${pkgdatadir}/scripts
+dist_scripts_DATA = \
+    Coordinate.pm \
+    coord-convert.pl \
+    geopdf2gtiff.pl \
+    get-BOMdata \
+    get-fcc-rac.pl \
+    get-gnis \
+    get-pop \
+    get-maptools.sh \
+    get-NWSdata \
+    get_shapelib.sh \
+    gpx2shape \
+    icontable.pl \
+    inf2geo.pl \
+    kiss-off.pl \
+    langElmerFudd.pl \
+    langMuppetsChef.pl \
+    langOldeEnglish.pl \
+    langPigLatin.pl \
+    langPirateEnglish.pl \
+    mapblast2geo.pl \
+    mapfgd.pl \
+    object2shp.pl \
+    overlay.pl \
+    ozi2geo.pl \
+    permutations.pl \
+    pos2shp.pl \
+    ridge_radar.pl \
+    slideshow.pl \
+    split_gnis.bash \
+    split_gnis.pl \
+    test_coord.pl \
+    toporama50k.pl \
+    toporama250k.pl\
+    track-get.pl \
+    update_langfile.pl \
+    values \
+    values.pl \
+    waypoint-get.pl \
+    xastir-fixcfg.sh \
+    xastir-migrate.sh \
+    Xastir_tigerpoly.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu scripts/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+values: $(top_builddir)/config.status $(srcdir)/values.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+values.pl: $(top_builddir)/config.status $(srcdir)/values.pl.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-dist_scriptsDATA: $(dist_scripts_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(scriptsdir)" || $(MKDIR_P) "$(DESTDIR)$(scriptsdir)"
+	@list='$(dist_scripts_DATA)'; test -n "$(scriptsdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(scriptsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(scriptsdir)" || exit $$?; \
+	done
+
+uninstall-dist_scriptsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_scripts_DATA)'; test -n "$(scriptsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(scriptsdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(scriptsdir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(scriptsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_scriptsDATA
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_scriptsDATA
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am \
+	install-data-hook install-dist_scriptsDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
+	uninstall-dist_scriptsDATA
+
+
+install-data-hook:
+	cd $(DESTDIR)$(scriptsdir) && \
+	chmod a+x *.sh *.pl *.py get-* gpx2* *.bash
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/scripts/Xastir_tigerpoly.py b/scripts/Xastir_tigerpoly.py
new file mode 100755
index 0000000..65e713d
--- /dev/null
+++ b/scripts/Xastir_tigerpoly.py
@@ -0,0 +1,562 @@
+#!/usr/bin/env python
+###############################################################################
+# $Id: Xastir_tigerpoly.py,v 1.11 2012/11/01 18:57:19 we7u Exp $
+#
+# Portions Copyright (C) 2004-2012  The Xastir Group
+#
+# Modified version of GDAL/OGR "tigerpoly.py" script (as described below)
+# adapted to assemble information from more tables of the TIGER/Line data
+# than had been done by the original, and with the option of dissolving
+# common boundaries between areas with identical landmark values.
+#
+# You must have installed GDAL/OGR, configured to use python in order to use 
+# this script
+###############################################################################
+# 
+# Adapted for Xastir use by Tom Russo
+#
+# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+#  When run with the "-d" option, this script changes the topology of 
+#  TIGER/Line polygons by dissolving common bounaries between adjacent 
+#  polygons with identical Landmark values.  This is done SOLELY for 
+#  improvement of on-screen presentation of the shapefiles, and the resulting 
+#  files have too much information removed to make them useful for any other 
+#  purpose but display in Xastir.
+#
+#  If any shapefile data produced by this script with the -d option are 
+#  distributed publicly, they should have a prominent disclaimer to this 
+#  effect.  The data produced by this script with that option bear only a 
+#  superficial, graphical resemblence to the  TIGER/Line data from which they 
+#  were created.
+#
+####################Original comments follow
+###############################################################################
+# tigerpoly.py,v 1.3 2003/07/11 14:52:13 warmerda Exp 
+#
+# Project:  OGR Python samples
+# Purpose:  Assemble TIGER Polygons.
+# Author:   Frank Warmerdam, warmerdam at pobox.com
+#
+###############################################################################
+# Copyright (c) 2003, Frank Warmerdam <warmerdam at pobox.com>
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+###############################################################################
+
+
+import osr
+import ogr
+import string
+import sys
+
+#############################################################################
+class Module:
+
+    def __init__( self ):
+        self.lines = {}
+        self.poly_line_links = {}
+
+#############################################################################
+# I dunno, does this initializer make sense?
+class Field:
+    def __init__( self ):
+        self.layer = ''
+        self.layerName = ''
+        self.field_defn = ''
+        self.fld_index = ''
+
+#############################################################################
+# We'll use this class to keep track of polygons that get mapped into each 
+# other
+class PolyMap:
+    def __init__( self ):
+      self.polyid=''
+      self.mappedlist=[]
+
+#############################################################################
+def Usage():
+    print 'Usage: tigerpoly.py [-d] infile [outfile].shp'
+    print
+    sys.exit(1)
+
+#############################################################################
+# Argument processing.
+
+infile = None
+outfile = None
+dissolve=0
+
+i = 1
+while i < len(sys.argv):
+    arg = sys.argv[i]
+
+    if arg == "-d":
+        dissolve=1
+    
+    elif infile is None:
+	infile = arg
+
+    elif outfile is None:
+	outfile = arg
+
+    else:
+	Usage()
+
+    i = i + 1
+
+if outfile is None:
+    outfile = 'poly.shp'
+
+if infile is None:
+    Usage()
+
+if dissolve == 1:
+   print '*******************************************************************'
+   print 'WARNING!  WARNING! WARNING!'
+   print 'You have chosen to dissolve polygons with identical landmark names/types.'
+   print ' Doing this changes the topology of the TIGER/Line data, and renders'
+   print ' the resulting shapefiles useful only for display purposes.'
+   print ' IF YOU DISTRIBUTE THIS DATA, PLEASE INCLUDE A DISCLAIMER THAT'
+   print ' THE DATA HAVE BEEN MODIFIED AND THAT THEIR USE FOR PURPOSES OTHER'
+   print ' DISPLAY IS NOT RECOMMENDED!'
+   print '*******************************************************************'
+
+#############################################################################
+# Open the datasource to operate on.
+
+ds = ogr.Open( infile, update = 0 )
+
+poly_layer = ds.GetLayerByName( 'Polygon' )
+pip_layer = ds.GetLayerByName( 'PIP' )
+areaLandmarks_layer = ds.GetLayerByName( 'AreaLandmarks' )
+Landmarks_layer = ds.GetLayerByName( 'Landmarks' )
+
+#############################################################################
+#	Create output file for the composed polygons.
+
+shp_driver = ogr.GetDriverByName( 'ESRI Shapefile' )
+shp_driver.DeleteDataSource( outfile )
+
+shp_ds = shp_driver.CreateDataSource( outfile )
+
+shp_layer = shp_ds.CreateLayer( 'out', geom_type = ogr.wkbPolygon )
+
+# Now create a list of all the fields for the DBF file, using the unique
+# fields in Polygon, PIP, AreaLandmarks and Landmarks --- eliminate
+# all fields of identical names (because those are just the fields that
+# link the records to each other).  When we do so, must store layer, field
+# index in the hash, and we'll write it back by 
+
+# Create a hash of field definitions indexed by field name.
+fields_hash = {}
+field_names = []
+
+src_defn = poly_layer.GetLayerDefn()
+poly_field_count = src_defn.GetFieldCount()
+
+for fld_index in range(poly_field_count):
+    src_fd = src_defn.GetFieldDefn( fld_index )
+    fields_hash[src_fd.GetName()] = Field()
+    fields_hash[src_fd.GetName()].layer=poly_layer
+    fields_hash[src_fd.GetName()].layerName='Polygon'
+    fields_hash[src_fd.GetName()].field_defn=src_defn
+    fields_hash[src_fd.GetName()].fld_index=fld_index
+    field_names.append(src_fd.GetName())
+#    print 'Got a Polygon field called %s' % src_fd.GetName()
+
+
+# now loop over other layers
+src_defn = pip_layer.GetLayerDefn()
+pip_field_count = src_defn.GetFieldCount()
+for fld_index in range(pip_field_count):
+    src_fd = src_defn.GetFieldDefn( fld_index )
+    try:
+      foo = fields_hash[src_fd.GetName()]
+#      print ' found pip field %s already in hash' % src_fd.GetName()
+    except:
+      field=Field()
+      fields_hash[src_fd.GetName()] = field
+      fields_hash[src_fd.GetName()].layer=pip_layer
+      fields_hash[src_fd.GetName()].layerName='PIP'
+      fields_hash[src_fd.GetName()].field_defn=src_defn
+      fields_hash[src_fd.GetName()].fld_index=fld_index
+      field_names.append(src_fd.GetName())
+#      print 'Got a pip field called %s' % src_fd.GetName()            
+
+src_defn = areaLandmarks_layer.GetLayerDefn()
+areaLandmarks_field_count = src_defn.GetFieldCount()
+for fld_index in range(areaLandmarks_field_count):
+    src_fd = src_defn.GetFieldDefn( fld_index )
+    try:
+      foo = fields_hash[src_fd.GetName()]
+#      print ' found areaLandmarks field %s already in hash' % src_fd.GetName()
+    except:
+      field=Field()
+      fields_hash[src_fd.GetName()] = field
+      fields_hash[src_fd.GetName()].layer=areaLandmarks_layer
+      fields_hash[src_fd.GetName()].layerName='AreaLandmarks'
+      fields_hash[src_fd.GetName()].field_defn=src_defn
+      fields_hash[src_fd.GetName()].fld_index=fld_index
+      field_names.append(src_fd.GetName())
+#      print 'Got a areaLandmarks field called %s' % src_fd.GetName()            
+src_defn = Landmarks_layer.GetLayerDefn()
+Landmarks_field_count = src_defn.GetFieldCount()
+for fld_index in range(Landmarks_field_count):
+    src_fd = src_defn.GetFieldDefn( fld_index )
+    try:
+      foo = fields_hash[src_fd.GetName()]
+#      print ' found Landmarks field %s already in hash' % src_fd.GetName()
+    except:
+      field=Field()
+      fields_hash[src_fd.GetName()] = field
+      fields_hash[src_fd.GetName()].layer=Landmarks_layer
+      fields_hash[src_fd.GetName()].layerName='Landmarks'
+      fields_hash[src_fd.GetName()].field_defn=src_defn
+      fields_hash[src_fd.GetName()].fld_index=fld_index
+      field_names.append(src_fd.GetName())
+#      print 'Got a Landmarks field called %s' % src_fd.GetName()            
+
+# we now have a hash whose keys are all our field names, and from which
+# we *should* be able to retreive fields as needed
+#print ' we found %d fields' % len(fields_hash)
+#print ' the names array has %d names ' % len(field_names)
+#for field_name in (field_names):
+#  print ' key %s we get field from %s ' % (field_name ,fields_hash[field_name].layerName)
+
+# Now loop over all those field names, create the dbf file definition
+
+for field_name in (field_names):
+  src_defn = fields_hash[field_name].field_defn
+  src_fd = src_defn.GetFieldDefn( fields_hash[field_name].fld_index )
+  fd = ogr.FieldDefn( src_fd.GetName(), src_fd.GetType() )
+  fd.SetWidth( src_fd.GetWidth() )
+  fd.SetPrecision( src_fd.GetPrecision() )
+  shp_layer.CreateField(fd)
+
+print 'Reading Lines'
+#############################################################################
+# Read all features in the line layer, holding just the geometry in a hash
+# for fast lookup by TLID.
+
+line_layer = ds.GetLayerByName( 'CompleteChain' )
+line_count = 0
+
+modules_hash = {}
+
+feat = line_layer.GetNextFeature()
+geom_id_field = feat.GetFieldIndex( 'TLID' )
+tile_ref_field = feat.GetFieldIndex( 'MODULE' )
+while feat is not None:
+    geom_id = feat.GetField( geom_id_field )
+    tile_ref = feat.GetField( tile_ref_field )
+
+    try:
+        module = modules_hash[tile_ref]
+    except:
+        module = Module()
+        modules_hash[tile_ref] = module
+
+    module.lines[geom_id] = feat.GetGeometryRef().Clone()
+    line_count = line_count + 1
+
+    feat.Destroy()
+
+    feat = line_layer.GetNextFeature()
+
+print 'Got %d lines in %d modules.' % (line_count,len(modules_hash))
+
+#############################################################################
+# Now we need to pull in all the PIP, AreaLandmarks and Landmarks features
+# and keep them in hashes based on POLYID
+
+#PIP:
+feat = pip_layer.GetNextFeature()
+polyid_field = feat.GetFieldIndex( 'POLYID' )
+pip_hash={}
+dest_polyid_hash={}
+
+while feat is not None:
+   poly_id = feat.GetField( polyid_field )
+   pip_hash[poly_id] = feat
+   # initially, every polygon is distinct, with no list of polys mapped into it
+   dest_polyid_hash[poly_id]=PolyMap()
+   dest_polyid_hash[poly_id].polyid=poly_id
+   feat = pip_layer.GetNextFeature()   
+
+print 'Processed %d PIP records.' % len(pip_hash)
+
+#AreaLandmarks
+feat = areaLandmarks_layer.GetNextFeature()
+polyid_field = feat.GetFieldIndex( 'POLYID' )
+areaLandmarks_hash={}
+
+while feat is not None:
+   poly_id = feat.GetField( polyid_field )
+   areaLandmarks_hash[poly_id] = feat
+   feat = areaLandmarks_layer.GetNextFeature()   
+print 'Processed %d AreaLandmarks records.' % len(areaLandmarks_hash)
+
+
+# Landmarks is not looked up by polyid, but by LAND, which links it to 
+# Landmarks
+feat = Landmarks_layer.GetNextFeature()
+land_field = feat.GetFieldIndex( 'LAND' )
+Landmarks_hash={}
+
+while feat is not None:
+   land_id = feat.GetField( land_field )
+   Landmarks_hash[land_id] = feat
+   feat = Landmarks_layer.GetNextFeature()   
+print 'Processed %d Landmarks records.' % len(Landmarks_hash)
+
+if dissolve == 1:
+  print 'Scanning PolyChains for polygons to dissolve.'
+  #############################################################################
+  #
+  # Now we sift through all the PolyChainLink records, find the ones that have
+  # distinct left and right polyids, but for which the associated landmark
+  # is identical.  We will dissolve those polygons by mapping their polyids
+  link_layer = ds.GetLayerByName( 'PolyChainLink' )
+
+  feat = link_layer.GetNextFeature()
+  lpoly_field = feat.GetFieldIndex( 'POLYIDL' )
+  rpoly_field = feat.GetFieldIndex( 'POLYIDR' )
+  
+  link_count=0
+  ndissolved=0
+  
+  while feat is not None: 
+      link_count = link_count+1
+  
+      orig_lpoly_id=feat.GetField( lpoly_field )
+      orig_rpoly_id=feat.GetField( rpoly_field )
+      try:
+        lpoly_id = dest_polyid_hash[orig_lpoly_id].polyid
+      except:
+        lpoly_id = 0
+  
+      try:
+        rpoly_id = dest_polyid_hash[orig_rpoly_id].polyid
+      except:
+        rpoly_id= 0
+   
+      #if not already identical (either because already dissolved, or because
+      #internal
+      if lpoly_id != rpoly_id:
+         #find the left and right areaLandmark, if there are any      
+         try:
+           left_areaLandmark=areaLandmarks_hash[lpoly_id]
+           l_landidx=left_areaLandmark.GetFieldIndex('LAND')      
+           l_land=left_areaLandmark.GetField(l_landidx)
+         except:
+           left_areaLandmark=None
+  
+         try:
+           right_areaLandmark=areaLandmarks_hash[rpoly_id]
+           r_landidx=right_areaLandmark.GetFieldIndex('LAND')      
+           r_land=right_areaLandmark.GetField(r_landidx)
+         except:
+           right_areaLandmark=None
+  
+         if left_areaLandmark is not None and right_areaLandmark is not None:
+           if l_land == r_land:
+              ndissolved = ndissolved+1
+              # we have two polys that need to be dissolved
+              # we will always do this by copying the left polygon's
+              # ID into the right base polygon and every polygon that was
+              # mapped to it, then adding the right polygon's
+              # ID and any IDs in its map list to the base polygon on the 
+              # left.  
+              dest_polyid_hash[rpoly_id].polyid=lpoly_id
+              for i in dest_polyid_hash[rpoly_id].mappedlist:
+                 dest_polyid_hash[i].polyid=lpoly_id
+                
+              dest_polyid_hash[lpoly_id].mappedlist.append(rpoly_id)
+              dest_polyid_hash[lpoly_id].mappedlist.extend(dest_polyid_hash[rpoly_id].mappedlist)
+              dest_polyid_hash[rpoly_id].mappedlist=[]
+  
+      feat.Destroy()
+  
+      feat = link_layer.GetNextFeature()
+
+  print 'Scanned %d links for polygon dissolve, dissolved %d boundaries.' % (link_count,ndissolved)
+
+
+
+#############################################################################
+# Read all polygon/chain links and build a hash keyed by POLY_ID listing
+# the chains (by TLID) attached to it. 
+
+link_layer = ds.GetLayerByName( 'PolyChainLink' )
+link_layer.ResetReading()
+
+feat = link_layer.GetNextFeature()
+geom_id_field = feat.GetFieldIndex( 'TLID' )
+tile_ref_field = feat.GetFieldIndex( 'MODULE' )
+lpoly_field = feat.GetFieldIndex( 'POLYIDL' )
+rpoly_field = feat.GetFieldIndex( 'POLYIDR' )
+
+link_count = 0
+
+while feat is not None:
+    module = modules_hash[feat.GetField( tile_ref_field )]
+
+    tlid = feat.GetField( geom_id_field )
+
+    orig_lpoly_id=feat.GetField( lpoly_field )
+    orig_rpoly_id=feat.GetField( rpoly_field )
+    try:
+      lpoly_id = dest_polyid_hash[orig_lpoly_id].polyid
+    except: 
+      lpoly_id = 0
+
+    try:
+      rpoly_id = dest_polyid_hash[orig_rpoly_id].polyid
+    except:
+      rpoly_id = 0
+
+    # sanity checking:
+    if lpoly_id != 0:
+      if lpoly_id != orig_lpoly_id and len(dest_polyid_hash[orig_lpoly_id].mappedlist) != 0:
+         print 'Arrgh --- found a left polygon mapped into another with a non-null list!'
+         sys.exit(1)
+
+    if rpoly_id != 0:
+      if rpoly_id != orig_rpoly_id and len(dest_polyid_hash[orig_rpoly_id].mappedlist) != 0:
+         print 'Arrgh --- found a right polygon mapped into another with a non-null list!'
+         sys.exit(1)
+
+    if lpoly_id != rpoly_id :
+      if lpoly_id != 0:
+        try:
+            module.poly_line_links[lpoly_id].append( tlid )
+        except:
+            module.poly_line_links[lpoly_id] = [ tlid ]
+  
+      if rpoly_id != 0:
+        try:
+            module.poly_line_links[rpoly_id].append( tlid )
+        except:
+            module.poly_line_links[rpoly_id] = [ tlid ]
+  
+      link_count = link_count + 1
+
+    feat.Destroy()
+
+    feat = link_layer.GetNextFeature()
+
+print 'Processed %d links.' % link_count
+
+
+# Boy, what a mess.  But we now have all the data we need in hashes, so we
+# can loop over POLYGON records and extract data as we need it.
+# Do that now:
+#############################################################################
+# Process all polygon features.
+
+feat = poly_layer.GetNextFeature()
+tile_ref_field = feat.GetFieldIndex( 'MODULE' )
+polyid_field = feat.GetFieldIndex( 'POLYID' )
+
+poly_count = 0
+
+while feat is not None:
+    module = modules_hash[feat.GetField( tile_ref_field )]
+    orig_polyid = feat.GetField( polyid_field )
+
+    try:
+      polyid=dest_polyid_hash[orig_polyid].polyid
+    except:
+      polyid=0
+
+    # we must only do those polygons that have not been mapped to others, or
+    # we'll be doing them multiple times
+    if polyid != 0 and polyid == orig_polyid:
+      tlid_list = module.poly_line_links[polyid]
+  
+      link_coll = ogr.Geometry( type = ogr.wkbGeometryCollection )
+      for tlid in tlid_list:
+          geom = module.lines[tlid]
+          link_coll.AddGeometry( geom )
+  
+      try:
+          poly = ogr.BuildPolygonFromEdges( link_coll )
+  
+          #print poly.ExportToWkt()
+          #feat.SetGeometryDirectly( poly )
+  
+          feat2 = ogr.Feature(feature_def=shp_layer.GetLayerDefn())
+  
+          for fld_index in range(len(field_names)):
+             theFieldName = field_names[fld_index]
+             layerName = fields_hash[theFieldName].layerName
+             theFieldIdx = fields_hash[theFieldName].fld_index
+#             print 'fetching field %s from layer %s' % (theFieldName, layerName)
+             # if it's from Polygon just pop it in because we have it now:
+             if layerName == 'Polygon':
+                feat2.SetField( fld_index, feat.GetField(theFieldIdx) )
+             # If it's from PIP, we definitely have one
+             elif layerName == 'PIP':
+                feat2.SetField(fld_index, pip_hash[polyid].GetField(theFieldIdx))
+             # this could be a problem, coz there might not be one
+             elif layerName == 'AreaLandmarks':
+                try:
+                  feat3 = areaLandmarks_hash[polyid]
+#                  print ' found feature with polyid %d in AreaLandmarks' % polyid
+                  feat2.SetField(fld_index, feat3.GetField(theFieldIdx))
+                except:
+                  feat2.UnsetField(fld_index)
+             # this one's mega tricky, coz it depends on there being
+             # an AreaLandmarks first
+             elif layerName == 'Landmarks':
+                try:
+                  feat3 = areaLandmarks_hash[polyid]
+#                  print ' found feature with polyid %d in AreaLandmarks' % polyid
+                  landidx1 = feat3.GetFieldIndex('LAND')
+#                  print '  LAND is field %d in AreaLandmarks' % landidx1
+#                  print '   LAND field in this record is %d.' % feat3.GetField(landidx1)
+                  feat4 = Landmarks_hash[feat3.GetField(landidx1)]
+#                  print ' found feature with LAND %d in Landmarks' % feat3.GetField(landidx1)
+                  feat2.SetField(fld_index, feat4.GetField(theFieldIdx))
+                except:
+                  feat2.UnsetField(fld_index)
+             else:
+                print 'unknown layer %s referenced.' % layerName
+  
+          feat2.SetGeometryDirectly( poly )
+  
+          shp_layer.CreateFeature( feat2 )
+          feat2.Destroy()
+  
+          poly_count = poly_count + 1
+      except:
+          print 'BuildPolygonFromEdges failed.'
+  
+    feat.Destroy()
+
+    feat = poly_layer.GetNextFeature()
+
+print 'Built %d polygons.' % poly_count
+           
+
+#############################################################################
+# Cleanup
+
+shp_ds.Destroy()
+ds.Destroy()
diff --git a/scripts/coord-convert.pl b/scripts/coord-convert.pl
new file mode 100755
index 0000000..b2df097
--- /dev/null
+++ b/scripts/coord-convert.pl
@@ -0,0 +1,280 @@
+#!/usr/bin/perl -w
+
+
+#
+# Written by Paul Lutt, KE7XT.
+# Released to the public domain.
+#
+#
+# $Id: coord-convert.pl,v 1.9 2010/07/03 22:09:48 we7u Exp $
+#
+#
+# Converts between different lat/lon formats.  Will also give UMS
+# position if the lat/lon resides somewhere inside the Seattle area
+# aeronautical map.
+#
+# UMS coordinates have been used in the past by King County, WA SAR.
+# It can be useful for plotting positions on Green Trails maps and
+# perhaps other maps.  The maps must be 15' topo maps and marked in
+# tenths of miles along the edge in order to make use of this
+# coordinate system.
+#
+# Web pages which discuss UMS format:
+#   http://www.impulse.net/~mlynch/land_nav.html
+#   http://www.logicsouth.com/~lcoble/dir9/land_nav.htm
+#   http://www.aasar.org/training/academy/navigation.pdf
+#
+
+
+use lib "${prefix}/lib";
+use Coordinate;         # WE7U's Coordinate.pm module
+
+
+# Create new Coordinate object
+my $position = Coordinate->new();
+
+
+$position->datum("WGS 84");    # Datum
+
+
+print "\n";
+print "Examples:    48.123N     122.123W\n";
+print "             48 07.380N  122 07.380W\n";
+print "             48 07 22.8N 122 07 22.8W\n";
+print "             10U  0565264  5330343\n";
+
+
+while (1) {
+
+    print "\nEnter a Lat/Long value or UTM value:\n";
+
+    # Snag the input
+    $_ = <>;
+
+    print "\n";
+
+    # If the first item has 2 digits and one character and there are
+    # three "words" in the input, we're starting with a UTM value.
+    if (/^\d\d[a-zA-Z]\s+\w+\s+\w+\s*$/) {
+
+        # printf("Found a UTM value\n");
+
+        # We'll convert it to the standard format first and then run
+        # through the rest of the code.
+
+        $zone = $_;
+        $easting = $_;
+        $northing = $_;
+
+        $zone =~ s/^(\d\d[a-zA-Z])\s+\w+\s+\w+\s*$/$1/;
+        $easting =~ s/^\d\d[a-zA-Z]\s+(\w+)\s+\w+\s*$/$1/;
+        $northing =~ s/^\d\d[a-zA-Z]\s+\w+\s+(\w+)\s*$/$1/;
+
+        if ($easting > 999999) {
+            printf("Easting value is too high!\n");
+            next;
+        }
+
+        $position->zone($zone);
+        $position->easting($easting);
+        $position->northing($northing);
+
+        # Convert to lat/lon values
+        $position->utm_to_lat_lon();
+
+        # printf("Calculated Lat, Long position(Lat, Long):  %f   %f\n",
+        #    $position->latitude(),
+        #    $position->longitude() );
+
+        $latitude = $position->latitude();
+        $longitude = $position->longitude();
+
+        $lat_dir = "N";
+        $long_dir = "E";
+ 
+        if ($latitude < 0.0) {
+            $latitude = abs($latitude);
+            $lat_dir = "S"
+        }
+        if ($longitude < 0.0) {
+            $longitude = abs($longitude);
+            $long_dir = "W";
+        }
+
+ 
+        # printf("%f%s %f%s\n", $latitude,$lat_dir,$longitude,$long_dir);
+
+       $_ = sprintf("%f%s %f%s",
+            $latitude,$lat_dir,$longitude,$long_dir);
+
+    }
+
+    # Look for lat/long value in the input
+
+    # Add missing decimal points.
+    s/^(\d+)([NSns])\s+(\d+)([EWew])\s*$/$1.$2 $3.$4/;
+
+    # Check for N/S/E/W characters in the input.  Set the
+    # appropriate flags if found.
+    $lat_dir = "N";
+    $long_dir = "E";
+    if (/S/ || /s/) { $lat_dir  = "S"; }
+    if (/W/ || /w/) { $long_dir = "W"; }
+    # Filter out these characters from the input
+    tr/nsewNSEW//d;
+
+    # Convert to DD MM SS format
+    ($lat_deg, $lat_min, $lat_sec,
+    $long_deg, $long_min, $long_sec) = split(' ');
+
+    # Decimal Degrees?
+    if ($lat_deg =~ /\./) {
+
+        $long_deg = $lat_min;   # Save long_degrees in proper place
+
+        $temp = $lat_deg;
+        $lat_deg = int $temp;
+        $lat_min = int ((abs($temp) * 60.0) % 60);
+
+        # Modulus converts to integers, so we bump up by 10 and then
+        # back down.
+        $lat_sec = (abs($temp) * 36000.0) % 600;
+        $lat_sec = $lat_sec / 10;
+
+        $temp = $long_deg;
+
+        $long_deg = int $temp;
+        $long_min = int ((abs($temp) * 60.0) % 60);
+        $long_sec = (abs($temp) * 36000.0) % 600;
+        $long_sec = $long_sec / 10;
+    }
+    # Decimal Minutes?
+    elsif ($lat_min =~ /\./) {
+
+        $long_min = $long_deg;  # Save long_minutes in proper place
+        $long_deg = $lat_sec;   # Save long_degrees in proper place
+
+        $temp = $lat_min;
+        $lat_min = int abs($temp);
+        $lat_sec = (abs($temp) * 600.0) % 600;
+        $lat_sec = $lat_sec / 10;
+
+        $temp = $long_min;
+        $long_min = int abs($temp);
+        $long_sec = (abs($temp) * 600.0) % 600;
+        $long_sec = $long_sec / 10;
+    }
+    # Decimal Seconds
+    else {  # Already in DD MM SS format, don't convert
+    }
+
+    # Print out the three lat/long formats
+    printf("                Decimal Degrees: %8.5f%s   %8.5f%s\n",
+        $lat_deg + ($lat_min/60.0) + ($lat_sec/3600.0), $lat_dir,
+        $long_deg + ($long_min/60.0) + ($long_sec/3600.0), $long_dir );
+ 
+    printf("        Degrees/Decimal Minutes: %02d %06.3f%s  %02d %06.3f%s\n",
+        $lat_deg, $lat_min + ($lat_sec/60.0), $lat_dir,
+        $long_deg, $long_min + ($long_sec/60.0), $long_dir );
+
+    printf("   Degrees/Minutes/Dec. Seconds: %02d %02d %4.1f%s %02d %02d %4.1f%s\n",
+        $lat_deg, $lat_min, $lat_sec, $lat_dir,
+        $long_deg, $long_min, $long_sec, $long_dir);
+
+    # Fill in the coordinate object with the current lat/lon.
+    # Assuming WGS84 datum
+    if ($lat_dir =~ /S/) {
+        $position->latitude( -( $lat_deg + ($lat_min/60.0) + ($lat_sec/3600.0) ) );
+    }
+    else {
+        $position->latitude( $lat_deg + ($lat_min/60.0) + ($lat_sec/3600.0) );
+    }
+ 
+    if ($long_dir =~ /W/) {
+        $position->longitude( -( $long_deg + ($long_min/60.0) + ($long_sec/3600.0) ) );
+    }
+    else {
+        $position->longitude( $long_deg + ($long_min/60.0) + ($long_sec/3600.0) );
+    }
+
+    #printf("%f %f\n",$position->latitude,$position->longitude);
+
+    $position->lat_lon_to_utm();
+    printf("  Universal Transverse Mercator: %s  %07.0f  %07.0f\n",
+        $position->zone(),
+        $position->easting(),
+        $position->northing() );
+
+    # Check whether the coordinates are within the SEA aeronautical
+    # map area
+    $lat_err = 0;
+    if ($lat_dir =~ /S/ ||
+        $lat_deg < 44 || $lat_deg > 49 ||
+	    ($lat_deg == 44 && ($lat_min < 30 || ($lat_min == 30 && $lat_sec == 0))) ||
+	    ($lat_deg == 49 && ($lat_min > 0 || $lat_sec > 0))) {
+	print " lat. out of range ";
+	$lat_err = 1;
+    }
+
+    $long_err = 0;
+    if ($long_dir =~ /E/ ||
+        $long_deg < 117 || $long_deg > 125 ||
+	    ($long_deg == 117 && ($long_min == 0 && $long_sec == 0)) ||
+	    ($long_deg == 125 && ($long_min > 0 || $long_sec > 0))) {
+	print " long. out of range";
+        $long_err = 1;
+    }
+
+    next if ( $lat_err || $long_err);
+
+
+    # Compute UMS coordinates
+    $y_sec = 3600 * ($lat_deg - 44) + 60 * $lat_min + $lat_sec;
+    $y_sec = 18000 - $y_sec;
+
+    $x_sec = 3600 * ($long_deg - 117) + 60 * $long_min + $long_sec;
+    $x_sec = 28800 - $x_sec;
+
+    $quad = 32 * int($y_sec / 900) + int($x_sec / 900) + 1;
+
+#    print "\tx_sec= $x_sec, y_sec= $y_sec, quad= $quad\n";
+
+    $y_subquad_offset = int($y_sec / 450);
+    $x_subquad_offset = int($x_sec / 450);
+
+    if (&even($x_subquad_offset) && &even($y_subquad_offset)) {
+        print "        UMS (Green Trails Maps): SEA ${quad} A ";
+	printf "%02d", &s2m_x($x_sec - (450 * $x_subquad_offset));
+	printf "%02d\n", &s2m_y($y_sec - (450 * $y_subquad_offset));
+    } elsif (&odd($x_subquad_offset) && &even($y_subquad_offset)) {
+        print "        UMS (Green Trails Maps): SEA ${quad} B ";
+	printf "%02d", &s2m_x(450 * ($x_subquad_offset + 1) - $x_sec);
+	printf "%02d\n", &s2m_y($y_sec - (450 * $y_subquad_offset));
+    } elsif (&even($x_subquad_offset) && &odd($y_subquad_offset)) {
+        print "        UMS (Green Trails Maps): SEA ${quad} C ";
+	printf "%02d", &s2m_x($x_sec - (450 * $x_subquad_offset));
+	printf "%02d\n", &s2m_y(450 * ($y_subquad_offset + 1) - $y_sec);
+    } else {
+        print "        UMS (Green Trails Maps): SEA ${quad} D ";
+	printf "%02d", &s2m_x(450 * ($x_subquad_offset + 1) - $x_sec);
+	printf "%02d\n", &s2m_y(450 * ($y_subquad_offset + 1) - $y_sec);
+    }
+}
+
+sub even {
+    return (($_[0] & 1) == 0);
+}
+
+sub odd {
+    return (($_[0] & 1) == 1);
+}
+
+sub s2m_y {
+    return (int((0.1917966 * $_[0]) + 0.5));
+}
+
+sub s2m_x {
+    return (int((cos(($lat_deg + ($lat_min / 60.0) + ($lat_sec / 3600.0)) / 57.29578) * (0.1917966 * $_[0])) + 0.5));
+}
+
+
diff --git a/scripts/geopdf2gtiff.pl b/scripts/geopdf2gtiff.pl
new file mode 100755
index 0000000..0147342
--- /dev/null
+++ b/scripts/geopdf2gtiff.pl
@@ -0,0 +1,231 @@
+#!/usr/bin/env perl
+
+###############################################################################
+# $Id: geopdf2gtiff.pl,v 1.5 2012/11/01 18:57:19 we7u Exp $
+#
+# Portions Copyright (C) 2004-2012  The Xastir Group
+#
+# Script to convert a GeoPDF file with included neatline into a collar-stripped
+# geotiff in EPSG:4326 projection (WGS84 equidistant cylindrical) in 8-bit
+# color.
+#
+# You must have installed GDAL/OGR, configured to use python in order to use 
+# this script.  This is because the script attempts to run rgb2pct.py, which
+# is only installed if you've built GDAL with python support.
+#
+# This also depends on the -cutline and -crop_to_cutline features of 
+# gdalwarp, which are only present in versions of GDAL after 1.8.1.  
+# 
+# Last Edit:$Date: 2012/11/01 18:57:19 $
+# Revision:$Revision: 1.5 $
+# Last Edited By: $Author: we7u $
+###############################################################################
+
+use Getopt::Long;
+
+my $fudgeNeatline;
+$result=GetOptions("fixneatline|f"=>\$fudgeNeatline);
+
+# Input file is a geopdf:
+if ($#ARGV<0)
+{
+    print STDERR "Usage: $0 <geopdfname>\n";
+    exit 1;
+}
+
+my $inputPDF=$ARGV[0];
+if (! -e $inputPDF)
+{
+    print STDERR "File $inputPDF does not exist.\n";
+    exit 1;
+}
+
+open GDALINFO, "gdalinfo $inputPDF |" or die "can't fork $!";
+my $readingCoordSys=0;
+my $coordSys="";
+my $readingMetadata=0;
+my $neatlinePoly="";
+my $minLat=360,$maxLat=-360,$minLon=360,$maxLon=-360,$templat,$templon;
+
+while (<GDALINFO>)
+{
+  if (/^Driver: (.*)$/)
+  {
+      if ($1 ne "PDF/Geospatial PDF")
+      {
+          print STDERR "This script is intended to run only on GeoPDF input files.\n";
+          exit 1;
+      }
+      next;
+  }
+  if (/^Coordinate System is:/)
+  {
+      $readingCoordSys=1;
+      next;
+  }
+  if ($readingCoordSys == 1)
+  {
+      # This is tricky --- finding the end of the coordinate system
+      # means looking for the first line that starts in column 1 that isn't
+      # the first line of the coordinate system.  All lines of the coordinate
+      # system other than the first start with space.
+      if (/^[^ ]/ && $coordSys ne "")
+      {
+          $readingCoordSys=0;
+          next;
+      }
+      else
+      {
+          chomp($_);
+          $coordSys .= $_;
+          next;
+      }
+  }
+  if (/^Metadata:/)
+  {
+      $readingMetadata=1;
+      next;
+  }
+  if ($readingMetadata==1)
+  {
+      if (/^Corner Coordinates:/)
+      {
+          $readingMetadata=0;
+          next;
+      }
+      if (/^ *NEATLINE=(.*)$/)
+      {
+          $neatlinePoly=$1;
+          next;
+      }
+  }
+  if (/^Band ([0-9]+).*Type=([^,]*)/)
+  {
+      $bandinfo[$#bandinfo+1]=$2;
+      next;
+  }
+  if (/^(Upper|Lower) (Left|Right)/)
+  {
+      s/(Upper|Lower) (Left|Right) *\([^)]*\) *//;
+      /\(([^,]*), *([^\)]*)\)/;
+      $templonstr=$1;
+      $templatstr=$2;
+      $templonstr =~ /([0-9]*)d( *[0-9]*)'( *[0-9.]*)"([EW])/;
+      $deg=$1; $min=$2; $sec=$3; $hem=$4;
+      $templon=$deg+$min/60+$sec/3600;
+      $templon *= -1 if ($hem eq "W");
+      $minLon=$templon if ($templon<$minLon);
+      $maxLon=$templon if ($templon>$maxLon);
+
+      $templatstr =~ /([0-9]*)d( *[0-9]*)'( *[0-9.]*)"([NS])/;
+      $deg=$1; $min=$2; $sec=$3; $hem=$4;
+      $templat=$deg+$min/60+$sec/3600;
+      $templat *= -1 if ($hem eq "S");
+      $minLat=$templat if ($templat<$minLat);
+      $maxLat=$templat if ($templat>$maxLat);
+
+  }
+    
+}
+close GDALINFO;
+
+if (! $fudgeNeatline)
+{
+# Create a CSV for the neatline.  OGR will recognize this geometry
+    open CSVFILE, ">$inputPDF.csv";
+    print CSVFILE "foo,WKT\n";
+    print CSVFILE "bar,\"$neatlinePoly\"\n";
+    close CSVFILE;
+    
+# Unfortunately, there's no easy way to attach a spatial reference system
+# (SRS) to the csv file so that gdalwarp will recognize it.  So make a 
+# virtual layer out of the CSV with the reference system in it.
+    open VRTFILE, ">$inputPDF.vrt";
+    print VRTFILE "<OGRVRTDataSource>\n";
+    print VRTFILE " <OGRVRTLayer name=\"$inputPDF\">\n";
+    print VRTFILE "   <LayerSRS>$coordSys</LayerSRS>\n";
+    print VRTFILE "   <SrcDataSource>$inputPDF.csv</SrcDataSource>\n";
+    print VRTFILE "   <GeometryType>wkbPolygon</GeometryType>\n";
+    print VRTFILE "   <GeometryField>WKT</GeometryField>\n";
+    print VRTFILE " </OGRVRTLayer>\n";
+    print VRTFILE "</OGRVRTDataSource>\n";
+    close VRTFILE;
+}
+else
+{
+    print "User asked us to fudge the neatline, finding nearest 7.5 minute quad boundaries\n";
+
+
+    # Instead of using the neatline specified, round it to nearest 7.5' 
+    # quad boundary
+    $left=(int((abs($minLon)-int(abs($minLon)))/.125+.5)*.125+int(abs($minLon)))*($minLon/abs($minLon));
+    $right=(int((abs($maxLon)-int(abs($maxLon)))/.125+.5)*.125+int(abs($maxLon)))*($maxLon/abs($maxLon));
+    if ($maxLon<0)
+    {
+        $temp=$left;
+        $left=$right;
+        $right=$temp;
+    }
+    $bottom=(int((abs($minLat)-int(abs($minLat)))/.125+.5)*.125+int(abs($minLat)))*($minLat/abs($minLat));
+    $top=(int((abs($maxLat)-int(abs($maxLat)))/.125+.5)*.125+int(abs($maxLat)))*($maxLat/abs($maxLat));
+    if ($maxLat<0)
+    {
+        $temp=$top;
+        $top=$bottom;
+        $bottom=$temp;
+    }
+
+
+    open CSVFILE, ">$inputPDF.csv";
+    print CSVFILE "foo,WKT\n";
+    print CSVFILE "bar,\"POLYGON(($left $top,$right $top, $right $bottom, $left $bottom, $left $top))\"\n";
+    close CSVFILE;
+
+# Unfortunately, there's no easy way to attach a spatial reference system
+# (SRS) to the csv file so that gdalwarp will recognize it.  So make a 
+# virtual layer out of the CSV with the reference system in it.
+    open VRTFILE, ">$inputPDF.vrt";
+    print VRTFILE "<OGRVRTDataSource>\n";
+    print VRTFILE " <OGRVRTLayer name=\"$inputPDF\">\n";
+    print VRTFILE "   <LayerSRS>EPSG:4326</LayerSRS>\n";
+    print VRTFILE "   <SrcDataSource>$inputPDF.csv</SrcDataSource>\n";
+    print VRTFILE "   <GeometryType>wkbPolygon</GeometryType>\n";
+    print VRTFILE "   <GeometryField>WKT</GeometryField>\n";
+    print VRTFILE " </OGRVRTLayer>\n";
+    print VRTFILE "</OGRVRTDataSource>\n";
+    close VRTFILE;
+}
+
+# The VRT virtual source will now appear to gdal warp as a complete 
+# specification of the neatline, with both coordinates *AND* description of
+# the coordinate system.  This will enable gdalwarp to do the clipping of the
+# neatline *AND* conversion to a different coordinate system in the same
+# operation.  Had we not done the vrt, gdalwarp would have assumed the 
+# neatline to be in the coordinates of the DESTINATION raster, not the
+# source raster.
+
+$outputTif=$inputPDF;
+$outputTif =~ s/pdf/tif/i;
+
+# We will warp from whatever the coordinate system is into EPSG:4326, the
+# coordinate system that requires the least work and involves the fewest
+# approximations from Xastir.
+#$theGdalWarp="gdalwarp -cutline $inputPDF.vrt -crop_to_cutline -t_srs EPSG:4326  -co \"COMPRESS=PACKBITS\" $inputPDF $outputTif";
+$theGdalWarp="gdalwarp -cutline $inputPDF.vrt -crop_to_cutline -t_srs EPSG:4326  $inputPDF $outputTif";
+
+system ($theGdalWarp) == 0 or die "System $theGdalWarp failed: $?";
+
+
+if ($#bandinfo>0)
+{
+    print "This is a multi-band raster, dithering...\n";
+    system ("mv $outputTif $$.tif");
+#    $theRGB2PCT="rgb2pct.py $$.tif $$-2.tif";
+    $theRGB2PCT="rgb2pct.py $$.tif $outputTif";
+    system ($theRGB2PCT) == 0 or die "Could not run rgb2pct: $?";
+#    system("gdal_translate -co \"COMPRESS=PACKBITS\" $$-2.tif $outputTif") == 0 or die "Could not gdal_translate: $?";
+    system("rm -f $$.tif $$-2.tif");
+}
+
+# now clean up our mess:
+system ("rm $inputPDF.csv $inputPDF.vrt");
diff --git a/scripts/get-BOMdata b/scripts/get-BOMdata
new file mode 100755
index 0000000..cc4836b
--- /dev/null
+++ b/scripts/get-BOMdata
@@ -0,0 +1,95 @@
+#!/bin/sh
+#
+# $Id: get-BOMdata,v 1.1 2012/03/02 20:26:50 we7u Exp $
+#
+# Script to retrieve BOM data files. 
+#
+# Originally written 2006/03/07 by Steven, WM5Z, and Curt, WE7U.
+# Modified from original get-NWSdata script by Geoff VK2XJG.
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# See README.MAPS for a bit more information on the program.
+#
+#
+# NOTE:  Run this script as root.
+#
+# MAINTAINERS:  Go here to find out what the latest versions are:
+# <ftp://ftp.bom.gov.au/anon/home/adfd/spatial/>
+
+
+FILE1="gfe_public_weather"           # BOM Spatial: Public Warning Zone Boundaries
+FILE2="gfe_metro_areas"              # BOM Spatial: Metropolitan Warning Area Boundaries
+FILE3="gfe_coastal_waters"           # BOM Spatial: Coastal Forecast Marine Zones
+FILE4="gfe_coastal_waters_warnings"  # BOM Spatial: Coastal Warning Zones
+FILE5="gfe_local_effects"            # BOM Spatial: Local Effects Areas
+FILE6="gfe_fire_weather"             # BOM Spatial: Fire Weather Zone Boundaries
+FILE7="LGA08aAust"                   # Local Government Area Boundaries
+
+x=`dirname $0`
+. $x/values
+cd ${prefix}/share/xastir/Counties
+
+
+# Remove any old zip files hanging around in this directory
+#
+rm -f *.zip 2>&1 >/dev/null
+
+
+# Fetch new copies, unzip into place, delete archive.
+#
+#
+DIR=wsom
+for d in $FILE1 $FILE2 $FILE3 $FILE4 $FILE5 $FILE6; do
+if [ -e $d.shp ]
+  then
+    echo "Already have $d shapefile, skipping..."
+  else
+    # Remove possible older copies
+    cut=`echo $d|cut -c1-30 -`
+    rm -f $cut*.shx $cut*.shp $cut*.dbf $cut*.prj $cut*.zip 2>&1 >/dev/null
+    wget ftp://ftp.bom.gov.au/anon/home/adfd/spatial/$d.zip
+    unzip $d.zip
+    rm -f *.zip
+  
+    mv $d*.shx $d.shx 2>&1 >/dev/null
+    mv $d*.shp $d.shp 2>&1 >/dev/null
+    mv $d*.dbf $d.dbf 2>&1 >/dev/null
+    mv $d*.prj $d.prj 2>&1 >/dev/null
+    mv $d*.sbx $d.sbx 2>&1 >/dev/null
+    mv $d*.sbn $d.sbn 2>&1 >/dev/null
+
+fi
+done
+
+DIR=county
+for d in $FILE7; do
+if [ -e $d.shp ]
+  then
+    echo "Already have $d shapefile, skipping..."
+  else
+    # Remove possible older copies
+    cut=`echo $d|cut -c1-2 -`
+    rm -f $cut*.shx $cut*.shp $cut*.dbf $cut*.prj $cut*.zip 2>&1 >/dev/null
+    wget http://wxsvr.aprs.net.au/shapefiles/$d\_shape.zip
+    unzip $d\_shape.zip
+    rm -f *.zip
+fi
+done
+
+
diff --git a/scripts/get-NWSdata b/scripts/get-NWSdata
new file mode 100755
index 0000000..f7652c4
--- /dev/null
+++ b/scripts/get-NWSdata
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# $Id: get-NWSdata,v 1.32 2012/12/03 21:30:39 we7u Exp $
+#
+# Script to retrieve NWS data files. 
+#
+# Originally written 2006/03/07 by Steven, WM5Z, and Curt, WE7U.
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# See README.MAPS for a bit more information on the program.
+#
+#
+# NOTE:  Run this script as root.
+#
+# MAINTAINERS:  Go here to find out what the latest versions are:
+# <http://www.weather.gov/geodata/>
+
+
+# Please only have ONE of each variable listed here!  Note that the "Valid
+# Date" listed on the NWS web pages is the date at which the Shapefile
+# should START to be used.  Don't just blindly put the newest filename
+# here if that start-date hasn't arrived yet!
+#
+FILE1="w_11oc12"  # NWSM Libraries: County Warning Area Boundaries
+FILE2="z_04de12"  # NWSM Libraries: Public Zone Boundaries
+FILE3="mz11oc12"  # NWSM Libraries: Coastal and Offshore Marine Zones
+FILE4="oz28jn12"  # NWSM Libraries: Coastal and Offshore Marine Zones
+FILE5="hz30mr09"  # NWSM Libraries: Coastal and Offshore Marine Zones
+FILE6="fz04de12"  # NWSM Libraries: Fire Weather Zone Boundaries
+FILE7="c_11oc12"  # AWIPS County Libraries (under "States, Provinces & Counties", "U.S. Counties")
+
+
+x=`dirname $0`
+. $x/values
+cd ${prefix}/share/xastir/Counties
+
+
+# Remove any old zip files hanging around in this directory
+#
+rm -f *.zip 2>&1 >/dev/null
+
+
+# Fetch new copies, unzip into place, delete archive.
+#
+#
+DIR=wsom
+for d in $FILE1 $FILE2 $FILE3 $FILE4 $FILE5 $FILE6; do
+if [ -e $d.shp ]
+  then
+    echo "Already have $d shapefile, skipping..."
+  else
+    # Remove possible older copies
+    cut=`echo $d|cut -c1-2 -`
+    rm -f $cut*.shx $cut*.shp $cut*.dbf $cut*.prj $cut*.zip 2>&1 >/dev/null
+    wget http://www.weather.gov/geodata/catalog/$DIR/data/$d.zip
+    unzip $d.zip
+    rm -f *.zip
+fi
+done
+
+DIR=county
+for d in $FILE7; do
+if [ -e $d.shp ]
+  then
+    echo "Already have $d shapefile, skipping..."
+  else
+    # Remove possible older copies
+    cut=`echo $d|cut -c1-2 -`
+    rm -f $cut*.shx $cut*.shp $cut*.dbf $cut*.prj $cut*.zip 2>&1 >/dev/null
+    wget http://www.weather.gov/geodata/catalog/$DIR/data/$d.zip
+    unzip $d.zip
+    rm -f *.zip
+fi
+done
+
diff --git a/scripts/get-fcc-rac.pl b/scripts/get-fcc-rac.pl
new file mode 100755
index 0000000..42fcdbb
--- /dev/null
+++ b/scripts/get-fcc-rac.pl
@@ -0,0 +1,141 @@
+#!/usr/bin/perl -W
+#
+# $Id: get-fcc-rac.pl,v 1.11 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# Updated on 7/5/03 to reflect the new directory structure
+# N0VH
+#
+# Note: Run this script as root in order to write the files into the
+# destination directory listed below, or change directory write access.
+use File::Basename;
+$dirname=dirname($0);
+require ($dirname."/values.pl");
+
+my $XASTIR_BASE="${prefix}/share/xastir";
+
+
+# This script uses temporary storage space in /var/tmp to do its work.
+chdir "/var/tmp";
+
+
+#####################################################################
+# Get the RAC database, process it.
+#   Download size:  ~2MB
+# Final file size: ~13MB
+#####################################################################
+#
+
+$file  = "amateur.zip";
+#$file2 = "amateur.rpt";
+$file2 = "amateur.txt";
+
+
+print STDERR "*********************************\n";
+print STDERR "*** Fetching the RAC database ***\n";
+print STDERR "*********************************\n";
+#`wget -c http://205.236.99.41/%7Eindicatif/download/$file`;
+`wget -c http://apc-cap.ic.gc.ca/datafiles/$file`;
+
+
+if (-e $file && -r $file && -f $file) {
+
+  print STDERR "***********************************\n";
+  print STDERR "*** Installing the RAC database ***\n";
+  print STDERR "***********************************\n";
+  `unzip $file $file2`;
+  `mv $file2 $XASTIR_BASE/fcc/AMACALL.LST`;
+}
+
+# Remove the RAC download files
+unlink $file, $file2;
+
+
+#####################################################################
+# Get the FCC database, process it.
+#   Download size:  ~84MB
+# Final file size: ~101MB
+#####################################################################
+#
+my $file  = "l_amat.zip";
+my $file2 = "EN.dat";
+
+ 
+print STDERR "*********************************\n";
+print STDERR "*** Fetching the FCC database ***\n";
+print STDERR "*********************************\n";
+`wget -c http://wireless.fcc.gov/uls/data/complete/$file`;
+
+if (-e $file && -r $file && -f $file) {
+
+  my $file_out = "$XASTIR_BASE/fcc/$file2";
+
+  # Get rid of characters "^M^M^J" which are sometimes present, sort
+  # the file by callsign & remove old entries for vanity call access.
+  print STDERR "*****************************************************\n";
+  print STDERR "*** Filtering/sorting/installing the FCC database ***\n";
+  print STDERR "*****************************************************\n";
+
+  my %from = ();
+ 
+  open FILE, "unzip -p $file $file2|" or die "Can't open $file2 in $file : $!";
+  open FILE_OUT, '|-', "sort -k 5,5 -t \\| -o $file_out" or die "Can't sort $file_out : $!";
+  while( <FILE> ) {
+    if (/^EN\|(\d+)\|\|\|(\w+)\|.*/) {
+      $x = $1;
+      $z = $2;
+      chop;
+      chop;
+      $y = $_;
+      if (defined $from{$2}) { # check for vanity reassignment
+        if ($from{$z} =~ /^EN\|(\d+)\|\|\|(\w+)\|.*/) {
+          if ($1 < $x) {
+            $replaced++;
+            $from{$2} = $y;
+          }
+        }
+      }
+      else {
+        $from{$2} = $_;
+      }
+    }
+  }
+  close FILE;
+ 
+  for my $callsign ( keys %from ) {
+    $total++;
+    print FILE_OUT "$from{$callsign}\n";
+  }
+  close FILE_OUT;
+
+  print STDERR "Total callsigns:  " . $total . ".\n";
+  print STDERR " Replaced callsigns:  " . $replaced . ".\n";
+}
+
+# Remove the FCC download files
+unlink $file;
+
+
+
+
+print STDERR "*************\n";
+print STDERR "*** Done! ***\n";
+print STDERR "*************\n";
+
+
diff --git a/scripts/get-gnis b/scripts/get-gnis
new file mode 100755
index 0000000..878f04f
--- /dev/null
+++ b/scripts/get-gnis
@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# $Id: get-gnis,v 1.16 2012/11/01 18:57:19 we7u Exp $
+#
+# Script to retrieve GNIS files by state. 
+#
+# Written 20041205 Dan Brown N8YSZ
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# Look at the README for more information on the program.
+#
+
+GNIS_SITE=http://geonames.usgs.gov/docs/stategaz
+SUFFIX=_Features_20090401
+
+x=`dirname $0`
+. $x/values
+
+if [ $# -lt 1 ]
+then
+    printf "%s: error - Need at least one state to download\n" $0
+    printf "Usage: %s ST [ST]... \n" $0
+    exit 1 
+fi
+
+cd /tmp 
+
+while [ $1 ]
+do 
+
+    MYSTATE=`printf ${1} | tr a-z A-Z `
+
+    printf "Retrieving GNIS file for %s\n" ${MYSTATE}
+
+    rm -f ${MYSTATE}${SUFFIX}.zip ${MYSTATE}${SUFFIX}.txt
+    if (wget ${GNIS_SITE}/${MYSTATE}${SUFFIX}.zip)
+    then
+        unzip ${MYSTATE}${SUFFIX}.zip 
+    else 
+        rm -f ${MYSTATE}${SUFFIX}.zip ${MYSTATE}${SUFFIX}.txt
+        wget ${GNIS_SITE}/${MYSTATE}${SUFFIX}.txt
+    fi
+
+    if ( [ -f ${MYSTATE}${SUFFIX}.txt ] )
+    then 
+        printf "File successfully downloaded. Moving to ${prefix}/share/xastir/GNIS\n" 
+        sudo mv ${MYSTATE}${SUFFIX}.txt ${prefix}/share/xastir/GNIS/${MYSTATE}.gnis
+	if [ ${MYSTATE} = "AK" -o ${MYSTATE} = "HI" ]; then
+		sudo recode utf16..utf8 ${prefix}/share/xastir/GNIS/${MYSTATE}.gnis
+	fi
+    else 
+        printf "File for %s not successfully downloaded.\n" ${MYSTATE}
+    fi 
+
+shift
+
+done 
+
+
diff --git a/scripts/get-maptools.sh b/scripts/get-maptools.sh
new file mode 100755
index 0000000..9de4b20
--- /dev/null
+++ b/scripts/get-maptools.sh
@@ -0,0 +1,370 @@
+#!/bin/bash +x
+#
+# $Id: get-maptools.sh,v 1.14 2012/11/01 18:57:19 we7u Exp $
+#
+#
+# Script originally to retrieve and install Shapelib. 
+# Written 20050227 Dan Brown N8YSZ
+# Modified 20060321 to generalize for all maptools - N8YSZ. 
+#
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+#
+
+#
+# Figure out whether we have bsdtar or gnutar on the system.  Either
+# should work.  If not, we'll have to check for "gunzip" and then do
+# "gunzip -c file.tar.gz | tar xf -" instead.
+#
+echo
+echo Checking for necessary utilities...
+if (wget --version 2>&1 | grep "GNU")
+then
+    echo ***Found wget.  Good!
+else
+    echo ***Did not find wget.  Exiting...
+fi
+TAR=gtar
+if ($TAR --version 2>&1 | grep "GNU")
+then
+    echo ***Found GNU tar as \'gtar\'.  Good!
+else
+    echo Did not find gtar, checking for tar...
+    TAR=tar
+    if ($TAR --version 2>&1 | grep "GNU")
+    then
+        echo ***Found GNU tar as \'tar\'.  Good!
+    else
+        echo Did not find GNU tar.  Checking for bsdtar...
+        if ($TAR --version 2>&1 | grep "bsdtar")
+        then
+            echo ***Found bsdtar as \'tar\'.  Good!
+        else
+            echo Did not find bsdtar.  Checking for gunzip...
+            if (gunzip --version 2>&1 | grep "GNU")
+            then
+                echo ***Found gunzip.  Good!
+                echo Checking for tar...
+                if test -e /usr/local/bin/tar -o -e /usr/bin/tar -o -e /bin/tar
+                then
+                    echo ***Found tar.  Good!
+                    TAR=""
+                else
+                    echo ***Did not find tar.  Exiting...
+                    exit
+                fi
+            else
+                echo ***Did not find gunzip.  Exiting...
+                exit
+            fi
+        fi
+    fi
+fi
+#echo $TAR
+
+
+MAPTOOLS=http://dl.maptools.org/dl
+
+# 
+XASDIR=$HOME/src/xastir
+XASTIR_TMP=$XASDIR/tmp
+XASTIR_LIB=$XASDIR/lib
+
+if [ ! -d $XASTIR_TMP ]
+then
+    printf "WARNING: %s Doesn't appear to exist. Creating temporary directory\n" $XASTIR_TMP
+    # Make sure this exists!
+    mkdir -p $XASTIR_TMP
+fi
+
+printf "Checking MACHTYPE found: %s\n" $MACHTYPE
+
+if [ ${MACHTYPE}.z = '.z' ]
+then
+    printf "You really ought to upgrade to a current version of bash \n"
+    printf "Making best guess attempt using uname\n"
+    UNAME=`uname`
+else
+    UNAME=$MACHTYPE
+fi
+
+if [ -e /sbin/ldconfig ]
+then
+    printf "OS is %s. Found ldconfig.\n" $UNAME 	 
+    DO_LDCONFIG='yes'
+else
+    printf "OS is %s. Skipping ldconfig.\n" $UNAME 
+    DO_LDCONFIG='no'
+fi
+
+printf "Checking for sudo\n" 
+
+if  SUDO=`which sudo` 
+then 
+    printf "$SUDO found - validating $SUDO privileges\n" 
+    if $SUDO -v 
+    then
+        printf "Ok, we can continue\n"
+    else
+        printf "ERROR: %s needs $SUDO privileges - aborting \n" $0
+        exit 
+    fi 
+else
+    printf "Sudo not found. Checking for appropriate privs\n" 
+    if [ $DO_LD_CONFIG="yes" -a -f /etc/ld.so.conf ]
+    then
+        if  touch -a /etc/ld.so.conf 
+        then
+            printf "We can modify /etc/ld.so.conf\n"
+        else
+            printf "ERROR: We cannot modify /etc/ld.so.conf - aborting\n"
+            exit 
+	fi 
+    fi
+
+    if touch -a /usr/local/lib 
+    then
+        printf "We can modify /usr/local/lib\n"
+    else
+        printf "ERROR: We cannot modify /usr/local/lib - aborting\n"
+        exit
+    fi 
+fi 
+
+if [ $DO_LDCONFIG = "no" ]
+then
+    printf "OS is %s - Skipping ldconfig \n" $UNAME
+else
+
+    printf "Checking /etc/ld.so.conf configuration\n"
+
+    if [ -d /etc/ld.so.conf.d ]
+    then 
+	LDCONF_FILE=/etc/ld.so.conf.d/xastir.conf 
+    else
+	LDCONF_FILE=/etc/ld.so.conf
+    fi
+
+    if [ ! -f $LDCONF_FILE ]
+    then 
+	sudo touch $LDCONF_FILE
+    fi
+
+    if (! grep /usr/local/lib $LDCONF_FILE 2>&1 > /dev/null) 
+    then
+        printf "Warning: /usr/local/lib not in %s - adding it\n" $LDCONF_FILE
+	if MKTEMP=`which mktemp`
+	then
+	    TMPFILE=`mktemp -t ld.so.conf.XXXXXXXXXX`
+	else
+	    TMPFILE='/tmp/ld.so.conf.XXXXXXXXXX'
+	    $SUDO rm -f $TMPFILE
+	    touch $TMPFILE
+	fi
+	cp $LDCONF_FILE $TMPFILE
+	$SUDO cp $LDCONF_FILE $LDCONF_FILE.orig.$$
+        printf "/usr/local/lib\n" >> $TMPFILE
+        $SUDO cp $TMPFILE $LDCONF_FILE
+
+    fi
+
+    if (! grep /usr/local/lib $LDCONF_FILE 2>&1 > /dev/null) 
+    then
+        printf "ERROR: could not add /usr/local/lib to %s - aborting\n " $LDCONFIG_FILE
+        exit
+    fi
+
+fi
+
+
+# pcre arguably doesn't belong here
+
+ALL="	http://internap.dl.sourceforge.net/sourceforge/pcre/pcre-6.3.tar.gz
+	http://dl.maptools.org/dl/shapelib/shapelib-1.2.10.tar.gz\
+	http://dl.maptools.org/dl/proj/proj-4.4.9.tar.gz\
+	http://dl.maptools.org/dl/geotiff/libgeotiff/libgeotiff-1.2.3.tar.gz\
+	http://dl.maptools.org/dl/gdal/gdal-1.3.2.tar.gz"
+
+#for XA_LIB in shapelib-1.2.10 proj-4.4.9 gdal-1.3.1 libgeotiff-1.2.3
+
+for XA_LIB_URL in $ALL
+do 
+
+
+# Check for a working dir
+
+	if [ ! -d $XASTIR_TMP ]
+	then
+	    printf "ERROR: %s Doesn't appear to exist.\n" $XASTIR_TMP
+	    printf "Please create dir and/or edit script. Exiting\n"
+	    exit 
+	else 
+	    cd $XASTIR_TMP
+	fi
+
+
+# 	PACKAGE_DIR=`echo $XA_LIB | sed -e "s/\-.*//"`
+
+	XA_LIB_FILE=`echo $XA_LIB_URL | sed -e "s/.*\///g"`
+#	XA_LIB_URL=${MAPTOOLS}/${PACKAGE_DIR}/${XA_LIB_FILE}
+	XA_LIB=`echo $XA_LIB_FILE | sed -e "s/.tar.gz//"`
+	printf "Working on: %s\n" $XA_LIB
+	printf "Working in: %s\n" `pwd`
+	
+
+# Cleanup Leftovers 
+
+	if [ -e $XA_LIB_FILE -o -e $XA_LIB ]
+	then
+	
+	    printf "cleaning up old %s - will be saved under dir: %s \n" $XA_LIB old.$$
+	    mkdir old.$$
+	    mv -f ${XA_LIB}* old.$$/
+	fi 
+
+# Get Files from Maptools 
+
+	printf "Retrieving: %s\n" $XA_LIB
+
+	if (wget $XA_LIB_URL)
+	then
+            if test x"$TAR" != x
+            then
+                if ($TAR -xzf $XA_LIB_FILE )
+                then 
+                    printf "%s successfully downloaded.\n" $XA_LIB_FILE
+                else 
+                    printf "ERROR: %s not successfully downloaded - skipping.\n" $XA_LIB_FILE
+                fi 
+            else
+                if (gunzip -c $XA_LIB_FILE | tar xf - )
+                then 
+                    printf "%s successfully downloaded.\n" $XA_LIB_FILE
+                else 
+                    printf "ERROR: %s not successfully downloaded - skipping.\n" $XA_LIB_FILE
+                fi 
+            fi
+	fi 
+
+	printf "Building %s\n\n" $XA_LIB
+	cd $XA_LIB
+	printf "Working in: %s\n" `pwd`
+
+	# Standards and methods and packaging - so many to chose from!
+
+	if ( printf $XA_LIB |grep -i proj) 
+	then
+		cd nad
+		XA_LIB_URL=${MAPTOOLS}/proj/proj-datumgrid-1.3.zip
+		wget $XA_LIB_URL
+		unzip proj-datumgrid-1.3.zip
+		cd $XASTIR_TMP/$XA_LIB 
+	fi
+
+	if [ $XA_LIB = 'shapelib-1.2.10' ] 
+	then
+	# Need a couple fixes for shapelib on Cygwin. 
+
+		if (echo $UNAME |grep -i cygwin ) 2>&1 
+		then
+		    mv Makefile Makefile.dist
+		    sed -e "s/h libshp.so/hlibshp.sl/" -e "s/-lc/-lcygwin/"  < Makefile.dist > Makefile 
+		fi 
+		make 
+		make lib
+#WARNING WARNING WARNING
+# On any system that uses GCC 4.x as its compiler, it is probably necessary
+# to uncomment the stuff between here and the next "else".  If you see
+# an error message of the form
+#  /usr/bin/ld: makegeo: hidden symbol `__stack_chk_fail_local' in /usr/lib/libc_nonshared.a(stack_chk_fail_local.oS) is referenced by DSO
+#  /usr/bin/ld: final link failed: Nonrepresentable section on output
+#  collect2: ld returned 1 exit status
+# when libgeotiff's makefile gets to linking "makegeo", this is your
+# problem.  Uncomment these lines and rerun the script.
+#----uncomment below--------
+#       elif [ $XA_LIB = 'libgeotiff-1.2.3' ]
+#       then
+#          #The libgeotiff tar ball has last modification time of the configure
+#          # script and the configure.in from which it's generated such that
+#          # as soon as we type "make", the Makefile tries to regenerate
+#          # configure and then run it with no arguments, interfering with
+#          # our intentions here.  So we "touch" configure so it's newer
+#          # than configure.in, and make leaves them alone.  The right 
+#          # fix would be to change that makefile, but this is easier
+#          touch configure
+#          # libgeotiff tries to use ld -shared for linking shared library,
+#          # which is wrong on linux with GCC 4.x
+#          ./configure --with-ld-shared="gcc -shared"
+#          make 
+	else
+		./configure
+		make 
+	fi  2>&1 >>${XA_LIB}.build.$$
+
+	printf "\n----------------------------------------------------------------------\n"
+	printf "Attempting install of %s\n" ${XA_LIB}
+
+	if [ ${XA_LIB} = 'shapelib-1.2.10' ] 
+	then
+		$SUDO make lib_install
+	else
+		$SUDO make install
+	fi 2>&1 >> ${XA_LIB}.install.$$
+
+        printf "\n----------------------------------------------------------------------\n"
+	if $!
+	then
+
+	    printf "If you got no errors(*), %s should now be installed!!\n" $XA_LIB
+	    printf "\t(* warnings should be OK)\n"
+
+	else
+
+	    printf "Error: Install of %s appears to have failed \n" $XA_LIB
+	fi 
+
+        printf "If there are errors or warnings, please see: \n"
+        printf "\t%s\n" ${XASTIR_TMP}/${XA_LIB}/README
+        printf "\t%s\n" ${XASTIR_TMP}/${XA_LIB}/${XA_LIB}.build.$$
+        printf "\t%s\n" ${XASTIR_TMP}/${XA_LIB}/${XA_LIB}.install.$$
+        printf "\n----------------------------------------------------------------------\n"
+
+
+
+	if [ $DO_LDCONFIG = "no" ]
+	then
+	    printf "OS is %s - Skipping ldconfig \n" $UNAME
+	else
+	    printf "Running ldconfig\n" 
+	    if ($SUDO ldconfig ) 
+	    then
+	        printf "ldconfig completed successfully\n\n" 
+	    else
+	        printf "ldconfig had errors - you may need to run ldconfig manually.\n" 
+	    fi
+	fi
+
+done     # with getting and building
+
+
+printf "Congratulations, %s is done. \n" $0
+printf "For more information see %s\n" ${XASDIR}/README.MAPS
+
+
diff --git a/scripts/get-pop b/scripts/get-pop
new file mode 100755
index 0000000..e6d31b8
--- /dev/null
+++ b/scripts/get-pop
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# $Id$
+#
+# Script to retrieve GNIS files by state. 
+#
+# Written 20041205 Dan Brown N8YSZ
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+#
+
+#GNIS_SITE=ftp://aprs.tamu.edu/pub/GNIS
+GNIS_SITE=http://www.eng.uah.edu/pub/xastir
+SUFFIX=.gnis
+
+x=`dirname $0`
+. $x/values
+
+if [ $# -lt 1 ]
+then
+    printf "%s: error - Need at least one state to download\n" $0
+    printf "Usage: %s ST [ST]... \n" $0
+    exit 1 
+fi
+
+cd /tmp 
+
+while [ $1 ]
+do 
+
+    MYSTATE=`printf ${1} | tr a-z A-Z `
+
+    printf "Retrieving GNIS file for %s\n" ${MYSTATE}
+
+    rm -f ${MYSTATE}${SUFFIX}.bz2 ${MYSTATE}${SUFFIX}.txt ${MYSTATE}${SUFFIX}.gz
+    if (wget ${GNIS_SITE}/${MYSTATE}${SUFFIX}.bz2)
+    then
+        bunzip2 ${MYSTATE}${SUFFIX}.bz2 
+    elif (wget ${GNIS_SITE}/${MYSTATE}${SUFFIX}.gz)
+    then
+        gunzip ${MYSTATE}${SUFFIX}.gz
+    else 
+        rm -f ${MYSTATE}${SUFFIX}.zip ${MYSTATE}${SUFFIX} ${MYSTATE}${SUFFIX}.gz
+        wget ${GNIS_SITE}/${MYSTATE}${SUFFIX}
+    fi
+
+    if ( [ -f ${MYSTATE}${SUFFIX}.txt ] ) then 
+        printf "File successfully downloaded. Moving to ${prefix}/share/xastir/GNIS\n" 
+        sudo mv ${MYSTATE}${SUFFIX}.txt ${prefix}/share/xastir/GNIS/${MYSTATE}.pop
+	if [ ${MYSTATE} = "AK" -o ${MYSTATE} = "HI" ]; then
+		sudo recode utf16..utf8 ${prefix}/share/xastir/GNIS/${MYSTATE}.pop
+	fi
+    elif ( [ -f ${MYSTATE}${SUFFIX} ] ) then 
+        printf "File successfully downloaded. Moving to ${prefix}/share/xastir/GNIS\n" 
+        sudo mv ${MYSTATE}${SUFFIX} ${prefix}/share/xastir/GNIS/${MYSTATE}.pop
+    else
+        printf "File for %s not successfully downloaded.\n" ${MYSTATE}
+    fi 
+
+shift
+
+done 
+
+
diff --git a/scripts/get_shapelib.sh b/scripts/get_shapelib.sh
new file mode 100644
index 0000000..0c94b24
--- /dev/null
+++ b/scripts/get_shapelib.sh
@@ -0,0 +1,189 @@
+#!/bin/sh +x
+#
+#
+# Script to retrieve and install Shapelib. 
+#
+# Written 20050227 Dan Brown N8YSZ
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+#
+
+SHAPELIB=shapelib-1.2.10
+
+SHAPELIB_FILE=${SHAPELIB}.tar.gz
+
+SHAPELIB_URL=http://dl.maptools.org/dl/shapelib/${SHAPELIB_FILE}
+
+XASDIR=$HOME/src/xastir
+XASTIR_TMP=$XASDIR/tmp
+XASTIR_LIB=$XASDIR/lib
+
+
+UNAME=`uname -o`
+
+if [ $UNAME = 'Cygwin' ]
+then
+    printf "OS is %s. Skipping sudo tests.\n" $UNAME 
+else 
+    printf "Checking for sudo\n" 
+
+    if  SUDO=`which sudo` 
+    then 
+        printf "$SUDO found - validating $SUDO privileges\n" 
+        if $SUDO -v 
+        then
+            printf "Ok, we can continue\n"
+        else
+            printf "ERROR: %s needs $SUDO privileges - aborting \n" $0
+            exit 
+        fi 
+    else
+
+#
+# The following isn't very portable and should be modified. 
+#
+        printf "Sudo not found. Checking for appropriate privs\n" 
+        if touch -a /etc/ld.so.conf 
+        then
+            printf "We can modify /etc/ld.so.conf\n"
+        else
+            printf "ERROR: We cannot modify /etc/ld.so.conf - aborting\n"
+            exit 
+        fi 
+        if touch -a /usr/local/lib 
+        then
+            printf "We can modify /usr/local/lib\n"
+        else
+            printf "ERROR: We cannot modify /usr/local/lib - aborting\n"
+            exit
+        fi 
+    fi 
+fi 
+
+if [ ! -d $XASTIR_TMP ]
+then
+    printf "WARNING: %s Doesn't appear to exist. Creating temporary directory\n" $XASTIR_TMP
+    # Make sure this exists!
+    mkdir -p $XASTIR_TMP
+fi
+cd $XASTIR_TMP
+
+if [ -e $SHAPELIB_FILE -o -e $SHAPELIB ]
+then
+
+    printf "cleaning up old shapelib - will be saved under dir: %s \n" old.$$
+    mkdir old.$$
+    mv -f shapelib* old.$$/
+fi 
+
+printf "Retrieving shapelib\n"
+
+if (wget $SHAPELIB_URL)
+then
+    if (tar -xzf $SHAPELIB_FILE )
+    then 
+        printf "shapelib successfully downloaded.\n" 
+    else 
+        printf "ERROR: %s not successfully downloaded - aborting.\n" $SHAPELIB_FILE
+    fi 
+fi 
+
+printf "Building shapelib\n" 
+cd $SHAPELIB
+
+# Need a couple fixes for shapelib on Cygwin. 
+if [ $UNAME = 'Cygwin' ]
+then
+    mv Makefile Makefile.dist
+    sed -e "s/h libshp.so/hlibshp.sl/" -e "s/-lc/-lcygwin/"  < Makefile.dist > Makefile 
+fi 
+
+make 
+make lib
+
+printf "Attempting install\n"
+printf "\n----------------------------------------------------------------------\n"
+if $SUDO make lib_install
+then
+    printf "\n\n\n----------------------------------------------------------------------\n"
+else
+    printf "\n\n\n----------------------------------------------------------------------\n"
+    printf "Error: Install appears to have failed - aborting \n"
+fi 
+
+
+if [ $UNAME = 'Cygwin' ]
+then
+    printf "OS is %s - Skipping ldconfig " $UNAME
+else
+
+    printf "Checking /etc/ld.so.conf"
+
+    if [ -d /etc/ld.so.conf.d ]
+    then 
+	LDCONF_FILE=/etc/ld.so.conf.d/xastir.conf 
+    else
+	LDCONF_FILE=/etc/ld.so.conf
+    fi
+
+    if [ ! -f $LDCONF_FILE ]
+    then 
+	sudo touch $LDCONF_FILE
+    fi
+
+    if (! grep /usr/local/lib $LDCONF_FILE 2>&1 > /dev/null) 
+    then
+        printf "Warning: /usr/local/lib not in %s - adding it\n" $LDCONF_FILE
+	if MKTEMP=`which mktemp`
+	then
+	    TMPFILE=`mktemp -t ld.so.conf.XXXXXXXXXX`
+	else
+	    TMPFILE='/tmp/ld.so.conf.XXXXXXXXXX'
+	    $SUDO rm -f $TMPFILE
+	    touch $TMPFILE
+	fi
+        cp $LDCONF_FILE $TMPFILE
+        printf "/usr/local/lib\n" >> $TMPFILE
+        $SUDO cp $LDCONF_FILE $LDCONF_FILE.save 
+        $SUDO cp $TMPFILE $LDCONF_FILE
+    fi
+
+    if ( grep /usr/local/lib $LDCONF_FILE ) 
+    then
+        printf "Running ldconfig\n" 
+        if ($SUDO ldconfig ) 
+        then
+            printf "ldconfig completed successfully\n\n" 
+        else
+            printf "ldconfig had errors - you may need to run ldconfig manually.\n" 
+        fi
+    else
+        printf "ERROR: could not add /usr/local/lib to $LDCONF_FILE - aborting\n"
+        exit
+    fi
+fi
+
+printf "Congratulations, %s is done. \n" $0
+printf "If you got no errors, shapelib should now be installed!!\n"
+printf "If there are errors, please see: \n"
+printf "\t%s\n" ${XASTIR_TMP}/${SHAPELIB}/README
+printf "\t%s\n" ${XASDIR}/README.MAPS
+
+
diff --git a/scripts/gpx2shape b/scripts/gpx2shape
new file mode 100755
index 0000000..4a114dd
--- /dev/null
+++ b/scripts/gpx2shape
@@ -0,0 +1,218 @@
+#!/usr/bin/perl
+
+# $Id: gpx2shape,v 1.1 2006/06/01 17:04:25 we7u Exp $ 
+
+#
+# Copyright (C) 2006 James Washer
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+
+
+use strict;
+use XML::Simple;
+use Getopt::Std;
+use Geo::Shapelib qw/:all/;  
+
+my $routenum=1;
+my @vertices;
+my $shp;
+my ($comment,$notes,$elevation)=("no comment", "no note",-9999);
+my %shapetype = ( wpt => 1, rte => 3, trk => 3 );
+
+our ( $opt_v, $opt_t, $opt_w, $opt_r, $opt_d, $opt_s);
+getopts("vtwrds");#v=verbose t=tracks w=waypoints r=routes d=dbfawk s=shapefile_prefix
+
+
+print " args are \"@ARGV\"vals are $opt_t, $opt_w, $opt_r, $opt_d\n" if $opt_v;
+my $f = $ARGV[0];
+$opt_s =$ARGV[0];
+$opt_s =~ s/.gpx$//;
+
+print "shapename is $opt_s\n" if $opt_v;
+
+my $xml = XMLin($f,ForceArray => 1);
+
+process_rte() if $opt_r;
+process_trk()   if $opt_t;
+process_wpt()   if $opt_w;
+
+
+exit;
+sub dumpit{
+	use Data::Dumper;
+	print Dumper($xml);
+	exit;
+}
+
+
+#################################################################
+######################   SHAPEFILE SETUP  #######################
+#################################################################
+sub init_shape{
+	my $type=shift;
+
+
+	$shp = new Geo::Shapelib;
+	$shp->{Name}=${opt_s}."-".$type;
+	$shp->{Shapetype}= $shapetype{$type};
+	
+
+	$shp->{FieldNames} = [ 'Name', 'Comment', 'Notes', 'Elevation' ];
+	$shp->{FieldTypes} = [ 'String:40','String:40','String:100','Integer:8' ];
+
+}
+
+sub save_shape{
+	$shp->save();
+}
+
+sub do_shape{
+	my($type,$name,$comment,$notes,$elevation)=@_;
+
+	push @{$shp->{Shapes}}, { SHPType => $shapetype{$type}, ShapeID => $name, NVertices => scalar @vertices, Vertices => [ @vertices ] }; 
+	push @{$shp->{ShapeRecords}}, [ $name, $comment, $notes, $elevation];
+	
+	print "\t\tdo_shape $name $type ",scalar @vertices,"\n" if $opt_v;
+}
+
+#################################################################
+######################   ROUTE PROCESSING #######################
+#################################################################
+sub process_rte{
+	print "Process Route called\n";
+	unless(exists $xml->{rte}){
+		print "\tNo Routes\n" if $opt_v;
+		return;
+	}
+	my $aref=$xml->{rte};
+	return unless defined $aref;
+	die "Unepected reference $aref\n" unless ref($aref) eq  "ARRAY";
+	
+
+	init_shape('rte');
+	foreach my $rref ( @$aref ){
+		my $name="Route.$routenum++";
+		$name=$rref->{name}->[0] if defined $rref->{name};
+		print "\tProcessing route \"$name\"\n" if $opt_v;
+	
+		@vertices=();
+		do_route($rref->{rtept});
+		do_shape('rte',$name,"","","");
+	}
+	save_shape();
+
+}
+
+sub do_route{
+	my $rtept_ref=shift;
+	die "do_route Unepected reference $rtept_ref\n" unless ref($rtept_ref) eq "ARRAY";
+	foreach my $rtept ( @$rtept_ref ){
+		#print "\t\t$rtept->{lon}  $rtept->{lat}  $rtept->{name}->[0] $rtept->{sym}->[0]\n";
+		my $snell=get_snell($rtept);
+		print_snell($snell) if $opt_v;
+		push @vertices, [ $snell->{lon}, $snell->{lat} ];
+		
+	}
+}
+#################################################################
+######################  TRACK PROCESSING  #######################
+#################################################################
+sub process_trk{
+	print "Process Track called\n";
+	unless(exists $xml->{trk}){
+		print "\tNo Tracks\n" if $opt_v;
+		return;
+	}
+	my $aref=$xml->{trk};
+	
+	my $aref=$xml->{trk};
+	die "Unepected reference $aref\n" unless ref($aref) eq  "ARRAY";
+
+	init_shape('trk');
+	foreach my $tref( @$aref ){
+		print "Track $tref->{name}->[0]\n" if $opt_v;
+		
+		@vertices=();
+    
+
+		foreach my $ele ( @{$tref->{trkseg}->[0]->{trkpt}}){
+			my $snell=get_snell($ele);
+			print_snell($snell) if $opt_v;
+			push @vertices, [ $snell->{lon}, $snell->{lat} ];
+		}
+
+		do_shape('trk',$tref->{name}->[0],"","","");
+
+	}
+	save_shape();
+
+
+}
+
+sub do_trk{
+	my $trk_aref=shift;
+	die "Unepected reference $trk_aref\n" unless ref($trk_aref) eq  "ARRAY";
+}
+#################################################################
+##################### WAYPOINT PROCESSING #######################
+#################################################################
+sub process_wpt{
+	print "Process Waypoint called\n";
+	unless(exists $xml->{wpt}){
+		print "\tNo Waypoints\n" if $opt_v;
+		return;
+	}
+	my $aref=$xml->{wpt};
+	die "Unepected reference $aref\n" unless ref($aref) eq  "ARRAY";
+	init_shape('wpt');
+	foreach my $wref ( @$aref ){
+		my $snell=get_snell($wref);
+		print_snell($snell) if $opt_v;
+		@vertices=[ $snell->{lon}, $snell->{lat} ];
+		do_shape('wpt',$snell->{name},$snell->{cmt},$snell->{ele});
+	}
+	save_shape();
+}
+
+#################################################################
+#################################################################
+#################################################################
+#cute "SNELL" is Symbol Name Elevation Latitude Longitude
+
+sub get_snell { 
+	my $ref=shift;
+	my %val=(lat => "0.0", lon => "0.0", ele => "0.0", name => "NoName", sym => "Waypoint", cmt => "NoComment");
+	$val{lon}=$ref->{lon} if exists $ref->{lon};
+	$val{lat}=$ref->{lat} if exists $ref->{lat};
+	$val{name}=$ref->{name}->[0] if exists $ref->{name} and exists  $ref->{name}->[0];
+	$val{sym}=$ref->{sym}->[0] if exists $ref->{sym};
+	$val{ele}=$ref->{ele}->[0] if exists $ref->{ele};
+	$val{cmt}=$ref->{cmt}->[0] if exists $ref->{cmt};
+	return \%val;
+
+}
+
+
+sub print_snell {
+	my $snell=shift;
+	print "\t\t$snell->{lon} $snell->{lat} $snell->{ele} $snell->{name} $snell->{sym}\n";
+}
+#################################################################
+#################################################################
+#################################################################
+
+
diff --git a/scripts/icontable.pl b/scripts/icontable.pl
new file mode 100755
index 0000000..8370ebd
--- /dev/null
+++ b/scripts/icontable.pl
@@ -0,0 +1,158 @@
+#!/usr/bin/perl
+# $Id: icontable.pl,v 1.5 2009/04/04 18:37:57 gstueve Exp $
+
+# XASTIR icon table overview generator                        20.02.01
+#  Copyright (C) 2001 Rolf Bleher                  http://www.dk7in.de
+
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#  see file COPYING for details
+
+#--------------------------------------------------------------------------
+
+# This script produces an overview graphics with all symbols used by Xastir
+# Output is as a XPM file to STDOUT
+#     typical call:  icontable.pl > symbols.xpm
+
+#--------------------------------------------------------------------------
+use File::Basename;
+$dirname=dirname($0);
+require ($dirname."/values.pl");
+
+# symbols file from XASTIR V2.1, change the path for your environment
+$SYMBFILE = $prefix."/share/xastir/symbols/symbols.dat";
+
+#--------------------------------------------------------------------------
+%sympix = ();
+$lasttable  = $table;
+$lastsymbol = $symbol;
+$tablist = "/\\";
+ at coltab = qw(#FFFF00 #CD6500 #A020F0 #CCCCCC #CD0000 #FF4040 #CD3333 #00008B #00BFFF #006400 #EE0000 #00CD00 #0000CD #FFFFFF #5A5A5A #878787 #454545 #000000 None);
+setuppics();
+#storepics();    # store all icons as separate XPM files
+exit;
+#--------------------------------------------------------------------------
+sub setuppics {
+  my $table  = '';
+  my $symbol = '';
+  my ($i,$j,$c);
+  my $line;
+  my $head;
+  my $str;
+  my $pix;
+  my $pixstr;
+  if (-f $SYMBFILE) {
+    if (open(FH, "<$SYMBFILE")) {
+      my %col = ();
+SYM:  while(<FH>) {
+        last if (/DONE/);
+        if (/TABLE (.)/) {
+          $table = $1;
+          if(length($_)>20) { $descr = 1 }
+          next;
+        }
+        if (/APRS (.)/) {
+          $symbol = $1;
+          next if ($table ne '/' && $table ne '\\');   # ignore other
+          $pixstr = '';
+          for ($i=0;$i<20;$i++) {
+            $line = <FH>;
+            $line =~ s/\n//;
+            $line =~ s/\r//;
+            next SYM if (length($line) != 20);
+            $pixstr .= $line;
+            for ($j=0;$j<20;$j++) {
+              $c = substr($line,$j,1);
+              $col{$c} = $c;
+            }
+          }
+          $sympix{$table.$symbol} = $pixstr;
+        }
+      }
+      $str = "";
+      for ($i=0;$i<20;$i++) {
+        $str .= "....................";
+      }
+      $sympix{"  "} = $str;
+  
+      $head = ''; $j = 0;
+      foreach $c (keys %col) {
+        $head .= colstr($c);
+        $j++;
+      }
+     $head = "/* XPM */{\"337 258 $j 1 \",\n".$head;
+
+#      12 lines with 16 symbols each     x 337  y 
+
+      $pix = "";
+      foreach $table ("/","\\") {
+        for ($i=2;$i<8;$i++) {                  # symbol row
+          $pix .=  "\"".("q" x 337)."\",\n";    # black hor line
+          for ($j=0;$j<20;$j++) {               # scan line
+            $pix .= "\"";                       # start of scan line
+            for ($k=0;$k<16;$k++) {             # symbol column
+              $pix .= "q";                      # vert line
+              $symbol = chr($i*16+$k);
+              $pix .= substr(getpic($table.$symbol),$j*20,20);
+            }
+            $pix .= "q\",\n";                   # vert line
+          }
+        }
+        if ($table eq "\\") {           # {
+          $pix .=  "\"".("q" x 337)."\"};\n";      # black hor line
+        } else {
+          $pix .=  "\"".("q" x 337)."\",\n";       # black hor line
+          for ($i=0;$i<4;$i++) {
+            $pix .=  "\"".("." x 337)."\",\n";     # hor space
+          }
+        }
+      }
+      printf($head.$pix);
+      close(FH);
+    }
+  }
+}
+#--------------------------------------------------------------------------
+sub colstr {                                 # setup string for color
+  my ($c) = @_;
+  if ($c eq '#') {                           # Yellow
+    $cidx = 0;
+  } elsif ($c ge 'a' && $c le 'q') {
+    $cidx = ord($c)-ord('a')+1;
+  } else {
+    $cidx = @coltab-1;                       # Transparent
+  }
+  return("\"$c c $coltab[$cidx]\",\n");
+}
+#--------------------------------------------------------------------------
+sub getpic {
+  my ($id) = @_;
+  $str = $sympix{$id};
+  if (! $str) {
+    $str = $sympix{"  "};      # default
+  }
+  $str;
+}
+#--------------------------------------------------------------------------
+sub storepics {                              # extract all icons to files
+  foreach $cc (keys %sympix) {
+    $fname = sprintf("Aprs%2.2X%2.2X.xpm",ord(substr($cc,0,1)),ord(substr($cc,1,1)));
+    if (open(FH,">$fname")) {
+      printf(FH "%s",getpic($cc));
+      close(FH);
+    }
+  }
+}
+#--------------------------------------------------------------------------
diff --git a/scripts/inf2geo.pl b/scripts/inf2geo.pl
new file mode 100755
index 0000000..a8c1fe7
--- /dev/null
+++ b/scripts/inf2geo.pl
@@ -0,0 +1,249 @@
+#!/usr/bin/perl
+
+# Written by Curt Mills, WE7U
+# Released to the public domain.
+#
+# $Id: inf2geo.pl,v 1.11 2010/07/03 22:09:48 we7u Exp $
+#
+#
+# Invoke this script against one or more info files by typing:
+#
+#       inf2geo.pl filename.inf
+# -or-
+#       inf2geo.pl *.inf
+#
+# To process all .inf files in that directory.
+#
+# Note:  This script requires GraphicsMagick or ImageMagick packages
+# to be installed before it will function properly.  Install one of
+# these via your package manager.
+#
+#
+# What the script does for you:
+# Read in .inf file (from Ui-View)
+# Convert the lat/long coordinates into dd.dddd format
+# Get the image extents via "identify -ping filename" or
+# "gm identify -ping filename".
+# Write out the .geo file
+# Note that this program assumes (and converts to)
+# lower-case for the filename.
+#
+# Note:  It appears that .INF files store the lat/lon
+# in DD.MM.MMMM format.  Converting the script to this
+# format.
+#
+# 2003-08-15 ZL2UMF: add processing multiple files in one go (masks and whot-not)
+#	    so you can convert all your ui-view maps in one step
+
+#use strict; 
+use IO::File;
+
+#go through every filename passed to this script
+
+#printf("ARGV:%d\n",$#ARGV);
+
+if ($#ARGV == -1) {
+    # No filenames on the command line
+    printf("\n\n\nNo filenames specified.  Invoke this script against one\n");
+    printf("or more .inf files by typing:\n\n");
+    printf("        inf2geo.pl filename.inf\n");
+    printf("-or-\n");
+    printf("        inf2geo.pl *.inf\n\n");
+    printf("To process all .inf files in that directory.\n\n");
+    exit;
+}
+else {
+    foreach my $file (@ARGV) {
+        print "*** $file ***\n";
+    
+        #make a geo of this file
+        makeGeo ($file);
+    }
+    
+}
+
+exit; #just in case
+
+sub makeGeo {
+    my $inf_filename = shift;
+    
+    my $filename = $inf_filename;
+    $filename =~ s/\.inf$//i; 
+    
+    my $geo_filename = $filename . ".geo";
+    
+#    $inf = IO::File->new("< $ARGV[0].inf")
+#	or $inf = IO::File->new("< $ARGV[0].INF")
+#	or $inf = IO::File->new("< $ARGV[0].Inf")
+
+    #skip this file if geo already exists
+    return print "$filename.geo already exists, will not overwrite\n"   if( -e "$filename.geo" );
+
+    #read the inf file
+    my $inf = IO::File->new ( "< $inf_filename" )
+	or return print "\nCouldn't open $inf_filename for reading:\n$!\n\n";
+
+    #make the new geo file
+    $geo = IO::File->new("> $geo_filename")
+	or return print "Couldn't open $geo_filename for writing: $!\n";
+
+    $upper_left = $inf->getline();
+    my ($tp0_lon, $tp0_lat) = split(',', $upper_left);
+    chomp($tp0_lat);
+
+    # Reverse them
+    if ( ($tp0_lat =~ /E/) || ($tp0_lat =~ /W/) )  {
+	$temp = $tp0_lat;
+	$tp0_lat = $tp0_lon;
+	$tp0_lon = $temp;
+    }
+
+    $lower_right = $inf->getline();
+    ($tp1_lon, $tp1_lat) = split(',', $lower_right);
+    chomp($tp1_lat);
+
+    # Reverse them
+    if ( ($tp1_lat =~ /E/) || ($tp1_lat =~ /W/) ) {
+	$temp = $tp1_lat;
+	$tp1_lat = $tp1_lon;
+	$tp1_lon = $temp;
+    }
+
+    #do some maths
+    $tp0_lat2 = &convert($tp0_lat) or return;
+    $tp0_lon2 = &convert($tp0_lon) or return;
+    $tp1_lat2 = &convert($tp1_lat) or return;
+    $tp1_lon2 = &convert($tp1_lon) or return;
+
+    my ($final_filename, $string) = &findImageFile($filename) or return;
+
+
+    # The format returned by string changed from this:
+    # test.gif 1148x830+0+0 PseudoClass 256c 48kb GIF 1s
+    # to this:
+    # test.gif GIF 1148x830+0+0 PseudoClass 256c Palette 8-bit 48kb 0.4u 0:01
+    # in later versions of ImageMagick.
+    #
+    # GraphicsMagick returns a string like this:
+    # i4-mo.gif GIF 1020x581+0+0 PseudoClass 256c 8-bit 475.8k 0.050u 0:01
+    #
+
+    chomp($string);
+    $string =~ s/.*\s(\d+x\d+).*/$1/;    # Grab the 1148x830 portion
+
+    #print "String: $string\n";
+
+    $x = $y = $string;
+
+    $x =~ s/(\d+)x\d+/$1/;
+    $y =~ s/\d+x(\d+)/$1/;
+
+    #print "X: $x\nY: $y\n";
+
+    $x1 = $x - 1;    # We start numbering pixels at zero, not 1
+    $y1 = $y - 1;    # We start numbering pixels at zero, not 1
+
+    #print "X: $x\nY: $y\n";
+    #print "X1: $x1\nY1: $y1\n";
+    
+    
+    #write to the geo file
+    printf $geo "FILENAME    $final_filename\n";
+    printf $geo "TIEPOINT    0\t\t0\t$tp0_lon2\t$tp0_lat2\n";
+    printf $geo "TIEPOINT    $x1\t$y1\t$tp1_lon2\t$tp1_lat2\n";
+    printf $geo "IMAGESIZE   $x\t$y\n";
+    printf $geo "#$string\n";
+    printf $geo "#\n# Converted from a .INF file by WE7U's inf2geo.pl script\n#\n";
+
+
+    $inf->close();
+    $geo->close();
+
+}
+
+
+
+
+sub convert
+{
+    #print "$_[0] -> ";
+    ($dd,$mm,$mm2) = split('\.', $_[0]);
+    $mm2 =~ s/(\d+).*/$1/;
+    $mm = $mm . "\." . $mm2;
+    $number = $dd + ($mm / 60.0);
+
+    if ( ($_[0] =~ /S/) || ($_[0] =~ /s/)
+      || ($_[0] =~ /W/) || ($_[0] =~ /w/) )
+    {
+        $number = -$number;
+    }
+
+    # Latitude bound checking
+    if ( ($_[0] =~ /S/) || ($_[0] =~ /s/) || ($_[0] =~ /N/) || ($_[0] =~ /n/) ) {
+        if ($dd > 90) {
+            print "Latitude degrees out-of-bounds: $dd.  Must be <= 90\n";
+	    return;
+        }
+        if ($mm >= 60) {
+            print "Latitude minutes out-of-bounds: $mm.  Must be < 60\n";
+	    return;
+        }
+        if (abs($number) > 90.0) {
+            print "Latitude out-of-bounds: $number.  Must be between -90 and +90\n";
+	    return;
+        }
+    }
+    # Longitude bounds checking
+    else {
+        if ($dd > 180) {
+            print "Longitude degrees out-of-bounds: $dd.  Must be <= 180\n";
+	    return;
+        }
+        if ($mm >= 60) {
+            print "Longitude minutes out-of-bounds: $mm.  Must be < 60\n";
+	    return;
+        }
+        if (abs($number) > 180.0) {
+            print "Longitude out-of-bounds: $number.  Must be between -180 and +180\n";
+	    return;
+        }
+    }
+ 
+    #print "$number\n";
+    #print "Temp = $temp\n";
+    return($number);
+}
+
+
+
+sub findImageFile {
+    $filename = shift;
+    @extensions = ("gif", "bmp", "jpg", "png", "emf");
+    foreach $xtn (@extensions) {
+        $try_filename = "$filename.$xtn";
+#        print "Looking for $try_filename\n";
+
+        # Try GraphicsMagick's 'gm' first
+        $string = `gm identify -ping $try_filename 2>/dev/null`;
+        if ($string eq "") {
+            # Else try ImageMagick's 'identify'
+            $string = `identify -ping $try_filename 2>/dev/null`;
+        }
+        if ($string ne "") {
+            # Found the file and GM or IM
+            $filename = $try_filename;
+            $image_size = $string;
+        }
+    }
+    if ($image_size eq "") {
+        print "Image file not found for $filename, may be be a case problem\n" ;
+        print "or a problem finding GraphicsMagick's 'gm' or ImageMagick's 'identify' program\n";
+        print "Make sure that either GraphicsMagick or ImageMagick is installed.\n";
+        return;
+    }
+    
+    print "Found this image: $image_size\n";
+    return ($filename, $image_size);
+}
+
+
diff --git a/scripts/kiss-off.pl b/scripts/kiss-off.pl
new file mode 100755
index 0000000..c145c21
--- /dev/null
+++ b/scripts/kiss-off.pl
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+# $Id: kiss-off.pl,v 1.3 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2004-2012  Curt Mills, WE7U
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+
+# This script will send the proper characters to STDOUT to command a
+# KISS TNC out of KISS mode.  Redirect it to the port that the TNC
+# is connected to.  Turn off the port in Xastir first.
+
+# It is assumed that the baud rate on the port and the baud rate of
+# the TNC match, if not, this won't work.  If you've just been using
+# the TNC in Xastir, they probably match.
+
+# Use the script like this:
+#
+# ./kiss-off.pl >/dev/ttyS1
+#
+
+
+sleep 1;
+printf("%c%c%c", 192, 255, 192);
+sleep 1;
+
diff --git a/scripts/langElmerFudd.pl b/scripts/langElmerFudd.pl
new file mode 100755
index 0000000..d56c518
--- /dev/null
+++ b/scripts/langElmerFudd.pl
@@ -0,0 +1,94 @@
+#!/usr/bin/perl -W
+
+# $Id: langElmerFudd.pl,v 1.6 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2008-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+
+
+# Run it like this:
+#
+#   cd xastir/config
+#   ../scripts/langElmerFudd.pl -split  <language-English.sys >language-ElmerFudd.sys
+# or
+#   ../scripts/langElmerFudd.pl <some-input-file >some-output-file
+#
+# "-split": Translate 2nd part of line only (Xastir language file).
+# Without it:  Translate entire text.
+
+
+# Regex strings derived from:
+# http://www.faqs.org/docs/diveintopython/dialect_divein.html
+# http://www.siafoo.net/snippet/133
+# http://dougal.gunters.org/blog/2004/08/30/text-filter-suite
+
+
+# Check whether we're translating an Xastir language file or plain
+# text:
+#   "-split" present:  Translate the 2nd piece of each line.
+#   "-split" absent:   Translate the entire text.
+my $a;
+if ($#ARGV < 0) { $a = ""; }
+else            { $a = shift; }
+$do_split = 0;
+if (length($a) > 0 && $a =~ m/-split/) {
+  $do_split = 1;
+}
+
+while ( <> ) {
+
+  # Change the "Id:" RCS tag to show that we translated the file.
+  if (m/^#.*\$Id:/) {
+      print "# language-ElmerFudd.sys, translated from language-English.sys\n";
+      print "# Please do not edit this derived file.\n";
+      next;
+  }
+  # Skip other comment lines
+  if (m/^#/) {
+    next;
+  }
+
+  if ($do_split) {
+    # Split each incoming line by the '|' character
+    @pieces = split /\|/;
+
+    # Translate the second portion of each line only
+    $_ = $pieces[1];
+  }
+
+  s/[rl]/w/g;
+  s/[RL]/W/g;
+  s/([Qq])u/$1w/g;
+  s/th(\b)/f/g;
+  s/TH(\b)/F/g;
+  s/th/d/g;
+  s/Th/D/g;
+  s/([Nn])[.]/$1, uh-hah-hah-hah./g;
+
+  if ($do_split) {
+    # Combine the line again for output to STDOUT
+    $pieces[1] = $_;
+    print join '|', @pieces;
+  }
+  else {
+    print;
+  }
+}
+
+
diff --git a/scripts/langMuppetsChef.pl b/scripts/langMuppetsChef.pl
new file mode 100755
index 0000000..66b51f6
--- /dev/null
+++ b/scripts/langMuppetsChef.pl
@@ -0,0 +1,145 @@
+#!/usr/bin/perl -W
+
+# $Id: langMuppetsChef.pl,v 1.7 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2008-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+
+
+# Run it like this:
+#
+#   cd xastir/config
+#   ../scripts/langMuppetsChef.pl -split <language-English.sys >language-MuppetsChef.sys
+# or
+#   ../scripts/langMuppetsChef.pl <some-input-file >some-output-file
+#
+# "-split": Translate 2nd part of line only (Xastir language file).
+# Without it:  Translate entire text.
+
+
+# Regex strings derived from:
+# http://www.siafoo.net/snippet/133
+# http://www.faqs.org/docs/diveintopython/dialect_divein.html
+# http://dougal.gunters.org/blog/2004/08/30/text-filter-suite
+
+
+# Check whether we're translating an Xastir language file or plain
+# text:
+#   "-split" present:  Translate the 2nd piece of each line.
+#   "-split" absent:   Translate the entire text.
+my $a;
+if ($#ARGV < 0) { $a = ""; }
+else            { $a = shift; }
+$do_split = 0;
+if (length($a) > 0 && $a =~ m/-split/) {
+  $do_split = 1;
+}
+
+while ( <> ) {
+
+  # Change the "Id:" RCS tag to show that we translated the file.
+  if (m/^#.*\$Id:/) {
+    print "# language-MuppetsChef.sys, translated from language-English.sys\n";
+    print "# Please do not edit this derived file.\n";
+    next;
+  }
+  # Skip other comment lines
+  if (m/^#/) {
+    next;
+  }
+
+  if ($do_split) {
+    # Split each incoming line by the '|' character
+    @pieces = split /\|/;
+
+    # Translate the second portion of each line only
+    $_ = $pieces[1];
+  }
+
+  s/An/Un/g;
+  s/an/un/g;
+  s/Au/Oo/g;
+  s/au/oo/g;
+  s/a\b/e/g;
+  s/A\b/E/g;
+  s/en\b/ee/g;
+  s/\bew/oo/g;
+  s/\be\b/e-a/g;
+  s/\be/i/g;
+  s/\bE/I/g;
+  s/\bf/ff/g;
+  s/\bir/ur/g;
+  s/(\w*?)i(\w*?)$/$1ee$2/g;
+  s/\bow/oo/g;
+  s/\bo/oo/g;
+  s/\bO/Oo/g;
+  s/the/zee/g;
+  s/The/Zee/g;
+  s/th\b/t/g;
+  s/\btion/shun/g;
+  s/\bu/oo/g;
+  s/\bU/Oo/g;
+  s/v/f/g;
+  s/V/F/g;
+  s/w/w/g;
+  s/W/W/g;
+  s/([a-z])[.]/$&.  Bork Bork Bork!/g;
+
+  # From the text-filter-suite:
+  s/(\w)ew/$1oo/g;
+  s/(\w)ow/$1oo/g;
+  s/(\W)o/$1oo/g;
+  s/(\W)O/$1Oo/g;
+  s/(\w)u/$1oo/g;
+  s/(\w)U/$1Oo/g;
+  s/a(\w)/e$1/g;
+  s/A(\w)/E$1/g;
+  s/en(\W)/ee$1/g;
+  s/(\w)e(\W)/$1e-a$2/g;
+  s/(\W)e/$1i/g;
+  s/(\W)E/$1I/g;
+  s/(\w)f/$1ff/g;
+  s/(\w)ir/$1ur/g;
+  s/([a-m])i/$1ee/g;
+  s/([A-M])i/$1EE/g;
+  s/(\w)o/$1u/g;
+  s/the/zee/g;
+  s/The/Zee/g;
+  s/th(\W)/t$1/g;
+  s/(\w)tion/$1shun/g;
+  s/v/f/g;
+  s/V/F/g;
+  s/w/v/g;
+  s/W/V/g;
+  s/f{2,}/ff/g;
+  s/o{2,}/oo/g;
+  s/e{2,}/ee/g;
+#  s/([\.!\?])\s*(</[^>]+>)?\s*$/$1 Bork Bork Bork!$2/g;
+
+  if ($do_split) {
+    # Combine the line again for output to STDOUT
+    $pieces[1] = $_;
+    print join '|', @pieces;
+  }
+  else {
+    print;
+  }
+}
+
+
diff --git a/scripts/langOldeEnglish.pl b/scripts/langOldeEnglish.pl
new file mode 100755
index 0000000..2d75b10
--- /dev/null
+++ b/scripts/langOldeEnglish.pl
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -W
+
+# $Id: langOldeEnglish.pl,v 1.6 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2008-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+
+
+# Run it like this:
+#
+#   cd xastir/config
+#   ../scripts/langOldeEnglish.pl -split <language-English.sys >language-OldeEnglish.sys
+# or
+#   ../scripts/langOldeEnglish.pl <some-input-file >some-output-file
+#
+# "-split": Translate 2nd part of line only (Xastir language file).
+# Without it:  Translate entire text.
+
+
+# Regex strings derived from:
+# http://www.faqs.org/docs/diveintopython/dialect_divein.html
+# http://www.siafoo.net/snippet/133
+
+
+# Check whether we're translating an Xastir language file or plain
+# text:
+#   "-split" present:  Translate the 2nd piece of each line.
+#   "-split" absent:   Translate the entire text.
+my $a;
+if ($#ARGV < 0) { $a = ""; }
+else            { $a = shift; }
+$do_split = 0;
+if (length($a) > 0 && $a =~ m/-split/) {
+  $do_split = 1;
+}
+
+while ( <> ) {
+
+  # Change the "Id:" RCS tag to show that we translated the file.
+  if (m/^#.*\$Id:/) {
+    print "# language-OldeEnglish.sys, translated from language-English.sys\n";
+    print "# Please do not edit this derived file.\n";
+    next;
+  }
+  # Skip other comment lines
+  if (m/^#/) {
+    next;
+  }
+
+  if ($do_split) {
+    # Split each incoming line by the '|' character
+    @pieces = split /\|/;
+
+    # Translate the second portion of each line only
+    $_ = $pieces[1];
+  }
+
+  s/i([bcdfghjklmnpqrstvwxyz])e\b/y$1/g;
+  s/i([bcdfghjklmnpqrstvwxyz])e/y$1$1e/g;
+  s/ick\b/yk/g;
+  s/ia([bcdfghjklmnpqrstvwxyz])/e$1e/g;
+  s/e[ea]([bcdfghjklmnpqrstvwxyz])/e$1e/g;
+  s/([bcdfghjklmnpqrstvwxyz])y/$1ee/g;
+  s/([bcdfghjklmnpqrstvwxyz])er/$1re/g;
+  s/([aeiou])re\b/$1r/g;
+  s/ia([bcdfghjklmnpqrstvwxyz])/i$1e/g;
+  s/tion\b/cioun/g;
+  s/ion\b/ioun/g;
+  s/aid/ayde/g;
+  s/ai/ey/g;
+  s/ay\b/y/g;
+  s/ay/ey/g;
+  s/ant/aunt/g;
+  s/ea/ee/g;
+  s/oa/oo/g;
+  s/ue/e/g;
+  s/oe/o/g;
+  s/ou/ow/g;
+  s/ow/ou/g;
+  s/\bhe/hi/g;
+  s/ve\b/veth/g;
+  s/se\b/e/g;
+  s/\'s\b/es/g;
+  s/ic\b/ick/g;
+  s/ics\b/icc/g;
+  s/ical\b/ick/g;
+  s/tle\b/til/g;
+  s/ll\b/l/g;
+  s/ould\b/olde/g;
+  s/own\b/oune/g;
+  s/un\b/onne/g;
+  s/rry\b/rye/g;
+  s/est\b/este/g;
+  s/pt\b/pte/g;
+  s/th\b/the/g;
+  s/ch\b/che/g;
+  s/ss\b/sse/g;
+  s/([wybdp])\b/$1e/g;
+  s/([rnt])\b/$1$1e/g;
+  s/from/fro/g;
+  s/when/whan/g;
+
+  if ($do_split) {
+    # Combine the line again for output to STDOUT
+    $pieces[1] = $_;
+    print join '|', @pieces;
+  }
+  else {
+    print;
+  }
+}
+
+
diff --git a/scripts/langPigLatin.pl b/scripts/langPigLatin.pl
new file mode 100755
index 0000000..82410b6
--- /dev/null
+++ b/scripts/langPigLatin.pl
@@ -0,0 +1,85 @@
+#!/usr/bin/perl -W
+
+# $Id: langPigLatin.pl,v 1.8 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2007-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+
+
+# Run it like this:
+#
+#   cd xastir/config
+#   ../scripts/langPigLatin.pl -split <language-English.sys >language-PigLatin.sys
+# or
+#   ../scripts/langPigLatin.pl <some-input-file >some-output-file
+#
+# "-split": Translate 2nd part of line only (Xastir language file).
+# Without it:  Translate entire text.
+
+
+# Regex strings derived from:
+# http://www.perlmonks.org/?node_id=3586
+
+
+# Check whether we're translating an Xastir language file or plain
+# text:
+#   "-split" present:  Translate the 2nd piece of each line.
+#   "-split" absent:   Translate the entire text.
+my $a;
+if ($#ARGV < 0) { $a = ""; }
+else            { $a = shift; }
+$do_split = 0;
+if (length($a) > 0 && $a =~ m/-split/) {
+  $do_split = 1;
+}
+
+while ( <> ) {
+
+  # Change the "Id:" RCS tag to show that we translated the file.
+  if (m/^#.*\$Id:/) {
+    print "# language-PigLatin.sys, translated from language-English.sys\n";
+    print "# Please do not edit this derived file.\n";
+    next;
+  }
+  # Skip other comment lines
+  if (m/^#/) {
+    next;
+  }
+
+  if ($do_split) {
+    # Split each incoming line by the '|' character
+    @pieces = split /\|/;
+
+    # Translate the second portion of each line only
+    $_ = $pieces[1];
+  }
+
+  s/\b(qu|y(?=[^t])|[^\W\daeiouy]*)([a-z']+)/$2.($1||"w")."ay"/eg;
+
+  if ($do_split) {
+    # Combine the line again for output to STDOUT
+    $pieces[1] = $_;
+    print join '|', @pieces;
+  }
+  else {
+    print;
+  }
+}
+
+
diff --git a/scripts/langPirateEnglish.pl b/scripts/langPirateEnglish.pl
new file mode 100755
index 0000000..8ea2def
--- /dev/null
+++ b/scripts/langPirateEnglish.pl
@@ -0,0 +1,545 @@
+#!/usr/bin/perl -W
+
+# $Id: langPirateEnglish.pl,v 1.11 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2008-2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# Look at the README for more information on the program.
+#
+# Run it like this:
+#
+#   cd xastir/config
+#   ../scripts/langPirateEnglish.pl -split <language-English.sys >language-PirateEnglish.sys
+# or
+#   ../scripts/langPirateEnglish.pl <some-input-file >some-output-file
+#
+# "-split": Translate 2nd part of line only (Xastir language file).
+# Without it:  Translate entire text.
+
+
+# Regex strings derived from:
+# http://userscripts.org/scripts/review/25998
+# http://dougal.gunters.org/blog/2004/08/30/text-filter-suite
+
+
+# Check whether we're translating an Xastir language file or plain
+# text:
+#   "-split" present:  Translate the 2nd piece of each line.
+#   "-split" absent:   Translate the entire text.
+my $a;
+if ($#ARGV < 0) { $a = ""; }
+else            { $a = shift; }
+$do_split = 0;
+if (length($a) > 0 && $a =~ m/-split/) {
+  $do_split = 1;
+}
+
+while ( <> ) {
+
+  # Change the "Id:" RCS tag to show that we translated the file.
+  if (m/^#.*\$Id:/) {
+      print "# language-PirateEnglish.sys, translated from language-English.sys\n";
+      print "# Please do not edit this derived file.\n";
+      next;
+  }
+  # Skip other comment lines
+  if (m/^#/) {
+    next;
+  }
+
+  if ($do_split) {
+    # Split each incoming line by the '|' character
+    @pieces = split /\|/;
+
+    # Translate the second portion of each line only
+    $_ = $pieces[1];
+  }
+
+  # Custom for Xastir:
+  s/\bham\b/matey/g;
+  s/\bhi hi\b/it be a joke, matey/g;
+  s/\bk7gps\b/Th\' Good Cap\'n/g; 
+  s/\bDave Dobbins\b/Th\' Good Cap\'n/g; 
+  s/\bAPRS\'er\b/Fellow Pirate/g;  
+  s/\b[Aa]prs\'er\b/fellow pirate/g; 
+  s/\bHerb Gerhardt\b/scurvy dog/g;
+  s/\bkb7uvc\b/scurvy dog/g;
+  s/\bwa7nwp\b/cabin boy/g;
+  s/\b[Mm]ap(s*)\b/Treasure Map/g;
+  s/\bXastir\b/HMS Xastir/g;
+  s/\bxastir\b/HMS xastir/g;
+  s/\bXASTIR\b/HMS XASTIR/g;
+  s/\bStation/Ship/g;
+  s/\bstation/ship/g;
+  s/\bView/Gander/g;
+  s/\bview/gander/g;
+  s/\bFile/Scroll/g;
+  s/\bfile/scroll/g;
+  #s/\bFile/Parchment/g;
+  #s/\bfile/parchment/g;
+  s/\bMessage/Dispatch/g;
+  s/\bmessage/dispatch/g;
+  s/\bLogging/Scribblin'/g;
+  s/\blogging/scribblin'/g;
+  s/\bLog/Scribble/g;
+  s/\blog/scribble/g;
+  s/\bPrint/Affix to parchment/g;
+  s/\bprint/affix to parchment/g;
+  s/\bCancel/Nay/g;
+  s/\bcancel/nay/g;
+  s/Close/Nay/g;
+  s/close/nay/g;
+  s/\bOK/Aye/g;
+  s/\bOk/Aye/g;
+  s/\bok/aye/g;
+  s/\bQuit/Nay/g;
+  s/\bquit/nay/g;
+  s/\bExit/Run Away!/g;
+  s/\bexit/run away!/g;
+  s/\bSelect/Choose 'yer Weapon!/g;
+  s/\bselect/choose 'yer weapon!/g;
+  s/\bCompressed/Scrawny/g;
+  s/\bcompressed/scrawny/g;
+  s/\bAudio/Racket/g;
+  s/\baudio/racket/g;
+  s/\bFont/Scribble/g;
+  s/\bfont/scribble/g;
+  s/\bSatellite/Heavenly Body/g;
+  s/\bsatellite/heavenly body/g;
+  s/\bSnapshot/Etching/g;
+  s/\bsnapshot/etching/g;
+  #s/\bObject//g;
+  #s/\bobject//g;
+  #s/\bItem//g;
+  #s/\bitem//g;
+  s/\bInterface/Grapple/g;
+  s/\binterface/grapple/g;
+  s/\bConfigure/Provision me' ship/g;
+  s/\bconfigure/provision me' ship/g;
+
+  # From userscripts:
+  s/About/\'bout/g;
+  s/\babout\b/\'bout/g;
+  s/\ba lot\b/mightily/g;
+  s/\bam\b/be/g;
+  s/\bamputee\b/peg leg/g;
+  s/\bafraid\b/lily-livered/g;
+  s/\band\b/an\'/g;
+  s/\baround\b/\'round/g;
+  s/\battack\b/pillage/g;
+  s/\battacked\b/raped and pillaged/g;
+  s/\barrest\b/keelhaul/g;
+  s/\bAIDS\b/scurvy/g;
+  s/\baids\b/scurvy/g;
+  s/\bATTN\b/AVAST/g;
+
+  s/\bbad\b/scurvy/g;
+  s/\bbeer\b/grog/g;
+  s/\bvodka\b/grog/g;
+  s/\bban him\b/make him walk the plank/g;
+  s/\bcar\b/ship/g;
+  s/\bBAN HIM\b/Make him walk the plank!/g;
+  s/\bBan him\b/Make him walk the plank/g;
+
+  s/\bale\b/grog/g;
+  s/\bbetween\b/betwixt/g;
+  s/\bwhiskey\b/grog/g;
+  s/\bbeauty\b/gov\'nor\'s daughter/g;
+  s/\bbefore\b/\'ere/g;
+  s/\bbanned\b/forced t\' walk the plank/g;
+  s/\bbetween\b/\'tween/g;
+  s/\bboy\b/jim lad/g;
+  s/\bboys\b/jim lads/g;
+  s/\bbought\b/pilfered/g;
+  s/\b4chan\b/House o\' Bilge Rats/g;
+
+  s/\bAsia\b/Th\' Mystic East/g;
+  s/\bJapan\b/Th\' Mystic East/g;
+  s/\bChina\b/Th\' Mystic East/g;
+  s/\bKorea\b/Th\' Mystic East/g;
+  s/\basia\b/Th\' Mystic East/g;
+  s/\bjapan\b/Th\' Mystic East/g;
+  s/\bchina\b/Th\' Mystic East/g;
+  s/\bkorea\b/Th\' Mystic East/g;
+  s/\bIndia\b/Hindustan/g;
+  s/\bIsrael\b/Th\' Holy Lands/g;
+  s/\bindia\b/Hindustan/g;
+  s/\bisrael\b/Th\' Holy Lands/g;
+  s/\bIraq\b/Th\' Ottoman Empire/g;
+  s/\bIran\b/Th\' Ottoman Empire/g;
+  s/\bPakistan\b/Th\' Ottoman Empire/g;
+  s/\bAfghanistan\b/Th\' Ottoman Empire/g;
+  s/\biraq\b/Th\' Ottoman Empire/g;
+  s/\biran\b/Th\' Ottoman Empire/g;
+  s/\bpakistan\b/Th\' Ottoman Empire/g;
+  s/\bafghanistan\b/Th\' Ottoman Empire/g;
+  s/\bAfrica\b/Th\' Dark Continent/g;
+  s/\bafrica\b/Th\' Dark Continent/g;
+
+  s/\bcheat\b/hornswaggle/g;
+  s/\bchild\b/wee one/g;
+  s/\bchildren\b/wee ones/g;
+  s/\bcoffee\b/grog/g;
+  s/\bcondemn\b/keelhaul/g;
+
+  s/\bconference\b/parlay/g;
+  s/\bcrazy\b/addled/g;
+  s/\bjapanophile\b/scurvy mutt/g;
+  s/\bweeaboo\b/scurvy mutt/g;
+  s/\boh crap\b/shiver me timbers!/g;
+  s/\bover\b/o\'er/g; 
+  s/\bThe Token Shop\b/Honest Jack\'s Swag Shop/g; 
+  s/\bToken Shop\b/Honest Jack\'s Swag Shop/g; 
+
+  s/\bdamn\b/damn\'ed/g;    
+  s/\bdevil\b/Davy Jones/g;    
+  s/\bdie\b/head to Davy Jones\' Locker/g;  
+  s/\bdead\b/\'n Davy Jones\' Locker/g;
+  s/\bdoesn\'t\b/don\'t/g;
+  s/\bdollars\b/pieces o\' eight/g;
+  s/\beveryone\b/all hands/g;
+  s/\beyewear\b/eye patch/g;
+  s/\bglasses\b/eye patches/g;
+  s/\bfight\b/duel/g;
+  s/\bgreatly\b/mightily/g;
+  s/\bgold\b/dubloons/g;
+  s/\bha\b/har har/g;
+  s/\bhaha\b/har har/g;
+  s/\bbase\b/port/g;
+  s/\bfort\b/port/g;
+  s/\bhah\b/har har/g;
+  s/\bheh\b/har har/g;
+  s/\bHa\b/Har har/g;
+  s/\bflag\b/Jolly Roger/g;
+  s/\bhouse\b/shanty/g;
+  s/\bidiot\b/bilge rat/g;
+
+  s/\bhit\b/flog/g;
+  s/\btorrents\b/Blackbeard\'s treasure /g;
+  s/\btorrent\b/Blackbeard\'s treasure/g;
+
+  s/\bn00b\b/landlubber/g; 
+  s/\bnoob\b/landlubber/g; 
+  s/\btroll\b/blowhard/g;
+  s/\bdrive\b/sail/g;
+  s/\bcoins\b/pieces o\' eight/g;
+  s/\bcorrect\b/right an\' true/g;
+
+  s/\bfly\b/sail/g;
+  s/\bfool\b/squiffy/g;
+  s/\bfoolish\b/addled/g;
+  s/\bfor\b/fer/g;
+  s/\bFor\b/Fer/g;
+  s/\bfriend\b/matey/g;
+  s/\bfriends\b/hearties/g;
+  s/\bgirl\b/lass/g;
+  s/\bex-girlfriend\b/festerin\' harlot/g;
+  s/\bex girlfriend\b/festerin\' harlot/g;
+  s/\bgood\b/worthy/g;
+  s/\byou\'re\b/yer/g;  
+  s/\byour\b/yer/g; 
+
+  s/\bhello\b/ahoy/g;
+  s/\bHello\b/Ahoy/g;
+  s/\bhey\b/avast!/g;
+  s/\bHey\b/Avast/g;
+  s/\bhey\b/avast!/g;
+  s/\bhi\b/ahoy/g; 
+  s/\bHi\b/Ahoy/g; 
+  s/\bHiya\b/Ahoy/g;   
+  s/\bhiya\b/ahoy/g;   
+  s/\bmoney\b/booty/g; 
+  s/\bguy\b/feller/g;  
+  s/\bfellow\b/feller/g;
+  s/\bidiot\b/scalawag/g;
+  s/ing\b/in\'/g;
+  s/\bin\b/\'n/g;
+  s/\bis\b/be/g;
+  s/\bit\'s\b/\'tis/g;
+  s/\bit is\b/\'tis/g;
+  s/\bkid\b/wee one/g;
+  s/\bkids\b/wee ones/g;
+  s/\bkill\b/keelhaul/g;
+
+  s/\bis not\b/be not/g;
+  s/\baren\'t\b/be not/g;
+  s/\bare\b/be/g;
+  s/\bam\b/be/g;
+  s/\bAre\b/Be/g;
+  s/\blol\b/yo ho ho!/g;
+  s/\blolol\b/Me sides be splittin\'!/g;
+  s/\bodd\b/addled/g;
+  s/\bof\b/o\'/g;
+  s/\bohmigod\b/begad!/g;
+  s/\bomigod\b/begad!/g;
+  s/\bomg\b/begad!/g;
+  s/\bOMG\b/BEGAD!/g;
+  s/\bo rly\b/be that right, sailor?/g;
+  s/\borly\b/be that right, sailor?/g;
+  s/\bya rly\b/Sailor, \'tis true/g;
+  s/\byarly\b/Sailor, \'tis true/g;
+  s/\bwhoamg\b/shiver me timbers!/g;
+
+  s/\bmoney\b/booty/g;
+  s/\bmy\b/me/g;
+  s/\bprosecute\b/keelhaul/g;
+  s/\bpants\b/britches/g;
+  s/\bHello\b/Ahoy!/g; 
+  s/\bquick\b/smart/g;
+  s/\bquickly\b/smartly/g;
+  s/\bthe rules\b/the Pirate\'s Code/g;
+  s/\bnice\b/fine/g;
+  s/\bthe Internet\b/The Seven Seas/g;
+  s/\bThe Internet\b/The Seven Seas/g;
+  s/\binternet\b/Seven Seas/g;
+  s/\bInternet\b/Seven Seas/g;
+
+  s/\bsilly\b/addled/g;
+  s/\bsword\b/cutlass/g;
+  s/\bshe\b/the lass/g;
+  s/\bshut up\b/pipe down/g;
+  #s/\bspeech/parlance/g;
+  #s/\bSpeech/Parlance/g;
+  s/\bspeech/parley/g;
+  s/\bSpeech/Parley/g;
+  s/\bsteal\b/commandeer/g;
+  s/\bdownload\b/plunder/g;
+  s/\bDownload\b/Plunder/g;
+
+  s/\bsexy\b/saucy/g;
+  s/\btelescope\b/spyglass/g;
+  s/\bterrorist\b/scourge o\' the seven seas/g;
+  s/\bterrorists\b/scalawags/g;
+  s/tion\b/tin\'/g;
+  s/\bthere\b/thar/g;
+  s/tions\b/tin\'s/g;
+  s/\bto\b/t\'/g;
+  s/\btomorrow\b/the morrow/g;
+  s/\btruck\b/vessel/g;
+    
+  s/\bwasn\'t\b/weren\'t/g;
+  s/\bwant to\b/wish t\'/g;
+  s/\bwanna\b/wish t\'/g;
+  s/\bYep\b/Aye/g; 
+  s/\byep\b/aye/g; 
+  s/\bwoman\b/buxom beauty/g;
+  s/\bwomen\b/wenches/g;
+  s/\bwin\b/triumph/g;
+  s/\bwins\b/triumphs/g;
+  s/\bwork\b/deck swabbing/g;
+  s/\bwine\b/grog/g;
+  s/\byes\b/aye/g;
+  s/\bYes\b/Aye/g;
+  s/\bno\b/nay/g;
+  s/\bNo\b/Nay/g;
+  s/\bnah\b/nay/g;
+  s/\bNah\b/Nay/g;
+  s/\bYeah\b/Aye/g;
+  s/\byeah\b/Aye/g;
+
+  s/\byou\b/ye/g;
+  s/\byour\b/yer/g;
+  s/\bwtf\b/what devilry!/g;
+  s/\bWTF\b/Begad, what devilry be is?!/g;
+  s/\bFacebook\b/PirateBook/g;
+  s/\bThis message was deleted at the request of the original poster\b/This here message be taken back by a yellow-bellied pirate/g;
+  s/\bThis message has been deleted by a moderator\b/This poor soul had a run-in with the authorities/g;
+  s/\bGood Tokens\b/Pieces o\' Eight/g;
+  s/\bBad Tokens\b/Black Marks/g;
+  s/\byou\'re\b/yer/g;
+  s/\bYou\'re\b/Yer/g;
+  s/\bwins\b/triumphs/g;   
+
+  s/\bHome\b/Haven/g;
+  s/\bAdd a link\b/Add plunder/g;
+  s/\bRandom link\b/Who needs maps?/g;
+  s/\bTop rated links\b/Quality grog/g;
+  s/\bLinks o\' the week\b/Modern fashions/g;
+  s/\bWiki\b/Wikis/g;
+  s/\bAll links\b/All th\' plunder/g;
+  s/\bFavorites\b/Treasures/g;
+  s/\bSearch\b/Scour/g;
+  s/\bStats\b/Specs/g;
+  s/\bBoards\b/Th\' Tavern/g;
+  s/\bUser List\b/Roster/g;
+  s/\bLogout\b/Retreat/g;
+  s/\bHelp\b/Aid/g;
+  s/\bBoard List\b/Port/g;
+  s/\bCreate New Topic\b/Parley/g;
+  s/\bPost New Message\b/Parley/g;
+  s/\bNext Page\b/Next Map/g;
+  s/\bTagged\b/X\'d/g;
+  s/\bTag\b/X/g;
+
+  # From text-filter-suite/
+  s/\bmy\b/me/g;
+  s/\bboss\b/admiral/g;
+  s/\bmanager\b/admiral/g;
+  s/\b[Cc]aptain\b/Cap\'n/g;
+  s/\bmyself\b/meself/g;
+  s/\byour\b/yer/g;
+  s/\byou\b/ye/g;
+  s/\bfriend\b/matey/g;
+  s/\bfriends\b/maties/g;
+  s/\bco[-]?worker\b/shipmate/g;
+  s/\bco[-]?workers\b/shipmates/g;
+  s/\bpeople\b/scallywags/g;
+  s/\bearlier\b/afore/g;
+  s/\bold\b/auld/g;
+  s/\bthe\b/th\'/g;
+  s/\bof\b/o'/g;
+  s/\bdon\'t\b/dern\'t/g;
+  s/\bdo not\b/dern\'t/g;
+  s/\bnever\b/ne\'er/g;
+  s/\bever\b/e\'er/g;
+  s/\bover\b/o\'er/g;
+  s/\bYes\b/Aye/g;
+  s/\bNo\b/Nay/g;
+  s/\bYeah\b/Aye/g;
+  s/\byeah\b/aye/g;
+  s/\bdon\'t know\b/dinna/g;
+  s/\bdidn\'t know\b/did nay know/g;
+  s/\bhadn\'t\b/ha\'nae/g;
+  s/\bdidn\'t\b/di\'nae/g;
+  s/\bwasn\'t\b/weren\'t/g;
+  s/\bhaven\'t\b/ha\'nae/g;
+  s/\bfor\b/fer/g;
+  s/\bbetween\b/betwixt/g;
+  s/\baround\b/aroun\'/g;
+  s/\bto\b/t\'/g;
+  s/\bit\'s\b/\'tis/g;
+  s/\bwoman\b/wench/g;
+  s/\bwomen\b/wenches/g;
+  s/\blady\b/wench/g;
+  s/\bwife\b/lady/g;
+  s/\bgirl\b/lass/g;
+  s/\bgirls\b/lassies/g;
+  s/\bguy\b/lubber/g;
+  s/\bman\b/lubber/g;
+  s/\bfellow\b/lubber/g;
+  s/\bdude\b/lubber/g;
+  s/\bboy\b/lad/g;
+  s/\bboys\b/laddies/g;
+  s/\bchildren\b/little sandcrabs/g;
+  s/\bkids\b/minnows/g;
+  s/\bhim\b/that scurvey dog/g;
+  s/\bher\b/that comely wench/g;
+  s/\bhim\.\b/that drunken sailor/g;
+  s/\bHe\b/The ornery cuss/g;
+  s/\bShe\b/The winsome lass/g;
+  s/\bhe\'s\b/he be/g;
+  s/\bshe\'s\b/she be/g;
+  s/\bwas\b/were bein\'/g;
+  s/\bHey\b/Avast/g;
+  s/\bher\.\b/that lovely lass/g;
+  s/\bfood\b/chow/g;
+  s/\bmoney\b/dubloons/g;
+  s/\bdollars\b/pieces of eight/g;
+  s/\bcents\b/shillings/g;
+  s/\broad\b/sea/g;
+  s/\broads\b/seas/g;
+  s/\bstreet\b/river/g;
+  s/\bstreets\b/rivers/g;
+  s/\bhighway\b/ocean/g;
+  s/\bhighways\b/oceans/g;
+  s/\binterstate\b/high sea/g;
+  s/\bprobably\b/likely/g;
+  s/\bidea\b/notion/g;
+  s/\bcar\b/boat/g;
+  s/\bcars\b/boats/g;
+  s/\btruck\b/schooner/g;
+  s/\btrucks\b/schooners/g;
+  s/\bSUV\b/ship/g;
+  s/\bairplane\b/flying machine/g;
+  s/\bjet\b/flying machine/g;
+  s/\bmachine\b/contraption/g;
+  s/\bdriving\b/sailing/g;
+  s/\bunderstand\b/reckon/g;
+  s/\bdrive\b/sail/g;
+  s/\bdied\b/snuffed it/g;
+  s/ing\b/in\'/g;
+  s/ings\b/in\'s/g;
+
+  # These next two do cool random substitutions
+  #s/(\.\s)/e/avast("$0",3)/g;
+  #s/([!\?]\s)/e/avast("$0",2)/g; # Greater chance after exclamation
+
+
+# Add an opening phrase to each line randomly (see below)?
+
+
+  if ($do_split) {
+    # Combine the line again for output to STDOUT
+    $pieces[1] = $_;
+    print join '|', @pieces;
+  }
+  else {
+    print;
+  }
+}
+
+
+# Randomize use of this array, both in order and in frequency of
+# use.  Not currently used at all.
+#my @shouts = (
+#  ", avast$stub",
+#  "$stub Ahoy!",
+#  ", and a bottle of rum!",
+#  ", by Blackbeard's sword$stub",
+#  ", by Davy Jones' locker$stub",
+#  "$stub Walk the plank!",
+#  "$stub Aarrr!",
+#  "$stub Yaaarrrrr!",
+#  ", pass the grog!",
+#  ", and dinna spare the whip!",
+#  ", with a chest full of booty$stub",
+#  ", and a bucket o' chum$stub",
+#  ", we'll keel-haul ye!",
+#  "$stub Shiver me timbers!",
+#  "$stub And hoist the mainsail!",
+#  "$stub And swab the deck!",
+#  ", ye scurvey dog$stub",
+#  "$stub Fire the cannons!",
+#  ", to be sure$stub",
+#  ", I'll warrant ye$stub",
+#  ", on a dead man's chest!",
+#  "$stub Load the cannons!",
+#  "$stub Prepare to be boarded!",
+#  ", I'll warrant ye$stub",
+#  "$stub Ye'll be sleepin' with the fishes!",
+#  "$stub The sharks will eat well tonight!",
+#  "$stub Oho!",
+#  "$stub Fetch me spyglass!",
+# );
+
+
+# Randomize use of this array both in order and frequency of use.
+# Not currently used at all.
+my @openings = (
+  'Avast! ',
+  'Yarrr! ',
+  'Blimey! ',
+  'Ahoy! ',
+  'Harrr! ',
+  'Aye aye! ',
+  'Shiver me timbers! ',
+  'Arrrr! '
+);
+
+
diff --git a/scripts/mapblast2geo.pl b/scripts/mapblast2geo.pl
new file mode 100755
index 0000000..01440b0
--- /dev/null
+++ b/scripts/mapblast2geo.pl
@@ -0,0 +1,200 @@
+#!/usr/bin/perl
+# $Id: mapblast2geo.pl,v 1.3 2002/03/05 21:28:23 we7u Exp $
+
+# XASTIR .geo file generator for mapblast pixel maps    16.10.2001
+#  Copyright (C) 2001 Rolf Bleher              http://www.dk7in.de
+
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#  see file COPYING for details
+
+#--------------------------------------------------------------------------
+
+use POSIX;                      # provides acos() function
+                                            
+# some default values:
+$width  = 1280;                 # seems to be the maximum supported by mapblast
+$height = 1024;                 # seems to be the maximum supported by mapblast
+$pfx    = "../../pixelmaps/";   # prefix for path
+$pfx    = "";
+
+# undefined values:
+$scale  =    0;
+$lat    = 9999;
+$lon    = 9999;
+$help   =    0;
+
+#--------------------------------------------------------------------------
+
+while (@ARGV) {
+    $arg = shift @ARGV;
+    if ($arg =~ /^\-N(\d{1,2}(\.\d+)?)$/)  { $lat   =  $1 }
+    if ($arg =~ /^\-S(\d{1,2}(\.\d+)?)$/)  { $lat   = -$1 }
+    if ($arg =~ /^\-E(\d{1,3}(\.\d+)?)$/)  { $lon   =  $1 }
+    if ($arg =~ /^\-W(\d{1,3}(\.\d+)?)$/)  { $lon   = -$1 }
+    if ($arg =~ /^\-w(\d+)$/)              { $width =  $1 }
+    if ($arg =~ /^\-h(\d+)$/)              { $height=  $1 }
+    if ($arg =~ /^\-s(\d+)$/)              { $scale =  $1 }
+    if ($arg =~ /^\-s(\d+)k$/)             { $scale =  $1 * 1000 }
+    if ($arg =~ /^\-s(\d+)M$/)             { $scale =  $1 * 1000000 }
+    if ($arg =~ /^\-p(.+)$/)               { $pfx   =  $1 }
+    if ($arg eq '-?')                      { $help  =  1 }
+    if ($arg eq '-h')                      { $help  =  1 }
+    if ($arg eq '--help')                  { $help  =  1 }
+}
+
+if (!$help && $arg && $arg !~ /^\-/) {
+    $file = $arg;                       # last arg is file name
+} else {
+    print("ERROR: Map file name is missing\n");
+    $help = 1;
+}
+
+if (!$help) {
+    if ($lat == 9999) {         # we don't yet have a latitude
+        if ($file =~ /N(\d{1,2}(\.\d+)?)/)  { $lat =  $1 }
+        if ($file =~ /S(\d{1,2}(\.\d+)?)/)  { $lat = -$1 }
+    }
+    if ($lon == 9999) {         # we don't yet have a longitude
+        if ($file =~ /E(\d{1,3}(\.\d+)?)/)  { $lon =  $1 }
+        if ($file =~ /W(\d{1,3}(\.\d+)?)/)  { $lon = -$1 }
+    }
+    if ($scale == 0) {          # we don't yet have a map scale
+        if ($file =~ /\-(\d+)/)  { $scale =  $1 }
+        if ($file =~ /\-(\d+)k/) { $scale =  $1 * 1000 }
+        if ($file =~ /\-(\d+)M/) { $scale =  $1 * 1000000 }
+    }
+    if ($lat == 9999) {         # we need a latitude
+        print("ERROR: Latitude is missing\n");
+        $help = 1;
+    }
+    if ($lon == 9999) {         # we need a longitude
+        print("ERROR: Longitude is missing\n");
+        $help = 1;
+    }
+    if ($scale == 0) {          # we need a map scale
+        print("ERROR: Map scale is missing\n");
+        $help = 1;
+    }
+}
+    
+if ($help) {
+    usage();
+    exit 0;
+}
+
+if ($pfx && $pfx !~ /\/$/) { $pfx .= "/" }      # add trailing '/' if missing
+
+#--------------------------------------------------------------------------
+
+if ($scale >= 1000000) {
+    printf("ERROR: Maps with scaling of 1M and above are not yet supported!\n");
+    printf("       They use a different projection...\n");
+    exit 1;
+}
+
+if (abs($lat) > 89) {
+    printf("ERROR: Map center too near to the poles!\n");
+    exit 1;
+}
+
+# This scaling factor is just a wild guess!
+# But I need one, and this one is nice AND works quite well... ;-)
+$scale_y = 100.0 * pi();                # pixel/degree at 1M map scale
+
+$scale_x = $scale_y * calcScale($lat);  # adjust horizontal scale for latitude
+
+$scale_y *= (1000000 / $scale);         # adjust for current map scale
+$scale_x *= (1000000 / $scale);
+
+#--------------------------------------------------------------------------
+
+# DK7IN: I'm not sure, if this formula is exact for what Xastir
+#        is decoding, but in my region it works quite well
+#        I need to do some further investigation for the best accuracy
+$latmin = $lat - ($height / 2.0 - 2.5) / $scale_y;
+$latmax = $lat + ($height / 2.0 - 0.5) / $scale_y;
+$lonmin = $lon - ($width  / 2.0 - 0.5) / $scale_x;
+$lonmax = $lon + ($width  / 2.0 - 2.5) / $scale_x;
+
+printf("FileName %s%s\n",$pfx,$file);
+printf("\n");
+printf("ImageSize  %4d %4d\n",$width,$height);
+printf("TiePoint   %4d %4d  %10.6f %11.6f\n",0,0,$lonmin,$latmax);
+printf("TiePoint   %4d %4d  %10.6f %11.6f\n",$width-1,$height-1,$lonmax,$latmin);
+printf("Datum      WGS84\n");
+printf("Projection LatLon\n");
+printf("\n");
+printf("# map from mapblast center %10.6f %11.6f, scale %d\n",$lat,$lon,$scale);
+printf("# created with mapblast2geo.pl (DK7IN)\n");
+
+exit 0;
+
+#--------------------------------------------------------------------------
+
+sub usage {
+    my $name = $0;
+    if ($name =~ /^.*\/(.+)$/) { $name = $1 }
+    print("\n");
+    print("$name (c) 2001 Rolf Bleher <Rolf\@dk7in.de>\n");
+    print("create Xastir .geo files for mapblast pixel maps\n");
+    print("usage: $name [options] mapfile\n");
+    print("       -N52.5 -S10    define latitude\n");
+    print("       -E13.3 -W0.5   define longitude\n");
+    print("       -h1024         define map height in pixels (default 1024)\n");
+    print("       -w1280         define map width in pixels  (default 1280)\n");
+    print("       -s50000        define map scale, 50k or 1M is ok\n");
+    print("       -p../pixmaps   define prefix for path\n");
+    print("       -h -? --help   print this help file\n");
+    print("    it tries to extract center Lat/Lon and map scale\n");
+    print("    from the filename like N52.5E13.3-50k.xpm\n");
+    print("\n");
+}
+
+#--------------------------------------------------------------------------
+
+sub pi {
+    return(3.14159265358979323846);
+}
+
+#--------------------------------------------------------------------------
+
+sub deg2rad {
+    my ($deg) = @_;
+    return($deg * pi()/180.0);
+}
+
+#--------------------------------------------------------------------------
+
+# Calculate distance in meters between two locations
+sub dist {
+    my ($lat1, $lon1, $lat2, $lon2) = @_;
+    my $r_lat1 = deg2rad($lat1);
+    my $r_lon1 = deg2rad($lon1);
+    my $r_lat2 = deg2rad($lat2);
+    my $r_lon2 = deg2rad($lon2);
+    my $r_d = acos(sin($r_lat1) * sin($r_lat2) + cos($r_lat1) * cos($r_lat2) * cos($r_lon1-$r_lon2));
+    return($r_d*180.0*60.0/pi()*1852.0);
+}
+
+#--------------------------------------------------------------------------
+
+sub calcScale {                 # EW / NS scaling
+    my ($lat) = @_;
+    return(dist($lat,-1.0/120.0,$lat,1.0/120.0) / 1852.0);
+}
+
+#--------------------------------------------------------------------------
+
diff --git a/scripts/mapfgd.pl b/scripts/mapfgd.pl
new file mode 100755
index 0000000..e7342bb
--- /dev/null
+++ b/scripts/mapfgd.pl
@@ -0,0 +1,258 @@
+#!/usr/bin/perl
+# -*- perl -*-
+# Written by Derrick J Brashear, KB3EGH
+# Released to the public domain.
+
+# $Id: mapfgd.pl,v 1.5 2010/07/03 22:09:48 we7u Exp $
+
+# Usage: mapfgd <directory>
+# Creates fake fgd files for all correctly USGS-named maps which don't 
+# already have them
+
+local (@dirlist) = @ARGV;
+local ($mapdir);
+foreach $mapdir (@dirlist)
+{
+    opendir (DIR, $mapdir) || die "mapini: couldn't open directory \`$mapdir': $!\n";
+    local ($file, $fullfile, $expr, $mlat, $mlon, $mlats, $mlons);
+    local ($nlat, $nlon, $nlats, $nlons);
+    local ($dlat, $dlon, $inifile);
+    local ($imgwidth, $imglength, $imgres, $imgdepth, $imgphotometric);
+    local ($imgtimestamp);
+    foreach $file (sort grep (! /^\./, readdir (DIR)))
+    {
+        # Only examine .tif files.
+        next unless $file =~ /\.tif$/;
+        next unless $file =~ /^[iIoOcCfFkKlLpPjJgG]/;
+        $fullfile = $mapdir . '/' . $file;
+        $inifile = $mapdir . '/' . $file;
+        $inifile =~ s/\.tif$/.fgd/;
+        next if (-f $inifile);
+        open (INI, ">$inifile");
+        $file =~ /^([iIoOcCfFkKlLpPjJgG])([0-9][0-9])([0-9][0-9][0-9])([a-hA-H])([1-8])/;
+        $letter = $1;
+        $mlat = $2;
+        $mlon = $3;
+        $mlats = $4;
+        $mlons = $5;
+
+        if ($letter eq 'c') {
+            $dlon = 0-$mlon-2;
+            printf INI "1.5.1.1   WEST BOUNDING COORDINATE:  %.6f\n", $dlon;
+            $dlon = 0-$mlon;
+            printf INI "1.5.1.2   EAST BOUNDING COORDINATE:  %.6f\n", $dlon;
+            $dlat = $mlat+1;
+            printf INI "1.5.1.3   NORTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+            $dlat = $mlat;
+            printf INI "1.5.1.4   SOUTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+        } else {
+            if (($letter eq 'f') || ($letter eq 'g')){
+                $dlon = 0-$mlon-1;
+                printf INI "1.5.1.1   WEST BOUNDING COORDINATE:  %.6f\n", $dlon;
+                $dlon = 0-$mlon-(.125*$mlons)+.125;
+                printf INI "1.5.1.2   EAST BOUNDING COORDINATE:  %.6f\n", $dlon;
+                $dlat = $mlat+.375+(.125*(&lettonum ($mlats)));
+                printf INI "1.5.1.3   NORTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+                $dlat = $mlat-.125+(.125*(&lettonum ($mlats)));
+                printf INI "1.5.1.4   SOUTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+            } else {
+                if ($letter eq 'k') {
+                    $dlon = 0-$mlon-(.125*$mlons)-.125;
+                    printf INI "1.5.1.1   WEST BOUNDING COORDINATE:  %.6f\n", $dlon;
+                    $dlon = 0-$mlon-(.125*$mlons)+.125;
+                    printf INI "1.5.1.2   EAST BOUNDING COORDINATE:  %.6f\n", $dlon;
+                    $dlat = $mlat+(.125*(&lettonum ($mlats)));
+                    printf INI "1.5.1.3   NORTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+                    $dlat = $mlat-.125+(.125*(&lettonum ($mlats)));
+                    printf INI "1.5.1.4   SOUTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+                } else {
+		    if ($letter eq 'i') {
+			$dlon = 0-$mlon-(.125*$mlons)-.250;
+			printf INI "1.5.1.1   WEST BOUNDING COORDINATE:  %.6f\n", $dlon;
+			$dlon = 0-$mlon-(.125*$mlons)+.125;
+			printf INI "1.5.1.2   EAST BOUNDING COORDINATE:  %.6f\n", $dlon;
+			$dlat = $mlat+.125+(.125*(&lettonum ($mlats)));
+			printf INI "1.5.1.3   NORTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+			$dlat = $mlat-.125+(.125*(&lettonum ($mlats)));
+			printf INI "1.5.1.4   SOUTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+		    } else {
+			$dlon = 0-$mlon-(.125*$mlons);
+			printf INI "1.5.1.1   WEST BOUNDING COORDINATE:  %.6f\n", $dlon;
+			$dlon = 0-$mlon-(.125*$mlons)+.125;
+			printf INI "1.5.1.2   EAST BOUNDING COORDINATE:  %.6f\n", $dlon;
+			$dlat = $mlat+(.125*(&lettonum ($mlats)));
+			printf INI "1.5.1.3   NORTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+			$dlat = $mlat-.125+(.125*(&lettonum ($mlats)));
+			printf INI "1.5.1.4   SOUTH BOUNDING COORDINATE:  %.6f\n", $dlat;
+		    }
+                }
+            }
+        }
+
+        close (INI);
+    }
+    closedir (DIR);
+}
+
+sub lettonum
+{
+    local ($let) = @_;
+    if ($let eq 'a')
+    {return 1;}
+    if ($let eq 'b')
+    {return 2;}
+    if ($let eq 'c')
+    {return 3;}
+    if ($let eq 'd')
+    {return 4;}
+    if ($let eq 'e')
+    {return 5;}
+    if ($let eq 'f')
+    {return 6;}
+    if ($let eq 'g')
+    {return 7;}
+    if ($let eq 'h')
+    {return 8;}
+}
+sub nextlet
+{
+    local ($let,$scale) = @_;
+    if ($scale eq 'c') 
+    {$nlat++;return 'a';}
+    if ($scale eq 'f') {
+        if ($let eq 'a') 
+        {return 'e';}
+        if ($let eq 'e') 
+        {$nlat++;return 'a';}
+    }    
+    if ($let eq 'a')
+    {return 'b';}
+    if ($let eq 'b')
+    {return 'c';}
+    if ($let eq 'c')
+    {return 'd';}
+    if ($let eq 'd')
+    {return 'e';}
+    if ($let eq 'e')
+    {return 'f';}
+    if ($let eq 'f')
+    {return 'g';}
+    if ($let eq 'g')
+    {return 'h';}
+    if ($let eq 'h')
+    {$nlat++;return 'a';}
+}
+sub nextnum
+{
+    local ($let,$scale) = @_;
+    if ($scale eq 'c') {
+        $nlon+=2;
+        if ($nlon < 100) {
+            $nlon="0$nlon";
+        }
+        return '1';
+    }
+    if ($scale eq 'f') {
+        $nlon++;
+        if ($nlon < 100) {
+            $nlon="0$nlon";
+        }
+        return '1';
+    }
+    if ($let eq '1')
+    {return '2';}
+    if ($let eq '2')
+    {return '3';}
+    if ($let eq '3')
+    {return '4';}
+    if ($let eq '4')
+    {return '5';}
+    if ($let eq '5')
+    {return '6';}
+    if ($let eq '6')
+    {return '7';}
+    if ($let eq '7')
+    {return '8';}
+    if ($let eq '8')
+    {$nlon++;
+     if ($nlon < 100) {
+         $nlon="0$nlon";
+     }
+     return '1';}
+}
+sub oldlastnum
+{
+    local ($let,$scale) = @_;
+    if ($let = 1) 
+    {print INI "let was 1\n";$let=9; $nlon--; $nlon="0$nlon";}
+    $let--;
+    return $let;
+}
+sub lastnum
+{
+    local ($let,$scale) = @_;
+    if ($scale eq 'c') {
+        $nlon-=2; 
+        if ($nlon < 100) {
+            $nlon="0$nlon";
+        }
+        return '1';
+    }
+    if ($scale eq 'f') {
+        $nlon--; 
+        if ($nlon < 100) {
+            $nlon="0$nlon";
+        }
+        return '1';
+    }
+    if ($let eq '1') {
+        $nlon--; 
+        if ($nlon < 100) {
+            $nlon="0$nlon";
+        }
+        return '8';
+    }
+    if ($let eq '2')
+    {return '1';}
+    if ($let eq '3')
+    {return '2';}
+    if ($let eq '4')
+    {return '3';}
+    if ($let eq '5')
+    {return '4';}
+    if ($let eq '6')
+    {return '5';}
+    if ($let eq '7')
+    {return '6';}
+    if ($let eq '8')
+    {return '7';}
+}
+sub lastlet
+{
+    local ($let,$scale) = @_;
+    if ($scale eq 'c') 
+    {$nlat--;return 'a';}
+    if ($scale eq 'f') {
+        if ($let eq 'a') 
+        {$nlat--;return 'e';}
+        if ($let eq 'e') 
+        {return 'a';}
+    }    
+    if ($let eq 'a')
+    {$nlat--;return 'h';}
+    if ($let eq 'b')
+    {return 'a';}
+    if ($let eq 'c')
+    {return 'b';}
+    if ($let eq 'd')
+    {return 'c';}
+    if ($let eq 'e')
+    {return 'd';}
+    if ($let eq 'f')
+    {return 'e';}
+    if ($let eq 'g')
+    {return 'f';}
+    if ($let eq 'h')
+    {return 'g';}
+}
+
diff --git a/scripts/object2shp.pl b/scripts/object2shp.pl
new file mode 100755
index 0000000..588f2c2
--- /dev/null
+++ b/scripts/object2shp.pl
@@ -0,0 +1,147 @@
+#!/usr/bin/env perl
+#
+# $Id: object2shp.pl,v 1.5 2012/11/01 18:57:19 we7u Exp $
+#
+#  Copyright (C) 2006-2012 Tom Russo
+
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#  see file COPYING for details
+
+#--------------------------------------------------------------------------
+
+# This script produces an ESRI point shapefile from the object.log file, 
+# according to the "Rolling your own shapefile maps" section of README.MAPS
+# The point file will display using the TIGER Landmark Point dbfawk file
+#
+# This enables fast generation of point maps by using xastir to plop down
+# objects, then this script to turn the object.log file into a shapefile
+#
+# Typical usage:  
+#   object2shp.pl object.log myshape
+#
+# Remember to exit xastir and delete "object.log", otherwise xastir will
+# never forget your objects.
+#--------------------------------------------------------------------------
+
+
+if ($#ARGV != 1)
+{
+    print "Usage: $0 <object_file> <shapefile base name>\n";
+    exit 1;
+}
+
+
+open(INOBJ,"<$ARGV[0]") || die "Cannot open input object file $ARGV[0]\n";
+
+$cmd[0]="shpcreate $ARGV[1] point";
+$cmd[1]="dbfcreate $ARGV[1] -n ID 8 0 -s CFCC 4 -s NAME 30";
+$outfile=$ARGV[1];
+
+
+
+
+foreach $command (@cmd)
+{
+    system($command);
+    if ($? == -1) 
+    {
+        print "failed to execute: $!\n";
+    }
+    elsif ($? & 127) 
+    {
+        printf "child died with signal %d, %s coredump\n",
+        ($? & 127),  ($? & 128) ? 'with' : 'without';
+    }
+    elsif ($?&0xF0)
+    {
+        printf "child exited with value %d\n", $? >> 8;
+    }
+}
+
+# We now have the shapefile and dbf file created, start populating from the
+# objects file:
+
+$i=0;
+while (<INOBJ>)
+{
+    chomp($_);
+    $semicolon=substr($_,0,1);
+    $name=substr($_,1,9);
+    $live_or_dead=substr($_,10,1);
+    $timestamp=substr($_,11,7);
+    $lat=substr($_,18,8);
+    $symtab=substr($_,26,1);
+    $long=substr($_,27,9);
+    $sym=substr($_,36,1);
+
+#sanity check --- don't try to convert if the line doesn't conform to what
+# it should, or if it represents a killed object.  Sometimes objects get
+# commented out with #, etc.
+    next if ($semicolon ne ";");
+    next if ($live_or_dead eq "_");
+
+    $i++;  # bump the ID number so every point has a unique one
+
+    $lat_deg=substr($lat,0,2);
+    $lat_min=substr($lat,2,5);
+    $lat_hem=substr($lat,7,1);
+
+    $long_deg=substr($long,0,3);
+    $long_min=substr($long,3,5);
+    $long_hem=substr($long,8,1);
+
+    $lat=$lat_deg+$lat_min/60;
+    $lat *= -1 if ($lat_hem eq "S");
+
+    $long=$long_deg+$long_min/60;
+    $long *= -1 if ($long_hem eq "W");
+
+    # Construct symbol
+    
+    if ($symtab ne "/" && $symtab ne "\\")
+    {
+        print "overlay symbol, symtab is $symtab\n";
+        $overlay=$symtab;
+        $symtab="\\";
+        print " reset values symtab is $symtab, overlay is $overlay\n";
+    } 
+    else
+    {
+        $overlay=" ";
+    }
+
+    $cmd[0]="shpadd $outfile $long $lat";
+    $cmd[1]="dbfadd $outfile $i \'X$symtab$sym$overlay\' $name";
+    print $cmd[1]."\n";
+    foreach $command (@cmd)
+    {
+        system($command);
+        if ($? == -1) 
+        {
+            print "failed to execute: $!\n";
+        }
+        elsif ($? & 127) 
+        {
+            printf "child died with signal %d, %s coredump\n",
+            ($? & 127),  ($? & 128) ? 'with' : 'without';
+        }
+        elsif ($?&0xF0)
+        {
+            printf "child exited with value %d\n", $? >> 8;
+        }
+    }
+    
+}
diff --git a/scripts/overlay.pl b/scripts/overlay.pl
new file mode 100755
index 0000000..61d8fdb
--- /dev/null
+++ b/scripts/overlay.pl
@@ -0,0 +1,248 @@
+#!/usr/bin/perl
+
+
+# Written by Curt Mills, WE7U
+# Released to the public domain.
+#
+# $Id: overlay.pl,v 1.5 2010/07/03 22:09:48 we7u Exp $
+
+
+# Script to create Xastir "Overlay" files from "CSV" files of the
+# proper format (comma-delimited files).
+#
+# 1) Creates files in Xastir "log" format if you enter a callsign
+# below.  These files can then be put in your ~/.xastir/logs/
+# directory and brought in via the File->Open Log File menu option.
+# If you start with the CSV files in the ~/.xastir/logs/ directory
+# and process them there with this script, the output files will be
+# placed into the proper place for Xastir to find them.
+#
+# 2) If no callsign is entered, this script will create files in
+# Xastir's "~/.xastir/config/object.log" format.  You can then
+# replace or append the file to the object.log file, restart Xastir
+# or "Reload Object/Item History".
+#
+# NOTE: These APRS Items will become part of your locally
+# owned/transmitted objects, so if you don't want them transmitted,
+# turn of Object/Item transmit before bringing them in.
+#
+# Input:  Directory name.  If no directory name passed in, it will
+# operate on every CSV file in the current directory.
+#
+# Input format:
+# Name  N/S  lat  E/W  long   //  comment fields.............
+# SUPPLY,N,34.0000,W,78.0000,ICON,text1,text2,text3,text4,...
+#
+#
+# The name will have spaces removed if it is longer than nine
+# characters.  If it is still too long, vowels will be removed, then
+# it will be truncated to nine characters if still needed.  The full
+# name will be transmitted as a comment.  All other text fields will
+# also be transmitted as comments, so that they will all appear in
+# the Station Info dialog.
+#
+# Icons will be a default small red circle unless '/' or '\' is the
+# leading character in that field and the next specifies the APRS
+# symbol.  In that case the two-letter combination will get used as
+# the symbol for the Item.
+
+
+
+# Change this to match whatever callsign you're running Xastir as,
+# so that the APRS Items appear to have been generated locally.  You
+# can then suck this file in as a "log" file from within Xastir.  If
+# this field is empty, then instead write the packets out without a
+# header, as in Xastir's "object.log" format.
+$callsign = "";
+
+if ($callsign ne "") {
+  $callsign = uc($callsign) . '>APRS:';
+}
+
+
+
+# Main program.  Process every ".csv" file found in the directory.
+#
+$dirname = shift;
+if ($dirname == "") {
+  $dirname = ".";
+}
+
+opendir(DIR, $dirname) or die "Can't opendir $dirname: %!";
+
+while (defined($file = readdir(DIR))) {
+  chomp $file;
+
+  if ( $file =~ /\.csv$/ ) {
+
+    # Do something with "$dirname/$file"
+    &process_file($dirname, $file);
+  }
+  else {
+#    printf("$dirname/$file\n");
+  }
+}
+
+
+
+# Process one file.  Creates an output file that matches the
+# basename but changes the "csv" to "overlay".
+#
+sub process_file() {
+
+  $output_file = $_[1];
+  $output_file =~ s/\.csv$/.overlay/;
+
+  printf("$dirname/$file -> $output_file\n");
+ 
+  open(SOURCE, "< $_[1]")
+    or die "Couldn't open $path for reading: $!\n";
+
+  open(OUTPUT, "> $output_file")
+    or die "Couldn't open $output_file for writing: $!\n";
+  
+  while (<SOURCE>) {
+    &process_line($_);
+  }
+
+  close(SOURCE);
+  close(OUTPUT);
+}
+
+
+
+# Process one line.  Write the formatted data to the OUTPUT file.
+#
+sub process_line() {
+  #printf("$_[0]");
+
+  # Parse the CSV line into an array
+  @list = parse_csv($_[0]);
+
+  if (!($list[0] =~ m/Location/i)) {
+    #print OUTPUT @list;
+
+    # As a temporary measure, create items out of each of the lines,
+    # with a status line for each extra data object so that they
+    # appear in the Station Info dialog.
+    &create_items(@list);
+  }
+}
+
+
+
+# Create an APRS Item out of each array.  Create a status line for
+# each extra column associated with a line so that the info shows up
+# in the Station Info dialog.
+#
+# Examples.  Name is 3-9 characters:
+# )AID #2!4903.50N/07201.75WA
+# )G/WB4APR!53  .  N\002  .  Wd
+#
+sub create_items {
+
+  $name = $_[0];
+  if ($name eq "") {
+    printf("Error, name column is empty\n");
+  }
+
+  # If too long, try removing spaces first
+  if (length($name) > 9) {
+    $name =~ s/\s//ig;
+  }
+ 
+  # If still too long, remove vowels
+  if (length($name) > 9) {
+    $name =~ s/a//ig;
+    $name =~ s/e//ig;
+    $name =~ s/i//ig;
+    $name =~ s/o//ig;
+    $name =~ s/u//ig;
+  }
+ 
+  # Extend to three characters if short
+  if (length($name) < 3) {
+    $name = $name . "   ";
+  }
+
+  $name = substr($name,0,9);
+  $name[9] = "\0";  # Terminate name at 9 characters, minimum 3
+
+  $n_s = uc( substr($_[1],0,1) );
+  $latitude = $_[2];
+  $e_w = uc( substr($_[3],0,1) );
+  $longitude = $_[4];
+  if ($_[5] =~ /ICON/i) {
+    $icon1 = "/";
+    $icon2 = "/";
+  }
+  else {
+    $icon1 = substr($_[5],0,1);
+    $icon2 = substr($_[5],1,1);
+  }
+
+  # Convert lat/long to APRS format (or Base-91 Compressed format)
+  $lat_deg = $latitude;
+  $lat_deg =~ s/\.\d+$//;
+  $lat_deg = sprintf("%02d", $lat_deg);
+  $lat_min = $latitude;
+  $lat_min =~ s/^\d+\./0./;
+  $lat_min = $lat_min * 60.0;
+  $lon_deg = $longitude;
+  $lon_deg =~ s/\.\d+$//;
+  $lon_deg = sprintf("%03d", $lon_deg);
+  $lon_min = $longitude;
+  $lon_min =~ s/^\d+\./0./;
+  $lon_min = $lon_min * 60;
+
+  # Create an APRS "Item" packet
+  $line = sprintf("%s)%s!%s%05.2f%s%s%s%05.2f%s%s",
+    $callsign,
+    $name,
+    $lat_deg,
+    $lat_min,
+    $n_s,
+    $icon1,
+    $lon_deg,
+    $lon_min,
+    $e_w,
+    $icon2);
+
+  # Go process the rest of the columns, if any.  Create APRS Item
+  # packets with comments from them.
+  for ($i = 6; $i < 106; $i++) {
+    chomp $_[$i];
+    if ($_[$i] ne "") {
+      #printf("$_[$i]");
+      printf(OUTPUT "%s%s\n",
+        $line,
+        $_[$i]); 
+    }
+  }
+
+  # Write it out to the file, with the full name as a comment
+  printf(OUTPUT "%s%s\n",
+    $line,
+    $_[0]);
+}
+
+
+
+# Parse CVS line into an array, removing double-quotes and such if
+# found.
+#
+sub parse_csv {
+  my $text = shift; # Record containing comma-separated values
+  my @new = ();
+  push(@new, $+) while $text =~ m{
+    # The first part groups the phrase inside the quotes.
+    # See explanation of this pattern in MRE
+    "([^\"\\]*(?:\\.[^\"\\]*)*)",?
+      | ([^,]+),?
+      |  ,
+  }gx;
+  push(@new, undef) if substr($text, -1, 1) eq ',';
+  return @new;  # List of values that were comma-separated
+}
+
+
diff --git a/scripts/ozi2geo.pl b/scripts/ozi2geo.pl
new file mode 100755
index 0000000..10f98a4
--- /dev/null
+++ b/scripts/ozi2geo.pl
@@ -0,0 +1,211 @@
+#!/usr/bin/perl
+
+# Written by Curt Mills, WE7U
+# Released to the public domain.
+# Modified from the earlier inf2geo.pl script.
+#
+# $Id: ozi2geo.pl,v 1.6 2010/07/03 22:09:48 we7u Exp $
+#
+# Read in .map file (an OziExplorer file in this case).
+# Check the version of the map format (1st line).  My example is
+# version 2.2.
+# Get the filename from the 2nd line of the file.
+# Check that "WGS 84" or "NAD 83" are present in the file (5th
+# line?).
+# Check the "Map Projection".
+# Grab the first four points, which hopefully are the corners.
+# Snag the MMPXY lines and the MMPLL lines.  These are the X/Y and
+# Lat/Long of the corners in the example I have.
+# Write out the .geo file
+#
+# 2003-08-15 ZL2UMF: add processing multiple files in one go (masks
+# and whot-not) so you can convert all your maps in one step.
+
+#use strict; 
+use IO::File;
+
+
+#go through every filename passed to this script
+foreach my $file (@ARGV) {
+    print "*** $file ***\n";
+    
+    #make a geo of this file
+    makeGeo ($file);
+    
+}
+
+exit; #just in case
+
+
+
+
+
+sub makeGeo {
+    my $ozimap_filename = shift;
+   
+    # Snag the filename out of the .map file instead?  Here we
+    # create it from the.map filename.
+    #
+    my $filename = $ozimap_filename;
+    $filename =~ s/\.map$//i; 
+    
+    my $geo_filename = $filename . ".geo";
+    
+#    $ozimap = IO::File->new("< $ARGV[0].map")
+#	or $ozimap = IO::File->new("< $ARGV[0].MAP")
+#	or $ozimap = IO::File->new("< $ARGV[0].Map")
+
+    #skip this file if geo already exists
+    return print "$filename.geo already exists, will not overwrite\n"   if( -e "$filename.geo" );
+
+    #read the map file
+    my $ozimap = IO::File->new ( "< $ozimap_filename" )
+	or return print "\nCouldn't open $ozimap_filename for reading:\n$!\n\n";
+
+    #make the new geo file
+    $geo = IO::File->new("> $geo_filename")
+	or return print "Couldn't open $geo_filename for writing: $!\n";
+
+    # First line should be something like:
+    # "OziExplorer Map Data File Version 2.2"
+    #
+    $tmp = $ozimap->getline();
+print "\t$tmp";
+
+    $final_filename = $ozimap->getline();
+    chomp($final_filename);
+#print $final_filename;
+
+# Check that the filename we just read matches the filename we
+# created from the .map filename.
+
+    $tmp = $ozimap->getline();
+#print $tmp;
+
+    $tmp = $ozimap->getline();
+
+    # Get the datum
+    $tmp = $ozimap->getline();
+#print $tmp;
+
+# Check that the datum is "WGS 84", "WGS84", "NAD 83", or "NAD83".
+    if ($tmp =~ /WGS 84/i
+        || $tmp =~ /WGS84/i
+        || $tmp =~ /NAD 83/i
+        || $tmp =~ /NAD83/i) {
+    }
+    else {
+      print "***Datum is not WGS84 or NAD83: Results will be inaccurate***\n";
+    }
+
+    # Read until we find "Map Projection" at the start of a line.
+    #
+    $done = 0;
+    while (!$done) {
+      $tmp = $ozimap->getline();
+#print $tmp;
+      if ($tmp=~ /Map Projection/) {
+        $done++;
+      }
+    }
+    if ($tmp =~ /UTM/i) {
+      print "***Found UTM projection: Results will be inaccurate***\n";
+#print "$tmp";
+    }
+
+# We have the map projection.  Check it.  Issue a warning if it's
+# not what we can handle easily.
+
+    # Read until we find "MMPXY" at the start of a line.
+    #
+    $done = 0;
+    while (!$done) {
+      $tmp = $ozimap->getline();
+      if ($tmp=~ /MMPXY/) {
+        $done++;
+      }
+    }
+    $MMPXY1 = $tmp;
+#print $MMPXY1;
+    $MMPXY2 = $ozimap->getline();
+#print $MMPXY2;
+    $MMPXY3 = $ozimap->getline();
+#print $MMPXY3;
+    $MMPXY4 = $ozimap->getline();
+#print $MMPXY4;
+    $MMPLL1 = $ozimap->getline();
+#print $MMPLL1;
+    $MMPLL2 = $ozimap->getline();
+#print $MMPLL2;
+    $MMPLL3 = $ozimap->getline();
+#print $MMPLL3;
+    $MMPLL4 = $ozimap->getline();
+#print $MMPLL4;
+
+# If the corners are always listed in circular order, we can choose
+# to use corners 1 and 3 for our tiepoints.  Try this.
+
+
+    # Read until we find "Map Image Width" inside a line.
+    #
+    $done = 0;
+    while (!$done) {
+      $tmp = $ozimap->getline();
+      if ($tmp=~ /Map Image Width/) {
+        $done++;
+      }
+    }
+#print $tmp;
+    $image_size = $tmp;
+
+# That should be all that we need to read from the file.
+
+    # Get the X/Y for the tiepoints
+    my ($a, $b, $x0, $y0) = split(',', $MMPXY1);
+    chomp($x0);
+    chomp($y0);
+    # Convert to numbers
+    $x0 = $x0 * 1;
+    $y0 = $y0 * 1;
+
+#print "$x0 $y0\n";
+
+    my ($a, $b, $x1, $y1) = split(',', $MMPXY3);
+    chomp($x1);
+    chomp($y1);
+    # Convert to numbers
+    $x1 = $x1 * 1;
+    $y1 = $y1 * 1;
+
+#print "$x1 $y1\n";
+
+    # Get the lat/long for the tiepoints
+    my ($a, $b, $tp0_lon, $tp0_lat) = split(',', $MMPLL1);
+    chomp($tp0_lon);
+    chomp($tp0_lat);
+
+#print "$tp0_lon $tp0_lat\n";
+
+    my ($a, $b, $tp1_lon, $tp1_lat) = split(',', $MMPLL3);
+    chomp($tp1_lon);
+    chomp($tp1_lat);
+
+#print "$tp1_lon $tp1_lat\n";
+
+    # Split out the imagesize string
+    my ($a, $b, $width, $height) = split(',', $image_size);
+    chomp($width);
+    chomp($height);
+
+    #write to the geo file
+    printf $geo "FILENAME    $final_filename\n";
+    printf $geo "TIEPOINT    $x0\t\t$y0\t$tp0_lon\t$tp0_lat\n";
+    printf $geo "TIEPOINT    $x1\t$y1\t$tp1_lon\t$tp1_lat\n";
+    printf $geo "IMAGESIZE   $width\t$height\n";
+    printf $geo "#\n# Converted from an OziExplorer .MAP file by WE7U's ozi2geo.pl script\n#\n";
+
+    $ozimap->close();
+    $geo->close();
+}
+
+
diff --git a/scripts/permutations.pl b/scripts/permutations.pl
new file mode 100755
index 0000000..8baca20
--- /dev/null
+++ b/scripts/permutations.pl
@@ -0,0 +1,391 @@
+#!/usr/bin/perl -w
+
+
+#
+# Written by Paul Lutt, KE7XT & Curt Mills, WE7U.
+# Released to the public domain.
+#
+#
+# $Id: permutations.pl,v 1.11 2010/07/03 22:09:48 we7u Exp $
+#
+#
+# Finds the different lat/long representations corresponding to the
+# input numbers.  A space is required between the degrees portion
+# and the rest of the input.  Writes out a log file containing APRS
+# objects suitable for importing into Xastir, to graphically plot
+# the locations of the objects.  Now that Xastir has a server port
+# we could directly inject them into the program via that route as
+# well, but we currently don't do that.
+#
+# Converts between different lat/lon formats.  Will also give UMS
+# position if the lat/lon resides somewhere inside the Seattle area
+# aeronautical map.
+#
+# UMS coordinates have been used in the past by King County, WA SAR.
+# It can be useful for plotting positions on Green Trails maps and
+# perhaps other maps.  The maps must be 15' topo maps and marked in
+# tenths of miles along the edge in order to make use of this
+# coordinate system.
+#
+# Web pages which discuss UMS format:
+#   http://www.impulse.net/~mlynch/land_nav.html
+#   http://www.logicsouth.com/~lcoble/dir9/land_nav.htm
+#   http://www.aasar.org/training/academy/navigation.pdf
+#
+
+
+use lib "/usr/local/lib";
+use Coordinate;         # WE7U's Coordinate.pm module
+
+
+# Get the username
+$user = getlogin;
+chomp $user;
+$filename = "/var/tmp/PERMUTATIONS-$user.log";
+
+
+sub convert {
+
+    # Snag the input
+    $_ = $_[0];
+
+    print "\n";
+
+    # If the first item has 2 digits and one character and there are
+    # three "words" in the input, we're starting with a UTM value.
+    if (/^\d\d[a-zA-Z]\s+\w+\s+\w+\s*$/) {
+
+        # printf("Found a UTM value\n");
+
+        # We'll convert it to the standard format first and then run
+        # through the rest of the code.
+
+        $zone = $_;
+        $easting = $_;
+        $northing = $_;
+
+        $zone =~ s/^(\d\d[a-zA-Z])\s+\w+\s+\w+\s*$/$1/;
+        $easting =~ s/^\d\d[a-zA-Z]\s+(\w+)\s+\w+\s*$/$1/;
+        $northing =~ s/^\d\d[a-zA-Z]\s+\w+\s+(\w+)\s*$/$1/;
+
+        if ($easting > 999999) {
+            printf("Easting value is too high!\n");
+            return;
+        }
+
+        $position->zone($zone);
+        $position->easting($easting);
+        $position->northing($northing);
+
+        # Convert to lat/lon values
+        $position->utm_to_lat_lon();
+
+        # printf("Calculated Lat, Long position(Lat, Long):  %f   %f\n",
+        #    $position->latitude(),
+        #    $position->longitude() );
+
+        $latitude = $position->latitude();
+        $longitude = $position->longitude();
+
+        $lat_dir = "N";
+        $long_dir = "E";
+ 
+        if ($latitude < 0.0) {
+            $latitude = abs($latitude);
+            $lat_dir = "S"
+        }
+        if ($longitude < 0.0) {
+            $longitude = abs($longitude);
+            $long_dir = "W";
+        }
+
+ 
+        # printf("%f%s %f%s\n", $latitude,$lat_dir,$longitude,$long_dir);
+
+       $_ = sprintf("%f%s %f%s",
+            $latitude,$lat_dir,$longitude,$long_dir);
+
+    }
+
+    # Look for lat/long value in the input
+
+    # Check for N/S/E/W characters in the input.  Set the
+    # appropriate flags if found.
+    $lat_dir = "N";
+    $long_dir = "E";
+    if (/S/ || /s/) { $lat_dir  = "S"; }
+    if (/W/ || /w/) { $long_dir = "W"; }
+    # Filter out these characters from the input
+    tr/nsewNSEW//d;
+
+    # Convert to DD MM SS format
+    ($lat_deg, $lat_min, $lat_sec,
+    $long_deg, $long_min, $long_sec) = split(' ');
+
+    # Decimal Degrees?
+    if ($lat_deg =~ /\./) {
+
+        $long_deg = $lat_min;   # Save long_degrees in proper place
+
+        $temp = $lat_deg;
+        $lat_deg = int $temp;
+        $lat_min = int ((abs($temp) * 60.0) % 60);
+
+        # Modulus converts to integers, so we bump up by 10 and then
+        # back down.
+        $lat_sec = (abs($temp) * 36000.0) % 600;
+        $lat_sec = $lat_sec / 10;
+
+        $temp = $long_deg;
+
+        $long_deg = int $temp;
+        $long_min = int ((abs($temp) * 60.0) % 60);
+        $long_sec = (abs($temp) * 36000.0) % 600;
+        $long_sec = $long_sec / 10;
+    }
+    # Decimal Minutes?
+    elsif ($lat_min =~ /\./) {
+
+        $long_min = $long_deg;  # Save long_minutes in proper place
+        $long_deg = $lat_sec;   # Save long_degrees in proper place
+
+        $temp = $lat_min;
+        $lat_min = int abs($temp);
+        $lat_sec = (abs($temp) * 60.0) % 60;
+        $lat_sec = $lat_sec / 10;
+
+        $temp = $long_min;
+        $long_min = int abs($temp);
+        $long_sec = (abs($temp) * 600.0) % 600;
+        $long_sec = $long_sec / 10;
+    }
+    # Decimal Seconds
+    else {  # Already in DD MM SS format, don't convert
+    }
+
+    # Print out the three lat/long formats
+    printf("                Decimal Degrees: %8.5f%s   %8.5f%s\n",
+        $lat_deg + ($lat_min/60.0) + ($lat_sec/3600.0), $lat_dir,
+        $long_deg + ($long_min/60.0) + ($long_sec/3600.0), $long_dir );
+ 
+    printf("        Degrees/Decimal Minutes: %02d %06.3f%s  %02d %06.3f%s\n",
+        $lat_deg, $lat_min + ($lat_sec/60.0), $lat_dir,
+        $long_deg, $long_min + ($long_sec/60.0), $long_dir );
+
+    printf("   Degrees/Minutes/Dec. Seconds: %02d %02d %4.1f%s %02d %02d %4.1f%s\n",
+        $lat_deg, $lat_min, $lat_sec, $lat_dir,
+        $long_deg, $long_min, $long_sec, $long_dir);
+
+    # Dump out the coordinate in APRS Item format:
+    printf(FH "TEST>APRS:)%s!%02d%05.2f%s/%03d%05.2f%s/\n",
+        $_[1],
+        $lat_deg,
+        $lat_min + ($lat_sec/60.0),
+        $lat_dir,
+        $long_deg,
+        $long_min + ($long_sec/60.0),
+        $long_dir );
+
+    # Fill in the coordinate object with the current lat/lon.
+    # Assuming WGS84 datum
+    if ($lat_dir =~ /S/) {
+        $position->latitude( -( $lat_deg + ($lat_min/60.0) + ($lat_sec/3600.0) ) );
+    }
+    else {
+        $position->latitude( $lat_deg + ($lat_min/60.0) + ($lat_sec/3600.0) );
+    }
+ 
+    if ($long_dir =~ /W/) {
+        $position->longitude( -( $long_deg + ($long_min/60.0) + ($long_sec/3600.0) ) );
+    }
+    else {
+        $position->longitude( $long_deg + ($long_min/60.0) + ($long_sec/3600.0) );
+    }
+
+    #printf("%f %f\n",$position->latitude,$position->longitude);
+
+    $position->lat_lon_to_utm();
+    printf("  Universal Transverse Mercator: %s  %07.0f  %07.0f\n",
+        $position->zone(),
+        $position->easting(),
+        $position->northing() );
+
+    # Check whether the coordinates are within the SEA aeronautical
+    # map area
+    $lat_err = 0;
+    if ($lat_dir =~ /S/ ||
+        $lat_deg < 44 || $lat_deg > 49 ||
+	    ($lat_deg == 44 && ($lat_min < 30 || ($lat_min == 30 && $lat_sec == 0))) ||
+	    ($lat_deg == 49 && ($lat_min > 0 || $lat_sec > 0))) {
+	print " lat. out of range ";
+	$lat_err = 1;
+    }
+
+    $long_err = 0;
+    if ($long_dir =~ /E/ ||
+        $long_deg < 117 || $long_deg > 125 ||
+	    ($long_deg == 117 && ($long_min == 0 && $long_sec == 0)) ||
+	    ($long_deg == 125 && ($long_min > 0 || $long_sec > 0))) {
+	print " long. out of range";
+        $long_err = 1;
+    }
+
+    return if ( $lat_err || $long_err);
+
+
+    # Compute UMS coordinates
+    $y_sec = 3600 * ($lat_deg - 44) + 60 * $lat_min + $lat_sec;
+    $y_sec = 18000 - $y_sec;
+
+    $x_sec = 3600 * ($long_deg - 117) + 60 * $long_min + $long_sec;
+    $x_sec = 28800 - $x_sec;
+
+    $quad = 32 * int($y_sec / 900) + int($x_sec / 900) + 1;
+
+#    print "\tx_sec= $x_sec, y_sec= $y_sec, quad= $quad\n";
+
+    $y_subquad_offset = int($y_sec / 450);
+    $x_subquad_offset = int($x_sec / 450);
+
+    if (&even($x_subquad_offset) && &even($y_subquad_offset)) {
+        print "        UMS (Green Trails Maps): SEA ${quad} A ";
+	printf "%02d", &s2m_x($x_sec - (450 * $x_subquad_offset));
+	printf "%02d\n", &s2m_y($y_sec - (450 * $y_subquad_offset));
+    } elsif (&odd($x_subquad_offset) && &even($y_subquad_offset)) {
+        print "        UMS (Green Trails Maps): SEA ${quad} B ";
+	printf "%02d", &s2m_x(450 * ($x_subquad_offset + 1) - $x_sec);
+	printf "%02d\n", &s2m_y($y_sec - (450 * $y_subquad_offset));
+    } elsif (&even($x_subquad_offset) && &odd($y_subquad_offset)) {
+        print "        UMS (Green Trails Maps): SEA ${quad} C ";
+	printf "%02d", &s2m_x($x_sec - (450 * $x_subquad_offset));
+	printf "%02d\n", &s2m_y(450 * ($y_subquad_offset + 1) - $y_sec);
+    } else {
+        print "        UMS (Green Trails Maps): SEA ${quad} D ";
+	printf "%02d", &s2m_x(450 * ($x_subquad_offset + 1) - $x_sec);
+	printf "%02d\n", &s2m_y(450 * ($y_subquad_offset + 1) - $y_sec);
+    }
+}
+
+
+
+sub even {
+    return (($_[0] & 1) == 0);
+}
+
+
+
+sub odd {
+    return (($_[0] & 1) == 1);
+}
+
+
+
+sub s2m_y {
+    return (int((0.1917966 * $_[0]) + 0.5));
+}
+
+
+
+sub s2m_x {
+    return (int((cos(($lat_deg + ($lat_min / 60.0) + ($lat_sec / 3600.0)) / 57.29578) * (0.1917966 * $_[0])) + 0.5));
+}
+
+
+
+##############
+# Main Program
+##############
+
+open (FH, ">$filename") || die "Couldn't open file for writing:$!\n";
+
+
+# Create new Coordinate object
+$position = Coordinate->new();
+
+
+$position->datum("WGS 84");    # Datum
+
+
+print "\n";
+print "Examples:  48  07228N   122 07228W\n";
+print "           48  08N      122 07W\n";
+print "          10U  0565264  5330343\n";
+
+print "\nAPRS Items will be written to: $filename\n";
+print "Enter a Lat/Long value or UTM value:\n";
+
+
+# Snag the input
+$input = <>;
+
+# Get rid of whitespace at the beginning
+$input =~ s/\s*//;
+
+# UTM value?
+if ($input =~ /^\d\d[a-zA-Z]\s+\w+\s+\w+\s*$/) {
+
+    $input2 = $input;
+    &convert($input2, "UTM");
+
+print "\n";
+
+    # Swap Easting/Northing values and convert again.  Leave the
+    # zone in it's original spot.
+    $input2 = $input;
+    $input2 =~ s/^(\d\d[a-zA-Z])\s+(\w+)\s+(\w+)\s*$/$1 $3 $2\n/;
+
+print $input2;
+    &convert($input2, "UTM2");
+}
+# else must be lat/lon value
+else {
+
+    # Need to break up the input into several possible formats,
+    # possibly including swapping lat/long pieces and plotting N/S
+    # and E/W variants.
+
+    # I'm going to assume that the user knows his/her approximate
+    # lat/lon, so they can input it in roughly the proper format to
+    # begin with.  All that's left then is to determine which of the
+    # three lat/lon formats it's in.
+
+    # 48  07228N   122 07228W
+
+    $input =~ s/^(\w+)\s+(\d)(\w)\s+(\w+)\s+(\d)(\w)\s*$/$1 0$2$3 $4 0$5$6\n/;
+
+    # DD.DDD
+    $input2 = $input;
+    $input2 =~ s/^(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s*$/$1.$2 $3.$4\n/;
+print $input2;
+    &convert($input2, "DD.DDD");
+
+print "\n";
+
+    # DD MM.MMM
+    $input2 = $input;
+    $input2 =~ s/^(\w+)\s+(\d\d)(\w+)\s+(\w+)\s+(\d\d)(\w+)\s*$/$1 $2.$3 $4 $5.$6\n/;
+    $input2 =~ s/(\.N)/.00N/;
+    $input2 =~ s/(\.S)/.00S/;
+    $input2 =~ s/(\.E)/.00E/;
+    $input2 =~ s/(\.W)/.00W/;
+print $input2;
+    &convert($input2, "DD MM.MM");
+
+print "\n";
+
+    # DD MM SS.S
+    $input2 = $input;
+    $input2 =~ s/^(\w+)\s+(\d\d)(\w)\s+(\w+)\s+(\d\d)(\w)\s*$/$1 $2 00.$3 $4 $5 00.$6\n/;
+    $input2 =~ s/^(\w+)\s+(\d\d)(\d)(\w)\s+(\w+)\s+(\d\d)(\d)(\w)\s*$/$1 $2 $3.$4 $5 $6 $7.$8\n/;
+    $input2 =~ s/^(\w+)\s+(\d\d)(\d\d)(\w+)\s+(\w+)\s+(\d\d)(\d\d)(\w+)\s*$/$1 $2 $3.$4 $5 $6 $7.$8\n/;
+    $input2 =~ s/(\.N)/.0N/;
+    $input2 =~ s/(\.S)/.0S/;
+    $input2 =~ s/(\.E)/.0E/;
+    $input2 =~ s/(\.W)/.0W/;
+    $input2 =~ s/\s(\d)(\.\d)/ 0$1$2/g;
+print $input2;
+    &convert($input2, "DD MM SS");
+
+}
+
+close(FH);
diff --git a/scripts/pos2shp.pl b/scripts/pos2shp.pl
new file mode 100755
index 0000000..2fb3c5e
--- /dev/null
+++ b/scripts/pos2shp.pl
@@ -0,0 +1,162 @@
+#!/usr/bin/env perl
+#
+# $Id: pos2shp.pl,v 1.7 2012/11/01 18:57:19 we7u Exp $
+#
+#  Copyright (C) 2006-2012 Tom Russo
+
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#  see file COPYING for details
+
+#--------------------------------------------------------------------------
+# This script produces an ESRI point shapefile from an APRS overlay
+# file (*.pos), according to the "Rolling your own shapefile maps"
+# section of README.MAPS The point file will display using the TIGER
+# Landmark Point dbfawk file.
+#
+# This enables fast generation of point maps in Shapefile format
+# from APRS overlay files.
+#
+# Typical usage:  
+#   pos2shp.pl file.pos myshape
+#--------------------------------------------------------------------------
+
+
+if ($#ARGV != 1)
+{
+    print "Usage: $0 <file.pos> <shapefile base name>\n";
+    exit 1;
+}
+
+
+open(INOBJ,"<$ARGV[0]") || die "Cannot open input overlay file $ARGV[0]\n";
+
+$cmd[0]="shpcreate $ARGV[1] point";
+$cmd[1]="dbfcreate $ARGV[1] -n ID 8 0 -s CFCC 4 -s NAME 30";
+$outfile=$ARGV[1];
+
+
+
+
+foreach $command (@cmd)
+{
+    system($command);
+    if ($? == -1) 
+    {
+        print "failed to execute: $!\n";
+    }
+    elsif ($? & 127) 
+    {
+        printf "child died with signal %d, %s coredump\n",
+        ($? & 127),  ($? & 128) ? 'with' : 'without';
+    }
+    elsif ($?&0xF0)
+    {
+        printf "child exited with value %d\n", $? >> 8;
+    }
+}
+
+
+# We now have the shapefile and dbf file created, start populating from the
+# overlay file:
+
+$i=0;
+$first_line = 1;
+while (<INOBJ>)
+{
+    chomp($_);
+
+    # Skip the first line if it starts with a '*' (comment line).
+    next if ($first_line && (substr($_,0,1) eq '*') );
+    $first_line = 0;
+
+    $temp = $_;
+    @bits = split('!', $temp);
+
+    # Sanity check --- don't try to convert if the line doesn't
+    # conform to what we expect.  We should have two items in the
+    # array at this point.
+    next if (length(@bits) < 1);
+
+    $name2 = $bits[0];
+    $rest = $bits[1];
+
+    $name = substr($name2,0,9); # Chop at 9 chars
+    $name =~ s/\w+\s+$//; # Remove trailing spaces
+
+    $lat=substr($rest,0,8);
+    $symtab=substr($rest,8,1);
+    $long=substr($rest,9,9);
+    $sym=substr($rest,18,1);
+
+# TODO: Do something with the comment field?  It appears that if we
+# add too much here we get strange results when displayed in Xastir.
+    $comment=substr($rest,19,100);
+#    $name = $name . ":" . $comment;
+
+    $i++;  # bump the ID number so every point has a unique one
+
+    $lat_deg=substr($lat,0,2);
+    $lat_min=substr($lat,2,5);
+    $lat_hem=substr($lat,7,1);
+
+    $long_deg=substr($long,0,3);
+    $long_min=substr($long,3,5);
+    $long_hem=substr($long,8,1);
+
+    $lat=$lat_deg+$lat_min/60;
+    $lat *= -1 if ($lat_hem eq "S");
+
+    $long=$long_deg+$long_min/60;
+    $long *= -1 if ($long_hem eq "W");
+
+    # Construct symbol
+    
+    if ($symtab ne "/" && $symtab ne "\\")
+    {
+        print "overlay symbol, symtab is $symtab\n";
+        $overlay=$symtab;
+        $symtab="\\";
+        print " reset values symtab is $symtab, overlay is $overlay\n";
+    } 
+    else
+    {
+        $overlay=" ";
+    }
+
+    $cmd[0]="shpadd $outfile $long $lat";
+    $cmd[1]="dbfadd $outfile $i \'X$symtab$sym$overlay\' $name";
+    print $cmd[1]."\n";
+    foreach $command (@cmd)
+    {
+        system($command);
+        if ($? == -1) 
+        {
+            print "failed to execute: $!\n";
+        }
+        elsif ($? & 127) 
+        {
+            printf "child died with signal %d, %s coredump\n",
+            ($? & 127),  ($? & 128) ? 'with' : 'without';
+        }
+        elsif ($?&0xF0)
+        {
+            printf "child exited with value %d\n", $? >> 8;
+        }
+    }
+    
+}
+
+
diff --git a/scripts/ridge_radar.pl b/scripts/ridge_radar.pl
new file mode 100755
index 0000000..2209fd8
--- /dev/null
+++ b/scripts/ridge_radar.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+#
+# $Id: ridge_radar.pl,v 1.2 2010/07/03 22:09:48 we7u Exp $
+#
+# Contributed to the public domain.  Authored by Jeremy McDermond
+# (NH6Z).
+#
+# This script takes a single argument:  The abbreviation of the
+# radar station off of the NWS site, and outputs to STDOUT a .geo
+# file that should be correct.
+# NOTE:  You'll need to install "LWP::UserAgent" and "Image::Size"
+# from CPAN to make it work.
+#
+# Here's a typical invocation which creates a NYC Ridge Radar .geo
+# file called OKX_NOR.geo:
+#
+#       ./ridge_radar.pl OKX > OKX_NOR.geo
+#
+# Of course you'd typically put the resulting file in your Xastir
+# maps directory and reindex maps to make it available for use.
+
+
+use strict;
+use LWP::UserAgent;
+use Image::Size;
+
+my $station = uc($ARGV[0]);
+
+my $gif_url = 'http://radar.weather.gov/ridge/RadarImg/N0R/' .  $station . '_N0R_0.gif';
+
+my $response = LWP::UserAgent->new->request(
+  HTTP::Request->new( GET => $gif_url )
+);
+
+unless($response->is_success) {
+  die "Couldn't get radar image: ", $response->status_line, "\n";
+}
+
+my ($img_x, $img_y) = imgsize(\$response->content);
+
+my $response = LWP::UserAgent->new->request(
+  HTTP::Request->new( GET => 'http://radar.weather.gov/ridge/RadarImg/N0R/' . $station .  '_N0R_0.gfw' )
+);
+
+unless($response->is_success) {
+  die "Couldn't get radar descriptor: ", $response->status_line, "\n";
+}
+
+my ( $yscale, undef, undef, $xscale, $lon, $lat ) = split(/\r\n/, $response->content);
+
+my $tiepoint_lat = $lat - ($yscale * $img_y);
+my $tiepoint_lon = $lon - ($xscale * $img_x);
+
+print "URL\t\t$gif_url\n";
+print "TIEPOINT\t0\t0\t$lon\t$lat\n";
+print "TIEPOINT\t$img_x\t$img_y\t$tiepoint_lon\t$tiepoint_lat\n";
+print "IMAGESIZE\t$img_x\t$img_y\n";
+print "REFRESH\t\t60\n";
+print "TRANSPARENT\t0x0\n";
+print "PROJECTION\tLatLon\n";
+
+
diff --git a/scripts/slideshow.pl b/scripts/slideshow.pl
new file mode 100755
index 0000000..eb3897f
--- /dev/null
+++ b/scripts/slideshow.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# $Id: slideshow.pl,v 1.3 2012/11/01 18:57:19 we7u Exp $
+#
+# Script to create a slideshow from Xastir snapshot images.  Note
+# that this script is Unix/Linux-centric due to the use of the $HOME
+# variable and the use of the "cp" command.
+#
+# Written 20090415 by Curt Mills, WE7U
+#
+# Copyright (C) 2012  The Xastir Group
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+#
+# Copies/renames ~/.xastir/tmp/snapshot.png files so that a
+# slideshow can be created from the images at a later date.  The
+# script monitors the input directory.  Any new snapshot.png file
+# that appears is allowed to age for a few seconds to make sure that
+# Xastir is done writing the file, then the file is copied to the
+# ~/.xastir/tmp/slideshow/ directory as a numbered file.  See below
+# for one method for turning these files into an animated GIF, or
+# else bring them up in some slideshow program and display them in
+# numerical order.  The name of the file contains the Unix Epoch
+# timestamp (the exact second that the file was made).
+#
+#
+# A note from Carl Makin, vk1kcm, modified slightly by Curt, we7u,
+# regarding creation of an animated GIF from the slideshow images:
+#
+# -------------------------------------------------------------------
+# This will create an animated gif that loops in your browser.
+#   gm convert -delay 20 -loop snapshot*.png animation.gif
+# See:
+#   http://www.graphicsmagick.org/FAQ.html#how-do-i-create-a-gif-animation-sequence-to-display-within-netscape
+# I think you can also great mpegs by changing the filename to "animation.mpg".
+# -------------------------------------------------------------------
+#
+
+
+$home = $ENV{"HOME"};
+$input_dir = "$home/.xastir/tmp";
+$output_dir = "$input_dir/slideshow";
+
+
+# Create the slideshow directory if it doesn't exist
+mkdir $output_dir;
+
+chdir $input_dir;
+
+while (1) {
+  $current_time = time;
+
+  # Snag the age of the existing snapshot.png file
+  $number = (stat("snapshot.png"))[9];
+
+  $difference = $current_time - $number;
+
+  # If the age of the file is more than 15 seconds but less than 31
+  # minutes, copy the file to the slideshow directory and rename it
+  # along the way.  Note that Xastir can produce snapshots at a rate
+  # of between one per minute, and one per 30 minutes.
+  #
+  if ( ($difference > 15) && ($difference < (31 * 60)) ) {
+
+    # Copy the snapshot image to the slideshow directory, renaming
+    # it with the Unix Epoch time, something like: "1239897417.png".
+    # Only copies the file if the source file is newer than the
+    # destination, which prevents copying the file again and again
+    # if it's the last file in your sequence.
+    #
+    `cp -u snapshot.png $output_dir/$number.png`;
+  }
+  sleep 30;
+}
+
+
diff --git a/scripts/split_gnis.bash b/scripts/split_gnis.bash
new file mode 100755
index 0000000..ee6292c
--- /dev/null
+++ b/scripts/split_gnis.bash
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# $Id: split_gnis.bash,v 1.2 2004/03/15 23:49:20 we7u Exp $
+
+# script created 14-MAR-04 by William Baguhn, kc9asi
+# This script is in the public domain.
+# Comments or suggestions to kc9asi at arrl.net
+
+# This script uses the "fromdos" program.  You may need to change
+# that line to use "dos2unix" instead, depending on what utilities
+# are available on your system.
+
+# This will take a GNIS datapoint file (typically for a whole state, 8+Mb),
+# break it down into smaller chunks (typically for a county, 30-200k)
+# it will also throw away the stupid trailing spaces and <CR>'s at EOL.
+
+# My short experiment: the state of wisconsin.
+# Started with a 12.5Mb file.
+# ended with 93 files, totaling 6.7Mb.
+# and, the data files run a whole lot faster, especially when zoomed in.
+
+test -e $1 || (echo Try calling $0 with a file as an argument.; exit)
+
+# field 4 isn't just counties, but it's an acceptable label
+# as it's usually counties
+cut -f4 -d, <$1 >$1.counties
+
+# remove duplicates (sort, uniq)
+# the cut here gets rid of any "quirks" because of commas that came earlier
+# than were expected, as cut doesn't recognize quoting depths
+sort <$1.counties | uniq | cut -f2 -d\" >$1.counties.uniq
+
+# now we want to replace spaces with periods, so that counties with
+# spaces in their names work appropriately both for grep and filenaming
+tr " " . <$1.counties.uniq >$1.counties
+rm $1.counties.uniq
+
+# OK, now we should have a file with a list of the various divisions
+# SO, split each one apart
+
+# the regexp for grep assures that we just get "county" and not county,
+# hopefully this will make more sensible breaks as county names are
+# sometimes found in other names as well.
+# (i.e. Grant county, and Grant Community Park)
+# the \"county\" should get the former, and ignore the latter.
+
+# the fromdos/sed call will drop any dead whitespace at the end of a line
+
+# the test/rm call will delete files if they are zero length.
+
+
+for foo in `cat $1.counties` ; do
+  rm -f $1.$foo
+  echo Extracting $foo
+  grep ,\"$foo\", $1 | fromdos | sed -e 's/[ ]*$//g' >>$1.$foo.gnis
+  test -s $1.$foo.gnis || rm $1.$foo.gnis
+done
+
+
+# clean up after ourselves
+rm $1.counties
diff --git a/scripts/split_gnis.pl b/scripts/split_gnis.pl
new file mode 100755
index 0000000..33dc07f
--- /dev/null
+++ b/scripts/split_gnis.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl -w
+#
+# $Id: split_gnis.pl,v 1.3 2005/01/02 05:26:23 tvrusso Exp $
+#
+# split_gnis.pl -- 2004 Mar 15 -- jmt at twilley.org
+
+# This script is designed to break large GNIS datapoint files
+# into smaller chunks and will dispose of extra whitespace properly.
+
+# It is based on a bash script written by kc9asi at arrl.net.
+
+# The filenames used as input should be put on the command line.
+
+
+while (<>) {
+  next unless /[A-Z][a-z]/;
+  s/\s+$//;
+  my $line = $_;
+  my @fields = split /\|/, $line;
+#  print "Fields is @fields\n";
+  # key is "state county"
+  my $key = $fields[1] . " " . $fields[4];
+  $key =~ s/ /_/g;
+  push @{$county{$key}}, $line;
+}
+
+foreach $elem (keys %county) {
+  my $name = $elem . ".gnis";
+  open(OUT,">$name");
+  foreach $line (@{$county{$elem}}) {
+    print OUT $line, "\n";
+  }
+  close(OUT);
+}
+
diff --git a/scripts/test_coord.pl b/scripts/test_coord.pl
new file mode 100755
index 0000000..6c824f6
--- /dev/null
+++ b/scripts/test_coord.pl
@@ -0,0 +1,151 @@
+#!/usr/bin/perl -w
+
+
+# test_coord.pl:  Perl code to test out the Coordinate.pm
+# module.
+#
+# Copyright (C) 2000-2012  Curt Mills, WE7U
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+
+#
+# $Id: test_coord.pl,v 1.7 2012/11/01 18:57:19 we7u Exp $
+#
+#
+# TODO:
+# -----
+#
+
+
+#------------------------------------------------------------------------------------------------
+
+use lib "/usr/local/lib";
+use Coordinate;		# Snag WE7U's Coordinate module
+
+
+&test();
+
+
+#
+# Routine for testing out the module.
+#
+# Need to add in tests for each method and object type.
+#
+sub test
+{
+  my $to_WGS84 = 0;
+  my $from_WGS84 = 1;
+
+  my $position = Coordinate->new();
+
+
+  $position->latitude(48.125);
+  $position->longitude(-122.500);
+  $position->datum("NAD27 CONUS MEAN:W of Mississippi/Except Louisiana/Minnesota/Missouri"); 	# Datum
+
+
+  printf("Starting position(Lat, Long):  %s   %s\n",
+	$position->latitude(),
+	$position->longitude() );
+
+  $position->degrees_minutes_seconds();		# Convert to DD MM SS format
+  printf("Starting position(Lat, Long):  %s   %s\n",
+	$position->formatted_latitude(),
+	$position->formatted_longitude() );
+
+  $position->lat_lon_to_utm();
+  printf("Calculated UTM position(Easting, Northing, Zone):  %f   %f   %s\n",
+	$position->easting(),
+	$position->northing(),
+	$position->zone() );
+	
+  $position->utm_to_lat_lon();
+  printf("Calculated Lat, Long position(Lat, Long):  %f   %f\n",
+	$position->latitude(),
+	$position->longitude() );
+
+
+  print "Changing from NAD27 to WGS84 datum...\n";
+  $position = $position->datum_shift_to_wgs84();
+  printf("Calculated Lat, Long position(Lat, Long):  %f   %f\n",
+        $position->latitude(),
+        $position->longitude() );
+
+  $position->degrees_minutes_seconds();		# Convert to DD MM SS
+  printf("Calculated Lat, Long position(Lat, Long):  %s   %s\n",
+	$position->formatted_latitude(),
+	$position->formatted_longitude() );
+
+  print "Changing from WGS84 to NAD27 datum...\n";
+  $position = $position->datum_shift_from_wgs84_to( "NAD27 CONUS MEAN:W of Mississippi/Except Louisiana/Minnesota/Missouri" );
+  printf("Calculated Lat, Long position(Lat, Long):  %f   %f\n",
+        $position->latitude(),
+        $position->longitude() );
+
+  print "\n0\n";
+  my $temp = CoordinateFormat->new( "0" );
+  printf("        decimal_degrees: %s\n",   $temp->decimal_degrees( ) );
+  printf("        degrees_minutes: %s\n",   $temp->degrees_minutes( ) );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds() );
+
+  print "180\n";
+  $temp->raw( "180" );
+  printf("        decimal_degrees: %s\n",   $temp->decimal_degrees( "180") );
+  printf("        degrees_minutes: %s\n",   $temp->degrees_minutes( "180") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180") );
+
+  print "180 30\n";
+  $temp->raw( "180 30" );
+  printf("        decimal_degrees: %s\n",   $temp->decimal_degrees( "180 30") );
+  printf("        degrees_minutes: %s\n",   $temp->degrees_minutes( "180 30") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30") );
+
+  print "180.50\n";
+  $temp->raw( "180.50" );
+  printf("        decimal_degrees: %s\n",   $temp->decimal_degrees( "180.50") );
+  printf("        degrees_minutes: %s\n",   $temp->degrees_minutes( "180.50") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180.50") );
+
+  $temp->raw( "180 30.50" );
+  print "180 30.50\n";
+  printf("        decimal_degrees: %s\n",   $temp->decimal_degrees( "180 30.50") );
+  printf("        degrees_minutes: %s\n",   $temp->degrees_minutes( "180 30.50") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30.50") );
+
+  $temp->raw( "180 30 30" );
+  print "180 30 30\n";
+  printf("        decimal_degrees: %s\n",   $temp->decimal_degrees( "180 30 30") );
+  printf("        degrees_minutes: %s\n",   $temp->degrees_minutes( "180 30 30") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30 30") );
+
+  $temp->raw( "180 30 30.5" );
+  print "180 30 30.5\n";
+  printf("        decimal_degrees: %s\n", $temp->decimal_degrees("180 30 30.5") );
+  printf("        degrees_minutes: %s\n", $temp->degrees_minutes("180 30 30.5") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("180 30 30.5") );
+
+  $temp->raw( "-180 30 30.5" );
+  print "-180 30 30.5\n";
+  printf("        decimal_degrees: %s\n", $temp->decimal_degrees("-180 30 30.5") );
+  printf("        degrees_minutes: %s\n", $temp->degrees_minutes("-180 30 30.5") );
+  printf("degrees_minutes_seconds: %s\n\n", $temp->degrees_minutes_seconds("-180 30 30.5") );
+
+  EllipsoidTable->enumerate();
+  DatumTable->enumerate();
+}
+
+
diff --git a/scripts/toporama250k.pl b/scripts/toporama250k.pl
new file mode 100755
index 0000000..06ff56d
--- /dev/null
+++ b/scripts/toporama250k.pl
@@ -0,0 +1,276 @@
+#!/usr/bin/perl -W
+
+
+# $Id: toporama250k.pl,v 1.13 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2004-2012 The Xastir Group.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+
+
+# This will retrieve the 1:250k map images from the "Department of
+# Natural Resources Geomatics Canada" site.  These are topographic
+# map files for the whole of Canada!
+#
+#
+# - "cd /usr/local/share/xastir/maps"
+#
+# - Assure you have write privileges in the directory above either
+#   by becoming root using the "su" command, using "sudo", or
+#   temporarily changing ownership and/or privileges on the
+#   "maps" directory.
+#
+# - "/usr/local/lib/xastir/toporama250k.pl"
+#
+# - The script will create/populate this directory heirarchy:
+#   .../maps/toporama/images/
+#   .../maps/toporama/images/b250k/
+#
+# - Move/rename directories/contents as you wish.
+#
+# - In Xastir:  "Map->Configure->Index: Reindex ALL Maps!"
+#
+#
+# Note that the same map files are also available from Steve Dimse's
+# site:  "http://mm.aprs.net/maps/geo/toporama"
+#
+#
+# Code for this script contributed by Adi Linden, VA3ADI.
+# Modifications for latitudes above 67 degrees north contributed by Tom Tessier, VE4TRT
+
+
+
+# Create the "toporama" directory
+mkdir "toporama";
+chdir "toporama";
+
+
+# Retrieve the 1:250,000 map images.  Skipping those that we've
+# already downloaded.
+`wget -nv -np -nH -N -r -m -l 0 -T 10 http://toporama.cits.rncan.gc.ca/images/b250k/`;
+
+
+# Remove index.html files
+`rm -rf \`find ./images -type f -name index.html\*\``;
+# Remove *.asc files
+`rm -rf \`find ./images -type f -name \*.asc\``;
+
+
+
+# Define some stuff
+$base_dir = "images/b250k";
+
+# This defines the top left corner of the 0 grid up to 67 degrees north latitude. 
+$basex = '-56';
+$basey = '44';
+%offsetx = ( 'a'  => 3,
+             'b'  => 2,
+             'c'  => 1,
+             'd'  => 0,
+             'e'  => 0,
+             'f'  => 1,
+             'g'  => 2,
+             'h'  => 3,
+             'i'  => 3,
+             'j'  => 2,
+             'k'  => 1,
+             'l'  => 0,
+             'm'  => 0,
+             'n'  => 1,
+             'o'  => 2,
+             'p'  => 3,
+             '1'  => 3,
+             '2'  => 2,
+             '3'  => 1,
+             '4'  => 0,
+             '5'  => 0,
+             '6'  => 1,
+             '7'  => 2,
+             '8'  => 3,
+             '9'  => 3,
+             '10' => 2,
+             '11' => 1,
+             '12' => 0,
+             '13' => 0,
+             '14' => 1,
+             '15' => 2,
+             '16' => 3 );
+%offsety = ( 'a'  => 3,
+             'b'  => 3,
+             'c'  => 3,
+             'd'  => 3,
+             'e'  => 2,
+             'f'  => 2,
+             'g'  => 2,
+             'h'  => 2,
+             'i'  => 1,
+             'j'  => 1,
+             'k'  => 1,
+             'l'  => 1,
+             'm'  => 0,
+             'n'  => 0,
+             'o'  => 0,
+             'p'  => 0,
+             '1'  => 3,
+             '2'  => 3,
+             '3'  => 3,
+             '4'  => 3,
+             '5'  => 2,
+             '6'  => 2,
+             '7'  => 2,
+             '8'  => 2,
+             '9'  => 1,
+             '10' => 1,
+             '11' => 1,
+             '12' => 1,
+             '13' => 0,
+             '14' => 0,
+             '15' => 0,
+             '16' => 0 );
+
+# This defines the top left corner of the 0 grid between 68 and 84 degrees north latitude.
+%offsetx68 = ( 'a'  => 4,
+             'b'  => 0,
+             'c'  => 0,
+             'd'  => 4,
+             'e'  => 4,
+             'f'  => 0,
+             'g'  => 0,
+             'h'  => 4,
+             '1'  => 4,
+             '2'  => 0,
+             '3'  => 0,
+             '4'  => 4,
+             '5'  => 4,
+             '6'  => 0,
+             '7'  => 0,
+             '8'  => 4 );
+%offsety68 = ( 'a'  => 3,
+             'b'  => 3,
+             'c'  => 2,
+             'd'  => 2,
+             'e'  => 1,
+             'f'  => 1,
+             'g'  => 0,
+             'h'  => 0,
+             '1'  => 3,
+             '2'  => 3,
+             '3'  => 2,
+             '4'  => 2,
+             '5'  => 1,
+             '6'  => 1,
+             '7'  => 0,
+             '8'  => 0 );
+
+#def
+
+use File::Find;
+
+print "Writing .geo files\n";
+ 
+find(\&process, $base_dir);
+
+print "\nDone.\n";
+
+
+
+# Run for each file found
+sub process
+{
+    # Only look for .gif files
+    if ( /.gif$/ ) {
+        
+        # Get the map sheet designation from the file name
+        $file = "$_";
+        $grida = substr($file, 0, 3);
+        $gridb = substr($file, 3, 1);
+	$hilat = substr($file, 2, 1);
+
+	# .geo calculations for lattitudes greater than 78 degrees north latitude.
+        if ( $grida > 119 ) {
+ 
+           # Calculate top left coordinates of the map sheet
+            use integer;
+            $topx = $basex - ((($grida/10) +10 ) / 22 * 16) + $offsetx68{$gridb} * 2; 
+            $topy = 84 - $offsety68{$gridb} * 1;
+            $botx = $topx + 8;
+            $boty = $topy - 2;
+
+            # Create the output file
+            $out = substr($file, 0, 4) . ".geo";
+            open (OUT, ">$out") or die "Can't open $OUT: $!\n";
+            print OUT "# Automatically created by toporama250k.pl\n";
+            print OUT "FILENAME\t$file\n";
+            print OUT "#\t\tx\ty\tlon\tlat\n";
+            print OUT "TIEPOINT\t0\t0\t$topx\t$topy\n";
+            print OUT "TIEPOINT\t6399\t1599\t$botx\t$boty\n";
+            print OUT "IMAGESIZE\t6400\t1600\n";
+            close OUT;
+
+            print ".";
+            next;
+        }
+
+	# .geo calculations for lattitudes between 68 and 78 degrees north latitude.
+	if ( $hilat > 6 ) {
+
+            # Calculate top left coordinates of the map sheet
+            use integer;
+            $topx = $basex - $grida / 10 * 8 + $offsetx68{$gridb} * 1; 
+            $topy = $basey + ($grida % 10) * 4 - $offsety68{$gridb} * 1;
+            $botx = $topx + 4;
+            $boty = $topy - 1;
+
+            # Create the output file
+            $out = substr($file, 0, 4) . ".geo";
+            open (OUT, ">$out") or die "Can't open $OUT: $!\n";
+            print OUT "# Automatically created by toporama250k.pl\n";
+            print OUT "FILENAME\t$file\n";
+            print OUT "#\t\tx\ty\tlon\tlat\n";
+            print OUT "TIEPOINT\t0\t0\t$topx\t$topy\n";
+            print OUT "TIEPOINT\t6399\t1599\t$botx\t$boty\n";
+            print OUT "IMAGESIZE\t6400\t1600\n";
+            close OUT;
+
+            print ".";
+	    next;
+
+	}
+
+        # Calculate top left coordinates of the map sheet
+        use integer;
+        $topx = $basex - $grida / 10 * 8 + $offsetx{$gridb} * 2; 
+        $topy = $basey + ($grida % 10) * 4 - $offsety{$gridb} * 1;
+        $botx = $topx + 2;
+        $boty = $topy - 1;
+
+        # Create the output file
+        $out = substr($file, 0, 4) . ".geo";
+        open (OUT, ">$out") or die "Can't open $OUT: $!\n";
+        print OUT "# Automatically created by toporama250k.pl\n";
+        print OUT "FILENAME\t$file\n";
+        print OUT "#\t\tx\ty\tlon\tlat\n";
+        print OUT "TIEPOINT\t0\t0\t$topx\t$topy\n";
+        print OUT "TIEPOINT\t3199\t1599\t$botx\t$boty\n";
+        print OUT "IMAGESIZE\t3200\t1600\n";
+        close OUT;
+
+        print ".";
+    }
+        
+}
diff --git a/scripts/toporama50k.pl b/scripts/toporama50k.pl
new file mode 100755
index 0000000..a789be8
--- /dev/null
+++ b/scripts/toporama50k.pl
@@ -0,0 +1,195 @@
+#!/usr/bin/perl -W
+
+# $Id: toporama50k.pl,v 1.12 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2004-2012 The Xastir Group.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# Look at the README for more information on the program.
+
+
+# This will retrieve the 1:50k map images from the "Department of
+# Natural Resources Geomatics Canada" site.  These are topographic
+# map files for the whole of Canada!
+#
+#
+# - "cd /usr/local/share/xastir/maps"
+#
+# - Assure you have write privileges in the directory above either
+#   by becoming root using the "su" command, using "sudo", or
+#   temporarily changing ownership and/or privileges on the
+#   "maps" directory.
+#
+# - "/usr/local/lib/xastir/toporama50k.pl"
+#
+# - The script will create/populate this directory heirarchy:
+#   .../maps/toporama/images/
+#   .../maps/toporama/images/b50k/
+#
+# - Move/rename directories/contents as you see fit.
+#
+# - In Xastir:  "Map->Configure->Index: Reindex ALL Maps!"
+#
+#
+# Note that the same map files are also available from Steve Dimse's
+# site:  "http://mm.aprs.net/maps/geo/toporama"
+#
+#
+# Code for this script contributed by Adi Linden, VA3ADI.
+
+
+
+# Create the "toporama" directory
+mkdir "toporama";
+chdir "toporama";
+
+
+# Retrieve the 1:50,000 map images.  Skipping those that we've
+# already downloaded.
+`wget -nv -np -nH -N -r -m -l 0 -T 10 http://toporama.cits.rncan.gc.ca/images/b50k/`;
+
+
+# Remove index.html files
+`rm -rf \`find ./images -type f -name index.html\*\``;
+# Remove *.asc files
+`rm -rf \`find ./images -type f -name \*.asc\``;
+
+
+# Define some stuff
+$base_dir = "images/b50k";
+
+# This defines the top left corner of the 0 grid. 
+$basex = '-56';
+$basey = '44';
+%offsetx = ( 'a'  => 3,
+             'b'  => 2,
+             'c'  => 1,
+             'd'  => 0,
+             'e'  => 0,
+             'f'  => 1,
+             'g'  => 2,
+             'h'  => 3,
+             'i'  => 3,
+             'j'  => 2,
+             'k'  => 1,
+             'l'  => 0,
+             'm'  => 0,
+             'n'  => 1,
+             'o'  => 2,
+             'p'  => 3,
+             '01' => 3,
+             '02' => 2,
+             '03' => 1,
+             '04' => 0,
+             '05' => 0,
+             '06' => 1,
+             '07' => 2,
+             '08' => 3,
+             '09' => 3,
+             '10' => 2,
+             '11' => 1,
+             '12' => 0,
+             '13' => 0,
+             '14' => 1,
+             '15' => 2,
+             '16' => 3 );
+%offsety = ( 'a'  => 3,
+             'b'  => 3,
+             'c'  => 3,
+             'd'  => 3,
+             'e'  => 2,
+             'f'  => 2,
+             'g'  => 2,
+             'h'  => 2,
+             'i'  => 1,
+             'j'  => 1,
+             'k'  => 1,
+             'l'  => 1,
+             'm'  => 0,
+             'n'  => 0,
+             'o'  => 0,
+             'p'  => 0,
+             '01' => 3,
+             '02' => 3,
+             '03' => 3,
+             '04' => 3,
+             '05' => 2,
+             '06' => 2,
+             '07' => 2,
+             '08' => 2,
+             '09' => 1,
+             '10' => 1,
+             '11' => 1,
+             '12' => 1,
+             '13' => 0,
+             '14' => 0,
+             '15' => 0,
+             '16' => 0 );
+
+use File::Find;
+
+print "Writing .geo files\n";
+
+find(\&process, $base_dir);
+
+print "\nDone.\n";
+
+
+
+# Run for each file found
+sub process
+{
+    # Only look for .gif files
+    if ( /.gif$/ ) {
+        
+        # Get the map sheet designation from the file name
+        $file = "$_";
+        $grida = substr($file, 0, 3);
+        $gridb = substr($file, 3, 1);
+        $gridc = substr($file, 4, 2);
+
+        if ( $grida > 119 ) {
+            next;
+        }
+
+        # Calculate top left coordinates of the map sheet
+        use integer;
+        $topx = $basex - $grida / 10 * 8 + $offsetx{$gridb} * 2; 
+        $topy = $basey + ($grida % 10) * 4 - $offsety{$gridb} * 1;
+        no integer;
+        $topx = $topx + $offsetx{$gridc} * 0.5;
+        $topy = $topy - $offsety{$gridc} * 0.25;
+        $botx = $topx + 0.5;
+        $boty = $topy - 0.25;
+
+        # Create the output file
+        $out = substr($file, 0, 6) . ".geo";
+        open (OUT, ">$out") or die "Can't open $OUT: $!\n";
+        print OUT "# Automatically created by toporama50k.pl\n";
+        print OUT "FILENAME\t$file\n";
+        print OUT "#\t\tx\ty\tlon\tlat\n";
+        print OUT "TIEPOINT\t0\t0\t$topx\t$topy\n";
+        print OUT "TIEPOINT\t3199\t1599\t$botx\t$boty\n";
+        print OUT "IMAGESIZE\t3200\t1600\n";
+        close OUT;
+
+        print ".";
+    }
+        
+}
+
+
diff --git a/scripts/track-get.pl b/scripts/track-get.pl
new file mode 100755
index 0000000..5ed4589
--- /dev/null
+++ b/scripts/track-get.pl
@@ -0,0 +1,163 @@
+#!/usr/bin/perl
+
+# $Id: track-get.pl,v 1.5 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2000-2012  Curt Mills, WE7U
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+
+# This script will ask for an item designator, then create a file
+# with that name + ".log" in the ~/.xastir/logs directory.  The
+# file will contain APRS items created from the downloaded Garmin
+# tracklog.  Reading that log file with Xastir will result in an
+# object with a track being displayed on the map screen.
+
+# You may wish to bump up MAX_TRACKS in db.h to 1024 in order to see
+# the entire log, but be careful with Xastir's memory image growing
+# too fast if you're connected to the 'net after making this change.
+
+# This script uses the GPS::Garmin module which can be obtained
+# from http://sourceforge.net/projects/perl-gps/
+
+
+use GPS::Garmin;
+use IO::File;
+
+
+# Flush STDOUT
+$| = 1;
+
+
+# Hard-coded "from" callsign name.  This becomes the "sending"
+# callsign for the APRS Items.
+$from = "SAR";
+
+
+# Ask for the item name.  This will turn into the 3-9 character APRS
+# item name.
+printf("\n\nEnter item designator: Length 1-9, all except '!' and '_' allowed, case respected:\n\n");
+printf("\t123456789\n\t");
+$name = <>;
+chomp $name;
+if (length($name) < 1) {
+  die "Must be at least one character!\n";
+}
+if (length($name) > 9) {
+  $name =~ s/(.{9}).*/\1/;  # Terminate it at 9 chars
+}
+if (length($name) < 3) {
+  $name = $name . "   ";    # Pad the name with spaces
+  $name =~ s/(.{3}).*/\1/;  # Terminate it at 3 chars
+}
+
+# We need to enforce the naming restrictions for APRS Items.  '!'
+# and '_' are not allowed, anything else that's printable ASCII is
+# ok.
+ at j = split(//, $name);
+for ($i = 0; $i < length($name); $i++) {
+#printf("$i  $j[$i]\n");
+  if (     ($j[$i] lt ' ')
+        || ($j[$i] gt '~')
+        || ($j[$i] eq '!')
+        || ($j[$i] eq '_') ) {
+    $j[$i] = ' ';
+  }
+}
+$name = join("", at j);
+
+$filename = "~/.xastir/logs/$name.log";
+
+# Get rid of spaces in the filename
+$filename =~ s/\s+//g;
+
+# Expand the tilde into the home directory
+$filename =~ s{ ^ ~ ( [^/]* ) }
+              { $1
+                    ? (getpwnam($1))[7]
+                    : ( $ENV{HOME} || $ENV{LOGDIR}
+                         || (getpwuid($>))[7]
+                      )
+}ex;
+
+printf("\nThe item designator will be: ($name)\n");
+printf("The output filename will be: ($filename)\n\n");
+printf("Connect Garmin GPS to /dev/ttyS0 (COM1), set it to Garmin/Garmin mode.\n");
+printf("Press <ENTER> to proceed with download, Ctrl-C to abort\n");
+<>;
+
+
+# Create a file to hold the data
+$output = IO::File->new("> $filename")
+  or die "Couldn't open $filename for writing: $!\n";
+
+
+$gps = new GPS::Garmin( 'Port' => '/dev/ttyS0',
+                       'Baud' => 9600,
+                      ) or die "Unable to connect to receiver: $!";
+
+
+# Transfer trackpoints:
+$i = 0;
+$gps->prepare_transfer("trk");
+while ($gps->records)
+{
+  ($lat,$lon,$time) = $gps->grab;
+#  printf("%f %f %d\n",$lat,$lon,$time);
+  if ($lon < 0) {
+    $londeg = sprintf("%d",-$lon);
+    $lonmin = (-$lon - $londeg) * 60;
+    $lonchar = "W";
+  }
+  else {
+    $londeg = sprintf("%d",$lon);
+    $lonchar = "E";
+    $lonmin = ($lon - $londeg) * 60;
+  }
+  if ($lat < 0) {
+    $latdeg = sprintf("%d",-$lat);
+    $latmin = (-$lat - $latdeg) * 60;
+    $latchar = "S";
+  }
+  else {
+    $latdeg = sprintf("%d",$lat);
+    $latmin = ($lat - $latdeg) * 60;
+    $latchar = "N";
+  }
+
+  # Write an APRS Item for each trackpoint
+  printf($output "%s>APRS:)%s!%02d%05.2f%s/%03d%05.2f%s%s\n",
+    $from,
+    $name,
+    $latdeg,
+    $latmin,
+    $latchar,
+    $londeg,
+    $lonmin,
+    $lonchar,
+    "/");
+
+  if (! ($i % 10) ) {
+    printf("$i ");
+  }
+  $i++;
+}
+
+printf("\n\nThe data has been saved in: ($filename)\n");
+printf("Please open this logfile with Xastir to display the track\n");
+printf("!!!Remember to set your GPS back to NMEA mode for APRS!!!\n");
+
+
diff --git a/scripts/update_langfile.pl b/scripts/update_langfile.pl
new file mode 100755
index 0000000..5531b2f
--- /dev/null
+++ b/scripts/update_langfile.pl
@@ -0,0 +1,117 @@
+#!/usr/bin/perl -w
+# $Id: update_langfile.pl,v 1.2 2002/02/12 01:27:39 dk7in Exp $
+
+# Update utility for XASTIR language files                  17.04.2001
+#  Copyright (C) 2001 Rolf Bleher                  http://www.dk7in.de
+
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#  see file COPYING for details
+                                                                                
+#--------------------------------------------------------------------------
+
+# This program adds missing entries to the translated language files and
+# deletes obsolete entries.
+# If a translated comment before an entry block is found it will be preserved.
+# There might be problems with the comment with a changed block sequence.
+# I assume that you start it in the directory with the language files,
+# call it with the translated language file as parameter.
+
+# DK7IN: for now it assumes that the language files reside
+#        in the current directory
+
+#--------------------------------------------------------------------------
+$LF1   = "language-English.sys";        # original language file
+$LF2   = "language-German.sys";         # translated language file
+$LFOUT = "language-new.sys";            # modified translated language file
+if (@ARGV) {
+    $LF2 = shift @ARGV;
+}
+#--------------------------------------------------------------------------
+open(IN1,$LF1)      or die "ERROR: could not open $LF1!\n";
+open(IN2,$LF2)      or die "ERROR: could not open $LF2!\n";
+open(OUT,">$LFOUT") or die "ERROR: could not write to $LFOUT!\n";
+#--------------------------------------------------------------------------
+%token = ();                                    # translated tokens
+ at cmt1  = ();                                    # original comment
+ at cmt2  = ();                                    # translated comment
+
+# collect all available translated tokens
+while (<IN2>) {
+    next if (/^#/);                             # skip comment lines
+    if (/^([A-Z]+[0-9]+)(|.+|.?|.*)$/) {
+        $token{$1} = $2;                        # store translated text entry
+    }
+}
+
+# process language file
+while (<IN1>) {                                 # original language file
+    if (/^#/) {                                 # comment line
+        push(@cmt1,$_);                         # store comment
+    } else {
+        if (/^([A-Z]+)([0-9]+)(|.+|.?|.*)$/) {   # data line
+            $name = $1;
+            $numb = $2;
+            $arg  = $3;
+
+            if (@cmt1) {                        # pending comment
+                                                # try to find the translation
+                seek IN2, 0, 0;                 # reposition to begin of file
+                @cmt2  = ();                    # translated comment
+                $match = 0;
+                while (<IN2>) {
+                    $line = $_;
+                    if (/^([A-Z]+)([0-9]+)(|.+|.?|.*)$/) {
+                        $curr = $1;
+                        if ($name eq $curr) {   # same block
+                            $match = 1;
+                            last;
+                        } else {
+                            @cmt2 = ();         # clear wrong comment
+                        }
+                    } else {
+                        if (/^#/) {             # store comment
+                            push(@cmt2,$_);
+                        }
+                    }
+                }
+                if ($match && @cmt2) {          # found translated comment
+                    foreach $line (@cmt2) {
+                        print(OUT $line);       # translated comment
+                    }
+                } else {
+                    foreach $line (@cmt1) {
+                        print(OUT $line);       # original comment
+                    }
+                }
+                @cmt1 = ();
+            }
+
+            if ($token{$name.$numb}) {          # found translation
+                $arg = $token{$name.$numb};
+            }
+            printf(OUT "%s%s%s\n",$name,$numb,$arg);
+        } else {
+            print("ERROR: $_");                 # bad line format
+        }
+    }
+}
+close(IN1);
+close(IN2);
+close(OUT);
+
+exit;
+#--------------------------------------------------------------------------
+
diff --git a/scripts/values b/scripts/values
new file mode 100644
index 0000000..b0f7c27
--- /dev/null
+++ b/scripts/values
@@ -0,0 +1,2 @@
+#!/bin/sh
+prefix=/usr/local;
diff --git a/scripts/values.in b/scripts/values.in
new file mode 100644
index 0000000..a52ee4d
--- /dev/null
+++ b/scripts/values.in
@@ -0,0 +1,2 @@
+#!/bin/sh
+prefix=@prefix@;
diff --git a/scripts/values.pl b/scripts/values.pl
new file mode 100644
index 0000000..3362236
--- /dev/null
+++ b/scripts/values.pl
@@ -0,0 +1,8 @@
+#!/usr/bin/perl
+$prefix="/usr/local";
+
+=include for usage
+use File::Basename;
+$dirname=dirname($0);
+require ($dirname."/values.pl");
+
diff --git a/scripts/values.pl.in b/scripts/values.pl.in
new file mode 100644
index 0000000..5d66200
--- /dev/null
+++ b/scripts/values.pl.in
@@ -0,0 +1,8 @@
+#!/usr/bin/perl
+$prefix="@prefix@";
+
+=include for usage
+use File::Basename;
+$dirname=dirname($0);
+require ($dirname."/values.pl");
+
diff --git a/scripts/waypoint-get.pl b/scripts/waypoint-get.pl
new file mode 100755
index 0000000..18c33bf
--- /dev/null
+++ b/scripts/waypoint-get.pl
@@ -0,0 +1,165 @@
+#!/usr/bin/perl
+
+# $Id: waypoint-get.pl,v 1.4 2012/11/01 18:57:19 we7u Exp $
+
+# Copyright (C) 2000-2012  Curt Mills, WE7U
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+
+# This script will ask for a name, then create a file
+# with that name + ".log" in the ~/.xastir/logs directory.  The
+# file will contain APRS items created from the downloaded Garmin
+# waypoints.  Reading that log file with Xastir will result in one
+# item appearing on the map screen for each waypoint, labeled with
+# the name of that waypoint.
+
+# This script uses the GPS::Garmin module which can be obtained
+# from http://sourceforge.net/projects/perl-gps/
+
+
+use GPS::Garmin;
+use IO::File;
+
+
+# Flush STDOUT
+$| = 1;
+
+
+# Hard-coded "from" callsign name.  This becomes the "sending"
+# callsign for the APRS Items.
+$from = "SAR";
+
+
+# Ask for the name.  This gets changed into the complete log file name.
+printf("\n\nEnter name for file: '.log' will get added to the end:\n\n");
+$name = <>;
+chomp $name;
+if (length($name) < 1) {
+  die "Must be at least one character!\n";
+}
+
+$filename = "~/.xastir/logs/$name.log";
+
+# Get rid of spaces in the filename
+$filename =~ s/\s+//g;
+
+# Expand the tilde into the home directory
+$filename =~ s{ ^ ~ ( [^/]* ) }
+              { $1
+                    ? (getpwnam($1))[7]
+                    : ( $ENV{HOME} || $ENV{LOGDIR}
+                         || (getpwuid($>))[7]
+                      )
+}ex;
+
+printf("\nThe output filename will be: ($filename)\n\n");
+printf("Connect Garmin GPS to /dev/ttyS0 (COM1), set it to Garmin/Garmin mode.\n");
+printf("Press <ENTER> to proceed with download, Ctrl-C to abort\n");
+<>;
+
+
+# Create a file to hold the data
+$output = IO::File->new("> $filename")
+  or die "Couldn't open $filename for writing: $!\n";
+
+
+$gps = new GPS::Garmin( 'Port' => '/dev/ttyS0',
+                       'Baud' => 9600,
+                      ) or die "Unable to connect to receiver: $!";
+
+
+# Transfer waypoints:
+$i = 0;
+$gps->prepare_transfer("wpt");
+while ($gps->records)
+{
+  ($title,$lat,$lon,$desc) = $gps->grab;
+
+  #printf("%f\t%f\t%s\t%s\n",$lat,$lon,$desc,$title);
+
+  if ($lon < 0) {
+    $londeg = sprintf("%d",-$lon);
+    $lonmin = (-$lon - $londeg) * 60;
+    $lonchar = "W";
+  }
+  else {
+    $londeg = sprintf("%d",$lon);
+    $lonchar = "E";
+    $lonmin = ($lon - $londeg) * 60;
+  }
+  if ($lat < 0) {
+    $latdeg = sprintf("%d",-$lat);
+    $latmin = (-$lat - $latdeg) * 60;
+    $latchar = "S";
+  }
+  else {
+    $latdeg = sprintf("%d",$lat);
+    $latmin = ($lat - $latdeg) * 60;
+    $latchar = "N";
+  }
+
+  chomp $title;
+  if (length($title) < 1) {
+    die "Must be at least one character!\n";
+  }
+  if (length($title) > 9) {
+    $title =~ s/(.{9}).*/\1/;  # Terminate it at 9 chars
+  }
+  if (length($title) < 3) {
+    $title = $title . "   ";    # Pad the title with spaces
+    $title =~ s/(.{3}).*/\1/;  # Terminate it at 3 chars
+  }
+
+  # We need to enforce the naming restrictions for APRS Items.  '!'
+  # and '_' are not allowed, anything else that's printable ASCII is
+  # ok.
+  @j = split(//, $title);
+  for ($k = 0; $k < length($title); $k++) {
+  #printf("$k  $j[$k]\n");
+    if (     ($j[$k] lt ' ')
+          || ($j[$k] gt '~')
+          || ($j[$k] eq '!')
+          || ($j[$k] eq '_') ) {
+      $j[$k] = ' ';
+    }
+  }
+  $title = join("", at j);
+
+  # Write an APRS Item for each waypoint
+  printf($output "%s>APRS:)%s!%02d%05.2f%s/%03d%05.2f%s%s\n",
+    $from,
+    $title,
+    $latdeg,
+    $latmin,
+    $latchar,
+    $londeg,
+    $lonmin,
+    $lonchar,
+    "/");
+
+  if (! ($i % 10) ) {
+    printf("$i ");
+  }
+
+  $i++;
+}
+
+printf("\n\nThe data has been saved in: ($filename)\n");
+printf("Please open this logfile with Xastir to display the waypoints.\n");
+printf("!!!Remember to set your GPS back to NMEA mode for APRS!!!\n");
+
+
diff --git a/scripts/xastir-fixcfg.sh b/scripts/xastir-fixcfg.sh
new file mode 100755
index 0000000..f095add
--- /dev/null
+++ b/scripts/xastir-fixcfg.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# $Id: xastir-fixcfg.sh,v 1.12 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# fix up a user's .xastir/config/xastir.cnf to rewrite /usr/local/xastir
+# to ${prefix}/share/${name}.
+. `dirname $0`/values
+CNF=.xastir/config/xastir.cnf
+INDEX=.xastir/config/map_index.sys
+SELECT=.xastir/config/selected_maps.sys
+cd
+if [ -f $CNF ]; then
+    rm $INDEX
+    mv $CNF $CNF.backup
+    mv $SELECT $SELECT.backup
+    if [ $? -ne 0 ]; then
+	echo "$CNF: unable to rename!"
+	exit 1
+    fi
+    sed -e 's:/usr/local/xastir/:${prefix}/share/xastir/:' <$CNF.backup >$CNF
+    if [ $? -ne 0 ]; then
+	echo "$CNF: sed failed!"
+	mv $CNF.backup $CNF
+	exit 1
+    fi
+else
+    echo "No $CNF to edit"
+fi
+echo "Done.  Old config file is in $CNF.backup"
+exit 0
+
+
diff --git a/scripts/xastir-migrate.sh b/scripts/xastir-migrate.sh
new file mode 100755
index 0000000..5984ed5
--- /dev/null
+++ b/scripts/xastir-migrate.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# $Id: xastir-migrate.sh,v 1.12 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2003-2012  The Xastir Group
+#
+# migrate from old xastir USER FILES to new directory structure.
+# Stuff that was under /usr/local/xastir is now under ${prefix}/share/xastir/
+# fixed up the .xastir/config/xastir.cfg as well.
+# XXX Do we throw away the xastir non-user files (config, doc, help)?
+. `dirname $0`/values
+PREFIX=
+OLD=$PREFIX/usr/local/xastir
+NEW=$PREFIX${prefix}/share/xastir
+rr=0
+if [ -d $OLD ]; then
+        if [ ! -d $NEW ]; then
+	    (umask 022; mkdir -p $NEW)
+	fi
+	echo "Moving xastir user files"
+	echo "From: $OLD"
+	echo "  To: $NEW"
+	for i in Counties GNIS config doc fcc help maps sounds symbols
+        do
+	    if [ -d $OLD/$i ]; then
+		if [ -d $NEW/$i ]; then
+		    echo "$NEW/$i: destination directory already exists;  Overlaying files."
+		    (cd $OLD/$i; tar cf - .) | (cd $NEW/$i; tar xvfp -)
+		    r=$?
+		    if [ $r -ne 0 ]; then
+			echo Failed to move directory $i
+			rr=`expr $rr + $r`
+		    else
+			# clean up the source directory
+			rm -rf $OLD/$i
+		    fi
+		else
+		    # hope they are in the same FS!
+		    mv $OLD/$i $NEW/$i
+		    r=$?
+		    rr=`expr $rr + $r`
+		    if [ $r -ne 0 ]; then
+			echo Failed to move directory $i
+		    fi
+		fi
+	    else
+		echo "$OLD/$i: old directory not found."
+	    fi
+	done
+else
+        echo "$OLD: not found.  Nothing to migrate."
+fi
+if [ $rr -ne 0 ]; then
+    echo "WARNING: Some files/directories not moved.  Please check $OLD and $NEW"
+else
+    echo "No Errors"
+fi
+exit $rr
+
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..7d65623
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,103 @@
+# $Id: Makefile.am,v 1.53 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+bin_PROGRAMS = xastir xastir_udp_client testdbfawk
+
+SUBDIRS = @SUBRTREE@ @SUBSHP@
+DIST_SUBDIRS = rtree shapelib
+
+EXTRA_DIST=icon.xbm
+
+XASTIR_SRC = \
+    alert.c alert.h \
+    awk.c awk.h \
+    bulletin_gui.c bulletin_gui.h \
+    color.c color.h \
+    datum.c datum.h \
+    db.c database.h \
+    db_gis.c db_gis.h \
+    dbfawk.c dbfawk.h \
+    draw_symbols.c draw_symbols.h \
+    fcc_data.c fcc_data.h \
+    festival.c festival.h \
+    fetch_remote.c fetch_remote.h \
+    geo-find.c geo.h \
+    geocoder_gui.c \
+    gps.c gps.h \
+    hashtable.c hashtable_private.h hashtable.h \
+    hashtable_itr.c hashtable_itr.h \
+    hostname.c hostname.h \
+    igate.c igate.h \
+    interface.c interface.h \
+    interface_gui.c \
+    io-common.c io-mmap.c io.h \
+    lang.c lang.h \
+    leak_detection.h \
+    list_gui.c list_gui.h \
+    locate_gui.c \
+    location.c \
+    location_gui.c \
+    main.c main.h \
+    maps.c maps.h \
+    map_cache.c map_cache.h \
+    map_dos.c \
+    map_gdal.c \
+    map_geo.c \
+    map_gnis.c \
+    map_OSM.c map_OSM.h \
+    map_pop.c \
+    map_pdb.c \
+    map_shp.c \
+    map_tif.c \
+    map_tiger.c \
+    map_WMS.c \
+    messages.c messages.h \
+    messages_gui.c \
+    objects.h objects.c \
+    popup.h \
+    popup_gui.c \
+    rac_data.c rac_data.h \
+    rotated.c rotated.h \
+    rpl_malloc.c rpl_malloc.h \
+    shp_hash.c shp_hash.h \
+    snprintf.c snprintf.h \
+    sound.c symbols.h \
+    tile_mgmnt.c tile_mgmnt.h \
+    track_gui.c track_gui.h \
+    util.c util.h \
+    view_message_gui.c \
+    wx.c wx.h \
+    wx_gui.c \
+    x_spider.c x_spider.h \
+    xa_config.c xa_config.h \
+    xastir.h
+
+xastir_SOURCES = $(XASTIR_SRC) compiledate.c
+
+xastir_udp_client_SOURCES = \
+    xastir_udp_client.c
+
+testdbfawk_SOURCES = \
+    testdbfawk.c \
+    awk.c \
+    dbfawk.c \
+    rpl_malloc.c rpl_malloc.h
+
+compiledate.c: $(XASTIR_SRC)
+	rm -f compiledate.c compiledate.o
+	echo 'char compiledate[] = "'"Compiled: `date`"'";' > compiledate.c
+
+remove_compiledate:
+	rm -f compiledate.c compiledate.o
+
+xastir_LDADD=@LIBRTREE@ @LIBSHP@
+
+testdbfawk_LDADD=@LIBSHP@
+
+xastir_LINK=$(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+
+xastir_udp_client_LINK=$(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+
+testdbfawk_LINK=$(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..afb3439
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,837 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.53 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = xastir$(EXEEXT) xastir_udp_client$(EXEEXT) \
+	testdbfawk$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_testdbfawk_OBJECTS = testdbfawk.$(OBJEXT) awk.$(OBJEXT) \
+	dbfawk.$(OBJEXT) rpl_malloc.$(OBJEXT)
+testdbfawk_OBJECTS = $(am_testdbfawk_OBJECTS)
+testdbfawk_DEPENDENCIES =
+am__objects_1 = alert.$(OBJEXT) awk.$(OBJEXT) bulletin_gui.$(OBJEXT) \
+	color.$(OBJEXT) datum.$(OBJEXT) db.$(OBJEXT) db_gis.$(OBJEXT) \
+	dbfawk.$(OBJEXT) draw_symbols.$(OBJEXT) fcc_data.$(OBJEXT) \
+	festival.$(OBJEXT) fetch_remote.$(OBJEXT) geo-find.$(OBJEXT) \
+	geocoder_gui.$(OBJEXT) gps.$(OBJEXT) hashtable.$(OBJEXT) \
+	hashtable_itr.$(OBJEXT) hostname.$(OBJEXT) igate.$(OBJEXT) \
+	interface.$(OBJEXT) interface_gui.$(OBJEXT) \
+	io-common.$(OBJEXT) io-mmap.$(OBJEXT) lang.$(OBJEXT) \
+	list_gui.$(OBJEXT) locate_gui.$(OBJEXT) location.$(OBJEXT) \
+	location_gui.$(OBJEXT) main.$(OBJEXT) maps.$(OBJEXT) \
+	map_cache.$(OBJEXT) map_dos.$(OBJEXT) map_gdal.$(OBJEXT) \
+	map_geo.$(OBJEXT) map_gnis.$(OBJEXT) map_OSM.$(OBJEXT) \
+	map_pop.$(OBJEXT) map_pdb.$(OBJEXT) map_shp.$(OBJEXT) \
+	map_tif.$(OBJEXT) map_tiger.$(OBJEXT) map_WMS.$(OBJEXT) \
+	messages.$(OBJEXT) messages_gui.$(OBJEXT) objects.$(OBJEXT) \
+	popup_gui.$(OBJEXT) rac_data.$(OBJEXT) rotated.$(OBJEXT) \
+	rpl_malloc.$(OBJEXT) shp_hash.$(OBJEXT) snprintf.$(OBJEXT) \
+	sound.$(OBJEXT) tile_mgmnt.$(OBJEXT) track_gui.$(OBJEXT) \
+	util.$(OBJEXT) view_message_gui.$(OBJEXT) wx.$(OBJEXT) \
+	wx_gui.$(OBJEXT) x_spider.$(OBJEXT) xa_config.$(OBJEXT)
+am_xastir_OBJECTS = $(am__objects_1) compiledate.$(OBJEXT)
+xastir_OBJECTS = $(am_xastir_OBJECTS)
+xastir_DEPENDENCIES =
+am_xastir_udp_client_OBJECTS = xastir_udp_client.$(OBJEXT)
+xastir_udp_client_OBJECTS = $(am_xastir_udp_client_OBJECTS)
+xastir_udp_client_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(testdbfawk_SOURCES) $(xastir_SOURCES) \
+	$(xastir_udp_client_SOURCES)
+DIST_SOURCES = $(testdbfawk_SOURCES) $(xastir_SOURCES) \
+	$(xastir_udp_client_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+SUBDIRS = @SUBRTREE@ @SUBSHP@
+DIST_SUBDIRS = rtree shapelib
+EXTRA_DIST = icon.xbm
+XASTIR_SRC = \
+    alert.c alert.h \
+    awk.c awk.h \
+    bulletin_gui.c bulletin_gui.h \
+    color.c color.h \
+    datum.c datum.h \
+    db.c database.h \
+    db_gis.c db_gis.h \
+    dbfawk.c dbfawk.h \
+    draw_symbols.c draw_symbols.h \
+    fcc_data.c fcc_data.h \
+    festival.c festival.h \
+    fetch_remote.c fetch_remote.h \
+    geo-find.c geo.h \
+    geocoder_gui.c \
+    gps.c gps.h \
+    hashtable.c hashtable_private.h hashtable.h \
+    hashtable_itr.c hashtable_itr.h \
+    hostname.c hostname.h \
+    igate.c igate.h \
+    interface.c interface.h \
+    interface_gui.c \
+    io-common.c io-mmap.c io.h \
+    lang.c lang.h \
+    leak_detection.h \
+    list_gui.c list_gui.h \
+    locate_gui.c \
+    location.c \
+    location_gui.c \
+    main.c main.h \
+    maps.c maps.h \
+    map_cache.c map_cache.h \
+    map_dos.c \
+    map_gdal.c \
+    map_geo.c \
+    map_gnis.c \
+    map_OSM.c map_OSM.h \
+    map_pop.c \
+    map_pdb.c \
+    map_shp.c \
+    map_tif.c \
+    map_tiger.c \
+    map_WMS.c \
+    messages.c messages.h \
+    messages_gui.c \
+    objects.h objects.c \
+    popup.h \
+    popup_gui.c \
+    rac_data.c rac_data.h \
+    rotated.c rotated.h \
+    rpl_malloc.c rpl_malloc.h \
+    shp_hash.c shp_hash.h \
+    snprintf.c snprintf.h \
+    sound.c symbols.h \
+    tile_mgmnt.c tile_mgmnt.h \
+    track_gui.c track_gui.h \
+    util.c util.h \
+    view_message_gui.c \
+    wx.c wx.h \
+    wx_gui.c \
+    x_spider.c x_spider.h \
+    xa_config.c xa_config.h \
+    xastir.h
+
+xastir_SOURCES = $(XASTIR_SRC) compiledate.c
+xastir_udp_client_SOURCES = \
+    xastir_udp_client.c
+
+testdbfawk_SOURCES = \
+    testdbfawk.c \
+    awk.c \
+    dbfawk.c \
+    rpl_malloc.c rpl_malloc.h
+
+xastir_LDADD = @LIBRTREE@ @LIBSHP@
+testdbfawk_LDADD = @LIBSHP@
+xastir_LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+xastir_udp_client_LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+testdbfawk_LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	      echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	      $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+testdbfawk$(EXEEXT): $(testdbfawk_OBJECTS) $(testdbfawk_DEPENDENCIES) 
+	@rm -f testdbfawk$(EXEEXT)
+	$(testdbfawk_LINK) $(testdbfawk_OBJECTS) $(testdbfawk_LDADD) $(LIBS)
+xastir$(EXEEXT): $(xastir_OBJECTS) $(xastir_DEPENDENCIES) 
+	@rm -f xastir$(EXEEXT)
+	$(xastir_LINK) $(xastir_OBJECTS) $(xastir_LDADD) $(LIBS)
+xastir_udp_client$(EXEEXT): $(xastir_udp_client_OBJECTS) $(xastir_udp_client_DEPENDENCIES) 
+	@rm -f xastir_udp_client$(EXEEXT)
+	$(xastir_udp_client_LINK) $(xastir_udp_client_OBJECTS) $(xastir_udp_client_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/alert.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/awk.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bulletin_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/color.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/compiledate.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/datum.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/db.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/db_gis.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfawk.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/draw_symbols.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fcc_data.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/festival.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fetch_remote.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/geo-find.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/geocoder_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gps.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hashtable.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hashtable_itr.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hostname.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/igate.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/interface.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/interface_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/io-common.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/io-mmap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lang.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/list_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/locate_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/location.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/location_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_OSM.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_WMS.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_cache.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_dos.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_gdal.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_geo.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_gnis.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_pdb.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_pop.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_shp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_tif.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_tiger.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/maps.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/messages.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/messages_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/objects.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/popup_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rac_data.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rotated.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rpl_malloc.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shp_hash.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/snprintf.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sound.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/testdbfawk.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tile_mgmnt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/track_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/util.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/view_message_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wx.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wx_gui.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/x_spider.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xa_config.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xastir_udp_client.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic ctags ctags-recursive distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+	ps ps-am tags tags-recursive uninstall uninstall-am \
+	uninstall-binPROGRAMS
+
+
+compiledate.c: $(XASTIR_SRC)
+	rm -f compiledate.c compiledate.o
+	echo 'char compiledate[] = "'"Compiled: `date`"'";' > compiledate.c
+
+remove_compiledate:
+	rm -f compiledate.c compiledate.o
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/alert.c b/src/alert.c
new file mode 100644
index 0000000..4a33099
--- /dev/null
+++ b/src/alert.c
@@ -0,0 +1,2275 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: alert.c,v 1.113 2012/03/02 20:26:50 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+
+// alert_redraw_on_update will cause refresh_image to get called.
+// alert_add_entry sets it.
+
+
+// In the alert structure, flags[] is size 16.  Only the first two
+// positions in the array are currently used.
+//
+// alert_entry.flags[0] // on_screen
+//          ?  Initial state or ready-to-recompute state
+//          -   Expired between 1 sec and 1 hour
+//          Y   Active alert within viewport
+//          N   Active alert outside viewport
+//
+// alert_entry.flags[1] // source
+//          DATA_VIA_TNC
+//          DATA_VIA_LOCAL
+//
+// alert_entry.to   alert_entry.alert_level
+//     CANCL            C   // Colors of alerts?????
+//     TEST             T   // Colors of alerts?????
+//     WARN             R   // Colors of alerts?????
+//     CIVIL            R   // Colors of alerts?????
+//     WATCH            Y   // Colors of alerts?????
+//     ADVIS            B   // Colors of alerts?????
+//     Other            G   // Colors of alerts?????
+//     Unset            ?
+//
+//
+// Here's how Xastir breaks down an alert into an alert struct:
+//
+// SFONPW>APRS::NWS-ADVIS:191700z,WIND,CA_Z007,CA_Z065, ALAMEDA AND CON & NAPA COUNTY {JDIAA
+// |----|       |-------| |-----| |--| |-----| |-----|                                 |-|
+//   |              |        |     |      |       |                                     |
+//  from            to       |     |    title   title                               issue_date
+//                           |  alert_tag
+//                        activity (expiration)
+//
+//
+// The code should also handle the case where the packet looks like
+// this (it's the same as the above packet except for no expiration
+// date):
+//
+// SFONPW>APRS::NWS-ADVIS:WIND,CA_Z007,CA_Z065, ALAMEDA AND CON & NAPA COUNTY {JDIAA
+//
+//
+// Expiration is then computed from the activity field.  Alert_level
+// is computed from "to" and/or "alert_tag".
+//
+//
+// Stuff from Dale, paraphrased by Curt:
+//
+// WATCH - weather of some type is possible or probable for a geographic 
+// area- at present I cannot do watches because they can cover huge areas 
+// with hundreds of counties across many states.  I have a prototye of a 
+// polygon generator - but that is a whole other can of worms
+// 
+// WARN - warning - Severe or dangerous weather is occuring or is about to 
+// occur in a geographical area.  This we do a pretty good job on output.
+// 
+// ADVIS - advisory - this can be trivial all the way to a tornado report.
+// If a tornado warning is issued and another tornado sighting happens in 
+// the same county/zone during the valid time of the first- the info is 
+// transmitted as an advisory.  Most of the time is is updates for other 
+// messages.
+// 
+// CANCL - cancelation- discussed in earlier e-mail
+// 
+// I would add CIVIL for terrorist  earthquake  catostrophic type stuff - 
+// the D7 and D&)) have special alarms built in so that a message to 
+// NWS-CIVIL would alert folks no matter what there filters are set for.
+// 
+//
+// The clue to which shapefile to use is in the 4th char in the
+// title (which is the first following an '_')
+//
+// ICTSVS>APRS::NWS-ADVIS:120145z,SEVERE_WEATHER,KS_Z091, {C14AA
+// TSASVR>APRS::NWS-WARN :120230z,SVRTSM,OK_C113,  OSAGE COUNTY {C16AA
+//
+// C = county file         (c_mmddyy.dbf)
+// A = County Warning File (w_mmddyy.dbf)
+// Z = Zone File           (z_mmddyy.dbf or mz_mmddyy.dbf)
+// F = Fire zone file      (fz_mmddyy.dbf)
+// A = Canadian Area       (a_mmddyy.dbf)
+// R = Canadian Region     (r_mmddyy.dbf)
+//
+// Alerts are comma-delimited on the air s.t. after the
+// :NWS-?????: the first field is the time in zulu (or local
+// with no 'z'), the 2nd is the warning type
+// (severe_thunderstorm etc.), the 3rd and up to 7th are s.t.
+// the first 2 letters are the state or marine zone (1st field
+// in both the county and zone .dbf files) followed by an
+// underline char '_', the area type as above (C, Z, or A),
+// then a 3 digit numerical code derived from:
+//
+// Counties:  the fips code (4th field in the .dbf)
+//
+// Zones: the zone number (2nd field in the .dbf)
+//
+// Marine Zones: have proper code in 1st field with addition of '_' in correct place.
+//
+// CWA: 2nd field has cwa-, these are always "CW_A" plus the cwa
+//
+// You must ignore anything after a space in the alert.
+//
+// We will probably want to add the "issue time" to the alert record
+// and parse that out if it's present.  Change the view dialog to
+// show expiration time, issue time, who the alert is apparently
+// from, and the stuff after the curly brace.  Some of that info
+// will be useful soon in a finger command to the weather server.
+//
+// New compressed-mode weather alert packets:
+//
+// LZKNPW>APRS::NWS-ADVIS:221000z,WINTER_STORM,ARZ003>007-012>016-021>025-030>034-037>047-052>057-062>069{LLSAA
+//
+// The trick is to step thru the data base contained in the
+// shapefiles to determine what areas to light up.  In the above
+// example read ">" as "thru" and "-" as "and".
+//
+// More from Dale:
+// It occurs to me you might need some insight into what shapefile to look
+// through for a zone/county. The current shape files are c_22mr02, 
+// z_16mr02, and mz21fe02.
+//
+// ICTSVS>APRS::NWS-ADVIS:120145z,SEVERE_WEATHER,KS_Z091, {C14AA
+// would be in z_ file
+//
+// TSASVR>APRS::NWS-WARN :120230z,SVRTSM,OK_C113,  OSAGE COUNTY {C16AA
+// would be in c_ file
+//
+// problem comes with marine warnings-
+//
+// AM,AN,GM,PZ,PK,PM,LS,LM,LH,LO,LE,SL will look like states, but will all 
+// come from the mz file.
+//
+// so AM_Z686 looks like a state zone, but is a marine zone.
+// Aprs Plus requires the exact file name to be specified - winaprs just 
+// looks for a file in the nwsshape folder starting c_ z_ and mz.  Someone 
+// in the middle of Kansas might not need the marine at all- but here I am 
+// closer to marine zones than land. The fact there is an index file for 
+// the shapes should help the speed in a lookup.
+//
+// More from Dale:
+// The CWA areas themselves were included for just one product- generally
+// called the "Hazardous Weather Outlook".  The idea was to be able to
+// click on your region and get a synopsis as a Skywarn Heads-up.  In
+// winaprs it turned out that you would get (unwanted) the CWA outline
+// instead of some other data about a specific station.  It makes more
+// sense to have three or 4 "home CWA'S" that are defined in the config
+// file - and have a dialog box to view the Hazardous WX Outlook and
+// watches and warnings just for that CWA.  One step futher- I assume there
+// is something that trips alarms when a warning is received for a county
+// or zone right around you - the cwa or cwa's of interest could be derived
+// from that if it already exists.  A long way to say don't worry about CWA
+// maps as far as watches/warnings.
+// 
+// I think the easy coding for determining which shapefile to use would
+// look like;
+// 
+// char sevenCharStr[8];  // seven character string in warning or derived
+// //                        from compressed string i. e. AL_Z001
+// 
+// if the 4th char == 'C' then use "c_shapefile"
+// if the 4th char == 'Z';
+//       if the first two char == 'AN' ||
+//       if the first two char == 'AM' ||
+//       if the first two char == 'GM' ||
+//       If the first two char == 'PZ' ||
+//       if the first two char == 'LH' ||
+//       if the first two char == 'LO' ||
+//       if the first two char == 'LS' ||          
+//       if the first two char == 'SL' ||
+//       if the first two char == 'LM' ||
+//            then use the "mzshapefile"
+//       else use the "z_shapefile"
+//
+// I am running out of time but that should be all there is to it- I
+// will send you a complete list of marine zones later today- I
+// think there are no more than 13 or 14 to search through - better
+// that the 54 "states"- could be hard coded.
+
+// We now  have fire weather alerts also.  From Dale:
+// "Ok I think we can use this to solve a problem with the Fire
+// Watches and Warnings taking over the map of someone not
+// interested.  Roger,  I had to take Fire warnings off the regular
+// aprs-is feeds and send it to firenet.us server only because of
+// complaints of the maps getting cluttered-- with data most people
+// didn't want. Even though the NWS sends "AZZ148" just as if it
+// were to be found in the z_mmddyy.dbf (warning zone) type file,
+// wxsvr knows it is coming out of a "Fire Weather" type product and
+// can substitute "AZF148" .  Client software (read xastir &
+// Ui-view) would know to look in the fireweather shapefile.  If
+// someone doesn't have the fire shapefile loaded, it would just be
+// ignored (I think)."
+
+
+// Found on the AWIPS web pages so far:
+// AWIPS Counties          C
+// County Warning Areas    A
+// Zone Forecast Areas     Z
+// Coastal Marine Zones    Z
+// Offshore Marine Zones   Z
+// High Seas Marine Zones  Z    (Says "Not for operational use")
+// Fire Weather Zones      FZ
+//
+// Don't forget about the Canadian Areas and Regions, which are
+// created by Dale Huguley from Environment Canada data.
+//
+//
+// AWIPS Counties:
+// -----------------------------
+// STATE        character   2
+// CWA          character   9
+// COUNTYNAME   character   24
+// FIPS         character   5
+// TIME_ZONE    character   2
+// FE_AREA      character   2
+// LON          numeric     10,5
+// LAT          numeric     9,5
+//
+//
+// County Warning Areas:
+// -----------------------------
+// WFO          character   3
+// CWA          character   3
+// LON          numeric     10,5
+// LAT          numeric     9,5
+//
+//
+// Zone Forecast Areas:
+// -----------------------------
+// STATE        character   2
+// ZONE         character   3
+// CWA          character   3
+// NAME         character   254
+// STATE_ZONE   character   5
+// TIME_ZONE    character   2
+// FE_AREA      character   2
+// LON          numeric     10,5
+// LAT          numeric     9,5
+//
+//
+// Coastal and Offshore Marine Zones:
+// ----------------------------------
+// ID           character   6
+// WFO          character   3
+// NAME         character   250
+// LON          numeric     10,5
+// LAT          numeric     9,5
+// WFO_AREA     character   200
+//
+//
+// High Seas Marine Zones:
+// -----------------------------
+// WFO          character   3
+// LON          numeric     10,5
+// LAT          numeric     9,5
+// HEADING      character   250
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef  HAVE_LOCALE_H
+#include <locale.h>
+#endif  // HAVE_LOCALE_H
+
+#ifdef  HAVE_LIBINTL_H
+#include <libintl.h>
+#define _(x)        gettext(x)
+#else   // HAVE_LIBINTL_H
+#define _(x)        (x)
+#endif  // HAVE_LIBINTL_H
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "alert.h"
+#include "util.h"
+#include "snprintf.h"
+#include "wx.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+
+// New method for weather alerts, using a hash
+//
+#define ALERT_HASH_SIZE 4096
+static struct hashtable *wx_alert_hash = NULL;
+
+int alert_redraw_on_update = 0;
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+// The following group of functions implement hash storage for
+// weather alerts.  This makes the code very fast, which is good
+// because we run through these alerts often.
+/////////////////////////////////////////////////////////////////////
+
+
+
+// Starting with an alert_entry, create a concatenated string
+// containing:
+//
+//   *) "From" callsign
+//   *) Zone
+//   *) First four chars after the '{' char (the "issue date" field
+//      plus one more character).
+//
+// These items should make the alert unique or nearly unique whether
+// it was received from the WXSVR software or from hand-entered
+// alerts.  WXSVR is where all of the machine-readable alerts come
+// from and is run by Dale Huguley.
+//
+// This function takes a mostly filled-in alert_entry and fills in
+// the unique_string variable portion with values from other
+// variables in the record.
+//
+void alert_fill_unique_string(alert_entry *alert) {
+    xastir_snprintf(alert->unique_string,
+        sizeof(alert->unique_string),
+        "%s%s%c%c%c%c",
+        alert->from,
+        alert->title,
+        alert->seq[0],
+        alert->seq[1],
+        alert->seq[2],
+        alert->seq[3]);
+
+    //fprintf(stderr,"'%s'\t'%s'\t'%s'\n", alert->from, alert->title, alert->seq);
+//    fprintf(stderr,"Unique string:'%s'\n", alert->unique_string);
+}
+
+
+
+
+
+// Add the chars (multiplied by a function of their index number to
+// weight them) then truncate the final number to ALERT_HASH_SIZE.
+// This should spread them nicely over the entire hash table.
+//
+unsigned int wx_alert_hash_from_key(void *key) {
+    alert_entry *temp = key;
+    char *jj = temp->unique_string;
+    unsigned int hash = 1;
+    int ii = 1;
+
+    while (*jj != '\0') {
+        hash = hash + ((unsigned int)*jj++ * ii);
+        ii += 4;
+    }
+
+    hash = hash % ALERT_HASH_SIZE;
+
+//fprintf(stderr,"%d\n", hash);
+
+    return ((unsigned int)hash);
+}
+
+
+
+
+
+// According to Dale Huguley the FROM callsign plus the first four
+// chars after the curly brace (at the end) should make the record
+// unique.  Whether or not CANCEL messages get assigned to the
+// proper live record is another matter.  They may, or may not match
+// using this scheme, but it's probably better than other schemes.
+// Multiple types of alerts can come out in the same message for the
+// same zone/county.  In this case the fourth character will change
+// from an 'A' to a 'B' or other char to denote the different
+// messages with the same FROM and timestamp chars.  This again
+// keeps each alert unique.
+//
+int wx_alert_keys_equal(void *key1, void *key2) {
+    alert_entry *t1 = key1;
+    alert_entry *t2 = key2;
+
+    // These fprintf's allow us to see how many cache hits we get
+    // and what the results were of the match.  If different
+    // unique_string's hash to the same value, we run through this
+    // compare once for each already-inserted record that also has
+    // the same hash vaue.
+//    fprintf(stderr,"Comparing %s to %s\t",(char *)key1,(char *)key2);
+
+    if (strlen((char *)t1->unique_string) == strlen((char *)t2->unique_string)
+            && strncmp((char *)t1->unique_string,
+                    (char *)t2->unique_string,
+                    strlen((char *)t1->unique_string))==0) {
+
+//        fprintf(stderr,"    match %s = %s\n", t1->unique_string, t2->unique_string);
+        return(1);
+    }
+    else {
+//        fprintf(stderr,"  no match\n");
+        return(0);
+    }
+}
+
+
+
+
+
+// Creates the wx_alert_hash if it doesn't exist yet.  If clobber is
+// non-zero, destroys any existing hash then creates a new one.
+//
+void init_wx_alert_hash(int clobber) {
+//    fprintf(stderr," Initializing wx_alert_hash \n");
+    // make sure we don't leak
+//fprintf(stderr,"init_wx_alert_hash\n");
+    if (wx_alert_hash) {
+//fprintf(stderr,"Already have one!\n");
+        if (clobber) {
+//fprintf(stderr,"Clobbering hash table\n");
+            hashtable_destroy(wx_alert_hash, 1);
+            wx_alert_hash = create_hashtable(ALERT_HASH_SIZE,
+                wx_alert_hash_from_key,
+                wx_alert_keys_equal);
+        }
+    }
+    else {
+//fprintf(stderr,"Creating hash table from scratch\n");
+        wx_alert_hash = create_hashtable(ALERT_HASH_SIZE,
+            wx_alert_hash_from_key,
+            wx_alert_keys_equal);
+    }
+}
+
+
+
+
+
+// Fetch an alert from the wx_alert_hash based on the from call
+// concatenated with the first four chars after the '{' character.
+// This concatenated string should be unique across weather alerts
+// if the alert came from the WXSVR.
+//
+// If it was a hand-entered alert, it won't have the '{' string at
+// the end.  In that case use the from call and zone concatenated
+// together instead for matching purposes.
+//
+alert_entry *get_wx_alert_from_hash(char *unique_string) {
+    alert_entry *result = NULL;
+
+    if (unique_string == NULL || *unique_string == '\0') {
+        fprintf(stderr,"Empty unique_string passed to get_wx_alert_from_hash()\n");
+        return(NULL);
+    }
+
+    if (!wx_alert_hash) {  // no table to search
+//fprintf(stderr,"Creating hash table\n");
+        init_wx_alert_hash(1); // so create one
+        return NULL;
+    }
+
+//fprintf(stderr,"   searching for %s...",unique_string);
+
+    result = hashtable_search(wx_alert_hash, unique_string);
+    return (result);
+}
+
+
+
+
+
+// Add a wx alert to the hash.
+// This function checks whether there already is something in the
+// hash table that matches.  If a match found, it skips the record,
+// else it inserts a new wx alert record into the hash.
+//
+// Unfortunately it appears that any unique_string that hashes to
+// the same value causes us to think it's a duplicate.
+//
+void add_wx_alert_to_hash(char *unique_string, alert_entry *alert_record) {
+    alert_entry *temp;  // alert_record
+    alert_entry *new_record;
+    char *new_unique_str;
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"add_wx_alert_to_hash start\n");
+
+    if (unique_string == NULL
+            || unique_string[0] == '\0'
+            || alert_record == NULL) {
+        if (debug_level & 2)
+            fprintf(stderr,"add_wx_alert_to_hash finish\n");
+        return;
+    }
+
+    if (!wx_alert_hash) {  // no table to add to
+//fprintf(stderr,"init_wx_alert_hash\n");
+        init_wx_alert_hash(1); // so create one
+    }
+
+    // Remove any matching entry to avoid duplicates
+    temp = hashtable_remove(wx_alert_hash, unique_string);
+    if (temp) { // If value found, free the storage space for it as
+                // the hashtable_remove function doesn't.  It does
+                // however remove the key (callsign) ok.
+        free(temp);
+    }
+
+//fprintf(stderr, "\t\t\tAdding %s...\n", unique_string);
+
+    // Allocate new space for the key and the record
+    new_unique_str = (char *)malloc(50);
+    CHECKMALLOC(new_unique_str);
+
+    new_record = (alert_entry*)malloc(sizeof(alert_entry));
+    CHECKMALLOC(new_record);
+
+    xastir_snprintf(new_unique_str, 50, "%s", unique_string);
+
+    memcpy(new_record, alert_record, sizeof(alert_entry));
+
+    //                    hash           title  alert_record
+    if (!hashtable_insert(wx_alert_hash, new_unique_str, new_record)) {
+        fprintf(stderr,"Insert failed on wx alert hash --- fatal\n");
+        free(new_unique_str);
+        free(new_record);
+//        exit(1);
+    }
+
+    // Yet another check to see whether hash insert/update worked
+    // properly
+    temp = get_wx_alert_from_hash(unique_string);
+    if (!temp) {
+        fprintf(stderr,"***Failed wx alert hash insert/update***\n");
+    }
+    else {
+//fprintf(stderr,"Current: %s -> %s\n",
+//    unique_string,
+//    temp);
+    }
+
+    if (debug_level & 2)
+        fprintf(stderr,"add_wx_alert_to_hash finish\n");
+}
+
+
+
+
+
+// Create the wx alert hash table iterator so that we can iterate
+// through the entire hash table and draw the alerts.
+//
+struct hashtable_itr *create_wx_alert_iterator(void) {
+
+    if (wx_alert_hash && hashtable_count(wx_alert_hash) > 0) {
+        return(hashtable_iterator(wx_alert_hash));
+    }
+    else {
+        return(NULL);
+    }
+}
+
+
+
+
+
+// Get the wx alert entry that the iterator is pointing to.  Advance
+// the iterator to the following wx alert.
+//
+alert_entry *get_next_wx_alert(struct hashtable_itr *iterator) {
+    alert_entry *temp = NULL;
+
+    if (wx_alert_hash
+            && iterator
+            && hashtable_count(wx_alert_hash) > 0) {
+
+        // Get record
+        temp = hashtable_iterator_value(iterator);
+
+        // Advance to the next record
+        hashtable_iterator_advance(iterator);
+    }
+    return(temp);
+}
+
+
+
+
+// alert_print_list()
+//
+// Debug routine.  Currently attached to the Test() function in
+// main.c, but the button in the file menu is normally grey'ed out.
+// This function prints the current weather alert list out to the
+// xterm.
+//
+void alert_print_list(void) {
+
+}
+
+
+
+
+
+// Needed by alert_expire() below
+static time_t last_alert_expire = 0;
+
+
+
+// alert_expire()
+//
+// Function which iterates through the wx alert hash table, removing
+// expired alerts as it goes.  Makes sure that the expired alert
+// doesn't get drawn or shown in the View->WX Alerts dialog.
+//
+// Returns the quantity of alerts that were just expired.
+//
+int alert_expire(int curr_sec) {
+//    int ii;
+    int expire_count = 0;
+    struct hashtable_itr *iterator;
+    alert_entry *temp;
+
+
+    // Check only every 60 seconds
+    if ( (last_alert_expire + 60) > curr_sec ) {
+        return(0);
+    }
+    last_alert_expire = curr_sec;
+
+    if (debug_level & 2)
+        fprintf(stderr,"Checking for expired alerts...\n");
+
+    iterator = create_wx_alert_iterator();
+    while (iterator) {
+
+        // Get current record
+        temp = hashtable_iterator_value(iterator);
+
+        if (!temp) {
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 1\n");
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+            return(expire_count);
+        }
+
+        // If wx alert has expired, remove the record from the hash.
+        if (temp->expiration < time(NULL)) {
+
+            if (debug_level & 2) {
+                fprintf(stderr,
+                    "alert_expire: Clearing %s, current: %lu, alert: %lu\n",
+                    temp->unique_string,
+                    (unsigned long)time(NULL),
+                    (unsigned long)temp->expiration);
+            }
+
+            // Free the storage space
+            free(temp);
+
+            // Delete the entry and advance to the next
+            hashtable_iterator_remove(iterator);
+
+            expire_count++;
+        }
+        else {
+            if (temp && iterator) {
+                // Else advance to the next entry
+                hashtable_iterator_advance(iterator);
+            }
+        }
+    }
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 2\n");
+    if (iterator) free(iterator);
+#endif  // USING_LIBGC
+
+    // Cause a screen redraw if we expired some alerts
+    if (expire_count) {
+        // Schedule a screen update 'cuz we have a new alert
+        alert_redraw_on_update = redraw_on_new_data = 2;
+ 
+    }
+
+    return(expire_count);
+}
+
+
+
+
+
+// alert_add_entry()
+//
+// This function adds a new alert to our alert list.
+//
+// Returns address of new entry or NULL.
+// Called from alert_build_list() function.
+//
+/*@null@*/ static alert_entry *alert_add_entry(alert_entry *entry) {
+//    alert_entry *ptr;
+//    int i;
+
+set_dangerous("alert.c:alert_add_entry()");
+
+    if (debug_level & 2)
+        fprintf(stderr,"alert_add_entry\n");
+
+    if (strlen(entry->title) == 0) {
+        if (debug_level & 2)
+            fprintf(stderr,"alert_add_entry: Empty title!\n");
+
+clear_dangerous();
+
+        return(NULL);
+    }
+
+    // Skip NWS_SOLAR and -NoActivationExpected alerts, they don't
+    // interest us.
+    if ( (strcmp(entry->to, "NWS-SOLAR") == 0)
+            || (strcmp(entry->to, "NWS_SOLAR") == 0) ) {
+        if (debug_level & 2)
+            fprintf(stderr,"NWS-SOLAR, skipping\n");
+
+clear_dangerous();
+
+        return(NULL);
+    }
+    if (strcasecmp(entry->title, "-NoActivationExpected") == 0) {
+        if (debug_level & 2)
+            fprintf(stderr,"NoActivationExpected, skipping\n");
+
+clear_dangerous();
+
+        return(NULL);
+    }
+
+    // Check whether this new alert has already expired.  If so,
+    // don't add it.
+    if (entry->expiration < time(NULL)) {
+        if (debug_level & 2) {
+            fprintf(stderr,
+                "Newest Alert Expired->Clearing, current: %lu, alert: %lu\n",
+                (unsigned long)time(NULL),
+                (unsigned long)entry->expiration );
+        }
+
+clear_dangerous();
+
+        return(NULL);
+    }
+
+    // Check for non-zero alert title, non-expired alert time in new
+    // alert.
+    if (entry->title[0] != '\0' && entry->expiration >= time(NULL)) {
+
+        // Schedule a screen update 'cuz we have a new alert
+        alert_redraw_on_update = redraw_on_new_data = 2;
+
+//WE7U
+
+set_dangerous("alert.c:add_wx_alert_to_hash()");
+
+add_wx_alert_to_hash(entry->unique_string, entry);
+
+clear_dangerous();
+
+return(entry);
+
+    }
+
+    // If we got to here, the title was empty or the alert has
+    // already expired?  Figure out why we might ever get here.
+    if (debug_level & 2) {
+        fprintf(stderr,"Exiting alert_add_entry() without actually adding the alert:\n");
+        fprintf(stderr,"%s %s %lu\n",
+            entry->to,
+            entry->title,
+            (unsigned long)entry->expiration);
+    }
+
+clear_dangerous();
+
+    return(NULL);
+}
+
+
+
+// alert_active()
+//
+// Here's where we get rid of expired alerts in the list.  Called
+// from alert_display_request(), alert_on_screen(),
+// and alert_build_list() functions.  Also called from
+// maps.c:load_alert_maps() function.
+//
+// Returns the alert level.
+//
+// Alert Match Levels:
+// 0 = ?
+// 1 = R
+// 2 = Y
+// 3 = B
+// 4 = T
+// 5 = G
+// 6 = C
+//
+int alert_active(alert_entry *alert, alert_match_level match_level) {
+    alert_entry *a_ptr;
+    char l_list[] = {"?RYBTGC"};
+    int level = 0;
+    time_t now;
+
+
+    if (strlen(alert->title) == 0) {
+        if (debug_level & 2)
+            fprintf(stderr,"alert_active:NULL\n");
+        return(0);
+    }
+ 
+    if (debug_level & 2)
+        fprintf(stderr,"alert_active:%s\n",alert->title);
+
+    (void)time(&now);
+
+//    if ((a_ptr = alert_match(alert, match_level))) {
+    if ((a_ptr = get_wx_alert_from_hash(alert->unique_string))) {
+        if (a_ptr->expiration >= now) {
+            for (level = 0; a_ptr->alert_level != l_list[level] && level < (int)sizeof(l_list); level++);
+        }
+        else if (a_ptr->expiration < (now - 3600)) {    // More than an hour past the expiration,
+            a_ptr->title[0] = '\0';                     // so delete it from list by clearing
+                                                        // out the title.
+//WE7U
+
+            // Schedule an update 'cuz we need to delete an expired
+            // alert from the list.
+            alert_redraw_on_update = redraw_on_new_data = 2;
+        }
+        else if (a_ptr->flags[on_screen] == '?') {  // Expired between 1sec and 1hr and found '?'
+            a_ptr->flags[on_screen] = '-';
+ 
+            // Schedule a screen update 'cuz we have an expired alert
+            alert_redraw_on_update = redraw_on_new_data = 2;
+        }
+    }
+    return (level);
+}
+
+
+
+
+
+// alert_display_request()
+//
+// Function which checks whether an alert should be displayed.
+// Called from maps.c:load_alert_maps() function.
+//
+int alert_display_request(void) {
+//    int i;
+    int alert_count;
+    static int last_alert_count;
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"alert_display_request\n");
+
+//WE7U
+    if (wx_alert_hash)
+        alert_count = hashtable_count(wx_alert_hash);
+    else
+        return((int)FALSE);
+
+    // If we found any, return TRUE.
+    if (alert_count != last_alert_count) {
+        last_alert_count = alert_count;
+        return ((int)TRUE);
+    }
+
+    return ((int)FALSE);
+}
+
+
+// alert_list_count
+int alert_list_count(void) {
+    int count = 0;
+    if (wx_alert_hash)
+      return(hashtable_count(wx_alert_hash));
+    else
+      return count;
+}
+
+
+// alert_on_screen()
+//
+// Returns a count of active weather alerts in the list which are
+// within our viewport.
+// Called from main.c:UpdateTime() function.  Used for sounding
+// alarm if a new weather alert appears on screen.
+//
+int alert_on_screen(void) {
+//    int i;
+    int alert_count = 0;
+    struct hashtable_itr *iterator;
+    alert_entry *temp;
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"alert_on_screen\n");
+
+//WE7U
+
+    iterator = create_wx_alert_iterator();
+    temp = get_next_wx_alert(iterator);
+    while (iterator != NULL && temp) {
+        if (alert_active(temp, ALERT_ALL)
+                && temp->flags[on_screen] == 'Y') {
+            alert_count++;
+        }
+        temp = get_next_wx_alert(iterator);
+    }
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 3\n");
+    if (iterator) free(iterator);
+#endif  // USING_LIBGC
+
+    return (alert_count);
+}
+
+
+
+
+
+// alert_build_list()
+//
+// This function builds alert_entry structs from message entries that
+// contain NWS alert messages.
+//
+// Called from alert_data_add() function.
+//
+//
+// Here's how Xastir breaks down an alert into an alert struct:
+//
+// SFONPW>APRS::NWS-ADVIS:191700z,WIND,CA_Z007,CA_Z065, ALAMEDA AND CON & NAPA COUNTY {JDIAA
+// |----|       |-------| |-----| |--| |-----| |-----|                                 |-|
+//   |              |        |     |      |       |                                     |
+//  from            to       |     |    title   title                               issue_date
+//                           |  alert_tag
+//                        activity (expiration)
+//
+//
+// The code should also handle the case where the packet looks like
+// this (same except no expiration date):
+//
+// SFONPW>APRS::NWS-ADVIS:WIND,CA_Z007,CA_Z065, ALAMEDA AND CON & NAPA COUNTY {JDIAA
+//
+// We also have compressed NWS alerts, signified by NWS_ADVIS
+// (underline instead of dash).  Note that Pete Loveall, AE5PL, is
+// also sending out alerts and sending the "compressed" zone format
+// with "NWS-" which is different than how Dale Huguley was sending
+// them out.  Pete's change is to support Kenwood radios.
+//
+//
+// Expiration is then computed from the activity field.  Alert_level
+// is computed from "to" and/or "alert_tag".  There can be up to
+// five titles in this original format.
+//
+// Here are some real examples captured over the 'net (may be quite old):
+//
+// TAEFFS>APRS::NWS-ADVIS:181830z,FLOOD,FL_C013,FL_C037,FL_C045,FL_C077, {HHEAA
+// ICTFFS>APRS::NWS-ADVIS:180200z,FLOOD,KS_C035, {HEtAA
+// JANFFS>APRS::NWS-ADVIS:180200z,FLOOD,MS_C049,MS_C079,MS_C089,MS_C099,MS_C121, {HEvAA
+// DSMFFS>APRS::NWS-ADVIS:180500z,FLOOD,IA_Z086, {HHGAA
+// EAXFFS>APRS::NWS-ADVIS:180500z,FLOOD,MO_Z023,MO_Z024,MO_Z028,MO_Z030,MO_Z031, {HHIAA
+// SECIND>APRS::NWS-SOLAR:Flx134 A004 BK0001232.  PlnK0000232.Ep............Ee........ {HLaAA
+// SHVFFS>APRS::NWS-ADVIS:181800z,FLOOD,TX_C005,TX_C073,TX_C347,TX_C365,TX_C401, {HF2AA
+// FWDFFS>APRS::NWS-ADVIS:180200z,FLOOD,TX_C379,TX_C467, {HF5AA
+// LCHFFS>APRS::NWS-ADVIS:180400z,FLOOD,LA_C003,LA_C079, {HIdAA
+// GIDFFS>APRS::NWS-ADVIS:180200z,FLOOD,NE_C125, {H2uAA
+// FWDSWO>APRS::NWS-ADVIS:181100z,SKY,CW_AFWD, -NO Activation Expected {HLqAA
+// BGMWSW>APRS::NWS-ADVIS:180500z,WINTER_WEATHER,NY_Z015,NY_Z016,NY_Z017,NY_Z022,NY_Z023, {HKYAA
+// AMAWSW>APRS::NWS-WARN :180400z,WINTER_STORM,OK_Z001,OK_Z002,TX_Z001,TX_Z002,TX_Z003, {HLGBA
+//
+// New compressed-mode weather alert packets:
+//
+// LZKNPW>APRS::NWS-ADVIS:221000z,WINTER_STORM,ARZ003>007-012>016-021>025-030>034-037>047-052>057-062>069{LLSAA
+//
+// or perhaps (leading zeroes removed):
+//
+// LZKNPW>APRS::NWS-ADVIS:221000z,WINTER_STORM,ARZ3>7-12>16-21>25-30>34-37>47-52>57-62>69{LLSAA
+//
+// This one's real:
+// DVNFFS>APRS,qAO,WXSVR::NWS_ADVIS:022300z,FLOOD,IAC57-95-103-111-115-163-171-ILC1-67-71-131-MOC45 {2FsAA
+//
+// The trick is to step thru the data base contained in the
+// shapefiles to determine what areas to light up.  In the above
+// example read ">" as "thru" and "-" as "and".
+//
+//
+// RIWWSW>APRS::NWS-WARN :191800z,WINTER_STORM,WY_Z014, GREEN MOUNTAINS {JBNBA
+// RIWWSW>APRS::SKYRIW   :WINTER STORM WARNING CONTINUING TODAY {JBNBB
+// RIWWSW>APRS::SKYRIW   :THROUGH SATURDAY {JBNBC
+//
+//
+// We'll create and fill in "entry", then copy various "titles" into
+// is such as "ID_C001", then insert that alert into the system.
+//
+//
+// VK2XJG - November 2011:
+// Here are some examples of strings from the new WXSVR-AU for the Aussie Bureau of Meteorology (BOM) alerts:
+//
+// NECMWW>APRS::BOM_WARN :141300z,WIND,TAS_MW002>003-005>007-009 {D55AG
+// YKPMWW>APRS::BOM_ADVIS:131330z,WIND,SA_MW005 {D5aAA
+// 
+// For the BOM alerts note that the STATE portion of the zone can be two or three characters - valid state
+// prefixes are "NSW,VIC,QLD,TAS,NT,WA,SA". The two characters following the underscore denote the shapefile to use
+// These will be one of "CW,MW,PW,FW or ME".
+//
+// WXSVR-AU also does NOT strip leading zeros from the zone strings, however the existing NWS code allows for this, so
+// it should be supported if WXSVR-AU strips the zeros in the future.
+//
+//
+//
+#define TITLE_SIZE 64
+void alert_build_list(Message *fill) {
+    alert_entry entry, *list_ptr;
+    char title[5][TITLE_SIZE+1];  // Storage place for zone/county titles
+    int ii, jj;
+    char *ptr;
+    DataRow *p_station;
+    int compressed_wx_packet = 0;
+    char uncompressed_wx[10000];
+    struct hashtable_itr *iterator;
+
+
+    //fprintf(stderr,"Message_line:%s\n",fill->message_line);
+
+    if (debug_level & 2) {
+        fprintf(stderr,"alert_build_list:%s>%s:%s\n",
+            fill->from_call_sign,
+            fill->call_sign,
+            fill->message_line);
+    }
+
+    // Empty this string first
+    uncompressed_wx[0] = uncompressed_wx[1] = '\0';
+
+    // Check for "SKY" text in the "call_sign" field.
+    if (strncmp(fill->call_sign,"SKY",3) == 0) {
+        // Special handling for SKY messages only.
+
+        if (debug_level & 2)
+            fprintf(stderr,"Sky Message: %s\n",fill->message_line);
+
+        // Find a matching alert_record, check whether or not it is
+        // expired.  If not, add this additional text into the
+        // "desc[0123]" fields, in order.  Check that the
+        // FROM callsign and the first four chars after the curly
+        // brace match.  The next character specifies which message
+        // block to fill in.  In order they should be:
+        //
+        // B = "desc0"
+        // C = "desc1"
+        // D = "desc2"
+        // E = "desc3".
+        //
+        // A matching alert record would have the same "from" field
+        // and the first four characters of the "seq" field would
+        // match.
+        //
+        // Need to make this SKY data expire from the message list
+        // somehow?
+        // 
+        // Remember to blank out these fields when we expire an
+        // alert.  Check that all other fields are cleared in this
+        // case as well.
+        //
+
+        // Run through the alert list looking for a match to the
+        // FROM and first four chars of SEQ
+//WE7U
+        iterator = create_wx_alert_iterator();
+        for (list_ptr = get_next_wx_alert(iterator); iterator != NULL && list_ptr; list_ptr = get_next_wx_alert(iterator)) {
+            if ( (strcasecmp(list_ptr->from, fill->from_call_sign) == 0)
+                    && ( strncmp(list_ptr->seq,fill->seq,4) == 0 ) ) {
+
+                if (debug_level & 2)
+                    fprintf(stderr,"%s:Found a matching alert to a SKY message:\t",list_ptr->seq);
+
+                switch (fill->seq[4]) {
+                    case 'B':
+                        xastir_snprintf(list_ptr->desc0,
+                            sizeof(list_ptr->desc0),
+                            "%s",
+                            fill->message_line);
+                        if (debug_level & 2)
+                            fprintf(stderr,"Wrote into desc0: %s\n",fill->message_line);
+                        break;
+                    case 'C':
+                        xastir_snprintf(list_ptr->desc1,
+                            sizeof(list_ptr->desc1),
+                            "%s",
+                            fill->message_line);
+                        if (debug_level & 2)
+                            fprintf(stderr,"Wrote into desc1: %s\n",fill->message_line);
+                        break;
+                    case 'D':
+                        xastir_snprintf(list_ptr->desc2,
+                            sizeof(list_ptr->desc2),
+                            "%s",
+                            fill->message_line);
+                        if (debug_level & 2)
+                            fprintf(stderr,"Wrote into desc2: %s\n",fill->message_line);
+                        break;
+                    case 'E':
+                    default:
+                        xastir_snprintf(list_ptr->desc3,
+                            sizeof(list_ptr->desc3),
+                            "%s",
+                            fill->message_line);
+                        if (debug_level & 2)
+                            fprintf(stderr,"Wrote into desc3: %s\n",fill->message_line);
+                        break;
+                }
+            }
+        }
+        if (debug_level & 2)
+            fprintf(stderr,"alert_build_list return 1\n");
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator a4\n");
+        if (iterator) free(iterator);
+#endif  // USING_LIBGC
+        return;
+    }
+
+    if (debug_level & 2)
+        fprintf(stderr,"1\n");
+
+    if (fill->active == RECORD_ACTIVE) {
+        int ignore_title = 0;
+#define MAX_SUB_ALERTS 5000
+        char *title_ptr[MAX_SUB_ALERTS];
+        int ret;
+
+
+        if (debug_level & 2)
+            fprintf(stderr,"2\n");
+
+        memset(&entry, 0, sizeof(entry));
+        // flags[0] specifies whether it's onscreen or not
+        memset(entry.flags, (int)'?', sizeof(entry.flags));
+
+        // flags[source] specifies source of the alert DATA_VIA_TNC or
+        // DATA_VIA_LOCAL
+        entry.flags[source] = fill->heard_via_tnc;
+        p_station = NULL;
+        if (search_station_name(&p_station,fill->from_call_sign,1))
+            entry.flags[source] = p_station->data_via;
+
+        // Zero the title strings.  We can have up to five alerts in
+        // a non-compressed weather alert.
+        title[0][0] = '\0';
+        title[1][0] = '\0';
+        title[2][0] = '\0';
+        title[3][0] = '\0';
+        title[4][0] = '\0';
+
+        // This fills in the zone numbers (title) for uncompressed
+        // alerts with up to five alerts per message.  This doesn't
+        // handle filling in the title for compressed alerts though.
+        ret = sscanf(fill->message_line,
+                "%20[^,],%20[^,],%32[^,],%32[^,],%32[^,],%32[^,],%32[^,]",
+                entry.activity,      // 191700z
+                entry.alert_tag,     // WIND
+                &title[0][0],        // CA_Z007
+                &title[1][0],        // ...
+                &title[2][0],        // ...
+                &title[3][0],        // ...
+                &title[4][0]);       // ...
+
+        if (ret < 3)
+          fprintf(stderr,"sscanf parsed %d values in alert.c (3-7 ok) %s->%s: %s\n", ret, 
+			fill->from_call_sign, fill->call_sign, fill->message_line);
+
+        // Force a termination for each
+        entry.activity[20]  = '\0';
+        entry.alert_tag[20] = '\0';
+        title[0][TITLE_SIZE]        = '\0';
+        title[1][TITLE_SIZE]        = '\0';
+        title[2][TITLE_SIZE]        = '\0';
+        title[3][TITLE_SIZE]        = '\0';
+        title[4][TITLE_SIZE]        = '\0';
+
+        // Check for "NWS_" in the call_sign field.  Underline
+        // signifies compressed alert format.  Dash signifies
+        // non-compressed format.
+//
+// TEMPORARY CHANGE:  Process all NWS_ or NWS- as compressed to
+// handle the format that Pete Loveall, AE5PL, is putting out on the
+// 'net.  The correct change would be to check inside the data
+// portion for compressed-format zones in all cases and de-compress
+// them when found.
+// WE7U.
+//
+//        if (strncmp(fill->call_sign,"NWS_",4) == 0) {
+        if (       (strncmp(fill->call_sign,"NWS_",4) == 0)
+                || (strncmp(fill->call_sign,"NWS-",4) == 0) ) {
+
+            char compressed_wx[512];
+            char *ptr;
+
+/////////////////////////////////////////////////////////////////////
+// Compressed weather alert special code
+/////////////////////////////////////////////////////////////////////
+
+            compressed_wx_packet++; // Set the flag
+
+//fprintf(stderr, "Found compressed alert packet via NWS_!\n");
+
+//fprintf(stderr,"Compressed Weather Alert:%s\n",fill->message_line);
+//fprintf(stderr,"Compressed alerts are not fully implemented yet.\n");
+
+            // Create a new weather alert for each of these and then
+            // call this function on each one?  Seems like it might
+            // work fine if we watch out for global variables.
+            // Another method would be to create an incoming message
+            // for each one and add it to the message queue, or just
+            // a really long new message and add it to the queue,
+            // in which case we'd exit from this routine as soon as
+            // it was submitted.
+            ret = sscanf(fill->message_line, "%20[^,],%20[^,],%255[^, ]",
+                entry.activity,
+                entry.alert_tag,
+                compressed_wx);     // Stick the long string in here
+
+            if (ret != 3) {
+                fprintf(stderr,"sscanf parsed %d/3 values in alert.c\n", ret);
+                compressed_wx[0] = '\0';  // Remove stale compressed alerts.
+                compressed_wx_packet = 0; //Clear flag in error condition.
+            }
+
+            compressed_wx[255] = '\0';
+
+//fprintf(stderr,"Line:%s\n",compressed_wx);
+
+            // Snag alpha characters (should be three) at the start
+            // of the string.  Use those until we hit more alpha
+            // characters.  First two characters of each 3-letter
+            // alpha group are the state, last character is the
+            // zone/county/marine-zone indicator.
+
+// Need to be very careful here to validate the letters/numbers, and
+// to not run off the end of the string.  Need more code here to do
+// this validation.
+
+
+            // Scan through entire string
+            ptr = compressed_wx;
+            while (ptr < (compressed_wx + strlen(compressed_wx))) {
+                char prefix[5];
+                char suffix[4];
+                char temp_suffix[4];
+                char ending[4];
+                int iterations = 0;
+
+
+                // Snag the ALPHA portion
+                xastir_snprintf(prefix,
+                    sizeof(prefix),
+                    "%s",
+                    ptr);
+                ptr += 2;
+                prefix[2] = '_';
+                prefix[3] = ptr[0];
+                prefix[4] = '\0';   // Terminate the string
+                ptr += 1;
+
+                // prefix should now contain something like "MN_Z"
+
+                // Snag the NUMERIC portion.  Note that the field
+                // width can vary between 1 and 3.  The leading
+                // zeroes have been removed.
+                xastir_snprintf(temp_suffix,
+                    sizeof(temp_suffix),
+                    "%s",
+                    ptr);
+
+                temp_suffix[3] = '\0';   // Terminate the string
+                if (temp_suffix[1] == '-' || temp_suffix[1] == '>') {
+                    temp_suffix[1] = '\0';
+                    ptr += 1;
+                }
+                else if (temp_suffix[1] != '\0' && 
+                         (temp_suffix[2] == '-' || temp_suffix[2] == '>')) {
+                    temp_suffix[2] = '\0';
+                    ptr += 2;
+                }
+                else {
+                    ptr += 3;
+                }
+
+                // temp_suffix should now contain something like
+                // "039" or "45" or "2".  Add leading zeroes to give
+                // "suffix" a length of 3.
+                xastir_snprintf(suffix,
+                    sizeof(suffix),
+                    "000");
+                switch (strlen(temp_suffix)) {
+                    case 1: // Copy one char across
+                        suffix[2] = temp_suffix[0];
+                        break;
+                    case 2: // Copy two chars across
+                        suffix[1] = temp_suffix[0];
+                        suffix[2] = temp_suffix[1];
+                        break;
+                    case 3: // Copy all three chars across
+                        xastir_snprintf(suffix,
+                            sizeof(suffix),
+                            "%s",
+                            temp_suffix);
+                        break;
+                }
+                // Make sure suffix is terminated properly
+                suffix[3] = '\0';
+
+// We have our first zone (of this loop) extracted!
+if (debug_level & 2)
+    fprintf(stderr,"1Zone:%s%s\n",prefix,suffix);
+
+                // Add it to our zone string.  In this case we know
+                // that the lengths of the strings we're working
+                // with are quite short.  Little danger of
+                // overrunning our destination string.
+                strncat(uncompressed_wx,
+                    ",",
+                    sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                strncat(uncompressed_wx,
+                    prefix,
+                    sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx)); 
+                strncat(uncompressed_wx,
+                    suffix,
+                    sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                // Terminate it every time
+                uncompressed_wx[9999] = '\0';
+
+if (debug_level & 2)
+    fprintf(stderr,"uncompressed_wx:%s\n",uncompressed_wx);
+
+                // Here we keep looping until we hit another alpha
+                // portion.  We need to look at the field separator
+                // to determine whether we have another separate
+                // field coming up or a range to enumerate.
+                while ( (ptr < (compressed_wx + strlen(compressed_wx)))
+                        && ( is_num_chr(ptr[1]) ) ) {
+
+                    iterations++;
+
+                    // Break out of this loop if we don't find an
+                    // alpha character fairly quickly.  That way the
+                    // Xastir main thread can't hang in this loop
+                    // forever if the input string is malformed.
+                    if (iterations > 30)
+                        break;
+
+                    // Look for '>' or '-' character.  If former, we
+                    // have a numeric sequence to ennumerate.  If the
+                    // latter, we either have another zone number or
+                    // another prefix coming up.
+                    if (ptr[0] == '>' || ptr[0] == '<') { // Numeric zone sequence
+                        int start_number;
+                        int end_number;
+                        int kk;
+
+
+                        ptr++;  // Skip past the '>' or '<' characters
+
+                        // Snag the NUMERIC portion.  May be between
+                        // 1 and three digits long.
+                        xastir_snprintf(ending,
+                            sizeof(ending),
+                            "%s",
+                            ptr);
+
+                        // Terminate the string and advance the
+                        // pointer past it.
+                        if (!is_num_chr(ending[0])) {
+                            // We have a problem, 'cuz we didn't
+                            // find at least one number.  Packet is
+                            // badly formatted.
+                            return;
+                        }
+                        else if (!is_num_chr(ending[1])) {
+                            ending[1] = '\0';
+                            ptr++;
+                        }
+                        else if (!is_num_chr(ending[2])) {
+                            ending[2] = '\0';
+                            ptr+=2;
+                        }
+                        else {
+                            ending[3] = '\0';
+                            ptr+=3;
+                        }
+                        
+                        // ending should now contain something like
+                        // "046" or "35" or "2"
+if (debug_level & 2)
+    fprintf(stderr,"Ending:%s\n",ending);
+
+                        start_number = (int)atoi(suffix);
+                        end_number = (int)atoi(ending);
+                        for ( kk=start_number+1; kk<=end_number; kk++) {
+                            xastir_snprintf(suffix,4,"%03d",kk);
+
+if (debug_level & 2)
+    fprintf(stderr,"2Zone:%s%s\n",prefix,suffix);
+
+                            // And another zone... Ennumerate
+                            // through the sequence, adding each
+                            // new zone to our zone string.  In this
+                            // case we know that the lengths of the
+                            // strings we're working with are quite
+                            // short.  Little danger of overrunning
+                            // our destination string.
+                            strncat(uncompressed_wx,
+                                ",",
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            strncat(uncompressed_wx,
+                                prefix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx)); 
+                            strncat(uncompressed_wx,
+                                suffix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            // Terminate it every time
+                            uncompressed_wx[9999] = '\0';
+                        }
+                    }
+
+                    // Wasn't a '>' character, so check for a '-'
+                    else if (ptr[0] == '-') {
+                        // New zone number, not a numeric sequence.
+
+                        ptr++;  // Skip past the '-' character
+
+                        if ( is_num_chr(ptr[0]) ) {
+                            // Found another number.  Use the prefix
+                            // stored from last time.
+
+                            // Snag the NUMERIC portion.  Note that the field
+                            // width can vary between 1 and 3.  The leading
+                            // zeroes have been removed.
+                            xastir_snprintf(temp_suffix,
+                                sizeof(temp_suffix),
+                                "%s",
+                                ptr);
+
+                            // Terminate the string and advance the
+                            // pointer past it.
+                            if (!is_num_chr(temp_suffix[0])) {
+                                // We have a problem, 'cuz we didn't
+                                // find at least one number.  Packet is
+                                // badly formatted.
+                                return;
+                            }
+                            else if (!is_num_chr(temp_suffix[1])) {
+                                temp_suffix[1] = '\0';
+                                ptr++;
+                            }
+                            else if (!is_num_chr(temp_suffix[2])) {
+                                temp_suffix[2] = '\0';
+                                ptr+=2;
+                            }
+                            else {
+                                temp_suffix[3] = '\0';
+                                ptr+=3;
+                            }
+
+                            // temp_suffix should now contain something like
+                            // "039" or "45" or "2".  Add leading zeroes to give
+                            // "suffix" a length of 3.
+                            xastir_snprintf(suffix,
+                                sizeof(suffix),
+                                "000");
+                            switch (strlen(temp_suffix)) {
+                                case 1: // Copy one char across
+                                    suffix[2] = temp_suffix[0];
+                                    break;
+                                case 2: // Copy two chars across
+                                    suffix[1] = temp_suffix[0];
+                                    suffix[2] = temp_suffix[1];
+                                                break;
+                                case 3: // Copy all three chars across
+                                    xastir_snprintf(suffix,
+                                        sizeof(suffix),
+                                        "%s",
+                                        temp_suffix);
+                                    break;
+                            }
+
+if (debug_level & 2)
+    fprintf(stderr,"3Zone:%s%s\n",prefix,suffix);
+
+                            // And another zone...
+                            // Add it to our zone string.  In this
+                            // case we know that the lengths of the
+                            // strings we're working with are quite
+                            // short.  Little danger of overrunning
+                            // our destination string.
+                            strncat(uncompressed_wx,
+                                ",",
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            strncat(uncompressed_wx,
+                                prefix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx)); 
+                            strncat(uncompressed_wx,
+                                suffix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            // Terminate it every time
+                            uncompressed_wx[9999] = '\0';
+                        }
+                        else {  // New prefix (not a number)
+                            // Start at the top of the outer loop again
+                        }
+                    }
+                }
+                // Skip past '-' character, if any, so that we can
+                // get to the next prefix
+                // RZG:Added the ptr check, so we don't read a byte off the end
+                if ( (ptr < (compressed_wx + strlen(compressed_wx))) && (ptr[0] == '-') ) {
+                    ptr++;
+                }
+            }
+
+            if (debug_level & 2)
+                fprintf(stderr,"Uncompressed: %s\n",
+                    uncompressed_wx);
+        }
+/////////////////////////////////////////////////////////////////////
+// End of compressed weather alert special code
+/////////////////////////////////////////////////////////////////////
+
+        // Australian Buerau of Meeorology alerts (BOM)
+        // Geoff VK2XJG
+
+        // Check for "BOM_" in the call_sign field.  
+        // WXSVR-AU delivers messages in this format, keeping the protocol as close to
+        // the NWS WXSVR as possible.
+        // Underline signifies compressed alert format.  Dash signifies
+        // non-compressed format, although this has not been implemented on the server.
+
+        if (       (strncmp(fill->call_sign,"BOM_",4) == 0)
+                || (strncmp(fill->call_sign,"BOM-",4) == 0) ) {
+
+            char compressed_wx[512];
+            char *ptr;
+
+/////////////////////////////////////////////////////////////////////
+// Compressed weather alert (BOM) special code
+/////////////////////////////////////////////////////////////////////
+
+            compressed_wx_packet++; // Set the flag
+
+//fprintf(stderr, "Found compressed alert packet via BOM_!\n");
+
+//fprintf(stderr,"Compressed Weather Alert:%s\n",fill->message_line);
+//fprintf(stderr,"Compressed alerts are not fully implemented yet.\n");
+
+            // Create a new weather alert for each of these and then
+            // call this function on each one?  Seems like it might
+            // work fine if we watch out for global variables.
+            // Another method would be to create an incoming message
+            // for each one and add it to the message queue, or just
+            // a really long new message and add it to the queue,
+            // in which case we'd exit from this routine as soon as
+            // it was submitted.
+            ret = sscanf(fill->message_line, "%20[^,],%20[^,],%255[^, ]",
+                entry.activity,
+                entry.alert_tag,
+                compressed_wx);     // Stick the long string in here
+
+            if (ret != 3) {
+                fprintf(stderr,"sscanf parsed %d/3 values in alert.c\n", ret);
+                compressed_wx[0] = '\0';  // Remove stale compressed alerts.
+                compressed_wx_packet = 0; //Clear flag in error condition.
+            }
+
+            compressed_wx[255] = '\0';
+
+//fprintf(stderr,"Line:%s\n",compressed_wx);
+
+            // Snag alpha characters (should be five) at the start
+            // of the string.  Use those until we hit more alpha
+            // characters.  First two/three characters of each 5-letter
+            // alpha group are the state, last two characters are the
+            // zone/county/marine-zone indicator.
+
+// Need to be very careful here to validate the letters/numbers, and
+// to not run off the end of the string.  Need more code here to do
+// this validation.
+
+
+            // Scan through entire string
+            ptr = compressed_wx;
+            while (ptr < (compressed_wx + strlen(compressed_wx))) {
+                char prefix[7];
+                char suffix[4];
+                char temp_suffix[4];
+                char ending[4];
+                int iterations = 0;
+
+
+                // Snag the ALPHA portion
+                xastir_snprintf(prefix,
+                    sizeof(prefix),
+                    "%s",
+                    ptr);
+                ptr += 3;
+                // Handle a 2 letter state abbreviation (SA/WA/NT)
+                if (prefix[2] == '_' ) {
+                    prefix[3] = ptr[0];
+                    prefix[5] = '\0';   // Terminate the string
+                    ptr += 3;
+                } 
+                // All other cases are 3 letter states (NSW/VIC/TAS/QLD)
+                else {
+                    prefix[3] = ptr[0];
+                    prefix[6] = '\0';   // Terminate the string
+                    ptr += 3;
+                }
+
+                // prefix should now contain something like "TAS_CW" or "SA_PW"
+
+                // Snag the NUMERIC portion.  Note that the field
+                // width can vary between 1 and 3.  The leading
+                // zeroes have been removed.
+                xastir_snprintf(temp_suffix,
+                    sizeof(temp_suffix),
+                    "%s",
+                    ptr);
+
+                temp_suffix[3] = '\0';   // Terminate the string
+                if (temp_suffix[1] == '-' || temp_suffix[1] == '>') {
+                    temp_suffix[1] = '\0';
+                    ptr += 1;
+                }
+                else if (temp_suffix[1] != '\0' && 
+                         (temp_suffix[2] == '-' || temp_suffix[2] == '>')) {
+                    temp_suffix[2] = '\0';
+                    ptr += 2;
+                }
+                else {
+                    ptr += 3;
+                }
+
+                // temp_suffix should now contain something like
+                // "039" or "45" or "2".  Add leading zeroes to give
+                // "suffix" a length of 3.
+                xastir_snprintf(suffix,
+                    sizeof(suffix),
+                    "000");
+                switch (strlen(temp_suffix)) {
+                    case 1: // Copy one char across
+                        suffix[2] = temp_suffix[0];
+                        break;
+                    case 2: // Copy two chars across
+                        suffix[1] = temp_suffix[0];
+                        suffix[2] = temp_suffix[1];
+                        break;
+                    case 3: // Copy all three chars across
+                        xastir_snprintf(suffix,
+                            sizeof(suffix),
+                            "%s",
+                            temp_suffix);
+                        break;
+                }
+                // Make sure suffix is terminated properly
+                suffix[3] = '\0';
+
+// We have our first zone (of this loop) extracted!
+if (debug_level & 2)
+    fprintf(stderr,"1Zone:%s%s\n",prefix,suffix);
+
+                // Add it to our zone string.  In this case we know
+                // that the lengths of the strings we're working
+                // with are quite short.  Little danger of
+                // overrunning our destination string.
+                strncat(uncompressed_wx,
+                    ",",
+                    sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                strncat(uncompressed_wx,
+                    prefix,
+                    sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx)); 
+                strncat(uncompressed_wx,
+                    suffix,
+                    sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                // Terminate it every time
+                uncompressed_wx[9999] = '\0';
+
+if (debug_level & 2)
+    fprintf(stderr,"uncompressed_wx:%s\n",uncompressed_wx);
+
+                // Here we keep looping until we hit another alpha
+                // portion.  We need to look at the field separator
+                // to determine whether we have another separate
+                // field coming up or a range to enumerate.
+                while ( (ptr < (compressed_wx + strlen(compressed_wx)))
+                        && ( is_num_chr(ptr[1]) ) ) {
+
+                    iterations++;
+
+                    // Break out of this loop if we don't find an
+                    // alpha character fairly quickly.  That way the
+                    // Xastir main thread can't hang in this loop
+                    // forever if the input string is malformed.
+                    if (iterations > 30)
+                        break;
+
+                    // Look for '>' or '-' character.  If former, we
+                    // have a numeric sequence to ennumerate.  If the
+                    // latter, we either have another zone number or
+                    // another prefix coming up.
+                    if (ptr[0] == '>' || ptr[0] == '<') { // Numeric zone sequence
+                        int start_number;
+                        int end_number;
+                        int kk;
+
+
+                        ptr++;  // Skip past the '>' or '<' characters
+
+                        // Snag the NUMERIC portion.  May be between
+                        // 1 and three digits long.
+                        xastir_snprintf(ending,
+                            sizeof(ending),
+                            "%s",
+                            ptr);
+
+                        // Terminate the string and advance the
+                        // pointer past it.
+                        if (!is_num_chr(ending[0])) {
+                            // We have a problem, 'cuz we didn't
+                            // find at least one number.  Packet is
+                            // badly formatted.
+                            return;
+                        }
+                        else if (!is_num_chr(ending[1])) {
+                            ending[1] = '\0';
+                            ptr++;
+                        }
+                        else if (!is_num_chr(ending[2])) {
+                            ending[2] = '\0';
+                            ptr+=2;
+                        }
+                        else {
+                            ending[3] = '\0';
+                            ptr+=3;
+                        }
+                        
+                        // ending should now contain something like
+                        // "046" or "35" or "2"
+if (debug_level & 2)
+    fprintf(stderr,"Ending:%s\n",ending);
+
+                        start_number = (int)atoi(suffix);
+                        end_number = (int)atoi(ending);
+                        for ( kk=start_number+1; kk<=end_number; kk++) {
+                            xastir_snprintf(suffix,4,"%03d",kk);
+
+if (debug_level & 2)
+    fprintf(stderr,"2Zone:%s%s\n",prefix,suffix);
+
+                            // And another zone... Ennumerate
+                            // through the sequence, adding each
+                            // new zone to our zone string.  In this
+                            // case we know that the lengths of the
+                            // strings we're working with are quite
+                            // short.  Little danger of overrunning
+                            // our destination string.
+                            strncat(uncompressed_wx,
+                                ",",
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            strncat(uncompressed_wx,
+                                prefix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx)); 
+                            strncat(uncompressed_wx,
+                                suffix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            // Terminate it every time
+                            uncompressed_wx[9999] = '\0';
+                        }
+                    }
+
+                    // Wasn't a '>' character, so check for a '-'
+                    else if (ptr[0] == '-') {
+                        // New zone number, not a numeric sequence.
+
+                        ptr++;  // Skip past the '-' character
+
+                        if ( is_num_chr(ptr[0]) ) {
+                            // Found another number.  Use the prefix
+                            // stored from last time.
+
+                            // Snag the NUMERIC portion.  Note that the field
+                            // width can vary between 1 and 3.  The leading
+                            // zeroes have been removed.
+                            xastir_snprintf(temp_suffix,
+                                sizeof(temp_suffix),
+                                "%s",
+                                ptr);
+
+                            // Terminate the string and advance the
+                            // pointer past it.
+                            if (!is_num_chr(temp_suffix[0])) {
+                                // We have a problem, 'cuz we didn't
+                                // find at least one number.  Packet is
+                                // badly formatted.
+                                return;
+                            }
+                            else if (!is_num_chr(temp_suffix[1])) {
+                                temp_suffix[1] = '\0';
+                                ptr++;
+                            }
+                            else if (!is_num_chr(temp_suffix[2])) {
+                                temp_suffix[2] = '\0';
+                                ptr+=2;
+                            }
+                            else {
+                                temp_suffix[3] = '\0';
+                                ptr+=3;
+                            }
+
+                            // temp_suffix should now contain something like
+                            // "039" or "45" or "2".  Add leading zeroes to give
+                            // "suffix" a length of 3.
+                            xastir_snprintf(suffix,
+                                sizeof(suffix),
+                                "000");
+                            switch (strlen(temp_suffix)) {
+                                case 1: // Copy one char across
+                                    suffix[2] = temp_suffix[0];
+                                    break;
+                                case 2: // Copy two chars across
+                                    suffix[1] = temp_suffix[0];
+                                    suffix[2] = temp_suffix[1];
+                                                break;
+                                case 3: // Copy all three chars across
+                                    xastir_snprintf(suffix,
+                                        sizeof(suffix),
+                                        "%s",
+                                        temp_suffix);
+                                    break;
+                            }
+
+if (debug_level & 2)
+    fprintf(stderr,"3Zone:%s%s\n",prefix,suffix);
+
+                            // And another zone...
+                            // Add it to our zone string.  In this
+                            // case we know that the lengths of the
+                            // strings we're working with are quite
+                            // short.  Little danger of overrunning
+                            // our destination string.
+                            strncat(uncompressed_wx,
+                                ",",
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            strncat(uncompressed_wx,
+                                prefix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx)); 
+                            strncat(uncompressed_wx,
+                                suffix,
+                                sizeof(uncompressed_wx) - 1 - strlen(uncompressed_wx));
+                            // Terminate it every time
+                            uncompressed_wx[9999] = '\0';
+                        }
+                        else {  // New prefix (not a number)
+                            // Start at the top of the outer loop again
+                        }
+                    }
+                }
+                // Skip past '-' character, if any, so that we can
+                // get to the next prefix
+                // RZG:Added the ptr check, so we don't read a byte off the end
+                if ( (ptr < (compressed_wx + strlen(compressed_wx))) && (ptr[0] == '-') ) {
+                    ptr++;
+                }
+            }
+
+            if (debug_level & 2)
+                fprintf(stderr,"Uncompressed: %s\n",
+                    uncompressed_wx);
+        }
+/////////////////////////////////////////////////////////////////////
+// End of compressed weather (BOM) alert special code
+/////////////////////////////////////////////////////////////////////
+
+
+
+        if (debug_level & 2)
+            fprintf(stderr,"3\n");
+
+       // Terminate the strings
+        entry.activity[20] = entry.alert_tag[20] = '\0';
+
+        // If the expire time is missing, shift fields to the right
+        // by one field.  Evidently we can have an alert come across
+        // that doesn't have an expire time.  The code shuffles the
+        // titles to the next record before fixing up the title and
+        // alert_tag for entry.
+        if (!isdigit((int)entry.activity[0]) && entry.activity[0] != '-') {
+
+            if (title[0][0] == '\0') {
+                // No alerts in this message
+            }
+
+            // If it's a trashed packet, we may have entries here
+            // that are too long.  Assure that we don't overwrite
+            // the strings.
+            for (jj = 4; jj > 0; jj--) {
+                xastir_snprintf(&title[jj][0],
+                    sizeof(&title[jj][0]),
+                    "%s",
+                    &title[jj-1][0]);
+            }
+ 
+            xastir_snprintf(&title[0][0],
+                sizeof(&title[0][0]),
+                "%s",
+                entry.alert_tag);
+ 
+            xastir_snprintf(entry.alert_tag,
+                sizeof(entry.alert_tag),
+                "%s",
+                entry.activity);
+            entry.alert_tag[20] = '\0';
+ 
+            // Shouldn't we clear out entry.activity in this
+            // case???  We've determined it's not a date/time value.
+            xastir_snprintf(entry.activity,sizeof(entry.activity),"------z");
+            entry.expiration = sec_now() + (24 * 60 * 60);   // Add a day
+        }
+        else {
+            // Compute expiration time_t from zulu time
+            entry.expiration = time_from_aprsstring(entry.activity);
+        }
+
+        if (debug_level & 2)
+            fprintf(stderr,"4\n");
+
+        // Copy the sequence (which contains issue_date_time and
+        // message sequence) into the record.
+        xastir_snprintf(entry.seq,sizeof(entry.seq),"%s",fill->seq);
+
+        if (debug_level & 2)
+            fprintf(stderr,"5\n");
+
+        // Now compute issue_date_time from the first three characters of
+        // the sequence number:
+        // 0-9   = 0-9
+        // 10-35 = A-Z
+        // 36-61 = a-z
+        // The 3 characters are Day/Hour/Minute of the issue date time in
+        // zulu time.
+        if (strlen(fill->seq) == 5) {   // Looks ok so far
+            // Could add another check to make sure that the first two
+            // chars are a digit or a capital letter.
+            char c;
+            char date_time[10];
+            char temp[3];
+
+
+            date_time[0] = '\0';
+            for ( ii = 0; ii < 3; ii++ ) {
+                c = fill->seq[ii];   // Snag one character
+
+                if (is_num_chr(c)) {    // Found numeric char
+                    temp[0] = '0';
+                    temp[1] = c;
+                    temp[2] = '\0';
+                }
+
+                else if (c >= 'A' && c <= 'Z') {    // Found upper-case letter
+                    // Need to take ord(c) - 55 to get the number
+                    xastir_snprintf(temp,sizeof(temp),"%02d",(int)c - 55);
+                }
+
+                else if (c >= 'a' && c <= 'z') {    // Found lower-case letter
+                    // Need to take ord(c) - 61 to get the number
+                    xastir_snprintf(temp,sizeof(temp),"%02d",(int)c - 61);
+                }
+
+                strncat(date_time,temp,2);  // Concatenate the strings
+            }
+            strncat(date_time,"z",1);   // Add a 'z' on the end.
+
+            if (debug_level & 2)
+                fprintf(stderr,"Seq: %s,\tIssue_time: %s\n",fill->seq,date_time);
+
+            xastir_snprintf(entry.issue_date_time,
+                sizeof(entry.issue_date_time),
+                "%s",
+                date_time);
+            //entry.issue_date_time = time_from_aprsstring(date_time);
+        } else {
+            xastir_snprintf(entry.issue_date_time,
+                sizeof(entry.issue_date_time),
+                "%s",
+                "312359z");
+        }
+
+        if (debug_level & 2)
+            fprintf(stderr,"6\n");
+
+
+///////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////
+
+ 
+        // Iterate through up to five uncompressed alerts, or
+        // through the string of now-uncompressed "compressed"
+        // alerts, creating an alert out of each.
+        //
+        if (compressed_wx_packet) { // Handle compressed packet.
+            // Skip the first character of our uncompressed_wx
+            // string, as it's a leading comma.  Snag out each
+            // string in turn and use that as the title for a
+            // weather alert.
+
+            // Feed &uncompressed_wx[1] to split_string to fill in
+            // an array with the various zone names.
+            split_string(&uncompressed_wx[1],
+                title_ptr,
+                MAX_SUB_ALERTS,
+                ',');
+        }
+        else {  // Handle non-compressed packet
+            // We have up to five alerts to process.
+
+            // Set up an array of char pointers so that we can use
+            // the same code for either compressed or uncompressed
+            // weather alerts.
+            title_ptr[0] = &title[0][0];
+            title_ptr[1] = &title[1][0];
+            title_ptr[2] = &title[2][0];
+            title_ptr[3] = &title[3][0];
+            title_ptr[4] = &title[4][0];
+            title_ptr[5] = NULL;    // Make sure we terminate
+        }
+
+// We now have all of our titles pointed to by the title_ptr[]
+// array.  Either type of alert can be processed identically now.
+
+
+        // Try to create alerts out of each one.
+
+        for (ii = 0; ii < MAX_SUB_ALERTS && title_ptr[ii]; ii++) {
+
+            // Copy into our entry.title variable
+            xastir_snprintf(entry.title,
+                sizeof(entry.title),
+                "%s",
+                title_ptr[ii]);
+
+            // Terminate title string
+            entry.title[sizeof(entry.title)-1] = '\0';
+//fprintf(stderr,"Title: %s\n",entry.title);
+
+            // This one removes spaces from the title.
+            //while ((ptr = strpbrk(entry.title, " ")))
+            //    memmove(ptr, ptr+1, strlen(ptr)+1);
+
+            // Instead we should blank out the title and any
+            // following alert titles if a space is encountered, as
+            // we're to disregard anything after a space in the
+            // information field.
+            if (ignore_title)   // Blank out title if flag is set
+                entry.title[0] = '\0';
+
+            // If we found a space in a title, this signifies that
+            // we hit the end of the current list of zones.
+            if ( (ptr = strpbrk(entry.title, " ")) ) {
+                ignore_title++;     // Set flag for following titles
+                entry.title[0] = '\0';  // Blank out title
+            }
+
+            if ((ptr = strpbrk(entry.title, "}>=!:/*+;"))) {
+                if (debug_level & 2) {
+                    fprintf(stderr,
+                        "Warning: Weird Weather Message: %ld:%s>%s:%s!\n",
+                        (long)fill->sec_heard,
+                        fill->from_call_sign,
+                        fill->call_sign,
+                        fill->message_line);
+                }
+                *ptr = '\0';
+            }
+
+            // Skip loop iterations if we don't have a title for an
+            // entry
+            if (entry.title[0] == '\0')
+                continue;
+
+            xastir_snprintf(entry.from,
+                sizeof(entry.from),
+                "%s",
+                fill->from_call_sign);
+            xastir_snprintf(entry.to,
+                sizeof(entry.to),
+                "%s",
+                fill->call_sign);
+            xastir_snprintf(entry.seq,
+                sizeof(entry.seq),
+                "%s",
+                fill->seq);
+
+            // NWS_ADVIS or NWS_CANCL normally appear in the "to"
+            // field.  ADVIS can appear in the alert_tag field on a
+            // CANCL message though, and we want CANCL to have
+            // priority.
+            if (strstr(entry.alert_tag, "CANCL") || strstr(entry.to, "CANCL"))
+                entry.alert_level = 'C';
+
+            else if (!strncmp(entry.alert_tag, "TEST", 4) || strstr(entry.to, "TEST"))
+                entry.alert_level = 'T';
+
+            else if (strstr(entry.alert_tag, "WARN") || strstr(entry.to, "WARN"))
+                entry.alert_level = 'R';
+
+            else if (strstr(entry.alert_tag, "CIVIL") || strstr(entry.to, "CIVIL"))
+                entry.alert_level = 'R';
+
+            else if (strstr(entry.alert_tag, "WATCH") || strstr(entry.to, "WATCH"))
+                entry.alert_level = 'Y';
+
+            else if (strstr(entry.alert_tag, "ADVIS") || strstr(entry.to, "ADVIS"))
+                entry.alert_level = 'B';
+
+            else
+                entry.alert_level = 'G';
+
+
+            // Kludge for fire zones
+            if (!strncmp(entry.alert_tag,"RED_FLAG",8))
+            {
+                // Replace "Z" in the zone field with "F"
+                if (entry.title[3] == 'Z')
+                    entry.title[3] = 'F';
+            }
+            // Look for a similar alert
+
+
+// We need some improvements here.  We compare these fields:
+//
+// from         SFONPW      SFONPW
+// to           NWS-ADVIS   NWS-CANCL
+// alert_tag    WIND        WIND_ADVIS_CANCEL
+// title        CA_Z007     CA_Z007
+//
+// Of these, "from" and "title" should remain the same between an
+// alert and a cancelled alert.  "to" and "alert_tag" change.  Since
+// we're comparing all four fields, the cancels don't match any
+// existing alerts.
+
+
+//WE7U
+            // Fill in the unique_string variable.  We need this for
+            // our hash code.
+            alert_fill_unique_string(&entry);
+ 
+            if ((list_ptr = get_wx_alert_from_hash(entry.unique_string))) {
+//fprintf(stderr,"alert_build_list: found match: %s\n",entry.unique_string);
+
+
+// We found a match!  We probably need to copy some more data across
+// between the records:  seq, alert_tag, alert_level, from, to,
+// issue_date_time, expiration?
+// If it's a CANCL or CANCEL, we need to make sure the cancel
+// packet's information is kept and the other's info is tossed, so
+// that the alert doesn't get drawn anymore.
+
+                // If we're not trying to replace a cancelled alert with
+                // a new non-cancelled alert, go ahead and copy the
+                // fields across.
+                if ( (list_ptr->alert_level != 'C') // Stored alert is _not_ a CANCEL
+                        || (entry.alert_level == 'C') ) { // Or new one _is_ a CANCEL
+                    list_ptr->expiration = entry.expiration;
+                    xastir_snprintf(list_ptr->activity,
+                        sizeof(list_ptr->activity),
+                        "%s",
+                        entry.activity);
+                    xastir_snprintf(list_ptr->alert_tag,
+                        sizeof(list_ptr->alert_tag),
+                        "%s",
+                        entry.alert_tag);
+                    list_ptr->alert_level = entry.alert_level;
+                    xastir_snprintf(list_ptr->seq,
+                        sizeof(list_ptr->seq),
+                        "%s",
+                        entry.seq);
+                    xastir_snprintf(list_ptr->from,
+                        sizeof(list_ptr->from),
+                        "%s",
+                        entry.from);
+                    xastir_snprintf(list_ptr->to,
+                        sizeof(list_ptr->to),
+                        "%s",
+                        entry.to);
+                    xastir_snprintf(list_ptr->issue_date_time,
+                        sizeof(list_ptr->issue_date_time),
+                        "%s",
+                        entry.issue_date_time);
+                }
+                else {
+                    // Don't copy the info across, as we'd be making a
+                    // cancelled alert active again if we did.
+                }
+            }
+            else {    // No similar alert, add a new one to the list
+                entry.index = -1;    // Haven't found it in a file yet
+
+                (void)alert_add_entry(&entry);
+            }
+
+            if (alert_active(&entry, ALERT_ALL)) {
+                // Empty "if" body here?????  LCLINT caught this.
+            }
+
+        }   // End of for loop
+
+
+        // Signify that we're done processing the NWS message
+        fill->active = RECORD_CLOSED;
+    }
+
+    if (debug_level & 2)
+        fprintf(stderr,"alert_build_list return 2\n");
+}
+
+
diff --git a/src/alert.h b/src/alert.h
new file mode 100644
index 0000000..76de546
--- /dev/null
+++ b/src/alert.h
@@ -0,0 +1,98 @@
+/*
+ * $Id: alert.h,v 1.31 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef __XASTIR_ALERT_H
+#define __XASTIR_ALERT_H
+
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+
+#include "database.h"
+//#include "maps.h"
+
+
+// How many alerts we add storage for each time we're short.
+#define ALERT_COUNT_INCREMENT 200
+
+
+typedef enum {
+    ALERT_TITLE,
+    ALERT_TAG,
+    ALERT_TO,
+    ALERT_FROM
+} alert_match_level;
+
+#define ALERT_ALL ALERT_FROM
+enum flag_list {on_screen, source, max_flag=16};
+
+typedef struct {
+    char unique_string[50];
+    double top_boundary, left_boundary, bottom_boundary, right_boundary;
+    time_t expiration;  // In local time (secs since epoch)
+    char activity[21];
+    char alert_tag[21];
+    char title[33];
+    char alert_level;
+    char from[10];
+    char to[10];
+    /* referenced flags
+       0 - on screen
+       1 - source
+    */
+    char flags[max_flag];
+    char filename[64];
+    int  index;         // Index into shapefile
+    char seq[10];
+    char issue_date_time[10];
+    char desc0[68];     // Space for additional text.
+    char desc1[68];     // Spec allows 67 chars per
+    char desc2[68];     // message.
+    char desc3[68];     //
+} alert_entry;
+
+
+extern void alert_print_list(void);
+extern int alert_active(alert_entry *alert, alert_match_level match_level);
+extern int alert_display_request(void);
+extern int alert_on_screen(void);
+extern int alert_redraw_on_update;
+extern int alert_expire(int curr_sec);
+extern void alert_build_list(Message *fill);
+extern struct hashtable_itr *create_wx_alert_iterator(void);
+extern alert_entry *get_next_wx_alert(struct hashtable_itr *iterator);
+extern int alert_list_count(void);
+
+#endif /* __XASTIR_ALERT_H */
+
+
diff --git a/src/awk.c b/src/awk.c
new file mode 100644
index 0000000..28ed1eb
--- /dev/null
+++ b/src/awk.c
@@ -0,0 +1,1111 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: awk.c,v 1.40 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ */
+
+
+//
+// These functions allocate new memory:
+// ------------------------------------
+// awk_new_symtab
+// awk_declare_sym
+// awk_compile_action
+// awk_new_rule
+// awk_new_program
+// awk_load_program_file
+// awk_load_program_array
+//
+// These functions free memory:
+// ----------------------------
+// awk_free_symtab
+// awk_free_action
+// awk_free_rule
+// awk_free_program
+// awk_uncompile_program (indirectly)
+//
+
+
+/*
+ * This is a library of Awk-like functions to facilitate, for example,
+ * canonicalizing DBF attributes for shapefiles into internal Xastir
+ * values when rendering shapefile maps, or rewriting labels
+ * (e.g. callsigns into tactical calls), etc.
+ *
+ * Uses Philip Hazel's Perl-compatible regular expression library (pcre).  
+ * See www.pcre.org.
+ *
+ * Alan Crosswell, n2ygk at weca.org
+ *
+ * TODO
+ *   permit embedded ;#} inside string assignment (balance delims)
+ *   implement \t, \n, \0[x]nn etc.
+ *   instantiate new symbols instead of ignoring them?
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#ifdef HAVE_LIBPCRE
+#include <stdio.h>
+#include <string.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <ctype.h>
+#include <sys/types.h>
+#include "awk.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define min(a,b) ((a)<(b)?(a):(b))
+
+/*
+ * Symbol table
+ *
+ * Symbols $0-$9 are set by the results of the pcre pattern match.
+ * Other symbols are declared by the caller and bound to variables
+ * in the caller's program.  Make sure they are still in scope when
+ * the pattern matcher is invoked!
+ *
+ * This assumes a very small symbol table, so it is searched linearly.
+ * No fancy hash table lookups are needed.
+ * XXX YES THEY ARE!
+ */
+
+#define MAXSUBS 10              /* $0 thru $9 should be plenty */
+
+
+
+
+
+/*
+ * awk_new_symtab: alloc a symbol table with $0-$9 pre-declared.
+ */
+awk_symtab *awk_new_symtab(void) {
+    awk_symtab *n = calloc(1,sizeof(awk_symtab));
+    static char sym[MAXSUBS][2];
+    int i;
+
+
+    if (!n) {
+        fprintf(stderr, "Couldn't allocate memory in awk_new_symtab()\n");
+        return(NULL);
+    }
+
+    for (i = 0; i < MAXSUBS; i++) {
+        sym[i][0] = i+'0';
+        sym[i][1] = '\0';
+        awk_declare_sym(n,sym[i],STRING,NULL,0); /* just reserve the name */
+    }
+    return n;
+}
+
+
+
+
+
+void awk_free_symtab(awk_symtab *s) {
+    int i;
+
+    for (i = 0; i < AWK_SYMTAB_HASH_SIZE; i++) {
+        awk_symbol *p,*x;
+        
+        for (x = s->hash[i]; x ; x = p) {
+            p = x->next_sym;
+
+            free(x);
+        }
+    }
+}
+
+
+
+
+
+/*
+ * awk_declare_sym: declare a symbol and bind to storage for its value.
+ */
+int awk_declare_sym(awk_symtab *this,
+                const char *name, 
+                enum awk_symtype type,
+                const void *val,
+                const int size) {
+    awk_symbol *s = calloc(1,sizeof(awk_symbol));
+    awk_symbol *p;
+    u_int i;
+
+
+    if (!s) {
+        fprintf(stderr, "Couldn't allocate memory in awk_declare_sym()\n");
+        return -1;
+    }
+
+    s->name = name;
+    s->namelen = strlen(name);
+    s->type = type;
+    s->val = (void *)val;
+    s->size = size;
+    s->len = 0;
+    i = AWK_SYM_HASH(s->name,s->namelen);
+    if ((p = this->hash[i]) != NULL) {
+        s->next_sym = p;        /* insert at top of bucket */
+    }
+    this->hash[i] = s;          /* make (new) top of bucket */
+
+    return 0;
+}
+
+
+
+
+
+/*
+ * awk_find_sym: search symtab for symbol
+ */
+awk_symbol *awk_find_sym(awk_symtab *this,
+                 const char *name,
+                 const int len) {
+    awk_symbol *s;
+    char c;
+
+
+    // Create holding spot for first character in order to speed up
+    // the loop below.  Note that "toupper()" is very slow on some
+    // systems so we took it out of this function to speed things
+    // up.  We evidently don't need case insensitive behavior here
+    // anyway.
+    //
+    c = name[0];
+
+    // Check through the hash
+    //
+    for (s = this->hash[AWK_SYM_HASH(name,len)]; s; s = s->next_sym) {
+
+        // Check length first (fast operation)
+        if (s->namelen == len) {
+
+            // Check first char next (fast operation)
+            if (s->name[0] == c) {
+
+                // Ok so far, test the entire string (slow
+                // operation, case sensitive)
+                if (len == 1)
+                    return s;
+                if (len > 1 && strncmp(s->name+1,name+1,len-1) == 0)
+                    return s;
+            }
+        }
+    }
+    return NULL;
+}
+
+
+
+
+
+/*
+ * awk_set_sym: set a symbol's value (writes into bound storage).
+ * Returns -1 if it was unable to (symbol not found).
+ */
+/*
+int awk_set_sym(awk_symbol *s,
+            const char *val, 
+            const int len) {
+    int l = len + 1;
+    int minlen = min(s->size-1,l);
+
+    if (!s)
+        return -1;
+    switch(s->type) {
+    case STRING:
+        if (minlen > 0) {
+            // Change this to an xastir_snprintf() function if we
+            // need to use this awk_set_sym() function later.
+            // strncpy won't null-terminate the string if there's no
+            // '\0' in the first minlen bytes.
+            strncpy(s->val,val,minlen);
+            s->len = l - 1;
+        }
+        break;
+    case INT:
+        *((int *)s->val) = atoi(val);
+        s->len = sizeof(int);
+        break;
+    case FLOAT:
+        *((double *)s->val) = atof(val);
+        s->len = sizeof(double);
+        break;
+    default:
+        return -1;
+        break;
+    }
+    return 0;
+}
+*/
+
+
+
+
+
+/* 
+ * awk_get_sym: copy (and cast) symbol's value into supplied string buffer 
+ */
+int awk_get_sym(awk_symbol *s,          /* symbol */
+            char *store,        /* store result here */
+            int size,           /* sizeof(*store) */
+            int *len) {         /* store length here */
+    int minlen;
+    char cbuf[128];             /* conversion buffer for int/float */
+    int cbl;
+
+    if (!s)
+        return -1;
+    *store = '\0';
+    *len = 0;
+    switch(s->type) {
+    case STRING:
+        if (s->len > 0) {
+            minlen = min(s->len,size-1);
+            if (minlen > 0) {
+                xastir_snprintf(store,
+                    size,
+                    "%s",
+                    (char *)(s->val));
+                *len = minlen;
+            } else 
+                *len = 0;
+        } else
+            *len = 0;
+        break;
+    case INT:
+        if (s->len > 0) {
+            sprintf(cbuf,"%d",*((int *)s->val));
+            cbl = strlen(cbuf);
+            minlen = min(cbl,size-1);
+            if (minlen > 0) {
+                xastir_snprintf(store,
+                    size,
+                    "%s",
+                    cbuf);
+                *len = minlen;
+            } else
+                *len = 0;
+        } else
+            *len = 0;
+        break;
+    case FLOAT:
+        if (s->len > 0) {
+            sprintf(cbuf,"%f",*((double *)s->val));
+            cbl = strlen(cbuf);
+            minlen = min(cbl,size-1);
+            if (minlen > 0) {
+                xastir_snprintf(store,
+                    size,
+                    "%s",
+                    cbuf);
+                *len = minlen;
+            } else
+                *len = 0;
+        } else
+            *len = 0;
+        break;
+    }
+    return 0;
+}
+
+
+
+
+
+/*
+ *  Action compilation and interpretation.
+ *
+ *  Action grammar is:
+ *  <attr_set> := <attr> "=" value 
+ *  <op>   := "next" | "skip"   (next skips to next field;  skip skips to next
+ *                               record.)
+ *  <stmt> := <attr_set> | <op>
+ *  <stmt_list> := <stmt_list> ";" <stmt> | <stmt>
+ *  <action> := <stmt_list> 
+ *
+ * It's a trivial grammar so no need for yacc/bison.
+ */
+
+/*
+ * awk_compile_stmt: "Compiles" a single action statement.
+ */
+int awk_compile_stmt(awk_symtab *this,
+             awk_action *p,
+             const char *stmt,
+             int len) {
+    const char *s = stmt, *op, *ep;
+  
+    while (isspace((int)*s)) {               /* clean up leading white space */
+        ++s;
+        --len;
+    }
+    ep = &s[len];
+
+    if ((op = strchr(s,'=')) != NULL) {   /* it's either an assignment */
+        const char *val = op+1;
+        while (isspace((int)*val)) {
+            val++;
+            len--;
+        }
+        --op;
+        while (isspace((int)*op) && op>s) op--;
+        p->opcode = ASSIGN;
+        p->dest = awk_find_sym(this,s,(op-s+1));
+        if (!p->dest) {
+            return -1;
+        }
+        p->expr = val;
+        p->exprlen = (ep-val);
+    } else {                    /* or the "next" keyword */
+        const char *r;
+
+        for (r=&s[len-1]; isspace((int)*r); r--,len--) ; /* trim trailing white space */
+        if (len == 4 && strncmp(s,"next",4) == 0) {
+            p->opcode = NEXT;
+        } else if (len == 4 && strncmp(s,"skip",4) == 0) {
+            p->opcode = SKIP;
+        } else {                /* failed to parse */
+            return -1;
+        }
+    }
+    return 0;
+}
+
+
+
+
+
+/*
+ * awk_compile_action: Break the action up into stmts and compile them
+ *  and link them together.
+ */
+awk_action *awk_compile_action(awk_symtab *this, const char *act) {
+    awk_action *p, *first = calloc(1,sizeof(awk_action));
+    const char *cs,*ns;         /* current, next stmt */
+
+
+    p = first;
+
+    if (!p) {
+        fprintf(stderr,"Couldn't allocate memory in awk_compile_action()\n");
+        return NULL;
+    }
+
+    for (cs = ns = act; ns && *ns; cs = (*ns==';')?ns+1:ns) {
+        ns = strchr(cs,';');
+        if (!ns)                        /* end of string */
+            ns = &cs[strlen(cs)];
+        if (awk_compile_stmt(this,p,cs,(ns-cs)) >= 0) {
+            p->next_act = calloc(1,sizeof(awk_action));
+            if (!p->next_act) {
+                fprintf(stderr,"Couldn't allocate memoryin awk_compile_action (2)\n");
+            }
+            p = p->next_act;
+        }
+    } 
+    return first;
+}
+
+
+
+
+
+/*
+ * awk_free_action: Free the compiled action
+ */
+void awk_free_action(awk_action *a) {
+
+    while (a) {
+        awk_action *p = a;
+        a = p->next_act;
+        free(p);
+    }
+}
+
+
+
+
+
+/* 
+ * awk_eval_expr: expand $vars into dest and do type conversions as
+ *  needed.  For strings, just write directly into dest->val.  For
+ *  ints/floats, write to a temp buffer and then atoi() or atof().
+ */
+void awk_eval_expr(awk_symtab *this,
+               awk_symbol *dest, 
+               const char *expr,
+               int exprlen) {
+    int i,dmax,dl,newlen;
+    char c,delim;
+    char *dp;
+    const char *symname;
+    int done;
+    char tbuf[128];
+    awk_symbol *src;
+
+    if (dest && expr) {
+        if (dest->type == STRING) {
+            dp = dest->val; /* just expand directly to result buffer */
+            dmax = dest->size;
+        } else {
+            dp = tbuf;          /* use temp buffer */
+            dmax = sizeof(tbuf);
+        }
+        for (done = 0, i = 0, dl = 0; !done && i < dmax && exprlen > 0; i++) {
+            switch (c = *expr) {
+            case '"':
+            case '\'':          /* trim off string delims */
+                ++expr;
+                --exprlen;
+                if (expr[exprlen-1] == c) /* look for matching close delim */
+                    --exprlen;
+                break;
+            case '$':        /* $... look for variable substitution */
+                if (--exprlen < 0) {
+                    done = 1;
+                    break;
+                }
+                c = *++expr;            /* what's after the $? */
+                switch (c) {
+                case '{':       /* ${var}... currently broken (see TODO) */
+                    delim='}';
+                    ++expr;     /* skip the open delim */
+                    --exprlen;
+                    break;
+                case '(':       /* $(var)... */
+                    delim=')';
+                    ++expr;
+                    --exprlen;
+                    break;
+                default:        /* $var ... */
+                    delim='\0';
+                    break;
+                }
+                /* now search for the var name using closing delim */
+                symname = expr;
+                if (delim == '\0') {    /* no close delim */
+                    while (!isspace((int)*expr) && !ispunct((int)*expr) && exprlen > 0) {
+                        ++expr;
+                        --exprlen;
+                    }
+                } else {                /* search for close delim */
+                    while (*expr != delim && exprlen > 0) {
+                        ++expr;
+                        --exprlen;
+                    }
+                }
+                src = awk_find_sym(this,symname,(expr-symname));
+                if (delim) {    /* gotta skip over the close delim */
+                    ++expr;
+                    --exprlen;
+                }
+                /* make sure src and dest of string copy don't overlap */
+                if (src && src->type == STRING 
+                    && dp >= (char *)src->val 
+                    && dp <= &((char *)src->val)[src->size]) {
+                    char *sp;
+                    int free_it = 0;
+
+                    if ((int)sizeof(tbuf) >= src->size) { /* tbuf big enuf */
+                        sp = tbuf;
+                    } else {    /* tbuf too small */
+                        free_it++;
+                        sp = malloc(src->size);
+                        if (!sp) { /* oh well! */
+                            fprintf(stderr,"Couldn't allocate memory in awk_eval_expr()\n");
+                            break; 
+                        }
+                    }
+                    awk_get_sym(src,sp,src->size,&newlen);
+                    bcopy(sp,dp,newlen); /* now copy it in */
+
+                    // We only want to free it if we malloc'ed it.
+                    if (free_it)
+                        free(sp);
+
+                } else {
+                    awk_get_sym(src,dp,(dmax-dl),&newlen);
+                }
+                dl += newlen;
+                dp += newlen;
+                break;
+            case '\\':          /* \... quote next char */
+                /* XXX TODO: implement \n,\t,\0[x].. etc. */
+                if (--exprlen < 0) {
+                    done = 1;
+                } else {
+                    if (dl < dmax) {    
+                        *dp++ = *expr++;        /* copy the quoted char */
+                        ++dl;
+                    }
+                }
+                break;
+            default:                    /* just copy the character */
+                if (--exprlen < 0) {
+                    done = 1;
+                } else {
+                    if (dl < dmax) {    
+                        *dp++ = *expr++;        /* copy the char */
+                        ++dl;
+                    }
+                }
+                break;
+            }   /* end switch (*expr) */
+        } /* end for loop */
+        *dp = '\0';                     /* null terminate the string */
+        switch(dest->type) {
+        case INT:
+            if (dest->size >= (int)sizeof(int)) {
+                *((int *)dest->val) = atoi(tbuf);
+                dest->len = sizeof(int);
+            }
+            break;
+        case FLOAT:
+            if (dest->size >= (int)sizeof(double)) {
+                *((double *)dest->val) = atof(tbuf);
+                dest->len = sizeof(double);
+            }
+            break;
+        case STRING:            /* already filled val in */
+            dest->len = dl;     /* just update len */
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+
+
+
+
+/*
+ * awk_exec_action: interpret the compiled action.
+ */
+int awk_exec_action(awk_symtab *this, const awk_action *code) {
+    const awk_action *p;
+    int done = 0;
+
+    for (p = code; p && !done; p = p->next_act) {
+        switch (p->opcode) {
+        case NEXT:
+            done = 1;
+            break;
+        case SKIP:
+            done = 2;
+            break;
+        case ASSIGN:
+            awk_eval_expr(this,p->dest,p->expr,p->exprlen);
+            break;
+        case NOOP:
+            break;
+        default:
+            break;
+        }
+    }
+    return done;
+}
+
+
+
+/*
+ * Rules consists of pcre patterns and actions.  A program is
+ *  the collection of rules to apply as a group.
+ */
+
+
+
+/*
+ * awk_new_rule: alloc a rule
+ */
+awk_rule *awk_new_rule(void) {
+    awk_rule *n = calloc(1,sizeof(awk_rule));
+
+    if (!n)
+        fprintf(stderr,"Couldn't allocate memory in awk_new_rule()\n");
+
+    return n;
+}
+
+
+
+
+
+void awk_free_rule(awk_rule *r) {
+
+    if (r) {
+        if (r->flags&AR_MALLOC) {
+            if (r->act)
+                free((char *)r->act);
+            if (r->pattern)
+                free((char *)r->pattern);
+            if (r->tables)
+                pcre_free((void *)r->tables);
+            if (r->re)
+                pcre_free(r->re);
+            if (r->pe)
+                pcre_free(r->pe);
+        }
+        if (r->code)
+            awk_free_action(r->code);
+        free(r);
+    }
+}
+
+
+
+
+
+/*
+ * awk_new_program: alloc a program
+ */
+awk_program *awk_new_program(void) {
+    awk_program *n = calloc(1,sizeof(awk_program));
+
+    if (!n)
+        fprintf(stderr,"Couldn't allocate memory in awk_new_program()\n");
+
+    return n;
+}
+
+
+
+
+
+void awk_free_program(awk_program *rs) {
+    awk_rule *r;
+
+    if (rs) {
+        for (r = rs->head; r; ) {
+            awk_rule *x = r;
+            r = r->next_rule;
+            awk_free_rule(x);
+        }
+        free(rs);
+    }
+}
+
+
+
+
+
+/*
+ * awk_add_rule: add a rule to a program
+ */
+void awk_add_rule(awk_program *this, awk_rule *r) {
+    if (!this)
+        return;
+    if (!this->last) {
+        this->head = this->last = r;
+        r->next_rule = NULL;
+    } else {
+        this->last->next_rule = r;
+        this->last = r;
+    }
+}
+
+
+
+
+
+/*
+ * awk_load_program_array:  load program from an array of rules.  Use this
+ *  to load a program from a statically declared array (see test main
+ *  program for an example).
+ */
+awk_program *awk_load_program_array(awk_rule rules[], /* rules array */
+                                    int nrules) { /* size of array */
+    awk_program *n = awk_new_program();
+    awk_rule *r; 
+
+    if (!n)
+        return NULL;
+
+    for (r = rules; r < &rules[nrules]; r++) {
+        awk_add_rule(n,r);
+    }
+    return n;
+}
+
+
+
+
+
+static void garbage(const char *file, 
+                    int line, 
+                    const char *buf, 
+                    const char *cp) {
+    fprintf(stderr,"%s:%d: parse error:\n",file,line);
+    fputs(buf,stderr);
+    fputc('\n',stderr);
+    while (cp-- > buf)
+        fputc(' ',stderr);
+    fputs("^\n\n",stderr);
+}
+
+
+
+
+
+/*
+ * awk_load_program_file:  load program from a file.
+ *
+ * File syntax is a simplified version of awk:
+ *
+ * {action}
+ * /pattern/ {action}
+ * BEGIN {action}
+ * BEGIN_RECORD {action}
+ * END_RECORD {action}
+ * END {action}
+ * # comments...
+ * (blank lines)
+ *
+ * Note that action can continue onto subsequent lines.
+ */
+awk_program *awk_load_program_file(const char *file) { /* rules filename */
+    awk_program *n = awk_new_program();
+    awk_rule *r; 
+    FILE *f = fopen(file,"r");
+    char in[1024];
+    int line = 0;
+
+    if (!f) {
+        if (n)
+            awk_free_program(n);
+        return NULL;
+    }
+
+    if (!n)
+        return NULL;
+
+    while (fgets(in,sizeof(in),f)) {
+        char *cp = in, *p;
+        int l = strlen(in);
+
+        ++line;
+        if (in[l-1] == '\n')
+            in[--l] = '\0';
+        while (isspace((int)*cp)) ++cp;
+        switch(*cp) {
+        case '\0':              /* empty line */
+            continue;
+        case '#':               /* comment line */
+            continue;
+        case '/':               /* begin regexp */
+            r = awk_new_rule();
+            r->ruletype = REGEXP;
+            p = ++cp;;              /* now points at pattern */
+        more:
+            while (*cp && *cp != '/') ++cp; /* find end of pattern */
+            if (cp > in && cp[-1] == '\\') { /* '/' quoted */
+                ++cp;
+                goto more;      /* so keep going */
+            }
+            if (*cp != '\0')    /* zap end of pattern */
+                *cp++ = '\0';
+            r->pattern = strdup(p);
+
+            break;
+        case 'B':               /* BEGIN? */
+            if (strncmp(cp,"BEGIN_RECORD",12) == 0) {
+                r = awk_new_rule();
+                r->ruletype = BEGIN_REC;
+                cp += 12;        /* strlen("BEGIN_RECORD") */
+            } else if (strncmp(cp,"BEGIN",5) == 0) {
+                r = awk_new_rule();
+                r->ruletype = BEGIN;
+                cp += 5;        /* strlen("BEGIN") */
+            } else {
+                garbage(file,line,in,cp);
+                continue;
+            }
+            break;
+        case 'E':               /* END? */
+            if (strncmp(cp,"END_RECORD",10) == 0) {
+                r = awk_new_rule();
+                r->ruletype = END_REC;
+                cp += 10;        /* strlen("END_RECORD") */
+            } else if (strncmp(cp,"END",3) == 0) {
+                r = awk_new_rule();
+                r->ruletype = END;
+                cp += 3;        /* strlen("END") */
+            } else {
+                garbage(file,line,in,cp);
+                continue;
+            }
+            break;
+        default:
+            garbage(file,line,in,cp);
+            continue;
+        }
+        while (isspace((int)*cp)) ++cp; /* skip whitespace */
+        if (*cp == '{') {
+            p = ++cp;
+        loop: 
+            while (*cp && *cp != '}' && *cp != '#') ++cp;
+            if (*cp == '\0' || *cp == '#') { /* continues on next line */
+                *cp++=' ';       /* replace \n w/white space */
+                if (cp >= &in[sizeof(in)-1]) {
+                    garbage(file,line,"line too long",0);
+                    return n;
+                }
+                if (!fgets(cp,sizeof(in)-(cp-in),f)) {
+                    fprintf(stderr,"%s:%d: failed to parse\n",file,line);
+                    return n;
+                }
+                ++line;
+                goto loop;      /* keep looking for that close bracket */
+            }
+            if (*cp != '\0')    /* zap end of act */
+                *cp++ = '\0';
+
+            r->act = strdup(p);
+
+            r->flags |= AR_MALLOC;
+            /* make sure there's no extraneous junk on the line */
+            while (*cp && isspace((int)*cp)) ++cp;
+            if (*cp == '#' || *cp == '\0')
+                awk_add_rule(n,r);
+            else {
+                garbage(file,line,in,cp);
+                continue;
+            }
+        } else {
+            garbage(file,line,in,cp);
+            continue;
+        }
+    } /* end while */
+    fclose(f);
+    return n;
+}
+
+
+
+
+
+/*
+ * awk_compile_program: Once loaded (from array or file), the program is compiled.  Check for already compiled program.
+ */
+int awk_compile_program(awk_symtab *symtab, awk_program *rs) {
+    const char *error;
+    awk_rule *r;
+    int erroffset;
+
+    if (!rs)
+        return -1;
+
+    rs->symtbl = symtab;
+    for (r = rs->head; r; r = r->next_rule) {
+        if (r->ruletype == REGEXP) {
+            if (r->tables)
+                pcre_free((void *)r->tables);
+            r->tables = pcre_maketables(); /* NLS locale parse tables */
+            if (!r->re)
+                r->re = pcre_compile(r->pattern, /* the pattern */
+                                     0, /* default options */
+                                     &error, /* for error message */
+                                     &erroffset, /* for error offset */
+                                     r->tables); /* NLS locale character tables */
+
+            if (!r->re) {
+                int i;
+                
+                fprintf(stderr,"parse error: %s\n",r->pattern);
+                fprintf(stderr,"             ");
+                for (i = 0; i < erroffset; i++)
+                    fputc(' ',stderr);
+                fprintf(stderr,"^\n");
+                return -1;
+            }
+            if (!r->pe)
+                r->pe = pcre_study(r->re, 0, &error); /* optimize the regexp */
+        } else if (r->ruletype == BEGIN) {
+            rs->begin = r;
+        } else if (r->ruletype == BEGIN_REC) {
+            rs->begin_rec = r;
+        } else if (r->ruletype == END_REC) {
+            rs->end_rec = r;
+        } else if (r->ruletype == END) {
+            rs->end = r;
+        }
+        if (!r->code)
+            r->code = awk_compile_action(rs->symtbl,r->act); /* compile the action */
+    }
+    return 0;
+}
+
+
+
+
+
+/* 
+ * awk_uncompile_program: Frees the compiled program (patterns and stmts)
+ * but keeps the program text loaded so it can be recompiled (e.g. with a
+ * new symtbl).
+ */
+void awk_uncompile_program(awk_program *p) {
+    awk_rule *r;
+
+    if (!p)
+        return;
+
+    for (r = p->head; r; r = r->next_rule) {
+        if (r->ruletype == REGEXP) {
+            if (r->tables)
+                pcre_free((void *)r->tables);
+            r->tables = NULL;
+            if (r->re)
+                pcre_free(r->re);
+            r->re = NULL;
+            if (r->pe)
+                pcre_free(r->pe);
+            r->pe = NULL;
+        }
+        if (r->code)
+            awk_free_action(r->code); /* free the action */
+        r->code = NULL;
+    }
+}
+
+
+
+
+
+/*
+ * awk_exec_program: apply the program to the given buffer
+ */
+int awk_exec_program(awk_program *this, char *buf, int len) {
+    int i,rc,done = 0;
+    awk_rule *r;
+    int ovector[3*MAXSUBS];
+#define OVECLEN (sizeof(ovector)/sizeof(ovector[0]))
+
+    if (!this || !buf || len <= 0)
+        return 0;
+    
+    for (r = this->head; r && !done ; r = r->next_rule) {
+        if (r->ruletype == REGEXP) {
+            rc = pcre_exec(r->re,r->pe,buf,len,0,0,ovector,OVECLEN);
+            /* assign values to as many of $0 thru $9 as were set */
+            /* XXX - avoid calling awk_find_sym for these known values */
+            for (i = 0; rc > 0 && i < rc && i < MAXSUBS ; i++) {
+                char symname[2];
+                awk_symbol *s;
+                
+                symname[0] = i + '0';
+                symname[1] = '\0';
+                s = awk_find_sym(this->symtbl,symname,1);
+                s->val = &buf[ovector[2*i]];
+                s->len = ovector[2*i+1]-ovector[2*i];
+            }
+            /* clobber the remaining $n thru $9 */
+            for (; i < MAXSUBS; i++) {
+                char symname[10];
+                awk_symbol *s;
+                
+                symname[0] = i + '0';
+                symname[1] = '\0';
+                s = awk_find_sym(this->symtbl,symname,1);
+                s->len = 0;
+            }
+            if (rc > 0) {
+                done = awk_exec_action(this->symtbl,r->code);
+            }
+        }
+    }
+    return done;
+}
+
+
+
+
+
+/*
+ * awk_exec_begin_record: run the special BEGIN_RECORD rule, if any
+ */
+int awk_exec_begin_record(awk_program *this) {
+    if (this && this->begin_rec)
+        return awk_exec_action(this->symtbl,this->begin_rec->code);
+    else
+        return 0;
+}
+
+
+
+
+
+/*
+ * awk_exec_begin: run the special BEGIN rule, if any
+ */
+int awk_exec_begin(awk_program *this) {
+    if (this && this->begin)
+        return awk_exec_action(this->symtbl,this->begin->code);
+    else
+        return 0;
+}
+
+
+
+
+
+/*
+ * awk_exec_end_record: run the special END_RECORD rule, if any
+ */
+int awk_exec_end_record(awk_program *this) {
+    if (this && this->end_rec)
+        return awk_exec_action(this->symtbl,this->end_rec->code);
+    else
+        return 0;
+}
+
+
+
+
+
+/*
+ * awk_exec_end: run the special END rule, if any
+ */
+int awk_exec_end(awk_program *this) {
+    if (this && this->end)
+        return awk_exec_action(this->symtbl,this->end->code);
+    else
+        return 0;
+}
+
+
+#endif /* HAVE_LIBPCRE */
+
+
diff --git a/src/awk.h b/src/awk.h
new file mode 100644
index 0000000..7fb98dd
--- /dev/null
+++ b/src/awk.h
@@ -0,0 +1,127 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: awk.h,v 1.14 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ */
+#ifndef AWK_H
+#define AWK_H
+#ifdef HAVE_PCRE_H
+#include <pcre.h>
+#endif
+#ifdef HAVE_PCRE_PCRE_H
+#include <pcre/pcre.h>
+#endif
+
+enum awk_symtype {STRING,INT,FLOAT}; /* the only data types */
+
+typedef struct awk_symbol_ {	/* symbol table entry */
+    struct awk_symbol_ *next_sym; /* linked list */
+    const char *name;           /* name of the symbol */
+    int namelen;                /* length of the name */
+    enum awk_symtype type;	/* data type of symbol value */
+    void *val;                  /* storage for the value */
+    int size;                   /* size of *val */
+    int len;                    /* current length of *val */
+} awk_symbol;
+
+#define AWK_SYMTAB_HASH_SIZE 0xff
+typedef struct awk_symtab_ {	/* symbol table anchor */
+    awk_symbol *hash[AWK_SYMTAB_HASH_SIZE];
+} awk_symtab;
+
+#define AWK_SYM_HASH(n,l) ((*n)&AWK_SYMTAB_HASH_SIZE)
+//#define AWK_SYM_HASH(n,l) ((n[0]+((l>1)?n[1]:0))&AWK_SYMTAB_HASH_SIZE)
+
+typedef struct awk_action_ {	/* a program statement */
+    struct awk_action_ *next_act;
+    enum {NOOP=0, NEXT, SKIP, ASSIGN} opcode;
+    awk_symbol *dest;		/* destination of assignment */
+    const char *expr;           /* value setting expression */
+    int exprlen;                /* length of expression */
+} awk_action;
+
+typedef struct awk_rule_ {
+    struct awk_rule_ *next_rule;    /* linked list */
+    enum {BEGIN,BEGIN_REC,END_REC,END,REGEXP} ruletype;
+    const char *pattern;        /* pcre pattern string */
+    const u_char *tables;       /* pcre NLS tables */
+    pcre *re;                   /* pcre compiled pattern */
+    pcre_extra *pe;             /* pcre optimized pattern */
+    const char *act;            /* the program string */
+    awk_action *code;		/* compiled program */
+    int flags;			/* some flags */
+#define AR_MALLOC 0x01		/* pattern, act were malloc'd by me */
+} awk_rule;
+
+typedef struct awk_program_ {	/* anchor for the list of rules */
+    awk_symtab *symtbl;	       /* the symbol table for this program */
+    awk_rule *head;		/* head of list */
+    awk_rule *last;		/* last element */
+    awk_rule *begin;		/* optional BEGIN rule */
+    awk_rule *begin_rec;        /* optional BEGIN_RECORD rule */
+    awk_rule *end_rec;		/* optional END_RECORD rule */
+    awk_rule *end;		/* optional END rule */
+} awk_program;
+
+extern awk_symtab *awk_new_symtab(void);
+extern void awk_free_symtab(awk_symtab *s);
+extern int awk_declare_sym(awk_symtab *this,
+                       const char *name, 
+                       enum awk_symtype type,
+                       const void *val,
+                       const int size);
+extern awk_symbol *awk_find_sym(awk_symtab *this,
+                        const char *name,
+                        const int len);
+extern int awk_set_sym(awk_symbol *s,
+                   const char *val, 
+                   const int len);
+extern int awk_get_sym(awk_symbol *s, 
+                   char *store,
+                   int size,   
+                   int *len);   
+extern int awk_compile_stmt(awk_symtab *this,
+                    awk_action *p,
+                    const char *stmt,
+                    int len);
+extern awk_action *awk_compile_action(awk_symtab *this, const char *act);
+extern void awk_free_action(awk_action *a);
+extern void awk_eval_expr(awk_symtab *this,
+		      awk_symbol *dest, 
+		      const char *expr,
+		      int exprlen);
+extern int awk_exec_action(awk_symtab *this, const awk_action *code);
+extern awk_rule *awk_new_rule(void);
+extern void awk_free_rule(awk_rule *r);
+extern awk_program *awk_new_program(void);
+extern void awk_free_program(awk_program *rs);
+void awk_add_rule(awk_program *this, awk_rule *r);
+extern awk_program *awk_load_program_array(awk_rule rules[],int nrules);
+extern awk_program *awk_load_program_file(const char *file);
+extern int awk_compile_program(awk_symtab *symtbl,awk_program *rs);
+extern void awk_uncompile_program(awk_program *rs);
+extern int awk_exec_program(awk_program *this, char *buf, int len);
+extern int awk_exec_begin_record(awk_program *this);
+extern int awk_exec_end_record(awk_program *this);
+extern int awk_exec_begin(awk_program *this);
+extern int awk_exec_end(awk_program *this);
+
+#endif /*!AWK_H*/
diff --git a/src/bulletin_gui.c b/src/bulletin_gui.c
new file mode 100644
index 0000000..2eb82fc
--- /dev/null
+++ b/src/bulletin_gui.c
@@ -0,0 +1,804 @@
+/*
+ * $Id: bulletin_gui.c,v 1.46 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <ctype.h>
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_XBAE_MATRIX_H
+#include <Xbae/Matrix.h>
+#endif  // HAVE_XBAE_MATRIX_H
+
+#include <X11/Xatom.h>
+#include <X11/Shell.h>
+
+#ifdef    HAVE_LIBINTL_H
+#include <libintl.h>
+#define    _(x)    gettext(x)
+#else   // HAVE_LIBINTL_H
+#define    _(x)    (x)
+#endif  // HAVE_LIBINTL_H
+
+#include "xastir.h"
+#include "main.h"
+#include "bulletin_gui.h"
+#include "interface.h"
+#include "util.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+Widget Display_bulletins_dialog = NULL;
+Widget Display_bulletins_text = NULL;
+Widget dist_data = NULL;
+Widget zero_bulletin_data = NULL;
+
+static xastir_mutex display_bulletins_dialog_lock;
+
+int bulletin_range;
+int new_bulletin_flag = 0;
+int new_bulletin_count = 0;
+static time_t first_new_bulletin_time = 0;
+static time_t last_new_bulletin_time = 0;
+
+
+
+
+
+void bulletin_gui_init(void)
+{
+    init_critical_section(&display_bulletins_dialog_lock);
+}
+
+
+
+
+
+// Function called from check_for_new_bulletins() if a new bulletin
+// has come in that's within our range and we have
+// pop_up_new_bulletins enabled.  This causes the Bulletins() dialog
+// to come up and rescan the message database for all bulletins that
+// are within the radius specified.  By the time this gets called
+// we've already waited a few seconds to try to get the posit to
+// come in that matches the bulletin, and have then checked the
+// database to make sure that the new bulletins received are still
+// within our range.
+void popup_bulletins(void) {
+    if ((Display_bulletins_dialog == NULL)) {   // Dialog not up
+
+        // Bring up the dialog
+        Bulletins( (Widget)NULL, (XtPointer)NULL, (XtPointer)NULL );
+    }
+}
+
+
+
+
+
+void bulletin_message(char *call_sign, char *tag, char *packet_message, time_t sec_heard) {
+    char temp[200];
+    char temp_my_course[10];
+    char temp_text[30];
+    double distance;
+    XmTextPosition pos, eol, eod;
+    struct tm *tmp;
+    time_t timehd;
+    char time_str[20];
+    char *temp_ptr;
+
+
+    timehd=sec_heard;
+    tmp = localtime(&timehd);
+
+    if ( (packet_message != NULL) && (strlen(packet_message) > MAX_MESSAGE_LENGTH) ) {
+        if (debug_level & 1)
+            fprintf(stderr,"bulletin_message:  Message length too long\n");
+        return;
+    }
+
+    (void)strftime(time_str,sizeof(time_str),"%b %d %H:%M",tmp);
+
+    distance = distance_from_my_station(call_sign,temp_my_course);
+    xastir_snprintf(temp, sizeof(temp), "%-9s:%-4s (%s %6.1f %s) %s\n",
+            call_sign, &tag[3], time_str, distance,
+            english_units ? langcode("UNIOP00004"): langcode("UNIOP00005"),
+            packet_message);
+
+// Operands of <= have incompatible types (double, int):
+    if ( ( ((int)distance <= bulletin_range) && (distance > 0.0) )
+            || (view_zero_distance_bulletins && distance == 0.0)
+            || ( (bulletin_range == 0) && (distance > 0.0) ) ) {
+
+begin_critical_section(&display_bulletins_dialog_lock, "bulletin_gui.c:bulletin_message" );
+
+        if ((Display_bulletins_dialog != NULL) && Display_bulletins_text != NULL) {   // Dialog is up
+
+            eod = XmTextGetLastPosition(Display_bulletins_text);
+            xastir_snprintf(temp_text,
+                sizeof(temp_text),
+                "%s",
+                temp);
+
+            temp_text[14] = '\0';
+
+            // Look for this bulletin ID.  "pos" will hold the first char position if found.
+            if (XmTextFindString(Display_bulletins_text, 0, temp_text, XmTEXT_FORWARD, &pos)) {
+
+                // Found it, so now find the end-of-line for it
+                if (XmTextFindString(Display_bulletins_text, pos, "\n", XmTEXT_FORWARD, &eol))
+                  eol++;
+                else 
+                  eol = eod;
+
+                // And replace the old bulletin with a new copy
+                if (eol == eod)
+                  temp[strlen(temp)-1] = '\0';
+                XmTextReplace(Display_bulletins_text, pos, eol, temp);
+            } else {
+                for (pos = 0; strlen(temp_text) > 12 && pos < eod;) {
+                    if (XmCOPY_SUCCEEDED == XmTextGetSubstring(Display_bulletins_text, pos, 14, 30, temp_text)) {
+                        if (temp_text[0] && strncmp(temp, temp_text, 14) < 0)
+                            break;
+                    } else
+                        break;
+
+                    if (XmTextFindString(Display_bulletins_text, pos, "\n", XmTEXT_FORWARD, &eol))
+                      pos = ++eol;
+                    else
+                      pos = eod;
+                }
+                if (pos == eod) {
+                  temp[strlen(temp)-1] = '\0'; // End-of-Data remove trailing LF
+                  if (pos > 0) { // Already have text. Need to insert LF between items
+                    memmove(&temp[1], temp, strlen(temp));
+                    temp[0] = '\n';
+                  }
+                }
+                XmTextInsert(Display_bulletins_text,pos,temp);
+            }
+            temp_ptr = XmTextFieldGetString(dist_data);
+            bulletin_range = atoi(temp_ptr);
+            XtFree(temp_ptr);
+        }
+
+end_critical_section(&display_bulletins_dialog_lock, "bulletin_gui.c:bulletin_message" );
+
+    }
+}
+
+
+
+
+
+static void bulletin_line(Message *fill) {
+    bulletin_message(fill->from_call_sign, fill->call_sign, fill->message_line, fill->sec_heard);
+}
+
+
+
+
+
+static void scan_bulletin_file(void) {
+    mscan_file(MESSAGE_BULLETIN, bulletin_line);
+}
+
+
+
+
+
+// bulletin_data_add
+//
+// Adds the bulletin to the message database.  Updates the Bulletins
+// dialog if it is up.  Causes Bulletins dialog to pop up if the
+// bulletin matches certain parameters.
+//
+long temp_bulletin_record;
+
+void bulletin_data_add(char *call_sign, char *from_call, char *data,
+        char *seq, char type, char from) {
+    int distance = -1;
+
+    // Add to the message database
+    (void)msg_data_add(call_sign,
+        from_call,
+        data,
+        " ",    // Need something here.  Empty string no good.
+        MESSAGE_BULLETIN,
+        from,
+        &temp_bulletin_record);
+
+    // If we received a NEW bulletin
+    if (temp_bulletin_record == -1L) {
+        char temp[10];
+
+
+//fprintf(stderr,"We think it's a new bulletin!\n");
+ 
+        // We add to the distance in order to come up with 0.0
+        // if the distance is not known at all (no position
+        // found yet).
+        distance = (int)(distance_from_my_station(from_call,temp) + 0.9999);
+
+        if ( (bulletin_range == 0)
+                || (distance <= bulletin_range && distance > 0)
+                || (view_zero_distance_bulletins && distance == 0.0) ) {
+            // We have a _new_ bulletin that's within our
+            // current range setting.  Note that it's also possible
+            // to have a zero distance for the bulletin (we haven't
+            // heard a posit from the sending station yet), then get
+            // a posit later.
+
+            if (debug_level & 1) {
+                fprintf(stderr,"New bulletin:");
+                fprintf(stderr,"%05d:%9s:%c:%c:%9s:%s:%s  ",
+                    distance,
+                    call_sign,
+                    type,
+                    from,
+                    from_call,
+                    data,
+                    seq);
+                fprintf(stderr,"  Distance ok:%d miles",distance);
+            }
+
+            if (pop_up_new_bulletins) {
+//fprintf(stderr,"bulletin_data_add: popping up bulletins\n");
+                popup_bulletins();
+                if (debug_level & 1)
+                    fprintf(stderr,"\n");
+            }
+            else {
+                if (debug_level & 1) {
+                    fprintf(stderr,", but popups disabled!\n");
+                }
+            }
+        }
+        else {
+//            fprintf(stderr,", but distance didn't work out!\n");
+        }
+    }
+    // Update the View->Bulletins dialog if it's up
+    bulletin_message(from_call,
+        call_sign,
+        data,
+        sec_now());
+
+}
+
+
+
+
+
+// Find each bulletin that is within our range _and_ within our time
+// parameters for new bulletins.  Count them only.  Results returned
+// in the new_bulletin_count variable.
+void count_bulletin_messages(char *call_sign, char *packet_message, time_t sec_heard) {
+    char temp_my_course[10];
+    double distance;
+
+    if ( (packet_message != NULL) && (strlen(packet_message) > MAX_MESSAGE_LENGTH) ) {
+        if (debug_level & 1)
+            fprintf(stderr,"bulletin_message:  Message length too long\n");
+        return;
+    }
+
+    distance = distance_from_my_station(call_sign,temp_my_course);
+
+// Operands of <= have incompatible types (double, int):
+    if ( ( ((int)distance <= bulletin_range) && (distance > 0.0) )
+            || (view_zero_distance_bulletins && distance == 0.0)
+            || ( (bulletin_range == 0) && (distance > 0.0) ) ) {
+
+        // Is it newer than our first new_bulletin timestamp?
+        if (sec_heard >= first_new_bulletin_time) {
+            new_bulletin_count++;
+        }
+    }
+}
+
+
+
+
+
+static void count_bulletin_line(Message *fill) {
+    count_bulletin_messages(fill->from_call_sign, fill->message_line, fill->sec_heard);
+}
+
+
+
+
+
+static void count_new_bulletins(void) {
+    mscan_file(MESSAGE_BULLETIN, count_bulletin_line);
+}
+
+
+
+
+
+// Function called by mscan_file for each bulletin with zero for the
+// position_known flag.  See next function find_zero_position_bulletins()
+//
+static void zero_bulletin_processing(Message *fill) {
+    DataRow *p_station; // Pointer to station data
+
+
+    if (!fill->position_known) {
+
+        //fprintf(stderr,"Position unknown: %s:%s\n",
+        //    fill->from_call_sign,
+        //    fill->message_line);
+
+        // Check to see if we _now_ have a position for this non-new
+        // bulletin.  If so, change the position_known flag on that
+        // record to a one, update the record, set the proper timers
+        // and then schedule a popup if it fits within our current
+        // parameters.
+
+        if ( search_station_name(&p_station,fill->from_call_sign,1) ) {
+            // Found a bulletin for which we get to fill in a new
+            // position!
+
+            if ( (p_station->coord_lon == 0l)
+                    && (p_station->coord_lat == 0l) ) {
+                //fprintf(stderr,"Found it but still no valid position!\n");
+            }
+            else { // Found valid position for this bulletin
+
+                //fprintf(stderr,"Found it now! %s:%s\n",
+                //    fill->from_call_sign,
+                //    fill->message_line);
+
+                // Mark it as found
+                fill->position_known = 1;
+
+                // Fake the timestamp so that we check messages back
+                // to at least this one we just found.  Allow for the
+                // fact that we might find several older messages, so
+                // we only want to keep taking the timestamp backwards
+                // in time here.
+                if (first_new_bulletin_time > (fill->sec_heard) )
+                    first_new_bulletin_time = fill->sec_heard;
+
+                // Check whether we really wish to pop them up
+                if (pop_up_new_bulletins) { 
+                    int distance;
+                    char temp_my_course[10];
+ 
+                    distance = (int)(distance_from_my_station(fill->from_call_sign,
+                        temp_my_course) + 0.9999);
+
+                    if ( (bulletin_range == 0)
+                            || (distance <= bulletin_range && distance > 0) ) {
+                        if (debug_level & 1) {
+                            fprintf(stderr,"Filled in distance for earlier bulletin:%d miles\n",
+                                distance);
+                        }
+
+                        // If view_zero_distance_bulletins was not
+                        // turned on, then we probably haven't seen
+                        // this bulletin until now.  Popup up the
+                        // Bulletin dialog.
+                        if (!view_zero_distance_bulletins) {
+//fprintf(stderr,"zero_bulletin_processing: popping up bulletins\n");
+                            popup_bulletins();
+                        }
+                    }
+                }
+            }
+        }
+        else {
+            // No position known for the bulletin.  Skip it for now.
+            //fprintf(stderr,"Still not found\n");
+        }
+    }
+}
+
+
+
+
+
+// Find all bulletins that have a zero for the position_known flag.
+// Calls the function above for each bulletin.
+//
+static void find_zero_position_bulletins(void) {
+    mscan_file(MESSAGE_BULLETIN, zero_bulletin_processing);
+}
+
+
+
+
+
+// Function called by main.c:UpdateTime().  Checks whether enough
+// time has passed since the last new bulletin came in (so that the
+// posit for it might come in as well).  If so, checks for bulletins
+// that are newer than first_new_bulletin_time and fit within our
+// range.  If any found, it updates the Bulletins dialog.
+time_t last_bulletin_check = (time_t)0l;
+
+void check_for_new_bulletins(int curr_sec) {
+
+    // Check every 15 seconds max
+    if ( (last_bulletin_check + 15) > curr_sec ) {
+        return;
+    }
+    last_bulletin_check = curr_sec;
+
+    // Look first to see if we might be able to fill in positions on
+    // any older bulletins, then cause a popup for those that fit
+    // our parameters.  The below function sets new_bulletin_flag if
+    // it is able to fill in a distance for an older bulletin.
+// Note:  This is time-consuming!
+    find_zero_position_bulletins();
+
+    // Any new bulletins to check?  If not, return
+    if (!new_bulletin_flag) {
+        return;
+    }
+
+    // Enough time passed since most recent bulletin?  Need to have
+    // enough time to perhaps fill in a distance for each bulletin.
+    if ( (last_new_bulletin_time + 15) > curr_sec ) {
+        //fprintf(stderr,"Not enough time has passed\n");
+        return;
+    }
+
+    // If we get to here, then we think we may have at least one new
+    // bulletin, and the latest arrived more than XX seconds ago
+    // (currently 15 seconds).  Check for bulletins which have
+    // timestamps equal to or newer than first_new_bulletin_time and
+    // fit within our range.
+
+    new_bulletin_count = 0;
+
+//fprintf(stderr,"Checking for new bulletins\n");
+
+    count_new_bulletins();
+
+//fprintf(stderr,"%d new bulletins found\n",new_bulletin_count);
+
+    if (new_bulletin_count) {
+//fprintf(stderr,"check_for_new_bulletins: popping up bulletins\n");
+        popup_bulletins();
+
+        if (debug_level & 1)
+            fprintf(stderr,"New bulletins (%d) caused popup!\n",new_bulletin_count);
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"No bulletin popup generated.\n");
+    }
+
+    // Reset so that we can do it all over again later.  We need
+    // mutex locks protecting these variables.
+    first_new_bulletin_time = last_new_bulletin_time + 1;
+    new_bulletin_flag = 0;
+}
+
+
+
+
+
+void Display_bulletins_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    char *temp_ptr;
+
+
+    // Keep this.  It stores the range in a global variable when we destroy the dialog.
+    temp_ptr = XmTextFieldGetString(dist_data);
+    bulletin_range = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    XtPopdown(shell);
+
+begin_critical_section(&display_bulletins_dialog_lock, "bulletin_gui.c:Display_bulletins_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    Display_bulletins_dialog = (Widget)NULL;
+
+end_critical_section(&display_bulletins_dialog_lock, "bulletin_gui.c:Display_bulletins_destroy_shell" );
+
+}
+
+
+
+
+
+void Display_bulletins_change_range(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char *temp_ptr;
+
+
+    // Keep this.  It stores the range in a global variable when we destroy the dialog.
+    temp_ptr = XmTextFieldGetString(dist_data);
+    bulletin_range = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    view_zero_distance_bulletins = (int)XmToggleButtonGetState(zero_bulletin_data);
+    //fprintf(stderr,"%d\n",view_zero_distance_bulletins);
+
+    Display_bulletins_destroy_shell( widget, clientData, callData);
+    Bulletins( widget, clientData, callData);
+}
+
+
+
+
+
+void  Zero_Bulletin_Data_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        view_zero_distance_bulletins = atoi(which);
+    else
+        view_zero_distance_bulletins = 0;
+
+    Display_bulletins_destroy_shell( widget, Display_bulletins_dialog, callData);
+    Bulletins( widget, clientData, callData);
+}
+
+
+
+
+ 
+void Bulletins(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget pane, form, button_range, button_close, dist, dist_units;
+    unsigned int n;
+    Arg args[50];
+    Atom delw;
+    char temp[10];
+
+
+    if(!Display_bulletins_dialog) {
+
+
+begin_critical_section(&display_bulletins_dialog_lock, "bulletin_gui.c:Bulletins" );
+
+
+        Display_bulletins_dialog = XtVaCreatePopupShell(langcode("BULMW00001"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Bulletins pane",
+                xmPanedWindowWidgetClass,
+                Display_bulletins_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        form =  XtVaCreateWidget("Bulletins form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        dist = XtVaCreateManagedWidget(langcode("BULMW00002"),
+                xmLabelWidgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        dist_data = XtVaCreateManagedWidget("dist_data", 
+                xmTextFieldWidgetClass, 
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 8,
+                XmNwidth, ((8*7)+2),
+                XmNmaxLength, 8,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, dist,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        dist_units = XtVaCreateManagedWidget((english_units?langcode("UNIOP00004"):langcode("UNIOP00005")),
+                xmLabelWidgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, dist_data,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_range = XtVaCreateManagedWidget(langcode("BULMW00003"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, dist_units,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        zero_bulletin_data = XtVaCreateManagedWidget(langcode("WPUPCFD029"),
+                xmToggleButtonWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, button_range,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(zero_bulletin_data,XmNvalueChangedCallback,Zero_Bulletin_Data_toggle,"1");
+        if (view_zero_distance_bulletins)
+            XmToggleButtonSetState(zero_bulletin_data,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(zero_bulletin_data,FALSE,FALSE);
+ 
+        n=0;
+        XtSetArg(args[n], XmNrows, 15); n++;
+        XtSetArg(args[n], XmNcolumns, 108); n++;
+        XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
+        XtSetArg(args[n], XmNeditable, FALSE); n++;
+        XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
+        XtSetArg(args[n], XmNwordWrap, TRUE); n++;
+        XtSetArg(args[n], XmNscrollHorizontal, TRUE); n++;
+        XtSetArg(args[n], XmNscrollVertical, TRUE); n++;
+        XtSetArg(args[n], XmNcursorPositionVisible, FALSE); n++;
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
+        XtSetArg(args[n], XmNtopWidget, dist); n++;
+        XtSetArg(args[n], XmNtopOffset, 20); n++;
+        XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNbottomOffset, 30); n++;
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNleftOffset, 5); n++;
+        XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNrightOffset, 5); n++;
+        XtSetArg(args[n], XmNforeground, MY_FG_COLOR); n++;
+        XtSetArg(args[n], XmNbackground, MY_BG_COLOR); n++;
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+
+
+        Display_bulletins_text = XmCreateScrolledText(form,
+                "Bulletins text",
+                args,
+                n);
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_range, XmNactivateCallback, Display_bulletins_change_range, Display_bulletins_dialog);
+        XtAddCallback(button_close, XmNactivateCallback, Display_bulletins_destroy_shell, Display_bulletins_dialog);
+
+        pos_dialog(Display_bulletins_dialog);
+
+        delw = XmInternAtom(XtDisplay(Display_bulletins_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(Display_bulletins_dialog, delw, Display_bulletins_destroy_shell, (XtPointer)Display_bulletins_dialog);
+
+        xastir_snprintf(temp, sizeof(temp), "%d", bulletin_range);
+        XmTextFieldSetString(dist_data, temp);
+
+        XtManageChild(form);
+        XtManageChild(Display_bulletins_text);
+        XtVaSetValues(Display_bulletins_text, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+        redraw_on_new_packet_data=1;
+        XtPopup(Display_bulletins_dialog,XtGrabNone);
+
+end_critical_section(&display_bulletins_dialog_lock, "bulletin_gui.c:Bulletins" );
+
+        scan_bulletin_file();
+
+        // Move focus to the Close button.  This appears to
+        // highlight the button fine, but we're not able to hit the
+        // <Enter> key to have that default function happen.  Note:
+        // We _can_ hit the <SPACE> key, and that activates the
+        // option.
+        //XmUpdateDisplay(Display_bulletins_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    }  else {
+        (void)XRaiseWindow(XtDisplay(Display_bulletins_dialog), XtWindow(Display_bulletins_dialog));
+    }
+}
+
+
diff --git a/src/bulletin_gui.h b/src/bulletin_gui.h
new file mode 100644
index 0000000..e2500c3
--- /dev/null
+++ b/src/bulletin_gui.h
@@ -0,0 +1,38 @@
+/*
+ * $Id: bulletin_gui.h,v 1.16 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef __XASTIR_BULLETIN_GUI_H
+#define __XASTIR_BULLETIN_GUI_H
+
+extern int bulletin_range;
+
+
+// From bulletin_gui.c
+extern void bulletin_gui_init(void);
+extern void bulletin_data_add(char *call_sign, char *from_call, char *data, char *seq, char type, char from);
+extern void check_for_new_bulletins(int current_sec);
+
+#endif  // __XASTIR_BULLETIN_GUI_H
+
+
diff --git a/src/color.c b/src/color.c
new file mode 100644
index 0000000..da06aed
--- /dev/null
+++ b/src/color.c
@@ -0,0 +1,304 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: color.c,v 1.23 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "color.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+static color_load color_choice[MAX_COLORS];
+static int colors_loaded;
+static int rm, gm, bm; // rgb masks
+static int rs, gs, bs; // rgb shifts
+int visual_depth;
+
+
+
+
+
+/**********************************************************************************/
+/* load color file                                                                */
+/* load the colors to be used with Xastir                                         */
+/* Return 1 if good 0 if not found or error                                       */
+/**********************************************************************************/
+
+int load_color_file(void) {
+    FILE *f;
+    char temp[40];
+    int r,g,b;
+    char colorname[50];
+    int ok,x;
+
+    xastir_snprintf(temp, sizeof(temp), "config/xastir.rgb");
+    colors_loaded=0;
+    ok=1;
+    f=fopen(get_data_base_dir(temp),"r");
+    if (f!=NULL) {
+        while (!feof(f) && ok) {
+            if (fscanf(f,"%d %d %d %49s",&r,&g,&b,colorname)==4) {
+                if (colors_loaded < MAX_COLORS) {
+                    for (x=0; x<colors_loaded;x++) {
+                        if (strcmp(color_choice[x].colorname,colorname)==0) {
+                            ok=0;
+                            fprintf(stderr,"Error! Duplicate color found %s\n",colorname);
+                        }
+                    }
+                    if (ok) {
+                       
+                        xastir_snprintf(color_choice[colors_loaded].colorname,
+                            MAX_COLORNAME,
+                            "%s",
+                            colorname);
+
+// Do we really want to assign to unsigned short int's here?
+                        color_choice[colors_loaded].color.red=(unsigned short)(r*257);
+                        color_choice[colors_loaded].color.blue=(unsigned short)(b*257);
+                        color_choice[colors_loaded].color.green=(unsigned short)(g*257);
+                        colors_loaded++;
+                    }
+                } else {
+                    ok=0;
+                    fprintf(stderr,"Error! MAX_COLORS has been exceeded\n");
+                }
+            }
+        }
+        (void)fclose(f);
+    } else {
+        ok=0;
+        fprintf(stderr,"Error! can not find color file: %s\n", get_data_base_dir(temp));
+    }
+    return(ok);
+}
+
+
+
+
+
+/**********************************************************************************/
+/* GetPixelbyName                                                                 */
+/* get color for the named choice                                                 */
+/* return the pixel data                                                          */
+/**********************************************************************************/
+
+Pixel GetPixelByName( Widget w, char *colorname) {
+    Display *dpy = XtDisplay(w);
+    int scr = DefaultScreen(dpy);
+    char warning[200];
+    int i,found;
+
+    found=-1;
+    i=0;
+
+    do {
+        if (strcmp(color_choice[i].colorname, colorname)==0)
+            found=i;
+
+        i++;
+    } while (i<colors_loaded && found <0);
+
+    if (found >= 0) {
+
+        // XFreeColors() here generates an error.  Why?
+        // "BadAccess (attempt to access private resource denied)"
+        // XFreeColors(dpy, cmap, &(color_choice[found].color.pixel),1,0);
+
+        if (XAllocColor(dpy,cmap,&color_choice[found].color)) {
+            return(color_choice[found].color.pixel);
+        }
+        else {
+            xastir_snprintf(warning, sizeof(warning), "Couldn't allocate color %s", colorname);
+            XtWarning(warning);
+            return(BlackPixel(dpy,scr));
+        }
+    }
+    else {
+        xastir_snprintf(warning, sizeof(warning), "Couldn't find color %s", colorname);
+        XtWarning(warning);
+        return(BlackPixel(dpy,scr));
+    }
+}
+
+
+
+
+
+void setup_visual_info(Display* dpy, int scr) {
+    int visuals_matched, i, j;
+    XVisualInfo *visual_list, *vp;
+    XVisualInfo visual_template;
+    rm = gm = bm = rs = gs = bs = 0;
+
+    visual_list = XGetVisualInfo(dpy, VisualNoMask, &visual_template, &visuals_matched);
+    if (visuals_matched) {
+        if (debug_level & 16)
+            fprintf(stderr,"Found %d visuals\n", visuals_matched);
+
+        for (i = 0; i < visuals_matched; i++) {
+            vp = &visual_list[i];
+
+            if (vp->visualid == XVisualIDFromVisual(DefaultVisual(dpy, scr))) {
+                if (vp->class == TrueColor ||
+                    vp->class == DirectColor) {
+                    if (vp->red_mask   == 0xf800 &&
+                        vp->green_mask == 0x07e0 &&
+                        vp->blue_mask  == 0x001f)
+                        visual_type = RGB_565;
+                    else if (vp->red_mask   == 0x7c00 &&
+                             vp->green_mask == 0x03e0 &&
+                             vp->blue_mask  == 0x001f)
+                        visual_type = RGB_555;
+                    else if (vp->red_mask   == 0xff0000 &&
+                             vp->green_mask == 0x00ff00 &&
+                             vp->blue_mask  == 0x0000ff)
+                        visual_type = RGB_888;
+                    else {
+                        rm = vp->red_mask;
+                        gm = vp->green_mask;
+                        bm = vp->blue_mask;
+                        for (j = 31; j >= 0; j--) {
+                            if (rm >= (1 << j)) {
+                                rs = j - 15;
+                                break;
+                            }
+                        }
+                        for (j = 31; j >= 0; j--) {
+                            if (gm >= (1 << j)) {
+                                gs = j - 15;
+                                break;
+                            }
+                        }
+                        for (j = 31; j >= 0; j--) {
+                            if (bm >= (1 << j)) {
+                                bs = j - 15;
+                                break;
+                            }
+                        }
+                        visual_type = RGB_OTHER;
+                    }
+                }
+                else
+                    visual_type = NOT_TRUE_NOR_DIRECT;
+                if (debug_level & 16)
+                    fprintf(stderr,"\tID:           0x%lx,  Default\n", vp->visualid);
+            }
+            else if (debug_level & 16)
+                fprintf(stderr,"\tID:           0x%lx\n", vp->visualid);
+    
+            // Store color depth for use by other routines.
+            visual_depth = vp->depth;
+
+            if (debug_level & 16) {
+                fprintf(stderr,"\tScreen:       %d\n",  vp->screen);
+                fprintf(stderr,"\tDepth:        %d\n",  vp->depth);
+                fprintf(stderr,"\tClass:        %d",    vp->class);
+                switch (vp->class) {
+                case StaticGray:
+                    fprintf(stderr,",  StaticGray\n");
+                    break;
+                case GrayScale:
+                    fprintf(stderr,",  GrayScale\n");
+                    break;
+                case StaticColor:
+                    fprintf(stderr,",  StaticColor\n");
+                    break;
+                case PseudoColor:
+                    fprintf(stderr,",  PseudoColor\n");
+                    break;
+                case TrueColor:
+                    fprintf(stderr,",  TrueColor\n");
+                    break;
+                case DirectColor:
+                    fprintf(stderr,",  DirectColor\n");
+                    break;
+                default:
+                    fprintf(stderr,",  ??\n");
+                    break;
+                }
+                fprintf(stderr,"\tClrmap Size:  %d\n", vp->colormap_size);
+                fprintf(stderr,"\tBits per RGB: %d\n", vp->bits_per_rgb);
+                fprintf(stderr,"\tRed Mask:     0x%lx\n",   vp->red_mask);
+                fprintf(stderr,"\tGreen Mask:   0x%lx\n",   vp->green_mask);
+                fprintf(stderr,"\tBlue Mask:    0x%lx\n\n", vp->blue_mask);
+            }
+        }
+    }
+    XFree(visual_list);
+}
+
+
+
+
+
+void pack_pixel_bits(unsigned short r, unsigned short g, unsigned short b, unsigned long* pixel)
+{
+    switch (visual_type) {
+    case RGB_565:
+        *pixel = (( r       & 0xf800) |
+                  ((g >> 5) & 0x07e0) |
+                   (b >> 11));
+        break;
+    case RGB_555:
+        *pixel = (((r >> 1) & 0x7c00) |
+                  ((g >> 6) & 0x03e0) |
+                   (b >> 11));
+        break;
+    case RGB_888:
+        *pixel = (((r << 8) & 0xff0000) |
+                  ( g       & 0x00ff00) |
+                   (b >> 8));
+        break;
+    case RGB_OTHER:
+        if (rs >= 0)
+            *pixel = ((r << rs) & rm);
+        else
+            *pixel = ((r >> (-rs)) & rm);
+        if (gs >= 0)
+            *pixel |= ((g << gs) & gm);
+        else
+            *pixel |= ((g >> (-gs)) & gm);
+        if (bs >= 0)
+            *pixel |= ((b << bs) & bm);
+        else
+            *pixel |= ((b >> (-bs)) & bm);
+        break;
+    case NOT_TRUE_NOR_DIRECT:
+    default:
+        break;
+    }
+}
+
+
diff --git a/src/color.h b/src/color.h
new file mode 100644
index 0000000..92fb590
--- /dev/null
+++ b/src/color.h
@@ -0,0 +1,53 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: color.h,v 1.15 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_COLOR_H
+#define XASTIR_COLOR_H
+
+#define MAX_COLORS 81
+
+#define MAX_COLORNAME 40
+typedef struct {
+    char colorname[MAX_COLORNAME];
+    XColor color;
+} color_load;
+
+typedef enum {
+    NOT_TRUE_NOR_DIRECT,
+    RGB_565,
+    RGB_555,
+    RGB_888,
+    RGB_OTHER
+} Pixel_Format;
+extern Pixel_Format visual_type;
+extern int visual_depth;
+
+/* from color.c */
+extern int load_color_file(void);
+extern Pixel GetPixelByName(Widget w, char *colorname);
+extern void setup_visual_info(Display* dpy, int scr);
+extern void pack_pixel_bits(unsigned short r, unsigned short g, unsigned short b, unsigned long* pixel);
+
+#endif /* XASTIR_COLOR_H */
+
diff --git a/src/compiledate.c b/src/compiledate.c
new file mode 100644
index 0000000..cdddd97
--- /dev/null
+++ b/src/compiledate.c
@@ -0,0 +1 @@
+char compiledate[] = "Compiled: Tue Dec  4 15:36:48 PST 2012";
diff --git a/src/database.h b/src/database.h
new file mode 100644
index 0000000..35635b9
--- /dev/null
+++ b/src/database.h
@@ -0,0 +1,669 @@
+/*
+ * $Id: database.h,v 1.56 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/* Note: this file should be called db.h, but was renamed to database.h
+ * to avoid conflicts with the Berkeley DB package.  */
+
+/*
+ * Database structures
+ *
+ */
+
+#ifndef XASTIR_DATABASE_H
+#define XASTIR_DATABASE_H
+
+
+#define MSG_INCREMENT 200
+#define MAX_CALLSIGN 9       // Objects are up to 9 chars
+#define MAX_TACTICAL_CALL 57 // Up to XX chars for tactical calls
+#define MAX_COMMENT_LINES 20  // Save XX unique comment strings per station
+#define MAX_STATUS_LINES 20   // Save XX unique status strings per station
+
+/* define max size of info field */
+#define MAX_INFO_FIELD_SIZE 256
+
+// Number of times to send killed objects/items before ceasing to
+// transmit them.
+#define MAX_KILLED_OBJECT_RETRANSMIT 20
+
+// Check entire station list at this rate for objects/items that
+// might need to be transmitted via the decaying algorithm.  This is
+// the start rate, which gets doubled on each transmit.
+#define OBJECT_CHECK_RATE 20
+
+// We should probably be using APRS_DF in extract_bearing_NRQ()
+// and extract_omnidf() functions.  We aren't currently.
+/* Define APRS Types */
+enum APRS_Types {
+    APRS_NULL,
+    APRS_MSGCAP,
+    APRS_FIXED,
+    APRS_DOWN,      // Not used anymore
+    APRS_MOBILE,
+    APRS_DF,
+    APRS_OBJECT,
+    APRS_ITEM,
+    APRS_STATUS,
+    APRS_WX1,
+    APRS_WX2,
+    APRS_WX3,
+    APRS_WX4,
+    APRS_WX5,
+    APRS_WX6,
+    QM_WX,
+    PEET_COMPLETE,
+    RSWX200,
+    GPS_RMC,
+    GPS_GGA,
+    GPS_GLL,
+    STATION_CALL_DATA,
+    OTHER_DATA,
+    APRS_MICE,
+    APRS_GRID,
+    DALLAS_ONE_WIRE,
+    DAVISMETEO,
+    DAVISAPRSDL
+};
+
+
+/* Define Record Types */
+#define NORMAL_APRS     'N'
+#define MOBILE_APRS     'M'
+#define DF_APRS         'D'
+#define DOWN_APRS       'Q'
+#define NORMAL_GPS_RMC  'C'
+#define NORMAL_GPS_GGA  'A'
+#define NORMAL_GPS_GLL  'L'
+#define APRS_WX1        '1'
+#define APRS_WX2        '2'
+#define APRS_WX3        '3'
+#define APRS_WX4        '4'
+#define APRS_WX5        '5'
+#define APRS_WX6        '6'
+
+/* define RECORD ACTIVES */
+#define RECORD_ACTIVE    'A'
+#define RECORD_NOTACTIVE 'N'
+#define RECORD_CLOSED     'C'
+
+/* define data from info type */
+#define DATA_VIA_LOCAL 'L'
+#define DATA_VIA_TNC   'T'
+#define DATA_VIA_NET   'I'
+#define DATA_VIA_FILE  'F'
+#define DATA_VIA_DATABASE  'D'
+
+
+/* define Heard info type */
+#define VIA_TNC         'Y'
+#define NOT_VIA_TNC     'N'
+
+/* define Message types */
+#define MESSAGE_MESSAGE  'M'
+#define MESSAGE_BULLETIN 'B'
+#define MESSAGE_NWS      'W'
+
+// Define file info, string length are without trailing '\0'
+#define MAX_TIME             20
+#define MAX_LONG             12
+#define MAX_LAT              11
+#define MAX_ALTITUDE         10         //-32808.4 to 300000.0? feet
+#define MAX_SPEED             9         /* ?? 3 in knots */
+#define MAX_COURSE            7         /* ?? */
+#define MAX_POWERGAIN         7
+#define MAX_STATION_TIME     10         /* 6+1 */
+#define MAX_SAT               4
+#define MAX_DISTANCE         10
+#define MAX_WXSTATION        50
+#define MAX_TEMP            100
+
+#define MAX_MESSAGE_LENGTH  100
+#define MAX_MESSAGE_ORDER    10
+
+// track export file formats
+#define EXPORT_XASTIR_TRACK 0
+#define EXPORT_KML_TRACK 1
+
+extern char *get_most_recent_ack(char *callsign);
+ 
+extern void Set_Del_Object(Widget w, XtPointer clientData, XtPointer calldata); // From main.c
+
+
+extern char my_callsign[MAX_CALLSIGN+1];
+extern char my_lat[MAX_LAT];
+extern char my_long[MAX_LONG];
+
+
+
+// Used for messages and bulletins
+typedef struct {
+    char active;
+    char data_via;
+    char type;
+    char heard_via_tnc;
+    time_t sec_heard;
+    time_t last_ack_sent;
+    char packet_time[MAX_TIME];
+    char call_sign[MAX_CALLSIGN+1];
+    char from_call_sign[MAX_CALLSIGN+1];
+    char message_line[MAX_MESSAGE_LENGTH+1];
+    char seq[MAX_MESSAGE_ORDER+1];
+    char acked;
+    char position_known;
+    time_t interval;
+    int tries;
+} Message;
+
+
+
+// Struct used to create linked list of most recent ack's
+typedef struct _ack_record {
+    char callsign[MAX_CALLSIGN+1];
+    char ack[5+1];
+    struct _ack_record *next;
+} ack_record;
+
+
+
+#ifdef MSG_DEBUG
+extern void msg_clear_data(Message *clear);
+extern void msg_copy_data(Message *to, Message *from);
+#else   // MSG_DEBUG
+#define msg_clear_data(clear) memset((Message *)clear, 0, sizeof(Message))
+#define msg_copy_data(to, from) memmove((Message *)to, (Message *)from, \
+                                        sizeof(Message))
+#endif /* MSG_DEBUG */
+
+extern int message_update_time(void);
+
+
+
+enum AreaObjectTypes {
+    AREA_OPEN_CIRCLE     = 0x0,
+    AREA_LINE_LEFT       = 0x1,
+    AREA_OPEN_ELLIPSE    = 0x2,
+    AREA_OPEN_TRIANGLE   = 0x3,
+    AREA_OPEN_BOX        = 0x4,
+    AREA_FILLED_CIRCLE   = 0x5,
+    AREA_LINE_RIGHT      = 0x6,
+    AREA_FILLED_ELLIPSE  = 0x7,
+    AREA_FILLED_TRIANGLE = 0x8,
+    AREA_FILLED_BOX      = 0x9,
+    AREA_MAX             = 0x9,
+    AREA_NONE            = 0xF
+};
+
+
+
+enum AreaObjectColors {
+    AREA_BLACK_HI  = 0x0,
+    AREA_BLUE_HI   = 0x1,
+    AREA_GREEN_HI  = 0x2,
+    AREA_CYAN_HI   = 0x3,
+    AREA_RED_HI    = 0x4,
+    AREA_VIOLET_HI = 0x5,
+    AREA_YELLOW_HI = 0x6,
+    AREA_GRAY_HI   = 0x7,
+    AREA_BLACK_LO  = 0x8,
+    AREA_BLUE_LO   = 0x9,
+    AREA_GREEN_LO  = 0xA,
+    AREA_CYAN_LO   = 0xB,
+    AREA_RED_LO    = 0xC,
+    AREA_VIOLET_LO = 0xD,
+    AREA_YELLOW_LO = 0xE,
+    AREA_GRAY_LO   = 0xF
+};
+
+
+
+typedef struct {
+    unsigned type : 4;
+    unsigned color : 4;
+    unsigned sqrt_lat_off : 8;
+    unsigned sqrt_lon_off : 8;
+    unsigned corridor_width : 16;
+} AreaObject;
+
+
+
+typedef struct {
+    char aprs_type;
+    char aprs_symbol;
+    char special_overlay;
+    AreaObject area_object;
+} APRS_Symbol;
+
+
+
+// Struct for holding current weather data.
+// This struct is pointed to by the DataRow structure.
+// An empty string indicates undefined data.
+typedef struct {                //                      strlen
+    time_t  wx_sec_time;
+    int     wx_storm;           // Set to one if severe storm
+    char    wx_time[MAX_TIME];
+    char    wx_course[4];       // in �                     3
+    char    wx_speed[4];        // in mph                   3
+    time_t  wx_speed_sec_time;
+    char    wx_gust[4];         // in mph                   3
+    char    wx_hurricane_radius[4];  //nautical miles       3
+    char    wx_trop_storm_radius[4]; //nautical miles       3
+    char    wx_whole_gale_radius[4]; // nautical miles      3
+    char    wx_temp[5];         // in �F                    3
+    char    wx_rain[10];        // in hundredths inch/h     3
+    char    wx_rain_total[10];  // in hundredths inch
+    char    wx_snow[6];         // in inches/24h            3
+    char    wx_prec_24[10];     // in hundredths inch/day   3
+    char    wx_prec_00[10];     // in hundredths inch       3
+    char    wx_hum[5];          // in %                     3
+    char    wx_baro[10];        // in hPa                   6
+    char    wx_fuel_temp[5];    // in �F                    3
+    char    wx_fuel_moisture[5];// in %                     2
+    char    wx_type;
+    char    wx_station[MAX_WXSTATION];
+    int     wx_compute_rain_rates;  //  Some stations provide rain rates
+                                  // directly, others require Xastir to
+                                  // compute from total rain.  Flag this,
+                                  // so we don't clobber useful info from
+                                  // a station.
+} WeatherRow;
+
+
+
+// Struct for holding track data.  Keeps a dynamically allocated
+// doubly-linked list of track points.  The first record should have its
+// "prev" pointer set to NULL and the last record should have its "next"
+// pointer set to NULL.  If no track storage exists then the pointers to
+// these structs in the DataRow struct should be NULL.
+typedef struct _TrackRow{
+    long    trail_long_pos;     // coordinate of trail point
+    long    trail_lat_pos;      // coordinate of trail point
+    time_t  sec;                // date/time of position
+    long    speed;              // in 0.1 km/h   undefined: -1
+    int     course;             // in degrees    undefined: -1
+    long    altitude;           // in 0.1 m      undefined: -99999
+    char    flag;               // several flags, see below
+    struct  _TrackRow *prev;    // pointer to previous record in list
+    struct  _TrackRow *next;    // pointer to next record in list
+} TrackRow;
+
+
+
+// trail flag definitions
+#define TR_LOCAL        0x01    // heard direct (not via digis)
+#define TR_NEWTRK       0x02    // start new track
+
+
+
+// Struct for holding comment/status data.  Will keep a dynamically
+// allocated list of text.  Every different comment field will be
+// stored in a separate line.
+typedef struct _CommentRow{
+    char   *text_ptr;           // Ptr to the comment text
+    time_t sec_heard;           // Latest timestamp for this comment/status
+    struct _CommentRow *next;   // Ptr to next record or NULL
+} CommentRow;
+
+
+
+#define MAX_MULTIPOINTS 35
+
+
+
+// Struct for holding multipoint data.
+typedef struct _MultipointRow{
+    long multipoints[MAX_MULTIPOINTS][2];
+} MultipointRow;
+
+
+
+// Break DataRow into several structures.  DataRow will contain the
+// parameters that are common across all types of stations.  DataRow
+// will contain a pointer to TrackRow if it is a moving station, and
+// contain a pointer to WeatherRow if it is a weather station.  If no
+// weather or track data existed, the pointers will be NULL.  This new
+// way of storing station data will save a LOT of memory.  If a
+// station suddenly starts moving or spitting out weather data the new
+// structures will be allocated, filled in, and pointers to them
+// installed in DataRow.
+//
+// Station storage now is organized as an ordered linked list. We have
+// both sorting by name and by time last heard
+//
+// todo: check the string length!
+//
+typedef struct _DataRow {
+
+    struct _DataRow *n_next;    // pointer to next element in name ordered list
+    struct _DataRow *n_prev;    // pointer to previous element in name ordered
+                                // list
+    struct _DataRow *t_newer;   // pointer to next element in time ordered
+                                // list (newer)
+    struct _DataRow *t_older;   // pointer to previous element in time ordered
+                                // list (older)
+
+    char call_sign[MAX_CALLSIGN+1]; // call sign or name index or object/item
+                                    // name
+    char *tactical_call_sign;   // Tactical callsign.  NULL if not assigned
+    APRS_Symbol aprs_symbol;
+    long coord_lon;             // Xastir coordinates 1/100 sec, 0 = 180�W
+    long coord_lat;             // Xastir coordinates 1/100 sec, 0 =  90�N
+
+    int  time_sn;               // serial number for making time index unique
+    time_t sec_heard;           // time last heard, used also for time index
+    time_t heard_via_tnc_last_time;
+    time_t direct_heard;        // KC2ELS - time last heard direct
+
+// Change into time_t structs?  It'd save us a bunch of space.
+    char packet_time[MAX_TIME];
+    char pos_time[MAX_TIME];
+
+//    char altitude_time[MAX_TIME];
+//    char speed_time[MAX_TIME];
+//    char station_time[MAX_STATION_TIME];
+//    char station_time_type;
+
+    short flag;                 // several flags, see below
+    char pos_amb;               // Position ambiguity, 0 = none,
+                                // 1 = 0.1 minute...
+
+    unsigned int error_ellipse_radius; // Degrades precision for this
+                                // station, from 0 to 65535 cm or
+                                // 655.35 meters.  Assigned when we
+                                // decode each type of packet.
+                                // Default is 6.0 meters (600 cm)
+                                // unless we know the GPS position
+                                // is augmented, or is degraded by
+                                // less precision in the packet.
+
+    unsigned int lat_precision;	// In 100ths of a second latitude
+    unsigned int lon_precision;	// In 100ths of a second longitude
+
+    int trail_color;            // trail color (when assigned)
+    char record_type;
+    char data_via;              // L local, T TNC, I internet, F file
+
+// Change to char's to save space?
+    int  heard_via_tnc_port;
+    int  last_port_heard;
+    unsigned int  num_packets;
+    char *node_path_ptr;        // Pointer to path string
+    char altitude[MAX_ALTITUDE]; // in meters (feet gives better resolution ??)
+    char speed[MAX_SPEED+1];    // in knots (same as nautical miles/hour)
+    char course[MAX_COURSE+1];
+    char bearing[MAX_COURSE+1];
+    char NRQ[MAX_COURSE+1];
+    char power_gain[MAX_POWERGAIN+1];   // Holds the phgd values
+    char signal_gain[MAX_POWERGAIN+1];  // Holds the shgd values (for DF'ing)
+
+    WeatherRow *weather_data;   // Pointer to weather data or NULL
+ 
+    CommentRow *status_data;    // Ptr to status records or NULL
+    CommentRow *comment_data;   // Ptr to comment records or NULL
+
+    // Below two pointers are NULL if only one position has been received
+    TrackRow *oldest_trackpoint; // Pointer to oldest track point in
+                                 // doubly-linked list
+    TrackRow *newest_trackpoint; // Pointer to newest track point in
+                                 // doubly-linked list
+
+    // When the station is an object, it can include coordinates
+    // of related points. Currently these are being used to draw
+    // outlines of NWS severe weather watches and warnings, and
+    // storm regions. The coordinates are stored here in Xastir
+    // coordinate form. Element [x][0] is the latitude, and 
+    // element [x][1] is the longitude.  --KG4NBB
+    //
+    // Is there anything preventing a multipoint string from being
+    // in other types of packets, in the comment field?  --WE7U
+    //
+    int num_multipoints;
+    char type;      // from '0' to '9'
+    char style;     // from 'a' to 'z'
+    MultipointRow *multipoint_data;
+
+
+///////////////////////////////////////////////////////////////////////
+// Optional stuff for Objects/Items only (I think, needs to be
+// checked).  These could be moved into an ObjectRow structure, with
+// only a NULL pointer here if not an object/item.
+///////////////////////////////////////////////////////////////////////
+ 
+    char origin[MAX_CALLSIGN+1]; // call sign originating an object
+    short object_retransmit;     // Number of times to retransmit object.
+                                 // -1 = forever
+                                 // Used currently to stop sending killed
+                                 // objects.
+    time_t last_transmit_time;   // Time we last transmitted an object/item.
+                                 // Used to implement decaying transmit time
+                                 // algorithm
+    short transmit_time_increment; // Seconds to add to transmit next time
+                                   // around.  Used to implement decaying
+                                   // transmit time algorithm
+//    time_t last_modified_time;   // Seconds since the object/item
+                                 // was last modified.  We'll
+                                 // eventually use this for
+                                 // dead-reckoning.
+    char signpost[5+1];          // Holds signpost data
+    int  df_color;
+    char sats_visible[MAX_SAT];
+    char probability_min[10+1];  // Holds prob_min (miles)
+    char probability_max[10+1];  // Holds prob_max (miles)
+
+} DataRow;
+
+
+
+// Used to store one vertice in CADRow object
+typedef struct _VerticeRow{
+    long    latitude;           // Xastir coordinates 1/100sec, 0 = 180W
+    long    longitude;          // Xastir coordinates 1/100sec, 0 =  90N
+    struct  _VerticeRow *next;  // Pointer to next record in list
+} VerticeRow;
+
+#define CAD_LABEL_MAX_SIZE 40
+#define CAD_COMMENT_MAX_SIZE 256
+
+
+// CAD Objects
+typedef struct _CADRow {
+    struct _CADRow *next;       // Pointer to next element in list
+    time_t creation_time;       // Time at which object was first created
+    VerticeRow *start;          // Pointer to first VerticeRow
+    int line_color;             // Border color
+    int line_type;              // Border linetype
+    int line_width;             // Border line width
+    float computed_area;        // Area in square kilometers
+    float raw_probability;      // Probability of area (POA) or probability of
+                                // detection (POD) stored as probability 
+                                // with a value between 0 and 1.
+                                // Set and get with CAD_object_get_raw_probability()
+                                // and CAD_object_set_raw_probability(), rather 
+                                // than by a direct request for CADRow->raw_probability.
+    long label_latitude;        // Latitude for label placement
+    long label_longitude;       // Longitude for label placement
+    char label[CAD_LABEL_MAX_SIZE];             // Name of polygon
+    char comment[CAD_COMMENT_MAX_SIZE];          // Comments associated with polygon
+} CADRow;
+
+
+extern CADRow *CAD_list_head;
+
+
+
+// station flag definitions.  We have 16 bits available here as
+// "flag" in "DataRow" is defined as a short.
+//
+#define ST_OBJECT       0x01    // station is an object
+#define ST_ITEM         0x02    // station is an item
+#define ST_ACTIVE       0x04    // station is active (deleted objects are
+                                // inactive)
+#define ST_MOVING       0x08    // station is moving
+#define ST_DIRECT       0x10    // heard direct (not via digis)
+#define ST_VIATNC       0x20    // station heard via TNC
+#define ST_3RD_PT       0x40    // third party traffic
+#define ST_MSGCAP       0x80    // message capable (not used yet)
+#define ST_STATUS       0x100   // got real status message
+#define ST_INVIEW       0x200   // station is in current screen view
+#define ST_MYSTATION    0x400   // station is owned by my call-SSID
+#define ST_MYOBJITEM    0x800   // object/item owned by me
+
+
+#ifdef DATA_DEBUG
+extern void clear_data(DataRow *clear);
+extern void copy_data(DataRow *to, DataRow *from);
+#else   // DATA_DEBUG
+#define clear_data(clear) memset((DataRow *)clear, 0, sizeof(DataRow))
+#define copy_data(to, from) memmove((DataRow *)to, (DataRow *)from, \
+                                    sizeof(DataRow))
+#endif /* DATA_DEBUG */
+
+
+extern void db_init(void);
+extern void export_trail_as_kml(DataRow *p_station);   // export trail of one or all stations to kml file
+
+//
+extern int is_my_call(char *call, int exact);
+extern int is_my_station(DataRow *p_station);
+extern int is_my_object_item(DataRow *p_station);
+
+void mscan_file(char msg_type, void (*function)(Message *fill));
+extern void msg_record_ack(char *to_call_sign, char *my_call, char *seq,
+                           int timeout, int cancel);
+extern void msg_record_interval_tries(char *to_call_sign, char *my_call,
+                            char *seq, time_t interval, int tries);
+extern void display_file(Widget w);
+extern void clean_data_file(void);
+extern void read_file_line(FILE *f);
+extern void mdisplay_file(char msg_type);
+extern void mem_display(void);
+extern long sort_input_database(char *filename, char *fill, int size);
+extern void sort_display_file(char *filename, int size);
+extern void clear_sort_file(char *filename);
+extern void display_packet_data(void);
+extern int  redraw_on_new_packet_data;
+extern int decode_ax25_header(unsigned char *data_string, int *length);
+extern int decode_ax25_line(char *line, char from, int port, int dbadd);
+
+// utilities
+extern void packet_data_add(char *from, char *line, int data_port);
+extern void General_query(Widget w, XtPointer clientData, XtPointer calldata);
+extern void IGate_query(Widget w, XtPointer clientData, XtPointer calldata);
+extern void WX_query(Widget w, XtPointer clientData, XtPointer calldata);
+extern unsigned long max_stations;
+extern int  heard_via_tnc_in_past_hour(char *call);
+
+// messages
+extern void update_messages(int force);
+extern void mdelete_messages_from(char *from);
+extern void mdelete_messages_to(char *to);
+extern void init_message_data(void);
+extern void check_message_remove(time_t curr_sec);
+extern int  new_message_data;
+extern time_t msg_data_add(char *call_sign, char *from_call, char *data,
+                           char *seq, char type, char from, long *record_out);
+
+// stations
+extern int st_direct_timeout;   // Interval that ST_DIRECT flag stays set
+extern int station_count;       // Count of stations in the database
+extern int station_count_save;  // Old copy of the above
+extern DataRow *n_first;  // pointer to first element in name ordered station
+                          // list
+extern DataRow *n_last;   // pointer to last element in name ordered station
+                          // list
+extern DataRow *t_oldest; // pointer to first element in time ordered station
+                          // list
+extern DataRow *t_newest; // pointer to last element in time ordered station
+                          // list
+extern void init_station_data(void);
+extern void Station_data(Widget w, XtPointer clientData, XtPointer calldata);
+extern int station_data_auto_update;
+extern int  next_station_name(DataRow **p_curr);
+extern int  prev_station_name(DataRow **p_curr);
+extern int  next_station_time(DataRow **p_curr);
+extern int  prev_station_time(DataRow **p_curr);
+extern int  search_station_name(DataRow **p_name, char *call, int exact);
+extern int  search_station_time(DataRow **p_time, time_t heard, int serial);
+extern void check_station_remove(time_t curr_sec);
+extern void delete_all_stations(void);
+extern void station_del(char *callsign);
+extern void my_station_add(char *my_call_sign, char my_group, char my_symbol,
+                           char *my_long, char *my_lat, char *my_phg, 
+                           char *my_comment, char my_amb);
+extern void my_station_gps_change(char *pos_long, char *pos_lat, char *course, 
+                                  char *speed, char speedu, char *alt, 
+                                  char *sats);
+extern int  locate_station(Widget w, char *call, int follow_case, 
+                           int get_match, int center_map);
+extern void update_station_info(Widget w);
+
+// objects/items
+extern time_t last_object_check;
+
+// trails
+extern int  delete_trail(DataRow *fill);
+
+// weather
+extern int  get_weather_record(DataRow *fill);
+
+extern void set_map_position(Widget w, long lat, long lon);
+
+
+// just used for aloha calcs
+typedef struct {
+    double distance;
+    char call_sign[MAX_CALLSIGN+1]; // call sign or name index or object/item
+                                    // name
+    char is_mobile;
+    char is_other_mobile;
+    char is_wx;
+    char is_digi; // can only tell this if using a digi icon!
+    char is_home; // stationary stations that are not digis
+} aloha_entry;
+typedef struct { 
+    int digis;
+    int wxs;
+    int other_mobiles;
+    int mobiles_in_motion;
+    int homes;
+    int total;
+} aloha_stats;
+
+double calc_aloha_distance(void); //meat
+void calc_aloha(int curr_sec); // periodic function
+void Show_Aloha_Stats(Widget w, XtPointer clientData, 
+                      XtPointer callData); // popup window
+
+int comp_by_dist(const void *,const void *);// used only for qsort
+DataRow * sanity_check_time_list(time_t); // used only for debugging
+void dump_time_sorted_list(void);
+
+extern int store_trail_point(DataRow *p_station, long lon, long lat, time_t sec, char *alt, char *speed, char *course, short stn_flag);
+
+#ifdef HAVE_DB
+extern int add_simple_station(DataRow *p_new_station,char *station, char *origin, char *symbol, char *overlay, char *aprs_type, char *latitude, char *longitude, char *record_type, char *node_path, char *transmit_time, char *timeformat);
+
+#endif /* HAVE_DB */
+
+#endif /* XASTIR_DATABASE_H */
diff --git a/src/datum.c b/src/datum.c
new file mode 100644
index 0000000..ee91b30
--- /dev/null
+++ b/src/datum.c
@@ -0,0 +1,818 @@
+/*
+   See the top of datum.h for information on this code.
+   N7TAP
+
+   Portions Copyright (C) 2002-2012  The Xastir Group
+
+   $Id: datum.c,v 1.28 2012/08/25 16:38:29 tvrusso Exp $
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "xastir.h"
+#include "datum.h"
+#include "main.h"
+#include "util.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+//  ellipsoid: index into the gEllipsoid[] array, in which
+//             a is the ellipsoid semimajor axis
+//             invf is the inverse of the ellipsoid flattening f
+//  dx, dy, dz: ellipsoid center with respect to WGS84 ellipsoid center
+//    x axis is the prime meridian
+//    y axis is 90 degrees east longitude
+//    z axis is the axis of rotation of the ellipsoid
+
+// The following values for dx, dy and dz were extracted from the output of
+// the GARMIN PCX5 program. The output also includes values for da and df, the
+// difference between the reference ellipsoid and the WGS84 ellipsoid semi-
+// major axis and flattening, respectively. These are replaced by the
+// data contained in the structure array gEllipsoid[], which was obtained from
+// the Defence Mapping Agency document number TR8350.2, "Department of Defense
+// World Geodetic System 1984."
+
+/*
+   The above are the original comments by John Waers.
+
+   Curt Mills, WE7U wrote a perl version of this code and added more datums
+   from Peter H. Dana's website.
+
+   Reference Ellipsoids:
+   http://www.Colorado.EDU/geography/gcraft/notes/datum/elist.html
+
+   Reference Ellipsoids and Datums:
+   http://www.Colorado.EDU/geography/gcraft/notes/datum/edlist.html
+
+   I've loaded the numbers from that second, newer web page.
+   N7TAP
+*/
+
+/* Keep the enum in datum.h up to date with the order of this array */
+const Ellipsoid gEllipsoid[] = {
+//      name                         a            1/f
+    {  "Airy 1830",                  6377563.396, 299.3249646   },
+    {  "Modified Airy",              6377340.189, 299.3249646   },
+    {  "Australian National",        6378160.0,   298.25        },
+    {  "Bessel 1841",                6377397.155, 299.1528128   },
+    {  "Bessel 1841 (Namibia)",      6377483.865, 299.1528128   },
+    {  "Clarke 1866",                6378206.4,   294.9786982   },
+    {  "Clarke 1880",                6378249.145, 293.465       },
+    {  "Everest (India 1830)",       6377276.345, 300.8017      },
+    {  "Everest (India 1956)",       6377301.243, 300.8017      },
+    {  "Everest (Sabah Sarawak)",    6377298.556, 300.8017      },
+    {  "Everest (Malaysia 1969)",    6377295.664, 300.8017      },
+    {  "Everest (Malay. & Sing)",    6377304.063, 300.8017      },
+    {  "Everest (Pakistan)",         6377309.613, 300.8017      },
+    {  "Fischer 1960 (Mercury)",     6378166.0,   298.3         },
+    {  "Modified Fischer 1960",      6378155.0,   298.3         },
+    {  "Fischer 1968",               6378150.0,   298.3         },
+    {  "Helmert 1906",               6378200.0,   298.3         },
+    {  "Hough 1960",                 6378270.0,   297.0         },
+    {  "Indonesian 1974",            6378160.0,   298.247       },
+    {  "International 1924",         6378388.0,   297.0         },
+    {  "Krassovsky 1940",            6378245.0,   298.3         },
+    {  "GRS 67",                     6378160.0,   298.247167427 },
+    {  "GRS 80",                     6378137.0,   298.257222101 },
+    {  "South American 1969",        6378160.0,   298.25        },
+    {  "WGS 60",                     6378165.0,   298.3         },
+    {  "WGS 66",                     6378145.0,   298.25        },
+    {  "WGS 72",                     6378135.0,   298.26        },
+    {  "WGS 84",                     6378137.0,   298.257223563 }
+};
+
+
+
+
+
+/* Keep correct indices to commonly used datums in the enum in datum.h */
+/* Feel free to add mnemonic indices for datums that you use */
+const Datum gDatum[] = {
+//     name                                                             ellipsoid      dx       dy      dz
+    { "Adindan (Burkina Faso)",                                         E_CLARKE_80,   -118,    -14,    218 }, // 0
+    { "Adindan (Cameroon)",                                             E_CLARKE_80,   -134,     -2,    210 }, // 1
+    { "Adindan (Ethiopia)",                                             E_CLARKE_80,   -165,    -11,    206 }, // 2
+    { "Adindan (Mali)",                                                 E_CLARKE_80,   -123,    -20,    220 }, // 3
+    { "Adindan (MEAN FOR Ethiopia; Sudan)",                             E_CLARKE_80,   -166,    -15,    204 }, // 4
+    { "Adindan (Senegal)",                                              E_CLARKE_80,   -128,    -18,    224 }, // 5
+    { "Adindan (Sudan)",                                                E_CLARKE_80,   -161,    -14,    205 }, // 6
+    { "Afgooye (Somalia)",                                               E_KRASS_40,    -43,   -163,     45 }, // 7
+    { "Ain el Abd 1970 (Bahrain)",                                         E_INT_24,   -150,   -250,     -1 }, // 8
+    { "Ain el Abd 1970 (Saudi Arabia)",                                    E_INT_24,   -143,   -236,      7 }, // 9
+    { "American Samoa 1962 (American Samoa Islands)",                   E_CLARKE_66,   -115,    118,    426 }, // 10
+    { "Anna 1 Astro 1965 (Cocos Islands)",                                E_AUS_NAT,   -491,    -22,    435 }, // 11
+    { "Antigua Island Astro 1943 (Antigua (Leeward Islands))",          E_CLARKE_80,   -270,     13,     62 }, // 12
+    { "Arc 1950 (Botswana)",                                            E_CLARKE_80,   -138,   -105,   -289 }, // 13
+    { "Arc 1950 (Burundi)",                                             E_CLARKE_80,   -153,     -5,   -292 }, // 14
+    { "Arc 1950 (Lesotho)",                                             E_CLARKE_80,   -125,   -108,   -295 }, // 15
+    { "Arc 1950 (Malawi)",                                              E_CLARKE_80,   -161,    -73,   -317 }, // 16
+    { "Arc 1950 (MEAN FOR Botswana; Lesotho; Malawi; Swaziland; Zaire; Zambia; Zimbabwe)",      E_CLARKE_80,   -143,    -90,   -294 }, // 17
+    { "Arc 1950 (Swaziland)",                                           E_CLARKE_80,   -134,   -105,   -295 }, // 18
+    { "Arc 1950 (Zaire)",                                               E_CLARKE_80,   -169,    -19,   -278 }, // 19
+    { "Arc 1950 (Zambia)",                                              E_CLARKE_80,   -147,    -74,   -283 }, // 20
+    { "Arc 1950 (Zimbabwe)",                                            E_CLARKE_80,   -142,    -96,   -293 }, // 21
+    { "Arc 1960 (MEAN FOR Kenya; Tanzania)",                            E_CLARKE_80,   -160,     -6,   -302 }, // 22
+    { "Arc 1960 (Kenya)",                                               E_CLARKE_80,   -157,     -2,   -299 }, // 23
+    { "Arc 1960 (Taanzania)",                                           E_CLARKE_80,   -175,    -23,   -303 }, // 24
+    { "Ascension Island 1958 (Ascension Island)",                          E_INT_24,   -205,    107,     53 }, // 25
+    { "Astro Beacon E 1945 (Iwo Jima)",                                    E_INT_24,    145,     75,   -272 }, // 26
+    { "Astro DOS 71/4 (St Helena Island)",                                 E_INT_24,   -320,    550,   -494 }, // 27
+    { "Astro Tern Island (FRIG) 1961 (Tern Island)",                       E_INT_24,    114,   -116,   -333 }, // 28
+    { "Astronomical Station 1952 (Marcus Island)",                         E_INT_24,    124,   -234,    -25 }, // 29
+    { "Australian Geodetic 1966 (Australia; Tasmania)",                   E_AUS_NAT,   -133,    -48,    148 }, // 30
+    { "Australian Geodetic 1984 (Australia; Tasmania)",                   E_AUS_NAT,   -134,    -48,    149 }, // 31
+    { "Ayabelle Lighthouse (Djibouti)",                                 E_CLARKE_80,    -79,   -129,    145 }, // 32
+    { "Bellevue (IGN) (Efate & Erromango Islands)",                        E_INT_24,   -127,   -769,    472 }, // 33
+    { "Bermuda 1957 (Bermuda)",                                         E_CLARKE_66,    -73,    213,    296 }, // 34
+    { "Bissau (Guinea-Bissau)",                                            E_INT_24,   -173,    253,     27 }, // 35
+    { "Bogota Observatory (Colombia)",                                     E_INT_24,    307,    304,   -318 }, // 36
+    { "Bukit Rimpah (Indonesia (Bangka & Belitung Ids))",                 E_BESS_41,   -384,    664,    -48 }, // 37
+    { "Camp Area Astro (Antarctica (McMurdo Camp Area))",                  E_INT_24,   -104,   -129,    239 }, // 38
+    { "Campo Inchauspe (Argentina)",                                       E_INT_24,   -148,    136,     90 }, // 39
+    { "Canton Astro 1966 (Phoenix Islands)",                               E_INT_24,    298,   -304,   -375 }, // 40
+    { "Cape (South Africa)",                                            E_CLARKE_80,   -136,   -108,   -292 }, // 41
+    { "Cape Canaveral (Bahamas; Florida)",                              E_CLARKE_66,     -2,    151,    181 }, // 42
+    { "Carthage (Tunisia)",                                             E_CLARKE_80,   -263,      6,    431 }, // 43
+    { "Chatham Island Astro 1971 (New Zealand (Chatham Island))",          E_INT_24,    175,    -38,    113 }, // 44
+    { "Chua Astro (Paraguay)",                                             E_INT_24,   -134,    229,    -29 }, // 45
+    { "Corrego Alegre (Brazil)",                                           E_INT_24,   -206,    172,     -6 }, // 46
+    { "Dabola (Guinea)",                                                E_CLARKE_80,    -83,     37,    124 }, // 47
+    { "Deception Island (Deception Island; Antarctia)",                 E_CLARKE_80,    260,     12,   -147 }, // 48
+    { "Djakarta (Batavia) (Indonesia (Sumatra))",                         E_BESS_41,   -377,    681,    -50 }, // 49
+    { "DOS 1968 (New Georgia Islands (Gizo Island))",                      E_INT_24,    230,   -199,   -752 }, // 50
+    { "Easter Island 1967 (Easter Island)",                                E_INT_24,    211,    147,    111 }, // 51
+    { "Estonia; Coordinate System 1937 (Estonia)",                        E_BESS_41,    374,    150,    588 }, // 52
+    { "European 1950 (Cyprus)",                                            E_INT_24,   -104,   -101,   -140 }, // 53
+    { "European 1950 (Egypt)",                                             E_INT_24,   -130,   -117,   -151 }, // 54
+    { "European 1950 (England; Channel Islands; Scotland; Shetland Islands)",         E_INT_24,    -86,    -96,   -120 }, // 55
+    { "European 1950 (England; Ireland; Scotland; Shetland Islands)",         E_INT_24,    -86,    -96,   -120 }, // 56
+    { "European 1950 (Finland; Norway)",                                   E_INT_24,    -87,    -95,   -120 }, // 57
+    { "European 1950 (Greece)",                                            E_INT_24,    -84,    -95,   -130 }, // 58
+    { "European 1950 (Iran)",                                              E_INT_24,   -117,   -132,   -164 }, // 59
+    { "European 1950 (Italy (Sardinia))",                                  E_INT_24,    -97,   -103,   -120 }, // 60
+    { "European 1950 (Italy (Sicily))",                                    E_INT_24,    -97,    -88,   -135 }, // 61
+    { "European 1950 (Malta)",                                             E_INT_24,   -107,    -88,   -149 }, // 62
+    { "European 1950 (MEAN FOR Austria; Belgium; Denmark; Finland; France; W Germany; Gibraltar; Greece; Italy; Luxembourg; Netherlands; Norway; Portugal; Spain; Sweden; Switzerland)",         E_INT_24,    -87,    -98,   -121 }, // 63
+    { "European 1950 (MEAN FOR Austria; Denmark; France; W Germany; Netherlands; Switzerland)",         E_INT_24,    -87,    -96,   -120 }, // 64
+    { "European 1950 (MEAN FOR Iraq; Israel; Jordan; Lebanon; Kuwait; Saudi Arabia; Syria)",         E_INT_24,   -103,   -106,   -141 }, // 65
+    { "European 1950 (Portugal; Spain)",                                   E_INT_24,    -84,   -107,   -120 }, // 66
+    { "European 1950 (Tunisia)",                                           E_INT_24,   -112,    -77,   -145 }, // 67
+    { "European 1979 (MEAN FOR Austria; Finland; Netherlands; Norway; Spain; Sweden; Switzerland)",         E_INT_24,    -86,    -98,   -119 }, // 68
+    { "Fort Thomas 1955 (Nevis; St. Kitts (Leeward Islands))",          E_CLARKE_80,     -7,    215,    225 }, // 69
+    { "Gan 1970 (Republic of Maldives)",                                   E_INT_24,   -133,   -321,     50 }, // 70
+    { "Geodetic Datum 1949 (New Zealand)",                                 E_INT_24,     84,    -22,    209 }, // 71
+    { "Graciosa Base SW 1948 (Azores (Faial; Graciosa; Pico; Sao Jorge; Terceira))",         E_INT_24,   -104,    167,    -38 }, // 72
+    { "Guam 1963 (Guam)",                                               E_CLARKE_66,   -100,   -248,    259 }, // 73
+    { "Gunung Segara (Indonesia (Kalimantan))",                           E_BESS_41,   -403,    684,     41 }, // 74
+    { "GUX 1 Astro (Guadalcanal Island)",                                  E_INT_24,    252,   -209,   -751 }, // 75
+    { "Herat North (Afghanistan)",                                         E_INT_24,   -333,   -222,    114 }, // 76
+    { "Hermannskogel Datum (Croatia -Serbia, Bosnia-Herzegovina)",    E_BESS_41_NAM,    653,   -212,    449 }, // 77
+    { "Hjorsey 1955 (Iceland)",                                            E_INT_24,    -73,     46,    -86 }, // 78
+    { "Hong Kong 1963 (Hong Kong)",                                        E_INT_24,   -156,   -271,   -189 }, // 79
+    { "Hu-Tzu-Shan (Taiwan)",                                              E_INT_24,   -637,   -549,   -203 }, // 80
+    { "Indian (Bangladesh)",                                           E_EVR_IND_30,    282,    726,    254 }, // 81
+    { "Indian (India; Nepal)",                                         E_EVR_IND_56,    295,    736,    257 }, // 82
+    { "Indian (Pakistan)",                                                E_EVR_PAK,    283,    682,    231 }, // 83
+    { "Indian 1954 (Thailand)",                                        E_EVR_IND_30,    217,    823,    299 }, // 84
+    { "Indian 1960 (Vietnam (Con Son Island))",                        E_EVR_IND_30,    182,    915,    344 }, // 85
+    { "Indian 1960 (Vietnam (Near 16�N))",                             E_EVR_IND_30,    198,    881,    317 }, // 86
+    { "Indian 1975 (Thailand)",                                        E_EVR_IND_30,    210,    814,    289 }, // 87
+    { "Indonesian 1974 (Indonesia)",                                       E_IND_74,    -24,    -15,      5 }, // 88
+    { "Ireland 1965 (Ireland)",                                          E_MOD_AIRY,    506,   -122,    611 }, // 89
+    { "ISTS 061 Astro 1968 (South Georgia Islands)",                       E_INT_24,   -794,    119,   -298 }, // 90
+    { "ISTS 073 Astro 1969 (Diego Garcia)",                                E_INT_24,    208,   -435,   -229 }, // 91
+    { "Johnston Island 1961 (Johnston Island)",                            E_INT_24,    189,    -79,   -202 }, // 92
+    { "Kandawala (Sri Lanka)",                                         E_EVR_IND_30,    -97,    787,     86 }, // 93
+    { "Kerguelen Island 1949 (Kerguelen Island)",                          E_INT_24,    145,   -187,    103 }, // 94
+    { "Kertau 1948 (West Malaysia & Singapore)",                     E_EVR_MAL_SING,    -11,    851,      5 }, // 95
+    { "Kusaie Astro 1951 (Caroline Islands)",                              E_INT_24,    647,   1777,  -1124 }, // 96
+    { "Korean Geodetic System (South Korea)",                              E_GRS_80,      0,      0,      0 }, // 97
+    { "L. C. 5 Astro 1961 (Cayman Brac Island)",                        E_CLARKE_66,     42,    124,    147 }, // 98
+    { "Leigon (Ghana)",                                                 E_CLARKE_80,   -130,     29,    364 }, // 99
+    { "Liberia 1964 (Liberia)",                                         E_CLARKE_80,    -90,     40,     88 }, // 100
+    { "Luzon (Philippines (Excluding Mindanao))",                       E_CLARKE_66,   -133,    -77,    -51 }, // 101
+    { "Luzon (Philippines (Mindanao))",                                 E_CLARKE_66,   -133,    -79,    -72 }, // 102
+    { "M'Poraloko (Gabon)",                                             E_CLARKE_80,    -74,   -130,     42 }, // 103
+    { "Mahe 1971 (Mahe Island)",                                        E_CLARKE_80,     41,   -220,   -134 }, // 104
+    { "Massawa (Ethiopia (Eritrea))",                                     E_BESS_41,    639,    405,     60 }, // 105
+    { "Merchich (Morocco)",                                             E_CLARKE_80,     31,    146,     47 }, // 106
+    { "Midway Astro 1961 (Midway Islands)",                                E_INT_24,    912,    -58,   1227 }, // 107
+    { "Minna (Cameroon)",                                               E_CLARKE_80,    -81,    -84,    115 }, // 108
+    { "Minna (Nigeria)",                                                E_CLARKE_80,    -92,    -93,    122 }, // 109
+    { "Montserrat Island Astro 1958 (Montserrat (Leeward Islands))",      E_CLARKE_80,    174,    359,    365 }, // 110
+    { "Nahrwan (Oman (Masirah Island))",                                E_CLARKE_80,   -247,   -148,    369 }, // 111
+    { "Nahrwan (Saudi Arabia)",                                         E_CLARKE_80,   -243,   -192,    477 }, // 112
+    { "Nahrwan (United Arab Emirates)",                                 E_CLARKE_80,   -249,   -156,    381 }, // 113
+    { "Naparima BWI (Trinidad & Tobago)",                                  E_INT_24,    -10,    375,    165 }, // 114
+    { "North American 1927 (Alaska (Excluding Aleutian Ids))",          E_CLARKE_66,     -5,    135,    172 }, // 115
+    { "North American 1927 (Alaska (Aleutian Ids East of 180�W))",      E_CLARKE_66,     -2,    152,    149 }, // 116
+    { "North American 1927 (Alaska (Aleutian Ids West of 180�W))",      E_CLARKE_66,      2,    204,    105 }, // 117
+    { "North American 1927 (Bahamas (Except San Salvador Id))",         E_CLARKE_66,     -4,    154,    178 }, // 118
+    { "North American 1927 (Bahamas (San Salvador Island))",            E_CLARKE_66,      1,    140,    165 }, // 119
+    { "North American 1927 (Canada (Alberta; British Columbia))",       E_CLARKE_66,     -7,    162,    188 }, // 120
+    { "North American 1927 (Canada (Manitoba; Ontario))",               E_CLARKE_66,     -9,    157,    184 }, // 121
+    { "North American 1927 (Canada (New Brunswick; Newfoundland; Nova Scotia; Quebec))",      E_CLARKE_66,    -22,    160,    190 }, // 122
+    { "North American 1927 (Canada (Northwest Territories; Saskatchewan))",      E_CLARKE_66,      4,    159,    188 }, // 123
+    { "North American 1927 (Canada (Yukon))",                           E_CLARKE_66,     -7,    139,    181 }, // 124
+    { "North American 1927 (Canal Zone)",                               E_CLARKE_66,      0,    125,    201 }, // 125
+    { "North American 1927 (Cuba)",                                     E_CLARKE_66,     -9,    152,    178 }, // 126
+    { "North American 1927 (Greenland (Hayes Peninsula))",              E_CLARKE_66,     11,    114,    195 }, // 127
+    { "North American 1927 (MEAN FOR Antigua; Barbados; Barbuda; Caicos Islands; Cuba; Dominican Republic; Grand Cayman; Jamaica; Turks Islands)",      E_CLARKE_66,     -3,    142,    183 }, // 128
+    { "North American 1927 (MEAN FOR Belize; Costa Rica; El Salvador; Guatemala; Honduras; Nicaragua)",      E_CLARKE_66,      0,    125,    194 }, // 129
+    { "North American 1927 (MEAN FOR Canada)",                          E_CLARKE_66,    -10,    158,    187 }, // 130
+    { "North American 1927 (MEAN FOR CONUS)",                           E_CLARKE_66,     -8,    160,    176 }, // 131
+    { "North American 1927 (MEAN FOR CONUS (East of Mississippi; River Including Louisiana; Missouri; Minnesota))",      E_CLARKE_66,     -9,    161,    179 }, // 132
+    { "North American 1927 (MEAN FOR CONUS (West of Mississippi; River Excluding Louisiana; Minnesota; Missouri))",      E_CLARKE_66,     -8,    159,    175 }, // 133
+    { "North American 1927 (Mexico)",                                   E_CLARKE_66,    -12,    130,    190 }, // 134
+    { "North American 1983 (Alaska (Excluding Aleutian Ids))",             E_GRS_80,      0,      0,      0 }, // 135
+    { "North American 1983 (Aleutian Ids)",                                E_GRS_80,     -2,      0,      4 }, // 136
+    { "North American 1983 (Canada)",                                      E_GRS_80,      0,      0,      0 }, // 137
+    { "North American 1983 (CONUS)",                                       E_GRS_80,      0,      0,      0 }, // 138
+    { "North American 1983 (Hawaii)",                                      E_GRS_80,      1,      1,     -1 }, // 139
+    { "North American 1983 (Mexico; Central America)",                     E_GRS_80,      0,      0,      0 }, // 140
+    { "North Sahara 1959 (Algeria)",                                    E_CLARKE_80,   -186,    -93,    310 }, // 141
+    { "Observatorio Meteorologico 1939 (Azores (Corvo & Flores Islands))",         E_INT_24,   -425,   -169,     81 }, // 142
+    { "Old Egyptian 1907 (Egypt)",                                        E_HELM_06,   -130,    110,    -13 }, // 143
+    { "Old Hawaiian (Hawaii)",                                          E_CLARKE_66,     89,   -279,   -183 }, // 144
+    { "Old Hawaiian (Kauai)",                                           E_CLARKE_66,     45,   -290,   -172 }, // 145
+    { "Old Hawaiian (Maui)",                                            E_CLARKE_66,     65,   -290,   -190 }, // 146
+    { "Old Hawaiian (MEAN FOR Hawaii; Kauai; Maui; Oahu)",              E_CLARKE_66,     61,   -285,   -181 }, // 147
+    { "Old Hawaiian (Oahu)",                                            E_CLARKE_66,     58,   -283,   -182 }, // 148
+    { "Oman (Oman)",                                                    E_CLARKE_80,   -346,     -1,    224 }, // 149
+    { "Ordnance Survey Great Britain 1936 (England)",                     E_AIRY_30,    371,   -112,    434 }, // 150
+    { "Ordnance Survey Great Britain 1936 (England; Isle of Man; Wales)",        E_AIRY_30,    371,   -111,    434 }, // 151
+    { "Ordnance Survey Great Britain 1936 (MEAN FOR England; Isle of Man; Scotland; Shetland Islands; Wales)",        E_AIRY_30,    375,   -111,    431 }, // 152
+    { "Ordnance Survey Great Britain 1936 (Scotland; Shetland Islands)",        E_AIRY_30,    384,   -111,    425 }, // 153
+    { "Ordnance Survey Great Britain 1936 (Wales)",                       E_AIRY_30,    370,   -108,    434 }, // 154
+    { "Pico de las Nieves (Canary Islands)",                               E_INT_24,   -307,    -92,    127 }, // 155
+    { "Pitcairn Astro 1967 (Pitcairn Island)",                             E_INT_24,    185,    165,     42 }, // 156
+    { "Point 58 (MEAN FOR Burkina Faso & Niger)",                       E_CLARKE_80,   -106,   -129,    165 }, // 157
+    { "Pointe Noire 1948 (Congo)",                                      E_CLARKE_80,   -148,     51,   -291 }, // 158
+    { "Porto Santo 1936 (Porto Santo; Madeira Islands)",                   E_INT_24,   -499,   -249,    314 }, // 159
+    { "Provisional South American 1956 (Bolivia)",                         E_INT_24,   -270,    188,   -388 }, // 160
+    { "Provisional South American 1956 (Chile (Northern; Near 19�S))",         E_INT_24,   -270,    183,   -390 }, // 161
+    { "Provisional South American 1956 (Chile (Southern; Near 43�S))",         E_INT_24,   -305,    243,   -442 }, // 162
+    { "Provisional South American 1956 (Colombia)",                        E_INT_24,   -282,    169,   -371 }, // 163
+    { "Provisional South American 1956 (Ecuador)",                         E_INT_24,   -278,    171,   -367 }, // 164
+    { "Provisional South American 1956 (Guyana)",                          E_INT_24,   -298,    159,   -369 }, // 165
+    { "Provisional South American 1956 (MEAN FOR Bolivia; Chile; Colombia; Ecuador; Guyana; Peru; Venezuela)",         E_INT_24,   -288,    175,   -376 }, // 166
+    { "Provisional South American 1956 (Peru)",                            E_INT_24,   -279,    175,   -379 }, // 167
+    { "Provisional South American 1956 (Venezuela)",                       E_INT_24,   -295,    173,   -371 }, // 168
+    { "Provisional South Chilean 1963 (Chile (Near 53�S) (Hito XVIII))",         E_INT_24,     16,    196,     93 }, // 169
+    { "Puerto Rico (Puerto Rico; Virgin Islands)",                      E_CLARKE_66,     11,     72,   -101 }, // 170
+    { "Pulkovo 1942 (Russia)",                                           E_KRASS_40,     28,   -130,    -95 }, // 171
+    { "Qatar National (Qatar)",                                            E_INT_24,   -128,   -283,     22 }, // 172
+    { "Qornoq (Greenland (South))",                                        E_INT_24,    164,    138,   -189 }, // 173
+    { "Reunion (Mascarene Islands)",                                       E_INT_24,     94,   -948,  -1262 }, // 174
+    { "Rome 1940 (Italy (Sardinia))",                                      E_INT_24,   -225,    -65,      9 }, // 175
+    { "S-42 (Pulkovo 1942) (Hungary)",                                   E_KRASS_40,     28,   -121,    -77 }, // 176
+    { "S-42 (Pulkovo 1942) (Poland)",                                    E_KRASS_40,     23,   -124,    -82 }, // 177
+    { "S-42 (Pulkovo 1942) (Czechoslavakia)",                            E_KRASS_40,     26,   -121,    -78 }, // 178
+    { "S-42 (Pulkovo 1942) (Latvia)",                                    E_KRASS_40,     24,   -124,    -82 }, // 179
+    { "S-42 (Pulkovo 1942) (Kazakhstan)",                                E_KRASS_40,     15,   -130,    -84 }, // 180
+    { "S-42 (Pulkovo 1942) (Albania)",                                   E_KRASS_40,     24,   -130,    -92 }, // 181
+    { "S-42 (Pulkovo 1942) (Romania)",                                   E_KRASS_40,     28,   -121,    -77 }, // 182
+    { "S-JTSK (Czechoslavakia (Prior 1 JAN 1993))",                       E_BESS_41,    589,     76,    480 }, // 183
+    { "Santo (DOS) 1965 (Espirito Santo Island)",                          E_INT_24,    170,     42,     84 }, // 184
+    { "Sao Braz (Azores (Sao Miguel; Santa Maria Ids))",                   E_INT_24,   -203,    141,     53 }, // 185
+    { "Sapper Hill 1943 (East Falkland Island)",                           E_INT_24,   -355,     21,     72 }, // 186
+    { "Schwarzeck (Namibia)",                                         E_BESS_41_NAM,    616,     97,   -251 }, // 187
+    { "Selvagem Grande 1938 (Salvage Islands)",                            E_INT_24,   -289,   -124,     60 }, // 188
+    { "Sierra Leone 1960 (Sierra Leone)",                               E_CLARKE_80,    -88,      4,    101 }, // 189
+    { "South American 1969 (Argentina)",                                E_S_AMER_69,    -62,     -1,    -37 }, // 190
+    { "South American 1969 (Bolivia)",                                  E_S_AMER_69,    -61,      2,    -48 }, // 191
+    { "South American 1969 (Brazil)",                                   E_S_AMER_69,    -60,     -2,    -41 }, // 192
+    { "South American 1969 (Chile)",                                    E_S_AMER_69,    -75,     -1,    -44 }, // 193
+    { "South American 1969 (Colombia)",                                 E_S_AMER_69,    -44,      6,    -36 }, // 194
+    { "South American 1969 (Ecuador)",                                  E_S_AMER_69,    -48,      3,    -44 }, // 195
+    { "South American 1969 (Ecuador (Baltra; Galapagos))",              E_S_AMER_69,    -47,     26,    -42 }, // 196
+    { "South American 1969 (Guyana)",                                   E_S_AMER_69,    -53,      3,    -47 }, // 197
+    { "South American 1969 (MEAN FOR Argentina; Bolivia; Brazil; Chile; Colombia; Ecuador; Guyana; Paraguay; Peru; Trinidad & Tobago; Venezuela)",      E_S_AMER_69,    -57,      1,    -41 }, // 198
+    { "South American 1969 (Paraguay)",                                 E_S_AMER_69,    -61,      2,    -33 }, // 199
+    { "South American 1969 (Peru)",                                     E_S_AMER_69,    -58,      0,    -44 }, // 200
+    { "South American 1969 (Trinidad & Tobago)",                        E_S_AMER_69,    -45,     12,    -33 }, // 201
+    { "South American 1969 (Venezuela)",                                E_S_AMER_69,    -45,      8,    -33 }, // 202
+    { "South Asia (Singapore)",                                      E_MOD_FISCH_60,      7,    -10,    -26 }, // 203
+    { "Tananarive Observatory 1925 (Madagascar)",                          E_INT_24,   -189,   -242,    -91 }, // 204
+    { "Timbalai 1948 (Brunei; E. Malaysia (Sabah Sarawak))",          E_EVR_SAB_SAR,   -679,    669,    -48 }, // 205
+    { "Tokyo (Japan)",                                                    E_BESS_41,   -148,    507,    685 }, // 206
+    { "Tokyo (MEAN FOR Japan; South Korea; Okinawa)",                     E_BESS_41,   -148,    507,    685 }, // 207
+    { "Tokyo (Okinawa)",                                                  E_BESS_41,   -158,    507,    676 }, // 208
+    { "Tokyo (South Korea)",                                              E_BESS_41,   -147,    506,    687 }, // 209
+    { "Tristan Astro 1968 (Tristan da Cunha)",                             E_INT_24,   -632,    438,   -609 }, // 210
+    { "Viti Levu 1916 (Fiji (Viti Levu Island))",                       E_CLARKE_80,     51,    391,    -36 }, // 211
+    { "Voirol 1960 (Algeria)",                                          E_CLARKE_80,   -123,   -206,    219 }, // 212
+    { "Wake Island Astro 1952 (Wake Atoll)",                               E_INT_24,    276,    -57,    149 }, // 213
+    { "Wake-Eniwetok 1960 (Marshall Islands)",                           E_HOUGH_60,    102,     52,    -38 }, // 214
+    { "WGS 1972 (Global Definition)",                                      E_WGS_72,      0,      0,      0 }, // 215
+    { "WGS 1984 (Global Definition)",                                      E_WGS_84,      0,      0,      0 }, // 216
+    { "Yacare (Uruguay)",                                                  E_INT_24,   -155,    171,     37 }, // 217
+    { "Zanderij (Suriname)",                                               E_INT_24,   -265,    120,   -358 }  // 218
+};
+
+
+
+static const double PI = 3.14159265358979323846;
+
+
+
+
+
+/* As you can see this little function is just a 2 step datum shift, going through WGS84. */
+void datum_shift(double *latitude, double *longitude, short fromDatumID, short toDatumID)
+{
+    wgs84_datum_shift(TO_WGS_84,   latitude, longitude, fromDatumID);
+    wgs84_datum_shift(FROM_WGS_84, latitude, longitude, toDatumID);
+}
+
+
+
+
+
+/*
+        Function to convert latitude and longitude in decimal degrees from WGS84 to
+        another datum or from another datum to WGS84. The arguments to this function
+        include a direction flag 'fromWGS84', pointers to double precision latitude
+        and longitude, and an index to the gDatum[] array.
+*/
+void wgs84_datum_shift(short fromWGS84, double *latitude, double *longitude, short datumID)
+{
+    double dx = gDatum[datumID].dx;
+    double dy = gDatum[datumID].dy;
+    double dz = gDatum[datumID].dz;
+
+    double phi = *latitude * PI / 180.0;
+    double lambda = *longitude * PI / 180.0;
+    double a0, b0, es0, f0;                     /* Reference ellipsoid of input data */
+    double a1, b1, es1, f1;                     /* Reference ellipsoid of output data */
+    double psi;                                 /* geocentric latitude */
+    double x, y, z;                             /* 3D coordinates with respect to original datum */
+    double psi1;                                /* transformed geocentric latitude */
+
+    if (datumID == D_WGS_84)                    // do nothing if current datum is WGS84
+        return;
+
+    if (fromWGS84) {                            /* convert from WGS84 to new datum */
+        a0 = gEllipsoid[E_WGS_84].a;                            /* WGS84 semimajor axis */
+        f0 = 1.0 / gEllipsoid[E_WGS_84].invf;                   /* WGS84 flattening */
+        a1 = gEllipsoid[gDatum[datumID].ellipsoid].a;
+        f1 = 1.0 / gEllipsoid[gDatum[datumID].ellipsoid].invf;
+    }
+    else {                                      /* convert from datum to WGS84 */
+        a0 = gEllipsoid[gDatum[datumID].ellipsoid].a;           /* semimajor axis */
+        f0 = 1.0 / gEllipsoid[gDatum[datumID].ellipsoid].invf;  /* flattening */
+        a1 = gEllipsoid[E_WGS_84].a;                            /* WGS84 semimajor axis */
+        f1 = 1.0 / gEllipsoid[E_WGS_84].invf;                   /* WGS84 flattening */
+        dx = -dx;
+        dy = -dy;
+        dz = -dz;
+    }
+
+    b0 = a0 * (1 - f0);                         /* semiminor axis for input datum */
+    es0 = 2 * f0 - f0*f0;                       /* eccentricity^2 */
+
+    b1 = a1 * (1 - f1);                         /* semiminor axis for output datum */
+    es1 = 2 * f1 - f1*f1;                       /* eccentricity^2 */
+
+    /* Convert geodedic latitude to geocentric latitude, psi */
+    if (*latitude == 0.0 || *latitude == 90.0 || *latitude == -90.0)
+        psi = phi;
+    else
+        psi = atan((1 - es0) * tan(phi));
+
+    /* Calculate x and y axis coordinates with respect to the original ellipsoid */
+    if (*longitude == 90.0 || *longitude == -90.0) {
+        x = 0.0;
+        y = fabs(a0 * b0 / sqrt(b0*b0 + a0*a0*pow(tan(psi), 2.0)));
+    }
+    else {
+        x = fabs((a0 * b0) /
+                 sqrt((1 + pow(tan(lambda), 2.0)) * (b0*b0 + a0*a0 * pow(tan(psi), 2.0))));
+        y = fabs(x * tan(lambda));
+    }
+
+    if (*longitude < -90.0 || *longitude > 90.0)
+        x = -x;
+    if (*longitude < 0.0)
+        y = -y;
+
+    /* Calculate z axis coordinate with respect to the original ellipsoid */
+    if (*latitude == 90.0)
+        z = b0;
+    else if (*latitude == -90.0)
+        z = -b0;
+    else
+        z = tan(psi) * sqrt((a0*a0 * b0*b0) / (b0*b0 + a0*a0 * pow(tan(psi), 2.0)));
+
+    /* Calculate the geocentric latitude with respect to the new ellipsoid */
+    psi1 = atan((z - dz) / sqrt((x - dx)*(x - dx) + (y - dy)*(y - dy)));
+
+    /* Convert to geocentric latitude and save return value */
+    *latitude = atan(tan(psi1) / (1 - es1)) * 180.0 / PI;
+
+    /* Calculate the longitude with respect to the new ellipsoid */
+    *longitude = atan((y - dy) / (x - dx)) * 180.0 / PI;
+
+    /* Correct the resultant for negative x values */
+    if (x-dx < 0.0) {
+        if (y-dy > 0.0)
+            *longitude = 180.0 + *longitude;
+        else
+            *longitude = -180.0 + *longitude;
+    }
+}
+
+
+
+
+
+#define deg2rad (PI / 180)
+#define rad2deg (180.0 / PI)
+
+
+
+
+
+/*
+  Source
+  Defense Mapping Agency. 1987b. DMA Technical Report: Supplement to Department of Defense World Geodetic System
+  1984 Technical Report. Part I and II. Washington, DC: Defense Mapping Agency
+*/
+//
+// Convert lat/long to UTM/UPS coordinates
+void ll_to_utm_ups(short ellipsoidID, const double lat, const double lon,
+        double *utmNorthing, double *utmEasting, char* utmZone, int utmZoneLength)
+{
+    //converts lat/long to UTM coords.  Equations from USGS Bulletin 1532
+    //East Longitudes are positive, West longitudes are negative.
+    //North latitudes are positive, South latitudes are negative
+    //Lat and Long are in decimal degrees
+    //Written by Chuck Gantz- chuck.gantz at globalstar.com
+
+    double a = gEllipsoid[ellipsoidID].a;
+    double f = 1.0 / gEllipsoid[ellipsoidID].invf;
+    double eccSquared = (2 * f) - (f * f);
+    double k0 = 0.9996;
+
+    double LongOrigin;
+    double eccPrimeSquared;
+    double N, T, C, A, M;
+
+    //Make sure the longitude is between -180.00 .. 179.9
+    double LongTemp = (lon+180)-(int)((lon+180)/360)*360-180; // -180.00 .. 179.9;
+
+    double LatRad = lat*deg2rad;
+    double LongRad = LongTemp*deg2rad;
+    double LongOriginRad;
+    int    ZoneNumber;
+
+    ZoneNumber = (int)((LongTemp + 180)/6) + 1;
+
+    if (coordinate_system == USE_UTM_SPECIAL
+            || coordinate_system == USE_MGRS) {
+
+        // Special zone for southern Norway.  Used for military
+        // version of UTM (MGRS) only.
+        if ( lat >= 56.0 && lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0 )
+            ZoneNumber = 32;
+
+        // Handle the special zones for Svalbard.  Used for military
+        // version of UTM (MGRS) only.
+        if (lat >= 72.0 && lat < 84.0) {
+            if (LongTemp >= 0.0  && LongTemp <  9.0)
+                ZoneNumber = 31;
+            else if (LongTemp >= 9.0  && LongTemp < 21.0)
+                ZoneNumber = 33;
+            else if (LongTemp >= 21.0 && LongTemp < 33.0)
+                ZoneNumber = 35;
+            else if (LongTemp >= 33.0 && LongTemp < 42.0)
+                ZoneNumber = 37;
+        }
+    }
+
+    LongOrigin = (ZoneNumber - 1)*6 - 180 + 3;  //+3 puts origin in middle of zone
+    LongOriginRad = LongOrigin * deg2rad;
+
+    if (lat > 84.0 || lat < -80.0) {
+        // We're in the UPS areas (near the poles).  ZoneNumber
+        // should not be printed in this case.
+        xastir_snprintf(utmZone,
+            utmZoneLength,
+            "%c",
+            utm_letter_designator(lat, lon));
+    }
+    else {  // We're in the UTM areas (not near the poles).
+        //compute the UTM Zone from the latitude and longitude
+        xastir_snprintf(utmZone,
+            utmZoneLength,
+            "%d%c",
+            ZoneNumber,
+            utm_letter_designator(lat, lon));
+    }
+
+    eccPrimeSquared = (eccSquared)/(1-eccSquared);
+    
+    if (lat > 84.0 || lat < -80.0) {
+        //
+        // We're dealing with UPS coordinates (near the poles)
+        //
+        // The following piece of code which implements UPS
+        // conversion is derived from code that John Waers
+        // <jfwaers at csn.net> placed in the public domain.  It's from
+        // his program "MacGPS45".
+
+        double t, e, rho;
+        const double k0 = 0.994;
+        double lambda = lon * (PI/180.0);
+        double phi = fabs(lat * (PI/180.0) );
+
+        e = sqrt(eccSquared);
+        t = tan(PI/4.0 - phi/2.0) / pow( (1.0 - e * sin(phi)) / (1.0 + e * sin(phi)), (e/2.0) );
+        rho = 2.0 * a * k0 * t / sqrt(pow(1.0+e, 1.0+e) * pow(1.0-e, 1.0-e));
+        *utmEasting = rho * sin(lambda);
+        *utmNorthing = rho * cos(lambda);
+
+        if (lat > 0.0)  // Northern hemisphere
+            *utmNorthing = -(*utmNorthing);
+
+        *utmEasting  += 2.0e6;  // Add in false easting and northing
+        *utmNorthing += 2.0e6;
+    }
+    else {
+        //
+        // We're dealing with UTM coordinates
+        //
+        N = a/sqrt(1-eccSquared*sin(LatRad)*sin(LatRad));
+        T = tan(LatRad)*tan(LatRad);
+        C = eccPrimeSquared*cos(LatRad)*cos(LatRad);
+        A = cos(LatRad)*(LongRad-LongOriginRad);
+
+        M = a*((1 -
+            eccSquared/4 -
+            3*eccSquared*eccSquared/64 -
+            5*eccSquared*eccSquared*eccSquared/256) * LatRad -
+            (3*eccSquared/8 +
+            3*eccSquared*eccSquared/32 +
+            45*eccSquared*eccSquared*eccSquared/1024) * sin(2*LatRad) +
+            (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024) * sin(4*LatRad) -
+            (35*eccSquared*eccSquared*eccSquared/3072) * sin(6*LatRad));
+
+        *utmEasting = (double)(k0*N*(A+(1-T+C)*A*A*A/6
+            + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
+            + 500000.0);
+
+        *utmNorthing = (double)(k0*(M+N*tan(LatRad)*
+            (A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
+            + (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
+
+        if (lat < 0)
+            *utmNorthing += 10000000.0; //10000000 meter offset for southern hemisphere
+    }
+}
+
+
+
+
+
+// Handles UPS/UTM coordinates equally well!
+//
+char utm_letter_designator(double lat, double lon)
+{
+    // This routine determines the correct UTM/UPS letter designator
+    // for the given latitude.  Originally written by Chuck Gantz-
+    // chuck.gantz at globalstar.com
+    // Modified to handle UPS zones.  --we7u
+    char LetterDesignator;
+
+    if ((84 >= lat) && (lat >=  72)) LetterDesignator = 'X';
+    else if ((72  > lat) && (lat >=  64)) LetterDesignator = 'W';
+    else if ((64  > lat) && (lat >=  56)) LetterDesignator = 'V';
+    else if ((56  > lat) && (lat >=  48)) LetterDesignator = 'U';
+    else if ((48  > lat) && (lat >=  40)) LetterDesignator = 'T';
+    else if ((40  > lat) && (lat >=  32)) LetterDesignator = 'S';
+    else if ((32  > lat) && (lat >=  24)) LetterDesignator = 'R';
+    else if ((24  > lat) && (lat >=  16)) LetterDesignator = 'Q';
+    else if ((16  > lat) && (lat >=   8)) LetterDesignator = 'P';
+    else if (( 8  > lat) && (lat >=   0)) LetterDesignator = 'N';
+    else if (( 0  > lat) && (lat >=  -8)) LetterDesignator = 'M';
+    else if ((-8  > lat) && (lat >= -16)) LetterDesignator = 'L';
+    else if ((-16 > lat) && (lat >= -24)) LetterDesignator = 'K';
+    else if ((-24 > lat) && (lat >= -32)) LetterDesignator = 'J';
+    else if ((-32 > lat) && (lat >= -40)) LetterDesignator = 'H';
+    else if ((-40 > lat) && (lat >= -48)) LetterDesignator = 'G';
+    else if ((-48 > lat) && (lat >= -56)) LetterDesignator = 'F';
+    else if ((-56 > lat) && (lat >= -64)) LetterDesignator = 'E';
+    else if ((-64 > lat) && (lat >= -72)) LetterDesignator = 'D';
+    else if ((-72 > lat) && (lat >= -80)) LetterDesignator = 'C';
+    else {
+        //
+        // We're dealing with UPS (N/S Pole) coordinates, not UTM
+        //
+        if (lat > 84) { // North Pole, Y/Z zones
+            if ((0 <= lon) && (lon <= 180))
+                LetterDesignator = 'Z';     // E or + longitude
+            else
+                LetterDesignator = 'Y';     // W or - longitude
+        }
+        else {  // Lat < 80S, South Pole, A/B zones
+            if ((0 <= lon) && (lon <= 180))
+                LetterDesignator = 'B';     // E or + longitude
+            else
+                LetterDesignator = 'A';     // W or - longitude
+        }
+    }
+    return LetterDesignator;
+}
+
+
+
+
+
+// The following piece of code which implements UPS conversion is
+// derived from code that John Waers <jfwaers at csn.net> placed in
+// the public domain.  It's from his program "MacGPS45".
+// 
+static void calcPhi(double *phi, double e, double t)
+{
+        double old = PI/2.0 - 2.0 * atan(t);
+        short maxIterations = 20;
+        
+        while ( (fabs((*phi - old) / *phi) > 1.0e-8) && maxIterations-- ) { 
+                old = *phi;
+                *phi = PI/ 2.0 - 2.0 * atan( t * pow((1.0 - e * sin(*phi)) / ((1.0 + e * sin(*phi))), (e / 2.0)) );
+        }
+}
+
+
+
+
+
+// Converts from UTM/UPS coordinates to Lat/Long coordinates.
+//
+void utm_ups_to_ll(short ellipsoidID, const double utmNorthing, const double utmEasting,
+               const char* utmZone, double *lat,  double *lon)
+{
+    // Converts UTM coords to lat/long.  Equations from USGS
+    // Bulletin 1532.  East Longitudes are positive, West longitudes
+    // are negative.  North latitudes are positive, South latitudes
+    // are negative Lat and Long are in decimal degrees.
+    // Written by Chuck Gantz- chuck.gantz at globalstar.com
+    // Modified by WE7U to add UPS support.
+
+    double k0 = 0.9996;
+    double a = gEllipsoid[ellipsoidID].a;
+    double f = 1.0 / gEllipsoid[ellipsoidID].invf;
+    double eccSquared = (2 * f) - (f * f);
+    double eccPrimeSquared;
+    double e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared));
+    double N1, T1, C1, R1, D, M;
+    double LongOrigin;
+    double mu, phi1, phi1Rad;
+    double x, y;
+    int ZoneNumber;
+    char* ZoneLetter;
+    int NorthernHemisphere; // 1=northern hemisphere, 0=southern
+
+
+//fprintf(stderr,"%s  %f  %f\n",
+//    utmZone,
+//    utmEasting,
+//    utmNorthing);
+
+    x = utmEasting;
+    y = utmNorthing;
+
+    ZoneNumber = strtoul(utmZone, &ZoneLetter, 10);
+
+    // Remove any possible leading spaces
+    remove_leading_spaces(ZoneLetter);
+
+    // Make sure the zone letter is upper-case
+    *ZoneLetter = toupper(*ZoneLetter);
+
+//fprintf(stderr,"ZoneLetter: %s\n", ZoneLetter);
+
+    if (       *ZoneLetter == 'Y'       // North Pole
+            || *ZoneLetter == 'Z'       // North Pole
+            || *ZoneLetter == 'A'       // South Pole
+            || *ZoneLetter == 'B') {    // South Pole
+
+        // The following piece of code which implements UPS
+        // conversion is derived from code that John Waers
+        // <jfwaers at csn.net> placed in the public domain.  It's from
+        // his program "MacGPS45".
+ 
+        //
+        // We're dealing with a UPS coordinate (near the poles)
+        // instead of a UTM coordinate.  We need to do entirely
+        // different calculations for UPS.
+        //
+        double e, t, rho;
+        const double k0 = 0.994;
+
+
+//fprintf(stderr,"UPS Coordinates\n");
+
+
+        e = sqrt(eccSquared);
+
+        x -= 2.0e6; // Remove false easting and northing
+        y -= 2.0e6;
+
+        rho = sqrt(x*x + y*y);
+        t = rho * sqrt(pow(1.0+e, 1.0+e) * pow(1.0-e, 1.0-e)) / (2.0 * a * k0);
+
+        calcPhi(lat, e, t);
+
+        *lat /= (PI/180.0);
+
+        // This appears to be necessary in order to get proper
+        // positions in the south polar region
+        if (*ZoneLetter == 'A' || *ZoneLetter == 'B') {
+            *lat = -*lat;
+        }
+
+        if (y != 0.0)
+            t = atan(fabs(x/y));
+        else {
+            t = PI / 2.0;
+            if (x < 0.0) t = -t;
+        }
+
+        if (*ZoneLetter == 'Z' || *ZoneLetter == 'Y')
+            y = -y; // Northern hemisphere
+
+        if (y < 0.0)
+            t = PI - t;
+
+        if (x < 0.0)
+            t = -t;
+
+        *lon = t / (PI/180.0);
+
+/*
+        fprintf(stderr,"datum.c:utm_ups_to_ll(): Found UPS Coordinate: %s %f %f\n",
+            utmZone,
+            utmEasting,
+            utmNorthing);
+*/
+        return; // Done computing UPS coordinates
+    }
+
+
+    // If we make it here, we're working on UTM coordinates (not
+    // UPS coordinates).
+
+
+    x = utmEasting - 500000.0; //remove 500,000 meter offset for longitude
+    y = utmNorthing;
+ 
+
+    if ((*ZoneLetter - 'N') >= 0)
+        NorthernHemisphere = 1;//point is in northern hemisphere
+    else {
+        NorthernHemisphere = 0;//point is in southern hemisphere
+        y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
+    }
+
+    LongOrigin = (ZoneNumber - 1)*6 - 180 + 3;  //+3 puts origin in middle of zone
+
+    eccPrimeSquared = (eccSquared)/(1-eccSquared);
+
+    M = y / k0;
+    mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256));
+
+    phi1Rad = mu + (3*e1/2-27*e1*e1*e1/32)*sin(2*mu)
+                 + (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu)
+                 + (151*e1*e1*e1/96)*sin(6*mu);
+    phi1 = phi1Rad*rad2deg;
+
+    N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad));
+    T1 = tan(phi1Rad)*tan(phi1Rad);
+    C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad);
+    R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5);
+    D = x/(N1*k0);
+
+    *lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
+                                           +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720);
+    *lat *= rad2deg;
+
+    *lon = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)
+            *D*D*D*D*D/120)/cos(phi1Rad);
+    *lon = LongOrigin + (*lon) * rad2deg;
+}
+
+
diff --git a/src/datum.h b/src/datum.h
new file mode 100644
index 0000000..0d90d35
--- /dev/null
+++ b/src/datum.h
@@ -0,0 +1,112 @@
+/*
+   Portions Copyright (C) 2002-2012  The Xastir Group
+
+   The datum conversion code here and in datum.c is from MacGPS 45.
+
+   According to the Read_Me file in the source archive of that program,
+   the author says the following:
+
+   "I've read the legalese statements that everyone attaches to works like this,
+   but I can never remember what they say. Suffice it to say that I am releasing
+   this source code to the public domain, and you are free to do with it what you
+   like. If you find it of some use and include any of it in an application,
+   credits (and perhaps a copy of your program, if your feel so inclined) would
+   be appreciated.
+
+   John F. Waers <jfwaers at csn.net>"
+
+   If you ever read this, John, thanks for the code and feel free to try out
+   Xastir, it's free.
+
+   The UTM to/from Lat/Long translations were written by Chuck Gantz
+   <chuck.gantz at globalstar.com>.  Curt Mills received permission via e-mail
+   to release the code under the GPL for a conversion he did to perl.
+   I deduce from this that including it in Xastir, a GPL program is no problem.
+   Thanks Chuck!
+
+   N7TAP
+   $Id: datum.h,v 1.18 2012/11/01 18:57:19 we7u Exp $
+*/
+
+
+
+// Equatorial radius of the Earth.  In our distance/angular/area
+// calculations (not here in datum.h/datum.c, but elsewhere in the
+// code) we currently ignore flattening as you go towards the poles.
+//
+// The datum translation code in datum.h/datum.c doesn't use these
+// three defines at all:  That code uses ellipsoids and so
+// flattening is accounted for there.
+#define EARTH_RADIUS_METERS     6378138.0
+#define EARTH_RADIUS_KILOMETERS 6378.138
+#define EARTH_RADIUS_MILES      3963.1836
+
+
+#define FROM_WGS_84 1
+#define TO_WGS_84   0
+void wgs84_datum_shift(short fromWGS84, double *latitude, double *longitude, short datumID);
+void datum_shift(double *latitude, double *longitude, short fromDatumID, short toDatumID);
+
+typedef struct {
+    char  *name;    // name of ellipsoid
+    double a;       // semi-major axis, meters
+    double invf;    // 1/f
+} Ellipsoid;
+
+extern const Ellipsoid gEllipsoid[];
+
+enum Ellipsoid_Names { // Must match the order of the Ellipsoids defined in datum.c
+    E_AIRY_30,
+    E_MOD_AIRY,
+    E_AUS_NAT,
+    E_BESS_41,
+    E_BESS_41_NAM,
+    E_CLARKE_66,
+    E_CLARKE_80,
+    E_EVR_IND_30,
+    E_EVR_IND_56,
+    E_EVR_SAB_SAR,
+    E_EVR_MAL_69,
+    E_EVR_MAL_SING,
+    E_EVR_PAK,
+    E_FISCH_60_MERC,
+    E_MOD_FISCH_60,
+    E_FISCH_68,
+    E_HELM_06,
+    E_HOUGH_60,
+    E_IND_74,
+    E_INT_24,
+    E_KRASS_40,
+    E_GRS_67,
+    E_GRS_80,
+    E_S_AMER_69,
+    E_WGS_60,
+    E_WGS_66,
+    E_WGS_72,
+    E_WGS_84
+};
+    
+typedef struct {
+    char *name;
+    short ellipsoid;
+    short dx;
+    short dy;
+    short dz;
+} Datum;
+
+extern const Datum gDatum[];
+
+enum Common_Datum_Names { // Must match the indices of the Datums defined in datum.c
+    D_NAD_27_CONUS = 131,
+    D_NAD_83_CONUS = 138,
+    D_WGS_72 = 215,
+    D_WGS_84 = 216
+};
+
+void ll_to_utm_ups(short ellipsoidID, const double lat, const double lon,
+             double *utmNorthing, double *utmEasting, char* utmZone, int utmZoneLength);
+void utm_ups_to_ll(short ellipsoidID, const double utmNorthing, const double utmEasting,
+               const char* utmZone, double *lat, double *lon);
+char utm_letter_designator(double lat, double lon);
+
+
diff --git a/src/db.c b/src/db.c
new file mode 100644
index 0000000..8b09df9
--- /dev/null
+++ b/src/db.c
@@ -0,0 +1,19490 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: db.c,v 1.663 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/* Note: the header file for db.c should be called db.h, 
+ * but is named database.h to avoid conflicts with the 
+ * Berkeley DB package.  
+ */
+
+// NOTE:  decode_info_field() is a good place to start for decoding.
+
+
+// Used only for special debugging of message/station expiration.
+// Leave commented out for normal operation.
+//#define EXPIRE_DEBUG
+#define DEBUG_MESSAGE_REMOVE_CYCLE 15
+#define DEBUG_STATION_REMOVE_CYCLE 15
+#define DEBUG_MESSAGE_REMOVE 600
+#define DEBUG_STATION_REMOVE 600
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <math.h>
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "draw_symbols.h"
+#include "alert.h"
+#include "util.h"
+#include "bulletin_gui.h"
+#include "fcc_data.h"
+#include "geo.h"
+#include "gps.h"
+#include "rac_data.h"
+#include "interface.h"
+#include "maps.h"
+#include "wx.h"
+#include "igate.h"
+#include "list_gui.h"
+#include "objects.h"
+#include "track_gui.h"
+#include "xa_config.h"
+#include "x_spider.h"
+#include "db_gis.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+
+#define STATION_REMOVE_CYCLE 300    /* check station remove in seconds (every 5 minutes) */
+#define MESSAGE_REMOVE_CYCLE 600    /* check message remove in seconds (every 10 minutes) */
+#define IN_VIEW_MIN         600l    /* margin for off-screen stations, with possible trails on screen, in minutes */
+#define TRAIL_POINT_MARGIN   30l    /* margin for off-screen trails points, for segment to be drawn, in minutes */
+#define TRAIL_MAX_SPEED      900    /* max. acceptible speed for drawing trails, in mph */
+#define MY_TRAIL_COLOR      0x16    /* trail color index reserved for my station */
+#define TRAIL_ECHO_TIME       30    /* check for delayed echos during last 30 minutes */
+/* MY_TRAIL_DIFF_COLOR changed to user configurable my_trail_diff_color  */
+
+
+/////////////////////////////////////
+#define GUARD_SIZE 10
+char GUARD_BAND_THREE[GUARD_SIZE];
+/////////////////////////////////////
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+// Station Info
+Widget  db_station_popup = (Widget)NULL;
+char *db_station_info_callsign = NULL;
+Pixmap  SiS_icon0, SiS_icon;
+Widget  SiS_symb;
+Widget  station_list;
+Widget  button_store_track;
+int station_data_auto_update = 0;
+
+
+// Used to store all the calls we might "relay" digipeat by.
+// Separated by commas.  Up to 50 callsigns of 9 chars each plus
+// comma delimiters.
+char relay_digipeater_calls[10*MAX_RELAY_DIGIPEATER_CALLS];
+
+Widget si_text;
+Widget db_station_info  = (Widget)NULL;
+
+static xastir_mutex db_station_info_lock;
+static xastir_mutex db_station_popup_lock;
+
+void redraw_symbols(Widget w);
+int  delete_weather(DataRow *fill);
+int  delete_multipoints(DataRow *fill);
+void Station_data_destroy_track(Widget widget, XtPointer clientData, XtPointer callData);
+void my_station_gps_change(char *pos_long, char *pos_lat, char *course, char *speed, char speedu, char *alt, char *sats);
+void station_shortcuts_update_function(int hash_key, DataRow *p_rem);
+int position_on_extd_screen(long lat, long lon);  
+
+int  extract_speed_course(char *info, char *speed, char *course);
+int  extract_bearing_NRQ(char *info, char *bearing, char *nrq);
+
+int skip_dupe_checking;
+int  tracked_stations = 0;       // A count variable used in debug code only
+void track_station(Widget w, char *call_tracked, DataRow *p_station);
+
+int  new_message_data;
+time_t last_message_remove;     // last time we did a check for message removing
+
+////////////////////////////////////
+char GUARD_BAND_FOUR[GUARD_SIZE];
+////////////////////////////////////
+
+//// Save most recent 100 packets in an array called packet_data_string[]
+#define MAX_PACKET_DATA_DISPLAY 100
+int  redraw_on_new_packet_data;
+char packet_data_string[MAX_PACKET_DATA_DISPLAY][MAX_LINE_SIZE+1];
+int first_line=-1;
+int next_line=0;
+int ncharsdel=0;
+int nlinesadd=0;
+
+///////////////////////////////////
+char GUARD_BAND_ONE[GUARD_SIZE];
+///////////////////////////////////
+
+int station_count;              // number of stored stations
+int station_count_save = 0;     // old copy of above
+DataRow *n_first;               // pointer to first element in name sorted station list
+DataRow *n_last;                // pointer to last  element in name sorted station list
+DataRow *t_oldest;              // pointer to first element in time sorted station list (oldest)
+DataRow *t_newest;              // pointer to last  element in time sorted station list (newest)
+time_t last_station_remove;     // last time we did a check for station removing
+time_t last_sec,curr_sec;       // for comparing if seconds in time have changed
+int next_time_sn;               // time serial number for unique time index
+
+///////////////////////////////////
+char GUARD_BAND_TWO[GUARD_SIZE];
+///////////////////////////////////
+
+
+
+int emergency_distance_check = 1;
+float emergency_range = 280.0;  // Default is 4hrs @ 70mph distance
+
+CADRow *CAD_list_head = NULL;   // pointer to first element in CAD objects list
+
+void draw_trail(Widget w, DataRow *fill, int solid);
+void export_trail(DataRow *p_station);          // export trail of one or all stations to xastir export file
+//void export_trail_as_kml(DataRow *p_station);   // export trail of one or all stations to kml file
+
+int decoration_offset_x = 0;
+int decoration_offset_y = 0;
+int last_station_info_x = 0;
+int last_station_info_y = 0;
+int fcc_lookup_pushed = 0;
+int rac_lookup_pushed = 0;
+
+time_t last_object_check = 0;   // Used to determine when to re-transmit objects/items
+
+time_t last_emergency_time = 0;
+char last_emergency_callsign[MAX_CALLSIGN+1];
+int st_direct_timeout = 60 * 60;        // 60 minutes.
+
+// Used in search_station_name() function.  Shortcuts into the
+// station list based on the least-significant 7 bits of the first
+// two letters of the callsign/object name.
+DataRow *station_shortcuts[16384];
+
+// used to time aloha calculations
+static time_t aloha_time = 0;
+static time_t aloha_status_time = 0;
+static double aloha_radius=-1;  // in miles
+static aloha_stats the_aloha_stats;
+// calculate every half hour, display in status line every 5 minutes
+#define ALOHA_CALC_INTERVAL 1800 
+#define ALOHA_STATUS_INTERVAL 300
+
+int process_emergency_packet_again = 0;
+
+
+
+
+
+void db_init(void)
+{
+    int ii;
+
+
+    // Set up guard bands around important global pointers
+    for (ii = 0; ii < GUARD_SIZE; ii++) {
+        GUARD_BAND_ONE[ii]   = 0x00;
+        GUARD_BAND_TWO[ii]   = 0x00;
+        GUARD_BAND_THREE[ii] = 0x00;
+        GUARD_BAND_FOUR[ii]  = 0x00;
+    }
+
+    init_critical_section( &db_station_info_lock );
+    init_critical_section( &db_station_popup_lock );
+    last_emergency_callsign[0] = '\0';
+
+    // Seed the random number generator
+    srand(1);
+}
+
+
+
+
+
+///////////////////////////////////  Utilities  ////////////////////////////////////////////////////
+
+
+
+// Variable used for below test code
+//int we7u_count = 50;
+
+
+
+// Check guard bands around important global pointers.
+//
+// These guard bands are initialized in db.c:db_init()
+//
+// Returns:  0 if ok
+//           1 if guard band has been tampered with
+//
+int check_guard_band(void) {
+    int ii;
+
+    for (ii = 0; ii < GUARD_SIZE; ii++) {
+        if (GUARD_BAND_ONE[ii] != 0x00
+            || GUARD_BAND_TWO[ii] != 0x00
+            || GUARD_BAND_THREE[ii] != 0x00
+            || GUARD_BAND_FOUR[ii] != 0x00) {
+
+            if (GUARD_BAND_ONE[ii]   != 0x00)
+                fprintf(stderr, "WARNING: GUARD_BAND_ONE   was corrupted!\n");
+
+            if (GUARD_BAND_TWO[ii]   != 0x00)
+                fprintf(stderr, "WARNING: GUARD_BAND_TWO   was corrupted!\n");
+
+            if (GUARD_BAND_THREE[ii] != 0x00)
+                fprintf(stderr, "WARNING: GUARD_BAND_THREE was corrupted!\n");
+
+            if (GUARD_BAND_FOUR[ii]  != 0x00)
+                fprintf(stderr, "WARNING: GUARD_BAND_FOUR  was corrupted!\n");
+
+fprintf(stderr, "Previous incoming line was: %s\n", incoming_data_copy_previous);
+fprintf(stderr, "    Last incoming line was: %s\n", incoming_data_copy);
+
+abort();    // Cause immediate exit to aid in debugging
+
+            return(1);
+        }
+    }
+
+// Test code
+/*
+if (we7u_count-- <= 0) {
+    GUARD_BAND_ONE[0] = 0x01;
+    GUARD_BAND_TWO[0] = 0x01;
+    GUARD_BAND_THREE[0] = 0x01;
+    GUARD_BAND_FOUR[0] = 0x01;
+}
+*/
+
+    return(0);
+}
+
+
+
+
+
+/*
+ *  Check whether callsign is mine.  "exact == 1" checks the SSID
+ *  for a match as well.  "exact == 0" checks only the base
+ *  callsign.
+ */
+int is_my_call(char *call, int exact) {
+    char *p_del;
+    int ok;
+
+
+    // U.S. special-event callsigns can be as short as three
+    // characters, any less and we don't have a valid callsign.  We
+    // don't check for that restriction here though.
+
+    if (exact) {
+        // We're looking for an exact match
+        ok = (int)( !strcmp(call,my_callsign) );
+        //fprintf(stderr,"My exact call found: %s\n",call);
+    }
+    else {
+        // We're looking for a similar match.  Compare only up to
+        // the '-' in each (if present).
+        int len1,len2;
+
+        p_del = index(call,'-');
+        if (p_del == NULL)
+            len1 = (int)strlen(call);
+        else
+            len1 = p_del - call;
+
+        p_del = index(my_callsign,'-');
+        if (p_del == NULL)
+            len2 = (int)strlen(my_callsign);
+        else
+            len2 = p_del - my_callsign;
+
+        ok = (int)(len1 == len2 && !strncmp(call,my_callsign,(size_t)len1));
+        //fprintf(stderr,"My base call found: %s\n",call);
+    }
+ 
+    return(ok);
+}
+
+
+
+
+
+int is_my_station(DataRow *p_station) {
+    // if station is owned by me (including SSID)
+    return(p_station->flag & ST_MYSTATION);
+}
+
+
+
+
+
+int is_my_object_item(DataRow *p_station) {
+    // If object/item is owned by me (including SSID)
+    return(p_station->flag & ST_MYOBJITEM);
+}
+
+
+
+
+
+/*
+ *  Change map position if neccessary while tracking a station
+ *      we call it with defined station call and position
+ */
+int is_tracked_station(char *call_sign) {
+    int found;
+    char call_find[MAX_CALLSIGN+1];
+    int ii;
+    int call_len;
+
+    if (!track_station_on)
+        return(0);
+
+    call_len = 0;
+    found = 0;
+
+    if (!track_case) {
+        for ( ii = 0; ii < (int)strlen(tracking_station_call); ii++ ) {
+            if (isalpha((int)tracking_station_call[ii]))
+                call_find[ii] = toupper((int)tracking_station_call[ii]);
+            else
+                call_find[ii] = tracking_station_call[ii];
+        }
+        call_find[ii] = '\0';
+    }
+    else {
+        xastir_snprintf(call_find,
+            sizeof(call_find),
+            "%s",
+            tracking_station_call);
+    }
+
+    if (debug_level & 256) {
+        fprintf(stderr,"is_tracked_station(): CALL %s %s %s\n",
+            tracking_station_call,
+            call_find, call_sign);
+    }
+
+    if (track_match) {
+        if (strcmp(call_find,call_sign) == 0) { // we want an exact match
+            found = 1;
+        }
+    }
+    else {
+        found = 0;
+        call_len = (int)(strlen(call_sign) - strlen(call_find));
+        if (strlen(call_find) <= strlen(call_sign)) {
+            found = 1;
+            for ( ii = 0; ii <= call_len; ii++ ) {
+                if (!track_case) {
+                    if (!strncasecmp(call_find,call_sign+ii,strlen(call_find)) == 0) {
+                        found = 0;  // Found a mis-match
+                    }
+                }
+                else {
+                    if (!strncmp(call_find,call_sign+ii,strlen(call_find)) == 0) {
+                        found = 0;
+                    }
+                }
+            }
+        }
+    }
+    return(found);
+}
+
+
+
+
+
+/////////////////////////////////////////// Messages ///////////////////////////////////////////
+
+static long *msg_index;
+static long msg_index_end;
+static long msg_index_max;
+
+static Message *msg_data; // Array containing all messages,
+                          // including ones we've transmitted (via
+                          // loopback in the code)
+
+time_t last_message_update = 0;
+ack_record *ack_list_head = NULL;  // Head of linked list storing most recent ack's
+int satellite_ack_mode;
+
+
+// How often update_messages() will run, in seconds.
+// This is necessary because routines like UpdateTime()
+// call update_messages() VERY OFTEN.
+//
+// Actually, we just changed the code around so that we only call
+// update_messages() with the force option, and only when we receive a
+// message.  message_update_delay is no longer used, and we don't call
+// update_messages() from UpdateTime() anymore.
+static int message_update_delay = 300;
+
+
+
+
+
+// Saves latest ack in a linked list.  We need this value in order
+// to use Reply/Ack protocol when sending out messages.
+void store_most_recent_ack(char *callsign, char *ack) {
+    ack_record *p;
+    int done = 0;
+    char call[MAX_CALLSIGN+1];
+    char new_ack[5+1];
+
+    xastir_snprintf(call,
+        sizeof(call),
+        "%s",
+        callsign);
+    remove_trailing_spaces(call);
+
+    // Get a copy of "ack".  We might need to change it.
+    xastir_snprintf(new_ack,
+        sizeof(new_ack),
+        "%s",
+        ack);
+
+    // If it's more than 2 characters long, we can't use it for
+    // Reply/Ack protocol as there's only space enough for two.
+    // In this case we need to make sure that we blank out any
+    // former ack that was 1 or 2 characters, so that communications
+    // doesn't stop.
+    if ( strlen(new_ack) > 2 ) {
+        // It's too long, blank it out so that gets saved as "",
+        // which will overwrite any previously saved ack's that were
+        // short enough to use.
+        new_ack[0] = '\0';
+    }
+
+    // Search for matching callsign through linked list
+    p = ack_list_head;
+    while ( !done && (p != NULL) ) {
+        if (strcasecmp(call,p->callsign) == 0) {
+            done++;
+        }
+        else {
+            p = p->next;
+        }
+    }
+
+    if (done) { // Found it.  Update the ack field.
+        //fprintf(stderr,"Found callsign %s on recent ack list, Old:%s, New:%s\n",call,p->ack,new_ack);
+        xastir_snprintf(p->ack,sizeof(p->ack),"%s",new_ack);
+    }
+    else {  // Not found.  Add a new record to the beginning of the
+            // list.
+        //fprintf(stderr,"New callsign %s, adding to list.  Ack: %s\n",call,new_ack);
+        p = (ack_record *)malloc(sizeof(ack_record));
+        CHECKMALLOC(p);
+
+        xastir_snprintf(p->callsign,sizeof(p->callsign),"%s",call);
+        xastir_snprintf(p->ack,sizeof(p->ack),"%s",new_ack);
+        p->next = ack_list_head;
+        ack_list_head = p;
+    }
+}
+
+
+
+
+
+// Gets latest ack by callsign
+char *get_most_recent_ack(char *callsign) {
+    ack_record *p;
+    int done = 0;
+    char call[MAX_CALLSIGN+1];
+
+    xastir_snprintf(call,
+        sizeof(call),
+        "%s",
+        callsign);
+    remove_trailing_spaces(call);
+
+    // Search for matching callsign through linked list
+    p = ack_list_head;
+    while ( !done && (p != NULL) ) {
+        if (strcasecmp(call,p->callsign) == 0) {
+            done++;
+        }
+        else {
+            p = p->next;
+        }
+    }
+
+    if (done) { // Found it.  Return pointer to ack string.
+        //fprintf(stderr,"Found callsign %s on linked list, returning ack: %s\n",call,p->ack);
+        return(&p->ack[0]);
+    }
+    else {
+        //fprintf(stderr,"Callsign %s not found\n",call);
+        return(NULL);
+    }
+}
+
+
+
+
+
+void init_message_data(void) {  // called at start of main
+
+    new_message_data = 0;
+    last_message_remove = sec_now();
+}
+
+
+
+
+
+#ifdef MSG_DEBUG
+void msg_clear_data(Message *clear) {
+    int size;
+    int i;
+    unsigned char *data_ptr;
+
+    data_ptr = (unsigned char *)clear;
+    size=sizeof(Message);
+    for(i=0;i<size;i++)
+        *data_ptr++ = 0;
+}
+
+
+
+
+
+void msg_copy_data(Message *to, Message *from) {
+    int size;
+    int i;
+    unsigned char *data_ptr;
+    unsigned char *data_ptr_from;
+
+    data_ptr = (unsigned char *)to;
+    data_ptr_from = (unsigned char *)from;
+    size=sizeof(Message);
+    for(i=0;i<size;i++)
+        *data_ptr++ = *data_ptr_from++;
+}
+#endif /* MSG_DEBUG */
+
+
+
+
+
+// Returns 1 if it's time to update the messages again
+int message_update_time (void) {
+    if ( sec_now() > (last_message_update + message_update_delay) )
+        return(1);
+    else
+        return(0);
+}
+
+
+
+
+
+int msg_comp_active(const void *a, const void *b) {
+    char temp_a[MAX_CALLSIGN+MAX_CALLSIGN+MAX_MESSAGE_ORDER+2];
+    char temp_b[MAX_CALLSIGN+MAX_CALLSIGN+MAX_MESSAGE_ORDER+2];
+
+    xastir_snprintf(temp_a, sizeof(temp_a), "%c%s%s%s",
+            ((Message*)a)->active, ((Message*)a)->call_sign,
+            ((Message*)a)->from_call_sign,
+            ((Message*)a)->seq);
+    xastir_snprintf(temp_b, sizeof(temp_b), "%c%s%s%s",
+            ((Message*)b)->active, ((Message*)b)->call_sign,
+            ((Message*)b)->from_call_sign,
+            ((Message*)b)->seq);
+
+    return(strcmp(temp_a, temp_b));
+}
+
+
+
+
+
+int msg_comp_data(const void *a, const void *b) {
+    char temp_a[MAX_CALLSIGN+MAX_CALLSIGN+MAX_MESSAGE_ORDER+1];
+    char temp_b[MAX_CALLSIGN+MAX_CALLSIGN+MAX_MESSAGE_ORDER+1];
+
+    xastir_snprintf(temp_a, sizeof(temp_a), "%s%s%s",
+            msg_data[*(long*)a].call_sign, msg_data[*(long *)a].from_call_sign,
+            msg_data[*(long *)a].seq);
+    xastir_snprintf(temp_b, sizeof(temp_b), "%s%s%s", msg_data[*(long*)b].call_sign,
+            msg_data[*(long *)b].from_call_sign, msg_data[*(long *)b].seq);
+
+    return(strcmp(temp_a, temp_b));
+}
+
+
+
+
+
+void msg_input_database(Message *m_fill) {
+    void *m_ptr;
+    long i;
+
+    if (msg_index_end == msg_index_max) {
+        for (i = 0; i < msg_index_end; i++) {
+
+            // Check for a record that is marked RECORD_NOTACTIVE.
+            // If found, use that record instead of malloc'ing a new
+            // one.
+            if (msg_data[msg_index[i]].active == RECORD_NOTACTIVE) {
+
+                // Found an unused record.  Fill it in.
+                memcpy(&msg_data[msg_index[i]], m_fill, sizeof(Message));
+
+// Sort msg_data
+                qsort(msg_data, (size_t)msg_index_end, sizeof(Message), msg_comp_active);
+
+                for (i = 0; i < msg_index_end; i++) {
+                    msg_index[i] = i;
+                    if (msg_data[i].active == RECORD_NOTACTIVE) {
+                        msg_index_end = i;
+                        break;
+                    }
+                }
+
+// Sort msg_index
+                qsort(msg_index, (size_t)msg_index_end, sizeof(long *), msg_comp_data);
+
+                // All done with this message.
+                return;
+            }
+        }
+
+        // Didn't find free message record.  Fetch some more space.
+        // Get more msg_data space.
+        m_ptr = realloc(msg_data, (msg_index_max+MSG_INCREMENT)*sizeof(Message));
+        if (m_ptr) {
+            msg_data = m_ptr;
+
+            // Get more msg_index space
+            m_ptr = realloc(msg_index, (msg_index_max+MSG_INCREMENT)*sizeof(Message *));
+            if (m_ptr) {
+                msg_index = m_ptr;
+                msg_index_max += MSG_INCREMENT;
+
+//fprintf(stderr, "Max Message Array: %ld\n", msg_index_max);
+
+            }
+            else {
+                XtWarning("Unable to allocate more space for message index.\n");
+            }
+        }
+        else {
+            XtWarning("Unable to allocate more space for message database.\n");
+        }
+    }
+    if (msg_index_end < msg_index_max) {
+        msg_index[msg_index_end] = msg_index_end;
+
+        // Copy message data into new message record.
+        memcpy(&msg_data[msg_index_end++], m_fill, sizeof(Message));
+
+// Sort msg_index
+        qsort(msg_index, (size_t)msg_index_end, sizeof(long *), msg_comp_data);
+    }
+}
+
+
+
+
+
+// Does a binary search through a sorted message database looking
+// for a string match.
+//
+// If two or more messages match, this routine _should_ return the
+// message with the latest timestamp.  This will ensure that earlier
+// messages don't get mistaken for current messages, for the case
+// where the remote station did a restart and is using the same
+// sequence numbers over again.
+//
+long msg_find_data(Message *m_fill) {
+    long record_start, record_mid, record_end, return_record, done;
+    char tempfile[MAX_CALLSIGN+MAX_CALLSIGN+MAX_MESSAGE_ORDER+1];
+    char tempfill[MAX_CALLSIGN+MAX_CALLSIGN+MAX_MESSAGE_ORDER+1];
+
+
+    xastir_snprintf(tempfill, sizeof(tempfill), "%s%s%s",
+            m_fill->call_sign,
+            m_fill->from_call_sign,
+            m_fill->seq);
+
+    return_record = -1L;
+    if (msg_index && msg_index_end >= 1) {
+        /* more than one record */
+         record_start=0L;
+         record_end = (msg_index_end - 1);
+         record_mid=(record_end-record_start)/2;
+
+         done=0;
+         while (!done) {
+
+            /* get data for record start */
+            xastir_snprintf(tempfile, sizeof(tempfile), "%s%s%s",
+                    msg_data[msg_index[record_start]].call_sign,
+                    msg_data[msg_index[record_start]].from_call_sign,
+                    msg_data[msg_index[record_start]].seq);
+
+            if (strcmp(tempfill, tempfile) < 0) {
+                /* filename comes before */
+                /*fprintf(stderr,"Before No data found!!\n");*/
+                done=1;
+                break;
+            }
+            else { /* get data for record end */
+
+                xastir_snprintf(tempfile, sizeof(tempfile), "%s%s%s",
+                        msg_data[msg_index[record_end]].call_sign,
+                        msg_data[msg_index[record_end]].from_call_sign,
+                        msg_data[msg_index[record_end]].seq);
+
+                if (strcmp(tempfill,tempfile)>=0) { /* at end or beyond */
+                    if (strcmp(tempfill, tempfile) == 0) {
+                        return_record = record_end;
+//fprintf(stderr,"record %ld",return_record);
+                    }
+
+                    done=1;
+                    break;
+                }
+                else if ((record_mid == record_start) || (record_mid == record_end)) {
+                    /* no mid for compare check to see if in the middle */
+                    done=1;
+                    xastir_snprintf(tempfile, sizeof(tempfile), "%s%s%s",
+                            msg_data[msg_index[record_mid]].call_sign,
+                            msg_data[msg_index[record_mid]].from_call_sign,
+                            msg_data[msg_index[record_mid]].seq);
+                    if (strcmp(tempfill,tempfile)==0) {
+                        return_record = record_mid;
+//fprintf(stderr,"record: %ld",return_record);
+                    }
+                }
+            }
+            if (!done) { /* get data for record mid */
+                xastir_snprintf(tempfile, sizeof(tempfile), "%s%s%s",
+                        msg_data[msg_index[record_mid]].call_sign,
+                        msg_data[msg_index[record_mid]].from_call_sign,
+                        msg_data[msg_index[record_mid]].seq);
+
+                if (strcmp(tempfill, tempfile) == 0) {
+                    return_record = record_mid;
+//fprintf(stderr,"record %ld",return_record);
+                    done = 1;
+                    break;
+                }
+
+                if(strcmp(tempfill, tempfile)<0)
+                    record_end = record_mid;
+                else
+                    record_start = record_mid;
+
+                record_mid = record_start+(record_end-record_start)/2;
+            }
+        }
+    }
+    return(return_record);
+}
+
+
+
+
+
+void msg_replace_data(Message *m_fill, long record_num) {
+    memcpy(&msg_data[msg_index[record_num]], m_fill, sizeof(Message));
+}
+
+
+
+
+
+void msg_get_data(Message *m_fill, long record_num) {
+    memcpy(m_fill, &msg_data[msg_index[record_num]], sizeof(Message));
+}
+
+
+
+
+
+void msg_update_ack_stamp(long record_num) {
+
+    //fprintf(stderr,"Attempting to update ack stamp: %ld\n",record_num);
+    if ( (record_num >= 0) && (record_num < msg_index_end) ) {
+        msg_data[msg_index[record_num]].last_ack_sent = sec_now();
+        //fprintf(stderr,"Ack stamp: %ld\n",msg_data[msg_index[record_num]].last_ack_sent);
+    }
+    //fprintf(stderr,"\n\n\n*** Record: %ld ***\n\n\n",record_num);
+}
+
+
+
+
+
+// Called when we receive an ACK.  Sets the "acked" field in a
+// Message which gets rid of the highlighting in the Send Message
+// dialog for that message line.  This lets us know which messages
+// have been acked and which have not.  If timeout is non-zero, then
+// set acked to 2:  We use this in update_messages() to flag that
+// "*TIMEOUT*" should prefix the string.  If cancelled is non-zero,
+// set acked to 3:  We use this in update_messages() to flag that
+// "*CANCELLED*" should prefix the string.
+//
+void msg_record_ack(char *to_call_sign,
+                    char *my_call,
+                    char *seq,
+                    int timeout,
+                    int cancel) {
+    Message m_fill;
+    long record;
+    int do_update = 0;
+
+    if (debug_level & 1) {
+        fprintf(stderr,"Recording ack for message to: %s, seq: %s\n",
+            to_call_sign,
+            seq);
+    }
+
+    // Find the corresponding message in msg_data[i], set the
+    // "acked" field to one.
+
+    substr(m_fill.call_sign, to_call_sign, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign, my_call, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.from_call_sign);
+
+    substr(m_fill.seq, seq, MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+    // Look for a message with the same to_call_sign, my_call,
+    // and seq number
+    record = msg_find_data(&m_fill);
+
+    if (record == -1L) { // No match yet, try another tactic.
+        if (seq[2] == '}' && strlen(seq) == 3) {
+
+            // Try it again without the trailing '}' character
+            m_fill.from_call_sign[2] = '\0';
+
+            // Look for a message with the same to_call_sign,
+            // my_call, and seq number (minus the trailing '}')
+            record = msg_find_data(&m_fill);
+        }
+    }
+
+    if(record != -1L) {     // Found a match!
+        if (debug_level & 1) {
+            fprintf(stderr,"Found in msg db, updating acked field %d -> 1, seq %s, record %ld\n",
+                msg_data[msg_index[record]].acked,
+                seq,
+                record);
+        }
+        // Only cause an update if this is the first ack.  This
+        // reduces dialog "flashing" a great deal
+        if ( msg_data[msg_index[record]].acked == 0 ) {
+
+            // Check for my callsign (including SSID).  If found,
+            // update any open message dialogs
+            if (is_my_call(msg_data[msg_index[record]].from_call_sign, 1) ) {
+
+                //fprintf(stderr,"From: %s\tTo: %s\n",
+                //    msg_data[msg_index[record]].from_call_sign,
+                //    msg_data[msg_index[record]].call_sign);
+
+                do_update++;
+            }
+        }
+        else {  // This message has already been acked.
+        }
+
+        if (cancel)
+            msg_data[msg_index[record]].acked = (char)3;
+        else if (timeout)
+            msg_data[msg_index[record]].acked = (char)2;
+        else
+            msg_data[msg_index[record]].acked = (char)1;
+
+        // Set the interval to zero so that we don't display it
+        // anymore in the dialog.  Same for tries.
+        msg_data[msg_index[record]].interval = 0;
+        msg_data[msg_index[record]].tries = 0;
+
+        if (debug_level & 1) {
+            fprintf(stderr,"Found in msg db, updating acked field %d -> 1, seq %s, record %ld\n\n",
+                msg_data[msg_index[record]].acked,
+                seq,
+                record);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"Matching message not found\n");
+    }
+
+    if (do_update) {
+
+        update_messages(1); // Force an update
+
+        // Call check_popup_messages() here in order to pop up any
+        // closed Send Message dialogs.  For first ack's or
+        // CANCELLED messages it is less important, but for TIMEOUT
+        // messages it is very important.
+        //
+        (void)check_popup_window(m_fill.call_sign, 2);  // Calls update_messages()
+    }
+}
+
+
+
+
+
+// Called when we receive a REJ packet (reject).  Sets the "acked"
+// field in a Message to 4 to indicate that the message has been
+// rejected by the remote station.  This gets rid of the
+// highlighting in the Send Message dialog for that message line.
+// This lets us know which messages have been rejected and which
+// have not.  We use this in update_messages() to flag that
+// "*REJECTED*" should prefix the string.
+//
+// The most common source of REJ packets would be from sending to a
+// D700A who's buffers are full, so that it can't take another
+// message.
+//
+void msg_record_rej(char *to_call_sign,
+                    char *my_call,
+                    char *seq) {
+    Message m_fill;
+    long record;
+    int do_update = 0;
+
+    if (debug_level & 1) {
+        fprintf(stderr,"Recording rej for message to: %s, seq: %s\n",
+            to_call_sign,
+            seq);
+    }
+
+    // Find the corresponding message in msg_data[i], set the
+    // "acked" field to four.
+
+    substr(m_fill.call_sign, to_call_sign, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign, my_call, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.from_call_sign);
+
+    substr(m_fill.seq, seq, MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+    // Look for a message with the same to_call_sign, my_call,
+    // and seq number
+    record = msg_find_data(&m_fill);
+
+    if (record == -1L) { // No match yet, try another tactic.
+        if (seq[2] == '}' && strlen(seq) == 3) {
+
+            // Try it again without the trailing '}' character
+            m_fill.from_call_sign[2] = '\0';
+
+            // Look for a message with the same to_call_sign,
+            // my_call, and seq number (minus the trailing '}')
+            record = msg_find_data(&m_fill);
+        }
+    }
+
+    if(record != -1L) {     // Found a match!
+        if (debug_level & 1) {
+            fprintf(stderr,"Found in msg db, updating acked field %d -> 4, seq %s, record %ld\n",
+                msg_data[msg_index[record]].acked,
+                seq,
+                record);
+        }
+        // Only cause an update if this is the first rej.  This
+        // reduces dialog "flashing" a great deal
+        if ( msg_data[msg_index[record]].acked == 0 ) {
+
+            // Check for my callsign (including SSID).  If found,
+            // update any open message dialogs
+            if (is_my_call(msg_data[msg_index[record]].from_call_sign, 1) ) {
+
+                //fprintf(stderr,"From: %s\tTo: %s\n",
+                //    msg_data[msg_index[record]].from_call_sign,
+                //    msg_data[msg_index[record]].call_sign);
+
+                do_update++;
+            }
+        }
+        else {  // This message has already been acked.
+        }
+
+        // Actually record the REJ here
+        msg_data[msg_index[record]].acked = (char)4;
+
+        // Set the interval to zero so that we don't display it
+        // anymore in the dialog.  Same for tries.
+        msg_data[msg_index[record]].interval = 0;
+        msg_data[msg_index[record]].tries = 0;
+
+        if (debug_level & 1) {
+            fprintf(stderr,"Found in msg db, updating acked field %d -> 4, seq %s, record %ld\n\n",
+                msg_data[msg_index[record]].acked,
+                seq,
+                record);
+        }
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"Matching message not found\n");
+    }
+
+    if (do_update) {
+
+        update_messages(1); // Force an update
+
+        // Call check_popup_messages() here in order to pop up any
+        // closed Send Message dialogs.  For first ack's or
+        // CANCELLED messages it is less important, but for TIMEOUT
+        // messages it is very important.
+        //
+        (void)check_popup_window(m_fill.call_sign, 2);  // Calls update_messages()
+    }
+}
+
+
+
+
+
+// Called from check_and_transmit_messages().  Updates the interval
+// field in our message record for the message currently being
+// transmitted.  We'll use this in the Send Message dialog to
+// display the current message interval.
+//
+void msg_record_interval_tries(char *to_call_sign,
+                    char *my_call,
+                    char *seq,
+                    time_t interval,
+                    int tries) {
+    Message m_fill;
+    long record;
+
+    if (debug_level & 1) {
+        fprintf(stderr,"Recording interval for message to: %s, seq: %s\n",
+            to_call_sign,
+            seq);
+    }
+
+    // Find the corresponding message in msg_data[i]
+
+    substr(m_fill.call_sign, to_call_sign, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign, my_call, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.from_call_sign);
+
+    substr(m_fill.seq, seq, MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+    // Look for a message with the same to_call_sign, my_call,
+    // and seq number
+    record = msg_find_data(&m_fill);
+    if(record != -1L) {     // Found a match!
+        if (debug_level & 1) {
+            fprintf(stderr,
+                "Found in msg db, updating interval field %ld -> 1, seq %s, record %ld\n",
+                (long)msg_data[msg_index[record]].interval,
+                seq,
+                record);
+        }
+
+        msg_data[msg_index[record]].interval = interval;
+        msg_data[msg_index[record]].tries = tries;
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"Matching message not found\n");
+    }
+
+    update_messages(1); // Force an update
+}
+
+
+
+
+
+// Returns: time_t for last_ack_sent
+//          -1 if the message doesn't pass our tests
+//           0 if it is a new message.
+//
+// Also returns the record number found if not passed a NULL pointer
+// in record_out or -1L if it's a new record.
+//
+time_t msg_data_add(char *call_sign, char *from_call, char *data,
+        char *seq, char type, char from, long *record_out) {
+    Message m_fill;
+    long record;
+    char time_data[MAX_TIME];
+    int do_msg_update = 0;
+    time_t last_ack_sent;
+    int distance = -1;
+    char temp[10];
+    int group_message = 0;
+
+
+    if (debug_level & 1)
+        fprintf(stderr,"msg_data_add start\n");
+//fprintf(stderr,"from:%s, to:%s, seq:%s\n", from_call, call_sign, seq);
+
+    // Set the default output condition.  We'll change this later if
+    // we need to.
+    if (record_out != NULL)
+        *record_out = -1l;
+
+    // Check for some reasonable string in call_sign parameter
+    if (call_sign == NULL || strlen(call_sign) == 0) {
+        if (debug_level & 1)
+            fprintf(stderr,"msg_data_add():call_sign was NULL or empty, exiting\n");
+        return((time_t)-1l);
+    }
+//else
+//fprintf(stderr,"msg_data_add():call_sign: %s\n", call_sign);
+ 
+    if ( (data != NULL) && (strlen(data) > MAX_MESSAGE_LENGTH) ) {
+        if (debug_level & 2)
+            fprintf(stderr,"msg_data_add:  Message length too long\n");
+        return((time_t)-1l);
+    }
+
+    substr(m_fill.call_sign, call_sign, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign, from_call, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.seq, seq, MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+// If the sequence number is blank, then it may have been a query,
+// directed query, or group message.  Assume it is a new message in
+// each case and add it.
+
+    if (seq[0] != '\0') {   // Normal station->station messaging or
+                            // bulletins
+        // Look for a message with the same call_sign,
+        // from_call_sign, and seq number
+        record = msg_find_data(&m_fill);
+//fprintf(stderr,"RECORD %ld  \n",record);
+//fprintf(stderr,"Normal station->station message\n");
+    }
+    else {  // Group message/query/etc.
+        record = -1L;
+        group_message++;    // Flag it as a group message
+//fprintf(stderr,"Group message/query/etc\n");
+    }
+    msg_clear_data(&m_fill);
+    if(record != -1L) { /* fill old data */
+        msg_get_data(&m_fill, record);
+        last_ack_sent = m_fill.last_ack_sent;
+        //fprintf(stderr,"Found: last_ack_sent: %ld\n",m_fill.last_ack_sent);
+
+        //fprintf(stderr,"Found a duplicate message.  Updating fields, seq %s\n",seq);
+
+        // If message is different this time, do an update to the
+        // send message window and update the sec_heard field.  The
+        // remote station must have restarted and is re-using the
+        // sequence numbers.  What a pain!
+        if (strcmp(m_fill.message_line,data) != 0) {
+            m_fill.sec_heard = sec_now();
+            last_ack_sent = (time_t)0;
+//fprintf(stderr,"Message is different this time: Setting last_ack_sent to 0\n");
+ 
+            if (type != MESSAGE_BULLETIN) { // Not a bulletin
+                do_msg_update++;
+            }
+        }
+
+        // If message is the same, but the sec_heard field is quite
+        // old (more than 8 hours), the remote station must have
+        // restarted, is re-using the sequence numbers, and just
+        // happened to send the same message with the same sequence
+        // number.  Again, what a pain!  Either that, or we
+        // connected to a spigot with a _really_ long queue!
+        if (m_fill.sec_heard < (sec_now() - (8 * 60 * 60) )) {
+            m_fill.sec_heard = sec_now();
+            last_ack_sent = (time_t)0;
+//fprintf(stderr,"Found >8hrs old: Setting last_ack_sent to 0\n");
+
+            if (type != MESSAGE_BULLETIN) { // Not a bulletin
+                do_msg_update++;
+            }
+        }
+
+        // Check for zero time
+        if (m_fill.sec_heard == (time_t)0) {
+            m_fill.sec_heard = sec_now();
+            fprintf(stderr,"Zero time on a previous message.\n");
+        }
+    }
+    else {
+        // Only do this if it's a new message.  This keeps things
+        // more in sequence by not updating the time stamps
+        // constantly on old messages that don't get ack'ed.
+        m_fill.sec_heard = sec_now();
+        last_ack_sent = (time_t)0;
+        //fprintf(stderr,"New msg: Setting last_ack_sent to 0\n");
+
+        if (type != MESSAGE_BULLETIN) { // Not a bulletin
+//fprintf(stderr,"Found new message\n");
+            do_msg_update++;    // Always do an update to the
+                                // message window for new messages
+        }
+    }
+
+    /* FROM */
+    m_fill.data_via=from;
+    m_fill.active=RECORD_ACTIVE;
+    m_fill.type=type;
+    if (m_fill.heard_via_tnc != VIA_TNC)
+        m_fill.heard_via_tnc = (from == 'T') ? VIA_TNC : NOT_VIA_TNC;
+
+    distance = (int)(distance_from_my_station(from_call,temp) + 0.9999);
+ 
+    if (distance != 0) {    // Have a posit from the sending station
+        m_fill.position_known = 1;
+        //fprintf(stderr,"Position known: %s\n",from_call);
+    }
+    else {
+        //fprintf(stderr,"Position not known: %s\n",from_call);
+    }
+
+    substr(m_fill.call_sign,call_sign,MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign,from_call,MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.from_call_sign);
+
+    // Update the message field
+    substr(m_fill.message_line,data,MAX_MESSAGE_LENGTH);
+
+    substr(m_fill.seq,seq,MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+    // Create a timestamp from the current time
+    xastir_snprintf(m_fill.packet_time,
+        sizeof(m_fill.packet_time),
+        "%s",
+        get_time(time_data));
+
+    if(record == -1L) {     // No old record found
+        if (group_message)
+            m_fill.acked = 1;   // Group msgs/queries need no ack
+        else
+            m_fill.acked = 0;   // We can't have been acked yet
+
+        m_fill.interval = 0;
+        m_fill.tries = 0;
+
+        // We'll be sending an ack right away if this is a new
+        // message, so might as well set the time now so that we
+        // don't care about failing to set it in
+        // msg_update_ack_stamp due to the record number being -1.
+        m_fill.last_ack_sent = sec_now();
+
+        msg_input_database(&m_fill);    // Create a new entry
+        //fprintf(stderr,"No record found: Setting last_ack_sent to sec_now()00\n");
+    }
+    else {  // Old record found
+        //fprintf(stderr,"Replacing the message in the database, seq %s\n",seq);
+        msg_replace_data(&m_fill, record);  // Copy fields from m_fill to record
+    }
+
+    /* display messages */
+    if (type == MESSAGE_MESSAGE)
+        all_messages(from,call_sign,from_call,data);
+
+    // Check for my callsign (including SSID).  If found, update any
+    // open message dialogs
+    if (       is_my_call(m_fill.from_call_sign, 1)
+            || is_my_call(m_fill.call_sign, 1) ) {
+
+        if (do_msg_update) {
+            update_messages(1); // Force an update
+        }
+    }
+ 
+    if (debug_level & 1)
+        fprintf(stderr,"msg_data_add end\n");
+
+    // Return the important variables we'll need
+    if (record_out != NULL)
+        *record_out = record;
+
+//fprintf(stderr,"\nrecord_out:%ld record %ld\n",*record_out,record);
+    return(last_ack_sent);
+
+}   // End of msg_data_add()
+
+
+
+
+
+// alert_data_add:  Function which adds NWS weather alerts to the
+// alert hash.
+//
+// This function adds alerts directly to the alert hash, bypassing
+// the message list and associated message-scan functions.
+//
+void alert_data_add(char *call_sign, char *from_call, char *data,
+        char *seq, char type, char from) {
+    Message m_fill;
+    char time_data[MAX_TIME];
+    char user_base_dir[MAX_VALUE];
+
+    if (debug_level & 2)
+        fprintf(stderr,"alert_data_add start\n");
+
+
+    if (log_wx_alert_data && from != DATA_VIA_FILE) {
+        char temp_msg[MAX_MESSAGE_LENGTH+1];
+
+        // Attempt to reconstruct the original weather alert packet
+        // here, minus the path.
+        xastir_snprintf(temp_msg,
+            sizeof(temp_msg),
+            "%s>APRS::%-9s:%s{%s",
+            from_call,
+            call_sign,
+            data,
+            seq);
+        log_data( get_user_base_dir(LOGFILE_WX_ALERT, user_base_dir, 
+                                    sizeof(user_base_dir)), 
+                  temp_msg);
+//        fprintf(stderr, "%s\n", temp_msg);
+    }
+
+
+    if ( (data != NULL) && (strlen(data) > MAX_MESSAGE_LENGTH) ) {
+        if (debug_level & 2)
+            fprintf(stderr,"alert_data_add:  Message length too long\n");
+        return;
+    }
+
+    substr(m_fill.call_sign, call_sign, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign, from_call, MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.seq, seq, MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+    m_fill.sec_heard = sec_now();
+
+    /* FROM */
+    m_fill.data_via=from;
+    m_fill.active=RECORD_ACTIVE;
+    m_fill.type=type;
+
+    // We don't have a value filled in yet here!
+    //if (m_fill.heard_via_tnc != VIA_TNC)
+    m_fill.heard_via_tnc = (from == 'T') ? VIA_TNC : NOT_VIA_TNC;
+
+    substr(m_fill.call_sign,call_sign,MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.call_sign);
+
+    substr(m_fill.from_call_sign,from_call,MAX_CALLSIGN);
+    (void)remove_trailing_asterisk(m_fill.from_call_sign);
+
+    // Update the message field
+    substr(m_fill.message_line,data,MAX_MESSAGE_LENGTH);
+
+    substr(m_fill.seq,seq,MAX_MESSAGE_ORDER);
+    (void)remove_trailing_spaces(m_fill.seq);
+    (void)remove_leading_spaces(m_fill.seq);
+
+    // Create a timestamp from the current time
+    xastir_snprintf(m_fill.packet_time,
+        sizeof(m_fill.packet_time),
+        "%s",
+        get_time(time_data));
+
+    // Go try to add it to our alert hash.  alert_build_list() will
+    // check for duplicates before adding it.
+
+    alert_build_list(&m_fill);
+
+    // This function fills in the Shapefile filename and index
+    // so that we can later draw it.
+    fill_in_new_alert_entries();
+
+    if (debug_level & 2)
+        fprintf(stderr,"alert_data_add end\n");
+
+}   // End of alert_data_add()
+ 
+
+
+
+
+// What I'd like to do for the following routine:  Use
+// XmTextGetInsertionPosition() or XmTextGetCursorPosition() to
+// find the last of the text.  Could also save the position for
+// each SendMessage window.  Compare the timestamps of messages
+// found with the last update time.  If newer, then add them to
+// the end.  This should stop the incessant scrolling.
+
+// Another idea, easier method:  Create a buffer.  Snag out the
+// messages from the array and sort by time.  Put them into a
+// buffer.  Figure out the length of the text widget, and append
+// the extra length of the buffer onto the end of the text widget.
+// Once the message data is turned into a linked list, it might
+// be sorted already by time, so this window will look better
+// anyway.
+
+// Calling update_messages with force == 1 will cause an update
+// no matter what message_update_time() says.
+void update_messages(int force) {
+    static XmTextPosition pos;
+    char temp1[MAX_CALLSIGN+1];
+    char temp2[500];
+    char stemp[20];
+    long i;
+    int mw_p;
+    char *temp_ptr;
+
+
+    if ( message_update_time() || force) {
+
+//fprintf(stderr,"update_messages()\n");
+
+        //fprintf(stderr,"Um %d\n",(int)sec_now() );
+
+        /* go through all mw_p's! */
+
+        // Perform this for each message window
+        for (mw_p=0; msg_index && mw_p < MAX_MESSAGE_WINDOWS; mw_p++) {
+            //pos=0;
+
+begin_critical_section(&send_message_dialog_lock, "db.c:update_messages" );
+
+            if (mw[mw_p].send_message_dialog!=NULL/* && mw[mw_p].message_group==1*/) {
+
+//fprintf(stderr,"\n");
+
+//fprintf(stderr,"found send_message_dialog\n");
+
+                // Clear the text from message window
+                XmTextReplace(mw[mw_p].send_message_text,
+                    (XmTextPosition) 0,
+                    XmTextGetLastPosition(mw[mw_p].send_message_text),
+                    "");
+
+                // Snag the callsign you're dealing with from the message dialogue
+                if (mw[mw_p].send_message_call_data != NULL) {
+                    temp_ptr = XmTextFieldGetString(mw[mw_p].send_message_call_data);
+                    xastir_snprintf(temp1,
+                        sizeof(temp1),
+                        "%s",
+                        temp_ptr);
+                    XtFree(temp_ptr);
+
+                    new_message_data--;
+                    if (new_message_data<0)
+                        new_message_data=0;
+
+                    if(strlen(temp1)>0) {   // We got a callsign from the dialog so
+                        // create a linked list of the message indexes in time-sorted order
+
+                        typedef struct _index_record {
+                            int index;
+                            time_t sec_heard;
+                            struct _index_record *next;
+                        } index_record;
+                        index_record *head = NULL;
+                        index_record *p_prev = NULL;
+                        index_record *p_next = NULL;
+
+                        // Allocate the first record (a dummy record)
+                        head = (index_record *)malloc(sizeof(index_record));
+                        CHECKMALLOC(head);
+
+                        head->index = -1;
+                        head->sec_heard = (time_t)0;
+                        head->next = NULL;
+
+                        (void)remove_trailing_spaces(temp1);
+                        (void)to_upper(temp1);
+
+                        pos = 0;
+                        // Loop through looking for messages to/from
+                        // that callsign (including SSID)
+                        for (i = 0; i < msg_index_end; i++) {
+                            if (msg_data[msg_index[i]].active == RECORD_ACTIVE
+                                    && (strcmp(temp1, msg_data[msg_index[i]].from_call_sign) == 0
+                                        || strcmp(temp1,msg_data[msg_index[i]].call_sign) == 0)
+                                    && (is_my_call(msg_data[msg_index[i]].from_call_sign, 1)
+                                        || is_my_call(msg_data[msg_index[i]].call_sign, 1)
+                                        || mw[mw_p].message_group ) ) {
+                                int done = 0;
+
+                                // Message matches our parameters so
+                                // save the relevant data about the
+                                // message in our linked list.  Compare
+                                // the sec_heard field to see whether
+                                // we're higher or lower, and insert the
+                                // record at the correct spot in the
+                                // list.  We end up with a time-sorted
+                                // list.
+                                p_prev  = head;
+                                p_next = p_prev->next;
+                                while (!done && (p_next != NULL)) {  // Loop until end of list or record inserted
+
+                                    //fprintf(stderr,"Looping, looking for insertion spot\n");
+
+                                    if (p_next->sec_heard <= msg_data[msg_index[i]].sec_heard) {
+                                        // Advance one record
+                                        p_prev = p_next;
+                                        p_next = p_prev->next;
+                                    }
+                                    else {  // We found the correct insertion spot
+                                        done++;
+                                    }
+                                }
+
+                                //fprintf(stderr,"Inserting\n");
+
+                                // Add the record in between p_prev and
+                                // p_next, even if we're at the end of
+                                // the list (in that case p_next will be
+                                // NULL.
+                                p_prev->next = (index_record *)malloc(sizeof(index_record));
+                                CHECKMALLOC(p_prev->next);
+
+                                p_prev->next->next = p_next; // Link to rest of records or NULL
+                                p_prev->next->index = i;
+                                p_prev->next->sec_heard = msg_data[msg_index[i]].sec_heard;
+// Remember to free this entire linked list before exiting the loop for
+// this message window!
+                            }
+                        }
+                        // Done processing the entire list for this
+                        // message window.
+
+                        //fprintf(stderr,"Done inserting/looping\n");
+
+                        if (head->next != NULL) {   // We have messages to display
+                            int done = 0;
+
+                            //fprintf(stderr,"We have messages to display\n");
+
+                            // Run through the linked list and dump the
+                            // info out.  It's now in time-sorted order.
+
+// Another optimization would be to keep a count of records added, then
+// later when we were dumping it out to the window, only dump the last
+// XX records out.
+
+                            p_prev = head->next;    // Skip the first dummy record
+                            p_next = p_prev->next;
+                            while (!done && (p_prev != NULL)) {  // Loop until end of list
+                                int j = p_prev->index;  // Snag the index out of the record
+                                char prefix[50];
+                                char interval_str[50];
+                                int offset = 22;    // Offset for highlighting
+
+
+                                //fprintf(stderr,"\nLooping through, reading messages\n");
+ 
+//fprintf(stderr,"acked: %d\n",msg_data[msg_index[j]].acked);
+ 
+                                // Message matches so snag the important pieces into a string
+                                xastir_snprintf(stemp, sizeof(stemp),
+                                    "%c%c/%c%c %c%c:%c%c",
+                                    msg_data[msg_index[j]].packet_time[0],
+                                    msg_data[msg_index[j]].packet_time[1],
+                                    msg_data[msg_index[j]].packet_time[2],
+                                    msg_data[msg_index[j]].packet_time[3],
+                                    msg_data[msg_index[j]].packet_time[8],
+                                    msg_data[msg_index[j]].packet_time[9],
+                                    msg_data[msg_index[j]].packet_time[10],
+                                    msg_data[msg_index[j]].packet_time[11]
+                                );
+
+// Somewhere in here we appear to be losing the first message.  It
+// doesn't get written to the window later in the QSO.  Same for
+// closing the window and re-opening it, putting the same callsign
+// in and pressing "New Call" button.  First message is missing.
+
+                                // Label the message line with who sent it.
+                                // If acked = 2 a timeout has occurred
+                                // If acked = 3 a cancel has occurred
+                                if (msg_data[msg_index[j]].acked == 2) {
+                                    xastir_snprintf(prefix,
+                                        sizeof(prefix),
+                                        "%s ",
+                                        langcode("WPUPMSB016") ); // "*TIMEOUT*"
+                                }
+                                else if (msg_data[msg_index[j]].acked == 3) {
+                                    xastir_snprintf(prefix,
+                                        sizeof(prefix),
+                                        "%s ",
+                                        langcode("WPUPMSB017") ); // "*CANCELLED*"
+                                }
+                                else if (msg_data[msg_index[j]].acked == 4) {
+                                    xastir_snprintf(prefix,
+                                        sizeof(prefix),
+                                        "%s ",
+                                        langcode("WPUPMSB018") ); // "*REJECTED*"
+                                }
+                                else prefix[0] = '\0';
+
+                                if (msg_data[msg_index[j]].interval) {
+                                    xastir_snprintf(interval_str,
+                                        sizeof(interval_str),
+                                        ">%d/%lds",
+                                        msg_data[msg_index[j]].tries + 1,
+                                        (long)msg_data[msg_index[j]].interval);
+
+                                    // Don't highlight the interval
+                                    // value
+                                    offset = offset + strlen(interval_str);
+                                }
+                                else {
+                                    interval_str[0] = '\0';
+                                }
+
+                                xastir_snprintf(temp2, sizeof(temp2),
+                                    "%s %-9s%s>%s%s\n",
+                                    // Debug code.  Trying to find sorting error
+                                    //"%ld  %s  %-9s>%s\n",
+                                    //msg_data[msg_index[j]].sec_heard,
+                                    stemp,
+                                    msg_data[msg_index[j]].from_call_sign,
+                                    interval_str,
+                                    prefix,
+                                    msg_data[msg_index[j]].message_line);
+
+//fprintf(stderr,"message: %s\n", msg_data[msg_index[j]].message_line);
+//fprintf(stderr,"update_messages: %s|%s", temp1, temp2);
+ 
+                                if (debug_level & 2) fprintf(stderr,"update_messages: %s|%s\n", temp1, temp2);
+                                // Replace the text from pos to pos+strlen(temp2) by the string "temp2"
+                                if (mw[mw_p].send_message_text != NULL) {
+
+                                    // Insert the text at the end
+//                                    XmTextReplace(mw[mw_p].send_message_text,
+//                                            pos,
+//                                            pos+strlen(temp2),
+//                                            temp2);
+
+                                    XmTextInsert(mw[mw_p].send_message_text,
+                                            pos,
+                                            temp2);
+ 
+                                    // Set highlighting based on the
+                                    // "acked" field.  Callsign
+                                    // match here includes SSID.
+//fprintf(stderr,"acked: %d\t",msg_data[msg_index[j]].acked);
+                                    if ( (msg_data[msg_index[j]].acked == 0)    // Not acked yet
+                                            && ( is_my_call(msg_data[msg_index[j]].from_call_sign, 1)) ) {
+//fprintf(stderr,"Setting underline\t");
+                                        XmTextSetHighlight(mw[mw_p].send_message_text,
+                                            pos+offset,
+                                            pos+strlen(temp2),
+                                            //XmHIGHLIGHT_SECONDARY_SELECTED); // Underlining
+                                            XmHIGHLIGHT_SELECTED);         // Reverse Video
+                                    }
+                                    else {  // Message was acked, get rid of highlighting
+//fprintf(stderr,"Setting normal\t");
+                                        XmTextSetHighlight(mw[mw_p].send_message_text,
+                                            pos+offset,
+                                            pos+strlen(temp2),
+                                            XmHIGHLIGHT_NORMAL);
+                                    }
+
+//fprintf(stderr,"Text: %s\n",temp2); 
+
+                                    pos += strlen(temp2);
+
+                                }
+
+                                // Advance to the next record in the list
+                                p_prev = p_next;
+                                if (p_next != NULL)
+                                    p_next = p_prev->next;
+
+                            }   // End of while
+                        }   // End of if
+                        else {  // No messages matched, list is empty
+                        }
+
+// What does this do?  Move all of the text?
+//                        if (pos > 0) {
+//                            if (mw[mw_p].send_message_text != NULL) {
+//                                XmTextReplace(mw[mw_p].send_message_text,
+//                                        --pos,
+//                                        XmTextGetLastPosition(mw[mw_p].send_message_text),
+//                                        "");
+//                            }
+//                        }
+
+                        //fprintf(stderr,"Free'ing list\n");
+
+                        // De-allocate the linked list
+                        p_prev = head;
+                        while (p_prev != NULL) {
+
+                            //fprintf(stderr,"You're free!\n");
+
+                            p_next = p_prev->next;
+                            free(p_prev);
+                            p_prev = p_next;
+                        }
+
+                        // Show the last added message in the window
+                        XmTextShowPosition(mw[mw_p].send_message_text,
+                            pos);
+                    }
+                }
+            }
+
+end_critical_section(&send_message_dialog_lock, "db.c:update_messages" );
+
+        }
+        last_message_update = sec_now();
+
+//fprintf(stderr,"Message index end: %ld\n",msg_index_end);
+ 
+    }
+}
+
+
+
+
+
+void mdelete_messages_from(char *from) {
+    long i;
+
+    // Mark message records with RECORD_NOTACTIVE.  This will mark
+    // them for re-use.
+    for (i = 0; msg_index && i < msg_index_end; i++)
+        if (strcmp(msg_data[i].call_sign, my_callsign) == 0 && strcmp(msg_data[i].from_call_sign, from) == 0)
+            msg_data[i].active = RECORD_NOTACTIVE;
+}
+
+
+
+
+
+void mdelete_messages_to(char *to) {
+    long i;
+
+    // Mark message records with RECORD_NOTACTIVE.  This will mark
+    // them for re-use.
+    for (i = 0; msg_index && i < msg_index_end; i++)
+        if (strcmp(msg_data[i].call_sign, to) == 0)
+            msg_data[i].active = RECORD_NOTACTIVE;
+}
+
+
+
+
+
+void mdelete_messages(char *to_from) {
+    long i;
+
+    // Mark message records with RECORD_NOTACTIVE.  This will mark
+    // them for re-use.
+    for (i = 0; msg_index && i < msg_index_end; i++)
+        if (strcmp(msg_data[i].call_sign, to_from) == 0 || strcmp(msg_data[i].from_call_sign, to_from) == 0)
+            msg_data[i].active = RECORD_NOTACTIVE;
+}
+
+
+
+
+
+void mdata_delete_type(const char msg_type, const time_t reference_time) {
+    long i;
+
+    // Mark message records with RECORD_NOTACTIVE.  This will mark
+    // them for re-use.
+    for (i = 0; msg_index && i < msg_index_end; i++)
+
+        if ((msg_type == '\0' || msg_type == msg_data[i].type)
+                && msg_data[i].active == RECORD_ACTIVE
+                && msg_data[i].sec_heard < reference_time)
+
+            msg_data[i].active = RECORD_NOTACTIVE;
+}
+
+
+
+
+
+void check_message_remove(time_t curr_sec) {       // called in timing loop
+
+    // Time to check for old messages again?  (Currently every ten
+    // minutes)
+#ifdef EXPIRE_DEBUG
+    if ( last_message_remove < (curr_sec - DEBUG_MESSAGE_REMOVE_CYCLE) ) {
+#else // EXPIRE_DEBUG
+    if ( last_message_remove < (curr_sec - MESSAGE_REMOVE_CYCLE) ) {
+#endif
+
+        // Yes it is.  Mark all messages that are older than
+        // sec_remove with the RECORD_NOTACTIVE flag.  This will
+        // mark them for re-use.
+#ifdef EXPIRE_DEBUG
+        mdata_delete_type('\0', curr_sec-DEBUG_MESSAGE_REMOVE);
+#else   // EXPIRE_DEBUG
+        mdata_delete_type('\0', curr_sec-sec_remove);
+#endif
+
+        last_message_remove = curr_sec;
+    }
+
+    // Should we sort them at this point so that the unused ones are
+    // near the end?  It looks like the message input functions do
+    // this, so I guess we don't need to do it here.
+}
+
+
+
+
+
+void mscan_file(char msg_type, void (*function)(Message *)) {
+    long i;
+
+    for (i = 0; msg_index && i < msg_index_end; i++)
+        if ((msg_type == '\0' || msg_type == msg_data[msg_index[i]].type) &&
+                msg_data[msg_index[i]].active == RECORD_ACTIVE)
+            function(&msg_data[msg_index[i]]);
+}
+
+
+
+
+
+void mprint_record(Message *m_fill) {
+    fprintf(stderr,
+        "%-9s>%-9s %s:%5s %s:%c :%s\n",
+        m_fill->from_call_sign,
+        m_fill->call_sign,
+        langcode("WPUPMSB013"), // "seq"
+        m_fill->seq,
+        langcode("WPUPMSB014"), // "type"
+        m_fill->type,
+        m_fill->message_line);
+}
+
+
+
+
+
+void mdisplay_file(char msg_type) {
+    fprintf(stderr,"\n\n");
+    mscan_file(msg_type, mprint_record);
+    fprintf(stderr,"\tmsg_index_end %ld, msg_index_max %ld\n", msg_index_end, msg_index_max);
+}
+
+
+
+
+
+/////////////////////////////////////// Station Data ///////////////////////////////////////////
+
+
+
+
+
+void pad_callsign(char *callsignout, char *callsignin) {
+    int i,l;
+
+    l=(int)strlen(callsignin);
+    for(i=0; i<9;i++) {
+        if(i<l) {
+            if(isalnum((int)callsignin[i]) || callsignin[i]=='-') {
+                callsignout[i]=callsignin[i];
+            }
+            else {
+                callsignout[i] = ' ';
+            }
+        }
+        else {
+            callsignout[i] = ' ';
+        }
+    }
+    callsignout[i] = '\0';
+}
+
+
+
+
+
+// Check for valid overlay characters:  'A-Z', '0-9', and 'a-j'.  If
+// 'a-j', it's from a compressed posit, and we need to convert it to
+// '0-9'.
+void overlay_symbol(char symbol, char data, DataRow *fill) {
+
+    if ( data != '/' && data !='\\') {  // Symbol overlay
+
+        if (data >= 'a' && data <= 'j') {
+            // Found a compressed posit numerical overlay
+            data = data - 'a'+'0';  // Convert to a digit
+        }
+        if ( (data >= '0' && data <= '9')
+                || (data >= 'A' && data <= 'Z') ) {
+            // Found normal overlay character
+            fill->aprs_symbol.aprs_type = '\\';
+            fill->aprs_symbol.special_overlay = data;
+        }
+        else {
+            // Bad overlay character.  Don't use it.  Insert the
+            // normal alternate table character instead.
+            fill->aprs_symbol.aprs_type = '\\';
+            fill->aprs_symbol.special_overlay='\0';
+        }
+    }
+    else {    // No overlay character
+        fill->aprs_symbol.aprs_type = data;
+        fill->aprs_symbol.special_overlay='\0';
+    }
+    fill->aprs_symbol.aprs_symbol = symbol;
+}
+
+
+
+
+
+APRS_Symbol *id_callsign(char *call_sign, char * to_call) {
+    char *ptr;
+    char *id = "/aUfbYX's><OjRkv";
+    char hold[MAX_CALLSIGN+1];
+    int index;
+    static APRS_Symbol symbol;
+
+    symbol.aprs_symbol = '/';
+    symbol.special_overlay = '\0';
+    symbol.aprs_type ='/';
+    ptr=strchr(call_sign,'-');
+    if(ptr!=NULL)                      /* get symbol from SSID */
+        if((index=atoi(ptr+1))<= 15)
+            symbol.aprs_symbol = id[index];
+
+    if (strncmp(to_call, "GPS", 3) == 0 || strncmp(to_call, "SPC", 3) == 0 || strncmp(to_call, "SYM", 3) == 0) {
+        substr(hold, to_call+3, 3);
+        if ((ptr = strpbrk(hold, "->,")) != NULL)
+            *ptr = '\0';
+
+        if (strlen(hold) >= 2) {
+            switch (hold[0]) {
+                case 'A':
+                    symbol.aprs_type = '\\';
+
+                case 'P':
+                    if (('0' <= hold[1] && hold[1] <= '9') || ('A' <= hold[1] && hold[1] <= 'Z'))
+                        symbol.aprs_symbol = hold[1];
+
+                    break;
+
+                case 'O':
+                    symbol.aprs_type = '\\';
+
+                case 'B':
+                    switch (hold[1]) {
+                        case 'B':
+                            symbol.aprs_symbol = '!';
+                            break;
+                        case 'C':
+                            symbol.aprs_symbol = '"';
+                            break;
+                        case 'D':
+                            symbol.aprs_symbol = '#';
+                            break;
+                        case 'E':
+                            symbol.aprs_symbol = '$';
+                            break;
+                        case 'F':
+                            symbol.aprs_symbol = '%';
+                            break;
+                        case 'G':
+                            symbol.aprs_symbol = '&';
+                            break;
+                        case 'H':
+                            symbol.aprs_symbol = '\'';
+                            break;
+                        case 'I':
+                            symbol.aprs_symbol = '(';
+                            break;
+                        case 'J':
+                            symbol.aprs_symbol = ')';
+                            break;
+                        case 'K':
+                            symbol.aprs_symbol = '*';
+                            break;
+                        case 'L':
+                            symbol.aprs_symbol = '+';
+                            break;
+                        case 'M':
+                            symbol.aprs_symbol = ',';
+                            break;
+                        case 'N':
+                            symbol.aprs_symbol = '-';
+                            break;
+                        case 'O':
+                            symbol.aprs_symbol = '.';
+                            break;
+                        case 'P':
+                            symbol.aprs_symbol = '/';
+                            break;
+                    }
+                    break;
+
+                case 'D':
+                    symbol.aprs_type = '\\';
+
+                case 'H':
+                    switch (hold[1]) {
+                        case 'S':
+                            symbol.aprs_symbol = '[';
+                            break;
+                        case 'T':
+                            symbol.aprs_symbol = '\\';
+                            break;
+                        case 'U':
+                            symbol.aprs_symbol = ']';
+                            break;
+                        case 'V':
+                            symbol.aprs_symbol = '^';
+                            break;
+                        case 'W':
+                            symbol.aprs_symbol = '_';
+                            break;
+                        case 'X':
+                            symbol.aprs_symbol = '`';
+                            break;
+                    }
+                    break;
+
+                case 'N':
+                    symbol.aprs_type = '\\';
+
+                case 'M':
+                    switch (hold[1]) {
+                        case 'R':
+                            symbol.aprs_symbol = ':';
+                            break;
+                        case 'S':
+                            symbol.aprs_symbol = ';';
+                            break;
+                        case 'T':
+                            symbol.aprs_symbol = '<';
+                            break;
+                        case 'U':
+                            symbol.aprs_symbol = '=';
+                            break;
+                        case 'V':
+                            symbol.aprs_symbol = '>';
+                            break;
+                        case 'W':
+                            symbol.aprs_symbol = '?';
+                            break;
+                        case 'X':
+                            symbol.aprs_symbol = '@';
+                            break;
+                    }
+                    break;
+
+                case 'Q':
+                    symbol.aprs_type = '\\';
+
+                case 'J':
+                    switch (hold[1]) {
+                        case '1':
+                            symbol.aprs_symbol = '{';
+                            break;
+                        case '2':
+                            symbol.aprs_symbol = '|';
+                            break;
+                        case '3':
+                            symbol.aprs_symbol = '}';
+                            break;
+                        case '4':
+                            symbol.aprs_symbol = '~';
+                            break;
+                    }
+                    break;
+
+                case 'S':
+                    symbol.aprs_type = '\\';
+
+                case 'L':
+                    if ('A' <= hold[1] && hold[1] <= 'Z')
+                        symbol.aprs_symbol = tolower((int)hold[1]);
+
+                    break;
+            }
+            if (hold[2]) {
+                if (hold[2] >= 'a' && hold[2] <= 'j') {
+                    // Compressed mode numeric overlay
+                    symbol.special_overlay = hold[2] - 'a';
+                }
+                else if ( (hold[2] >= '0' && hold[2] <= '9')
+                        || (hold[2] >= 'A' && hold[2] <= 'Z') ) {
+                    // Normal overlay character
+                    symbol.special_overlay = hold[2];
+                }
+                else {
+                    // Bad overlay character found
+                    symbol.special_overlay = '\0';
+                }
+            }
+            else {
+                // No overlay character found
+                symbol.special_overlay = '\0';
+            }
+        }
+    }
+    return(&symbol);
+}
+
+
+
+
+
+/******************************** Sort begin *************************** ****/
+
+
+
+
+
+void  clear_sort_file(char *filename) {
+    char ptr_filename[400];
+
+    xastir_snprintf(ptr_filename, sizeof(ptr_filename), "%s-ptr", filename);
+    (void)unlink(filename);
+    (void)unlink(ptr_filename);
+}
+
+
+
+
+
+void sort_reset_pointers(FILE *pointer,long new_data_ptr,long records, int type, long start_ptr) {
+    long cp;
+    long temp[13000];
+    long buffn,start_buffn;
+    long cp_records;
+    long max_buffer;
+    int my_size;
+
+    my_size=(int)sizeof(new_data_ptr);
+    max_buffer=13000l;
+    if(type==0) {
+        /* before start_ptr */
+        /* copy back pointers */
+        cp=start_ptr;
+        for(buffn=records; buffn > start_ptr; buffn-=max_buffer) {
+            start_buffn=buffn-max_buffer;
+            if(start_buffn<start_ptr)
+                start_buffn=start_ptr;
+
+            cp_records=buffn-start_buffn;
+            (void)fseek(pointer,(my_size*start_buffn),SEEK_SET);
+            if(fread(&temp,(my_size*cp_records),1,pointer)==1) {
+                (void)fseek(pointer,(my_size*(start_buffn+1)),SEEK_SET);
+                (void)fwrite(&temp,(my_size*cp_records),1,pointer);
+            }
+        }
+        /* copy new pointer in */
+        (void)fseek(pointer,(my_size*start_ptr),SEEK_SET);
+        (void)fwrite(&new_data_ptr,(size_t)my_size,1,pointer);
+    }
+}
+
+
+
+
+
+long sort_input_database(char *filename, char *fill, int size) {
+    FILE *my_data;
+    FILE *pointer;
+    char file_data[2000];
+
+    char ptr_filename[400];
+
+    char tempfile[2000];
+    char tempfill[2000];
+
+    int ptr_size;
+    long data_ptr;
+    long new_data_ptr;
+    long return_records;
+    long records;
+    long record_start;
+    long record_end;
+    long record_mid;
+    int done;
+
+    ptr_size=(int)sizeof(new_data_ptr);
+    xastir_snprintf(ptr_filename, sizeof(ptr_filename), "%s-ptr", filename);
+
+    /* get first string to sort on */
+    if (1 != sscanf(fill,"%1999s",tempfill)) {
+        fprintf(stderr,"sort_input_database(1): sscanf failed to parse\n");
+    }
+
+    data_ptr=0l;
+    my_data=NULL;
+    return_records=0l;
+    pointer = fopen(ptr_filename,"r+");
+    /* check if file is there */
+    if(pointer == NULL)
+      pointer = fopen(ptr_filename,"a+");
+
+    if(pointer!=NULL) {
+        my_data = fopen(filename,"a+");
+        if(my_data!=NULL) {
+
+            // Next statement needed for Solaris 7, as the fopen above
+            // doesn't put the filepointer at the end of the file.
+            (void) fseek(my_data,0l,SEEK_END);  //KD6ZWR
+
+            new_data_ptr = data_ptr = ftell(my_data);
+            (void)fwrite(fill,(size_t)size,1,my_data);
+            records = (data_ptr/size);
+            return_records=records+1;
+            if(records<1) {
+                /* no data yet */
+                (void)fseek(pointer,0l,SEEK_SET);
+                (void)fwrite(&data_ptr,(size_t)ptr_size,1,pointer);
+            }
+            else {
+                /* more than one record*/
+                (void)fseek(pointer,(ptr_size*records),SEEK_SET);
+                (void)fwrite(&data_ptr,(size_t)ptr_size,1,pointer);
+                record_start=0l;
+                record_end=records;
+                record_mid=(record_end-record_start)/2;
+                done=0;
+                while(!done) {
+                    /*fprintf(stderr,"Records Start %ld, Mid %ld, End %ld\n",record_start,record_mid,record_end);*/
+                    /* get data for record start */
+                    (void)fseek(pointer,(ptr_size*record_start),SEEK_SET);
+                    (void)fread(&data_ptr,(size_t)ptr_size,1,pointer);
+                    (void)fseek(my_data,data_ptr,SEEK_SET);
+                    if(fread(file_data,(size_t)size,1,my_data)==1) {
+                        /* COMPARE HERE */
+                        if (1 != sscanf(file_data,"%1999s",tempfile)) {
+                            fprintf(stderr,"sort_input_database(2): sscanf failed to parse\n");
+                        }
+                        if(strcasecmp(tempfill,tempfile)<0) {
+                            /* file name comes before */
+                            /*fprintf(stderr,"END - Before start\n");*/
+                            done=1;
+                            /* now place pointer before start*/
+                            sort_reset_pointers(pointer,new_data_ptr,records,0,record_start);
+                        }
+                        else {
+                            /* get data for record end */
+                            (void)fseek(pointer,(ptr_size*record_end),SEEK_SET);
+                            (void)fread(&data_ptr,(size_t)ptr_size,1,pointer);
+                            (void)fseek(my_data,data_ptr,SEEK_SET);
+                            if(fread(file_data,(size_t)size,1,my_data)==1) {
+                                /* COMPARE HERE */
+                                if (1 != sscanf(file_data,"%1999s",tempfile)) {
+                                    fprintf(stderr,"sort_input_database(3): sscanf failed to parse\n");
+                                }
+                                if(strcasecmp(tempfill,tempfile)>0) {
+                                    /* file name comes after */
+                                    /*fprintf(stderr,"END - After end\n");*/
+                                    done=1;
+                                    /* now place pointer after end */
+                                }
+                                else {
+                                    if((record_mid==record_start) || (record_mid==record_end)) {
+                                        /* no mid for compare check to see if in the middle */
+                                        /*fprintf(stderr,"END - NO Middle\n");*/
+                                        done=1;
+                                        /* now place pointer before start*/
+                                        if (record_mid==record_start)
+                                            sort_reset_pointers(pointer,new_data_ptr,records,0,record_mid+1);
+                                        else
+                                            sort_reset_pointers(pointer,new_data_ptr,records,0,record_mid-1);
+                                    }
+                                    else {
+                                        /* get data for record mid */
+                                        (void)fseek(pointer,(ptr_size*record_mid),SEEK_SET);
+                                        (void)fread(&data_ptr,(size_t)ptr_size,1,pointer);
+                                        (void)fseek(my_data,data_ptr,SEEK_SET);
+                                        if(fread(file_data,(size_t)size,1,my_data)==1) {
+                                            /* COMPARE HERE */
+                                            if (1 != sscanf(file_data,"%1999s",tempfile)) {
+                                                fprintf(stderr,"sort_input_database(4): sscanf failed to parse\n");
+                                            }
+                                            if(strcasecmp(tempfill,tempfile)<0) {
+                                                /* checking comes before */
+                                                /*record_start=0l;*/
+                                                record_end=record_mid;
+                                                record_mid=record_start+(record_end-record_start)/2;
+                                                /*fprintf(stderr,"TOP %ld, mid %ld\n",record_mid,record_end);*/
+                                            }
+                                            else {
+                                                /* checking comes after*/
+                                                record_start=record_mid;
+                                                /*record_end=end*/
+                                                record_mid=record_start+(record_end-record_start)/2;
+                                                /*fprintf(stderr,"BOTTOM start %ld, mid %ld\n",record_start,record_mid);*/
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        else
+            fprintf(stderr,"Could not open file %s\n",filename);
+    }
+    else
+        fprintf(stderr,"Could not open file %s\n",filename);
+
+    if(my_data!=NULL)
+        (void)fclose(my_data);
+
+    if(pointer!=NULL)
+        (void)fclose(pointer);
+
+    return(return_records);
+}
+
+
+
+
+
+/******************** sort end **********************/
+
+
+
+// is_altnet()
+//
+// Returns true if station fits the current altnet description.
+//
+int is_altnet(DataRow *p_station) {
+    char temp_altnet_call[20+1];
+    char temp2[20+1];
+    char *net_ptr;
+    int  altnet_match;
+    int  result;
+
+
+    // Snag a possible altnet call out of the record for later use
+    if (p_station->node_path_ptr != NULL)
+        substr(temp_altnet_call, p_station->node_path_ptr, MAX_CALLSIGN);
+    else
+        temp_altnet_call[0] = '\0';
+
+    // Save for later
+    xastir_snprintf(temp2,
+        sizeof(temp2),
+        "%s",
+        temp_altnet_call);
+
+    if ((net_ptr = strchr(temp_altnet_call, ',')))
+        *net_ptr = '\0';    // Chop the string at the first ',' character
+
+    for (altnet_match = (int)strlen(altnet_call); altnet && altnet_call[altnet_match-1] == '*'; altnet_match--);
+
+    result = (!strncmp(temp_altnet_call, altnet_call, (size_t)altnet_match)
+                 || !strcmp(temp_altnet_call, "local")
+                 || !strncmp(temp_altnet_call, "SPC", 3)
+                 || !strcmp(temp_altnet_call, "SPECL")
+//                 || is_my_call(p_station->call_sign,1)); // Check SSID as well
+                 || ( is_my_station(p_station) ) ) ;  // It's my callsign/SSID
+
+    if ( (debug_level & 1) && result )
+        fprintf(stderr,"%s  %-9s  %s\n", altnet_call, temp_altnet_call, temp2 );
+
+    return(result);
+}
+
+
+
+
+
+// Function which checks various filtering criteria (the Select struct)
+// and decides whether this station/object should be displayed.
+//
+// 0 = don't draw this station/object
+// 1 = ok to draw this station/object
+//
+int ok_to_draw_station(DataRow *p_station) {
+    time_t secs_now = sec_now();
+    // Check overall flag
+    if (Select_.none)
+        return 0;
+
+    // Check tactical flag
+    if (Select_.tactical
+            && (p_station->tactical_call_sign == NULL
+               || p_station->tactical_call_sign[0] == '\0'))
+        return 0;
+
+    // Check for my station and my objects/items
+//    if (strcmp(p_station->call_sign, my_callsign) == 0
+//        || (is_my_call(p_station->origin, 1)        // If station is owned by me (including SSID)
+//            && (   p_station->flag & ST_OBJECT      // And it's an object
+//                || p_station->flag & ST_ITEM) ) ) { // or an item
+//    if ( is_my_station(p_station) || is_my_object_item(p_station) ) {
+    if ( is_my_station(p_station) ) {
+        if (!Select_.mine)
+            return 0;
+    }
+    // Not mine, so check these next things
+    else {
+        // Check whether we wish to display TNC heard stations
+        if (p_station->flag & ST_VIATNC) {
+            if (!Select_.tnc)
+                return 0;
+
+            // Check whether we wish to display directly heard stations
+            if (p_station->flag & ST_DIRECT
+                    && secs_now < (p_station->direct_heard + st_direct_timeout)) {
+                if (!Select_.direct)
+                    return 0;
+            }
+            // Check whether we wish to display stations heard via a digi
+            else {
+                if (!Select_.via_digi)
+                    return 0;
+            }
+        }
+        // Check whether we wish to display net stations
+        else {
+            if (!Select_.net)
+                return 0;
+        }
+
+        // Check if we want to display data past the clear time
+        if (!Select_.old_data) {
+            if ((p_station->sec_heard + sec_clear) < secs_now)
+                return 0;
+        }
+    }
+
+
+    // Check whether object or item
+    if (p_station->flag & (ST_OBJECT | ST_ITEM)) {
+        // Check whether we wish to display objects/items
+        if (!Select_.objects ||
+            (!Select_.weather_objects && !Select_.gauge_objects && !Select_.other_objects))
+            return 0;
+
+        // Check if WX info and we wish to see it
+        if (p_station->weather_data) {
+            return Select_.weather_objects;
+        }
+        // Check if water gauge and we wish to see it
+        else if (p_station->aprs_symbol.aprs_type == '/'
+                 && p_station->aprs_symbol.aprs_symbol == 'w') {
+            return Select_.gauge_objects;
+        }
+        // Check if we wish to see other objects/items
+        else {
+            return Select_.other_objects;
+        }
+    }
+    else {    // Not an object or item
+        if (!Select_.stations ||
+            (!Select_.fixed_stations && !Select_.moving_stations && !Select_.weather_stations))
+            return 0;
+
+        // Check if we wish to see weather stations
+        if (p_station->weather_data) {
+            // We have weather data
+
+            // Check whether it is a citizen's weather station.
+            // Note that a "CW" prefix is Uruguay and "DW" prefix is
+            // Phillipines, so let's be careful how we filter here.
+            // All Cititzen's weather stations seen to date have had
+            // CW or DW and then four digits.
+            if ( (strncasecmp(p_station->call_sign,"CW",2) == 0)
+               || (strncasecmp(p_station->call_sign,"DW",2) == 0) ) {
+                if ( is_num_chr(p_station->call_sign[2])
+                     && is_num_chr(p_station->call_sign[3])
+                     && is_num_chr(p_station->call_sign[4])
+                     && is_num_chr(p_station->call_sign[5]) ) {
+                    return(Select_.weather_stations && Select_.CWOP_wx_stations);
+                }
+                else {
+                    return Select_.weather_stations;
+                }
+            }
+            else {
+                return Select_.weather_stations;
+            }
+        }
+        // Check if we wish to see other stations
+        else {
+            if (p_station->flag & ST_MOVING) {
+                return Select_.moving_stations;
+            }
+            else {
+                return Select_.fixed_stations;
+            }
+        }
+    }
+}
+
+
+
+
+
+// display_station
+//
+// single is 1 if the calling station wants to update only a
+// single station.  If updating multiple stations in a row, then
+// "single" will be passed to us as a zero.
+//
+// If current course/speed/altitude are absent, we check the last
+// track point to try to snag those numbers.
+//
+void display_station(Widget w, DataRow *p_station, int single) {
+    char temp_altitude[20];
+    char temp_course[20];
+    char temp_speed[20];
+    char dr_speed[20];
+    char temp_call[MAX_TACTICAL_CALL+1];
+    char wx_tm[50];
+    char temp_wx_temp[30];
+    char temp_wx_wind[40];
+    char temp_my_distance[20];
+    char temp_my_course[20];
+    char temp1_my_course[20];
+    char temp2_my_gauge_data[50];
+    time_t temp_sec_heard;
+    int temp_show_last_heard;
+    long l_lon, l_lat;
+    char orient;
+    float value;
+    char tmp[7+1];
+    int speed_ok = 0;
+    int course_ok = 0;
+    int wx_ghost = 0;
+    Pixmap drawing_target;
+    WeatherRow *weather = p_station->weather_data;
+    time_t secs_now = sec_now();
+    int ambiguity_flag;
+    long ambiguity_coord_lon, ambiguity_coord_lat;
+ 
+
+    if (debug_level & 128)
+        fprintf(stderr,"Display station (%s) called for Single=%d.\n", p_station->call_sign, single);
+
+    if (!ok_to_draw_station(p_station))
+        return;
+
+    // Set up call string for display
+    if (Display_.callsign) {
+        if (p_station->tactical_call_sign
+                && p_station->tactical_call_sign[0] != '\0') {
+            // Display tactical callsign instead if it has one
+            // defined.
+            xastir_snprintf(temp_call,
+                sizeof(temp_call),
+                "%s",
+                p_station->tactical_call_sign);
+        }
+        else {
+            // Display normal callsign.
+            xastir_snprintf(temp_call,
+                sizeof(temp_call),
+                "%s",
+                p_station->call_sign);
+        }
+    }
+    else {
+        temp_call[0] = '\0';
+    }
+
+    // Set up altitude string for display
+    temp_altitude[0] = '\0';
+
+    if (Display_.altitude) {
+        // Check whether we have altitude in the current data
+        if (strlen(p_station->altitude)>0) {
+            // Found it in the current data
+            xastir_snprintf(temp_altitude, sizeof(temp_altitude), "%.0f%s",
+                atof(p_station->altitude) * cvt_m2len, un_alt);
+        }
+
+        // Else check whether the previous position had altitude.
+        // Note that newest_trackpoint if it exists should be the
+        // same as the current data, so we have to go back one
+        // further trackpoint.
+        else if ( (p_station->newest_trackpoint != NULL)
+                && (p_station->newest_trackpoint->prev != NULL) ) {
+            if ( p_station->newest_trackpoint->prev->altitude > -99999l) {
+                // Found it in the tracklog
+                xastir_snprintf(temp_altitude, sizeof(temp_altitude), "%.0f%s",
+                    (float)(p_station->newest_trackpoint->prev->altitude * cvt_dm2len),
+                    un_alt);
+
+//                fprintf(stderr,"Trail data              with altitude: %s : %s\n",
+//                    p_station->call_sign,
+//                    temp_altitude);
+            }
+            else {
+                //fprintf(stderr,"Trail data w/o altitude                %s\n",
+                //    p_station->call_sign);
+            }
+        }
+    }
+
+    // Set up speed and course strings for display
+    temp_speed[0] = '\0';
+    dr_speed[0] = '\0';
+    temp_course[0] = '\0';
+
+    if (Display_.speed || Display_.dr_data) {
+        // don't display 'fixed' stations speed and course.
+        // Check whether we have speed in the current data and it's
+        // >= 0.
+        if ( (strlen(p_station->speed)>0) && (atof(p_station->speed) >= 0) ) {
+            speed_ok++;
+            xastir_snprintf(tmp,
+                sizeof(tmp),
+                "%s",
+                un_spd);
+            if (Display_.speed_short)
+                tmp[0] = '\0';          // without unit
+
+            xastir_snprintf(temp_speed, sizeof(temp_speed), "%.0f%s",
+                            atof(p_station->speed)*cvt_kn2len,tmp);
+        }
+        // Else check whether the previous position had speed
+        // Note that newest_trackpoint if it exists should be the
+        // same as the current data, so we have to go back one
+        // further trackpoint.
+        else if ( (p_station->newest_trackpoint != NULL)
+                  && (p_station->newest_trackpoint->prev != NULL) ) {
+
+            xastir_snprintf(tmp,
+                sizeof(tmp),
+                "%s",
+                un_spd);
+
+            if (Display_.speed_short)
+                tmp[0] = '\0';          // without unit
+
+            if ( p_station->newest_trackpoint->prev->speed > 0) {
+                speed_ok++;
+
+                xastir_snprintf(temp_speed, sizeof(temp_speed), "%.0f%s",
+                                p_station->newest_trackpoint->prev->speed * cvt_hm2len,
+                                tmp);
+            }
+        }
+    }
+
+    if (Display_.course || Display_.dr_data) {
+        // Check whether we have course in the current data
+        if ( (strlen(p_station->course)>0) && (atof(p_station->course) > 0) ) {
+            course_ok++;
+            xastir_snprintf(temp_course, sizeof(temp_course), "%.0f�",
+                            atof(p_station->course));
+        }
+        // Else check whether the previous position had a course
+        // Note that newest_trackpoint if it exists should be the
+        // same as the current data, so we have to go back one
+        // further trackpoint.
+        else if ( (p_station->newest_trackpoint != NULL)
+                  && (p_station->newest_trackpoint->prev != NULL) ) {
+            if( p_station->newest_trackpoint->prev->course > 0 ) {
+                course_ok++;
+                xastir_snprintf(temp_course, sizeof(temp_course), "%.0f�",
+                                (float)p_station->newest_trackpoint->prev->course);
+            }
+        }
+    }
+
+    // Save the speed into the dr string for later
+    xastir_snprintf(dr_speed,
+        sizeof(dr_speed),
+        "%s",
+        temp_speed);
+
+    if (!speed_ok  || !Display_.speed)
+        temp_speed[0] = '\0';
+
+    if (!course_ok || !Display_.course)
+        temp_course[0] = '\0';
+
+    // Set up distance and bearing strings for display
+    temp_my_distance[0] = '\0';
+    temp_my_course[0] = '\0';
+
+    if (Display_.dist_bearing && strcmp(p_station->call_sign,my_callsign) != 0) {
+        l_lat = convert_lat_s2l(my_lat);
+        l_lon = convert_lon_s2l(my_long);
+
+        // Get distance in nautical miles, convert to current measurement standard
+        value = cvt_kn2len * calc_distance_course(l_lat,l_lon,
+                p_station->coord_lat,p_station->coord_lon,temp1_my_course,sizeof(temp1_my_course));
+
+        if (value < 5.0)
+            sprintf(temp_my_distance,"%0.1f%s",value,un_dst);
+        else
+            sprintf(temp_my_distance,"%0.0f%s",value,un_dst);
+
+        xastir_snprintf(temp_my_course, sizeof(temp_my_course), "%.0f�",
+                atof(temp1_my_course));
+    }
+
+    // Set up weather strings for display
+    temp_wx_temp[0] = '\0';
+    temp_wx_wind[0] = '\0';
+
+    if (weather != NULL) {
+        // wx_ghost = 1 if the weather data is too old to display
+        wx_ghost = (int)(((sec_old + weather->wx_sec_time)) < secs_now);
+    }
+
+    if (Display_.weather
+            && Display_.weather_text
+            && weather != NULL      // We have weather data
+            && !wx_ghost) {         // Weather is current, display it
+
+        if (strlen(weather->wx_temp) > 0) {
+            xastir_snprintf(tmp,
+                sizeof(tmp),
+                "T:");
+            if (Display_.temperature_only)
+                tmp[0] = '\0';
+
+            if (english_units)
+                xastir_snprintf(temp_wx_temp, sizeof(temp_wx_temp), "%s%.0f�F ",
+                                tmp, atof(weather->wx_temp));
+            else
+                xastir_snprintf(temp_wx_temp, sizeof(temp_wx_temp), "%s%.0f�C ",
+                                tmp,((atof(weather->wx_temp)-32.0)*5.0)/9.0);
+        }
+
+        if (!Display_.temperature_only) {
+            if (strlen(weather->wx_hum) > 0) {
+                xastir_snprintf(wx_tm, sizeof(wx_tm), "H:%.0f%%", atof(weather->wx_hum));
+                strncat(temp_wx_temp,
+                    wx_tm,
+                    sizeof(temp_wx_temp) - 1 - strlen(temp_wx_temp));
+            }
+
+            if (strlen(weather->wx_speed) > 0) {
+                xastir_snprintf(temp_wx_wind, sizeof(temp_wx_wind), "S:%.0f%s ",
+                                atof(weather->wx_speed)*cvt_mi2len,un_spd);
+            }
+
+            if (strlen(weather->wx_gust) > 0) {
+                xastir_snprintf(wx_tm, sizeof(wx_tm), "G:%.0f%s ",
+                                atof(weather->wx_gust)*cvt_mi2len,un_spd);
+                strncat(temp_wx_wind,
+                    wx_tm,
+                    sizeof(temp_wx_wind) - 1 - strlen(temp_wx_wind));
+            }
+
+            if (strlen(weather->wx_course) > 0) {
+                xastir_snprintf(wx_tm, sizeof(wx_tm), "C:%.0f�", atof(weather->wx_course));
+                strncat(temp_wx_wind,
+                    wx_tm,
+                    sizeof(temp_wx_wind) - 1 - strlen(temp_wx_wind));
+            }
+
+            if (temp_wx_wind[strlen(temp_wx_wind)-1] == ' ') {
+                temp_wx_wind[strlen(temp_wx_wind)-1] = '\0';  // delete blank at EOL
+            }
+        }
+
+        if (temp_wx_temp[strlen(temp_wx_temp)-1] == ' ')
+            temp_wx_temp[strlen(temp_wx_temp)-1] = '\0';  // delete blank at EOL
+    }
+
+
+    (void)remove_trailing_asterisk(p_station->call_sign);  // DK7IN: is this needed here?
+
+    if (Display_.symbol_rotate)
+        orient = symbol_orient(p_station->course);   // rotate symbol
+    else
+        orient = ' ';
+
+    // Prevents my own call from "ghosting"?
+//    temp_sec_heard = (strcmp(p_station->call_sign, my_callsign) == 0) ? secs_now: p_station->sec_heard;
+    temp_sec_heard = (is_my_station(p_station)) ? secs_now : p_station->sec_heard;
+
+    // Check whether it's a locally-owned object/item
+//    if ( (is_my_call(p_station->origin,1))          // If station is owned by me (including SSID)
+//            && ( (p_station->flag & ST_OBJECT)      // And it's an object
+//              || (p_station->flag & ST_ITEM) ) ) {  // or an item
+//    if ( is_my_object_item(p_station) ) {
+//        temp_sec_heard = secs_now; // We don't want our own objects/items to "ghost"
+//    }
+
+    // Show last heard times only for others stations and their
+    // objects/items.
+//    temp_show_last_heard = (strcmp(p_station->call_sign, my_callsign) == 0) ? 0 : Display_.last_heard;
+    temp_show_last_heard = (is_my_station(p_station)) ? 0 : Display_.last_heard;
+
+
+
+//------------------------------------------------------------------------------------------
+
+    // If we're only planning on updating a single station at this time, we go
+    // through the drawing calls twice, the first time drawing directly onto
+    // the screen.
+    if (!pending_ID_message && single)
+        drawing_target = XtWindow(da);
+    else
+        drawing_target = pixmap_final;
+
+//_do_the_drawing:
+
+    // Check whether it's a locally-owned object/item
+//    if ( (is_my_call(p_station->origin,1))                  // If station is owned by me (including SSID)
+//            && ( (p_station->flag & ST_OBJECT)       // And it's an object
+//              || (p_station->flag & ST_ITEM  ) ) ) { // or an item
+//    if ( is_my_object_item(p_station) ) {
+//        temp_sec_heard = secs_now; // We don't want our own objects/items to "ghost"
+        // This isn't quite right since if it's a moving object, passing an incorrect
+        // sec_heard should give the wrong results.
+//    }
+
+    ambiguity_flag = 0; // Default
+
+    if (Display_.ambiguity && p_station->pos_amb) {
+        ambiguity_flag = 1;
+        draw_ambiguity(p_station->coord_lon,
+            p_station->coord_lat,
+            p_station->pos_amb,
+            &ambiguity_coord_lon, // New longitude may get passed back to us
+            &ambiguity_coord_lat, // New latitude may get passed back to us
+            temp_sec_heard,
+            drawing_target);
+    }
+
+    // Check for DF'ing data, draw DF circles if present and enabled
+    if (Display_.df_data && strlen(p_station->signal_gain) == 7) {  // There's an SHGD defined
+        //fprintf(stderr,"SHGD:%s\n",p_station->signal_gain);
+        draw_DF_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                        (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                        p_station->signal_gain,
+                        temp_sec_heard,
+                        drawing_target);
+    }
+
+    // Check for DF'ing beam heading/NRQ data
+    if (Display_.df_data && (strlen(p_station->bearing) == 3) && (strlen(p_station->NRQ) == 3)) {
+        //fprintf(stderr,"Bearing: %s\n",p_station->signal_gain,NRQ);
+        if (p_station->df_color == -1)
+            p_station->df_color = rand() % MAX_TRAIL_COLORS;
+
+        draw_bearing( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                      (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                      p_station->course,
+                      p_station->bearing,
+                      p_station->NRQ,
+                      trail_colors[p_station->df_color],
+                      Display_.df_beamwidth_data, Display_.df_bearing_data,
+                      temp_sec_heard,
+                      drawing_target);
+    }
+
+    // Check whether to draw dead-reckoning data by KJ5O
+    if (Display_.dr_data
+        && ( (p_station->flag & ST_MOVING)
+//        && (p_station->newest_trackpoint!=0
+             && course_ok
+             && speed_ok
+             && scale_y < 8000
+             && atof(dr_speed) > 0) ) {
+
+        // Does it make sense to try to do dead-reckoning on an
+        // object that has position ambiguity enabled?  I don't
+        // think so!
+        // 
+        if ( ! ambiguity_flag && ( (secs_now-temp_sec_heard) < dead_reckoning_timeout) ) {
+
+            draw_deadreckoning_features(p_station,
+                                        drawing_target,
+                                        w);
+        }
+    }
+
+    if (p_station->aprs_symbol.area_object.type != AREA_NONE) {
+        draw_area( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                   (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                   p_station->aprs_symbol.area_object.type,
+                   p_station->aprs_symbol.area_object.color,
+                   p_station->aprs_symbol.area_object.sqrt_lat_off,
+                   p_station->aprs_symbol.area_object.sqrt_lon_off,
+                   p_station->aprs_symbol.area_object.corridor_width,
+                   temp_sec_heard,
+                   drawing_target);
+    }
+
+
+    // Draw additional stuff if this is the tracked station
+    if (is_tracked_station(p_station->call_sign)) {
+//WE7U
+        draw_pod_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                         (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                         0.0020 * scale_y,
+                         colors[0x0e],   // Yellow
+                         drawing_target);
+        draw_pod_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                         (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                         0.0023 * scale_y,
+                         colors[0x44],   // Red
+                         drawing_target);
+        draw_pod_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                         (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                         0.0026 * scale_y,
+                         colors[0x61],   // Blue
+                         drawing_target);
+    }
+
+
+    // Draw additional stuff if this is a storm and the weather data
+    // is not too old to display.
+    if ( (weather != NULL) && weather->wx_storm && !wx_ghost ) {
+        char temp[4];
+
+
+        //fprintf(stderr,"Plotting a storm symbol:%s:%s:%s:\n",
+        //    weather->wx_hurricane_radius,
+        //    weather->wx_trop_storm_radius,
+        //    weather->wx_whole_gale_radius);
+
+// Still need to draw the circles in different colors for the
+// different ranges.  Might be nice to tint it as well.
+
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s",
+            weather->wx_hurricane_radius);
+
+        if ( (temp[0] != '\0') && (strncmp(temp,"000",3) != 0) ) {
+
+            draw_pod_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                             (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                             atof(temp) * 1.15078, // nautical miles to miles
+                             colors[0x44],   // Red
+                             drawing_target);
+        }
+
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s",
+            weather->wx_trop_storm_radius);
+
+        if ( (temp[0] != '\0') && (strncmp(temp,"000",3) != 0) ) {
+            draw_pod_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                             (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                             atof(temp) * 1.15078, // nautical miles to miles
+                             colors[0x0e],   // Yellow
+                             drawing_target);
+        }
+
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s",
+            weather->wx_whole_gale_radius);
+
+        if ( (temp[0] != '\0') && (strncmp(temp,"000",3) != 0) ) {
+            draw_pod_circle( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                             (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                             atof(temp) * 1.15078, // nautical miles to miles
+                             colors[0x0a],   // Green
+                             drawing_target);
+        }
+    }
+
+
+    // Draw wind barb if selected and we have wind, but not a severe
+    // storm (wind barbs just confuse the matter).
+    if (Display_.weather && Display_.wind_barb
+            && weather != NULL && atoi(weather->wx_speed) >= 5
+            && !weather->wx_storm
+            && !wx_ghost ) {
+        draw_wind_barb( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                        (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                        weather->wx_speed,
+                        weather->wx_course,
+                        temp_sec_heard,
+                        drawing_target);
+    }
+
+
+// WE7U
+    //
+    // Draw truncation/rounding rectangles plus error ellipses.
+    //
+//
+// We need to keep track of ellipse northing/easting radii plus
+// rectangle northing/easting offsets.  If both sets are present
+// we'll need to draw the summation of both geometric figures.
+// Check that the math works at/near the poles.  We may need to keep
+// track of truncation/rounding rectangles separately if some
+// devices or software use one method, some the other.
+//
+    if (!ambiguity_flag) {
+
+        // Check whether we're at a close enough zoom level to have
+        // the ellipses/rectangles be visible, else skip drawing for
+        // efficiency.
+        //
+//fprintf(stderr,"scale_y: %ld\t", scale_y);
+        if (scale_y < 17) { // 60' figures are good out to about zoom 16
+
+// Here we may have to check what type of device is being used (if
+// possible to determine) to decide whether to draw a truncation/
+// rounding rectangles or GPS error ellipses.  Truncation rectangles
+// have the symbol at one corner, rounding have it in the middle.
+// Based on the precision inherent in the packet we wish to draw a
+// GPS error ellipse instead, the decision point is when the packet
+// precision is adequate to show ~6 meters.
+//
+// OpenTracker APRS:  Truncation, rectangle
+// OpenTracker Base91:Truncation, ellipse
+// OpenTracker OpenTrac: Truncation, ellipse
+// TinyTrak APRS:     Truncation, rectangle
+// TinyTrak NMEA:     Truncation, ellipse/rectangle based on precision
+// TinyTrak Mic-E:    Truncation, rectangle
+// GPGGA:             Truncation, ellipse/rectangle based on precision/HDOP/Augmentation
+// GPRMC:             Truncation, ellipse/rectangle based on precision
+// GPGLL:             Truncation, ellipse/rectangle based on precision
+// Xastir APRS:       Truncation, rectangle
+// Xastir Base91:     Truncation, ellipse
+// UI-View APRS:      ??, rectangle
+// UI-View Base91:    ??, ellipse
+// APRS+SA APRS:      ??, rectangle
+// APRS+SA Base91:    ??, ellipse
+// PocketAPRS:        ??, rectangle
+// SmartAPRS:         ??, rectangle
+// HamHUD:            Truncation, ??
+// HamHUD GPRMC:      Truncation, ellipse/rectangle based on precision
+// Linksys NSLU2:     ??, rectangle
+// AGW Tracker:       ??, ??
+// APRSPoint:         ??, rectangle
+// APRSce:            ??, rectangle
+// APRSdos APRS:      ??, rectangle
+// APRSdos Base91:    ??, ellipse
+// BalloonTrack:      ??, ??
+// DMapper:           ??, ??
+// JavAPRS APRS:      ??, rectangle
+// JavAPRS Base91:    ??, ellipse
+// WinAPRS APRS:      ??, rectangle
+// WinAPRS Base91:    ??, ellipse
+// MacAPRS APRS:      ??, rectangle
+// MacAPRS Base91:    ??, ellipse
+// MacAPRSOSX APRS:   ??, rectangle
+// MacAPRSOSX Base91: ??, ellipse
+// X-APRS APRS:       ??, rectangle
+// X-APRS Base91:     ??, ellipse
+// OziAPRS:           ??, rectangle
+// NetAPRS:           ??, rectangle
+// APRS SCS:          ??, ??
+// RadioMobile:       ??, rectangle
+// KPC-3:             ??, rectangle
+// MicroTNC:          ??, rectangle
+// TigerTrak:         ??, rectangle
+// PicoPacket:        ??, rectangle
+// MIM:               ??, rectangle
+// Mic-Encoder:       ??, rectangle
+// Pic-Encoder:       ??, rectangle
+// Generic Mic-E:     ??, rectangle
+// D7A/D7E:           ??, rectangle
+// D700A:             ??, rectangle
+// Alinco DR-135:     ??, rectangle
+// Alinco DR-620:     ??, rectangle
+// Alinco DR-635:     ??, rectangle
+// Other:             ??, ??
+
+
+            // Initial try at drawing the error_ellipse_radius
+            // circles around the posit.  error_ellipse_radius is in
+            // centimeters.  Convert from cm to miles for
+            // draw_pod_circle().
+            //
+/*
+            draw_pod_circle( p_station->coord_lon,
+                             p_station->coord_lat,
+                             p_station->error_ellipse_radius / 100000.0 * 0.62137, // cm to mi
+                             colors[0x0f],  // White
+                             drawing_target);
+*/
+            draw_precision_rectangle( p_station->coord_lon,
+                             p_station->coord_lat,
+                             p_station->error_ellipse_radius, // centimeters (not implemented yet)
+                             p_station->lat_precision, // 100ths of seconds latitude
+                             p_station->lon_precision, // 100ths of seconds longitude
+                             colors[0x0f],  // White
+                             drawing_target);
+
+
+// Perhaps draw vectors from the symbol out to the borders of these
+// odd figures?  Draw an outline without vectors to the symbol?
+// Have the color match the track color assigned to that station so
+// the geometric figures can be kept separate from nearby stations?
+//
+// draw_truncation_rectangle + error_ellipse (symbol at corner)
+// draw_rounding_rectangle + error_ellipse (symbol in middle)
+
+        }
+    }
+
+    // Zero out the variable in case we don't use it below.
+    temp2_my_gauge_data[0] = '\0';
+ 
+    // If an H2O object, create a timestamp + last comment variable
+    // (which should contain gage-height and/or water-flow numbers)
+    // for use in the draw_symbol() function below.
+    if (p_station->aprs_symbol.aprs_type == '/'
+            && p_station->aprs_symbol.aprs_symbol == 'w'
+            && (   p_station->flag & ST_OBJECT    // And it's an object
+                || p_station->flag & ST_ITEM) ) { // or an item
+
+// NOTE:  Also check whether it was sent by the Firenet GAGE
+// script??  "GAGE-*"
+
+// NOTE:  Check most recent comment time against
+// p_station->sec_heard.  If they don't match, don't display the
+// comment.  This will make sure that older comment data doesn't get
+// displayed which can be quite misleading for stream gauges.
+
+        // Check whether we have any comment data at all.  If so,
+        // the first one will be the most recent comment and the one
+        // we wish to display.
+        if (p_station->comment_data != NULL) {
+            CommentRow *ptr;
+//            time_t sec;
+//            struct tm *time;
+
+
+            ptr = p_station->comment_data;
+ 
+            // Check most recent comment's sec_heard time against
+            // the station record's sec_heard time.  If they don't
+            // match, don't display the comment.  This will make
+            // sure that older comment data doesn't get displayed
+            // which can be quite misleading for stream gauges.
+            if (p_station->sec_heard == ptr->sec_heard) {
+    
+                // Note that text_ptr can be an empty string.
+                // That's ok.
+
+                // Also print the sec_heard timestamp so we know
+                // when this particular gauge data was received
+                // (Very important!).
+//                sec = ptr->sec_heard;
+//                time = localtime(&sec);
+
+                xastir_snprintf(temp2_my_gauge_data,
+                    sizeof(temp2_my_gauge_data),
+                    "%s",
+//                    "%02d/%02d %02d:%02d %s",
+//                    time->tm_mon + 1,
+//                    time->tm_mday,
+//                    time->tm_hour,
+//                    time->tm_min,
+                    ptr->text_ptr);
+//fprintf(stderr, "%s\n", temp2_my_gauge_data);
+            }
+        }
+    }
+
+    draw_symbol(w,
+                p_station->aprs_symbol.aprs_type,
+                p_station->aprs_symbol.aprs_symbol,
+                p_station->aprs_symbol.special_overlay,
+                (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                temp_call,
+                temp_altitude,
+                temp_course,    // ??
+                temp_speed,     // ??
+                temp_my_distance,
+                temp_my_course,
+// Display only if wx temp is current
+                (wx_ghost) ? "" : temp_wx_temp,
+// Display only if wind speed is current
+                (wx_ghost) ? "" : temp_wx_wind,
+                temp_sec_heard,
+                temp_show_last_heard,
+                drawing_target,
+                orient,
+                p_station->aprs_symbol.area_object.type,
+                p_station->signpost,
+                temp2_my_gauge_data,
+                1); // Increment "currently_selected_stations"
+
+    // If it's a Waypoint symbol, draw a line from it to the
+    // transmitting station.
+    if (p_station->aprs_symbol.aprs_type == '\\'
+            && p_station->aprs_symbol.aprs_symbol == '/') {
+
+        draw_WP_line(p_station,
+            ambiguity_flag,
+            ambiguity_coord_lon,
+            ambiguity_coord_lat,
+            drawing_target,
+            w);
+    }
+
+    // Draw other points associated with the station, if any.
+    // KG4NBB
+    if (debug_level & 128)
+        fprintf(stderr,"  Number of multipoints = %d\n",p_station->num_multipoints);
+    if (p_station->num_multipoints != 0) {
+        draw_multipoints( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                          (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                          p_station->num_multipoints,
+                          p_station->multipoint_data->multipoints,
+                          p_station->type, p_station->style,
+                          temp_sec_heard,
+                          drawing_target);
+    }
+
+    temp_sec_heard = p_station->sec_heard;    // DK7IN: ???
+
+    if (Display_.phg
+        && (!(p_station->flag & ST_MOVING) || Display_.phg_of_moving)) {
+
+        // Check for Map View "eyeball" symbol
+        if ( strncmp(p_station->power_gain,"RNG",3) == 0
+                && p_station->aprs_symbol.aprs_type == '/'
+                && p_station->aprs_symbol.aprs_symbol == 'E' ) {
+            // Map View "eyeball" symbol.  Don't draw the RNG ring
+            // for it.
+        }
+        else if (strlen(p_station->power_gain) == 7) {
+            // Station has PHG or RNG defined
+            //
+            draw_phg_rng( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                          (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                          p_station->power_gain,
+                          temp_sec_heard,
+                          drawing_target);
+        }
+        else if (Display_.default_phg && !(p_station->flag & (ST_OBJECT | ST_ITEM))) {
+            // No PHG defined and not an object/item.  Display a PHG
+            // of 3130 as default as specified in the spec:  9W, 3dB
+            // omni at 20 feet = 6.2 mile PHG radius.
+            //
+            draw_phg_rng( (ambiguity_flag) ? ambiguity_coord_lon : p_station->coord_lon,
+                          (ambiguity_flag) ? ambiguity_coord_lat : p_station->coord_lat,
+                          "PHG3130",
+                          temp_sec_heard,
+                          drawing_target);
+        }
+    }
+
+
+    // Draw minimum proximity circle?
+    if (p_station->probability_min[0] != '\0') {
+        double range = atof(p_station->probability_min);
+
+        // Draw red circle
+        draw_pod_circle(p_station->coord_lon,
+            p_station->coord_lat,
+            range,
+            colors[0x44],
+            drawing_target);
+    }
+
+    // Draw maximum proximity circle?
+    if (p_station->probability_max[0] != '\0') {
+        double range = atof(p_station->probability_max);
+
+        // Draw red circle
+        draw_pod_circle(p_station->coord_lon,
+            p_station->coord_lat,
+            range,
+            colors[0x44],
+            drawing_target);
+    }
+
+// DEBUG STUFF
+//            draw_pod_circle(x_long, y_lat, 1.5, colors[0x44], where);
+//            draw_pod_circle(x_long, y_lat, 3.0, colors[0x44], where);
+
+
+    // Now if we just did the single drawing, we want to go back and draw
+    // the same things onto pixmap_final so that when we do update from it
+    // to the screen all of the stuff will be there.
+//    if (drawing_target == XtWindow(da)) {
+//        drawing_target = pixmap_final;
+//        goto _do_the_drawing;
+//    }
+}
+
+
+
+
+
+// draw line relative
+void draw_test_line(Widget w, long x, long y, long dx, long dy, long ofs) {
+
+    x += screen_width  - 10 - ofs;
+    y += screen_height - 10;
+    (void)XDrawLine(XtDisplay(w),
+        pixmap_final,
+        gc,
+        l16(x),
+        l16(y),
+        l16(x+dx),
+        l16(y+dy));
+}
+
+
+
+
+
+// draw text
+void draw_ruler_text(Widget w, char * text, long ofs) {
+    int x,y;
+    int len;
+
+    len = (int)strlen(text);
+    x = screen_width  - 10 - ofs / 2;
+    y = screen_height - 10;
+    x -= len * 3;
+    y -= 3;
+    if (draw_labeled_grid_border==TRUE) { 
+        // move text up a few pixels to leave space for labeled border
+        y = y - 15;
+        x = x - 10;
+    }
+    draw_nice_string(w,pixmap_final,letter_style,x,y,text,0x10,0x20,len);
+}
+
+
+
+
+
+// Compute Range Scale in miles or kilometers.
+//
+// For this we need to figure out x-distance and y-distance across
+// the screen.  Take the smaller of the two, then figure out which
+// power of 2 miles fits from the center to the edge of the screen.
+// "For metric, use the nearest whole number kilometer in powers of
+// two of 1.5 km above the 1 mile scale.  At 1 mile and below, do
+// the conversion to meters where 1 mi is equal to 1600m..." (Bob
+// Bruninga's words).
+void draw_range_scale(Widget w) {
+    Dimension width, height;
+    long x, x0, y, y0;
+    double x_miles_km, y_miles_km, distance;
+    char temp_course[10];
+    long temp;
+    double temp2;
+    long range;
+    int small_flag = 0;
+    int x_screen, y_screen;
+    int len;
+    char text[80];
+    int border_offset = 0;  // number of pixels to offset the scale if a labeled map border is drawn
+
+
+    // Find out the screen values
+    XtVaGetValues(da,XmNwidth, &width, XmNheight, &height, NULL);
+
+    // Convert points to Xastir coordinate system
+
+    // X
+    x = center_longitude  - ((width *scale_x)/2);
+    x0 = center_longitude; // Center of screen
+
+    // Y
+    y = center_latitude   - ((height*scale_y)/2);
+    y0 = center_latitude;  // Center of screen
+
+    // Compute distance from center to each edge
+
+    // X distance.  Keep Y constant.
+    x_miles_km = cvt_kn2len * calc_distance_course(y0,x0,y0,x,temp_course,sizeof(temp_course));
+ 
+    // Y distance.  Keep X constant.
+    y_miles_km = cvt_kn2len * calc_distance_course(y0,x0,y,x0,temp_course,sizeof(temp_course));
+
+    // Choose the smaller distance
+    if (x_miles_km < y_miles_km) {
+        distance = x_miles_km;
+    }
+    else {
+        distance = y_miles_km;
+    }
+
+    // Convert it to nearest power of two that fits inside
+
+    if (english_units) { // English units
+        if (distance >= 1.0) {
+            // Shift it right until it is less than 2.
+            temp = (long)distance;
+            range = 1;
+            while (temp >= 2) {
+                temp = temp / 2;
+                range = range * 2;
+            }
+        }
+        else {  // Distance is less than one
+            // divide 1.0 by 2 until distance is greater
+            small_flag++;
+            temp2 = 1.0;
+            range = 1;
+            while (temp2 > distance) {
+                //fprintf(stderr,"temp2: %f,  distance: %f\n", temp2, distance);
+                temp2 = temp2 / 2.0;
+                range = range * 2;
+            }
+        }
+    }
+    else {  // Metric units
+        if (distance >= 12800.0)
+            range = 12800;
+        else if (distance >= 6400.0)
+            range = 6400;
+        else if (distance >= 3200.0)
+            range = 3200;
+        else if (distance >= 1600.0)
+            range = 1600;
+        else if (distance >= 800.0)
+            range = 800;
+        else if (distance >= 400.0)
+            range = 400;
+        else if (distance >= 200.0)
+            range = 200;
+        else if (distance >= 100.0)
+            range = 100;
+        else if (distance >= 50.0)
+            range = 50;
+        else if (distance >= 25.0)
+            range = 25;
+        else if (distance >= 12.0)
+            range = 12;
+        else if (distance >= 6.0)
+            range = 6;
+        else if (distance >= 3.0)
+            range = 3;
+        else {
+            small_flag++;
+            if (distance >= 1.6)
+                range = 1600;
+            else if (distance >= 0.8)
+                range = 800;
+            else if (distance >= 0.4)
+                range = 400;
+            else if (distance >= 0.2)
+                range = 200;
+            else if (distance >= 0.1)
+                range = 100;
+            else if (distance >= 0.05)
+                range = 50;
+            else if (distance >= 0.025)
+                range = 25;
+            else range = 12;
+        }
+    }
+
+    //fprintf(stderr,"Distance: %f\t", distance);
+    //fprintf(stderr,"Range: %ld\n", range);
+
+    if (english_units) { // English units
+        if (small_flag) {
+            xastir_snprintf(text,
+                sizeof(text),
+                "%s 1/%ld mi",
+                langcode("RANGE001"),   // "RANGE SCALE"
+                range);
+        }
+        else {
+            xastir_snprintf(text,
+                sizeof(text),
+                "%s %ld mi",
+                langcode("RANGE001"),   // "RANGE SCALE"
+                range);
+        }
+    }
+    else {  // Metric units
+        if (small_flag) {
+            xastir_snprintf(text,
+                sizeof(text),
+                "%s %ld m",
+                langcode("RANGE001"),   // "RANGE SCALE"
+                range);
+        }
+        else {
+            xastir_snprintf(text,
+                sizeof(text),
+                "%s %ld km",
+                langcode("RANGE001"),   // "RANGE SCALE"
+                range);
+        }
+    }
+
+    // Draw it on the screen
+    len = (int)strlen(text);
+    x_screen = 10;
+    y_screen = screen_height - 5;
+    if ((draw_labeled_grid_border==TRUE) && long_lat_grid) {
+        border_offset = get_rotated_label_text_length_pixels(w, "0", FONT_BORDER) + 3;
+        // don't draw range scale right on top of labeled border, move into map
+        draw_nice_string(w,pixmap_final,letter_style,x_screen+border_offset,y_screen-border_offset-3,text,0x10,0x20,len);
+    } 
+    else { 
+        // draw range scale in lower left corder of map
+        draw_nice_string(w,pixmap_final,letter_style,x_screen,y_screen,text,0x10,0x20,len);
+    }
+
+}
+
+
+
+
+
+/*
+ *  Calculate and draw ruler on right bottom of screen
+ */
+void draw_ruler(Widget w) {
+    int ruler_pix;      // min size of ruler in pixel
+    char unit[5+1];     // units
+    char text[20];      // ruler text
+    double ruler_siz;   // len of ruler in meters etc.
+    int mag;
+    int i;
+    int dx, dy;
+    int border_offset = 0;  // number of pixels to offset the scale if a labeled map border is drawn
+
+    ruler_pix = (int)(screen_width / 9);        // ruler size (in pixels)
+    ruler_siz = ruler_pix * scale_x * calc_dscale_x(center_longitude,center_latitude); // size in meter
+
+    if(english_units) {
+        if (ruler_siz > 1609.3/2) {
+            xastir_snprintf(unit,
+                sizeof(unit),
+                "mi");
+            ruler_siz /= 1609.3;
+        }
+        else {
+            xastir_snprintf(unit,
+                sizeof(unit),
+                "ft");
+            ruler_siz /= 0.3048;
+        }
+    }
+    else {
+        xastir_snprintf(unit,
+            sizeof(unit),
+            "m");
+        if (ruler_siz > 1000/2) {
+            xastir_snprintf(unit,
+                sizeof(unit),
+                "km");
+            ruler_siz /= 1000.0;
+        }
+    }
+
+    mag = 1;
+    while (ruler_siz > 5.0) {             // get magnitude
+        ruler_siz /= 10.0;
+        mag *= 10;
+    }
+    // select best value and adjust ruler length
+    if (ruler_siz > 2.0) {
+        ruler_pix = (int)(ruler_pix * 5.0 / ruler_siz +0.5);
+        ruler_siz = 5.0 * mag;
+    }
+    else {
+        if (ruler_siz > 1.0) {
+            ruler_pix = (int)(ruler_pix * 2.0 / ruler_siz +0.5);
+            ruler_siz = 2.0 * mag;
+        }
+        else {
+            ruler_pix = (int)(ruler_pix * 1.0 / ruler_siz +0.5);
+            ruler_siz = 1.0 * mag;
+        }
+    }
+    xastir_snprintf(text, sizeof(text), "%.0f %s",ruler_siz,unit);      // Set up string
+    //fprintf(stderr,"Ruler: %s, %d\n",text,ruler_pix);
+
+    (void)XSetLineAttributes(XtDisplay(w),gc,1,LineSolid,CapRound,JoinRound);
+    (void)XSetForeground(XtDisplay(w),gc,colors[0x20]);         // white
+    for (i = 8; i >= 0; i--) {
+        dx = (((i / 3)+1) % 3)-1;         // looks complicated...
+        dy = (((i % 3)+1) % 3)-1;         // I want 0 / 0 as last entry
+        if ((draw_labeled_grid_border==TRUE) && long_lat_grid) {
+            // move ruler up a few pixels to leave space for labeled border
+            border_offset = get_rotated_label_text_length_pixels(w, "0", FONT_BORDER) + 3;
+            dy = dy - border_offset - 3;
+            dx = dx - border_offset - 3;
+        }
+
+        // If text on black background style selected, draw a black
+        // rectangle in that corner of the map first so that the
+        // scale lines show up well.
+        //
+        // If first time through and text-on-black style
+        if ( (i == 8) && (letter_style == 2) ) {
+            XSetForeground(XtDisplay(w),gc,colors[0x10]);   // black
+            (void)XSetLineAttributes(XtDisplay(w),gc,20,LineSolid,CapProjecting,JoinMiter);
+            draw_test_line(w, dx, dy+5, ruler_pix, 0, ruler_pix);
+
+            // Reset to needed parameters for drawing the scale
+            (void)XSetLineAttributes(XtDisplay(w),gc,1,LineSolid,CapRound,JoinRound);
+            (void)XSetForeground(XtDisplay(w),gc,colors[0x20]);         // white
+        }
+
+        if (i == 0)
+            (void)XSetForeground(XtDisplay(w),gc,colors[0x10]);         // black
+
+        draw_test_line(w,dx,dy,          ruler_pix,0,ruler_pix);        // hor line
+        draw_test_line(w,dx,dy,              0,5,    ruler_pix);        // ver left
+        draw_test_line(w,dx+ruler_pix,dy,    0,5,    ruler_pix);        // ver right
+        if (text[0] == '2')
+            draw_test_line(w,dx+0.5*ruler_pix,dy,0,3,ruler_pix);        // ver middle
+
+        if (text[0] == '5') {
+            draw_test_line(w,dx+0.2*ruler_pix,dy,0,3,ruler_pix);        // ver middle
+            draw_test_line(w,dx+0.4*ruler_pix,dy,0,3,ruler_pix);        // ver middle
+            draw_test_line(w,dx+0.6*ruler_pix,dy,0,3,ruler_pix);        // ver middle
+            draw_test_line(w,dx+0.8*ruler_pix,dy,0,3,ruler_pix);        // ver middle
+        }
+    }
+
+    draw_ruler_text(w,text,ruler_pix);
+
+    draw_range_scale(w);
+}
+
+
+
+
+
+/*
+ *  Display all stations on screen (trail, symbol, info text)
+ */
+void display_file(Widget w) {
+    DataRow *p_station;         // pointer to station data
+    time_t temp_sec_heard;      // time last heard
+    time_t t_clr, t_old, now;
+
+    if(debug_level & 1)
+        fprintf(stderr,"Display File Start\n");
+
+    // Keep track of how many station we are currently displaying on
+    // the screen.  We'll display this number and the total number
+    // of objects in the database as displayed/total on the status
+    // line.  Each time we call display_station() we'll bump this
+    // number.
+    currently_selected_stations = 0;
+
+// Draw probability of detection circle, if enabled
+//draw_pod_circle(64000000l, 32400000l, 10, colors[0x44], pixmap_final);
+
+    now = sec_now();
+    t_old = now - sec_old;        // precalc compare times
+    t_clr = now - sec_clear;
+    temp_sec_heard = 0l;
+    p_station = t_oldest;                // start with oldest station, have newest on top at t_newest
+
+    while (p_station != NULL) {
+
+        if (debug_level & 64) {
+            fprintf(stderr,"display_file: Examining %s\n", p_station->call_sign);
+        }
+
+        // Skip deleted stations
+        if ( !(p_station->flag & ST_ACTIVE) ) {
+
+            if (debug_level & 64) {
+                fprintf(stderr,"display_file: ignored deleted %s\n", p_station->call_sign);
+            }
+
+            // Skip to the next station in the list
+            p_station = p_station->t_newer;  // next station
+            continue;
+        }
+ 
+        // Check for my objects/items
+//        if ( (is_my_call(p_station->origin, 1)        // If station is owned by me (including SSID)
+//                && (   p_station->flag & ST_OBJECT    // And it's an object
+//                    || p_station->flag & ST_ITEM) ) ) { // or an item
+//
+        // This case is covered by the is_my_station() call, so we
+        // don't need it here.
+//        if (is_my_object_item(p_station) ) {
+//            temp_sec_heard = now;
+//        }
+//        else {
+            // Callsign match here includes checking SSID
+//            temp_sec_heard = (is_my_call(p_station->call_sign,1))?  now: p_station->sec_heard;
+            temp_sec_heard = (is_my_station(p_station)) ? now : p_station->sec_heard;
+//        }
+
+        // Skip far away station
+        if ((p_station->flag & ST_INVIEW) == 0) {
+            // we make better use of the In View flag in the future
+
+            if (debug_level & 256) {
+                fprintf(stderr,"display_file: Station outside viewport\n");
+            }
+
+            // Skip to the next station in the list
+            p_station = p_station->t_newer;  // next station
+            continue;
+        }
+
+        // Skip if we're running an altnet and this station's not in
+        // it
+        if ( altnet && !is_altnet(p_station) ) {
+
+            if (debug_level & 64) {
+                fprintf(stderr,"display_file: Station %s skipped altnet\n",
+                    p_station->call_sign);
+            }
+ 
+            // Skip to the next station in the list
+            p_station = p_station->t_newer;  // next station
+            continue;
+        }
+
+        if (debug_level & 256) {
+            fprintf(stderr,"display_file:  Inview, check for trail\n");
+        }
+
+        // Display trail if we should
+        if (Display_.trail && p_station->newest_trackpoint != NULL) {
+            // ????????????   what is the difference? :
+
+            if (debug_level & 256) {
+                fprintf(stderr,"%s:    Trails on and have track data\n",
+                    "display_file");
+            }
+
+            if (temp_sec_heard > t_clr) {
+                // Not too old, so draw trail
+
+                if (temp_sec_heard > t_old) {
+                    // New trail, so draw solid trail
+
+                    if (debug_level & 256) {
+                        fprintf(stderr,"Drawing Solid trail for %s, secs old: %ld\n",
+                            p_station->call_sign,
+                            (long)(now - temp_sec_heard) );
+                    }
+                    draw_trail(w,p_station,1);
+                }
+                else {
+
+                    if (debug_level & 256) {
+                        fprintf(stderr,"Drawing trail for %s, secs old: %ld\n",
+                            p_station->call_sign,
+                            (long)(now - temp_sec_heard) );
+                    }
+                    draw_trail(w,p_station,0);
+                }
+            }
+            else {
+                if (debug_level & 256) {
+                    fprintf(stderr,"Station too old\n");
+                }
+            }
+        }
+        else {
+            if (debug_level & 256) {
+                fprintf(stderr,"Station trails %d, track data %lx\n",
+                    Display_.trail, (long int)p_station->newest_trackpoint);
+            }
+        }
+
+        if (debug_level & 256)
+            fprintf(stderr,"calling display_station()\n");
+
+        // This routine will also update the
+        // currently_selected_stations variable, if we're
+        // updating all of the stations at once.
+        display_station(w,p_station,0);
+
+        p_station = p_station->t_newer;  // next station
+    }
+
+    draw_ruler(w);
+
+    Draw_All_CAD_Objects(w);        // Draw all CAD objects, duh.
+
+    // Check if we should mark where we found an address
+    if (mark_destination && show_destination_mark) {
+        int offset;
+
+        // Set the line width in the GC.  Make it nice and fat.
+        (void)XSetLineAttributes (XtDisplay (w), gc_tint, 7, LineSolid, CapButt,JoinMiter);
+        (void)XSetForeground (XtDisplay (w), gc_tint, colors[0x27]);
+        (void)(void)XSetFunction (XtDisplay (da), gc_tint, GXxor);
+
+        // Scale it so that the 'X' stays the same size at all zoom
+        // levels.
+        offset = 25 * scale_y;
+
+        // Make a big 'X'
+        draw_vector(w,
+            destination_coord_lon-offset,  // x1
+            destination_coord_lat-offset,  // y1
+            destination_coord_lon+offset,  // x2
+            destination_coord_lat+offset,  // y2
+            gc_tint,
+            pixmap_final,
+            0);
+
+        draw_vector(w,
+            destination_coord_lon+offset,  // x1
+            destination_coord_lat-offset,  // y1
+            destination_coord_lon-offset,  // x2
+            destination_coord_lat+offset,  // y2
+            gc_tint,
+            pixmap_final,
+            0);
+    }
+
+    // And last, draw the ALOHA circle
+    if (Display_.aloha_circle) {
+        if (aloha_radius != -1) {
+              // if we actually have an aloha radius calculated already
+            long l_lat,l_lon;
+
+            l_lat = convert_lat_s2l(my_lat);
+            l_lon = convert_lon_s2l(my_long);
+            draw_aloha_circle(l_lon,
+                l_lat,
+                aloha_radius,
+                colors[0x0e],
+                pixmap_final);
+        }
+    }
+
+    // Check whether currently_selected_stations has changed.  If
+    // so, set station_count_save to 0 so that main.c will come
+    // along and update the counts on the status line.
+    if (currently_selected_stations != currently_selected_stations_save) {
+        station_count_save = 0;   // Cause an update to occur
+    }
+    currently_selected_stations_save = currently_selected_stations;
+
+
+    if (debug_level & 1)
+        fprintf(stderr,"Display File Stop\n");
+}
+
+
+
+
+
+//////////////////////////////  Station Info  /////////////////////////////////////
+
+
+
+
+
+/*
+ *  Delete Station Info PopUp
+ */
+void Station_data_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&db_station_info_lock, "db.c:Station_data_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    db_station_info = (Widget)NULL;
+
+end_critical_section(&db_station_info_lock, "db.c:Station_data_destroy_shell" );
+
+}
+
+
+
+
+
+/*
+ *  Store track data for current station
+ */
+void Station_data_store_track(Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    DataRow *p_station = clientData;
+
+    //busy_cursor(XtParent(w));
+    busy_cursor(appshell);
+
+    // Grey-out button so it doesn't get pressed twice
+    XtSetSensitive(button_store_track,FALSE);
+
+    // Store trail to file
+    export_trail(p_station);
+
+#ifdef HAVE_LIBSHP
+    // Save trail as a Shapefile map
+    create_map_from_trail(p_station->call_sign);
+#endif  // HAVE_LIBSHP
+
+    // store trail to kml file
+    export_trail_as_kml(p_station);
+}
+
+
+
+
+
+/*
+ *  Delete tracklog for current station
+ */
+void Station_data_destroy_track( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    DataRow *p_station = clientData;
+
+    if (delete_trail(p_station))
+        redraw_on_new_data = 2;         // redraw immediately
+}
+
+
+
+
+
+// This function merely reformats the button callback in order to
+// call wx_alert_double_click_action, which expects the parameter in
+// calldata instead of in clientData.
+//
+void Station_data_wx_alert(Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+//fprintf(stderr, "Station_data_wx_alert start\n");
+    wx_alert_finger_output( w, clientData);
+//fprintf(stderr, "Station_data_wx_alert end\n");
+}
+
+
+
+
+
+void Station_data_add_fcc(Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char temp[500];
+    FccAppl my_data;
+    char *station = (char *) clientData;
+
+    (void)check_fcc_data();
+    //busy_cursor(XtParent(w));
+    busy_cursor(appshell);
+    if (search_fcc_data_appl(station, &my_data)==1) {
+        /*fprintf(stderr,"FCC call %s\n",station);*/
+        xastir_snprintf(temp, sizeof(temp), "%s\n%s %s\n%s %s %s\n%s %s, %s %s, %s %s\n\n",
+            langcode("STIFCC0001"),
+            langcode("STIFCC0003"),my_data.name_licensee,
+            langcode("STIFCC0004"),my_data.text_street,my_data.text_pobox,
+            langcode("STIFCC0005"),my_data.city,
+            langcode("STIFCC0006"),my_data.state,
+            langcode("STIFCC0007"),my_data.zipcode);
+            XmTextInsert(si_text,0,temp);
+            XmTextShowPosition(si_text,0);
+
+        fcc_lookup_pushed = 1;
+    }
+}
+
+
+
+
+
+void Station_data_add_rac(Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char temp[512];
+    char club[512];
+    rac_record my_data;
+    char *station = (char *) clientData;
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        " ");
+    (void)check_rac_data();
+    //busy_cursor(XtParent(w));
+    busy_cursor(appshell);
+    if (search_rac_data(station, &my_data)==1) {
+        /*fprintf(stderr,"IC call %s\n",station);*/
+        xastir_snprintf(temp, sizeof(temp), "%s\n%s %s\n%s\n%s, %s\n%s\n",
+                langcode("STIFCC0002"),my_data.first_name,my_data.last_name,my_data.address,
+                my_data.city,my_data.province,my_data.postal_code);
+
+        if (my_data.qual_a[0] == 'A')
+            strncat(temp,
+                langcode("STIFCC0008"),
+                sizeof(temp) - 1 - strlen(temp));
+
+        if (my_data.qual_d[0] == 'D')
+            strncat(temp,
+                langcode("STIFCC0009"),
+                sizeof(temp) - 1 - strlen(temp));
+
+        if (my_data.qual_b[0] == 'B' && my_data.qual_c[0] != 'C')
+            strncat(temp,
+                langcode("STIFCC0010"),
+                sizeof(temp) - 1 - strlen(temp));
+
+        if (my_data.qual_c[0] == 'C')
+            strncat(temp,
+                langcode("STIFCC0011"),
+                sizeof(temp) - 1 - strlen(temp));
+
+        strncat(temp,
+            "\n",
+            sizeof(temp) - 1 - strlen(temp));
+
+        if (strlen(my_data.club_name) > 1){
+            xastir_snprintf(club, sizeof(club), "%s\n%s\n%s, %s\n%s\n",
+                    my_data.club_name, my_data.club_address,
+                    my_data.club_city, my_data.club_province, my_data.club_postal_code);
+            strncat(temp,
+                club,
+                sizeof(temp) - 1 - strlen(temp));
+        }
+        strncat(temp,
+            "\n",
+            sizeof(temp) - 1 - strlen(temp));
+        XmTextInsert(si_text,0,temp);
+        XmTextShowPosition(si_text,0);
+
+        rac_lookup_pushed = 1;
+    }
+}
+
+
+
+
+
+void Station_query_trace(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char *station = (char *) clientData;
+    char temp[50];
+    char call[25];
+
+    pad_callsign(call,station);
+    xastir_snprintf(temp, sizeof(temp), ":%s:?APRST", call);
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+    transmit_message_data(station,temp,NULL);
+}
+
+
+
+
+
+void Station_query_messages(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char *station = (char *) clientData;
+    char temp[50];
+    char call[25];
+
+    pad_callsign(call,station);
+    xastir_snprintf(temp, sizeof(temp), ":%s:?APRSM", call);
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+    transmit_message_data(station,temp,NULL);
+}
+
+
+
+
+
+void Station_query_direct(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char *station = (char *) clientData;
+    char temp[50];
+    char call[25];
+
+    pad_callsign(call,station);
+    xastir_snprintf(temp, sizeof(temp), ":%s:?APRSD", call);
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+    transmit_message_data(station,temp,NULL);
+}
+
+
+
+
+
+void Station_query_version(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char *station = (char *) clientData;
+    char temp[50];
+    char call[25];
+
+    pad_callsign(call,station);
+    xastir_snprintf(temp, sizeof(temp), ":%s:?VER", call);
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+    transmit_message_data(station,temp,NULL);
+}
+
+
+
+
+
+void General_query(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    char *location = (char *) clientData;
+    char temp[50];
+
+    xastir_snprintf(temp, sizeof(temp), "?APRS?%s", location);
+    output_my_data(temp,-1,0,0,0,NULL);  // Not igating
+}
+
+
+
+
+
+void IGate_query(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    output_my_data("?IGATE?",-1,0,0,0,NULL); // Not igating
+}
+
+
+
+
+
+void WX_query(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    output_my_data("?WX?",-1,0,0,0,NULL);    // Not igating
+}
+
+
+
+
+
+// Global variables for use with routines following
+Widget change_tactical_dialog = (Widget)NULL;
+Widget tactical_text = (Widget)NULL;
+DataRow *tactical_pointer = NULL;
+
+
+void Change_tactical_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    change_tactical_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Change_tactical_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp;
+
+    temp = XmTextGetString(tactical_text);
+
+    if (tactical_pointer->tactical_call_sign == NULL) {
+        // Malloc some memory to hold it.
+        tactical_pointer->tactical_call_sign = (char *)malloc(MAX_TACTICAL_CALL+1);
+    }
+
+    if (tactical_pointer->tactical_call_sign != NULL) {
+
+        // Check for blank tactical call.  If so, free the space.
+        if (temp[0] == '\0') {
+            free(tactical_pointer->tactical_call_sign);
+            tactical_pointer->tactical_call_sign = NULL;
+        }
+        else {
+            xastir_snprintf(tactical_pointer->tactical_call_sign,
+                MAX_TACTICAL_CALL+1,
+                "%s",
+                temp);
+        }
+
+        fprintf(stderr,
+            "Assigned tactical call \"%s\" to %s\n",
+            temp,
+            tactical_pointer->call_sign);
+
+        // Log the change in the tactical_calls.log file.
+        // Also adds it to the tactical callsign hash here.
+        log_tactical_call(tactical_pointer->call_sign,
+            tactical_pointer->tactical_call_sign);
+    }
+    else {
+        fprintf(stderr,
+            "Couldn't malloc space for tactical callsign\n");
+    }
+
+    XtFree(temp);
+
+    redraw_on_new_data = 2;  // redraw now
+
+    Change_tactical_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Change_tactical(Widget w, XtPointer clientData, XtPointer callData) {
+    static Widget pane, my_form, button_ok, button_close, label;
+    Atom delw;
+    Arg al[50];                     // Arg List
+    register unsigned int ac = 0;   // Arg Count
+
+    if (!change_tactical_dialog) {
+        change_tactical_dialog =
+            XtVaCreatePopupShell(langcode("WPUPSTI065"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Change Tactical pane",
+                xmPanedWindowWidgetClass,
+                change_tactical_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Change Tactical my_form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 3,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+
+        // set args for color
+        ac=0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        // Display the callsign or object/item name we're working on
+        // in a label at the top of the dialog.  Otherwise we don't
+        // know what station we're operating on.
+        //
+        label = XtVaCreateManagedWidget(tactical_pointer->call_sign,
+                xmLabelWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tactical_text = XtVaCreateManagedWidget("Change_Tactical text",
+                xmTextWidgetClass,
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, MAX_TACTICAL_CALL,
+                XmNwidth, ((MAX_TACTICAL_CALL*7)+2),
+                XmNmaxLength, MAX_TACTICAL_CALL,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Fill in the current value of tactical callsign
+        XmTextSetString(tactical_text, tactical_pointer->tactical_call_sign);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tactical_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tactical_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok,
+            XmNactivateCallback,
+            Change_tactical_change_data,
+            change_tactical_dialog);
+        XtAddCallback(button_close,
+            XmNactivateCallback,
+            Change_tactical_destroy_shell,
+            change_tactical_dialog);
+
+        pos_dialog(change_tactical_dialog);
+
+        delw = XmInternAtom(XtDisplay(change_tactical_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(change_tactical_dialog, delw, Change_tactical_destroy_shell, (XtPointer)change_tactical_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(change_tactical_dialog,XtGrabNone);
+        fix_dialog_size(change_tactical_dialog);
+
+        // Move focus to the Close button.  This appears to
+        // highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit
+        // the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(change_tactical_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    }
+    else {
+        (void)XRaiseWindow(XtDisplay(change_tactical_dialog),
+            XtWindow(change_tactical_dialog));
+    }
+}
+
+
+
+
+
+/*
+ *  Assign a tactical call to a station
+ */
+void Assign_Tactical_Call( Widget w, XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station = clientData;
+
+    //fprintf(stderr,"Object Name: %s\n", p_station->call_sign);
+    tactical_pointer = p_station;
+    Change_tactical(w, p_station, NULL);
+}
+
+
+
+
+
+/*
+ *  Change the trail color for a station
+ */
+void Change_trail_color( Widget w, XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station = clientData;
+    int temp;
+
+    temp = p_station->trail_color;
+
+    // Increment to the next color, round-robin style
+    temp = (temp + 1) % MAX_TRAIL_COLORS;
+
+    // Test for and skip if my trail color
+    if (temp == MY_TRAIL_COLOR) {
+        temp = (temp + 1) % MAX_TRAIL_COLORS;
+    }
+
+    p_station->trail_color = temp;
+
+    redraw_on_new_data = 2; // redraw symbols now
+}
+
+
+
+
+
+static void PosTestExpose(Widget parent, XtPointer clientData, XEvent *event, Boolean * continueToDispatch) {
+    Position x, y;
+
+    XtVaGetValues(parent, XmNx, &x, XmNy, &y, NULL);
+
+    if (debug_level & 1)
+        fprintf(stderr,"Window Decoration Offsets:  X:%d\tY:%d\n", x, y);
+
+    // Store the new-found offets in global variables
+    decoration_offset_x = (int)x;
+    decoration_offset_y = (int)y;
+
+    // Get rid of the event handler and the test dialog
+    XtRemoveEventHandler(parent, ExposureMask, True, (XtEventHandler) PosTestExpose, (XtPointer)NULL);
+//    XtRemoveGrab(XtParent(parent));  // Not needed?
+    XtDestroyWidget(XtParent(parent));
+}
+
+
+
+
+
+// Here's a stupid trick that we have to do in order to find out how big
+// window decorations are.  We need to know this information in order to
+// be able to kill/recreate dialogs in the same place each time.  If we
+// were to just get and set the X/Y values of the dialog, we would creep
+// across the screen by the size of the decorations each time.
+// I've seen it.  It's ugly.
+//
+void compute_decorations( void ) {
+    Widget cdtest = (Widget)NULL;
+    Widget cdform = (Widget)NULL;
+    Cardinal n = 0;
+    Arg args[50];
+ 
+
+    // We'll create a dummy dialog at 0,0, then query its
+    // position.  That'll give us back the position of the
+    // widget.  Subtract 0,0 from it (easy huh?) and we get
+    // the size of the window decorations.  Store these values
+    // in global variables for later use.
+
+    n = 0;
+    XtSetArg(args[n], XmNx, 0); n++;
+    XtSetArg(args[n], XmNy, 0); n++;
+
+    cdtest = (Widget) XtVaCreatePopupShell("compute_decorations test",
+                        xmDialogShellWidgetClass,
+                        appshell,
+                        args, n,
+                        NULL);
+ 
+    n = 0;
+    XtSetArg(args[n], XmNwidth, 0); n++;    // Make it tiny
+    XtSetArg(args[n], XmNheight, 0); n++;   // Make it tiny
+    cdform = XmCreateForm(cdtest, "compute_decorations test form", args, n);
+
+    XtAddEventHandler(cdform, ExposureMask, True, (XtEventHandler) PosTestExpose,
+        (XtPointer)NULL);
+
+    XtManageChild(cdform);
+    XtManageChild(cdtest);
+}
+
+
+
+
+
+// Enable/disable auto-update of Station_data dialog
+void station_data_auto_update_toggle ( /*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        station_data_auto_update = 1;
+    else
+        station_data_auto_update = 0;
+}
+
+
+
+
+
+// Fill in the station data window with real data
+void station_data_fill_in ( /*@unused@*/ Widget w, XtPointer clientData, XtPointer calldata ) {
+    DataRow *p_station;
+    char *station = (char *) clientData;
+    char temp[300];
+    int pos, last_pos;
+    char temp_my_distance[20];
+    char temp_my_course[20];
+    char temp1_my_course[20];
+    float temp_out_C, e, humidex;
+    long l_lat, l_lon;
+    float value;
+    WeatherRow *weather;
+    time_t sec;
+    struct tm *time;
+    int i;
+    int track_count = 0;
+
+// Maximum tracks listed in Station Info dialog.  This prevents
+// lockups on extremely long tracks.
+#define MAX_TRACK_LIST 50
+
+
+    db_station_info_callsign = (char *) clientData; // Used for auto-updating this dialog
+    temp_out_C=0;
+    pos=0;
+
+begin_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+    if (db_station_info == NULL) {  // We don't have a dialog to write to
+
+end_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+        return;
+    }
+
+    if (!search_station_name(&p_station,station,1)  // Can't find call,
+            || (p_station->flag & ST_ACTIVE) == 0) {  // or found deleted objects
+
+end_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+        return;
+    }
+
+
+    // Clear the text
+    XmTextSetString(si_text,NULL);
+
+
+    // Weather Data ...
+    if (p_station->weather_data != NULL
+            // Make sure the timestamp on the weather is current
+            && (int)(((sec_old + p_station->weather_data->wx_sec_time)) >= sec_now()) ) {
+
+        last_pos = pos;
+
+        weather = p_station->weather_data;
+
+        pos += strlen(temp);
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI024"),weather->wx_type,weather->wx_station);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        sprintf(temp, "\n");
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        if (english_units)
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI026"),weather->wx_course,weather->wx_speed);
+        else
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI025"),weather->wx_course,(int)(atof(weather->wx_speed)*1.6094));
+
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+
+        if (strlen(weather->wx_gust) > 0) {
+            if (english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI028"),weather->wx_gust);
+            else
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI027"),(int)(atof(weather->wx_gust)*1.6094));
+
+            strncat(temp,
+                "\n",
+                sizeof(temp) - 1 - strlen(temp));
+        }
+        else
+            xastir_snprintf(temp, sizeof(temp), "\n");
+
+        XmTextInsert(si_text, pos, temp);
+        pos += strlen(temp);
+
+        if (strlen(weather->wx_temp) > 0) {
+            if (english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI030"),weather->wx_temp);
+            else {
+                temp_out_C =(((atof(weather->wx_temp)-32)*5.0)/9.0);
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI029"),temp_out_C);
+            }
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_hum) > 0) {
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI031"),weather->wx_hum);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+// NOTE:  The below (Humidex) is not coded for english units, only for metric.
+// What is Humidex anyway?  Heat Index?  Wind Chill? --we7u
+
+        // DK7IN: ??? english_units ???
+        if (strlen(weather->wx_hum) > 0
+                && strlen(weather->wx_temp) > 0
+                && (!english_units) &&
+                (atof(weather->wx_hum) > 0.0) ) {
+
+            e = (float)(6.112 * pow(10,(7.5 * temp_out_C)/(237.7 + temp_out_C)) * atof(weather->wx_hum) / 100.0);
+            humidex = (temp_out_C + ((5.0/9.0) * (e-10.0)));
+
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI032"),humidex);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_baro) > 0) {
+            if (!english_units) {  // hPa
+                xastir_snprintf(temp, sizeof(temp),
+                    langcode("WPUPSTI033"),
+                    weather->wx_baro);
+            }
+            else {  // Inches Mercury
+                xastir_snprintf(temp, sizeof(temp),
+                    langcode("WPUPSTI063"),
+                    atof(weather->wx_baro)*0.02953);
+            }
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+            xastir_snprintf(temp, sizeof(temp), "\n");
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+        else {
+            if(last_pos!=pos) {
+                xastir_snprintf(temp, sizeof(temp), "\n");
+                XmTextInsert(si_text,pos,temp);
+                pos += strlen(temp);
+            }
+        }
+
+        if (strlen(weather->wx_snow) > 0) {
+            if(english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI035"),atof(weather->wx_snow));
+            else
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI034"),atof(weather->wx_snow)*2.54);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+            xastir_snprintf(temp, sizeof(temp), "\n");
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_rain) > 0 || strlen(weather->wx_prec_00) > 0
+                || strlen(weather->wx_prec_24) > 0) {
+            xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI036"));
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_rain) > 0) {
+            if (english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI038"),atof(weather->wx_rain)/100.0);
+            else
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI037"),atof(weather->wx_rain)*.254);
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_prec_24) > 0) {
+            if(english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI040"),atof(weather->wx_prec_24)/100.0);
+            else
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI039"),atof(weather->wx_prec_24)*.254);
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_prec_00) > 0) {
+            if (english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI042"),atof(weather->wx_prec_00)/100.0);
+            else
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI041"),atof(weather->wx_prec_00)*.254);
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_rain_total) > 0) {
+            xastir_snprintf(temp, sizeof(temp), "\n%s",langcode("WPUPSTI046"));
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+            if (english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI048"),atof(weather->wx_rain_total)/100.0);
+            else
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI047"),atof(weather->wx_rain_total)*.254);
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        // Fuel temp/moisture for RAWS weather stations
+        if (strlen(weather->wx_fuel_temp) > 0) {
+            if (english_units)
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI061"),weather->wx_fuel_temp);
+            else {
+                temp_out_C =(((atof(weather->wx_fuel_temp)-32)*5.0)/9.0);
+                xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI060"),temp_out_C);
+            }
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        if (strlen(weather->wx_fuel_moisture) > 0) {
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI062"),weather->wx_fuel_moisture);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+
+        xastir_snprintf(temp, sizeof(temp), "\n\n");
+ 
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+
+    // Packets received ... 
+    xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI005"),p_station->num_packets);
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        p_station->packet_time);
+    temp[2]='/';
+    temp[3]='\0';
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        p_station->packet_time+2);
+    temp[2]='/';
+    temp[3]='\0';
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        p_station->packet_time+4);
+    temp[4]=' ';
+    temp[5]='\0';
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        p_station->packet_time+8);
+    temp[2]=':';
+    temp[3]='\0';
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        p_station->packet_time+10);
+    temp[2]=':';
+    temp[3]='\0';
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        p_station->packet_time+12);
+    temp[2]='\n';
+    temp[3]='\0';
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    // Object
+    if (strlen(p_station->origin) > 0) {
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI000"),p_station->origin);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Print the tactical call, if any
+    if (p_station->tactical_call_sign
+            && p_station->tactical_call_sign[0] != '\0') {
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI065"), p_station->tactical_call_sign);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Heard via TNC ...
+    if ((p_station->flag & ST_VIATNC) != 0) {        // test "via TNC" flag
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI006"),p_station->heard_via_tnc_port);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+    else {
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI007"));
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    switch(p_station->data_via) {
+        case('L'):
+            xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI008"));
+            break;
+
+        case('T'):
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI009"),p_station->last_port_heard);
+            break;
+
+        case('I'):
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI010"),p_station->last_port_heard);
+            break;
+
+        case('F'):
+            xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI011"));
+            break;
+
+        case(DATA_VIA_DATABASE):
+            xastir_snprintf(temp, sizeof(temp), "last via db on interface %d",p_station->last_port_heard);
+            break;
+
+        default:
+            xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI012"));
+            break;
+    }
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    if (p_station->newest_trackpoint != NULL) {
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI013"));
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+    xastir_snprintf(temp, sizeof(temp), "\n");
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    // Echoed from: ...
+    // Callsign check here includes checking SSID
+//    if (is_my_call(p_station->call_sign,1)) {
+    if ( is_my_station(p_station) ) {
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("WPUPSTI055"));
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        for (i=0;i<6;i++) {
+            if (echo_digis[i][0] == '\0')
+                break;
+
+            xastir_snprintf(temp, sizeof(temp), " %s",echo_digis[i]);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+        }
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Data Path ...
+    if (p_station->node_path_ptr != NULL)
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI043"),p_station->node_path_ptr);
+    else
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI043"), "");
+
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+    xastir_snprintf(temp, sizeof(temp), "\n");
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    // Status ...
+    if(p_station->status_data != NULL) {   // Found at least one record
+        CommentRow *ptr;
+
+        ptr = p_station->status_data;
+
+        while (ptr != NULL) {
+            // We don't care if the pointer is NULL.  This will
+            // succeed anyway.  It'll just make an empty string.
+
+            // Note that text_ptr may be an empty string.  That's
+            // ok.
+
+            //Also print the sec_heard timestamp.
+            sec = ptr->sec_heard;
+            time = localtime(&sec);
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                langcode("WPUPSTI059"),
+                time->tm_mon + 1,
+                time->tm_mday,
+                time->tm_hour,
+                time->tm_min,
+                ptr->text_ptr);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            xastir_snprintf(temp, sizeof(temp), "\n");
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+            ptr = ptr->next;    // Advance to next record (if any)
+        }
+    }
+
+
+//    // Comments ...
+//    if(strlen(p_station->comments)>0) {
+//        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI044"),p_station->comments);
+//        XmTextInsert(si_text,pos,temp);
+//        pos += strlen(temp);
+//        xastir_snprintf(temp, sizeof(temp), "\n");
+//        XmTextInsert(si_text,pos,temp);
+//        pos += strlen(temp);
+//    }
+
+    // Comments ...
+    if(p_station->comment_data != NULL) {   // Found at least one record
+        CommentRow *ptr;
+
+        ptr = p_station->comment_data;
+
+        while (ptr != NULL) {
+            // We don't care if the pointer is NULL.  This will
+            // succeed anyway.  It'll just make an empty string.
+
+            // Note that text_ptr can be an empty string.  That's
+            // ok.
+
+            //Also print the sec_heard timestamp.
+            sec = ptr->sec_heard;
+            time = localtime(&sec);
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                langcode("WPUPSTI044"),
+                time->tm_mon + 1,
+                time->tm_mday,
+                time->tm_hour,
+                time->tm_min,
+                ptr->text_ptr);
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            xastir_snprintf(temp, sizeof(temp), "\n");
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+            ptr = ptr->next;    // Advance to next record (if any)
+        }
+    }
+
+    // Current Power Gain ...
+    if (strlen(p_station->power_gain) == 7) {
+        // Check for RNG instead of PHG
+        if (p_station->power_gain[0] == 'R') {
+            // Found a Range
+            xastir_snprintf(temp,
+                sizeof(temp),
+                langcode("WPUPSTI067"),
+                atoi(&p_station->power_gain[3]));
+        }
+        else {
+            // Found PHG
+            phg_decode(langcode("WPUPSTI014"), // "Current Power Gain"
+                p_station->power_gain,
+                temp,
+                sizeof(temp) );
+        }
+
+        // Check for Map View symbol:  Eyeball symbol with // RNG
+        // extension.
+        if ( strncmp(p_station->power_gain,"RNG",3) == 0
+                && p_station->aprs_symbol.aprs_type == '/'
+                && p_station->aprs_symbol.aprs_symbol == 'E' ) {
+
+//fprintf(stderr,"Found a Map View 'eyeball' symbol!\n");
+
+            // Center_Zoom() normally fills in the values with the
+            // current zoom/center for the map window.  We want to
+            // be able to override these with our own values in this
+            // case, derived from the object info.
+            center_zoom_override++;
+            Center_Zoom(w,NULL,(XtPointer)p_station);
+        }
+    }
+    else if (p_station->flag & (ST_OBJECT | ST_ITEM)) {
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s %s",
+            langcode("WPUPSTI014"), // "Current Power Gain:"
+            langcode("WPUPSTI068") );   // "none"
+    }
+    else if (english_units) {
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s %s (9W @ 20ft %s, 3dB %s, %s 6.2mi)",
+            langcode("WPUPSTI014"), // "Current Power Gain:"
+            langcode("WPUPSTI069"), // "default"
+            langcode("WPUPSTI070"), // "HAAT"
+            langcode("WPUPSTI071"), // "omni"
+            langcode("WPUPSTI072") ); // "range"
+//          "default (9W @ 20ft HAAT, 3dB omni, range 6.2mi)");
+    }
+    else {
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s %s (9W @ 6.1m %s, 3dB %s, %s 10.0km)",
+            langcode("WPUPSTI014"), // "Current Power Gain:"
+            langcode("WPUPSTI069"), // "default"
+            langcode("WPUPSTI070"), // "HAAT"
+            langcode("WPUPSTI071"), // "omni"
+            langcode("WPUPSTI072") ); // "range"
+//          "default (9W @ 6.1m HAAT, 3dB omni, range 10.0km)");
+            
+    }
+
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+    xastir_snprintf(temp, sizeof(temp), "\n");
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    // Current DF Info ...
+    if (strlen(p_station->signal_gain) == 7) {
+        shg_decode(langcode("WPUPSTI057"), p_station->signal_gain, temp, sizeof(temp) );
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+    if (strlen(p_station->bearing) == 3) {
+        bearing_decode(langcode("WPUPSTI058"), p_station->bearing, p_station->NRQ, temp, sizeof(temp) );
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Signpost Data
+    if (strlen(p_station->signpost) > 0) {
+        xastir_snprintf(temp, sizeof(temp), "%s: %s",langcode("POPUPOB029"), p_station->signpost);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Altitude ...
+    last_pos=pos;
+    if (strlen(p_station->altitude) > 0) {
+        if (english_units)
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI016"),atof(p_station->altitude)*3.28084,"ft");
+        else
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI016"),atof(p_station->altitude),"m");
+
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Course ...
+    if (strlen(p_station->course) > 0) {
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI017"),p_station->course);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Speed ...
+    if (strlen(p_station->speed) > 0) {
+        if (english_units)
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI019"),atof(p_station->speed)*1.1508);
+
+        else
+            xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI018"),atof(p_station->speed)*1.852);
+
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    if (last_pos!=pos) {
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Distance ...
+    last_pos = pos;
+
+    // do my course
+//    if (!is_my_call(p_station->call_sign,1)) { // Checks SSID as well
+    if ( !(is_my_station(p_station)) ) { // Checks SSID as well
+
+        l_lat = convert_lat_s2l(my_lat);
+        l_lon = convert_lon_s2l(my_long);
+
+        // Get distance in nautical miles.
+        value = (float)calc_distance_course(l_lat,l_lon,p_station->coord_lat,
+            p_station->coord_lon,temp1_my_course,sizeof(temp1_my_course));
+
+        // n7tap: This is a quick hack to get some more useful values for
+        //        distance to near ojects.
+        if (english_units) {
+            if (value*1.15078 < 0.99) {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    "%d %s",
+                    (int)(value*1.15078*1760),
+                    langcode("SPCHSTR004"));    // yards
+            }
+            else {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    langcode("WPUPSTI020"),     // miles
+                    value*1.15078);
+            }
+        }
+        else {
+            if (value*1.852 < 0.99) {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    "%d %s",
+                    (int)(value*1.852*1000),
+                    langcode("UNIOP00031"));    // 'm' as in meters
+            }
+            else {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    langcode("WPUPSTI021"),     // km
+                    value*1.852);
+            }
+        }
+        xastir_snprintf(temp_my_course, sizeof(temp_my_course), "%s�",temp1_my_course);
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPSTI022"),temp_my_distance,temp_my_course);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    if(last_pos!=pos) {
+        xastir_snprintf(temp, sizeof(temp), "\n");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    // Last Position
+    sec  = p_station->sec_heard;
+    time = localtime(&sec);
+    xastir_snprintf(temp, sizeof(temp), "%s%02d/%02d  %02d:%02d   ",langcode("WPUPSTI023"),
+        time->tm_mon + 1, time->tm_mday,time->tm_hour,time->tm_min);
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    if (coordinate_system == USE_UTM
+            || coordinate_system == USE_UTM_SPECIAL) {
+        convert_xastir_to_UTM_str(temp, sizeof(temp),
+            p_station->coord_lon, p_station->coord_lat);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+    else if (coordinate_system == USE_MGRS) {
+        convert_xastir_to_MGRS_str(temp,
+            sizeof(temp),
+            p_station->coord_lon,
+            p_station->coord_lat,
+            0);
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+    else {
+        if (coordinate_system == USE_DDDDDD) {
+            convert_lat_l2s(p_station->coord_lat, temp, sizeof(temp), CONVERT_DEC_DEG);
+        }
+        else if (coordinate_system == USE_DDMMSS) {
+            convert_lat_l2s(p_station->coord_lat, temp, sizeof(temp), CONVERT_DMS_NORMAL);
+        }
+        else {  // Assume coordinate_system == USE_DDMMMM
+            convert_lat_l2s(p_station->coord_lat, temp, sizeof(temp), CONVERT_HP_NORMAL);
+        }
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+
+        xastir_snprintf(temp, sizeof(temp), "  ");
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+
+        if (coordinate_system == USE_DDDDDD) {
+            convert_lon_l2s(p_station->coord_lon, temp, sizeof(temp), CONVERT_DEC_DEG);
+        }
+        else if (coordinate_system == USE_DDMMSS) {
+            convert_lon_l2s(p_station->coord_lon, temp, sizeof(temp), CONVERT_DMS_NORMAL);
+        }
+        else {  // Assume coordinate_system == USE_DDMMMM
+            convert_lon_l2s(p_station->coord_lon, temp, sizeof(temp), CONVERT_HP_NORMAL);
+        }
+        XmTextInsert(si_text,pos,temp);
+        pos += strlen(temp);
+    }
+
+    if (p_station->altitude[0] != '\0')
+        xastir_snprintf(temp, sizeof(temp), " %5.0f%s", atof(p_station->altitude)*cvt_m2len, un_alt);
+    else
+        substr(temp,"        ",1+5+strlen(un_alt));
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    if (p_station->speed[0] != '\0')
+        xastir_snprintf(temp, sizeof(temp), " %4.0f%s",atof(p_station->speed)*cvt_kn2len,un_spd);
+    else
+        substr(temp,"         ",1+4+strlen(un_spd));
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    if (p_station->course[0] != '\0')
+        xastir_snprintf(temp, sizeof(temp), " %3d�",atoi(p_station->course));
+    else
+        xastir_snprintf(temp, sizeof(temp), "     ");
+
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    // dl9sau
+    // Maidenhead Grid Locator
+    xastir_snprintf(temp, sizeof(temp), "  %s", sec_to_loc(p_station->coord_lon, p_station->coord_lat) );
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    if ((p_station->flag & ST_DIRECT) != 0)
+        xastir_snprintf(temp, sizeof(temp), " *\n");
+
+    else
+        xastir_snprintf(temp, sizeof(temp), "  \n");
+
+    XmTextInsert(si_text,pos,temp);
+    pos += strlen(temp);
+
+    // list rest of trail data
+    if (p_station->newest_trackpoint != NULL) {
+        TrackRow *ptr;
+
+        ptr = p_station->newest_trackpoint;
+
+        // Skip the first (latest) trackpoint as if it exists, it'll
+        // be the same as the data in the station record, which we
+        // just printed out.
+        if (ptr->prev != NULL)
+           ptr = ptr->prev;
+ 
+        while ( (ptr != NULL) && (track_count <= MAX_TRACK_LIST) ) {
+
+            track_count++;
+
+            sec  = ptr->sec;
+            time = localtime(&sec);
+            if ((ptr->flag & TR_NEWTRK) != '\0')
+                xastir_snprintf(temp, sizeof(temp), "            +  %02d/%02d  %02d:%02d   ",
+                    time->tm_mon + 1,time->tm_mday,time->tm_hour,time->tm_min);
+            else
+                xastir_snprintf(temp, sizeof(temp), "               %02d/%02d  %02d:%02d   ",
+                    time->tm_mon + 1,time->tm_mday,time->tm_hour,time->tm_min);
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            if (coordinate_system == USE_UTM
+                    || coordinate_system == USE_UTM_SPECIAL) {
+                convert_xastir_to_UTM_str(temp, sizeof(temp),
+                    ptr->trail_long_pos,
+                    ptr->trail_lat_pos);
+                XmTextInsert(si_text,pos,temp);
+                pos += strlen(temp);
+            }
+            else if (coordinate_system == USE_MGRS) {
+                convert_xastir_to_MGRS_str(temp,
+                    sizeof(temp),
+                    ptr->trail_long_pos,
+                    ptr->trail_lat_pos,
+                    0);
+                XmTextInsert(si_text,pos,temp);
+                pos += strlen(temp);
+            }
+            else {
+                if (coordinate_system == USE_DDDDDD) {
+                    convert_lat_l2s(ptr->trail_lat_pos,
+                        temp,
+                        sizeof(temp),
+                        CONVERT_DEC_DEG);
+                }
+                else if (coordinate_system == USE_DDMMSS) {
+                    convert_lat_l2s(ptr->trail_lat_pos,
+                        temp,
+                        sizeof(temp),
+                        CONVERT_DMS_NORMAL);
+                }
+                else {  // Assume coordinate_system == USE_DDMMMM
+                    convert_lat_l2s(ptr->trail_lat_pos,
+                        temp,
+                        sizeof(temp),
+                        CONVERT_HP_NORMAL);
+                }
+                XmTextInsert(si_text,pos,temp);
+                pos += strlen(temp);
+
+                xastir_snprintf(temp, sizeof(temp), "  ");
+                XmTextInsert(si_text,pos,temp);
+                pos += strlen(temp);
+
+                if (coordinate_system == USE_DDDDDD) {
+                    convert_lon_l2s(ptr->trail_long_pos,
+                        temp,
+                        sizeof(temp),
+                        CONVERT_DEC_DEG);
+                }
+                else if (coordinate_system == USE_DDMMSS) {
+                    convert_lon_l2s(ptr->trail_long_pos,
+                        temp,
+                        sizeof(temp),
+                        CONVERT_DMS_NORMAL);
+                }
+                else {  // Assume coordinate_system == USE_DDMMMM
+                    convert_lon_l2s(ptr->trail_long_pos,
+                        temp,
+                        sizeof(temp),
+                        CONVERT_HP_NORMAL);
+                }
+                XmTextInsert(si_text,pos,temp);
+                pos += strlen(temp);
+            }
+
+            if (ptr->altitude > -99999l)
+                xastir_snprintf(temp, sizeof(temp), " %5.0f%s",
+                    ptr->altitude * cvt_dm2len,
+                    un_alt);
+            else
+                substr(temp,"         ",1+5+strlen(un_alt));
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            if (ptr->speed >= 0)
+                xastir_snprintf(temp, sizeof(temp), " %4.0f%s",
+                    ptr->speed * cvt_hm2len,
+                    un_spd);
+            else
+                substr(temp,"         ",1+4+strlen(un_spd));
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            if (ptr->course >= 0)
+                xastir_snprintf(temp, sizeof(temp), " %3d�",
+                    ptr->course);
+            else
+                xastir_snprintf(temp, sizeof(temp), "     ");
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            // dl9sau
+            xastir_snprintf(temp, sizeof(temp), "  %s",
+                sec_to_loc(ptr->trail_long_pos,
+                    ptr->trail_lat_pos) );
+            XmTextInsert(si_text,pos,temp); 
+            pos += strlen(temp);
+
+            if ((ptr->flag & TR_LOCAL) != '\0')
+                xastir_snprintf(temp, sizeof(temp), " *\n");
+            else
+                xastir_snprintf(temp, sizeof(temp), "  \n");
+
+            XmTextInsert(si_text,pos,temp);
+            pos += strlen(temp);
+
+            // Go back in time one trackpoint
+            ptr = ptr->prev;
+        }
+    }
+
+
+    if (fcc_lookup_pushed) {
+        Station_data_add_fcc(w, clientData, calldata);
+    }
+    else if (rac_lookup_pushed) {
+        Station_data_add_rac(w, clientData, calldata);
+    }
+
+    XmTextShowPosition(si_text,0);
+
+end_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+}
+
+
+
+
+
+/* 
+ * Track from Station_data
+ *
+ * Called by Station_data function below from the Track Station
+ * button in Station Info.
+ */
+void Track_from_Station_data(/*@unused@*/ Widget w, XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station = clientData;
+ 
+    if (p_station->call_sign[0] != '\0') {
+        xastir_snprintf(tracking_station_call,
+            sizeof(tracking_station_call),
+            "%s",
+            p_station->call_sign);
+        track_station_on = 1;
+    }
+    else {
+        tracking_station_call[0] = '\0';
+    }
+}
+
+/* 
+ * Clear DF from Station_data
+ *
+ * Called by Station_data function below from the Clear DF Bearing
+ * button in Station Info.
+ */
+void Clear_DF_from_Station_data(/*@unused@*/ Widget w, XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station = clientData;
+ 
+    if (strlen(p_station->bearing) == 3) {
+        // we have DF data to clear
+        p_station->bearing[0]='\0';
+        p_station->NRQ[0]='\0';
+    }
+}
+
+
+
+
+
+/*
+ *  List station info and trail
+ *  If calldata is non-NULL, then we drop straight through to the
+ *  Modify->Object or Assign_Tactical_Call dialogs.
+ *
+ * Input parameters:
+ *     clientData:  Station callsign
+ *
+ *     calldata: NULL = Station Info
+ *               "1"  = Object -> Modify
+ *               "2"  = Move Object
+ *               "3"  = Assign Tactical Call
+ *               "4"  = Send Message To
+ *
+ */
+void Station_data(/*@unused@*/ Widget w, XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station;
+    char *station = (char *) clientData;
+    static char local_station[25];
+    char temp[300];
+    unsigned int n;
+    Atom delw;
+    static Widget  pane, form, button_cancel, button_message,
+        button_nws, button_fcc, button_rac, button_clear_track,
+        button_trace, button_messages, button_object_modify,
+        button_direct, button_version, station_icon, station_call,
+        station_type, station_data_auto_update_w,
+        button_tactical, button_change_trail_color,
+        button_track_station,button_clear_df;
+    Arg args[50];
+    Pixmap icon;
+    Position x,y;    // For saving current dialog position
+    int restore_position = 0;
+
+
+//fprintf(stderr,"db.c:Station_data start\n");
+
+    busy_cursor(appshell);
+
+    db_station_info_callsign = (char *) clientData; // Used for auto-updating this dialog
+
+
+    // Make a copy of the name.
+    xastir_snprintf(local_station,sizeof(local_station),"%s",station);
+
+    if (search_station_name(&p_station,station,1)   // find call
+        && (p_station->flag & ST_ACTIVE) != 0) {    // ignore deleted objects
+    }
+    else {
+        fprintf(stderr,"Couldn't find station in database\n");
+        return; // Don't update current/create new dialog
+    }
+
+
+    if (calldata != NULL) { // We were called from the
+                            // Object->Modify, Assign Tactical Call,
+                            // or Send Message To menu items.
+        if (strncmp(calldata,"1",1) == 0) {
+            Modify_object(w, (XtPointer)p_station, calldata);
+        }
+        else if (strncmp(calldata,"2",1) == 0) {
+            Modify_object(w, (XtPointer)p_station, calldata);
+        }
+        else if (strncmp(calldata,"3",1) == 0) {
+            Assign_Tactical_Call(w, (XtPointer)p_station, calldata);
+        }
+        else if (strncmp(calldata,"4",1) == 0) {
+//fprintf(stderr,"Send Message To: %s\n", p_station->call_sign);
+            Send_message_call(NULL, (XtPointer) p_station->call_sign, NULL);
+        }
+        return;
+    }
+
+ 
+    // If we haven't calculated our decoration offsets yet, do so now
+    if ( (decoration_offset_x == 0) && (decoration_offset_y == 0) ) {
+        compute_decorations();
+    }
+ 
+    if (db_station_info != NULL) {  // We already have a dialog
+        restore_position = 1;
+
+        // This is a pain.  We can get the X/Y position, but when
+        // we restore the new dialog to the same position we're
+        // off by the width/height of our window decorations.  Call
+        // above was added to pre-compute the offsets that we'll need.
+        XtVaGetValues(db_station_info, XmNx, &x, XmNy, &y, NULL);
+
+        // This call doesn't work.  It returns the widget location,
+        // just like the XtVaGetValues call does.  I need the window
+        // decoration location instead.
+        //XtTranslateCoords(db_station_info, 0, 0, &xnew, &ynew);
+        //fprintf(stderr,"%d:%d\t%d:%d\n", x, xnew, y, ynew);
+
+        if (last_station_info_x == 0)
+            last_station_info_x = x - decoration_offset_x;
+
+        if (last_station_info_y == 0)
+            last_station_info_y = y - decoration_offset_y;
+
+        // Now get rid of the old dialog
+       Station_data_destroy_shell(db_station_info, db_station_info, NULL);
+    }
+    else {
+        // Clear the global state variables
+        fcc_lookup_pushed = 0;
+        rac_lookup_pushed = 0;
+    }
+
+
+begin_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+
+    if (db_station_info == NULL) {
+        // Start building the dialog from the bottom up.  That way
+        // we can keep the buttons attached to the bottom of the
+        // form and the correct height, and let the text widget
+        // grow/shrink as the dialog is resized.
+
+        db_station_info = XtVaCreatePopupShell(langcode("WPUPSTI001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Station Data pane",
+            xmPanedWindowWidgetClass, db_station_info,
+            XmNbackground, colors[0xff],
+            NULL);
+
+        form =  XtVaCreateWidget("Station Data form",
+            xmFormWidgetClass, pane,
+            XmNfractionBase, 4,
+            XmNbackground, colors[0xff],
+            XmNautoUnmanage, FALSE,
+            XmNshadowThickness, 1,
+            NULL);
+
+
+// Start with the bottom row, left button
+
+
+        button_clear_track = NULL;  // Need this later, don't delete!
+        if (p_station->newest_trackpoint != NULL) {
+            // [ Clear Track ]
+            button_clear_track = XtVaCreateManagedWidget(langcode("WPUPSTI045"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNbottomOffset,5,
+                            XmNleftAttachment, XmATTACH_FORM,
+                            XmNleftOffset,5,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 1,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_clear_track, XmNactivateCallback, Station_data_destroy_track ,(XtPointer)p_station);
+
+        }
+        else {
+            // DK7IN: I drop the version button for mobile stations
+            // we just have too much buttons...
+            // and should find another solution
+            // [ Station Version Query ]
+            button_version = XtVaCreateManagedWidget(langcode("WPUPSTI052"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNbottomOffset,5,
+                            XmNleftAttachment, XmATTACH_FORM,
+                            XmNleftOffset,5,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 1,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_version, XmNactivateCallback, Station_query_version ,(XtPointer)p_station->call_sign);
+        }            
+
+        // [ Trace Query ]
+        button_trace = XtVaCreateManagedWidget(langcode("WPUPSTI049"),xmPushButtonGadgetClass, form,
+                                XmNtopAttachment, XmATTACH_NONE,
+                                XmNbottomAttachment, XmATTACH_FORM,
+                                XmNbottomOffset,5,
+                                XmNleftAttachment, XmATTACH_POSITION,
+                                XmNleftPosition, 1,
+                                XmNrightAttachment, XmATTACH_POSITION,
+                                XmNrightPosition, 2,
+                                XmNbackground, colors[0xff],
+                                XmNnavigationType, XmTAB_GROUP,
+                                XmNfontList, fontlist1,
+                                NULL);
+        XtAddCallback(button_trace, XmNactivateCallback, Station_query_trace ,(XtPointer)p_station->call_sign);
+
+        // [ Un-Acked Messages Query ]
+        button_messages = XtVaCreateManagedWidget(langcode("WPUPSTI050"),xmPushButtonGadgetClass, form,
+                                XmNtopAttachment, XmATTACH_NONE,
+                                XmNbottomAttachment, XmATTACH_FORM,
+                                XmNbottomOffset,5,
+                                XmNleftAttachment, XmATTACH_POSITION,
+                                XmNleftPosition, 2,
+                                XmNrightAttachment, XmATTACH_POSITION,
+                                XmNrightPosition, 3,
+                                XmNbackground, colors[0xff],
+                                XmNnavigationType, XmTAB_GROUP,
+                                XmNfontList, fontlist1,
+                                NULL);
+        XtAddCallback(button_messages, XmNactivateCallback, Station_query_messages ,(XtPointer)p_station->call_sign);
+
+        // [ Direct Stations Query ]
+        button_direct = XtVaCreateManagedWidget(langcode("WPUPSTI051"),xmPushButtonGadgetClass, form,
+                                XmNtopAttachment, XmATTACH_NONE,
+                                XmNbottomAttachment, XmATTACH_FORM,
+                                XmNbottomOffset,5,
+                                XmNleftAttachment, XmATTACH_POSITION,
+                                XmNleftPosition, 3,
+                                XmNrightAttachment, XmATTACH_POSITION,
+                                XmNrightPosition, 4,
+                                XmNbackground, colors[0xff],
+                                XmNnavigationType, XmTAB_GROUP,
+                                XmNfontList, fontlist1,
+                                NULL);
+        XtAddCallback(button_direct, XmNactivateCallback, Station_query_direct ,(XtPointer)p_station->call_sign);
+
+
+// Now proceed to the row above it, left button first
+
+
+        // [ Store Track ] or single Position
+        button_store_track = XtVaCreateManagedWidget(langcode("WPUPSTI054"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+//XmNtopWidget,XtParent(si_text),
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, (button_clear_track) ? button_clear_track : button_version,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_FORM,
+                            XmNleftOffset,5,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 1,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+        XtAddCallback(button_store_track,   XmNactivateCallback, Station_data_store_track ,(XtPointer)p_station);
+
+        if ( ((p_station->flag & ST_OBJECT) == 0) && ((p_station->flag & ST_ITEM) == 0) ) { // Not an object/
+            // fprintf(stderr,"Not an object or item...\n");
+            // [Send Message]
+            button_message = XtVaCreateManagedWidget(langcode("WPUPSTI002"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_trace,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 1,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 2,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_message, XmNactivateCallback, Send_message_call ,(XtPointer)p_station->call_sign);
+        }
+        else {
+            // fprintf(stderr,"Found an object or item...\n");
+            button_object_modify = XtVaCreateManagedWidget(langcode("WPUPSTI053"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_trace,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 1,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 2,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_object_modify,
+                XmNactivateCallback,
+                Modify_object,
+                (XtPointer)p_station);
+        }
+
+
+        // Check whether it is a non-weather alert object/item.  If
+        // so, try to use the origin callsign instead of the object
+        // for FCC/RAC lookups.
+        //
+        if ( (p_station->flag & ST_OBJECT) || (p_station->flag & ST_ITEM) ) {
+
+            // It turns out that objects transmitted by a station
+            // called "WINLINK" are what mess up the RAC button for
+            // Canadian stations.  Xastir sees the 'W' of WINLINK
+            // (the originating station) and assumes it is a U.S.
+            // station.  Here's a sample packet:
+            //
+// WINLINK>APWL2K,TCPIP*,qAC,T2MIDWEST:;VE7SEP-10*240521z4826.2 NW12322.5 Wa145.690MHz 1200b R11m RMSPacket EMCOMM
+            //
+            // If match on "WINLINK":  Don't copy origin callsign
+            // into local_station.  Use the object name instead
+            // which should be a callsign.
+            if (strncmp(p_station->origin,"WINLINK",7)) {
+                xastir_snprintf(local_station,sizeof(local_station),"%s",p_station->origin);
+            }
+        }
+
+
+        // Add "Fetch NWS Info" button if it is an object or item
+        // and has "WXSVR" in its path somewhere.
+        //
+        // Note from Dale Huguley:
+        //   "I would say an object with 6 upper alpha chars for the
+        //   "from" call and " {AAAAA" (space curly 5 alphanumerics)
+        //   at the end is almost guaranteed to be from Wxsvr.
+        //   Fingering for the six alphas and the first three
+        //   characters after the curly brace should be a reliable
+        //   finger - as in SEWSVR>APRS::a_bunch_of_info_in_here_
+        //   {H45AA finger SEWSVRH45 at wxsvr.net"
+        //
+        // Note from Curt:  I had to remove the space from the
+        // search as well, 'cuz the multipoint objects don't have
+        // the space before the final curly-brace.
+        //
+        if ( ( (p_station->flag & ST_OBJECT) || (p_station->flag & ST_ITEM) )
+                && (p_station->comment_data != NULL)
+                && ( strstr(p_station->comment_data->text_ptr, "{") != NULL ) ) {
+
+            static char temp[25];
+            char *ptr3;
+
+
+            button_nws = XtVaCreateManagedWidget(langcode("WPUPSTI064"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_messages,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 2,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 3,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+            // We need to contruct the "special" finger address.
+            // We'll use the FROM callsign and the first three chars
+            // of the curly-brace portion of the comment field.
+            // Callsign in this case is from the "origin" field.
+            // The curly-brace text is at the end of one of the
+            // "comment_data" records, hopefully the first one
+            // checked (most recent).
+            //
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                p_station->origin);
+            temp[6] = '\0';
+            ptr3 = strstr(p_station->comment_data->text_ptr,"{");
+            ptr3++; // Skip over the '{' character
+            strncat(temp,ptr3,3);
+
+//fprintf(stderr,"New Handle: %s\n", temp);
+
+            XtAddCallback(button_nws,
+                XmNactivateCallback,
+                Station_data_wx_alert,
+                (XtPointer)temp);
+        }
+
+
+        // Add FCC button only if probable match.  The U.S. has
+        // these prefixes assigned but not all are used for amateur
+        // stations:
+        //
+        //   AAA-ALZ
+        //   KAA-KZZ
+        //   NAA-NZZ
+        //   WAA-WZZ
+        //
+        else if ((! strncmp(local_station,"A",1)) || (!  strncmp(local_station,"K",1)) ||
+            (! strncmp(local_station,"N",1)) || (! strncmp(local_station,"W",1))  ) {
+
+            button_fcc = XtVaCreateManagedWidget(langcode("WPUPSTI003"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_messages,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 2,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 3,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_fcc,
+                XmNactivateCallback,
+                Station_data_add_fcc,
+                (XtPointer)local_station);
+
+            if ( ! check_fcc_data())
+                XtSetSensitive(button_fcc,FALSE);
+        }
+
+
+        // Add RAC button only if probable match.  Canada has these
+        // prefixes assigned but not all are used for amateur
+        // stations:
+        //
+        //   CFA-CKZ
+        //   CYA-CZZ
+        //   VAA-VGZ
+        //   VOA-VOZ
+        //   VXA-VYZ
+        //   XJA-XOZ
+        //
+        else if (!strncmp(local_station,"VA",2) || !strncmp(local_station,"VE",2) || !strncmp(local_station,"VO",2) || !strncmp(local_station,"VY",2)) {
+            button_rac = XtVaCreateManagedWidget(langcode("WPUPSTI004"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_messages,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 2,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 3,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_rac,
+                XmNactivateCallback,
+                Station_data_add_rac,
+                (XtPointer)local_station);
+
+            if ( ! check_rac_data())
+                XtSetSensitive(button_rac,FALSE);
+        }
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_direct,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 3,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 4,
+                            XmNrightOffset, 5,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+        XtAddCallback(button_cancel, XmNactivateCallback, Station_data_destroy_shell, db_station_info);
+
+        // Button to clear DF bearing data if we actually have some.
+        if (strlen(p_station->bearing) == 3) {
+            button_clear_df = XtVaCreateManagedWidget(langcode("WPUPSTI092"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_cancel,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 3,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 4,
+                            XmNrightOffset, 5,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+            XtAddCallback(button_clear_df, XmNactivateCallback,Clear_DF_from_Station_data, (XtPointer)p_station);
+        }
+            
+        button_track_station = XtVaCreateManagedWidget(langcode("WPUPTSP001"),xmPushButtonGadgetClass, form,
+                            XmNtopAttachment, XmATTACH_NONE,
+                            XmNbottomAttachment, XmATTACH_WIDGET,
+                            XmNbottomWidget, button_store_track,
+                            XmNbottomOffset, 1,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 0,
+                            XmNleftOffset,5,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 1,
+//                            XmNrightOffset, 5,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+        XtAddCallback(button_track_station, XmNactivateCallback,Track_from_Station_data, (XtPointer)p_station);
+
+ 
+
+// Now build from the top of the dialog to the buttons.
+
+
+        icon = XCreatePixmap(XtDisplay(appshell),RootWindowOfScreen(XtScreen(appshell)),
+                    20,20,DefaultDepthOfScreen(XtScreen(appshell)));
+
+        symbol(db_station_info,0,p_station->aprs_symbol.aprs_type,
+            p_station->aprs_symbol.aprs_symbol,
+            p_station->aprs_symbol.special_overlay,icon,0,0,0,' ');
+
+        station_icon = XtVaCreateManagedWidget("Station Data icon", xmLabelWidgetClass, form,
+                                XmNtopAttachment, XmATTACH_FORM,
+                                XmNtopOffset, 2,
+                                XmNbottomAttachment, XmATTACH_NONE,
+                                XmNleftAttachment, XmATTACH_FORM,
+                                XmNleftOffset, 5,
+                                XmNrightAttachment, XmATTACH_NONE,
+                                XmNlabelType, XmPIXMAP,
+                                XmNlabelPixmap,icon,
+                                XmNbackground, colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+
+        station_type = XtVaCreateManagedWidget("Station Data type", xmTextFieldWidgetClass, form,
+                                XmNeditable,   FALSE,
+                                XmNcursorPositionVisible, FALSE,
+                                XmNtraversalOn, FALSE,
+                                XmNshadowThickness,       0,
+                                XmNcolumns,5,
+                                XmNwidth,((5*7)+2),
+                                XmNbackground, colors[0xff],
+                                XmNtopAttachment,XmATTACH_FORM,
+                                XmNtopOffset, 2,
+                                XmNbottomAttachment,XmATTACH_NONE,
+                                XmNleftAttachment, XmATTACH_WIDGET,
+                                XmNleftWidget,station_icon,
+                                XmNleftOffset,10,
+                                XmNrightAttachment,XmATTACH_NONE,
+                                XmNfontList, fontlist1,
+                                NULL);
+
+        xastir_snprintf(temp, sizeof(temp), "%c%c%c", p_station->aprs_symbol.aprs_type,
+            p_station->aprs_symbol.aprs_symbol,
+            p_station->aprs_symbol.special_overlay);
+
+        XmTextFieldSetString(station_type, temp);
+        XtManageChild(station_type);
+
+        station_call = XtVaCreateManagedWidget("Station Data call", xmTextFieldWidgetClass, form,
+                                XmNeditable,   FALSE,
+                                XmNcursorPositionVisible, FALSE,
+                                XmNtraversalOn, FALSE,
+                                XmNshadowThickness,       0,
+                                XmNcolumns,10,
+                                XmNwidth,((10*7)+2),
+                                XmNbackground, colors[0xff],
+                                XmNtopAttachment,XmATTACH_FORM,
+                                XmNtopOffset, 2,
+                                XmNbottomAttachment,XmATTACH_NONE,
+                                XmNleftAttachment, XmATTACH_WIDGET,
+                                XmNleftWidget, station_type,
+                                XmNleftOffset,10,
+                                XmNrightAttachment,XmATTACH_NONE,
+                                XmNfontList, fontlist1,
+                                NULL);
+
+        XmTextFieldSetString(station_call,p_station->call_sign);
+        XtManageChild(station_call);
+
+        station_data_auto_update_w = XtVaCreateManagedWidget(langcode("WPUPSTI056"),
+                                xmToggleButtonGadgetClass, form,
+                                XmNtopAttachment,XmATTACH_FORM,
+                                XmNtopOffset, 2,
+                                XmNbottomAttachment,XmATTACH_NONE,
+                                XmNleftAttachment, XmATTACH_WIDGET,
+                                XmNleftWidget, station_call,
+                                XmNleftOffset,10,
+                                XmNrightAttachment,XmATTACH_NONE,
+                                XmNbackground,colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+        XtAddCallback(station_data_auto_update_w,XmNvalueChangedCallback,station_data_auto_update_toggle,"1");
+
+        //Add tactical button at the top/right
+        // "Assign Tactical Call"
+        button_tactical = XtVaCreateManagedWidget(langcode("WPUPSTI066"),xmPushButtonGadgetClass, form,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNtopOffset, 5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftOffset, 10,
+            XmNleftWidget, station_data_auto_update_w,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNbackground, colors[0xff],
+            XmNnavigationType, XmTAB_GROUP,
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(button_tactical,
+            XmNactivateCallback,
+            Assign_Tactical_Call,
+            (XtPointer)p_station);
+        if (p_station->flag & (ST_OBJECT | ST_ITEM)) {
+            // We don't allow setting tac-calls for objects/items,
+            // so make the button insensitive.
+            XtSetSensitive(button_tactical,FALSE);
+        }
+ 
+        //Add change_trail_color button at the top/right
+        // "Trail Color"
+        button_change_trail_color = XtVaCreateManagedWidget(langcode("WPUPSTI091"),
+            xmPushButtonGadgetClass, form,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNtopOffset, 5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftOffset, 10,
+            XmNleftWidget, button_tactical,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNbackground, colors[0xff],
+            XmNnavigationType, XmTAB_GROUP,
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(button_change_trail_color,
+            XmNactivateCallback,
+            Change_trail_color,
+            (XtPointer)p_station);
+ 
+        n=0;
+        XtSetArg(args[n], XmNrows, 15); n++;
+        XtSetArg(args[n], XmNcolumns, 100); n++;
+        XtSetArg(args[n], XmNeditable, FALSE); n++;
+        XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
+        XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
+        XtSetArg(args[n], XmNwordWrap, TRUE); n++;
+        XtSetArg(args[n], XmNbackground, colors[0xff]); n++;
+        XtSetArg(args[n], XmNscrollHorizontal, FALSE); n++;
+        XtSetArg(args[n], XmNcursorPositionVisible, FALSE); n++;
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
+        XtSetArg(args[n], XmNtopWidget, station_icon); n++;
+        XtSetArg(args[n], XmNtopOffset, 5); n++;
+        XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
+//        XtSetArg(args[n], XmNbottomWidget, button_store_track); n++;
+        XtSetArg(args[n], XmNbottomWidget, button_track_station); n++;
+        XtSetArg(args[n], XmNbottomOffset, 1); n++;
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNleftOffset, 5); n++;
+        XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNrightOffset, 5); n++;
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+
+        si_text = NULL;
+        si_text = XmCreateScrolledText(form,"Station_data",args,n);
+
+end_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+    // Fill in the si_text widget with real data
+    station_data_fill_in( w, (XtPointer)db_station_info_callsign, NULL);
+ 
+begin_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+// restore_position doesn't appear to work.  I get the dialog
+// positioned all over my virtual consoles if I try.  Reverting to
+// pos_dialog() for now.
+//        if (restore_position) {
+//            XtVaSetValues(db_station_info,XmNx,x - decoration_offset_x,XmNy,y - decoration_offset_y,NULL);
+//        }
+//        else {
+            pos_dialog(db_station_info);
+//        }
+
+        delw = XmInternAtom(XtDisplay(db_station_info),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(db_station_info, delw, Station_data_destroy_shell, (XtPointer)db_station_info);
+
+        XtManageChild(form);
+        XtManageChild(si_text);
+        XtVaSetValues(si_text, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+        if (station_data_auto_update)
+            XmToggleButtonSetState(station_data_auto_update_w,TRUE,FALSE);
+
+        if (calldata == NULL) { // We're not going straight to the Modify dialog
+                                // and will actually use the dialog we just drew
+
+            XtPopup(db_station_info,XtGrabNone);
+
+//            fix_dialog_size(db_station_info);
+            XmTextShowPosition(si_text,0);
+
+            // Move focus to the Cancel button.  This appears to highlight t
+            // button fine, but we're not able to hit the <Enter> key to
+            // have that default function happen.  Note:  We _can_ hit the
+            // <SPACE> key, and that activates the option.
+            XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+        }
+    }
+
+end_critical_section(&db_station_info_lock, "db.c:Station_data" );
+
+}
+
+
+
+
+
+// Used for auto-refreshing the Station_info dialog.  Called from
+// main.c:UpdateTime() every 30 seconds.
+//
+void update_station_info(Widget w) {
+
+begin_critical_section(&db_station_info_lock, "db.c:update_station_info" );
+
+    // If we have a dialog to update and a callsign to pass to it
+    if (( db_station_info != NULL)
+            && (db_station_info_callsign != NULL)
+            && (strlen(db_station_info_callsign) != 0) ) {
+
+end_critical_section(&db_station_info_lock, "db.c:update_station_info" );
+
+        // Fill in the si_text widget with real data
+        station_data_fill_in( w, (XtPointer)db_station_info_callsign, NULL);
+    }
+    else {
+
+end_critical_section(&db_station_info_lock, "db.c:update_station_info" );
+
+    }
+}
+
+
+
+
+
+/*
+ *  Station Info Selection PopUp window: Canceled
+ */
+void Station_info_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+// We used to close the detailed Station Info dialog here too, which
+// makes no sense.  Commenting this out so that we can close the
+// Station Chooser but leave the Station Info dialog open.
+//
+//    if (db_station_info!=NULL)
+//        Station_data_destroy_shell(db_station_info, db_station_info, NULL);
+
+    XtPopdown(shell);
+    (void)XFreePixmap(XtDisplay(appshell),SiS_icon0);  
+    (void)XFreePixmap(XtDisplay(appshell),SiS_icon);  
+
+begin_critical_section(&db_station_popup_lock, "db.c:Station_info_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    db_station_popup = (Widget)NULL;
+
+end_critical_section(&db_station_popup_lock, "db.c:Station_info_destroy_shell" );
+
+}
+
+
+
+
+
+// Global parameter so that we can pass another value to the below
+// function from the Station_info() function.  We need to be able to
+// pass this value off to the Station_data() function for special
+// operations like moves, where objects are on top of each other.
+//
+XtPointer station_info_select_global = NULL;
+
+
+
+
+
+/*
+ *  Station Info Selection PopUp window: Quit with selected station
+ */
+void Station_info_select_destroy_shell(Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int i,x;
+    char *temp;
+    char temp2[50];
+    XmString *list;
+    int found;
+    //Widget shell = (Widget) clientData;
+
+    found=0;
+
+begin_critical_section(&db_station_popup_lock, "db.c:Station_info_select_destroy_shell" );
+
+    if (db_station_popup) {
+        XtVaGetValues(station_list,XmNitemCount,&i,XmNitems,&list,NULL);
+
+        for (x=1; x<=i;x++) {
+            if (XmListPosSelected(station_list,x)) {
+                found=1;
+                if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&temp))
+                    x=i+1;
+            }
+        }
+
+        // DK7IN ?? should we not first close the PopUp, then call Station_data ??
+        if (found) {
+            xastir_snprintf(temp2, sizeof(temp2), "%s", temp);
+            // Only keep the station info, remove Tactical Call Sign
+            temp2[strcspn(temp2, "(")] = '\0';
+            remove_trailing_spaces(temp2);
+
+            // Call it with the global parameter at the last, so we
+            // can pass special parameters down that we couldn't
+            // directly pass to Station_info_select_destroy_shell().
+            Station_data(widget, temp2, station_info_select_global);
+
+            // Clear the global variable so that nothing else calls
+            // it with the wrong parameter
+            station_info_select_global = NULL;
+
+            XtFree(temp);
+        }
+/*
+        // This section of code gets rid of the Station Chooser.  Frank wanted to
+        // be able to leave the Station Chooser up after selection so that other
+        // stations could be selected, therefore I commented this out.
+        XtPopdown(shell);                   // Get rid of the station chooser popup here
+        (void)XFreePixmap(XtDisplay(appshell),SiS_icon0);
+        (void)XFreePixmap(XtDisplay(appshell),SiS_icon);
+        XtDestroyWidget(shell);             // and here
+        db_station_popup = (Widget)NULL;    // and here
+*/
+    }
+
+end_critical_section(&db_station_popup_lock, "db.c:Station_info_select_destroy_shell" );
+
+}
+
+
+
+
+
+/*
+ *  Station Info PopUp
+ *  if only one station in view it shows the data with Station_data()
+ *  otherwise we get a selection box
+ *  clientData will be non-null if we wish to drop through to the object->modify
+ *  or Assign Tactical Call dialogs.
+ *
+ * clientData: NULL = Station Info
+ *             "1"  = Object -> Modify
+ *             "2"  = Move Object
+ *             "3"  = Assign Tactical Call
+ *             "4"  = Send Message To
+ */
+void Station_info(Widget w, /*@unused@*/ XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station;
+    DataRow *p_found;
+    int num_found = 0;
+    unsigned long min_diff_x, diff_x, min_diff_y, diff_y;
+    XmString str_ptr;
+    unsigned int n;
+    Atom delw;
+    static Widget pane, form, button_ok, button_cancel;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+    char tactical_string[50];
+
+
+    busy_cursor(appshell);
+
+    min_diff_y = scale_y * 20;  // Pixels each way in y-direction.
+    min_diff_x = scale_x * 20;  // Pixels each way in x-direction.
+    p_found = NULL;
+    p_station = n_first;
+
+    // Here we just count them.  We go through the same type of code
+    // again later if we find more than one station.
+    while (p_station != NULL) {    // search through database for nearby stations
+
+        if ( ( (p_station->flag & ST_INVIEW) != 0)
+                && ok_to_draw_station(p_station) ) { // only test stations in view
+
+            if (!altnet || is_altnet(p_station)) {
+
+                // Here we calculate diff in terms of XX pixels,
+                // changed into lat/long values.  This keeps the
+                // affected rectangle the same at any zoom level.
+                // scale_y/scale_x is Xastir units/pixel.  Xastir
+                // units are in 1/100 of a second.  If we want to go
+                // 10 pixels in any direction (roughly, scale_x
+                // varies by latitude), then we want (10 * scale_y),
+                // and (10 * scale_x) if we want to make a very
+                // accurate square.
+
+                diff_y = (unsigned long)( labs((NW_corner_latitude+(menu_y*scale_y))
+                                          - p_station->coord_lat));
+
+                diff_x = (unsigned long)( labs((NW_corner_longitude+(menu_x*scale_x))
+                                          - p_station->coord_lon));
+
+                // If the station fits within our bounding box,
+                // count it 
+                if ((diff_y < min_diff_y) && (diff_x < min_diff_x)) {
+                    p_found = p_station;
+                    num_found++;
+                }
+            }
+        }
+        p_station = p_station->n_next;
+    }
+
+    if (p_found != NULL) {  // We found at least one station
+
+        if (num_found == 1) {
+            // We only found one station, so it's easy
+            Station_data(w,p_found->call_sign,clientData);
+        }
+        else {  // We found more: create dialog to choose a station
+
+            // Set up this global variable so that we can pass it
+            // off to Station_data from the
+            // Station_info_select_destroy_shell() function above.
+            // Without this global variable we don't have enough
+            // parameters passed to the final routine, so we can't
+            // move an object that is on top of another.  With it,
+            // we can.
+            station_info_select_global = clientData;
+
+            if (db_station_popup != NULL)
+                Station_info_destroy_shell(db_station_popup, db_station_popup, NULL);
+
+begin_critical_section(&db_station_popup_lock, "db.c:Station_info" );
+
+            if (db_station_popup == NULL) {
+                // Set up a selection box:
+                db_station_popup = XtVaCreatePopupShell(langcode("STCHO00001"),
+                    xmDialogShellWidgetClass, appshell,
+                    XmNdeleteResponse, XmDESTROY,
+                    XmNdefaultPosition, FALSE,
+                    XmNbackground, colors[0xff],
+                    XmNfontList, fontlist1,
+                    NULL);
+
+                pane = XtVaCreateWidget("Station_info pane",xmPanedWindowWidgetClass, db_station_popup,
+                            XmNbackground, colors[0xff],
+                            NULL);
+
+                form =  XtVaCreateWidget("Station_info form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+                // Attach buttons first to the bottom of the form,
+                // so that we'll be able to stretch this thing
+                // vertically to see all the callsigns.
+                //
+                button_ok = XtVaCreateManagedWidget("Info",xmPushButtonGadgetClass, form,
+                                XmNtopAttachment, XmATTACH_NONE,
+                                XmNbottomAttachment, XmATTACH_FORM,
+                                XmNbottomOffset, 5,
+                                XmNleftAttachment, XmATTACH_POSITION,
+                                XmNleftPosition, 1,
+                                XmNrightAttachment, XmATTACH_POSITION,
+                                XmNrightPosition, 2,
+                                XmNnavigationType, XmTAB_GROUP,
+                                XmNfontList, fontlist1,
+                                NULL);
+
+                button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, form,
+                                    XmNtopAttachment, XmATTACH_NONE,
+                                    XmNbottomAttachment, XmATTACH_FORM,
+                                    XmNbottomOffset, 5,
+                                    XmNleftAttachment, XmATTACH_POSITION,
+                                    XmNleftPosition, 3,
+                                    XmNrightAttachment, XmATTACH_POSITION,
+                                    XmNrightPosition, 4,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                XtAddCallback(button_cancel, XmNactivateCallback, Station_info_destroy_shell, db_station_popup);
+                XtAddCallback(button_ok, XmNactivateCallback, Station_info_select_destroy_shell, db_station_popup);
+
+
+                /*set args for color */
+                ac = 0;
+                XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+                XtSetArg(al[ac], XmNvisibleItemCount, 6); ac++;
+                XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+                XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+                XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+                XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+                XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+                XtSetArg(al[ac], XmNbottomWidget, button_ok); ac++;
+                XtSetArg(al[ac], XmNbottomOffset, 5); ac++;
+                XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+                XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+                XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+                station_list = XmCreateScrolledList(form,"Station_info list",al,ac);
+
+// DK7IN: I want to add the symbol in front of the call...
+        // icon
+        SiS_icon0 = XCreatePixmap(XtDisplay(appshell),RootWindowOfScreen(XtScreen(appshell)),20,20,
+                    DefaultDepthOfScreen(XtScreen(appshell)));
+        SiS_icon  = XCreatePixmap(XtDisplay(appshell),RootWindowOfScreen(XtScreen(appshell)),20,20,
+                    DefaultDepthOfScreen(XtScreen(appshell)));
+/*      SiS_symb  = XtVaCreateManagedWidget("Station_info icon", xmLabelWidgetClass, ob_form1,
+                            XmNlabelType,               XmPIXMAP,
+                            XmNlabelPixmap,             SiS_icon,
+                            XmNbackground,              colors[0xff],
+                            XmNleftAttachment,          XmATTACH_FORM,
+                            XmNtopAttachment,           XmATTACH_FORM,
+                            XmNbottomAttachment,        XmATTACH_NONE,
+                            XmNrightAttachment,         XmATTACH_NONE,
+                            NULL);
+*/
+
+                /*fprintf(stderr,"What station\n");*/
+                n = 1;
+                p_station = n_first;
+                while (p_station != NULL) {    // search through database for nearby stations
+
+                    if ( ( (p_station->flag & ST_INVIEW) != 0)
+                            && ok_to_draw_station(p_station) ) { // only test stations in view
+
+                        if (!altnet || is_altnet(p_station)) {
+
+                            diff_y = (unsigned long)( labs((NW_corner_latitude+(menu_y*scale_y))
+                                                      - p_station->coord_lat));
+
+                            diff_x = (unsigned long)( labs((NW_corner_longitude+(menu_x*scale_x))
+                                                      - p_station->coord_lon));
+
+                            // If the station fits within our
+                            // bounding box, count it.
+                            if ((diff_y < min_diff_y) && (diff_x < min_diff_x)) {
+                                /*fprintf(stderr,"Station %s\n",p_station->call_sign);*/
+				if (p_station->tactical_call_sign) {
+                                    xastir_snprintf(tactical_string, sizeof(tactical_string), "%s (%s)", p_station->call_sign,
+                                                    p_station->tactical_call_sign);
+                                    XmListAddItem(station_list, str_ptr = XmStringCreateLtoR(tactical_string,
+                                        XmFONTLIST_DEFAULT_TAG), (int)n++);
+				} else {
+                                XmListAddItem(station_list, str_ptr = XmStringCreateLtoR(p_station->call_sign,
+                                    XmFONTLIST_DEFAULT_TAG), (int)n++);
+				}
+                                XmStringFree(str_ptr);
+                            }
+                        }
+                    }
+                    p_station = p_station->n_next;
+                }
+
+
+                pos_dialog(db_station_popup);
+
+                delw = XmInternAtom(XtDisplay(db_station_popup),"WM_DELETE_WINDOW", FALSE);
+                XmAddWMProtocolCallback(db_station_popup, delw, Station_info_destroy_shell, (XtPointer)db_station_popup);
+
+                XtManageChild(form);
+                XtManageChild(station_list);
+                XtVaSetValues(station_list, XmNbackground, colors[0x0f], NULL);
+                XtManageChild(pane);
+
+                XtPopup(db_station_popup,XtGrabNone);
+
+                // Move focus to the Cancel button.  This appears to highlight t
+                // button fine, but we're not able to hit the <Enter> key to
+                // have that default function happen.  Note:  We _can_ hit the
+                // <SPACE> key, and that activates the option.
+                XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+            }
+
+end_critical_section(&db_station_popup_lock, "db.c:Station_info" );
+
+        }
+    }
+}
+
+
+
+
+
+int heard_via_tnc_in_past_hour(char *call) {
+    DataRow *p_station;
+    int in_hour;
+
+    in_hour=0;
+    if (search_station_name(&p_station,call,1)) {  // find call
+
+        // Check the heard_via_tnc_last_time timestamp.  This is a
+        // timestamp that is saved each time a station is heard via
+        // RF.  It is initially set to 0.  It does not get reset
+        // when a packet comes in via a non-TNC interface.
+        //
+        if (p_station->heard_via_tnc_last_time) {   // non-zero entry
+
+            // Should we check to see if the last packet was message
+            // capable?
+
+            // Decide whether it was heard on a TNC interface within
+            // the hour
+            in_hour = (int)((p_station->heard_via_tnc_last_time+3600l) > sec_now());
+
+            if(debug_level & 2)
+                fprintf(stderr, "Call %s: %ld %ld ok %d\n",
+                    call,
+                    (long)(p_station->heard_via_tnc_last_time),
+                    (long)sec_now(),
+                    in_hour);
+
+        }
+        else {
+            if (debug_level & 2)
+                fprintf(stderr,"Call %s Not heard via tnc\n",call);
+        }
+    }
+    else {
+        if (debug_level & 2)
+            fprintf(stderr,"IG:station not found\n");
+    }
+    return(in_hour);
+}
+
+
+
+
+
+//////////////////////////////////// Weather Data //////////////////////////////////////////////////
+
+
+
+
+
+/* valid characters for APRS weather data fields */
+int is_aprs_chr(char ch) {
+
+    if (isdigit((int)ch) || ch==' ' || ch=='.' || ch=='-')
+    return(1);
+    else
+    return(0);
+}
+
+
+
+
+
+int count_filler_chars(char ch) {
+
+    if (isdigit((int)ch) || ch==' ' || ch=='.' || ch=='-')
+    return(1);
+    else
+    return(0);
+}
+
+
+
+
+
+/* check data format    123 ___ ... */
+// We wish to count how many ' ' or '.' characters we find.  If it
+// equals zero or the field width, it might be a weather field.  If
+// not, then it might be part of a comment field or something else.
+//
+int is_weather_data(char *data, int len) {
+    int ok = 1;
+    int i;
+    int count = 0;
+
+    for (i=0;ok && i<len;i++)
+        if (!is_aprs_chr(data[i]))
+            ok = 0;
+
+    // Count filler characters.  Must equal zero or field width to
+    // be a weather field.  There doesn't appear to be a case where
+    // a single period is allowed in any weather-related fields.
+    //
+    for (i=0;ok && i<len;i++) {
+        if (data[i] == ' ' || data[i] == '.') {
+            count++;
+        }
+    }
+    if (count != 0 && count != len) {
+        ok = 0;
+    }
+
+    return(ok);
+}
+
+
+
+
+
+// Extract single weather data item from "data".  Returns it in
+// "temp".  Modifies "data" to remove the found data from the
+// string.  Returns a 1 if found, 0 if not found.
+//
+// PE1DNN
+// If the item is contained in the string but does not contain a
+// value then regard the item as "not found" in the weather string.
+//
+int extract_weather_item(char *data, char type, int datalen, char *temp) {
+    int i,ofs,found,len;
+
+
+//fprintf(stderr,"%s\n",data);
+
+    found=0;
+    len = (int)strlen(data);
+    for(ofs=0; !found && ofs<len-datalen; ofs++)      // search for start sequence
+        if (data[ofs]==type) {
+            found=1;
+            if (!is_weather_data(data+ofs+1, datalen))
+                found=0;
+        }
+    if (found) {   // ofs now points after type character
+        substr(temp,data+ofs,datalen);
+        for (i=ofs-1;i<len-datalen;i++)        // delete item from info field
+            data[i] = data[i+datalen+1];
+        if((temp[0] == ' ') || (temp[0] == '.')) {
+            // found it, but it doesn't contain a value!
+            // Clean up and report "not found" - PE1DNN
+            temp[0] = '\0';
+            found = 0;
+        }
+        else
+        {
+            if (debug_level & 2) {
+                fprintf(stderr,"extract_weather_item: %s\n",temp);
+            }
+        }
+    }
+    else
+        temp[0] = '\0';
+    return(found);
+}
+
+
+
+
+
+// test-extract single weather data item from information field.  In
+// other words:  Does not change the input string, but does test
+// whether the data is present.  Returns a 1 if found, 0 if not
+// found.
+//
+// PE1DNN
+// If the item is contained in the string but does not contain a
+// value then regard the item as "not found" in the weather string.
+//
+int test_extract_weather_item(char *data, char type, int datalen) {
+    int ofs,found,len;
+
+    found=0;
+    len = (int)strlen(data);
+    for(ofs=0; !found && ofs<len-datalen; ofs++)      // search for start sequence
+        if (data[ofs]==type) {
+            found=1;
+            if (!is_weather_data(data+ofs+1, datalen))
+                found=0;
+        }
+
+    // We really should test for numbers here (with an optional
+    // leading '-'), and test across the length of the substring.
+    //
+    if(found && ((data[ofs+1] == ' ') || (data[ofs+1] == '.'))) {
+        // found it, but it doesn't contain a value!
+        // report "not found" - PE1DNN
+        found = 0;
+    }
+
+    //fprintf(stderr,"test_extract: %c %d\n",type,found);
+    return(found);
+}
+
+
+
+
+
+// DK7IN 77
+// raw weather report            in information field
+// positionless weather report   in information field
+// complete weather report       with lat/lon
+//  see APRS Reference page 62ff
+//
+// Added 'F' for Fuel Temp and 'f' for Fuel Moisture in order to
+// decode these two new parameters used for RAWS weather station
+// objects.
+//
+// By the time we call this function we've already extracted any
+// time/position info at the beginning of the string.
+//
+int extract_weather(DataRow *p_station, char *data, int compr) {
+    char time_data[MAX_TIME];
+    char temp[5];
+    int  ok = 1;
+    WeatherRow *weather;
+    char course[4];
+    char speed[4];
+    int in_knots = 0;
+
+//WE7U
+// Try copying the string to a temporary string, then do some
+// extractions to see if a few weather items are present?  This
+// would allow us to have the weather items in any order, and if
+// enough of them were present, we consider it to be a weather
+// packet?  We'd need to qualify all of the data to make sure we had
+// the proper number of digits for each.  The trick is to make sure
+// we don't decide it's a weather packet if it's not.  We don't know
+// what people might send in packets in the future.
+
+    if (compr) {        // compressed position report
+        // Look for weather data in fixed locations first
+        if (strlen(data) >= 8
+                && data[0] =='g' && is_weather_data(&data[1],3)
+                && data[4] =='t' && is_weather_data(&data[5],3)) {
+
+            // Snag WX course/speed from compressed position data.
+            // This speed is in knots.  This assumes that we've
+            // already extracted speed/course from the compressed
+            // packet.  extract_comp_position() extracts
+            // course/speed as well.
+            xastir_snprintf(speed,
+                sizeof(speed),
+                "%s",
+                p_station->speed);
+            xastir_snprintf(course,
+                sizeof(course),
+                "%s",
+                p_station->course);
+            in_knots = 1;
+
+            //fprintf(stderr,"Found compressed wx\n");
+        }
+        // Look for weather data in non-fixed locations (RAWS WX
+        // Stations?)
+        else if ( strlen(data) >= 8
+                && test_extract_weather_item(data,'g',3)
+                && test_extract_weather_item(data,'t',3) ) {
+
+            // Snag WX course/speed from compressed position data.
+            // This speed is in knots.  This assumes that we've
+            // already extracted speed/course from the compressed
+            // packet.  extract_comp_position() extracts
+            // course/speed as well.
+            xastir_snprintf(speed,
+                sizeof(speed),
+                "%s",
+                p_station->speed);
+            xastir_snprintf(course,
+                sizeof(course),
+                "%s",
+                p_station->course);
+            in_knots = 1;
+
+            //fprintf(stderr,"Found compressed WX in non-fixed locations! %s:%s\n",
+            //    p_station->call_sign,data);
+
+        }
+        else {  // No weather data found
+            ok = 0;
+
+            //fprintf(stderr,"No compressed wx\n");
+        }
+    }
+    else {    // Look for non-compressed weather data
+        // Look for weather data in defined locations first
+        if (strlen(data)>=15 && data[3]=='/'
+                && is_weather_data(data,3) && is_weather_data(&data[4],3)
+                && data[7] =='g' && is_weather_data(&data[8], 3)
+                && data[11]=='t' && is_weather_data(&data[12],3)) {    // Complete Weather Report
+
+            // Get speed/course.  Speed is in knots.
+            (void)extract_speed_course(data,speed,course);
+            in_knots = 1;
+
+            // Either one not found?  Try again.
+            if ( (speed[0] == '\0') || (course[0] == '\0') ) {
+
+                // Try to get speed/course from 's' and 'c' fields
+                // (another wx format).  Speed is in mph.
+                (void)extract_weather_item(data,'c',3,course); // wind direction (in degrees)
+                (void)extract_weather_item(data,'s',3,speed);  // sustained one-minute wind speed (in mph)
+                in_knots = 0;
+            }
+
+            //fprintf(stderr,"Found Complete Weather Report\n");
+        }
+        // Look for date/time and weather in fixed locations first
+        else if (strlen(data)>=16
+                && data[0] =='c' && is_weather_data(&data[1], 3)
+                && data[4] =='s' && is_weather_data(&data[5], 3)
+                && data[8] =='g' && is_weather_data(&data[9], 3)
+                && data[12]=='t' && is_weather_data(&data[13],3)) { // Positionless Weather Data
+//fprintf(stderr,"Found positionless wx data\n");
+            // Try to snag speed/course out of first 7 bytes.  Speed
+            // is in knots.
+            (void)extract_speed_course(data,speed,course);
+            in_knots = 1;
+
+            // Either one not found?  Try again.
+            if ( (speed[0] == '\0') || (course[0] == '\0') ) {
+//fprintf(stderr,"Trying again for course/speed\n");
+                // Also try to get speed/course from 's' and 'c' fields
+                // (another wx format)
+                (void)extract_weather_item(data,'c',3,course); // wind direction (in degrees)
+                (void)extract_weather_item(data,'s',3,speed);  // sustained one-minute wind speed (in mph)
+                in_knots = 0;
+            }
+
+            //fprintf(stderr,"Found weather\n");
+        }
+        // Look for weather data in non-fixed locations (RAWS WX
+        // Stations?)
+        else if (strlen (data) >= 16
+                && test_extract_weather_item(data,'h',2)
+                && test_extract_weather_item(data,'g',3)
+                && test_extract_weather_item(data,'t',3) ) {
+
+            // Try to snag speed/course out of first 7 bytes.  Speed
+            // is in knots.
+            (void)extract_speed_course(data,speed,course);
+            in_knots = 1;
+
+            // Either one not found?  Try again.
+            if ( (speed[0] == '\0') || (course[0] == '\0') ) {
+
+                // Also try to get speed/course from 's' and 'c' fields
+                // (another wx format)
+                (void)extract_weather_item(data,'c',3,course); // wind direction (in degrees)
+                (void)extract_weather_item(data,'s',3,speed);  // sustained one-minute wind speed (in mph)
+                in_knots = 0;
+            }
+ 
+            //fprintf(stderr,"Found WX in non-fixed locations!  %s:%s\n",
+            //    p_station->call_sign,data);
+        }
+        else {  // No weather data found
+            ok = 0;
+
+            //fprintf(stderr,"No wx found\n");
+        }
+    }
+
+    if (ok) {
+        ok = get_weather_record(p_station);     // get existing or create new weather record
+    }
+
+    if (ok) {
+        weather = p_station->weather_data;
+
+        // Copy into weather speed variable.  Convert knots to mph
+        // if necessary.
+        if (in_knots) {
+            xastir_snprintf(weather->wx_speed,
+                sizeof(weather->wx_speed),
+                "%03.0f",
+                atoi(speed) * 1.1508);  // Convert knots to mph
+        }
+        else {
+            // Already in mph.  Copy w/no conversion.
+            xastir_snprintf(weather->wx_speed,
+                sizeof(weather->wx_speed),
+                "%s",
+                speed);
+        }
+
+        xastir_snprintf(weather->wx_course,
+            sizeof(weather->wx_course),
+            "%s",
+            course);
+
+        if (compr) {        // course/speed was taken from normal data, delete that
+            // fix me: we delete a potential real speed/course now
+            // we should differentiate between normal and weather data in compressed position decoding...
+//            p_station->speed_time[0]     = '\0';
+            p_station->speed[0]          = '\0';
+            p_station->course[0]         = '\0';
+        }
+
+        (void)extract_weather_item(data,'g',3,weather->wx_gust);      // gust (peak wind speed in mph in the last 5 minutes)
+
+        (void)extract_weather_item(data,'t',3,weather->wx_temp);      // temperature (in deg Fahrenheit), could be negative
+
+        (void)extract_weather_item(data,'r',3,weather->wx_rain);      // rainfall (1/100 inch) in the last hour
+
+        (void)extract_weather_item(data,'p',3,weather->wx_prec_24);   // rainfall (1/100 inch) in the last 24 hours
+
+        (void)extract_weather_item(data,'P',3,weather->wx_prec_00);   // rainfall (1/100 inch) since midnight
+
+        if (extract_weather_item(data,'h',2,weather->wx_hum))         // humidity (in %, 00 = 100%)
+                xastir_snprintf(weather->wx_hum, sizeof(weather->wx_hum), "%03d",(atoi(weather->wx_hum)+99)%100+1);
+
+        if (extract_weather_item(data,'b',5,weather->wx_baro))  // barometric pressure (1/10 mbar / 1/10 hPascal)
+            xastir_snprintf(weather->wx_baro,
+                sizeof(weather->wx_baro),
+                "%0.1f",
+                (float)(atoi(weather->wx_baro)/10.0));
+
+        // If we parsed a speed/course, a second 's' parameter means
+        // snowfall.  Try to parse it, but only in the case where
+        // we've parsed speed out of this packet already.
+        if ( (speed[0] != '\0') && (course[0] != '\0') ) {
+            (void)extract_weather_item(data,'s',3,weather->wx_snow);      // snowfall, inches in the last 24 hours
+        }
+
+        (void)extract_weather_item(data,'L',3,temp);                  // luminosity (in watts per square meter) 999 and below
+
+        (void)extract_weather_item(data,'l',3,temp);                  // luminosity (in watts per square meter) 1000 and above
+
+        (void)extract_weather_item(data,'#',3,temp);                  // raw rain counter
+
+        (void)extract_weather_item(data,'F',3,weather->wx_fuel_temp); // Fuel Temperature in �F (RAWS)
+
+        if (extract_weather_item(data,'f',2,weather->wx_fuel_moisture))// Fuel Moisture (RAWS) (in %, 00 = 100%)
+            xastir_snprintf(weather->wx_fuel_moisture,
+                sizeof(weather->wx_fuel_moisture),
+                "%03d",
+                (atoi(weather->wx_fuel_moisture)+99)%100+1);
+
+//    extract_weather_item(data,'w',3,temp);                          // ?? text wUII
+
+    // now there should be the name of the weather station...
+
+        // Create a timestamp from the current time
+        xastir_snprintf(weather->wx_time,
+            sizeof(weather->wx_time),
+            "%s",
+            get_time(time_data));
+
+        // Set the timestamp in the weather record so that we can
+        // decide whether or not to "ghost" the weather data later.
+        weather->wx_sec_time=sec_now();
+//        weather->wx_data=1;  // we don't need this
+
+//        case ('.'):/* skip */
+//            wx_strpos+=4;
+//            break;
+
+//        default:
+//            wx_done=1;
+//            weather->wx_type=data[wx_strpos];
+//            if(strlen(data)>wx_strpos+1)
+//                xastir_snprintf(weather->wx_station,    
+//                    sizeof(weather->wx_station),
+//                    "%s",
+//                    data+wx_strpos+1);
+//            break;
+    }
+    return(ok);
+}
+
+
+
+
+
+// Initial attempt at decoding tropical storm, tropical depression,
+// and hurricane data.
+//
+// This data can be in an Object report, but can also be in an Item
+// or position report.
+// "/TS" = Tropical Storm
+// "/HC" = Hurricane
+// "/TD" = Tropical Depression
+// "/TY" = Typhoon
+// "/ST" = Super Typhoon
+// "/SC" = Severe Cyclone
+
+// The symbol will be either "\@" for current position, or "/@" for
+// predicted position.
+//
+int extract_storm(DataRow *p_station, char *data, int compr) {
+    char time_data[MAX_TIME];
+    int  ok = 1;
+    WeatherRow *weather;
+    char course[4];
+    char speed[4];  // Speed in knots
+    char *p, *p2;
+
+
+// Should probably encode the storm type in the weather object and
+// print it out in plain text in the Station Info dialog.
+
+    if ((p = strstr(data, "/TS")) != NULL) {
+        // We have a Tropical Storm
+//fprintf(stderr,"Tropical Storm! %s\n",data);
+    }
+    else if ((p = strstr(data, "/TD")) != NULL) {
+        // We have a Tropical Depression
+//fprintf(stderr,"Tropical Depression! %s\n",data);
+    }
+    else if ((p = strstr(data, "/HC")) != NULL) {
+        // We have a Hurricane
+//fprintf(stderr,"Hurricane! %s\n",data);
+    }
+    else if ((p = strstr(data, "/TY")) != NULL) {
+        // We have a Typhoon
+//fprintf(stderr,"Hurricane! %s\n",data);
+    }
+    else if ((p = strstr(data, "/ST")) != NULL) {
+        // We have a Super Typhoon
+//fprintf(stderr,"Hurricane! %s\n",data);
+    }
+    else if ((p = strstr(data, "/SC")) != NULL) {
+        // We have a Severe Cyclone
+//fprintf(stderr,"Hurricane! %s\n",data);
+    }
+    else {  // Not one of the three we're trying to decode
+        ok = 0;
+        return(ok);
+    }
+
+//fprintf(stderr,"\n%s\n",data);
+
+    // Back up 7 spots to try to extract the next items
+    p2 = p - 7;
+    if (p2 >= data) {
+        // Attempt to extract course/speed.  Speed in knots.
+        if (!extract_speed_course(p2,speed,course)) {
+            // No speed/course to extract
+//fprintf(stderr,"No speed/course found\n");
+            ok = 0;
+            return(ok);
+        }
+    }
+    else {  // Not enough characters for speed/course.  Must have
+            // guessed wrong on what type of data it is.
+//fprintf(stderr,"No speed/course found 2\n");
+        ok = 0;
+        return(ok);
+    }
+
+
+//fprintf(stderr,"%s\n",data);
+
+    if (ok) {
+
+        // If we got this far, we have speed/course and know what type
+        // of storm it is.
+//fprintf(stderr,"Speed: %s, Course: %s\n",speed,course);
+
+        ok = get_weather_record(p_station);     // get existing or create new weather record
+    }
+
+    if (ok) {
+//        p_station->speed_time[0]     = '\0';
+
+        p_station->weather_data->wx_storm = 1;  // We found a storm
+
+        // Note that speed is in knots.  If we were stuffing it into
+        // "wx_speed" we'd have to convert it to MPH.
+        if (strcmp(speed,"   ") != 0 && strcmp(speed,"...") != 0) {
+            xastir_snprintf(p_station->speed,
+                sizeof(p_station->speed),
+                "%s",
+                speed);
+        }
+        else {
+            p_station->speed[0] = '\0';
+        }
+
+        if (strcmp(course,"   ") != 0 && strcmp(course,"...") != 0)
+            xastir_snprintf(p_station->course,
+                sizeof(p_station->course),
+                "%s",
+                course);
+        else
+            p_station->course[0] = '\0';
+ 
+        weather = p_station->weather_data;
+ 
+        p2++;   // Skip the description text, "/TS", "/HC", "/TD", "/TY", "/ST", or "/SC"
+
+        // Extract the sustained wind speed in knots
+        if(extract_weather_item(p2,'/',3,weather->wx_speed))
+            // Convert from knots to MPH
+            xastir_snprintf(weather->wx_speed,
+                sizeof(weather->wx_speed),
+                "%0.1f",
+                (float)(atoi(weather->wx_speed)) * 1.1508);
+
+//fprintf(stderr,"%s\n",data);
+
+        // Extract gust speed in knots
+        if (extract_weather_item(p2,'^',3,weather->wx_gust)) // gust (peak wind speed in knots)
+            // Convert from knots to MPH
+            xastir_snprintf(weather->wx_gust,
+                sizeof(weather->wx_gust),
+                "%0.1f",
+                (float)(atoi(weather->wx_gust)) * 1.1508);
+
+//fprintf(stderr,"%s\n",data);
+
+        // Pressure is already in millibars/hPa.  No conversion
+        // needed.
+        if (extract_weather_item(p2,'/',4,weather->wx_baro))  // barometric pressure (1/10 mbar / 1/10 hPascal)
+            xastir_snprintf(weather->wx_baro,
+                sizeof(weather->wx_baro),
+                "%0.1f",
+                (float)(atoi(weather->wx_baro)));
+
+//fprintf(stderr,"%s\n",data);
+
+        (void)extract_weather_item(p2,'>',3,weather->wx_hurricane_radius); // Nautical miles
+
+//fprintf(stderr,"%s\n",data);
+
+        (void)extract_weather_item(p2,'&',3,weather->wx_trop_storm_radius); // Nautical miles
+
+//fprintf(stderr,"%s\n",data);
+
+        (void)extract_weather_item(p2,'%',3,weather->wx_whole_gale_radius); // Nautical miles
+
+//fprintf(stderr,"%s\n",data);
+
+        // Create a timestamp from the current time
+        xastir_snprintf(weather->wx_time,
+            sizeof(weather->wx_time),
+            "%s",
+            get_time(time_data));
+
+        // Set the timestamp in the weather record so that we can
+        // decide whether or not to "ghost" the weather data later.
+        weather->wx_sec_time=sec_now();
+    }
+    return(ok);
+}
+
+
+
+
+
+/*
+ * Look for information about other points associated with this station.
+ * If found, compute the coordinates and save the information in the
+ * station structure.
+ * KG4NBB
+ */
+// If remove_string == 0, don't remove the string from the comment
+// field.  Useful for objects/items where we need to retransmit the
+// string unchanged.
+
+#define MULTI_DEBUG 2048
+#define LBRACE '{'
+#define RBRACE '}'
+#define START_STR " }"
+
+static void extract_multipoints(DataRow *p_station,
+        char *data,
+        int type,
+        int remove_string) {
+    // If they're in there, the multipoints start with the
+    // sequence <space><rbrace><lower><digit> and end with a <lbrace>.
+    // In addition, there must be no spaces in there, and there
+    // must be an even number of characters (after the lead-in).
+
+    char *p, *p2;
+    int found = 0;
+    char *end;
+    int data_size;
+
+
+    if (debug_level & MULTI_DEBUG)
+        fprintf(stderr,"extract_multipoints: start processing %s\n",
+                p_station->call_sign);
+
+    if (data == NULL) {
+        if (debug_level & MULTI_DEBUG)
+            fprintf(stderr,"extract_multipoints: No Data, returning\n");
+        return;
+    }
+
+    if (debug_level & MULTI_DEBUG)
+        fprintf(stderr,"Data: %s\t\t\n", data);
+
+    data_size = strlen(data);
+
+    end = data + (strlen(data) - 7);  // 7 == 3 lead-in chars, plus 2 points
+ 
+    p_station->num_multipoints = 0;
+
+    /*
+    for (p = data; !found && p <= end; ++p) {
+        if (*p == ' ' && *(p+1) == RBRACE && islower((int)*(p+2)) && isdigit((int)*(p+3)) && 
+                            (p2 = strchr(p+4, LBRACE)) != NULL && ((p2 - p) % 2) == 1) {
+            found = 1;
+        }
+    }
+    */
+
+    // Start looking at the beginning of the data.
+
+    p = data;
+
+    if (debug_level & MULTI_DEBUG) {
+        if (strstr(p,START_STR) == NULL)
+            fprintf(stderr," Data does not start with space-brace, it starts with %c%c\n", p[0],p[1]);
+        else
+            fprintf(stderr," Data starts with space-brace\n");
+    }
+
+    // Look for the opening string.
+
+    while (!found && p < end && (p = strstr(p, START_STR)) != NULL) {
+        // The opening string was found. Check the following information.
+        if (debug_level & MULTI_DEBUG) 
+            fprintf(stderr,"  Found opening brace, next chars are %c %c %c\n",
+                    *(p+2),*(p+3),*(p+4));
+
+        if (islower((int)*(p+2)) && isdigit((int)*(p+3)) && (p2 = strchr(p+4, LBRACE)) != NULL && ((p2 - p) % 2) == 1) {
+            // It all looks good!
+
+            found = 1;
+        }
+        else {
+            // The following characters are not right. Advance and
+            // look again.
+            if (debug_level & MULTI_DEBUG) 
+                fprintf(stderr,"  Found opening string (}) but next characters are not right: %c %c %c\n",*(p+2),*(p+3),*(p+4));
+            ++p;
+        }
+    }
+
+    if (found) {
+        long multiplier;
+        double d;
+        char *m_start = p;    // Start of multipoint string
+        char ok = 1;
+ 
+        if (debug_level & MULTI_DEBUG)
+            fprintf(stderr,"station %s contains \"%s\"\n", p_station->call_sign, p);
+
+        // The second character (the lowercase) indicates additional style information,
+        // such as color, line type, etc.
+
+        p_station->style = *(p+2);
+
+        // The third character (the digit) indicates the way the points should be
+        // used. They may be used to draw a closed polygon, a series of line segments,
+        // etc.
+
+        p_station->type = *(p+3);
+
+        // The fourth character indicates the scale of the coordinates that
+        // follow. It may range from '!' to '|' (124). The value represents the
+        // unit of measure (1, 0.1, 0.001, etc., in degrees) used in the offsets.
+        //
+        // Use the following formula to convert the char to the value:
+        // (10 ^ ((c - 33) / 20)) / 10000 degrees
+        //
+        // Finally we have to convert to Xastir units. Xastir stores coordinates
+        // as hudredths of seconds. There are 360,000 of those per degree, so we
+        // need to multiply by that factor so our numbers will be converted to
+        // Xastir units.
+
+        p = p + 4;
+
+        if (*p < '!' || *p > '|') {
+            fprintf(stderr,"extract_multipoints: invalid scale character %d\n", *p);
+            ok = 0; // Failure
+        }
+        else {
+
+            d = (double)(*p);
+            d = pow(10.0, ((d - 33) / 20)) / 10000.0 * 360000.0;
+            multiplier = (long)d;
+            if (debug_level & MULTI_DEBUG)
+                fprintf(stderr,"    multiplier factor is: %c %d %f (%ld)\n", *p, *p, d, multiplier);
+
+            ++p;
+
+            // The remaining characters are in pairs. Each pair is the
+            // offset lat and lon for one of the points. (The offset is
+            // from the actual location of the object.) Convert each
+            // character to its numeric value and save it.
+
+            while (*p != LBRACE && p_station->num_multipoints < MAX_MULTIPOINTS) {
+                // The characters are in the range '"' (34 decimal) to 'z' (122). They
+                // encode values in the range -44 to +44. To convert to the correct
+                // value 78 is subtracted from the character's value.
+
+                int lat_val = *p - 78;
+                int lon_val = *(p+1) - 78;
+
+                // Check for correct values.
+
+                if (lon_val < -44 || lon_val > 44 || lat_val < -44 || lat_val > 44) {
+                    char temp[MAX_LINE_SIZE+1];
+                    int i;
+
+                    // Filter the string so we don't send strange
+                    // chars to the xterm
+                    for (i = 0; i < (int)strlen(data); i++) {
+                        temp[i] = data[i] & 0x7f;
+                        if ( (temp[i] < 0x20) || (temp[i] > 0x7e) )
+                            temp[i] = ' ';
+                    }
+                    temp[strlen(data)] = '\0';
+                    
+                    fprintf(stderr,"extract_multipoints: invalid value in (filtered) \"%s\": %d,%d\n",
+                        temp,
+                        lat_val,
+                        lon_val);
+
+                    p_station->num_multipoints = 0;     // forget any points we already set
+                    ok = 0; // Failure to decode
+                    break;
+                }
+
+                // Malloc the storage area for this if we don't have
+                // it yet.
+                if (p_station->multipoint_data == NULL) {
+//fprintf(stderr, "Malloc'ing MultipointRow record, %s\n", p_station->call_sign);
+                    p_station->multipoint_data = malloc(sizeof(MultipointRow));
+                    if (p_station->multipoint_data == NULL) {
+                        p_station->num_multipoints = 0;
+                        fprintf(stderr,"Couldn't malloc MultipointRow'\n");
+                        if (debug_level & MULTI_DEBUG)
+                            fprintf(stderr,"extract_multipoints: Malloc failure, returning\n");
+                        return;
+                    }
+                }
+ 
+                if (debug_level & MULTI_DEBUG)
+                    fprintf(stderr,"computed offset %d,%d\n", lat_val, lon_val);
+
+                // Add the offset to the object's position to obtain the position of the point.
+                // Note that we're working in Xastir coordinates, and in North America they
+                // are exactly opposite to lat/lon (larger numbers are farther east and south).
+                // An offset with a positive value means that the point should be north and/or
+                // west of the object, so we have to *subtract* the offset to get the correct
+                // placement in Xastir coordinates.
+                // TODO: Consider what we should do in the other geographic quadrants. Should we
+                // check here for the correct sign of the offset? Or should the program that
+                // creates the offsets take that into account?
+
+                p_station->multipoint_data->multipoints[p_station->num_multipoints][0]
+                    = p_station->coord_lon - (lon_val * multiplier);
+                p_station->multipoint_data->multipoints[p_station->num_multipoints][1]
+                    = p_station->coord_lat - (lat_val * multiplier);
+
+                if (debug_level & MULTI_DEBUG)
+                    fprintf(stderr,
+                        "computed point %ld, %ld\n",
+                        p_station->multipoint_data->multipoints[p_station->num_multipoints][0],
+                        p_station->multipoint_data->multipoints[p_station->num_multipoints][1]);
+                p += 2;
+                ++p_station->num_multipoints;
+            }   // End of while loop
+        }
+
+        if (ok && remove_string) {
+            // We've successfully decoded a multipoint object?
+            // Remove the multipoint strings (and the sequence
+            // number at the end if present) from the data string.
+            // m_start points to the first character (a space).  'p'
+            // should be pointing at the LBRACE character.
+
+            // Make 'p' point to just after the end of the chars
+            while ( (p < data+strlen(data)) && (*p != ' ') ) {
+               p++;
+            }
+            // The string that 'p' points to now may be empty
+
+            // Truncate "data" at the starting brace - 1
+            *m_start = '\0';
+
+            // Now we have two strings inside "data".  Copy the 2nd
+            // string directly onto the end of the first.
+            strncat(data, p, data_size+1);
+
+            // The multipoint string and sequence number should be
+            // erased now from "data".
+//fprintf(stderr,"New Data: %s\n", data);
+        }
+
+        if (debug_level & MULTI_DEBUG)
+            fprintf(stderr,"    station has %d points\n", p_station->num_multipoints);
+    }
+
+    if (debug_level & MULTI_DEBUG)
+        fprintf(stderr,"extract_multipoints: Normal Return\n");
+}
+
+#undef MULTI_DEBUG
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+void init_weather(WeatherRow *weather) {    // clear weather data
+
+    weather->wx_sec_time             = (time_t)0;
+    weather->wx_storm                = 0;
+    weather->wx_time[0]              = '\0';
+    weather->wx_course[0]            = '\0';
+    weather->wx_speed[0]             = '\0';
+    weather->wx_speed_sec_time       = 0; // ??
+    weather->wx_gust[0]              = '\0';
+    weather->wx_hurricane_radius[0]  = '\0';
+    weather->wx_trop_storm_radius[0] = '\0';
+    weather->wx_whole_gale_radius[0] = '\0';
+    weather->wx_temp[0]              = '\0';
+    weather->wx_rain[0]              = '\0';
+    weather->wx_rain_total[0]        = '\0';
+    weather->wx_snow[0]              = '\0';
+    weather->wx_prec_24[0]           = '\0';
+    weather->wx_prec_00[0]           = '\0';
+    weather->wx_hum[0]               = '\0';
+    weather->wx_baro[0]              = '\0';
+    weather->wx_fuel_temp[0]         = '\0';
+    weather->wx_fuel_moisture[0]     = '\0';
+    weather->wx_type                 = '\0';
+    weather->wx_station[0]           = '\0';
+}
+
+
+
+
+
+int get_weather_record(DataRow *fill) {    // get or create weather storage
+    int ok=1;
+
+    if (fill->weather_data == NULL) {      // new weather data, allocate storage and init
+        fill->weather_data = malloc(sizeof(WeatherRow));
+        if (fill->weather_data == NULL) {
+            fprintf(stderr,"Couldn't allocate memory in get_weather_record()\n");
+            ok = 0;
+        }
+        else {
+            init_weather(fill->weather_data);
+        }
+    }
+    return(ok);
+}
+
+
+
+
+
+int delete_weather(DataRow *fill) {    // delete weather storage, if allocated
+
+    if (fill->weather_data != NULL) {
+        free(fill->weather_data);
+        fill->weather_data = NULL;
+        return(1);
+    }
+    return(0);
+}
+
+
+
+
+
+int delete_multipoints(DataRow *fill) { // delete multipoint storage, if allocated
+
+    if (fill->multipoint_data != NULL) {
+//fprintf(stderr,"Removing multipoint data, %s\n", fill->call_sign);
+        free(fill->multipoint_data);
+        fill->multipoint_data = NULL;
+        fill->num_multipoints = 0;
+        return(1);
+    }
+    return(0);
+}
+
+
+
+////////////////////////////////////////// Trails //////////////////////////////////////////////////
+
+
+
+/*
+ *  See if current color is defined as active trail color
+ */
+int trail_color_active(int color_index) {
+
+    // this should be made configurable...
+    // to select trail colors to use
+    
+    return(1);          // accept this color
+}
+
+
+
+
+
+/*
+ *  Get new trail color for a call
+ */
+int new_trail_color(char *call) {
+    int color, found, i;
+
+    // If my_trail_diff_color is set a 0, then we'll
+    // assign one color to every SSID from our callsign.  If
+    // 1, they get the next color available (round-robin style) just
+    // like all the other stations.
+    //
+    // 0 for last parameter in is_my_call() means skip SSID in
+    // callsign check.  Non-zero means the callsign + SSID must be
+    // an exact match.
+    if (is_my_call(call,my_trail_diff_color)) {
+        color = MY_TRAIL_COLOR;    // It's my call, so use special color
+    }
+    else {
+        // all other callsigns get some other color out of the color table
+        color = current_trail_color;
+        for(i=0,found=0;!found && i<MAX_TRAIL_COLORS;i++) {
+            color = (color + 1) % MAX_TRAIL_COLORS; // try next color in list
+            // skip special and or inactive colors.
+            if (color != MY_TRAIL_COLOR && trail_color_active(color))
+                found = 1;
+        }
+        if (found)
+            current_trail_color = color;        // save it for next time
+        else
+            color = current_trail_color;        // keep old color
+    }
+    return(color);
+}
+
+
+
+
+
+//
+// Store one trail point.  Allocate storage for the new data.
+//
+// We now store track data in a doubly-linked list.  Each record has a
+// pointer to the previous and the next record in the list.  The main
+// station record has a pointer to the oldest and the newest end of the
+// chain, and the chain can be traversed in either order.
+//
+int store_trail_point(DataRow *p_station,
+                      long lon,
+                      long lat,
+                      time_t sec,
+                      char *alt,
+                      char *speed,
+                      char *course,
+                      short stn_flag) {
+
+    char flag;
+    TrackRow *ptr;
+
+    //fprintf(stderr,"store_trail_point: %s\n",p_station->call_sign);
+
+    if (debug_level & 256) {
+        fprintf(stderr,"store_trail_point: for %s\n", p_station->call_sign);
+    }
+
+    // Allocate storage for the new track point
+    ptr = malloc(sizeof(TrackRow));
+    if (ptr == NULL) {
+        if (debug_level & 256) {
+            fprintf(stderr,"store_trail_point: MALLOC failed for trail.\n");
+        }
+        return(0); // Failed due to malloc
+    }
+ 
+    // Check whether we have any track data saved
+    if (p_station->newest_trackpoint == NULL) {
+        // new trail, do initialization
+
+        if (debug_level & 256) {
+            fprintf(stderr,"Creating new trail.\n");
+        }
+        tracked_stations++;
+
+        // Assign a new trail color 'cuz it's a new trail
+        p_station->trail_color = new_trail_color(p_station->call_sign);
+    }
+
+    // Start linking the record to the new end of the chain
+    ptr->prev = p_station->newest_trackpoint;   // Link to record or NULL
+    ptr->next = NULL;   // Newest end of chain
+
+    // Have an older record already?
+    if (p_station->newest_trackpoint != NULL) { // Yes
+        p_station->newest_trackpoint->next = ptr;
+    }
+    else {  // No, this is our first record
+        p_station->oldest_trackpoint = ptr;
+    }
+
+    // Link it in as our newest record
+    p_station->newest_trackpoint = ptr;
+
+    if (debug_level & 256) {
+        fprintf(stderr,"store_trail_point: Storing data for %s\n", p_station->call_sign);
+    }
+
+    ptr->trail_long_pos = lon;
+    ptr->trail_lat_pos  = lat;
+    ptr->sec            = sec;
+
+    if (alt[0] != '\0')
+            ptr->altitude = atoi(alt)*10;
+    else            
+            ptr->altitude = -99999l;
+
+    if (speed[0] != '\0')
+            ptr->speed  = (long)(atof(speed)*18.52);
+    else
+            ptr->speed  = -1;
+
+    if (course[0] != '\0')
+            ptr->course = (int)(atof(course) + 0.5);    // Poor man's rounding
+    else
+            ptr->course = -1;
+
+    flag = '\0';                    // init flags
+
+    if ((stn_flag & ST_DIRECT) != 0)
+            flag |= TR_LOCAL;           // set "local" flag
+
+    if (ptr->prev != NULL) {    // we have at least two points...
+        // Check whether distance between points is too far.  We
+        // must convert from degrees to the Xastir coordinate system
+        // units, which are 100th of a second.
+        if (    abs(lon - ptr->prev->trail_long_pos) > (trail_segment_distance * 60*60*100) ||
+                abs(lat - ptr->prev->trail_lat_pos)  > (trail_segment_distance * 60*60*100) ) {
+
+            // Set "new track" flag if there's
+            // "trail_segment_distance" degrees or more between
+            // points.  Originally was hard-coded to one degree, now
+            // set by a slider in the timing dialog.
+            flag |= TR_NEWTRK;
+        }
+        else {
+            // Check whether trail went above our maximum time
+            // between points.  If so, don't draw segment.
+            if (abs(sec - ptr->prev->sec) > (trail_segment_time *60)) {
+
+                // Set "new track" flag if long delay between
+                // reception of two points.  Time is set by a slider
+                // in the timing dialog.
+                flag |= TR_NEWTRK;
+            }
+        }
+    }
+    else {
+        // Set "new track" flag for first point received.
+        flag |= TR_NEWTRK;
+    }
+    ptr->flag = flag;
+
+    return(1);  // We succeeded
+}
+
+
+
+
+
+/*
+ *  Check if current packet is a delayed echo
+ */
+int is_trailpoint_echo(DataRow *p_station) {
+    int packets = 1;
+    time_t checktime;
+    char temp[50];
+    TrackRow *ptr;
+
+
+    // Check whether we're to skip checking for dupes (reading in
+    // objects/items from file is one such case).
+    //
+    if (skip_dupe_checking) {
+        return(0);  // Say that it isn't an echo
+    }
+
+    // Start at newest end of linked list and compare.  Return if we're
+    // beyond the checktime.
+    ptr = p_station->newest_trackpoint;
+
+    if (ptr == NULL)
+        return(0);  // first point couldn't be an echo
+
+    checktime = p_station->sec_heard - TRAIL_ECHO_TIME*60;
+
+    while (ptr != NULL) {
+
+        if (ptr->sec < checktime)
+            return(0);  // outside time frame, no echo found
+
+        if ((p_station->coord_lon == ptr->trail_long_pos)
+                && (p_station->coord_lat == ptr->trail_lat_pos)
+                && (p_station->speed == '\0' || ptr->speed < 0
+                        || (long)(atof(p_station->speed)*18.52) == ptr->speed)
+                        // current: char knots, trail: long 0.1m (-1 is undef)
+                && (p_station->course == '\0' || ptr->course <= 0
+                        || atoi(p_station->course) == ptr->course)
+                        // current: char, trail: int (-1 is undef)
+                && (p_station->altitude == '\0' || ptr->altitude <= -99999l
+                        || atoi(p_station->altitude)*10 == ptr->altitude)) {
+                        // current: char, trail: int (-99999l is undef)
+            if (debug_level & 1) {
+                fprintf(stderr,"delayed echo for %s",p_station->call_sign);
+                convert_lat_l2s(p_station->coord_lat, temp, sizeof(temp), CONVERT_HP_NORMAL);
+                fprintf(stderr," at %s",temp);
+                convert_lon_l2s(p_station->coord_lon, temp, sizeof(temp), CONVERT_HP_NORMAL);
+                fprintf(stderr," %s, already heard %d packets ago\n",temp,packets);
+            }
+            return(1);              // we found a delayed echo
+        }
+        ptr = ptr->prev;
+        packets++;
+    }
+    return(0);                      // no echo found
+}
+
+
+
+
+
+//
+//  Expire trail points.
+//
+// We now store track data in a doubly-linked list.  Each record has a
+// pointer to the previous and the next record in the list.  The main
+// station record has a pointer to the oldest and the newest end of the
+// chain, and the chain can be traversed in either order.  We use
+// this to advantage by adding records at one end of the list and
+// expiring them at the other.
+//
+void expire_trail_points(DataRow *p_station, time_t sec) {
+    int ii = 0;
+    int done = 0;
+    TrackRow *ptr;
+
+
+    //fprintf(stderr,"expire_trail_points: %s\n",p_station->call_sign);
+
+    if (debug_level & 256) {
+        fprintf(stderr,"expire_trail_points: %s\n",p_station->call_sign);
+    }
+
+    // Check whether we have any track data saved
+    if (p_station->oldest_trackpoint == NULL) {
+        return;     // Nothing to expire
+    }
+
+    // Iterate from oldest->newest trackpoints
+    while (!done && p_station->oldest_trackpoint != NULL) {
+        ptr = p_station->oldest_trackpoint;
+        if ( (ptr->sec + sec) >= sec_now() ) {
+            // New trackpoint, within expire time.  Quit checking
+            // the rest of the trackpoints for this station.
+            done++;
+        }
+        else {
+            //fprintf(stderr,"Found old trackpoint\n");
+
+            // Track too old.  Unlink this trackpoint and free it.
+            p_station->oldest_trackpoint = ptr->next;
+
+            // End of chain in this direction
+            if (p_station->oldest_trackpoint != NULL) {
+                p_station->oldest_trackpoint->prev = NULL;
+            }
+            else {
+                p_station->newest_trackpoint = NULL;
+            }
+
+            // Free up the space used by the expired trackpoint
+            free(ptr);
+
+            //fprintf(stderr,"Free'ing a trackpoint\n");
+
+            ii++;
+
+            // Reduce our count of mobile stations if the size of
+            // the track just went to zero.
+            if (p_station->oldest_trackpoint == NULL)
+                tracked_stations--;
+        }
+    }
+
+    if ( (debug_level & 256) && ii ) {
+        fprintf(stderr,"expire_trail_points: %d trackpoints free'd for %s\n",
+            ii,
+            p_station->call_sign);
+    }
+}
+
+
+
+
+
+/*
+ *  Delete comment records and free memory
+ */
+int delete_comments_and_status(DataRow *fill) {
+
+    // If the pointers are empty, we're done
+    if (       (fill->comment_data == NULL)
+            && (fill->status_data  == NULL) ) {
+        return(0);
+    }
+
+    if (fill->comment_data != NULL) {   // We have comment records
+        CommentRow *ptr;
+        CommentRow *ptr_next;
+
+        ptr = fill->comment_data;
+        ptr_next = ptr->next;
+        while (ptr != NULL) {
+            // Free the actual text string that we malloc'ed
+            if (ptr->text_ptr != NULL) {
+                free(ptr->text_ptr);
+            }
+            free(ptr);
+            ptr = ptr_next; // Advance to next record
+            if (ptr != NULL)
+                ptr_next = ptr->next;
+            else
+                ptr_next = NULL;
+        }
+    }
+    if (fill->status_data != NULL) {   // We have status records
+        CommentRow *ptr;
+        CommentRow *ptr_next;
+
+        ptr = fill->status_data;
+        ptr_next = ptr->next;
+        while (ptr != NULL) {
+            // Free the actual text string that we malloc'ed
+            if (ptr->text_ptr != NULL) {
+                free(ptr->text_ptr);
+            }
+            free(ptr);
+            ptr = ptr_next; // Advance to next record
+            if (ptr != NULL)
+                ptr_next = ptr->next;
+            else
+                ptr_next = NULL;
+        }
+    }
+    return(1);
+}
+
+
+
+
+
+/*
+ *  Delete trail and free memory
+ */
+int delete_trail(DataRow *fill) {
+
+    if (fill->newest_trackpoint != NULL) {
+        TrackRow *current;
+        TrackRow *next;
+
+        // Free the TrackRow records
+        current = fill->oldest_trackpoint;
+        while (current != NULL) {
+            next = current->next;
+            free(current);
+            current = next;
+        }
+
+        fill->oldest_trackpoint = NULL;
+        fill->newest_trackpoint = NULL;
+        tracked_stations--;
+        return(1);
+    }
+    return(0);
+}
+
+
+
+
+
+/*
+ *  Draw trail on screen.  If solid=1, draw type LineSolid, else
+ *  draw type LineOnOffDash.
+ *
+ *  If label_all_trackpoints=1, add the callsign next to each
+ *  trackpoint.  We may modify this and just add the callsign at the
+ *  start/end of each new track segment.
+ *
+ */
+void draw_trail(Widget w, DataRow *fill, int solid) {
+    char short_dashed[2]  = {(char)1,(char)5};
+    char medium_dashed[2] = {(char)5,(char)5};
+    unsigned long lat0, lon0, lat1, lon1;        // trail segment points
+    int col_trail, col_dot;
+    XColor rgb;
+    long brightness;
+    char flag1;
+    TrackRow *ptr;
+
+
+    if (!ok_to_draw_station(fill))
+        return;
+
+    // Expire old trackpoints first.  We use the
+    // remove-station-from-display time as the expire time for
+    // trackpoints.  This can be set from the Configure->Defaults
+    // dialog.
+    expire_trail_points(fill, sec_clear);
+
+    ptr = fill->newest_trackpoint;
+
+    // Trail should have at least two points
+    if ( (ptr != NULL) && (ptr->prev != NULL) ) {
+        int skip_dupes = 0; // Don't skip points first time through
+
+        if (debug_level & 256) {
+            fprintf(stderr,"draw_trail called for %s with %s.\n",
+                fill->call_sign, (solid? "Solid" : "Non-Solid"));
+        }
+
+        col_trail = trail_colors[fill->trail_color];
+
+        // define color of position dots in trail
+        rgb.pixel = col_trail;
+        XQueryColor(XtDisplay(w),cmap,&rgb);
+
+        brightness = (long)(0.3*rgb.red + 0.55*rgb.green + 0.15*rgb.blue);
+        if (brightness > 32000l) {
+            col_dot = trail_colors[0x05];   // black dot on light trails
+        }
+        else {
+            col_dot = trail_colors[0x06];   // white dot on dark trail
+        }
+
+        if (solid)
+            // Used to be "JoinMiter" and "CapButt" below
+            (void)XSetLineAttributes(XtDisplay(w), gc, 3, LineSolid, CapRound, JoinRound);
+        else {
+            // Another choice is LineDoubleDash
+            (void)XSetLineAttributes(XtDisplay(w), gc, 3, LineOnOffDash, CapRound, JoinRound);
+            (void)XSetDashes(XtDisplay(w), gc, 0, short_dashed , 2);
+        }
+
+        // Traverse linked list of trail points from newest to
+        // oldest
+        while ( (ptr != NULL) && (ptr->prev != NULL) ) {
+            lon0 = ptr->trail_long_pos;         // Trail segment start
+            lat0 = ptr->trail_lat_pos;
+            lon1 = ptr->prev->trail_long_pos;   // Trail segment end
+            lat1 = ptr->prev->trail_lat_pos;
+            flag1 = ptr->flag; // Are we at the start of a new trail?
+
+            if ((flag1 & TR_NEWTRK) == '\0') {
+                int lon0_screen, lat0_screen, lon1_screen, lat1_screen;
+
+                // draw trail segment
+                //
+                (void)XSetForeground(XtDisplay(w),gc,col_trail);
+                draw_vector(da,
+                    lon0,
+                    lat0,
+                    lon1,
+                    lat1,
+                    gc,
+                    pixmap_final,
+                    skip_dupes);
+
+                // draw position point itself
+                //
+                (void)XSetForeground(XtDisplay(w),gc,col_dot);
+                draw_point(w,
+                    lon0,
+                    lat0,
+                    gc,
+                    pixmap_final,
+                    skip_dupes);
+
+                // Draw the callsign to go with the point if
+                // label_all_trackpoints=1
+                //
+                if (Display_.callsign && Display_.label_all_trackpoints) {
+
+                    // Convert to screen coordinates
+                    lon0_screen = (lon0 - NW_corner_longitude) / scale_x;
+                    lat0_screen = (lat0 - NW_corner_latitude) / scale_y;
+
+                    // Convert to screen coordinates.
+                    lon1_screen = (lon1 - NW_corner_longitude) / scale_x;
+                    lat1_screen = (lat1 - NW_corner_latitude)  / scale_y;
+
+                    // The last position already gets its callsign
+                    // string drawn, plus that gets shifted based on
+                    // other parameters.  Draw both points of all
+                    // line segments except that one.  This will
+                    // result in strings getting drawn twice at
+                    // times, but they overlay on top of each other
+                    // so no big deal.
+                    //
+                    if (ptr != fill->newest_trackpoint) {
+
+                        draw_nice_string(da,
+                            pixmap_final,
+                            letter_style,
+                            lon0_screen+10,
+                            lat0_screen,
+                            fill->call_sign,
+                            0x08,
+                            0x0f,
+                            strlen(fill->call_sign));
+
+                        // If not same screen position as last drawn
+                        if (lon0_screen != lon1_screen
+                                && lat0_screen != lat1_screen) {
+
+                            draw_nice_string(da,
+                                pixmap_final,
+                                letter_style,
+                                lon1_screen+10,
+                                lat1_screen,
+                                fill->call_sign,
+                                0x08,
+                                0x0f,
+                                strlen(fill->call_sign));
+                        }
+                    }
+                }
+            }
+            ptr = ptr->prev;
+            skip_dupes = 1;
+        }
+        (void)XSetDashes(XtDisplay(w), gc, 0, medium_dashed , 2);
+    }
+    else if (debug_level & 256) {
+        fprintf(stderr,"Trail for %s does not contain 2 or more points.\n",
+            fill->call_sign);
+    }
+}
+
+
+
+
+
+// DK7IN: there should be some library functions for the next two,
+//        but I don't have any documentation while being in holidays...
+void month2str(int month, char *str, int str_size) {
+
+    switch (month) {
+        case  0: xastir_snprintf(str,str_size,"Jan"); break;
+        case  1: xastir_snprintf(str,str_size,"Feb"); break;
+        case  2: xastir_snprintf(str,str_size,"Mar"); break;
+        case  3: xastir_snprintf(str,str_size,"Apr"); break;
+        case  4: xastir_snprintf(str,str_size,"May"); break;
+        case  5: xastir_snprintf(str,str_size,"Jun"); break;
+        case  6: xastir_snprintf(str,str_size,"Jul"); break;
+        case  7: xastir_snprintf(str,str_size,"Aug"); break;
+        case  8: xastir_snprintf(str,str_size,"Sep"); break;
+        case  9: xastir_snprintf(str,str_size,"Oct"); break;
+        case 10: xastir_snprintf(str,str_size,"Nov"); break;
+        case 11: xastir_snprintf(str,str_size,"Dec"); break;
+        default: xastir_snprintf(str,str_size,"   "); break;
+    }
+}
+
+
+
+
+
+void wday2str(int wday, char *str, int str_size) {
+
+    switch (wday) {
+        case  0: xastir_snprintf(str,str_size,"Sun"); break;
+        case  1: xastir_snprintf(str,str_size,"Mon"); break;
+        case  2: xastir_snprintf(str,str_size,"Tue"); break;
+        case  3: xastir_snprintf(str,str_size,"Wed"); break;
+        case  4: xastir_snprintf(str,str_size,"Thu"); break;
+        case  5: xastir_snprintf(str,str_size,"Fri"); break;
+        case  6: xastir_snprintf(str,str_size,"Sat"); break;
+        default: xastir_snprintf(str,str_size,"   "); break;
+    }
+}
+
+
+
+
+
+/*
+ *  Export trail point to file
+ *
+ *  Don't call directly, call export_trail() or export_trail_as_kml() instead
+ *  as they need to open the file, set appropriate headers, and call export_trailstation()
+ *  to set the context for the position.
+ */
+void exp_trailpos(FILE *f,long lat,long lon,time_t sec,long speed,int course,long alt,int newtrk, int export_format) {
+    struct tm *time;
+    char lat_string[12+1];
+    char lon_string[12+1];
+    char month[3+1];
+    char wday[3+1];
+    float deg;
+
+    time  = gmtime(&sec);
+    month2str(time->tm_mon, month, sizeof(month));
+    wday2str(time->tm_wday, wday, sizeof(wday));
+    switch (export_format) { 
+        case EXPORT_KML_TRACK: 
+            // kml format is longitude,latitude,altitude triplets with
+            // a comma and no spaces separating elements of the triplet
+            // and a single space seperating sets of triplets in a 
+            // coordinates element.  Latitude and longitude are 
+            // both in decimal degrees.
+            deg = (float)(lon - 64800000l) / 360000.0;
+            fprintf(f,"%09.5f,",deg);
+            deg = -(float)(lat - 32400000l) / 360000.0;
+            fprintf(f,"%08.5f,",deg);
+            if (alt > -99999l)
+                fprintf(f,"%05.0f ",(float)(alt/10.0));
+            else        // undefined
+                fprintf(f,"0 ");
+            break;
+        case EXPORT_XASTIR_TRACK:
+        default:
+            if (newtrk)
+                fprintf(f,"\nN  New Track Start\n");
+            // DK7IN: The format may change in the near future !
+            //        Are there any standards? I want to be able to be compatible to
+            //        GPS data formats (e.g. G7TO) for easy interchange from/to GPS
+            //        How should we present undefined data? (speed/course/altitude)
+            convert_lat_l2s(lat, lat_string, sizeof(lat_string), CONVERT_UP_TRK);
+            convert_lon_l2s(lon, lon_string, sizeof(lon_string), CONVERT_UP_TRK);
+            fprintf(f,"T  %s",lat_string);
+            fprintf(f," %s",lon_string);
+            fprintf(f," %s %s %02d %02d:%02d:%02d %04d",wday,month,time->tm_mday,time->tm_hour,time->tm_min,time->tm_sec,time->tm_year+1900);
+
+            if (alt > -99999l)
+                fprintf(f,"  %5.0fm",(float)(alt/10.0));
+            else        // undefined
+                fprintf(f,"        ");
+        
+            if (speed >= 0)
+                fprintf(f," %4.0fkm/h",(float)(speed/10.0));
+            else        // undefined
+                fprintf(f,"          ");
+        
+            if (course >= 0)                    // DK7IN: is 0 undefined ?? 1..360 ?
+                fprintf(f," %3d�\n",course);
+            else        // undefined
+                fprintf(f,"     \n");
+    }
+}
+
+
+
+
+
+/*
+ *  Export trail for one station to file.
+ *  Don't call directly, call export_trail() or export_trail_as_kml() instead
+ *  as they need to open the file and set appropriate headers.
+ *
+ *  @param f handle of file to write to
+ *  @param p_station pointer to station to write
+ *  @param export_format file format to use (xastir tracklog or kml).
+ */
+void exp_trailstation(FILE *f, DataRow *p_station, int export_format) {
+    char timestring[101];  // string representation of the time heard or the current time
+    long lat0, lon0;
+    int newtrk;
+    time_t sec;
+    long speed;         // 0.1km/h
+    int  course;        // degrees
+    long alt;           // 0.1m
+    TrackRow *current;
+
+    newtrk = 1;
+
+    current = p_station->oldest_trackpoint;
+
+    switch (export_format) { 
+
+        case EXPORT_KML_TRACK: 
+           // This placemark is for a single position
+           // or for the most recent position of a trail 
+           // in either case represented as a <Point/> 
+           // and will show up as a labeled pushpin point.
+           fprintf(f,"<Placemark>");
+           get_iso_datetime(p_station->sec_heard,timestring,True,True);
+
+           if (p_station->origin == NULL || p_station->origin[0] == '\0') { 
+               fprintf(f,"<name>%s</name>\n",p_station->call_sign);
+               fprintf(f,"<description>");
+           } else { 
+               fprintf(f,"<name>%s</name>\n<description>Object from %s. \n",p_station->call_sign,p_station->origin);
+           }
+           // packets recieved %d last heard %s
+           fprintf(f,langcode("WPUPSTI005"),p_station->num_packets, timestring);
+           if (p_station->tactical_call_sign && p_station->tactical_call_sign[0] != '\0') { 
+                // tactical call %s 
+                fprintf(f, langcode("WPUPSTI065"), p_station->tactical_call_sign);
+           }
+           fprintf(f,"</description>\n");
+
+           // kml specifies w3c's date time format for timestamps
+           if (get_w3cdtf_datetime(p_station->sec_heard, timestring, False, False))
+              if (strlen(timestring) > 0) 
+                  fprintf(f,"<TimeStamp><when>%s</when></TimeStamp>",timestring);
+
+           if (current != NULL) {  
+               // We have trail points, create both a set of time stamp labled point placemarks
+               // and a linestring placemark to draw the trail.
+               fprintf(f,"<Point>\n<coordinates>");
+               if (p_station->altitude[0] != '\0')
+                   alt = atoi(p_station->altitude)*10;
+               else            
+                   alt = -99999l;
+               if (p_station->speed[0] != '\0')
+                   speed = (long)(atof(p_station->speed)*18.52);
+               else
+                   speed = -1;
+               if (p_station->course[0] != '\0')
+                   course = atoi(p_station->course);
+               else
+                   course = -1;
+               exp_trailpos(f,p_station->coord_lat,p_station->coord_lon,p_station->sec_heard,speed,course,alt,newtrk, export_format);
+               fprintf(f,"</coordinates></Point>");
+
+               fprintf(f,"</Placemark>\n");
+
+               // folow with a set of timestamped placemarks for each point on trail
+               while (current != NULL) {
+                   lon0   = current->trail_long_pos;                   // Trail segment start
+                   lat0   = current->trail_lat_pos;
+                   sec    = current->sec;
+                   speed  = current->speed;
+                   course = current->course;
+                   alt    = current->altitude;
+                   // kml specifies w3c's date time format for timestamps
+                   if (get_w3cdtf_datetime(sec,timestring,False,False) && (int)sec>0) { 
+                       // point has valid timestamp, write it
+                       fprintf(f,"<Placemark>");
+                       fprintf(f,"<name>%s at %s</name>\n",p_station->call_sign, timestring);
+                       fprintf(f,"<TimeStamp><when>%s</when></TimeStamp>",timestring);
+                       fprintf(f,"<Point><coordinates>");
+                       exp_trailpos(f,lat0,lon0,sec,speed,course,alt,newtrk, export_format);
+                       fprintf(f,"</coordinates></Point>");
+                       fprintf(f,"</Placemark>\n");
+                   }
+                   // Advance to the next point
+                   current = current->next;
+               }
+               // Prepare to follow with  a trail (as a <LineString/>).
+               fprintf(f,"<Placemark>");
+               if (p_station->origin == NULL || p_station->origin[0] == '\0')
+                   fprintf(f,"<name>%s (trail)</name>\n",p_station->call_sign);
+               else
+                   fprintf(f,"<name>%s (trail)</name>\n<description>Object from %s</description>\n",p_station->call_sign,p_station->origin);
+           }
+           break;
+
+        case EXPORT_XASTIR_TRACK:
+        default:
+           if (p_station->origin == NULL || p_station->origin[0] == '\0')
+               fprintf(f,"\n#C %s\n",p_station->call_sign);
+           else
+               fprintf(f,"\n#O %s %s\n",p_station->call_sign,p_station->origin);
+    }
+
+    // A trail must have at least two points:  One in the struct,
+    // and one in the tracklog.  If the station only has one point,
+    // there won't be a tracklog.  If the station has moved, then
+    // it'll have both.
+
+    // reset current, as we may have moved it past the last trackpoint
+    // while generating kml above.
+    current = p_station->oldest_trackpoint;
+
+    if (current != NULL) {  // We have trail points, loop through
+                            // them.  Skip the most current position
+                            // because it is included in the
+                            // tracklog (if we have a tracklog!).
+
+        switch (export_format) { 
+            case EXPORT_KML_TRACK: 
+                fprintf(f,"<LineString>\n<coordinates>");
+                break;
+            //default:
+                // no heading for set of points
+        }
+        while (current != NULL) {
+            lon0   = current->trail_long_pos;                   // Trail segment start
+            lat0   = current->trail_lat_pos;
+            sec    = current->sec;
+            speed  = current->speed;
+            course = current->course;
+            alt    = current->altitude;
+            if ((current->flag & TR_NEWTRK) != '\0')
+                newtrk = 1;
+ 
+            // identical for kml and xastir tracks, but could be different for other formats
+            switch (export_format) { 
+                case EXPORT_KML_TRACK: 
+                    exp_trailpos(f,lat0,lon0,sec,speed,course,alt,newtrk, export_format);
+                    break;
+                case EXPORT_XASTIR_TRACK:
+                default:
+                    exp_trailpos(f,lat0,lon0,sec,speed,course,alt,newtrk, export_format);
+            }
+
+            newtrk = 0;
+
+            // Advance to the next point
+            current = current->next;
+        }
+        switch (export_format) { 
+            case EXPORT_KML_TRACK: 
+                fprintf(f,"</coordinates>\n</LineString>\n");
+                break;
+            //default:
+                // no close for set of points
+       }
+    }
+    else {  // We don't have any tracklog, so write out the most
+            // current position only.
+    
+        if (p_station->altitude[0] != '\0')
+            alt = atoi(p_station->altitude)*10;
+        else            
+            alt = -99999l;
+
+        if (p_station->speed[0] != '\0')
+            speed = (long)(atof(p_station->speed)*18.52);
+        else
+            speed = -1;
+
+        if (p_station->course[0] != '\0')
+            course = atoi(p_station->course);
+        else
+            course = -1;
+
+        switch (export_format) { 
+            case EXPORT_KML_TRACK: 
+                fprintf(f,"<Point>\n\t<coordinates>");
+                exp_trailpos(f,p_station->coord_lat,p_station->coord_lon,p_station->sec_heard,speed,course,alt,newtrk, export_format);
+                fprintf(f,"</coordinates>\n\t</Point>\n");
+                break;
+            case EXPORT_XASTIR_TRACK:
+            default:
+                exp_trailpos(f,p_station->coord_lat,p_station->coord_lon,p_station->sec_heard,speed,course,alt,newtrk, export_format);
+        }
+    }
+
+    
+    switch (export_format) { 
+        case (EXPORT_KML_TRACK): 
+            fprintf(f,"</Placemark>\n");
+            break;
+        case (EXPORT_XASTIR_TRACK):
+        default:
+            fprintf(f,"\n");
+    }
+}
+
+
+
+
+//
+// Export trail data for one or all stations to file
+//
+// If p_station == NULL, store all stations, else store only one
+// station.
+//
+void export_trail(DataRow *p_station) {
+    char file[420];
+    FILE *f;
+    time_t sec;
+    struct tm *time;
+    int storeall;
+    char user_base_dir[MAX_VALUE];
+
+    sec = sec_now();
+    time  = gmtime(&sec);
+
+    if (p_station == NULL)
+        storeall = 1;
+    else
+        storeall = 0;
+
+    if (storeall) {
+        // define filename for storing all station
+        xastir_snprintf(file, sizeof(file),
+            "%s/%04d%02d%02d-%02d%02d%02d.trk",
+            get_user_base_dir("tracklogs", user_base_dir, 
+                              sizeof(user_base_dir)),
+            time->tm_year+1900,
+            time->tm_mon+1,
+            time->tm_mday,
+            time->tm_hour,
+            time->tm_min,
+            time->tm_sec);
+    }
+    else {
+        // define filename for current station
+        xastir_snprintf(file, sizeof(file), "%s/%s.trk", 
+                        get_user_base_dir("tracklogs", user_base_dir, 
+                                          sizeof(user_base_dir)), 
+                        p_station->call_sign);
+    }
+
+    // create or open file
+    (void)filecreate(file);     // create empty file if it doesn't exist
+    // DK7IN: owner should better be set to user, it is now root with kernel AX.25!
+
+    f=fopen(file,"a");          // open file for append
+    if (f != NULL) {
+
+        fprintf(f,
+            "# WGS-84 tracklog created by Xastir %04d/%02d/%02d %02d:%02d\n",
+            time->tm_year+1900,
+            time->tm_mon+1,
+            time->tm_mday,
+            time->tm_hour,
+            time->tm_min);
+
+        if (storeall) {
+            p_station = n_first;
+            while (p_station != NULL) {
+                exp_trailstation(f,p_station, EXPORT_XASTIR_TRACK);
+                p_station = p_station->n_next;
+            }
+        }
+        else {
+            exp_trailstation(f,p_station, EXPORT_XASTIR_TRACK);
+        }
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't create or open tracklog file %s\n",file);
+}
+
+
+
+
+
+//
+// Export trail data for one or all stations to a klm file suitable for 
+// loading into google earth/google maps/NASA worldwind etc.
+// For documentation of the KML (Keyhole Markup Language) format,
+// see: http://
+//
+// @param p_station pointer to datarow containing station to export
+// If p_station == NULL, store all stations, else store only one
+// station.
+//
+void export_trail_as_kml(DataRow *p_station) {
+    char file[420];
+    FILE *f;
+    time_t sec;
+    struct tm *time;
+    int storeall;
+    char user_base_dir[MAX_VALUE];
+
+    sec = sec_now();
+    time  = gmtime(&sec);
+
+    if (p_station == NULL)
+        storeall = 1;
+    else
+        storeall = 0;
+
+    if (storeall) {
+        // define filename for storing all station
+        xastir_snprintf(file, sizeof(file),
+            "%s/%04d%02d%02d-%02d%02d%02d.kml",
+            get_user_base_dir("tracklogs", user_base_dir, 
+                              sizeof(user_base_dir)),
+            time->tm_year+1900,
+            time->tm_mon+1,
+            time->tm_mday,
+            time->tm_hour,
+            time->tm_min,
+            time->tm_sec);
+    }
+    else {
+        // define filename for current station, call + current time.
+        xastir_snprintf(file, sizeof(file), 
+            "%s/%s_%04d%02d%02d-%02d%02d%02d.kml",
+            get_user_base_dir("tracklogs", user_base_dir, 
+                              sizeof(user_base_dir)),
+            p_station->call_sign,
+            time->tm_year+1900,
+            time->tm_mon+1,
+            time->tm_mday,
+            time->tm_hour,
+            time->tm_min,
+            time->tm_sec);
+    }
+
+    // create or open file
+    (void)filecreate(file);     // create empty file if it doesn't exist
+    // DK7IN: owner should better be set to user, it is now root with kernel AX.25!
+
+    f=fopen(file,"w+");          // open file for writing
+    if (f != NULL) {
+ 
+        fprintf(f,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://earth.google.com/kml/2.2\">\n<Document>\n<name>APRS Data</name>\n<open>1</open>\n");
+
+        fprintf(f,
+            "<description>WGS-84 tracklog created by Xastir %04d/%02d/%02d %02d:%02d</description>\n",
+            time->tm_year+1900,
+            time->tm_mon+1,
+            time->tm_mday,
+            time->tm_hour,
+            time->tm_min);
+
+        if (storeall) {
+            p_station = n_first;
+            while (p_station != NULL) {
+                exp_trailstation(f,p_station,EXPORT_KML_TRACK);
+                p_station = p_station->n_next;
+            }
+        }
+        else {
+            exp_trailstation(f,p_station,EXPORT_KML_TRACK);
+        }
+
+        fprintf(f,"</Document>\n</kml>");
+
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't create or open tracklog file %s\n",file);
+}
+
+
+
+//////////////////////////////////////  Station storage  ///////////////////////////////////////////
+
+// Station storage is done in a double-linked list. In fact there are two such
+// pointer structures, one for sorting by name and one for sorting by time.
+// We store both the pointers to the next and to the previous elements.  DK7IN
+
+/*
+ *  Setup station storage structure
+ */
+void init_station_data(void) {
+
+    station_count = 0;                  // empty station list
+    n_first = NULL;                     // pointer to next element in name sorted list
+    n_last  = NULL;                     // pointer to previous element in name sorted list
+    t_oldest = NULL;                     // pointer to oldest element in time sorted list
+    t_newest  = NULL;                     // pointer to newest element in time sorted list
+    last_sec = sec_now();               // check value for detecting changed seconds in time
+    next_time_sn = 0;                   // serial number for unique time index
+    current_trail_color = 0x00;         // first trail color used will be 0x01
+    last_station_remove = sec_now();    // last time we checked for stations to remove
+}
+
+
+
+
+
+/*
+ *  Initialize station data
+ */        
+void init_station(DataRow *p_station) {
+    // the list pointers should already be set
+    p_station->oldest_trackpoint  = NULL;         // no trail
+    p_station->newest_trackpoint  = NULL;         // no trail
+    p_station->trail_color        = 0;
+    p_station->weather_data       = NULL;         // no weather
+    p_station->coord_lat          = 0l;           //  90�N  \ undefined
+    p_station->coord_lon          = 0l;           // 180�W  / position
+    p_station->pos_amb            = 0;            // No ambiguity
+    p_station->error_ellipse_radius = 600;        // In cm, default 6 meters
+    p_station->lat_precision      = 60;           // In 100ths of seconds latitude (60 = 0.01 minutes)
+    p_station->lon_precision      = 60;           // In 100ths of seconds longitude (60 = 0.01 minutes)
+    p_station->call_sign[0]       = '\0';         // ?????
+    p_station->tactical_call_sign = NULL;
+    p_station->sec_heard          = 0;
+    p_station->time_sn            = 0;
+    p_station->flag               = 0;            // set all flags to inactive
+    p_station->object_retransmit  = -1;           // transmit forever
+    p_station->last_transmit_time = sec_now();    // Used for object/item decaying algorithm
+    p_station->transmit_time_increment = 0;       // Used in data_add()
+//    p_station->last_modified_time = 0;            // Used for object/item dead-reckoning
+    p_station->record_type        = '\0';
+    p_station->data_via           = '\0';         // L local, T TNC, I internet, F file
+    p_station->heard_via_tnc_port = 0;
+    p_station->heard_via_tnc_last_time = 0;
+    p_station->last_port_heard    = 0;
+    p_station->num_packets        = 0;
+    p_station->aprs_symbol.aprs_type = '\0';
+    p_station->aprs_symbol.aprs_symbol = '\0';
+    p_station->aprs_symbol.special_overlay = '\0';
+    p_station->aprs_symbol.area_object.type           = AREA_NONE;
+    p_station->aprs_symbol.area_object.color          = AREA_GRAY_LO;
+    p_station->aprs_symbol.area_object.sqrt_lat_off   = 0;
+    p_station->aprs_symbol.area_object.sqrt_lon_off   = 0;
+    p_station->aprs_symbol.area_object.corridor_width = 0;
+//    p_station->station_time_type  = '\0';
+    p_station->origin[0]          = '\0';        // no object
+    p_station->packet_time[0]     = '\0';
+    p_station->node_path_ptr      = NULL;
+    p_station->pos_time[0]        = '\0';
+//    p_station->altitude_time[0]   = '\0';
+    p_station->altitude[0]        = '\0';
+//    p_station->speed_time[0]      = '\0';
+    p_station->speed[0]           = '\0';
+    p_station->course[0]          = '\0';
+    p_station->bearing[0]         = '\0';
+    p_station->NRQ[0]             = '\0';
+    p_station->power_gain[0]      = '\0';
+    p_station->signal_gain[0]     = '\0';
+    p_station->signpost[0]        = '\0';
+    p_station->probability_min[0] = '\0';
+    p_station->probability_max[0] = '\0';
+//    p_station->station_time[0]    = '\0';
+    p_station->sats_visible[0]    = '\0';
+    p_station->status_data        = NULL;
+    p_station->comment_data       = NULL;
+    p_station->df_color           = -1;
+    
+    // Show that there are no other points associated with this
+    // station. We could also zero all the entries of the 
+    // multipoints[][] array, but nobody should be looking there
+    // unless this is non-zero.
+    // KG4NBB
+    
+    p_station->num_multipoints = 0;
+    p_station->multipoint_data = NULL;
+}
+
+
+
+
+
+/*
+ *  Remove element from name ordered list
+ */
+void remove_name(DataRow *p_rem) {      // todo: return pointer to next element
+    int update_shortcuts = 0;
+    int hash_key;   // We use a 14-bit hash key
+
+
+    // Do a quick check to see if we're removing a station record
+    // that is pointed to by our pointer shortcuts array.
+    // If so, update our pointer shortcuts after we're done.
+    //
+    // We create the hash key out of the lower 7 bits of the first
+    // two characters, creating a 14-bit key (1 of 16384)
+    //
+    hash_key = (int)((p_rem->call_sign[0] & 0x7f) << 7);
+    hash_key = hash_key | (int)(p_rem->call_sign[1] & 0x7f);
+
+    if (station_shortcuts[hash_key] == p_rem) {
+        // Yes, we're trying to remove a record that a hash key
+        // directly points to.  We'll need to redo that hash key
+        // after we remove the record.
+        update_shortcuts++;
+    }
+
+
+    // Proceed to the station record removal
+    //
+    if (p_rem->n_prev == NULL) { // Appears to be first element in list
+
+        if (n_first == p_rem) {  // Yes, head of list
+
+            // Make list head point to 2nd element in list (or NULL)
+            // so that we can delete the current record.
+            n_first = p_rem->n_next;
+        }
+        else {  // No, not first element in list.  Problem!  The
+                // list pointers are inconsistent for some reason.
+                // The chain has been broken and we have dangling
+                // pointers.
+
+            fprintf(stderr,
+                "remove_name(): ERROR: p->n_prev == NULL but p != n_first\n");
+
+abort();    // Cause a core dump at this point
+// Perhaps we could do some repair to the list pointers here?  Start
+// at the other end of the chain and navigate back to this end, then
+// fix up n_first to point to it?  This is at the risk of a memory
+// leak, but at least Xastir might continue to run.
+
+        }
+    }
+    else {  // Not the first element in the list.  Fix up pointers
+            // to skip the current record.
+        p_rem->n_prev->n_next = p_rem->n_next;
+    }
+
+
+    if (p_rem->n_next == NULL) { // Appears to be last element in list
+
+        if (n_last == p_rem) {   // Yes, tail of list
+
+            // Make list tail point to previous element in list (or
+            // NULL) so that we can delete the current record.
+            n_last = p_rem->n_prev;
+        }
+        else {  // No, not last element in list.  Problem!  The list
+                // pointers are inconsistent for some reason.  The
+                // chain has been broken and we have dangling
+                // pointers.
+
+            fprintf(stderr,
+                "remove_name(): ERROR: p->n_next == NULL but p != n_last\n");
+
+abort();    // Cause a core dump at this point
+// Perhaps we could do some repair to the list pointers here?  Start
+// at the other end of the chain and navigate back to this end, then
+// fix up n_last to point to it?  This is at the risk of a memory
+// leak, but at least Xastir might continue to run.
+
+        }
+    }
+    else {  // Not the last element in the list.  Fix up pointers to
+            // skip the current record.
+        p_rem->n_next->n_prev = p_rem->n_prev;
+    }
+
+
+    // Update our pointer shortcuts.  Pass the removed hash_key to
+    // the function so that we can try to redo just that hash_key
+    // pointer.
+    if (update_shortcuts) {
+//fprintf(stderr,"\t\t\t\t\t\tRemoval of hash key: %i\n", hash_key);
+
+        // The -1 tells the function to redo all of the hash table
+        // pointers because we deleted one of them.  Later we could
+        // optimize this so that only the specific pointer is fixed
+        // up.
+        station_shortcuts_update_function(-1, NULL);
+    }
+}
+
+
+
+
+
+/*
+ *  Remove element from time ordered list
+ */
+void remove_time(DataRow *p_rem) {      // todo: return pointer to next element
+
+    if (p_rem->t_older == NULL) { // Appears to be first element in list
+
+        if (t_oldest == p_rem) {  // Yes, head of list (oldest)
+
+            // Make oldest list head point to 2nd element in list (or NULL)
+            // so that we can delete the current record.
+            t_oldest = p_rem->t_newer;
+        }
+        else {  // No, not first (oldest) element in list.  Problem!
+                // The list pointers are inconsistent for some
+                // reason.  The chain has been broken and we have
+                // dangling pointers.
+
+            fprintf(stderr,
+                "remove_time(): ERROR: p->t_older == NULL but p != t_oldest\n");
+
+abort();    // Cause a core dump at this point
+// Perhaps we could do some repair to the list pointers here?  Start
+// at the other end of the chain and navigate back to this end, then
+// fix up t_oldest to point to it?  This is at the risk of a memory
+// leak, but at least Xastir might continue to run.
+
+        }
+    }
+    else {  // Not the first (oldest) element in the list.  Fix up
+            // pointers to skip the current record.
+        p_rem->t_older->t_newer = p_rem->t_newer;
+    }
+
+
+    if (p_rem->t_newer == NULL) { // Appears to be last (newest) element in list
+
+        if (t_newest == p_rem) {   // Yes, head of list (newest)
+
+            // Make newest list head point to previous element in
+            // list (or NULL) so that we can delete the current
+            // record.
+            t_newest = p_rem->t_older;
+        }
+        else {  // No, not newest element in list.  Problem!  The
+                // list pointers are inconsistent for some reason.
+                // The chain has been broken and we have dangling
+                // pointers.
+
+            fprintf(stderr,
+                "remove_time(): ERROR: p->t_newer == NULL but p != t_newest\n");
+
+abort();    // Cause a core dump at this point
+// Perhaps we could do some repair to the list pointers here?  Start
+// at the other end of the chain and navigate back to this end, then
+// fix up t_newest to point to it?  This is at the risk of a memory
+// leak, but at least Xastir might continue to run.
+
+        }
+    }
+    else {  // Not the newest element in the list.  Fix up pointers
+            // to skip the current record.
+        p_rem->t_newer->t_older = p_rem->t_older;
+    }
+}
+
+
+
+
+
+/*
+ *  Insert existing element into name ordered list before p_name.
+ *  If p_name is NULL then we add it to the end instead.
+ */
+void insert_name(DataRow *p_new, DataRow *p_name) {
+
+    // Set up pointer to next record (or NULL), sorted by name
+    p_new->n_next = p_name;
+
+    if (p_name == NULL) {       // Add to end of list
+
+        p_new->n_prev = n_last;
+
+        if (n_last == NULL)     // If we have an empty list
+            n_first = p_new;    // Add it to the head of the list
+
+        else    // List wasn't empty, add to the end of the list.
+            n_last->n_next = p_new;
+
+        n_last = p_new;
+    }
+
+    else {  // Insert new record ahead of p_name record
+
+        p_new->n_prev = p_name->n_prev;
+
+        if (p_name->n_prev == NULL)     // add to begin of list
+            n_first = p_new;
+        else
+            p_name->n_prev->n_next = p_new;
+
+        p_name->n_prev = p_new;
+    }
+}
+
+
+
+
+
+/*
+ *  Insert existing element into time ordered list before p_time
+ *  The p_new record ends up being on the "older" side of p_time when
+ *  all done inserting (closer in the list to the t_oldest pointer).
+ *  If p_time == NULL, insert at newest end of list.
+ */
+void insert_time(DataRow *p_new, DataRow *p_time) {
+
+    // Set up pointer to next record (or NULL), sorted by time
+    p_new->t_newer = p_time;
+
+    if (p_time == NULL) {               // add to end of list (becomes newest station)
+
+        p_new->t_older = t_newest;         // connect to previous end of list
+
+        if (t_newest == NULL)             // if list empty, create list
+            t_oldest = p_new;            // it's now our only station on the list
+        else
+            t_newest->t_newer = p_new;     // list not empty, link original last record to our new one
+
+        t_newest = p_new;                 // end of list (newest record pointer) points to our new record
+    }
+
+    else {                            // Else we're inserting into the middle of the list somewhere
+
+        p_new->t_older = p_time->t_older;
+
+        if (p_time->t_older == NULL)     // add to end of list (new record becomes oldest station)
+            t_oldest = p_new;
+        else
+            p_time->t_older->t_newer = p_new; // else 
+
+        p_time->t_older = p_new;
+    }
+}
+
+
+
+
+
+/*
+ *  Free station memory for one entry
+ */
+void delete_station_memory(DataRow *p_del) {
+    if (p_del == NULL)
+        return;
+    remove_name(p_del);
+    remove_time(p_del);
+    free(p_del);
+    station_count--;
+}
+
+
+
+
+
+/*
+ *  Create new uninitialized element in station list
+ *  and insert it before p_name after p_time entries.
+ *
+ *  Returns NULL if malloc error.
+ */
+/*@null@*/ DataRow *insert_new_station(DataRow *p_name, DataRow *p_time) {
+    DataRow *p_new;
+
+    p_new = (DataRow *)calloc(1, sizeof(DataRow));
+
+    if (p_new != NULL) {                // we really got the memory
+        insert_name(p_new,p_name);      // insert element into name ordered list
+        insert_time(p_new,p_time);      // insert element into time ordered list
+    }
+    else {  // p_new == NULL
+        fprintf(stderr,"ERROR: we got no memory for station storage\n");
+    }
+
+    return(p_new);                      // return pointer to new element
+}
+
+
+
+
+
+/*
+ *  Create new initialized element for call in station list
+ *  and insert it before p_name after p_time entries.
+ *
+ *  Returns NULL if mallc error.
+ */
+/*@null@*/ DataRow *add_new_station(DataRow *p_name, DataRow *p_time, char *call) {
+    DataRow *p_new;
+    int hash_key;   // We use a 14-bit hash key
+    char *tactical_call;
+
+
+    if (call[0] == '\0') {
+        // Do nothing.  No update needed.  Callsign is empty.
+        return(NULL);
+    }
+
+//fprintf(stderr,"Adding new station: %s\n",call);
+  
+    p_new = insert_new_station(p_name,p_time);  // allocate memory
+
+    if (p_new == NULL) {
+        // Couldn't allocate space for the station
+        return(NULL);
+    }
+
+    init_station(p_new);                    // initialize new station record
+    xastir_snprintf(p_new->call_sign,
+        sizeof(p_new->call_sign),
+        "%s",
+        call);
+    station_count++;
+
+    // Do some quick checks to see if we just inserted a new hash
+    // key or inserted at the beginning of a hash key (making the
+    // old pointer incorrect).  If so, update our pointers to match.
+
+    // We create the hash key out of the lower 7 bits of the first
+    // two characters, creating a 14-bit key (1 of 16384)
+    //
+    hash_key = (int)((call[0] & 0x7f) << 7);
+    hash_key = hash_key | (int)(call[1] & 0x7f);
+
+    if (station_shortcuts[hash_key] == NULL) {
+        // New hash key entry point found.  Fill in the pointer.
+//fprintf(stderr,"New hash key: %i, call: %s\n",
+//    hash_key,
+//    call);
+
+        station_shortcuts_update_function(hash_key, p_new);
+    }
+    else if (p_new->n_prev == NULL) {
+        // We just inserted at the beginning of the list.  Assume
+        // that we inserted at the beginning of our hash_key
+        // segment.
+//fprintf(stderr,"Start of list hash_key: %i, call: %s\n",
+//    hash_key,
+//    call);
+
+        station_shortcuts_update_function(hash_key, p_new);
+    }
+    else {
+        // Check whether either of the first two chars of the new
+        // callsign and the previous callsign are different.  If so,
+        // we need to update the hash table entry for our new record
+        // 'cuz we're at the start of a new hash table entry.
+        if (p_new->n_prev->call_sign[0] != call[0]
+                || p_new->n_prev->call_sign[1] != call[1]) {
+//fprintf(stderr,"Hash segment start: %i, call: %s\n",
+//    hash_key,
+//    call);
+
+            station_shortcuts_update_function(hash_key, p_new);
+        }
+    }
+
+//if (p_new->n_prev != NULL) {
+//    fprintf(stderr,"\tprev: %s",
+//        p_new->n_prev->call_sign);
+//}
+
+//if (p_new->n_next != NULL) {
+//    fprintf(stderr,"\t\tnext: %s",
+//        p_new->n_next->call_sign);
+//}
+//
+//fprintf(stderr,"\n");
+
+    // Check whether we have a tactical call to assign to this
+    // station in our tactical hash table.
+//fprintf(stderr,"Call:'%s'\n", call);
+    tactical_call = get_tactical_from_hash(call);
+
+    // If tactical call found and not blank
+    if (tactical_call && tactical_call[0] != '\0') {
+
+        // Malloc some memory to hold it in the station record.
+        p_new->tactical_call_sign = (char *)malloc(MAX_TACTICAL_CALL+1);
+        CHECKMALLOC(p_new->tactical_call_sign);
+
+//fprintf(stderr,"***Assigning tactical call to new record***\n");
+        xastir_snprintf(p_new->tactical_call_sign,
+            MAX_TACTICAL_CALL+1,
+            "%s",
+            tactical_call);
+
+        //if (tactical_call[0] == '\0')
+        //    fprintf(stderr,"Blank tactical call\n");
+    }
+    else {
+//fprintf(stderr,".");
+    }
+
+    return(p_new);                      // return pointer to new element
+}
+
+
+
+
+#ifdef HAVE_DB
+/* function add_simple_station() 
+ * adds an xastir DataRow using station and additional data from a simpleStation 
+ * record in a SQL database.  
+ * @param p_new_station Pointer to a DataRow for the new station, probably initalized as DataRow p_new_station = NULL
+ * @param station  String pointer for the callsign or object name
+ * @param origin   String pointer for the callsign for an object
+ * @param symbol   String pointer to an aprs symbol, will take the first character
+ * @param overlay  String pointer to an aprs overlay, will take the first character 
+ * @param aprs_type String pointer to an aprs type, will take the first character
+ * @param latitude  in decimal degrees
+ * @param longitude in decimal degrees
+ * @param record_type
+ * @param node_path
+ * @param transmit_time Time at which the station position was transmitted in a string pointer with format described by timeformat
+ * @param timeformat Format for the transmit_time, e.g. "%Y-%M-%D %h:%d:%m" see documentation for strptime
+ *
+ * @returns 0 if unable to add new station (p_new_station should be null)
+ * otherwise returns 1 (and p_new_station should be a pointer to the DataRow 
+ * for the new station record.
+ */
+int add_simple_station(DataRow *p_new_station,char *station, char *origin, char *symbol, char *overlay, char *aprs_type, char *latitude, char *longitude, char *record_type, char *node_path, char *transmit_time, char *timeformat) { 
+    int returnvalue = 0;
+    unsigned long x;  // xastir coordinate for longitude
+    unsigned long y;  // xastir coordinate for latitide
+    float lat;  // latitude converted from retrieved string
+    float lon;  // longitude converted from retrieved string
+    DataRow *p_time;  // pointer to new station record  
+    //DataRow *p_new_station_unused;
+    struct tm time;
+    time_t sec;
+    char timestring[100+1];
+    char empty[MAX_ALTITUDE];  // for storing trailpoint data (altitude, course, speed) we don't know here.
+    empty[0]='\0';
+
+    // Add a datarow using the retrieved station record from the postgis/mysql database.
+    p_time = NULL;
+    p_new_station = NULL;
+
+    if (debug_level & 4096)  
+        fprintf(stderr,"add_simple_station(%s)\n",station);
+
+    if (search_station_name(&p_new_station,station,1)) { 
+        // A datarow for this station exists, find out if the new record
+        // is older or younger than the existing DataRow for this station
+        strptime(transmit_time,timeformat,&time);
+        p_new_station->sec_heard = mktime(&time);
+        if(p_new_station->sec_heard > mktime(&time)) { 
+             // Add the new record as a trailpoint.
+             if (strlen(transmit_time) > 0) {
+                 strptime(transmit_time, timeformat, &time);
+                 sec = mktime(&time);
+                 lat = strtof(latitude,NULL);
+                 lon = strtof(longitude,NULL);
+                 if (convert_to_xastir_coordinates (&x, &y, lon, lat))
+                     (void)store_trail_point(p_new_station, x, y, sec, empty, empty, empty, 0);
+             }
+
+             // all done
+             returnvalue = 1;
+        } else { 
+             // Append the position of the existing record as a trailpoint
+             // and set the station DataRow to the new values.
+             (void)store_trail_point(p_new_station, p_new_station->coord_lon, p_new_station->coord_lat, p_new_station->sec_heard, empty, empty, empty, 0);
+        }
+    } else {
+        // add a new station
+        p_new_station = add_new_station(p_new_station,p_time,station);
+    }
+    if(returnvalue==0) { 
+        // Set the values for the p_new_station DataRow based on the
+        // supplied parameters.  At this point p_new_station might
+        // be either a brand new station record, or an existing 
+        // station record for the callsign that we were passed.
+        if (!(p_new_station==NULL)) { 
+            // set values for new station based on the database row
+            xastir_snprintf(p_new_station->origin,58,"%s",origin);
+            p_new_station->aprs_symbol.aprs_symbol = symbol[0];
+            p_new_station->aprs_symbol.special_overlay = overlay[0];
+            p_new_station->aprs_symbol.aprs_type = aprs_type[0];
+            lat = strtof(latitude,NULL);
+            lon = strtof(longitude,NULL);
+            if (convert_to_xastir_coordinates (&x, &y, lon, lat)) {
+               p_new_station->coord_lon = x;
+               p_new_station->coord_lat = y;
+            }
+            p_new_station->record_type = record_type[0];
+            // free node path, Malloc, and store the new path
+            if (p_new_station->node_path_ptr != NULL) { 
+                free(p_new_station->node_path_ptr);
+            }
+            p_new_station->node_path_ptr = (char *)malloc(strlen(node_path) + 1);
+            CHECKMALLOC(p_new_station->node_path_ptr);
+            substr(p_new_station->node_path_ptr,node_path,strlen(node_path));
+     
+            // also set flags for the station 
+            p_new_station->flag |= ST_ACTIVE;
+            if (position_on_extd_screen(p_new_station->coord_lat,p_new_station->coord_lon)) {
+                p_new_station->flag |= (ST_INVIEW);   // set   "In View" flag
+            } else {
+                p_new_station->flag &= (~ST_INVIEW);  // clear "In View" flag
+            }
+            p_new_station->data_via = DATA_VIA_DATABASE;  // treat as data from a file.
+            if (strlen(transmit_time) > 0) { 
+                //strptime(transmit_time,"%Y-%m-%d %H:%M:%S",&time);
+                strptime(transmit_time,timeformat,&time);
+                p_new_station->sec_heard = mktime(&time);
+                if (debug_level & 4096) {
+                    get_iso_datetime(p_new_station->sec_heard,timestring,False,False);
+                    fprintf(stderr,"time %s to [%s] using [%s]\n",transmit_time,timestring,timeformat);
+                }
+                if (p_new_station->sec_heard > sec_now()) 
+                    p_new_station->sec_heard = sec_now();
+                (void)strftime(timestring,MAX_TIME,"%m%d%Y%H%M%S",&time);
+                xastir_snprintf(p_new_station->pos_time,
+                     sizeof(p_new_station->pos_time),
+                     "%s",
+                     timestring);
+                }
+            returnvalue = 1;
+        }
+    }
+    return returnvalue;
+}
+#endif /* HAVE_DB */
+
+
+
+
+
+/*
+ *  Move station record before p_time in time ordered list
+ */
+void move_station_time(DataRow *p_curr, DataRow *p_time) {
+
+    if (p_curr != NULL) {               // need a valid record
+        remove_time(p_curr);
+        insert_time(p_curr,p_time);
+    }
+}
+
+
+
+
+
+/*
+ *  Move station record before p_name in name ordered list
+ */
+void move_station_name(DataRow *p_curr, DataRow *p_name) {
+
+    if (p_curr != NULL) {               // need a valid record
+        remove_name(p_curr);
+        insert_name(p_curr,p_name);
+    }
+}
+
+
+
+
+
+// Update all of the pointers so that they accurately reflect the
+// current state of the station database.
+//
+// NOTE:  This part of the code could be made smarter so that the
+// pointers are updated whenever they are found to be out of whack,
+// instead of zeroing all of them and starting from scratch each
+// time.  Alternate:  Follow the current pointer if non-NULL then go
+// up/down the list to find the current switchover point between
+// letters.
+//
+// Better:  Tie into the station insert function.  If a new letter
+// is inserted, or a new station at the beginning of a letter group,
+// run this function to keep things up to date.  That way we won't
+// have to traverse in both directions to find a callsign in the
+// search_station_name() function.
+//
+// If hash_key_in is -1, we need to redo all of the hash keys.  If
+// it is between 0 and 16383, then we need to redo just that one
+// hash key.  The 2nd parameter is either NULL for a removed record,
+// or a pointer to a new station record in the case of an addition.
+//
+void station_shortcuts_update_function(int hash_key_in, DataRow *p_rem) {
+    int ii;
+    DataRow *ptr;
+    int prev_hash_key = 0x0000;
+    int hash_key;
+
+
+// I just changed the function so that we can pass in the hash_key
+// that we wish to update:  We should be able to speed things up by
+// updating one hash key instead of all 16384 pointers.
+
+    if ( (hash_key_in != -1)
+            && (hash_key_in >= 0)
+            && (hash_key_in < 16384) ) {
+
+        // We're adding/changing a hash key entry
+        station_shortcuts[hash_key_in] = p_rem;
+//fprintf(stderr,"%i ",hash_key_in);
+    }
+    else {  // We're removing a hash key entry.
+
+        // Clear and rebuild the entire hash table.
+
+//??????????????????????????????????????????????????
+    // Clear all of the pointers before we begin????
+//??????????????????????????????????????????????????
+        for (ii = 0; ii < 16384; ii++) {
+            station_shortcuts[ii] = NULL;
+        }
+
+        ptr = n_first;  // Start of list
+
+
+        // Loop through entire list, writing the pointer into the
+        // station_shortcuts array whenever a new character is
+        // encountered.  Do this until the end of the array or the end
+        // of the list.
+        //
+        while ( (ptr != NULL) && (prev_hash_key < 16384) ) {
+
+            // We create the hash key out of the lower 7 bits of the
+            // first two characters, creating a 14-bit key (1 of 16384)
+            //
+            hash_key = (int)((ptr->call_sign[0] & 0x7f) << 7);
+            hash_key = hash_key | (int)(ptr->call_sign[1] & 0x7f);
+
+            if (hash_key > prev_hash_key) {
+
+                // We found the next hash_key.  Store the pointer at the
+                // correct location.
+                if (hash_key < 16384) {
+                    station_shortcuts[hash_key] = ptr;
+//fprintf(stderr,"%i ", hash_key);
+                }
+                prev_hash_key = hash_key;
+            }
+            ptr = ptr->n_next;
+        }
+//fprintf(stderr,"\n");
+
+    }
+
+}
+
+
+
+
+
+//
+// Search station record by callsign
+// Returns a station with a call equal or after the searched one
+//
+// We use a doubly-linked list for the stations, so we can traverse
+// in either direction.  We also use a 14-bit hash table created
+// from the first two letters of the call to dump us into the
+// beginning of the correct area that may hold the callsign, which
+// reduces search time quite a bit.  We end up doing a linear search
+// only through a small area of the linked list.
+//
+// DK7IN:  I don't look at case, objects and internet names could
+// have lower case.
+//
+int search_station_name(DataRow **p_name, char *call, int exact) {
+    int kk;
+    int hash_key;
+    int result;
+    int ok = 1;
+
+
+    (*p_name) = n_first;                                // start of alphabet
+
+    if (call[0] == '\0') {
+        // If call we're searching for is empty, return n_first as
+        // the pointer.
+        return(0);
+    }
+
+    // We create the hash key out of the lower 7 bits of the first
+    // two characters, creating a 14-bit key (1 of 16384)
+    //
+    hash_key = (int)((call[0] & 0x7f) << 7);
+    hash_key = hash_key | (int)(call[1] & 0x7f);
+
+    // Look for a match using hash table lookup
+    //
+    (*p_name) = station_shortcuts[hash_key];
+
+    if ((*p_name) == NULL) {    // No hash-table entry found.
+        int mm;
+
+//fprintf(stderr,"No hash-table entry found: call:%s\n",call);
+
+
+        // No index found for that letter.  Walk the array until
+        // we find an entry that is filled.  That'll be our
+        // potential insertion point (insertion into the list will
+        // occur just ahead of the hash entry).
+        for (mm = hash_key; mm < 16384; mm++) {
+            if (station_shortcuts[mm] != NULL) {
+                (*p_name) = station_shortcuts[mm];
+                break;
+            }
+        }
+    }
+//    else {
+//fprintf(stderr,"Hash key %d=%s, searching for call: %s\n",
+//    hash_key,
+//    (*p_name)->call_sign,
+//    call);
+//    }
+
+    // If we got to this point, we either have a NULL pointer or a
+    // real hash-table pointer entry.  A non-NULL pointer means that
+    // we have a match for the lower seven bits of the first two
+    // characters of the callsign.  Check the rest of the callsign,
+    // and jump out of the loop if we get outside the linear search
+    // area (if first two chars are different).
+
+    kk = (int)strlen(call);
+
+    // Search linearly through list.  Stop at end of list or break.
+    while ( (*p_name) != NULL) {
+
+        if (exact) {
+            // Check entire string for exact match
+            result = strcmp( call, (*p_name)->call_sign );
+        }
+        else {
+            // Check first part of string for match
+            result = strncmp( call, (*p_name)->call_sign, kk );
+        }
+
+        if (result < 0) {   // We went past the right location.
+                            // We're done.
+            ok = 0;
+//fprintf(stderr,"Went past possible entry point, searching for call: %s\n",call);
+            break;
+        }
+        else if (result == 0) { // Found a possible match
+//fprintf(stderr,"Found possible match: list:%s call:%s\n",
+//    (*p_name)->call_sign,
+//    call);
+            break;
+        }
+        else {  // Result > 0.  We haven't found it yet.
+            (*p_name) = (*p_name)->n_next;  // Next element in list
+        }
+    }
+
+    // Did we find anything?
+    if ( (*p_name) == NULL) {
+        ok = 0;
+//fprintf(stderr,"End of list reached, call: %s\n",call);
+        return(ok); // Nope.  No match found.
+    }
+
+    // If "exact" is set, check that the string lengths match as
+    // well.  If not, we didn't find it.
+    if (exact && ok && strlen((*p_name)->call_sign) != strlen(call))
+        ok = 0;
+
+    return(ok);         // if not ok: p_name points to correct insert position in name list
+}
+
+
+
+
+
+/*    
+ *  Search station record by time and time serial number, serial ignored if -1
+ *  Returns a station that is equal or older than the search criterium
+ */
+int search_station_time(DataRow **p_time, time_t heard, int serial) {
+    int ok = 1;
+
+    (*p_time) = t_newest;                                 // newest station
+    if (heard == 0) {                                   // we want the newest station
+        if (t_newest == NULL)
+            ok = 0;                                     // empty list
+    }
+    else {
+        while((*p_time) != NULL) {                      // check time
+            if ((*p_time)->sec_heard <= heard)          // compare
+                break;                                  // found time or earlier
+            (*p_time) = (*p_time)->t_older;              // next element
+        }
+        // we now probably have found the entry
+        if ((*p_time) != NULL && (*p_time)->sec_heard == heard) {
+            // we got a match, but there may be more of them
+            if (serial >= 0) {                          // check serial number, ignored if -1
+                while((*p_time) != NULL) {              // for unique time index
+                    if ((*p_time)->sec_heard == heard && (*p_time)->time_sn <= serial)  // compare
+                        break;                          // found it (same time, maybe earlier SN)
+                    if ((*p_time)->sec_heard < heard)   // compare
+                        break;                          // found it (earlier time)
+                    (*p_time) = (*p_time)->t_older;      // consider next element
+                }
+                if ((*p_time) == NULL || (*p_time)->sec_heard != heard || (*p_time)->time_sn != serial)
+                    ok = 0;                             // no perfect match
+            }
+        }
+        else
+            ok = 0;                                     // no perfect match
+    }
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Get pointer to next station in name sorted list
+ */
+int next_station_name(DataRow **p_curr) {
+    
+    if ((*p_curr) == NULL)
+        (*p_curr) = n_first;
+    else
+        (*p_curr) = (*p_curr)->n_next;
+    if ((*p_curr) != NULL)
+        return(1);
+    else
+        return(0);
+}
+
+
+
+
+
+/*
+ *  Get pointer to previous station in name sorted list
+ */
+int prev_station_name(DataRow **p_curr) {
+    
+    if ((*p_curr) == NULL)
+        (*p_curr) = n_last;
+    else
+        (*p_curr) = (*p_curr)->n_prev;
+    if ((*p_curr) != NULL)
+        return(1);
+    else
+        return(0);
+}
+
+
+
+    
+
+/*
+ *  Get pointer to newer station in time sorted list
+ */
+int next_station_time(DataRow **p_curr) {
+
+    if ((*p_curr) == NULL)
+        (*p_curr) = t_oldest;    // Grab oldest station if NULL passed to us???
+    else
+        (*p_curr) = (*p_curr)->t_newer;  // Else grab newer station
+    if ((*p_curr) != NULL)
+        return(1);
+    else
+        return(0);
+}
+
+
+
+
+
+/*
+ *  Get pointer to older station in time sorted list
+ */
+int prev_station_time(DataRow **p_curr) {
+    
+    if ((*p_curr) == NULL)
+        (*p_curr) = t_newest; // Grab newest station if NULL passed to us???
+    else
+        (*p_curr) = (*p_curr)->t_older;
+    if ((*p_curr) != NULL)
+        return(1);
+    else
+        return(0);
+}
+
+
+
+
+
+/*
+ *  Set flag for all stations in current view area or a margin area around it
+ *  That are the stations we look at if we want to draw symbols or trails
+ */
+void setup_in_view(void) {
+    DataRow *p_station;
+    long min_lat, max_lat;                      // screen borders plus space
+    long min_lon, max_lon;                      // for trails from off-screen stations
+    long marg_lat, marg_lon;                    // margin around screen
+
+    marg_lat = (long)(3 * screen_height * scale_y/2);
+    marg_lon = (long)(3 * screen_width  * scale_x/2);
+    if (marg_lat < IN_VIEW_MIN*60*100)          // allow a minimum area, 
+        marg_lat = IN_VIEW_MIN*60*100;          // there could be outside stations
+    if (marg_lon < IN_VIEW_MIN*60*100)          // with trail parts on screen
+        marg_lon = IN_VIEW_MIN*60*100;
+
+    // Only screen view
+    // min_lat = SE_corner_latitude
+    // max_lat = NW_corner_latitude;
+    // min_lon = NW_corner_longitude;
+    // max_lon = SE_corner_longitude;
+
+    // Screen view plus one screen wide margin
+    // There could be stations off screen with on screen trails
+    // See also the use of position_on_extd_screen()
+    min_lat = center_latitude  - marg_lat;
+    max_lat = center_latitude  + marg_lat;
+    min_lon = center_longitude - marg_lon;
+    max_lon = center_longitude + marg_lon;
+
+    p_station = n_first;
+    while (p_station != NULL) {
+        if ((p_station->flag & ST_ACTIVE) == 0        // ignore deleted objects
+                  || p_station->coord_lon < min_lon || p_station->coord_lon > max_lon
+                  || p_station->coord_lat < min_lat || p_station->coord_lat > max_lat
+                  || (p_station->coord_lat == 0 && p_station->coord_lon == 0)) {
+            // outside view and undefined stations:
+            p_station->flag &= (~ST_INVIEW);        // clear "In View" flag
+        }
+        else
+            p_station->flag |= ST_INVIEW;           // set "In View" flag
+        p_station = p_station->n_next;
+    }
+}
+
+
+
+
+
+/*
+ *  Check if position is inside screen borders
+ */
+int position_on_screen(long lat, long lon) {
+
+    if (   lon > NW_corner_longitude && lon < SE_corner_longitude
+            && lat > NW_corner_latitude && lat < SE_corner_latitude 
+            && !(lat == 0 && lon == 0))     // discard undef positions from screen
+        return(1);                      // position is inside the screen
+    else
+        return(0);
+}
+
+
+
+
+
+/*
+ *  Check if position is inside extended screen borders
+ *  (real screen + one screen margin for trails)
+ *  used for station "In View" flag
+ */
+int position_on_extd_screen(long lat, long lon) {
+    long marg_lat, marg_lon;                    // margin around screen
+
+    marg_lat = (long)(3 * screen_height * scale_y/2);
+    marg_lon = (long)(3 * screen_width  * scale_x/2);
+    if (marg_lat < IN_VIEW_MIN*60*100)          // allow a minimum area, 
+        marg_lat = IN_VIEW_MIN*60*100;          // there could be outside stations
+    if (marg_lon < IN_VIEW_MIN*60*100)          // with trail parts on screen
+        marg_lon = IN_VIEW_MIN*60*100;
+
+    if (    abs(lon - center_longitude) < marg_lon
+         && abs(lat - center_latitude)  < marg_lat
+         && !(lat == 0 && lon == 0))    // discard undef positions from screen
+        return(1);                      // position is inside the area
+    else
+        return(0);
+}
+
+
+
+
+
+/*
+ *  Check if position is inside inner screen area
+ *  (real screen + minus 1/6 screen margin)
+ *  used for station tracking
+ */
+int position_on_inner_screen(long lat, long lon) {
+
+    if (    lon > center_longitude-(long)(screen_width *scale_x/3)
+         && lon < center_longitude+(long)(screen_width *scale_x/3)
+         && lat > center_latitude -(long)(screen_height*scale_y/3)
+         && lat < center_latitude +(long)(screen_height*scale_y/3)
+         && !(lat == 0 && lon == 0))    // discard undef positions from screen
+        return(1);                      // position is inside the area
+    else
+        return(0);
+}
+
+
+
+
+
+/*
+ *  Delete single station with all its data    ?? delete messages ??
+ *  This function is called with a callsign parameter.  Only used for
+ *  my callsign, not for any other.
+ */
+void station_del(char *call) {
+    DataRow *p_name;                      // DK7IN: do it with move... ?
+
+    if (search_station_name(&p_name, call, 1)) {
+        (void)delete_trail(p_name);       // Free track storage if it exists.
+        (void)delete_weather(p_name);     // Free weather memory, if allocated
+        (void)delete_multipoints(p_name); // Free multipoint memory, if allocated
+        (void)delete_comments_and_status(p_name);  // Free comment storage if it exists
+        if (p_name->node_path_ptr != NULL)// Free malloc'ed path
+            free(p_name->node_path_ptr);
+        if (p_name->tactical_call_sign != NULL)
+            free(p_name->tactical_call_sign);
+        delete_station_memory(p_name);    // Free memory
+    }
+}
+
+
+
+
+
+/*
+ *  Delete single station with all its data    ?? delete messages ??
+ *  This function is called with a pointer instead of a callsign.
+ */
+void station_del_ptr(DataRow *p_name) {
+
+//fprintf(stderr,"db.c:station_del_ptr(): %s\n",p_name->call_sign);
+
+    if (p_name != NULL) {
+
+        // A bit of debug code:  Attempting to find out if we're
+        // deleting our own objects from time to time.  Leave this
+        // in until we're sure the problem has been fixed.
+////        if (is_my_call(p_name->origin,1)) { // Check SSID as well
+//        if ( is_my_object_item(p_name) ) { // Check SSID as well
+//            fprintf(stderr,"station_del_ptr: Removing my own object: %s\n",
+//                p_name->call_sign);
+//        }
+
+#ifdef EXPIRE_DEBUG
+        fprintf(stderr,"Removing: %s heard %d seconds ago\n",p_name->call_sign, (int)(sec_now() - p_name->sec_heard));
+#endif
+
+        (void)delete_trail(p_name);     // Free track storage if it exists.
+        (void)delete_weather(p_name);   // free weather memory, if allocated
+        (void)delete_multipoints(p_name); // Free multipoint memory, if allocated
+        (void)delete_comments_and_status(p_name);  // Free comment storage if it exists
+        if (p_name->node_path_ptr != NULL)  // Free malloc'ed path
+            free(p_name->node_path_ptr);
+        if (p_name->tactical_call_sign != NULL)
+            free(p_name->tactical_call_sign);
+        delete_station_memory(p_name);  // free memory, update
+                                        // linked lists, update
+                                        // station_count
+
+//fprintf(stderr,"db.c:station_del_ptr(): Deleted station\n");
+
+    }
+}
+
+
+
+
+
+/*
+ *  Delete all stations             ?? delete messages ??
+ */
+void delete_all_stations(void) {
+    DataRow *p_name;
+    DataRow *p_curr;
+    int ii;
+ 
+
+    // Clear all of the pointers before we begin
+    for (ii = 0; ii < 16384; ii++) {
+        station_shortcuts[ii] = NULL;
+    }
+   
+    p_name = n_first;
+    while (p_name != NULL) {
+        p_curr = p_name;
+        p_name = p_name->n_next;
+        station_del_ptr(p_curr);
+        //(void)delete_trail(p_curr);     // free trail memory, if allocated
+        //(void)delete_weather(p_curr);   // free weather memory, if allocated
+        //(void)delete_multipoints(p_curr);// Free multipoint memory, if allocated
+        //delete_station_memory(p_curr);  // free station memory
+    }
+    if (station_count != 0) {
+        fprintf(stderr,
+            "ERROR: station_count should be 0 after stations delete, is %d\n",
+            station_count);
+        station_count = 0;
+    }    
+}
+
+
+
+
+
+/*
+ *  Check if we have to delete old stations.
+ *
+ *  Called from main.c:UpdateTime() on a periodic basis.
+ *
+ */
+void check_station_remove(time_t curr_sec) {
+    DataRow *p_station, *p_station_t_newer;
+    time_t t_rem;
+    int done;
+
+
+    // Run through this routine every STATION_REMOVE_CYCLE
+    // seconds (currently every five minutes)
+#ifdef EXPIRE_DEBUG
+    // Check every 15 seconds, useful for debug only.
+    if (last_station_remove < (curr_sec - DEBUG_STATION_REMOVE_CYCLE)) {   // DEBUG
+#else
+    if (last_station_remove < (curr_sec - STATION_REMOVE_CYCLE)) {
+#endif
+
+
+//fprintf(stderr,"db.c:check_station_remove() is running\n");
+
+        // Compute the cutoff time.  Any stations older than t_rem
+        // will be removed, unless they have a tactical call or
+        // belong to us.
+        t_rem = curr_sec - sec_remove;
+
+#ifdef EXPIRE_DEBUG
+        // Expire every 15 seconds, useful for debug only.
+        t_rem = curr_sec - (1 * DEBUG_STATION_REMOVE);
+#endif
+
+        for (done = 0, p_station = t_oldest; p_station != NULL && !done; p_station = p_station_t_newer) {
+
+            // Save a pointer to the next record in time-order
+            // before we delete a record and lose it.
+            p_station_t_newer = p_station->t_newer;
+
+            if (p_station->sec_heard < t_rem) {
+
+//                if ( (is_my_call(p_station->call_sign,1)) // It's my station (including SSID) or
+//                        || ( (is_my_call(p_station->origin,1)) // Station is owned by me (including SSID)
+//                          && ( ((p_station->flag & ST_OBJECT) != 0) // and it's an object
+//                            || ((p_station->flag & ST_ITEM  ) != 0) ) ) ) { // or an item
+                if ( is_my_station(p_station) || is_my_object_item(p_station)) {
+
+                    // It's one of mine, leave it alone!
+
+#ifdef EXPIRE_DEBUG
+                    fprintf(stderr,"found old station: %s\t\t",p_station->call_sign);
+                    fprintf(stderr,"mine\n");
+#endif
+
+                }
+
+/*
+                else if (p_station->tactical_call_sign) {
+                    // Station has a tactical callsign assigned,
+                    // don't delete it.
+
+#ifdef EXPIRE_DEBUG
+                    fprintf(stderr,"found old station: %s\t\t",p_station->call_sign);
+                    fprintf(stderr,"tactical\n");
+#endif
+
+                }
+*/
+
+                else {  // Not one of mine, doesn't have a tactical
+                        // callsign assigned, so start deleting
+
+                    //The debug output needs to be before the delete, as 
+                    // we're freeing the data pointed to by p_station! 
+#ifdef EXPIRE_DEBUG
+                    fprintf(stderr,"found old station: %s\t\t",p_station->call_sign);
+                    fprintf(stderr,"deleting\n");
+                    fprintf(stderr,"Last heard time: %ld\n",p_station->sec_heard);
+                    fprintf(stderr," t_rem: %ld\n",t_rem);
+                    fprintf(stderr," next older record has time %ld\n",p_station_t_newer->sec_heard);
+#endif
+
+                    mdelete_messages(p_station->call_sign); // Delete messages
+                    station_del_ptr(p_station);
+                    //(void)delete_trail(p_station);        // Free track storage if it exists.
+                    //(void)delete_weather(p_station);      // Free weather memory, if allocated
+                    //(void)delete_multipoints(p_station);  // Free multipoint memory, if allocated
+                    //delete_station_memory(p_station);     // Free memory
+
+                }
+            }
+            else {
+#ifdef EXPIRE_DEBUG
+                DataRow *testPtr = sanity_check_time_list(t_rem);
+                if (testPtr) {
+                    fprintf(stderr,"TIME-SORTED LIST SANITY CHECK FAILED!\n");
+                    fprintf(stderr," At least one station left after expire with time older than %ld\n",t_rem);
+                    fprintf(stderr,"   Station name: %s\n", testPtr->call_sign);
+                    fprintf(stderr,"   Last heard time %ld\n",testPtr->sec_heard);
+                    fprintf(stderr,"   Seconds ago: %ld\n",curr_sec-testPtr->sec_heard);
+                    fprintf(stderr,"   Seconds older than expire time: %ld\n",t_rem-testPtr->sec_heard);
+                    fprintf(stderr,"--------\n");
+                    dump_time_sorted_list();
+                }
+#endif
+                done++;                                         // all other stations are newer...
+            }
+        }
+        last_station_remove = curr_sec;
+    }
+}
+
+
+
+
+
+/*
+ *  Delete an object (mark it as deleted)
+ */
+void delete_object(char *name) {
+    DataRow *p_station;
+
+//fprintf(stderr,"delete_object\n");
+
+    p_station = NULL;
+    if (search_station_name(&p_station,name,1)) {       // find object name
+        p_station->flag &= (~ST_ACTIVE);                // clear flag
+        p_station->flag &= (~ST_INVIEW);                // clear "In View" flag
+        if (position_on_screen(p_station->coord_lat,p_station->coord_lon))
+            redraw_on_new_data = 2;                     // redraw now
+            // there is some problem...  it is not redrawn immediately! ????
+            // but deleted from list immediatetly
+        redo_list = (int)TRUE;                          // and update lists
+    }
+}
+
+
+
+
+
+///////////////////////////////////////  APRS Decoding  ////////////////////////////////////////////
+
+/*
+ * Try to find a !DAO! format datum and extra precision string from the
+ * comment field of an APRS location packet (incl. objects and items).
+ * If !DAO! is found, it is removed from the comment.
+ * See http://web.ew.usna.edu/~bruninga/aprs/datum.txt
+ *
+ * lat and lon will contain the thousandth and ten thousandth
+ * minute digits of the location, if valid (see below).
+ * For example, if the final location is 70 deg 12.3456 minutes,
+ * lat or lon will contain 56. If the final location is
+ * 50 deg 56.2104 minutes, lat or lon will contain 4. So remember
+ * to zero pad! The range for lat/lon, when valid, is 0-99.
+ * datumch will contain the datum character, if found.
+ *
+ * daocomment must be null-terminated and must contain the comment field
+ *
+ * returns 3 if dao was found and contained a base-91 position
+ *   (= datumch, lat, and lon contents are all valid)
+ * returns 2 if dao was found and contained a human readable position
+ *   (= datumch, lat, and lon contents are all valid)
+ * returns 1 if dao was found but only included datum information
+ *   (= only datumch is valid)
+ * returns 0 if no valid dao was found
+ *   (= datumch, lat, and lon contents are all invalid, daocomment is unmodified)
+ *
+ * Tapio Sokura OH2KKU <tapio.sokura at iki.fi> 2007-11-15
+ */
+int decode_dao (int *lat, int *lon, char *datumch, char *daocomment) {
+	char *searchval, *rval;
+	size_t slen;
+
+	// Loop around searching for !DAO!, return the first valid match.
+	// The first '!' is found using strchr, the rest of the
+	// string is validated more manually.
+	searchval = daocomment;
+	rval = strchr(searchval, '!');
+	while (rval != NULL) {
+
+		// Check the remaining string length so we don't
+		// run past string end
+		slen = strlen(rval);
+		if (slen < 5) {
+			break;
+		}
+
+		if (rval[4] == '!' && rval[1] >= '!' && rval[1] <= '{') {
+			// found the !DAO! terminator and datum char is
+			// within the allowable range
+
+			if (rval[1] >= 'A' && rval[1] <= 'Z') {
+				// looks like human readable format
+
+				if (rval[2] == ' ' && rval[3] == ' ') {
+					// only datum information present
+					*datumch = rval[1];
+					memmove(rval, rval + 5, slen - 4);
+					return 1;
+
+				} else if (rval[2] >= '0' && rval[2] <= '9' &&
+					   rval[3] >= '0' && rval[3] <= '9') {
+					// human readable format 0-9 lat/lon ok
+
+					// ASCII - 48 = the integer digit we want.
+					// Multiply by 10, because we only get
+					// thousandths of a minute with human
+					// readable format.
+					*lat = ((int)rval[2] - 48) * 10;
+					*lon = ((int)rval[3] - 48) * 10;
+					*datumch = rval[1];
+					memmove(rval, rval + 5, slen - 4);
+					return 2;
+				}
+				// not ok for human readable format, continue searching
+
+			} else if (rval[1] >= 'a' && rval[1] <= 'z') {
+				// looks like base-91 format
+
+				if (rval[2] == ' ' && rval[3] == ' ') {
+					// only datum information present
+					*datumch = rval[1];
+					memmove(rval, rval + 5, slen - 4);
+					return 1;
+
+				} else if (rval[2] >= '!' && rval[2] <= '{' &&
+					   rval[3] >= '!' && rval[3] <= '{') {
+					// base-91 lat/lon ok
+					unsigned int lats, lons;
+					float latval, lonval;
+					lats = rval[2] - 33; // get base91 values
+					lons = rval[3] - 33;
+					latval = lats / 91.0 * 100; // do proper scaling
+					lonval = lons / 91.0 * 100;
+					*lat = (int)(latval + 0.5); // round and store
+					*lon = (int)(lonval + 0.5);
+					*datumch = rval[1];
+					memmove(rval, rval + 5, slen - 4);
+					return 3;
+				}
+				// not ok for base91 format, continue searching
+			}
+			// Datum chars outside A-Z and a-z are not
+			// handled (here at least).
+		}
+		
+		// If we end up here, we didn't find a match.
+		// Search for the next '!' char.
+		searchval = rval + 1;
+		rval = strchr(searchval, '!');
+	}
+
+	// No more string left to search and no match.
+	return 0;
+}
+
+
+
+/*
+ *  Extract Uncompressed Position Report from begin of line
+ *
+ * If a position is found, it is deleted from the data.
+ */
+int extract_position(DataRow *p_station, char **info, int type) {
+    int ok, dao_lat, dao_lon, dao_rval;
+    char temp_lat[10+1];
+    char temp_lon[11+1];
+    char temp_grid[8+1];
+    char *my_data;
+    char dao_datumch;
+    float gridlat;
+    float gridlon;
+    my_data = (*info);
+
+    if (type != APRS_GRID){ // Not a grid
+        ok = (int)(strlen(my_data) >= 19);
+        ok = (int)(ok && my_data[4]=='.' && my_data[14]=='.'
+            && (toupper(my_data[7]) =='N' || toupper(my_data[7]) =='S')
+            && (toupper(my_data[17])=='E' || toupper(my_data[17])=='W'));
+        // errors found:  [4]: X   [7]: n s   [17]: w e
+        if (ok) {
+            ok =             is_num_chr(my_data[0]);           // 5230.31N/01316.88E>
+            ok = (int)(ok && is_num_chr(my_data[1]));          // 0123456789012345678
+            ok = (int)(ok && is_num_or_sp(my_data[2]));
+            ok = (int)(ok && is_num_or_sp(my_data[3]));
+            ok = (int)(ok && is_num_or_sp(my_data[5]));
+            ok = (int)(ok && is_num_or_sp(my_data[6]));
+            ok = (int)(ok && is_num_chr(my_data[9]));
+            ok = (int)(ok && is_num_chr(my_data[10]));
+            ok = (int)(ok && is_num_chr(my_data[11]));
+            ok = (int)(ok && is_num_or_sp(my_data[12]));
+            ok = (int)(ok && is_num_or_sp(my_data[13]));
+            ok = (int)(ok && is_num_or_sp(my_data[15]));
+            ok = (int)(ok && is_num_or_sp(my_data[16]));
+        }
+                                            
+        if (ok) {
+            overlay_symbol(my_data[18], my_data[8], p_station);
+            p_station->pos_amb = 0;
+            // spaces in latitude set position ambiguity, spaces in longitude do not matter
+            // we will adjust the lat/long to the center of the rectangle of ambiguity
+            if (my_data[2] == ' ') {      // nearest degree
+                p_station->pos_amb = 4;
+                my_data[2]  = my_data[12] = '3';
+                my_data[3]  = my_data[5]  = my_data[6]  = '0';
+                my_data[13] = my_data[15] = my_data[16] = '0';
+            }
+            else if (my_data[3] == ' ') { // nearest 10 minutes
+                p_station->pos_amb = 3;
+                my_data[3]  = my_data[13] = '5';
+                my_data[5]  = my_data[6]  = '0';
+                my_data[15] = my_data[16] = '0';
+            }
+            else if (my_data[5] == ' ') { // nearest minute
+                p_station->pos_amb = 2;
+                my_data[5]  = my_data[15] = '5';
+                my_data[6]  = '0';
+                my_data[16] = '0';
+            }
+            else if (my_data[6] == ' ') { // nearest 1/10th minute
+                p_station->pos_amb = 1;
+                my_data[6]  = my_data[16] = '5';
+            }
+
+            xastir_snprintf(temp_lat,
+                sizeof(temp_lat),
+                "%s",
+                my_data);
+            temp_lat[9] = toupper(my_data[7]);
+            temp_lat[10] = '\0';
+
+            xastir_snprintf(temp_lon,
+                sizeof(temp_lon),
+                "%s",
+                my_data+9);
+            temp_lon[10] = toupper(my_data[17]);
+            temp_lon[11] = '\0';
+
+            // Check for !DAO!, beginning from the comment field.
+            // Datum is not used for the time being.
+            // Note: error/precision information (the white box on the map) is
+            // not updated here, because changes to p_station->lat/lon_precision
+            // are overridden in the calling function.
+            dao_rval = decode_dao(&dao_lat, &dao_lon, &dao_datumch, my_data + 19);
+            if (dao_rval == 2 || dao_rval == 3) {
+            	// 48 is the magic number to add to a single digit integer to
+            	// get the same digit in ASCII.
+            	temp_lat[7] = (char)(dao_lat / 10 + 48);
+            	temp_lat[8] = (char)(dao_lat % 10 + 48);
+            	temp_lon[8] = (char)(dao_lon / 10 + 48);
+            	temp_lon[9] = (char)(dao_lon % 10 + 48);
+            	// Signal that this is an accuracy-enhanced !DAO! position,
+            	// so the calling function can set the error boxes accordingly
+            	// (once somebody implements it).
+            	ok = dao_rval;
+            } else {
+            	// no valid !DAO! _location_ found, pad with zeroes instead
+            	temp_lat[7] = '0';
+            	temp_lat[8] = '0';
+            	temp_lon[8] = '0';
+            	temp_lon[9] = '0';
+            }
+
+            // Callsign check here also checks SSID for an exact
+            // match
+//            if (!is_my_call(p_station->call_sign,1)) {      // don't change my position, I know it better...
+            if ( !(is_my_station(p_station)) ) {      // don't change my position, I know it better...
+
+                p_station->coord_lat = convert_lat_s2l(temp_lat);   // ...in case of position ambiguity
+                p_station->coord_lon = convert_lon_s2l(temp_lon);
+            }
+
+            (*info) += 19;                  // delete position from comment
+        }
+    }
+    else { // It is a grid 
+        // first sanity checks, need more
+        ok = (int)(is_num_chr(my_data[2]));
+        ok = (int)(ok && is_num_chr(my_data[3]));
+        ok = (int)(ok && ((my_data[0]>='A')&&(my_data[0]<='R')));
+        ok = (int)(ok && ((my_data[1]>='A')&&(my_data[1]<='R')));
+        if (ok) {
+            xastir_snprintf(temp_grid,
+                sizeof(temp_grid),
+                "%s",
+                my_data);
+            // this test treats >6 digit grids as 4 digit grids; >6 are uncommon.
+            // the spec mentioned 4 or 6, I'm not sure >6 is even allowed.
+            if ( (temp_grid[6] != ']') || (temp_grid[4] == 0) || (temp_grid[5] == 0)){
+                p_station->pos_amb = 6; // 1deg lat x 2deg lon 
+                temp_grid[4] = 'L';
+                temp_grid[5] = 'L';
+            }
+            else {
+                p_station->pos_amb = 5; // 2.5min lat x 5min lon
+                temp_grid[4] = toupper(temp_grid[4]); 
+                temp_grid[5] = toupper(temp_grid[5]);
+            }
+            // These equations came from what I read in the qgrid source code and
+            // various mailing list archives.
+            gridlon= (20.*((float)temp_grid[0]-65.) + 2.*((float)temp_grid[2]-48.) + 5.*((float)temp_grid[4]-65.)/60.) - 180.;
+            gridlat= (10.*((float)temp_grid[1]-65.) + ((float)temp_grid[3]-48.) + 5.*(temp_grid[5]-65.)/120.) - 90.;
+            // could check for my callsign here, and avoid changing it...
+            p_station->coord_lat = (unsigned long)(32400000l + (360000.0 * (-gridlat)));
+            p_station->coord_lon = (unsigned long)(64800000l + (360000.0 * gridlon));
+            p_station->aprs_symbol.aprs_type = '/';
+            p_station->aprs_symbol.aprs_symbol = 'G';
+        }        // is it valid grid or not - "ok"
+        // could cut off the grid square from the comment here, but why bother?
+    } // is it grid or not
+    return(ok);
+}
+
+
+
+
+
+// DK7IN 99
+/*
+ *  Extract Compressed Position Report Data Formats from begin of line
+ *    [APRS Reference, chapter 9]
+ *
+ * If a position is found, it is deleted from the data.  If a
+ * compressed position is found, delete the three csT bytes as well,
+ * even if all spaces.
+ * Returns 0 if the packet is NOT a properly compressed position
+ * packet, returns 1 if ok.
+ */
+int extract_comp_position(DataRow *p_station, char **info, /*@unused@*/ int type) {
+    int ok;
+    int x1, x2, x3, x4, y1, y2, y3, y4;
+    int c = 0;
+    int s = 0;
+    int T = 0;
+    int len;
+    char *my_data;
+    float lon = 0;
+    float lat = 0;
+    float range;
+    int skip = 0;
+    char L;
+
+
+    if (debug_level & 1)
+        fprintf(stderr,"extract_comp_position: Start\n");
+
+    //fprintf(stderr,"extract_comp_position start: %s\n",*info);
+
+    // compressed data format  /YYYYXXXX$csT  is a fixed 13-character field
+    // used for ! / @ = data IDs
+    //   /     Symbol Table ID or overlay: '/' '\' A-Z a-j
+    //   YYYY  compressed latitude
+    //   XXXX  compressed longitude
+    //   $     Symbol Code
+    //   cs    compressed
+    //            course/speed
+    //            radio range
+    //            altitude
+    //   T     compression type ID
+
+    my_data = (*info);
+
+    // Check leading char.  Must be one of these:
+    // '/'
+    // '\'
+    // A-Z
+    // a-j
+    //
+    L = my_data[0];
+    if (   L == '/'
+        || L == '\\'
+        || ( L >= 'A' && L <= 'Z' )
+        || ( L >= 'a' && L <= 'j' ) ) {
+        // We're good so far
+    }
+    else {
+        // Note one of the symbol table or overlay characters, so
+        // there's something funky about this packet.  It's not a
+        // properly formatted compressed position.
+        return(0);
+    }
+
+    //fprintf(stderr,"my_data: %s\n",my_data);
+
+    // If c = space, csT bytes are ignored.  Minimum length:  8
+    // bytes for lat/lon, 2 for symbol, 3 for csT for a total of 13.
+    len = strlen(my_data);
+    ok = (int)(len >= 13);
+
+    if (ok) {
+        y1 = (int)my_data[1] - '!';
+        y2 = (int)my_data[2] - '!';
+        y3 = (int)my_data[3] - '!';
+        y4 = (int)my_data[4] - '!';
+        x1 = (int)my_data[5] - '!';
+        x2 = (int)my_data[6] - '!';
+        x3 = (int)my_data[7] - '!';
+        x4 = (int)my_data[8] - '!';
+
+        // csT bytes
+        if (my_data[10] == ' ') // Space
+            c = -1; // This causes us to ignore csT
+        else {
+            c = (int)my_data[10] - '!';
+            s = (int)my_data[11] - '!';
+            T = (int)my_data[12] - '!';
+        }
+        skip = 13;
+
+        // Convert ' ' to '0'.  Not specified in APRS Reference!  Do
+        // we need it?
+        if (x1 == -1) x1 = '\0';
+        if (x2 == -1) x2 = '\0';
+        if (x3 == -1) x3 = '\0';
+        if (x4 == -1) x4 = '\0';
+        if (y1 == -1) y1 = '\0';
+        if (y2 == -1) y2 = '\0';
+        if (y3 == -1) y3 = '\0';
+        if (y4 == -1) y4 = '\0';
+
+        ok = (int)(ok && (x1 >= '\0' && x1 < 91));  //  /YYYYXXXX$csT
+        ok = (int)(ok && (x2 >= '\0' && x2 < 91));  //  0123456789012
+        ok = (int)(ok && (x3 >= '\0' && x3 < 91));
+        ok = (int)(ok && (x4 >= '\0' && x4 < 91));
+        ok = (int)(ok && (y1 >= '\0' && y1 < 91));
+        ok = (int)(ok && (y2 >= '\0' && y2 < 91));
+        ok = (int)(ok && (y3 >= '\0' && y3 < 91));
+        ok = (int)(ok && (y4 >= '\0' && y4 < 91));
+
+        T &= 0x3F;      // DK7IN: force Compression Byte to valid format
+                        // mask off upper two unused bits, they should be zero!?
+
+        ok = (int)(ok && (c == -1 || ((c >=0 && c < 91) && (s >= 0 && s < 91) && (T >= 0 && T < 64))));
+
+        if (ok) {
+            lat = (((y1 * 91 + y2) * 91 + y3) * 91 + y4 ) / 380926.0; // in deg, 0:  90�N
+            lon = (((x1 * 91 + x2) * 91 + x3) * 91 + x4 ) / 190463.0; // in deg, 0: 180�W
+            lat *= 60 * 60 * 100;                       // in 1/100 sec
+            lon *= 60 * 60 * 100;                       // in 1/100 sec
+
+            // The below check should _not_ be done.  Compressed
+            // format can resolve down to about 1 foot worldwide
+            // (0.3 meters).
+            //if ((((long)(lat+4) % 60) > 8) || (((long)(lon+4) % 60) > 8))
+            //    ok = 0;   // check max resolution 0.01 min to
+                            // catch even more errors
+        }
+    }
+
+    if (ok) {
+        overlay_symbol(my_data[9], my_data[0], p_station);      // Symbol / Table
+
+        // Callsign check here includes checking SSID for an exact
+        // match
+//        if (!is_my_call(p_station->call_sign,1)) {  // don't change my position, I know it better...
+        if ( !(is_my_station(p_station)) ) {  // don't change my position, I know it better...
+ 
+            // Record the uncompressed lat/long that we just
+            // computed.
+            p_station->coord_lat = (long)((lat));               // in 1/100 sec
+            p_station->coord_lon = (long)((lon));               // in 1/100 sec
+        }
+
+        if (c >= 0) {                                   // ignore csT if c = ' '
+            if (c < 90) {   // Found course/speed or altitude bytes
+                if ((T & 0x18) == 0x10) {   // check for GGA (with altitude)
+                    xastir_snprintf(p_station->altitude, sizeof(p_station->altitude), "%06.0f",pow(1.002,(double)(c*91+s))*0.3048);
+                }
+                else { // Found compressed course/speed bytes
+
+                    // Convert 0 degrees to 360 degrees so that
+                    // Xastir will see it as a valid course and do
+                    // dead-reckoning properly on this station
+                    if (c == 0) {
+                        c = 90;
+                    }
+
+                    // Compute course in degrees
+                    xastir_snprintf(p_station->course,
+                        sizeof(p_station->course),
+                        "%03d",
+                        c*4);
+
+                    // Compute speed in knots
+                    xastir_snprintf(p_station->speed,
+                        sizeof(p_station->speed),
+                        "%03.0f",
+                        pow( 1.08,(double)s ) - 1.0);
+
+                    //fprintf(stderr,"Decoded speed:%s, course:%s\n",p_station->speed,p_station->course);
+
+                }
+            }
+            else {    // Found pre-calculated radio range bytes
+                if (c == 90) {
+                    // pre-calculated radio range
+                    range = 2 * pow(1.08,(double)s);    // miles
+
+                    // DK7IN: dirty hack...  but better than nothing
+                    if (s <= 5)                         // 2.9387 mi
+                        xastir_snprintf(p_station->power_gain, sizeof(p_station->power_gain), "PHG%s0", "000");
+                    else if (s <= 17)                   // 7.40 mi
+                        xastir_snprintf(p_station->power_gain, sizeof(p_station->power_gain), "PHG%s0", "111");
+                    else if (s <= 36)                   // 31.936 mi
+                        xastir_snprintf(p_station->power_gain, sizeof(p_station->power_gain), "PHG%s0", "222");
+                    else if (s <= 75)                   // 642.41 mi
+                        xastir_snprintf(p_station->power_gain, sizeof(p_station->power_gain), "PHG%s0", "333");
+                    else                       // max 90:  2037.8 mi
+                        xastir_snprintf(p_station->power_gain, sizeof(p_station->power_gain), "PHG%s0", "444");
+                }
+            }
+        }
+        (*info) += skip;    // delete position from comment
+    }
+
+    if (debug_level & 1) {
+        if (ok) {
+            fprintf(stderr,"*** extract_comp_position: Succeeded: %ld\t%ld\n",
+                p_station->coord_lat,
+                p_station->coord_lon);
+        }
+        else {
+            fprintf(stderr,"*** extract_comp_position: Failed!\n");
+        }
+    }
+
+    //fprintf(stderr,"  extract_comp_position end: %s\n",*info);
+
+    return(ok);
+}
+
+
+
+
+
+//
+//  Extract speed and/or course from beginning of info field
+//
+// Returns course in degrees, speed in KNOTS.
+//
+int extract_speed_course(char *info, char *speed, char *course) {
+    int i,found,len;
+
+    len = (int)strlen(info);
+    found = 0;
+    speed[0] = course[0] = '\0';
+    if (len >= 7) {
+        found = 1;
+        for(i=0; found && i<7; i++) {           // check data format
+            if (i==3) {                         // check separator
+                if (info[i]!='/')
+                    found = 0;
+            }
+            else {
+                if( !( isdigit((int)info[i])
+                        || (info[i] == ' ')     // Spaces and periods are allowed.  Need these
+                        || (info[i] == '.') ) ) // here so that we can get the field deleted
+                    found = 0;
+            }
+        }
+    }
+    if (found) {
+        substr(course,info,3);
+        substr(speed,info+4,3);
+        for (i=0;i<=len-7;i++)        // delete speed/course from info field
+            info[i] = info[i+7];
+    }
+    if (!found || atoi(course) < 1) {   // course 0 means undefined
+//        speed[0] ='\0';   // Don't do this!  We can have a valid
+//        speed without a valid course.
+        course[0]='\0';
+    }
+    else {  // recheck data format looking for undefined fields
+        for(i=0; i<2; i++) {
+            if( !(isdigit((int)speed[i]) ) )
+                speed[0] = '\0';
+            if( !(isdigit((int)course[i]) ) )
+                course[0] = '\0';
+        }
+    }
+
+    return(found);
+}
+
+
+
+
+
+/*
+ *  Extract bearing and number/range/quality from beginning of info field
+ */
+int extract_bearing_NRQ(char *info, char *bearing, char *nrq) {
+    int i,found,len;
+
+    len = (int)strlen(info);
+    found = 0;
+    if (len >= 8) {
+        found = 1;
+        for(i=1; found && i<8; i++)         // check data format
+            if(!(isdigit((int)info[i]) || (i==4 && info[i]=='/')))
+                found=0;
+    }
+    if (found) {
+        substr(bearing,info+1,3);
+        substr(nrq,info+5,3);
+
+//fprintf(stderr,"Bearing: %s\tNRQ: %s\n", bearing, nrq);
+
+        for (i=0;i<=len-8;i++)        // delete bearing/nrq from info field
+            info[i] = info[i+8];
+    }
+
+//    if (!found || nrq[2] == '0') {   // Q of 0 means useless bearing
+    if (!found) {
+        bearing[0] ='\0';
+        nrq[0]='\0';
+    }
+    return(found);
+}
+
+
+
+
+
+/*
+ *  Extract altitude from APRS info field          "/A=012345"    in feet
+ */
+int extract_altitude(char *info, char *altitude) {
+    int i,ofs,found,len;
+
+    found=0;
+    len = (int)strlen(info);
+    for(ofs=0; !found && ofs<len-8; ofs++)      // search for start sequence
+        if (strncmp(info+ofs,"/A=",3)==0) {
+            found=1;
+            // Are negative altitudes even defined?  Yes!  In Mic-E spec to -10,000 meters
+            if(!isdigit((int)info[ofs+3]) && info[ofs+3]!='-')  // First char must be digit or '-'
+                found=0;
+            for(i=4; found && i<9; i++)         // check data format for next 5 chars
+                if(!isdigit((int)info[ofs+i]))
+                    found=0;
+    }
+    if (found) {
+        ofs--;  // was one too much on exit from for loop
+        substr(altitude,info+ofs+3,6);
+        for (i=ofs;i<=len-9;i++)        // delete altitude from info field
+            info[i] = info[i+9];
+    }
+    else
+        altitude[0] = '\0';
+    return(found);
+}
+
+
+
+
+
+// TODO:
+// Comment Field
+
+
+
+
+ 
+/*
+ *  Extract powergain and/or range from APRS info field:
+ * "PHG1234/", "PHG1234", or "RNG1234" from APRS data extension.
+ */
+int extract_powergain_range(char *info, char *phgd) {
+    int i,found,len;
+    char *info2;
+
+
+//fprintf(stderr,"Info:%s\n",info);
+
+    // Check whether two strings of interest are present and snag a
+    // pointer to them.
+    info2 = strstr(info,"RNG");
+    if (!info2)
+        info2 = strstr(info,"PHG");
+    if (!info2) {
+        phgd[0] = '\0';
+        return(0);
+    }
+
+    found=0;
+    len = (int)strlen(info2);
+
+    if (len >= 9 && strncmp(info2,"PHG",3)==0
+            && info2[7]=='/'
+            && info2[8]!='A'  // trailing '/' not defined in Reference...
+            && isdigit((int)info2[3])
+            && isdigit((int)info2[4])
+            && isdigit((int)info2[5])
+            && isdigit((int)info2[6])) {
+        substr(phgd,info2,7);
+        found = 1;
+        for (i=0;i<=len-8;i++)        // delete powergain from data extension field
+            info2[i] = info2[i+8];
+    }
+    else {
+        if (len >= 7 && strncmp(info2,"PHG",3)==0
+                && isdigit((int)info2[3])
+                && isdigit((int)info2[4])
+                && isdigit((int)info2[5])
+                && isdigit((int)info2[6])) {
+            substr(phgd,info2,7);
+            found = 1;
+            for (i=0;i<=len-7;i++)        // delete powergain from data extension field
+                info2[i] = info2[i+7];
+        }
+        else if (len >= 7 && strncmp(info2,"RNG",3)==0
+                && isdigit((int)info2[3])
+                && isdigit((int)info2[4])
+                && isdigit((int)info2[5])
+                && isdigit((int)info2[6])) {
+            substr(phgd,info2,7);
+            found = 1;
+            for (i=0;i<=len-7;i++)        // delete powergain from data extension field
+                info2[i] = info2[i+7];
+        }
+        else {
+            phgd[0] = '\0';
+        }
+    }
+    return(found);
+}
+
+
+
+
+
+/*
+ *  Extract omnidf from APRS info field          "DFS1234/"    from APRS data extension
+ */
+int extract_omnidf(char *info, char *phgd) {
+    int i,found,len;
+
+    found=0;
+    len = (int)strlen(info);
+    if (len >= 8 && strncmp(info,"DFS",3)==0 && info[7]=='/'    // trailing '/' not defined in Reference...
+                 && isdigit((int)info[3]) && isdigit((int)info[5]) && isdigit((int)info[6])) {
+        substr(phgd,info,7);
+        for (i=0;i<=len-8;i++)        // delete omnidf from data extension field
+            info[i] = info[i+8];
+        return(1);
+    }
+    else {
+        phgd[0] = '\0';
+        return(0);
+    }
+}
+
+
+
+
+
+/*
+ *  Extract signpost data from APRS info field: "{123}", an APRS data extension
+ *  Format can be {1}, {12}, or {123}.  Letters or digits are ok.
+ */
+int extract_signpost(char *info, char *signpost) {
+    int i,found,len,done;
+
+//0123456
+//{1}
+//{12}
+//{121}
+
+    found=0;
+    len = (int)strlen(info);
+    if ( (len > 2)
+            && (info[0] == '{')
+            && ( (info[2] == '}' ) || (info[3] == '}' ) || (info[4] == '}' ) ) ) {
+
+        i = 1;
+        done = 0;
+        while (!done) {                 // Snag up to three digits
+            if (info[i] == '}') {       // We're done
+                found = i;              // found = position of '}' character
+                done++;
+            }
+            else {
+                signpost[i-1] = info[i];
+            }
+
+            i++;
+
+            if ( (i > 4) && !done) {    // Something is wrong, we should be done by now
+                done++;
+                signpost[0] = '\0';
+                return(0);
+            }
+        }
+        substr(signpost,info+1,found-1);
+        found++;
+        for (i=0;i<=len-found;i++) {    // delete omnidf from data extension field
+            info[i] = info[i+found];
+        }
+        return(1);
+    }
+    else {
+        signpost[0] = '\0';
+        return(0);
+    }
+}
+
+
+
+
+
+/*
+ *  Extract probability_min data from APRS info field: "Pmin1.23,"
+ *  Please note the ending comma.  We use it to delimit the field.
+ */
+int extract_probability_min(char *info, char *prob_min, int prob_min_size) {
+    int len,done;
+    char *c;
+    char *d;
+
+
+//fprintf(stderr,"%s\n",info);
+ 
+    len = (int)strlen(info);
+    if (len < 6) {          // Too short
+//fprintf(stderr,"Pmin too short: %s\n",info);
+        prob_min[0] = '\0';
+        return(0);
+    }
+
+    c = strstr(info,"Pmin");
+    if (c == NULL) {        // Pmin not found
+//fprintf(stderr,"Pmin not found: %s\n",info);
+        prob_min[0] = '\0';
+        return(0);
+    }
+
+    c = c+4;    // Skip the Pmin part
+    // Find the ending comma
+    d = c;
+    done = 0;
+    while (!done) {
+        if (*d == ',') {    // We're done
+            done++;
+        }
+        else {
+            d++;
+        }
+
+        // Check for string too long
+        if ( ((d-c) > 10) && !done) {    // Something is wrong, we should be done by now
+//fprintf(stderr,"Pmin too long: %d,%s\n",d-c,info);
+            prob_min[0] = '\0';
+            return(0);
+        }
+    }
+
+    // Copy the substring across
+    xastir_snprintf(prob_min,
+        prob_min_size,
+        "%s",
+        c);
+    prob_min[d-c] = '\0';
+    prob_min[10] = '\0';    // Just to make sure
+
+    // Delete data from data extension field 
+    d++;    // Skip the comma
+    done = 0;
+    while (!done) {
+        *(c-4) = *d;
+        if (*d == '\0')
+            done++;
+        c++;
+        d++;
+    }
+
+    return(1);
+}
+
+
+
+
+
+/*
+ *  Extract probability_max data from APRS info field: "Pmax1.23,"
+ *  Please note the ending comma.  We use it to delimit the field.
+ */
+int extract_probability_max(char *info, char *prob_max, int prob_max_size) {
+    int len,done;
+    char *c;
+    char *d;
+
+
+//fprintf(stderr,"%s\n",info);
+
+    len = (int)strlen(info);
+    if (len < 6) {          // Too short
+//fprintf(stderr,"Pmax too short: %s\n",info);
+        prob_max[0] = '\0';
+        return(0);
+    }
+
+    c = strstr(info,"Pmax");
+    if (c == NULL) {        // Pmax not found
+//fprintf(stderr,"Pmax not found: %s\n",info);
+        prob_max[0] = '\0';
+        return(0);
+    }
+
+    c = c+4;    // Skip the Pmax part
+    // Find the ending comma
+    d = c;
+    done = 0;
+    while (!done) {
+        if (*d == ',') {    // We're done
+            done++;
+        }
+        else {
+            d++;
+        }
+
+        // Check for string too long
+        if ( ((d-c) > 10) && !done) {    // Something is wrong, we should be done by now
+//fprintf(stderr,"Pmax too long: %d,%s\n",d-c,info);
+            prob_max[0] = '\0';
+            return(0);
+        }
+    }
+
+    // Copy the substring across
+    xastir_snprintf(prob_max,
+        prob_max_size,
+        "%s",
+        c);
+    prob_max[d-c] = '\0';
+    prob_max[10] = '\0';    // Just to make sure
+
+    // Delete data from data extension field 
+    d++;    // Skip the comma
+    done = 0;
+    while (!done) {
+        *(c-4) = *d;
+        if (*d == '\0')
+            done++;
+        c++;
+        d++;
+    }
+ 
+    return(1);
+}
+
+
+
+
+
+static void clear_area(DataRow *p_station) {
+    p_station->aprs_symbol.area_object.type           = AREA_NONE;
+    p_station->aprs_symbol.area_object.color          = AREA_GRAY_LO;
+    p_station->aprs_symbol.area_object.sqrt_lat_off   = 0;
+    p_station->aprs_symbol.area_object.sqrt_lon_off   = 0;
+    p_station->aprs_symbol.area_object.corridor_width = 0;
+}
+
+
+
+
+
+/*
+ *  Extract Area Object
+ */
+void extract_area(DataRow *p_station, char *data) {
+    int i, val, len;
+    unsigned int uval;
+    AreaObject temp_area;
+
+    /* NOTE: If we are here, the symbol was the area symbol.  But if this
+       is a slightly corrupted packet, we shouldn't blow away the area info
+       for this station, since it could be from a previously received good
+       packet.  So we will work on temp_area and only copy to p_station at
+       the end, returning on any error as we parse. N7TAP */
+
+    //fprintf(stderr,"Area Data: %s\n", data);
+
+    len = (int)strlen(data);
+    val = data[0] - '0';
+    if (val >= 0 && val <= AREA_MAX) {
+        temp_area.type = val;
+        val = data[4] - '0';
+        temp_area.color = AREA_BLACK_HI; // Initial value
+        if (data[3] == '/') {
+            if (val >=0 && val <= 9) {
+                temp_area.color = val;
+            }
+            else {
+                if (debug_level & 2)
+                    fprintf(stderr,"Bad area color (/)");
+                return;
+            }
+        }
+        else if (data[3] == '1') {
+            if (val >=0 && val <= 5) {
+                temp_area.color = 10 + val;
+            }
+            else {
+                if (debug_level & 2)
+                    fprintf(stderr,"Bad area color (1)");
+                return;
+            }
+        }
+
+        val = 0;
+        if (isdigit((int)data[1]) && isdigit((int)data[2])) {
+            val = (10 * (data[1] - '0')) + (data[2] - '0');
+        }
+        else {
+            if (debug_level & 2)
+                fprintf(stderr,"Bad area sqrt_lat_off");
+            return;
+        }
+        temp_area.sqrt_lat_off = val;
+
+        val = 0;
+        if (isdigit((int)data[5]) && isdigit((int)data[6])) {
+            val = (10 * (data[5] - '0')) + (data[6] - '0');
+        }
+        else {
+            if (debug_level & 2)
+                fprintf(stderr,"Bad area sqrt_lon_off");
+            return;
+        }
+        temp_area.sqrt_lon_off = val;
+
+        for (i = 0; i <= len-7; i++) // delete area object from data extension field
+            data[i] = data[i+7];
+        len -= 7;
+
+        if (temp_area.type == AREA_LINE_RIGHT || temp_area.type == AREA_LINE_LEFT) {
+            if (data[0] == '{') {
+                if (sscanf(data, "{%u}", &uval) == 1) {
+                    temp_area.corridor_width = uval & 0xffff;
+                    for (i = 0; i <= len; i++)
+                        if (data[i] == '}')
+                            break;
+                    uval = i+1;
+                    for (i = 0; i <= (int)(len-uval); i++)
+                        data[i] = data[i+uval]; // delete corridor width
+                }
+                else {
+                    if (debug_level & 2)
+                        fprintf(stderr,"Bad corridor width identifier");
+                    temp_area.corridor_width = 0;
+                    return;
+                }
+            }
+            else {
+                if (debug_level & 2)
+                    fprintf(stderr,"No corridor width specified");
+                temp_area.corridor_width = 0;
+            }
+        }
+        else {
+            temp_area.corridor_width = 0;
+        }
+    }
+    else {
+        if (debug_level & 2)
+            fprintf(stderr,"Bad area type: %c\n", data[0]);
+        return;
+    }
+
+    memcpy(&(p_station->aprs_symbol.area_object), &temp_area, sizeof(AreaObject));
+
+    if (debug_level & 2) {
+        fprintf(stderr,"AreaObject: type=%d color=%d sqrt_lat_off=%d sqrt_lon_off=%d corridor_width=%d\n",
+                p_station->aprs_symbol.area_object.type,
+                p_station->aprs_symbol.area_object.color,
+                p_station->aprs_symbol.area_object.sqrt_lat_off,
+                p_station->aprs_symbol.area_object.sqrt_lon_off,
+                p_station->aprs_symbol.area_object.corridor_width);
+    }
+}
+
+
+
+
+
+/*
+ *  Extract Time from begin of line      [APRS Reference, chapter 6]
+ *
+ * If a time string is found in "data", it is deleted from the
+ * beginning of the string.
+ */
+int extract_time(DataRow *p_station, char *data, int type) {
+    int len, i;
+    int ok = 0;
+
+    // todo: better check of time data ranges
+    len = (int)strlen(data);
+    if (type == APRS_WX2) {
+        // 8 digit time from stand-alone positionless weather stations...
+        if (len > 8) {
+            // MMDDHHMM   zulu time
+            // MM 01-12         todo: better check of time data ranges
+            // DD 01-31
+            // HH 01-23
+            // MM 01-59
+            ok = 1;
+            for (i=0;ok && i<8;i++)
+                if (!isdigit((int)data[i]))
+                    ok = 0;
+            if (ok) {
+//                substr(p_station->station_time,data+2,6);
+//                p_station->station_time_type = 'z';
+                for (i=0;i<=len-8;i++)         // delete time from data
+                    data[i] = data[i+8];
+            }
+        }
+    }
+    else {
+        if (len > 6) {
+            // Status messages only with optional zulu format
+            // DK7IN: APRS ref says one of 'z' '/' 'h', but I found 'c' at HB9TJM-8   ???
+            if (toupper(data[6])=='Z' || data[6]=='/' || toupper(data[6])=='H')
+                ok = 1;
+            for (i=0;ok && i<6;i++)
+                if (!isdigit((int)data[i]))
+                    ok = 0;
+            if (ok) {
+//                substr(p_station->station_time,data,6);
+//                p_station->station_time_type = data[6];
+                for (i=0;i<=len-7;i++)         // delete time from data
+                    data[i] = data[i+7];
+            }
+        }
+    }
+    return(ok);
+}
+
+
+
+
+
+// APRS Data Extensions               [APRS Reference p.27]
+//  .../...  Course & Speed, may be followed by others (see p.27)
+//  .../...  Wind Dir and Speed
+//  PHG....  Station Power and Effective Antenna Height/Gain
+//  RNG....  Pre-Calculated Radio Range
+//  DFS....  DF Signal Strength and Effective Antenna Height/Gain
+//  T../C..  Area Object Descriptor
+
+/* Extract one of several possible APRS Data Extensions */
+void process_data_extension(DataRow *p_station, char *data, /*@unused@*/ int type) {
+    char temp1[7+1];
+    char temp2[3+1];
+    char temp3[10+1];
+    char bearing[3+1];
+    char nrq[3+1];
+
+    if (p_station->aprs_symbol.aprs_type == '\\' && p_station->aprs_symbol.aprs_symbol == 'l') {
+            /* This check needs to come first because the area object extension can look
+               exactly like what extract_speed_course will attempt to decode. */
+            extract_area(p_station, data);
+    }
+    else {
+        clear_area(p_station); // we got a packet with a non area symbol, so clear the data
+
+        if (extract_speed_course(data,temp1,temp2)) {  // ... from Mic-E, etc.
+        //fprintf(stderr,"extracted speed/course\n");
+
+            if (atof(temp2) > 0) {
+            //fprintf(stderr,"course is non-zero\n");
+            xastir_snprintf(p_station->speed,
+                sizeof(p_station->speed),
+                "%06.2f",
+                atof(temp1));
+            xastir_snprintf(p_station->course,  // in degrees
+                sizeof(p_station->course),
+                "%s",
+                temp2);
+            }
+
+            if (extract_bearing_NRQ(data, bearing, nrq)) {  // Beam headings from DF'ing
+                //fprintf(stderr,"extracted bearing and NRQ\n");
+                xastir_snprintf(p_station->bearing,
+                    sizeof(p_station->bearing),
+                    "%s",
+                    bearing);
+                xastir_snprintf(p_station->NRQ,
+                    sizeof(p_station->NRQ),
+                    "%s",
+                    nrq);
+                p_station->signal_gain[0] = '\0';   // And blank out the shgd values
+            }
+        }
+        // Don't try to extract speed & course if a compressed
+        // object.  Test for beam headings for compressed packets
+        // here
+        else if (extract_bearing_NRQ(data, bearing, nrq)) {  // Beam headings from DF'ing
+
+            //fprintf(stderr,"extracted bearing and NRQ\n");
+            xastir_snprintf(p_station->bearing,
+                    sizeof(p_station->bearing),
+                    "%s",
+                    bearing);
+            xastir_snprintf(p_station->NRQ,
+                    sizeof(p_station->NRQ),
+                    "%s",
+                    nrq);
+            p_station->signal_gain[0] = '\0';   // And blank out the shgd values
+        }
+        else {
+            if (extract_powergain_range(data,temp1)) {
+
+//fprintf(stderr,"Found power_gain: %s\n", temp1);
+
+                xastir_snprintf(p_station->power_gain,
+                    sizeof(p_station->power_gain),
+                    "%s",
+                    temp1);
+
+                if (extract_bearing_NRQ(data, bearing, nrq)) {  // Beam headings from DF'ing
+                    //fprintf(stderr,"extracted bearing and NRQ\n");
+                    xastir_snprintf(p_station->bearing,
+                        sizeof(p_station->bearing),
+                        "%s",
+                        bearing);
+                    xastir_snprintf(p_station->NRQ,
+                        sizeof(p_station->NRQ),
+                        "%s",
+                        nrq);
+                    p_station->signal_gain[0] = '\0';   // And blank out the shgd values
+                }
+            }
+            else {
+                if (extract_omnidf(data,temp1)) {
+                    xastir_snprintf(p_station->signal_gain,
+                        sizeof(p_station->signal_gain),
+                        "%s",
+                        temp1);   // Grab the SHGD values
+                    p_station->bearing[0] = '\0';   // And blank out the bearing/NRQ values
+                    p_station->NRQ[0] = '\0';
+
+                    // The spec shows speed/course before DFS, but example packets that
+                    // come with DOSaprs show DFSxxxx/speed/course.  We'll take care of
+                    // that possibility by trying to decode speed/course again.
+                    if (extract_speed_course(data,temp1,temp2)) {  // ... from Mic-E, etc.
+                    //fprintf(stderr,"extracted speed/course\n");
+                        if (atof(temp2) > 0) {
+                            //fprintf(stderr,"course is non-zero\n");
+                            xastir_snprintf(p_station->speed,
+                                sizeof(p_station->speed),
+                                "%06.2f",
+                                atof(temp1));
+                            xastir_snprintf(p_station->course,
+                                sizeof(p_station->course),
+                                "%s",
+                                temp2);                    // in degrees
+                        }
+                    }
+
+                    // The spec shows that omnidf and bearing/NRQ can be in the same
+                    // packet, which makes no sense, but we'll try to decode it that
+                    // way anyway.
+                    if (extract_bearing_NRQ(data, bearing, nrq)) {  // Beam headings from DF'ing
+                        //fprintf(stderr,"extracted bearing and NRQ\n");
+                        xastir_snprintf(p_station->bearing,
+                            sizeof(p_station->bearing),
+                            "%s",
+                            bearing);
+                        xastir_snprintf(p_station->NRQ,
+                            sizeof(p_station->NRQ),
+                            "%s",
+                            nrq);
+                        //p_station->signal_gain[0] = '\0';   // And blank out the shgd values
+                    }
+                }
+            }
+        }
+
+        if (extract_signpost(data, temp2)) {
+            //fprintf(stderr,"extracted signpost data\n");
+            xastir_snprintf(p_station->signpost,
+                sizeof(p_station->signpost),
+                "%s",
+                temp2);
+        }
+
+        if (extract_probability_min(data, temp3, sizeof(temp3))) {
+            //fprintf(stderr,"extracted probability_min data: %s\n",temp3);
+            xastir_snprintf(p_station->probability_min,
+                sizeof(p_station->probability_min),
+                "%s",
+                temp3);
+        }
+ 
+        if (extract_probability_max(data, temp3, sizeof(temp3))) {
+            //fprintf(stderr,"extracted probability_max data: %s\n",temp3);
+            xastir_snprintf(p_station->probability_max,
+                sizeof(p_station->probability_max),
+                "%s",
+                temp3);
+        }
+    }
+}
+
+
+
+
+
+/* extract all available information from info field */
+void process_info_field(DataRow *p_station, char *info, /*@unused@*/ int type) {
+    char temp_data[6+1];
+//    char time_data[MAX_TIME];
+
+    if (extract_altitude(info,temp_data)) {                         // get altitude
+        xastir_snprintf(p_station->altitude, sizeof(p_station->altitude), "%.2f",atof(temp_data)*0.3048);
+        //fprintf(stderr,"%.2f\n",atof(temp_data)*0.3048);
+    }
+    // do other things...
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// type: 18
+// call_sign: VE6GRR-15
+// path: GPSLV,TCPIP,VE7DIE*
+// data: GPRMC,034728,A,5101.016,N,11359.464,W,000.0,284.9,110701,018.0,
+// from: T
+// port: 0
+// origin: 
+// third_party: 1
+
+
+
+
+
+//
+//  Extract data for $GPRMC, it fails if there is no position!!
+//
+// GPRMC,UTC-Time,status(A/V),lat,N/S,lon,E/W,SOG,COG,UTC-Date,Mag-Var,E/W,Fix-Quality[*CHK]
+// GPRMC,hhmmss[.sss],{A|V},ddmm.mm[mm],{N|S},dddmm.mm[mm],{E|W},[dd]d.d[ddddd],[dd]d.d[d],ddmmyy,[ddd.d],[{E|W}][,A|D|E|N|S][*CHK]
+//
+// The last field before the checksum is entirely optional, and in
+// fact first appeared in NMEA 2.3 (fairly recently).  Most GPS's do
+// not currently put out that field.  The field may be null or
+// nonexistent including the comma.  Only "A" or "D" are considered
+// to be active and reliable fixes if this field is present.
+// Fix-Quality:
+//  A: Autonomous
+//  D: Differential
+//  E: Estimated
+//  N: Not Valid
+//  S: Simulator
+//
+// $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
+// $GPRMC,104748.821,A,4301.1492,N,08803.0374,W,0.085048,102.36,010605,,*1A
+// $GPRMC,104749.821,A,4301.1492,N,08803.0377,W,0.054215,74.60,010605,,*2D
+//
+int extract_RMC(DataRow *p_station, char *data, char *call_sign, char *path, int *num_digits) {
+    char temp_data[40]; // short term string storage, MAX_CALLSIGN, ...  ???
+    char lat_s[20];
+    char long_s[20];
+    int ok;
+    char *Substring[12];  // Pointers to substrings parsed by split_string()
+    char temp_string[MAX_MESSAGE_LENGTH+1];
+    char temp_char;
+
+
+    if (debug_level & 256)
+        fprintf(stderr,"extract_RMC\n");
+
+    // should we copy it before processing? it changes data: ',' gets substituted by '\0' !!
+    ok = 0; // Start out as invalid.  If we get enough info, we change this to a 1.
+
+    if ( (data == NULL) || (strlen(data) < 34) ) {  // Not enough data to parse position from.
+        if (debug_level & 256)
+            fprintf(stderr,"Invalid RMC string: Too short\n");
+        return(ok);
+    }
+
+    p_station->record_type = NORMAL_GPS_RMC;
+    // Create a timestamp from the current time
+    // get_time saves the time in temp_data
+    xastir_snprintf(p_station->pos_time,
+        sizeof(p_station->pos_time),
+        "%s",
+        get_time(temp_data));
+    p_station->flag &= (~ST_MSGCAP);    // clear "message capable" flag
+
+    /* check aprs type on call sign */
+    p_station->aprs_symbol = *id_callsign(call_sign, path);
+
+    // Make a copy of the incoming data.  The string passed to
+    // split_string() gets destroyed.
+    xastir_snprintf(temp_string,
+        sizeof(temp_string),
+        "%s",
+        data);
+    split_string(temp_string, Substring, 12, ',');
+
+    // The Substring[] array contains pointers to each substring in
+    // the original data string.
+
+// GPRMC,034728,A,5101.016,N,11359.464,W,000.0,284.9,110701,018.0,E*7D
+//   0     1    2    3     4    5      6   7    8      9     10    11
+
+    if (Substring[0] == NULL)   // No GPRMC string
+        return(ok);
+
+    if (Substring[1] == NULL)   // No time string
+        return(ok);
+
+    if (Substring[2] == NULL)   // No valid fix char
+        return(ok);
+
+    if (Substring[2][0] != 'A' && Substring[2][0] != 'V')
+        return(ok);
+// V is a warning but we can get good data still ?
+// DK7IN: got no position with 'V' !
+
+    if (Substring[3] == NULL)   // No latitude string
+        return(ok);
+
+    if (Substring[4] == NULL)   // No latitude N/S
+        return(ok);
+
+// Need to check lat_s for validity here.  Note that some GPS's put out another digit of precision
+// (4801.1234) or leave one out (4801.12).  Next character after digits should be a ','
+
+    // Count digits after the decimal point for latitude
+    if (strchr(Substring[3],'.')) {
+        *num_digits = strlen(Substring[3]) - (int)(strchr(Substring[3],'.') - Substring[3]) - 1;
+    }
+    else {
+        *num_digits = 0;
+    }
+
+    temp_char = toupper((int)Substring[4][0]);
+
+    if (temp_char != 'N' && temp_char != 'S')   // Bad N/S
+        return(ok);
+
+    xastir_snprintf(lat_s,
+        sizeof(lat_s),
+        "%s%c",
+        Substring[3],
+        temp_char);
+
+    if (Substring[5] == NULL)   // No longitude string
+        return(ok);
+
+    if (Substring[6] == NULL)   // No longitude E/W
+        return(ok);
+
+// Need to check long_s for validity here.  Should be all digits.  Note that some GPS's put out another
+// digit of precision.  (12201.1234).  Next character after digits should be a ','
+
+    temp_char = toupper((int)Substring[6][0]);
+
+    if (temp_char != 'E' && temp_char != 'W')   // Bad E/W
+        return(ok);
+
+    xastir_snprintf(long_s,
+        sizeof(long_s),
+        "%s%c",
+        Substring[5],
+        temp_char);
+
+    p_station->coord_lat = convert_lat_s2l(lat_s);
+    p_station->coord_lon = convert_lon_s2l(long_s);
+
+    // If we've made it this far, We have enough for a position now!
+    ok = 1;
+
+    // Now that we have a basic position, let's see what other data
+    // can be parsed from the packet.  The rest of it can still be
+    // corrupt, so we're proceeding carefully under yellow alert on
+    // impulse engines only.
+
+// GPRMC,034728,A,5101.016,N,11359.464,W,000.0,284.9,110701,018.0,E*7D
+//   0     1    2    3     4    5      6   7    8      9     10    11
+
+    if (Substring[7] == NULL) { // No speed string
+        p_station->speed[0] = '\0'; // No speed available
+        return(ok);
+    }
+    else {
+        xastir_snprintf(p_station->speed,
+            MAX_SPEED,
+            "%s",
+            Substring[7]);
+        // Is it always knots, otherwise we need a conversion!
+    }
+
+    if (Substring[8] == NULL) { // No course string
+        xastir_snprintf(p_station->course,
+            sizeof(p_station->course),
+            "000.0");  // No course available
+        return(ok);
+    }
+    else {
+        xastir_snprintf(p_station->course,
+            MAX_COURSE,
+            "%s",
+            Substring[8]);
+    }
+
+    if (debug_level & 256) {
+        if (ok)
+            fprintf(stderr,"extract_RMC succeeded: %s\n",data);
+        else
+            fprintf(stderr,"extract_RMC failed: %s\n",data);
+    }
+
+    return(ok);
+}
+
+
+
+
+
+//
+//  Extract data for $GPGGA
+//
+// GPGGA,UTC-Time,lat,N/S,long,E/W,GPS-Quality,nsat,HDOP,MSL-Meters,M,Geoidal-Meters,M,DGPS-Data-Age(seconds),DGPS-Ref-Station-ID[*CHK]
+// GPGGA,hhmmss[.sss],ddmm.mm[mm],{N|S},dddmm.mm[mm],{E|W},{0-8},dd,[d]d.d,[-dddd]d.d,M,[-ddd]d.d,M,[dddd.d],[dddd][*CHK]
+//
+// GPS-Quality:
+//  0: Invalid Fix
+//  1: GPS Fix
+//  2: DGPS Fix
+//  3: PPS Fix
+//  4: RTK Fix
+//  5: Float RTK Fix
+//  6: Estimated (dead-reckoning) Fix
+//  7: Manual Input Mode
+//  8: Simulation Mode
+//
+// $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75 
+// $GPGGA,104438.833,4301.1439,N,08803.0338,W,1,05,1.8,185.8,M,-34.2,M,0.0,0000*40
+//
+// nsat=Number of Satellites being tracked
+//
+//
+int extract_GGA(DataRow *p_station,char *data,char *call_sign, char *path, int *num_digits) {
+    char temp_data[40]; // short term string storage, MAX_CALLSIGN, ...  ???
+    char lat_s[20];
+    char long_s[20];
+    int  ok;
+    char *Substring[15];  // Pointers to substrings parsed by split_string()
+    char temp_string[MAX_MESSAGE_LENGTH+1];
+    char temp_char;
+    int  temp_num;
+
+
+    if (debug_level & 256)
+        fprintf(stderr, "extract_GGA\n");
+
+    ok = 0; // Start out as invalid.  If we get enough info, we change this to a 1.
+ 
+    if ( (data == NULL) || (strlen(data) < 32) )  // Not enough data to parse position from.
+        return(ok);
+
+    p_station->record_type = NORMAL_GPS_GGA;
+    // Create a timestamp from the current time
+    // get_time saves the time in temp_data
+    xastir_snprintf(p_station->pos_time,
+        sizeof(p_station->pos_time),
+        "%s",
+        get_time(temp_data));
+    p_station->flag &= (~ST_MSGCAP);    // clear "message capable" flag
+
+    /* check aprs type on call sign */
+    p_station->aprs_symbol = *id_callsign(call_sign, path);
+
+    // Make a copy of the incoming data.  The string passed to
+    // split_string() gets destroyed.
+    xastir_snprintf(temp_string,
+        sizeof(temp_string),
+        "%s",
+        data);
+    split_string(temp_string, Substring, 15, ',');
+
+    // The Substring[] array contains pointers to each substring in
+    // the original data string.
+
+
+// GPGGA,hhmmss[.sss],ddmm.mm[mm],{N|S},dddmm.mm[mm],{E|W},{0-8},dd,[d]d.d,[-dddd]d.d,M,[-ddd]d.d,M,[dddd.d],[dddd][*CHK]
+//   0     1              2         3        4         5        6      7     8        9     1     1     1    1        1
+//                                                                                          0     1     2    3        4
+
+    if (Substring[0] == NULL)  // No GPGGA string
+        return(ok);
+
+    if (Substring[1] == NULL)  // No time string
+        return(ok);
+
+    if (Substring[2] == NULL)   // No latitude string
+        return(ok);
+
+    if (Substring[3] == NULL)   // No latitude N/S
+        return(ok);
+
+// Need to check lat_s for validity here.  Note that some GPS's put out another digit of precision
+// (4801.1234).  Next character after digits should be a ','
+
+    // Count digits after the decimal point for latitude
+    if (strchr(Substring[2],'.')) {
+        *num_digits = strlen(Substring[2]) - (int)(strchr(Substring[2],'.') - Substring[2]) - 1;
+    }
+    else {
+        *num_digits = 0;
+    }
+
+    temp_char = toupper((int)Substring[3][0]);
+
+    if (temp_char != 'N' && temp_char != 'S')   // Bad N/S
+        return(ok);
+
+    xastir_snprintf(lat_s,
+        sizeof(lat_s),
+        "%s%c",
+        Substring[2],
+        temp_char);
+
+    if (Substring[4] == NULL)   // No longitude string
+        return(ok);
+
+    if (Substring[5] == NULL)   // No longitude E/W
+        return(ok);
+
+// Need to check long_s for validity here.  Should be all digits.  Note that some GPS's put out another
+// digit of precision.  (12201.1234).  Next character after digits should be a ','
+
+    temp_char = toupper((int)Substring[5][0]);
+
+    if (temp_char != 'E' && temp_char != 'W')   // Bad E/W
+        return(ok);
+
+    xastir_snprintf(long_s,
+        sizeof(long_s),
+        "%s%c",
+        Substring[4],
+        temp_char);
+
+    p_station->coord_lat = convert_lat_s2l(lat_s);
+    p_station->coord_lon = convert_lon_s2l(long_s);
+
+    // If we've made it this far, We have enough for a position now!
+    ok = 1;
+
+
+    // Now that we have a basic position, let's see what other data
+    // can be parsed from the packet.  The rest of it can still be
+    // corrupt, so we're proceeding carefully under yellow alert on
+    // impulse engines only.
+
+    // Check for valid fix {
+    if (Substring[6] == NULL
+            || Substring[6][0] == '0'      // Fix quality
+            || Substring[7] == NULL        // Sat number
+            || Substring[8] == NULL        // hdop
+            || Substring[9] == NULL) {     // Altitude in meters
+        p_station->sats_visible[0] = '\0'; // Store empty sats visible
+        p_station->altitude[0] = '\0';;    // Store empty altitude
+        return(ok); // A field between fix quality and altitude is missing
+    }
+
+// Need to check for validity of this number.  Should be 0-12?  Perhaps a few more with WAAS, GLONASS, etc?
+    temp_num = atoi(Substring[7]);
+    if (temp_num < 0 || temp_num > 30) {
+        return(ok); // Number of satellites not valid
+    }
+    else {
+        // Store 
+        xastir_snprintf(p_station->sats_visible,
+            sizeof(p_station->sats_visible),
+            "%d",
+            temp_num);
+    }
+
+
+// Check for valid number for HDOP instead of just throwing it away?
+
+
+    xastir_snprintf(p_station->altitude,
+        sizeof(p_station->altitude),
+        "%s",
+        Substring[9]); // Get altitude
+
+// Need to check for valid altitude before conversion
+
+    // unit is in meters, if not adjust value ???
+
+    if (Substring[10] == NULL)  // No units for altitude
+        return(ok);
+
+    if (Substring[10][0] != 'M') {
+        //fprintf(stderr,"ERROR: should adjust altitude for meters\n");
+        //} else {  // Altitude units wrong.  Assume altitude bad
+        p_station->altitude[0] = '\0';
+    }
+
+    if (debug_level & 256) {
+        if (ok)
+            fprintf(stderr,"extract_GGA succeeded: %s\n",data);
+        else
+            fprintf(stderr,"extract_GGA failed: %s\n",data);
+    }
+
+    return(ok);
+}
+
+
+
+
+
+//
+//  Extract data for $GPGLL
+//
+// $GPGLL,4748.811,N,12219.564,W,033850,A*3C
+// lat, long, UTCtime in hhmmss, A=Valid, checksum
+//
+// GPGLL,4748.811,N,12219.564,W,033850,A*3C
+//   0       1    2      3    4    5   6
+//
+int extract_GLL(DataRow *p_station,char *data,char *call_sign, char *path, int *num_digits) {
+    char temp_data[40]; // short term string storage, MAX_CALLSIGN, ...  ???
+    char lat_s[20];
+    char long_s[20];
+    int ok;
+    char *Substring[7];  // Pointers to substrings parsed by split_string()
+    char temp_string[MAX_MESSAGE_LENGTH+1];
+    char temp_char;
+
+
+    if (debug_level & 256)
+        fprintf(stderr, "extract_GLL\n");
+
+    ok = 0; // Start out as invalid.  If we get enough info, we change this to a 1.
+  
+    if ( (data == NULL) || (strlen(data) < 28) )  // Not enough data to parse position from.
+        return(ok);
+
+    p_station->record_type = NORMAL_GPS_GLL;
+    // Create a timestamp from the current time
+    // get_time saves the time in temp_data
+    xastir_snprintf(p_station->pos_time,
+        sizeof(p_station->pos_time),
+        "%s",
+        get_time(temp_data));
+    p_station->flag &= (~ST_MSGCAP);    // clear "message capable" flag
+
+    /* check aprs type on call sign */
+    p_station->aprs_symbol = *id_callsign(call_sign, path);
+
+    // Make a copy of the incoming data.  The string passed to
+    // split_string() gets destroyed.
+    xastir_snprintf(temp_string,
+        sizeof(temp_string),
+        "%s",
+        data);
+    split_string(temp_string, Substring, 7, ',');
+
+    // The Substring[] array contains pointers to each substring in
+    // the original data string.
+
+    if (Substring[0] == NULL)  // No GPGGA string
+        return(ok);
+
+    if (Substring[1] == NULL)  // No latitude string
+        return(ok);
+
+    if (Substring[2] == NULL)   // No N/S string
+        return(ok);
+
+    if (Substring[3] == NULL)   // No longitude string
+        return(ok);
+
+    if (Substring[4] == NULL)   // No E/W string
+        return(ok);
+
+    temp_char = toupper((int)Substring[2][0]);
+    if (temp_char != 'N' && temp_char != 'S')
+        return(ok);
+
+    xastir_snprintf(lat_s,
+        sizeof(lat_s),
+        "%s%c",
+        Substring[1],
+        temp_char);
+// Need to check lat_s for validity here.  Note that some GPS's put out another digit of precision
+// (4801.1234).  Next character after digits should be a ','
+
+    // Count digits after the decimal point for latitude
+    if (strchr(Substring[1],'.')) {
+        *num_digits = strlen(Substring[1]) - (int)(strchr(Substring[1],'.') - Substring[1]) - 1;
+    }
+    else {
+        *num_digits = 0;
+    }
+
+    temp_char = toupper((int)Substring[4][0]);
+    if (temp_char != 'E' && temp_char != 'W')
+        return(ok);
+
+    xastir_snprintf(long_s,
+        sizeof(long_s),
+        "%s%c",
+        Substring[3],
+        temp_char);
+// Need to check long_s for validity here.  Should be all digits.  Note that some GPS's put out another
+// digit of precision.  (12201.1234).  Next character after digits should be a ','
+
+    p_station->coord_lat = convert_lat_s2l(lat_s);
+    p_station->coord_lon = convert_lon_s2l(long_s);
+    ok = 1; // We have enough for a position now
+
+    xastir_snprintf(p_station->course,
+        sizeof(p_station->course),
+        "000.0");  // Fill in with dummy values
+    p_station->speed[0] = '\0';        // Fill in with dummy values
+
+    // A is valid, V is a warning but we can get good data still?
+    // We don't currently check the data valid flag.
+
+    return(ok);
+}
+
+
+
+
+
+// Add a status line to the linked-list of status records
+// associated with a station.  Note that a blank status line is
+// allowed, but we don't store that unless we have seen a non-blank
+// status line previously.
+//
+void add_status(DataRow *p_station, char *status_string) {
+    CommentRow *ptr;
+    int add_it = 0;
+    int len;
+
+
+    len = strlen(status_string);
+
+    // Eliminate line-end chars
+    if (len > 1) {
+        if ( (status_string[len-1] == '\n')
+                || (status_string[len-1] == '\r') ) {
+            status_string[len-1] = '\0';
+        }
+    }
+
+    // Shorten it
+    //fprintf(stderr,"1Status: (%s)\n",status_string);
+    (void)remove_trailing_spaces(status_string);
+    //fprintf(stderr,"2Status: (%s)\n",status_string);
+    (void)remove_leading_spaces(status_string);
+    //fprintf(stderr,"3Status: (%s)\n",status_string);
+ 
+    len = strlen(status_string);
+
+    // Check for valid pointer
+    if (p_station != NULL) {
+
+// We should probably create a new station record for this station
+// if there isn't one.  This allows us to collect as much info about
+// a station as we can until a posit comes in for it.  Right now we
+// don't do this.  If we decide to do this in the future, we also
+// need a method to find out the info about that station without
+// having to click on an icon, 'cuz the symbol won't be on our map
+// until we have a posit.
+
+        //fprintf(stderr,"Station:%s\tStatus:%s\n",p_station->call_sign,status_string);
+
+        // Check whether we have any data stored for this station
+        if (p_station->status_data == NULL) {
+            if (len > 0) {
+                // No status stored yet and new status is non-NULL,
+                // so add it to the list.
+                add_it++;
+            }
+        }
+        else {  // We have status data stored already
+                // Check for an identical string
+            CommentRow *ptr2;
+            int ii = 0;
+ 
+            ptr = p_station->status_data;
+            ptr2 = ptr;
+            while (ptr != NULL) {
+
+                // Note that both text_ptr and comment_string can be
+                // empty strings.
+
+                if (strcasecmp(ptr->text_ptr, status_string) == 0) {
+                    // Found a matching string
+                    //fprintf(stderr,"Found match:
+                    //%s:%s\n",p_station->call_sign,status_string);
+
+// Instead of updating the timestamp, we'll delete the record from
+// the list and add it to the top in the code below.  Make sure to
+// tweak the "ii" pointer so that we don't end up shortening the
+// list unnecessarily.
+                    if (ptr == p_station->status_data) {
+
+                        // Only update the timestamp: We're at the
+                        // beginning of the list already.
+                        ptr->sec_heard = sec_now();
+
+                        return; // No need to add a new record
+                    }
+                    else {  // Delete the record
+                        CommentRow *ptr3;
+
+                        // Keep a pointer to the record
+                        ptr3 = ptr;
+
+                        // Close the chain, skipping this record
+                        ptr2->next = ptr3->next;
+
+                        // Skip "ptr" over the record we wish to
+                        // delete
+                        ptr = ptr3->next;
+
+                        // Free the record
+                        free(ptr3->text_ptr);
+                        free(ptr3);
+
+                        // Muck with the counter 'cuz we just
+                        // deleted one record
+                        ii--;
+                    }
+                }
+                ptr2 = ptr; // Back one record
+                if (ptr != NULL) {
+                    ptr = ptr->next;
+                }
+                ii++;
+            }
+
+
+            // No matching string found, or new timestamp found for
+            // old record.  Add it to the top of the list.
+            add_it++;
+            //fprintf(stderr,"No match:
+            //%s:%s\n",p_station->call_sign,status_string);
+
+            // We counted the records.  If we have more than
+            // MAX_STATUS_LINES records we'll delete/free the last
+            // one to make room for the next.  This keeps us from
+            // storing unique status records ad infinitum for active
+            // stations, limiting the total space used.
+            //
+            if (ii >= MAX_STATUS_LINES) {
+                // We know we didn't get a match, and that our list
+                // is full (as full as we want it to be).  Traverse
+                // the list again, looking for ptr2->next->next ==
+                // NULL.  If found, free last record and set the
+                // ptr2->next pointer to NULL.
+                ptr2 = p_station->status_data;
+                while (ptr2->next->next != NULL) {
+                    ptr2 = ptr2->next;
+                }
+                // At this point, we have a pointer to the last
+                // record in ptr2->next.  Free it and the text
+                // string in it.
+                free(ptr2->next->text_ptr);
+                free(ptr2->next);
+                ptr2->next = NULL;
+            } 
+        }
+
+        if (add_it) {   // We add to the beginning so we don't have
+                        // to traverse the linked list.  This also
+                        // puts new records at the beginning of the
+                        // list to keep them in sorted order.
+
+            ptr = p_station->status_data;  // Save old pointer to records
+            p_station->status_data = (CommentRow *)malloc(sizeof(CommentRow));
+            CHECKMALLOC(p_station->status_data);
+
+            p_station->status_data->next = ptr;    // Link in old records or NULL
+
+            // Malloc the string space we'll need, attach it to our
+            // new record
+            p_station->status_data->text_ptr = (char *)malloc(sizeof(char) * (len+1));
+            CHECKMALLOC(p_station->status_data->text_ptr);
+
+            // Fill in the string
+            xastir_snprintf(p_station->status_data->text_ptr,
+                len+1,
+                "%s",
+                status_string);
+
+            // Fill in the timestamp
+            p_station->status_data->sec_heard = sec_now();
+
+            //fprintf(stderr,"Station:%s\tStatus:%s\n\n",p_station->call_sign,p_station->status_data->text_ptr);
+        }
+    }
+}
+
+
+
+
+ 
+// Add a comment line to the linked-list of comment records
+// associated with a station.  Note that a blank comment is allowed
+// and necessary for the times when we wish to blank out the comment
+// on an object/item, but we don't store that unless we have seen a
+// non-blank comment line previously.
+//
+void add_comment(DataRow *p_station, char *comment_string) {
+    CommentRow *ptr;
+    int add_it = 0;
+    int len;
+
+
+    len = strlen(comment_string);
+
+    // Eliminate line-end chars
+    if (len > 1) {
+        if ( (comment_string[len-1] == '\n')
+                || (comment_string[len-1] == '\r') ) {
+            comment_string[len-1] = '\0';
+        }
+    }
+
+    // Shorten it
+    //fprintf(stderr,"1Comment: (%s)\n",comment_string);
+    (void)remove_trailing_spaces(comment_string);
+    //fprintf(stderr,"2Comment: (%s)\n",comment_string);
+
+    ///////TVR DEBUGING RESULTS 28 March 2007:
+    //NO! DON'T DO THIS --- it breaks multipoint objects!
+    //    (void)remove_leading_spaces(comment_string);
+    ///////////////////////////////////////////
+
+    //fprintf(stderr,"3Comment: (%s)\n",comment_string);
+ 
+    len = strlen(comment_string);
+
+    // Check for valid pointer
+    if (p_station != NULL) {
+
+        // Check whether we have any data stored for this station
+        if (p_station->comment_data == NULL) {
+            if (len > 0) {
+                // No comments stored yet and new comment is
+                // non-NULL, so add it to the list.
+                add_it++;
+            }
+        }
+        else {  // We have comment data stored already
+                // Check for an identical string
+            CommentRow *ptr2;
+            int ii = 0;
+ 
+            ptr = p_station->comment_data;
+            ptr2 = ptr;
+            while (ptr != NULL) {
+
+                // Note that both text_ptr and comment_string can be
+                // empty strings.
+
+                if (strcasecmp(ptr->text_ptr, comment_string) == 0) {
+                    // Found a matching string
+//fprintf(stderr,"Found match: %s:%s\n",p_station->call_sign,comment_string);
+
+// Instead of updating the timestamp, we'll delete the record from
+// the list and add it to the top in the code below.  Make sure to
+// tweak the "ii" pointer so that we don't end up shortening the
+// list unnecessarily.
+                    if (ptr == p_station->comment_data) {
+                        // Only update the timestamp:  We're at the
+                        // beginning of the list already.
+                        ptr->sec_heard = sec_now();
+
+                        return; // No need to add a new record
+                    }
+                    else {  // Delete the record
+                        CommentRow *ptr3;
+
+                        // Keep a pointer to the record
+                        ptr3 = ptr;
+
+                        // Close the chain, skipping this record
+                        ptr2->next = ptr3->next;
+
+                        // Skip "ptr" over the record we with to
+                        // delete
+                        ptr = ptr3->next;
+
+                        // Free the record
+                        free(ptr3->text_ptr);
+                        free(ptr3);
+
+                        // Muck with the counter 'cuz we just
+                        // deleted one record
+                        ii--;
+                    }
+                }
+                ptr2 = ptr; // Keep this pointer one record back as
+                            // we progress.
+
+                if (ptr != NULL) {
+                    ptr = ptr->next;
+                }
+
+                ii++;
+            }
+            // No matching string found, or new timestamp found for
+            // old record.  Add it to the top of the list.
+            add_it++;
+            //fprintf(stderr,"No match: %s:%s\n",p_station->call_sign,comment_string);
+
+            // We counted the records.  If we have more than
+            // MAX_COMMENT_LINES records we'll delete/free the last
+            // one to make room for the next.  This keeps us from
+            // storing unique comment records ad infinitum for
+            // active stations, limiting the total space used.
+            //
+            if (ii >= MAX_COMMENT_LINES) {
+
+                // We know we didn't get a match, and that our list
+                // is full (as we want it to be).  Traverse the list
+                // again, looking for ptr2->next->next == NULL.  If
+                // found, free that last record and set the
+                // ptr2->next pointer to NULL.
+                ptr2 = p_station->comment_data;
+                while (ptr2->next->next != NULL) {
+                    ptr2 = ptr2->next;
+                }
+                // At this point, we have a pointer to the last
+                // record in ptr2->next.  Free it and the text
+                // string in it.
+                free(ptr2->next->text_ptr);
+                free(ptr2->next);
+                ptr2->next = NULL;
+            } 
+        }
+
+        if (add_it) {   // We add to the beginning so we don't have
+                        // to traverse the linked list.  This also
+                        // puts new records at the beginning of the
+                        // list to keep them in sorted order.
+
+            ptr = p_station->comment_data;  // Save old pointer to records
+            p_station->comment_data = (CommentRow *)malloc(sizeof(CommentRow));
+            CHECKMALLOC(p_station->comment_data);
+
+            p_station->comment_data->next = ptr;    // Link in old records or NULL
+
+            // Malloc the string space we'll need, attach it to our
+            // new record
+            p_station->comment_data->text_ptr = (char *)malloc(sizeof(char) * (len+1));
+            CHECKMALLOC(p_station->comment_data->text_ptr);
+
+            // Fill in the string
+            xastir_snprintf(p_station->comment_data->text_ptr,
+                len+1,
+                "%s",
+                comment_string);
+
+            // Fill in the timestamp
+            p_station->comment_data->sec_heard = sec_now();
+        }
+    }
+}
+ 
+
+
+
+
+/*
+ *  Add data from APRS information field to station database
+ *  Returns a 1 if successful
+ */
+int data_add(int type,
+             char *call_sign,
+             char *path,
+             char *data,
+             char from,
+             int port,
+             char *origin,
+             int third_party,
+             int station_is_mine,
+             int object_is_mine) {
+
+    DataRow *p_station;
+    DataRow *p_time;
+    char call[MAX_CALLSIGN+1];
+    char new_station;
+    long last_lat, last_lon;
+    char last_alt[MAX_ALTITUDE];
+    char last_speed[MAX_SPEED+1];
+    char last_course[MAX_COURSE+1];
+    time_t last_stn_sec;
+    short last_flag;
+    char temp_data[40]; // short term string storage, MAX_CALLSIGN, ...
+    long l_lat, l_lon;
+    double distance;
+    char station_id[600];
+    int found_pos;
+    float value;
+    WeatherRow *weather;
+    int moving;
+    int changed_pos;
+    int screen_update;
+    int ok, store;
+    int ok_to_display;
+    int compr_pos;
+    char *p = NULL; // KC2ELS - used for WIDEn-N
+    int direct = 0;
+    int new_origin_is_mine = 0;
+    int num_digits = 0; // Number of digits after decimal point in NMEA string
+
+#ifdef HAVE_DB
+    int ii;  // loop counter for interfaces list
+#endif /* HAVE_DB */
+
+    // call and path had been validated before
+    // Check "data" against the max APRS length, and dump the packet if too long.
+    if ( (data != NULL) && (strlen(data) > MAX_INFO_FIELD_SIZE) ) {   // Overly long packet.  Throw it away.
+        if (debug_level & 1)
+            fprintf(stderr,"data_add: Overly long packet.  Throwing it away.\n");
+        return(0);  // Not an ok packet
+    }
+
+    // Check for some reasonable string in call_sign parameter
+    if (call_sign == NULL || strlen(call_sign) == 0) {
+        if (debug_level & 1)
+            fprintf(stderr,"data_add():call_sign was NULL or empty, exiting\n");
+        return(0);
+    }
+ 
+    if (debug_level & 1)
+        fprintf(stderr,"data_add:\n\ttype: %d\n\tcall_sign: %s\n\tpath: %s\n\tdata: %s\n\tfrom: %c\n\tport: %d\n\torigin: %s\n\tthird_party: %d\n",
+            type,
+            call_sign,
+            path,
+            data ? data : "NULL",       // This parameter may be NULL, if exp1 then exp2 else exp3 
+            from,
+            port,
+            origin ? origin : "NULL",   // This parameter may be NULL
+            third_party);
+
+    if (origin && is_my_call(origin, 1)) {
+        new_origin_is_mine++;   // The new object/item is owned by me
+    }
+
+    weather = NULL; // only to make the compiler happy...
+    found_pos = 1;
+    xastir_snprintf(call,
+        sizeof(call),
+        "%s",
+        call_sign);
+    p_station = NULL;
+    new_station = (char)FALSE;                          // to make the compiler happy...
+    last_lat = 0L;
+    last_lon = 0L;
+    last_stn_sec = sec_now();
+    last_alt[0]    = '\0';
+    last_speed[0]  = '\0';
+    last_course[0] = '\0';
+    last_flag      = 0;
+    ok = 0;
+    store = 0;
+    p_time = NULL;                                      // add to end of time sorted list (newest)
+    compr_pos = 0;
+
+    if (search_station_name(&p_station,call,1)) {       // If we found the station in our list
+
+        if (debug_level & 1)
+            fprintf(stderr,"data_add: Found existing station record.\n");
+ 
+        move_station_time(p_station,p_time);        // update time, change position in time sorted list
+        new_station = (char)FALSE;                  // we have seen this one before
+
+        if (is_my_station(p_station)) {
+            station_is_mine++; // Station is  me
+        }
+        //fprintf(stderr,"checks ok\n");
+    }
+    else {
+        //fprintf(stderr,"data_add()\n");
+
+        if (debug_level & 1)
+            fprintf(stderr,"data_add: No existing station record found.\n");
+ 
+        p_station = add_new_station(p_station,p_time,call);     // create storage
+        new_station = (char)TRUE;                       // for new station
+    }
+
+    if (p_station != NULL) {
+
+        last_lat = p_station->coord_lat;                // remember last position
+        last_lon = p_station->coord_lon;
+        last_stn_sec = p_station->sec_heard;
+        xastir_snprintf(last_alt,
+            sizeof(last_alt),
+            "%s",
+            p_station->altitude);
+        xastir_snprintf(last_speed,
+            sizeof(last_speed),
+            "%s",
+            p_station->speed);
+        xastir_snprintf(last_course,
+            sizeof(last_course),    
+            "%s",
+            p_station->course);
+        last_flag = p_station->flag;
+
+        // Wipe out old data so that it doesn't hang around forever
+        p_station->altitude[0] = '\0';
+        p_station->speed[0] = '\0';
+        p_station->course[0] = '\0';
+
+        ok = 1;                         // succeed as default
+
+
+        switch (type) {
+
+            case (APRS_MICE):           // Mic-E format
+            case (APRS_FIXED):          // '!'
+            case (APRS_MSGCAP):         // '='
+
+                if (!extract_position(p_station,&data,type)) {          // uncompressed lat/lon
+                    compr_pos = 1;
+                    if (!extract_comp_position(p_station,&data,type))   // compressed lat/lon
+                        ok = 0;
+                    else
+                        p_station->pos_amb = 0; // No ambiguity in compressed posits
+                }
+
+                if (ok) {
+
+                    // Create a timestamp from the current time
+                    xastir_snprintf(p_station->pos_time,
+                        sizeof(p_station->pos_time),
+                        "%s",
+                        get_time(temp_data));
+                    (void)extract_storm(p_station,data,compr_pos);
+                    (void)extract_weather(p_station,data,compr_pos);    // look for weather data first
+                    process_data_extension(p_station,data,type);        // PHG, speed, etc.
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 1);
+ 
+                    add_comment(p_station,data);
+
+                    p_station->record_type = NORMAL_APRS;
+                    if (type == APRS_MSGCAP)
+                        p_station->flag |= ST_MSGCAP;           // set "message capable" flag
+                    else
+                        p_station->flag &= (~ST_MSGCAP);        // clear "message capable" flag
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+                    if (type == APRS_MICE || !compr_pos) {
+                        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                        p_station->lat_precision = 60;
+                        p_station->lon_precision = 60;
+                    }
+                    else {
+                        p_station->error_ellipse_radius = 600; // Default of 6m
+                        p_station->lat_precision = 6;
+                        p_station->lon_precision = 6;
+                    }
+
+                }
+                break;
+
+/*
+            case (APRS_DOWN):           // '/'
+                ok = extract_time(p_station, data, type);               // we need a time
+                if (ok) {
+                    if (!extract_position(p_station,&data,type)) {      // uncompressed lat/lon
+                        compr_pos = 1;
+                        if (!extract_comp_position(p_station,&data,type)) // compressed lat/lon
+                            ok = 0;
+                        else
+                            p_station->pos_amb = 0; // No ambiguity in compressed posits
+                    }
+                }
+
+                if (ok) {
+
+                    // Create a timestamp from the current time
+                    xastir_snprintf(p_station->pos_time,
+                        sizeof(p_station->pos_time),
+                        "%s",
+                        get_time(temp_data));
+                    process_data_extension(p_station,data,type);        // PHG, speed, etc.
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 1);
+ 
+                    add_comment(p_station,data);
+
+                    p_station->record_type = DOWN_APRS;
+                    p_station->flag &= (~ST_MSGCAP);            // clear "message capable" flag
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+                    if (!compr_pos) {
+                        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                        p_station->lat_precision = 60;
+                        p_station->lon_precision = 60;
+                    }
+                    else {
+                        p_station->error_ellipse_radius = 600; // Default of 6m
+                        p_station->lat_precision = 6;
+                        p_station->lon_precision = 6;
+                    }
+                }
+                break;
+*/
+
+            case (APRS_DF):             // '@'
+            case (APRS_MOBILE):         // '@'
+
+                ok = extract_time(p_station, data, type);               // we need a time
+                if (ok) {
+                    if (!extract_position(p_station,&data,type)) {      // uncompressed lat/lon
+                        compr_pos = 1;
+                        if (!extract_comp_position(p_station,&data,type)) // compressed lat/lon
+                            ok = 0;
+                        else
+                            p_station->pos_amb = 0; // No ambiguity in compressed posits
+                    }
+                }
+                if (ok) {
+
+                    process_data_extension(p_station,data,type);        // PHG, speed, etc.
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 1);
+ 
+                    add_comment(p_station,data);
+
+                    if(type == APRS_MOBILE)
+                        p_station->record_type = MOBILE_APRS;
+                    else
+                        p_station->record_type = DF_APRS;
+                    //@ stations have messaging per spec
+                    p_station->flag |= (ST_MSGCAP);            // set "message capable" flag
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+                    if (!compr_pos) {
+                        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                        p_station->lat_precision = 60;
+                        p_station->lon_precision = 60;
+                    }
+                    else {
+                        p_station->error_ellipse_radius = 600; // Default of 6m
+                        p_station->lat_precision = 6;
+                        p_station->lon_precision = 6;
+                    }
+                }
+                break;
+
+            case (APRS_GRID):
+
+                ok = extract_position(p_station, &data, type);
+                if (ok) { 
+
+                    if (debug_level & 1)
+                        fprintf(stderr,"data_add: Got grid data for %s\n", call);
+
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 1);
+ 
+                    add_comment(p_station,data);
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+//                    p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+
+// WE7U
+// This needs to change based on the number of grid letters/digits specified
+//                    p_station->lat_precision = 60;
+//                    p_station->lon_precision = 60;
+                }
+                else {
+                    if (debug_level & 1)
+                        fprintf(stderr,"data_add: Bad grid data for %s : %s\n", call, data);
+                }
+                break;
+
+            case (STATION_CALL_DATA):
+
+                p_station->record_type = NORMAL_APRS;
+                found_pos = 0;
+                break;
+
+            case (APRS_STATUS):         // '>' Status Reports     [APRS Reference, chapter 16]
+
+                (void)extract_time(p_station, data, type);              // we need a time
+                // todo: could contain Maidenhead or beam heading+power
+
+                if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                    extract_multipoints(p_station, data, type, 1);
+ 
+                add_status(p_station,data);
+
+                p_station->flag |= (ST_STATUS);                         // set "Status" flag
+                p_station->record_type = NORMAL_APRS;                   // ???
+                found_pos = 0;
+                break;
+
+            case (OTHER_DATA):          // Other Packets          [APRS Reference, chapter 19]
+
+                // non-APRS beacons, treated as status reports until we get a real one
+
+                if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                    extract_multipoints(p_station, data, type, 1);
+ 
+                if ((p_station->flag & (~ST_STATUS)) == 0) {            // only store if no status yet
+
+                    add_status(p_station,data);
+
+                    p_station->record_type = NORMAL_APRS;               // ???
+                }
+                found_pos = 0;
+                break;
+
+            case (APRS_OBJECT):
+                if (debug_level & 2048) {
+                    fprintf (stderr,"  Object: before any extractions at all, data is \"%s\"\n",data);
+                    }
+
+                // If old match is a killed Object (owner doesn't
+                // matter), new one is an active Object and owned by
+                // us, remove the old record and create a new one
+                // for storing this Object.  Do the same for Items
+                // in the next section below.
+                //
+                // The easiest implementation might be to remove the
+                // old record and then call this routine again with
+                // the same parameters, which will cause a brand-new
+                // record to be created.
+                //
+                // The new record we're processing is an active
+                // object, as data_add() won't be called on a killed
+                // object.
+                //
+//                if ( is_my_call(origin,1)  // If new Object is owned by me (including SSID)
+                if (new_origin_is_mine
+                        && !(p_station->flag & ST_ACTIVE)
+                        && (p_station->flag & ST_OBJECT) ) {  // Old record was a killed Object
+                    station_del_ptr(p_station);  // Remove old killed Object
+                                                 // *completely*
+                    redo_list = (int)TRUE;
+                    return( data_add(type, call_sign, path, data, from, port, origin, third_party, 0, 1) );
+                }
+ 
+                ok = extract_time(p_station, data, type);               // we need a time
+                if (ok) {
+                    if (!extract_position(p_station,&data,type)) {      // uncompressed lat/lon
+                        compr_pos = 1;
+                        if (!extract_comp_position(p_station,&data,type)) // compressed lat/lon
+                            ok = 0;
+                        else
+                            p_station->pos_amb = 0; // No ambiguity in compressed posits
+                    }
+                }
+                p_station->flag |= ST_OBJECT;                           // Set "Object" flag
+                if (ok) {
+
+                    // If object was owned by me but another station
+                    // is transmitting it now, write entries into
+                    // the object.log file showing that we don't own
+                    // this object anymore.
+//                    if ( (is_my_call(p_station->origin,1))  // If station was owned by me (including SSID)
+//                            && (!is_my_call(origin,1)) ) {  // But isn't now
+                    if (is_my_object_item(p_station)    // If station was owned by me (include SSID)
+                            && !new_origin_is_mine) {   // But isn't now
+
+                        disown_object_item(call_sign, origin);
+                    }
+
+                    // If station is owned by me (including SSID)
+                    // but it's a new object/item
+//                    if ( (is_my_call(p_station->origin,1))
+                    if (new_origin_is_mine
+                            && (p_station->transmit_time_increment == 0) ) {
+                        // This will get us transmitting this object
+                        // on the decaying algorithm schedule.
+                        // We've transmitted it once if we've just
+                        // gotten to this code.
+                        p_station->transmit_time_increment = OBJECT_CHECK_RATE;
+//fprintf(stderr,"data_add(): Setting transmit_time_increment to %d\n", OBJECT_CHECK_RATE);
+                    }
+ 
+                    // Create a timestamp from the current time
+                    xastir_snprintf(p_station->pos_time,
+                        sizeof(p_station->pos_time),
+                        "%s",
+                        get_time(temp_data));
+
+                    xastir_snprintf(p_station->origin,
+                        sizeof(p_station->origin),
+                        "%s",
+                        origin);                   // define it as object
+                    if (debug_level & 2048) {
+                        fprintf (stderr,"  Object: before any extractions, data is \"%s\"\n",data);
+                    }
+                    (void)extract_storm(p_station,data,compr_pos);
+                    (void)extract_weather(p_station,data,compr_pos);    // look for wx info
+                    process_data_extension(p_station,data,type);        // PHG, speed, etc.
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if (debug_level & 2048) {
+                        fprintf (stderr,"  Object: calling extract_multipoints with data \"%s\"\n",data);
+                    }
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 0);
+ 
+                    add_comment(p_station,data);
+
+                    // the last char always was missing...
+                    //p_station->comments[ strlen(p_station->comments) - 1 ] = '\0';  // Wipe out '\n'
+                    // moved that to decode_ax25_line
+                    // and don't added a '\n' in interface.c
+                    p_station->record_type = NORMAL_APRS;
+                    p_station->flag &= (~ST_MSGCAP);            // clear "message capable" flag
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+                    if (!compr_pos) {
+                        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                        p_station->lat_precision = 60;
+                        p_station->lon_precision = 60;
+                    }
+                    else {
+                        p_station->error_ellipse_radius = 600; // Default of 6m
+                        p_station->lat_precision = 6;
+                        p_station->lon_precision = 6;
+                    }
+                }
+                break;
+
+            case (APRS_ITEM):
+
+                // If old match is a killed Item (owner doesn't
+                // matter), new one is an active Item and owned by
+                // us, remove the old record and create a new one
+                // for storing this Item.  Do the same for Objects
+                // in the previous section above.
+                //
+                // The easiest implementation might be to remove the
+                // old record and then call this routine again with
+                // the same parameters, which will cause a brand-new
+                // record to be created.
+                //
+                // The new record we're processing is an active
+                // Item, as data_add() won't be called on a killed
+                // Item.
+                //
+//                if ( is_my_call(origin,1)  // If new Item is owned by me (including SSID)
+                if (new_origin_is_mine
+                        && !(p_station->flag & ST_ACTIVE)
+                        && (p_station->flag & ST_ITEM) ) {  // Old record was a killed Item
+ 
+                    station_del_ptr(p_station);  // Remove old killed Item
+                                                 // *completely*
+                    redo_list = (int)TRUE;
+                    return( data_add(type, call_sign, path, data, from, port, origin, third_party, 0, 1) );
+                }
+ 
+                if (!extract_position(p_station,&data,type)) {          // uncompressed lat/lon
+                    compr_pos = 1;
+                    if (!extract_comp_position(p_station,&data,type))   // compressed lat/lon
+                        ok = 0;
+                    else
+                        p_station->pos_amb = 0; // No ambiguity in compressed posits
+                }
+                p_station->flag |= ST_ITEM;                             // Set "Item" flag
+                if (ok) {
+
+                    // If item was owned by me but another station
+                    // is transmitting it now, write entries into
+                    // the object.log file showing that we don't own
+                    // this item anymore.
+//                    if ( (is_my_call(p_station->origin,1))  // If station was owned by me (including SSID)
+//                            && (!is_my_call(origin,1)) ) {  // But isn't now
+                    if (is_my_object_item(p_station)
+                            && !new_origin_is_mine) {  // But isn't now
+
+                        disown_object_item(call_sign,origin);
+                    }
+ 
+                    // If station is owned by me (including SSID)
+                    // but it's a new object/item
+//                    if ( (is_my_call(p_station->origin,1))
+                    if (is_my_object_item(p_station)
+                            && (p_station->transmit_time_increment == 0) ) {
+                        // This will get us transmitting this object
+                        // on the decaying algorithm schedule.
+                        // We've transmitted it once if we've just
+                        // gotten to this code.
+                        p_station->transmit_time_increment = OBJECT_CHECK_RATE;
+//fprintf(stderr,"data_add(): Setting transmit_time_increment to %d\n", OBJECT_CHECK_RATE);
+                    }
+ 
+                    // Create a timestamp from the current time
+                    xastir_snprintf(p_station->pos_time,
+                        sizeof(p_station->pos_time),
+                        "%s",
+                        get_time(temp_data));
+                    xastir_snprintf(p_station->origin,
+                        sizeof(p_station->origin),
+                        "%s",
+                        origin);                   // define it as item
+                    (void)extract_storm(p_station,data,compr_pos);
+                    (void)extract_weather(p_station,data,compr_pos);    // look for wx info
+                    process_data_extension(p_station,data,type);        // PHG, speed, etc.
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 0);
+ 
+                    add_comment(p_station,data);
+
+                    // the last char always was missing...
+                    //p_station->comments[ strlen(p_station->comments) - 1 ] = '\0';  // Wipe out '\n'
+                    // moved that to decode_ax25_line
+                    // and don't added a '\n' in interface.c
+                    p_station->record_type = NORMAL_APRS;
+                    p_station->flag &= (~ST_MSGCAP);            // clear "message capable" flag
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+                    if (!compr_pos) {
+                        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                        p_station->lat_precision = 60;
+                        p_station->lon_precision = 60;
+                    }
+                    else {
+                        p_station->error_ellipse_radius = 600; // Default of 6m
+                        p_station->lat_precision = 6;
+                        p_station->lon_precision = 6;
+                    }
+                }
+                break;
+
+            case (APRS_WX1):    // weather in '@' or '/' packet
+
+                ok = extract_time(p_station, data, type);               // we need a time
+                if (ok) {
+                    if (!extract_position(p_station,&data,type)) {      // uncompressed lat/lon
+                        compr_pos = 1;
+                        if (!extract_comp_position(p_station,&data,type)) // compressed lat/lon
+                            ok = 0;
+                        else
+                            p_station->pos_amb = 0; // No ambiguity in compressed posits
+                    }
+                }
+                if (ok) {
+
+                    (void)extract_storm(p_station,data,compr_pos);
+                    (void)extract_weather(p_station,data,compr_pos);
+                    p_station->record_type = (char)APRS_WX1;
+
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 1);
+ 
+                    add_comment(p_station,data);
+
+                    // Assign a non-default value for the error
+                    // ellipse?
+                    if (!compr_pos) {
+                        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                        p_station->lat_precision = 60;
+                        p_station->lon_precision = 60;
+                    }
+                    else {
+                        p_station->error_ellipse_radius = 600; // Default of 6m
+                        p_station->lat_precision = 6;
+                        p_station->lon_precision = 6;
+                    }
+                }
+                break;
+
+            case (APRS_WX2):            // '_'
+
+                ok = extract_time(p_station, data, type);               // we need a time
+                if (ok) {
+                    (void)extract_storm(p_station,data,compr_pos);
+                    (void)extract_weather(p_station,data,0);            // look for weather data first
+                    p_station->record_type = (char)APRS_WX2;
+                    found_pos = 0;
+
+                    process_info_field(p_station,data,type);            // altitude
+
+                    if ( (p_station->coord_lat > 0) && (p_station->coord_lon > 0) )
+                        extract_multipoints(p_station, data, type, 1);
+                }
+                break;
+
+            case (APRS_WX4):            // '#'          Peet Bros U-II (km/h)
+            case (APRS_WX6):            // '*'          Peet Bros U-II (mph)
+            case (APRS_WX3):            // '!'          Peet Bros Ultimeter 2000 (data logging mode)
+            case (APRS_WX5):            // '$ULTW'      Peet Bros Ultimeter 2000 (packet mode)
+
+                if (get_weather_record(p_station)) {    // get existing or create new weather record
+                    weather = p_station->weather_data;
+                    if (type == APRS_WX3)   // Peet Bros Ultimeter 2000 data logging mode
+                        decode_U2000_L(1,(unsigned char *)data,weather);
+                    else if (type == APRS_WX5) // Peet Bros Ultimeter 2000 packet mode
+                        decode_U2000_P(1,(unsigned char *)data,weather);
+                    else    // Peet Bros Ultimeter-II
+                        decode_Peet_Bros(1,(unsigned char *)data,weather,type);
+                    p_station->record_type = (char)type;
+                    // Create a timestamp from the current time
+                    xastir_snprintf(weather->wx_time,
+                        sizeof(weather->wx_time),
+                        "%s",
+                        get_time(temp_data));
+                    weather->wx_sec_time = sec_now();
+                    found_pos = 0;
+                }
+                break;
+
+
+// GPRMC, digits after decimal point
+// ---------------------------------
+// 2  = 25.5 meter error ellipse
+// 3  =  6.0 meter error ellipse
+// 4+ =  6.0 meter error ellipse
+
+
+            case (GPS_RMC):             // $GPRMC
+
+// WE7U
+// Change this function to return HDOP and the number of characters
+// after the decimal point.
+                ok = extract_RMC(p_station,data,call_sign,path,&num_digits);
+
+                if (ok) {
+                    // Assign a non-default value for the error
+                    // ellipse?
+//
+// WE7U
+// Degrade based on the precision provided in the sentence.  If only
+// 2 digits after decimal point, give it 2550 as a radius (25.5m).
+// Best (smallest) circle should be 600 as we have no augmentation
+// flag to check here for anything better.
+//
+                    switch (num_digits) {
+
+                        case 0:
+                            p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                            p_station->lat_precision = 6000;
+                            p_station->lon_precision = 6000;
+                            break;
+
+                        case 1:
+                            p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                            p_station->lat_precision = 600;
+                            p_station->lon_precision = 600;
+                            break;
+
+                        case 2:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 60;
+                            p_station->lon_precision = 60;
+                            break;
+
+                        case 3:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 6;
+                            p_station->lon_precision = 6;
+                            break;
+
+                        case 4:
+                        case 5:
+                        case 6:
+                        case 7:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 0;
+                            p_station->lon_precision = 0;
+                            break;
+
+                        default:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 60;
+                            p_station->lon_precision = 60;
+                            break;
+                    }
+                }
+                break;
+
+
+// GPGGA, digits after decimal point, w/o augmentation
+// ---------------------------------------------------
+// 2   = 25.5 meter error ellipse
+// 3   =  6.0 meter error ellipse unless HDOP>4, then 10.0 meters
+// 4+  =  6.0 meter error ellipse unless HDOP>4, then 10.0 meters
+// 
+// 
+// GPGGA, digits after decimal point, w/augmentation
+// --------------------------------------------------
+// 2   = 25.5 meter error ellipse
+// 3   =  2.5 meter error ellipse unless HDOP>4, then 10.0 meters
+// 4+  =  0.6 meter error ellipse unless HDOP>4, then 10.0 meters
+
+
+            case (GPS_GGA):             // $GPGGA
+
+// WE7U
+// Change this function to return HDOP and the number of characters
+// after the decimal point.
+                ok = extract_GGA(p_station,data,call_sign,path,&num_digits);
+
+                if (ok) {
+                    // Assign a non-default value for the error
+                    // ellipse?
+//
+// WE7U
+// Degrade based on the precision provided in the sentence.  If only
+// 2 digits after decimal point, give it 2550 as a radius (25.5m).
+// 3 digits: 6m w/o augmentation unless HDOP >4 = 10m, 2.5m w/augmentation.
+// 4+ digits: 6m w/o augmentation unless HDOP >4 = 10m, 0.6m w/augmentation.
+//
+                     switch (num_digits) {
+
+                        case 0:
+                            p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                            p_station->lat_precision = 6000;
+                            p_station->lon_precision = 6000;
+                            break;
+
+                        case 1:
+                            p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                            p_station->lat_precision = 600;
+                            p_station->lon_precision = 600;
+                            break;
+
+                        case 2:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 60;
+                            p_station->lon_precision = 60;
+                            break;
+
+                        case 3:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 6;
+                            p_station->lon_precision = 6;
+                            break;
+
+                        case 4:
+                        case 5:
+                        case 6:
+                        case 7:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 0;
+                            p_station->lon_precision = 0;
+                            break;
+
+                        default:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 60;
+                            p_station->lon_precision = 60;
+                            break;
+                    }
+                }
+                break;
+
+
+// GPGLL, digits after decimal point
+// ---------------------------------
+// 2  = 25.5 meter error ellipse
+// 3  =  6.0 meter error ellipse
+// 4+ =  6.0 meter error ellipse
+
+
+            case (GPS_GLL):             // $GPGLL
+                ok = extract_GLL(p_station,data,call_sign,path,&num_digits);
+
+                if (ok) {
+                    // Assign a non-default value for the error
+                    // ellipse?
+//
+// WE7U
+// Degrade based on the precision provided in the sentence.  If only
+// 2 digits after decimal point, give it 2550 as a radius, otherwise
+// give it 600.
+//
+                     switch (num_digits) {
+
+                        case 0:
+                            p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                            p_station->lat_precision = 6000;
+                            p_station->lon_precision = 6000;
+                            break;
+ 
+                        case 1:
+                            p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+                            p_station->lat_precision = 600;
+                            p_station->lon_precision = 600;
+                            break;
+
+                        case 2:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 60;
+                            p_station->lon_precision = 60;
+                            break;
+
+                        case 3:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 6;
+                            p_station->lon_precision = 6;
+                            break;
+
+                        case 4:
+                        case 5:
+                        case 6:
+                        case 7:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 0;
+                            p_station->lon_precision = 0;
+                            break;
+
+                        default:
+                            p_station->error_ellipse_radius = 600; // Default of 6m
+                            p_station->lat_precision = 60;
+                            p_station->lon_precision = 60;
+                            break;
+                    }
+ 
+                }
+                break;
+
+            default:
+
+                fprintf(stderr,"ERROR: UNKNOWN TYPE in data_add\n");
+                ok = 0;
+                break;
+        }
+
+        // Left this one in, just in case.  Perhaps somebody might
+        // attach a multipoint string onto the end of a packet we
+        // might not expect.  For this case we need to check whether
+        // we have multipoints first, as we don't want to erase the
+        // work we might have done with a previous call to
+        // extract_multipoints().
+        if (ok && (p_station->coord_lat > 0)
+                && (p_station->coord_lon > 0)
+                && (p_station->num_multipoints == 0) ) {  // No multipoints found yet
+
+            extract_multipoints(p_station, data, type, 0);
+        }
+    }
+
+    if (!ok) {  // non-APRS beacon, treat it as Other Packet   [APRS Reference, chapter 19]
+
+        if (debug_level & 1) {
+            char filtered_data[MAX_LINE_SIZE + 1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                data-1);
+            makePrintable(filtered_data);
+            fprintf(stderr,"store non-APRS data as status: %s: |%s|\n",call,filtered_data);
+        }
+
+        // GPRMC etc. without a position is here too, but it should not be stored as status!
+
+        // store it as status report until we get a real one
+        if ((p_station->flag & (~ST_STATUS)) == 0) {         // only store it if no status yet
+ 
+            add_status(p_station,data-1);
+
+            p_station->record_type = NORMAL_APRS;               // ???
+ 
+        }
+ 
+        ok = 1;            
+        found_pos = 0;
+    }
+ 
+    curr_sec = sec_now();
+    if (ok) {
+
+        // data packet is valid
+        // announce own echo, we soon discard that packet...
+//        if (!new_station && is_my_call(p_station->call_sign,1) // Check SSID as well
+        if (!new_station
+                && is_my_station(p_station) // Check SSID as well
+                && strchr(path,'*') != NULL) {
+ 
+            upd_echo(path);   // store digi that echoes my signal...
+            statusline(langcode("BBARSTA033"),0);   // Echo from digipeater
+
+        }
+        // check if data is just a secondary echo from another digi
+        if ((last_flag & ST_VIATNC) == 0
+                || (curr_sec - last_stn_sec) > 15
+                || p_station->coord_lon != last_lon 
+                || p_station->coord_lat != last_lat)
+ 
+            store = 1;                     // don't store secondary echos
+    }
+ 
+    if (!ok && new_station)
+        delete_station_memory(p_station);       // remove unused record
+ 
+    if (store) {
+ 
+        // we now have valid data to store into database
+        // make time index unique by adding a serial number
+
+        if (station_is_mine) {
+            // This station is me.  Set the
+            // flag which shows that we own/control this
+            // station.  We use this flag later in lieu
+            // of the is_my_call() function in order to speed things
+            // up.
+            //
+            p_station->flag |= ST_MYSTATION;
+        }
+
+        // Check whether it's a locally-owned object/item
+        if ( object_is_mine
+                || (   new_origin_is_mine
+                    && (p_station->flag & ST_ACTIVE)
+                    && (p_station->flag & ST_OBJECT) ) ) {
+
+            p_station->flag |= ST_MYOBJITEM;
+
+            // Do nothing else.  We don't want to update the
+            // last-heard time so that it'll expire from the queue
+            // normally, unless it is a new object/item.
+            //
+            if (new_station) {
+                p_station->sec_heard = curr_sec;
+            }
+
+            // We need an exception later in this function for the
+            // case where we've moved an object/item (by how much?).
+            // We need to update the time in this case so that it'll
+            // expire later (in fact it could already be expired
+            // when we move it).  We should be able to move expired
+            // objects/items to make them active again.  Perhaps
+            // some other method as well?.
+        }
+        else {
+            // Reset the "my object" flag
+            p_station->flag &= ~ST_MYOBJITEM;
+
+            p_station->sec_heard = curr_sec;    // Give it a new timestamp
+        }
+
+        if (curr_sec != last_sec) {     // todo: if old time calculate time_sn from database
+            last_sec = curr_sec;
+            next_time_sn = 0;           // restart time serial number
+        }
+
+        p_station->time_sn = next_time_sn++;            // todo: warning if serial number too high
+        if (from == DATA_VIA_TNC) {                     // heard via TNC
+            if (!third_party) { // Not a third-party packet
+                p_station->flag |= ST_VIATNC;               // set "via TNC" flag
+                p_station->heard_via_tnc_last_time = curr_sec;
+                p_station->heard_via_tnc_port = port;
+            }
+            else {  // Third-party packet
+                // Leave the previous setting of "flag" alone.
+                // Specifically do NOT set the ST_VIATNC flag if it
+                // was a third-party packet.
+            }
+        }
+        else {  // heard other than TNC
+            if (new_station) {  // new station
+                p_station->flag &= (~ST_VIATNC);  // clear "via TNC" flag
+//fprintf(stderr,"New_station: Cleared ST_VIATNC flag: %s\n", p_station->call_sign);
+                p_station->heard_via_tnc_last_time = 0l;
+            }
+        }
+        p_station->last_port_heard = port;
+        p_station->data_via = from;
+        // Create a timestamp from the current time
+        xastir_snprintf(p_station->packet_time,
+            sizeof(p_station->packet_time),
+            "%s",
+            get_time(temp_data)); // get_time returns value in temp_data
+
+        p_station->flag |= ST_ACTIVE;
+        if (third_party)
+            p_station->flag |= ST_3RD_PT;               // set "third party" flag
+        else
+            p_station->flag &= (~ST_3RD_PT);            // clear "third party" flag
+        if (origin != NULL && strcmp(origin,"INET") == 0)  // special treatment for inet names
+            xastir_snprintf(p_station->origin,
+                sizeof(p_station->origin),
+                "%s",
+                origin);           // to keep them separated from calls
+        if (origin != NULL && strcmp(origin,"INET-NWS") == 0)  // special treatment for NWS
+            xastir_snprintf(p_station->origin,
+                sizeof(p_station->origin),
+                "%s",
+                origin);           // to keep them separated from calls
+
+        if (origin != NULL && strcmp(origin,"INET-BOM") == 0)  // special treatment for BOM (AU)
+            xastir_snprintf(p_station->origin,
+                sizeof(p_station->origin),
+                "%s",
+                origin);           // to keep them separated from calls
+
+        if (origin == NULL || origin[0] == '\0')        // normal call
+            p_station->origin[0] = '\0';                // undefine possible former object with same name
+
+
+        //--------------------------------------------------------------------
+
+        // KC2ELS
+        // Okay, here are the standards for ST_DIRECT:
+        // 1.  The packet must have been received via TNC.
+        // 2.  The packet must not have any * flags.
+        // 3.  If present, the first WIDEn-N (or TRACEn-N) must have n=N.
+        // A station retains the ST_DIRECT setting.  If
+        // "st_direct_timeout" seconds have passed since we set
+        // that bit then APRSD queries and displays based on the
+        // ST_DIRECT bit will skip that station.
+
+// In order to make this scheme work for stations that straddle both
+// RF and INET, we need to make sure that node_path_ptr doesn't get
+// overwritten with an INET path if there's an RF path already in
+// there and it has been less than st_direct_timeout seconds since
+// the station was last heard on RF.
+
+        if ((from == DATA_VIA_TNC)             // Heard via TNC
+                && !third_party                // Not a 3RD-Party packet
+                && path != NULL                // Path is not NULL
+                && strchr(path,'*') == NULL) { // No asterisk found
+
+            // Look for WIDE or TRACE
+            if ((((p = strstr(path,"WIDE")) != NULL) 
+                    && (p+=4)) || 
+                    (((p = strstr(path,"TRACE")) != NULL) 
+                    && (p+=5))) {
+
+                // Look for n=N on WIDEn-N/TRACEn-N digi field
+                if ((*p != '\0') && isdigit((int)*p)) {
+                    if ((*(p+1) != '\0') && (*(p+1) == '-')) {
+                        if ((*(p+2) != '\0') && isdigit((int)*(p+2))) {
+                            if (*(p) == *(p+2)) {
+                                direct = 1;
+                            }
+                            else {
+                                direct = 0;
+                            }
+                        }
+                        else {
+                            direct = 0;
+                        }
+                    }
+                    else {
+                        direct = 0;
+                    }
+                }
+                else {
+                    direct = 1;
+                }
+            }
+            else {
+                direct = 1;
+            }
+        }
+        else {
+            direct = 0;
+        }
+
+        if (direct == 1) {
+            // This packet was heard direct.  Set the ST_DIRECT bit
+            // and save the timestamp away.
+            if (debug_level & 1) {
+                fprintf(stderr,"Setting ST_DIRECT for station %s\n", 
+                    p_station->call_sign);
+            }
+            p_station->direct_heard = curr_sec;
+            p_station->flag |= (ST_DIRECT);
+        }
+        else {
+            // This packet was NOT heard direct.  Check whether we
+            // need to expire the ST_DIRECT bit.  A lot of fixed
+            // stations transmit every 30 minutes.  One hour gives
+            // us time to receive a direct packet from them among
+            // all the digipeated packets.
+
+            if ((p_station->flag & ST_DIRECT) != 0 &&
+                    curr_sec > (p_station->direct_heard + st_direct_timeout)) {
+                if (debug_level & 1)
+                    fprintf(stderr,"Clearing ST_DIRECT for station %s\n", 
+                        p_station->call_sign);
+                p_station->flag &= (~ST_DIRECT);
+            }
+        }
+
+        // If heard on TNC, overwrite node_path_ptr if any of these
+        // conditions are met:
+        //     *) direct == 1 (packet was heard direct)
+        //     *) ST_DIRECT flag == 0 (packet hasn't been heard
+        //     direct recently)
+        //     *) ST_DIRECT is set, st_direct_timeout has expired
+        //     (packet hasn't been heard direct recently)
+        //
+        // These rules will allow us to keep directly heard paths
+        // saved for at least an hour (st_direct_timeout), and not
+        // get overwritten with digipeated paths during that time.
+        //
+        if ((from == DATA_VIA_TNC)  // Heard via TNC
+                && !third_party     // Not a 3RD-Party packet
+                && path != NULL) {  // Path is not NULL
+
+            // Heard on TNC interface and not third party.  Check
+            // the other conditions listed in the comments above to
+            // decide whether we should overwrite the node_path_ptr
+            // variable.
+            //
+            if ( direct   // This packet was heard direct
+                 || (p_station->flag & ST_DIRECT) == 0  // Not heard direct lately
+                 || ( (p_station->flag & ST_DIRECT) != 0 // Not heard direct lately
+                      && (curr_sec > (p_station->direct_heard+st_direct_timeout) ) ) ) {
+
+                // Free any old path we might have
+                if (p_station->node_path_ptr != NULL)
+                    free(p_station->node_path_ptr);
+                // Malloc and store the new path
+                p_station->node_path_ptr = (char *)malloc(strlen(path) + 1);
+                CHECKMALLOC(p_station->node_path_ptr);
+
+                substr(p_station->node_path_ptr,path,strlen(path));
+            }
+        }
+
+        // If a 3rd-party packet heard on TNC, overwrite
+        // node_path_ptr only if heard_via_tnc_last_time is older
+        // than one hour (zero counts as well!), plus clear the
+        // ST_DIRECT and ST_VIATNC bits in this case.  This makes us
+        // keep the RF path around for at least one hour after the
+        // station is heard.
+        //
+        else if ((from == DATA_VIA_TNC)  // Heard via TNC
+                && third_party      // It's a 3RD-Party packet
+                && path != NULL) {  // Path is not NULL
+
+            // 3rd-party packet heard on TNC interface.  Check if
+            // heard_via_tnc_last_time is older than an hour.  If
+            // so, overwrite the path and clear a few bits to show
+            // that it has timed out on RF and we're now receiving
+            // that station from an igate.
+            //
+            if (curr_sec > (p_station->heard_via_tnc_last_time + 60*60)) {
+
+                // Yep, more than one hour old or is a zero,
+                // overwrite the node_path_ptr variable with the new
+                // one.  We're only hearing this station on INET
+                // now.
+
+                // Free any old path we might have
+                if (p_station->node_path_ptr != NULL)
+                    free(p_station->node_path_ptr);
+                // Malloc and store the new path
+                p_station->node_path_ptr = (char *)malloc(strlen(path) + 1);
+                CHECKMALLOC(p_station->node_path_ptr);
+
+                substr(p_station->node_path_ptr,path,strlen(path));
+
+                // Clear the ST_VIATNC bit
+                p_station->flag &= ~ST_VIATNC;
+            }
+
+            // If direct_heard is over an hour old, clear the
+            // ST_DIRECT flag.  We're only hearing this station on
+            // INET now.
+            // 
+            if (curr_sec > (p_station->direct_heard + st_direct_timeout)) {
+
+                // Yep, more than one hour old or is a zero, clear
+                // the ST_DIRECT flag.
+                p_station->flag &= ~ST_DIRECT;
+            }
+        }
+ 
+        // If heard on INET then overwrite node_path_ptr only if
+        // heard_via_tnc_last_time is older than one hour (zero
+        // counts as well!), plus clear the ST_DIRECT and ST_VIATNC
+        // bits in this case.  This makes us keep the RF path around
+        // for at least one hour after the station is heard.
+        //
+        else if (from != DATA_VIA_TNC  // From an INET interface
+                && !third_party        // Not a 3RD-Party packet
+                && path != NULL) {     // Path is not NULL
+
+            // Heard on INET interface.  Check if
+            // heard_via_tnc_last_time is older than an hour.  If
+            // so, overwrite the path and clear a few bits to show
+            // that it has timed out on RF and we're now receiving
+            // that station from the INET feeds.
+            //
+            if (curr_sec > (p_station->heard_via_tnc_last_time + 60*60)) {
+
+                // Yep, more than one hour old or is a zero,
+                // overwrite the node_path_ptr variable with the new
+                // one.  We're only hearing this station on INET
+                // now.
+
+                // Free any old path we might have
+                if (p_station->node_path_ptr != NULL)
+                    free(p_station->node_path_ptr);
+                // Malloc and store the new path
+                p_station->node_path_ptr = (char *)malloc(strlen(path) + 1);
+                CHECKMALLOC(p_station->node_path_ptr);
+
+                substr(p_station->node_path_ptr,path,strlen(path));
+
+                // Clear the ST_VIATNC bit
+                p_station->flag &= ~ST_VIATNC;
+/*
+fprintf(stderr,
+    "\ntype:%d call:%s path:%s data:%s from:%c port:%d origin:%s 3rd:%d\n",
+    type,
+    call_sign,
+    path,
+    data,
+    from,
+    port,
+    origin,
+    third_party);
+fprintf(stderr,"Cleared ST_VIATNC flag (2): %s\n", p_station->call_sign);
+*/
+            }
+
+            // If direct_heard is over an hour old, clear the
+            // ST_DIRECT flag.  We're only hearing this station on
+            // INET now.
+            // 
+            if (curr_sec > (p_station->direct_heard + st_direct_timeout)) {
+
+                // Yep, more than one hour old or is a zero, clear
+                // the ST_DIRECT flag.
+                p_station->flag &= ~ST_DIRECT;
+            }
+        }
+ 
+ 
+        //---------------------------------------------------------------------
+
+        p_station->num_packets += 1;
+        redo_list = (int)TRUE;          // we may need to update the lists
+
+        if (found_pos) {        // if station has a position with the data
+            if (position_on_extd_screen(p_station->coord_lat,p_station->coord_lon)) {
+                p_station->flag |= (ST_INVIEW);   // set   "In View" flag
+                if (debug_level & 256)
+                    fprintf(stderr,"Setting ST_INVIEW flag\n");
+            }
+            else {
+                p_station->flag &= (~ST_INVIEW);  // clear "In View" flag
+                if (debug_level & 256)
+                    fprintf(stderr,"Clearing ST_INVIEW flag\n");
+            }
+        }
+
+        screen_update = 0;
+        if (new_station) {
+            if (debug_level & 256) {
+                fprintf(stderr,"New Station %s\n", p_station->call_sign);
+            }
+            if (strlen(p_station->speed) > 0 && atof(p_station->speed) > 0) {
+                p_station->flag |= (ST_MOVING); // it has a speed, so it's moving
+                moving = 1;
+            }
+            if (position_on_screen(p_station->coord_lat,p_station->coord_lon)) {
+
+                if (p_station->coord_lat != 0 && p_station->coord_lon != 0) {   // discard undef positions from screen
+                    if (!altnet || is_altnet(p_station) ) {
+                        display_station(da,p_station,1);
+                        screen_update = 1;  // ???
+                    }
+                }
+            }
+        }
+        else {        // we had seen this station before...
+            if (debug_level & 256) {
+                fprintf(stderr,"New Data for %s %ld %ld\n", p_station->call_sign,
+                    p_station->coord_lat, p_station->coord_lon);
+            }
+            if (found_pos && position_defined(p_station->coord_lat,p_station->coord_lon,1)) { // ignore undefined and 0N/0E
+                if (debug_level & 256) {
+                    fprintf(stderr,"  Valid position for %s\n",
+                        p_station->call_sign);
+                }
+                if (p_station->newest_trackpoint != NULL) {
+                    if (debug_level & 256) {
+                        fprintf(stderr,"Station has a trail: %s\n",
+                            p_station->call_sign);
+                    }
+                    moving = 1;                         // it's moving if it has a trail
+                }
+                else {
+                    if (strlen(p_station->speed) > 0 && atof(p_station->speed) > 0) {
+                        if (debug_level & 256) {
+                            fprintf(stderr,"Speed detected on %s\n",
+                                p_station->call_sign);
+                        }
+                        moving = 1;                     // declare it moving, if it has a speed
+                    }
+                    else {
+                        if (debug_level & 256) {
+                            fprintf(stderr,"Position defined: %d, Changed: %s\n",
+                                position_defined(last_lat, last_lon, 1),
+                                (p_station->coord_lat != last_lat ||
+                                p_station->coord_lon != last_lon) ?
+                                "Yes" : "No");
+                        }
+
+                        // Here's where we detect movement
+                        if (position_defined(last_lat,last_lon,1)
+                                && (p_station->coord_lat != last_lat || p_station->coord_lon != last_lon)) {
+                            if (debug_level & 256) {
+                                fprintf(stderr,"Position Change detected on %s\n",
+                                    p_station->call_sign);
+                            }
+                            moving = 1;                 // it's moving if it has changed the position
+                        }
+                        else {
+                            if (debug_level & 256) {
+                                fprintf(stderr,"Station %s still appears stationary.\n",
+                                    p_station->call_sign);
+                                fprintf(stderr," %s stationary at %ld %ld (%ld %ld)\n",
+                                    p_station->call_sign,
+                                    p_station->coord_lat, p_station->coord_lon,
+                                    last_lat,             last_lon);
+                            }
+                            moving = 0;
+                        }
+                    }
+                }
+                changed_pos = 0;
+                if (moving == 1) {                      
+                    p_station->flag |= (ST_MOVING);
+                    // we have a moving station, process trails
+                    if (atoi(p_station->speed) < TRAIL_MAX_SPEED) {     // reject high speed data (undef gives 0)
+                        // we now may already have the 2nd position, so store the old one first
+                        if (debug_level & 256) {
+                            fprintf(stderr,"Station %s valid speed %s\n",
+                                p_station->call_sign, p_station->speed);
+                        }
+                        if (p_station->newest_trackpoint == NULL) {
+                            if (debug_level & 256) {
+                                fprintf(stderr,"Station %s no trail history.\n",
+                                    p_station->call_sign);
+                            }
+                            if (position_defined(last_lat,last_lon,1)) {  // ignore undefined and 0N/0E
+                                if (debug_level & 256) {
+                                    fprintf(stderr,"Storing old position for %s\n",
+                                        p_station->call_sign);
+                                }
+                                (void)store_trail_point(p_station,
+                                                        last_lon,
+                                                        last_lat,
+                                                        last_stn_sec,
+                                                        last_alt,
+                                                        last_speed,
+                                                        last_course,
+                                                        last_flag);
+                            }
+                        }
+                        //if (   p_station->coord_lon != last_lon
+                        //    || p_station->coord_lat != last_lat ) {
+                        // we don't store redundant points (may change this
+                                                // later ?)
+                                                //
+                        // There are often echoes delayed 15 minutes
+                        // or so it looks ugly on the trail, so I
+                        // want to discard them This also discards
+                        // immediate echoes. Duplicates back in time
+                        // up to TRAIL_ECHO_TIME minutes are
+                        // discarded.
+                        //
+                        if (!is_trailpoint_echo(p_station)) {
+                            (void)store_trail_point(p_station,
+                                                    p_station->coord_lon,
+                                                    p_station->coord_lat,
+                                                    p_station->sec_heard,
+                                                    p_station->altitude,
+                                                    p_station->speed,
+                                                    p_station->course,
+                                                    p_station->flag);
+                            changed_pos = 1;
+
+                            // Check whether it's a locally-owned object/item
+                            if (object_is_mine) {
+
+                                // Update time, change position in
+                                // time-sorted list to change
+                                // expiration time.
+                                move_station_time(p_station,p_time);
+                                // Give it a new timestamp
+                                p_station->sec_heard = curr_sec;
+
+                                //fprintf(stderr,"Updating last heard time\n");
+                            }
+                        }
+                        else if (debug_level & 256) {
+                            fprintf(stderr,"Trailpoint echo detected for %s\n",
+                                p_station->call_sign);
+                        }
+                    }
+                    else {
+                        if (debug_level & 256 || debug_level & 1)
+                            fprintf(stderr,"Speed over %d mph\n",TRAIL_MAX_SPEED);
+                    }
+
+                    if (track_station_on == 1)          // maybe we are tracking a station
+                        track_station(da,tracking_station_call,p_station);
+                } // moving...
+
+                // now do the drawing to the screen
+                ok_to_display = !altnet || is_altnet(p_station); // Optimization step, needed twice below.
+                screen_update = 0;
+                if (changed_pos == 1 && Display_.trail && ((p_station->flag & ST_INVIEW) != 0)) {
+                    if (ok_to_display) {
+                        if (debug_level & 256) {
+                            fprintf(stderr,"Adding Solid Trail for %s\n",
+                            p_station->call_sign);
+                        }
+                        draw_trail(da,p_station,1);         // update trail
+                        screen_update = 1;
+                    }
+                    else if (debug_level & 256) {
+                        fprintf(stderr,"Skipped trail for %s (altnet)\n",
+                            p_station->call_sign);
+                    }
+                }
+                if (position_on_screen(p_station->coord_lat,p_station->coord_lon)) {
+                    if (changed_pos == 1 || !position_defined(last_lat,last_lon,0)) {
+                        if (ok_to_display) {
+                            display_station(da,p_station,1);// update symbol
+                            screen_update = 1;
+                        }
+                    }
+                }
+            } // defined position
+        }
+
+        if (screen_update) {
+            if (p_station->data_via == 'T') {   // Data from local TNC
+//WE7U
+// or data_via == 'I' and last_port_heard == AGWPE interface
+                redraw_on_new_data = 2; // Update all symbols NOW!
+            }
+            else if (p_station->data_via == 'F') {  // If data from file
+                redraw_on_new_data = 1; // Update each 2 secs
+            }
+//            else if (scale_y > 2048) {  // Wider area of world
+            else {
+                redraw_on_new_data = 0; // Update each 60 secs
+            }
+        }
+
+        // announce stations in the status line
+//        if (!is_my_call(p_station->call_sign,1) // Check SSID as well
+//                && !is_my_call(p_station->origin,1) // Check SSID as well
+        if (!is_my_station(p_station)
+                && !is_my_object_item(p_station) // Check SSID as well
+                && !wait_to_redraw) {
+            if (new_station) {
+                if (p_station->origin[0] == '\0')   // new station
+                    xastir_snprintf(station_id, sizeof(station_id), langcode("BBARSTA001"),p_station->call_sign);
+                else                                // new object
+                    xastir_snprintf(station_id, sizeof(station_id), langcode("BBARSTA000"),p_station->call_sign);
+            }
+            else                                  // updated data
+                xastir_snprintf(station_id, sizeof(station_id), langcode("BBARSTA002"),p_station->call_sign);
+
+            statusline(station_id,0);
+        }
+
+        // announce new station with sound file or speech synthesis
+        if (new_station && !wait_to_redraw) {   // && !is_my_call(p_station->call_sign,1) // ???
+            if (sound_play_new_station)
+                play_sound(sound_command,sound_new_station);
+
+#ifdef HAVE_FESTIVAL
+            if (festival_speak_new_station) {
+                char speech_callsign[50];
+
+                xastir_snprintf(speech_callsign,
+                    sizeof(speech_callsign),
+                    "%s",
+                    p_station->call_sign);
+                spell_it_out(speech_callsign, 50);
+
+                xastir_snprintf(station_id,
+                    sizeof(station_id),
+                    "%s, %s",
+                    langcode("SPCHSTR010"),
+                    speech_callsign);
+                SayText(station_id);
+            }
+#endif  // HAVE_FESTIVAL
+        }
+
+        // check for range and DX
+//        if (found_pos && !is_my_call(p_station->call_sign,1)) { // Check SSID also
+        if (found_pos
+                && !is_my_station(p_station)) { // Check SSID also
+ 
+            // if station has a position with the data
+            /* Check Audio Alarms based on incoming packet */
+            /* FG don't care if this is on screen or off get position */
+            l_lat = convert_lat_s2l(my_lat);
+            l_lon = convert_lon_s2l(my_long);
+
+            // Get distance in nautical miles.
+            value = (float)calc_distance_course(l_lat,l_lon,
+                    p_station->coord_lat,p_station->coord_lon,temp_data,sizeof(temp_data));
+
+            // Convert to whatever measurement value we're currently using
+            distance = value * cvt_kn2len;
+        
+            /* check ranges */
+            if ((distance > atof(prox_min)) && (distance < atof(prox_max))) {
+                
+                //fprintf(stderr,"Station within proximity circle, creating waypoint\n");
+                create_garmin_waypoint(p_station->coord_lat,
+                                       p_station->coord_lon,
+                                       p_station->call_sign);
+
+                if (sound_play_prox_message) {
+                    xastir_snprintf(station_id, sizeof(station_id), 
+                                    "%s < %.3f %s",p_station->call_sign, 
+                                    distance,
+                                    english_units?langcode("UNIOP00004"):langcode("UNIOP00005"));
+                    statusline(station_id,0);
+                    play_sound(sound_command,sound_prox_message);
+                    /*fprintf(stderr,"%s> PROX distance %f\n",p_station->call_sign, distance);*/
+                }
+            }
+#ifdef HAVE_FESTIVAL
+            if ((distance > atof(prox_min)) && (distance < atof(prox_max)) && festival_speak_proximity_alert) {
+                char speech_callsign[50];
+
+                xastir_snprintf(speech_callsign,
+                    sizeof(speech_callsign),
+                    "%s",
+                    p_station->call_sign);
+                spell_it_out(speech_callsign, 50);
+
+                if (english_units) {
+                    if (distance < 1.0)
+                xastir_snprintf(station_id, sizeof(station_id), langcode("SPCHSTR005"), speech_callsign,
+                            (int)(distance * 1760), langcode("SPCHSTR004")); // say it in yards
+                    else if ((int)((distance * 10) + 0.5) % 10)
+                xastir_snprintf(station_id, sizeof(station_id), langcode("SPCHSTR006"), speech_callsign, distance,
+                        langcode("SPCHSTR003")); // say it in miles with one decimal
+                    else
+                xastir_snprintf(station_id, sizeof(station_id), langcode("SPCHSTR005"), speech_callsign, (int)(distance + 0.5),
+                        langcode("SPCHSTR003")); // say it in miles with no decimal
+                }
+                else {
+                    if (distance < 1.0)
+                xastir_snprintf(station_id, sizeof(station_id), langcode("SPCHSTR005"), speech_callsign,
+                        (int)(distance * 1000), langcode("SPCHSTR002")); // say it in meters
+                    else if ((int)((distance * 10) + 0.5) % 10)
+                xastir_snprintf(station_id, sizeof(station_id), langcode("SPCHSTR006"), speech_callsign, distance,
+                        langcode("SPCHSTR001")); // say it in kilometers with one decimal
+                    else
+                xastir_snprintf(station_id, sizeof(station_id), langcode("SPCHSTR005"), speech_callsign, (int)(distance + 0.5),
+                    langcode("SPCHSTR001")); // say it in kilometers with no decimal
+                }
+                SayText(station_id);
+            }
+#endif  // HAVE_FESTIVAL
+            /* FG really should check the path before we do this and add setup for these ranges */
+            if (sound_play_band_open_message && from == DATA_VIA_TNC && !(p_station->flag & ST_3RD_PT) &&
+                (distance > atof(bando_min)) && (distance < atof(bando_max))) {
+                xastir_snprintf(station_id, sizeof(station_id), "%s %s %.1f %s",p_station->call_sign, langcode("UMBNDO0001"),
+                        distance, english_units?langcode("UNIOP00004"):langcode("UNIOP00005"));
+                statusline(station_id,0);
+                play_sound(sound_command,sound_band_open_message);
+                /*fprintf(stderr,"%s> BO distance %f\n",p_station->call_sign, distance);*/
+	    }
+#ifdef HAVE_FESTIVAL
+            if (festival_speak_band_opening && from == DATA_VIA_TNC && !(p_station->flag & ST_3RD_PT) &&
+                (distance > atof(bando_min)) && (distance < atof(bando_max))) {
+                char speech_callsign[50];
+
+                xastir_snprintf(speech_callsign,
+                    sizeof(speech_callsign),
+                    "%s",
+                    p_station->call_sign);
+                spell_it_out(speech_callsign, 50);
+
+                xastir_snprintf(station_id,
+                    sizeof(station_id),
+                    langcode("SPCHSTR011"),
+                    speech_callsign,
+                    distance,
+                    english_units?langcode("SPCHSTR003"):langcode("SPCHSTR001"));
+                SayText(station_id);
+            }
+#endif  // HAVE_FESTIVAL
+
+        } // end found_pos
+
+
+#ifdef HAVE_DB
+        // Clumsy way of doing things - needs a more elegant approach
+        // iterate through interfaces 
+        if (p_station->data_via != DATA_VIA_DATABASE) { 
+            if (debug_level & 4096) 
+                fprintf(stderr,"Trying to store station %s to database interfaces.\n",p_station->call_sign);
+            for (ii=0;ii<MAX_IFACE_DEVICES;ii++) {
+                if (debug_level & 4096) {
+                   fprintf(stderr,"Trying interface [%d] ",ii);
+                   fprintf(stderr,"connection [%p]\n",&connections[ii]);
+                }
+                if (&connections[ii] != NULL){
+                    // Note < 4 is an artificial upper limit that may catch cases where the memmory 
+                    // for the connection has been overwritten.  
+                    if (connections[ii].type > 0 && connections[ii].type < 4){
+                        if (debug_level & 4096) 
+                            fprintf(stderr,"type=[%d]\n",connections[ii].type);                
+                        if (port_data[ii].status == DEVICE_UP) { 
+                            if (connections[ii].descriptor->device_type==DEVICE_SQL_DATABASE) { 
+                                if (debug_level & 4096) 
+                                    fprintf(stderr,"Trying interface %d\n",ii);
+                                // if interface is a sql server interface 
+                                // write station data to sql database
+                                ok = storeStationSimpleToGisDb(&connections[ii], p_station);
+                                if (ok==1) { 
+                                   if (debug_level & 4096) {
+                                       fprintf(stderr,"Stored station %s to database interface %d.\n",p_station->call_sign,ii);
+                                   }
+                                } else {
+                                   pingConnection(&connections[ii]);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+#endif /* HAVE_DB */
+
+    }   // valid data into database
+ 
+    return(ok);
+}   // End of data_add() function
+
+
+
+
+
+// Code to compute SmartBeaconing(tm) rates.
+//
+// SmartBeaconing(tm) was invented by Steve Bragg (KA9MVA) and Tony Arnerich
+// (KD7TA).  Its main goal is to change the beacon rate based on speed
+// and cornering.  It does speed-variant corner pegging and
+// speed-variant posit rate.
+
+// Some tweaks have been added to the generic SmartBeaconing(tm) algorithm,
+// but are current labeled as experimental and commented out:  1) We do
+// a posit as soon as we first cross below the sb_low_speed_limit, and
+// 2) We do a posit as soon as we cross above the sb_low_speed_limit if
+// we haven't done a posit for sb_turn_time seconds.  These tweaks are
+// intended to help show that the mobile station has stopped (so that
+// dead-reckoning doesn't keep it moving across the map on other
+// people's displays) and to more quickly show that the station is
+// moving again (for the case where they're in stop-and-go traffic
+// perhaps).
+//
+// It's possible that these new tweaks won't work well for the case
+// where a station is traveling near the speed of sb_low_speed_limit.
+// In this case they'll generate a posit each time they go below it and
+// every time they go above it if they haven't done a posit in
+// sb_turn_time seconds.  This could result in a lot of posits very
+// quickly.  We may need to add yet another limit just above the
+// sb_low_speed_limit for hysteresis, and not posit until we cross above
+// that new limit.
+//
+// Several special SmartBeaconing(tm) parameters come into play here:
+//
+// sb_turn_min          Minimum degrees at which corner pegging will
+//                      occur.  The next parameter affects this for
+//                      lower speeds.
+//
+// sb_turn_slope        Fudget factor for making turns less sensitive at
+//                      lower speeds.  No real units on this one.
+//                      It ends up being non-linear over the speed
+//                      range the way the original SmartBeaconing(tm)
+//                      algorithm works.
+//
+// sb_turn_time         Dead-time before/after a corner peg beacon.
+//                      Units are in seconds.
+//
+// sb_posit_fast        Fast posit rate, used if >= sb_high_speed_limit.
+//                      Units are in seconds.
+//
+// sb_posit_slow        Slow posit rate, used if <= sb_low_speed_limit.
+//                      Units are in minutes.
+//
+// sb_low_speed_limit   Low speed limit, units are in Mph.
+//
+// sb_high_speed_limit  High speed limit, units are in Mph.
+//
+//
+//  Input: Course in degrees
+//         Speed in knots
+//
+// Output: May force beacons by setting posit_next_time to various
+//         values.
+//
+// Modify: sb_POSIT_rate
+//         sb_current_heading
+//         sb_last_heading
+//         posit_next_time
+//
+//
+// With the defaults compiled into the code, here are the
+// turn_thresholds for a few speeds:
+//
+// Example: sb_turn_min = 20
+//          sb_turn_slope = 25
+//          sb_high_speed_limit = 60
+//
+//      > 60mph  20 degrees
+//        50mph  25 degrees
+//        40mph  26 degrees
+//        30mph  28 degrees
+//        20mph  33 degrees
+//        10mph  45 degrees
+//        3mph 103 degrees (we limit it to 80 now)
+//        2mph 145 degrees (we limit it to 80 now)
+//
+// I added a max threshold of 80 degrees into the code.  145 degrees
+// is unreasonable to expect except for perhaps switchback or 'U'
+// turns.
+//
+// It'd probably be better to do a linear interpolation of
+// turn_threshold based on min/max speed and min/max turns.  That's
+// not how the SmartBeaconing(tm) algorithm coders implemented it in
+// the HamHud though.
+//
+void compute_smart_beacon(char *current_course, char *current_speed) {
+    int course;
+    int speed;
+    int turn_threshold;
+    time_t secs_since_beacon;
+    int heading_change_since_beacon;
+    int beacon_now = 0;
+    int curr_sec = sec_now();
+
+    // Don't compute SmartBeaconing(tm) parameters or force any beacons
+    // if we're not in that mode!
+    if (!smart_beaconing)
+        return;
+
+    // Convert from knots to mph/kph (whichever is selected)
+    speed = (int)(atof(current_speed) * cvt_kn2len + 0.5); // Poor man's rounding
+
+    course = atoi(current_course);
+ 
+    secs_since_beacon = curr_sec - posit_last_time;
+ 
+    // Check for the low speed threshold, set to slow posit rate if
+    // we're going slow.
+    if (speed <= sb_low_speed_limit) {
+        //fprintf(stderr,"Slow speed\n");
+
+
+// EXPERIMENTAL!!!
+////////////////////////////////////////////////////////////////////
+        // Check to see if we're just crossing the threshold, if so,
+        // beacon.  This keeps dead-reckoning working properly on
+        // other people's displays.  Be careful for speeds near this
+        // threshold though.  We really need a slow-speed rate and a
+        // stop rate, with some distance between them, in order to
+        // have some hysteresis for these posits.
+//        if (sb_POSIT_rate != (sb_posit_slow * 60) ) { // Previous rate was _not_ the slow rate
+//            beacon_now++; // Force a posit right away
+//            //fprintf(stderr,"Stopping, POSIT!\n");
+//        }
+////////////////////////////////////////////////////////////////////
+
+
+        // Set to slow posit rate
+        sb_POSIT_rate = sb_posit_slow * 60; // Convert to seconds
+    }
+    else {  // We're moving faster than the low speed limit
+
+
+// EXPERIMENTAL!!!
+////////////////////////////////////////////////////////////////////
+        // Check to see if we're just starting to move.  Again, we
+        // probably need yet-another-speed-limit here to provide
+        // some hysteresis.
+//        if ( (secs_since_beacon > sb_turn_time)    // Haven't beaconed for a bit
+//                && (sb_POSIT_rate == (sb_posit_slow * 60) ) ) { // Last rate was the slow rate
+//            beacon_now++; // Force a posit right away
+//            //fprintf(stderr,"Starting to move, POSIT!\n");
+//        }
+////////////////////////////////////////////////////////////////////
+
+
+        // Start with turn_min degrees as the threshold
+        turn_threshold = sb_turn_min;
+
+        // Adjust rate according to speed
+        if (speed > sb_high_speed_limit) {  // We're above the high limit
+            sb_POSIT_rate = sb_posit_fast;
+            //fprintf(stderr,"Setting fast rate\n");
+        }
+        else {  // We're between the high/low limits.  Set a between rate
+            sb_POSIT_rate = (sb_posit_fast * sb_high_speed_limit) / speed;
+            //fprintf(stderr,"Setting medium rate\n");
+
+            // Adjust turn threshold according to speed
+            turn_threshold += (int)( (sb_turn_slope * 10) / speed);
+        }
+
+        // Force a maximum turn threshold of 80 degrees (still too
+        // high?)
+        if (turn_threshold > 80)
+            turn_threshold = 80;
+ 
+        // Check to see if we've written anything into
+        // sb_last_heading variable yet.  If not, write the current
+        // course into it.
+        if (sb_last_heading == -1)
+            sb_last_heading = course;
+
+        // Corner-pegging.  Note that we don't corner-peg if we're
+        // below the low-speed threshold.
+        heading_change_since_beacon = abs(course - sb_last_heading);
+        if (heading_change_since_beacon > 180)
+            heading_change_since_beacon = 360 - heading_change_since_beacon;
+
+        //fprintf(stderr,"course change:%d\n",heading_change_since_beacon);
+
+        if ( (heading_change_since_beacon > turn_threshold)
+                && (secs_since_beacon > sb_turn_time) ) {
+            beacon_now++;   // Force a posit right away
+
+            //fprintf(stderr,"Corner, POSIT!\tOld:%d\tNew:%d\tDifference:%d\tSpeed: %d\tTurn Threshold:%d\n",
+            //    sb_last_heading,
+            //    course,
+            //    heading_change_since_beacon,
+            //    speed,
+            //    turn_threshold);
+        }
+
+
+// EXPERIMENTAL
+////////////////////////////////////////////////////////////////////
+        // If we haven't beaconed for a bit (3 * sb_turn_time?), and
+        // just completed a turn, check to see if our heading has
+        // stabilized yet.  If so, beacon the latest heading.  We'll
+        // have to save another variable which says whether the last
+        // beacon was caused by corner-pegging.  The net effect is
+        // that we'll get an extra posit coming out of a turn that
+        // specifies our correct course and probably a more accurate
+        // speed until the next posit.  This should make
+        // dead-reckoning work even better.
+        if (0) {
+        }
+////////////////////////////////////////////////////////////////////
+
+
+    }
+
+    // Check to see whether we've sped up sufficiently for the
+    // posit_next_time variable to be too far out.  If so, shorten
+    // that interval to match the current speed.
+    if ( (posit_next_time - curr_sec) > sb_POSIT_rate)
+        posit_next_time = curr_sec + sb_POSIT_rate;
+
+
+    if (beacon_now) {
+        posit_next_time = 0;    // Force a posit right away
+    }
+
+    // Should we also check for a rate too fast for the current
+    // speed?  Probably not.  It'll get modified at the next beacon
+    // time, which will happen quickly.
+
+    // Save course for use later.  It gets put into sb_last_heading
+    // in UpdateTime() if a beacon occurs.  We then use it above to
+    // determine the course deviation since the last time we
+    // beaconed.
+    sb_current_heading = course;
+}
+
+
+
+
+
+// Speed is in knots
+void my_station_gps_change(char *pos_long, char *pos_lat, char *course, char *speed, /*@unused@*/ char speedu, char *alt, char *sats) {
+    long pos_long_temp, pos_lat_temp;
+    char temp_data[40];   // short term string storage
+    char temp_lat[12];
+    char temp_long[12];
+    DataRow *p_station;
+    DataRow *p_time;
+
+    // Note that speed will be in knots 'cuz it was derived from a
+    // GPRMC string without modification.
+
+    // Recompute the SmartBeaconing(tm) parameters based on current/past
+    // course & speed.  Sending the speed in knots.
+    //fprintf(stderr,"Speed: %s\n",speed);
+    compute_smart_beacon(course, speed);
+
+    p_station = NULL;
+    if (!search_station_name(&p_station,my_callsign,1)) {  // find my data in the database
+        p_time = NULL;          // add to end of time sorted list
+//fprintf(stderr,"my_station_gps_change()\n");
+        p_station = add_new_station(p_station,p_time,my_callsign);
+    }
+    p_station->flag |= ST_ACTIVE;
+    p_station->data_via = 'L';
+    p_station->flag &= (~ST_3RD_PT);            // clear "third party" flag
+    p_station->record_type = NORMAL_APRS;
+
+    // Free any old path we might have
+    if (p_station->node_path_ptr != NULL)
+        free(p_station->node_path_ptr);
+    // Malloc and store the new path
+    p_station->node_path_ptr = (char *)malloc(strlen("local") + 1);
+    CHECKMALLOC(p_station->node_path_ptr);
+
+    substr(p_station->node_path_ptr,"local",strlen("local"));
+ 
+    // Create a timestamp from the current time
+    xastir_snprintf(p_station->packet_time,
+        sizeof(p_station->packet_time),
+        "%s",
+        get_time(temp_data));
+    // Create a timestamp from the current time
+    xastir_snprintf(p_station->pos_time,
+        sizeof(p_station->pos_time),
+        "%s",
+        get_time(temp_data));
+    p_station->flag |= ST_MSGCAP;               // set "message capable" flag
+
+    /* convert to long and weed out any odd data */
+    pos_long_temp = convert_lon_s2l(pos_long);
+    pos_lat_temp  = convert_lat_s2l(pos_lat);
+
+    /* convert back to clean string for config data */
+    convert_lon_l2s(pos_long_temp, temp_data, sizeof(temp_data), CONVERT_HP_NORMAL);
+    xastir_snprintf(temp_long, sizeof(temp_long), "%c%c%c%c%c.%c%c%c%c",temp_data[0],temp_data[1],temp_data[2], temp_data[4],temp_data[5],
+            temp_data[7],temp_data[8], temp_data[9], temp_data[10]);
+    convert_lat_l2s(pos_lat_temp, temp_data, sizeof(temp_data), CONVERT_HP_NORMAL);
+    xastir_snprintf(temp_lat, sizeof(temp_lat), "%c%c%c%c.%c%c%c%c",temp_data[0],temp_data[1],temp_data[3],temp_data[4], temp_data[6],
+            temp_data[7], temp_data[8],temp_data[9]);
+
+    /* fill the data in */    // ???????????????
+    xastir_snprintf(my_lat,
+        sizeof(my_lat),
+        "%s",
+        temp_lat);
+    xastir_snprintf(my_long,
+        sizeof(my_long),
+        "%s",
+        temp_long);
+    p_station->coord_lat = convert_lat_s2l(my_lat);
+    p_station->coord_lon = convert_lon_s2l(my_long);
+
+    if ((p_station->coord_lon != pos_long_temp) || (p_station->coord_lat != pos_lat_temp)) {
+        /* check to see if enough to change pos on screen */
+        if ((pos_long_temp>NW_corner_longitude) && (pos_long_temp<SE_corner_longitude)) {
+            if ((pos_lat_temp>NW_corner_latitude) && (pos_lat_temp<SE_corner_latitude)) {
+                if((labs((p_station->coord_lon+(scale_x/2))-pos_long_temp)/scale_x)>0
+                        || (labs((p_station->coord_lat+(scale_y/2))-pos_lat_temp)/scale_y)>0) {
+                    //redraw_on_new_data = 1;   // redraw next chance
+                    //redraw_on_new_data = 2;     // better response?
+                    if (debug_level & 256) {
+                        fprintf(stderr,"Redraw on new gps data \n");
+                    }
+                    statusline(langcode("BBARSTA038"),0);
+                }
+                else if (debug_level & 256) {
+                    fprintf(stderr,"New Position same pixel as old.\n");
+                }
+            }
+            else if (debug_level & 256) {
+                fprintf(stderr,"New Position is off edge of screen.\n");
+            }
+        }
+        else if (debug_level & 256) {
+            fprintf(stderr,"New position is off side of screen.\n");
+        }
+    }
+
+    p_station->coord_lat = pos_lat_temp;    // DK7IN: we have it already !??
+    p_station->coord_lon = pos_long_temp;
+
+    curr_sec = sec_now();
+    my_last_altitude_time = curr_sec;
+    xastir_snprintf(p_station->speed,
+        sizeof(p_station->speed),
+        "%s",
+        speed);
+    // is speed always in knots, otherwise we need a conversion!
+    xastir_snprintf(p_station->course,
+        sizeof(p_station->course),
+        "%s",
+        course);
+    xastir_snprintf(p_station->altitude,
+        sizeof(p_station->altitude),
+        "%s",
+        alt);
+    // altu;    unit should always be meters  ????
+
+    if(debug_level & 256)
+        fprintf(stderr,"GPS MY_LAT <%s> MY_LONG <%s> MY_ALT <%s>\n",
+            my_lat, my_long, alt);
+
+    /* get my last altitude meters to feet */
+    my_last_altitude=(long)(atof(alt)*3.28084);
+
+    /* get my last course in deg */
+    my_last_course=atoi(course);
+
+    /* get my last speed in knots */
+    my_last_speed=(int)(atof(speed));
+    xastir_snprintf(p_station->sats_visible,
+        sizeof(p_station->sats_visible),
+        "%s",
+        sats);
+
+    // Update "heard" time for our new position
+    p_station->sec_heard = curr_sec;
+
+    //if (   p_station->coord_lon != last_lon
+    //    || p_station->coord_lat != last_lat ) {
+    // we don't store redundant points (may change this later ?)
+    // There are often echoes delayed 15 minutes or so it looks ugly
+    // on the trail, so I want to discard them This also discards
+    // immediate echoes.  Duplicates back in time up to
+    // TRAIL_ECHO_TIME minutes are discarded.
+    //
+    if (!is_trailpoint_echo(p_station)) {
+        (void)store_trail_point(p_station,
+                                p_station->coord_lon,
+                                p_station->coord_lat,
+                                curr_sec,
+                                p_station->altitude,
+                                p_station->speed,
+                                p_station->course,
+                                p_station->flag);
+    }
+    if (debug_level & 256) {
+        fprintf(stderr,"Adding Solid Trail for %s\n",
+        p_station->call_sign);
+    }
+    draw_trail(da,p_station,1);         // update trail
+    display_station(da,p_station,1);    // update symbol
+
+    if (track_station_on == 1)          // maybe we are tracking ourselves?
+        track_station(da,tracking_station_call,p_station);
+
+    // We parsed a good GPS string, so allow beaconing to proceed
+    // normally for a while.
+    my_position_valid = 3;
+    //fprintf(stderr,"Valid GPS input: my_position_valid = 3\n");
+ 
+    //redraw_on_new_data = 1;   // redraw next chance
+    redraw_on_new_data = 2;     // Immediate update of symbols/tracks
+}
+
+
+
+
+
+void my_station_add(char *my_callsign, char my_group, char my_symbol, char *my_long, char *my_lat, char *my_phg, char *my_comment, char my_amb) {
+    DataRow *p_station;
+    DataRow *p_time;
+    char temp_data[40];   // short term string storage
+    char *strp;
+
+    p_station = NULL;
+    if (!search_station_name(&p_station,my_callsign,1)) {  // find call 
+        p_time = NULL;          // add to end of time sorted list
+//fprintf(stderr,"my_station_add()\n");
+        p_station = add_new_station(p_station,p_time,my_callsign);
+    }
+    p_station->flag |= ST_ACTIVE;
+    p_station->flag |= ST_MYSTATION;
+    p_station->data_via = 'L';
+    p_station->flag &= (~ST_3RD_PT);            // clear "third party" flag
+    p_station->record_type = NORMAL_APRS;
+
+    if (transmit_compressed_posit) {
+        // Compressed posit
+        p_station->error_ellipse_radius = 600; // Default of 6m
+        p_station->lat_precision = 6;
+        p_station->lon_precision = 6;
+    }
+    else {
+        // Standard APRS posit
+        p_station->error_ellipse_radius = 2550; // 25.5m, or about 60ft resolution
+        p_station->lat_precision = 60;
+        p_station->lon_precision = 60;
+    }
+ 
+    // Free any old path we might have
+    if (p_station->node_path_ptr != NULL)
+        free(p_station->node_path_ptr);
+    // Malloc and store the new path
+    p_station->node_path_ptr = (char *)malloc(strlen("local") + 1);
+    CHECKMALLOC(p_station->node_path_ptr);
+
+    substr(p_station->node_path_ptr,"local",strlen("local"));
+
+    // Create a timestamp from the current time
+    xastir_snprintf(p_station->packet_time,
+        sizeof(p_station->packet_time),
+        "%s",
+        get_time(temp_data));
+    // Create a timestamp from the current time
+    xastir_snprintf(p_station->pos_time,
+        sizeof(p_station->pos_time),
+        "%s",
+        get_time(temp_data));
+    p_station->flag |= ST_MSGCAP;               // set "message capable" flag
+
+    /* Symbol overlay */
+    if(my_group != '/' && my_group != '\\') {
+        // Found an overlay character.  Check it.
+        if ( (my_group >= '0' && my_group <= '9')
+                || (my_group >= 'A' && my_group <= 'Z') ) {
+            // Overlay character is good
+            p_station->aprs_symbol.aprs_type = '\\';
+            p_station->aprs_symbol.special_overlay = my_group;
+        }
+        else {
+            // Found a bad overlay character
+            p_station->aprs_symbol.aprs_type = my_group;
+            p_station->aprs_symbol.special_overlay = '\0';
+        }
+    }
+    else {    // Normal symbol, no overlay
+        p_station->aprs_symbol.aprs_type = my_group;
+        p_station->aprs_symbol.special_overlay = '\0';
+    }
+    p_station->aprs_symbol.aprs_symbol = my_symbol;
+
+    p_station->pos_amb = my_amb;
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        my_lat);
+
+//fprintf(stderr," my_lat:%s\n",temp_data);
+
+    temp_data[9] = '\0';
+
+    strp = &temp_data[20];
+    xastir_snprintf(strp,
+//        sizeof(strp),   // No good, as strp is a pointer
+        (int)(sizeof(temp_data) / 2),
+        "%s",
+        my_long);
+    strp[10] = '\0';
+
+//fprintf(stderr,"my_long:%s\n",my_long);
+//fprintf(stderr,"my_long:%s\n",strp);
+
+    switch (my_amb) {
+    case 1: // 1/10th minute
+        temp_data[6] = strp[7] = '5';
+        break;
+    case 2: // 1 minute
+        temp_data[5] = strp[6] = '5';
+        temp_data[6] = '0';
+        strp[7]      = '0';
+        break;
+    case 3: // 10 minutes
+        temp_data[3] = strp[4] = '5';
+        temp_data[5] = temp_data[6] = '0';
+        strp[6]      = strp[7]      = '0';
+        break;
+    case 4: // 1 degree
+        temp_data[2] = strp[3] = '3';
+        temp_data[3] = temp_data[5] = temp_data[6] = '0';
+        strp[4]      = strp[6]      = strp[7]      = '0';
+        break;
+    case 0:
+    default:
+        break;
+    }
+    p_station->coord_lat = convert_lat_s2l(temp_data);
+    p_station->coord_lon = convert_lon_s2l(strp);
+
+    if (position_on_extd_screen(p_station->coord_lat,p_station->coord_lon)) {
+        p_station->flag |= (ST_INVIEW);   // set   "In View" flag
+    }
+    else {
+        p_station->flag &= (~ST_INVIEW);  // clear "In View" flag
+    }
+
+    substr(p_station->power_gain,my_phg,7);
+
+    add_comment(p_station,my_comment);
+
+    my_last_course = 0;         // set my last course in deg to zero
+    redo_list = (int)TRUE;      // update active station lists
+}
+
+
+
+
+
+// Write the text from the packet_data_string out to the dialog if
+// the dialog exists.  The user can contract/expand the dialog and
+// always have it filled with the most current data out of the
+// string.
+//
+void display_packet_data(void) {
+
+    if( (Display_data_dialog != NULL)
+            && (redraw_on_new_packet_data !=0)) {
+        int pos;
+        int last_char;
+        int i;
+
+        // Find out the last character position in the dialog text
+        // area.
+        last_char = XmTextGetLastPosition(Display_data_text);
+
+        //fprintf(stderr,"In display_packet_data: first_line=%d,next_line=%d,ncharsdel=%d,nlinesadd=%d\n",first_line,next_line,ncharsdel,nlinesadd);
+
+        if (first_line != -1) { // there is data in the array
+            if (last_char == 0 || ncharsdel>=last_char) { 
+                //fprintf(stderr,"  Starting from clean slate...\n");
+                // but there is no text in the dialog or more chars to delete than
+                // there actually are in the dialog
+                // Clear the dialog just in case:
+                XmTextReplace(Display_data_text,0,last_char,"");
+                
+                // display all the data in the ring
+                for (i=first_line;i != next_line;
+                     i=(i+1)%MAX_PACKET_DATA_DISPLAY) {
+                    XmTextReplace(Display_data_text,last_char,last_char,
+                                  packet_data_string[i]);
+                    last_char=XmTextGetLastPosition(Display_data_text);
+                    pos=last_char;
+                    XtVaSetValues(Display_data_text,XmNcursorPosition,
+                                  pos,NULL);
+                }
+                // Now clear counters so they're always the number of lines to
+                // add or characters to delete *since last display*
+                nlinesadd=0;
+                ncharsdel=0;
+            } else { // there is stuff left over after we delete old stuff
+                if (ncharsdel) { // we have something to delete off the top
+                    //fprintf(stderr,"  Must delete %d characters\n",ncharsdel);
+                    XmTextReplace(Display_data_text,0,ncharsdel,"");
+                    ncharsdel=0;
+                }
+                if (nlinesadd) { // and there's new stuff to add at end
+                    //fprintf(stderr,"  Must add %d lines\n",nlinesadd);
+                    last_char=XmTextGetLastPosition(Display_data_text);
+                    for (i=(next_line+MAX_PACKET_DATA_DISPLAY
+                            -nlinesadd)%MAX_PACKET_DATA_DISPLAY;
+                         i != next_line;
+                         i=(i+1)%MAX_PACKET_DATA_DISPLAY) {
+                        //fprintf(stderr,"     Adding data from line %d\n",i);
+                        XmTextReplace(Display_data_text,last_char,last_char,
+                                      packet_data_string[i]);
+                        last_char=XmTextGetLastPosition(Display_data_text);
+                        pos=last_char;
+                        XtVaSetValues(Display_data_text,XmNcursorPosition,
+                                  pos,NULL);
+                    }
+                    nlinesadd=0;
+                }
+            }
+        }
+    }
+    redraw_on_new_packet_data=0;
+}
+
+
+
+
+
+//
+// Note that the length of "line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+// data_port == -1 for x_spider port, normal interface number
+// otherwise.  -99 should give a "**" display, meaning all ports.
+//
+void packet_data_add(char *from, char *line, int data_port) {
+    int offset;
+    char prefix[3] = "";
+    int local_tnc_interface = 0;
+    int network_interface = 0;
+
+
+    if (data_port == -1) {  // x_spider port (server port)
+        xastir_snprintf(prefix,sizeof(prefix),"sp");
+    }
+    else if (data_port == -99){ // All ports, used for transmitting
+        xastir_snprintf(prefix,sizeof(prefix),"**");
+    }
+    else {
+        xastir_snprintf(prefix,sizeof(prefix),"%2d",data_port);
+    }
+
+    offset=0;
+    if (line[0]==(char)3)
+        offset=1;
+
+    // Check whether local or network interface
+    if (is_local_interface(data_port) || data_port == -99)
+        local_tnc_interface++;
+
+    if (is_network_interface(data_port) || data_port == -1 || data_port == -99)
+        network_interface++;
+
+    // Compare Display_packet_data_type against the port type
+    // associated with data_port to determine whether or not to
+    // display it.
+    //
+    switch (Display_packet_data_type) {
+
+        case 2:     // Display NET data only
+            if (!network_interface)
+                return; // Don't display it
+            break;
+
+        case 1:     // Display TNC data only
+            if (!local_tnc_interface)
+                return; // Don't display it
+            break;
+
+        case 0:     // Display both TNC and NET data
+        default:
+            break;
+    }
+
+//    fprintf(stderr,"display:%d, port:%d\n",
+//        Display_packet_data_type,
+//        data_port);
+
+    // Check the Capabilities toggle to see if we only want to show
+    // Station Capability packets
+    if (show_only_station_capabilities) {
+        if (!strstr(line, ":<") // Not a capabilities response
+                && !( strstr(line, my_callsign) && strstr(line, "?IGATE?") ) ) {
+            // Not a capabilities response and not my ?IGATE?
+            // request, don't display the packet.
+            return;
+        }
+    }
+
+    // Check the "Mine Only" toggle to see if we only want to show
+    // our own packets
+    if (Display_packet_data_mine_only) {
+        char short_call[MAX_CALLSIGN];
+        char *p;
+
+        xastir_snprintf(short_call,
+            sizeof(short_call),
+            "%s",
+            my_callsign);
+        if ( (p = index(short_call,'-')) ) {
+            *p = '\0';  // Terminate it
+        }
+ 
+        if (!strstr(line, short_call))
+            return;
+    }
+
+    redraw_on_new_packet_data++;
+
+   // Now save the packet in the history:
+    xastir_snprintf(packet_data_string[next_line],MAX_LINE_SIZE,"%s:%s-> %s\n",
+             prefix,from,line+offset);
+    next_line = (next_line+1)%MAX_PACKET_DATA_DISPLAY;
+    nlinesadd++;
+    if (first_line == -1) {
+        first_line = 0;
+    } 
+    else if (first_line == next_line) {
+        ncharsdel += strlen(packet_data_string[first_line]);
+        first_line = (first_line + 1) %MAX_PACKET_DATA_DISPLAY;
+    }
+
+}
+
+
+
+
+
+/*
+ *  Decode Mic-E encoded data
+ */
+int decode_Mic_E(char *call_sign,char *path,char *info,char from,int port,int third_party) {
+    int  ii;
+    int  offset;
+    unsigned char s_b1;
+    unsigned char s_b2;
+    unsigned char s_b3;
+    unsigned char s_b4;
+    unsigned char s_b5;
+    unsigned char s_b6;
+    unsigned char s_b7;
+    int  north,west,long_offset;
+    int  d,m,h;
+    char temp[MAX_LINE_SIZE+1];     // Note: Must be big in case we get long concatenated packets
+    char new_info[MAX_LINE_SIZE+1]; // Note: Must be big in case we get long concatenated packets
+    int  course;
+    int  speed;
+    int  msg1,msg2,msg3,msg;
+    int  info_size;
+    long alt;
+    int  msgtyp;
+    char rig_type[10];
+    int ok;
+        
+    // MIC-E Data Format   [APRS Reference, chapter 10]
+
+    // todo:  error check
+    //        drop wrong positions from receive errors...
+    //        drop 0N/0E position (p.25)
+    
+    /* First 7 bytes of info[] contains the APRS data type ID,    */
+    /* longitude, speed, course.                    */
+    /* The 6-byte destination field of path[] contains latitude,    */
+    /* N/S bit, E/W bit, longitude offset, message code.        */
+    /*
+
+    MIC-E Destination Field Format:
+    -------------------------------
+    Ar1DDDD0 Br1DDDD0 Cr1MMMM0 Nr1MMMM0 Lr1HHHH0 Wr1HHHH0 CrrSSID0
+    D = Latitude Degrees.
+    M = Latitude Minutes.
+    H = Latitude Hundredths of Minutes.
+    ABC = Message bits, complemented.
+    N = N/S latitude bit (N=1).
+    W = E/W longitude bit (W=1).
+    L = 100's of longitude degrees (L=1 means add 100 degrees to longitude
+    in the Info field).
+    C = Command/Response flag (see AX.25 specification).
+    r = reserved for future use (currently 0).
+    
+    */
+    /****************************************************************************
+    * I still don't handle:                                                     *
+    *    Custom message bits                                                    *
+    *    SSID special routing                                                   *
+    *    Beta versions of the MIC-E (which use a slightly different format).    *
+    *                                                                           *
+    * DK7IN : lat/long with custom msg works, altitude/course/speed works       *
+    *****************************************************************************/
+
+    if (debug_level & 1)
+        fprintf(stderr,"decode_Mic_E:  FOUND MIC-E\n");
+
+    // Note that the first MIC-E character was not passed to us, so we're
+    // starting just past it.
+    // Check for valid symbol table character.  Should be '/' or '\'
+    // or 0-9, A-Z.
+    //
+    if (        info[7] == '/'                          // Primary table
+            ||  info[7] == '\\'                         // Alternate table
+            || (info[7] >= '0' && info[7] <= '9')       // Overlay char
+            || (info[7] >= 'A' && info[7] <= 'Z') ) {   // Overlay char
+
+        // We're good, keep going
+
+    }
+    else { // Symbol table or overlay char incorrect
+
+        if (info[6] == '/' || info[6] == '\\') {    // Found it back one char in string
+            // Don't print out the full info string here because it
+            // can contain unprintable characters.  In fact, we
+            // should check the chars we do print out to make sure
+            // they're printable, else print a space char.
+            if (debug_level & 1) {
+                fprintf(stderr,"decode_Mic_E: Symbol table (%c), symbol (%c) swapped or corrupted packet?  Call=%s, Path=%s\n",
+                    ((info[7] > 0x1f) && (info[7] < 0x7f)) ? info[7] : ' ',
+                    ((info[6] > 0x1f) && (info[6] < 0x7f)) ? info[6] : ' ',
+                    call_sign,
+                    path);
+                fprintf(stderr,"Returned from data_add, invalid symbol table character: %c\n",info[7]);
+            }
+        }
+
+        return(1);  // No good, not MIC-E format or corrupted packet.  Return 1
+                    // so that it won't get added to the database at all.
+    }
+
+    // Check for valid symbol.  Should be between '!' and '~' only.
+    if (info[6] < '!' || info[6] > '~') {
+        if (debug_level & 1)
+            fprintf(stderr,"Returned from data_add, invalid symbol\n");
+
+        return(1);  // No good, not MIC-E format or corrupted packet.  Return 1
+                    // so that it won't get added to the database at all.
+    }
+
+    // Check for minimum MIC-E size.
+    if (strlen(info) < 8) {
+        if (debug_level & 1)
+            fprintf(stderr,"Returned from data_add, packet too short\n");
+
+        return(1);  // No good, not MIC-E format or corrupted packet.  Return 1
+                    // so that it won't get added to the database at all.
+    }
+
+    // Check for 8-bit characters in the first eight slots.  Not
+    // allowed per Mic-E chapter of the spec.
+    for (ii = 0; ii < 8; ii++) {
+        if ((unsigned char)info[ii] > 0x7f) {
+            // 8-bit data was found in the lat/long/course/speed
+            // portion.  Bad packet.  Drop it.
+//fprintf(stderr, "%s: 8-bits found in Mic-E packet initial portion. Dropping it.\n", call_sign);
+            return(1);
+        }
+    }
+
+    // Check whether we have more data.  If flag character is 0x1d
+    // (8-bit telemetry flag) then don't do the 8-bit check below.
+    if (strlen(info) > 8) {
+
+        // Check for the 8-bit telemetry flag
+        if ((unsigned char)info[8] == 0x1d) {
+            // 8-bit telemetry found, skip the check loop below
+        }
+        else {  // 8-bit telemetry flag was not found.  Check that
+                // we only have 7-bit characters through the rest of
+                // the packet.
+
+            for (ii = 8; ii < (int)strlen(info); ii++) {
+
+                if ((unsigned char)info[ii] > 0x7f) {
+                    // 8-bit data was found.  Bad packet.  Drop it.
+//fprintf(stderr, "%s: 8-bits found in Mic-E packet final portion (not 8-bit telemetry). Dropping it.\n", call_sign);
+                    return(1);
+                }
+            }
+        }
+    }
+
+    //fprintf(stderr,"Path1:%s\n",path);
+
+    msg1 = (int)( ((unsigned char)path[0] & 0x40) >>4 );
+    msg2 = (int)( ((unsigned char)path[1] & 0x40) >>5 );
+    msg3 = (int)( ((unsigned char)path[2] & 0x40) >>6 );
+    msg = msg1 | msg2 | msg3;   // We now have the complemented message number in one variable
+    msg = msg ^ 0x07;           // And this is now the normal message number
+    msgtyp = 0;                 // DK7IN: Std message, I have to add custom msg decoding
+
+    //fprintf(stderr,"Msg: %d\n",msg);
+
+    /* Snag the latitude from the destination field, Assume TAPR-2 */
+    /* DK7IN: latitude now works with custom message */
+    s_b1 = (unsigned char)( (path[0] & 0x0f) + (char)0x2f );
+    //fprintf(stderr,"path0:%c\ts_b1:%c\n",path[0],s_b1);
+    if (path[0] & 0x10)     // A-J
+        s_b1 += (unsigned char)1;
+
+    if (s_b1 > (unsigned char)0x39)        // K,L,Z
+        s_b1 = (unsigned char)0x20;
+    //fprintf(stderr,"s_b1:%c\n",s_b1);
+ 
+    s_b2 = (unsigned char)( (path[1] & 0x0f) + (char)0x2f );
+    //fprintf(stderr,"path1:%c\ts_b2:%c\n",path[1],s_b2);
+    if (path[1] & 0x10)     // A-J
+        s_b2 += (unsigned char)1;
+
+    if (s_b2 > (unsigned char)0x39)        // K,L,Z
+        s_b2 = (unsigned char)0x20;
+    //fprintf(stderr,"s_b2:%c\n",s_b2);
+ 
+    s_b3 = (unsigned char)( (path[2] & (char)0x0f) + (char)0x2f );
+    //fprintf(stderr,"path2:%c\ts_b3:%c\n",path[2],s_b3);
+    if (path[2] & 0x10)     // A-J
+        s_b3 += (unsigned char)1;
+
+    if (s_b3 > (unsigned char)0x39)        // K,L,Z
+        s_b3 = (unsigned char)0x20;
+    //fprintf(stderr,"s_b3:%c\n",s_b3);
+ 
+    s_b4 = (unsigned char)( (path[3] & 0x0f) + (char)0x30 );
+    //fprintf(stderr,"path3:%c\ts_b4:%c\n",path[3],s_b4);
+    if (s_b4 > (unsigned char)0x39)        // L,Z
+        s_b4 = (unsigned char)0x20;
+    //fprintf(stderr,"s_b4:%c\n",s_b4);
+ 
+    s_b5 = (unsigned char)( (path[4] & 0x0f) + (char)0x30 );
+    //fprintf(stderr,"path4:%c\ts_b5:%c\n",path[4],s_b5);
+    if (s_b5 > (unsigned char)0x39)        // L,Z
+        s_b5 = (unsigned char)0x20;
+    //fprintf(stderr,"s_b5:%c\n",s_b5);
+ 
+    s_b6 = (unsigned char)( (path[5] & 0x0f) + (char)0x30 );
+    //fprintf(stderr,"path5:%c\ts_b6:%c\n",path[5],s_b6);
+    if (s_b6 > (unsigned char)0x39)        // L,Z
+        s_b6 = (unsigned char)0x20;
+    //fprintf(stderr,"s_b6:%c\n",s_b6);
+ 
+    s_b7 =  (unsigned char)path[6];        // SSID, not used here
+    //fprintf(stderr,"path6:%c\ts_b7:%c\n",path[6],s_b7);
+ 
+    //fprintf(stderr,"\n");
+
+    // Special tests for 'L' due to position ambiguity deviances in
+    // the APRS spec table.  'L' has the 0x40 bit set, but they
+    // chose in the spec to have that represent position ambiguity
+    // _without_ the North/West/Long Offset bit being set.  Yuk!
+    // Please also note that the tapr.org Mic-E document (not the
+    // APRS spec) has the state of the bit wrong in columns 2 and 3
+    // of their table.  Reverse them.
+    if (path[3] == 'L')
+        north = 0;
+    else 
+        north = (int)((path[3] & 0x40) == (char)0x40);  // N/S Lat Indicator
+
+    if (path[4] == 'L')
+        long_offset = 0;
+    else
+        long_offset = (int)((path[4] & 0x40) == (char)0x40);  // Longitude Offset
+
+    if (path[5] == 'L')
+        west = 0;
+    else
+        west = (int)((path[5] & 0x40) == (char)0x40);  // W/E Long Indicator
+
+    //fprintf(stderr,"north:%c->%d\tlat:%c->%d\twest:%c->%d\n",path[3],north,path[4],long_offset,path[5],west);
+
+    /* Put the latitude string into the temp variable */
+    xastir_snprintf(temp, sizeof(temp), "%c%c%c%c.%c%c%c%c",s_b1,s_b2,s_b3,s_b4,s_b5,s_b6,
+            (north ? 'N': 'S'), info[7]);   // info[7] = symbol table
+
+    /* Compute degrees longitude */
+    xastir_snprintf(new_info,
+        sizeof(new_info),
+        "%s",
+        temp);
+    d = (int) info[0]-28;
+
+    if (long_offset)
+        d += 100;
+
+    if ((180<=d)&&(d<=189))  // ??
+        d -= 80;
+
+    if ((190<=d)&&(d<=199))  // ??
+        d -= 190;
+
+    /* Compute minutes longitude */
+    m = (int) info[1]-28;
+    if (m>=60)
+        m -= 60;
+
+    /* Compute hundredths of minutes longitude */
+    h = (int) info[2]-28;
+    /* Add the longitude string into the temp variable */
+    xastir_snprintf(temp, sizeof(temp), "%03d%02d.%02d%c%c",d,m,h,(west ? 'W': 'E'), info[6]);
+    strncat(new_info,
+        temp,
+        sizeof(new_info) - 1 - strlen(new_info));
+
+    /* Compute speed in knots */
+    speed = (int)( ( info[3] - (char)28 ) * (char)10 );
+    speed += ( (int)( (info[4] - (char)28) / (char)10) );
+    if (speed >= 800)
+        speed -= 800;       // in knots
+
+    /* Compute course */
+    course = (int)( ( ( (info[4] - (char)28) % 10) * (char)100) + (info[5] - (char)28) );
+    if (course >= 400)
+        course -= 400;
+
+    /*  ???
+        fprintf(stderr,"info[4]-28 mod 10 - 4 = %d\n",( ( (int)info[4]) - 28) % 10 - 4);
+        fprintf(stderr,"info[5]-28 = %d\n", ( (int)info[5]) - 28 );
+    */
+    xastir_snprintf(temp, sizeof(temp), "%03d/%03d",course,speed);
+    strncat(new_info,
+        temp,
+        sizeof(new_info) - 1 - strlen(new_info));
+    offset = 8;   // start of rest of info
+
+    /* search for rig type in Mic-E data */
+    rig_type[0] = '\0';
+    if (info[offset] != '\0' && (info[offset] == '>' || info[offset] == ']')) {
+        /* detected type code:     > TH-D7    ] TM-D700 */
+        if (info[offset] == '>')
+            xastir_snprintf(rig_type,
+                sizeof(rig_type),
+                " TH-D7");
+        else
+            xastir_snprintf(rig_type,
+                sizeof(rig_type),
+                " TM-D700");
+
+        offset++;
+    }
+
+    info_size = (int)strlen(info);
+    /* search for compressed altitude in Mic-E data */  // {
+    if (info_size >= offset+4 && info[offset+3] == '}') {  // {
+        /* detected altitude  ___} */
+        alt = ((((long)info[offset] - (long)33) * (long)91 +(long)info[offset+1] - (long)33) * (long)91
+                    + (long)info[offset+2] - (long)33) - 10000;  // altitude in meters
+        alt /= 0.3048;                                // altitude in feet, as in normal APRS
+
+        //32808 is -10000 meters, or 10 km (deepest ocean), which is as low as a MIC-E
+        //packet may go.  Upper limit is mostly a guess.
+        if ( (alt > 500000) || (alt < -32809) ) {  // Altitude is whacko.  Skip it.
+            if (debug_level & 1)
+                fprintf(stderr,"decode_Mic_E:  Altitude is whacko:  %ld feet, skipping altitude...\n", alt);
+            offset += 4;
+        }
+        else {  // Altitude is ok
+            xastir_snprintf(temp, sizeof(temp), " /A=%06ld",alt);
+            offset += 4;
+            strncat(new_info,
+                temp,
+                sizeof(new_info) - 1 - strlen(new_info));
+        }
+    }
+
+    /* start of comment */
+    if (strlen(rig_type) > 0) {
+        xastir_snprintf(temp, sizeof(temp), "%s",rig_type);
+        strncat(new_info,
+            temp,
+            sizeof(new_info) - 1 - strlen(new_info));
+    }
+
+    strncat(new_info,
+        " Mic-E ",
+        sizeof(new_info) - 1 - strlen(new_info));
+    if (msgtyp == 0) {
+        switch (msg) {
+            case 1:
+                strncat(new_info,
+                    "Enroute",
+                    sizeof(new_info) - 1 - strlen(new_info));
+                break;
+
+            case 2:
+                strncat(new_info,
+                    "In Service",
+                    sizeof(new_info) - 1 - strlen(new_info));
+                break;
+
+            case 3:
+                strncat(new_info,
+                    "Returning",
+                    sizeof(new_info) - 1 - strlen(new_info));
+                break;
+
+            case 4:
+                strncat(new_info,
+                    "Committed",
+                    sizeof(new_info) - 1 - strlen(new_info));
+                break;
+
+            case 5:
+                strncat(new_info,
+                    "Special",
+                    sizeof(new_info) - 1 - strlen(new_info));
+                break;
+
+            case 6:
+                strncat(new_info,
+                    "Priority",
+                    sizeof(new_info) - 1 - strlen(new_info));
+                break;
+
+            case 7:
+                strncat(new_info,
+                    "Emergency",
+                    sizeof(new_info) - 1 - strlen(new_info));
+
+                // Do a popup to alert the operator to this
+                // condition.  Make sure we haven't popped up an
+                // emergency message for this station within the
+                // last 30 minutes.  If we pop these up constantly
+                // it gets quite annoying.
+// EMERGENCY
+
+                if (emergency_distance_check) {
+                    double distance;
+                    char course_deg[5];
+
+
+                    distance = distance_from_my_station(call_sign, course_deg);
+
+// Because of the distance check we have to receive a valid position
+// from the station BEFORE we process the EMERGENCY portion and
+// check distance, doing the popups.  We need to figure out a way to
+// throw the packet back into the queue if it was an emergency
+// packet so that we process these packets twice each.  That way
+// only one packet from the emergency station is required to
+// generate the popups.
+
+                    if (distance == 0.0) {
+                        process_emergency_packet_again++;
+                    }
+
+                    // Check whether the station is near enough to
+                    // us to require that we alert on the packet.
+                    //
+                    // This may be slightly controversial, but if we
+                    // don't know WHERE a station is, we can't help
+                    // much in an emergency, can we?  The
+                    // zero-distance check helps in the case where
+                    // we haven't yet or never get a position packet
+                    // for a station.  As soon as we have a position
+                    // and it is within a reasonable range, we do
+                    // our emergency popups.
+                    //
+                    if ( distance != 0.0 && (float)distance <= emergency_range ) {
+
+                        if ( (strncmp(call_sign, last_emergency_callsign, strlen(call_sign)) != 0)
+                                || ((last_emergency_time + 60*30) < sec_now()) ) {
+
+                            char temp[50];
+                            char temp2[150];
+                            char temp3[300];
+                            char timestring[101];
+
+                            // Callsign is different or enough time has
+                            // passed
+
+                            last_emergency_time = sec_now();
+                            xastir_snprintf(last_emergency_callsign,
+                                sizeof(last_emergency_callsign),
+                                "%s",
+                                call_sign);
+
+                            // Bring up the Find Station dialog so that the
+                            // operator can go to the location quickly
+                            xastir_snprintf(locate_station_call,
+                                sizeof(locate_station_call),
+                                "%s",
+                                call_sign);
+
+                            Locate_station( (Widget)NULL, (XtPointer)NULL, (XtPointer)1 );
+
+                            // Bring up another dialog with the
+                            // callsign plus distance/bearing to the
+                            // station.
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.1f",
+                                distance);
+                            xastir_snprintf(temp2,
+                                sizeof(temp2),
+                                langcode("WPUPSTI022"),
+                                temp,
+                                course_deg);
+                            get_timestamp(timestring);
+                            xastir_snprintf(temp3,
+                                sizeof(temp3),
+                                "%s  %s",
+                                timestring,
+                                temp2);
+                            popup_message_always(call_sign, temp3);
+                        }
+                    }
+                }
+                break;
+
+            default:
+                strncat(new_info,
+                    "Off Duty",
+                    sizeof(new_info) - 1 - strlen(new_info));
+        }
+    }
+    else {
+        xastir_snprintf(temp, sizeof(temp), "Custom%d",msg);
+        strncat(new_info,
+            temp,
+            sizeof(new_info) - 1 - strlen(new_info));
+    }
+
+    if (info[offset] != '\0') {
+        /* Append the rest of the message to the expanded MIC-E message */
+        for (ii=offset; ii<info_size; ii++)
+            temp[ii-offset] = info[ii];
+
+        temp[info_size-offset] = '\0';
+        strncat(new_info,
+            " ",
+            sizeof(new_info) - 1 - strlen(new_info));
+        strncat(new_info,
+            temp,
+            sizeof(new_info) - 1 - strlen(new_info));
+    }
+
+    if (debug_level & 1) {
+        fprintf(stderr,"decode_Mic_E:  Done decoding MIC-E\n");
+        fprintf(stderr,"APRS_MICE, %s, %s, %s, %d, %d, NULL, %d\n",call_sign,path,new_info,from,port,third_party);
+        // type:        APRS_MICE,
+        // callsign:    N0EST-9,
+        // path:        TTPQ9P,W0MXW-1,WIDE,N0QK-1*,
+        // new_info:    4401.90N/09228.79W>278/007 /A=-05685 TM-D700 Mic-E Off Duty N0EST  ,
+        // from:        70,
+        // port:        -1,
+        //              NULL,
+        // third_party: 0
+    }
+
+    // We don't transmit Mic-E protocol from Xastir, so we know it's
+    // not our station's packets or our object/item packets,
+    // therefore the last two parameters here are both zero.
+    //
+    ok = data_add(APRS_MICE,call_sign,path,new_info,from,port,NULL,third_party, 0, 0);
+
+    if (debug_level & 1)
+        fprintf(stderr,"Returned from data_add, end of function\n");
+
+    return(ok);
+}   // End of decode_Mic_E()
+
+
+
+
+
+/*
+ *  Directed Station Query (query to my station)   [APRS Reference, chapter 15]
+ */
+int process_directed_query(char *call,char *path,char *message,char from) {
+    DataRow *p_station;
+    char from_call[MAX_CALLSIGN+1];
+    char temp[100];
+    int ok = 0;
+
+
+    if (debug_level & 1)
+        fprintf(stderr,"process_directed_query: %s\n",message);
+
+    // Check for proper usage of the APRSD query
+    if (!ok && strncmp(message,"APRSD",5) == 0 && from != 'F') {  // stations heard direct
+        pad_callsign(from_call,call);
+        xastir_snprintf(temp, sizeof(temp), ":%s:Directs=",from_call);
+        p_station = n_first;
+        while (p_station != NULL) {
+            if ((p_station->flag & ST_ACTIVE) != 0) {       // ignore deleted objects
+                if ( ((p_station->flag & ST_VIATNC) != 0)   // test "via TNC" flag
+                     && ((p_station->flag & ST_DIRECT) != 0) // And "direct" flag
+                     && sec_now() < (p_station->direct_heard + st_direct_timeout) // Within the last hour
+//                     && !is_my_call(p_station->call_sign,1) ) { // and not me (checks SSID too)
+                    && !(is_my_station(p_station)) ) { // and not me (checks SSID too)
+                    if (strlen(temp)+strlen(p_station->call_sign) < 65) {
+                        strncat(temp,
+                            " ",
+                            sizeof(temp) - 1 - strlen(temp));
+                        strncat(temp,
+                            p_station->call_sign,
+                            sizeof(temp) - 1 - strlen(temp));
+                    }
+                    else {
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+                        transmit_message_data(call,temp,NULL);
+                        xastir_snprintf(temp, sizeof(temp), 
+                                        ":%s:Directs=",from_call);
+                        strncat(temp,
+                            " ",
+                            sizeof(temp) - 1 - strlen(temp));
+                        strncat(temp,
+                            p_station->call_sign,
+                            sizeof(temp) - 1 - strlen(temp));
+                    }
+                }
+            }
+            p_station = p_station->n_next;
+        }
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+        transmit_message_data(call,temp,NULL);
+        ok = 1;
+    }
+    // Check for illegal case for the APRSD query
+    if (!ok && strncasecmp(message,"APRSD",5) == 0 && from != 'F') {  // stations heard direct
+        fprintf(stderr,
+            "%s just queried us with an illegal query: %s\n",
+            call,
+            message),
+        fprintf(stderr,
+            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+// NOT IMPLEMENTED YET
+    // Check for proper usage of the APRSH query
+    if (!ok && strncmp(message,"APRSH",5)==0) {
+        ok = 1;
+    }
+    // Check for illegal case for the APRSH query
+    if (!ok && strncasecmp(message,"APRSH",5)==0) {
+//        fprintf(stderr,
+//            "%s just queried us with an illegal query: %s\n",
+//            call,
+//            message),
+//        fprintf(stderr,
+//            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+// NOT IMPLEMENTED YET
+    // Check for proper usage of the APRSM query
+    if (!ok && strncmp(message,"APRSM",5)==0) {
+        ok = 1;
+    }
+    // Check for illegal case for the APRSM query
+    if (!ok && strncasecmp(message,"APRSM",5)==0) {
+//        fprintf(stderr,
+//            "%s just queried us with an illegal query: %s\n",
+//            call,
+//            message),
+//        fprintf(stderr,
+//            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+// NOT IMPLEMENTED YET
+    // Check for proper usage of the APRSO query
+    if (!ok && strncmp(message,"APRSO",5)==0) {
+        ok = 1;
+    }
+    // Check for illegal case for the APRSO query
+    if (!ok && strncasecmp(message,"APRSO",5)==0) {
+//        fprintf(stderr,
+//            "%s just queried us with an illegal query: %s\n",
+//            call,
+//            message),
+//        fprintf(stderr,
+//            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+    // Check for proper usage of the APRSP query
+    if (!ok && strncmp(message,"APRSP",5) == 0 && from != 'F') {
+        transmit_now = 1;       //send position
+        ok = 1;
+    }
+    // Check for illegal case for the APRSP query
+    if (!ok && strncasecmp(message,"APRSP",5) == 0 && from != 'F') {
+        fprintf(stderr,
+            "%s just queried us with an illegal query: %s\n",
+            call,
+            message),
+        fprintf(stderr,
+            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+// NOT IMPLEMENTED YET
+    // Check for proper usage of the APRSS query
+    if (!ok && strncmp(message,"APRSS",5)==0) {
+        ok = 1;
+    }
+    // Check for illegal case for the APRSS query
+    if (!ok && strncasecmp(message,"APRSS",5)==0) {
+//        fprintf(stderr,
+//            "%s just queried us with an illegal query: %s\n",
+//            call,
+//            message),
+//        fprintf(stderr,
+//            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+    // Check for proper usage of the APRST/PING? queries
+    if (!ok && (strncmp(message,"APRST",5)==0
+            ||  strncmp(message,"PING?",5)==0) && from != 'F') {
+        pad_callsign(from_call,call);
+        xastir_snprintf(temp, sizeof(temp), ":%s:PATH= %s>%s",from_call,call,path);    // correct format ?????
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+        transmit_message_data(call,temp,NULL);
+        ok = 1;
+    }
+
+
+    // Check for illegal case for the APRST/PING? queries
+    if (!ok && (strncasecmp(message,"APRST",5)==0
+            ||  strncasecmp(message,"PING?",5)==0) && from != 'F') {
+        fprintf(stderr,
+            "%s just queried us with an illegal query: %s\n",
+            call,
+            message),
+        fprintf(stderr,
+            "Consider sending a message, asking them to follow the spec\n");
+        ok = 1;
+    }
+
+
+    // Check for proper usage of the VER query (either case?)
+    if (!ok && strncasecmp("VER",message,3) == 0 && from != 'F') { // not in Reference !???
+        pad_callsign(from_call,call);
+        xastir_snprintf(temp, sizeof(temp), ":%s:%s",from_call,VERSIONLABEL);
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+        transmit_message_data(call,temp,NULL);
+        if (debug_level & 1)
+            fprintf(stderr,"Sent to %s:%s\n",call,temp);
+        ok = 1;
+    }
+
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Station Capabilities, Queries and Responses      [APRS Reference, chapter 15]
+ */
+//
+// According to Bob Bruninga we should wait a random time between 0
+// and 120 seconds before responding to a general query.  We use the
+// delayed-ack mechanism to add this randomness.
+//
+// NOTE:  We may end up sending these to RF when the query came in
+// over the internet.  We should check that.
+//
+int process_query( /*@unused@*/ char *call_sign, /*@unused@*/ char *path,char *message,char from,int port, /*@unused@*/ int third_party) {
+    char temp[100];
+    int ok = 0;
+    float randomize;
+
+
+    // Generate a random number between 0.0 and 1.0
+    randomize = rand() / (float)RAND_MAX;
+
+    // Convert to between 0 and 120 seconds
+    randomize = randomize * 120.0;
+//fprintf(stderr,"Randomize:%f\n", randomize);
+
+
+
+    // Check for proper usage of the ?APRS? query
+//
+// NOTE:  We need to add support in here for the radius circle as
+// listed in the spec for general queries.  Right now we respond to
+// all queries, whether we're inside the circle or not.  Spec says
+// this:
+//
+// ?Query?Lat,Long,Radius
+// 1  n  1 n 1 n  1  4 Bytes
+//
+// i.e. ?APRS? 34.02,-117.15,0200
+//
+// Note leading space in latitude as its value is positive.
+// Lat/long are floating point degrees.  N/E are positive, indicated
+// by a leading space.  S/W are negative.  Radius is in miles
+// expressed as a fixed 4-digit number in whole miles.  All stations
+// inside the specified circle should respond with a position report
+// and a status report.
+//
+    if (!ok && strncmp(message,"APRS?",5)==0) {
+        //
+        // Initiate a delayed transmit of our own posit.
+        // UpdateTime() uses posit_next_time to decide when to
+        // transmit, so we'll just muck with that.
+        //
+        if ( posit_next_time - sec_now() < randomize ) {
+            // Skip setting it, as we'll transmit soon anyway
+        }
+        else {
+            posit_next_time = (size_t)(sec_now() + randomize);
+        }
+        ok = 1;
+    }
+    // Check for illegal case for the ?APRS? query
+    if (!ok && strncasecmp(message,"APRS?",5)==0) {
+        ok = 1;
+//        fprintf(stderr,
+//            "%s just queried us with an illegal query: %s\n",
+//            call_sign,
+//            message),
+//        fprintf(stderr,
+//            "Consider sending a message, asking them to follow the spec\n");
+    }
+
+
+
+    // Check for proper usage of the ?IGATE? query
+    if (!ok
+            && strncmp(message,"IGATE?",6)==0
+            && port != -1) {    // Not from a log file
+
+        if (operate_as_an_igate && from != 'F') {
+            xastir_snprintf(temp, sizeof(temp), "<IGATE,MSG_CNT=%d,LOC_CNT=%d",(int)igate_msgs_tx,stations_types(3));
+
+            // OLD:
+            //output_my_data(temp,port,0,0,0,NULL);    // Not igating
+            // NEW:
+            transmit_message_data_delayed("ALL", temp, NULL, (time_t)(sec_now() + randomize) );
+        }
+        ok = 1;
+    }
+    // Check for illegal case for the ?IGATE? query
+    if (!ok
+            && strncasecmp(message,"IGATE?",6)==0
+            && port != -1) {    // Not from a log file
+
+        if (operate_as_an_igate && from != 'F') {
+            fprintf(stderr,
+                "%s just queried us with an illegal query: %s\n",
+                call_sign,
+                message),
+            fprintf(stderr,
+                "Consider sending a message, asking them to follow the spec\n");
+        }
+        ok = 1;
+    }
+
+
+
+    // Check for proper usage of the ?WX? query
+    if (!ok && strncmp(message,"WX?",3)==0) {
+
+// NOT IMPLEMENTED YET
+
+// Here we should check whether we are a weather station, and if so,
+// send out a delayed posit/weather string.
+//        if (we're a weather_station) {
+//            //
+//            // Initiate a delayed transmit of our own posit.
+//            // UpdateTime() uses posit_next_time to decide when to
+//            // transmit, so we'll just muck with that.
+//            //
+//            if ( posit_next_time - sec_now() < randomize ) {
+//                // Skip setting it, as we'll transmit soon anyway
+//            }
+//            else {
+//                posit_next_time = (size_t)(sec_now() + randomize);
+//            }
+//        }
+        ok = 1;
+    }
+    // Check for illegal case for the ?WX? query
+    if (!ok && strncasecmp(message,"WX?",3)==0) {
+        ok = 1;
+//        fprintf(stderr,
+//            "%s just queried us with an illegal query: %s\n",
+//            call_sign,
+//            message),
+//        fprintf(stderr,
+//            "Consider sending a message, asking them to follow the spec\n");
+    }
+
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Status Reports                              [APRS Reference, chapter 16]
+ */
+int process_status( /*@unused@*/ char *call_sign, /*@unused@*/ char *path, /*@unused@*/ char *message, /*@unused@*/ char from, /*@unused@*/ int port, /*@unused@*/ int third_party) {
+
+//    popup_message(langcode("POPEM00018"),message);  // What is it ???
+    return(1);
+}
+
+
+
+
+
+/*
+ *  shorten_path
+ *
+ * What to do with this one?
+ *      APW250,TCPIP*,ZZ2RMV-5*
+ * We currently convert it to:
+ *      APW250
+ * It's a packet that went across the 'net, then to RF, then back to
+ * the 'net.  We should probably drop it altogether?
+ *
+ *  Gets rid of unused digipeater fields (after the asterisk) and the
+ *  TCPIP field if it exists.  Used for creating the third-party
+ *  headers for igating purposes.  Note that for TRACEn-N and WIDEn-N
+ *  digi's, it's impossible to tell via the '*' character whether that
+ *  part of the path was used, but we can tell by the difference of
+ *  'n' and 'N'.  If they're different, then that part of the path was
+ *  used.  If it has counted down to just a TRACE or a WIDE (or TRACE7
+ *  or WIDE5), then it should have a '*' after it like normal.
+ */
+void shorten_path( char *path, char *short_path, int short_path_size ) {
+    int i,j,found_trace_wide,found_asterisk;
+    char *ptr;
+
+
+    if ( (path != NULL) && (strlen(path) >= 1) ) {
+
+        xastir_snprintf(short_path,
+            short_path_size,
+            "%s",
+            path);
+
+        // Terminate the path at the end of the last used digipeater
+        // This is trickier than it seems due to WIDEn-N and TRACEn-N
+        // digipeaters.
+
+        // Take a run through the entire path string looking for unused
+        // TRACE/WIDE paths.
+        for ( i = (strlen(path)-1); i >= 0; i-- ) { // Count backwards
+            // If we find ",WIDE3-3" or ",TRACE7-7" (numbers match),
+            // jam '\0' in at the comma.  These are unused digipeaters.
+            if (   (strstr(&short_path[i],",WIDE7-7") != NULL)
+                || (strstr(&short_path[i],",WIDE6-6") != NULL)
+                || (strstr(&short_path[i],",WIDE5-5") != NULL)
+                || (strstr(&short_path[i],",WIDE4-4") != NULL)
+                || (strstr(&short_path[i],",WIDE3-3") != NULL)
+                || (strstr(&short_path[i],",WIDE2-2") != NULL)
+                || (strstr(&short_path[i],",WIDE1-1") != NULL)
+                || (strstr(&short_path[i],",TRACE7-7") != NULL)
+                || (strstr(&short_path[i],",TRACE6-6") != NULL)
+                || (strstr(&short_path[i],",TRACE5-5") != NULL)
+                || (strstr(&short_path[i],",TRACE4-4") != NULL)
+                || (strstr(&short_path[i],",TRACE3-3") != NULL)
+                || (strstr(&short_path[i],",TRACE2-2") != NULL)
+                || (strstr(&short_path[i],",TRACE1-1") != NULL) ) {
+                short_path[i] = '\0';
+            }
+        }
+
+
+        // Take another run through short_string looking for used
+        // TRACE/WIDE paths.  Also look for '*' characters and flag
+        // if we see any.  If no '*' found, but a used TRACE/WIDE
+        // path found, chop the path after the used TRACE/WIDE.  This
+        // is to modify paths like this:
+        //     APRS,PY1AYH-15*,RELAY,WIDE3-2,PY1EU-1
+        // to this:
+        //     APRS,PY1AYH-15*,RELAY,WIDE3-2
+        j = 0;
+        found_trace_wide = 0;
+        found_asterisk = 0;
+        for ( i = (strlen(short_path)-1); i >= 0; i-- ) { // Count backwards
+
+            if (short_path[i] == '*')
+                found_asterisk++;
+
+            // Search for TRACEn/WIDEn.  If found (N!=n is guaranteed
+            // by the previous loop) set the lower increment for the next
+            // loop just past the last TRACEn/WIDEn found.  The used part
+            // of the TRACEn/WIDEn will still remain in our shorter path.
+            if (   (strstr(&short_path[i],"WIDE7") != NULL)
+                || (strstr(&short_path[i],"WIDE6") != NULL)
+                || (strstr(&short_path[i],"WIDE5") != NULL)
+                || (strstr(&short_path[i],"WIDE4") != NULL)
+                || (strstr(&short_path[i],"WIDE3") != NULL)
+                || (strstr(&short_path[i],"WIDE2") != NULL)
+                || (strstr(&short_path[i],"WIDE1") != NULL)
+                || (strstr(&short_path[i],"TRACE7") != NULL)
+                || (strstr(&short_path[i],"TRACE6") != NULL)
+                || (strstr(&short_path[i],"TRACE5") != NULL)
+                || (strstr(&short_path[i],"TRACE4") != NULL)
+                || (strstr(&short_path[i],"TRACE3") != NULL)
+                || (strstr(&short_path[i],"TRACE2") != NULL)
+                || (strstr(&short_path[i],"TRACE1") != NULL) ) {
+                j = i;
+                found_trace_wide++;
+                break;  // We only want to find the right-most one.
+                        // We've found a used digipeater!
+            }
+        }
+
+
+        // Chop off any unused digi's after a used TRACEn/WIDEn
+        if (!found_asterisk && found_trace_wide) {
+            for ( i = (strlen(short_path)-1); i >= j; i-- ) { // Count backwards
+                if (short_path[i] == ',') {
+                    short_path[i] = '\0';   // Terminate the string
+                }
+            }
+        }
+
+
+        // At this point, if we found a TRACEn or WIDEn, the "j"
+        // variable will be non-zero.  If not then it'll be zero and
+        // we'll run completely through the shorter path converting
+        // '*' characters to '\0'.
+        found_asterisk = 0;
+        for ( i = (strlen(short_path)-1); i >= j; i-- ) { // Count backwards
+            if (short_path[i] == '*') {
+                short_path[i] = '\0';   // Terminate the string
+                found_asterisk++;
+            }
+        }
+
+
+        // Check for TCPIP or TCPXX as the last digipeater.  If present,
+        // remove them.  TCPXX means that the packet came from an unregistered
+        // user, and those packets will be rejected in igate.c before they're
+        // sent to RF anyway.  igate.c will check for its presence in path,
+        // not in short_path, so we're ok here to get rid of it in short_path.
+        if (strlen(short_path) >= 5) {  // Get rid of "TCPIP" & "TCPXX"
+
+            ptr = &short_path[strlen(short_path) - 5];
+            if (   (strcasecmp(ptr,"TCPIP") == 0)
+                || (strcasecmp(ptr,"TCPXX") == 0) ) {
+                *ptr = '\0';
+            }
+            if ( (strlen(short_path) >= 1)  // Get rid of possible ending comma
+                    && (short_path[strlen(short_path) - 1] == ',') ) {
+                short_path[strlen(short_path) - 1] = '\0';
+            }
+        }
+
+
+        // We might have a string with zero used digipeaters.  In this case
+        // we will have no '*' characters and no WIDEn-N/TRACEn-N digis.
+        // Get rid of everything except the destination call.  These packets
+        // must have been heard directly by an igate station.
+        if (!found_trace_wide && !found_asterisk) {
+            for ( i = (strlen(short_path)-1); i >= j; i-- ) { // Count backwards
+                if (short_path[i] == ',') {
+                    short_path[i] = '\0';   // Terminate the string
+                }
+            }
+        }
+
+
+        // The final step:  Remove any asterisks in the path.
+        // We'll insert our own on the way out to RF again.
+        for ( i = 0; i < (int)(strlen(short_path) - 1); i++ ) {
+            if (short_path[i] == '*') {
+                for (j = i; j <= (int)(strlen(short_path) - 1); j++ ) {
+                  short_path[j] = short_path[j+1];  // Shift left by one char
+                }
+            }
+        }
+ 
+    
+    }
+    else {
+        short_path[0] = '\0';   // We were passed an empty string or a NULL.
+    }
+
+    if (debug_level & 1) {
+        fprintf(stderr,"%s\n",path);
+        fprintf(stderr,"%s\n\n",short_path);
+    }
+}
+
+
+
+
+
+// TODO:
+// *) Use the valid_call(call) function here?
+// *) Add a "Tactical Call Disable" togglebutton.  Default =
+//    disabled.
+// *) Send out TAC assignments as they are created via an APRS
+//    message?
+// *) Add "Send All Tactical Calls" menu entry.  Another entry to
+//    send them out repetitively?
+// *) Create a public/private distinction for TAC calls?
+// *) Add public/private toggle to the Tactical Callsign box, and
+//    have it send an APRS Message if public when changed?
+// *) Add a method to list the public/private TAC calls we currently
+//    have assigned.
+// *) Create an easier method to remove one or more TAC calls?
+//    Currently we have to send a blank assignment ("we7u-12=").
+// *) Log TAC calls and date/time for each assignment, including
+//    NULL assignments.
+//
+// From Bob:
+// *) Range filter - won't accept tactical assignments without a
+//    position within X miles of source.
+// *) Change filter - won't accept changes from others for locally
+//    created tac assignment.  Kind of implies two tables - local
+//    and remote Button/menu item to send local, or send all - each
+//    a manual operation, as we discussed.
+// *) Perhaps repeat messages fewer times if sent to TACTICAL than
+//    for a normal message?  This is so that more than one
+//    controller can manipulate them without having to wait for the
+//    timeout of the first message.
+//
+//
+int fill_in_tactical_callsign(char *call, char *tactical_call) {
+    DataRow *p_station;
+
+
+    // Convert callsign to upper-case
+    (void)to_upper(call);
+
+    // Get rid of white space on either end
+    (void)remove_leading_spaces(call);
+    (void)remove_trailing_spaces(call);
+    (void)remove_leading_spaces(tactical_call);
+    (void)remove_trailing_spaces(tactical_call);
+ 
+    // Find the station record.
+    if (!search_station_name(&p_station, call, 1)) {
+        // Station not found.
+
+        // Add the TAC call to the tactical hash for future
+        // application to a callsign via the log_tactical_call()
+        // function call below...
+    }
+
+    else {  // Found it!  Assign the new tactical call.  Some code
+            // here borrowed from db.c:Change_tactical_change_data()
+
+        // Check for blank incoming tactical call.
+        if (tactical_call[0] == '\0') {
+            // Blank tactical call string.  Free space and null
+            // pointer.
+            free(p_station->tactical_call_sign);
+            p_station->tactical_call_sign = NULL;
+        }
+
+        else {  // Non-blank incoming tactical call string
+
+            if (p_station->tactical_call_sign == NULL) {
+                // Malloc some memory to hold it.
+                p_station->tactical_call_sign = (char *)malloc(MAX_TACTICAL_CALL+1);
+            }
+            if (p_station->tactical_call_sign == NULL) {
+                fprintf(stderr,
+                    "Couldn't malloc space for tactical callsign\n");
+                return -1;
+            }
+
+            xastir_snprintf(p_station->tactical_call_sign,
+                MAX_TACTICAL_CALL+1,
+                "%s",
+                tactical_call);
+        }
+        redraw_on_new_data = 2;  // redraw now
+    }
+
+    // Log the change in the tactical_calls.log file.  Also adds it
+    // to the tactical callsign hash.
+    log_tactical_call(call, tactical_call);
+
+    return(0);
+}
+
+
+
+
+
+//
+// Assign tactical callsigns based on messages sent to "TACTICAL"
+//
+//  *) To set your own tactical callsign and send it to others,
+//     send an APRS message to "TACTICAL" with your callsign in
+//     the message text.
+//
+//  *) To send multiple tactical calls to others, send an APRS
+//     message to "TACTICAL" and enter:
+//     "CALL1=TAC1;CALL2=TAC2;CALL3=TAC3" in the message text.
+//
+//  '=' or ';' characters can not be in the TAC callsign.
+// 
+int tactical_data_add(char *call, char *message, char from) {
+    char *temp_ptr;
+
+
+    if (strlen(message) <= 1) {
+        return -1;
+    }
+
+    // Check whether we're dealing with one or multiple tactical
+    // callsign assignments.  Look for a '=' character.
+    temp_ptr = strrchr(message,'=');
+
+    if (temp_ptr == NULL) {
+        // No '=' character was found.  We're dealing with a single
+        // tactical assignment for the "call" callsign.  Extract the
+        // tactical call and assign it to the station data record
+        // for the station.
+
+        if (debug_level & 2)
+            fprintf(stderr, "One tactical assignment.\n");
+ 
+        fill_in_tactical_callsign(call, message);
+    }
+
+    else {  // We're dealing with multiple tactical assignments.
+        int ii;
+        const int max = 50;
+        char *Substring[max];
+        char *Call_Tac[2];
+
+
+        if (debug_level & 2)
+            fprintf(stderr, "Possibly multiple tactical assignments.\n");
+
+        // Split the message first on ';' characters to get the
+        // callsign=tactical pairs separated from each other.
+        split_string( message, Substring, max, ';' );
+
+        // Check whether we found more than one pair.
+        if (Substring[0] == NULL) { // No ';' chars were found.
+            // We might still have a single tactical definition in
+            // the message.  Assign "message" to Substring[0] for
+            // further processing below.
+
+            if (debug_level & 2)
+                fprintf(stderr, "No semicolons found.\n");
+
+            Substring[0] = message;
+        }
+
+        ii = 0;
+
+        while (Substring[ii] != NULL) {
+            // Split each string and process.  The results of each
+            // split will be in:
+            //   Call_Tac[0]    (Callsign)
+            //   Call_Tac[1]    (Tactical Callsign)
+            //
+            split_string( Substring[ii], Call_Tac, 2, '=' );
+
+            if (Call_Tac[0] != NULL) { // Found '=' char.
+
+                if (debug_level & 2) {
+                    fprintf(stderr, "Found a tactical pair:  %s->%s\n",
+                        Call_Tac[0],
+                        Call_Tac[1]);
+                }
+
+                fill_in_tactical_callsign(Call_Tac[0], Call_Tac[1]);
+            }
+            ii++;
+        }
+    }
+
+    return 0;
+}
+ 
+
+
+
+
+//
+//  Messages, Bulletins and Announcements         [APRS Reference, chapter 14]
+//
+//
+// Returns 1 if successful
+//         0 if not successful
+//
+int decode_message(char *call,char *path,char *message,char from,int port,int third_party) {
+    char *temp_ptr;
+    char ipacket_message[300];
+    char message_plus_acks[MAX_MESSAGE_LENGTH + 10];
+    char from_call[MAX_CALLSIGN+1];
+    char ack[20];
+    int ok, len;
+    char addr[9+1];
+    char addr9[9+1];
+    char msg_id[5+1];
+    char orig_msg_id[5+1];
+    char ack_string[6];
+    int done;
+    int reply_ack = 0;
+    int to_my_call = 0;
+    int to_my_base_call = 0;
+    int from_my_call = 0;
+
+
+    // :xxxxxxxxx:____0-67____             message              printable, except '|', '~', '{'
+    // :TACTICAL :text                     Tactical definition for sending station
+    // :TACTICAL :CALL1=TAC1;CALL2=TAC2    Tactical definitions for multiple stations
+    // :BLNn     :____0-67____             general bulletin     printable, except '|', '~'
+    // :BLNnxxxxx:____0-67____           + Group Bulletin
+    // :BLNX     :____0-67____             Announcement
+    // :NWS-xxxxx:____0-67____             NWS Service Bulletin
+    // :NWS_xxxxx:____0-67____             NWS Service Bulletin
+    // :BOM-xxxxx:____0-67____             BOM Service Bulletin (AU Wx)
+    // :BOM_xxxxx:____0-67____             BOM Service Bulletin (AU Wx)
+    // :xxxxxxxxx:ackn1-5n               + ack
+    // :xxxxxxxxx:rejn1-5n               + rej
+    // :xxxxxxxxx:____0-67____{n1-5n     + message
+    // :NTS....
+    //  01234567890123456
+    // 01234567890123456    old
+    // we get message with already extracted data ID
+
+    if (debug_level & 1)
+        fprintf(stderr,"decode_message: start\n");
+
+    if (debug_level & 1) {
+        if ( (message != NULL) && (strlen(message) > (MAX_MESSAGE_LENGTH + 10) ) ) {
+            //
+            // Overly long message.  Throw it away.  We're done.
+            //
+            fprintf(stderr,"decode_message: LONG message.  Dumping it.\n");
+            return(0);
+        }
+    }
+
+    if (is_my_call(call, 1) ) { // Check SSID also
+        from_my_call++;
+    }
+
+    ack_string[0] = '\0';   // Clear out the Reply/Ack result string
+
+    len = (int)strlen(message);
+    ok = (int)(len > 9 && message[9] == ':');
+
+    if (ok) {
+
+        substr(addr9,message,9); // extract addressee
+        xastir_snprintf(addr,
+            sizeof(addr),
+            "%s",
+            addr9);
+        (void)remove_trailing_spaces(addr);
+
+        if (is_my_call(addr,1)) { // Check includes SSID
+            to_my_call++;
+        }
+
+        if (is_my_call(addr,0)) { // Check ignores SSID.  We use
+                                  // this to catch messages to some
+                                  // of our other SSID's
+            to_my_base_call++;
+        }
+
+        message = message + 10; // pointer to message text
+
+        // Save the message text and the acks/reply-acks before we
+        // extract the acks below.
+        xastir_snprintf(message_plus_acks,
+            sizeof(message_plus_acks),
+            "%s",
+            message);
+
+        temp_ptr = strrchr(message,'{'); // look for message ID after
+                                         //*last* { in message.
+        msg_id[0] = '\0';
+        if (temp_ptr != NULL) {
+            substr(msg_id,temp_ptr+1,5); // extract message ID, could be non-digit
+            temp_ptr[0] = '\0';          // adjust message end (chops off message ID)
+        }
+
+        // Save the original msg_id away.
+        xastir_snprintf(orig_msg_id,
+            sizeof(orig_msg_id),
+            "%s",
+            msg_id);
+
+        // Check for Reply/Ack protocol in msg_id, which looks like
+        // this:  "{XX}BB", where XX is the sequence number for the
+        // message, and BB is the ack for the previous message from
+        // my station.  I've also seen this from APRS+: "{XX}B", so
+        // perhaps this is also possible "{X}B" or "{X}BB}".  We can
+        // also get auto-reply responses from APRS+ that just have
+        // "}X" or "}XX" at the end.  We decode those as well.
+        //
+
+        temp_ptr = strstr(msg_id,"}"); // look for Reply Ack in msg_id
+
+        if (temp_ptr != NULL) { // Found Reply/Ack protocol!
+ 
+            reply_ack++;
+
+//            if ( (debug_level & 1) && (is_my_call(addr,1)) ) { // Check SSID also
+            if ( (debug_level & 1) && to_my_call) { // Check SSID also
+                fprintf(stderr,"1Found Reply/Ack:%s\n",message);
+                fprintf(stderr,"Orig_msg_id:%s\t",msg_id);
+            }
+
+// Put this code into the UI message area as well (if applicable).
+
+            // Separate out the extra ack so that we can deal with
+            // it properly.
+            xastir_snprintf(ack_string,
+                sizeof(ack_string),
+                "%s",
+                temp_ptr+1); // After the '}' character!
+
+            // Terminate it here so that rest of decode works
+            // properly.  We can get duplicate messages
+            // otherwise.
+            //
+// Note that we modify msg_id here.  Use orig_msg_id if we need the
+// unmodified version (full REPLY-ACK version) later.
+            //
+            temp_ptr[0] = '\0'; // adjust msg_id end
+
+//            if ( (debug_level & 1) && (is_my_call(addr,1)) ) { // Check SSID also
+            if ( (debug_level & 1) && to_my_call) { // Check SSID also
+                fprintf(stderr,"New_msg_id:%s\tReply_ack:%s\n\n",
+                    msg_id,ack_string);
+            }
+
+        }
+        else {  // Look for Reply Ack in message without sequence
+                // number
+            temp_ptr = strstr(message,"}");
+
+            if (temp_ptr != NULL) {
+                int yy = 0;
+
+
+                reply_ack++;
+
+//                if ( (debug_level & 1) && (is_my_call(addr,1)) ) { // Check SSID also
+                if ( (debug_level & 1) && to_my_call) { // Check SSID also
+                    fprintf(stderr,"2Found Reply/Ack:%s\n",message);
+                }
+
+// Put this code into the UI message area as well (if applicable).
+                xastir_snprintf(ack_string,
+                    sizeof(ack_string),
+                    "%s",
+                    temp_ptr+1);    // After the '}' character!
+
+                ack_string[yy] = '\0';  // Terminate the string
+
+                // Terminate it here so that rest of decode works
+                // properly.  We can get duplicate messages
+                // otherwise.
+                temp_ptr[0] = '\0'; // adjust message end
+
+//                if ( (debug_level & 1) && (is_my_call(addr,1)) ) { // Check SSID also
+                if ( (debug_level & 1) && to_my_call) { // Check SSID also
+                    fprintf(stderr,"Reply_ack:%s\n\n",ack_string);
+                }
+            } 
+        }
+
+        done = 0;
+    }
+    else {
+        done = 1;                               // fall through...
+    }
+
+    if (debug_level & 1)
+        fprintf(stderr,"1\n");
+    len = (int)strlen(message);
+    //--------------------------------------------------------------------------
+    if (!done && len > 3 && strncmp(message,"ack",3) == 0) {              // ACK
+
+        // Received an ACK packet.  Note that these can carry the
+        // REPLY-ACK protocol or a single ACK sequence number plus
+        // perhaps an extra '}' on the end.  They should have one of
+        // these formats:
+        //      ack1        Normal ACK
+        //      ackY        Normal ACK
+        //      ack23       Normal ACK
+        //      ackfH       Normal ACK
+        //      ack23{      REPLY-ACK Protocol
+        //      ack2Q}3d    REPLY-ACK Protocol
+
+        substr(msg_id,message+3,5);
+        // fprintf(stderr,"ACK: %s: |%s| |%s|\n",call,addr,msg_id);
+//        if (is_my_call(addr,1)) { // Check SSID also
+        if (to_my_call) { // Check SSID also
+
+            // Note:  This function handles REPLY-ACK protocol just
+            // fine, stripping off the 2nd ack if present.  It uses
+            // only the first sequence number.
+            clear_acked_message(call,addr,msg_id);  // got an ACK for me
+
+            // This one also handles REPLY-ACK protocol just fine.
+            msg_record_ack(call,addr,msg_id,0,0);   // Record the ack for this message
+        }
+        else {  // ACK is for another station
+            // Now if I have Igate on and I allow to retransmit station data
+            // check if this message is to a person I have heard on my TNC within an X
+            // time frame. If if is a station I heard and all the conditions are ok
+            // spit the ACK out on the TNC -FG
+            if (operate_as_an_igate>1
+                    && from==DATA_VIA_NET
+//                    && !is_my_call(call,1) // Check SSID also
+                    && !from_my_call     // Check SSID also
+                    && port != -1) {    // Not from a log file
+                char short_path[100];
+
+//fprintf(stderr,"Igate check o:%d f:%c myc:%s cf:%s ct:%s\n",
+//    operate_as_an_igate,
+//    from,
+//    my_callsign,
+//    call,
+//    addr);
+                shorten_path(path,short_path,sizeof(short_path));
+
+                // Only send '}' and the ack_string if it's not
+                // empty, else just end the packet with the message
+                // string.  This keeps us from appending a '}' when
+                // it's not called for.
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message),
+//                    "}%s>%s,TCPIP,%s*::%s:%s%s%s",
+                    "}%s>%s,TCPIP,%s*::%s:%s",
+ 
+                    call,
+                    short_path,
+                    my_callsign,
+                    addr9,
+//                    message,
+                    message_plus_acks);
+//                    (ack_string[0] == '\0') ? "" : "}",
+//                    ack_string);
+
+if (reply_ack) { // For debugging, so we only have reply-ack
+                 // messages and acks scrolling across the screen.
+//    fprintf(stderr,"Attempting to send ACK to RF:  %s\n", ipacket_message);
+}
+
+                output_igate_rf(call,
+                    addr,
+                    path,
+                    ipacket_message,
+                    port,
+                    third_party,
+                    NULL);
+
+                igate_msgs_tx++;
+            }
+        }
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"2\n");
+    //--------------------------------------------------------------------------
+    if (!done && len > 3 && strncmp(message,"rej",3) == 0) {              // REJ
+
+        substr(msg_id,message+3,5);
+
+//        if ( is_my_call(addr,1) ) { // Check SSID also
+        if (to_my_call) {   // Check SSID also
+
+            // REJ is for me!
+//            fprintf(stderr,"Received a REJ packet from %s: |%s| |%s|\n",call,addr,msg_id);
+
+            // Note:  This function handles REPLY-ACK protocol just
+            // fine, stripping off the 2nd ack if present.  It uses
+            // only the first sequence number.
+            clear_acked_message(call,addr,msg_id);  // got an REJ for me
+
+            // This one also handles REPLY-ACK protocol just fine.
+            msg_record_rej(call,addr,msg_id);   // Record the REJ for this message
+        }
+        else {  // REJ is for another station
+            /* Now if I have Igate on and I allow to retransmit station data           */
+            /* check if this message is to a person I have heard on my TNC within an X */
+            /* time frame. If if is a station I heard and all the conditions are ok    */
+            /* spit the REJ out on the TNC                                             */
+            if (operate_as_an_igate>1
+                    && from==DATA_VIA_NET
+//                    && !is_my_call(call,1) // Check SSID also
+                    && !from_my_call    // Check SSID also
+                    && port != -1) {    // Not from a log file
+                char short_path[100];
+
+//fprintf(stderr,"Igate check o:%d f:%c myc:%s cf:%s ct:%s\n",
+//    operate_as_an_igate,
+//    from,
+//    my_callsign,
+//    call,
+//    addr);
+                shorten_path(path,short_path,sizeof(short_path));
+
+                // Only send '}' and the rej_string if it's not
+                // empty, else just end the packet with the message
+                // string.  This keeps us from appending a '}' when
+                // it's not called for.
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message),
+//                    "}%s>%s,TCPIP,%s*::%s:%s%s%s",
+                    "}%s>%s,TCPIP,%s*::%s:%s",
+ 
+                    call,
+                    short_path,
+                    my_callsign,
+                    addr9,
+//                    message,
+                    message_plus_acks);
+//                    (ack_string[0] == '\0') ? "" : "}",
+//                    ack_string);
+
+if (reply_ack) { // For debugging, so we only have reply-ack
+                 // messages and acks scrolling across the screen.
+//    fprintf(stderr,"Attempting to send REJ to RF:  %s\n", ipacket_message);
+}
+
+                output_igate_rf(call,
+                    addr,
+                    path,
+                    ipacket_message,
+                    port,
+                    third_party,
+                    NULL);
+
+                igate_msgs_tx++;
+            }
+        }
+
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"3\n");
+    //--------------------------------------------------------------------------
+    if (!done && strncmp(addr,"TACTICAL",8) == 0) {                  // Tactical definition
+
+        if (debug_level & 2)
+            fprintf(stderr,"found TACTICAL: |%s| |%s|\n",call,message);
+
+        tactical_data_add(call,message,from);
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"TAC\n");
+    //--------------------------------------------------------------------------
+    if (!done && strncmp(addr,"BLN",3) == 0) {                       // Bulletin
+        // fprintf(stderr,"found BLN: |%s| |%s|\n",addr,message);
+        bulletin_data_add(addr,call,message,"",MESSAGE_BULLETIN,from);
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"4\n");
+
+    //--------------------------------------------------------------------------
+//    if (!done && strlen(msg_id) > 0 && is_my_call(addr,1)) { // Message for me (including SSID check)
+    if (!done && strlen(msg_id) > 0 && to_my_call) {         // Message for me (including SSID check)
+                                                             // with msg_id (sequence number)
+        time_t last_ack_sent;
+        long record;
+
+
+// Remember to put this code into the UI message area as well (if
+// applicable).
+
+        // Check for Reply/Ack
+        if (reply_ack && strlen(ack_string) != 0) { // Have a free-ride ack to deal with
+
+//fprintf(stderr, "reply-ack: clear_acked_message()\n");
+            clear_acked_message(call,addr,ack_string);  // got an ACK for me
+
+//fprintf(stderr, "reply-ack: msg_record_ack()\n");
+            msg_record_ack(call,addr,ack_string,0,0);   // Record the ack for this message
+        }
+
+        // Save the ack 'cuz we might need it while talking to this
+        // station.  We need it to implement Reply/Ack protocol.
+
+// Note that msg_id has already been truncated by this point.
+// orig_msg_id contains the full REPLY-ACK text.
+
+//fprintf(stderr, "store_most_recent_ack()\n");
+        store_most_recent_ack(call,msg_id);
+ 
+        // fprintf(stderr,"found Msg w line to me: |%s| |%s|\n",message,msg_id);
+        last_ack_sent = msg_data_add(addr,
+                            call,
+                            message,
+                            msg_id,
+                            MESSAGE_MESSAGE,
+                            from,
+                            &record); // id_fixed
+
+        // Here we need to know if it is a new message or an old.
+        // If we've already received it, we don't want to kick off
+        // the alerts or pop up the Send Message dialog again.  If
+        // last_ack_sent == (time_t)0, then it is a new message.
+        //
+        if (last_ack_sent == (time_t)0l && record == -1l) { // Msg we've never received before
+
+            new_message_data += 1;
+
+            // Note that the check_popup_window() function will
+            // re-create a Send Message dialog if one doesn't exist
+            // for this QSO.  Only call it for the first message
+            // line or the first ack, not for any repeats.
+            //
+//fprintf(stderr,"***check_popup_window 1\n");
+            (void)check_popup_window(call, 2);  // Calls update_messages()
+
+            //update_messages(1); // Force an update
+
+            if (sound_play_new_message)
+                play_sound(sound_command,sound_new_message);
+
+#ifdef HAVE_FESTIVAL
+/* I re-use ipacket_message as my string buffer */
+            if (festival_speak_new_message_alert) {
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message),
+                    "You have a new message from %s.",
+                    call);
+                SayText(ipacket_message);
+            }
+            if (festival_speak_new_message_body) {
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message),
+                    " %s",
+                    message);
+                SayText(ipacket_message);
+            }
+
+#endif  // HAVE_FESTIVAL
+
+        }
+
+        // Try to only send an ack out once per 30 seconds at the
+        // fastest.
+//WE7U
+// Does this 30-second check work?
+        //
+        if ( from != 'F'  // Not from a log file
+                && (last_ack_sent != (time_t)-1l)   // Not an error
+                && (last_ack_sent + 30 ) < sec_now()
+                && !satellite_ack_mode // Disable separate ack's for satellite work
+                && port != -1 ) {   // Not from a log file
+
+            char path[MAX_LINE_SIZE+1];
+
+
+            //fprintf(stderr,"Sending ack: %ld %ld %ld\n",last_ack_sent,sec_now(),record);
+
+            // Update the last_ack_sent field for the message
+            msg_update_ack_stamp(record);
+
+            pad_callsign(from_call,call);         /* ack the message */
+
+
+            // Attempt to snag a custom path out of the Send Message
+            // dialog, if set.  If not set, path will contain '\0';
+            get_send_message_path(call, path, MAX_LINE_SIZE+1);
+//fprintf(stderr,"Path: %s\n", path);
+
+
+            // In this case we want to send orig_msg_id back, not
+            // the (possibly) truncated msg_id.  This is per Bob B's
+            // Reply/Ack spec, sent to xastir-dev on Nov 14, 2001.
+            xastir_snprintf(ack, sizeof(ack), ":%s:ack%s",from_call,orig_msg_id);
+
+//WE7U
+// Need to figure out the reverse path for this one instead of
+// passing a NULL for the path?  Probably not, as auto-calculation
+// of paths isn't a good idea.
+//
+// What we need to do here is check whether we have a custom path
+// set for this QSO.  If so, pass that path along as the transmit
+// path.  messages.h:Message_Window struct has the send_message_path
+// variable in it.  If a Message_Window still exists for this QSO
+// then we can snag the user-entered path from there.  If the struct
+// has already been destroyed then we have nowhere to snag the
+// custom path from and have to rely on the default paths in each
+// interface properties dialog instead.  Then again, we _could_ snag
+// the path out of the last received message in the message database
+// for that case.  Might be better to disable the Close button, or
+// warn the user that the custom path will be lost if they close the
+// Send Message dialog.
+
+
+            // Send out the immediate ACK
+            if (path[0] == '\0')
+                transmit_message_data(call,ack,NULL);
+            else
+                transmit_message_data(call,ack,path);
+
+
+            if (record != -1l) { // Msg we've received before
+
+                // It's a message that we've received before,
+                // consider sending an extra ACK in about 30 seconds
+                // to try to get it to the remote station.  Perhaps
+                // another one in 60 seconds as well.
+
+//                fprintf(stderr,
+//                    "We've received this message before.\n");
+//                fprintf(stderr,
+//                    "Sending a couple of delayed ack's.\n");
+
+                if (path[0] == '\0') {
+                    transmit_message_data_delayed(call,ack,NULL,sec_now()+30);
+                    transmit_message_data_delayed(call,ack,NULL,sec_now()+60);
+                    transmit_message_data_delayed(call,ack,NULL,sec_now()+120);
+                }
+                else {
+                    transmit_message_data_delayed(call,ack,path,sec_now()+30);
+                    transmit_message_data_delayed(call,ack,path,sec_now()+60);
+                    transmit_message_data_delayed(call,ack,path,sec_now()+120);
+                }
+            }
+
+
+            if (auto_reply == 1) {
+
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message), "AA:%s", auto_reply_message);
+
+                if (debug_level & 2)
+                    fprintf(stderr,"Send autoreply to <%s> from <%s> :%s\n",
+                        call, my_callsign, ipacket_message);
+
+//                if (!is_my_call(call,1)) // Check SSID also
+                if (!from_my_call) // Check SSID also
+                    output_message(my_callsign, call, ipacket_message, "");
+            }
+        }
+
+else {
+//fprintf(stderr,"Skipping ack: %ld %ld\n",last_ack_sent,sec_now());
+}
+
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"5a\n");
+
+    //--------------------------------------------------------------------------
+    if (!done && strlen(msg_id) == 0 && to_my_call) {   // Message for me (including SSID check)
+                                                        // but without message-ID.
+        // These should appear in a Send Message dialog and should
+        // NOT get ack'ed.  Kenwood radios send this message type as
+        // an auto-answer or a buffer-full message.  They look
+        // something like:
+        //
+        //      :WE7U-13 :Not at keyboard.
+        //
+
+        time_t last_ack_sent;
+        long record;
+
+
+        if (len > 2
+                && message[0] == '?'
+                && port != -1   // Not from a log file
+                && to_my_call) { // directed query (check SSID also)
+            // Smallest query known is "?WX".
+            if (debug_level & 1)
+                fprintf(stderr,"Received a directed query\n");
+            done = process_directed_query(call,path,message+1,from);
+        }
+
+        // fprintf(stderr,"found Msg w line to me: |%s| |%s|\n",message,msg_id);
+        last_ack_sent = msg_data_add(addr,
+                            call,
+                            message,
+                            msg_id,
+                            MESSAGE_MESSAGE,
+                            from,
+                            &record); // id_fixed
+
+        // Here we need to know if it is a new message or an old.
+        // If we've already received it, we don't want to kick off
+        // the alerts or pop up the Send Message dialog again.  If
+        // last_ack_sent == (time_t)0, then it is a new message.
+        //
+        if (last_ack_sent == (time_t)0l && record == -1l) { // Msg we've never received before
+
+            new_message_data += 1;
+
+            // Note that the check_popup_window() function will
+            // re-create a Send Message dialog if one doesn't exist
+            // for this QSO.  Only call it for the first message
+            // line or the first ack, not for any repeats.
+            //
+//fprintf(stderr,"***check_popup_window 1\n");
+            (void)check_popup_window(call, 2);  // Calls update_messages()
+
+            //update_messages(1); // Force an update
+
+            if (sound_play_new_message)
+                play_sound(sound_command,sound_new_message);
+
+#ifdef HAVE_FESTIVAL
+/* I re-use ipacket_message as my string buffer */
+            if (festival_speak_new_message_alert) {
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message),
+                    "You have a new message from %s.",
+                    call);
+                SayText(ipacket_message);
+            }
+            if (festival_speak_new_message_body) {
+                xastir_snprintf(ipacket_message,
+                    sizeof(ipacket_message),
+                    " %s",
+                    message);
+                SayText(ipacket_message);
+            }
+
+#endif  // HAVE_FESTIVAL
+
+        }
+
+        // Update the last_ack_sent field for the message, even
+        // though we won't be sending an ack in response.
+        msg_update_ack_stamp(record);
+
+
+//fprintf(stderr,"Received msg for me w/o ack\n");
+
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"5b\n");
+
+    //--------------------------------------------------------------------------
+    if (!done
+            && ( (strncmp(addr,"NWS-",4) == 0)          // NWS weather alert
+              || (strncmp(addr,"NWS_",4) == 0)          // NWS weather alert compressed
+              || (strncmp(addr,"BOM-",4) == 0)          // BOM (AU) weather alert 
+              || (strncmp(addr,"BOM_",4) == 0) ) ) {    // BOM (AU) weather alert compressed
+
+        // could have sort of line number
+        //fprintf(stderr,"found NWS: |%s| |%s| |%s|\n",addr,message,msg_id);
+
+        (void)alert_data_add(addr,
+            call,
+            message,
+            msg_id,
+            MESSAGE_NWS,
+            from);
+
+        done = 1;
+        if (operate_as_an_igate>1
+                && from==DATA_VIA_NET
+//                && !is_my_call(call,1) // Check SSID also
+                && !from_my_call // Check SSID also
+                && port != -1) { // Not from a log file
+            char short_path[100];
+
+            shorten_path(path,short_path,sizeof(short_path));
+
+            xastir_snprintf(ipacket_message,
+                sizeof(ipacket_message),
+                "}%s>%s,TCPIP,%s*::%s:%s",
+                call,
+                short_path,
+                my_callsign,
+                addr9,
+                message);
+
+            output_nws_igate_rf(call,
+                path,
+                ipacket_message,
+                port,
+                third_party);
+        }
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"6a\n");
+    //--------------------------------------------------------------------------
+    if (!done && strncmp(addr,"SKY",3) == 0) {  // NWS weather alert additional info
+
+        // could have sort of line number
+        //fprintf(stderr,"found SKY: |%s| |%s| |%s|\n",addr,message,msg_id);
+
+/*
+        (void)alert_data_add(addr,
+            call,
+            message,
+            msg_id,
+            MESSAGE_NWS,
+            from);
+*/
+
+// We don't wish to record these in memory.  They cause an infinite
+// loop in the current code and a massive memory leak.
+return(1);  // Tell the calling program that the packet was ok so
+            // that it doesn't add it with data_add() itself!
+
+
+        done = 1;
+        if (operate_as_an_igate>1
+                && from==DATA_VIA_NET
+//                && !is_my_call(call,1) // Check SSID also
+                && !from_my_call    // Check SSID also
+                && port != -1) { // Not from a log file
+            char short_path[100];
+
+            shorten_path(path,short_path,sizeof(short_path));
+
+            xastir_snprintf(ipacket_message,
+                sizeof(ipacket_message),
+                "}%s>%s,TCPIP,%s*::%s:%s",
+                call,
+                short_path,
+                my_callsign,
+                addr9,
+                message);
+
+            output_nws_igate_rf(call,
+                path,
+                ipacket_message,
+                port,
+                third_party);
+        }
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"6b\n");
+    //--------------------------------------------------------------------------
+    if (!done && strlen(msg_id) > 0) {  // Other message with linenumber.  This
+                                        // is either a message for someone else
+                                        // or a message for another one of my
+                                        // SSID's.
+        long record_out;
+        time_t last_ack_sent;
+        char message_plus_note[MAX_MESSAGE_LENGTH + 30];
+ 
+ 
+        if (debug_level & 2)
+            fprintf(stderr,"found Msg w/line: |%s| |%s| |%s|\n",
+                addr,
+                message,
+                orig_msg_id);
+
+        if (to_my_base_call && !from_my_call) {
+            // Special case:  We saw a message w/msg_id that was to
+            // one of our other SSID's, but it was not from
+            // ourselves.  That last bit (!from_my_call) is
+            // important in the case where we're working an event
+            // with several stations using the same callsign.
+            //
+            // Store as if it came to my callsign, with a zeroed-out
+            // msg_id so we can't try to ack it.  We also need some
+            // other indication in the "Send Message" dialog as to
+            // what's happening.  Perhaps add the original callsign
+            // to the message itself in a note at the start?
+            //
+            xastir_snprintf(message_plus_note,
+                sizeof(message_plus_note),
+                "(Sent to:%s) %s",
+                addr,
+                message);
+            last_ack_sent = msg_data_add(my_callsign,
+                call,
+                message_plus_note,
+                "",
+                MESSAGE_MESSAGE,
+                from,
+                &record_out);
+        }
+        else {  // Normal case, messaging between other people
+            last_ack_sent = msg_data_add(addr,
+                call,
+                message,
+                msg_id,
+                MESSAGE_MESSAGE,
+                from,
+                &record_out);
+        }
+ 
+        new_message_data += look_for_open_group_data(addr);
+ 
+        // Note that the check_popup_window() function will
+        // re-create a Send Message dialog if one doesn't exist for
+        // this QSO.  Only call it for the first message line or the
+        // first ack, not for any repeats.
+        //
+        if (last_ack_sent == (time_t)0l && record_out == -1l) { // Msg we've never received before
+//fprintf(stderr,"***check_popup_window 2\n");
+
+            // Callsign check here also checks SSID for exact match
+//            if ((is_my_call(call,1) && check_popup_window(addr, 2) != -1)
+//            if ((from_my_call && check_popup_window(addr, 2) != -1)
+// We need to do an SSID-non-specific check here so that we can pick
+// up messages intended for other stations of ours.
+//            if ((to_my_base_call && check_popup_window(addr, 2) != -1)
+            if ((to_my_base_call && check_popup_window(call, 2) != -1)
+                    || check_popup_window(call, 0) != -1
+                    || check_popup_window(addr, 1) != -1) {
+//fprintf(stderr,"Matches my base call\n");
+                update_messages(1); // Force an update
+            }
+        }
+
+        /* Now if I have Igate on and I allow to retransmit station data           */
+        /* check if this message is to a person I have heard on my TNC within an X */
+        /* time frame. If if is a station I heard and all the conditions are ok    */
+        /* spit the message out on the TNC -FG                                     */
+        if (operate_as_an_igate>1
+                && last_ack_sent != (time_t)-1l
+                && from==DATA_VIA_NET
+//                && !is_my_call(call,1) // Check SSID also
+                && !from_my_call        // Check SSID also
+//                && !is_my_call(addr,1) // Check SSID also
+                && !to_my_call          // Check SSID also
+                && port != -1) {    // Not from a log file
+            char short_path[100];
+
+//fprintf(stderr,"Igate check o:%d f:%c myc:%s cf:%s ct:%s\n",
+//    operate_as_an_igate,
+//    from,
+//    my_callsign,
+//    call,
+//    addr);
+
+            shorten_path(path,short_path,sizeof(short_path));
+            xastir_snprintf(ipacket_message,
+                sizeof(ipacket_message),
+//                "}%s>%s,TCPIP,%s*::%s:%s{%s",
+                "}%s>%s,TCPIP,%s*::%s:%s",
+                call,
+                short_path,
+                my_callsign,
+                addr9,
+                message_plus_acks);
+//                message,
+//                orig_msg_id);
+
+if (reply_ack) { // For debugging, so we only have reply-ack
+                 // messages and acks scrolling across the screen.
+//    fprintf(stderr,"Attempting to send message to RF: %s\n", ipacket_message);
+}
+
+            output_igate_rf(call,
+                addr,
+                path,
+                ipacket_message,
+                port,
+                third_party,
+                NULL);
+
+            igate_msgs_tx++;
+        }
+        done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"7\n");
+    //--------------------------------------------------------------------------
+
+    if (!done) {                                   // message without line number
+        long record_out;
+        time_t last_ack_sent;
+
+
+        if (debug_level & 4)
+            fprintf(stderr,"found Msg: |%s| |%s|\n",addr,message);
+//found Msg: |WE7U-13| |?APRSD|
+//found Msg: |WE7U-14| |Directs=|
+
+
+        last_ack_sent = msg_data_add(addr,
+            call,
+            message,
+            "",
+            MESSAGE_MESSAGE,
+            from,
+            &record_out);
+
+        new_message_data++;      // ??????
+
+        // Note that the check_popup_window() function will
+        // re-create a Send Message dialog if one doesn't exist for
+        // this QSO.  Only call it for the first message line or the
+        // first ack, not for any repeats.
+        //
+        if (last_ack_sent == (time_t)0l && record_out == -1l) { // Msg we've never received before
+//fprintf(stderr,"***check_popup_window 3\n");
+            if (check_popup_window(addr, 1) != -1) {
+                //update_messages(1); // Force an update
+            }
+        }
+
+        // Could be response to a query.  Popup a messsage.
+
+// Check addr for my_call and !third_party, then check later in the
+// packet for my_call if it is a third_party message?  Depends on
+// what the packet looks like by this point.
+        if ( last_ack_sent != (time_t)-1l
+                && (message[0] != '?')
+//                && is_my_call(addr,1) ) { // Check SSID also
+                && to_my_call ) { // Check SSID also
+
+            // We no longer wish to have both popups and the Send
+            // Group Message dialogs come up for every query
+            // response, so we use popup_message() here instead of
+            // popup_message_always() so that by default we'll see
+            // the below message in STDERR.  If --with-errorpopups
+            // has been configured in, we'll get a popup as well.
+            // Send Group Message dialogs work well for multi-line
+            // query responses, so we'll leave it that way.
+            //
+            popup_message(langcode("POPEM00018"),message);
+
+            // Check for Reply/Ack.  APRS+ sends an AA: response back
+            // for auto-reply, with an embedded free-ride Ack.
+            if (strlen(ack_string) != 0) {  // Have an extra ack to deal with
+
+                clear_acked_message(call,addr,ack_string);  // got an ACK for me
+
+                msg_record_ack(call,addr,ack_string,0,0);   // Record the ack for this message
+            }
+        }
+ 
+        // done = 1;
+    }
+    if (debug_level & 1)
+        fprintf(stderr,"9\n");
+    //--------------------------------------------------------------------------
+
+    if (ok)
+        (void)data_add(STATION_CALL_DATA,
+            call,
+            path,
+            message,
+            from,
+            port,
+            NULL,
+            third_party,
+            0,  // Not a packet from my station
+            0); // Not my object/item
+
+    if (debug_level & 1)
+        fprintf(stderr,"decode_message: finish\n");
+
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  UI-View format messages, not relevant for APRS, format is not specified in APRS Reference
+ *
+ * This function is not currently called anywhere in the code.
+ */
+int decode_UI_message(char *call,char *path,char *message,char from,int port,int third_party) {
+    char *temp_ptr;
+    char from_call[MAX_CALLSIGN+1];
+    char ack[20];
+    char addr[9+1];
+    int ok, len;
+    char msg_id[5+1];
+    int done;
+    int from_my_call = 0;
+    int to_my_call = 0;
+
+
+    if (is_my_call(call, 1) ) { // Check SSID also
+        from_my_call++;
+    }
+ 
+    // I'm not sure, but I think they use 2 digit line numbers only
+    // extract addr from path
+    substr(addr,path,9);
+    ok = (int)(strlen(addr) > 0);
+    if (ok) {
+        temp_ptr = strstr(addr,",");         // look for end of first call
+        if (temp_ptr != NULL)
+            temp_ptr[0] = '\0';                 // adjust addr end
+        ok = (int)(strlen(addr) > 0);
+    }
+
+    if (is_my_call(addr, 1) ) { // Check SSID also
+        to_my_call++;
+    }
+
+    len = (int)strlen(message);
+    ok = (int)(len >= 2);
+    if (ok) {
+        temp_ptr = strstr(message,"~");         // look for message ID
+        msg_id[0] = '\0';
+        if (temp_ptr != NULL) {
+            substr(msg_id,temp_ptr+1,2);        // extract message ID, could be non-digit
+            temp_ptr[0] = '\0';                 // adjust message end
+        }
+        done = 0;
+    }
+    else
+        done = 1;                               // fall through...
+    len = (int)strlen(message);
+    //--------------------------------------------------------------------------
+    // Callsign check here checks SSID as well
+//    if (!done && msg_id[0] != '\0' && is_my_call(addr,1)) {      // message for me
+    if (!done && msg_id[0] != '\0' && to_my_call) {      // message for me
+        time_t last_ack_sent;
+        long record;
+
+        last_ack_sent = msg_data_add(addr,
+            call,
+            message,
+            msg_id,
+            MESSAGE_MESSAGE,
+            from,
+            &record);
+
+        new_message_data += 1;
+
+        // Note that the check_popup_window() function will
+        // re-create a Send Message dialog if one doesn't exist for
+        // this QSO.  Only call it for the first message line or the
+        // first ack, not for any repeats.
+        //
+        if (last_ack_sent == (time_t)0l && record == -1l) { // Msg we've never received before
+//fprintf(stderr,"***check_popup_window 4\n");
+            (void)check_popup_window(call, 2);
+            //update_messages(1); // Force an update
+        }
+
+        if (last_ack_sent != (time_t)-1l) {
+
+            if (sound_play_new_message)
+                play_sound(sound_command,sound_new_message);
+
+            // Only send an ack or autoresponse once per 30 seconds
+            if ( (from != 'F')
+                    && ( (last_ack_sent + 30) < sec_now()) ) {
+
+                //fprintf(stderr,"Sending ack: %ld %ld %ld\n",last_ack_sent,sec_now(),record);
+
+                // Record the fact that we're sending an ack now
+                msg_update_ack_stamp(record);
+
+                pad_callsign(from_call,call);         /* ack the message */
+                xastir_snprintf(ack, sizeof(ack), ":%s:ack%s",from_call,msg_id);
+
+// Nice to return via the reverse path here?  No!  Better to use the
+// default paths instead of a calculated reverse path.
+
+                transmit_message_data(call,ack,NULL);
+                if (auto_reply == 1) {
+                    char temp[300];
+    
+                    xastir_snprintf(temp, sizeof(temp), "AA:%s", auto_reply_message);
+    
+                    if (debug_level & 2)
+                        fprintf(stderr,"Send autoreply to <%s> from <%s> :%s\n",
+                            call, my_callsign, temp);
+    
+//                    if (!is_my_call(call,1)) // Check SSID also
+                    if (!from_my_call) // Check SSID also
+                        output_message(my_callsign, call, temp, "");
+                }
+            }
+        }
+        done = 1;
+    }
+    //--------------------------------------------------------------------------
+    if (!done && len == 2 && msg_id[0] == '\0') {                // ACK
+        substr(msg_id,message,5);
+//        if (is_my_call(addr,1)) { // Check SSID also
+        if (to_my_call) { // Check SSID also
+
+            clear_acked_message(call,addr,msg_id); // got an ACK for me
+
+            msg_record_ack(call,addr,msg_id,0,0);  // Record the ack for this message
+        }
+//        else {                                          // ACK for other station
+            /* Now if I have Igate on and I allow to retransmit station data           */
+            /* check if this message is to a person I have heard on my TNC within an X */
+            /* time frame. If if is a station I heard and all the conditions are ok    */
+            /* spit the ACK out on the TNC -FG                                         */
+////            if (operate_as_an_igate>1 && from==DATA_VIA_NET && !is_my_call(call,1)) {
+//            if (operate_as_an_igate>1 && from==DATA_VIA_NET && !from_my_call) {
+//                char short_path[100];
+                //fprintf(stderr,"Igate check o:%d f:%c myc:%s cf:%s ct:%s\n",operate_as_an_igate,from,my_callsign,call,addr); {
+
+//                shorten_path(path,short_path,sizeof(short_path));
+                //sprintf(ipacket_message,"}%s>%s:%s:%s",call,path,addr9,message);
+//                sprintf(ipacket_message,"}%s>%s,TCPIP,%s*::%s:%s",call,short_path,my_callsign,addr9,message);
+//                output_igate_rf(call,addr,path,ipacket_message,port,third_party,NULL);
+//                igate_msgs_tx++;
+//            }
+//        }
+        done = 1;
+    }
+    //--------------------------------------------------------------------------
+    if (ok) {
+        (void)data_add(STATION_CALL_DATA,
+            call,
+            path,
+            message,
+            from,
+            port,
+            NULL,
+            third_party,
+            0,  // Not a packet from my station
+            0); // Not my object/item
+    }
+
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Decode APRS Information Field and dispatch it depending on the Data Type ID
+ *
+ *         call = Callsign or object/item name string
+ *         path = Path string
+ *      message = Info field (corrupted already if object/item packet)
+ *       origin = Originating callsign if object/item, otherwise NULL
+ *         from = DATA_VIA_LOCAL/DATA_VIA_TNC/DATA_VIA_NET/DATA_VIA_FILE
+ *         port = Port number
+ *  third_party = Set to one if third-party packet
+ * orig_message = Unmodified info field
+ *
+ */
+void decode_info_field(char *call,
+                       char *path,
+                       char *message,
+                       char *origin,
+                       char from, int port,
+                       int third_party,
+                       char *orig_message) {
+
+    char line[MAX_LINE_SIZE+1];
+    int  ok_igate_net;
+    int  ok_igate_rf;
+    int  done, ignore;
+    char data_id;
+    int station_is_mine = 0;
+    int object_is_mine = 0;
+    char user_base_dir[MAX_VALUE];
+
+    /* remember fixed format starts with ! and can be up to 24 chars in the message */ // ???
+    if (debug_level & 1)
+        fprintf(stderr,"decode_info_field: c:%s p:%s m:%s f:%c o:%s\n",call,path,message,from,origin);
+    if (debug_level & 1)
+        fprintf(stderr,"decode_info_field: Past check\n");
+
+    done         = 0;       // if 1, packet was decoded
+    ignore       = 0;       // if 1, don't treat undecoded packets as status text
+    ok_igate_net = 0;       // if 1, send packet to internet
+    ok_igate_rf  = 0;       // if 1, igate packet to RF if "from" is in nws-stations.txt
+
+    if ( is_my_call(call, 1) ) {
+        station_is_mine++; // Station is controlled by me
+    }
+ 
+    if ( (message != NULL) && (strlen(message) > MAX_LINE_SIZE) ) { // Overly long message, throw it away.
+        if (debug_level & 1)
+            fprintf(stderr,"decode_info_field: Overly long message.  Throwing it away.\n");
+        done = 1;
+    }
+    else if (message == NULL || strlen(message) == 0) {      // we could have an empty message
+        (void)data_add(STATION_CALL_DATA,call,path,NULL,from,port,origin,third_party, station_is_mine, 0);
+        done = 1;                                       // don't report it to internet
+    }
+
+    // special treatment for objects/items.
+    if (!done && origin[0] != '\0') {
+
+        // If station/object/item is owned by me (including SSID)
+        if ( is_my_call(origin, 1) ) {
+            object_is_mine++;
+        }
+ 
+        if (message[0] == '*') {    // set object
+            (void)data_add(APRS_OBJECT,call,path,message+1,from,port,origin,third_party, station_is_mine, object_is_mine);
+            if (strlen(origin) > 0 && strncmp(origin,"INET",4)!=0) {
+                ok_igate_net = 1;   // report it to internet
+            }
+            ok_igate_rf = 1;
+            done = 1;
+        }
+
+        else if (message[0] == '!') {   // set item
+            (void)data_add(APRS_ITEM,call,path,message+1,from,port,origin,third_party, station_is_mine, object_is_mine);
+            if (strlen(origin) > 0 && strncmp(origin,"INET",4)!=0) {
+                ok_igate_net = 1;   // report it to internet
+            }
+            ok_igate_rf = 1;
+            done = 1;
+        }
+
+        else if (message[0] == '_') {   // delete object/item
+            DataRow *p_station;
+
+            delete_object(call);    // ?? does not vanish from map immediately !!???
+
+            // If object was owned by me but another station is
+            // transmitting it now, write entries into the
+            // object.log file showing that we don't own this object
+            // anymore.
+            p_station = NULL;
+            if (search_station_name(&p_station,call,1)) {
+//                if ( (is_my_call(p_station->origin,1))  // If station was owned by me (including SSID)
+//                        && (!is_my_call(origin,1)) ) {  // But isn't now
+                if (is_my_object_item(p_station)    // If station was owned by me (including SSID)
+                        && (!object_is_mine) ) {  // But isn't now
+                    disown_object_item(call,origin);
+                }
+            }
+            if (strlen(origin) > 0 && strncmp(origin,"INET",4)!=0) {
+                ok_igate_net = 1;   // report it to internet
+            }
+            ok_igate_rf = 1;
+            done = 1;
+        }
+    }
+
+    if (!done) {
+        int rdf_type;
+
+        data_id = message[0];           // look at the APRS Data Type ID (first char in information field)
+        message += 1;                   // extract data ID from information field
+        ok_igate_net = 1;               // as default report packet to internet
+
+        if (debug_level & 1) {
+            if (ok_igate_net)
+                fprintf(stderr,"decode_info_field: ok_igate_net can be read\n");
+        }
+
+        switch (data_id) {
+            case '=':   // Position without timestamp (with APRS messaging)
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: = (position w/o timestamp)\n");
+
+//WE7U
+// Need to check for weather info in this packet type as well?
+
+                done = data_add(APRS_MSGCAP,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '!':   // Position without timestamp (no APRS messaging) or Ultimeter 2000 WX
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: ! (position w/o timestamp or Ultimeter 2000 WX)\n");
+                if (message[0] == '!' && is_xnum_or_dash(message+1,40))   // Ultimeter 2000 WX
+                    done = data_add(APRS_WX3,call,path,message+1,from,port,origin,third_party, station_is_mine, 0);
+                else
+                    done = data_add(APRS_FIXED,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '/':   // Position with timestamp (no APRS messaging)
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: / (position w/timestamp)\n");
+
+//WE7U
+// Need weather decode in this section similar to the '@' section
+// below.
+
+                if ((toupper(message[14]) == 'N' || toupper(message[14]) == 'S') &&
+                    (toupper(message[24]) == 'W' || toupper(message[24]) == 'E')) { // uncompressed format
+                    if (debug_level & 1)
+                        fprintf(stderr,"decode_info_field: / (uncompressed position w/timestamp no messaging)\n");
+                    if (message[29] == '/') {
+                        if (message[33] == 'g' && message[37] == 't')
+                            done = data_add(APRS_WX1,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                        else
+                            done = data_add(APRS_MOBILE,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                    }
+                    else
+                        done = data_add(APRS_DF,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                }
+                else {                                                // compressed format
+                    if (debug_level & 1)
+                        fprintf(stderr,"decode_info_field: / (compressed position w/timestamp no messaging)\n");
+                    if (message[16] >= '!' && message[16] <= 'z') {     // csT is speed/course
+                        if (message[20] == 'g' && message[24] == 't')   // Wx data
+                            done = data_add(APRS_WX1,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                        else
+                            done = data_add(APRS_MOBILE,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                    }
+                    else
+                        done = data_add(APRS_DF,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                }
+//                done = data_add(APRS_DOWN,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '@':   // Position with timestamp (with APRS messaging)
+                // DK7IN: could we need to test the message length first?
+                if ((toupper(message[14]) == 'N' || toupper(message[14]) == 'S') &&
+                    (toupper(message[24]) == 'W' || toupper(message[24]) == 'E')) {       // uncompressed format
+                    if (debug_level & 1)
+                        fprintf(stderr,"decode_info_field: @ (uncompressed position w/timestamp)\n");
+                    if (message[29] == '/') {
+                        if (message[33] == 'g' && message[37] == 't')
+                            done = data_add(APRS_WX1,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                        else
+                            done = data_add(APRS_MOBILE,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                    }
+                    else
+                        done = data_add(APRS_DF,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                }
+                else {                                                // compressed format
+                    if (debug_level & 1)
+                        fprintf(stderr,"decode_info_field: @ (compressed position w/timestamp)\n");
+                    if (message[16] >= '!' && message[16] <= 'z') {     // csT is speed/course
+                        if (message[20] == 'g' && message[24] == 't')   // Wx data
+                            done = data_add(APRS_WX1,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                        else
+                            done = data_add(APRS_MOBILE,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                    }
+                    else
+                        done = data_add(APRS_DF,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                }
+                ok_igate_rf = done;
+                break;
+
+            case '[':   // Maidenhead grid locator beacon (obsolete- but used for meteor scatter)
+                done = data_add(APRS_GRID,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+            case 0x27:  // Mic-E  Old GPS data (or current GPS data in Kenwood TM-D700)
+            case 0x60:  // Mic-E  Current GPS data (but not used in Kennwood TM-D700)
+            //case 0x1c:// Mic-E  Current GPS data (Rev. 0 beta units only)
+            //case 0x1d:// Mic-E  Old GPS data (Rev. 0 beta units only)
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: 0x27 or 0x60 (Mic-E)\n");
+                done = decode_Mic_E(call,path,message,from,port,third_party);
+                ok_igate_rf = done;
+                break;
+
+            case '_':   // Positionless weather data                [APRS Reference, chapter 12]
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: _ (positionless wx data)\n");
+                done = data_add(APRS_WX2,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '#':   // Peet Bros U-II Weather Station (km/h)    [APRS Reference, chapter 12]
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: # (peet bros u-II wx station)\n");
+                if (is_xnum_or_dash(message,13))
+                    done = data_add(APRS_WX4,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '*':   // Peet Bros U-II Weather Station (mph)
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: * (peet bros u-II wx station)\n");
+                if (is_xnum_or_dash(message,13))
+                    done = data_add(APRS_WX6,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '$':   // Raw GPS data or Ultimeter 2000
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: $ (raw gps or ultimeter 2000)\n");
+                if (strncmp("ULTW",message,4) == 0 && is_xnum_or_dash(message+4,44))
+                    done = data_add(APRS_WX5,call,path,message+4,from,port,origin,third_party, station_is_mine, 0);
+                else if (strncmp("GPGGA",message,5) == 0)
+                    done = data_add(GPS_GGA,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                else if (strncmp("GPRMC",message,5) == 0)
+                    done = data_add(GPS_RMC,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                else if (strncmp("GPGLL",message,5) == 0)
+                    done = data_add(GPS_GLL,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                else {
+                        // handle VTG and WPT too  (APRS Ref p.25)
+                }
+                ok_igate_rf = done;
+                break;
+
+            case ':':   // Message
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: : (message)\n");
+
+                // Do message logging if that feature is enabled.
+                if (log_message_data && from != DATA_VIA_FILE) {
+                    char temp_msg[MAX_MESSAGE_LENGTH+1];
+
+                    xastir_snprintf(temp_msg,
+                        sizeof(temp_msg),
+                        "%s>%s:%s",
+                        call,
+                        path,
+                        orig_message);
+                    log_data( get_user_base_dir(LOGFILE_MESSAGE, user_base_dir, 
+                                                sizeof(user_base_dir)), 
+                              temp_msg );
+                }
+
+//fprintf(stderr,"Calling decode_message\n");
+                done = decode_message(call,path,message,from,port,third_party);
+//fprintf(stderr,"Back from decode_message\n");
+                // there could be messages I should not retransmit to internet... ??? Queries to me...
+                break;
+
+            case '>':   // Status                                   [APRS Reference, chapter 16]
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: > (status)\n");
+                done = data_add(APRS_STATUS,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                ok_igate_rf = done;
+                break;
+
+            case '?':   // Query
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: ? (query)\n");
+                done = process_query(call,path,message,from,port,third_party);
+                ignore = 1;     // don't treat undecoded packets as status text
+                break;
+
+            case 'T':   // Telemetry data                           [APRS Reference, chapter 13]
+                // We treat these as status packets currently.
+                ok_igate_rf = 1;
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: T (telem)\n");
+                 done = data_add(APRS_STATUS,call,path,message,from,port,origin,third_party, station_is_mine, 0);
+                break;
+ 
+            case '{':   // User-defined APRS packet format     //}
+                // We treat these as status packets currently.
+                ok_igate_rf = 1;
+                break;
+ 
+            case '<':   // Station capabilities                     [APRS Reference, chapter 15]
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: ~,<\n");
+                //
+                // We could tweak the Incoming Data dialog to add
+                // filter togglebuttons.  One such toggle could be
+                // "Station Capabilities".  We'd then have a usable
+                // dialog for displaying things like ?IGATE?
+                // responses.  In this case we wouldn't have to do
+                // anything special with the packet for decoding,
+                // just let it hit the default block below for
+                // putting them into the status field of the record.
+                // One downside is that we'd only be able to catch
+                // new station capability records in that dialog.
+                // The only way to look at past capability records
+                // would be the Station Info dialog for each
+                // station.
+                //
+                //fprintf(stderr,"%10s:  %s\n", call, message);
+
+                // Don't set "done" as we want these to appear in
+                // the status text for the record.
+                break;
+
+            case '%':   // Agrelo DFJr / MicroFinder Radio Direction Finding
+
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: %%\n");
+
+                // Here is where we'd add a call to an RDF decode
+                // function so that we could display vectors on the
+                // map for each RDF position.
+
+//
+// Agrelo format:  "%XXX/Q<cr>"
+//
+// "XXX" is relative bearing to the signal (000-359).  Careful here:
+// At least one unit reports in magnetic instead of relative
+// degrees.  "000" means no direction info available, 360 means true
+// north.
+//
+// "Q" is bearing quality (0-9).  0 = unsuitable.  9 = manually
+// entered.  1-8 = varying quality with 8 being the best.
+//
+// I've also seen these formats, which may not be Agrelo compatible:
+//
+//      "%136.0/9"
+//      "%136.0/8/158.0" (That last number is magnetic bearing)
+//
+// These sentences may be sent MULTIPLE times per second, like 20 or
+// more!  If we decide to average readings, we'll need to dump our
+// averages and start over if our course changes.
+//
+
+                // Check for Agrelo format:
+                if (    strlen(message) >= 5
+                        && is_num_chr(message[0])   // "%136/9"
+                        && is_num_chr(message[1])
+                        && is_num_chr(message[2])
+                        && message[3] == '/'
+                        && is_num_chr(message[4]) ) {
+
+                    rdf_type = 1;
+
+                    fprintf(stderr,
+                        "Type 1 RDF packet from call: %s\tBearing: %c%c%c\tQuality: %c\n",
+                        call,
+                        message[0],
+                        message[1],
+                        message[2],
+                        message[4]);
+ 
+                }
+
+                // Check for extended formats (not
+                // Agrelo-compatible):
+                else if (strlen(message) >= 13
+                        && is_num_chr(message[0])   // "%136.0/8/158.0"
+                        && is_num_chr(message[1])
+                        && is_num_chr(message[2])
+                        && message[3] == '.'
+                        && is_num_chr(message[4])
+                        && message[5] == '/'
+                        && is_num_chr(message[6])
+                        && message[7] == '/'
+                        && is_num_chr(message[8])
+                        && is_num_chr(message[9])
+                        && is_num_chr(message[10])
+                        && message[11] == '.'
+                        && is_num_chr(message[12]) ) {
+
+                    rdf_type = 3;
+
+                    fprintf(stderr,
+                        "Type 3 RDF packet from call: %s\tBearing: %c%c%c%c%c\tQuality: %c\tMag Bearing: %c%c%c%c%c\n",
+                        call,
+                        message[0],
+                        message[1],
+                        message[2],
+                        message[3],
+                        message[4],
+                        message[6],
+                        message[8],
+                        message[9],
+                        message[10],
+                        message[11],
+                        message[12]);
+                }
+
+                // Check for extended formats (not
+                // Agrelo-compatible):
+                else if (strlen(message) >= 7
+                        && is_num_chr(message[0])   // "%136.0/9"
+                        && is_num_chr(message[1])
+                        && is_num_chr(message[2])
+                        && message[3] == '.'
+                        && is_num_chr(message[4])
+                        && message[5] == '/'
+                        && is_num_chr(message[6]) ) {
+
+                    rdf_type = 2;
+
+                    fprintf(stderr,
+                        "Type 2 RDF packet from call: %s\tBearing: %c%c%c%c%c\tQuality: %c\n",
+                        call,
+                        message[0],
+                        message[1],
+                        message[2],
+                        message[3],
+                        message[4],
+                        message[6]);
+                }
+
+                // Don't set "done" as we want these to appear in
+                // the status text for the record until we get the
+                // full decoding for this type of packet coded up.
+                break;
+ 
+            case '~':   // UI-format messages, not relevant for APRS ("Do not use" in Reference)
+            case ',':   // Invalid data or test packets             [APRS Reference, chapter 19]
+            case '&':   // Reserved -- Map Feature
+                if (debug_level & 1)
+                    fprintf(stderr,"decode_info_field: ~,&\n");
+                ignore = 1;     // Don't treat undecoded packets as status text
+                break;
+        }
+
+        if (debug_level & 1) {
+            if (done)
+                fprintf(stderr,"decode_info_field: done = 1\n");
+            else
+                fprintf(stderr,"decode_info_field: done = 0\n");
+            if (ok_igate_net)
+                fprintf(stderr,"decode_info_field: ok_igate_net can be read 2\n");
+        }
+
+        if (debug_level & 1)
+            fprintf(stderr,"decode_info_field: done with big switch\n");
+
+        // Add most remaining data to the station record as status
+        // info
+        //
+        if (!done && !ignore) {         // Other Packets        [APRS Reference, chapter 19]
+            done = data_add(OTHER_DATA,call,path,message-1,from,port,origin,third_party, station_is_mine, 0);
+            ok_igate_net = 0;           // don't put data on internet       ????
+            if (debug_level & 1)
+                fprintf(stderr,"decode_info_field: done with data_add(OTHER_DATA)\n");
+        }
+
+        if (!done) {                    // data that we do ignore...
+            //fprintf(stderr,"decode_info_field: not decoding info: Call:%s ID:%c Msg:|%s|\n",call,data_id,message);
+            ok_igate_net = 0;           // don't put data on internet
+            if (debug_level & 1)
+                fprintf(stderr,"decode_info_field: done with ignored data\n");
+        }
+    }
+
+    if (third_party)
+        ok_igate_net = 0;   // don't put third party traffic on internet
+
+//    if (is_my_call(call,1)) // Check SSID as well
+    if (station_is_mine)
+        ok_igate_net = 0;   // don't put my data on internet     ???
+
+    if (ok_igate_net) {
+
+        if (debug_level & 1)
+            fprintf(stderr,"decode_info_field: ok_igate_net start\n");
+
+        if ( (from == DATA_VIA_TNC) // Came in via a TNC
+                && (strlen(orig_message) > 0) ) { // Not empty
+
+            // Here's where we inject our own callsign like this:
+            // "WE7U-15,I" in order to provide injection ID for our
+            // igate.
+            xastir_snprintf(line,
+                sizeof(line),
+                "%s>%s,%s,I:%s",
+                (strlen(origin)) ? origin : call,
+                path,
+                my_callsign,
+                orig_message);
+
+//fprintf(stderr,"decode_info_field: IGATE>NET %s\n",line);
+            output_igate_net(line, port, third_party);
+        }
+    }
+
+    // Attempt to gate to RF only if the following conditions are
+    // met:
+    //
+    //   *) ok_igate_rf flag is set.
+    //   *) Not my exact callsign.
+    //   *) Packet was from the INET, not local RF
+    //   *) The "from" call matches a line in data/nws-stations.txt,
+    //      verified by igate.c:check_NWS_stations().
+    //
+    // The output_igate_rf() function will also do some checks on
+    // the packet before allowing it to be igated, including a
+    // dupe-check.
+    //
+    // Callsign check here checks SSID as well
+//    if (ok_igate_rf && !is_my_call(call,1) && from == DATA_VIA_NET) {
+    if (ok_igate_rf
+            && !station_is_mine
+            && from == DATA_VIA_NET) {
+
+        char ipacket_message[300];
+        char short_path[100];
+
+        shorten_path(path,short_path,sizeof(short_path));
+
+        xastir_snprintf(ipacket_message,
+            sizeof(ipacket_message),
+            "}%s>%s,TCPIP,%s*:%s",
+            (strlen(origin)) ? origin : call,
+            short_path,
+            my_callsign,
+            orig_message);
+
+        // If origin, pass "call" to output_igate_rf() as the last
+        // parameter.  This would be the object/item name.
+        output_igate_rf((strlen(origin)) ? origin : call,
+            (strlen(origin)) ? origin : call,
+            path,
+            ipacket_message,
+            port,
+            third_party,
+            (strlen(origin)) ? call : NULL);
+
+//fprintf(stderr,"decode_info_field: IGATE>RF %s\n",ipacket_message);
+    }
+
+    if (debug_level & 1)
+        fprintf(stderr,"decode_info_field: done\n");
+}
+
+
+
+
+
+/*
+ *  Extract object or item data from information field before processing
+ *
+ *  Returns 1 if valid object found, else returns 0.
+ *
+ */
+int extract_object(char *call, char **info, char *origin) {
+    int ok, i;
+
+    // Object and Item Reports     [APRS Reference, chapter 11]
+    ok = 0;
+    // todo: add station originator to database
+    if ((*info)[0] == ';') {                    // object
+        // fixed 9 character object name with any printable ASCII character
+        if (strlen((*info)) > 1+9) {
+            substr(call,(*info)+1,9);           // extract object name
+            (*info) = (*info) + 10;
+            // Remove leading spaces ? They look bad, but are allowed by the APRS Reference ???
+            (void)remove_trailing_spaces(call);
+            if (valid_object(call)) {
+                // info length is at least 1
+                ok = 1;
+            }
+        }
+    }
+    else if ((*info)[0] == ')') {             // item
+        // 3 - 9 character item name with any printable ASCII character
+        if (strlen((*info)) > 1+3) {
+            for (i = 1; i <= 9; i++) {
+                if ((*info)[i] == '!' || (*info)[i] == '_') {
+                    call[i-1] = '\0';
+                    break;
+                }
+                call[i-1] = (*info)[i];
+            }
+            call[9] = '\0';  // In case we never saw '!' || '_'
+            (*info) = &(*info)[i];
+            // Remove leading spaces ? They look bad, but are allowed by the APRS Reference ???
+            //(void)remove_trailing_spaces(call);   // This statement messed up our searching!!! Don't use it!
+            if (valid_object(call)) {
+                // info length is at least 1
+                ok = 1;
+            }
+        }
+    }
+    else {
+        fprintf(stderr,"Not an object, nor an item!!! call=%s, info=%s, origin=%s.\n",
+               call, *info, origin);
+    }
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Extract third-party traffic from information field before processing
+ */
+int extract_third_party(char *call,
+                        char *path,
+                        int path_size,
+                        char **info,
+                        char *origin,
+                        int origin_size) {
+    int ok;
+    char *p_call;
+    char *p_path;
+
+    p_call = NULL;                              // to make the compiler happy...
+    p_path = NULL;                              // to make the compiler happy...
+    ok = 0;
+    if (!is_my_call(call,1)) { // Check SSID also
+        // todo: add reporting station call to database ??
+        //       but only if not identical to reported call
+        (*info) = (*info) +1;                   // strip '}' character
+        p_call = strtok((*info),">");           // extract call
+        if (p_call != NULL) {
+            p_path = strtok(NULL,":");          // extract path
+            if (p_path != NULL) {
+                (*info) = strtok(NULL,"");      // rest is information field
+                if ((*info) != NULL)            // the above looks dangerous, but works on same string
+                    if (strlen(p_path) < 100)
+                        ok = 1;                 // we have found all three components
+            }
+        }
+    }
+
+    if ((debug_level & 1) && !ok)
+        fprintf(stderr,"extract_third_party: invalid format from %s\n",call);
+
+    if (ok) {
+
+        xastir_snprintf(path,
+            path_size,
+            "%s",
+            p_path);
+
+        ok = valid_path(path);                  // check the path and convert it to TAPR format
+        // Note that valid_path() also removes igate injection identifiers
+
+        if ((debug_level & 1) && !ok) {
+            char filtered_data[MAX_LINE_SIZE + 1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                path);
+            makePrintable(filtered_data);
+            fprintf(stderr,"extract_third_party: invalid path: %s\n",filtered_data);
+        }
+    }
+
+    if (ok) {                                         // check callsign
+        (void)remove_trailing_asterisk(p_call);       // is an asterisk valid here ???
+        if (valid_inet_name(p_call,(*info),origin,origin_size)) { // accept some of the names used in internet
+            // Treat it as object with special origin
+            xastir_snprintf(call,
+                MAX_CALLSIGN+1,
+                "%s",
+                p_call);
+        }
+        else if (valid_call(p_call)) {              // accept real AX.25 calls
+            xastir_snprintf(call,
+                MAX_CALLSIGN+1,
+                "%s",
+                p_call);
+        }
+        else {
+            ok = 0;
+            if (debug_level & 1) {
+                char filtered_data[MAX_LINE_SIZE + 1];
+
+                xastir_snprintf(filtered_data,
+                    sizeof(filtered_data),
+                    "%s",
+                    p_call);
+                makePrintable(filtered_data);
+                fprintf(stderr,"extract_third_party: invalid call: %s\n",filtered_data);
+            }
+        }
+    }
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Extract text inserted by TNC X-1J4 from start of info line
+ */
+void extract_TNC_text(char *info) {
+    int i,j,len;
+
+    if (strncasecmp(info,"thenet ",7) == 0) {   // 1st match
+        len = strlen(info)-1;
+        for (i=7;i<len;i++) {
+            if (info[i] == ')')
+                break;
+        }
+        len++;
+        if (i>7 && info[i] == ')' && info[i+1] == ' ') {        // found
+            i += 2;
+            for (j=0;i<=len;i++,j++) {
+                info[j] = info[i];
+            }
+        }
+    }
+}
+
+
+
+
+
+//WE7U2
+// We feed a raw 7-byte string into this routine.  It decodes the
+// callsign-SSID and tells us whether there are more callsigns after
+// this.  If the "asterisk" input parameter is nonzero it'll add an
+// asterisk to the callsign if it has been digipeated.  This
+// function is called by the decode_ax25_header() function.
+//
+// Inputs:  string          Raw input string
+//          asterisk        1 = add "digipeated" asterisk
+//
+// Outputs: callsign        Processed string
+//          returned int    1=more callsigns follow, 0=end of address field
+//
+int decode_ax25_address(char *string, char *callsign, int asterisk) {
+    int i,j;
+    char ssid;
+    char t;
+    int more = 0;
+    int digipeated = 0;
+
+    // Shift each of the six callsign characters right one bit to
+    // convert to ASCII.  We also get rid of the extra spaces here.
+    j = 0;
+    for (i = 0; i < 6; i++) {
+        t = ((unsigned char)string[i] >> 1) & 0x7f;
+        if (t != ' ') {
+            callsign[j++] = t;
+        }
+    }
+
+    // Snag out the SSID byte to play with.  We need more than just
+    // the 4 SSID bits out of it.
+    ssid = (unsigned char)string[6];
+
+    // Check the digipeat bit
+    if ( (ssid & 0x80) && asterisk)
+        digipeated++;   // Has been digipeated
+
+    // Check whether it is the end of the address field
+    if ( !(ssid & 0x01) )
+        more++; // More callsigns to come after this one
+
+    // Snag the four SSID bits
+    ssid = (ssid >> 1) & 0x0f;
+
+    // Construct the SSID number and add it to the end of the
+    // callsign if non-zero.  If it's zero we don't add it.
+    if (ssid) {
+        callsign[j++] = '-';
+        if (ssid > 9) {
+            callsign[j++] = '1';
+        }
+        ssid = ssid % 10;
+        callsign[j++] = '0' + ssid;
+    }
+
+    // Add an asterisk if the packet has been digipeated through
+    // this callsign
+    if (digipeated)
+        callsign[j++] = '*';
+
+    // Terminate the string
+    callsign[j] = '\0';
+
+    return(more);
+}
+
+
+
+
+
+// Function which receives raw AX.25 packets from a KISS interface and
+// converts them to a printable TAPR-2 (more or less) style string.
+// We receive the packet with a KISS Frame End character at the
+// beginning and a "\0" character at the end.  We can end up with
+// multiple asterisks, one for each callsign that the packet was
+// digipeated through.  A few other TNC's put out this same sort of
+// format.
+//
+// Note about KISS & CRC's:  The TNC checks the CRC.  If bad, it
+// drops the packet.  If good, it sends it to the computer WITHOUT
+// the CRC bytes.  There's no way at the computer end to check
+// whether the packet was corrupted over the serial channel between
+// the TNC and the computer.  Upon sending a KISS packet to the TNC,
+// the TNC itself adds the CRC bytes back on before sending it over
+// the air.  In Xastir we can just assume that we're getting
+// error-free packets from the TNC, ignoring possible corruption
+// over the serial line.
+//
+// Some versions of KISS can encode the radio channel (for
+// multi-port TNC's) in the command byte.  How do we know we're
+// running those versions of KISS though?  Here are the KISS
+// variants that I've been able to discover to date:
+//
+// KISS               No CRC, one radio port
+//
+// SMACK              16-bit CRC, multiport TNC's
+//
+// KISS-CRC
+//
+// 6-PACK
+//
+// KISS Multi-drop (Kantronics) 8-bit XOR Checksum, multiport TNC's (AGWPE compatible)
+// BPQKISS (Multi-drop)         8-bit XOR Checksum, multiport TNC's
+// XKISS (Kantronics)           8-bit XOR Checksum, multiport TNC's
+//
+// JKISS              (AGWPE and BPQ32 compatible)
+//
+// MKISS              Linux driver which supports KISS/BPQ and
+//                    hardware handshaking?  Also Paccomm command to
+//                    immediately enter KISS mode.
+//
+// FlexKISS           -,
+// FlexCRC            -|-- These are all the same!
+// RMNC-KISS          -|
+// CRC-RMNC           -'
+//
+//
+// It appears that none of the above protocols implement any form of
+// hardware flow control.
+// 
+// 
+// Compare this function with interface.c:process_ax25_packet() to
+// see if we're missing anything important.
+//
+//
+// Inputs:  data_string         Raw string (must be MAX_LINE_SIZE or bigger)
+//          length              Length of raw string (may get changed here)
+//
+// Outputs: int                 0 if it is a bad packet,
+//                              1 if it is good
+//          data_string         Processed string
+//
+int decode_ax25_header(unsigned char *data_string, int *length) {
+    char temp[20];
+    char result[MAX_LINE_SIZE+100];
+    char dest[15];
+    int i, ptr;
+    char callsign[15];
+    char more;
+    char num_digis = 0;
+
+
+    // Do we have a string at all?
+    if (data_string == NULL)
+        return(0);
+
+    // Drop the packet if it is too long.  Note that for KISS packets
+    // we can't use strlen() as there can be 0x00 bytes in the
+    // data itself.
+    if (*length > 1024) {
+        data_string[0] = '\0';
+        *length = 0;
+        return(0);
+    }
+
+    // Start with an empty string for the result
+    result[0] = '\0';
+
+    ptr = 0;
+
+    // Process the destination address
+    for (i = 0; i < 7; i++)
+        temp[i] = data_string[ptr++];
+    temp[7] = '\0';
+    more = decode_ax25_address(temp, callsign, 0); // No asterisk
+    xastir_snprintf(dest,sizeof(dest),"%s",callsign);
+
+    // Process the source address
+    for (i = 0; i < 7; i++)
+        temp[i] = data_string[ptr++];
+    temp[7] = '\0';
+    more = decode_ax25_address(temp, callsign, 0); // No asterisk
+
+    // Store the two callsigns we have into "result" in the correct
+    // order
+    xastir_snprintf(result,sizeof(result),"%s>%s",callsign,dest);
+
+    // Process the digipeater addresses (if any)
+    num_digis = 0;
+    while (more && num_digis < 8) {
+        for (i = 0; i < 7; i++)
+            temp[i] = data_string[ptr++];
+        temp[7] = '\0';
+
+        more = decode_ax25_address(temp, callsign, 1); // Add asterisk
+        strncat(result,
+            ",",
+            sizeof(result) - 1 - strlen(result));
+        strncat(result,
+            callsign,
+            sizeof(result) - 1 - strlen(result));
+        num_digis++;
+    }
+
+    strncat(result,
+        ":",
+        sizeof(result) - 1 - strlen(result));
+
+
+    // Check the Control and PID bytes and toss packets that are
+    // AX.25 connect/disconnect or information packets.  We only
+    // want to process UI packets in Xastir.
+
+
+    // Control byte should be 0x03 (UI Frame).  Strip the poll-bit
+    // from the PID byte before doing the comparison.
+    if ( (data_string[ptr++] & (~0x10)) != 0x03) {
+        return(0);
+    }
+
+
+    // PID byte should be 0xf0 (normal AX.25 text)
+    if (data_string[ptr++] != 0xf0)
+        return(0);
+
+
+// WE7U:  We get multiple concatenated KISS packets sometimes.  Look
+// for that here and flag when it happens (so we know about it and
+// can fix it someplace earlier in the process).  Correct the
+// current packet so we don't get the extra garbage tacked onto the
+// end.
+    for (i = ptr; i < *length; i++) {
+        if (data_string[i] == KISS_FEND) {
+            fprintf(stderr,"***Found concatenated KISS packets:***\n");
+            data_string[i] = '\0';    // Truncate the string
+            break;
+        }
+    }
+
+    // Add the Info field to the decoded header info
+    strncat(result,
+        (char *)(&data_string[ptr]),
+        sizeof(result) - 1 - strlen(result));
+
+    // Copy the result onto the top of the input data.  Note that
+    // the length can sometimes be longer than the input string, so
+    // we can't just use the "length" variable here or we'll
+    // truncate our string.  Make sure the data_string variable is
+    // MAX_LINE_SIZE or bigger.
+    //
+    xastir_snprintf((char *)data_string,
+        MAX_LINE_SIZE,
+        "%s",
+        result);
+
+    // Write out the new length
+    *length = strlen(result); 
+
+//fprintf(stderr,"%s\n",data_string);
+
+    return(1);
+}
+
+
+
+
+
+// RELAY the packet back out onto RF if received on a port with
+// digipeat enabled and the packet header has a non-digipeated RELAY
+// or my_callsign entry.  This is for AX.25 kernel networking ports
+// or Serial KISS TNC ports only:  Regular serial TNC's have these
+// features enabled/disabled through the startup/shutdown files.
+//
+// Adding asterisks:
+// Keep whatever digipeated fields have already been set.  If
+// there's a "RELAY", "WIDE1-1", or "my_callsign" entry that hasn't
+// been digipeated yet, change it to "my_callsign*".
+//
+// This might be much easier to code into the routine that first
+// receives the packet (for Serial KISS TNC's).  There we'd have
+// access to every digipeated bit directly instead of parsing
+// asterisks out of a string.
+//
+// NOTE:  We don't handle this case properly:  Multiple
+// RELAY's/WIDE1-1's or my_callsign's in the path, where one of the
+// earlier matching callsigns has been digipeated, but a later one
+// has not.  We'll find the first matching callsign and the last
+// digi, and we won't relay the packet.  This probably won't happen
+// much in the real world.
+//
+// We could also do premptive digipeating here and skip over
+// callsigns that haven't been digipeated yet.  Should we set the
+// digipeated bits on everything before it?  Probably.  Either that
+// or remove the callsigns ahead of it in the list that weren't
+// digipeated.
+//
+void relay_digipeat(char *call, char *path, char *info, int port) {
+    char new_path[110+1];
+    char new_digi[MAX_CALLSIGN+2];  // Need extra for '*' storage
+    int  ii, jj;
+    int  done;
+    char destination[MAX_CALLSIGN+1];
+
+#define MAX_RELAY_SUBSTRINGS 10
+    char *Substring[MAX_RELAY_SUBSTRINGS];  // Pointers to substrings parsed by split_string()
+
+    // Pointers to all of the possible calls we with to digipeat by
+    char *Relay_Calls[MAX_RELAY_DIGIPEATER_CALLS];
+
+    char temp_string[MAX_LINE_SIZE+1];
+
+    // These strings are debugging tools
+    char small_string[200];
+    char big_string[2000];
+
+
+    // Check whether transmits are disabled globally
+    if (transmit_disable) {
+        return;
+    }
+
+    // Check whether relay_digipeat has been enabled for this interface.
+    // If not, get out while the gettin's good.
+    if (devices[port].relay_digipeat != 1) {
+        return;
+    }
+
+    // Check whether transmit has been enabled for this interface.
+    // If not, get out while the gettin's good.
+    if (devices[port].transmit_data != 1) {
+        return;
+    }
+
+    // Check for the only four types of interfaces where we might
+    // want to do RELAY digipeating.  If not one of these, go
+    // bye-bye.
+    if (       (devices[port].device_type != DEVICE_SERIAL_KISS_TNC)
+            && (devices[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+            && (devices[port].device_type != DEVICE_AX25_TNC)
+            && (devices[port].device_type != DEVICE_NET_AGWPE) ) {
+        return;
+    }
+
+
+sprintf(big_string,"\nrelay_digipeat: inputs:\n\tport: %d\n\tcall: %s\n\tpath: %s\n\tinfo: %s\n",
+    port, call, path, info);
+
+
+    // Check to see if this is my own transmitted packet (in some
+    // cases you get your own packets back from interfaces)
+    if (!strcasecmp(call, my_callsign)) {
+        //fprintf(stderr,"relay_digipeat: packet was mine, don't digipeat it!\n");
+        return;
+    }
+
+
+    // Make a copy of the incoming path.  The string passed to
+    // split_string() gets destroyed.
+    xastir_snprintf(temp_string,
+        sizeof(temp_string),
+        "%s",
+        path);
+    split_string(temp_string, Substring, MAX_RELAY_SUBSTRINGS, ',');
+    // Each element in the path is now pointed to by a char ptr in
+    // the Substring array.  If a NULL is found in the array, that's
+    // the end of the path.
+
+
+    if (Substring[0] == NULL) {
+        // Something's wrong!  Couldn't find anything in the path
+        // string, not even a destination callsign?
+//fprintf(stderr, "\t\tNo path: %s\n", path);
+        return;
+    }
+    else {  // Save the destination callsign away
+        xastir_snprintf(destination,
+            sizeof(destination),
+            "%s",
+            Substring[0]);
+        //fprintf(stderr,"Destination: %s\n",destination);
+    }
+    // We'll skip the first call in the path (pointed to by
+    // Substring[0]) in the loops below.  That's the destination
+    // call and we don't want to look for RELAY or my_callsign
+    // there.
+
+
+    // Check to see if we just ran out of path
+    if (Substring[1] == NULL) { // No digipeaters listed
+        //fprintf(stderr,"relay_digipeat: ran out of path, don't digipeat it!\n");
+//fprintf(stderr, "\t\tNo digi's listed: %s\n", path);
+        return;
+    }
+
+
+    //fprintf(stderr,"      Path: %s\n",path);
+    // We could also loop through the array and dump them out until
+    // we hit a NULL if necessary.
+
+
+    // Find the first digipeater callsign _after_ any digis that
+    // have asterisks.  Run through the array in reverse, looking
+    // for the digi callsign with an asterisk after it that's
+    // closest to the end of the path.
+    ii = MAX_RELAY_SUBSTRINGS - 1;
+    done = 0;
+    while (!done && ii > 0) {
+
+        if (Substring[ii] != NULL) {
+
+            if (strstr(Substring[ii],"*")) {
+                ii++;   // Found an asterisk:  Used digi.  Point to
+                        // the digi _after_ this one.
+                done++; // We found what we're looking for!
+            }
+            else {  // No asterisk found yet.
+                ii--;
+            }
+        }
+        else {  // No filled-in digipeater field found yet.
+            ii--;
+        }
+    }
+
+
+    if (ii == 0) {  // No asterisks found.  Entire path unused?
+        // Set ii to first actual digi field instead of the
+        // destination callsign.
+        ii = 1;
+    }
+    else {  // ii points to first unused digi field.
+    }
+
+
+    if (Substring[ii] == NULL) {    // No unused digi's found.
+                                    // We're done here.
+//fprintf(stderr, "\t\tPath used up: %s\n", path);
+        return;
+    }
+
+ 
+//fprintf(stderr,"\t\tUnused digi: %s\tPath: %s\n", Substring[ii], path);
+
+
+    // Split the relay digipeater calls into separate substrings.
+    // Split on comma delimiters.  We get rid of extra spaces at the
+    // point where we read the string in from the config file
+    // (xa_config.c), so spaces between the calls are ok (but not
+    // tabs).
+    split_string(relay_digipeater_calls, Relay_Calls, MAX_RELAY_DIGIPEATER_CALLS, ',');
+
+    // Check for match against my_callsign in this digipeater slot
+    done = 0;
+    if (strcmp(Substring[ii], my_callsign) == 0) {
+        // It's our callsign.  Digipeat using this call slot.
+        done++;
+    }
+    else {  // Not my_callsign.  Check every non-empty string in
+            // Relay_Calls[] for a match.
+
+        jj = 0;
+        while (!done && jj < MAX_RELAY_DIGIPEATER_CALLS) {
+
+            // Check for ending conditions
+            if (Relay_Calls[jj] == NULL || Relay_Calls[jj][0] == '\0') {
+                // We hit the end of the array of possible
+                // digipeater calls and had no match.  Exit from
+                // this routine as we're not going to digipeat on
+                // this callsign slot.
+
+// Later we could add the option of "preemptive digipeating", where
+// we look further down the path for a possible match.  We're not
+// doing that now.
+
+//                fprintf(stderr,"End of Relay_Calls array: %d\n",jj);
+                return;
+            }
+
+            // If we made it to here, we should have a valid
+            // digipeater callsign in the Relay_Calls[jj] slot to
+            // compare against.
+
+            if (debug_level & 1) {
+                fprintf(stderr,"\tComparing %s to %s\n",
+                    Substring[ii],
+                    Relay_Calls[jj]);
+            }
+
+            if (strcmp(Substring[ii], Relay_Calls[jj]) == 0) {
+                done++;
+//                fprintf(stderr,"match, done++\n");
+            }
+            else {
+                jj++;
+//                fprintf(stderr,"incrementing jj: %d\n", jj);
+            }
+        }
+    }
+    if (!done) {
+        // No valid digipeating callsign found in this slot, exit
+        // this routine as we're not going to digipeat this packet.
+        return;
+    }
+
+
+/*
+OLD CODE:
+    // Check for RELAY, WIDE1-1 (the new relay) or my_callsign in
+    // this digipeater slot.  If none of these found then exit this
+    // routine.
+    if (       (strcmp(Substring[ii], "RELAY")     != 0)
+            && (strcmp(Substring[ii], "WIDE1-1")   != 0)
+            && (strcmp(Substring[ii], my_callsign) != 0) ) {
+        // Some other callsign found in this digi field.  Don't
+        // relay the packet.
+//fprintf(stderr,"Not relay, wide1-1, or %s, skipping\n", my_callsign);
+        return;
+    }
+*/
+
+
+    // Ok, we made it!  We have RELAY, WIDE1-1, or my_callsign that
+    // hasn't been digipeated through, and we wish to change that
+    // fact.  Put in our callsign for all three cases and add an
+    // asterisk to the end of the call.  Also had to fix up the KISS
+    // transmit routine so that it'll set the digipeated bit for
+    // each callsign that has an asterisk.
+
+    // Contruct the new digi call, with the trailing asterisk
+    xastir_snprintf(new_digi,
+        sizeof(new_digi),
+        "%s*",
+        my_callsign);
+    Substring[ii] = new_digi; // Point to new digi string instead of old
+    //fprintf(stderr,"*** new_digi: %s\tSubstring: %s\n",
+    //    new_digi,
+    //    Substring[ii]);
+
+    // Construct the new path, substituting the correct portion.
+    // Start with the first digi and a comma:
+    xastir_snprintf(new_path,
+        sizeof(new_path),
+        "%s,",
+        Substring[1]);
+    
+    ii = 2;
+    while ( (Substring[ii] != NULL)
+            && (ii < MAX_RELAY_SUBSTRINGS) ) {
+        strncat(new_path,
+            Substring[ii],
+            sizeof(new_path) - 1 - strlen(new_path));
+        ii++;
+        if (Substring[ii] != NULL)  // Add a comma if more to come
+            strncat(new_path,
+                ",",
+                sizeof(new_path) - 1 - strlen(new_path));
+    }
+
+//fprintf(stderr,"*** New Path: %s,%s\n", destination, new_path);
+
+
+    if (       (devices[port].device_type == DEVICE_SERIAL_KISS_TNC)
+            || (devices[port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+
+#ifdef SERIAL_KISS_RELAY_DIGI
+//        fprintf(stderr,"KISS RELAY short_path: %s\n", short_path);
+//        fprintf(stderr,"KISS RELAY   new_path: %s\n", new_path);
+        send_ax25_frame(port, call, destination, new_path, info);
+#endif
+
+    }
+    else if (devices[port].device_type == DEVICE_AX25_TNC) {
+        char header_txt[MAX_LINE_SIZE+5];
+
+        //fprintf(stderr,"AX25 RELAY   new_path: %s\n", new_path);
+
+        // set from call
+        xastir_snprintf(header_txt, sizeof(header_txt), "%c%s %s\r", '\3', "MYCALL", call);
+        if (port_data[port].status == DEVICE_UP)
+            port_write_string(port, header_txt);
+        // set path
+        xastir_snprintf(header_txt, sizeof(header_txt), "%c%s %s VIA %s\r", '\3', "UNPROTO",
+            destination, new_path);
+        if (port_data[port].status == DEVICE_UP)
+            port_write_string(port, header_txt);
+        // set converse mode
+        xastir_snprintf(header_txt, sizeof(header_txt), "%c%s\r", '\3', "CONV");
+        if (port_data[port].status == DEVICE_UP)
+            port_write_string(port, header_txt);
+        // send packet
+        if (port_data[port].status == DEVICE_UP)
+            port_write_string(port, info);
+    }
+    else if (devices[port].device_type == DEVICE_NET_AGWPE) {
+        send_agwpe_packet(port, // Xastir interface port
+            atoi(devices[port].device_host_filter_string), // AGWPE RadioPort
+            '\0',                         // Type of frame (data)
+            (unsigned char *)call,        // source
+            (unsigned char *)destination, // destination
+            (unsigned char *)new_path,    // Path,
+            (unsigned char *)info,
+            strlen(info));
+    }
+
+
+//WE7U
+sprintf(small_string,"relay_digipeat: outputs:\n\tport: %d\n\tcall: %s\n\tdest: %s\n\tpath: %s\n\tinfo: %s\n",
+    port, call, destination, new_path, info);
+strncat(big_string,
+    small_string,
+    sizeof(big_string) - 1 - strlen(big_string));
+//fprintf(stderr,"%s",big_string);
+
+
+// Example packet:
+//K7FZO>APW251,SEATAC*,WIDE4-1:=4728.00N/12140.83W;PHG3030/Middle Fork Snoqualmie River -251-<630>
+
+}
+
+
+
+
+
+/*
+ *  Decode AX.25 line
+ *  \r and \n should already be stripped from end of line
+ *  line should not be NULL
+ *
+ * If dbadd is set, add to database.  Otherwise, just return true/false
+ * to indicate whether input is valid AX25 line.
+ */
+//
+// Note that the length of "line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+int decode_ax25_line(char *line, char from, int port, int dbadd) {
+    char *call_sign;
+    char *path0;
+    char path[100+1];           // new one, we may add an '*'
+    char *info;
+    char info_copy[MAX_LINE_SIZE+1];
+    char call[MAX_CALLSIGN+1];
+    char origin[MAX_CALLSIGN+1];
+    int ok;
+    int third_party;
+    char backup[MAX_LINE_SIZE+1];
+    char tmp_line[MAX_LINE_SIZE+1];
+    char tmp_path[100+1];
+    char *ViaCalls[10];
+
+
+    // Check guard band around pointers.  Make sure it's pristine.
+    if ( check_guard_band() ) {
+        fprintf(stderr, "WARNING:  Guard band around global pointers was corrupted!\n");
+    }
+
+    xastir_snprintf(backup,
+        sizeof(backup),
+        "%s",
+        line);
+
+// This is a good one to enable for debugging without getting too
+// many other types of messages to the xterm.  It will enable the
+// block below.
+//#define WE7U_DEBUG
+
+#ifndef WE7U_DEBUG
+    if (debug_level & 1)
+#endif
+    {
+        char filtered_data[MAX_LINE_SIZE+1];
+
+        xastir_snprintf(filtered_data,
+            sizeof(filtered_data),
+            "%s",
+            line);
+        filtered_data[MAX_LINE_SIZE] = '\0';    // Terminate it
+
+        makePrintable(filtered_data);
+        fprintf(stderr,"decode_ax25_line: start parsing %s\n", filtered_data);
+    }
+
+    if (line == NULL) {
+        fprintf(stderr,"decode_ax25_line: line == NULL.\n");
+        return(FALSE);
+    }
+
+    if ( (line != NULL) && (strlen(line) > MAX_LINE_SIZE) ) { // Overly long message, throw it away.  We're done.
+        if (debug_level & 1)
+            fprintf(stderr,"\ndecode_ax25_line: LONG packet.  Dumping it:\n%s\n",line);
+        return(FALSE);
+    }
+
+    if (line[strlen(line)-1] == '\n')           // better: look at other places,
+                                                // so that we don't get it here...
+        line[strlen(line)-1] = '\0';            // Wipe out '\n', to be sure
+    if (line[strlen(line)-1] == '\r')
+        line[strlen(line)-1] = '\0';            // Wipe out '\r'
+
+    call_sign   = NULL;
+    path0       = NULL;
+    info        = NULL;
+    origin[0]   = '\0';
+    call[0]     = '\0';
+    path[0]     = '\0';
+    third_party = 0;
+
+    // CALL>PATH:APRS-INFO-FIELD                // split line into components
+    //     ^    ^
+    ok = 0;
+    call_sign = strtok(line,">");               // extract call from AX.25 line
+    if (call_sign != NULL) {
+        path0 = strtok(NULL,":");               // extract path from AX.25 line
+        if (path0 != NULL) {
+            info = strtok(NULL,"");             // rest is info_field
+            if (info != NULL) {
+                if ((info - path0) < 100) {     // check if path could be copied
+                    ok = 1;                     // we have found all three components
+                }
+            }
+        }
+    }
+
+    if (ok) {
+
+        xastir_snprintf(path,
+            sizeof(path),
+            "%s",
+            path0);
+
+        memset(info_copy, '\0', sizeof(info_copy));
+        xastir_snprintf(info_copy,
+            sizeof(info_copy),
+            "%s",
+            info);
+
+        ok = valid_path(path);                  // check the path and convert it to TAPR format
+        // Note that valid_path() also removes igate injection identifiers
+
+        if ((debug_level & 1) && !ok) {
+            char filtered_data[MAX_LINE_SIZE + 1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                path);
+            makePrintable(filtered_data);
+            fprintf(stderr,"decode_ax25_line: invalid path: %s\n",filtered_data);
+        }
+    }
+
+    if (ok) {
+        // If it's not me transmitting it:
+        if (strcmp(my_callsign,call_sign) != 0) {
+            
+            // Check for "EMERGENCY" anywhere in the line.
+            // APRS+SA also supports any of these in the TO: field:
+            //
+            //      EMERGENCY
+            //      ALARM
+            //      ALERT
+            //      WARNING
+            //      WXALARM
+            //      EM
+            //
+            // Snag just the TO: field from the path, used for most of the
+            // comparisons below.  It will be pointed to by ViaCalls[0];
+            xastir_snprintf(tmp_path,   // Make a temporary backup
+                            sizeof(tmp_path),
+                            "%s",
+                            path);
+            split_string(tmp_path, ViaCalls, 10, ',');
+
+            if (       (strstr(backup,      "EMERGENCY"))    // Checks entire line
+                       || (strcmp(ViaCalls[0], "ALARM") == 0)   // Checks to_field
+                       || (strcmp(ViaCalls[0], "ALERT") == 0)   // Checks to_field
+                       || (strcmp(ViaCalls[0], "WARNING") == 0) // Checks to_field
+                       || (strcmp(ViaCalls[0], "WXALARM") == 0) // Checks to_field
+                       || (strcmp(ViaCalls[0], "EM") == 0) ) {  // Checks to_field
+
+                double distance;    // miles or km
+                char course_deg[5];
+
+// EMERGENCY
+                if (emergency_distance_check) {
+
+                    distance = distance_from_my_station(call_sign, course_deg);
+
+// Because of the distance check we have to receive a valid position
+// from the station BEFORE we process the EMERGENCY portion and
+// check distance, doing the popups.  We need to figure out a way to
+// throw the packet back into the queue if it was an emergency
+// packet so that we process these packets twice each.  That way
+// only one packet from the emergency station is required to
+// generate the popups.
+
+                    if (distance == 0.0) {
+                        process_emergency_packet_again++;
+                    }
+
+                    // Check whether the station is near enough to
+                    // us to require that we alert on the packet.
+                    //
+                    // This may be slightly controversial, but if we
+                    // don't know WHERE a station is, we can't help
+                    // much in an emergency, can we?  The
+                    // zero-distance check helps in the case where
+                    // we haven't yet or never get a position packet
+                    // for a station.  As soon as we have a position
+                    // and it is within a reasonable range, we do
+                    // our emergency popups.
+                    //
+                    if ( distance != 0.0 && (float)distance <= emergency_range ) {
+
+// Do the conversion for emergency_range to mi or km as needed.
+//                        if (english_units) {
+//                        }
+//                        else {
+//                        }
+                
+                        // Do a popup to alert the operator to this
+                        // condition.  Make sure we haven't popped
+                        // up an emergency message for this station
+                        // within the last 30 minutes.  If we pop
+                        // these up constantly it gets quite
+                        // annoying.
+                        if ( (strncmp(call_sign, last_emergency_callsign, strlen(call_sign)) != 0)
+                             || ((last_emergency_time + 60*30) < sec_now()) ) {
+
+                            char temp[50];
+                            char temp2[150];
+                            char temp3[300];
+                            char timestring[101];
+                    
+                            // Callsign is different or enough time
+                            // has passed
+                    
+                            last_emergency_time = sec_now();
+                            xastir_snprintf(last_emergency_callsign,
+                            sizeof(last_emergency_callsign),
+                                            "%s",
+                                            call_sign);
+                    
+                            // Bring up the Find Station dialog so
+                            // that the operator can go to the
+                            // location quickly.
+                            xastir_snprintf(locate_station_call,
+                                            sizeof(locate_station_call),
+                                            "%s",
+                                            call_sign);
+                    
+                            Locate_station( (Widget)NULL,
+                                (XtPointer)NULL,
+                                (XtPointer)1 );
+
+                            // Bring up an additional popup dialog
+                            // that shows the entire packet, so the
+                            // user can make a determination as to
+                            // whether the packet is or is not a
+                            // real emergency.
+                            //
+                            popup_message_always(langcode("POPEM00036"), backup);
+
+                            // Bring up another dialog with the
+                            // callsign plus distance/bearing to the
+                            // station.
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.1f",
+                                distance);
+                            xastir_snprintf(temp2,
+                                sizeof(temp2),
+                                langcode("WPUPSTI022"),
+                                temp,
+                                course_deg);
+                            get_timestamp(timestring);
+                            xastir_snprintf(temp3,
+                                sizeof(temp3),
+                                "%s  %s",
+                                timestring,
+                                temp2);
+                            popup_message_always(call_sign, temp3);
+
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if (ok) {
+
+        // Attempt to digipeat this packet if we should.  If port=-2,
+        // we received this packet from the x_spider server and we
+        // should not attempt to digipeat it.  If port=-1, it's from
+        // a log file.  Again, don't digipeat it.
+        if (port >= 0)
+            relay_digipeat(call_sign, path, info, port);
+ 
+        extract_TNC_text(info);                 // extract leading text from TNC X-1J4
+        if (strlen(info) > 256)                 // first check if information field conforms to APRS specs
+            ok = 0;                             // drop packets too long
+        if ((debug_level & 1) && !ok) {
+            char filtered_data[MAX_LINE_SIZE + 1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                info);
+            makePrintable(filtered_data);
+            fprintf(stderr,"decode_ax25_line: info field too long: %s\n",filtered_data);
+        }
+    }
+
+    if (ok) {                                                   // check callsign
+        (void)remove_trailing_asterisk(call_sign);              // is an asterisk valid here ???
+        if (valid_inet_name(call_sign,info,origin,sizeof(origin))) { // accept some of the names used in internet
+            xastir_snprintf(call,
+                sizeof(call),
+                "%s",
+                call_sign);
+        }
+        else if (valid_call(call_sign)) {                     // accept real AX.25 calls
+            xastir_snprintf(call,
+                sizeof(call),
+                "%s",
+                call_sign);
+        }
+        else {
+            ok = 0;
+            if (debug_level & 1) {
+                char filtered_data[MAX_LINE_SIZE + 1];
+
+                xastir_snprintf(filtered_data,
+                    sizeof(filtered_data),
+                    "%s",
+                    call_sign);
+                makePrintable(filtered_data);
+                fprintf(stderr,"decode_ax25_line: invalid call: %s\n",filtered_data);
+            }
+        }
+    }
+
+    if (!dbadd)
+    {
+        if (debug_level & 1)
+            fprintf(stderr,"decode_ax25_line: exiting\n");
+
+        return(ok);
+    }
+
+    if (ok && info[0] == '}') {                                 // look for third-party traffic
+        ok = extract_third_party(call,path,sizeof(path),&info,origin,sizeof(origin)); // extract third-party data
+        third_party = 1;
+
+        // Add it to the HEARD queue for this interface.  We use this
+        // for igating purposes.  If some other igate beat us to this
+        // packet, we don't want to duplicate it over the air.  If
+        // port=-2, we received it from the x_spider server and we
+        // should not save it in the queue.  If port=-1, the packet
+        // came from a log file and again we shouldn't save it to
+        // the queue.
+        if (port >= 0)
+            insert_into_heard_queue(port, backup);
+    }
+
+    if (ok && (info[0] == ';' || info[0] == ')')) {             // look for objects or items
+        xastir_snprintf(origin,
+            sizeof(origin),
+            "%s",
+            call);
+        ok = extract_object(call,&info,origin);                 // extract object data
+    }
+
+    if (ok) {
+        // decode APRS information field, always called with valid call and path
+        // info is a string with 0 - 256 bytes
+        // fprintf(stderr,"dec: %s (%s) %s\n",call,origin,info);
+        if (debug_level & 1) {
+            char filtered_data[MAX_LINE_SIZE+80];
+            sprintf(filtered_data,
+                "Registering data %s %s %s %s %c %d %d",
+                call, path, info, origin, from, port, third_party);
+            makePrintable(filtered_data);
+            fprintf(stderr,"c/p/i/o fr pt tp: %s\n", filtered_data);
+        }
+        decode_info_field(call,
+            path,
+            info,
+            origin,
+            from,
+            port,
+            third_party,
+            info_copy);
+    }
+
+
+    if (port == -2) {    // We received this packet from an x_spider
+        // server.  We need to dump it out all of our
+        // transmit-enabled ports.
+
+        // If the string starts with "user" or "pass", it's an
+        // authentication string.  We need to send those through as
+        // well so that the user gets logged into the internet
+        // server and can send/receive packets/messages.  We also
+        // dump it to our console so that we can see who logged in
+        // to us.
+        if (strncasecmp(line,"user",4) == 0
+                || strncasecmp(line,"pass",4 == 0)
+                || strncasecmp(line,"filter",6 == 0)) {
+            fprintf(stderr,"\tLogged on: %s\n", line);
+
+// If the line has a "filter" parameter in it, we need to remove it,
+// else a client may change our filtering parameters.  Perhaps we
+// should skip the authentication stuff as well, as the servers
+// might get confused if we pass two different authentications on
+// the same socket?
+
+        }
+        else if (strlen(line) > 0) {    // Not empty
+            // Send the packet unchanged out all of our
+            // transmit-enabled ports.  We should send it as
+            // third-party igated packets if we're sending to
+            // servers, send it unchanged if sending through TNC?
+
+//fprintf(stderr,"Retransmitting x_spider packet: %s\n", line);
+
+            // Here's where we inject our own callsign like this:
+            // "WE7U-15,I" in order to provide injection ID for our
+            // igate.
+            xastir_snprintf(tmp_line,
+                sizeof(tmp_line),
+                "%s>%s,%s,I:%s",
+                call_sign,
+                path,
+                my_callsign,
+                info_copy);
+
+//fprintf(stderr,"decode_ax25_line: IGATE>NET %s\n",tmp_line);
+//fprintf(stderr,"call: %s\tcall_sign: %s\n", call, call_sign);
+
+            output_igate_net(tmp_line, port, 0); // 0="not third-party"
+        }
+    }
+
+// EMERGENCY
+    // For emergency packets we need to process them twice, to try
+    // to get a position before we do the distance check.
+    //
+// This causes an infinite loop on packets that don't have a
+// distance!  Disabling it for now.
+    if (process_emergency_packet_again) {
+        process_emergency_packet_again = 0;
+//fprintf(stderr,"Again: %s\n", backup);
+//        decode_ax25_line(backup, from, port, dbadd);
+    }
+
+    if (debug_level & 1)
+        fprintf(stderr,"decode_ax25_line: exiting\n");
+
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Read a line from file.  We use this to read in log files and to
+ *  read in findu track files.  For findu track files we need to get
+ *  rid of the <br> at the end of the lines, else it shows up in our
+ *  comment lines in Station_info.
+ */
+void  read_file_line(FILE *f) {
+    char line[MAX_LINE_SIZE+1];
+    char cin;
+    int pos;
+
+    pos = 0;
+    line[0] = '\0';
+    while (!feof(f)) {
+        if (fread(&cin,1,1,f) == 1) {
+            if (cin != (char)10 && cin != (char)13) {   // normal characters
+                if (pos < MAX_LINE_SIZE) {
+                    line[pos++] = cin;
+                 }
+            }
+            else {                                    // CR or LF
+                if (cin == (char)10) {                  // Found LF as EOL char
+                    char *ptr;
+
+                    line[pos] = '\0';                   // Always add a terminating zero after last char
+                    pos = 0;                            // start next line
+
+                    // Get rid of <br> HTML tag at end of line here.
+                    // Findu track files have them.
+                    ptr = strstr(line, "<br>");
+                    if (ptr) {  // Found one of them
+                        *ptr = '\0';  // Terminate the line at that point
+                    }
+
+                    // Save backup copies of this string and the
+                    // previous string.  Used for debugging
+                    // purposes.  If we get a segfault, we can print
+                    // out the last two messages received.
+                    xastir_snprintf((char *)incoming_data_copy_previous,
+                        MAX_LINE_SIZE,
+                        "%s",
+                        incoming_data_copy);
+                    xastir_snprintf((char *)incoming_data_copy,
+                        MAX_LINE_SIZE,
+                        "%s",
+                        line);
+
+                    if (line[0] != '#') {
+                        decode_ax25_line(line,'F',-1, 1);   // Decode the packet
+                    }
+
+                    return;                             // only read line by line
+                }
+            }
+        }
+    }
+    if (feof(f)) {                                      // Close file if at the end
+        (void)fclose(f);
+        read_file = 0;
+        statusline(langcode("BBARSTA012"),0);           // File done..
+        redraw_on_new_data = 2;                         // redraw immediately after finish
+    }
+}
+
+
+
+
+
+/*
+ *  Center map to new position
+ */
+void set_map_position(Widget w, long lat, long lon) {
+    // see also map_pos() in location.c
+
+    // Set interrupt_drawing_now because conditions have changed
+    // (new map center).
+    interrupt_drawing_now++;
+
+    set_last_position();
+    center_latitude  = lat;
+    center_longitude = lon;
+    setup_in_view();  // flag all stations in new screen view
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(w)) {
+//        (void)XCopyArea(XtDisplay(w),pixmap_final,XtWindow(w),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+/*
+ *  Search for a station to be located (for Tracking and Find Station)
+ */
+int locate_station(Widget w, char *call, int follow_case, int get_match, int center_map) {
+    DataRow *p_station;
+    char call_find[MAX_CALLSIGN+1];
+    char call_find1[MAX_CALLSIGN+1];
+    int ii;
+    int call_len;
+
+    call_len = 0;
+    if (!follow_case) {
+        for (ii=0; ii<(int)strlen(call); ii++) {
+            if (isalpha((int)call[ii]))
+                call_find[ii] = toupper((int)call[ii]);         // Problem with lowercase objects/names!!
+            else
+                call_find[ii] = call[ii];
+        }
+        call_find[ii] = '\0';
+        xastir_snprintf(call_find1,
+            sizeof(call_find1),
+            "%s",
+            call_find);
+    }
+    else
+        xastir_snprintf(call_find1,
+            sizeof(call_find1),
+            "%s",
+            call);
+
+    if (search_station_name(&p_station,call_find1,get_match)) {
+        if (position_defined(p_station->coord_lat,p_station->coord_lon,0)) {
+            if (center_map || !position_on_inner_screen(p_station->coord_lat,p_station->coord_lon))
+                 // only change map if really neccessary
+                set_map_position(w, p_station->coord_lat, p_station->coord_lon);
+            return(1);                  // we found it
+        }
+    }
+    return(0);
+}
+
+
+
+
+
+/*
+ *  Look for other stations that the tracked one has gotten close to.
+ *  and speak a proximity warning.
+ *   TODO: 
+ *    - sort matches by distance
+ *    - set upper bound on number of matches so we don't speak forever
+ *    - use different proximity distances for different station types?
+ *    - look for proximity to embedded map objects
+ */
+void search_tracked_station(DataRow **p_tracked) {
+    DataRow *t = (*p_tracked);
+    DataRow *curr = NULL;
+
+
+    if (debug_level & 1) {
+        char lat[20],lon[20];
+    
+        convert_lat_l2s(t->coord_lat,
+                        lat,
+                        sizeof(lat),
+                        CONVERT_HP_NORMAL);
+        convert_lon_l2s(t->coord_lon,
+                        lon,
+                        sizeof(lat),
+                        CONVERT_HP_NORMAL);
+
+        fprintf(stderr,"Searching for stations close to tracked station %s at %s %s ...\n",
+                t->call_sign,lat,lon);
+    }
+
+    while (next_station_time(&curr)) {
+        if (curr != t && curr->flag&ST_ACTIVE) {
+
+            float distance; // Distance in whatever measurement
+                            // units we're currently using.
+            char bearing[10];
+            char station_id[600];
+
+            distance =  (float)calc_distance_course(t->coord_lat,
+                                   t->coord_lon, 
+                                   curr->coord_lat,
+                                   curr->coord_lon,
+                                   bearing,
+                                   sizeof(bearing)) * cvt_kn2len;
+
+            if (debug_level & 1) 
+                fprintf(stderr,"Looking at %s: distance %.3f bearing %s (%s)\n",
+                        curr->call_sign,distance,bearing,convert_bearing_to_name(bearing,1));
+
+            /* check ranges (copied from earlier prox alert code, above) */
+            if ((distance > atof(prox_min)) && (distance < atof(prox_max))) {
+                if (debug_level & 1) 
+                        fprintf(stderr," tracked station is near %s!\n",curr->call_sign);
+
+                if (sound_play_prox_message) {
+                        sprintf(station_id,"%s < %.3f %s from %s",t->call_sign, distance,
+                                english_units?langcode("UNIOP00004"):langcode("UNIOP00005"),
+                                curr->call_sign);
+                        statusline(station_id,0);
+                        play_sound(sound_command,sound_prox_message);
+                }
+#ifdef HAVE_FESTIVAL
+                if (festival_speak_tracked_proximity_alert) {
+                        if (english_units) {
+                            if (distance < 1.0)
+                                sprintf(station_id, langcode("SPCHSTR007"), t->call_sign,
+                                        (int)(distance * 1760), langcode("SPCHSTR004"),
+                                        convert_bearing_to_name(bearing,1), curr->call_sign);
+                            else if ((int)((distance * 10) + 0.5) % 10)
+                                sprintf(station_id, langcode("SPCHSTR008"), t->call_sign, distance,
+                                        langcode("SPCHSTR003"), convert_bearing_to_name(bearing,1),
+                                        curr->call_sign);
+                            else
+                                sprintf(station_id, langcode("SPCHSTR007"), t->call_sign, (int)(distance + 0.5),
+                                        langcode("SPCHSTR003"), convert_bearing_to_name(bearing,1),
+                                        curr->call_sign);
+                        }
+                        else {                /* metric */
+                            if (distance < 1.0)
+                                sprintf(station_id, langcode("SPCHSTR007"), t->call_sign,
+                                        (int)(distance * 1000), langcode("SPCHSTR002"), 
+                                        convert_bearing_to_name(bearing,1), curr->call_sign);
+                            else if ((int)((distance * 10) + 0.5) % 10)
+                                sprintf(station_id, langcode("SPCHSTR008"), t->call_sign, distance,
+                                        langcode("SPCHSTR001"), 
+                                        convert_bearing_to_name(bearing,1), curr->call_sign);
+                            else
+                                sprintf(station_id, langcode("SPCHSTR007"), t->call_sign, (int)(distance + 0.5),
+                                        langcode("SPCHSTR001"), convert_bearing_to_name(bearing,1),
+                                        curr->call_sign);
+                        }
+                    if (debug_level & 1) 
+                        fprintf(stderr," %s\n",station_id);
+                    SayText(station_id);
+                }
+#endif  /* HAVE_FESTIVAL */
+            }
+        }
+    }   // end of while
+}
+
+
+
+
+
+/*
+ *  Change map position if neccessary while tracking a station
+ *      we call it with defined station call and position
+ */
+void track_station(Widget w, char *call_tracked, DataRow *p_station) {
+    long x_ofs, y_ofs;
+    long new_lat, new_lon;
+
+    if ( is_tracked_station(p_station->call_sign) ) {   // We want to track this station
+        new_lat = p_station->coord_lat;                 // center map to station position as default
+        new_lon = p_station->coord_lon;
+        x_ofs = new_lon - center_longitude;            // current offset from screen center
+        y_ofs = new_lat - center_latitude;
+        if ((labs(x_ofs) > (screen_width*scale_x/3)) || (labs(y_ofs) > (screen_height*scale_y/3))) {
+            // only redraw map if near border (margin 1/6 of screen at each side)
+            if (labs(y_ofs) < (screen_height*scale_y/2))
+                new_lat  += y_ofs/2;                    // give more space in driving direction
+            if (labs(x_ofs) < (screen_width*scale_x/2))
+                new_lon += x_ofs/2;
+
+            set_map_position(w, new_lat, new_lon);      // center map to new position
+
+        }
+        search_tracked_station(&p_station);
+    }
+}
+
+
+
+
+
+// ********************************************************************
+// calc aloha_distance()
+// calculate and return alhoa circle radius in current distance units
+// The ALOHA radius is computed according to the algorithm described by
+// Bob Bruninga at http://web.usna.navy.mil/~bruninga/aprs/ALOHAcir.txt
+// with some clarification provided py private email.
+//
+// The gist of it is that we grab a list of all stations heard via TNC
+// and sort it b distance from our station.  We then accumulate a 
+// count of how many theoretical packets would be introduced into the local 
+// area in 30 minutes from these stations, and stop when we hit 1800 
+// (the supposed limit of the channel capacity).  The distance to the last
+// station we counted is our ALOHA limit.  Per Bob B., this should be plotted
+// on the  map as a circle with no user-selectable way of turning it off.
+//
+double calc_aloha_distance(void) {
+    DataRow *p_station = n_first;  // walk in alphabetical order
+    aloha_entry *aloha_array;
+    aloha_entry *temp_aloha_array;
+
+    int num_aloha_alloc=1000;
+    int num_aloha_entries=0;
+    int digi_copies=1;
+    char temp[10]; // needed for course_deg argument of 
+                   // distance_from_my_station
+
+    int sum;
+    double distance;
+    int ii;
+
+    // This should be enough, though we'll realloc if necessary
+    aloha_array = (aloha_entry *)malloc (num_aloha_alloc*sizeof(aloha_entry));
+    CHECKMALLOC(aloha_array);
+
+    // We need a list of all stations that were heard via tnc:
+    while (p_station != NULL) {
+        if (num_aloha_entries == num_aloha_alloc) { 
+            num_aloha_alloc *= 2;
+            temp_aloha_array=realloc(aloha_array,num_aloha_alloc);
+            if (temp_aloha_array) {
+                aloha_array=temp_aloha_array;
+            }
+            else {
+                fprintf(stderr,"***** Realloc failed *****\n");
+                exit(1);
+            }
+        }
+        if ( (p_station->flag & ST_VIATNC) != 0 && 
+             (p_station->flag & ST_ACTIVE) != 0 ) {
+            if (position_defined(p_station->coord_lat,p_station->coord_lon,1)){
+                xastir_snprintf(aloha_array[num_aloha_entries].call_sign,
+                    MAX_CALLSIGN+1,
+                    "%s",
+                    p_station->call_sign);
+                aloha_array[num_aloha_entries].is_digi = 
+                    aloha_array[num_aloha_entries].is_mobile = 
+                    aloha_array[num_aloha_entries].is_other_mobile = 
+                    aloha_array[num_aloha_entries].is_home = 
+                    aloha_array[num_aloha_entries].is_wx = (char) FALSE;
+                aloha_array[num_aloha_entries].distance = 
+                    distance_from_my_station(p_station->call_sign,temp);
+
+                if ( p_station->newest_trackpoint != NULL 
+                     && strlen(p_station->speed) > 0) {
+                        // If the station has a track and a speed of any value 
+                        // (even zero), it's a mobile.
+                        aloha_array[num_aloha_entries].is_mobile = (char) TRUE;
+                } 
+                else if  ( (p_station->aprs_symbol.aprs_type=='/' 
+                            && (strchr("'<=>()*0COPRSUXY[^abefgjkpsuv",
+                                       p_station->aprs_symbol.aprs_symbol) 
+                                != NULL))
+                            || (p_station->aprs_symbol.aprs_type=='\\' 
+                                && (strchr("/0>AKOS^knsuv",
+                                           p_station->aprs_symbol.aprs_symbol) 
+                                    != NULL))) {
+                    // 
+                    // Per private email exchange with Bob Bruninga:
+                    // If the station has one of these symbols, 
+                    //  it's "other mobile"
+                    // these are also listed on
+                    // web.usna.navy.mil/~bruninga/aprs/aprs11.html
+                    //
+                    aloha_array[num_aloha_entries].is_other_mobile =(char)TRUE;
+                }
+                else if ( p_station-> record_type == APRS_WX1 ||
+                          p_station-> record_type == APRS_WX2 ||
+                          p_station-> record_type == APRS_WX3 ||
+                          p_station-> record_type == APRS_WX4 ||
+                          p_station-> record_type == APRS_WX5 ||
+                          p_station-> record_type == APRS_WX6 || 
+                          p_station-> aprs_symbol.aprs_symbol=='_') {
+                    // Bob B. uses the station symbol "_" to select this, but
+                    // agrees that if we do it this way it's probably better
+                    // -- this says if we've gotten any WX data, it's a WX 
+                    // station
+                    aloha_array[num_aloha_entries].is_wx = (char) TRUE;
+                } 
+                else if (p_station->aprs_symbol.aprs_symbol=='#') { 
+                    // Per Bob B., if it has "#" as its symbol, it's
+                    // assumed to be a digi.
+                    aloha_array[num_aloha_entries].is_digi = (char) TRUE;
+                }
+                else {
+                    // Anything that hasn't gotten selected yet is just a home
+                    aloha_array[num_aloha_entries].is_home = (char) TRUE;
+                }
+
+                num_aloha_entries++;
+            }
+        }
+        p_station = p_station-> n_next;
+    }
+
+    if (debug_level & 2048) {
+        fprintf (stderr,"aloha_distance: Found %d local stations\n",
+             num_aloha_entries);
+    }
+    
+    // we now have all the stations heard via TNC.  Now sort it by distance
+    qsort((void *) aloha_array,num_aloha_entries,sizeof(aloha_entry),
+          comp_by_dist);
+
+    // Starting from the closest, working outward, accumulate
+    sum=0;
+    the_aloha_stats.digis=0;
+    the_aloha_stats.wxs = 0;
+    the_aloha_stats.other_mobiles = 0;
+    the_aloha_stats.mobiles_in_motion = 0;
+    the_aloha_stats.homes = 0;
+    the_aloha_stats.total = 0;
+
+    for (ii=0;(ii<num_aloha_entries && sum < 1800);ii++) {
+        the_aloha_stats.total++;
+        if (aloha_array[ii].is_digi) {
+            sum += digi_copies*3;
+            digi_copies++; // per Bob's web page.  Makes more distant
+                           // stations than this digi count for more, since
+                           // they have been digipeated.
+            the_aloha_stats.digis++;
+        }
+        else if (aloha_array[ii].is_home) {
+            sum += digi_copies*2; 
+            the_aloha_stats.homes++;
+        }
+        else if (aloha_array[ii].is_wx) {
+            sum += digi_copies*6;
+            the_aloha_stats.wxs++;
+        }
+        else if (aloha_array[ii].is_mobile) {
+            sum += digi_copies*15;
+            the_aloha_stats.mobiles_in_motion++;
+        }
+        else if (aloha_array[ii].is_other_mobile) {
+            sum += digi_copies*7;
+            the_aloha_stats.other_mobiles++;
+        }
+        if (debug_level & 2048) {
+            fprintf(stderr,"  %d:%s: d=%f, digi=%c, mobile=%c, motion=%c, home=%c, wx=%c (cum=%d)\n",
+                    ii,
+                    aloha_array[ii].call_sign,
+                    aloha_array[ii].distance,
+                    (aloha_array[ii].is_digi)?'y':'n',
+                    (aloha_array[ii].is_other_mobile)?'y':'n',
+                    (aloha_array[ii].is_mobile)?'y':'n',
+                    (aloha_array[ii].is_home)?'y':'n',
+                    (aloha_array[ii].is_wx)?'y':'n',sum);
+        }
+    }
+    
+    if (ii>0 && ii < num_aloha_entries && sum >= 1800) { // we hit the limit
+        distance = aloha_array[ii-1].distance;
+    }
+    else {
+        distance = -1; // indeterminate, not enough data yet
+    }
+
+    free (aloha_array); // make sure we don't leak
+    return distance;
+    
+}
+
+
+
+
+
+// Used by qsort to sort the aloha entries
+int comp_by_dist(const void *av,const void *bv) {
+    aloha_entry *a = (aloha_entry *) av;
+    aloha_entry *b = (aloha_entry *) bv;
+     if (a->distance < b->distance)
+         return -1;
+     if (a->distance > b->distance)
+         return 1;
+
+     return 0;
+}
+
+
+
+
+
+// Called periodically by UpdateTime, we calculate our aloha radius every
+// so often.  (Bob B. recommends every 30 minutes)
+void calc_aloha(int secs_now)    {
+    char status_text[100];
+
+    if (aloha_time == 0) { // first call
+        aloha_time = secs_now+ALOHA_CALC_INTERVAL; 
+        aloha_status_time = secs_now+ALOHA_STATUS_INTERVAL;
+        aloha_radius = -1.0;
+
+// Debug:  Let's us play with/display aloha circles right away:
+//aloha_radius = 40.0;    // Miles
+
+        the_aloha_stats.digis=0;
+        the_aloha_stats.wxs = 0;
+        the_aloha_stats.other_mobiles = 0;
+        the_aloha_stats.mobiles_in_motion = 0;
+        the_aloha_stats.homes = 0;
+        the_aloha_stats.total = 0;
+        //fprintf(stderr,"Initialized aloha radius time\n");
+    } 
+    else {
+        if (secs_now > aloha_time) {
+            aloha_radius = calc_aloha_distance(); 
+            aloha_time = secs_now + ALOHA_CALC_INTERVAL;
+            if (debug_level & 2048) {
+                if (aloha_radius < 0) {
+                    fprintf(stderr,"Aloha distance indeterminate\n");
+                }
+                else {
+                    fprintf(stderr,"Aloha distance is %f",aloha_radius);
+                    if (english_units) {
+                        fprintf(stderr," miles.\n");
+                    } 
+                    else {
+                        fprintf(stderr," km.\n");
+                    }
+                }
+            }
+        }
+        if (secs_now > aloha_status_time) {
+            if ( aloha_radius != -1 ) {
+                xastir_snprintf(status_text,
+                    sizeof(status_text),
+                    langcode("BBARSTA044"),
+                    (english_units) ? (int)aloha_radius : (int)(aloha_radius * cvt_mi2len),
+                    (english_units) ? " miles" : " km");
+                statusline(status_text,1);
+            }
+            aloha_status_time = secs_now + ALOHA_STATUS_INTERVAL;
+        }
+    }
+}
+
+
+
+
+
+// popup window on menu request
+void Show_Aloha_Stats(Widget w, XtPointer clientData, XtPointer callData)  {
+
+    char temp[2000];
+    char format[1000];
+
+    unsigned long time_since_aloha_update;
+    int minutes, hours;
+    char Hours[7];
+    char Minutes[9];
+
+    if (aloha_radius != -1) {
+        // we've done at least one interval, and aloha_time is the time
+        // for the *next* one.  We want the time since the last one.
+        time_since_aloha_update = sec_now()-(aloha_time-ALOHA_CALC_INTERVAL); 
+        
+
+        hours = time_since_aloha_update/3600;
+        time_since_aloha_update -= hours*3600;
+        minutes = time_since_aloha_update/60;
+
+        if (hours == 1)
+            xastir_snprintf(Hours,sizeof(Hours),"%s",
+                            langcode("TIME003")); // Hour
+        else
+            xastir_snprintf(Hours,sizeof(Hours),"%s",
+                            langcode("TIME004")); // Hours
+        
+        
+        if (minutes == 1)
+            xastir_snprintf(Minutes,sizeof(Minutes),"%s",
+                            langcode("TIME005")); // Minute
+        else
+            xastir_snprintf(Minutes,sizeof(Minutes),"%s",
+                            langcode("TIME006")); // Minutes
+
+        // Build up the whole format string
+        // "Aloha radius %d"
+        xastir_snprintf(format,sizeof(format),"%s",langcode("WPUPALO001"));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        // "Stations inside...: %d"
+        strncat(format,langcode("WPUPALO002"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        //" Digis:               %d"
+        strncat(format,langcode("WPUPALO003"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        //" Mobiles (in motion): %d"
+        strncat(format,langcode("WPUPALO004"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        //" Mobiles (other):     %d"
+        strncat(format,langcode("WPUPALO005"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        //" WX stations:         %d"
+        strncat(format,langcode("WPUPALO006"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        //" Home stations:       %d"
+        strncat(format,langcode("WPUPALO007"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+        //"Last calculated %s ago."
+        strncat(format,langcode("WPUPALO008"),sizeof(format) - 1 - strlen(format));
+        strncat(format,"\n",sizeof(format) - 1 - strlen(format));
+
+        // We now have the whole format string, now print using it:
+        xastir_snprintf(temp,sizeof(temp),format,
+            (english_units) ? (int)aloha_radius : (int)(aloha_radius * cvt_mi2len),
+            (english_units)?" miles":" km",
+            the_aloha_stats.total,
+            the_aloha_stats.digis,
+            the_aloha_stats.mobiles_in_motion,
+            the_aloha_stats.other_mobiles,
+            the_aloha_stats.wxs,
+            the_aloha_stats.homes,
+            hours, Hours,
+            minutes, Minutes);
+
+        popup_message_always(langcode("PULDNVI016"),temp);
+    }
+    else {
+        // Not calculated yet
+        popup_message_always(langcode("PULDNVI016"),langcode("WPUPALO666"));
+    }
+}
+
+// Debugging tool:
+// Check to see if time list contains any stations older than remove_time.
+// If the expire code did its job properly, there should be none.  If there
+// are none, we return NULL.  If there are any, we return the pointer to the
+// last one found (which should be the newest of them by virtue of how we
+// walk the list).
+DataRow * sanity_check_time_list(time_t remove_time)  {
+    DataRow *p_station, *p_station_t_newer, *retval;
+    retval=NULL;
+    
+    for (p_station = t_oldest; p_station != NULL; 
+         p_station = p_station_t_newer) {
+        p_station_t_newer = p_station->t_newer;
+        // Don't count my station in this.
+        if (!is_my_station(p_station) && p_station->sec_heard < remove_time) {
+            retval=p_station;
+        }
+    }
+
+    return (retval);
+}
+
+// Debugging tool
+// dump out the entire time-sorted list starting from oldest and proceeding
+// to newest
+void dump_time_sorted_list(void) {
+    DataRow *p_station, *p_station_t_newer;
+    struct tm *time;
+    fprintf(stderr,"\tTime-sorted list dump \n");
+    fprintf(stderr, "\t Call Sign:\tsec_heard\tdate/time\n");
+    for (p_station = t_oldest; p_station != NULL; 
+         p_station = p_station_t_newer) {
+        p_station_t_newer = p_station->t_newer;
+        time = localtime(&p_station->sec_heard);
+
+        fprintf(stderr,"\t%s\t%ld\t%02d/%02d %02d:%02d:%02d\n",
+                p_station->call_sign, (long int) p_station->sec_heard,
+                time->tm_mon+1,time->tm_mday,
+                time->tm_hour, time->tm_min, time->tm_sec);
+    }
+}
+
+
diff --git a/src/db_gis.c b/src/db_gis.c
new file mode 100644
index 0000000..bc1245d
--- /dev/null
+++ b/src/db_gis.c
@@ -0,0 +1,2675 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: db_gis.c,v 1.27 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2007-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+// include postgresql library for postgis support
+#ifdef HAVE_POSTGIS
+#include <libpq-fe.h>
+// pg_type.h contains constants for OID values to use in paramTypes arrays
+// in prepared queries.
+#include <pg_type.h>   
+#endif // HAVE_POSTGIS
+
+// mysql error library for mysql error code constants
+#ifdef HAVE_MYSQL
+#include <my_global.h>
+#include <my_sys.h>
+#include <mysql.h>
+#include <errmsg.h>
+#include <time.h>
+#endif // HAVE_MYSQL
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+// Some systems don't have strtof
+#ifndef HAVE_STRTOF
+  #define strtof(a,b) atof(a)
+#endif
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <Xm/XmAll.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "database.h"
+#include "main.h"
+#include "util.h"
+#include "xastir.h"
+#include "db_gis.h"
+
+#ifdef HAVE_DB
+/* db_gis.c
+ *
+ * Functions supporting connections to databases, including GIS enabled
+ * databases that hold OpenGIS objects and can apply spatial indicies.
+ *
+ * XASTIR GIS database code is separated into three layers
+ *
+ *  1) Supporting XASTIR logic (ui elements, cad integration, 
+ *     map drawing, etc).
+ *  2a) Generic db storage/retrieval code - wrappers for layer 3
+ *  2b) Connection management code
+ *  3a) DBMS specific db storage/retrieval code for spatial databases
+ *  3b) DBMS specific db storage/retrieval code for non-spatial databases
+ * 
+ * Data structures in an underlying database can be considered as a fourth 
+ * level.
+ *  
+ *  Code for layers 2 and 3 is in this file.
+ *
+ *  Layer 2 functions should be extern and called from elsewhere to
+ *    perform spatial database operations.  Xastir shouldn't need to care
+ *    if an underlying database has spatial support or not for simple data.
+ *    Some functionality might require spatial object support and might be 
+ *    included only if a spatial database is available.  Thus 3b code may only
+ *    support a subset of the 2a functions, while 3a code should support all
+ *    2a functions.
+ *    Layer 2a wrappers should take and return values in xastir coordinates,
+ *    and convert them to decimal degrees to pass on to layer 3.  Likewise
+ *    return values from layer 3 to layer 2a should be in decimal degrees, 
+ *    limiting the number of different places at which the xastir/decimal 
+ *    degree conversion code needs to be invoked.  This would not be true if 
+ *    data are fed directly from decimal degree feeds into the database, so 
+ *    there may also be a need for layer 2 functions that deal only with 
+ *    latitude and longitude in decimal degrees.
+ *
+ *  Layer 3 functions should not be extern and should only be called 
+ *    by layer 2 functions from within this file.  
+ *    Layer 3 functions should take and return values in decimal degrees.
+ *    Xastir objects should be passed down into layer 3, as doing
+ *    so should make code easier to maintain (but harder to extend) than using
+ *    generic structures for transport of data between layers 2 and 3.  
+ *    Passing a station struct from layer 2 to 3 makes layer 2 a very simple
+ *    wrapper, but requires new layer 3 code to write station data to a map
+ *    layer rather than to a DataRow (to, for example, prepare a layer of 
+ *    temperature data at points for analysis and generation of a temperature
+ *    grid.)  [Using generic structures for transport would let the layer 3  
+ *    code remain unchanged while layer 2 functions are added or extended, but
+ *    requires added maintainance to synchronise xastir structs, the generic
+ *    structs, and database structures.]
+ *
+ *  A spatially enabled database is expected to support OpenGIS spatial 
+ *  objects and be able to apply spatial indicies to the data.  A 
+ *  non-spatially enabled database is expected to hold coordinates using
+ *  separate fields for latitude and longitude.  Layer 3 functions that
+ *  interact with a spatial database will need to convert decimal degrees
+ *  to well known text (WKT, and perhaps also well known binary, WKB) 
+ *  representations.  Layer 3 functions that interact with non-spatially 
+ *  enabled databases can just pass raw latitudes and longitudes.
+ * 
+ *  All spatial data are expected to be in WGS84 projection EPSG:4326
+ *
+ *  Support for five sets of underlying database schema elements is envisioned
+ *   - a very simple station at point and time table
+ *   - schema elements to support CAD objects with arbitrary associated data
+ *     tables.
+ *   - a schema capable of holding the full range of aprs data using spatial
+ *     elements (Points, Polygons, etc).
+ *   - full support for APRSWorld tables (using latitude and longitude fields
+ *     rather than spatial elements).  
+ *   - arbitrary tables with schema discovery for arbitrary GIS databases 
+ *     such as Tiger data.  
+ *   The first three of these will require schema version awareness and will
+ *   produce compatability/database lifecycle issues.  
+ *
+ *  Descriptions of how to make connections to databases are stored in 
+ *  connection descriptors.  Connection descriptors describe the DBMS, whether
+ *  the database has/lacks spatial support, the schema type (simple, 
+ *  simple+cad, xastir full, APRSWorld, etc for the database, and connection 
+ *  parameters (server, user, database).  The layer 2/3 separation is intended
+ *  to allow functions (layer 2) to be called from within xastir (layer 1) 
+ *  without the need to test which function to call for which dbms.  Some 
+ *  functions may be schema specific, others may be able to use any of 
+ *  several different schemas.  Connections can be opened from a database 
+ *  descriptor, and more than one descriptor can point to the same database. 
+ *  (Thus a single MySQL database may contain simple xastir tables, xastir 
+ *  CAD object tables, and APRSWorld tables, but two different descriptors 
+ *  would be used to define connections to talk to the APRSWorld tables and 
+ *  the simple+cad tables within what MySQL considers one schema.  A given 
+ *  version of xastir will expect a particular version or range of versions 
+ *  for database schemas - an older version of xastir may expect fields that 
+ *  no longer exist in a database created for a newer version of xastir and 
+ *  vice versa.  
+ *  
+ *  Data selected from a spatial database might be brought into xastir as 
+ *   stations just like an internet feed or findu fetch trail query, as 
+ *   editable CAD objects, or as map layers.  
+ */
+
+/******************* DATABASE SUPPORT IS EXPERIMENTAL ***********************/
+/**************** CODE IN THIS FILE MAY CHANGE AT ANY TIME ******************/
+// Layer 3 declarations
+
+// xastir_dbms_type is used in interface_gui.c to set up cb_items to populate 
+// database picklist.  Define and internationalise here.
+char xastir_dbms_type[4][XASTIR_DB_DESCRIPTOR_MAX_SIZE+1] = {"","MySQL (lat/long)","Postgresql/Postgis","MySQL Spatial"} ;
+// xastir_schema_type is used in interface_gui.c to set up cb_item to populate
+// schema type picklist Sql_Database_schema_type_data. Define and internationalize here.
+char xastir_schema_type[5][XASTIR_SCHEMA_DESCRIPTOR_MAX_SIZE+1] = {"","Xastir Simple","Xastir CAD","Xastir Full","APRSWorld"} ;
+
+const char *POSTGIS_TIMEFORMAT = "%Y-%m-%d %H:%M:%S%z";
+const char *MYSQL_TIMEFORMAT = "%Y-%m-%d %H:%M:%S";
+
+/*
+// store integer values for picklist items, but use localized strings on picklists
+char xastir_dbms_type[3][XASTIR_DB_DESCRIPTOR_MAX_SIZE+1];   // array of xastir database type strings
+xastir_snprintf(&xastir_dbms_type[DB_MYSQL][0],
+     XASTIR_DB_DESCRIPTOR_MAX_SIZE, 
+     "%s",langcode("XADBMST001"));
+xastir_snprintf(&xastir_dbms_type[DB_POSTGIS][0], 
+     sizeof(&xastir_dbms_type[DB_POSTGIS][0]), 
+     "%s", langcode("XADBMST002"));
+xastir_snprintf(&xastir_dbms_type[DB_MYSQL_SPATIAL][0], 
+     sizeof(&xastir_dbms_type[DB_MYSQL_SPATIAL][0]), 
+     "%s",langcode("XADBMST003"));
+
+char xastir_schema_type[4][XASTIR_SCHEMA_DESCRIPTOR_MAX_SIZE+1];  // array of xastir schema type strings
+xastir_snprintf(xastir_schema_type[XASTIR_SCHEMA_SIMPLE], 
+     sizeof(xastir_schema_type[XASTIR_SCHEMA_SIMPLE][0]),
+      "%s",langcode ("XASCHEMA01"));
+xastir_snprintf(xastir_schema_type[XASTIR_SCHEMA_CAD][0], 
+     sizeof(xastir_schema_type[XASTIR_SCHEMA_CAD][0]),
+      "%s", langcode("XASCHEMA02"));
+xastir_snprintf(xastir_schema_type[XASTIR_SCHEMA_COMPLEX][0], 
+     sizeof(xastir_schema_type[XASTIR_SCHEMA_COMPLEX][0]), 
+     "%s", langcode("XASCHEMA03"));
+xastir_snprintf(xastir_schema_type[XASTIR_SCHEMA_APRSWORLD], 
+     sizeof(xastir_schema_type[XASTIR_SCHEMA_APRSWORLD][0]), 
+     "%s", langcode("XASCHEMA04"));
+*/
+
+#ifdef HAVE_SPATIAL_DB
+#ifdef HAVE_POSTGIS
+int storeStationToGisDbPostgis(Connection *aDbConnection, DataRow *aStation);
+int storeCadToGisDbPostgis(Connection *aDbConnection, CADRow *aCadObject); 
+int storeStationSimplePointToGisDbPostgis(Connection *aDbConnection, DataRow *aStation); 
+int testXastirVersionPostgis(Connection *aDbConnection);
+int getAllSimplePositionsPostgis(Connection *aDbConnection);
+int getAllSimplePositionsPostgisInBoundingBox(Connection *aDbConnection, char* str_e_long, char* str_w_long, char* str_n_lat, char* str_s_lat);
+//PGconn postgres_conn_struct[MAX_DB_CONNECTIONS];
+#endif /* HAVE_POSTGIS*/
+#ifdef HAVE_MYSQL_SPATIAL
+int storeStationToGisDbMysql(Connection *aDbConnection, DataRow *aStation); 
+int storeCadToGisDbMysql(Connection *aDbConnection, CADRow *aCadObject); 
+int storeStationSimplePointToGisDbMysql(Connection *aDbConnection, DataRow *aStation); 
+int getAllSimplePositionsMysqlSpatial(Connection *aDbConnection);
+int getAllCadFromGisDbMysql(Connection *aDbConnection); 
+int getAllSimplePositionsMysqlSpatialInBoundingBox(Connection *aDbConnection, char* str_e_long, char* str_w_long, char* str_n_lat, char* str_s_lat);
+#endif /* HAVE_MYSQL_SPATIAL */
+#endif /* HAVE_SPATIAL_DB */
+//Connection connection_struc[MAX_DB_CONNECTIONS];
+Connection connections[MAX_IFACE_DEVICES];
+int connections_initialized = 0;
+#ifdef HAVE_MYSQL
+//MYSQL mysql_conn_struct, *mysql_connection = &mysql_conn_struct;
+//MYSQL mcs[MAX_DB_CONNECTIONS];
+Connection dbc_struct, *dbc = &dbc_struct;
+int testXastirVersionMysql(Connection *aDbConnection);
+int storeStationSimplePointToDbMysql(Connection *aDbConnection, DataRow *aStation); 
+int getAllSimplePositionsMysql(Connection *aDbConnection);
+int getAllSimplePositionsMysqlInBoundingBox(Connection *aDbConnection, char *str_e_long, char *str_w_long, char *str_n_lat, char *str_s_lat);
+int storeStationToDbMysql(Connection *aDbConnection, DataRow *aStation);
+void mysql_interpret_error(int errorcode, Connection *aDbConnection);
+#endif /* HAVE_MYSQL*/
+
+// Layer 2a: Generic GIS db storage code. ************************************
+// Wrapper functions for actual DBMS specific actions
+
+#ifdef HAVE_SPATIAL_DB
+
+// ******** Functions that require spatialy enabled database support *********
+
+
+
+
+
+/* function storeStationToGisDb() 
+ * Stores the information about a station and its most recent position
+ * to a spatial database.
+ * @param aDbConnection generic database connection to the database in
+ * which the station information is to be stored.
+ * @param aStation the station to store.
+ * @returns 0 on failure, 1 on success.  On failure, stores error message
+ * in connection.
+ */
+int storeStationToGisDb(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;
+    if (aDbConnection==NULL || aStation==NULL) 
+       return returnvalue;
+    // This function is dbms agnostic, and hands the call off to a 
+    // function for the relevant database type.  That function picks the 
+    // relevant schema and either handles the query or passes it on to 
+    // a function to handle that schema.  
+
+
+
+    switch (aDbConnection->type) {
+        #ifdef HAVE_POSTGIS
+        case DB_POSTGIS :
+            returnvalue = storeStationToGisDbPostgis(aDbConnection, aStation);
+        break; 
+        #endif /* HAVE_POSTGIS */
+        #ifdef HAVE_MYSQL_SPATIAL
+        case DB_MYSQL_SPATIAL :
+            returnvalue = storeStationToGisDbMysql(aDbConnection, aStation);
+        break;
+        #endif /* HAVE_MYSQL_SPATIAL */
+        #ifdef HAVE_MYSQL
+        case DB_MYSQL :
+            returnvalue = storeStationToDbMysql(aDbConnection, aStation);
+        break;
+        #endif /* HAVE_MYSQL*/
+    }
+    return returnvalue;
+}
+
+
+
+
+
+
+/* function storeCadToGisDb()
+ * Stores current data about objects (including CAD objects) and their 
+ * most recent positions to a spatial database.  Objects are treated as
+ * points
+*/
+int storeCadToGisDb(Connection *aDbConnection, CADRow *aCadObject) { 
+    int returnvalue = 0;
+    if (aDbConnection==NULL || aCadObject==NULL) 
+       return returnvalue;
+
+
+    // check that connection has cad support in schema
+    return returnvalue;
+}
+
+
+
+
+
+
+/* function storeStationTrackToGisDb() 
+ * Stores information about a station and track of all recieved positions from 
+ * that station (including weather information if present) to a spatial
+ * database.
+ * @param aDbConnection generic database connection to the database in
+ * which the station information is to be stored.
+ * @param aStation the station to store.
+ * @returns 0 on failure, 1 on success.  On failure, stores error message
+ * in connection.
+ */
+int storeStationTrackToGisDb(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;
+    if (aDbConnection==NULL || aStation==NULL) 
+       return returnvalue;
+
+    return returnvalue;
+}
+
+
+
+
+
+
+#endif /* HAVE_SPATIAL_DB */
+
+
+
+
+
+// ***** Functions that do not require spatialy enabled database support ******
+// Include "Simple" in these function names.  They should only deal with point
+// data, not polygons or complex spatial objects.  Station positions and times
+// demarking implicit tracks should be ok.  
+
+
+
+
+
+
+/* function storeStationSimpleToGisDb() 
+ * Stores basic information about a station and its most recent position
+ * to a spatial database. Stores only callsign, most recent position, 
+ * and time.  Intended for testing and simple logging uses.
+ * Underlying table should have structure:
+ * create table simpleStation (
+ *    simpleStationId int primary key not null auto_increment
+ *    station varchar(9) not null,  // max_callsign
+ *    time date not null default now(),
+ *    position POINT  // or latitude float, longitude float for simple db.
+ * ); 
+ ****  or perhaps it should be an APRSWorld table??  ****
+ ****  or perhaps it should be an APRSWorld table, but with POINT when supported??  ****
+ *
+ * ********* generalize to lat/lon fields or position POINT. ******
+ * @param aDbConnection generic database connection to the database in
+ * which the station information is to be stored.
+ * @param aStation the station to store.
+ * @returns 0 on failure, 1 on success.  On failure, stores error message
+ * in connection.
+ */
+int storeStationSimpleToGisDb(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;
+    int triedDatabase = 0;
+    if (debug_level & 4096) 
+        fprintf(stderr,"in storeStationSimpleToGisDb() "); 
+    if (aDbConnection==NULL || aStation==NULL) 
+        return returnvalue;
+    if (aStation->data_via == DATA_VIA_DATABASE) { 
+        if (debug_level & 4096) 
+            fprintf(stderr,"skipping station heard from Database\n"); 
+        returnvalue = 1;
+        return returnvalue;
+    }
+    if (debug_level & 4096) 
+        fprintf(stderr,"with connection->type: %d\n",aDbConnection->type);
+
+    switch (aDbConnection->type) {
+        #ifdef HAVE_POSTGIS
+        case DB_POSTGIS :
+            returnvalue = storeStationSimplePointToGisDbPostgis(aDbConnection, aStation);
+            triedDatabase++;
+        break; 
+        #endif /* HAVE_POSTGIS */
+        #ifdef HAVE_MYSQL_SPATIAL
+        case DB_MYSQL_SPATIAL :
+            returnvalue = storeStationSimplePointToGisDbMysql(aDbConnection, aStation);
+            triedDatabase++;
+        break;
+        #endif /* HAVE_MYSQL_SPATIAL */
+        #ifdef HAVE_MYSQL
+        case DB_MYSQL :
+            returnvalue = storeStationSimplePointToDbMysql(aDbConnection, aStation);
+            triedDatabase++;
+        break;
+        #endif /* HAVE_MYSQL*/
+    }
+    if (triedDatabase==0) { 
+    }
+    return returnvalue;
+}
+
+
+
+
+
+
+/* function getAllSimplePositions()
+ * Given a database connection, return all simple station positions stored in
+ * that database.  
+ */
+int getAllSimplePositions(Connection *aDbConnection) {
+    int returnvalue = 0;
+    int triedDatabase = 0;
+    if (aDbConnection==NULL) 
+        return returnvalue;
+    if (debug_level & 4096) { 
+       fprintf(stderr,"in getAllSimplePositions ");    
+       fprintf(stderr,"with aDbConnection->type %d\n",aDbConnection->type);    
+    }
+
+    switch (aDbConnection->type) {
+        #ifdef HAVE_POSTGIS
+        case DB_POSTGIS :
+            //fprintf(stderr,"connection [%p]\n",aDbConnection);        
+            //fprintf(stderr,"connection->phandle [%p]\n",aDbConnection->phandle);        
+            returnvalue = getAllSimplePositionsPostgis(aDbConnection);
+            triedDatabase++;
+        break; 
+        #endif /* HAVE_POSTGIS */
+        #ifdef HAVE_MYSQL_SPATIAL
+        case DB_MYSQL_SPATIAL :
+            returnvalue = getAllSimplePositionsMysqlSpatial(aDbConnection);
+            triedDatabase++;
+        break;
+        #endif /* HAVE_MYSQL_SPATIAL */
+        #ifdef HAVE_MYSQL
+        case DB_MYSQL :
+            returnvalue = getAllSimplePositionsMysql(aDbConnection);
+            triedDatabase++;
+        break;
+        #endif /* HAVE_MYSQL*/
+    }
+    if (triedDatabase==0) { 
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* function getAllSimplePositionsInBoundingBox()
+ * Given a database connection and a bounding box, return all simple station 
+ * positions stored in that database that fall within the bounds of the box.  
+ * Takes eastern, western, northern, and southern bounds of box in xastir 
+ * coordinates.  
+ */
+int getAllSimplePositionsInBoundingBox(Connection *aDbConnection, int east, int west, int north, int south) {
+    int returnvalue = 0;
+    int triedDatabase = 0;
+    char str_e_long[11];
+    char str_n_lat[10];
+    char str_w_long[11];
+    char str_s_lat[10];
+    if (aDbConnection==NULL) 
+        return returnvalue;
+    // convert from xastir coordinates to decimal degrees
+    convert_lon_l2s(east, str_e_long, sizeof(str_e_long), CONVERT_DEC_DEG);
+    convert_lat_l2s(north, str_n_lat, sizeof(str_n_lat), CONVERT_DEC_DEG);
+    convert_lon_l2s(west, str_w_long, sizeof(str_w_long), CONVERT_DEC_DEG);
+    convert_lat_l2s(south, str_s_lat, sizeof(str_s_lat), CONVERT_DEC_DEG);
+    switch (aDbConnection->type) {
+        #ifdef HAVE_POSTGIS
+        case DB_POSTGIS :
+            returnvalue = getAllSimplePositionsPostgisInBoundingBox(aDbConnection,str_e_long,str_w_long,str_n_lat,str_s_lat);
+            triedDatabase++;
+        break; 
+        #endif /* HAVE_POSTGIS */
+        #ifdef HAVE_MYSQL_SPATIAL
+        case DB_MYSQL_SPATIAL :
+            returnvalue = getAllSimplePositionsMysqlSpatialInBoundingBox(aDbConnection,str_e_long,str_w_long,str_n_lat,str_s_lat);
+            triedDatabase++;
+        break;
+        #endif /* HAVE_MYSQL_SPATIAL */
+        #ifdef HAVE_MYSQL
+        case DB_MYSQL :
+            returnvalue = getAllSimplePositionsMysqlInBoundingBox(aDbConnection,str_e_long,str_w_long,str_n_lat,str_s_lat);
+            triedDatabase++;
+        break;
+        #endif /* HAVE_MYSQL*/
+    }
+    if (triedDatabase==0) { 
+    }
+    return returnvalue;
+}
+
+
+// Layer 2b: Connection managment. *******************************************
+/* It should be possible to maintain a list of an arbitrary number of defined
+ * data sources of different types, and to have an arbitrary number of 
+ * connections to these data sources open at the same time.  
+ *
+ * Some issues: How to handle login credentials for databases?  Request on
+ * connection?  How to perform multiple operations with the same datasource 
+ * (e.g. logging to the database from feeds while querying CAD objects).
+ * Probably want to be able to store password, request password on connect, 
+ * or use configuration file (e.g. my.ini) for password) - let user tune
+ * choices to environment.
+ *
+ * The existing interface code seems better suited to having a fixed number 
+ * of interfaces with zero or one database connection associated with each
+ * interface than handing an arbitrary number of connections per interface.  
+ */
+
+
+
+// simple testing hardcoded database connection testing function
+// remove this function and call in main.c  when integration with 
+// interfaces is working.
+// fill in password, uncomment, and uncomment code in main.c for
+// simple database write test - writes station in n_first to simple mysql db
+/*
+ioparam simpleDbTest(void) {
+   ioparam test;
+   Connection conn;
+   int ok;
+   xastir_snprintf(test.device_name, sizeof(test.device_name), "Test Connection");
+   test.database_type = DB_MYSQL;
+   xastir_snprintf(test.device_host_name, sizeof(test.device_host_name), "localhost");
+   test.sp = 3306;
+   xastir_snprintf(test.database_username, sizeof(test.database_username), "xastir_test");
+   // hardcode a test password here for simple test
+   xastir_snprintf(test.device_host_pswd, sizeof(test.device_host_pswd), "hardcoded test password");
+   xastir_snprintf(test.database_schema, sizeof(test.database_schema), "xastir");
+   test.database_schema_type = XASTIR_SCHEMA_SIMPLE;
+   xastir_snprintf(test.database_unix_socket, sizeof(test.database_unix_socket), "/var/lib/mysql/mysql.sock");
+   
+   got_conn=openConnection(&test, conn);
+   ok = storeStationSimpleToGisDb(&conn, n_first);
+
+   return test;
+}
+*/
+
+
+int initConnections() {
+   int x;
+   if (debug_level & 4096) 
+       fprintf(stderr,"initConnections()\n");
+   for (x=0;x<MAX_IFACE_DEVICES;x++) {
+      initAConnection(&connections[x], x);
+   }
+   if (debug_level & 4096) { 
+       for (x=0;x<MAX_IFACE_DEVICES;x++) {
+           #ifdef HAVE_POSTGIS
+           fprintf(stderr,"Initialized connection %d [%p] type=%d phandle=[%p]\n",x,&connections[x],connections[x].type,connections[x].phandle);
+           #endif /* HAVE_POSTGIS */
+           #ifdef HAVE_MYSQL
+           fprintf(stderr,"Initialized connection %d mhandle=[%p]\n",x,&connections[x].mhandle);
+           #endif /* HAVE_MYSQL */
+       }
+   }
+   return 1;
+}
+
+/* Function initAConnections() 
+ * Given a connection structure, initialize the storage for the 
+ * database connections, link the connection to the relevant
+ * interface, and set default values for other parameters.  */
+int initAConnection(Connection *connection, int x) {
+   int y;
+      connection->descriptor = &devices[x];
+      connection->type = 0;              // assign no type by default
+      connection->interface_number = x;  // so we can reference port_data[] from a connection
+                                             // without knowing the connection's position in 
+                                             // connections[] 
+      // malloc for the PGconn will cause segfault on trying to 
+      // open the connection
+#ifdef HAVE_POSTGIS
+      connection->phandle = (PGconn*)malloc(sizeof(PGconn*));
+#endif /* HAVE_POSTGIS */
+#ifdef HAVE_MYSQL
+      //connection->mhandle = (MYSQL)malloc(sizeof(MYSQL));
+      mysql_init(&connection->mhandle);
+#endif /* HAVE_MYSQL */
+      for(y=0;y<MAX_CONNECTION_ERROR_MESSAGE;y++) { 
+          connection->errormessage[y]=' '; 
+      }
+      connection->errormessage[MAX_CONNECTION_ERROR_MESSAGE-1]='\0'; 
+      if (debug_level & 4096) {
+          fprintf(stderr,"initAConnection() [%d]\n",x);
+      }
+   return 1;
+}
+
+/* Function openConnection()
+ * Opens the specified database connection.
+ * @param anIface a database connection description (host username etc).
+ * @param connection a generic database connection for which the 
+ * appropriate MySQL or Postgresql connection handle will be used
+ * for the open connection on success.
+ * @returns 0 on any error, 1 for successful connection
+ * on connection failure, returns 0 and sets error message in 
+ * the connection descriptor.
+ */
+int openConnection(ioparam *anIface, Connection *connection) {
+    int returnvalue = 0;
+    int connection_made = 0;
+    #ifdef HAVE_POSTGIS
+    char connection_string[900];
+    int connected;   // status of connection polling loop
+    time_t start_time;
+    PGconn *postgres_connection;
+    PostgresPollingStatusType poll;
+    #endif /* HAVE_POSTGIS */
+    #ifdef HAVE_MYSQL
+    unsigned long client_flag = 0; // parameter used for mysql connection, is normally 0.
+    unsigned int port;  // port to make connection on
+    #endif /* HAVE_MYSQL */
+
+
+    if (anIface==NULL) {
+        fprintf(stderr,"Null iface\n");
+        return returnvalue;
+    }
+    if (anIface==NULL || connection==NULL) {
+        fprintf(stderr,"Null connection\n");
+        return returnvalue;
+    }
+    if (debug_level & 4096) {
+        fprintf(stderr,"opening connection [%p] \n",connection);
+    }
+//    #ifdef HAVE_MYSQL
+//    switch (anIface->database_type) { 
+//        #ifdef HAVE_MYSQL_SPATIAL
+//        case DB_MYSQL_SPATIAL : 
+//        #endif /* HAVE_MYSQL_SPATIAL */
+//        #ifdef HAVE_MYSQL
+//        case DB_MYSQL : 
+//        #endif /* HAVE_MYSQL */
+//        // instantiate the MYSQL structure for the connection
+//        //fprintf(stderr,"calling mysql_init\n");        
+//        //connection->mhandle = mysql_init(&connection->mhandle);
+//        //fprintf(stderr,"called mysql_init\n");        
+//    }
+//    #endif /* HAVE_MYSQL */
+    // clear any existing error message
+    xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), " "); 
+    if (debug_level & 4096) 
+          fprintf(stderr,"Entering openConnection with anIface [%p] and conn [%p]\n",anIface,connection);
+
+    connection->type = anIface->database_type;
+    //connection->descriptor = anIface;
+
+    if (connections_initialized == 0) { 
+        connections_initialized = initConnections();
+        connections_initialized = 1;
+    }
+  
+    // TODO: need some sort of connection listener to handle reconnection attempts when a connection fails...
+    
+    // try to open connection
+    if (!(anIface==NULL)) { 
+        switch (anIface->database_type) {
+            #ifdef HAVE_POSTGIS
+            case DB_POSTGIS : 
+                if (debug_level & 4096)
+                    fprintf(stderr,"Opening Connection to a Postgresql/Postgis database.\n");
+                // If type is postgis, connect to postgis database.
+                // build connection string from parameters
+                xastir_snprintf(connection_string, sizeof(connection_string), \
+                   "host=%s user=%s password=%s dbname=%s port=%d", \
+                   anIface->device_host_name, anIface->database_username, anIface->device_host_pswd, anIface->database_schema, anIface->sp);
+                // Use nonblocking connection (connectStart and connectPoll)
+                //connection->phandle = PQconnectStart(connection_string);
+                postgres_connection = PQconnectStart(connection_string);
+                //if (connection->phandle == NULL) {  
+                if (postgres_connection == NULL) {  
+                    xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Insufficient memory to open connection.");
+                } else {
+                    connected = 0;
+                    // can connect, run PQ_connect_poll loop
+                    // Note: xastir needs to decide when to time out
+                    start_time = sec_now();
+                    statusline("Connecting to Postgresql database",1);
+                    while ((connected==0) & (sec_now()<(start_time+30))) { 
+                       // need to add a timer to polling loop
+                       //poll = PQconnectPoll(connection->phandle);
+                       poll = PQconnectPoll(postgres_connection);
+                       if (poll == PGRES_POLLING_FAILED || poll == PGRES_POLLING_OK) { 
+                          connected = 1;
+                       } 
+                       // add connection status feedback here if desired
+                    }
+                    //if (PQstatus(connection->phandle)==CONNECTION_OK) {
+                    if (PQstatus(postgres_connection)==CONNECTION_OK) {
+                        if (debug_level & 4096)
+                            fprintf(stderr,"Connected to Postgresql database on %s\n",anIface->device_host_name);
+                        // connection successfull
+                        connection->phandle = postgres_connection;
+                        connection->type=DB_POSTGIS;
+                        //connection->descriptor = anIface;
+                        xastir_snprintf(connection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, " ");
+                        connection_made = 1;
+                    } else {
+                        // connection attempt failed
+                        fprintf(stderr,"Failed to connect to Postgresql database on %s\n",anIface->device_host_name);
+                        fprintf(stderr,"Postgres Error: %s\n", PQerrorMessage(postgres_connection));
+                        xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Unable to make Postgresql connection %s. %s", PQerrorMessage(postgres_connection), connection_string); 
+                    }
+                }
+                break;
+            #endif /* HAVE_POSTGIS */
+            #ifdef HAVE_MYSQL_SPATIAL
+            case DB_MYSQL_SPATIAL : 
+                // if type is mysql (=>4.1), connect to mysql database
+                if (debug_level & 4096) 
+                     fprintf(stderr,"Opening connection to a MySQL (spatial) database.\n");
+                if (&connection->mhandle == NULL) { 
+                    // insufficient memory to initalize a new database handle 
+                    xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Insufficient memory to open connection.");
+                } else { 
+                    port = anIface->sp;
+                    statusline("Connecting to MySQL database",1);
+                    if (debug_level & 4096) 
+                        fprintf(stderr,"Opening connection to %s.\n",anIface->device_host_name);
+                    mysql_real_connect(&connection->mhandle, anIface->device_host_name, anIface->database_username, anIface->device_host_pswd, anIface->database_schema, port, anIface->database_unix_socket, client_flag); 
+                    //MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
+                    if (&connection->mhandle == NULL) { 
+                        // unable to establish connection
+                        xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Unable to establish connection: %s", mysql_error(&connection->mhandle));
+                        fprintf(stderr,"Failed to connect to MySQL database on %s\n",anIface->device_host_name);
+                        fprintf(stderr, "MySQL Error: %s", mysql_error(&connection->mhandle));
+                    } else { 
+
+// mysql_real_connect is coming back with non-null failed connection.
+
+                        // connected to database
+                        // make sure error message for making connection is empty.
+                        xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), " ");
+                        xastir_snprintf(connection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, " ");
+
+                        // ping the server
+                        if (mysql_ping(&connection->mhandle)==0) { 
+                            fprintf(stderr,"mysql ping ok [0]\n");
+                            connection_made = 1;
+                            // store connection information
+                            connection->type = DB_MYSQL_SPATIAL;
+                            //connection->descriptor = anIface;
+                            if (debug_level & 4096) 
+                                fprintf(stderr,"Connected to MySQL database, connection stored\n");
+                        } else {
+                            fprintf(stderr,"mysql ping failed [1]\n");
+                            fprintf(stderr,"Can't connect to MySQL database: Can't ping server.\n");
+                            xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Unable to ping MySQL server.  Server may be down. Check connection paramenters.");
+                        }
+                    }
+                }
+                break;
+            #endif /* HAVE_MYSQL_SPATIAL */
+            #ifdef HAVE_MYSQL
+            case DB_MYSQL : 
+                // if type is mysql (<4.1), connect to mysql database
+                if (debug_level & 4096) 
+                    fprintf(stderr,"Opening connection to a MySQL database.\n");
+                if (&connection->mhandle == NULL) { 
+                    // insufficient memory to initalize a new database handle 
+                    xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Insufficient memory to open connection.");
+                    fprintf(stderr,"Insufficient memory to open mysql connection [mysql_init(*MYSQL) returned null].\n");
+                } else { 
+                    client_flag = CLIENT_COMPRESS;
+                    port = anIface->sp;
+// **** fails if database_unix_socket doesn't exist                    
+                    mysql_real_connect(&connection->mhandle, anIface->device_host_name, anIface->database_username, anIface->device_host_pswd, anIface->database_schema, port, anIface->database_unix_socket, client_flag); 
+                    if (&connection->mhandle == NULL) { 
+                        fprintf(stderr,"Unable to establish connection to MySQL database\nHost: %s Schema: %s Username: %s\n",anIface->device_host_name, anIface->database_schema, anIface->database_username);
+                        // unable to establish connection
+                        xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Unable to establish MySQL connection. Host: %s Username: %s Password: %s Schema %s Port: %d", anIface->device_host_name, anIface->database_username, anIface->device_host_pswd, anIface->database_schema, port); 
+                        fprintf(stderr,"Failed to connect to MySQL database on %s\n",anIface->device_host_name);
+                        fprintf(stderr, "MySQL Error: %s", mysql_error(&connection->mhandle));
+                    } else { 
+                        fprintf(stderr,"Connected to MySQL database on %s\n",anIface->device_host_name);
+                        // connected to database
+                        // make sure error message for making connection is empty.
+                        xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), " ");
+                        xastir_snprintf(connection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, " ");
+
+                        // ping the server
+                        if (mysql_ping(&connection->mhandle)==0) { 
+                            fprintf(stderr,"mysql ping ok [0]\n");
+                            connection_made = 1;
+                            // store connection information
+                            connection->type = DB_MYSQL;
+                            //connection->descriptor = anIface;
+                            if (debug_level & 4096) 
+                                fprintf(stderr,"Connected to MySQL database, connection stored\n");
+                        } else {
+                            fprintf(stderr,"mysql ping failed [1]\n");
+                            xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "Unable to ping MySQL server.  Server may be down. Check connection paramenters.");
+                            fprintf(stderr,"Can't connect to MySQL database: Can't ping server.\n");
+                        }
+                    }
+                }
+                break;
+            #endif /* HAVE_MYSQL*/
+        }  /* end switch */
+    }  /* end test for null interface */
+
+    if (connection_made==1) { 
+        if (debug_level & 4096) {
+            fprintf(stderr,"Connection made: ");       
+            fprintf(stderr,"connection->type [%d]\n",connection->type);
+        }
+        if (testConnection((Connection*)connection)==True) { 
+            returnvalue = 1;
+            statusline("Connected to database",1);
+        } else { 
+            statusline("Incompatable database schema",1);
+            fprintf(stderr,"Connection OK, but incompatable schema. [%s]\n",connection->errormessage);
+            xastir_snprintf(anIface->database_errormessage, sizeof(anIface->database_errormessage), "%s",connection->errormessage);
+            closeConnection(connection,-1);
+            //free(connection);
+        }
+    } else { 
+        // Detailed error message should have been returned above, but make sure
+        // there is at least a minimal failure message regardless of the problem.
+        statusline("Failed to connect to database",1);
+        fprintf(stderr,"Failed to make database connection.\n");   
+        //free(connection);   // not pointing to the right thing ??
+        port_data[connection->interface_number].status = DEVICE_ERROR;
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* Function closeConnection()
+ * Closes the specified database connection.
+ * @param aDbConnection a generic database connection handle.
+ */
+int closeConnection(Connection *aDbConnection, int port_number) {
+    //ioparam db =  aDbConnection->descriptor;
+fprintf(stderr,"Closing connection on port %d\n",port_number);   
+    if (aDbConnection==NULL)
+       return 0;
+    // free up connection resources
+    switch (aDbConnection->type) {
+        #ifdef HAVE_POSTGIS
+        case DB_POSTGIS : 
+fprintf(stderr,"Connection type is postgis.\n");   
+            // if type is postgis, close connection to postgis database
+            if (aDbConnection->phandle!=NULL) { 
+                if (port_data[port_number].status==DEVICE_UP) { 
+                   PQfinish(aDbConnection->phandle);
+                }
+                //free(aDbConnection->phandle);
+            }
+            break;
+        #endif /* HAVE_POSTGIS */
+        #ifdef HAVE_MYSQL_SPATIAL
+        case DB_MYSQL_SPATIAL : 
+             // if type is mysql, close connection to mysql database
+            if (&aDbConnection->mhandle!=NULL) { 
+                if (debug_level & 4096) {   
+                    fprintf(stderr,"Connection type to close is mysql spatial.\n");   
+                    fprintf(stderr,"mysql_stat [%s]\n",mysql_stat(&aDbConnection->mhandle));        
+                }
+                mysql_close(&aDbConnection->mhandle);
+                //free(aDbConnection->mhandle);
+            }
+            break;
+        #endif /* HAVE_MYSQL_SPATIAL */
+        #ifdef HAVE_MYSQL
+        case DB_MYSQL : 
+fprintf(stderr,"Connection type is mysql.\n");   
+            // if type is mysql, close connection to mysql database
+            if (&aDbConnection->mhandle!=NULL) { 
+                mysql_close(&aDbConnection->mhandle);
+                //free(aDbConnection->mhandle);
+            }
+            break;
+        #endif /* HAVE_MYSQL*/
+    }
+
+    return 1;
+}
+
+
+
+
+
+/* Tests a database connection to see if the server is responding.
+ * @param aDbConnection pointer to a generic connection handle.
+ * @returns 0 on any error, 1 for successful ping.
+ */
+int pingConnection(Connection *aDbConnection) { 
+    int returnvalue = True;
+    int dbreturn;
+    #ifdef HAVE_POSTGIS
+    ConnStatusType psql_status;
+    #endif /* HAVE_POSTGIS */
+
+    if (aDbConnection==NULL)
+       return 0;
+
+    if (debug_level & 4096) { 
+        fprintf(stderr,"Pinging database server type=[%d]\n",aDbConnection->type);
+    //} else {
+        //fprintf(stderr,"Pinging database server.\n");
+    } 
+
+    switch (aDbConnection->type) {
+       #ifdef HAVE_POSTGIS
+       case DB_POSTGIS: 
+           returnvalue = False;
+           // is the connection open  [required]
+           if (aDbConnection->phandle!=NULL) { 
+                psql_status = PQstatus(aDbConnection->phandle);
+                if (psql_status!=CONNECTION_OK) { 
+                    xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Postgresql connection failed");
+                    fprintf(stderr, "PQstatus returned CONNECTION_BAD, probably unable to connect to server.\n");
+
+                } else { 
+                    if (debug_level & 4096) { 
+                        fprintf(stderr, "PQstatus returned CONNECTION_OK.\n");
+                    }
+                    returnvalue = True;
+                }
+           }
+           break;
+       #endif /* HAVE_POSTGIS */
+       #ifdef HAVE_MYSQL_SPATIAL
+       case DB_MYSQL_SPATIAL: 
+           returnvalue = False;
+           // is the connection open  [required]
+           if (&aDbConnection->mhandle!=NULL) { 
+               // can we ping the server [required]
+               dbreturn = mysql_ping(&aDbConnection->mhandle);
+               if (dbreturn>0) { 
+                    mysql_interpret_error(dbreturn, aDbConnection);
+                    fprintf(stderr, "MySQL Ping failed, probably unable to connect to server.\n");
+               } else {
+                    if (debug_level & 4096) { 
+                        fprintf(stderr, "MySQL Ping OK.\n");
+                        fprintf(stderr,"mysql_stat [%s]\n",mysql_stat(&aDbConnection->mhandle));        
+                    }
+                    returnvalue = True;
+               }
+           }
+           break;
+       #endif /* HAVE_MYSQL_SPATIAL */
+       #ifdef HAVE_MYSQL
+       case DB_MYSQL: 
+           // is the connection open  [required]
+           if (&aDbConnection->mhandle != NULL) { 
+               dbreturn = mysql_ping(&aDbConnection->mhandle);
+               if (dbreturn>0) { 
+                    mysql_interpret_error(dbreturn, aDbConnection);
+                    fprintf(stderr, "MySQL Ping failed, probably unable to connect to server.\n");
+               } else {
+                    if (debug_level & 4096) { 
+                        fprintf(stderr, "MySQL Ping OK.\n");
+                        fprintf(stderr,"mysql_stat [%s]\n",mysql_stat(&aDbConnection->mhandle));        
+                    }
+                   returnvalue = True;
+               }  
+           }
+           break;
+       #endif /* HAVE_MYSQL*/
+    }
+    if (returnvalue==0) {
+       fprintf(stderr,"\n[%s]\n",aDbConnection->errormessage);
+       statusline("Database Ping Failed",1);
+       port_data[aDbConnection->interface_number].status = DEVICE_ERROR;
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* Tests a database connection and the underlying schema to see
+ * if the connection is open, the schema version is supported by
+ * this version of the code, and to see what permissions are 
+ * available */ 
+int testConnection(Connection *aDbConnection){
+    int returnvalue = True;
+    int dbreturn;
+    int major_version;
+    int minor_version;
+    char warning[100];
+
+    #ifdef HAVE_POSTGIS
+    ConnStatusType psql_status;
+    PGresult *result;
+    const char *postgis_sql = "SELECT COUNT(*) FROM geometry_columns";  // test to see if schema used in connection has postgis support added
+    #endif /* HAVE_POSTGIS */ 
+    if (aDbConnection==NULL)
+       return 0;
+    xastir_snprintf(warning, 100, " ");  // make sure warning is empty
+    switch (aDbConnection->type) {
+       #ifdef HAVE_POSTGIS
+       case DB_POSTGIS: 
+           returnvalue = False;
+           // is the connection open  [required]
+           if (aDbConnection->phandle!=NULL) { 
+                psql_status = PQstatus(aDbConnection->phandle);
+                if (psql_status!=CONNECTION_OK) { 
+                    xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Postgresql connection failed");
+                    fprintf(stderr, "PQstatus returned CONNECTION_BAD, probably unable to connect to server.\n");
+
+                } else { 
+                    fprintf(stderr, "PQstatus returned CONNECTION_OK.\n");
+                    // which version of postgresql are we running
+                    dbreturn = PQserverVersion(aDbConnection->phandle);
+                    major_version = dbreturn / 10000;
+                    minor_version =  (dbreturn - (major_version*10000)) / 100;
+                    fprintf(stderr,"Postgresql version [%d] %d.%d\n",dbreturn,major_version,minor_version);
+    
+                    // is the database spatially enabled [required]
+                    result = PQexec(aDbConnection->phandle,postgis_sql);
+                    if (result==NULL) { 
+                        // PQexec probably couldn't allocate memory for the result set.
+                        xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Null result: %s\n",PQerrorMessage(aDbConnection->phandle));
+                        fprintf(stderr, "testConnection() Null result\nPostgresql Error : %s\n",PQerrorMessage(aDbConnection->phandle));
+                    } else { 
+                        // PQexec returned a result, but it may not be valid, check to see.
+                        if (PQresultStatus(result)==PGRES_COMMAND_OK || PQresultStatus(result)==PGRES_TUPLES_OK) { 
+                            // PQexec returned a valid result set, meaning that a geometry_types table exists.
+                            
+    
+                            // are the needed tables present [required] 
+                            // check schema type (simple, simple+cad, full, aprsworld)
+                            // check version of database schema for compatability
+                            if (testXastirVersionPostgis(aDbConnection)==1) { 
+                                returnvalue = True;
+                            }
+                            // does the user have select privileges [required]
+                            // does the user have update privileges [optional] 
+                            // does the user have inesrt privileges [optional]
+                            // does the user have delete privileges [optional]
+                        } else { 
+                            // schema lacks a geometry_columns table, either schema or database lacks postgis support
+                            xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "No geometry_columns table found.  Is PostGIS installed and added to this schema?\n");
+                            xastir_snprintf(warning, 100, "No geometry_columns table found. PostGIS may not be installed, or the schema may not have PostGIS support added.");
+                            fprintf(stderr, "No geometry_columns table found.\nPostGIS may not be installed, or the schema may not have PostGIS support added.\n");
+                            fprintf(stderr, "Postgresql Error : %s\n",PQerrorMessage(aDbConnection->phandle));
+                        }
+                    }
+                }
+           }
+           break;
+       #endif /* HAVE_POSTGIS */
+       #ifdef HAVE_MYSQL_SPATIAL
+       case DB_MYSQL_SPATIAL: 
+           returnvalue = False;
+           // is the connection open  [required]
+           if (&aDbConnection->mhandle!=NULL) { 
+               // can we ping the server [required]
+               dbreturn = mysql_ping(&aDbConnection->mhandle);
+               if (dbreturn>0) { 
+                    mysql_interpret_error(dbreturn, aDbConnection);
+                    fprintf(stderr,"Ping of mysql server failed.\n");
+                    xastir_snprintf(warning, 100, "%s",aDbConnection->errormessage);
+
+               } else { 
+                   if (debug_level & 4096) {
+                       fprintf(stderr,"mysql_stat [%s]\n",mysql_stat(&aDbConnection->mhandle));        
+                   }
+                   // is the database spatially enabled [required]
+                   // determine from db version >= 4.2
+                   // MySQL 4.1 is past end of life, 4.2 at end of life but still in widespread use, e.g. RHEL4 (in early 2008).
+                   // mysql_server_version is new to mysql 4.1, prepared queries stabilized in 4.2
+                   dbreturn = mysql_get_server_version(&aDbConnection->mhandle);
+                   if (dbreturn>0) { 
+                       major_version = dbreturn / 10000;
+                       minor_version =  (dbreturn - (major_version*10000)) / 100;
+                       if (major_version>=5 || (major_version==4 && minor_version >=2)) {  
+                            fprintf(stderr,"MySQL Server version %d.%d OK.\n",major_version,minor_version);
+                            // check version of database schema for compatability
+                            dbreturn = testXastirVersionMysql(aDbConnection);
+                            if (dbreturn==1) {  
+                                fprintf(stderr,"Compatible Xastir database version found on server.\n");
+                           
+                                // are the needed tables present [required]
+                                // check schema type (simple, simple+cad, full, aprsworld)
+                                // does the user have select privileges [required]
+                                // does the user have update privileges [optional] 
+                                // does the user have insert privileges [optional]
+                                // does the user have delete privileges [optional] 
+                                returnvalue = True;
+                            } else { 
+                                 fprintf(stderr,"Xastir database version on server is not compatable with this version of Xastir.\n");
+                                 // aDbConnection->errormessage should have been set in testXastirVersionMysql
+                                 xastir_snprintf(warning, 100, "%s",aDbConnection->errormessage);
+                            }
+                        } else { 
+                            // version too low
+                            fprintf(stderr,"MySQL Server version %d.%d is too low and is not supported in Xastir.\n",major_version,minor_version);
+                            xastir_snprintf(warning, 100, "MySQL Server version %d.%d is too low and is not supported in Xastir.",major_version,minor_version);
+                        }
+                   } else {
+                      // ? mysql<4.1
+                   }
+               }
+           }
+           break;
+       #endif /* HAVE_MYSQL_SPATIAL */
+       #ifdef HAVE_MYSQL
+       case DB_MYSQL: 
+           // is the connection open  [required]
+           if (&aDbConnection->mhandle != NULL) { 
+                dbreturn = mysql_ping(&aDbConnection->mhandle);
+                if (dbreturn>0) { 
+                     mysql_interpret_error(dbreturn, aDbConnection);
+                } else { 
+                   if (debug_level & 4096) {
+                       fprintf(stderr,"mysql_stat [%s]\n",mysql_stat(&aDbConnection->mhandle));        
+                   }
+                   // is the database spatially enabled [optional]
+                   // determine from db version >= 4.1
+                   #ifdef HAVE_MYSQL_SPATIAL
+                   // mysql_server_version is new to mysql 4.1
+                   dbreturn = mysql_get_server_version(&aDbConnection->mhandle);
+                   #endif /* HAVE_MYSQL_SPATIAL */
+                    // are the needed tables present [required]
+                      // check schema type (simple, simple+cad, aprsworld)
+                      // full requires objects, not supported here.
+                      // check version of database schema for compatability
+                   dbreturn = testXastirVersionMysql(aDbConnection);
+                      // does the user have select privileges [required]
+                      // does the user have update privileges [optional] 
+                      // does the user have insert privileges [optional]
+                      // does the user have delete privileges [optional]
+                }
+           }
+           break;
+       #endif /* HAVE_MYSQL*/
+    }
+    if (returnvalue==0) { 
+       fprintf(stderr,"\n[%s]\n",aDbConnection->errormessage);
+       xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Incompatable schema: %s",warning); 
+       fprintf(stderr,"\n[%s]\n",aDbConnection->errormessage);
+       // Note: Don't close connection here, we haven't handed the error to the user yet.
+       //closeConnection(aDbConnection,-1);
+       fprintf(stderr,"\n[%s]\n",aDbConnection->errormessage);
+    }
+    return returnvalue;
+}
+
+
+
+
+// Layer 3: DBMS specific db storage code *************************************
+// Functions in this section should be local to this file and not exported
+// Export functions in section 2a above.  
+//
+// Layer 3a: DBMS specific GIS db storage code ********************************
+// Functions supporting queries to specific types of GIS enabled databasesa
+// 
+
+#ifdef HAVE_SPATIAL_DB
+
+#ifdef HAVE_POSTGIS
+// Postgis implementation of spatial database functions
+
+
+
+
+
+/* postgresql+postgis implementation of storeStationToGisDb().  */
+int storeStationToGisDbPostgis(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;
+    //ioparam *device = aDbConnection->descriptor;
+    // check type of schema to use (XASTIR simple, full or APRSWorld) 
+    switch (devices[aDbConnection->interface_number].database_schema_type) {
+        case XASTIR_SCHEMA_SIMPLE : 
+            returnvalue = storeStationSimplePointToGisDbPostgis(aDbConnection,aStation);
+            break;
+        case XASTIR_SCHEMA_APRSWORLD : 
+            break;
+        case XASTIR_SCHEMA_COMPLEX :
+            break;
+        // otherwise error message
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* postgresql+postgis implementation of storeCadToGisDb().  */
+int storeCadToGisDbPostgis(Connection *aDbConnection, CADRow *aCadObject) { 
+    int returnvalue = 0;
+
+    return returnvalue;
+}
+
+
+
+
+
+/* function storeStationSimplePointToGisDbPostgis()
+ * Postgresql/Postgis implementation of wrapper storeStationSimplePointToGisDb().
+ * Should only be called through wrapper function.  Do not call directly.
+ */
+int storeStationSimplePointToGisDbPostgis(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;  // Default return value is failure.
+    int ok;  // Holds results of tests when building query.
+    char wkt[MAX_WKT];  // well know text representation of latitude and longitude of point
+    char timestring[101];  // string representation of the time heard or the current time
+    char call_sign[(MAX_CALLSIGN*2)+1];  // temporary holding for escaped callsign
+    char aprs_symbol[2];  // temporary holding for escaped aprs symbol
+    char aprs_type[2];    // temporary holding for escaped aprs type
+    char special_overlay[2];  // temporary holding for escaped overlay
+    char origin[(MAX_CALLSIGN*2)+1]; // temporary holding for escaped origin
+    char node_path[(NODE_PATH_SIZE*2)+1];  // temporary holding for escaped node_path
+    char record_type[2];  // temporary holding for escaped record_type 
+    //PGconn *conn = aDbConnection->phandle;
+    PGresult *prepared = NULL;
+    PGresult *result = NULL;
+    int count;  // returned value from count query
+    const int PARAMETERS = 9;
+    // parameter arrays for prepared query
+    const char *paramValues[PARAMETERS];  
+    // To use native Postgres POINT for position instead of postgis geometry point.
+    //const Oid paramTypes[6] = { VARCHAROID, TIMESTAMPTZOID, POINTOID, VARCHAROID, VARCHAROID, VARCHAROID };
+    //const Oid paramTypes[6] = { 1043, 1184, 600, 1043, 1043, 1043 };
+    // Native postgres (8.2) geometries don't have spatial support as rich as Postgis extensions.
+    // use postgis geometry Point instead:
+    // lookup OID for geometry:  select OID from pg_type where typname = 'geometry'; returns 19480
+    //const Oid paramTypes[6] = { VARCHAROID, TIMESTAMPTZOID, 19480, VARCHAROID, VARCHAROID, VARCHAROID };
+    //const Oid paramTypes[6] = { 1043, 1184, 19480, 1043, 1043, 1043 };
+    // Value 18480 is probably installation specific, use unknownOID instead:
+    //const Oid paramTypes[9] = { VARCHAROID, TIMESTAMPTZOID, UNKNOWNOID, VARCHAROID, VARCHAROID, VARCHAROID, VARCHAROID, VARCHAROID, VARCHAROID };
+    const Oid paramTypes[9] = { 1043, 1184, 705, 1043, 1043, 1043, 1043, 1043, 1043 };
+    const char *sql = "insert into simpleStation (station, transmit_time, position, symbol, overlay, aprstype, origin, record_type, node_path) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)";
+    const char *StatementName = "InsertSimpleStation";
+    const char *StatementExists = "select count(*) from pg_prepared_statements where name = 'InsertSimpleStation'";
+
+   
+    if (debug_level & 4096) {
+        fprintf(stderr,"In postgres simple station insert\n");
+        fprintf(stderr,"with connection [%p] \n",aDbConnection);
+        fprintf(stderr,"connection->phandle [%p]\n",aDbConnection->phandle);        
+    }
+    if (aDbConnection->phandle==NULL) { 
+       fprintf(stderr,"Trying to save station on null postgresql connection\n");
+       return returnvalue;
+    }
+    if (PQserverVersion(aDbConnection->phandle)==0) {
+       // no connection to server
+       fprintf(stderr,"Trying to save station on closed postgresql connection\n");
+       return returnvalue;
+    }
+    if (debug_level & 4096) {
+        fprintf(stderr,"Postgresql version=%d\n",PQserverVersion(aDbConnection->phandle));
+    }
+
+    // Check to see if this prepared statement exists in the current session
+    // and create it if it does not.  
+    // Query adds connection overhead - should probably track with a global variable, 
+    // and query/recreate statment only on failure.  
+    ok = 0;
+    // pg_prepared_statements system view added in postgresql 8.2  
+    if (PQserverVersion(aDbConnection->phandle)>80199) { 
+        result = PQexec(aDbConnection->phandle, "select count(*) from pg_prepared_statements where name = 'InsertSimpleStation'");
+        result = PQexec(aDbConnection->phandle, StatementExists);
+        if (result==NULL) { 
+           fprintf(stderr,"Postgres Check for Prepared Query exec Failed: %s\n", PQerrorMessage(aDbConnection->phandle));
+           xastir_snprintf(aDbConnection->errormessage,MAX_CONNECTION_ERROR_MESSAGE,PQerrorMessage(aDbConnection->phandle));
+        } else {
+            count = 0;
+            if (PQresultStatus(result) == PGRES_TUPLES_OK) { 
+                count = atoi(PQgetvalue(result,0,0));
+            }
+            if (count==0) { 
+                // Statement doesn't exist, so prepare it, let PQprepare report on any error that got us a NULL result.
+                prepared = PQprepare(aDbConnection->phandle, StatementName, sql, PARAMETERS, paramTypes);
+                if (PQresultStatus(prepared)==PGRES_COMMAND_OK) { 
+                    ok = 1;
+                } else {
+                   // error condition - can't prepare statement
+                   fprintf(stderr,"Postgres Prepare Query Failed: %s\n", PQerrorMessage(aDbConnection->phandle));
+                   xastir_snprintf(aDbConnection->errormessage,MAX_CONNECTION_ERROR_MESSAGE,PQerrorMessage(aDbConnection->phandle));
+                   exit(1);
+    
+                }
+            } else if (count==1) { 
+                // prepared statement exists, we can go ahead with query.
+                ok = 1;
+            } else {
+                fprintf(stderr,"Postgres Check for Prepared Query getvalue (count=%d) failed: %s\n",count, PQresultErrorMessage(result));
+                xastir_snprintf(aDbConnection->errormessage,MAX_CONNECTION_ERROR_MESSAGE,PQresultErrorMessage(result));
+            }
+        }
+    } else { 
+        prepared = PQprepare(aDbConnection->phandle, StatementName, sql, PARAMETERS, paramTypes);
+        ok = 1;
+    }
+    if (ok==1) {
+        // native postgis POINT is (99.999 099.999) instead of POINT (99.999 099.999)
+        // ok = xastirCoordToLatLongPosgresPoint(aStation->coord_lon, aStation->coord_lat, wkt);
+        //
+        // Prepared query is ready, get and fill in the parameter values
+        // from the station provided, then fire the query.
+        ok = xastirCoordToLatLongWKT(aStation->coord_lon, aStation->coord_lat, wkt);
+        if (ok==1) { 
+            // Postgresql 8 documentation indicates that escape string should not be performed
+            // when calling PQexecParams or its sibling routines, not explicit, but implication
+            // is that PQexecPrepared with passed parameters is a sibling routine and we 
+            // shouldn't be running PQescapeStringConn() on the parameters.
+            // If used, form would be:
+            // PQescapeStringConn(conn,call_sign,aStation->call_sign,(MAX_CALLSIGN*2)+1,escape_error);
+            xastir_snprintf(call_sign,MAX_CALLSIGN+1,"%s",aStation->call_sign);
+            if (strlen(aStation->origin) > 0) { 
+                xastir_snprintf(origin,sizeof(origin),"%s",aStation->origin);
+            } else { 
+                xastir_snprintf(origin,1,"%c",'\0');
+            } 
+            xastir_snprintf(record_type,2,"%c",aStation->record_type);
+            if (aStation->node_path_ptr==NULL) { 
+                xastir_snprintf(node_path,2," ");
+            } else {  
+                xastir_snprintf(node_path,sizeof(node_path),"%s",aStation->node_path_ptr);
+            }   
+            if (debug_level & 4096) {
+               fprintf(stderr,"node_path   (12345678901234567890123456789012345678901234567890123456)\n"); 
+               fprintf(stderr,"node_path = [%s]\n",node_path); 
+            } 
+            // Get time in seconds, adjust to datetime
+            // If aStation is my station or another unset sec_heard is 
+            // encountered, use current time instead. Conversely, use time
+            // provided in sec_heard if sec_heard is an invalid time.
+            get_iso_datetime(aStation->sec_heard,timestring,True,False);
+
+            // set parameter values to call, transmit_time, and position
+            paramValues[0]=call_sign;
+            paramValues[1]=timestring;
+            paramValues[2]=wkt;
+            if (aStation->aprs_symbol.aprs_symbol==NULL) { 
+                xastir_snprintf(aprs_symbol,2," ");
+                paramValues[3]=&aprs_symbol;
+            } else { 
+                xastir_snprintf(aprs_symbol,2,"%c",aStation->aprs_symbol.aprs_symbol);
+                paramValues[3]=aprs_symbol;
+            }
+            if (aStation->aprs_symbol.special_overlay==NULL) { 
+                xastir_snprintf(special_overlay,2," ");
+                paramValues[4]=&special_overlay;
+            } else { 
+                xastir_snprintf(special_overlay,2,"%c",aStation->aprs_symbol.special_overlay);
+                paramValues[4]=&special_overlay;
+            }
+            if (aStation->aprs_symbol.aprs_type==NULL) { 
+                xastir_snprintf(aprs_type,2," ");
+                paramValues[5]=&aprs_type;
+            } else { 
+                xastir_snprintf(aprs_type,2,"%c",aStation->aprs_symbol.aprs_type);
+                paramValues[5]=aprs_type;
+            }
+            paramValues[6]=origin;
+            paramValues[7]=record_type;
+            paramValues[8]=node_path;
+
+            if (debug_level & 4096)  {
+                 fprintf(stderr,"Inserting: Call: %s, Time: %s, Position: %s, Symbol:%s,%s,%s Origin:%s, Node_path:%s, Record type:%s\n",paramValues[0],paramValues[1],paramValues[2],paramValues[3],paramValues[4],paramValues[5],paramValues[6],paramValues[8],paramValues[7]);
+            }
+       
+            // send query
+            result = PQexecPrepared(aDbConnection->phandle,StatementName,PARAMETERS,paramValues,NULL,NULL,POSTGRES_RESULTFORMAT_TEXT);
+            if (PQresultStatus(result)!=PGRES_COMMAND_OK) { 
+                   fprintf(stderr,"Postgres Insert query failed:%s\n",PQresultErrorMessage(result));
+                   // error, get error message.
+                   xastir_snprintf(aDbConnection->errormessage,MAX_CONNECTION_ERROR_MESSAGE,PQresultErrorMessage(result));
+            } else { 
+                 // query was successfull
+                returnvalue=1;
+            }    
+        } else { 
+            // problem with coordinates of station 
+            fprintf(stderr,"Unable to save station to Postgres db, Error converting latitude or longitude from xastir coordinates\n");                   
+            xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Error converting latitude or longitude from xastir coordinates: %ld,%ld",aStation->coord_lat,aStation->coord_lon);
+        }
+    }
+    if (result!=NULL) 
+        PQclear(result);
+    if (prepared!=NULL)
+        PQclear(prepared);
+    return returnvalue;
+}
+
+
+
+
+
+/* function testXastirVersionPostgis()
+ * Postgresql/Postgis implementation of wrapper testXastirVersionPostgis().
+ * Should only be called through wrapper function.  Do not call directly.
+ */
+int testXastirVersionPostgis(Connection *aDbConnection) {
+    int returnvalue = 0;
+    int version_number;
+    int compatable_series;
+    const char sql[100] = "select version_number, compatable_series from version order by version_number desc limit 1";  
+    PGresult *result;
+    PGconn *conn = aDbConnection->phandle;
+    
+    result = PQexec(conn,sql);
+    if (result==NULL) { 
+        // PQexec probably couldn't allocate memory for the result set.
+        xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Null result: %s\n",PQerrorMessage(conn));
+        fprintf(stderr, "testXastirVersionPostgis() Null result\nPostgresql Error : %s\n",PQerrorMessage(conn));
+    } else { 
+        // PQexec returned a result, but it may not be valid, check to see.
+        if (PQresultStatus(result)==PGRES_COMMAND_OK || PQresultStatus(result)==PGRES_TUPLES_OK) { 
+            if (PQntuples(result)!=1) { 
+                fprintf(stderr,"Version table doesn't appear to contain any rows.\n");
+                xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Version table doesn't appear to contain any rows.");
+            } else { 
+                version_number = atoi(PQgetvalue(result,0,0));
+                compatable_series = atoi(PQgetvalue(result,0,1));
+                if (version_number == XASTIR_SPATIAL_DB_VERSION) { 
+                    returnvalue = 1;
+                } else { 
+                    if (version_number < XASTIR_SPATIAL_DB_VERSION && compatable_series == XASTIR_SPATIAL_DB_COMPATABLE_SERIES) {
+                        returnvalue = 1;
+                        fprintf(stderr,"Version in schema (%d) is compatible with this version of xastir (%d).\n",version_number,XASTIR_SPATIAL_DB_VERSION);
+                    } else { 
+                        fprintf(stderr,"Version in schema (%d) is not compatible with this version of xastir (%d).\n",version_number,XASTIR_SPATIAL_DB_VERSION);
+                        xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Version in schema (%d) is not compatible with this version of xastir (%d).",version_number,XASTIR_SPATIAL_DB_VERSION);
+                        fprintf(stderr,"%s",aDbConnection->errormessage);
+                        returnvalue = 0;
+                    }
+
+                }
+            }
+
+        }
+        PQclear(result);
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* function getAllSimplePositionsPostgis()
+ * Postgresql/Postgis implementation of wrapper getAllSimplePositions().
+ * Should only be called through wrapper function.  Do not call directly.
+ */
+int getAllSimplePositionsPostgis(Connection *aDbConnection) {
+    int returnvalue = 0;  // value to return from function, 1 for success, 0 for failure
+    int row;  // row counter for result set loop
+    int station_count = 0;  // number of new stations retrieved
+    unsigned long x;  // xastir coordinate for longitude
+    unsigned long y;  // xastir coordinate for latitide
+    unsigned long u_long;
+    unsigned long u_lat;
+    char *s_lat[13];  // string latitude
+    char *s_lon[13];  // string longitude
+    float lat;  // latitude converted from retrieved string
+    float lon;  // longitude converted from retrieved string
+    const char *sql = "select station, symbol, overlay, aprstype, transmit_time, AsText(position), origin, record_type, node_path, X(position), Y(position) from simpleStation order by station, transmit_time asc";
+    // station is column 0, symbol is column 1, etc.
+    PGconn *conn = aDbConnection->phandle;
+    char feedback[100];
+    char lastcall[MAX_CALLSIGN+1];  //holds last retrieved callsign
+    int  exists;            //shortcut to skip db check if currently retrieved callsign equals last retrieved callsign
+    DataRow *p_new_station;  // pointer to new station record  
+    DataRow *p_time;  // pointer to new station record  
+    int skip;
+    int points_this_station;  // number of times this station has been heard.
+    char empty[MAX_ALTITUDE];
+    struct tm time;
+    time_t sec;
+    empty[0]='\0';
+    xastir_snprintf(feedback,100,"Retrieving Postgis records\n");
+    stderr_and_statusline(feedback);
+    //fprintf(stderr,"connection->phandle [%p]\n",aDbConnection->phandle);        
+    // run query and retrieve result set
+    PGresult *result = PQexec(conn,sql);
+
+    if (result==NULL) { 
+       // PQexec probably couldn't allocate memory for the result set.
+       xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Null result: %s\n",PQerrorMessage(conn));
+       fprintf(stderr, "getAllSimplePositionsPostgis() Null result\nPostgresql Error : %s\n",PQerrorMessage(conn));
+    } else { 
+       // PQexec returned a result, but it may not be valid, check to see.
+       if (PQresultStatus(result)==PGRES_COMMAND_OK || PQresultStatus(result)==PGRES_TUPLES_OK) { 
+          // PQexec returned a valid result set.
+          xastir_snprintf(feedback,100,"Retrieving %i Postgis records\n",PQntuples(result));
+          stderr_and_statusline(feedback);
+          xastir_snprintf(lastcall,MAX_CALLSIGN+1," ");
+          points_this_station = 0;
+          for (row=0; row<PQntuples(result); row++) {
+              // step through rows in result set and add each to xastir db as a minimal DataRow
+              if (PQgetisnull(result,row,0)) {
+                  // station name is null, skip.
+              } else {
+                  // check if station exists
+                  p_new_station = NULL;
+                  exists = 0;
+                  // Shortcut check to see if this station has been loaded already
+                  // works as returned rows are ordered by station.
+                  // TODO: add_simple_station will not update the linked list of station properly, 
+                  // when data from more than one database for the same station is loaded
+                  // and a more recently loaded database contains station data with timestamps
+                  // older than the timestamp from a previously loaded database.
+                  // This shows up as search_station_name failing to locate 
+                  // existing stations and stations not being found on station info 
+                  // (because they have expired from the list).
+                  // This will also be a problem if old data for stations heard live are
+                  // retrieved from a database while xastir is running.   
+                  if (strcmp(PQgetvalue(result,row,0),lastcall)==0) { 
+                      points_this_station++;
+                      exists = 1;
+                  } else {  
+                      if (search_station_name(&p_new_station,PQgetvalue(result,row,0),1)) {  
+                          points_this_station++;
+                          exists = 1;
+                      } else { 
+                          points_this_station=1;
+                      }
+                  }
+                  xastir_snprintf(lastcall,MAX_CALLSIGN+1,PQgetvalue(result,row,0));
+                  if (exists==1) {
+                       // This station allready exists as a DataRow in the xastir db.
+                       // Don't create a duplicate record, but add to the DataRow's track.
+
+                       //  check if it is a mobile station        
+                       // We can't easily identify mobile stations from position position
+                       // becaue of rounding errors, therefore exclude stations that are likely to be fixed.
+                       // _/ = wx
+                       skip = 0;
+                       if ((PQgetvalue(result,row,1)[0]=='_') && (PQgetvalue(result,row,3)[0]=='/')) { 
+                           skip = 1;   // wx
+                       }
+                       if ((PQgetvalue(result,row,1)[0]=='-') && (PQgetvalue(result,row,3)[0]=='/')) { 
+                           skip = 1;   // house
+                       }
+
+
+                       if (skip==0) { 
+                           // add to track
+                           if (search_station_name(&p_new_station,PQgetvalue(result,row,0),1)) { 
+                               if (points_this_station<3) { 
+                                   //existing station record needs to be added as a trailpoint
+                                   (void)store_trail_point(p_new_station, p_new_station->coord_lon, p_new_station->coord_lat, p_new_station->sec_heard, empty, empty, empty, 0);
+                               }
+
+                               // store this trail point
+                               lat = atof(PQgetvalue(result,row,10)); 
+                               lon = atof(PQgetvalue(result,row,9)); 
+                               if (strlen(PQgetvalue(result,row,4)) > 0) {
+                                   strptime(PQgetvalue(result,row,4), "%Y-%m-%d %H:%M:%S%z", &time);
+                                   sec = mktime(&time);
+                               }
+                               if(convert_to_xastir_coordinates( &u_long, &u_lat, lon, lat)) 
+                                   (void)store_trail_point(p_new_station, u_long, u_lat, sec, empty, empty, empty, 0);
+
+                               if (p_new_station->sec_heard < sec) { 
+                                   // update the station record to this position
+                                   if(convert_to_xastir_coordinates(&u_long, &u_lat, lon, lat)) { 
+                                       p_new_station->coord_lat = u_lat;
+                                       p_new_station->coord_lon = u_long;
+                                       p_new_station->sec_heard = sec;
+                                   }
+                               }
+                           }    
+                       }
+
+                  } else { 
+                       // This station isn't in the xastir db. 
+                       //int add_simple_station(DataRow *p_new_station,char *station, char *origin, char *symbol, char *overlay, char *aprs_type, char *latitude, char *longitude, char *record_type, char *node_path, char *transmit_time) { 
+                       //const char *sql = "select station, symbol, overlay, aprstype, transmit_time, AsText(position), origin, record_type, node_path, X(position), Y(position) from simpleStation order by station, transmit_time asc";
+                       add_simple_station(p_new_station,PQgetvalue(result,row,0), PQgetvalue(result,row,6), PQgetvalue(result,row,1), PQgetvalue(result,row,2), PQgetvalue(result,row,3), PQgetvalue(result,row,10), PQgetvalue(result,row,9), PQgetvalue(result,row,7), PQgetvalue(result,row,8), PQgetvalue(result,row,4), POSTGIS_TIMEFORMAT);
+                    
+                       station_count ++;
+                  }  // end else, new station
+              } // end else, station is not null 
+          } // end for loop stepping through rows
+          redo_list = (int)TRUE;      // update active station lists
+          xastir_snprintf(feedback,100,"Added %d stations from Postgis\n",station_count);
+          stderr_and_statusline(feedback);
+       } else {       
+           // sql query had a problem retrieving result set.
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "%s %s\n",PQresStatus(PQresultStatus(result)),PQerrorMessage(conn));
+           fprintf(stderr, "getAllSimplePositionsPostgis() %s\nPostgresql Error : %s\n",PQresStatus(PQresultStatus(result)),PQerrorMessage(conn));
+       }
+       // done with result set, so free the resource.
+       PQclear(result);
+    } 
+    return returnvalue;
+}
+
+
+
+
+
+/* function getAllSimplePositionsPostgisInBoundingBox()
+ * Postgresql/Postgis implementation of wrapper getAllSimplePositionsInBoundingBox().
+ * Should only be called through wrapper function.  Do not call directly.
+ */
+int getAllSimplePositionsPostgisInBoundingBox(Connection *aDbConnection, char* str_e_long, char* str_w_long, char* str_n_lat, char* str_s_lat) {
+    int returnvalue = 0;
+    // set up prepared query with bounding box 
+    // postgis simple table uses POINT
+    char sql[100] = "select call, transmit_time, position from simpleStation where ";  
+    PGconn *conn = aDbConnection->phandle;
+   
+
+    return returnvalue;
+}
+
+
+
+
+#endif /* HAVE_POSTGIS */
+
+#ifdef HAVE_MYSQL_SPATIAL
+// Mysql 5 implementation of spatial database functions
+
+
+
+
+
+/* function storeStationToGisDbMysql
+ * MySQL implemenation of storeStationToGisDb
+ * Should be private to db_gis.c 
+ * Should only be called through wrapper function.  Do not call directly.
+ * @param aDbConnection an exastir database connection struct describing
+ * the connection.
+ * @param aStation
+ * Returns 0 for failure, 1 for success.  
+ * If failure, stores error message in aDbConnection->errormessage.
+ */
+int storeStationToGisDbMysql(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;
+    //ioparam *device = aDbConnection->descriptor;
+    // check type of schema to use (XASTIR simple, full or APRSWorld) 
+    switch (devices[aDbConnection->interface_number].database_schema_type) {
+        case XASTIR_SCHEMA_SIMPLE : 
+            returnvalue = storeStationSimplePointToGisDbMysql(aDbConnection,aStation);
+            break;
+        case XASTIR_SCHEMA_APRSWORLD : 
+            break;
+        case XASTIR_SCHEMA_COMPLEX :
+            break;
+        // otherwise error message
+    }
+    return returnvalue;
+}
+
+
+
+
+
+
+/* function storeCadToGisDbMysql
+ * MySQL implementation of storeCadToGisDbMysql
+ * Should be private to db_gis.c 
+ * Should only be called through wrapper function.  Do not call directly.
+ * @param aDbConnection an exastir database connection struct describing
+ * the connection.
+ * @param aCadObject
+ * Returns 0 for failure, 1 for success.  
+ * If failure, stores error message in aDbConnection->errormessage.
+ */
+int storeCadToGisDbMysql(Connection *aDbConnection, CADRow *aCadObject) { 
+    int returnvalue = 0;
+   
+    return returnvalue;
+}
+
+
+
+
+
+
+/* support function for prepared statements
+int bind_mysql_string_parameter(MYSQL_BIND *bind, int bind_number, char* buffer, int provided_length, int buffer_length, my_bool is_null) {
+       bind[bind_number]->buffer = buffer;
+       bind[bind_number]->length = provided_length;
+       bind[bind_number]->buffer_length = buffer_length;
+       bind[bind_number]->buffer_type = MYSQL_TYPE_STRING
+       bind[bind_number]->is_null = is_null;
+}
+*/
+
+
+
+
+
+/* function storeStationSimplePointToGisDbMysql()
+ * MySQL implementation of wrapper storeStationSimplePointToGisDb().
+ * Should be private to db_gis.c 
+ * Should only be called through wrapper function.  Do not call directly.
+ * @param aDbConnection an xastir database connection struct describing
+ * the connection.
+ * @param aStation
+ * Returns 0 for failure, 1 for success.  
+ * On failure sets error message in aDbConnection->errormessage.
+ */
+int storeStationSimplePointToGisDbMysql(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;
+    int mysqlreturn;  // hold return value of mysql query
+    int param_count;  // check on the number of parameters present in the prepared statement
+    int ok;    // variable to store results of tests preparatory to firing query
+    // temporary holding variables for bind buffers
+    char wkt[MAX_WKT];  // well know text representation of latitude and longitude of point
+    char aprs_symbol[2];  // temporary holding for escaped aprs symbol
+    char aprs_type[2];    // temporary holding for escaped aprs type
+    char special_overlay[2];  // temporary holding for escaped overlay
+    char record_type[2];              // temporary holding for escaped record type
+    char origin[MAX_CALLSIGN+1];  // temporary holding for escaped origin
+    char node_path[NODE_PATH_SIZE+1];         // temporary holding for escaped node_path_ptr
+    MYSQL_STMT *statement;
+    // bind string lengths
+    unsigned long call_sign_length;
+    unsigned long wkt_length;
+    unsigned long aprs_symbol_length;
+    unsigned long aprs_type_length;
+    unsigned long special_overlay_length;
+    unsigned long origin_length;
+    unsigned long record_type_length;
+    unsigned long node_path_length;
+    // time
+    MYSQL_TIME timestamp;
+    char timestring[100+1];
+    time_t secs_now;
+    struct tm *ts;  // to convert time to component parts for bind.buffer_type MYSQL_TYPE_DATETIME
+    // define prepared statement and matching bind array
+    #define SQL "INSERT INTO simpleStationSpatial (station, transmit_time, position, symbol, overlay, aprstype, origin, record_type, node_path) VALUES (?,?,PointFromText(?),?,?,?,?,?,?)"
+    MYSQL_BIND bind[9];   // bind array for prepared query.
+    int parameters = 9;
+    // Note:
+    // bind[9], SQL "?????????", and param_count must all match value of parameters
+    // nine bound parameters, nine question marks in the statement, and param_count returned as nine.
+
+    if (debug_level & 4096) {
+        fprintf(stderr,"in storeStationSimplePointToGisDbMysql\n");    
+        fprintf(stderr,"with connection [%p] \n",aDbConnection);
+    }
+    
+    if (&aDbConnection->mhandle==NULL) 
+       return returnvalue;
+
+    statement = mysql_stmt_init(&aDbConnection->mhandle);
+    if (!statement) { 
+       fprintf(stderr,"Unable to create mysql prepared statement.  May be out of memmory.\n");    
+    }
+    mysql_stmt_prepare(statement, SQL, strlen(SQL));
+    if (!statement) { 
+        mysql_interpret_error(*mysql_error(&aDbConnection->mhandle),aDbConnection);
+    } else { 
+       // test to make sure that statement has the correct number of parameters
+       param_count=mysql_stmt_param_count(statement);
+       if (param_count!=parameters) { 
+           fprintf(stderr,"Number of bound parameters %d does not match expected value %d\nFor query[%s]",param_count,parameters,SQL);
+           fprintf(stderr, " %s\n", mysql_stmt_error(statement));
+       } else {
+           // set up the buffers 
+           memset(bind, 0, sizeof(bind));
+
+           bind[0].buffer =  (char *)&aStation->call_sign;
+           bind[0].length = &call_sign_length;
+           bind[0].buffer_length = MAX_CALLSIGN;
+           bind[0].buffer_type = MYSQL_TYPE_STRING;
+           bind[0].is_null = 0;
+
+           bind[1].buffer = (char *)×tamp;
+           bind[1].length = 0;
+           bind[1].buffer_type = MYSQL_TYPE_DATETIME;
+           bind[1].is_null = 0;
+
+           bind[2].buffer = (char *)&wkt;
+           bind[2].length = &wkt_length;
+           bind[2].buffer_length = MAX_WKT;
+           bind[2].buffer_type = MYSQL_TYPE_STRING;
+           bind[2].is_null = 0;
+
+           bind[3].buffer = (char *)&aprs_symbol;
+           bind[3].length = &aprs_symbol_length;
+           bind[3].buffer_length = 2;
+           bind[3].buffer_type = MYSQL_TYPE_STRING;
+           bind[3].is_null = 0;
+
+           bind[4].buffer = (char *)&special_overlay;
+           bind[4].length = &special_overlay_length;
+           bind[4].buffer_length = 2;
+           bind[4].buffer_type = MYSQL_TYPE_STRING;
+           bind[4].is_null = 0;
+
+           bind[5].buffer = (char *)&aprs_type;
+           bind[5].length = &aprs_type_length;
+           bind[5].buffer_length = 2;
+           bind[5].buffer_type = MYSQL_TYPE_STRING;
+           bind[5].is_null = 0;
+
+           bind[6].buffer = (char *)&origin;  // segfaults with origin of zero length, otherwise writes bad data
+           bind[6].length = &origin_length;
+           bind[6].buffer_length = MAX_CALLSIGN;
+           bind[6].buffer_type = MYSQL_TYPE_STRING;
+           bind[6].is_null = 0;
+
+           bind[7].buffer = (char *)&record_type;
+           bind[7].length = &record_type_length;
+           bind[7].buffer_length = 2;
+           bind[7].buffer_type = MYSQL_TYPE_STRING;
+           bind[7].is_null = 0;
+
+           bind[8].buffer = (char *)&node_path; 
+           bind[8].length = &node_path_length;
+           bind[8].buffer_length = NODE_PATH_SIZE;
+           bind[8].buffer_type = MYSQL_TYPE_STRING;
+           bind[8].is_null = 0;
+
+           ok = mysql_stmt_bind_param(statement,bind);
+           if (ok!=0) { 
+               fprintf(stderr,"Error binding parameters to mysql prepared statement.\n");                   
+               mysql_interpret_error(mysql_errno(&aDbConnection->mhandle),aDbConnection);
+               fprintf(stderr,mysql_stmt_error(statement));
+           } else { 
+
+               // get call, time, and position
+               // call is required
+               if (aStation->call_sign!=NULL && strlen(aStation->call_sign)>0) { 
+                   call_sign_length = strlen(aStation->call_sign);
+        
+                   // get time in seconds, adjust to datetime
+                   // If my station or another unset sec_heard is 
+                   // encountered, use current time instead, use time
+                   // provided if it was invalid.
+                   get_iso_datetime(aStation->sec_heard,timestring,True,False);
+                   if ((int)aStation->sec_heard==0 ) { 
+                       secs_now = sec_now();
+                       ts = localtime(&secs_now);
+                   } else { 
+                       ts = localtime(&aStation->sec_heard);
+                   }
+                   timestamp.year = ts->tm_year + 1900;  // tm_year is from 1900
+                   timestamp.month = ts->tm_mon + 1;     // tm_mon is from 0
+                   timestamp.day = ts->tm_mday;          // tm_mday is from 1
+                   timestamp.hour = ts->tm_hour;
+                   timestamp.minute = ts->tm_min;
+                   timestamp.second = ts->tm_sec;
+                   ok = xastirCoordToLatLongWKT(aStation->coord_lon, aStation->coord_lat, wkt);
+                   if (ok==1) { 
+                       wkt_length = strlen(wkt);
+
+
+                       if (aStation->aprs_symbol.aprs_symbol) { 
+                           xastir_snprintf(aprs_symbol,2,"%c",aStation->aprs_symbol.aprs_symbol);
+                       } else { 
+                           xastir_snprintf(aprs_symbol,2,"%c",'\0');
+                       }
+                       aprs_symbol_length = strlen(aprs_symbol);
+
+                       if (aStation->aprs_symbol.aprs_type) { 
+                           xastir_snprintf(aprs_type,2,"%c",aStation->aprs_symbol.aprs_type);
+                       } else { 
+                           xastir_snprintf(aprs_type,2,"%c",'\0');
+                       }
+                       aprs_type_length = strlen(aprs_type);
+
+                       if (aStation->aprs_symbol.special_overlay) { 
+                           xastir_snprintf(special_overlay,2,"%c",aStation->aprs_symbol.special_overlay);
+                       } else { 
+                           xastir_snprintf(special_overlay,2,"%c",'\0');
+                       }
+                       special_overlay_length = strlen(special_overlay);
+
+                       if (aStation->origin) { 
+                           xastir_snprintf(origin,MAX_CALLSIGN+1,"%s",aStation->origin);
+                       } else { 
+                           //xastir_snprintf(origin,2,"%c",'\0');
+                           origin[0]='\0';
+                       }
+                       origin_length = strlen(origin);
+
+                       if (aStation->record_type) { 
+                           xastir_snprintf(record_type,2,"%c",aStation->record_type);
+                       } else { 
+                           //xastir_snprintf(record_type,2,"%c",'\0');
+                           record_type[0]='\0';
+                       }
+                       record_type_length = strlen(record_type);
+                       
+                       if (aStation->node_path_ptr) { 
+                            if (debug_level & 4096) {
+                                fprintf(stderr,"node_path   (12345678901234567890123456789012345678901234567890123456)\n"); 
+                                fprintf(stderr,"node_path = [%s]\n",aStation->node_path_ptr); 
+                           }
+                           xastir_snprintf(node_path,NODE_PATH_SIZE+1,"%s",aStation->node_path_ptr);
+                       } else { 
+                           //xastir_snprintf(node_path,2,"%c",'\0');
+                           node_path[0]='\0';
+                       }
+                       node_path_length = strlen(node_path);
+
+                       // all the bound parameters should be available and correct
+                       if (debug_level & 4096) 
+                          fprintf(stderr,"saving station %s  %d %d %d %d:%d:%d wkt=%s [%s][%s][%s] \n",aStation->call_sign,ts->tm_year,ts->tm_mon,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec,wkt,aprs_type,aprs_symbol,record_type);
+                       // send query
+                       mysqlreturn = mysql_stmt_execute(statement);
+                       if (mysqlreturn!=0) { 
+                           returnvalue=0;
+                           fprintf(stderr,"%s\n",mysql_stmt_error(statement));
+                           mysql_interpret_error(mysqlreturn,aDbConnection);
+                       } else {
+                           returnvalue=1;
+                       }
+                   } else { 
+                        fprintf(stderr,"Unable to save station to mysql db, Error converting latitude or longitude from xastir coordinates\n");                   
+                        xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Error converting latitude or longitude from xastir coordinates: %ld,%ld",aStation->coord_lat,aStation->coord_lon);
+                   }
+               } else { 
+                   // set call not null error message
+                   fprintf(stderr,"Unable to save station to mysql db, Station call sign was blank or null.\n");                   
+                   xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Station callsign is required and was blank or null.");
+               }
+           } // end of bind check
+       }  // end of parameter count check
+    }
+    mysql_stmt_free_result(statement); 
+    mysql_stmt_close(statement);
+    if (returnvalue==0) { 
+        pingConnection(aDbConnection);
+    }
+
+    return returnvalue;
+}
+
+
+
+
+
+
+int getAllSimplePositionsMysqlSpatial(Connection *aDbConnection) {
+    int returnvalue = 0;
+    DataRow *p_new_station;
+    int station_count = 0;  // number of new stations retrieved
+    char *s_lat[13];  // string latitude
+    char *s_lon[13];  // string longitude
+    float lat;  // latitude converted from retrieved string
+    float lon;  // longitude converted from retrieved string
+    unsigned long u_lat;
+    unsigned long u_long;
+    int points_this_station;
+    char feedback[100];
+    struct tm time;
+    time_t sec;
+    int skip; // used in identifying mobile stations
+    char sql[] = "select station, transmit_time, AsText(position), symbol, overlay, aprstype, origin, record_type, node_path from simpleStationSpatial order by station, transmit_time asc";
+    char lastcall[MAX_CALLSIGN+1];  //holds last retrieved callsign
+    int  exists;            //shortcut to skip db check if currently retrieved callsign equals last retrieved callsign
+    MYSQL_RES *result;
+    MYSQL_ROW row;
+    char empty[MAX_ALTITUDE];
+    int ok;   // to hold mysql_query return value
+    empty[0]='\0';
+    ok = mysql_query(&aDbConnection->mhandle,sql);
+    if (ok==0) { 
+        result = mysql_use_result(&aDbConnection->mhandle);
+        if (result!=NULL) { 
+            xastir_snprintf(feedback,100,"Retrieving MySQL records\n");
+            stderr_and_statusline(feedback);
+            // with mysql_use_result each call to mysql_fetch_row retrieves
+            // a row of data from the server.  Mysql_store_result might use
+            // too much memory in retrieving a large result set all at once.
+            xastir_snprintf(lastcall,MAX_CALLSIGN+1," ");
+            points_this_station=0;
+            while ((row = mysql_fetch_row(result))) { 
+               // retrieve data from the row
+               // test to see if this is a valid station
+               if (row[0]==NULL) { 
+                  // station is null, skip
+               } else { 
+                  p_new_station = NULL;
+                  exists = 0;
+                  // Shortcut check to see if station has allready been heard
+                  // works as query is ordered by station.
+                  if (strcmp(lastcall,row[0])==1) { 
+                      exists = 1;
+                          points_this_station++;
+                  } else { 
+                      if (search_station_name(&p_new_station,row[0],1)) {  
+                          exists = 1;
+                          points_this_station++;
+                      } else {
+                          points_this_station=1;
+                      }
+                  }
+                  xastir_snprintf(lastcall,MAX_CALLSIGN+1,row[0]);
+                  if (exists==1) {
+                       // This station is allready in present as a DataRow in the xastir db.
+                       // check to see if this is likely to be a mobile station 
+
+                       // We can't easily identify mobile stations from position position
+                       // becaue of rounding errors, therefore exclude stations that are likely to be fixed.
+                       // _/ = wx
+                       skip = 0;
+                       if ((strcmp(row[3],"_")==0) & (strcmp(row[5],"/")==0)) { 
+                           skip = 1;   // wx
+                       }
+                       if ((strcmp(row[3],"-")==0) & (strcmp(row[5],"/")==0)) { 
+                           skip = 1;   // house
+                       }
+
+                       if (skip==0) { 
+                           // add to track
+
+                           if (search_station_name(&p_new_station,row[0],1)) { 
+                               if (points_this_station<3) { 
+                                   //existing station record needs to be added as a trailpoint
+                                   (void)store_trail_point(p_new_station, p_new_station->coord_lon, p_new_station->coord_lat, p_new_station->sec_heard, empty, empty, empty, 0);
+                               }
+                               // store this trail point
+                               lat = xastirWKTPointToLatitude(row[2]); 
+                               lon = xastirWKTPointToLongitude(row[2]); 
+                               if (strlen(row[1]) > 0) {
+                                   strptime(row[1], "%Y-%m-%d %H:%M:%S", &time);
+                                   sec = mktime(&time);
+                                   //fprintf(stderr,"trailpoint time:  %ld  [%s]\n", sec, row[1]);      
+                               }
+                               if(convert_to_xastir_coordinates( &u_long, &u_lat, lon, lat)) {
+                                   (void)store_trail_point(p_new_station, u_long, u_lat, sec, empty, empty, empty, 0);
+                               }
+                               if (p_new_station->sec_heard < sec) { 
+                                   // update the station record to this position
+                                   if(convert_to_xastir_coordinates(&u_long, &u_lat, lon, lat)) { 
+                                       p_new_station->coord_lat = u_lat;
+                                       p_new_station->coord_lon = u_long;
+                                       p_new_station->sec_heard = sec;
+                                   }
+                               } 
+                           } // search_station_name    
+                       }  // !skip
+                  } else { 
+                       // This station isn't in the xastir db. 
+                       // Add a datarow using the retrieved station record from the postgis database.
+                       lat = xastirWKTPointToLatitude(row[2]); 
+                       lon = xastirWKTPointToLongitude(row[2]); 
+                       xastir_snprintf(s_lat,13,"%3.6f",lat);
+                       xastir_snprintf(s_lon,13,"%3.6f",lon);
+                       add_simple_station(p_new_station, row[0], row[6], row[3], row[4], row[5], s_lat, s_lon, row[7], row[8], row[1],(char*)MYSQL_TIMEFORMAT);
+
+                       station_count++;
+                  }
+               }
+            }
+        } else { 
+            // error fetching the result set
+            fprintf(stderr,"mysql error: %s\n",mysql_error(&aDbConnection->mhandle));
+            mysql_interpret_error(mysql_errno(&aDbConnection->mhandle),aDbConnection);
+        }
+        xastir_snprintf(feedback,100,"Retreived %d new stations from MySQL\n",station_count);
+        stderr_and_statusline(feedback);
+        mysql_free_result(result);
+    } else { 
+       // query didn't execute correctly
+       mysql_interpret_error(ok,aDbConnection);
+    }
+
+    return returnvalue;
+}
+
+
+
+
+
+
+int getAllCadFromGisDbMysql(Connection *aDbConnection) { 
+    int returnvalue = 0;
+    int mysqlreturn;
+    MYSQL *conn = &aDbConnection->mhandle;
+     
+    return returnvalue;
+}
+
+
+
+
+
+int getAllSimplePositionsMysqlSpatialInBoundingBox(Connection *aDbConnection, char* str_e_long, char* str_w_long, char* str_n_lat, char* str_s_lat) {
+    int returnvalue = 0;
+    int mysqlreturn;
+    MYSQL *conn = &aDbConnection->mhandle;
+     
+    return returnvalue;
+
+}
+
+
+
+
+/* 
+
+  // some thoughts on database schema elements
+
+  create database xastir;
+  grant select on xastir to user xastir_user at localhost identified by encrypted password '<password>';
+  
+  create table version (
+     version_number int,
+     compatable_series int
+  );
+  grant select on version to xastir_user at localhost
+  insert into version (version_number) values (XASTIR_SPATIAL_DB_VERSION);
+  insert into version (version_number) values (XASTIR_SPATIAL_DB_COMPATIBLE_SERIES);
+
+  # should be minimum fields needed to populate a DataRow and a related 
+  # APRS_Symbol in xastir 
+  create table simpleStation (
+     simpleStationId int primary key not null auto_increment
+     station varchar(MAX_CALLSIGN) not null,  # callsign of station, length up to max_callsign
+     symbol varchar(1),     # aprs symbol character
+     overlay varchar(1),    # aprs overlay table character
+     aprstype varchar(1),    # aprs type, required???
+     transmit_time datetime not null default now(),  # transmission time, if available, otherwise storage time
+     position POINT   # position of station or null if latitude and longitude are not available
+  );
+
+                                                                          
+
+  grant select, insert on simpleStation to xastir_user at localhost;
+
+
+  create table datarow (
+      datarow_id int not null primary key auto_increment,
+      call_sign varchar(10) not null,
+      tactical_call_sign varchar() not null default '',
+      c_aprs_symbol_id int 
+      location POINT,
+      time_sn int,
+      sec_heard long,
+      heard_via_tnc_last_time long,
+      direct_heard long,
+      packet_time varchar,
+      pos_time varchar,
+      flag int,
+      pos_amb varchar(1),
+      error_ellipse_radius int,
+      lon_precision int,
+      lat_precision int,
+      trail_color int,
+      record_type varchar(1),
+      data_via varchar(1),
+      heard_via_tnc_port int, 
+      last_port_heard int,
+      num_packets int,
+      altitude varchar([MAX_ALTITUDE]),
+      speed varchar([MAX_SPEED+1]),
+      course varchar([MAX_COURSE+1]),
+      bearing varchar([MAX_COURSE+1]),
+      NRQ varchar([MAX_COURSE+1]),
+      power_gain varchar([MAX_POWERGAIN+1]),
+      signal_gain varchar([MAX_POWERGAIN+1])
+  );
+
+  
+
+*/
+
+#endif /* HAVE_MYSQL_SPATIAL */
+
+#endif /* HAVE_SPATIAL_DB */
+
+
+
+
+
+
+// Layer 3b: DBMS specific db storage code for non spatial databases **********
+// Functions supporting queries to specific types of databases that lack 
+// spatial extensions.  Limited to storing points using latitude and longitude
+// fields without spatial objects or spatial indexing.  
+// 
+
+#ifdef HAVE_MYSQL
+// functions for MySQL database version < 4.1, or MySQL schema objects that don't 
+// include spatial indicies.  
+//
+//********* Support for MySQL < 4.1 is depreciated  *****************************
+//********* Expect MySQL support to be limited to MySQL 5+ **********************
+//
+
+
+
+
+
+/* function storeStationSimplePointToDbMysql()
+ * MySQL implementation of wrapper storeStationSimplePointToGisDb().
+ * Should be private to db_gis.c
+ * Should only be called through wrapper function.  Do not call directly.
+ * Returns 0 for failure, 1 for success.  
+ * If failure, stores error message in aDbConnection->errormessage.
+ */
+int storeStationSimplePointToDbMysql(Connection *aDbConnection, DataRow *aStation) { 
+    int returnvalue = 0;  // default return value is failure.
+    int mysqlreturn = 1;  // result of sending mysql query.
+    char sql[400];
+    // Next three variables are one character in two bytes plus one character for
+    // filling by mysql_real_escape_string().  
+    char aprs_symbol[3];  // temporary holding for escaped aprs symbol
+    char aprs_type[3];    // temporary holding for escaped aprs type
+    char special_overlay[3];  // temporary holding for escaped overlay
+    char record_type[3];              // temporary holding for escaped record type
+    char from[3];  // temporary holding for all of the above length 3 variables
+    char call_sign[(MAX_CALLSIGN)*2+1];   // temporary holding for escaped callsign
+    char origin[(MAX_CALLSIGN)*2+1];  // temporary holding for escaped origin
+    char node_path[(NODE_PATH_SIZE*2)+1];         // temporary holding for escaped node_path_ptr
+    float longitude;
+    float latitude;
+    int ok;
+    char timestring[100+1];
+
+    if (debug_level & 4096) 
+        fprintf(stderr,"In storestationsimpletodbmysql()\n");
+
+    // prepared statements not present below MySQL version 4.1
+    // details of prepared statement support changed between versions 4.1 and 5.0.  
+    // char [] sql = "insert into simpleStation (call, transmit_time, latitude, longitude) values ('%1','%2','%3','%4'))";
+    // call is a required element for a simple station
+    if (aStation!=NULL && aStation->call_sign!=NULL && strlen(aStation->call_sign)>0) {
+        // get time in seconds, adjust to datetime
+        // If my station or another unset sec_heard is 
+        // encountered, use current time instead, use time
+        // provided if it was invalid.
+        get_iso_datetime(aStation->sec_heard,timestring,True,False);
+        // get coord_lat, coord_long in xastir coordinates and convert to decimal degrees
+        ok = convert_from_xastir_coordinates (&longitude, &latitude, aStation->coord_lon, aStation->coord_lat);
+        // latitude and longitude are required elements for a simple station record.
+        if (ok==1) { 
+            // build insert query with call, time, and position
+            // handle special cases of null, \ and ' characters in type, symbol, and overlay.
+            if (aStation->aprs_symbol.aprs_symbol) { 
+                xastir_snprintf(from,2,"%c",aStation->aprs_symbol.aprs_symbol);
+                mysql_real_escape_string(&aDbConnection->mhandle,aprs_symbol,from,1);
+            } else { 
+                xastir_snprintf(aprs_symbol,2,"%c",'\0');
+            }
+            if (aStation->aprs_symbol.aprs_type) { 
+                xastir_snprintf(from,2,"%c",aStation->aprs_symbol.aprs_type);
+                mysql_real_escape_string(&aDbConnection->mhandle,aprs_type,from,1);
+            } else { 
+                xastir_snprintf(aprs_type,2,"%c",'\0');
+            }
+            if (aStation->aprs_symbol.special_overlay) { 
+                xastir_snprintf(from,2,"%c",aStation->aprs_symbol.special_overlay);
+                mysql_real_escape_string(&aDbConnection->mhandle,special_overlay,from,1);
+            } else { 
+                xastir_snprintf(special_overlay,2,"%c",'\0');
+            } 
+  
+            // Need to escape call sign - may contain special characters: 
+            // insert into simpleStation (station, symbol, overlay, aprstype, transmit_time, latitude, longitude) 
+            // values ('Fry's','/\0\0',' ','//\0','2007-08-07 21:55:43 -0400','47.496834','-122.198166')
+            mysql_real_escape_string(&aDbConnection->mhandle,call_sign,(aStation->call_sign),strlen(aStation->call_sign));
+            // just in case, set a default value for record_type and escape it.
+            if (aStation->record_type) { 
+                fprintf(stderr,"record_type: %c\n",aStation->record_type);
+                xastir_snprintf(from,2,"%c",aStation->record_type);
+                mysql_real_escape_string(&aDbConnection->mhandle,record_type,from,1);
+            } else { 
+                xastir_snprintf(record_type,2,"%c",NORMAL_APRS);
+            }
+
+            if (strlen(aStation->origin) > 0) { 
+                mysql_real_escape_string(&aDbConnection->mhandle,origin,(aStation->origin),strlen(aStation->origin));
+            } else { 
+                xastir_snprintf(origin,2,"%c",'\0');
+            } 
+            if (aStation->node_path_ptr) { 
+                //mysql_real_escape_string(conn,&node_path,aStation->node_path_ptr,((strlen(aStation->node_path_ptr)*2)+1));
+                xastir_snprintf(node_path,sizeof(node_path),"%s",aStation->node_path_ptr);
+            } else { 
+                xastir_snprintf(node_path,2,"%c",'\0');
+            } 
+            
+            xastir_snprintf(sql,sizeof(sql),"insert into simpleStation (station, symbol, overlay, aprstype, transmit_time, latitude, longitude, origin, record_type, node_path) values ('%s','%s','%s','%s','%s','%3.6f','%3.6f','%s','%s','%s')", call_sign, aprs_symbol, special_overlay, aprs_type,timestring,latitude,longitude,origin,record_type,node_path);
+
+            if (debug_level & 4096) 
+                fprintf(stderr,"MySQL Query:\n%s\n",sql);
+
+            // send query 
+            mysql_ping(&aDbConnection->mhandle);
+            mysqlreturn = mysql_real_query(&aDbConnection->mhandle, sql, strlen(sql)+1);
+            if (mysqlreturn!=0) { 
+                // get the mysql error message
+                fprintf(stderr,mysql_error(&aDbConnection->mhandle));
+                fprintf(stderr,"\n");
+                mysql_interpret_error(mysqlreturn,aDbConnection);
+            } else {
+                // insert query was successfull, return value is ok.
+                returnvalue=1;
+            }
+        } else { 
+            xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Error converting latitude or longitude from xastir coordinates: %ld,%ld",aStation->coord_lat,aStation->coord_lon);
+        } 
+    } else { 
+        // set call not null error message
+        xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Station callsign is required and was blank or null.");
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* function testXastirVersionMysql() 
+ * checks the xastir database version number of a connected MySQL database against the 
+ * version range supported by the running copy of xastir.
+ * @param aDbConnection pointer to a Connection struct describing the connection
+ * @returns 0 if incompatable, 1 if compatable, -1 on connection failure.
+ *
+ * db       program
+ * v  cs    v   cs    compatable
+ * 1  1     1   1     1    identical 
+ * 2  1     1   1     1    database newer than program (added fields, not queried)
+ * 1  1     2   1     0    program newer than database (added fields, queries fail).
+ * 3  2     2   1     0    different series
+ * 2  1     3   2     0    different series
+ *
+ * TODO: Need function to test for available schemas with mysql_list_tables()
+ */
+int testXastirVersionMysql(Connection *aDbConnection) {
+    int returnvalue = -1;
+    MYSQL_RES *result;
+    MYSQL_ROW row;
+    int version_number;
+    int compatible_series;
+    char sql[] = "select version_number, compatable_series from version order by version_number desc limit 1";  
+    int ok;   // to hold mysql_query return value
+    ok = mysql_query(&aDbConnection->mhandle,sql);
+    if (ok==0) { 
+        result = mysql_use_result(&aDbConnection->mhandle);
+        if (result!=NULL) { 
+            if ((row = mysql_fetch_row(result))) { 
+                version_number = atoi((char *)row[0]);
+                if (version_number == XASTIR_SPATIAL_DB_VERSION) { 
+                   returnvalue = 1;
+                   fprintf(stderr,"Version in schema (%d) is the same as this version of xastir (%d).\n",version_number,XASTIR_SPATIAL_DB_VERSION);
+                } else { 
+                    compatible_series = atoi((char *)row[1]);
+                    if (version_number < XASTIR_SPATIAL_DB_VERSION && compatible_series == XASTIR_SPATIAL_DB_COMPATABLE_SERIES) {
+                        returnvalue = 1;
+                        fprintf(stderr,"Version in schema (%d) is compatible with this version of xastir (%d).\n",version_number,XASTIR_SPATIAL_DB_VERSION);
+                    } else { 
+                        fprintf(stderr,"Version in schema (%d) is not compatible with this version of xastir (%d).\n",version_number,XASTIR_SPATIAL_DB_VERSION);
+                        xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Version in schema (%d) is not compatible with this version of xastir (%d).",version_number,XASTIR_SPATIAL_DB_VERSION);
+                        fprintf(stderr,"%s",aDbConnection->errormessage);
+                        returnvalue = 0;
+                    }
+                }
+            } else {
+                // result returned, but no rows = incompatable
+                returnvalue = 0;
+                fprintf(stderr,"Version table doesn't appear to contain any rows.\n");
+                xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Version table doesn't appear to contain any rows.");
+            }
+        } else { 
+            fprintf(stderr,"Schema doesn't appear to contain a version table.\n");
+            xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Schema doesn't appear to contain a version table.");
+        } 
+        mysql_free_result(result);
+    } else { 
+         fprintf(stderr,"Query failed, Schema doesn't appear to contain a version table.\n");
+         xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "Query for version table failed.");
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* function storeStationToDbMysql() 
+ */
+int storeStationToDbMysql(Connection *aDbConnection, DataRow *aStation){
+    int returnvalue = 0;
+    //ioparam *device = aDbConnection->descriptor;
+    // check type of schema to use (XASTIR simple, full or APRSWorld) 
+    switch (devices[aDbConnection->interface_number].database_schema_type) {
+        case XASTIR_SCHEMA_SIMPLE : 
+            returnvalue = storeStationSimplePointToDbMysql(aDbConnection,aStation);
+            break;
+        case XASTIR_SCHEMA_APRSWORLD : 
+            break;
+        case XASTIR_SCHEMA_COMPLEX :
+            break;
+        // otherwise error message
+    }
+    return returnvalue;
+}
+
+
+
+
+
+/* function getAllSimplePositionsMysql()
+ * MySQL implementation of getAllSimplePositions for a MySQL database that
+ * does not include spatial support.
+ * @param aDbConnection an exastir database connection struct describing
+ * the connection.
+ * Returns 0 for failure, 1 for success.  
+ * If failure, stores error message in aDbConnection->errormessage.
+ */
+int getAllSimplePositionsMysql(Connection *aDbConnection) {
+    int returnvalue = 0;
+    DataRow *p_new_station;
+    //DataRow *p_time;
+    int station_count = 0;  // number of new stations retrieved
+    //unsigned long x;  // xastir coordinate for longitude
+    //unsigned long y;  // xastir coordinate for latitide
+    //float lat;  // latitude converted from retrieved string
+    //float lon;  // longitude converted from retrieved string
+    char feedback[100];
+    //struct tm time;
+    char sql[] = "select station, transmit_time, latitude, longitude, symbol, overlay, aprstype, origin, record_type, node_path from simpleStation order by station, transmit_time";
+    MYSQL_RES *result;
+    MYSQL_ROW row;
+    int ok;   // to hold mysql_query return value
+    ok = mysql_query(&aDbConnection->mhandle,sql);
+    if (ok==0) { 
+        result = mysql_use_result(&aDbConnection->mhandle);
+        if (result!=NULL) { 
+            xastir_snprintf(feedback,100,"Retrieving MySQL records\n");
+            stderr_and_statusline(feedback);
+            // with mysql_use_result each call to mysql_fetch_row retrieves
+            // a row of data from the server.  Mysql_store_result might use
+            // too much memory in retrieving a large result set all at once.
+            while ((row = mysql_fetch_row(result))) { 
+               // retrieve data from the row
+               // test to see if this is a valid station
+               if (row[0]==NULL) { 
+                  // station is null, skip
+               } else { 
+                  p_new_station = NULL;
+                  if (search_station_name(&p_new_station,row[0],1)) {  
+                       // This station is allready in present as a DataRow in the xastir db.
+                       // Add data to the station's track.
+                  } else { 
+                       // This station isn't in the xastir db. 
+                       // Add a datarow using the retrieved station record from the postgis database.
+                       add_simple_station(p_new_station, row[0], row[7], row[4], row[5], row[6], row[2], row[3], row[8], row[9], row[1],(char*)MYSQL_TIMEFORMAT);
+
+                       station_count++;
+                  }
+               }
+            }
+        } else { 
+            // error fetching the result set
+            fprintf(stderr,"mysql error: %s\n",mysql_error(&aDbConnection->mhandle));
+            mysql_interpret_error(mysql_errno(&aDbConnection->mhandle),aDbConnection);
+        }
+        xastir_snprintf(feedback,100,"Retreived %d new stations from MySQL\n",station_count);
+        stderr_and_statusline(feedback);
+        mysql_free_result(result);
+    } else { 
+       // query didn't execute correctly
+       mysql_interpret_error(ok,aDbConnection);
+    }
+    return returnvalue;
+}
+
+
+int getAllSimplePositionsMysqlInBoundingBox(Connection *aDbConnection, char *str_e_long, char *str_w_long, char *str_n_lat, char *str_s_lat) {
+    int returnvalue = 0;
+
+    return returnvalue;
+}
+
+
+
+/* function mysql_interpret_error() 
+ * given a mysql error code and an xastir connection, sets an appropriate
+ * error message in the errormessage field of the connection.  Interprets
+ * numeric error codes returned by mysql functions.
+ * @param errorcode A result returned by a mysql function that can be 
+ * interpreted as an error code.  
+ * @param aDbConnection an xastir database connection struct describing the
+ * connection and its current state.
+ * Note - it is possible to give this function a connection on which an
+ * error has not occured along with an error code.  This function does
+ * not check the connection or assess whether an error actually occured
+ * on it or not, it simply interprets an error code and writes the 
+ * interpretation into the connection that was passed to it.  
+ */
+void mysql_interpret_error(int errorcode, Connection *aDbConnection) { 
+    fprintf(stderr,"Error communicating with MySQL database. Error code=%d\n",errorcode);
+    switch (errorcode) {
+       case CR_OUT_OF_MEMORY :
+           // insufficient memory for query
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "MySQL: Out of Memory");
+           // notify the connection status listener
+           break;
+       // mysql_query errors
+       case CR_COMMANDS_OUT_OF_SYNC :
+           // commands in improper order
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "MySQL: Commands out of sync");
+           break;
+       case CR_SERVER_GONE_ERROR :
+           // mysql server has gone away
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "MySQL: Connection to server lost");
+           // notify the connection status listener
+           break;
+       case CR_SERVER_LOST :
+           // server connection was lost during query
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "MySQL: Connection to server lost during query");
+           // notify the connection status listener
+           break;
+       case CR_UNKNOWN_ERROR :
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "MySQL: Unknown Error");
+           break;
+       default:
+           xastir_snprintf(aDbConnection->errormessage, MAX_CONNECTION_ERROR_MESSAGE, "MySQL: Unrecognized error Code [%d]", errorcode);
+    }
+    fprintf(stderr,"%s\n",aDbConnection->errormessage);
+}
+
+#endif /* HAVE_MYSQL*/
+
+// add code for a lightweight database here
+
+
+
+
+
+
+
+#endif /* HAVE_DB*/
+
+// Functions related to GIS, but not database specific ************************
+
+
+
+
+/* Function  xastirCoordToLatLongPostgresPoint
+ * converts a point in xastir coordinates to a native postgres representation 
+ * of a point using latitude and longitude in decimal degrees in the WGS84 
+ * projection EPSG:4326. Format is similar to WKT, but without leading POINT.
+ * @param x longitude in xastir coordinates = decimal 100ths of a second.  
+ * @param y latitude in xastir coordinates = decimal 100ths of a second.  
+ * @param pointer to a char[ at least 24] string to hold point representation.
+ * returns 1 on success, 0 on failure.
+ */
+int xastirCoordToLatLongPostgresPoint(long x, long y, char *wkt) { 
+    // 1 xastir coordinate = 1/100 of a second
+    // 100*60*60 xastir coordinates (=360000 xastir coordinates) = 1 degree
+    // 360000   xastir coordinates = 1 degree
+    // conversion to string decimal degrees handled by utility fuctions
+    int returnvalue = 0;  // defaults to failure
+    float latitude;
+    float longitude;
+    int ok;
+    ok = convert_from_xastir_coordinates (&longitude,&latitude, x, y);
+    if (ok>0) { 
+       xastir_snprintf(wkt, MAX_WKT, "(%3.6f, %3.6f)", latitude, longitude);
+       returnvalue = 1;
+    } 
+    return returnvalue;
+}
+
+
+
+
+
+
+/* Function  xastirCoordToLatLongWKT
+ * converts a point in xastir coordinates to a well known text string (WKT)
+ * representation of a point using latitude and longitude in decimal degrees
+ * in the WGS84 projection EPSG:4326
+ * @param x longitude in xastir coordinates = decimal 100ths of a second.  
+ * @param y latitude in xastir coordinates = decimal 100ths of a second.  
+ * @param pointer to a char[29] string to hold well known text representation.
+ * returns 1 on success, 0 on failure.
+ */
+int xastirCoordToLatLongWKT(long x, long y, char *wkt) { 
+    // 1 xastir coordinate = 1/100 of a second
+    // 100*60*60 xastir coordinates (=360000 xastir coordinates) = 1 degree
+    // 360000   xastir coordinates = 1 degree
+    // conversion to string decimal degrees handled by utility fuctions
+    int returnvalue = 0;  // defaults to failure
+    float latitude;
+    float longitude;
+    int ok;
+    ok = convert_from_xastir_coordinates (&longitude,&latitude, x, y);
+    if (ok>0) { 
+       xastir_snprintf(wkt, MAX_WKT, "POINT(%3.6f %3.6f)", longitude, latitude);
+       returnvalue = 1;
+    } 
+    return returnvalue;
+}
+
+
+
+
+
+float xastirWKTPointToLongitude(char *wkt) { 
+    float returnvalue = 0.0;
+    char temp[MAX_WKT];
+    char *space = NULL;
+    int x;
+    if (wkt[0]=='P' && wkt[1]=='O' && wkt[2]=='I' && wkt[3]=='N' && wkt[4]=='T' && wkt[5]=='(') { 
+        // this is a point
+        xastir_snprintf(temp, MAX_WKT, "%s", wkt);
+        // truncate at the space
+        space = strchr(temp,' ');
+        if (space != NULL) { 
+            *space = '\0';
+        }
+        // remove the leading "POINT("
+        for (x=0;x<6;x++) {  
+            temp[x]=' ';
+        }
+        returnvalue = atof(temp);
+    }
+    return returnvalue;
+}
+
+
+
+
+
+float xastirWKTPointToLatitude(char *wkt) { 
+    float returnvalue = 0.0;
+    char temp[MAX_WKT];
+    char *paren = NULL;
+    int x;
+    if (wkt[0]=='P' && wkt[1]=='O' && wkt[2]=='I' && wkt[3]=='N' && wkt[4]=='T' && wkt[5]=='(') { 
+        // this is a point
+        xastir_snprintf(temp, MAX_WKT, "%s", wkt);
+        // truncate at the trailing parenthesis
+        paren = strchr(temp,')');
+        if (paren != NULL) { 
+            *paren = '\0';
+        }
+        // convert all leading characters up to the space to spaces.
+        for (x=0;x<(int)(strlen(temp));x++)  {
+            if (temp[x]==' ') { 
+               x = (int)(strlen(temp));
+           } else { 
+               temp[x] = ' ';
+           }
+        }
+        returnvalue = atof(temp);
+    }
+    return returnvalue;
+
+}
+
diff --git a/src/db_gis.h b/src/db_gis.h
new file mode 100644
index 0000000..3ac0405
--- /dev/null
+++ b/src/db_gis.h
@@ -0,0 +1,176 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: db_gis.h,v 1.15 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2007-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#include "xastir.h"
+#include "interface.h"  // ioparam struct is used to store descriptions of databases
+                        // to which to connect.
+extern int xastirCoordToLatLongWKT(long x, long y, char *wkt);
+extern int xastirCoordToLatLongPoint(long x, long y, char *wkt);
+extern float xastirWKTPointToLatitude(char *wkt);
+extern float xastirWKTPointToLongitude(char *wkt);
+
+// maximum size of a well known text representation of a geometry
+// 100 should be fine for points, will need to be longer for other geometries.
+#define MAX_WKT 100
+
+#ifdef HAVE_DB
+// maximum number of open database connections
+#define MAX_DB_CONNECTIONS 20
+
+// includes for database client libraries and 
+// constants to identify database types
+// constants are used in interface_gui.c 
+// where the specify order on picklist 
+// *** Need to localize these and the schema types ***
+#ifdef HAVE_MYSQL
+// MySQL version 3.x and higher
+#include <mysql.h>
+// mysql error message codes
+#include <errmsg.h>
+#define DB_MYSQL 1
+#endif /* HAVE_MYSQL */
+
+#ifdef HAVE_SPATIAL_DB
+
+#ifdef HAVE_POSTGIS
+// Postgresql with postgis
+#include <libpq-fe.h>
+#define DB_POSTGIS 2
+#define POSTGRES_RESULTFORMAT_TEXT 0
+#endif /* HAVE_POSTGIS */
+
+#ifdef HAVE_MYSQL_SPATIAL
+// MySQL version 4.1 and higher
+#define DB_MYSQL_SPATIAL 3
+#endif /* HAVE_MYSQL_SPATIAL */
+
+#define MAX_DB_TYPE 3 // largest value for DB_ 
+                      // used in load_data_or_default
+#define NODE_PATH_SIZE 56  // field size for node_path, for data_row.node_path_ptr 
+
+// constants to control database schema versioning
+
+// Version of the mysql/postgresql table structures this version of xastir expects to find.
+// Any change or addition of database schema elements should trigger a version change.
+// Newer versions of xastir should require an older database to be upgraded to the 
+// current version before allowing queries to run against that database.
+#define XASTIR_SPATIAL_DB_VERSION 1  
+// Allow grouping of forward compatible table structures allowing an older version of xastir to
+// interact with a database created by a newer version of xastir of the same compatble series
+// addition of new tables and fields shouldn't change comapatable series, but renamed, deleted, 
+// or shortened schema elements should change compatible series (changes where a select or 
+// or insert query run by an older version of xastir will fail against a newer database).
+#define XASTIR_SPATIAL_DB_COMPATABLE_SERIES 1  
+
+// constants to indicate schema to use in a database
+#define XASTIR_SCHEMA_SIMPLE 1     // simple station table only
+#define XASTIR_SCHEMA_CAD 2        // simple station table and cad objects
+#define XASTIR_SCHEMA_COMPLEX 3    // full aprs concept support
+#define XASTIR_SCHEMA_APRSWORLD 4  // aprs world implementaiton
+
+#define MAX_XASTIR_SCHEMA 4  // largest value for xastir_schema_ 
+                             // used in load_data_or_default
+
+#define XASTIR_SCHEMA_DESCRIPTOR_MAX_SIZE 50  // largest allowed size of a localized schema descriptor string
+#define XASTIR_DB_DESCRIPTOR_MAX_SIZE 50      // largest allowed size of a localized dbms descriptor string
+
+
+// description of a database
+// replaced with extension of ioparam struct in interface.h
+/*
+typedef struct {
+   char name[MAX_DEVICE_NAME+1]; // name of connection to display to user  - ioparam device_name
+   char host[255];    // hostname for database server           - ioparam device_host_name
+   int port;          // port on which to connect to database server  - ioparam sp
+   char password[20]; // password to use to connect to database - ioparam device_host_password
+   char username[20]; // username to use to connect to database 
+   int type;          // type of dbms (posgresql, mysql, etc)   
+   char schema[20];   // name of database or schema to use
+   char makeerrormessage[255]; // most recent error message from attempting to make a 
+                      // connection with using this descriptor.
+   int schema_type;    // table structures to use in the database
+                      // A database schema could contain both APRSWorld 
+                      // and XASTIR table structures, but a separate database
+                      // descriptor should be defined for each.  
+   char unix_socket[255];   // MySQL - unix socket parameter (path and filename)
+   //connection_list open_connections // list of open connections to this database
+} DbDescriptor;
+*/
+#define MAX_CONNECTION_ERROR_MESSAGE 255
+// a database connection 
+typedef struct {
+   int type;          // type of dbms (postgresql, mysql, etc, redundant from descriptor->type)
+   ioparam *descriptor;  // connection parameters used to establish this connnection
+                      // stored in ioparam struct defined in interface.h
+#ifdef HAVE_MYSQL
+   MYSQL mhandle;   // mysql connection
+#endif /* HAVE_MYSQL */
+#ifdef HAVE_POSTGIS
+   PGconn  *phandle;  // postgres connection
+#endif /* HAVE_POSTGIS */
+   char errormessage[MAX_CONNECTION_ERROR_MESSAGE]; // most recent error message on this connection.
+   int interface_number;  // number of the interface on which this connection is managed
+} Connection; 
+
+
+// list of database connections
+//typedef struct{
+//   Connection *conn;  // a database connection
+//   ioparam *iface;    // interface definition for the connection
+//} ConnectionList;
+
+//extern ConnectionList connections[MAX_IFACE_DEVICES];
+extern Connection connections[MAX_IFACE_DEVICES];
+extern int connections_initialized;
+
+
+// connection management
+extern int openConnection (ioparam *aioparm, Connection *conn);
+int initAConnection(Connection *connection, int x);
+extern int closeConnection (Connection *aDbConnection, int port_number);
+extern int testConnection(Connection *aDbConnection);
+int pingConnection(Connection *aDbConnection);
+
+extern char xastir_dbms_type[4][51];
+extern char xastir_schema_type[5][51];
+
+// storing and retrieving data from a database
+extern int storeStationToGisDb(Connection *aDbConnection, DataRow *aStation);
+extern int storeCadToGisDb(Connection *aDbConnection, CADRow *aCadObject);
+extern int storeStationSimpleToGisDb(Connection *aDbConnection, DataRow *aStation);
+extern int getAllSimplePositions(Connection *aDbConnection);
+extern int getAllSimplePositionsInBoundingBox(Connection *aDbConnection, int east, int west, int north, int south);
+extern ioparam simpleDbTest(void);
+
+#endif /* HAVE_SPATIAL_DB */
+
+extern int initConnections(void);
+#endif /* HAVE_DB */
+
+// structure to hold a latutude and longitude in decimal degrees
+typedef struct {
+  float latitude;
+  float longitude;
+} Point;
+
+
diff --git a/src/dbfawk.c b/src/dbfawk.c
new file mode 100644
index 0000000..a82a793
--- /dev/null
+++ b/src/dbfawk.c
@@ -0,0 +1,498 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: dbfawk.c,v 1.38 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ */
+/*
+ * This library glues the Awk-like functions (see awk.c) to attributes
+ * for shapefiles (contained in DBF files).
+ *
+ * Alan Crosswell, n2ygk at weca.org
+ *
+ */
+
+
+//
+// Functions which allocate memory:
+// --------------------------------
+// dbfawk_field_list
+// dbfawk_load_sigs
+// dbfawk_find_sig
+// dbfawk_parse_record (indirectly)
+//
+// Functions which free memory:
+// ----------------------------
+// dbfawk_free_info
+// dbfawk_load_sigs
+// dbfawk_free_sig
+// dbfawk_free_sigs
+// dbfawk_find_sig
+//
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#if defined(WITH_DBFAWK) && defined(HAVE_LIBSHP) && defined(HAVE_LIBPCRE)
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include "awk.h"
+#include "dbfawk.h"
+#include "snprintf.h"
+#include "maps.h"
+
+#include <sys/stat.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+/*
+ * dbfawk_sig:  Generate a signature for a DBF file.
+ *  Fills in sig and returns number of fields.
+ */
+int dbfawk_sig(DBFHandle dbf, char *sig, int size) {
+  int nf = 0;
+
+  if (sig && size > 0 && dbf) {
+    int i;
+    char *sp;
+    int width,prec;
+    
+    nf = DBFGetFieldCount(dbf);
+    for (i = 0, sp=sig; sp < &sig[size-XBASE_FLDHDR_SZ] && i < nf ; i++) {
+      DBFGetFieldInfo(dbf,i,sp,&width,&prec);
+      sp += strlen(sp);
+      *sp++ = ':';              /* field name separator */
+    }
+    if (i)
+      *--sp = '\0';             /* clobber the trailing sep */
+  }
+  return nf;
+}
+
+
+
+
+
+/* Free a field list */
+void dbfawk_free_info ( dbfawk_field_info *list) {
+    dbfawk_field_info *x, *p;
+
+    for ( p = list; p != NULL; ) {
+        x = p;
+        p = p->next;
+        free(x);
+    }
+}
+
+
+
+
+
+/*
+ * dbfawk_field_list: Generate a list of info about fields to read for
+ *  a given DBFHandle and colon-separated list of fieldnames.
+ */
+dbfawk_field_info *dbfawk_field_list(DBFHandle dbf, char *dbffields) {
+  dbfawk_field_info *fi = NULL, *head = NULL, *prev;
+  int nf;
+  char *sp;
+
+  /* now build up the list of fields to read */
+  for (nf = 0, sp = dbffields, prev = NULL; *sp; nf++) {
+    char *d,*p = sp;
+    char junk[XBASE_FLDHDR_SZ];
+    int w,prec;
+
+    fi = calloc(1,sizeof(dbfawk_field_info));
+    if (!fi) {
+        fprintf(stderr,"dbfawk_field_list: first calloc failed\n");
+        return NULL;
+    }
+
+    if (prev) {
+        prev->next = fi;
+    } else {                    /* no prev, must be first one */
+        head = fi;
+    }
+    d = fi->name;
+    while (*p && *p != ':') *d++ = *p++;
+    if (*p == ':')
+      *p++ = '\0';
+    *d='\0';
+    fi->num = DBFGetFieldIndex(dbf, fi->name);
+    fi->type = DBFGetFieldInfo(dbf, fi->num, junk, &w, &prec);
+    sp = p;
+    prev = fi;
+  }
+
+  return head;
+}
+
+
+
+
+
+/*
+ * dbfawk_load_sigs:  Load up dbfawk signature mappings
+ *  Reads *.dbfawk and registers dbffields "signature".
+ *  Returns head of sig_info list.
+ *
+ *  TODO - consider whether it makes sense to use a private symtbl,
+ *   compile and then free here or require the caller to pass in a
+ *   symtbl that has dbfinfo declared.
+ */
+// Malloc's dbfawk_sig_info and returns a filled-in list
+
+dbfawk_sig_info *dbfawk_load_sigs(const char *dir, /* directory path */
+                                  const char *ftype) /* filetype */ { 
+    DIR *d;
+    struct dirent *e;
+    struct stat nfile;
+    char fullpath[MAX_FILENAME];
+    int ftlen;
+    dbfawk_sig_info *i = NULL, *head = NULL;
+    awk_symtab *symtbl;
+    char dbfinfo[1024];         /* local copy of signature */
+
+    if (!dir || !ftype) {
+        return NULL;
+    }
+    ftlen = strlen(ftype);
+    d = opendir(dir);
+    if (!d) {
+        return NULL;
+    }
+
+    symtbl = awk_new_symtab();
+    if (!symtbl) {
+        return NULL;
+    }
+
+    awk_declare_sym(symtbl,"dbfinfo",STRING,dbfinfo,sizeof(dbfinfo));
+
+    while ((e = readdir(d)) != NULL) {
+        int len = strlen(e->d_name);
+        char *path = calloc(1,len+strlen(dir)+2);
+
+        // Check for hidden files or directories
+        if (e->d_name[0] == '.') {
+            // Hidden, skip it
+            free(path);
+            continue;
+        }
+
+        // Check for regular files
+
+        xastir_snprintf(fullpath,
+            sizeof(fullpath),
+            "%s/%s",
+            dir,
+            e->d_name);
+
+        if (stat(fullpath, &nfile) != 0) {
+            // Couldn't stat file
+            free(path);
+            continue;
+        }
+
+        if ((nfile.st_mode & S_IFMT) != S_IFREG) {
+            // Not a regular file
+            free(path);
+            continue;
+        }
+ 
+        if (!path) {
+            if (symtbl)
+                awk_free_symtab(symtbl);
+            fprintf(stderr,"failed to malloc in dbfawk.c!\n");
+	    closedir(d);
+            return NULL;
+        }
+ 
+        *dbfinfo = '\0';
+        if (len > ftlen && (strcmp(&e->d_name[len-ftlen],ftype) == 0)) {
+            if (!head) {
+                i = head = calloc(1,sizeof(dbfawk_sig_info));
+
+                if (!i) {
+                    fprintf(stderr,"failed to malloc in dbfawk.c!\n");
+                    free(path);
+                    if (symtbl)
+                      awk_free_symtab(symtbl);
+		    closedir(d);
+                    return NULL;
+                }
+            } else {
+                i->next = calloc(1,sizeof(dbfawk_sig_info));
+
+                if (!i->next) {
+                    fprintf(stderr,"failed to malloc in dbfawk.c!\n");
+                    free(path);
+                    if (symtbl)
+                      awk_free_symtab(symtbl);
+		    closedir(d);
+                    return head; // Return what we were able to gather.
+                }
+
+                i = i->next;
+            }
+
+            xastir_snprintf(path,
+                len+strlen(dir)+2,
+                "%s/%s",
+                dir,
+                e->d_name);
+
+            i->prog = awk_load_program_file(path);
+
+            if (awk_compile_program(symtbl,i->prog) < 0) {
+                fprintf(stderr,"%s: failed to parse\n",e->d_name);
+            } else {
+                /* dbfinfo must be defined in BEGIN rule */
+                awk_exec_begin(i->prog); 
+
+                i->sig = strdup(dbfinfo);
+
+                awk_uncompile_program(i->prog);
+            }
+        }
+        free(path);
+    }
+
+    closedir(d);
+
+    if (symtbl)
+        awk_free_symtab(symtbl);
+
+    return head;
+}
+
+
+
+
+
+void dbfawk_free_sig(dbfawk_sig_info *ptr) {
+
+    if (ptr) {
+        if (ptr->prog)
+            awk_free_program(ptr->prog);
+
+        if (ptr->sig) {
+            free(ptr->sig);
+        }
+        free(ptr);
+    }
+}
+
+
+
+
+
+void dbfawk_free_sigs(dbfawk_sig_info *list) {
+    dbfawk_sig_info *x, *p;
+
+    for (p = list; p; ) {
+        x = p;
+        p = p->next;
+        dbfawk_free_sig(x);
+    }
+}
+
+
+
+
+
+/*
+ * dbfawk_find_sig:  Given a DBF file's "signature", find the appropriate
+ * awk program.  If filename is not null, see if there's a per-file .dbfawk
+ * and load it.
+ */
+
+dbfawk_sig_info *dbfawk_find_sig(dbfawk_sig_info *Dbf_sigs,
+                                 const char *sig,
+                                 const char *file) {
+    dbfawk_sig_info *result = NULL;
+
+    if (file) {
+        char *dot, *perfile = calloc(1,strlen(file)+7);
+        dbfawk_sig_info *info;
+
+        if (!perfile) {
+            fprintf(stderr,"failed to malloc in dbfawk_find_sig!\n");
+            return NULL;
+        }
+
+        xastir_snprintf(perfile,
+            strlen(file)+7,
+            "%s",
+            file);
+
+        dot = strrchr(perfile,'.');
+
+        if (dot)
+            *dot = '\0';
+
+        strncat(perfile, ".dbfawk", 8);
+
+        info = calloc(1,sizeof(*info));
+ 
+        if (!info) {
+            fprintf(stderr,"failed to malloc in dbfawk_find_sig!\n");
+            free(perfile);
+            return NULL;
+        }
+        info->prog = awk_load_program_file(perfile);
+        /* N.B. info->sig is left NULL since it won't be searched, and 
+           to flag that it's safe to free this memory when we're done with
+           it */
+        info->sig = NULL;
+        free(perfile);
+        if (info->prog) {
+ 
+            return info;
+        }
+        else {
+            dbfawk_free_sigs(info);
+        }
+        /* fall through and do normal signature search */
+    }
+
+    for (result = Dbf_sigs; result; result = result->next) {
+        if (strcmp(result->sig,sig) == 0) {
+            return result;
+        }
+    }
+    return NULL;
+}
+
+
+
+
+
+/*
+ * dbfawk_parse_record:  Read a dbf record and parse only the fields
+ *  listed in 'fi' using the program, 'rs'.
+ */
+void dbfawk_parse_record(awk_program *rs,
+                         DBFHandle dbf,
+                         dbfawk_field_info *fi,
+                         int i) {
+    dbfawk_field_info *finfo;
+
+    awk_exec_begin_record(rs); /* execute a BEGIN_RECORD rule if any */
+
+    for (finfo = fi; finfo ; finfo = finfo->next) {
+        char qbuf[1024];
+
+        switch (finfo->type) {
+        case FTString:
+	    sprintf(qbuf,"%s=%s",finfo->name,DBFReadStringAttribute(dbf,i,finfo->num));
+	    break;
+        case FTInteger:
+	    sprintf(qbuf,"%s=%d",finfo->name,DBFReadIntegerAttribute(dbf,i,finfo->num));
+	    break;
+        case FTDouble:
+	    sprintf(qbuf,"%s=%f",finfo->name,DBFReadDoubleAttribute(dbf,i,finfo->num));
+	    break;
+        case FTInvalid:
+        default:
+	    sprintf(qbuf,"%s=??",finfo->name);
+	    break;
+        }
+        if (awk_exec_program(rs,qbuf,strlen(qbuf)) == 2)
+            break;
+    }
+    awk_exec_end_record(rs); /* execute an END_RECORD rule if any */
+}
+
+
+
+
+
+#ifndef HAVE_DBFGETFIELDINDEX
+#include <ctype.h>
+/************************************************************************/
+/*                            str_to_upper()                            */
+/************************************************************************/
+
+static void str_to_upper (char *string) {
+  int len;
+  short i = -1;
+
+  len = strlen (string);
+
+  while (++i < len)
+    if (isalpha(string[i]) && islower(string[i]))
+      string[i] = toupper ((int)string[i]);
+}
+
+
+
+
+
+/************************************************************************/
+/*                          DBFGetFieldIndex()                          */
+/*                                                                      */
+/*      Get the index number for a field in a .dbf file.                */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/************************************************************************/
+
+int DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName) {
+  char          name[12], name1[12], name2[12];
+  int           i;
+
+  xastir_snprintf(name1,
+    sizeof(name1),
+    "%s",
+    pszFieldName);
+        
+  str_to_upper(name1);
+
+  for( i = 0; i < DBFGetFieldCount(psDBF); i++ ) {
+      DBFGetFieldInfo( psDBF, i, name, NULL, NULL );
+      xastir_snprintf(name2,
+        sizeof(name2),
+        "%s",
+        name);
+      str_to_upper(name2);
+
+      if(!strncmp(name1,name2,10))
+	return(i);
+    }
+  return(-1);
+}
+
+
+
+#endif
+#endif /* HAVE_LIBSHP && HAVE_LIBPCRE */
+
+
diff --git a/src/dbfawk.h b/src/dbfawk.h
new file mode 100644
index 0000000..bf55a5a
--- /dev/null
+++ b/src/dbfawk.h
@@ -0,0 +1,65 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: dbfawk.h,v 1.13 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ */
+#ifndef DBFAWK_H
+#define DBFAWK_H
+
+#ifndef _SHAPEFILE_H_INCLUDED
+#ifdef HAVE_SHAPEFIL_H
+#include <shapefil.h>
+#else
+#ifdef HAVE_LIBSHP_SHAPEFIL_H
+#include <libshp/shapefil.h>
+#else
+#error HAVE_LIBSHP defined but no corresponding include defined
+#endif // HAVE_LIBSHP_SHAPEFIL_H
+#endif // HAVE_SHAPEFIL_H
+#endif // _SHAPEFILE_H_INCLUDED
+
+typedef struct dbfawk_field_info_ {
+    struct dbfawk_field_info_ *next;
+    char name[XBASE_FLDHDR_SZ];   /* name of the field */
+    int num;                      /* column number */
+    DBFFieldType type;            /* data type */
+} dbfawk_field_info;
+
+typedef struct dbfawk_sig_info_ {
+    struct dbfawk_sig_info_ *next;
+    char *sig;                  /* dbfinfo signature */
+    awk_program *prog;          /* the program for this signature */
+} dbfawk_sig_info;
+
+extern int dbfawk_sig(DBFHandle dbf, char *sig, int size);
+extern dbfawk_field_info *dbfawk_field_list(DBFHandle dbf, char *dbffields);
+extern dbfawk_sig_info *dbfawk_load_sigs(const char *dir, const char *ftype);
+extern dbfawk_sig_info *dbfawk_find_sig(dbfawk_sig_info *info, 
+                                        const char *sig,
+                                        const char *file);
+extern void dbfawk_free_sig(dbfawk_sig_info *sig);
+extern void dbfawk_free_sigs(dbfawk_sig_info *list);
+extern void dbfawk_free_info(dbfawk_field_info *list);
+extern void dbfawk_parse_record(awk_program *rs,
+                                DBFHandle dbf,
+                                dbfawk_field_info *fi,
+                                int i);
+#endif /* !DBFAWK_H*/
diff --git a/src/draw_symbols.c b/src/draw_symbols.c
new file mode 100644
index 0000000..30d4842
--- /dev/null
+++ b/src/draw_symbols.c
@@ -0,0 +1,3547 @@
+/*
+ * $Id: draw_symbols.c,v 1.120 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "database.h"
+#include "draw_symbols.h"
+#include "main.h"
+#include "util.h"
+#include "color.h"
+#include "maps.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+
+#define ANGLE_UPDOWN 30         /* prefer horizontal cars if less than 45 degrees */
+
+int symbols_loaded = 0;
+int symbols_cache[5] = {0,0,0,0,0};
+Widget select_symbol_dialog = (Widget)NULL;
+static xastir_mutex select_symbol_dialog_lock;
+Pixmap select_icons[(126-32)*2];    //33 to 126 with both '/' and '\' symbols (94 * 2) or 188
+int symbol_change_requested_from = 0;
+
+
+ 
+
+
+void draw_symbols_init(void)
+{
+    init_critical_section( &select_symbol_dialog_lock );
+}
+
+
+
+
+
+/*** symbol data ***/
+
+void clear_symbol_data(void) {
+    int my_size;
+    int i;
+    char *data_ptr;
+
+    data_ptr = (char *)symbol_data;
+    my_size = (int)sizeof(SymbolData);
+    for (i=0;i<my_size;i++)
+        *data_ptr++ = '\0';
+    symbols_loaded = 0;
+}
+
+
+
+
+
+/* 
+ *  Draw nice looking text
+ */
+void draw_nice_string(Widget w, Pixmap where, int style, long x, long y, char *text, int bgcolor, int fgcolor, int length) {
+    GContext gcontext;
+    XFontStruct *xfs_ptr;
+    int font_width, font_height;
+
+
+    if (x > screen_width)  return;
+    if (x < 0)             return;
+    if (y > screen_height) return;
+    if (y < 0)             return;
+
+    switch (style) {
+
+        case 0:
+            // make outline style
+            (void)XSetForeground(XtDisplay(w),gc,colors[bgcolor]);
+            // draw an outline 1 pixel bigger than text
+            (void)XDrawString(XtDisplay(w),where,gc,x+1,y-1,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x+1,y,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x+1,y+1,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x-1,y,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x-1,y-1,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x-1,y+1,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x,y+1,text,length);
+            (void)XDrawString(XtDisplay(w),where,gc,x,y-1,text,length);
+            break;
+
+        case 1:
+            // draw text the old way in a gray box
+            // Leave this next one hard-coded to 0xff.  This keeps
+            // the background as gray.
+
+// With a large font, the background rectangle is too small.  Need
+// to include the font metrics in this drawing algorithm.
+
+            (void)XSetForeground(XtDisplay(w),gc,colors[0xff]);
+            (void)XFillRectangle(XtDisplay(w),where,gc,x-1,(y-10),(length*6)+2,11);
+            (void)XSetForeground(XtDisplay(w),gc,colors[bgcolor]);
+            (void)XDrawString(XtDisplay(w),where,gc,x+1,y+1,text,length);
+            break;
+
+        case 2:
+        default:
+            // draw white or colored text in a black box
+
+            // With a large font, the background rectangle is too
+            // small.  Need to include the font metrics in this
+            // drawing algorithm, which we do here.
+
+            gcontext = XGContextFromGC(gc);
+
+            xfs_ptr = XQueryFont(XtDisplay(w), gcontext);
+
+
+//            font_width = xfs_ptr->max_bounds.width
+//                + xfs_ptr->max_bounds.rbearing
+//                - xfs_ptr->max_bounds.lbearing;
+//            font_width = xfs_ptr->max_bounds.width;
+            font_width = (int)((xfs_ptr->max_bounds.width
+                + xfs_ptr->max_bounds.width
+                + xfs_ptr->max_bounds.width
+                + xfs_ptr->min_bounds.width) / 4);
+
+            font_height = xfs_ptr->max_bounds.ascent
+                + xfs_ptr->max_bounds.descent;
+
+            if (xfs_ptr) {
+                // This leaks memory if the last parameter is a "0"
+                XFreeFontInfo(NULL, xfs_ptr, 1);
+            }
+
+            // Normal font returns 10 & 13.  Large system font
+            // returns 13 & 20 here.
+            //fprintf(stderr,
+            //    "Font dimemsions:  Width:%d  Height:%d\n",
+            //    font_width,
+            //    font_height);
+ 
+            (void)XSetForeground( XtDisplay(w),
+                gc,
+                GetPixelByName(w,"black") );
+
+// Old:
+//(void)XFillRectangle(XtDisplay(w),where,gc,x-2,(y-11),(length*6)+3,13);
+
+// New:  This one makes the black rectangle too long for smaller
+// fonts.  Perhaps because they are proportional?
+            (void)XFillRectangle( XtDisplay(w),
+                where,
+                gc,
+                x-2,                    // X
+                y-font_height,          // Y
+                (length*font_width)+3,  // width
+                font_height+2);         // height
+
+            break;
+
+    }
+
+    // finally draw the text
+    (void)XSetForeground(XtDisplay(w),gc,colors[fgcolor]);
+    (void)XDrawString(XtDisplay(w),where,gc,x,y,text,length);
+}
+
+
+
+
+
+/* symbol drawing routines */
+
+
+
+
+
+// Function to draw a line between a WP symbol "\/" and the
+// transmitting station.  We pass it the WP symbol.  It does a
+// lookup for the transmitting station callsign to get those
+// coordinates, then draws a line between the two symbols if
+// possible (both on screen).
+//
+// If the symbol was a Waypoint symbol, "\/", we need to draw a line
+// from the transmitting station to the waypoint symbol according to
+// the spec.  Take care to not draw the line any longer than needed
+// (don't exercise the X11 long-line drawing bug).  According to the
+// spec we also need to change the symbol to just a red dot, but
+// it's nice having the "WP" above it so we can differentiate it
+// from the other red dot symbol.
+//
+// We should skip drawing the line if the object/item is not being drawn.
+// Should we skip it if the origination station isn't being drawn?
+// Do we need to add yet another togglebutton to enable/disable this line?
+//
+// Note that this type of operation, making a relation between two
+// symbols, breaks our paradism quite a bit.  Until now all symbols
+// have been independent of each other.  Perhaps we should store the
+// location of one symbol in the data of the other so that we won't
+// have to compare back and forth.  This won't help much if either
+// or both symbols are moving.  Probably better to just do a lookup
+// of the originating station by callsign through our lists and then
+// draw the line between the two coordinates each time.
+//
+void draw_WP_line(DataRow *p_station,
+                  int ambiguity_flag,
+                  long ambiguity_coord_lon,
+                  long ambiguity_coord_lat,
+                  Pixmap where,
+                  Widget w) {
+    DataRow *transmitting_station = NULL;
+    int my_course;
+    long x_long, y_lat;
+    long x_long2, y_lat2;
+    double lat_m;
+    long x, y;
+    long x2, y2;
+    double temp;
+    int color = trail_colors[p_station->trail_color];
+    float temp_latitude, temp_latitude2;
+    float temp_longitude, temp_longitude2;
+
+
+    // Compute screen position of waypoint symbol
+    if (ambiguity_flag) {
+        x_long = ambiguity_coord_lon;
+        y_lat = ambiguity_coord_lat;
+    }
+    else {
+        x_long = p_station->coord_lon;
+        y_lat = p_station->coord_lat;
+    }
+
+    // x & y are screen location of waypoint symbol
+    x = (x_long - NW_corner_longitude)/scale_x;
+    y = (y_lat - NW_corner_latitude)/scale_y;
+ 
+    // Find transmitting station, get it's position.
+    // p_station->origin contains the callsign for the transmitting
+    // station.  Do a lookup on that callsign through our database
+    // to get the position of that station.
+
+    if (!search_station_name(&transmitting_station,p_station->origin,1)) {
+        // Can't find call,
+        return;
+    }
+
+    x_long2 = transmitting_station->coord_lon;
+    y_lat2 = transmitting_station->coord_lat;
+
+    // x2 & y2 are screen location of transmitting station
+    x2 = (x_long2 - NW_corner_longitude)/scale_x;
+    y2 = (y_lat2 - NW_corner_latitude)/scale_y;
+
+
+/*
+    if ((x2 - x) > 0) {
+        my_course = (int)( 57.29578
+            * atan( (double)((y2-(y*1.0)) / (x2-(x*1.0) ) ) ) );
+    }
+    else {
+        my_course = (int)( 57.29578
+            * atan( (double)((y2-(y*1.0)) / (x-(x2*1.0) ) ) ) );
+    }
+*/
+
+    // Use the mid-latitude formulas for calculating the rhumb line
+    // course.  Modified to minimize the number of conversions we
+    // need to do.
+//    lat_m = (double)( (y_lat + y_lat2) / 2.0 );
+
+    // Convert from Xastir coordinate system
+//    lat_m = (double)( -((lat_m - 32400000l) / 360000.0) );
+
+    lat_m = -((y_lat - 32400000l) / 360000.0)
+            + -((y_lat2 - 32400000l) / 360000.0);
+    lat_m = lat_m / 2.0;
+
+    convert_from_xastir_coordinates(&temp_longitude2,
+        &temp_latitude2,
+        x_long2,
+        y_lat2);
+
+    convert_from_xastir_coordinates(&temp_longitude,
+        &temp_latitude,
+        x_long,
+        y_lat);
+
+    temp = (double)( (temp_longitude2 - temp_longitude)
+            / (temp_latitude2 - temp_latitude) );
+// Check for divide-by-zero here????
+
+    // Calculate course and convert to degrees
+    my_course = (int)( 57.29578 * atan( cos(lat_m) * temp) );
+
+    // The arctan function returns values between -90 and +90.  To
+    // obtain the true course we apply the following rules:
+    if (temp_latitude2 > temp_latitude
+            && temp_longitude2 > temp_longitude) {
+        // Do nothing.
+    }
+    else if (temp_latitude2 < temp_latitude
+            && temp_longitude2 > temp_longitude) {
+        my_course = 180 - my_course;
+    }
+    else if (temp_latitude2 < temp_latitude
+            && temp_longitude2 < temp_longitude) {
+        my_course = 180 + my_course;
+    }
+    else if (temp_latitude2 > temp_latitude
+            && temp_longitude2 < temp_longitude) {
+        my_course = 360 - my_course;
+    }
+    else {
+        // ??
+        // Do nothing.
+    }
+
+//fprintf(stderr,"course:%d\n", my_course);
+
+    // Convert to screen angle
+//    my_course = my_course + 90;
+
+    // Compute whether either of them are on-screen.  If so, draw at
+    // least part of the line between them.
+    (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+    (void)XSetForeground(XtDisplay(da),gc,color); // red3
+
+// Check that our parameters are within spec for XDrawLine.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+    (void)XDrawLine(XtDisplay(da),where,gc,
+        l16(x),      // int
+        l16(y),      // int
+        l16(x2),     // int
+        l16(y2));    // int
+}
+
+ 
+
+
+
+//draw_pod_circle(64000000l, 32400000l, 10, colors[0x44], pixmap_final);
+//
+// Probability of Detection circle:  A circle around the point last
+// seen drawn at the distance that a person of that description
+// could travel since they were last seen.  It helps to limit a
+// search to a reasonable area.
+//
+// It'd be nice to have some method of showing where the center of
+// the circle was as well, in case we don't have a PLS object placed
+// there also.  Perhaps a small dot and/or four lines going from
+// that point to the edge of the circle?
+//
+// range is in miles
+// x_long/y_lat are in Xastir lat/lon units
+//
+void draw_pod_circle(long x_long, long y_lat, double range, int color, Pixmap where) {
+    double diameter;
+    double a,b;
+
+
+// Prevents it from being drawn when the symbol is off-screen.
+// It'd be better to check for lat/long +/- range to see if it's on the screen.
+
+//    if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+
+//        if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+
+//            if ((x_long < 0) || (x_long > 129600000l))
+//                return;
+
+//            if ((y_lat < 0) || (y_lat > 64800000l))
+//                return;
+
+            // Range is in miles.  Bottom term is in meters before the 0.0006214
+            // multiplication factor which converts it to miles.
+            // Equation is:  2 * ( range(mi) / x-distance across window(mi) )
+            diameter = 2.0 * ( range/
+                (scale_x * calc_dscale_x(center_longitude,center_latitude) * 0.0006214 ) );
+
+            // If less than 4 pixels across, skip drawing it.
+            if (diameter <= 4.0)
+                return;
+
+            a = diameter;
+            b = diameter / 2;
+
+            //fprintf(stderr,"Range:%f\tDiameter:%f\n",range,diameter);
+
+            (void)XSetLineAttributes(XtDisplay(da), gc, 2, LineSolid, CapButt,JoinMiter);
+            //(void)XSetForeground(XtDisplay(da),gc,colors[0x0a]);
+            //(void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+            (void)XSetForeground(XtDisplay(da),gc,color);
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+            (void)XDrawArc(XtDisplay(da),where,gc,
+                l16(((x_long-NW_corner_longitude)/scale_x)-(diameter/2)), // int
+                l16(((y_lat-NW_corner_latitude)/scale_y)-(diameter/2)),   // int
+                lu16(diameter),         // unsigned int
+                lu16(diameter),         // unsigned int
+                l16(0),                 // int
+                l16(64*360));           // int
+
+// We may need to check for the lat/long being way too far
+// off-screen, refusing to draw the circles if so, if and only if we
+// get into X11 drawing bugs as-is.
+
+
+//        }
+//    }
+}
+
+
+
+
+
+// range is in centimeters (0 to 65535 representing 0 to 655.35 meters)
+// x_long/y_lat are in Xastir lat/lon units
+// lat_precision/lon-precision are in 100ths of seconds of lat/lon
+//
+void draw_precision_rectangle(long x_long,
+                              long y_lat,
+                              double range, // Not implemented yet
+                              unsigned int lat_precision,
+                              unsigned int lon_precision,
+                              int color,
+                              Pixmap where) {
+
+// Prevents it from being drawn when the symbol is off-screen.
+// It'd be better to check for lat/long +/- range to see if it's on the screen.
+
+    if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+
+        if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+            long x2, y2;
+
+
+//            if ((x_long < 0) || (x_long > 129600000l))
+//                return;
+
+//            if ((y_lat < 0) || (y_lat > 64800000l))
+//                return;
+
+            (void)XSetLineAttributes(XtDisplay(da), gc, 2, LineSolid, CapButt,JoinMiter);
+            //(void)XSetForeground(XtDisplay(da),gc,colors[0x0a]);
+            //(void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+            (void)XSetForeground(XtDisplay(da),gc,color);
+
+            if (x_long > 64800000L) {
+                // Eastern hemisphere, add X's (go further east)
+                x2 = x_long + lon_precision;
+            }
+            else {
+                // Western hemisphere, subtract X's (go further west)
+                x2 = x_long - lon_precision;
+            }
+
+            if (y_lat > 32400000L) {
+                // Southern hemisphere, add Y's (go further north)
+                y2 = y_lat + lat_precision;
+            }
+            else {
+                // Northern hemisphere, subtract Y's (go further south)
+                y2 = y_lat - lat_precision;
+            }
+
+            draw_vector(da, x_long, y_lat, x_long, y2, gc, where, 0); // x_long constant
+            draw_vector(da, x_long, y2, x2, y2, gc, where, 0); // y2 constant
+            draw_vector(da, x2, y2, x2, y_lat, gc, where, 0); // x2 constant
+            draw_vector(da, x2, y_lat, x_long, y_lat, gc, where, 0); // y_lat constant
+        }
+    }
+}
+
+
+
+
+
+void draw_phg_rng(long x_long, long y_lat, char *phg, time_t sec_heard, Pixmap where) {
+    double range, diameter;
+    int offx,offy;
+    long xx,yy,xx1,yy1,fxx,fyy;
+    double tilt;
+    double a,b;
+    char is_rng;
+    char *strp;
+
+
+    if ( ((sec_old+sec_heard)>sec_now()) || Select_.old_data ) {
+
+// Prevents it from being drawn when the symbol is off-screen.
+// It'd be better to check for lat/long +/- range to see if it's on the screen.
+
+//        if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+
+//            if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+
+                xx=0l;
+                yy=0l;
+                xx1=0l;
+                yy1=0l;
+                fxx=0l;
+                fyy=0l;
+                tilt=0.0;
+                is_rng=0;
+                offx=0;
+                offy=0;
+
+                if (phg[0] == 'R' && phg[1] == 'N' && phg[2] == 'G')
+                    is_rng = 1;
+
+//                if ((x_long < 0) || (x_long > 129600000l))
+//                    return;
+
+//                if ((y_lat < 0) || (y_lat > 64800000l))
+//                    return;
+
+                if (is_rng) {
+                    strp = &phg[3];
+                    range = atof(strp);
+                }
+                else {
+                    range = phg_range(phg[3],phg[4],phg[5]);
+                }
+
+                // Range is in miles.  Bottom term is in meters before the 0.0006214
+                // multiplication factor which converts it to miles.
+                // Equation is:  2 * ( range(mi) / x-distance across window(mi) )
+                diameter = 2.0 * ( range/
+                    (scale_x * calc_dscale_x(center_longitude,center_latitude) * 0.0006214 ) );
+
+                // If less than 4 pixels across, skip drawing it.
+                if (diameter <= 4.0)
+                    return;
+
+                //fprintf(stderr,"PHG: %s, Diameter: %f\n", phg, diameter);
+
+                a = diameter;
+                b = diameter / 2;
+
+                if (!is_rng) {  // Figure out the directivity, if outside range of 0-8 it's declared to be an omni
+
+                    switch (phg[6]-'0') {
+
+                        case(0):
+                            offx=0;
+                            offy=0;
+                            break;
+
+                        case(1):    //  45
+                            offx=-1*(diameter/6);
+                            offy=diameter/6;
+                            tilt=5.49778;
+                            break;
+
+                        case(2):    //  90
+                            offx=-1*(diameter/6);
+                            offy=0;
+                            tilt=0;
+                            break;
+
+                        case(3):    // 135
+                            offx=-1*(diameter/6);
+                            offy=-1*(diameter/6);
+                            tilt=.78539;
+                            break;
+
+                        case(4):    // 180
+                            offx=0;
+                            offy=-1*(diameter/6);
+                            tilt=1.5707;
+                            break;
+
+                        case(5):    // 225
+                            offx=diameter/6;
+                            offy=-1*(diameter/6);
+                            tilt=2.3561;
+                            break;
+
+                        case(6):    // 270
+                            offx=diameter/6;
+                            offy=0;
+                            tilt=3.14159;
+                            break;
+
+                        case(7):    // 315
+                            offx=diameter/6;
+                            offy=diameter/6;
+                            tilt=3.92699;
+                            break;
+
+                        case(8):    // 360
+                            offx=0;
+                            offy=diameter/6;
+                            tilt=4.71238;
+                            break;
+
+                        default:
+                            offx=0;
+                            offy=0;
+                            break;
+                    }   // End of switch
+                }
+
+                //fprintf(stderr,"PHG=%02f %0.2f %0.2f %0.2f pix %0.2f\n",range,power,height,gain,diameter);
+
+                (void)XSetLineAttributes(XtDisplay(da), gc, 1, LineSolid, CapButt,JoinMiter);
+
+                if ((sec_old+sec_heard)>sec_now())
+                    (void)XSetForeground(XtDisplay(da),gc,colors[0x0a]);
+                else
+                    (void)XSetForeground(XtDisplay(da),gc,colors[0x52]);
+
+                if (is_rng || phg[6]=='0') {    // Draw circl
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+                    (void)XDrawArc(XtDisplay(da),where,gc,
+                        l16(((x_long-NW_corner_longitude)/scale_x)-(diameter/2)), // int
+                        l16(((y_lat-NW_corner_latitude)/scale_y)-(diameter/2)),   // int
+                        lu16(diameter), // unsigned int
+                        lu16(diameter), // unsigned int
+                        l16(0),         // int
+                        l16(64*360));   // int
+                }
+                else {    // Draw oval to depict beam heading
+
+                    // If phg[6] != '0' we still draw a circle, but the center
+                    // is offset in the indicated direction by 1/3 the radius.
+                                
+                    // Draw Circle
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+                    (void)XDrawArc(XtDisplay(da),where,gc,
+                        l16(((x_long-NW_corner_longitude)/scale_x)-(diameter/2) - offx),  // int
+                        l16(((y_lat-NW_corner_latitude)/scale_y)-(diameter/2) - offy),    // int
+                        lu16(diameter), // unsigned int
+                        lu16(diameter), // unsigned int
+                        l16(0),         // int
+                        l16(64*360));   // int
+                }
+//            }
+//        }
+    }
+}
+
+
+
+
+
+// Function to draw DF circles around objects/stations for DF'ing purposes.
+//
+// We change from filled circles to open circles at zoom level 128 for speed purposes.
+//
+void draw_DF_circle(long x_long, long y_lat, char *shgd, time_t sec_heard, Pixmap where) {
+    double range, diameter;
+    int offx,offy;
+    long xx,yy,xx1,yy1,fxx,fyy;
+    double tilt;
+    double a,b;
+
+
+    if ( ((sec_old+sec_heard)>sec_now()) || Select_.old_data ) {
+
+
+// Prevents it from being drawn when the symbol is off-screen.
+// It'd be better to check for lat/long +/- range to see if it's on the screen.
+
+//        if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+
+//            if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+
+//                if ((x_long < 0) || (x_long > 129600000l))
+//                    return;
+
+//                if ((y_lat < 0) || (y_lat > 64800000l))
+//                    return;
+
+                xx=0l;
+                yy=0l;
+                xx1=0l;
+                yy1=0l;
+                fxx=0l;
+                fyy=0l;
+                tilt=0.0;
+                offx=0;
+                offy=0;
+
+                range = shg_range(shgd[3],shgd[4],shgd[5]);
+
+                // Range is in miles.  Bottom term is in meters before the 0.0006214
+                // multiplication factor which converts it to miles.
+                // Equation is:  2 * ( range(mi) / x-distance across window(mi) )
+                //
+                diameter = 2.0 * ( range/
+                    (scale_x * calc_dscale_x(center_longitude,center_latitude) * 0.0006214 ) );
+
+                // If less than 4 pixels across, skip drawing it.
+                if (diameter <= 4.0)
+                    return;
+
+                //fprintf(stderr,"PHG: %s, Diameter: %f\n", shgd, diameter);
+
+                a = diameter;
+                b = diameter / 2;
+
+                // Figure out the directivity, if outside range of 0-8 it's declared to be an omni
+                switch (shgd[6]-'0') {
+                    case(0):
+                        offx=0;
+                        offy=0;
+                        break;
+
+                    case(1):    //  45
+                        offx=-1*(diameter/6);
+                        offy=diameter/6;
+                        tilt=5.49778;
+                        break;
+
+                    case(2):    //  90
+                        offx=-1*(diameter/6);
+                        offy=0;
+                        tilt=0;
+                        break;
+
+                    case(3):    // 135
+                        offx=-1*(diameter/6);
+                        offy=-1*(diameter/6);
+                        tilt=.78539;
+                        break;
+
+                    case(4):    // 180
+                        offx=0;
+                        offy=-1*(diameter/6);
+                        tilt=1.5707;
+                        break;
+
+                    case(5):    // 225
+                        offx=diameter/6;
+                        offy=-1*(diameter/6);
+                        tilt=2.3561;
+                        break;
+
+                    case(6):    // 270
+                        offx=diameter/6;
+                        offy=0;
+                        tilt=3.14159;
+                        break;
+
+                    case(7):    // 315
+                        offx=diameter/6;
+                        offy=diameter/6;
+                        tilt=3.92699;
+                        break;
+
+                    case(8):    // 360
+                        offx=0;
+                        offy=diameter/6;
+                        tilt=4.71238;
+                        break;
+
+                    default:
+                        offx=0;
+                        offy=0;
+                        break;
+                }
+                //fprintf(stderr,"PHG=%02f %0.2f %0.2f %0.2f pix %0.2f\n",range,power,height,gain,diameter);
+
+                //fprintf(stderr,"scale_y: %u\n",scale_y);
+
+                if (scale_y > 128) { // Don't fill in circle if zoomed in too far (too slow!)
+                    (void)XSetLineAttributes(XtDisplay(da), gc_stipple, 1, LineSolid, CapButt,JoinMiter);
+                }
+                else {
+                    (void)XSetLineAttributes(XtDisplay(da), gc_stipple, 8, LineSolid, CapButt,JoinMiter);
+                }
+
+                // Stipple the area instead of obscuring the map underneath
+                (void)XSetStipple(XtDisplay(da), gc_stipple, pixmap_50pct_stipple);
+                (void)XSetFillStyle(XtDisplay(da), gc_stipple, FillStippled);
+
+                // Choose the color for the DF'ing circle
+                // We try to choose similar colors to those used in DOSaprs,
+                // which are qbasic or gwbasic colors.
+                switch (shgd[3]) {
+
+                    case '9':   // Light Red
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x25]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x25]);
+                        break;
+
+                    case '8':   // Red
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2d]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2d]);
+                        break;
+
+                    case '7':   // Light Magenta
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x26]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x26]);
+                        break;
+
+                    case '6':   // Magenta
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2e]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2e]);
+                        break;
+
+                    case '5':   // Light Cyan
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x24]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x24]);
+                        break;
+
+                    case '4':   // Cyan
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2c]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2c]);
+                        break;
+
+                    case '3':   // White
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x0f]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x0f]);
+                        break;
+
+                    case '2':   // Light Blue
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x22]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x22]);
+                        break;
+
+                    case '1':   // Blue
+                        if ((sec_old+sec_heard)>sec_now())  // New
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2a]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x2a]);
+                        break;
+
+                    case '0':   // DarkGray (APRSdos) or Black (looks better). We use Black.
+                    default:
+                        if ((sec_old+sec_heard)>sec_now())  // New (was 0x30)
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x08]);
+                        else                                // Old
+                            (void)XSetForeground(XtDisplay(da),gc_stipple,colors[0x08]);
+                        break;
+                }
+
+                // If shgd[6] != '0' we still draw a circle, but the center
+                // is offset in the indicated direction by 1/3 the radius.
+                                
+                // Draw Circle
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+                (void)XDrawArc(XtDisplay(da),where,gc_stipple,
+                    l16(((x_long-NW_corner_longitude)/scale_x)-(diameter/2) - offx),  // int
+                    l16(((y_lat-NW_corner_latitude)/scale_y)-(diameter/2) - offy),    // int
+                    lu16(diameter), // unsigned int
+                    lu16(diameter), // unsigned int
+                    l16(0),         // int
+                    l16(64*360));   // int
+
+                if (scale_y > 128) { // Don't fill in circle if zoomed in too far (too slow!)
+
+                    while (diameter > 1.0) {
+                        diameter = diameter - 1.0;
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+                        (void)XDrawArc(XtDisplay(da),where,gc_stipple,
+                            l16(((x_long-NW_corner_longitude)/scale_x)-(diameter/2) - offx),  // int
+                            l16(((y_lat-NW_corner_latitude)/scale_y)-(diameter/2) - offy),    // int
+                            lu16(diameter),  // unsigned int
+                            lu16(diameter),  // unsigned int
+                            l16(0),         // int
+                            l16(64*360));   // int
+                    }
+                }
+//            }
+//        }
+    }
+    // Change back to non-stipple for whatever drawing occurs after this
+    (void)XSetFillStyle(XtDisplay(da), gc_stipple, FillSolid);
+}
+
+
+
+
+
+// Draw the ALOHA circle
+// Identical to draw_pod_circle when this was first written, but separated
+// just in case that POD functionality ever changes per the comments in it
+void draw_aloha_circle(long x_long, long y_lat, double range, int color, Pixmap where) {
+    double diameter;
+    double a,b;
+    long width, height;
+
+
+    // Range is in miles.  Bottom term is in meters before the
+    // 0.0006214 multiplication factor which converts it to miles.
+    // Equation is:  2 * ( range(mi) / x-distance across window(mi) )
+    diameter = 2.0 * ( range/
+        (scale_x * calc_dscale_x(center_longitude,center_latitude) * 0.0006214 ) );
+
+    // If less than 4 pixels across, skip drawing it.
+    if (diameter <= 4.0)
+        return;
+
+    a = diameter;
+    b = diameter / 2;
+
+
+    // Check for the center of the circle being off the edge of the
+    // earth (that's _our_ station position by the way!).
+    //
+//    if ((x_long < 0) || (x_long > 129600000l))
+//        return;
+
+//        if ((y_lat < 0) || (y_lat > 64800000l))
+//            return;
+
+    //fprintf(stderr,"Range:%f\tDiameter:%f\n",range,diameter);
+
+    width = (((x_long-NW_corner_longitude)/scale_x)-(diameter/2));
+    height = (((y_lat-NW_corner_latitude)/scale_y)-(diameter/2));
+
+//    if (width < 0 || width > 32767 || height < 0 || height > 32767) {
+//        return;
+//    }
+
+    (void)XSetLineAttributes(XtDisplay(da), gc, 2, LineSolid, CapButt,JoinMiter);
+    //(void)XSetForeground(XtDisplay(da),gc,colors[0x0a]);
+    //(void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+    (void)XSetForeground(XtDisplay(da),gc,color);
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+    (void)XDrawArc(XtDisplay(da),where,gc,
+        l16(width),     // int
+        l16(height),    // int
+        lu16(diameter), // unsigned int
+        lu16(diameter), // unsigned int
+        l16(0),         // int
+        l16(64*360));   // int
+}
+
+
+
+
+
+static int barb_len;
+static int barb_spacing;
+
+
+
+
+
+// Change barb parameters based on our current zoom level, so the
+// barbs don't get too long as we zoom out.
+void set_barb_parameters(void) {
+    float factor = 1.0;
+
+    // Initial settings
+    barb_len = 16;
+    barb_spacing = 16;
+
+    // Scale factor
+    if      (scale_y > 80000)
+        factor = 3.0;
+    else if (scale_y > 40000)
+        factor = 2.5;
+    else if (scale_y > 20000)
+        factor = 2.0;
+    else if (scale_y > 10000)
+        factor = 1.5;
+
+    // Scale them, plus use poor man's rounding
+    barb_len = (int)((barb_len / factor) + 0.5);
+    barb_spacing = (int)((barb_spacing / factor) + 0.5);;
+}
+
+
+
+
+
+void draw_half_barbs(int *i, int quantity, float bearing_radians, long x, long y, char *course, Pixmap where) {
+    float barb_radians = bearing_radians + ( (45/360.0) * 2.0 * M_PI);
+    int j;
+    long start_x, start_y, off_x, off_y;
+
+
+    for (j = 0; j < quantity; j++) {
+        // Starting point for barb is (*i * barb_spacing) pixels
+        // along bearing_radians vector
+        *i = *i + barb_spacing;
+        off_x = *i * cos(bearing_radians);
+        off_y = *i * sin(bearing_radians);
+        start_y = y + off_y;
+        start_x = x + off_x;
+
+        // Set off in the barb direction now
+        off_y = (long)( (barb_len / 2) * sin(barb_radians) );
+        off_x = (long)( (barb_len / 2) * cos(barb_radians) );
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineSolid, CapButt,JoinMiter);
+        (void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+
+// Check that our parameters are within spec for XDrawLine.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+        (void)XDrawLine(XtDisplay(da),where,gc,
+            l16(start_x),           // int
+            l16(start_y),           // int
+            l16(start_x + off_x),   // int
+            l16(start_y + off_y));  // int
+    }
+}
+
+
+
+
+
+void draw_full_barbs(int *i, int quantity, float bearing_radians, long x, long y, char *course, Pixmap where) {
+    float barb_radians = bearing_radians + ( (45/360.0) * 2.0 * M_PI);
+    int j;
+    long start_x, start_y, off_x, off_y;
+
+
+    for (j = 0; j < quantity; j++) {
+        // Starting point for barb is (*i * barb_spacing) pixels
+        // along bearing_radians vector
+        *i = *i + barb_spacing;
+        off_x = *i * cos(bearing_radians);
+        off_y = *i * sin(bearing_radians);
+        start_y = y + off_y;
+        start_x = x + off_x;
+
+        // Set off in the barb direction now
+        off_y = (long)( barb_len * sin(barb_radians) );
+        off_x = (long)( barb_len * cos(barb_radians) );
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineSolid, CapButt,JoinMiter);
+        (void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+
+// Check that our parameters are within spec for XDrawLine.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+        (void)XDrawLine(XtDisplay(da),where,gc,
+            l16(start_x),           // int
+            l16(start_y),           // int
+            l16(start_x + off_x),   // int
+            l16(start_y + off_y));  // int
+    }
+}
+
+
+
+
+
+void draw_triangle_flags(int *i, int quantity, float bearing_radians, long x, long y, char *course, Pixmap where) {
+    float barb_radians = bearing_radians + ( (45/360.0) * 2.0 * M_PI);
+    int j;
+    long start_x, start_y, off_x, off_y, off_x2, off_y2;
+    XPoint points[3];
+
+
+    for (j = 0; j < quantity; j++) {
+        // Starting point for barb is (*i * barb_spacing) pixels
+        // along bearing_radians vector
+        *i = *i + barb_spacing;
+        off_x = *i * cos(bearing_radians);
+        off_y = *i * sin(bearing_radians);
+        start_y = y + off_y;
+        start_x = x + off_x;
+
+        // Calculate 2nd point along staff
+        off_x2 = (barb_spacing/2) * cos(bearing_radians);
+        off_y2 = (barb_spacing/2) * sin(bearing_radians);
+
+        // Set off in the barb direction now
+        off_y = (long)( barb_len * sin(barb_radians) );
+        off_x = (long)( barb_len * cos(barb_radians) );
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineSolid, CapButt,JoinMiter);
+        (void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+
+        points[0].x = start_x;           points[0].y = start_y;
+        points[1].x = start_x + off_x;   points[1].y = start_y + off_y;
+        points[2].x = start_x + off_x2;  points[2].y = start_y + off_y2;
+
+        // Number of points is always 3 here, so we don't need to
+        // check first before calling XFillPolygon().
+        (void)XFillPolygon(XtDisplay(da), where, gc, points, 3, Convex, CoordModeOrigin);
+    }
+}
+
+
+
+
+
+void draw_square_flags(int *i, int quantity, float bearing_radians, long x, long y, char *course, Pixmap where) {
+    float barb_radians = bearing_radians + ( (90/360.0) * 2.0 * M_PI);
+    int j;
+    long start_x, start_y, off_x, off_y, off_x2, off_y2;
+    XPoint points[4];
+
+
+    for (j = 0; j < quantity; j++) {
+        // Starting point for barb is (*i * barb_spacing) pixels
+        // along bearing_radians vector
+        *i = *i + barb_spacing;
+        off_x = *i * cos(bearing_radians);
+        off_y = *i * sin(bearing_radians);
+        start_y = y + off_y;
+        start_x = x + off_x;
+
+        // Calculate 2nd point along staff
+        off_x2 = (barb_spacing/2) * cos(bearing_radians);
+        off_y2 = (barb_spacing/2) * sin(bearing_radians);
+
+        // Set off in the barb direction now
+        off_y = (long)( barb_len * sin(barb_radians) );
+        off_x = (long)( barb_len * cos(barb_radians) );
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineSolid, CapButt,JoinMiter);
+        (void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+
+        points[0].x = start_x;                   points[0].y = start_y;
+        points[1].x = start_x + off_x;           points[1].y = start_y + off_y;
+        points[2].x = start_x + off_x + off_x2;  points[2].y = start_y + off_y + off_y2;
+        points[3].x = start_x + off_x2;          points[3].y = start_y + off_y2;
+
+        // Number of points is always 4 here, so we don't need to
+        // check first before calling XFillPolygon().
+        (void)XFillPolygon(XtDisplay(da), where, gc, points, 4, Convex, CoordModeOrigin);
+    }
+}
+
+
+
+
+
+// Function to draw wind barbs.  Use speed in knots to determine the
+// flags and barbs to draw along the shaft.  Course is in true
+// degrees, in the direction that the wind is coming from.
+//
+//   Square flag = 100 knots
+// Triangle flag = 50 knots
+//     Full barb = 10 knots
+//     Half barb = 5 knots
+//
+void draw_wind_barb(long x_long, long y_lat, char *speed,
+        char *course, time_t sec_heard, Pixmap where) {
+    int square_flags = 0;
+    int triangle_flags = 0;
+    int full_barbs = 0;
+    int half_barbs = 0;
+    int shaft_length = 0;
+    int my_speed = atoi(speed);     // In mph (so far)
+    int my_course = atoi(course);   // In � true
+    float bearing_radians;
+    long off_x,off_y;
+    long x,y;
+    int i;
+
+
+// Ghost the wind barb if sec_heard is too long.
+// (TBD)
+
+
+// What to do if my_speed is zero?  Blank out any wind barbs
+// that were written before?
+
+
+    // Prevents it from being drawn when the symbol is off-screen.
+    // It'd be better to check for lat/long +/- range to see if it's
+    // on the screen.
+
+    if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+
+        if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+
+//            if ((x_long < 0) || (x_long > 129600000l))
+//                return;
+
+//            if ((y_lat < 0) || (y_lat > 64800000l))
+//                return;
+
+            // Ok to draw wind barb
+
+        }
+        else {
+            return;
+        }
+    }
+    else {
+        return;
+    }
+
+    // Set up the constants for our zoom level
+    set_barb_parameters();
+
+    // Convert from mph to knots for wind speed.
+    my_speed = my_speed * 0.8689607;
+
+    //fprintf(stderr,"mph:%s, knots:%d\n",speed,my_speed);
+
+    // Adjust so that it fits our screen angles.  We're off by
+    // 90 degrees.
+    my_course = (my_course - 90) % 360;
+
+    square_flags = (int)(my_speed / 100);
+    my_speed = my_speed % 100;
+
+    triangle_flags = (int)(my_speed / 50);
+    my_speed = my_speed % 50;
+
+    full_barbs = (int)(my_speed / 10);
+    my_speed = my_speed % 10;
+
+    half_barbs = (int)(my_speed / 5);
+
+    shaft_length = barb_spacing * (square_flags + triangle_flags + full_barbs
+                   + half_barbs + 1);
+
+    // Set a minimum length for the shaft?
+    if (shaft_length < 2)
+        shaft_length = 2;
+
+    if (debug_level & 128) {
+        fprintf(stderr,"Course:%d,\tL:%d,\tsq:%d,\ttr:%d,\tfull:%d,\thalf:%d\n",
+            atoi(course),
+            shaft_length,
+            square_flags,
+            triangle_flags,
+            full_barbs,
+            half_barbs);
+    }
+
+    // Draw shaft at proper angle.
+    bearing_radians = (my_course/360.0) * 2.0 * M_PI;
+
+    off_y = (long)( shaft_length * sin(bearing_radians) );
+    off_x = (long)( shaft_length * cos(bearing_radians) );
+
+    x = (x_long - NW_corner_longitude)/scale_x;
+    y = (y_lat - NW_corner_latitude)/scale_y;
+
+    (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineSolid, CapButt,JoinMiter);
+    (void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+
+// Check that our parameters are within spec for XDrawLine.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+    (void)XDrawLine(XtDisplay(da),where,gc,
+            l16(x),             // int
+            l16(y),             // int
+            l16(x + off_x),     // int
+            l16(y + off_y));    // int
+
+    // Increment along shaft and draw filled polygons at:
+    // "(angle + 45) % 360" degrees to create flags.
+
+    i = barb_spacing;
+    // Draw half barbs if any
+    if (half_barbs)
+        draw_half_barbs(&i,
+            half_barbs,
+            bearing_radians,
+            x,
+            y,
+            course,
+            where);
+
+    // Draw full barbs if any
+    if (full_barbs)
+        draw_full_barbs(&i,
+            full_barbs,
+            bearing_radians,
+            x,
+            y,
+            course,
+            where);
+
+    // Draw triangle flags if any
+    if (triangle_flags)
+        draw_triangle_flags(&i,
+                triangle_flags,
+                bearing_radians,
+                x,
+                y,
+                course,
+                where);
+
+    // Draw rectangle flags if any
+    if (square_flags)
+        draw_square_flags(&i,
+              square_flags,
+              bearing_radians,
+              x,
+              y,
+              course,
+              where);
+}
+
+
+
+
+
+// Function to draw beam headings for DF'ing purposes.  Separates NRQ into its
+// components, which are Number/Range/Quality.
+//
+// If N is 0, then the NRQ value is meaningless.  1 through 8 are hits per period
+// of time (auto-DF'ing equipment).  A value of 8 means all samples possible got
+// a hit.  A value of 9 means that the report is manual.
+//
+// Range limits the length of the line to the original map's scale of the sending
+// station.  The range is 2**R, so for R=4 the range would be 16 miles.
+//
+// Q is a single digit from 0-9 and provides indication of bearing accuracy:
+// 0 Useless
+// 1 <240 deg (worst)
+// 2 <120 deg
+// 3 <64  deg
+// 4 <32  deg
+// 5 <16  deg
+// 6 <8   deg
+// 7 <4   deg
+// 8 <2   deg
+// 9 <1   deg (best)
+//
+//
+// TODO: Should we draw with XOR for this function?  Would appear on
+// most maps that way, and we wouldn't have to worry much about
+// color.
+//
+// TODO: If Q between 1 and 8, shade the entire area to show the
+// beam width?
+//
+//
+// Latest:  We ignore the color parameter and draw everything using
+// red3.
+//
+// The distance calculations below use nautical miles.  Here we
+// ignore the difference between nautical and statute miles as it
+// really doesn't make much difference how long we draw the vectors:
+// The angle is what is important here.
+//
+void draw_bearing(long x_long, long y_lat, char *course,
+                  char *bearing, char *NRQ, int color, int draw_beamwidth, 
+                  int draw_bearing,
+                  time_t sec_heard, Pixmap where) {
+    double range = 0;
+    double real_bearing = 0.0;
+    double real_bearing_min = 0.0;
+    double real_bearing_max = 0.0;
+    int width = 0;
+    long x_long2, x_long3, x_long4, y_lat2, y_lat3, y_lat4;
+    double screen_miles;
+
+
+    if ( ((sec_old+sec_heard)>sec_now()) || Select_.old_data ) {
+
+        // Check for a zero value for N.  If found, the NRQ value is meaningless
+        // and we need to assume some working default values.
+        if (NRQ[0] != '0') {
+
+            // "range" as used below is in nautical miles.
+            range = (double)( pow(2.0,NRQ[1] - '0') );
+
+            switch (NRQ[2]) {
+                case('1'):
+                    width = 240;    // Degrees of beam width.  What's the point?
+                    break;
+                case('2'):
+                    width = 120;    // Degrees of beam width.  What's the point?
+                    break;
+                case('3'):
+                    width = 64; // Degrees of beam width.  What's the point?
+                    break;
+                case('4'):
+                    width = 32; // Degrees of beam width.  Starting to be usable.
+                    break;
+                case('5'):
+                    width = 16; // Degrees of beam width.  Usable.
+                    break;
+                case('6'):
+                    width = 8;  // Degrees of beam width.  Usable.
+                    break;
+                case('7'):
+                    width = 4;  // Degrees of beam width.  Nice!
+                    break;
+                case('8'):
+                    width = 2;  // Degrees of beam width.  Nice!
+                    break;
+                case('9'):
+                    width = 1;  // Degrees of beam width.  Very Nice!
+                    break;
+                case('0'):  // "Useless" beam width according to spec
+                default:
+                    return; // Exit routine without drawing vectors
+                    break;
+            }
+        }
+        else {  // Assume some default values.
+            range = 512.0;  // Assume max range of 512 nautical miles
+            width = 8;      // Assume 8 degrees for beam width
+        }
+
+        // We have the course of the vehicle and the bearing from the
+        // vehicle.  Now we need the real bearing.
+        //
+        if (atoi(course) != 0) {
+            real_bearing = atoi(course) + atoi(bearing);
+            real_bearing_min = real_bearing + 360.0 - (width/2.0);
+            real_bearing_max = real_bearing + (width/2.0);
+        }
+        else {
+            real_bearing = atoi(bearing);
+            real_bearing_min = real_bearing + 360.0 - (width/2.0);
+            real_bearing_max = real_bearing + (width/2.0);
+        }
+
+        while (real_bearing > 360.0)
+            real_bearing -= 360.0;
+
+        while (real_bearing_min > 360.0)
+            real_bearing_min -= 360.0;
+
+        while (real_bearing_max > 360.0)
+            real_bearing_max -= 360.0;
+
+        // want this in nautical miles
+        screen_miles = scale_x * calc_dscale_x(center_longitude,center_latitude) 
+          * .5400;
+
+        // Shorten range to more closely fit the screen
+        if ( range > (3.0 * screen_miles) )
+            range = 3.0 * screen_miles;
+
+        // We now have a distance and a bearing for each vector.
+        // Compute the end points via dead-reckoning here.  It will give
+        // us points between which we can draw a vector and makes the
+        // rest of the code much easier.  Need to skip adding 270
+        // degrees if we use that method.
+        //
+        if (draw_beamwidth) {
+          compute_DR_position(x_long,       // input (long)
+                              y_lat,        // input (long)
+                              range,        // input in nautical miles (double)
+                              real_bearing_min,     // input in � true (double)
+                              &x_long2,             // output (*long)
+                              &y_lat2);             // output (*long)
+
+          compute_DR_position(x_long,       // input (long)
+                              y_lat,        // input (long)
+                              range,        // input in nautical miles (double)
+                              real_bearing_max,    // input in � true (double)
+                              &x_long3,            // output (*long)
+                              &y_lat3);            // output (*long)
+        }
+
+        if (draw_bearing) {
+          compute_DR_position(x_long,       // input (long)
+                              y_lat,        // input (long)
+                              range,        // input in nautical miles (double)
+                              real_bearing,   // input in � true (double)
+                              &x_long4,           // output (*long)
+                              &y_lat4);           // output (*long)
+        }
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 2, LineSolid, CapButt,JoinMiter);
+        //(void)XSetForeground(XtDisplay(da),gc,colors[0x0a]);
+        if (draw_beamwidth) {
+          (void)XSetForeground(XtDisplay(da),gc,colors[0x4a]); // red2
+          draw_vector(da, x_long, y_lat, x_long2, y_lat2, gc, where, 0);
+          draw_vector(da, x_long, y_lat, x_long3, y_lat3, gc, where, 0);
+        }
+
+        if (draw_bearing) {
+          (void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+          draw_vector(da, x_long, y_lat, x_long4, y_lat4, gc, where, 0);
+        }          
+    }
+
+    // Change back to non-stipple for whatever drawing occurs after this
+//    (void)XSetFillStyle(XtDisplay(da), gc_tint, FillSolid);
+}
+
+
+
+
+
+// TODO:  Pass back the modified x_long/y_lat to the calling routine
+// and use the new lat/long to place the symbol.  This will knock
+// off the digits on the right that the ambiguity specifies.  We
+// then add 1/2 the rectangle offsets in order to get the symbol
+// placed in the middle of the rectangle.
+//
+void draw_ambiguity(long x_long, long y_lat, char amb, long *amb_x_long, long *amb_y_lat, time_t sec_heard, Pixmap where) {
+    unsigned long left, right, top, bottom;
+    long offset_lat, offset_long;
+    int scale_limit;
+
+
+    // Assign these first in case we do a sudden return from the
+    // function.
+    *amb_x_long = x_long;
+    *amb_y_lat = y_lat;
+
+//    if ((x_long < 0) || (x_long > 129600000l))
+//        return;
+
+//    if ((y_lat < 0) || (y_lat > 64800000l))
+//        return;
+
+    switch (amb) {
+    case 1: // +- 1/10th minute
+        offset_lat = offset_long = 600;
+        scale_limit = 256;
+
+        // Truncate digits off the right
+        x_long = (long)(x_long / 600);
+        x_long = x_long * 600;
+        y_lat = (long)(y_lat / 600);
+        y_lat = y_lat * 600;
+        break;
+
+    case 2: // +- 1 minute
+        offset_lat = offset_long = 6000;
+        scale_limit = 2048;
+
+        // Truncate digits off the right
+        x_long = (long)(x_long / 6000);
+        x_long = x_long * 6000;
+        y_lat = (long)(y_lat / 6000);
+        y_lat = y_lat * 6000;
+        break;
+
+    case 3: // +- 10 minutes
+        offset_lat = offset_long = 60000;
+        scale_limit = 16384;
+
+        // Truncate digits off the right
+        x_long = (long)(x_long / 60000);
+        x_long = x_long * 60000;
+        y_lat = (long)(y_lat / 60000);
+        y_lat = y_lat * 60000;
+        break;
+
+    case 4: // +- 1 degree
+        offset_lat = offset_long = 360000;
+        scale_limit = 65536;
+
+        // Truncate digits off the right
+        x_long = (long)(x_long / 360000);
+        x_long = x_long * 360000;
+        y_lat = (long)(y_lat / 360000);
+        y_lat = y_lat * 360000;
+        break;
+
+// TODO:  The last two cases need fixing up like the above
+
+    case 5: // grid square: 2.5min lat x 5min lon
+        offset_lat  = 360000.0 * 1.25 / 60.0;
+        offset_long = 360000.0 * 2.50 / 60.0;
+        scale_limit = 1024;
+        break;
+
+    case 6: // grid square: 1deg lat x 2deg lon
+        offset_lat  = 360000.0 * 0.5;
+        offset_long = 360000.0 * 1.0;
+        scale_limit = 16384;
+        break;
+
+    case 0:
+    default:
+        return; // if no ambiguity, do nothing
+        break;
+
+    }
+
+    // Re-assign them here as they should have been truncated on the
+    // right by the above code.  We'll use these new values
+    // to draw the symbols and the other associated symbol data
+    // (external to this function).
+    //
+    *amb_x_long = x_long + (offset_long/2);
+    *amb_y_lat = y_lat + (offset_lat / 2);
+
+
+    if (scale_y > scale_limit) {
+        // Ambiguity box will be smaller than smallest symbol so
+        // don't draw it.
+//fprintf(stderr,"scale_y > scale_limit\n");
+        return;
+    }
+
+    if ( ((sec_old+sec_heard)<=sec_now()) && !Select_.old_data ) {
+        return;
+    }
+
+    left   = x_long;
+    top    = y_lat;
+    right  = x_long + offset_long;
+    bottom = y_lat  + offset_lat;
+
+
+    (void)XSetForeground(XtDisplay(da), gc, colors[0x08]);
+
+    // Draw rectangle (unfilled) plus vectors from symbol to
+    // corners.
+
+    (void)XSetLineAttributes(XtDisplay(da), gc,
+        2, LineOnOffDash, CapButt,JoinMiter);
+
+    // Top line of rectangle
+    draw_vector(da,left,top,right,top,gc,pixmap_final, 0);
+
+    // Bottom line of rectangle
+    draw_vector(da,left,bottom,right,bottom,gc,pixmap_final, 1);
+        
+    // Left line of rectangle
+    draw_vector(da,left,top,left,bottom,gc,pixmap_final, 1);
+ 
+    // Right line of rectangle
+    draw_vector(da,right,top,right,bottom,gc,pixmap_final, 1);
+
+    // Diagonal lines 
+    draw_vector(da,left,top,right,bottom,gc,pixmap_final, 1);
+    draw_vector(da,right,top,left,bottom,gc,pixmap_final, 1);
+}
+
+
+
+
+
+// Function which specifies whether any part of a bounding box fits
+// on the screen, using screen coordinates as inputs.
+//
+static __inline__ int onscreen(long left, long right, long top, long bottom) {
+    // This checks to see if any part of a box is on the screen.
+    if (left > screen_width || right < 0 || top > screen_height || bottom < 0)
+        return 0;
+    else
+        return 1;
+}
+
+
+
+
+
+// According to the spec, the lat/long point is the upper left
+// corner of the object, and the offsets are down and to the right
+// (except for one line type where it's down and to the left).  This
+// doesn't appear to be the case in dos/winAPRS.  Matching what they
+// do:
+//
+// Type 0 Circle:    Tie = center, offsets = vert/horiz. sizes.
+// Type 1 Line:      Tie = bottom right, offsets = left and up.
+// Type 2 Ellipse:   Tie = center, offsets = vert/horiz. sizes.
+// Type 3 Triangle:  Tie = bottom right, offsets = height/width.
+// Type 4 Rectangle: Tie = lower right, offsets = left and up.
+// Type 5 Circle:    Tie = center, offsets = vert/horiz. sizes.
+// Type 6 Line:      Tie = bottom left, offsets = right and up.
+// Type 7 Ellipse:   Tie = center, offsets = vert/horiz. sizes.
+// Type 8 Triangle:  Tie = bottom right, offsets = height/width.
+// Type 9 Rectangle: Tie = lower right, offsets = left and up.
+//
+// Exceptions to this are the triangle, ellipse, and circle.  The
+// ellipse and circle have the lat/long as the center point.  The
+// triangle is an isosceles triangle with the lat/long point being
+// the bottom right and the bottom of the triangle being horizontal.
+//
+void draw_area(long x_long, long y_lat, char type, char color,
+               char sqrt_lat_off, char sqrt_lon_off, unsigned int width, time_t sec_heard, Pixmap where) {
+    long left, top, right, bottom, xoff, yoff;
+    int  c;
+    XPoint points[4];
+
+
+//    if ((x_long < 0) || (x_long > 129600000l) ||
+//        (y_lat  < 0) || (y_lat  > 64800000l))
+//        return;
+
+    xoff = 360000.0 / 1500.0 * (sqrt_lon_off * sqrt_lon_off) / scale_x;
+    yoff = 360000.0 / 1500.0 * (sqrt_lat_off * sqrt_lat_off) / scale_y;
+
+    right  = (x_long - NW_corner_longitude) / scale_x;
+    bottom = (y_lat  - NW_corner_latitude)  / scale_y;
+    left   = right  - xoff;
+    top    = bottom - yoff;
+
+    // colors[0x21] is the first in the list of area object colors in main.c
+    c = colors[0x21 + color];
+
+    (void)XSetForeground(XtDisplay(da), gc, c);
+    if (xoff < 20 || yoff < 20)
+        (void)XSetLineAttributes(XtDisplay(da), gc, 1, LineSolid, CapButt,JoinMiter);
+    else
+        (void)XSetLineAttributes(XtDisplay(da), gc, 2, LineSolid, CapButt,JoinMiter);
+    (void)XSetFillStyle(XtDisplay(da), gc, FillSolid); // just in case
+    (void)XSetStipple(XtDisplay(da), gc, pixmap_50pct_stipple);
+
+    switch (type) {
+    case AREA_OPEN_BOX:
+        if (onscreen(left, right, top, bottom)) {
+
+// Check that our parameters are within spec for XDrawRectangle
+// Tricky 'cuz the XRectangle struct has short's and unsigned short's,
+// while XDrawRectangle man-page says int's/unsigned int's.  We'll
+// stick to 16-bit just to make sure.
+
+            (void)XDrawRectangle(XtDisplay(da), where, gc,
+                 l16(left),     // int
+                 l16(top),      // int
+                 lu16(xoff),    // unsigned int
+                 lu16(yoff));   // unsigned int
+        }
+        break;
+    case AREA_FILLED_BOX:
+        if (onscreen(left, right, top, bottom)) {
+            (void)XSetFillStyle(XtDisplay(da), gc, FillStippled);
+            (void)XFillRectangle(XtDisplay(da), where, gc, l16(left), l16(top), l16(xoff), l16(yoff));
+        }
+        break;
+    /* For the rest of the objects, the l16 limiting of the values is inadequate because the
+       shapes will still be draw wrong if the value actually was limited down.
+       However, this is slightly better than passing long or int values that would just be
+       used as 16bit by X (i.e.: truncated) until I/we come up with some sort of clipping algorithm.
+       In real use, what I'm talking about will occur based on two things: the size of the area and
+       the zoom level being used.  The more the extents of the area go beyond the edges of the screen,
+       the more this will happen. N7TAP */
+    case AREA_OPEN_CIRCLE:
+    case AREA_OPEN_ELLIPSE:
+        right  += xoff;
+        bottom += yoff;
+        if (onscreen(left, right, top, bottom)) {
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+            (void)XDrawArc(XtDisplay(da), where, gc,
+                 l16(left),         // int
+                 l16(top),          // int
+                 lu16(2*xoff),      // unsigned int
+                 lu16(2*yoff),      // unsigned int
+                 l16(0),            // int
+                 l16(64 * 360));    // int
+        }
+        break;
+    case AREA_FILLED_CIRCLE:
+    case AREA_FILLED_ELLIPSE:
+        right  += xoff;
+        bottom += yoff;
+        if (onscreen(left, right, top, bottom)) {
+            (void)XSetFillStyle(XtDisplay(da), gc, FillStippled);
+            (void)XFillArc(XtDisplay(da), where, gc, l16(left), l16(top), l16(2*xoff), l16(2*yoff), 0, 64 * 360);
+        }
+        break;
+    case AREA_LINE_RIGHT:
+        left  += xoff;
+        right += xoff;
+        if (width > 0) {
+            double angle = atan((float)xoff/(float)yoff);
+// Check for divide-by-zero here???
+
+            int conv_width = width/(scale_x*calc_dscale_x(center_longitude,center_latitude)*0.0006214);
+            points[0].x = l16(left-(conv_width * cos(angle))+xoff);
+            points[0].y = l16(top -(conv_width * sin(angle)));
+            points[1].x = l16(left-(conv_width * cos(angle)));
+            points[1].y = l16(top -(conv_width * sin(angle))+yoff);
+            points[2].x = l16(left+(conv_width * cos(angle)));
+            points[2].y = l16(top +(conv_width * sin(angle))+yoff);
+            points[3].x = l16(left+(conv_width * cos(angle))+xoff);
+            points[3].y = l16(top +(conv_width * sin(angle)));
+            if (onscreen(points[1].x, points[3].x, points[0].y, points[2].y)) {
+                (void)XSetFillStyle(XtDisplay(da), gc, FillStippled);
+
+                // Number of points is always 4 here, so we don't
+                // need to check first before calling
+                // XFillPolygon().
+                (void)XFillPolygon(XtDisplay(da), where, gc, points, 4, Convex, CoordModeOrigin);
+            }
+        }
+        if (onscreen(left, right, top, bottom)) {
+            (void)XSetFillStyle(XtDisplay(da), gc, FillSolid);
+
+// Check that our parameters are within spec for XDrawLine.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+            (void)XDrawLine(XtDisplay(da), where, gc,
+                l16(left),      // int
+                l16(bottom),    // int
+                l16(right),     // int
+                l16(top));      // int
+        }
+        break;
+    case AREA_LINE_LEFT:
+        if (width > 0) {
+            double angle = atan((float)xoff/(float)yoff);
+// Check for divide-by-zero here???
+
+            int conv_width = width/(scale_x*calc_dscale_x(center_longitude,center_latitude)*0.0006214);
+            points[0].x = l16(left+(conv_width * cos(angle)));
+            points[0].y = l16(top -(conv_width * sin(angle)));
+            points[1].x = l16(left+(conv_width * cos(angle))+xoff);
+            points[1].y = l16(top -(conv_width * sin(angle))+yoff);
+            points[2].x = l16(left-(conv_width * cos(angle))+xoff);
+            points[2].y = l16(top +(conv_width * sin(angle))+yoff);
+            points[3].x = l16(left-(conv_width * cos(angle)));
+            points[3].y = l16(top +(conv_width * sin(angle)));
+            if (onscreen(points[3].x, points[1].x, points[0].y, points[2].y)) {
+                (void)XSetFillStyle(XtDisplay(da), gc, FillStippled);
+
+                // Number of points is always 4 here, so we don't
+                // need to check first before calling
+                // XFillPolygon().
+                (void)XFillPolygon(XtDisplay(da), where, gc, points, 4, Convex, CoordModeOrigin);
+            }
+        }
+        if (onscreen(left, right, top, bottom)) {
+            (void)XSetFillStyle(XtDisplay(da), gc, FillSolid);
+
+// Check that our parameters are within spec for XDrawLine.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+            (void)XDrawLine(XtDisplay(da), where, gc,
+                l16(right),     // int
+                l16(bottom),    // int
+                l16(left),      // int
+                l16(top));      // int
+        }
+        break;
+    case AREA_OPEN_TRIANGLE:
+        left -= xoff;
+        points[0].x = l16(right);     points[0].y = l16(bottom);
+        points[1].x = l16(left+xoff); points[1].y = l16(top);
+        points[2].x = l16(left);      points[2].y = l16(bottom);
+        points[3].x = l16(right);     points[3].y = l16(bottom);
+        if (onscreen(left, right, top, bottom)) {
+
+// Check that our parameters are within spec for XDrawLines.  We'll
+// stick to 16-bit values here due to warnings on the man-page
+// regarding XSegment structs and the protocol only handling
+// short's/unsigned short's, just in case.
+
+            (void)XDrawLines(XtDisplay(da), where, gc,
+                points,             // XPoint *
+                l16(4),             // int
+                CoordModeOrigin);   // int
+        }
+        break;
+    case AREA_FILLED_TRIANGLE:
+        left -= xoff;
+        points[0].x = l16(right);     points[0].y = l16(bottom);
+        points[1].x = l16(left+xoff); points[1].y = l16(top);
+        points[2].x = l16(left);      points[2].y = l16(bottom);
+        if (onscreen(left, right, top, bottom)) {
+            (void)XSetFillStyle(XtDisplay(da), gc, FillStippled);
+
+            // Number of points is always 3 here, so we don't need
+            // to check first before calling XFillPolygon().
+            (void)XFillPolygon(XtDisplay(da), where, gc, points, 3, Convex, CoordModeOrigin);
+        }
+        break;
+    default:
+        break;
+    }
+    (void)XSetFillStyle(XtDisplay(da), gc, FillSolid);
+}
+
+
+
+
+
+/* DK7IN: Statistics for colors in all symbols (as of 16.03.2001)
+60167 .
+ 6399 q
+ 3686 m
+ 3045 c
+ 2034 j
+ 1903 h
+ 1726 l
+ 1570 k
+ 1063 g
+ 1051 #
+  840 p
+  600 ~
+  477 i
+  443 n
+  430 a
+  403 o
+  337 f
+  250 b
+  207 e
+  169 d
+*/
+
+
+
+
+
+// read pixels from file, speeding it up by smart ordering of switches
+void read_symbol_from_file(FILE *f, char *pixels, char table_char) {
+    int x,y;                
+    int color;
+    char line[100];
+    char pixels_copy[400];
+    char *p,*q;
+    unsigned char a, b, c;
+
+    for (y=0;y<20;y++) {
+        (void)get_line(f,line,100);
+        for (x=0;x<20;x++) {
+            switch (line[x]) {
+                case('.'):       // transparent
+                    color=0xff;
+                    break;
+                case('q'):       // #000000  black   0%
+                    color=0x51;
+                    break;
+                case('m'):       // #FFFFFF  white 100%
+                    color=0x4d;
+                    break;
+                case('c'):       // #CCCCCC  gray80 80%
+                    color=0x43;
+                    break;
+                case('j'):       // #EE0000  red2
+                    color=0x4a;
+                    break;
+                case('h'):       // #00BFFF  Deep sky blue
+                    color=0x48;
+                    break;
+                case('l'):       // #0000CD  mediumblue
+                    color=0x4c;
+                    break;
+                case('k'):       // #00CD00  green3
+                    color=0x4b;
+                    break;
+                case('g'):       // #00008B  blue4
+                    color=0x47;
+                    break;
+                case('#'):       // #FFFF00  yellow
+                    color=0x40;
+                    break;
+                case('p'):       // #454545  gray27 27%
+                    color=0x50;
+                    break;
+                case('~'):       // used in the last two symbols in the file
+                    color=0xff;  // what should it be? was transparent before...
+                    break;
+                case('i'):       // #006400  Dark Green
+                    color=0x49;
+                    break;
+                case('n'):       // #878787  gray53 52%
+                    color=0x4e;
+                    break;
+                case('a'):       // #CD6500  darkorange2
+                    color=0x41;
+                    break;
+                case('o'):       // #5A5A5A  gray59 35%
+                    color=0x4f;
+                    break;
+                case('f'):       // #CD3333  brown3
+                    color=0x46;
+                    break;
+                case('b'):       // #A020F0  purple
+                    color=0x42;
+                    break;
+                case('e'):       // #FF4040  brown1
+                    color=0x45;
+                    break;
+                case('d'):       // #CD0000  red3
+                    color=0x44;
+                    break;
+                case('r'):       //          LimeGreen  DK7IN: saw this in the color definitions...
+                    color=0x52;                         // so we could use it
+                    break;
+                default:
+                    color=0xff;
+                    break;
+            }
+            pixels[y*20+x] = (char)(color);
+        }
+    }
+
+    // Create outline on icons, if needed
+    // Do not change the overlays and "number" tables
+    if((icon_outline_style != 0) && (table_char != '~') && (table_char != '#'))
+    {
+        switch(icon_outline_style) {
+        case 1:  color = 0x51; // Black
+                 break;
+        //case 2:  color = 0x43; // Grey 80%
+        case 2:  color = 0x4e; // Grey 52%
+                 break;
+        case 3:  color = 0x4d; // White
+                 break;
+        default: color = 0xff; // Transparent
+                 break;
+        }
+
+        p = pixels;
+        q = &pixels_copy[0];
+
+        for (y=0;y<20;y++) {
+            for (x=0;x<20;x++) {
+                *q = *p; // copy current color
+
+                // If transparent see if the pixel is on the edge
+                if(*q == (char) 0xff)
+                {
+                    //check if left or right is none transparent
+                    b = c = 0xff;
+
+                    // left (left only possible if x > 0)
+                    if(x > 0)
+                        b = p[-1];
+                    // right (right only possible if x < 19)
+                    if(x < 19)
+                        c = p[+1];
+
+                    // if non-transparent color is found change pixel
+                    // to outline color
+                    if((b != (unsigned char) 0xff)
+                            || (c != (unsigned char) 0xff)) {
+                        // change to icon outline color
+                        *q = color;
+                    }
+
+                    if((y > 0) && (*q == (char) 0xff)) {
+                        //check if left-up, up or right-up is none transparent
+                        //"up" only possible if y > 0
+                        a = b = c = 0xff;
+
+                        // left-up (left only possible if x > 0)
+                        if(x > 0)
+                            a = p[-21];
+                        // up
+                        b = p[-20];
+                        // right-up (right only possible if x < 19)
+                        if(x < 19)
+                            c = p[-19];
+
+                        // if non-transparent color is found change pixel
+                        // to outline color
+                        if((a != (unsigned char) 0xff)
+                                || (b != (unsigned char) 0xff)
+                                || (c != (unsigned char) 0xff)) {
+                            // change to icon outline color
+                            *q = color;
+                        }
+                    }
+
+                    if((y < 19) && (*q == (char) 0xff)) {
+                        //check if left-down, down or right-down is none transparent
+                        //"down" only possible if y < 19
+                        a = b = c = 0xff;
+
+                        // left-down (left only possible if x > 0)
+                        if(x > 0)
+                            a = p[+19];
+                        // down
+                        b = p[+20];
+                        // right-down (right only possible if x < 19)
+                        if(x < 19)
+                            c = p[+21];
+
+                        // if non-transparent color is found change pixel
+                        // to outline color
+                        if((a != (unsigned char) 0xff)
+                                || (b != (unsigned char) 0xff)
+                                || (c != (unsigned char) 0xff)) {
+                            // change to icon outline color
+                            *q = color;
+                        }
+                    }
+                }
+
+                p++;
+                q++;
+            }
+        }
+        memcpy(pixels, pixels_copy, 400);
+    }
+}
+
+
+
+
+
+/* read in symbol table */
+void load_pixmap_symbol_file(char *filename, int reloading) {
+    FILE *f;
+    char filen[500];
+    char line[100];
+    char table_char;
+    char symbol_char;
+    int done;
+    char pixels[400];
+    char orient;
+
+    busy_cursor(appshell);
+    symbols_loaded = 0;
+    table_char = '\0';
+    symbol_char = '\0';
+    done = 0;
+    xastir_snprintf(filen, sizeof(filen), "%s/%s", SYMBOLS_DIR, filename);
+    f = fopen(filen,"r");
+    if (f!=NULL) {
+        while (!feof(f) && !done) {
+            (void)get_line(f,line,100);
+            if (strncasecmp("TABLE ",line,6)==0) {
+                table_char=line[6];
+                /*fprintf(stderr,"TABLE %c\n",table_char);*/
+            } else {
+                if (strncasecmp("DONE",line,4)==0) {
+                    done=1;
+                    /*fprintf(stderr,"DONE\n");*/
+                } else {
+                    if (strncasecmp("APRS ",line,5)==0) {
+                        symbol_char=line[5];
+                        if (strlen(line)>=20 && line[19] == 'l')     // symbol with orientation ?
+                            orient = 'l';   // should be 'l' for left
+                        else
+                            orient = ' ';
+                        read_symbol_from_file(f, pixels, table_char);                      // read pixels for one symbol
+                        insert_symbol(table_char,symbol_char,pixels,270,orient,reloading); // always have normal orientation
+                        if (orient == 'l') {
+                            insert_symbol(table_char,symbol_char,pixels, 0,'u',reloading); // create other orientations
+                            insert_symbol(table_char,symbol_char,pixels, 90,'r',reloading);
+                            insert_symbol(table_char,symbol_char,pixels,180,'d',reloading);
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        fprintf(stderr,"Error opening symbol file %s\n",filen);
+        popup_message("Error opening symbol file","Error opening symbol file");
+    }
+
+    if (f != NULL)
+        (void)fclose(f);
+}
+
+
+
+
+
+// add a symbol to the end of the symbol table.
+//
+// Here we actually draw the pixels into the SymbolData struct,
+// which contains separate Pixmap's for the icon, the transparent
+// background, and the ghost image.
+//
+void insert_symbol(char table, char symbol, char *pixel, int deg, char orient, int reloading) {
+    int x,y,idx,old_next,color,last_color,last_gc2;
+
+    if (symbols_loaded < MAX_SYMBOLS) {
+        // first time loading, -> create pixmap...        
+        // when reloading -> reuse already created pixmaps...
+        if(reloading == 0) {
+            symbol_data[symbols_loaded].pix=XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                DefaultDepthOfScreen(XtScreen(appshell)));
+
+            symbol_data[symbols_loaded].pix_mask=XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                1);
+
+            symbol_data[symbols_loaded].pix_mask_old=XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                1);
+        }
+
+        old_next=0;
+        last_color = -1;    // Something bogus
+        last_gc2 = -1;      // Also bogus
+
+        for (y=0;y<20;y++) {
+            for (x=0;x<20;x++) {
+                switch (deg) {
+                    case(0):
+                        idx = 20* (19-x) +   y;
+                        break;
+                    case(90):
+                        idx = 20*   y    + (19-x);
+                        break;
+                    case(180):
+                        idx = 20* (19-x) + (19-y);
+                        break;
+                    default:
+                        idx = 20*   y    +   x;
+                        break;
+                }
+                color = (int)(pixel[idx]);
+                if (color<0)
+                    color = 0xff;
+
+// Change to new color only when necessary.  We use two different
+// GC's here, one for the main icon pixmap, and one for the symbol
+// mask and ghost layer.
+
+
+                // DK7IN: is (da) correct or should this be (appshell) ?
+                if (color != last_color) {
+                    (void)XSetForeground(XtDisplay(da),gc,colors[color]);
+                    last_color = color;
+                }
+
+// Check that our parameters are within spec for XDrawPoint.  Tricky
+// 'cuz the XPoint struct uses short's, while XDrawPoint manpage
+// specifies int's.  We'll stick to 16-bit numbers just to make
+// sure.
+
+                (void)XDrawPoint(XtDisplay(da),
+                    symbol_data[symbols_loaded].pix,
+                    gc,
+                    l16(x),     // int
+                    l16(y));    // int
+                // DK7IN
+
+
+                // Create symbol mask
+                if (color != 0xff) {
+                    if (last_gc2 != 1) {
+                        (void)XSetForeground(XtDisplay(appshell),gc2,1);  // active bit
+                        last_gc2 = 1;
+                    }
+                }
+                else {
+                    if (last_gc2 != 0) {
+                        (void)XSetForeground(XtDisplay(appshell),gc2,0);  // transparent.
+                        last_gc2 = 0;
+                    }
+                }
+
+// Check that our parameters are within spec for XDrawPoint.  Tricky
+// 'cuz the XPoint struct uses short's, while XDrawPoint manpage
+// specifies int's.  We'll stick to 16-bit numbers just to make
+// sure.
+
+                (void)XDrawPoint(XtDisplay(appshell),
+                    symbol_data[symbols_loaded].pix_mask,
+                    gc2,
+                    l16(x),     // int
+                    l16(y));    // int
+
+
+                // Create ghost symbol mask by setting every 2nd bit
+                // to transparent
+                old_next++;
+                if (old_next>1) {
+                    old_next=0;
+                    if (last_gc2 != 0) {
+                        (void)XSetForeground(XtDisplay(appshell),gc2,0);
+                        last_gc2 = 0;
+                    }
+                }
+
+// Check that our parameters are within spec for XDrawPoint.  Tricky
+// 'cuz the XPoint struct uses short's, while XDrawPoint manpage
+// specifies int's.  We'll stick to 16-bit numbers just to make
+// sure.
+
+                (void)XDrawPoint(XtDisplay(appshell),
+                    symbol_data[symbols_loaded].pix_mask_old,
+                    gc2,
+                    l16(x),     // int
+                    l16(y));    // int
+            }
+            old_next++;    // shift one bit every scan line for ghost image
+            if (old_next>1)
+                old_next=0;
+        }
+        symbol_data[symbols_loaded].active = SYMBOL_ACTIVE;
+        symbol_data[symbols_loaded].table  = table;
+        symbol_data[symbols_loaded].symbol = symbol;
+        symbol_data[symbols_loaded].orient = orient;
+        symbols_loaded++;
+    }
+}
+
+
+
+
+
+/* calculate symbol orientation from course */
+char symbol_orient(char *course) {
+    char orient;
+    float mydir;
+
+    orient = ' ';
+    if (strlen(course)) {
+        mydir = (float)atof(course);
+        if (mydir > 0) {
+            if (mydir < (float)( 180+ANGLE_UPDOWN ) )
+                orient = 'd';
+            if (mydir < (float)( 180-ANGLE_UPDOWN ) )
+                orient = 'r';
+            if (mydir < (float)ANGLE_UPDOWN || mydir > (float)( 360-ANGLE_UPDOWN) )
+                orient = 'u';
+        }
+    }
+    return(orient);
+}
+
+
+
+
+
+// Storage for an index into the symbol table that we may need
+// later.
+int nosym_index = -1;
+
+
+// Look through our symbol table for a match.
+//
+void symbol(Widget w, int ghost, char symbol_table, char symbol_id, char symbol_overlay, Pixmap where,
+            int mask, long x_offset, long y_offset, char orient) {
+    int i;
+    int found;
+    int alphanum_index = -1;
+
+
+    if (x_offset > screen_width)  return;
+    if (x_offset < 0)             return;
+    if (y_offset > screen_height) return;
+    if (y_offset < 0)             return;
+
+    /* DK7IN: orient  is ' ','l','r','u','d'  for left/right/up/down symbol orientation */
+    // if symbol could be rotated, normal symbol orientation in symbols.dat is to the left
+
+
+    // Find the nosymbol index if we haven't filled it in by now.
+    // This "for" loop should get run only once during Xastir's
+    // entire runtime, so it shouldn't contribute much to CPU
+    // loading.
+    if (nosym_index == -1) {
+        for ( i = 0; i < symbols_loaded; i++ ) {
+            if (symbol_data[i].active == SYMBOL_ACTIVE) {
+                if (symbol_data[i].table == '!'
+                        && symbol_data[i].symbol == '#') {
+                    nosym_index = i;       // index of special symbol (if none available)
+                    break;
+                }
+            }
+        }
+    }
+
+
+    // Handle the overlay character.  The "for" loop below gets run
+    // once every time we encounter an overlay character, which
+    // isn't all that often.
+    if (symbol_overlay == '\0' || symbol_overlay == ' ') {
+        alphanum_index = 0; // we don't want an overlay
+    }
+    else {  // Find the overlay character index
+        for ( i = 0; i < symbols_loaded; i++ ) {
+            if (symbol_data[i].active == SYMBOL_ACTIVE) {
+                if (symbol_data[i].table == '#'
+                        && symbol_data[i].symbol == symbol_overlay) {
+                    alphanum_index = i; // index of symbol for character overlay
+                    break;
+                }
+            }
+        }
+    }
+
+
+    found = -1;
+
+    // Check last few symbols we used to see if we can shortcut
+    // looking through the entire index.  The symbols array really
+    // should be turned into a hash to save time.  Basically we've
+    // implemented a very short cache here, but it keeps us from
+    // looking through the entire symbol array sometimes.
+    //
+    for ( i = 0; i < 5; i++ ) {
+//fprintf(stderr,"Checking symbol cache\n");
+        if (symbol_data[symbols_cache[i]].table == symbol_table
+                && symbol_data[symbols_cache[i]].symbol == symbol_id) {
+            // We found the matching symbol in the cache
+            found = symbols_cache[i];  // index of symbol
+//fprintf(stderr,"Symbol cache hit:%d\n",found);
+            break;
+        }
+    }
+
+    if (found == -1) {  // Not found in symbols cache
+
+        for ( i = 0; i < symbols_loaded; i++ ) {
+            if (symbol_data[i].active == SYMBOL_ACTIVE) {
+                if (symbol_data[i].table == symbol_table
+                        && symbol_data[i].symbol == symbol_id) {
+                    // We found the matching symbol
+                    found = i;  // index of symbol
+
+                    // Save newly found symbol in cache, shift other
+                    // cache entries down by one so that newest is
+                    // at the beginning for the cache search.
+//fprintf(stderr,"Saving in cache\n");
+                    symbols_cache[4] = symbols_cache[3];
+                    symbols_cache[3] = symbols_cache[2];
+                    symbols_cache[2] = symbols_cache[1];
+                    symbols_cache[1] = symbols_cache[0];
+                    symbols_cache[0] = i;
+
+                    break;
+                }
+            }
+        }
+    }
+
+    if (found == -1) {  // Didn't find a matching symbol
+        found = nosym_index;
+        if (symbol_table && symbol_id && debug_level & 128)
+            fprintf(stderr,"No Symbol Yet! %2x:%2x\n", (unsigned int)symbol_table, (unsigned int)symbol_id);
+    } else {                    // maybe we want a rotated symbol
+
+
+// It looks like we originally did not want to rotate the symbol if
+// it was ghosted?  Why?  For dead-reckoning we do want it to be
+// rotated when ghosted.
+//      if (!(orient == ' ' || orient == 'l' || symbol_data[found].orient == ' ' || ghost)) {
+        if (!(orient == ' ' || orient == 'l' || symbol_data[found].orient == ' ')) {
+            for (i = found; i < symbols_loaded; i++) {
+                if (symbol_data[i].active == SYMBOL_ACTIVE) {
+                    if (symbol_data[i].table == symbol_table && symbol_data[i].symbol == symbol_id
+                             && symbol_data[i].orient == orient) {
+                        found=i;  // index of rotated symbol
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+
+    if (mask) {
+        if (ghost)
+            (void)XSetClipMask(XtDisplay(w),gc,symbol_data[found].pix_mask_old);
+        else
+            (void)XSetClipMask(XtDisplay(w),gc,symbol_data[found].pix_mask);
+    }
+    (void)XSetClipOrigin(XtDisplay(w),gc,x_offset,y_offset);
+    (void)XCopyArea(XtDisplay(w),symbol_data[found].pix,where,gc,0,0,20,20,x_offset,y_offset);
+
+
+    if(alphanum_index > 0) {
+        if (ghost)
+            (void)XSetClipMask(XtDisplay(w),gc,symbol_data[alphanum_index].pix_mask_old);
+        else
+            (void)XSetClipMask(XtDisplay(w),gc,symbol_data[alphanum_index].pix_mask);
+
+        (void)XSetClipOrigin(XtDisplay(w),gc,x_offset,y_offset);
+        (void)XCopyArea(XtDisplay(w),symbol_data[alphanum_index].pix,where,gc,0,0,20,20,x_offset,y_offset); // rot
+    }
+
+    (void)XSetClipMask(XtDisplay(w),gc,None);
+}
+
+
+
+
+
+// Speed is in converted units by this point (kph or mph)
+void draw_symbol(Widget w, char symbol_table, char symbol_id, char symbol_overlay,
+        long x_long,long y_lat, char *callsign_text, char *alt_text, char *course_text,
+        char *speed_text, char *my_distance, char *my_course, char *wx_temp,
+        char* wx_wind, time_t sec_heard, int temp_show_last_heard, Pixmap where,
+        char orient, char area_type, char *signpost, char *gauge_data, int bump_count) {
+
+    long x_offset,y_offset;
+    int length;
+    int ghost;
+    int posyl;
+    int posyr;
+
+
+    if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+
+        if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+
+//            if ((x_long+10 < 0) || (x_long-10 > 129600000l))  // 360 deg
+//                return;
+
+//            if ((y_lat+10 < 0) || (y_lat-10 > 64800000l))     // 180 deg
+//                return;
+
+            x_offset=((x_long-NW_corner_longitude)/scale_x)-(10);
+            y_offset=((y_lat -NW_corner_latitude) /scale_y)-(10);
+            ghost = (int)(((sec_old+sec_heard)) < sec_now());
+
+            if (bump_count)
+                currently_selected_stations++;
+
+            if (Display_.symbol)
+                symbol(w,ghost,symbol_table,symbol_id,symbol_overlay,where,1,x_offset,y_offset,orient);
+
+            posyr = 10;      // align symbols vertically centered to the right
+            if ( (!ghost || Select_.old_data) && strlen(alt_text)>0)
+                posyr -= 7;
+            if (strlen(callsign_text)>0)
+                posyr -= 7;
+            if ( (!ghost || Select_.old_data) && strlen(speed_text)>0)
+                posyr -= 7;
+            if ( (!ghost || Select_.old_data) && strlen(course_text)>0)
+                posyr -= 7;
+            if (area_type == AREA_LINE_RIGHT)
+                posyr += 9;
+            if (signpost[0] != '\0')    // Signpost data?
+                posyr -=7;
+            // we may eventually have more adjustments for different types of areas
+
+            length=(int)strlen(alt_text);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)+12;
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,alt_text,0x08,0x48,length);
+                posyr += 13;
+            }
+
+            length=(int)strlen(callsign_text);
+            if (length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)+12;
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,callsign_text,0x08,0x0f,length);
+                posyr += 13;
+            }
+
+            length=(int)strlen(speed_text);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)+12;
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,speed_text,0x08,0x4a,length);
+                posyr += 13;
+            }
+
+            length=(int)strlen(course_text);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)+12;
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,course_text,0x08,0x52,length);
+                posyr += 13;
+            }
+ 
+            length=(int)strlen(signpost);   // Make it white like callsign?
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)+12;
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,signpost,0x08,0x0f,length);
+                posyr += 13;
+            }
+ 
+            posyl = 10; // distance and direction goes to the left.
+                                // Also minutes last heard.
+            if ( (!ghost || Select_.old_data) && strlen(my_distance)>0)
+                posyl -= 7;
+            if ( (!ghost || Select_.old_data) && strlen(my_course)>0)
+                posyl -= 7;
+            if ( (!ghost || Select_.old_data) && temp_show_last_heard)
+                posyl -= 7;
+
+            length=(int)strlen(my_distance);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=(((x_long-NW_corner_longitude)/scale_x)-(length*6))-12;
+                y_offset=((y_lat  -NW_corner_latitude) /scale_y)+posyl;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,my_distance,0x08,0x0f,length);
+                posyl += 13;
+            }
+            length=(int)strlen(my_course);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=(((x_long-NW_corner_longitude)/scale_x)-(length*6))-12;
+                y_offset=((y_lat  -NW_corner_latitude) /scale_y)+posyl;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,my_course,0x08,0x0f,length);
+                posyl += 13;
+            }
+            if ( (!ghost || Select_.old_data) && temp_show_last_heard) {
+                char age[20];
+                float minutes;
+                float hours;
+                int fgcolor;
+
+
+                // Color code the time string based on
+                // time since last heard:
+                //  Green:  0-29 minutes
+                // Yellow: 30-59 minutes
+                //    Red: 60 minutes to 1 day
+                //  White: 1 day or later
+
+                minutes = (float)( (sec_now() - sec_heard) / 60.0);
+                hours = minutes / 60.0;
+
+                // Heard from this station within the
+                // last 30 minutes?
+                if (minutes < 30.0) {
+                    xastir_snprintf(age,
+                        sizeof(age),
+                        "%d%s",
+                        (int)minutes,
+                        langcode("UNIOP00034"));    // min
+                    fgcolor = 0x52; // green
+                }
+                // 30 to 59 minutes?
+                else if (minutes < 60.0) {
+                    xastir_snprintf(age,
+                        sizeof(age),
+                        "%d%s",
+                        (int)minutes,
+                        langcode("UNIOP00034"));    // min
+                    fgcolor = 0x40; // yellow
+                }
+                // 1 hour to 1 day old?
+                else if (hours <= 24.0) {
+                    xastir_snprintf(age,
+                        sizeof(age),
+                        "%.1f%s",
+                        hours,
+                        langcode("UNIOP00035"));    // hr
+                    fgcolor = 0x4a; // red
+                }
+                // More than a day old
+                else {
+                    xastir_snprintf(age,
+                        sizeof(age),
+                        "%.1f%s",
+                        hours / 24.0,
+                        langcode("UNIOP00036"));    // day
+                    fgcolor = 0x0f; // white
+                }
+
+                length = strlen(age);
+                x_offset=(((x_long-NW_corner_longitude)/scale_x)-(length*6))-12;
+                y_offset=((y_lat  -NW_corner_latitude) /scale_y)+posyl;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,age,0x08,fgcolor,length);
+                posyl += 13;
+            }
+
+            // weather goes to the bottom, centered horizontally.
+            if (posyr < posyl)
+                posyr = posyl;
+            if (posyr < 18)
+                posyr = 18;
+
+            length=(int)strlen(wx_temp);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)-(length*3);
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,wx_temp,0x08,0x40,length);
+                posyr += 13;
+            }
+
+            length=(int)strlen(wx_wind);
+            if ( (!ghost || Select_.old_data) && length>0) {
+                x_offset=((x_long-NW_corner_longitude)/scale_x)-(length*3);
+                y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                draw_nice_string(w,where,letter_style,x_offset,y_offset,wx_wind,0x08,0x40,length);
+            }
+
+            if (gauge_data != NULL) {
+                // Gauge data goes on the bottom, centered
+                // horizontally.  White.
+                if (posyr < posyl)
+                    posyr = posyl;
+                if (posyr < 22)
+                    posyr = 22;
+
+                length=(int)strlen(gauge_data);
+                if ( (!ghost || Select_.old_data) && length>0) {
+                    x_offset=((x_long-NW_corner_longitude)/scale_x)-(length*3);
+                    y_offset=((y_lat -NW_corner_latitude) /scale_y)+posyr;
+                    draw_nice_string(w,where,letter_style,x_offset,y_offset,gauge_data,0x08,0x0f,length);
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+/*
+ * Looks at the style to determine what color to use.
+ * KG4NBB
+ */
+static int getLineColor(char styleChar) {
+    int color;
+
+    switch (styleChar) {
+        case 'a':
+        case 'b':
+        case 'c':
+            color = colors[0x0c];   // red
+            break;
+
+        case 'd':
+        case 'e':
+        case 'f':
+            color = colors[0x0e];   // yellow
+            break;
+
+        case 'g':
+        case 'h':
+        case 'i':
+            color = colors[0x09];   // blue
+            break;
+
+        case 'j':
+        case 'k':
+        case 'l':
+            color = colors[0x0a];   // green
+            break;
+
+        default:
+            color = colors[0x0a];   // green
+            break;
+    }
+
+    return color;
+}
+
+
+
+
+
+/*
+ * Looks at the style to determine what line type to use.
+ * KG4NBB
+ */
+static int getLineStyle(char styleChar) {
+    int style;
+
+    switch (styleChar) {
+        case 'a':
+        case 'd':
+        case 'g':
+        case 'j':
+            style = LineSolid;
+            break;
+        
+        case 'b':
+        case 'e':
+        case 'h':
+        case 'k':
+            style = LineOnOffDash;
+            break;
+
+        case 'c':
+        case 'f':
+        case 'i':
+        case 'l':
+            style = LineDoubleDash;
+            break;
+
+        default:
+            style = LineSolid;
+            break;
+    }
+
+    return style;
+}
+
+
+
+
+
+/*
+ * Draw the other points associated with the station.
+ * KG4NBB
+ */
+void draw_multipoints(long x_long, long y_lat, int numpoints, long mypoints[][2], char type, char style, time_t sec_heard, Pixmap where) {
+    int ghost;
+    int skip_duplicates;
+
+
+    // See if we should draw multipoints for this station. This only happens
+    // if there are points to draw and the object has not been cleared (or 
+    // we're supposed to show old data).
+
+    // Per Dale Huguley in e-mail 07/10/2003, a good interval for
+    // the severe weather polygons to disappear is 10 minutes.  We
+    // hard-code it here so the user can't mess it up too badly with
+    // the ghosting interval.
+//    ghost = (int)(((sec_old+sec_heard)) < sec_now());
+    ghost = (int)( ( sec_heard + (10 * 60) ) < sec_now() );
+
+    // We don't want to draw them if the ghost interval is up, no
+    // matter whether Include Expired Data is checked.
+    //if ( (!ghost || Select_.old_data) && (numpoints > 0) ) {
+    if ( !ghost  && (numpoints > 0) ) {
+
+        //long x_offset, y_offset;
+        int  i;
+//        XPoint xpoints[MAX_MULTIPOINTS + 1];
+
+#if 0
+        long mostNorth, mostSouth, mostWest, mostEast;
+
+        // Check to see if the object is onscreen.
+        // Look for the coordinates that are farthest north, farthest south,
+        // farthest west, and farthest east. Then check to see if any of that
+        // box is onscreen. If so, proceed with drawing. This is all done in
+        // Xastir coordinates.
+
+        mostNorth = mostSouth = y_lat;
+        mostWest = mostEast = x_long;
+
+        for (i = 0; i < numpoints; ++i) {
+            if (mypoints[i][0] < mostNorth)
+                mostNorth = mypoints[i][0];
+            if (mypoints[i][0] > mostSouth)
+                mostSouth = mypoints[i][0];
+            if (mypoints[i][1] < mostWest)
+                mostWest = mypoints[i][1];
+            if (mypoints[i][1] > mostEast)
+                mostEast = mypoints[i][1];
+        }
+
+        if (onscreen(mostWest, mostEast, mostNorth, mostSouth))
+#else   // 0
+
+        // See if the station icon is on the screen. If so, draw the associated
+        // points. The drawback to this approach is that if the station icon is
+        // scrolled off the edge of the display the points aren't drawn even if
+        // one or more of them is on the display.
+
+//        if( (x_long > NW_corner_longitude) && (x_long < SE_corner_longitude)
+//            && (y_lat > NW_corner_latitude) && (y_lat < SE_corner_latitude) )
+#endif  // 0
+        {
+            //x_offset = (x_long - NW_corner_longitude) / scale_x;
+            //y_offset = (y_lat - NW_corner_latitude) / scale_y;
+
+            // Convert each of the points from Xastir coordinates to
+            // screen coordinates and fill in the xpoints array.
+
+//            for (i = 0; i < numpoints; ++i) {
+//                xpoints[i].x = (mypoints[i][0] - NW_corner_longitude) / scale_x;
+//                xpoints[i].y = (mypoints[i][1] - NW_corner_latitude) / scale_y;
+//                // fprintf(stderr,"   %d: %d,%d\n", i, xpoints[i].x, xpoints[i].y);
+//            }
+
+            // The type parameter determines how the points will be used.
+            // After determining the type, use the style parameter to
+            // get the color and line style.
+
+            switch (type) {
+
+                case '0':           // closed polygon
+                default:
+                    // Repeat the first point so the polygon will be closed.
+
+//                    xpoints[numpoints].x = xpoints[0].x;
+//                    xpoints[numpoints].y = xpoints[0].y;
+
+                    // First draw a wider black line.
+                    (void)XSetForeground(XtDisplay(da), gc, colors[0x08]);  // black
+                    (void)XSetLineAttributes(XtDisplay(da), gc, 4, LineSolid, CapButt, JoinMiter);
+
+                    skip_duplicates = 0;
+                    for (i = 0; i < numpoints-1; i++) {
+//                        (void)XDrawLines(XtDisplay(da), where, gc, xpoints, numpoints+1, CoordModeOrigin);
+                        draw_vector(da, mypoints[i][0],
+                            mypoints[i][1],
+                            mypoints[i+1][0],
+                            mypoints[i+1][1],
+                            gc,
+                            where,
+                            skip_duplicates);
+
+                        skip_duplicates = 1;
+                    }
+                    // Close the polygon
+                    draw_vector(da,
+                        mypoints[i][0],
+                        mypoints[i][1],
+                        mypoints[0][0],
+                        mypoints[0][1],
+                        gc,
+                        where,
+                        skip_duplicates);
+
+                    // Then draw the appropriate colored line on top of it.
+                    (void)XSetForeground(XtDisplay(da), gc, getLineColor(style));
+                    (void)XSetLineAttributes(XtDisplay(da), gc, 2, getLineStyle(style), CapButt, JoinMiter);
+
+                    skip_duplicates = 0;
+                    for (i = 0; i < numpoints-1; i++) {
+//                        (void)XDrawLines(XtDisplay(da), where, gc, xpoints, numpoints+1, CoordModeOrigin);
+                        draw_vector(da, mypoints[i][0],
+                            mypoints[i][1],
+                            mypoints[i+1][0],
+                            mypoints[i+1][1],
+                            gc,
+                            where,
+                            skip_duplicates);
+
+                        skip_duplicates = 1;
+                    }
+                    // Close the polygon
+                    draw_vector(da,
+                        mypoints[i][0],
+                        mypoints[i][1],
+                        mypoints[0][0],
+                        mypoints[0][1],
+                        gc,
+                        where,
+                        skip_duplicates);
+
+                    break;
+
+                case '1':           // line segments
+
+                    (void)XSetForeground(XtDisplay(da), gc, getLineColor(style));
+                    (void)XSetLineAttributes(XtDisplay(da), gc, 2, getLineStyle(style), CapButt, JoinMiter);
+
+                    skip_duplicates = 0;
+                    for (i = 0; i < numpoints-1; i++) {
+//                        (void)XDrawLines(XtDisplay(da), where, gc, xpoints, numpoints, CoordModeOrigin);
+                        draw_vector(da, mypoints[i][0],
+                            mypoints[i][1],
+                            mypoints[i+1][0],
+                            mypoints[i+1][1],
+                            gc,
+                            where,
+                            skip_duplicates);
+
+                        skip_duplicates = 1;
+                    }
+
+                    break;
+
+                // Other types have yet to be implemented.
+            }
+        }
+    }
+}
+
+
+
+
+
+void Select_symbol_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    int i;
+
+    XtPopdown(shell);
+
+    // Free all 188 symbol pixmaps
+    for ( i = 0; i < (126-32)*2; i++ ) {
+        (void)XFreePixmap(XtDisplay(appshell),select_icons[i]);
+    }
+
+begin_critical_section(&select_symbol_dialog_lock, "draw_symbols.c:Select_symbol_destroy_shell" );
+ 
+    XtDestroyWidget(shell);
+    select_symbol_dialog = (Widget)NULL;
+
+end_critical_section(&select_symbol_dialog_lock, "draw_symbols.c:Select_symbol_destroy_shell" );
+
+}
+
+
+
+
+
+void Select_symbol_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char table[2];
+    char symbol[2];
+    int i = XTPOINTER_TO_INT(clientData);
+
+    //fprintf(stderr,"Selected a symbol: %d\n", clientData);
+
+    if ( i > 0) {
+        //fprintf(stderr,"Symbol is from primary symbol table: /%c\n",(char)i);
+        table[0] = '/';
+        symbol[0] = (char)i;
+    }
+    else {
+        //fprintf(stderr,"Symbol is from secondary symbol table: \\%c\n",(char)(-i));
+        table[0] = '\\';
+        symbol[0] = (char)(-i);
+    }
+    table[1] = '\0';
+    symbol[1] = '\0';
+
+
+    if (symbol_change_requested_from == 1) {        // Configure->Station Dialog
+        symbol_change_requested_from = 0;
+        //fprintf(stderr,"Updating Configure->Station Dialog\n");
+
+        XmTextFieldSetString(station_config_group_data,table);
+        XmTextFieldSetString(station_config_symbol_data,symbol);
+        updateSymbolPictureCallback(widget,clientData,callData);
+    }
+    else if (symbol_change_requested_from == 2) {   // Create->Object/Item Dialog
+        symbol_change_requested_from = 0;
+        //fprintf(stderr,"Updating Create->Object/Item Dialog\n");
+
+        XmTextFieldSetString(object_group_data,table);
+        XmTextFieldSetString(object_symbol_data,symbol);
+        updateObjectPictureCallback(widget,clientData,callData);
+    }
+    else {  // Do nothing.  We shouldn't be here.
+        symbol_change_requested_from = 0;
+    }
+
+    Select_symbol_destroy_shell(widget,select_symbol_dialog,callData);
+}
+
+
+
+
+
+void Select_symbol( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, my_form2, my_form3, button_cancel,
+            frame, frame2, label1, label2, b1;
+    int i;
+    Atom delw;
+
+
+    if (!select_symbol_dialog) {
+
+
+begin_critical_section(&select_symbol_dialog_lock, "draw_symbols.c:Select_symbol" );
+
+
+        select_symbol_dialog = XtVaCreatePopupShell(langcode("SYMSEL0001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Select_symbol pane",
+                xmPanedWindowWidgetClass, 
+                select_symbol_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Select_symbol my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        frame = XtVaCreateManagedWidget("Select_symbol frame", 
+                xmFrameWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset,10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        label1 = XtVaCreateManagedWidget(langcode("SYMSEL0002"),
+                xmLabelWidgetClass,
+                frame,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        frame2 = XtVaCreateManagedWidget("Select_symbol frame", 
+                xmFrameWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset,10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, frame,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        label2 = XtVaCreateManagedWidget(langcode("SYMSEL0003"),
+                xmLabelWidgetClass,
+                frame2,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        my_form2 =  XtVaCreateWidget("Select_symbol my_form2",
+                xmRowColumnWidgetClass, 
+                frame,
+                XmNorientation, XmHORIZONTAL,
+                XmNpacking, XmPACK_COLUMN,
+                XmNnumColumns, 10,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form3 =  XtVaCreateWidget("Select_symbol my_form3",
+                xmRowColumnWidgetClass, 
+                frame2,
+                XmNorientation, XmHORIZONTAL,
+                XmNpacking, XmPACK_COLUMN,
+                XmNnumColumns, 10,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // Symbols:  33 to 126, for both '/' and '\' tables (94 * 2)
+        // 33 = start of icons in ASCII table, 126 = end
+
+        // Draw the primary symbol set
+        for ( i = 33; i < 127; i++ ) {
+
+            select_icons[i-33] = XCreatePixmap(XtDisplay(appshell),
+                    RootWindowOfScreen(XtScreen(appshell)),
+                    20,
+                    20,
+                    DefaultDepthOfScreen(XtScreen(appshell)));
+ 
+            b1 = XtVaCreateManagedWidget("symbol button",
+                    xmPushButtonWidgetClass, 
+                    my_form2,
+                    XmNlabelType,               XmPIXMAP,
+                    XmNlabelPixmap,             select_icons[i-33],
+                    XmNnavigationType, XmTAB_GROUP,
+                    MY_FOREGROUND_COLOR,
+                    MY_BACKGROUND_COLOR,
+                    XmNfontList, fontlist1,
+                    NULL);
+
+            symbol(b1,0,'/',(char)i,' ',select_icons[i-33],0,0,0,' ');  // create icon
+
+            // Here we send back the ascii number of the symbol.  We need to keep it within
+            // the range of short int's.
+            XtAddCallback(b1,
+                XmNactivateCallback,
+                Select_symbol_change_data,
+                INT_TO_XTPOINTER(i) );
+        }
+
+        // Draw the alternate symbol set
+        for ( i = 33+94; i < 127+94; i++ ) {
+
+            select_icons[i-33] = XCreatePixmap(XtDisplay(appshell),
+                    RootWindowOfScreen(XtScreen(appshell)),
+                    20,
+                    20,
+                    DefaultDepthOfScreen(XtScreen(appshell)));
+ 
+            b1 = XtVaCreateManagedWidget("symbol button",
+                    xmPushButtonWidgetClass, 
+                    my_form3,
+                    XmNlabelType,               XmPIXMAP,
+                    XmNlabelPixmap,             select_icons[i-33],
+                    XmNnavigationType, XmTAB_GROUP,
+                    MY_FOREGROUND_COLOR,
+                    MY_BACKGROUND_COLOR,
+                    XmNfontList, fontlist1,
+                    NULL);
+
+            symbol(b1,0,'\\',(char)i-94,' ',select_icons[i-33],0,0,0,' ');  // create icon
+
+            // Here we send back the ascii number of the symbol negated.  We need to keep it
+            // within the range of short int's.
+            XtAddCallback(b1,
+                XmNactivateCallback,
+                Select_symbol_change_data,
+                INT_TO_XTPOINTER(-(i-94)) );
+        }
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, Select_symbol_destroy_shell, select_symbol_dialog);
+
+        pos_dialog(select_symbol_dialog);
+
+        delw = XmInternAtom(XtDisplay(select_symbol_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(select_symbol_dialog, delw, Select_symbol_destroy_shell, (XtPointer)select_symbol_dialog);
+        XtManageChild(my_form3);
+        XtManageChild(my_form2);
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(select_symbol_dialog,XtGrabNone);
+        fix_dialog_size(select_symbol_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(select_symbol_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+
+end_critical_section(&select_symbol_dialog_lock, "draw_symbols.c:Select_symbol" );
+
+
+    } else
+        (void)XRaiseWindow(XtDisplay(select_symbol_dialog), XtWindow(select_symbol_dialog));
+}
+
+
+
+
+
+// Function to draw dead-reckoning symbols.
+//
+void draw_deadreckoning_features(DataRow *p_station,
+                                 Pixmap where,
+                                 Widget w) {
+    double my_course;
+    long x_long, y_lat;
+    long x_long2, y_lat2;
+    long x, y;
+    long x2, y2;
+    double diameter;
+    int color = trail_colors[p_station->trail_color];
+//    int symbol_on_screen = 0;
+    int ghosted_symbol_on_screen = 0;
+
+
+// This function takes a bit of CPU if we are zoomed out.  It'd be
+// best to check first whether the zoom level and the speed make it
+// worth computing DR at all for this station.  As a first
+// approximation, we could turn off DR if we're at zoom 8000 or
+// higher:
+//
+//    if (scale_y > 8000)
+//        return;
+
+
+    x_long = p_station->coord_lon;
+    y_lat = p_station->coord_lat;
+
+    // x/y are screen locations for start position
+    x = (x_long - NW_corner_longitude)/scale_x;
+    y = (y_lat - NW_corner_latitude)/scale_y;
+
+    y_lat2 = y_lat;
+    x_long2 = x_long;
+
+    // Compute the latest DR'ed position for the object
+    compute_current_DR_position(p_station,
+        &x_long2,
+        &y_lat2);
+
+    // x2/y2 are screen location for ghost symbol (DR'ed position)
+    x2 = (x_long2 - NW_corner_longitude)/scale_x;
+    y2 = (y_lat2 - NW_corner_latitude)/scale_y;
+
+
+    // Check DR'ed symbol position
+    if (    (x_long2>NW_corner_longitude) &&
+            (x_long2<SE_corner_longitude) &&
+            (y_lat2>NW_corner_latitude) &&
+            (y_lat2<SE_corner_latitude) &&
+            ((x_long>=0) && (x_long<=129600000l)) &&
+            ((y_lat>=0) && (y_lat<=64800000l))) {
+
+        ghosted_symbol_on_screen++;
+    }
+
+
+    // Draw the DR arc
+    //
+    if (Display_.dr_arc && ghosted_symbol_on_screen) {
+
+        double xdiff, ydiff;
+
+
+        xdiff = (x2-x) * 1.0;
+        ydiff = (y2-y) * 1.0;
+
+        // a squared + b squared = c squared
+        diameter = 2.0 * sqrt( (double)( (ydiff*ydiff) + (xdiff*xdiff) ) );
+
+        //fprintf(stderr,"Range:%f\tDiameter:%f\n",range,diameter);
+
+        if (diameter > 10.0) {
+            int arc_degrees = (sec_now() - p_station->sec_heard) * 90 / (5*60);
+
+            if (arc_degrees > 360) {
+                arc_degrees = 360;
+        }
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 1, LineOnOffDash, CapButt,JoinMiter);
+        //(void)XSetForeground(XtDisplay(da),gc,colors[0x0a]);
+        //(void)XSetForeground(XtDisplay(da),gc,colors[0x44]); // red3
+        (void)XSetForeground(XtDisplay(da),gc,color);
+
+
+        // Compute angle from the two screen positions.
+        //
+        if (xdiff != 0) {
+//We should guard against divide-by-zero here!
+             my_course = 57.29578 * atan(xdiff/ ydiff);
+        }
+        else {
+            if (ydiff >= 0) {
+                my_course = 180.0;
+            }
+            else {
+                my_course = 0.0;
+            }
+        }
+
+
+//fprintf(stderr,"my_course:%f\n", my_course);
+        // The arctan function returns values between -90 and +90.  To
+        // obtain the true course we apply the following rules:
+        if (ydiff > 0 && xdiff > 0) {
+//fprintf(stderr,"1\n");  // Lower-right quadrant
+            my_course = 360.0 - my_course;
+        }
+        else if (ydiff < 0.0 && xdiff > 0.0) {
+//fprintf(stderr,"2\n");  // Upper-right quadrant
+            my_course = 180.0 - my_course;
+        }
+        else if (ydiff < 0.0 && xdiff < 0.0) {
+//fprintf(stderr,"3\n");  // Upper-left quadrant
+            my_course = 180.0 - my_course;
+        }
+        else if (ydiff > 0.0 && xdiff < 0.0) {
+//fprintf(stderr,"4\n");  // Lower-left quadrant
+            my_course = 360.0 - my_course;
+        }
+        else {  // 0/90/180/270
+//fprintf(stderr,"5\n");
+            my_course = 180.0 + my_course;
+        }
+
+
+        // Convert to screen angle for XDrawArc routines:
+        my_course = my_course + 90.0;
+
+        if (my_course > 360.0)
+            my_course = my_course - 360.0;
+ 
+//fprintf(stderr,"\tmy_course2:%f\n", my_course);
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+        (void)XDrawArc(XtDisplay(da),where,gc,
+            l16(x-(diameter/2)),    // int
+            l16(y-(diameter/2)),    // int
+            lu16(diameter),         // unsigned int
+            lu16(diameter),         // unsigned int
+            l16(-64*my_course),     // int
+            l16(64/2*arc_degrees)); // int
+
+// Check that our parameters are within spec for XDrawArc.  Tricky
+// 'cuz the XArc struct has short's and unsigned short's, while
+// XDrawArc man-page says int's/unsigned int's.  We'll stick to 16-bit
+// just to make sure.
+
+        (void)XDrawArc(XtDisplay(da),where,gc,
+            l16(x-(diameter/2)),        // int
+            l16(y-(diameter/2)),        // int
+            lu16(diameter),             // unsigned int
+            lu16(diameter),             // unsigned int
+            l16(-64*my_course),         // int
+            l16(-64/2*arc_degrees));    // int
+        }
+    }
+
+
+// Note that for the DR course, if we're in the middle of the symbol
+// and the DR'ed symbol (ghosted symbol), but neither of them are
+// on-screen, the DR'ed course won't display.
+//
+    // Draw the DR'ed course if either the symbol or the DR'ed
+    // symbol (ghosted symbol) are on-screen.
+    //
+    if (Display_.dr_course) {
+
+        (void)XSetLineAttributes(XtDisplay(da), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+        (void)XSetForeground(XtDisplay(da),gc,color); // red3
+
+        // This one changes the angle as the vector gets longer, by
+        // about 10 degrees (A test at 133 degrees -> 143 degrees).
+        // draw_vector() needs to truncate the line in this case,
+        // maintaining the same slope.  This behavior is _much_
+        // better than the XDrawLine above though!
+        //
+        draw_vector(w,
+            x_long,
+            y_lat,
+            x_long2,
+            y_lat2,
+            gc,
+            where,
+            0);
+    }
+
+
+    // Draw the DR'ed symbol (ghosted symbol) if enabled and if
+    // on-screen.
+    //
+    if (Display_.dr_symbol && ghosted_symbol_on_screen) {
+
+        draw_symbol(w,
+            p_station->aprs_symbol.aprs_type,
+            p_station->aprs_symbol.aprs_symbol,
+            p_station->aprs_symbol.special_overlay,
+            x_long2,
+            y_lat2,
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            "",
+            p_station->sec_heard-sec_old,   // Always draw it ghosted
+            0,
+            where,
+            symbol_orient(p_station->course),
+            p_station->aprs_symbol.area_object.type,
+            p_station->signpost,
+            (char) 0x00,
+            0);  // Don't bump the station count
+    }
+}
+
+
diff --git a/src/draw_symbols.h b/src/draw_symbols.h
new file mode 100644
index 0000000..25a3318
--- /dev/null
+++ b/src/draw_symbols.h
@@ -0,0 +1,77 @@
+/*
+ * $Id: draw_symbols.h,v 1.33 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_DRAW_SYMBOLS_H
+#define __XASTIR_DRAW_SYMBOLS_H
+
+#define SYMBOL_ACTIVE    'A'
+#define SYMBOL_NOTACTIVE 'N'
+
+#define MAX_SYMBOLS 400
+
+typedef struct {
+    char active;                // ??
+    char table;                 // table character
+    char symbol;                // symbol character
+    char orient;                // orientation of the symbol, one of ' ',  'l','r','u','d'
+    Pixmap pix;                 // icon picture
+    Pixmap pix_mask;            // mask for transparent background
+    Pixmap pix_mask_old;        // mask for ghost symbols, half transparent icons
+} SymbolData;
+
+extern SymbolData symbol_data[];
+
+extern void draw_nice_string(Widget w, Pixmap where, int style, long x, long y, char *text, int bgcolor, int fgcolor, int length);
+extern void clear_symbol_data(void);
+extern void read_symbol_from_file(FILE *f, char *pixels, char table_char);
+extern void load_pixmap_symbol_file(char *filename, int reloading);
+extern void insert_symbol(char table, char symbol, char *pixel, int deg, char orient, int reloading);
+extern char symbol_orient(char *course);
+extern void symbol(Widget w, int ghost,char symbol_table, char symbol_id, char symbol_overlay, Pixmap where, int mask, long x_offset, long y_offset, char rotate);
+
+extern void draw_WP_line(DataRow *p_station, int ambiguity_flag, long ambiguity_coord_lon, long ambiguity_coord_lat, Pixmap where, Widget w);
+
+extern void draw_symbol(Widget w, char symbol_table, char symbol_id, char symbol_overlay, long x_lon, long y_lat,char *callsign_text, char *alt_text, char *course_text, char *speed_text, char *my_distance, char *my_course, char *wx_temp, char* wx_wind, time_t sec_heard, int temp_show_last_heard, Pixmap where, char rotate, char area_type, char *signpost, char *gauge_data, int bump_count );
+
+extern void draw_pod_circle(long x_long, long y_lat, double range, int color, Pixmap where);
+extern void draw_precision_rectangle(long x_long, long y_lat, double range, unsigned int lat_precision, unsigned int lon_precision, int color, Pixmap where);
+extern void draw_aloha_circle(long x_long, long y_lat, double range, int color, Pixmap where);
+extern void draw_phg_rng(long x_long, long y_lat, char *phg, time_t sec_heard, Pixmap where);
+extern void draw_DF_circle(long x_long, long y_lat, char *shgd, time_t sec_heard, Pixmap where);
+extern void draw_wind_barb(long x_long, long y_lat, char *speed, char *course, time_t sec_heard, Pixmap where);
+extern void draw_bearing(long x_long, long y_lat, char *course, char *bearing, char *NRQ, int color, int draw_beamwidth, int draw_bearing, time_t sec_heard, Pixmap where);
+extern void draw_ambiguity(long x_long, long y_lat, char amb, long *amb_x_long, long *amb_y_lat, time_t sec_heard, Pixmap where);
+extern void draw_area(long x_long, long y_lat, char type, char color, char sqrt_lat_off, char sqrt_lon_off, unsigned int width, time_t sec_heard, Pixmap where);
+extern void draw_multipoints(long x_long, long y_lat, int numpoints, long points[][2], char type, char style, time_t sec_heard, Pixmap where);  // KG4NBB
+extern void Select_symbol( Widget w, XtPointer clientData, XtPointer callData);
+extern int symbol_change_requested_from;
+extern Widget select_symbol_dialog;
+extern void Select_symbol_destroy_shell( Widget widget, XtPointer clientData, XtPointer callData);
+extern void draw_symbols_init(void);
+extern void draw_deadreckoning_features(DataRow *p_station, Pixmap where, Widget w);
+
+#endif  // __XASTIR_DRAW_SYMBOLS_H
+
+
diff --git a/src/fcc_data.c b/src/fcc_data.c
new file mode 100644
index 0000000..76f76db
--- /dev/null
+++ b/src/fcc_data.c
@@ -0,0 +1,503 @@
+/*
+ * $Id: fcc_data.c,v 1.25 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "fcc_data.h"
+#include "xa_config.h"
+#include "main.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+char *call_only(char *callsign) {
+    int i, len;
+
+    len = strlen(callsign);
+    for (i = 0; i < len; i++) {
+         if (!isalnum((int)callsign[i])) {
+            callsign[i]='\0';
+            i=len;
+        }
+    }
+    return(callsign);
+}
+
+
+
+
+
+/* ====================================================================  */
+/*    build a new (or newer if I check the file date) index file	 */
+/*    check for current ic index file					 */
+/*    FG: added a date check in case the FCC file has been updated.    */
+/*      appl.dat must have a time stamp newer than the index file time  */
+/*      stamp. Use the touch command on the appl.dat file to make the   */
+/*      time current if necessary.                                      */
+//    How this works:  The index file contains a few callsigns and their
+//    offsets into the large database file.  The code uses these as
+//    jump-off points to look for a particular call, to speed things up.
+/* ******************************************************************** */
+int build_fcc_index(int type){
+    FILE *fdb;
+    FILE *fndx;
+    unsigned long call_offset = 0;
+    unsigned long x = 0;
+    char fccdata[FCC_DATA_LEN+8];
+    char database_name[100];
+    int found,i,num;
+    char appl_file_path[MAX_VALUE];
+
+    if (type==1)
+        xastir_snprintf(database_name, sizeof(database_name), "fcc/appl.dat");
+    else
+        xastir_snprintf(database_name, sizeof(database_name), "fcc/EN.dat");
+
+    /* ====================================================================    */
+    /*    If the index file is there, exit                */
+    /*                                    */
+    get_user_base_dir("data/appl.ndx", appl_file_path, 
+                      sizeof(appl_file_path));
+    if (filethere(appl_file_path)) {
+        /* if file is there make sure the index date is newer */
+        if (file_time(get_data_base_dir(database_name))<=file_time(appl_file_path))
+            return(1);
+        else {
+            // FCC index old, rebuilding
+            statusline(langcode("STIFCC0100"),1);
+
+            fprintf(stderr,"FCC index is old.  Rebuilding index.\n");
+//            XmTextFieldSetString(text,"FCC index old, rebuilding");
+//            XtManageChild(text);
+//            XmUpdateDisplay(XtParent(text));     // DK7IN: do we need this ???
+        }
+    }
+
+    /* ====================================================================    */
+    /*    Open the database and index file                */
+    /*                                    */
+    fdb=fopen(get_data_base_dir(database_name),"rb");
+    if (fdb==NULL){
+        fprintf(stderr,"Build:Could not open FCC data base: %s\n", get_data_base_dir(database_name) );
+        return(0);
+    }
+
+    fndx=fopen(appl_file_path,"w");
+    if (fndx==NULL){
+        fprintf(stderr,"Build:Could not open/create FCC data base index: %s\n", appl_file_path );
+        (void)fclose(fdb);
+        return(0);
+    }
+
+    /* ====================================================================    */
+    /*    write out the current callsign and RBA of the db file         */
+    /*    skip (index_skip) records and do it again until no more        */
+    /*                                    */
+    xastir_snprintf(fccdata,sizeof(fccdata)," ");
+    while(!feof(fdb)) {
+        call_offset = (unsigned long)ftell(fdb);
+        (void)fgets(fccdata, (int)sizeof(fccdata), fdb);
+        found=0;
+        num=0;
+        if (type==2) {
+            for(i=0;i<14 && !found;i++) {
+                if(fccdata[i]=='|') {
+                    num++;
+                    if(num==4)
+                        found=i+1;
+                }
+            }
+        }
+        (void)call_only(fccdata+found);
+        fprintf(fndx,"%-6.6s%li\n",fccdata+found,call_offset+found);
+        for (x=0;x<=500 && !feof(fdb);x++) {
+            if (fgets(fccdata, (int)sizeof(fccdata), fdb)==NULL)
+                break;
+        }
+    }
+    (void)fclose(fdb);
+    (void)fclose(fndx);
+
+//    XmTextFieldSetString(text,"");
+//    XtManageChild(text);
+
+    return(1);
+}
+
+
+
+
+
+/* ====================================================================    */
+/*    Check for ic data base file                    */
+/*    Check/build the index                        */
+/*                                    */
+/* ******************************************************************** */
+int check_fcc_data(void) {
+    int fcc_data_available = 0;
+    if (filethere(get_data_base_dir("fcc/EN.dat")) && filethere(get_data_base_dir("fcc/appl.dat"))) {
+        if(file_time(get_data_base_dir("fcc/appl.dat"))<=file_time(get_data_base_dir("fcc/EN.dat"))) {
+            /*fprintf(stderr,"NEW FORMAT FCC DATA FILE is NEWER THAN OLD FCC FORMAT\n");*/
+            if (build_fcc_index(2))
+                fcc_data_available=2;
+            else {
+                fprintf(stderr,"Check:Could not build fcc data base index\n");
+                fcc_data_available=0;
+            }
+        } else {
+            /*fprintf(stderr,"OLD FORMAT FCC DATA FILE is NEWER THAN NEW FCC FORMAT\n");*/
+            if (build_fcc_index(1))
+                fcc_data_available=1;
+            else {
+                fprintf(stderr,"Check:Could not build fcc data base index\n");
+                fcc_data_available=0;
+            }
+        }
+    } else {
+        if (filethere(get_data_base_dir("fcc/EN.dat"))) {
+            /*fprintf(stderr,"NO OLD FCC, BUT NEW FORMAT FCC DATA AVAILABLE\n");*/
+            if (build_fcc_index(2))
+                fcc_data_available=2;
+            else {
+                fprintf(stderr,"Check:Could not build fcc data base index\n");
+                fcc_data_available=0;
+            }
+        } else {
+            if (filethere(get_data_base_dir("fcc/appl.dat"))) {
+                /*fprintf(stderr,"NO NEW FCC, BUT OLD FORMAT FCC DATA AVAILABLE\n");*/
+                if (build_fcc_index(1))
+                    fcc_data_available=1;
+                else {
+                    fprintf(stderr,"Check:Could not build fcc data base index\n");
+                    fcc_data_available=0;
+                }
+            }
+        }
+    }
+    return(fcc_data_available);
+}
+
+
+
+
+
+int search_fcc_data_appl(char *callsign, FccAppl *data) {
+    FILE *f;
+    char line[200];
+    int line_pos;
+    char data_in[16385];
+    int found, xx, bytes_read;
+    char temp[15];
+    int len;
+    int which;
+    int i,ii;
+    int pos_it;
+    int llen;
+    char calltemp[8];
+    int pos,ix,num;
+    FILE *fndx;
+    long call_offset = 0;
+    char char_offset[16];
+    char index[32];
+    char appl_file_path[MAX_VALUE];
+
+    data->id_file_num[0] = '\0';
+    data->type_purpose[0] = '\0';
+    data->type_applicant=' ';
+    data->name_licensee[0] = '\0';
+    data->text_street[0] = '\0';
+    data->text_pobox[0] = '\0';
+    data->city[0] = '\0';
+    data->state[0] = '\0';
+    data->zipcode[0] = '\0';
+    data->date_issue[0] = '\0';
+    data->date_expire[0] = '\0';
+    data->date_last_change[0] = '\0';
+    data->id_examiner[0] = '\0';
+    data->renewal_notice=' ';
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        callsign);
+    (void)call_only(temp);
+
+    xastir_snprintf(calltemp, sizeof(calltemp), "%-6.6s", temp);
+// calltemp doesn't appear to get used anywhere...
+
+    /* add end of field data */
+    strncat(temp, "|", sizeof(temp) - 1 - strlen(temp));
+    len=(int)strlen(temp);
+    found=0;
+    line_pos=0;
+    /* check the database again */
+    which = check_fcc_data();
+
+    // Check for first letter of a U.S. callsign
+    if (! (callsign[0] == 'A' || callsign[0] == 'K' || callsign[0] == 'N' || callsign[0] == 'W') )
+        return(0);  // Not found
+
+    // ====================================================================
+    // Search thru the index, get the RBA 
+    // 
+    // This gives us a jumping-off point to start looking in the right
+    // neighborhood for the callsign of interest.
+    //
+    get_user_base_dir("data/appl.ndx", appl_file_path, sizeof(appl_file_path));
+    fndx=fopen(appl_file_path,"r");
+    if (fndx!=NULL){
+        (void)fgets(index,(int)sizeof(index),fndx);
+        xastir_snprintf(char_offset,sizeof(char_offset),"%s",&index[6]);
+
+        // Search through the indexes looking for a callsign which is
+        // close to the callsign of interest.  If callsign is later in
+        // the alphabet than the current index, snag the next index.
+        while (!feof(fndx) && strncmp(callsign,index,6) > 0) {
+            xastir_snprintf(char_offset,sizeof(char_offset),"%s",&index[6]);
+            (void)fgets(index,(int)sizeof(index),fndx);
+        }
+    } else {
+        fprintf(stderr,"Search:Could not open FCC data base index: %s\n", appl_file_path );
+        return (0);
+    }
+    call_offset = atol(char_offset);
+
+    (void)fclose(fndx);
+
+    /* ====================================================================    */
+    /*    Continue with the original search                */
+    /*                                                                */
+
+    f=NULL;
+    switch (which) {
+        case(1):
+            f=fopen(get_data_base_dir("fcc/appl.dat"),"r");
+            break;
+
+        case(2):
+            f=fopen(get_data_base_dir("fcc/EN.dat"),"r");
+            break;
+
+        default:
+            break;
+    }
+    if (f!=NULL) {
+        (void)fseek(f, call_offset,SEEK_SET);
+        while (!feof(f) && !found) {
+            bytes_read=(int)fread(data_in,1,16384,f);
+            if (bytes_read>0) {
+                for (xx=0;(xx<bytes_read) && !found;xx++) {
+                    if(data_in[xx]!='\n' && data_in[xx]!='\r') {
+                        if (line_pos<199) {
+                            line[line_pos++]=data_in[xx];
+                            line[line_pos]='\0';
+                        }
+                    } else {
+                        line_pos=0;
+                        /*fprintf(stderr,"line:%s\n",line);*/
+                        pos=0;
+                        num=0;
+                        if (which==2) {
+                            for (ix=0;ix<14 && !pos;ix++) {
+                                if (line[ix]=='|') {
+                                    num++;
+                                    if (num==4)
+                                        pos=ix+1;
+                                }
+                            }
+                        }
+                        if (strncmp(line+pos,temp,(size_t)len)==0) {
+                            found=1;
+                            /*fprintf(stderr,"line:%s\n",line);*/
+                            llen=(int)strlen(line);
+                            /* replace "|" with 0 */
+                            for (ii=pos;ii<llen;ii++) {
+                                if (line[ii]=='|')
+                                    line[ii]='\0';
+                            }
+                            pos_it=pos;
+                            for (i=0; i<15; i++) {
+                                for (ii=pos_it;ii<llen;ii++) {
+                                    if (line[ii]=='\0') {
+                                        pos_it=ii;
+                                        ii=llen+1;
+                                    }
+                                }
+                                pos_it++;
+                                if (line[pos_it]!='\0') {
+                                    /*fprintf(stderr,"DATA %d %d:%s\n",i,pos_it,line+pos_it);*/
+                                    switch (which) {
+                                        case(1):
+                                            switch(i) {
+                                                case(0):
+                                                    xastir_snprintf(data->id_file_num,sizeof(data->id_file_num),"%s",line+pos_it);
+                                                    break;
+
+                                                case(1):
+                                                    xastir_snprintf(data->type_purpose,sizeof(data->type_purpose),"%s",line+pos_it);
+                                                    break;
+
+                                                case(2):
+                                                    data->type_applicant=line[pos_it];
+                                                    break;
+
+                                                case(3):
+                                                    xastir_snprintf(data->name_licensee,sizeof(data->name_licensee),"%s",line+pos_it);
+                                                    break;
+
+                                                case(4):
+                                                    xastir_snprintf(data->text_street,sizeof(data->text_street),"%s",line+pos_it);
+                                                    break;
+
+                                                case(5):
+                                                    xastir_snprintf(data->text_pobox,sizeof(data->text_pobox),"%s",line+pos_it);
+                                                    break;
+
+                                                case(6):
+                                                    xastir_snprintf(data->city,sizeof(data->city),"%s",line+pos_it);
+                                                    break;
+
+                                                case(7):
+                                                    xastir_snprintf(data->state,sizeof(data->state),"%s",line+pos_it);
+                                                    break;
+
+                                                case(8):
+                                                    xastir_snprintf(data->zipcode,sizeof(data->zipcode),"%s",line+pos_it);
+                                                    break;
+
+                                                case(9):
+                                                    xastir_snprintf(data->date_issue,sizeof(data->date_issue),"%s",line+pos_it);
+                                                    break;
+
+                                                case(11):
+                                                    xastir_snprintf(data->date_expire,sizeof(data->date_expire),"%s",line+pos_it);
+                                                    break;
+
+                                                case(12):
+                                                    xastir_snprintf(data->date_last_change,sizeof(data->date_last_change),"%s",line+pos_it);
+                                                    break;
+
+                                                case(13):
+                                                    xastir_snprintf(data->id_examiner,sizeof(data->id_examiner),"%s",line+pos_it);
+                                                    break;
+
+                                                case(14):
+                                                    data->renewal_notice=line[pos_it];
+                                                    break;
+
+                                                default:
+                                                    break;
+                                            }
+                                            break;
+
+                                        case(2):
+                                            switch (i) {
+                                                case(0):
+                                                    xastir_snprintf(data->id_file_num,sizeof(data->id_file_num),"%s",line+pos_it);
+                                                    break;
+
+                                                case(2):
+                                                    xastir_snprintf(data->name_licensee,sizeof(data->name_licensee),"%s",line+pos_it);
+                                                    break;
+
+                                                case(10):
+                                                    xastir_snprintf(data->text_street,sizeof(data->text_street),"%s",line+pos_it);
+                                                    break;
+
+                                                case(11):
+                                                    xastir_snprintf(data->city,sizeof(data->city),"%s",line+pos_it);
+                                                    break;
+
+                                                case(12):
+                                                    xastir_snprintf(data->state,sizeof(data->state),"%s",line+pos_it);
+                                                    break;
+
+                                                case(13):
+                                                    xastir_snprintf(data->zipcode,sizeof(data->zipcode),"%s",line+pos_it);
+                                                    break;
+
+                                                default:
+                                                    break;
+                                            }
+                                            break;
+
+                                        default:
+                                            break;
+                                    }
+                                }
+                            }
+                        }
+                        else {
+                            // Check whether we passed the alphabetic
+                            // location for the callsign.  Return if so.
+                            if ( (temp[0] < line[pos]) ||
+                                    ( (temp[0] == line[pos]) && (temp[1] < line[pos+1]) ) ) {
+
+                                // "Callsign Search", "Callsign Not Found!"
+                                popup_message_always(langcode("STIFCC0101"),
+                                    langcode("STIFCC0102") );
+
+                                //fprintf(stderr,"%c%c\t%c%c\n",temp[0],temp[1],line[pos],line[pos+1]);
+                                (void)fclose(f);
+                                return(0);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        (void)fclose(f);
+    } else {
+        fprintf(stderr,"Could not open FCC appl data base at: %s\n", get_data_base_dir("fcc/") );
+    }
+    return(found);
+}
+
+
diff --git a/src/fcc_data.h b/src/fcc_data.h
new file mode 100644
index 0000000..82760ea
--- /dev/null
+++ b/src/fcc_data.h
@@ -0,0 +1,90 @@
+/*
+ * $Id: fcc_data.h,v 1.10 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/*
+ * FCC Database structures
+ *
+ */
+
+/*
+type_purpose - Indicates the reason why the application was
+               filed.  Multiple codes may occur.  Codes are:
+
+    A  New license
+    B  Change existing class
+    C  Change name
+    D  Change mailing address
+    E  Change callsign
+    F  Renewal on Form 610
+    G  Add record (internal)
+    H  Duplicate license request
+    I  Change Issue/Expiration Date
+    J  Supercede
+    K  Internal correction code
+    L  Delete
+    N  Renewal on form 610R
+    O  Renewal on form 610B
+    P  Modification on form 610B
+    Q  Restore both database and pending
+    R  Restore database
+    S  Special callsign change
+
+type_applicant - Indicates type of application.  Codes are:
+
+    A  Alien
+    C  Club
+    I  Individual
+    M  Military recreation
+    R  RACES
+
+*/
+
+#ifndef XASTIR_FCC_DATA_H
+#define XASTIR_FCC_DATA_H
+
+#define FCC_DATA_LEN 200
+
+typedef struct{
+    char id_callsign[11];
+    char id_file_num[11];
+    char type_purpose[9];
+    char type_applicant;
+    char name_licensee[41];
+    char text_street[36];
+    char text_pobox[21];
+    char city[30];
+    char state[3];
+    char zipcode[10];
+    char filler;
+    char date_issue[7];
+    char date_expire[7];
+    char date_last_change[7];
+    char id_examiner[4];
+    char renewal_notice;
+} FccAppl;
+
+extern int check_fcc_data(void);
+extern int search_fcc_data_appl(char *callsign, FccAppl *data);
+
+#endif /* XASTIR_FCC_DATA_H */
diff --git a/src/festival.c b/src/festival.c
new file mode 100644
index 0000000..f5a5ca5
--- /dev/null
+++ b/src/festival.c
@@ -0,0 +1,476 @@
+// Modification for Xastir CVS purposes
+//
+// Portions Copyright (C) 2000-2012  The Xastir Group
+//
+// $Id: festival.c,v 1.25 2012/08/25 16:38:29 tvrusso Exp $
+//
+// End of modification
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/*                Centre for Speech Technology Research                  */
+/*                     University of Edinburgh, UK                       */
+/*                        Copyright (c) 1999                             */
+/*                        All Rights Reserved.                           */
+/*                                                                       */
+/*  Permission is hereby granted, free of charge, to use and distribute  */
+/*  this software and its documentation without restriction, including   */
+/*  without limitation the rights to use, copy, modify, merge, publish,  */
+/*  distribute, sublicense, and/or sell copies of this work, and to      */
+/*  permit persons to whom this work is furnished to do so, subject to   */
+/*  the following conditions:                                            */
+/*   1. The code must retain the above copyright notice, this list of    */
+/*      conditions and the following disclaimer.                         */
+/*   2. Any modifications must be clearly marked as such.                */
+/*   3. Original authors' names are not deleted.                         */
+/*   4. The authors' names are not used to endorse or promote products   */
+/*      derived from this software without specific prior written        */
+/*      permission.                                                      */
+/*                                                                       */
+/*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK        */
+/*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
+/*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
+/*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE     */
+/*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
+/*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
+/*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
+/*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
+/*  THIS SOFTWARE.                                                       */
+/*                                                                       */
+/*************************************************************************/
+/*             Author :  Alan W Black (awb at cstr.ed.ac.uk)                */
+/*             Date   :  March 1999                                      */
+/*-----------------------------------------------------------------------*/
+/*                                                                       */
+/* Client end of Festival server API in C designed specifically for      */
+/* Galaxy Communicator use though might be of use for other things       */
+/*                                                                       */
+/* This is a standalone C client, no other Festival or Speech Tools      */
+/* libraries need be link with this.  Thus is very small.                */
+/*                                                                       */
+/* Compile with (plus socket libraries if required)                      */
+/*    cc -o festival_client -DSTANDALONE festival_client.c               */
+/*                                                                       */
+/* Run as                                                                */
+/*    festival_client -text "hello there" -o hello.snd                   */
+/*                                                                       */
+/*                                                                       */
+/* This is provided as an example, it is quite limited in what it does   */
+/* but is functional compiling without -DSTANDALONE gives you a simple   */
+/* API                                                                   */
+/*                                                                       */
+/*************************************************************************/
+/*                                                                       */
+/* Heavily modified and Hacked together to provide a general purpose     */
+/* interface for use in XASTIR by:                                       */
+/*                                                                       */
+/*    Ken Koster    N7IPB    03/24/2001                                  */
+/*                                                                       */
+/*                                                                       */      
+/*  More comments added and 'do' loop that waited for 'ok' response      */
+/*  removed.  Also cleaned up escape processing                          */
+/*                                                                       */
+/*                  N7IPB    04/04/2001                                  */
+/*  Test for errno result from 'read' operation and re-opening of        */
+/*  connection if it gets closed.                                        */
+/*                  N7IPB    04/08/2001                                  */
+/*                                                                       */
+/*=======================================================================*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "xastir.h"
+#include "festival.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+FT_Info *info = NULL;
+
+static char last_speech_text[8000];
+static time_t last_speech_time = (time_t)0;
+static time_t festival_connect_attempt_time = (time_t)0;
+
+
+
+
+
+// Set up default struct
+//
+void festival_default_info(void) {
+
+    if (info == NULL) { // First time through
+
+        // Malloc storage for the struct
+        info = (FT_Info *)malloc(1 * sizeof(FT_Info));
+
+        // Fill in the struct
+        if (info != NULL) {
+            info->server_host = FESTIVAL_DEFAULT_SERVER_HOST;
+            info->server_port = FESTIVAL_DEFAULT_SERVER_PORT;
+            info->text_mode = FESTIVAL_DEFAULT_TEXT_MODE;
+            info->server_fd = -1;
+        }
+        else {  // Couldn't allocate memory
+            fprintf(stderr,"festival_default_info: Couldn't malloc\n");
+        }
+    }
+
+    return;
+}
+
+
+
+
+
+// Returns a FD to a remote server
+//
+static int festival_socket_open(const char *host, int port) {
+    struct sockaddr_in serv_addr;
+    struct hostent *serverhost;
+    int fd;
+
+
+    // Delay at least 60 seconds between each socket attempt
+    if ( (festival_connect_attempt_time + 60) > sec_now() ) {
+        //fprintf(stderr,"Not time yet\n");
+        return(-1);
+    }
+    festival_connect_attempt_time = sec_now();
+
+    if ((fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+        fprintf(stderr,"festival_client: can't get socket\n");
+        return(-1);
+    }
+
+    memset(&serv_addr, 0, sizeof(serv_addr));
+
+    if ((int)(serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
+        /* its a name rather than an ipnum */
+        serverhost = gethostbyname(host);
+        if (serverhost == (struct hostent *)0) {
+            fprintf(stderr,"festival_client: gethostbyname failed\n");
+            return(-1);
+        }
+        memmove(&serv_addr.sin_addr,serverhost->h_addr, (size_t)serverhost->h_length);
+    }
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_port = htons(port);
+
+    if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
+        fprintf(stderr,"festival_client: connect to server failed\n");
+        (void)close(fd);    // Close the socket
+        return(-1);
+    }
+    return(fd);
+}
+
+
+
+
+
+/***********************************************************************/
+/* Public Functions to this API                                        */
+/***********************************************************************/
+
+
+
+// Close socket to server
+//
+int festivalClose(void) {
+
+    //fprintf(stderr,"festivalClose()\n");
+
+    if (info != NULL) {    // We have a struct allocated
+
+        // Check whether we have a socket open
+        if (info->server_fd != -1) {
+            fprintf(stderr,"Closing Festival socket\n");
+            (void)close(info->server_fd);   // Close the socket
+            info->server_fd = -1;   // Just to be safe
+        }
+
+        // Free the struct, zero the pointer.  The struct will get
+        // re-created/re-initialized later when we re-open the
+        // festival connection.
+        free(info);
+        info = NULL;
+    }
+
+    return(0);
+}
+
+
+
+
+
+// Open socket to server.  Close the connection if one is already
+// open.
+//
+int festivalOpen(void) {
+
+
+    //fprintf(stderr,"festivalOpen()\n");
+
+    festival_default_info();
+
+    // Check whether we have a record to work with
+    if (info == NULL) {
+        return(-1);
+    }
+
+    // Check whether we already have a socket open (or think we do)
+    if (info->server_fd != -1) {    // We have a socket open
+        (void)festivalClose();      // Close it, free struct
+        usleep(50000);              // 50ms wait
+    }
+
+    info->server_fd = festival_socket_open(info->server_host, info->server_port);
+
+    if (info->server_fd == -1) {    // Error occured opening socket
+        //fprintf(stderr,"festivalOpen: Error opening socket\n");
+        (void)festivalClose();      // Close, free struct
+        usleep(50000);              // 50ms wait
+        return(-1);
+    }
+
+    return(0);
+}
+
+
+
+
+
+void festivalStringToSpeech(char *text) {
+    FILE *fd;
+    char *p;
+    char ack[4];
+    int n;
+    int tmp = 0;
+    int ret;
+
+
+    //fprintf(stderr,"festivalStringToSpeech()\n");
+
+    // If we don't have a struct allocated
+    if (info == 0) {
+        if (festivalOpen() == -1) { // Allocate struct, open socket
+            //fprintf(stderr,"festivalStringToSpeech: Couldn't open socket to Festival\n");
+            return;
+        }
+    }
+
+    if (info == 0) {    // If socket is still not open
+        return;
+    }
+
+    if (info->server_fd == -1) {
+        fprintf(stderr,"festival_client: server connection unopened\n");
+        (void)festivalClose();
+        return;
+    }
+
+    fd = fdopen(dup(info->server_fd),"wb");
+
+    if (fd == NULL) {
+        fprintf(stderr,"Couldn't create duplicate socket\n");
+        (void)festivalClose();
+        return;
+    }
+
+    /*
+    **  Send the mode commands to festival
+    */
+    ret = fprintf(fd,"(audio_mode `async)\n(SayText \"\n");
+
+    if (ret == 0 || ret == -1) {
+        fprintf(stderr,"Couldn't send mode commands to festival\n");
+        (void)fclose(fd);
+        (void)festivalClose();
+        return;
+    }
+
+    /* 
+    **  Copy text over to server, escaping any quotes 
+    */ 
+    for (p=text; p && (*p != '\0'); p++) {
+        if ((*p == '"') || (*p == '\\')) {
+
+            if (putc('\\',fd) == EOF) { // Error writing to socket
+                fprintf(stderr,"Error writing to socket\n");
+                (void)fclose(fd);
+                (void)festivalClose();
+                return;
+            }
+        }
+        else {
+            /* 
+            ** Then convert any embedded '-' into the word 'dash'
+            ** This could cause problems with spoken text from 
+            ** Weather alerts or messages.  We'll deal with that 
+            ** later if necessary.  Making this a separate function
+            ** is probably the thing to do.
+            */
+            if (*p == '-' ) {
+
+                ret = fprintf(fd,",dash,");
+
+                if (ret == 0 || ret == -1) {
+                    fprintf(stderr,"Error writing to socket\n");
+                    (void)fclose(fd);
+                    (void)festivalClose();
+                    return;
+                }
+            }
+            else {
+
+                if (putc(*p,fd) == EOF) {   // Error writing to socket
+                    fprintf(stderr,"Error writing to socket\n");
+                    (void)fclose(fd);
+                    (void)festivalClose();
+                    return;
+                }
+            }
+        }
+    } 
+    /*
+    ** Complete the command to xastir, close the quotes and 
+    ** set the mode to 'fundamental'
+    */
+    ret = fprintf(fd,"\" \"%s\")\n",info->text_mode);
+
+    if (ret == 0 || ret == -1) {
+        fprintf(stderr,"Error writing to socket\n");
+        (void)fclose(fd);
+        (void)festivalClose();
+        return;
+    }
+
+    /*
+    ** Close the duplicate port we used for writing
+    */
+    (void)fclose(fd);
+    /*
+    ** Read back info from server
+    **
+    ** We don't really care what we get back.  If it's an error
+    ** We're just going to continue on anyway so I've removed the
+    ** check here for the 'OK' response.  We still check for an ERror
+    ** but we just print the fact we got it and continue on
+    **
+    ** This could probably use some work,  I need to study the 
+    ** festival docs a bit more,  this could block and it could 
+    ** also have more than 3bytes that need to be read.  It doesn't
+    ** appear to matter but should be checked into. 
+    */
+    for (n=0; n < 3; ) {
+        if ( ( tmp = read(info->server_fd,ack+n,3-n)) != -1 ) {
+            n = n + tmp;
+        }
+        else {
+            if (debug_level & 2) {
+                fprintf(stderr,"Error reading festival ACK - %s\n",strerror(errno));
+            }
+            n = 3;
+            if (errno == ECONNRESET) {
+
+                fprintf(stderr,"Connection reset\n");
+                info = 0;
+
+                (void)festivalClose();
+
+                if (festivalOpen() == -1) {
+                    fprintf(stderr,"festivalStringToSpeech2: Couldn't open socket to Festival\n");
+                    return;
+                }
+ 
+            } 
+        }
+    }
+        
+    /*
+    ** Null terminate the string
+    */
+    ack[3] = '\0';
+    if (strcmp(ack,"ER\n") == 0) {    /* server got an error */
+        fprintf(stderr,"festival_client: server returned error\n");
+    }
+    return;
+}
+
+
+
+
+
+int SayText(char *text) {
+
+    if (debug_level & 2)
+        fprintf(stderr,"SayText: %s\n",text);
+
+    // Check whether the last text was the same and it hasn't been
+    // enough time between them (30 seconds).  We include our speech
+    // system test string here so that we don't have to wait 30
+    // seconds between Test button-presses.
+    if ( (strcmp(last_speech_text,text) == 0) // Strings match
+            && (strcmp(text,SPEECH_TEST_STRING) != 0)
+            && (last_speech_time + 30 > sec_now()) ) {
+
+/*
+    fprintf(stderr,
+        "Same text, skipping speech: %d seconds, %s\n",
+        (int)(sec_now() - last_speech_time),
+        text);
+*/
+
+        return(1);
+    }
+
+    //fprintf(stderr,"Speaking: %s\n",text);
+
+    xastir_snprintf(last_speech_text,
+        sizeof(last_speech_text),
+        "%s",
+        text);
+    last_speech_time = sec_now();
+
+    festivalStringToSpeech(text);
+
+    return(0);
+}
+
+
+
+
+
+int SayTextInit(void) {
+
+    if (festivalOpen() == -1) {
+        fprintf(stderr,"SayText: Couldn't open socket to Festival\n");
+    }
+ 
+    last_speech_text[0] = '\0';
+    last_speech_time = (time_t)0;
+
+    return(0);
+}
+
+
diff --git a/src/festival.h b/src/festival.h
new file mode 100644
index 0000000..89879e9
--- /dev/null
+++ b/src/festival.h
@@ -0,0 +1,102 @@
+// Modification for Xastir CVS purposes
+//
+// Portions Copyright (C) 2000-2012  The Xastir Group
+//
+// $Id: festival.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+//
+// End of modification
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/*                Centre for Speech Technology Research                  */
+/*                     University of Edinburgh, UK                       */
+/*                        Copyright (c) 1999                             */
+/*                        All Rights Reserved.                           */
+/*                                                                       */
+/*  Permission is hereby granted, free of charge, to use and distribute  */
+/*  this software and its documentation without restriction, including   */
+/*  without limitation the rights to use, copy, modify, merge, publish,  */
+/*  distribute, sublicense, and/or sell copies of this work, and to      */
+/*  permit persons to whom this work is furnished to do so, subject to   */
+/*  the following conditions:                                            */
+/*   1. The code must retain the above copyright notice, this list of    */
+/*      conditions and the following disclaimer.                         */
+/*   2. Any modifications must be clearly marked as such.                */
+/*   3. Original authors' names are not deleted.                         */
+/*   4. The authors' names are not used to endorse or promote products   */
+/*      derived from this software without specific prior written        */
+/*      permission.                                                      */
+/*                                                                       */
+/*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK        */
+/*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
+/*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
+/*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE     */
+/*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
+/*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
+/*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
+/*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
+/*  THIS SOFTWARE.                                                       */
+/*                                                                       */
+/*************************************************************************/
+/*             Author :  Alan W Black (awb at cstr.ed.ac.uk)                */
+/*             Date   :  March 1999                                      */
+/*-----------------------------------------------------------------------*/
+/*                                                                       */
+/* Client end of Festival server API (in C) designed specifically for    */
+/* Galaxy Communicator use, though might be of use for other things      */
+/*                                                                       */
+/*=======================================================================*/
+#ifndef _FESTIVAL_CLIENT_H_
+#define _FESTIVAL_CLIENT_H_
+
+#define FESTIVAL_DEFAULT_SERVER_HOST "localhost"
+#define FESTIVAL_DEFAULT_SERVER_PORT 1314
+#define FESTIVAL_DEFAULT_TEXT_MODE "fundamental"
+
+typedef struct FT_Info
+{
+    int encoding;
+    char *server_host;
+    int server_port;
+    char *text_mode;
+    
+    int server_fd;
+} FT_Info;
+
+typedef struct FT_Wave
+{
+    int num_samples;
+    int sample_rate;
+    short *samples;
+} FT_Wave;
+
+void delete_FT_Wave(FT_Wave *wave);
+void delete_FT_Info(FT_Info *info);
+
+#define SWAPSHORT(x) ((((unsigned)x) & 0xff) << 8 | \
+                      (((unsigned)x) & 0xff00) >> 8)
+#define SWAPINT(x) ((((unsigned)x) & 0xff) << 24 | \
+                    (((unsigned)x) & 0xff00) << 8 | \
+            (((unsigned)x) & 0xff0000) >> 8 | \
+                    (((unsigned)x) & 0xff000000) >> 24)
+
+/* Sun, HP, SGI Mips, M68000 */
+#define FAPI_BIG_ENDIAN (((char *)&fapi_endian_loc)[0] == 0)
+/* Intel, Alpha, DEC Mips, Vax */
+#define FAPI_LITTLE_ENDIAN (((char *)&fapi_endian_loc)[0] != 0)
+
+
+/*****************************************************************/
+/*  Public functions to interface                                */
+/*****************************************************************/
+
+/* If called with NULL will attempt to access using defaults */
+int festivalOpen(void);
+void festivalStringToWave(char *text);
+int festivalClose(void);
+
+#endif  // _FESTIVAL_CLIENT_H_
+
+
diff --git a/src/fetch_remote.c b/src/fetch_remote.c
new file mode 100644
index 0000000..4477c40
--- /dev/null
+++ b/src/fetch_remote.c
@@ -0,0 +1,267 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: fetch_remote.c,v 1.4 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <math.h>
+#include <errno.h>
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif  // HAVE_LIBCURL
+
+// Needed for size_t
+#include <sys/types.h>
+
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern int debug_level;
+extern int net_map_timeout;
+
+/* curl routines */
+#ifdef HAVE_LIBCURL
+
+struct FtpFile {
+  char *filename;
+  FILE *stream;
+};
+
+
+
+
+
+size_t curl_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
+  struct FtpFile *out = (struct FtpFile *)stream;
+  if (out && !out->stream) {
+    out->stream=fopen(out->filename, "wb");
+    if (!out->stream)
+      return -1;
+  }
+  return fwrite(buffer, size, nmemb, out->stream);
+}
+
+/*
+ * xastir_curl_init - create curl session with common options
+ */
+CURL *xastir_curl_init(char *errBuf) {
+    CURL *mySession;
+    char agent_string[15];
+    
+    mySession = curl_easy_init();
+    if (mySession != NULL) {
+        if (debug_level & 8192) {
+            curl_easy_setopt(mySession, CURLOPT_VERBOSE, 1);
+        } else {
+            curl_easy_setopt(mySession, CURLOPT_VERBOSE, 0);
+        }
+
+
+        curl_easy_setopt(mySession, CURLOPT_ERRORBUFFER, errBuf);
+
+        xastir_snprintf(agent_string, sizeof(agent_string),"Xastir");
+        curl_easy_setopt(mySession, CURLOPT_USERAGENT, agent_string);
+
+        // write function
+        curl_easy_setopt(mySession, CURLOPT_WRITEFUNCTION, curl_fwrite);
+
+        curl_easy_setopt(mySession, CURLOPT_TIMEOUT, (long)net_map_timeout);
+        curl_easy_setopt(mySession, CURLOPT_CONNECTTIMEOUT, (long)(net_map_timeout/2));
+
+        // Added in libcurl 7.9.8
+#if (LIBCURL_VERSION_NUM >= 0x070908)
+        curl_easy_setopt(mySession, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
+#endif  // LIBCURL_VERSION_NUM
+
+        // Added in libcurl 7.10.6
+#if (LIBCURL_VERSION_NUM >= 0x071006)
+        curl_easy_setopt(mySession, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+#endif  // LIBCURL_VERSION_NUM
+
+        // Added in libcurl 7.10.7
+#if (LIBCURL_VERSION_NUM >= 0x071007)
+        curl_easy_setopt(mySession, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+#endif  // LIBCURL_VERSION_NUM
+
+        // Added in libcurl 7.10
+#if (LIBCURL_VERSION_NUM >= 0x070a00)
+        // This prevents a segfault for the case where we get a timeout on
+        // domain name lookup.  It has to do with the ALARM signal
+        // and siglongjmp(), which we use in hostname.c already.
+        // This URL talks about it a bit more, plus see the libcurl
+        // docs:
+        //
+        //     http://curl.haxx.se/mail/lib-2002-12/0103.html
+        //
+        curl_easy_setopt(mySession, CURLOPT_NOSIGNAL, 1);
+#endif // LIBCURL_VERSION_NUM
+
+    }
+
+    return(mySession);
+} // xastir_curl_init()
+
+/*
+ * fetch_remote_tile - downloads file using an open curl session
+ * Returns curl result code.
+ */
+int fetch_remote_tile(CURL *session, char *tileURL, char *tileFileName) {
+    CURLcode res;
+    struct FtpFile ftpfile;
+
+    curl_easy_setopt(session, CURLOPT_URL, tileURL);
+    ftpfile.filename = tileFileName;
+    ftpfile.stream = NULL;
+    curl_easy_setopt(session, CURLOPT_FILE, &ftpfile);    
+
+    res = curl_easy_perform(session);
+
+    if (ftpfile.stream)
+        fclose(ftpfile.stream);
+
+    return(res);
+
+} // fetch_remote_tile()
+
+#endif  // HAVE_LIBCURL
+
+
+/*
+ * fetch_remote_file
+ * Returns: 0 If file retrieved
+ *          1 If there was a problem getting the file
+ */
+int fetch_remote_file(char *fileimg, char *local_filename) {
+#ifdef HAVE_LIBCURL
+    CURL *curl;
+    CURLcode res;
+    char curlerr[CURL_ERROR_SIZE];
+    struct FtpFile ftpfile;
+
+//fprintf(stderr, "Fetching remote file: %s\n", fileimg);
+
+    curl = xastir_curl_init(curlerr);
+
+    if (curl) { 
+
+        // download from fileimg
+        curl_easy_setopt(curl, CURLOPT_URL, fileimg);
+        ftpfile.filename = local_filename;
+        ftpfile.stream = NULL;
+        curl_easy_setopt(curl, CURLOPT_FILE, &ftpfile);    
+
+        res = curl_easy_perform(curl);
+
+        curl_easy_cleanup(curl);
+
+        if (CURLE_OK != res) {
+            fprintf(stderr, "curl told us %d\n", res);
+            fprintf(stderr, "curlerr: %s\n", curlerr);
+            fprintf(stderr,
+                "Perhaps a timeout? Try increasing \"Internet Map Timout\".\n");
+        }
+
+        if (ftpfile.stream)
+            fclose(ftpfile.stream);
+
+        // Return error-code if we had trouble
+        if (CURLE_OK != res) {
+            return(1);
+        }
+
+    } else { 
+        fprintf(stderr,"Couldn't download the file %s\n", fileimg);
+        fprintf(stderr,
+            "Perhaps a timeout? Try increasing \"Internet Map Timout\".\n");
+ 
+        return(1);
+    }
+    return(0);  // Success!
+
+#else   // HAVE_LIBCURL
+
+#ifdef HAVE_WGET
+
+    char tempfile[500];
+
+    //"%s --server-response --timestamping --user-agent=Xastir --tries=1 --timeout=%d --output-document=%s \'%s\' 2> /dev/null\n",
+    xastir_snprintf(tempfile, sizeof(tempfile),
+        "%s --server-response --user-agent=Xastir --tries=1 --timeout=%d --output-document=%s \'%s\' 2> /dev/null\n",
+        WGET_PATH,
+        net_map_timeout,
+        local_filename,
+        fileimg);
+
+    if (debug_level & 2)
+        fprintf(stderr,"%s",tempfile);
+
+    if ( system(tempfile) ) {   // Go get the file
+        fprintf(stderr,"Couldn't download the file\n");
+        fprintf(stderr,
+            "Perhaps a timeout? Try increasing \"Internet Map Timout\".\n");
+ 
+        return(1);
+    }
+    return(0);  // Success!
+
+#else // HAVE_WGET
+
+    fprintf(stderr,"libcurl or 'wget' not installed.  Can't download file\n");
+    return(1);
+
+#endif  // HAVE_WGET
+#endif  // HAVE_LIBCURL
+
+}        
diff --git a/src/fetch_remote.h b/src/fetch_remote.h
new file mode 100644
index 0000000..8f70c64
--- /dev/null
+++ b/src/fetch_remote.h
@@ -0,0 +1,40 @@
+/*
+ * $Id: fetch_remote.h,v 1.3 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_FETCH_REMOTE_H
+#define __XASTIR_FETCH_REMOTE_H
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+CURL *xastir_curl_init(char *errBuf);
+int fetch_remote_tile(CURL *session, char *tileURL, char *tileFileName);
+#endif  // HAVE_LIBCURL
+
+int fetch_remote_file(char *fileimg, char *local_filename);
+
+
+#endif // __XASTIR_FETCH_REMOTE_H
+
+
diff --git a/src/geo-find.c b/src/geo-find.c
new file mode 100644
index 0000000..e75ab99
--- /dev/null
+++ b/src/geo-find.c
@@ -0,0 +1,529 @@
+
+// $Id: geo-find.c,v 1.17 2012/08/25 16:38:29 tvrusso Exp $
+
+
+/* Copyright 2002 Daniel Egnor.  See LICENSE.geocoder file.
+ * Portions Copyright (C) 2004-2012  The Xastir Group
+ *
+ * The geo_find() function defined here uses an address map built by 
+ * geo-*-to-* to parse an address and convert it to geographical
+ * coordinates.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "geo.h"
+#include "io.h"
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define D(x)
+
+
+
+struct state {
+	struct io_file *index;
+
+	/* Text input */
+	int input_depth;
+	const char *input_begin,*input_end;
+	char buffer[100],*buffer_next,*buffer_end;
+	const char *next;
+
+	/* Working hypothesis */
+	int address;
+	struct { int begin,end; } range[4];
+	int range_count;
+
+	/* Answer */
+	struct geo_location *out;
+};
+
+
+
+
+
+static int is_valid(struct state *s) {
+	int i,pos[sizeof(s->range)/sizeof(*s->range)];
+
+	if (0 == s->range_count) return 0;
+
+	for (i = 0; i < s->range_count; ++i) {
+D(printf("    Metarange #%d: %d entries\n",i,(s->range[i].end - s->range[i].begin) / 8));
+		pos[i] = s->range[i].begin;
+	}
+
+	for (;;) {
+		int i_begin = 1,i_end = 1;
+		int best_begin = 1,best_end = 1;
+		char out_side = 'X';
+		int out_addr = 0,out_lat = 0,out_long = 0;
+
+D(printf("Searching ---\n"));
+		for (i = 0; i != i_begin; i = (i + 1) % s->range_count) {
+			int r_begin,r_end;
+			for (;;) {
+				int n;
+				if (pos[i] >= s->range[i].end || pos[i] < 0) {
+D(printf("    Range #%d @ %d: End\n",i,(pos[i] - s->range[i].begin) / 8));
+					return 0;
+				}
+				n = io_in_i4(s->index,
+				    io_in_i4(s->index,pos[i],&r_begin),&r_end);
+				if (n < 0) 
+					return 0;
+D(printf("    Range #%d @ %d: [%d,%d)\n",i,(pos[i] - s->range[i].begin) / 8,r_begin,r_end));
+				if (r_end > best_begin && r_begin < r_end) 
+					break;
+				pos[i] = n;
+			}
+			if (r_begin > best_begin) {
+				best_begin = r_begin;
+				best_end = r_end;
+				i_begin = i_end = i;
+D(printf("        Best -> [%d#%d,%d#%d)\n",best_begin,i_begin,best_end,i_end));
+			}
+			else if (r_end < best_end) {
+				best_end = r_end;
+				i_end = i;
+D(printf("        Best -> [%d#%d,%d#%d)\n",best_begin,i_begin,best_end,i_end));
+			}
+		}
+
+D(printf("Address range ---\n"));
+		pos[i_end] += 8; /* hack... */
+		do {
+			int next,lon,lat,addr;
+			best_begin = io_in_i4(s->index,best_begin,&next);
+			best_begin = io_in_i4(s->index,best_begin,&lon);
+			best_begin = io_in_i4(s->index,best_begin,&lat);
+			best_begin = io_in_i4(s->index,best_begin,&addr);
+
+			/* PERF: This should be a binary search... */
+			while (best_begin >= 0 && best_begin < next) {
+				short da;
+				signed char dln,dlt;
+				char side;
+				best_begin = io_in_i2(s->index,best_begin,&da);
+				best_begin = io_in_i1(s->index,best_begin,&dln);
+				best_begin = io_in_i1(s->index,best_begin,&dlt);
+				best_begin = io_in(s->index,best_begin,&side,1);
+D(printf("    %c: %d vs. %d\n",side,addr + da,s->address / 2));
+				if (addr + da <= s->address / 2) {
+					out_side = side;
+					out_addr = addr + da;
+					out_lat = lat + dlt;
+					out_long = lon + dln;
+				} else if ('X' == out_side) {
+					best_begin = next;
+D(printf("    Not this time.\n"));
+					break;
+				}
+				else if (NULL != s->out) {
+					const int parity = s->address % 2;
+
+					s->out->before.address =
+						2 * out_addr + parity;
+					s->out->before.latitude =
+						out_lat / 100000.0;
+					s->out->before.longitude =
+						out_long / 100000.0;
+
+					if ('X' == side) --da;
+					s->out->after.address =
+						2 * (addr + da) + parity;
+					s->out->after.latitude =
+						(lat + dlt) / 100000.0;
+					s->out->after.longitude =
+						(lon + dln) / 100000.0;
+
+					s->out->at.address = s->address;
+					s->out->at.latitude = (out_lat +
+						(lat + dlt - out_lat) *
+						(s->address / 2 - out_addr) /
+						(addr + da - out_addr)) /
+						100000.0;
+					s->out->at.longitude = (out_long +
+						(lon + dln - out_long) *
+						(s->address / 2 - out_addr) /
+						(addr + da - out_addr)) /
+						100000.0;
+
+					s->out->side = out_side;
+D(printf("    Success!\n"));
+					return 1;
+				} 
+				else {
+D(printf("    Success...\n"));
+					return 1;
+				}
+			}
+		} 
+		while (best_begin > 0 && best_begin < best_end);
+	}
+}
+
+
+
+
+
+static int find_name(
+    	struct io_file *index,int begin,int end,
+    	char type,const char *name, unsigned int name_len) {
+	const int size = 45;
+	const int count = (end - begin) / size;
+	const int mid = begin + size * (count / 2);
+	char test[41];
+	if (count <= 1) return begin;
+	if (io_in(index,mid - size,test,sizeof test) < 0) return -1;
+	if (name_len > sizeof test - 1)
+		name_len = sizeof test - 1;
+	if (type > test[0]
+	|| (type == test[0] && strncasecmp(name,test + 1,name_len) > 0))
+		return find_name(index,mid,end,type,name,name_len);
+	else
+		return find_name(index,begin,mid,type,name,name_len);
+}
+
+
+
+static const char *next_word(struct state *,const char *);
+
+
+
+static int get_name_at( struct state *s,
+                        char type,
+                        int (*f)(struct state *),
+                        const char *last) {
+
+	char n[41];
+	const char *next,*save;
+	unsigned int len = last - s->next;
+	int begin,end,pos;
+
+	if (io_in_i4(s->index,
+                io_in_i4(s->index,
+                io_in_i4(s->index,0,NULL),&begin),&end) < 0
+            || (pos = find_name(s->index,begin,end,type,s->next,len)) < 0
+            ||  pos == end
+            || (pos = io_in_i4(s->index,io_in(s->index,pos,n,sizeof n),&begin)) < 0
+            ||  pos == end
+            || (pos = io_in_i4(s->index,io_in(s->index,pos,NULL,sizeof n),&end)) < 0
+            ||  n[0] != type
+            ||  strncasecmp(n + 1,s->next,len)) {
+        D(printf("    '%c' \"%.*s\" not found\n",type,len,s->next));
+		return 0;
+	}
+
+	if ('=' == n[len + 1]) { /* alias expansion */
+		char * const replace = (s->next - s->buffer) + s->buffer;
+		int delta;
+
+		begin = len + 2;
+
+		while (begin < (int)sizeof n && ' ' == n[begin]) ++begin;
+
+        end = sizeof n;
+
+        while (end > begin && ' ' == n[end - 1]) --end;
+
+        if (end < (int)sizeof n) ++end;
+
+        if (end - begin > (int)len) end = begin + len;
+
+D(printf("    Replacing '%.*s' with '%.*s'\n",len,n + 1,end - begin,&n[begin]));
+
+		memcpy(replace,n + begin,end - begin);
+		memmove(replace + (end - begin),
+                        replace + len,
+		        s->buffer_end - replace - len);
+
+		delta = len - (end - begin);
+		s->buffer_end -= delta;
+		s->buffer_next -= delta;
+D(printf("    Buffer is now: '%.*s'\n",s->buffer_end - s->buffer,s->buffer));
+		return 1;
+	}
+
+	next = next_word(s,last);
+	if (next != last && get_name_at(s,type,f,next)) return 1;
+
+	pos = len;
+
+	while (++pos < (int)sizeof n) if (' ' != n[pos]) return 0;
+
+	s->range[s->range_count].begin = begin;
+	s->range[s->range_count].end = end;
+	++s->range_count;
+	save = s->next;
+	s->next = last;
+D(printf(">>> '%c' \"%.*s\" found\n",type,len - 1,n + 1));
+	if (NULL != f && f(s)) {
+        char *out = NULL;
+
+		switch (type) {
+		case 'E':
+		case 'O':
+			out = s->out ? s->out->street_name : NULL;
+			break;
+		case 'C':
+			out = s->out ? s->out->city_name : NULL;
+			break;
+		case 'S':
+			out = s->out ? s->out->state_name : NULL;
+			break;
+		}
+
+		if (NULL != out) {
+            // strncpy is dangerous as it can leave a string
+            // unterminated if the destination isn't big enough to
+            // hold the '\0' character.  Must terminate the string
+            // manually in all cases, as we do here.
+			strncpy(out,n + 1,len - 1);
+			out[len - 1] = '\0';
+		}
+
+		s->next = save;
+		return 1;
+	}
+
+D(printf("<<< '%c' \"%.*s\"\n",type,len - 1,n + 1));
+	--s->range_count;
+	s->next = save;
+	return 0;
+}
+
+
+
+
+
+static const char *input_word(struct state *s,const char *pos) {
+	assert(pos >= s->buffer && pos <= s->buffer_end);
+	if (pos != s->buffer_end) {
+		while (pos < s->buffer_end && *pos != ' ') ++pos;
+		while (pos < s->buffer_end && *pos == ' ') ++pos;
+		return pos;
+	}
+
+	while (s->input_begin != s->input_end 
+	   && (s->input_depth > 0 || !isalnum((int)*s->input_begin))) {
+		const char ch = *s->input_begin++;
+		if ('(' == ch)
+			++s->input_depth;
+		if (')' == ch && s->input_depth > 0)
+			--s->input_depth;
+	}
+
+	while (s->input_begin != s->input_end
+	   &&  s->buffer_end != &s->buffer[sizeof s->buffer]
+           &&  isalnum((int)*s->input_begin)) {
+		if (s->buffer == s->buffer_end
+		|| !isdigit((int)s->buffer_end[-1]) || !isalpha((int)*s->input_begin))
+			*s->buffer_end++ = *s->input_begin;
+		++s->input_begin;
+	}
+
+	if (pos != s->buffer_end 
+	&&  s->buffer_end != &s->buffer[sizeof s->buffer])
+		*s->buffer_end++ = ' ';
+	return s->buffer_end;
+}
+
+
+
+
+
+static const char *next_word(struct state *s,const char *pos) {
+	const char * const next = input_word(s,pos);
+	const char * const save = s->next;
+	assert(pos >= s->buffer && pos <= s->buffer_next);
+	if (pos != s->buffer_next || next == pos) return next;
+
+	s->next = pos;
+	s->buffer_next = s->buffer + (next - s->buffer);
+	if (get_name_at(s,'A',NULL,s->buffer_next)) {
+		s->buffer_next = s->buffer + (pos - s->buffer);
+		s->next = save;
+		return next_word(s,pos);
+		/* NOTE! make sure aliases do not form a cycle */
+	}
+
+	s->next = save;
+	return next;
+}
+
+
+
+
+
+static int get_name(struct state *s,char type,int (*f)(struct state *)) {
+	const char * const next = next_word(s,s->next);
+	if (s->next == next) return 0;
+	return get_name_at(s,type,f,next);
+}
+
+
+
+
+
+static int get_zip(struct state *s) {
+	const char * const next = next_word(s,s->next);
+	int zip,zip_offset;
+
+	if (s->next == next) return 0;
+	zip = io_strntoi(s->next,next - s->next);
+	if (zip <= 0 || zip >= 100000
+	||  io_in_i4(s->index,0,&zip_offset) < 0)
+		return 0;
+
+	s->range[s->range_count].begin = zip_offset + 4 * zip;
+	s->range[s->range_count].end = zip_offset + 4 * zip + 8;
+	++s->range_count;
+D(printf(">>> %d\n",zip));
+	if (is_valid(s)) {
+		if (NULL != s->out) s->out->zip_code = zip;
+		return 1;
+	}
+D(printf("<<< %d\n",zip));
+	--s->range_count;
+	return 0;
+}
+
+
+
+
+
+static int optional_zip(struct state *s) {
+	return get_zip(s) || is_valid(s);
+}
+
+
+
+
+
+static int get_state(struct state *s) {
+	return get_name(s,'S',optional_zip) || optional_zip(s);
+}
+
+
+
+
+
+static int get_city(struct state *s) {
+	return get_name(s,'C',get_state) || get_zip(s);
+}
+
+
+
+
+
+static int skip_stuff(struct state *s) {
+	const char * const begin = s->next;
+	int skipped;
+	for (skipped = 0; skipped < 7; ++skipped)
+		if (get_city(s)) {
+			s->next = begin;
+			return 1;
+		}
+		else {
+			const char * const next = next_word(s,s->next);
+			if (next == s->next) break;
+			s->next = next;
+		}
+
+	s->next = begin;
+	return 0;
+}
+
+
+
+
+
+static int get_street(struct state *s) {
+	return get_name(s,(s->address % 2) ? 'O' : 'E',skip_stuff);
+}
+
+
+
+
+
+static int get_address(struct state *s) {
+    const char * const begin = s->next;
+    const char * const next = next_word(s,begin);
+
+
+//fprintf(stderr,"get_address\n");
+
+    if (begin == next) {
+        return 0;
+    }
+
+    s->address = io_strntoi(begin,next - s->next);
+    if (0 == s->address) {
+        return 0;
+    }
+
+    s->next = next;
+    if (get_street(s)) {
+        s->next = begin;
+        return 1;
+    }
+
+    s->next = next_word(s,s->next);
+    if (get_street(s)) {
+        s->next = begin;
+        return 1;
+    }
+
+    s->next = next_word(s,s->next);
+    if (get_street(s)) {
+        s->next = begin;
+        return 1;
+    }
+
+    s->next = begin;
+
+    return 0;
+}
+
+
+
+
+
+int geo_find( struct io_file *index,
+              const char *str,
+              int len,
+    	      struct geo_location *out) {
+
+    struct state s;
+
+
+    if (NULL == index) return 0;
+
+    s.index = index;
+    s.input_depth = 0;
+    s.input_begin = str;
+    s.input_end = str + len;
+    s.next = s.buffer_end = s.buffer_next = s.buffer;
+    s.address = s.range_count = 0;
+
+    if (NULL != (s.out = out)) {
+        out->zip_code = 0;
+        out->street_name[0] = '\0';
+        out->city_name[0] = '\0';
+        out->state_name[0] = '\0';
+    }
+    return get_address(&s);
+}
+
+
diff --git a/src/geo.h b/src/geo.h
new file mode 100644
index 0000000..310a99f
--- /dev/null
+++ b/src/geo.h
@@ -0,0 +1,49 @@
+
+// $Id: geo.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+
+
+/* Copyright 2002 Daniel Egnor.  See LICENSE.geocoder file.
+ * Portions Copyright (C) 2004-2012  The Xastir Group
+ *
+ * The geo_find() function is the query interface for turning addressees
+ * into geographical locations using an 'address map' built from TIGER/Line
+ * and FIPS-55 data by the geo-*-to-* programs. */
+
+#ifndef GEOCODER_GEO_H
+#define GEOCODER_GEO_H
+
+#include "io.h"
+
+extern long destination_coord_lat;
+extern long destination_coord_lon;
+extern int mark_destination;
+extern int show_destination_mark;
+
+extern char geocoder_map_filename[400];
+
+
+struct geo_corner {
+	int address;
+	double latitude,longitude;
+};
+
+/* Decoded address location. */
+struct geo_location {
+	/* "Before" and "after" are the previous and next "control point"; 
+         * these are the known locations, "at" is the interpolated point
+	 * corresponding to the supplied address. */
+	struct geo_corner before,after,at;
+	int zip_code; /* 0 if none found in address */
+	char side;    /* 'L' or 'R' */
+        char street_name[41],city_name[41],state_name[41];
+                      /* Empty if none found in address */
+};
+
+/* Arguments: m = Address map file to use
+ *            a = Address string to parse
+ *            len = Length of address string (in characters)
+ *            out = Address of location to output
+ * Returns: Nonzero iff an address was recognized and decoded. */
+int geo_find(struct io_file *m,const char *a,int len,struct geo_location *out);
+
+#endif
diff --git a/src/geocoder_gui.c b/src/geocoder_gui.c
new file mode 100644
index 0000000..78d3e86
--- /dev/null
+++ b/src/geocoder_gui.c
@@ -0,0 +1,572 @@
+/*
+ * $Id: geocoder_gui.c,v 1.27 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <Xm/XmAll.h>
+#ifdef HAVE_XBAE_MATRIX_H
+#include <Xbae/Matrix.h>
+#endif  // HAVE_XBAE_MATRIX_H
+
+
+#include "xastir.h"
+#include "main.h"
+#include "lang.h"
+//#include "maps.h"
+#include "io.h"
+#include "geo.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+Widget geocoder_place_dialog = (Widget)NULL;
+Widget geocoder_zip_data = (Widget)NULL;
+Widget geocoder_state_data = (Widget)NULL;
+Widget geocoder_locality_data = (Widget)NULL;
+Widget geocoder_address_data = (Widget)NULL;
+Widget geocoder_map_file_data = (Widget)NULL;
+char geocoder_zip_name[50];
+char geocoder_state_name[50];
+char geocoder_locality_name[255];
+char geocoder_address_name[255];
+char geocoder_map_filename[400];
+static xastir_mutex geocoder_place_dialog_lock;
+
+long destination_coord_lat = 0;
+long destination_coord_lon = 0;
+int mark_destination = 0;
+int show_destination_mark = 0;
+
+
+
+
+
+void geocoder_gui_init(void)
+{
+    init_critical_section( &geocoder_place_dialog_lock );
+    geocoder_zip_name[0] = '\0';
+    geocoder_state_name[0] = '\0';
+    geocoder_locality_name[0] = '\0';
+    geocoder_address_name[0] = '\0';
+}
+
+
+
+
+
+/**** GEOCODER FIND PLACE ******/
+
+void Geocoder_place_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    geocoder_place_dialog = (Widget)NULL;
+
+end_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place_destroy_shell" );
+
+}
+
+
+
+
+
+/*
+ *  Geocoder a place by centering the map at its position
+ */
+void Geocoder_place_now(Widget w, XtPointer clientData, XtPointer callData) {
+    struct io_file *index;
+    struct geo_location loc;
+    char input[1024];
+    char *temp_ptr;
+
+
+    /* find place and go there */
+    temp_ptr = XmTextFieldGetString(geocoder_zip_data);
+    xastir_snprintf(geocoder_zip_name,
+        sizeof(geocoder_zip_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(geocoder_state_data);
+    xastir_snprintf(geocoder_state_name,
+        sizeof(geocoder_state_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(geocoder_locality_data);
+    xastir_snprintf(geocoder_locality_name,
+        sizeof(geocoder_locality_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(geocoder_address_data);
+    xastir_snprintf(geocoder_address_name,
+        sizeof(geocoder_address_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(geocoder_map_file_data);
+    xastir_snprintf(geocoder_map_filename,
+        sizeof(geocoder_map_filename),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(geocoder_zip_name);
+    (void)remove_trailing_spaces(geocoder_state_name);
+    (void)remove_trailing_spaces(geocoder_locality_name);
+    (void)remove_trailing_spaces(geocoder_address_name);
+
+/*
+fprintf(stderr,"%s\n%s\n%s\n%s\n%s\n",
+    geocoder_zip_name,
+    geocoder_state_name,
+    geocoder_locality_name,
+    geocoder_address_name,
+    geocoder_map_filename);
+*/
+
+    index = io_open(geocoder_map_filename);
+
+    xastir_snprintf(input,
+        sizeof(input),
+        "%s %s%s%s %s",
+        geocoder_address_name,
+        geocoder_locality_name,
+        (strlen(geocoder_state_name) != 0)?",":"",
+        geocoder_state_name,
+        geocoder_zip_name);
+
+    if (debug_level & 1)
+        fprintf(stderr,"Searching for: %s\n", input);
+
+    if (geo_find(index,input,strlen(input),&loc)) {
+        long coord_lon, coord_lat;
+        char lat_str[20];
+        char long_str[20];
+        int lon, lat, lons, lats, tmp1;
+        char lond = 'E';
+        char latd = 'N';
+        double res, tmp;
+
+
+        if (loc.at.longitude < 0) {
+            loc.at.longitude = -loc.at.longitude;
+            lond = 'W';
+        }
+        if (loc.at.latitude < 0) {
+            loc.at.latitude = -loc.at.latitude;
+            latd = 'S';
+        }
+
+        lon = loc.at.longitude;
+        lat = loc.at.latitude;
+
+        res = loc.at.longitude - lon;
+        tmp = (res * 100); 
+        tmp = tmp * 60 / 100;
+        tmp1 = tmp;
+        lon = (lon * 100) + tmp1;
+        lons = (tmp - tmp1) * 100;
+
+        res = loc.at.latitude - lat;
+        tmp = (res * 100); 
+        tmp = tmp * 60 / 100;
+        tmp1 = tmp;
+        lat = (lat * 100) + tmp1;
+        lats = (tmp - tmp1) * 100;
+
+        xastir_snprintf(lat_str,
+            sizeof(lat_str),
+            "%d.%02d%c",
+            lat,
+            lats,
+            latd);
+
+        coord_lat = convert_lat_s2l(lat_str);
+
+        xastir_snprintf(long_str,
+            sizeof(long_str),
+            "%s%d.%02d%c",
+            (lon < 10000)?"0":"",
+            lon,
+            lons,
+            lond);
+
+        coord_lon = convert_lon_s2l(long_str);
+
+        destination_coord_lat = coord_lat;
+        destination_coord_lon = coord_lon;
+        mark_destination = 1;
+
+        popup_message_always( langcode("POPEM00029"), geocoder_address_name );
+        set_map_position(w, coord_lat, coord_lon);
+    }
+    else {
+        popup_message_always(langcode("POPEM00025"),geocoder_address_name);
+    }
+    Geocoder_place_destroy_shell(w, clientData, callData);
+}
+
+
+
+
+
+void  Show_dest_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        show_destination_mark = atoi(which);
+    }
+    else {
+        show_destination_mark = 0;
+    }
+}
+
+
+
+
+
+void Geocoder_place(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget pane, form, button_ok, button_cancel, sep,
+        zip, state, locality, address, map_file, show_dest_toggle;
+    Atom delw;
+
+    if (!geocoder_place_dialog) {
+
+begin_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place" );
+
+        // Find Address
+        geocoder_place_dialog = XtVaCreatePopupShell(langcode("PULDNMP029"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Geocoder_place pane",xmPanedWindowWidgetClass, geocoder_place_dialog,
+                XmNbackground, colors[0xff],
+                NULL);
+
+        form =  XtVaCreateWidget("Geocoder_place form",xmFormWidgetClass, pane,
+                XmNfractionBase, 2,
+                XmNbackground, colors[0xff],
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                NULL);
+
+        // Address:
+        address = XtVaCreateManagedWidget(langcode("FEATURE007"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        geocoder_address_data = XtVaCreateManagedWidget("Geocoder_address_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 32,
+                XmNwidth, ((32*7)+2),
+                XmNmaxLength, 254,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, address,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // City:
+        locality = XtVaCreateManagedWidget(langcode("FEATURE008"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, address,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        geocoder_locality_data = XtVaCreateManagedWidget("Geocoder_address_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 32,
+                XmNwidth, ((32*7)+2),
+                XmNmaxLength, 254,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, address,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, locality,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // State/Province:
+        state = XtVaCreateManagedWidget(langcode("FEATURE002"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, locality,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        geocoder_state_data = XtVaCreateManagedWidget("Geocoder_state_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 4,
+                XmNwidth, ((4*7)+2),
+                XmNmaxLength, 2,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, locality,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, state,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Mark Destination
+        show_dest_toggle = XtVaCreateManagedWidget(langcode("FEATURE009"),xmToggleButtonGadgetClass, form,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, locality,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, geocoder_state_data,
+                XmNleftOffset, 20,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(show_dest_toggle,XmNvalueChangedCallback,Show_dest_toggle,"1");
+        if (show_destination_mark)
+            XmToggleButtonSetState(show_dest_toggle,TRUE,FALSE);
+
+
+        // Zip Code:
+        zip = XtVaCreateManagedWidget(langcode("FEATURE010"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, state,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        geocoder_zip_data = XtVaCreateManagedWidget("Geocoder_zip_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 12,
+                XmNwidth, ((12*7)+2),
+                XmNmaxLength, 10,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, state,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, zip,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Geocoding File:
+        map_file = XtVaCreateManagedWidget(langcode("FEATURE011"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zip,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        geocoder_map_file_data = XtVaCreateManagedWidget("geocoder_map_file_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 40,
+                XmNwidth, ((40*7)+2),
+                XmNmaxLength, 254,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, zip,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, map_file,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        sep = XtVaCreateManagedWidget("Geocoder_place sep", xmSeparatorGadgetClass,form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,geocoder_map_file_data,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("WPUPLSP005"),xmPushButtonGadgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNbackground, colors[0xff],
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 5,
+                XmNbackground, colors[0xff],
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Geocoder_place_now, geocoder_place_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Geocoder_place_destroy_shell, geocoder_place_dialog);
+
+        XmTextFieldSetString(geocoder_zip_data,geocoder_zip_name);
+        XmTextFieldSetString(geocoder_state_data,geocoder_state_name);
+        XmTextFieldSetString(geocoder_locality_data,geocoder_locality_name);
+        XmTextFieldSetString(geocoder_address_data,geocoder_address_name);
+        XmTextFieldSetString(geocoder_map_file_data,geocoder_map_filename);
+
+        pos_dialog(geocoder_place_dialog);
+
+        delw = XmInternAtom(XtDisplay(geocoder_place_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(geocoder_place_dialog, delw, Geocoder_place_destroy_shell, (XtPointer)geocoder_place_dialog);
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+end_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place" );
+
+        XtPopup(geocoder_place_dialog,XtGrabNone);
+        fix_dialog_size(geocoder_place_dialog);
+
+        XmProcessTraversal(button_ok, XmTRAVERSE_CURRENT);
+
+    } else {
+        (void)XRaiseWindow(XtDisplay(geocoder_place_dialog), XtWindow(geocoder_place_dialog));
+    }
+}
+
+
diff --git a/src/gps.c b/src/gps.c
new file mode 100644
index 0000000..edc6cb2
--- /dev/null
+++ b/src/gps.c
@@ -0,0 +1,874 @@
+/*
+ * $Id: gps.c,v 1.57 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <Xm/XmAll.h>
+
+// The following files support setting the system time from the GPS
+#if TIME_WITH_SYS_TIME
+  // Define needed by some versions of Linux in order to define
+  // strptime()
+#ifndef __USE_XOPEN
+# define __USE_XOPEN
+#endif
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "gps.h"
+#include "main.h"
+#include "interface.h"
+#include "lang.h"
+#include "util.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+char gps_gprmc[MAX_GPS_STRING+1];
+char gps_gpgga[MAX_GPS_STRING+1];
+char gps_sats[4] = "";
+char gps_alt[8] = "";
+char gps_spd[10] = "";
+char gps_sunit[2] = "";
+char gps_cse[10] = "";
+int  gps_valid = 0; // 0=invalid, 1=valid, 2=2D Fix, 3=3D Fix
+ 
+int gps_stop_now;
+
+
+
+
+
+// This function is destructive to its first parameter
+//
+// GPRMC,UTC-Time,status(A/V),lat,N/S,lon,E/W,SOG,COG,UTC-Date,Mag-Var,E/W[*CHK]
+// GPRMC,hhmmss[.sss],{A|V},ddmm.mm[mm],{N|S},dddmm.mm[mm],{E|W},[dd]d.d[ddddd],[dd]d.d[d],ddmmyy,[ddd.d],[{E|W}][,A|D|E|N|S][*CHK]
+//
+// The last field before the checksum is entirely optional, and in
+// fact first appeared in NMEA 2.3 (fairly recently).  Most GPS's do
+// not currently put out that field.  The field may be null or
+// nonexistent including the comma.  Only "A" or "D" are considered
+// to be active and reliable fixes if this field is present.
+// Fix-Quality:
+//  A: Autonomous
+//  D: Differential
+//  E: Estimated
+//  N: Not Valid
+//  S: Simulator
+//
+// $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
+// $GPRMC,104748.821,A,4301.1492,N,08803.0374,W,0.085048,102.36,010605,,*1A
+// $GPRMC,104749.821,A,4301.1492,N,08803.0377,W,0.054215,74.60,010605,,*2D
+//
+int decode_gps_rmc( char *data,
+                    char *long_pos,
+                    int long_pos_length,
+                    char *lat_pos,
+                    int lat_pos_length,
+                    char *spd,
+                    char *unit,
+                    int unit_length,
+                    char *cse,
+                    time_t *stim,
+                    int *status) {
+
+    char *temp_ptr;
+    char *temp_ptr2;
+    char temp_data[MAX_LINE_SIZE+1];    // Big in case we get concatenated packets (it happens!)
+    char sampletime[7]; // We ignore fractional seconds
+    char long_pos_x[11];
+    char long_ew;
+    char lat_pos_y[10];
+    char lat_ns;
+    char speed[10];
+    char speed_unit;
+    char course[8];
+    char sampledate[7];
+
+#ifdef HAVE_STRPTIME
+    char sampledatime[15];
+    char *tzp;
+    char tzn[512];
+    struct tm stm;
+#endif // HAVE_STRPTIME
+ 
+
+// We should check for a minimum line length before parsing,
+// and check for end of input while tokenizing.
+
+    if ( (data == NULL) || (strlen(data) < 37) )
+        return(0);  // Not enough data to parse position from.
+
+    if (strncmp(data,"$GPRMC,",7) != 0)   // No GPRMC found
+        return(0);
+
+    if(strchr(data,',') == NULL)  // No comma found
+        return(0);
+
+    (void)strtok(data,",");   // get GPRMC and skip it
+    temp_ptr=strtok(NULL,",");   // get time
+
+    if (temp_ptr == NULL)   // No comma found
+        return(0);
+
+    xastir_snprintf(sampletime,
+        sizeof(sampletime),
+        "%s",
+        temp_ptr);
+
+    temp_ptr=strtok(NULL,",");  // get fix status
+
+    if (temp_ptr == NULL) // No comma found
+        return(0);
+
+    if (temp_ptr[0] == 'A')
+        *status = 1;
+    else
+        *status = 0;
+
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[2] = '\0';
+
+    if (temp_data[0] != 'A')  // V is a warning but we can get good data still ?
+        return(0);  // Didn't find 'A' in the proper spot
+
+    temp_ptr=strtok(NULL,",");  // get latitude
+
+    if (temp_ptr == NULL)
+        return(0);  // Doesn't look like latitude
+
+    // Newer GPS'es appear not to zero-fill on the left.  Check for
+    // the decimal point in all the possible places.
+    if (temp_ptr[1] != '.'
+            && temp_ptr[2] != '.'
+            && temp_ptr[3] != '.'
+            && temp_ptr[4] != '.') {
+        return(0);  // Doesn't look like latitude
+    }
+
+// Note:  Starlink Invicta shows "lllll.ll" format for latitude in
+// the GPRMC sentence, which would mean we'd need another term in
+// the above, and would need to terminate at [10] below (making sure
+// we extended the field another char as well to handle it).  I'm
+// hoping it was a typo in the Starlink Invicta spec, as latitude
+// never requires three digits for degrees.
+
+    xastir_snprintf(lat_pos_y,
+        sizeof(lat_pos_y),
+        "%s",
+        temp_ptr);
+    lat_pos_y[9] = '\0';
+
+// Note that some GPS's put out latitude with extra precision, such as 4801.1234
+
+    // Check for comma char, replace with '\0'
+    temp_ptr2 = strstr(lat_pos_y, ",");
+    if (temp_ptr2)
+        temp_ptr2[0] = '\0';
+
+    temp_ptr=strtok(NULL,",");  // get N-S
+
+    if (temp_ptr == NULL)   // No comma found
+        return(0);
+
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[1] = '\0';
+
+    lat_ns=toupper((int)temp_data[0]);
+
+    if(lat_ns != 'N' && lat_ns != 'S')
+        return(0);  // Doesn't look like latitude
+
+    temp_ptr=strtok(NULL,",");  // get long
+
+    if (temp_ptr == NULL)
+        return(0);  // Doesn't look like longitude
+
+    // Newer GPS'es appear not to zero-fill on the left.  Check for
+    // the decimal point in all the possible places.
+    if (temp_ptr[1] != '.'
+            && temp_ptr[2] != '.'
+            && temp_ptr[3] != '.'
+            && temp_ptr[4] != '.'
+            && temp_ptr[5] != '.') {
+        return(0);  // Doesn't look like longitude
+    }
+
+
+    xastir_snprintf(long_pos_x,
+        sizeof(long_pos_x),
+        "%s",
+        temp_ptr);
+    long_pos_x[10] = '\0';
+
+// Note that some GPS's put out longitude with extra precision, such as 12201.1234
+
+    // Check for comma char, replace with '\0'
+    temp_ptr2 = strstr(long_pos_x, ",");
+    if (temp_ptr2)
+        temp_ptr2[0] = '\0';
+
+    temp_ptr=strtok(NULL,",");  // get E-W
+
+    if (temp_ptr == NULL)   // No comma found
+        return(0);
+
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[1] = '\0';
+
+    long_ew=toupper((int)temp_data[0]);
+
+    if (long_ew != 'E' && long_ew != 'W')
+        return(0);  // Doesn't look like longitude
+
+    temp_ptr=strtok(NULL,",");  // Get speed
+
+    if (temp_ptr == 0)  // No comma found
+        return(0);
+
+    xastir_snprintf(speed,
+        sizeof(speed),
+        "%s",
+        temp_ptr);
+    speed[9] = '\0';
+
+    speed_unit='K';
+    temp_ptr=strtok(NULL,",");  // Get course
+
+    if (temp_ptr == NULL)   // No comma found
+        return(0);
+
+    xastir_snprintf(course,
+        sizeof(course),
+        "%s",
+        temp_ptr);
+    course[7] = '\0';
+
+    temp_ptr=strtok(NULL,",");   // get date of fix
+
+    if (temp_ptr == NULL)   // No comma found
+        return(0);
+
+    xastir_snprintf(sampledate,
+        sizeof(sampledate),
+        "%s",
+        temp_ptr);
+    sampledate[6] = '\0';
+
+
+    // Data is good
+    xastir_snprintf(long_pos, long_pos_length, "%s%c", long_pos_x,long_ew);
+    xastir_snprintf(lat_pos, lat_pos_length, "%s%c", lat_pos_y, lat_ns);
+    xastir_snprintf(spd, 10, "%s", speed);
+    xastir_snprintf(unit, unit_length, "%c", speed_unit);
+    xastir_snprintf(cse, 10, "%s", course);
+
+#ifdef HAVE_STRPTIME
+    // Translate date/time into time_t GPS time is in UTC.  First,
+    // save existing TZ Then set conversion to UTC, then set back to
+    // existing TZ.
+    tzp=getenv("TZ");
+    if ( tzp == NULL ) {
+        tzp = "";
+    }
+    xastir_snprintf(tzn,
+        sizeof(tzn),
+        "TZ=%s",
+        tzp);
+    putenv("TZ=UTC");
+    tzset();
+    xastir_snprintf(sampledatime,
+        sizeof(sampledatime),
+        "%s%s",
+        sampledate,
+        sampletime);
+    (void)strptime(sampledatime, "%d%m%y%H%M%S", &stm);
+    *stim=mktime(&stm);
+    putenv(tzn);
+    tzset();
+#endif  // HAVE_STRPTIME
+
+    //fprintf(stderr,"Speed %s\n",spd);
+    return(1);
+}
+
+
+
+
+
+// This function is destructive to its first parameter
+//
+// GPGGA,UTC-Time,lat,N/S,long,E/W,GPS-Quality,nsat,HDOP,MSL-Meters,M,Geoidal-Meters,M,DGPS-Data-Age(seconds),DGPS-Ref-Station-ID[*CHK]
+// GPGGA,hhmmss[.sss],ddmm.mm[mm],{N|S},dddmm.mm[mm],{E|W},{0-8},dd,[d]d.d,[-dddd]d.d,M,[-ddd]d.d,M,[dddd.d],[dddd][*CHK]
+//
+// GPS-Quality:
+//  0: Invalid Fix
+//  1: GPS Fix
+//  2: DGPS Fix
+//  3: PPS Fix
+//  4: RTK Fix
+//  5: Float RTK Fix
+//  6: Estimated (dead-reckoning) Fix
+//  7: Manual Input Mode
+//  8: Simulation Mode
+//
+// $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75 
+// $GPGGA,104438.833,4301.1439,N,08803.0338,W,1,05,1.8,185.8,M,-34.2,M,0.0,0000*40
+//
+int decode_gps_gga( char *data,
+                    char *long_pos,
+                    int long_pos_length,
+                    char *lat_pos,
+                    int lat_pos_length,
+                    char *sats,
+                    char *alt,
+                    char *aunit,
+                    int *status ) {
+
+    char *temp_ptr;
+    char *temp_ptr2;
+    char temp_data[MAX_LINE_SIZE+1];    // Big in case we get concatenated packets (it happens!)
+    char long_pos_x[11];
+    char long_ew;
+    char lat_pos_y[10];
+    char lat_ns;
+    char sats_visible[4];
+    char altitude[8];
+    char alt_unit;
+
+
+// We should check for a minimum line length before parsing,
+// and check for end of input while tokenizing.
+
+
+    if ( (data == NULL) || (strlen(data) < 35) )  // Not enough data to parse position from.
+        return(0);
+
+    if (strncmp(data,"$GPGGA,",7) != 0)
+        return(0);
+
+    if (strchr(data,',') == NULL)
+        return(0);
+
+    if (strtok(data,",") == NULL) // get GPGGA and skip it
+        return(0);
+
+    if(strtok(NULL,",") == NULL)    // get time and skip it
+        return(0);
+
+    temp_ptr = strtok(NULL,",");    // get latitude
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    xastir_snprintf(lat_pos_y,
+        sizeof(lat_pos_y),
+        "%s",
+        temp_ptr);
+    lat_pos_y[9] = '\0';
+
+// Note that some GPS's put out latitude with extra precision, such as 4801.1234
+
+    // Check for comma char, replace with '\0'
+    temp_ptr2 = strstr(lat_pos_y, ",");
+    if (temp_ptr2)
+        temp_ptr2[0] = '\0';
+
+    temp_ptr = strtok(NULL,",");    // get N-S
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[1] = '\0';
+
+    lat_ns=toupper((int)temp_data[0]);
+
+    if(lat_ns != 'N' && lat_ns != 'S')
+        return(0);
+
+    temp_ptr = strtok(NULL,",");    // get long
+
+    if(temp_ptr == NULL)
+        return(0);
+
+    xastir_snprintf(long_pos_x,
+        sizeof(long_pos_x),
+        "%s",
+        temp_ptr);
+    long_pos_x[10] = '\0';
+
+// Note that some GPS's put out longitude with extra precision, such as 12201.1234
+
+    // Check for comma char, replace with '\0'
+    temp_ptr2 = strstr(long_pos_x, ",");
+    if (temp_ptr2)
+        temp_ptr2[0] = '\0';
+
+    temp_ptr = strtok(NULL,",");    // get E-W
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[1] = '\0';
+
+    long_ew=toupper((int)temp_data[0]);
+
+    if (long_ew != 'E' && long_ew != 'W')
+        return(0);
+
+    temp_ptr = strtok(NULL,",");    // get FIX Quality
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[1] = '\0';
+
+    // '0' = bad fix, positive numbers = ok
+    if(temp_data[0] == '0')
+        return(0);
+
+    // Save the fix quality in "status"
+    *status = atoi(temp_data);
+
+    temp_ptr=strtok(NULL,",");      // Get sats vis
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    xastir_snprintf(sats_visible,
+        sizeof(sats_visible),
+        "%s",
+        temp_ptr);
+    sats_visible[2] = '\0';
+
+    temp_ptr=strtok(NULL,",");      // get hoz dil
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    temp_ptr=strtok(NULL,",");      // Get altitude
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    // Get altitude
+    xastir_snprintf(altitude,
+        sizeof(altitude),
+        "%s",
+        temp_ptr);
+    altitude[7] = '\0';
+
+    temp_ptr=strtok(NULL,",");      // get UNIT
+
+    if (temp_ptr == NULL)
+        return(0);
+
+    // get UNIT
+    xastir_snprintf(temp_data,
+        sizeof(temp_data),
+        "%s",
+        temp_ptr);
+    temp_data[1] = '\0';
+
+    alt_unit=temp_data[0];
+
+    // Data is good
+    xastir_snprintf(long_pos, long_pos_length, "%s%c", long_pos_x, long_ew);
+    xastir_snprintf(lat_pos, lat_pos_length, "%s%c", lat_pos_y, lat_ns);
+    xastir_snprintf(sats, 4, "%s", sats_visible);
+    xastir_snprintf(alt, 8, "%s", altitude);
+    xastir_snprintf(aunit, 2, "%c", alt_unit);
+
+    return(1);
+}
+
+
+
+
+
+//
+// Note that the length of "gps_line_data" can be up to
+// MAX_DEVICE_BUFFER, which is currently set to 4096.
+//
+int gps_data_find(char *gps_line_data, int port) {
+
+    char long_pos[20],lat_pos[20],aunit[2];
+    time_t t;
+    char temp_str[MAX_GPS_STRING+1];
+    int have_valid_string = 0;
+#ifndef __CYGWIN__
+    struct timeval tv;
+    struct timezone tz;
+#endif  // __CYGWIN__
+ 
+
+
+    if (strncmp(gps_line_data,"$GPRMC,",7)==0) {
+
+        if (debug_level & 128) {
+            char filtered_data[MAX_LINE_SIZE+1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                gps_line_data);
+            
+            makePrintable(filtered_data);
+            fprintf(stderr,"Got RMC %s\n", filtered_data);
+        }
+
+        if (debug_level & 128) {
+            // Got GPS RMC String
+            statusline(langcode("BBARSTA015"),0);
+        }
+
+        xastir_snprintf(gps_gprmc,
+            sizeof(gps_gprmc),
+            "%s",
+            gps_line_data);
+
+        xastir_snprintf(temp_str, sizeof(temp_str), "%s", gps_gprmc);
+        // decode_gps_rmc is destructive to its first parameter
+        if (decode_gps_rmc( temp_str,
+                            long_pos,
+                            sizeof(long_pos),
+                            lat_pos,
+                            sizeof(lat_pos),
+                            gps_spd,
+                            gps_sunit,
+                            sizeof(gps_sunit),
+                            gps_cse,
+                            &t,
+                            &gps_valid ) == 1) {    // mod station data
+            // got GPS data
+            have_valid_string++;
+            if (debug_level & 128)
+                fprintf(stderr,"RMC <%s> <%s><%s> %c <%s>\n",
+                    long_pos,lat_pos,gps_spd,gps_sunit[0],gps_cse);
+
+            if (debug_level & 128) {
+                fprintf(stderr,"Checking for Time Set on %d (%d)\n",
+                    port, devices[port].set_time);
+            }
+
+// Don't set the time if it's a Cygwin system.  Causes problems with
+// date, plus time can be an hour off if daylight savings time is
+// enabled on Windows.
+//
+#ifndef __CYGWIN__
+            if (devices[port].set_time) {
+                tv.tv_sec=t;
+                tv.tv_usec=0;
+                tz.tz_minuteswest=0;
+                tz.tz_dsttime=0;
+
+                if (debug_level & 128) {
+                    fprintf(stderr,"Setting Time %ld EUID: %d, RUID: %d\n",
+                        (long)t, (int)getuid(), (int)getuid());
+                }
+
+#ifdef HAVE_SETTIMEOFDAY
+
+ENABLE_SETUID_PRIVILEGE;
+                settimeofday(&tv, &tz);
+DISABLE_SETUID_PRIVILEGE;
+
+#endif  // HAVE_SETTIMEOFDAY
+
+            }
+
+#endif  // __CYGWIN__
+
+        }
+    }
+    else {
+        if (debug_level & 128) {
+            int i;
+            fprintf(stderr,"Not $GPRMC: ");
+            for (i = 0; i<7; i++)
+                fprintf(stderr,"%c", gps_line_data[i]);
+            fprintf(stderr,"\n");
+        }
+    }
+
+    if (strncmp(gps_line_data,"$GPGGA,",7)==0) {
+
+        if (debug_level & 128) {
+            char filtered_data[MAX_LINE_SIZE+1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                gps_line_data);
+
+            makePrintable(filtered_data);
+            fprintf(stderr,"Got GGA %s\n", filtered_data);
+        }
+
+        if (debug_level & 128) {
+            // Got GPS GGA String
+            statusline(langcode("BBARSTA016"),0);
+        }
+
+        xastir_snprintf(gps_gpgga,
+            sizeof(gps_gpgga),
+            "%s",
+            gps_line_data);
+
+        xastir_snprintf(temp_str, sizeof(temp_str), "%s", gps_gpgga);
+
+        // decode_gps_gga is destructive to its first parameter
+        if ( decode_gps_gga( temp_str,
+                             long_pos,
+                             sizeof(long_pos),
+                             lat_pos,
+                             sizeof(lat_pos),
+                             gps_sats,
+                             gps_alt,
+                             aunit,
+                             &gps_valid ) == 1) { // mod station data
+            // got GPS data
+            have_valid_string++;
+            if (debug_level & 128)
+                fprintf(stderr,"GGA <%s> <%s> <%s> <%s> %c\n",
+                    long_pos,lat_pos,gps_sats,gps_alt,aunit[0]);
+        }
+    }
+    else {
+        if (debug_level & 128) {
+            int i;
+            fprintf(stderr,"Not $GPGGA: ");
+            for (i = 0; i<7; i++)
+                fprintf(stderr,"%c",gps_line_data[i]);
+            fprintf(stderr,"\n");
+        }
+    }
+
+
+    if (have_valid_string) {
+
+        if (debug_level & 128) {
+            statusline(langcode("BBARSTA037"),0);
+        }
+
+        // Go update my screen position
+        my_station_gps_change(long_pos,lat_pos,gps_cse,gps_spd,
+            gps_sunit[0],gps_alt,gps_sats);
+
+        // gps_stop_now is how we tell main.c that we've got a valid GPS string.
+        // Only useful for HSP mode?
+        if (!gps_stop_now)
+            gps_stop_now=1;
+
+        // If HSP port, shutdown gps for timed interval
+        if (port_data[port].device_type == DEVICE_SERIAL_TNC_HSP_GPS) {
+            // return dtr to normal
+            port_dtr(port,0);
+        }
+    }
+    return(have_valid_string);
+}
+
+
+
+
+
+static char checksum[3];
+
+
+
+
+ 
+// Function to compute checksums for NMEA sentences
+//
+// Input: "$............*"
+// Output: Two character string containing the checksum
+//
+// Checksum is computed from the '$' to the '*', but not including
+// these two characters.  It is an 8-bit Xor of the characters
+// specified, encoded in hexadecimal format.
+//
+char *nmea_checksum(char *nmea_sentence) {
+    int i;
+    int sum = 0;
+    int right;
+    int left;
+    char convert[17] = "0123456789ABCDEF";
+
+
+    for (i = 1; i < ((int)strlen(nmea_sentence) - 1); i++) {
+        sum = sum ^ nmea_sentence[i];
+    }
+  
+    right = sum % 16;
+    left = (sum / 16) % 16;
+
+    xastir_snprintf(checksum, sizeof(checksum), "%c%c",
+        convert[left],
+        convert[right]);
+
+    return(checksum);
+}
+ 
+
+
+
+
+
+// Function which will send an NMEA sentence to a Garmin GPS which
+// will create a waypoint if the Garmin is set to NMEA-in/NMEA-out
+// mode.  The sentence looks like this:
+//
+// $GPWPL,4807.038,N,01131.000,E,WPTNME*31
+//
+// $GPWPL,4849.65,N,06428.53,W,0001*54
+// $GPWPL,4849.70,N,06428.50,W,0002*50
+//
+// 4807.038,N   Latitude
+// 01131.000,E  Longitude
+// WPTNME       Waypoint Name (stick to 6 chars for compatibility?)
+// *31          Checksum, always begins with '*'
+//
+//
+// Future implementation ideas:
+//
+// Create linked list of waypoints/location.
+// Use the list to prevent multiple writes of the same waypoint if
+// nothing has changed.
+//
+// Use the list to check distance of previously-written waypoints.
+// If we're out of range, delete the waypoint and remove it from the
+// list.
+//
+// Perhaps write the list to disk also.  As we shut down, delete the
+// waypoints (self-cleaning).  As we come up, load them in again?
+// We could also just continue cleaning out waypoints that are
+// out-of-range since the last time we ran the program.  That's
+// probably a better solution.
+//
+void create_garmin_waypoint(long latitude,long longitude,char *call_sign) {
+    char short_callsign[10];
+    char lat_string[15];
+    char long_string[15];
+    char lat_char;
+    char long_char;
+    int i,j,len;
+    char out_string[80];
+    char out_string2[80];
+
+
+    convert_lat_l2s(latitude,
+        lat_string,
+        sizeof(lat_string),
+        CONVERT_HP_NOSP);
+    lat_char = lat_string[strlen(lat_string) - 1];
+    lat_string[strlen(lat_string) - 1] = '\0';
+
+    convert_lon_l2s(longitude,
+        long_string,
+        sizeof(long_string),
+        CONVERT_HP_NOSP);
+    long_char = long_string[strlen(long_string) - 1];
+    long_string[strlen(long_string) - 1] = '\0';
+
+    len = strlen(call_sign);
+    if (len > 9)
+        len = 9;
+
+    j = 0;
+    for (i = 0; i <= len; i++) {    // Copy the '\0' as well
+        if (call_sign[i] != '-') {  // We don't want the dash
+            short_callsign[j++] = call_sign[i];
+        }
+    }
+    short_callsign[6] = '\0';   // Truncate at 6 chars
+
+    // Convert to upper case.  Garmin's don't seem to like lower
+    // case waypoint names
+    to_upper(short_callsign);
+
+    //fprintf(stderr,"Creating waypoint for %s:%s\n",call_sign,short_callsign);
+
+    xastir_snprintf(out_string, sizeof(out_string),
+        "$GPWPL,%s,%c,%s,%c,%s*",
+        lat_string,
+        lat_char,
+        long_string,
+        long_char,
+        short_callsign);
+
+    nmea_checksum(out_string);
+
+    xastir_snprintf(out_string2,
+        sizeof(out_string2),
+        "%s%s",
+        out_string,
+        checksum);
+
+    output_waypoint_data(out_string2);
+
+    //fprintf(stderr,"%s\n",out_string2);
+}
+
+
diff --git a/src/gps.h b/src/gps.h
new file mode 100644
index 0000000..bfbd550
--- /dev/null
+++ b/src/gps.h
@@ -0,0 +1,44 @@
+/*
+ * $Id: gps.h,v 1.16 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_GPS_H
+#define __XASTIR_GPS_H
+
+#include "xastir.h"
+
+#define MAX_GPS_STRING 300
+
+extern char gps_sats[4];
+extern int  gps_valid;
+
+extern int gps_stop_now;
+
+extern int gps_data_find(char *gps_line_data, int port);
+
+extern void create_garmin_waypoint(long latitude,long longitude,char *call_sign);
+
+#endif  // __XASTIR_GPS_H
+
+
diff --git a/src/hashtable.c b/src/hashtable.c
new file mode 100644
index 0000000..9244565
--- /dev/null
+++ b/src/hashtable.c
@@ -0,0 +1,277 @@
+
+
+// $Id: hashtable.c,v 1.12 2012/08/25 16:38:29 tvrusso Exp $
+
+
+/* Copyright (C) 2004 Christopher Clark <firstname.lastname at cl.cam.ac.uk> */
+/* Portions Copyright (C) 2004-2012  The Xastir Group */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+
+// Must be last include file
+#include "leak_detection.h" /* defines GC_MALLOC/GC_FREE */
+
+
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(struct entry *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
+    return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            freekey(e->k);
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f); }
+        }
+    }
+    free(h->table);
+    free(h);
+}
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname at cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+
diff --git a/src/hashtable.h b/src/hashtable.h
new file mode 100644
index 0000000..73abcfa
--- /dev/null
+++ b/src/hashtable.h
@@ -0,0 +1,194 @@
+
+
+// $Id: hashtable.h,v 1.8 2012/11/01 18:57:19 we7u Exp $
+
+
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname at cl.cam.ac.uk> */
+// Portions Copyright (C) 2004-2012  The Xastir Group
+
+
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname at cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+
diff --git a/src/hashtable_itr.c b/src/hashtable_itr.c
new file mode 100644
index 0000000..74a12a7
--- /dev/null
+++ b/src/hashtable_itr.c
@@ -0,0 +1,212 @@
+
+
+// $Id: hashtable_itr.c,v 1.14 2012/08/25 16:38:29 tvrusso Exp $
+
+
+/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname at cl.cam.ac.uk> */
+/* Portions Copyright (C) 2004-2012  The Xastir Group */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdlib.h> /* defines NULL */
+#include <stdio.h>
+//#include <string.h>
+//#include <math.h>
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_itr.h"
+
+// Must be last include file
+#include "leak_detection.h" /* defines GC_MALLOC/GC_FREE */
+
+
+
+
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+    unsigned int i, tablelength;
+    struct hashtable_itr *itr = (struct hashtable_itr *)
+        malloc(sizeof(struct hashtable_itr));
+    if (NULL == itr) return NULL;
+    itr->h = h;
+    itr->e = NULL;
+    itr->parent = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) return itr;
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+    return itr;
+}
+
+/*****************************************************************************/
+/* key      - return the key of the (key,value) pair at the current position */
+/* value    - return the value of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{ 
+    if (!i) 
+        return NULL;
+    if (i->e) 
+        return i->e->k;
+    else 
+        return NULL;
+}
+
+void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{ 
+    if (!i) 
+        return NULL;
+    if (i->e) {
+        return i->e->v;
+    } else {
+        return NULL;
+    }
+
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+    unsigned int j,tablelength;
+    struct entry **table;
+    struct entry *next;
+    if (NULL == itr->e) return 0; /* stupidity check */
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->parent = itr->e;
+        itr->e = next;
+        return -1;
+    }
+    tablelength = itr->h->tablelength;
+    itr->parent = NULL;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        return 0;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            itr->e = NULL;
+            return 0;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    return -1;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ *          and advance the iterator, if there is a successive
+ *          element.
+ *          If you want the value, read it before you remove:
+ *          beware memory leaks if you don't.
+ *          Returns zero if end of iteration. */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr)
+{
+    struct entry *remember_e, *remember_parent;
+    int ret;
+
+    /* Do the removal */
+    if (NULL == (itr->parent))
+    {
+        /* element is head of a chain */
+        itr->h->table[itr->index] = itr->e->next;
+    } else {
+        /* element is mid-chain */
+        itr->parent->next = itr->e->next;
+    }
+    /* itr->e is now outside the hashtable */
+    remember_e = itr->e;
+    itr->h->entrycount--;
+    freekey(remember_e->k);
+
+    /* Advance the iterator, correcting the parent */
+    remember_parent = itr->parent;
+    ret = hashtable_iterator_advance(itr);
+    if (itr->parent == remember_e) { itr->parent = remember_parent; }
+    free(remember_e);
+    return ret;
+}
+
+/*****************************************************************************/
+int /* returns zero if not found */
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k)
+{
+    struct entry *e, *parent;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+
+    e = h->table[index];
+    parent = NULL;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            itr->index = index;
+            itr->e = e;
+            itr->parent = parent;
+            itr->h = h;
+            return -1;
+        }
+        parent = e;
+        e = e->next;
+    }
+    return 0;
+}
+
+
+/*
+ * Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname at cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+
diff --git a/src/hashtable_itr.h b/src/hashtable_itr.h
new file mode 100644
index 0000000..6fb46d2
--- /dev/null
+++ b/src/hashtable_itr.h
@@ -0,0 +1,123 @@
+
+
+// $Id: hashtable_itr.h,v 1.9 2012/11/01 18:57:19 we7u Exp $
+
+
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname at cl.cam.ac.uk> */
+// Portions Copyright (C) 2004-2012  The Xastir Group
+
+
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable.h"
+#include "hashtable_private.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    struct entry *parent;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+#if 0
+// BZZZZT!  it is very, very wrong to be inlining this this way.
+// If one calls hashtable_iterator on a hash table from which everything
+// has been deleted, the iterator has a null for i->e.  
+// It is not good to require the caller to check the internals of the iterator
+// structure just to be sure there are no null pointers inside.
+// For whatever reason, these are defined again in the hashtable_iterator.c
+// file, not inlined.  I have modified the ones in hashtable_iterator so they
+// actually check for nulls and don't try to dereference them.
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+#else
+// SO instead of inlining, just declare.  No need to be "extern"
+// The ones in the .c file check their arguments and return nulls if they
+// can't comply with the request.  Much nicer for the calling routine to 
+// check a return value than to monkey with the internals of the struct.
+void * hashtable_iterator_key(struct hashtable_itr *i);
+void * hashtable_iterator_value(struct hashtable_itr *i);
+#endif 
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ *          NB: if you need the value to free it, read it before
+ *          removing. ie: beware memory leaks!
+ *          returns zero if advanced to end of table */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ *          matching the supplied key.
+            h points to the hashtable to be searched.
+ *          returns zero if not found. */
+int
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
+{ \
+    return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
+
+/*
+ * Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname at cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+
diff --git a/src/hashtable_private.h b/src/hashtable_private.h
new file mode 100644
index 0000000..208c155
--- /dev/null
+++ b/src/hashtable_private.h
@@ -0,0 +1,80 @@
+
+
+// $Id: hashtable_private.h,v 1.11 2012/11/01 18:57:19 we7u Exp $
+
+
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname at cl.cam.ac.uk> */
+/* Portions Copyright (C) 2004-2012  The Xastir Group */
+
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int primeindex;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+    return (hashvalue % tablelength);
+}
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname at cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+
diff --git a/src/hostname.c b/src/hostname.c
new file mode 100644
index 0000000..4812fe0
--- /dev/null
+++ b/src/hostname.c
@@ -0,0 +1,347 @@
+/*
+ * $Id: hostname.c,v 1.32 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <Xm/XmAll.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <signal.h>
+
+//Needed for Solaris 2.5
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <setjmp.h>
+#include <netinet/in.h>
+#include <sys/wait.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "lang.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+#ifndef HAVE_SIGHANDLER_T
+  #ifdef HAVE_SIG_T
+    typedef sig_t sighandler_t;
+  #else
+    typedef void (*sighandler_t)(int);
+  #endif
+#endif
+
+
+#ifndef __LCLINT__
+  #ifndef HAVE_SIGJMP_BUF
+    jmp_buf ret_place;
+  #else // HAVE_SIGJMP_BUF
+    static  sigjmp_buf ret_place;       /* Jump address if alarm */
+  #endif    // HAVE_SIGJMP_BUF
+#endif // __LCLINT__
+
+
+
+
+
+/*************************************************************************/
+/* Time out on connect                                                   */
+/* In case there is a problem in getting the hostname or connecting      */
+/* (see  setjmp below).                                                  */
+/*************************************************************************/
+
+static void host_time_out( /*@unused@*/ int sig) {
+#ifndef __LCLINT__
+    siglongjmp(ret_place,0);
+#endif // __LCLINT__
+}
+
+
+
+
+
+/*************************************************************************/
+/* do a nice host lookup (don't thread!!)                                */
+/*                                                                       */
+/* host: name to lookup                                                  */
+/* ip: buffer for ip's must be 400 bytes at least                        */
+/* time: time in seconds to wait                                         */
+/*                                                                       */
+/* return the ip or ip's of the host name                                */
+/* or these strings:                                                     */
+/* NOHOST  for no host by that name found                                */
+/* NOIP    for host found but no ip address available                    */
+/* TIMEOUT for time exceeded                                             */
+/*************************************************************************/
+
+char *host_lookup(char *host, char *ip, int ip_size, int time) {
+    /*struct sockaddr_in address;*/
+    char **names, **addrs;
+    static struct hostent *hostinfo;
+
+#ifdef RETSIGTYPE
+    RETSIGTYPE * previous_loc;
+#else 
+#error RETSIGTYPE not defined
+#endif
+
+    pid_t host_pid;
+    int status;
+    char ip_addr[400];
+    char temp[40];
+    int fp[2];
+    char buf[400];
+    int ip_found;
+    int first;
+    int tm;
+    int ips;
+    int i;
+    char ttemp[60];
+    int wait_host;
+
+    if (debug_level & 1024)
+        fprintf(stderr,"Start Host lookup\n");
+
+    memset(ip_addr,(int)'\0',sizeof(ip_addr));
+    memset(buf,(int)'\0',sizeof(buf));
+
+    busy_cursor(appshell);
+
+    if (debug_level & 1024)
+        fprintf(stderr,"Creating pipe\n");
+
+    if (pipe(fp)==0) {          // Create a pipe for communication
+
+        host_pid = fork();      // Fork off a child process
+
+        if (debug_level & 1024)
+            fprintf(stderr,"Host fork\n");
+
+        if (host_pid!=-1) {     // If the fork was successful
+
+//---------------------------------------------------------------------------------------
+            if (host_pid==0) {  // We're in the child process
+
+
+                // Go back to default signal handler instead of
+                // calling restart() on SIGHUP
+                (void) signal(SIGHUP,SIG_DFL);
+
+
+                // Change the name of the new child process.  So far
+                // this only works for "ps" listings, not for "top".
+                // This code only works on Linux.  For BSD use
+                // setproctitle(3), NetBSD can use setprogname(2).
+#ifdef __linux__
+                init_set_proc_title(my_argc, my_argv, my_envp);
+                set_proc_title("%s", "hostname lookup (xastir)");
+                //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
+#endif  // __linux__
+
+
+                // Close the end of the pipe we don't need here
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"Child closing read end of pipe\n");
+
+                close(fp[0]);   // Read end of the pipe
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"Set alarm \n");
+
+#ifdef RETSIGTYPE
+                previous_loc = (RETSIGTYPE *)signal(SIGALRM, host_time_out);
+#else
+                previous_loc = signal(SIGALRM, host_time_out);
+#endif
+
+                // Set up to jump here if we time out on SIGALRM
+                if (sigsetjmp(ret_place,-1)!=0) {
+
+                    // Turn off the alarm
+                    (void)alarm(0);
+
+                    // Reset the SIGALRM handler to its previous value
+                    (void)signal(SIGALRM, (sighandler_t)previous_loc);
+
+                    // Return net connection time out
+                    xastir_snprintf(ip_addr, sizeof(ip_addr), "TIMEOUT");
+                    (void)write(fp[1],ip_addr,strlen(ip_addr));
+
+                    if (debug_level & 1024)
+                        fprintf(stderr,"Child closing write end of pipe\n");
+
+                    close(fp[1]);   // All done writing to the pipe
+                    exit(EXIT_FAILURE); // Exit from child process
+                }
+                (void)alarm(time);  // Start the timer
+
+                // Make the call that may time out if no response from DNS
+                /*hostinfo = gethostbyname2(host,AF_INET); some systems don't have this*/
+                hostinfo = gethostbyname(host);
+
+                // If we get to here, we haven't timed out
+                // and we have an answer to process.
+
+                // Turn off the alarm
+                (void)alarm(0);
+                // Reset the SIGALRM handler to its previous value
+                (void)signal(SIGALRM, (sighandler_t)previous_loc);
+
+                if (hostinfo) {
+                    names = hostinfo -> h_aliases;
+                    ip_found=0;
+
+                    /* look at all names */
+                    ips=0;
+                    first=0;
+                    if (!*names)
+                        first=1;
+
+                    while (*names || first) {
+                        if (hostinfo -> h_addrtype == AF_INET) {
+                            ip_found=1;
+                            addrs = hostinfo -> h_addr_list;
+                            while (*addrs) {
+                                xastir_snprintf(temp, sizeof(temp), "%s",
+                                        inet_ntoa(*(struct in_addr *)*addrs));
+
+                                if (debug_level & 1024)
+                                    fprintf(stderr,"IP [%s]\n",temp);
+
+                                if (strlen(temp)>7) {
+                                    /* IP found */
+                                    if((strlen(ip_addr)+strlen(temp))<sizeof(ip_addr)) {
+
+                                        if (ips>0) {
+                                            strncat(ip_addr,
+                                                " ",
+                                                sizeof(ip_addr) - 1 - strlen(ip_addr));
+                                        }
+
+                                        strncat(ip_addr,
+                                            temp,
+                                            sizeof(ip_addr) - 1 - strlen(ip_addr));
+
+                                        ips++;
+                                    }
+                                }
+                                addrs++;
+                            }
+                        }
+                        if (first) {
+                            *names=NULL;
+                            first=0;
+                        } else
+                            names++;
+                    }
+                    if (ip_found==0) {
+                        /* Host not found */
+                        xastir_snprintf(ip_addr, sizeof(ip_addr), "NOIP");
+
+                        if (debug_level & 1024)
+                            fprintf(stderr,"Host NO IP");
+
+                    }
+                }
+                else {
+                    /* Host not found */
+                    xastir_snprintf(ip_addr, sizeof(ip_addr), "NOHOST");
+
+                    if (debug_level & 1024)
+                        fprintf(stderr,"NO HOST\n");
+
+                }
+                if (debug_level & 1024)
+                    fprintf(stderr,"Clear alarm 1\n");
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"Clear alarm 2\n");
+
+                (void)write(fp[1],ip_addr,strlen(ip_addr));
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"Child closing write end of pipe\n");
+
+                close(fp[1]);   // All done writing to the pipe
+                exit(EXIT_FAILURE); // Exit from child process
+
+            }   // End of child process
+//---------------------------------------------------------------------------------------
+            else {
+                // We're in the parent process at this point
+
+                // Close the end of the pipe we don't need here
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"Parent closing write end of pipe\n");
+
+                close(fp[1]);   // Write end of the pipe
+
+                tm=1;
+                wait_host=1;
+                while (wait_host!=-1) {
+                    xastir_snprintf(ttemp, sizeof(ttemp), langcode("BBARSTA031"), tm++);
+                    statusline(ttemp,1);        // Looking up hostname...
+
+                    for (i=0; i < 60 && wait_host!=-1; i++) {
+                        wait_host=waitpid(host_pid,&status,WNOHANG);
+                        /* update display while waiting */
+//                        XmUpdateDisplay(XtParent(da));
+                        //usleep(500);
+                        sched_yield();
+                    }
+                }
+                (void)read(fp[0],buf,sizeof(buf)-1);
+
+                xastir_snprintf(ip, ip_size, "%s", buf);
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"Parent closing read end of pipe\n");
+
+                close(fp[0]);   // Close the read end of the pipe
+            }
+        }
+        else {  // We didn't fork
+            // Close both ends of the pipe to make
+            // sure we've cleaned up properly
+            close(fp[0]);
+            close(fp[1]);
+        }
+    }
+    else {  // No pipe created
+    }
+    return(ip);
+}
+
+
diff --git a/src/hostname.h b/src/hostname.h
new file mode 100644
index 0000000..652f15f
--- /dev/null
+++ b/src/hostname.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: hostname.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_HOSTNAME_H
+#define __XASTIR_HOSTNAME_H
+
+extern char *host_lookup(char *host, char *ip, int ip_size, int time);
+
+#endif  // __XASTIR_HOSTNAME_H
+
+
diff --git a/src/icon.xbm b/src/icon.xbm
new file mode 100644
index 0000000..a4085b2
--- /dev/null
+++ b/src/icon.xbm
@@ -0,0 +1,20 @@
+#define icon_width 40
+#define icon_height 40
+static unsigned char icon_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00,
+   0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x80,
+   0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+   0x00, 0x10, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0x00, 0x20, 0x20,
+   0x10, 0x00, 0x00, 0x10, 0x20, 0x10, 0x00, 0x00, 0x08, 0x20, 0x20, 0x00,
+   0x00, 0x04, 0x20, 0x20, 0x00, 0x00, 0x02, 0x28, 0x60, 0x00, 0x00, 0x27,
+   0x28, 0x60, 0xfc, 0xff, 0x3f, 0x28, 0x60, 0xfe, 0xff, 0x3f, 0xe8, 0x7f,
+   0xfe, 0xff, 0x27, 0xef, 0x7f, 0xfe, 0xff, 0x07, 0xef, 0x7f, 0xfe, 0xff,
+   0x07, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff,
+   0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+   0xff, 0xff, 0xff, 0xff, 0xfc, 0x0f, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0x00,
+   0xfc, 0x0f, 0xf8, 0x07, 0x00, 0xf8, 0x07, 0xf0, 0x03, 0x00, 0xf0, 0x03,
+   0xe0, 0x01, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/igate.c b/src/igate.c
new file mode 100644
index 0000000..1ca656d
--- /dev/null
+++ b/src/igate.c
@@ -0,0 +1,1443 @@
+/*
+ * $Id: igate.c,v 1.66 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <termios.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Xm/XmAll.h>
+#include <X11/Xatom.h>
+#include <X11/Shell.h>
+
+#include "xastir.h"
+#include "igate.h"
+#include "main.h"
+#include "interface.h"
+#include "xa_config.h"
+#include "util.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+time_t last_nws_stations_file_time = 0;
+int NWS_stations = 0;
+int max_NWS_stations = 0;
+NWS_Data *NWS_station_data;
+
+
+void load_NWS_stations(char *file);
+int check_NWS_stations(char *call);
+
+
+
+// Struct for holding packet data.  We use dynamically-allocated
+// singly-linked lists.  The last record should have its "next"
+// pointer set to NULL.
+//
+typedef struct _DupeRecord{
+    char    data[MAX_LINE_SIZE+15]; // Packet data
+    time_t  time;                       // The time the record was inserted
+    struct  _DupeRecord *next;          // pointer to next record in list
+} DupeRecord;
+
+
+
+// Sent and Heard queue pointers.  These are used for the dupe-checking
+// we do in the below routines.  We have one Sent and one Heard queue
+// for each interface device.  These pointers will point to the head of
+// each queue.  We really only need these queues for each TNC interface,
+// but the user might destroy a NET interface and create a TNC interface
+// during a single runtime, so we need to populate all of the pointers
+// just in case.  If people switch types, the old queue will empty out
+// (effectively anyway) within XX seconds, so we don't have to worry
+// about cleaning out the queues in this case.
+//
+DupeRecord *heard_queue[MAX_IFACE_DEVICES];
+DupeRecord  *sent_queue[MAX_IFACE_DEVICES];
+
+
+
+// Types of queues for each interface
+#define HEARD               0
+#define SENT                1
+
+
+
+// Insert mode for the queues
+#define NO_FORCED_INSERT    0
+#define FORCED_INSERT       1
+
+
+
+
+
+// Initialization routine for this module which sets up the queue
+// pointers when Xastir first starts.  Called from main.c:main()
+//
+void igate_init(void) {
+    int i;
+
+    for (i = 0; i < MAX_IFACE_DEVICES; i++) {
+        heard_queue[i] = NULL;
+        sent_queue[i] = NULL;
+    }
+}
+
+
+
+
+
+//
+// not_a_dupe:  Function which checks for duplicate packets.
+//
+// Returns: 1 if it's _not_ a duplicate record or we have an error
+//          0 if it _is_ a duplicate record
+//
+// Since we need to run through every record checking for dupes anyway,
+// we check the timestamp on each one as we go through.  If too old, we
+// delete it from the head of the chain.  We add new records to the end.
+// This makes it easy to keep it as a singly-linked list, and only have
+// to deal with one record at a time.
+//
+// The way this is set up we keep a thirty second queue for each
+// interface.  Any records older than this are at the head of the chain
+// and are deleted one by one whenever this routine is called again due
+// to a new packet coming through.  It's ok if these records sit around
+// on the queue for a long time due to no igate activity.  It doesn't
+// take long to delete them!
+//
+int not_a_dupe(int queue_type, int port, char *line, int insert_mode) {
+    DupeRecord *ptr;
+    DupeRecord *ptr_last;
+    int insert_new;
+    time_t time_cutoff;
+    int found_dupe = 0;
+    char match_line[MAX_LINE_SIZE*2];
+    char line2[MAX_LINE_SIZE+1];
+    char *c0, *c1, *c2;
+
+
+    if ( (line == NULL) || (line[0] == '\0') )
+        return(1);
+
+
+    // Figure out what's "old"
+    time_cutoff = sec_now() - (time_t)29;   // 29 seconds ago
+
+
+    // Fill the destination string with zeroes.  This is a nice
+    // segfault-prevention technique.  Whatever strings we throw in here
+    // will be automatically terminated.
+    memset(match_line, 0, MAX_LINE_SIZE*2);
+
+
+    switch (queue_type) {
+
+        case HEARD:
+            ptr_last = ptr = heard_queue[port]; // May be NULL!
+
+            // The insert_into_heard_queue() function below (called by
+            // db.c decode routines in turn) will call this function
+            // with FORCED_INSERT.  Other routines in igate.c will call
+            // it with NO_FORCED_INSERT.  For the Heard queue we only
+            // want the db.c decode routines inserting records.
+            if (insert_mode == FORCED_INSERT)
+                insert_new = 1; // Insert new records.
+            else
+                insert_new = 0; // Don't insert new records.
+
+            // RF packets will have third-party headers and regular
+            // headers that must be stripped off.  We only want to store
+            // 3rd party RF strings in the Heard queue as the others
+            // aren't going to be igated anyway.  For matching and
+            // storage purposes the 3rd party packets should look
+            // identical to how they were originally passed on the 'net,
+            // so that we can try to find duplicates before transmitting
+            // them again.
+
+// NOTE:  Below is the parsing code for an internet packet for the Sent
+// queue.  Modify it to parse 3rd party packets for the Heard queue.
+
+// VE7VFM-12>APD214,VE7VAN-3*,WIDE3*:}WA7JAK>APK002,TCPIP*,VE7VFM-12*::N7WGR-7  :does{2
+
+            // Changes needed before parsing code:  Get rid of first
+            // part of packet up to the '}' symbol.  After this the
+            // generic parsing code will work.
+// Note that the REPLY-ACK algorithm also uses the '}' symbol.
+
+            c0 = strstr(line, ":}"); // Find start of 3rd party packet
+            if (c0 == NULL) {   // Not 3rd party packet
+                if (debug_level & 1024)
+                    fprintf(stderr," Not 3rd party HeardQ: %s\n",line);
+                return(1);
+            }
+
+            // Copy original packet into line2 for later parsing.  We
+            // want to keep the '}' character because our own
+            // transmissions out RF have that character as well.
+// Note that the REPLY-ACK algorithm also uses the '}' symbol.
+            if (debug_level & 1024)
+                fprintf(stderr,"3rd party HeardQ: %s\n",line);
+
+            xastir_snprintf(line2,
+                sizeof(line2),
+                "%s",
+                c0+1);
+
+            break;
+
+        case SENT:
+            // For this queue we always want to insert records.  Only
+            // igate.c functions call this.
+            ptr_last = ptr = sent_queue[port];  // May be NULL!
+            insert_new = 1; // Insert new records
+
+            // No extra changes needed before parsing code, Example:
+            // }VE7VFM-11>APW251,TCPIP,WE7U-14*::VE7VFM-9 :OK GOT EMAIL OK{058
+            xastir_snprintf(line2,
+                sizeof(line2),
+                "%s",
+                line);
+
+            if (debug_level & 1024)
+                fprintf(stderr," COMPLETE SENT PACKET: %s\n",line2);
+
+            break;
+
+        default:    
+            // We shouldn't be here.
+            return(1);
+
+            break;
+    }
+
+
+    // Create the string we're going to compare against and that we
+    // might store in the queue.  Knock off the path info and just check
+    // source/destination/info portions of the packet for a match.
+ 
+    c1 = strstr(line2, ","); // Find comma after destination
+    c2 = strstr(line2, ":"); // Find end of path
+
+    if ( (c1 != NULL) && (c2 != NULL) ) {           // Found both separators
+
+        // Copy source/destination portion
+        xastir_snprintf(match_line,
+            sizeof(match_line),
+            "%s",
+            line2);
+        match_line[(int)(c1-line2)] = '\0';         // Terminate the substring
+
+        strncat(match_line,                         // Copy info portion
+            c2+1,
+            sizeof(match_line) - 1 - strlen(match_line));
+    }
+    else {  // At least one separator was not found, copy entire string
+        xastir_snprintf(match_line,
+            sizeof(match_line),
+            "%s",
+            line2);
+    }
+
+
+    // Run through the selected queue from beginning to end.  If the
+    // pointer is NULL, the queue is empty and we're already done.
+    while (ptr != NULL && !found_dupe) {
+
+        // Check the timestamp to determine whether to delete this
+        // record
+        if (ptr->time < time_cutoff) {  // Old record, delete it
+            DupeRecord *temp;
+
+            if (debug_level & 1024) {
+                switch (queue_type) {
+                    case HEARD:
+                        fprintf(stderr,"HEARD Deleting record: %s\n",ptr->data);
+                        break;
+                    case SENT:
+                        fprintf(stderr," SENT Deleting record: %s\n",ptr->data);
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            // Delete record and free up the space
+            temp = ptr;
+            ptr = ptr->next;    // May be NULL!
+            free(temp);
+
+            // Point master queue pointer to new head of queue.
+            // Make sure to carry along ptr_last as well, as this is
+            // our possible insertion point later.
+            switch (queue_type) {
+                case HEARD:
+                    heard_queue[port] = ptr_last = ptr; // May be NULL!
+                    break;
+                case SENT:
+                    sent_queue[port] = ptr_last = ptr;  // May be NULL!
+                default:
+                    break;
+            }
+        }
+
+        else {  // Record is current.  Check for a match.
+
+            //fprintf(stderr,"\n\t\t%s\n\t\t%s\n",ptr->data,match_line);
+
+            if (strcmp(ptr->data,match_line) == 0) {
+                // We found a dupe!  We're done with the loop.
+                found_dupe++;
+
+                if (debug_level & 1024) {
+                    switch (queue_type) {
+                        case HEARD:
+                            fprintf(stderr,"HEARD*     Found dupe: %s\n",match_line);
+                            break;
+                        case SENT:
+                            fprintf(stderr,"SENT*      Found dupe: %s\n",match_line);
+                        default:
+                            break;
+                    }
+                }
+            }
+            else {  // Not a dupe, skip to the next record in the
+                    // queue.  Keep a pointer to the last record
+                    // compared so that we have a possible insertion
+                    // point later.  Once we hit the end (NULL), we
+                    // can't back up one.
+                ptr_last = ptr;     // Save pointer to last record
+                ptr = ptr->next;    // Advance one.  May be NULL!
+            }
+        }
+    }   // End of while loop
+
+
+    if (found_dupe) {
+
+        if (debug_level & 1024) {
+            switch (port_data[port].device_type) {
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_AX25_TNC:
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                case DEVICE_NET_AGWPE:
+                    fprintf(stderr,"        Found RF dupe: %s\n",match_line);
+                    break;
+
+                default:
+                    fprintf(stderr,"       Found NET dupe: %s\n",match_line);
+                    break;
+            }
+        }
+
+        return(0);  // Found a dupe, return
+    }
+
+    else {
+
+        // If insert_new == 1, insert each non-dupe record into the
+        // queue and give it a timestamp.  ptr_next is currently
+        // either NULL or points to the last record in the chain.
+        if (insert_new) {
+            DupeRecord *temp;
+
+            if (debug_level & 1024) {
+                switch (queue_type) {
+                    case HEARD:
+                        fprintf(stderr,"HEARD   Adding record: %s\n",match_line);
+                        break;
+                    case SENT:
+                        fprintf(stderr," SENT   Adding record: %s\n",match_line);
+                        break;
+                    default:
+                        break;
+                }
+            }
+
+            // Allocate a new storage space for the record and fill
+            // it in.
+            temp = (DupeRecord *)malloc(sizeof(DupeRecord));
+
+            if (!temp) {
+                fprintf(stderr,"Couldn't allocate memory in not_a_dupe()\n");
+                return(1);  // Send back "not a dupe"
+            }
+
+            temp->time = (time_t)sec_now();
+
+            xastir_snprintf(temp->data,
+                sizeof(temp->data),
+                "%s",
+                match_line);
+
+            temp->next = NULL;  // Will be the end of the linked list
+
+            if (ptr_last == NULL) { // Queue is currently empty
+
+                // Add record to empty list.  Point master queue pointer
+                // to new head of queue.
+                switch (queue_type) {
+                    case HEARD:
+                        heard_queue[port] = temp;
+                        break;
+                    case SENT:
+                        sent_queue[port] = temp;
+                    default:
+                        break;
+                }
+            }
+            else {  // Queue is not empty, add the record to the end of
+                    // the list.
+                ptr_last->next = temp;
+            }
+        }
+    }
+    return(1);  // Nope, not a dupe
+}
+
+
+
+
+ 
+// Function which the receive routines call to insert a received
+// packet into the HEARD queue for an interface.  The packet will
+// get added to the end of the linked list if it's not a duplicate
+// record.
+//
+// Check to make sure it's an RF interface, else return
+//
+void insert_into_heard_queue(int port, char *line) {
+
+    switch (port_data[port].device_type) {
+
+        case DEVICE_SERIAL_TNC_AUX_GPS:
+        case DEVICE_SERIAL_TNC_HSP_GPS:
+        case DEVICE_SERIAL_TNC:
+        case DEVICE_AX25_TNC:
+        case DEVICE_SERIAL_KISS_TNC:
+        case DEVICE_SERIAL_MKISS_TNC:
+        case DEVICE_NET_AGWPE:
+ 
+            // We're not using the dupe check function, but merely the
+            // expiration and insert functions of not_a_dupe()
+
+            // Don't insert the "Tickle" lines that keep the internet
+            // sockets alive 
+            if ( (strncasecmp(line,"# Tickle",8) != 0)
+                    && (strncasecmp(line,"#Tickle",7) != 0) ) {
+                (void)not_a_dupe(HEARD, port, line, FORCED_INSERT);
+            }
+
+            break;
+
+        default:    // Get out if not an RF interface
+            return;
+
+            break;
+    }
+}
+
+
+
+
+
+/****************************************************************/
+/* output data to inet interfaces                               */
+/* line: data to send out                                       */
+/* port: port data came from                                    */
+/****************************************************************/
+void output_igate_net(char *line, int port, int third_party) {
+    char data_txt[MAX_LINE_SIZE+5];
+    char temp[MAX_LINE_SIZE+5];
+    char *call_sign;
+    char *path;
+    char *message;
+    int len,i,x,first;
+    int igate_options;
+    char log_file_path[MAX_VALUE];
+
+    call_sign = NULL;
+    path      = NULL;
+    message   = NULL;
+    first     = 1;
+
+    if (line == NULL)
+        return;
+
+    if (line[0] == '\0')
+        return;
+
+    // Don't igate packets read in from a log file (port -1).
+    // Packets from x_spider (port -2) are ok to igate.
+    if (port == -1)
+        return;
+
+//fprintf(stderr,"Igating: %s\n", line);
+
+    // Should we Igate from RF->NET?
+    if (operate_as_an_igate <= 0)
+        return;
+
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        line);
+
+    // Check for null call_sign field
+    call_sign = strtok(temp,">");
+    if (call_sign == NULL)
+        return;
+
+    // Check for null path field
+    path = strtok(NULL,":");
+    if (path == NULL)
+        return;
+
+    get_user_base_dir(LOGFILE_IGATE,log_file_path, sizeof(log_file_path));
+    // Check for "TCPIP" or "TCPXX" in the path.  If found, don't
+    // gate this into the internet again, it's already been gated to
+    // RF, which means it's already been on the 'net.  No looping
+    // allowed here...
+    //
+    // We also now support NOGATE and RFONLY options.  If these are
+    // seen in the path, do _not_ gate those packets into the
+    // internet.
+    //
+    // Don't gate OpenTrac expanded packets to the 'net.
+    //
+    if ( (strstr(path,"TCPXX") != NULL)
+            || (strstr(path,"TCPIP") != NULL && port >= 0) // x_spider ok
+            || (strstr(path,"NOGATE") != NULL)
+            || (strstr(path,"RFONLY") != NULL)
+            || (strstr(path,"OPNTRK") != NULL)      // OpenTrac Packet
+            || (strstr(path,"OPNTRC") != NULL) ) {  // OpenTrac Packet
+ 
+            if (log_igate && (debug_level & 1024) ) {
+
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "IGATE RF->NET(%c):%s\n",
+                    third_party ? 'T':'N',
+                    line);
+                log_data( log_file_path, temp );
+
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "REJECT: Packet was gated before or shouldn't be gated!\n");
+                log_data( log_file_path, temp );
+
+                fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+ 
+    // Check for null message field
+    message = strtok(NULL,"");
+    if (message == NULL)
+        return;
+
+    // Check for third party messages.  We don't want to gate these
+    // back onto the internet feeds
+// Note that the REPLY-ACK algorithm also uses the '}' symbol.
+    if (message[0] == '}') {
+
+        if (log_igate && (debug_level & 1024) ) {
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE RF->NET(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: Third party traffic!\n");
+            log_data( log_file_path, temp );
+
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+    // Check for "general" queries.  We don't wish to gate these in
+    // either direction.  There are exactly three general query
+    // types defined in the spec.
+    //
+    if ( (   strstr(message,"?APRS?" ) != NULL)
+         || (strstr(message,"?IGATE?") != NULL)
+         || (strstr(message,"?WX?"   ) != NULL) ) {
+
+        // We found a general query, don't gate it.
+
+        if (log_igate && (debug_level & 1024) ) {
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE RF->NET(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: General Query!\n");
+            log_data( log_file_path, temp );
+
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+    len = (int)strlen(call_sign);
+    for (i=0;i<len;i++) {
+
+        // just in case we see an asterisk get rid of it
+        if (call_sign[i] == '*') {
+            call_sign[i] = '\0';
+            i = len+1;
+        }
+    }
+
+    // Check for my callsign
+    if (strcmp(call_sign,my_callsign) == 0) {
+
+        if (log_igate && (debug_level & 1024) ) {
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE RF->NET(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: From my call!\n");
+            log_data( log_file_path, temp );
+
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+ 
+    // Should I filter out more here.. get rid of all data
+    // or Look in the path for things line "AP" "GPS" "ID" etc..?
+
+begin_critical_section(&devices_lock, "igate.c:output_igate_net" );
+
+    // If received from x_spider port or it's our own tactical call.
+    // Here are the special port numbers we might see:
+    // -1: We're reading in from a log file
+    // -2: Packet came from x_spider server port (therefore it's
+    //     already authenticated)
+    // -3: We're reading in tactical calls from file
+    //
+    if (port == -1)         // Packet came from a log file.
+        igate_options = 0;  // Don't igate it.
+
+    else if (port == -2)    // Packet came from x_spider server port
+        igate_options = 1;  // Ok to igate.
+
+    else if (port == -3)    // We're reading tactical call from file.
+        igate_options = 0;  // Don't igate it.
+
+    else if (port < -2)     // Errant port number.
+        igate_options = 0;  // Don't igate it.
+
+    else    // Port number is 0 or positive number.  A real port.
+            // Decide whether to igate it based on the port's
+            // configuration.
+        igate_options = devices[port].igate_options;
+
+
+end_critical_section(&devices_lock, "igate.c:output_igate_net" );
+
+    if (igate_options <= 0 ) {
+
+        if (log_igate && (debug_level & 1024) ) {
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE RF->NET(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: No RF->NET from input port [%d]!\n",
+                port);
+            log_data( log_file_path, temp );
+
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+    xastir_snprintf(data_txt,
+        sizeof(data_txt),
+        "%s%c%c",
+        line,
+        '\r',
+        '\n');
+
+    // write data out to net interfaces
+    for (x = 0; x < MAX_IFACE_DEVICES; x++) {
+
+        // Find all internet interfaces that are "up"
+        if (port_data[x].device_type == DEVICE_NET_STREAM
+                && x!=port && port_data[x].status == DEVICE_UP) {
+            int pcode;
+
+            // Check whether we have a valid callsign/password
+            // combination for this interface.  If not, don't gate
+            // packets to it.
+            pcode = atoi(port_data[x].device_host_pswd);
+            if (checkHash(my_callsign, pcode)) {
+                // The pcode checks out.  Allow sending the
+                // packet out to the internet.
+
+                // log traffic for the first "up" interface only
+                if (log_igate && first) {
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "IGATE RF->NET(%c):%s\n",
+                        third_party ? 'T':'N',
+                        line);
+                    log_data( log_file_path, temp );
+
+                    first = 0;
+                }
+
+                // Now log the interface that each bit of traffic
+                // goes out on.
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "TRANSMIT: IGate RF->NET packet on device:%d\n",
+                    x);
+
+                // log output
+                if (log_igate)
+                    log_data( log_file_path, temp );
+
+                if (debug_level & 1024)
+                    fprintf(stderr,"%s\n",temp);
+
+                // Write this data out to the Inet port The "1"
+                // means raw format, the last digit says to _not_
+                // use the unproto_igate path
+                output_my_data(data_txt,x,1,0,0,NULL);
+//fprintf(stderr,"Sending: %s\n", data_txt);
+            }
+        }
+    }
+}
+
+
+
+
+
+/****************************************************************/
+/* output data to tnc interfaces                                */
+/* from: type of port heard from (No! It's the source call!)    */
+/* call: call sign heard from (No! It's the destination call!)  */
+/* line: data to gate to rf                                     */
+/* port: port data came from                                    */
+/****************************************************************/
+void output_igate_rf(char *from, char *call, char *path, char *line,
+        int port, int third_party, char *object_name) {
+
+    char temp[MAX_LINE_SIZE+20];
+    int x;
+    int first = 1;
+    int found_in_nws_file = 0;
+    char log_file_path[MAX_VALUE];
+    char nws_file_path[MAX_VALUE];
+
+
+    if ( (from == NULL) || (call == NULL) || (path == NULL) || (line == NULL) )
+        return;
+
+    if ( (from[0] == '\0') || (call[0] == '\0') || (path[0] == '\0') || (line[0] == '\0') )
+        return;
+
+    // Should we Igate from NET->RF?
+    if (operate_as_an_igate <= 1)
+        return;
+
+
+    get_user_base_dir(LOGFILE_IGATE,log_file_path, sizeof(log_file_path));
+
+    // Don't gate anything with NOGATE in it, in either direction.
+    // Same for OpenTrac packets.
+    if ( (strstr(path,"NOGATE") != NULL)
+         || (strstr(path,"OPNTRK") != NULL)     // OpenTrac Packet
+         || (strstr(path,"OPNTRC") != NULL) ) { // OpenTrac Packet
+        // "NOGATE" was found in the header.  Don't gate it.
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: NOGATE found in path or shouldn't be gated!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+    // Don't gate "general" queries in any direction.  There are
+    // exactly three general query types defined in the spec.
+    //
+    if (   (strstr(line,"?APRS?" ) != NULL)
+        || (strstr(line,"?IGATE?") != NULL)
+        || (strstr(line,"?WX?"   ) != NULL) ) {
+
+        // We found a general query, don't gate it.
+
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: General Query!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+
+     // check to see if the nws-stations file is newer than last read
+    get_user_base_dir("data/nws-stations.txt",nws_file_path, 
+                      sizeof(nws_file_path));
+    if (last_nws_stations_file_time < file_time(nws_file_path)) {
+        last_nws_stations_file_time = file_time(nws_file_path);
+        load_NWS_stations(nws_file_path);
+        //fprintf(stderr,"NWS Station file time is old\n");
+    }
+
+
+    // Check whether gating of packets from this station/object/item
+    // has been specifically authorized via the nws-stations.txt
+    // mechanism.
+    //
+    if (object_name) {  // It's an object or item name
+
+        if ( check_NWS_stations( object_name ) || group_active(object_name)) {
+
+            found_in_nws_file++; // Object/Item is in nws-stations.txt
+        }
+    }
+    else {              // It's a station callsign
+
+        if ( check_NWS_stations( from ) || group_active(from)) {
+
+            found_in_nws_file++; // Source callsign is in nws-stations.txt
+        }
+    }
+// The above is really the same as the following code, but less
+// confusing:
+//    if (check_NWS_stations( (object_name) ? object_name : from ) ) {
+//        found_in_nws_file++;
+//    }      
+
+ 
+    // Check for TCPXX in string only if station wasn't found in the
+    // nws-stations.txt file.  If TCPXX found, we have an
+    // unregistered net user and the packet shouldn't normally head
+    // to RF.
+    //
+    // I removed the trailing asterisk -we7u
+    //
+    // Note that we CAN now gate stations to RF that have TCPXX in
+    // the string if they are authorized via the nws-stations.txt
+    // mechanism.
+    //
+    if (!found_in_nws_file) { // Skip this check if they're always authorized via the file
+
+        if (strstr(path,"TCPXX") != NULL) {
+
+            // "TCPXX" was found in the header.  We have an
+            // unregistered user.
+
+            if (log_igate && (debug_level & 1024) ) {
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "IGATE NET->RF(%c):%s\n",
+                    third_party ? 'T':'N',
+                    line);
+                log_data( log_file_path, temp );
+    
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "REJECT: Unregistered net user!\n");
+                log_data( log_file_path, temp );
+                fprintf(stderr, "%s", temp);
+            }
+            return;
+        }
+    }
+
+
+
+// If we made it to this point, the packet is from an authorized net
+// user (no TCPXX found in the path), or the callsign has been
+// authorized via the nws-stations.txt file (whether or not TCPXX
+// was found in the path).
+//
+// Found in file: Gate always
+//
+// Not found:     Gate if TCPXX not in path -AND- if destination
+//                station was heard in last hour on RF -AND- if
+//                source station was NOT heard in last hour on RF.
+
+
+
+    // Check whether the source and destination calls have been
+    // heard on local RF.
+    if ( !found_in_nws_file // Skip this check if they're always authorized via the file
+         && ( !heard_via_tnc_in_past_hour(call)==1    // Haven't heard destination call in previous hour
+            || heard_via_tnc_in_past_hour(from)) ) {  // Have heard source call in previous hour
+
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+        //  heard(call),  heard(from) : RF-to-RF talk
+        // !heard(call),  heard(from) : Destination not heard on TNC
+        // !heard(call), !heard(from) : Destination/source not heard on TNC
+
+        if (!heard_via_tnc_in_past_hour(call))
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: Destination not heard on TNC within an hour %s!\n",
+                call );
+        else
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: RF->RF talk!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+ 
+
+
+    // Station we are going to is heard via tnc but station sending
+    // shouldn't be heard via TNC.  Write data out to interfaces.
+    for (x=0; x<MAX_IFACE_DEVICES;x++) {
+
+        //fprintf(stderr,"%d\n",x);
+
+//WE7U
+        // Check here against "heard" queue for each interface.
+        // Drop the packet on the floor if it was already received
+        // on this interface within the last XX seconds.  This means
+        // that some other igate beat us to the punch.  The receive
+        // routines have to fill this queue.  Prune outdated
+        // records.
+        //
+        // Also check here against "sent" queue for each interface.
+        // Drop the packet on the floor if already sent within the
+        // last XX seconds.  Add this packet to the queue if it
+        // isn't already in it.  Prune outdated records.
+        if (x != port
+                && not_a_dupe(HEARD, x, line, NO_FORCED_INSERT)
+                && not_a_dupe( SENT, x, line, NO_FORCED_INSERT) ) {
+
+            //fprintf(stderr,"output_igate_rf: Not a dupe port %d, transmitting\n",x);
+
+            switch (port_data[x].device_type) {
+
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_AX25_TNC:
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                case DEVICE_NET_AGWPE:
+
+begin_critical_section(&devices_lock, "igate.c:output_igate_rf" );
+
+                    if (devices[x].igate_options>1 && port_data[x].status==DEVICE_UP) {
+
+                        // log traffic for first "up" interface only
+                        if (log_igate && first) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "IGATE NET->RF(%c):%s\n",
+                                third_party ? 'T':'N',
+                                line);
+                            log_data( log_file_path, temp );
+                            first = 0;
+                        }
+
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "TRANSMIT: IGate NET->RF packet on device:%d\n",
+                            x);
+
+                        // log output
+                        if (log_igate)
+                            log_data( log_file_path, temp );
+
+                        if (debug_level & 1024)
+                            fprintf(stderr, "%s", temp);
+
+                        // ok write this data out to the RF port
+
+end_critical_section(&devices_lock, "igate.c:output_igate_rf" );
+
+                        // First "0" means "cooked"
+                        // format, last digit: use
+                        // unproto_igate path
+                        output_my_data(line,x,0,0,1,NULL);
+
+//fprintf(stderr, "Igating->RF: %s\n", line);
+
+begin_critical_section(&devices_lock, "igate.c:output_igate_rf" );
+
+                    }
+                    else {
+                        if (log_igate && (debug_level & 1024) ) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "IGATE NET->RF(%c):%s\n",
+                                third_party ? 'T':'N',
+                                line);
+                            log_data( log_file_path, temp );
+
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "REJECT: NET->RF on port [%d]!\n",
+                                x);
+                            log_data( log_file_path, temp );
+                            fprintf(stderr, "%s", temp);
+                        }
+                    }
+
+end_critical_section(&devices_lock, "igate.c:output_igate_rf" );
+
+                    break;
+
+                default:
+                    break;
+            }   // End of switch
+        }   // End of if
+    }   // End of for
+}
+
+
+
+
+
+void add_NWS_stations(void) {
+    void *tmp_ptr;
+
+    if (NWS_stations>=max_NWS_stations) {
+        if ((tmp_ptr = realloc(NWS_station_data, sizeof(NWS_Data)*(max_NWS_stations+11)))) {
+            NWS_station_data = tmp_ptr;
+            max_NWS_stations += 10;
+        }
+        else {
+            fprintf(stderr,"Unable to allocate more space for NWS_station_data\n");
+        }
+    }
+}
+
+
+
+
+
+/****************************************************************/
+/* Load NWS stations file                                       */
+/* file: file to read                                           */
+/****************************************************************/
+void load_NWS_stations(char *file) {
+    FILE *f;
+    char line[40];
+
+    if (file == NULL)
+        return;
+
+    if (file[0] == '\0')
+        return;
+
+    if (NWS_station_data) {
+        free(NWS_station_data);
+        NWS_station_data = NULL;
+    }
+
+    NWS_stations = 0;
+    max_NWS_stations = 0;
+
+    f = fopen(file,"r");
+    if (f!=NULL) {
+        while (!feof(f)) {
+            if (strlen(get_line(f,line,40))>0) {
+                // look for comment
+                if (line[0] != '#' ) {
+                    NWS_stations++;
+                    add_NWS_stations();
+                    if (NWS_station_data != NULL) {
+                        // add data
+                        // Note:  Size of string variable is 12
+                        // bytes, defined in igate.h
+                        if (1 != sscanf(line,"%11s",NWS_station_data[NWS_stations-1].call)) {
+                            fprintf(stderr,"load_NWS_stations: sscanf parsing error\n");
+                        }
+                        if (debug_level & 1024)
+                            fprintf(stderr,"LINE:%s\n",line);
+                    }
+                    else {
+                        fprintf(stderr,"Can't allocate data space for NWS station\n");
+                    }
+                }
+            }
+        }
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't open NWS stations file: %s\n", file);
+}
+
+
+
+
+
+// check NWS stations file
+//
+// call: call to check
+// returns 1 for found
+//
+// Both the incoming call and the stored call we're matching against
+// have to be >= 3 characters long.  This routine will match only up
+// to the length of the stored string, so we now allow partial
+// matches.
+//
+int check_NWS_stations(char *call) {
+    int ok, i, length, length_incoming;
+
+
+    if (call == NULL)
+        return(0);
+
+    if (call[0] == '\0')
+        return(0);
+
+    if (NWS_station_data == NULL)
+        return(0);
+
+    if (debug_level & 1024)
+        fprintf(stderr,"igate.c::check_NWS_stations %s\n", call);
+
+    // Make sure that the incoming call is longer than three
+    // characters.  If not, skip it.
+    length_incoming = strlen(call);
+    if (length_incoming < 3)
+        return(0);
+
+    ok=0;
+    for (i=0; i<NWS_stations && !ok; i++) {
+
+        // Compute length of stored string.  If it's shorter than
+        // three characters, skip it and go on to the next one.
+        length = strlen(NWS_station_data[i].call);
+
+        if (length >= 3) {
+            // Compare the incoming call only up to the length of the
+            // stored call.  This allows partial matches.  The
+            // stored call could be significantly shorter than the
+            // incoming call, but at least three characters.
+            if (strncasecmp(call, NWS_station_data[i].call, length)==0) {
+
+                ok=1; // match found 
+                if (debug_level & 1024) {
+                    fprintf(stderr,"NWS-MATCH:(%s) (%s)\n",NWS_station_data[i].call,call);
+                }
+            }
+        }
+        else {
+            // Do nothing.  Stored call is too short.
+        }
+    }
+    return(ok);
+}
+
+
+
+
+
+/****************************************************************/
+/* output NWS data to tnc interfaces                            */
+/* from: type of port heard from                                */
+/* call: call sign heard from                                   */
+/* line: data to gate to rf                                     */
+/* port: port data came from                                    */
+/****************************************************************/
+void output_nws_igate_rf(char *from, char *path, char *line, int port, int third_party) {
+    char temp[MAX_LINE_SIZE+20];
+    int x;
+    int first = 1;
+    char log_file_path[MAX_VALUE];
+    char nws_file_path[MAX_VALUE];
+
+
+    if ( (from == NULL) || (path == NULL) || (line == NULL) )
+        return;
+
+    if ( (from[0] == '\0') || (path[0] == '\0') || (line[0] == '\0') )
+        return;
+
+    // Should we Igate from NET->RF?
+    if (operate_as_an_igate <= 1)
+        return;
+
+    get_user_base_dir(LOGFILE_IGATE,log_file_path, sizeof(log_file_path));
+    get_user_base_dir("data/nws-stations.txt",nws_file_path, 
+                      sizeof(nws_file_path));
+
+    // Check for TCPXX in string!  If found, we have an
+    // unregistered net user.
+    // I removed the trailing asterisk --we7u
+    if (strstr(path,"TCPXX") != NULL) {
+        // "TCPXX" was found in the header.  We have an
+        // unregistered user.
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "NWS IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: Unregistered net user!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+    // no unregistered net user found in string.  Look for NOGATE
+    // next.
+
+    if ( strstr(path,"NOGATE") != NULL ) {
+        // "NOGATE" was found in the header.  Don't gate it.
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "NWS IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: NOGATE found in path!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+ 
+    // see if we can gate NWS messages
+    if (!filethere(nws_file_path)) {
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "NWS IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: No nws-stations.txt file!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return;
+    }
+
+    // check to see if the nws-stations file is newer than last read
+    if (last_nws_stations_file_time < file_time(nws_file_path)) {
+        last_nws_stations_file_time = file_time(nws_file_path);
+        load_NWS_stations(nws_file_path);
+        //fprintf(stderr,"NWS Station file time is old\n");
+    }
+
+    // Look for NWS station in file data
+    if (!check_NWS_stations(from) || !group_active(from)){ // Couldn't find the station
+
+        if (log_igate && (debug_level & 1024) ) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "NWS IGATE NET->RF(%c):%s\n",
+                third_party ? 'T':'N',
+                line);
+            log_data( log_file_path, temp );
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "REJECT: No matching station in nws-stations.txt file!\n");
+            log_data( log_file_path, temp );
+            fprintf(stderr, "%s", temp);
+        }
+        return; // Match for station not found in file
+    }
+
+    //fprintf(stderr,"SENDING NWS VIA TNC!!!!\n");
+    // write data out to interfaces
+    for (x=0; x<MAX_IFACE_DEVICES;x++) {
+
+//WE7U
+        // Check here against "heard" queue for each interface.
+        // Drop the packet on the floor if it was already received
+        // on this interface within the last XX seconds.  This means
+        // that some other igate beat us to the punch.  The receive
+        // routines have to fill this queue.  Prune outdated
+        // records.
+        //
+        // Also check here against "sent" queue for each interface.
+        // Drop the packet on the floor if already sent within the
+        // last XX seconds.  Add this packet to the queue if it
+        // isn't already in it.  Prune outdated records.
+        if (x != port
+                && not_a_dupe(HEARD, x, line, NO_FORCED_INSERT)
+                && not_a_dupe( SENT, x, line, NO_FORCED_INSERT) ) {
+
+            switch (port_data[x].device_type) {
+
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_AX25_TNC:
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                case DEVICE_NET_AGWPE:
+
+begin_critical_section(&devices_lock, "igate.c:output_nws_igate_rf" );
+
+                    if (devices[x].igate_options>1
+                            && port_data[x].status==DEVICE_UP) {
+
+                        // log traffic for first "up" interface only
+                        if (log_igate && first) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "NWS IGATE NET->RF(%c):%s\n",
+                                third_party ? 'T':'N',
+                                line);
+                            log_data( log_file_path, temp );
+                            first = 0;
+                        }
+
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "TRANSMIT: IGate NET->RF packet on device:%d\n",
+                            x);
+
+                        // log output
+                        if (log_igate)
+                            log_data( log_file_path, temp );
+
+                        if (debug_level & 1024)
+                            fprintf(stderr, "%s", temp);
+
+                        // ok write this data out to the RF port
+
+end_critical_section(&devices_lock, "igate.c:output_nws_igate_rf" );
+
+                        // First "0" means "cooked"
+                        // format, last digit: use
+                        // unproto_igate path
+                        output_my_data(line,x,0,0,1,NULL);
+
+begin_critical_section(&devices_lock, "igate.c:output_nws_igate_rf" );
+
+                    }
+                    else {
+                        if (log_igate && (debug_level & 1024) ) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "NWS IGATE NET->RF(%c):%s\n",
+                                third_party ? 'T':'N',
+                                line);
+                            log_data( log_file_path, temp );
+
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "REJECT: NET->RF on port [%d]!\n",
+                                x);
+                            log_data( log_file_path, temp );
+                            fprintf(stderr, "%s", temp);
+                        }
+                    }
+
+end_critical_section(&devices_lock, "igate.c:output_nws_igate_rf" );
+
+                   break;
+
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+
diff --git a/src/igate.h b/src/igate.h
new file mode 100644
index 0000000..dee05d8
--- /dev/null
+++ b/src/igate.h
@@ -0,0 +1,41 @@
+/*
+ * $Id: igate.h,v 1.13 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_IGATE_H
+#define __XASTIR_IGATE_H
+
+typedef struct {
+    char call[12];
+} NWS_Data;
+
+extern void igate_init(void);
+extern void insert_into_heard_queue(int port, char *line);
+extern void output_igate_net(char *line, int port, int third_party);
+extern void output_igate_rf(char *from, char *call, char *path, char *line, int port, int third_party, char *object_name);
+extern void output_nws_igate_rf(char *from, char *path, char *line, int port, int third_party);
+
+#endif  // __XASTIR_IGATE_H
+
+
diff --git a/src/interface.c b/src/interface.c
new file mode 100644
index 0000000..f5d5e94
--- /dev/null
+++ b/src/interface.c
@@ -0,0 +1,10181 @@
+/*
+ * $Id: interface.c,v 1.305 2012/10/23 00:37:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/*
+ AX.25 Parts adopted from: aprs_tty.c by Henk de Groot - PE1DNN
+*/
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <signal.h>
+#include <termios.h>
+#include <pwd.h>
+#include <termios.h>
+#include <setjmp.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#include <netinet/in.h>     // Moved ahead of inet.h as reports of some *BSD's not
+                            // including this as they should.
+#include <arpa/inet.h>
+#include <netinet/tcp.h>    // Needed for TCP_NODELAY setsockopt() (disabling Nagle algorithm)
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif  // HAVE_NETDB_H
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <errno.h>
+
+#ifdef  HAVE_LOCALE_H
+#include <locale.h>
+#endif  // HAVE_LOCALE_H
+
+#ifdef  HAVE_LIBINTL_H
+#include <libintl.h>
+#define _(x)        gettext(x)
+#else   // HAVE_LIBINTL_H
+#define _(x)        (x)
+#endif  // HAVE_LIBINTL_H
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "symbols.h"
+#include "main.h"
+#include "xa_config.h"
+//#include "maps.h"
+#include "interface.h"
+#include "util.h"
+#include "wx.h"
+#include "hostname.h"
+#include "x_spider.h"
+#include "db_gis.h"
+
+#ifdef HAVE_LIBAX25
+#include <netax25/ax25.h>
+#include <netrose/rose.h>
+#include <netax25/axlib.h>
+#include <netax25/axconfig.h>
+#endif  // HAVE_LIBAX25
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#ifndef SIGRET
+#define SIGRET  void
+#endif  // SIGRET
+
+
+//extern pid_t getpgid(pid_t pid);
+extern void port_write_binary(int port, unsigned char *data, int length);
+ 
+
+iodevices dtype[MAX_IFACE_DEVICE_TYPES]; // device names
+
+iface port_data[MAX_IFACE_DEVICES];     // shared port data
+
+int port_id[MAX_IFACE_DEVICES];         // shared port id data
+
+xastir_mutex port_data_lock;            // Protects the port_data[] array of structs
+xastir_mutex data_lock;                 // Protects incoming_data_queue
+xastir_mutex output_data_lock;          // Protects interface.c:channel_data() function only
+xastir_mutex connect_lock;              // Protects port_data[].thread_status and port_data[].connect_status
+
+void port_write_string(int port, char *data);
+
+int ax25_ports_loaded = 0;
+
+
+// Incoming data queue
+typedef struct _incoming_data_record {
+    int length;   // Used for binary strings such as KISS
+    int port;
+    unsigned char data[MAX_LINE_SIZE];
+} incoming_data_record;
+#define MAX_INPUT_QUEUE 1000
+static incoming_data_record incoming_data_queue[MAX_INPUT_QUEUE];
+unsigned char incoming_data_copy[MAX_LINE_SIZE];            // Used for debug
+unsigned char incoming_data_copy_previous[MAX_LINE_SIZE];   // Used for debug
+
+// interface wait time out
+int NETWORK_WAITTIME;
+
+
+
+
+
+// Read/write pointers for the circular input queue
+static int incoming_read_ptr = 0;
+static int incoming_write_ptr = 0;
+static int queue_depth = 0;
+static int push_count = 0;
+static int pop_count = 0;
+
+
+
+
+
+// Fetch a record from the circular queue.
+// Returns 0 if no records available
+// Else returns length of string, data_string and port
+// data_string variable should be of size MAX_LINE_SIZE
+//
+int pop_incoming_data(unsigned char *data_string, int *port) {
+    int length;
+    int jj;
+
+    if (begin_critical_section(&data_lock, "interface.c:pop_incoming_data" ) > 0)
+            fprintf(stderr,"data_lock\n");
+
+    // Check for queue empty
+    if (incoming_read_ptr == incoming_write_ptr) {
+        // Yep, it's empty
+
+//fprintf(stderr,"\n\t<- EMPTY!\n");
+
+        queue_depth = 0;
+ 
+        if (end_critical_section(&data_lock, "interface.c:pop_incoming_data" ) > 0)
+            fprintf(stderr,"data_lock\n");
+        return(0);
+    }
+
+    // Bump the read pointer
+    incoming_read_ptr = (incoming_read_ptr + 1) % MAX_INPUT_QUEUE;
+
+    *port = incoming_data_queue[incoming_read_ptr].port;
+
+    length = incoming_data_queue[incoming_read_ptr].length;
+
+    // This isn't safe for binary data.  It gets truncated at the
+    // first zero byte!
+    // xastir_snprintf((char *)data_string,
+    //     (length < MAX_LINE_SIZE) ? length : MAX_LINE_SIZE,
+    //     "%s",
+    //     incoming_data_queue[incoming_read_ptr].data);
+    //
+    // Binary safe code
+    for (jj = 0; jj < length; jj++) {
+        data_string[jj] = incoming_data_queue[incoming_read_ptr].data[jj];
+    }
+
+    // Add terminator, just in case
+    data_string[length+1] = '\0';
+
+    queue_depth--;
+    pop_count++;
+
+//if (push_count != pop_count)
+//    fprintf(stderr,"Pushes:%d\tPops:%d\n", push_count, pop_count);
+//else
+//    fprintf(stderr,"Pushes = \tPops\n");
+
+    // For DEBUG, to see if the queue how the queue is getting used
+//    if (queue_depth > 1) {
+//        fprintf(stderr,"%d\t", queue_depth);
+//    }
+
+//fprintf(stderr,"\n\t<- %s",data_string);
+
+    if (end_critical_section(&data_lock, "interface.c:pop_incoming_data" ) > 0)
+        fprintf(stderr,"data_lock\n");
+
+    return(length);
+}
+
+
+
+
+
+// Add one record to the circular queue.  Returns 1 if queue is
+// full, 0 if successful.
+//
+int push_incoming_data(unsigned char *data_string, int length, int port) {
+    int next_write_ptr = (incoming_write_ptr + 1) % MAX_INPUT_QUEUE;
+    int jj;
+
+
+    if (begin_critical_section(&data_lock, "interface.c:push_incoming_data" ) > 0)
+            fprintf(stderr,"data_lock\n");
+
+    // Check whether queue is full
+    if (incoming_read_ptr == next_write_ptr) {
+        // Yep, it's full!
+
+//fprintf(stderr,"\n-> FULL!");
+
+        if (end_critical_section(&data_lock, "interface.c:push_incoming_data" ) > 0)
+            fprintf(stderr,"data_lock\n");
+        return(1);
+    }
+
+//fprintf(stderr,"\n-> %s",data_string);
+
+
+    // Advance the write pointer
+    incoming_write_ptr = next_write_ptr;
+
+    incoming_data_queue[incoming_write_ptr].length = length;
+
+    incoming_data_queue[incoming_write_ptr].port = port;
+
+    // This isn't safe for binary data.  It gets truncated at the
+    // first zero byte!
+    // xastir_snprintf((char *)incoming_data_queue[incoming_write_ptr].data,
+    //     (length < MAX_LINE_SIZE) ? length : MAX_LINE_SIZE,
+    //     "%s",
+    //     data_string);
+    //
+    // Binary safe
+    for (jj = 0; jj < length; jj++) {
+        incoming_data_queue[incoming_write_ptr].data[jj] = data_string[jj];
+    }
+
+    queue_depth++;
+    push_count++;
+
+    if (end_critical_section(&data_lock, "interface.c:push_incoming_data" ) > 0)
+        fprintf(stderr,"data_lock\n");
+
+    return(0);
+}
+
+
+
+
+
+// Returns 1 if a local interface, 0 otherwise
+//
+int is_local_interface(int port) {
+
+    switch (port_data[port].device_type) {
+
+        case DEVICE_SERIAL_TNC:
+        case DEVICE_SERIAL_TNC_HSP_GPS:
+        case DEVICE_SERIAL_GPS:
+        case DEVICE_SERIAL_WX:
+        case DEVICE_AX25_TNC:
+        case DEVICE_SERIAL_TNC_AUX_GPS:
+        case DEVICE_SERIAL_KISS_TNC:
+        case DEVICE_SERIAL_MKISS_TNC:
+            return(1);  // Found a local interface
+            break;
+
+        // Could be port -1 which signifies a spider port or port
+        // -99 which signifies "All Ports" and is used for
+        // transmitting out all ports at once.
+        default:
+            return(0);  // Unknown or network interface
+            break;
+    }
+}
+
+
+
+
+
+// Returns 1 if a network interface, 0 otherwise
+//
+int is_network_interface(int port) {
+
+    switch (port_data[port].device_type) {
+
+        case DEVICE_NET_STREAM:
+        case DEVICE_NET_GPSD:
+        case DEVICE_NET_WX:
+        case DEVICE_NET_DATABASE:
+        case DEVICE_NET_AGWPE:
+            return(1);  // Found a network interface
+            break;
+
+        // Could be port -1 which signifies a spider port or port
+        // -99 which signifies "All Ports" and is used for
+        // transmitting out all ports at once.
+        default:
+            return(0);  // Unknown or local interface
+            break;
+    }
+}
+
+
+
+
+
+
+// Create a packet and send to AGWPE for transmission.
+// Format is as follows:
+//
+//  RadioPort     4 bytes (0-3)
+//  DataType      4 bytes (4-7)
+//  FromCall     10 bytes (8-17)
+//  ToCall       10 bytes (18-27)
+//  DataLength    4 bytes (28-31)
+//  UserField     4 bytes (32-35)
+//  Data         DataLength bytes (36-?)
+//
+// Callsigns are null-terminated at end of string, but callsign
+// field width is specified to be 10 bytes in all cases.
+//
+// Path is split up into the various ViaCalls.  Path may also be a
+// NULL pointer.
+//
+// If type != '\0', then we'll create the specified type of packet.
+//
+// Else if Path is not empty, we'll use packet format "V" with
+// Viacalls prepended to the Data portion of the packet, 10 chars
+// per digi, with the number of digis as the first character.  The
+// packet data then follows after the last via callsign.
+//
+// Else if no Path, then put the Data directly into the Data
+// field and use "M" format packets.
+//
+// We currently use the base portion of my_callsign as the username
+// portion of the AGWPE login.  This must be upper-case when you're
+// setting up the account in AGWPE, as that's what we send to
+// authenticate.
+//
+void send_agwpe_packet(int xastir_interface,// Xastir interface port
+                       int RadioPort,       // AGWPE RadioPort
+                       unsigned char type,
+                       unsigned char *FromCall,
+                       unsigned char *ToCall,
+                       unsigned char *Path,
+                       unsigned char *Data,
+                       int length) {
+    int ii;
+#define agwpe_header_size 36
+    unsigned char output_string[512+agwpe_header_size];
+    unsigned char path_string[200];
+    int full_length;
+    int data_length;
+
+
+/*
+fprintf(stderr,"Sending to AGWPE RadioPort %d, ", RadioPort);
+fprintf(stderr,"Type:%c, From:%s, To:%s, Path:%s, Data:%s\n",
+    type, FromCall, ToCall, Path, Data);
+*/
+
+    // Check size of data
+    if (length > 512)
+        return;
+
+    // Clear the output_string (set to binary zeroes)
+    for (ii = 0; ii < (int)sizeof(output_string); ii++) {
+        output_string[ii] = '\0';
+    }
+
+    if (type != 'P') {
+        // Write the port number into the frame.  Note that AGWPE
+        // uses 1 for the first port in its GUI, but the programming
+        // interface starts at 0.
+        output_string[0] = (unsigned char)RadioPort;
+
+        if (FromCall)   // Write the FromCall string into the frame
+            xastir_snprintf((char *)&output_string[8],
+                sizeof(output_string) - 8,
+                "%s",
+                FromCall);
+
+        if (ToCall) // Write the ToCall string into the frame
+            xastir_snprintf((char *)&output_string[18],
+                sizeof(output_string) - 18,
+                "%s",
+                ToCall);
+    }
+
+    if ( (type != '\0') && (type != 'P') ) {
+        // Type was specified, not a data frame or login frame
+
+        // Write the type character into the frame
+        output_string[4] = type;
+
+        // Send the packet to AGWPE
+        port_write_binary(xastir_interface,
+            output_string,
+            agwpe_header_size);
+    }
+ 
+    else if (Path == NULL) { // No ViaCalls, Data or login packet
+
+        if (type == 'P') {
+            // Login/Password frame
+            char callsign_base[15];
+            int new_length;
+
+
+            // Write the type character into the frame
+            output_string[4] = type;
+
+            // Compute the callsign base string
+            // (callsign minus SSID)
+            xastir_snprintf(callsign_base,
+                sizeof(callsign_base),
+                "%s",
+                my_callsign);
+            // Change '-' into end of string
+            strtok(callsign_base, "-");
+
+            // Length = length of each string plus the two
+            // terminating zeroes.
+            //new_length = strlen(callsign_base) + length + 2;
+            new_length = 255+255;
+
+            output_string[28] = (unsigned char)(new_length % 256);
+            output_string[29] = (unsigned char)((new_length >> 8) % 256);
+
+/*
+fprintf(stderr,"Length bytes:  %02x %02x %02x %02x\n",
+    output_string[28],
+    output_string[29],
+    output_string[30],
+    output_string[31]);
+*/
+
+// Write login/password out as 255-byte strings each
+
+            // Put the login string into the buffer
+            xastir_snprintf((char *)&output_string[agwpe_header_size],
+                sizeof(output_string) - agwpe_header_size,
+                "%s",
+                callsign_base);
+
+            // Put the password string into the buffer
+            xastir_snprintf((char *)&output_string[agwpe_header_size+255],
+                sizeof(output_string) - agwpe_header_size - 255,
+                "%s",
+                Data);
+
+//fprintf(stderr,"AGWPE User:%s,  Pass:%s\n",callsign_base, Data);
+
+            // Send the packet to AGWPE
+            port_write_binary(xastir_interface,
+                output_string,
+                255+255+agwpe_header_size);
+        }
+        else {  // Data frame
+            // Write the type character into the frame
+            output_string[4] = 'M'; // Unproto, no via calls
+
+            // Write the PID type into the frame
+            output_string[6] = 0xF0;    // UI Frame
+
+            output_string[28] = (unsigned char)(length % 256);
+            output_string[29] = (unsigned char)((length >> 8) % 256);
+
+/*
+fprintf(stderr,"Length bytes:  %02x %02x %02x %02x\n",
+    output_string[28],
+    output_string[29],
+    output_string[30],
+    output_string[31]);
+*/
+
+            // Copy Data onto the end of the string.  This one
+            // doesn't have to be null-terminated, so strncpy() is
+            // ok to use here.  strncpy stops at the first null byte
+            // though.  Proper for a binary output routine?  NOPE!
+            strncpy((char *)(&output_string[agwpe_header_size]),(char *)Data, length);
+
+            full_length = length + agwpe_header_size;
+
+            // Send the packet to AGWPE
+            port_write_binary(xastir_interface,
+                output_string,
+                full_length);
+
+//fprintf(stderr, "Sent: %s\n", Data);
+
+        }
+    }
+
+    else {  // We have ViaCalls.  Data packet.
+        char *ViaCall[10];
+
+        // Doesn't need to be null-terminated, so strncpy is ok to
+        // use here.  strncpy stops at the first null byte though.
+        // Proper for a binary output routine?  NOPE!
+        strncpy((char *)path_string, (char *)Path, sizeof(path_string));
+
+        // Convert path_string to upper-case
+        to_upper((char *)path_string);
+
+//fprintf(stderr,"path_string: %s\n", path_string);
+
+        split_string((char *)path_string, ViaCall, 10, ',');
+
+        // Write the type character into the frame
+        output_string[4] = 'V'; // Unproto, via calls present
+
+        // Write the PID type into the frame
+        output_string[6] = 0xF0;    // UI Frame
+
+        // Write the number of ViaCalls into the first byte
+        if (ViaCall[7]) {
+//fprintf(stderr, "Eight viacalls\n");
+            output_string[agwpe_header_size] = 0x08;
+        }
+        else if (ViaCall[6]) {
+//fprintf(stderr, "Seven viacalls\n");
+            output_string[agwpe_header_size] = 0x07;
+        }
+        else if (ViaCall[5]) {
+//fprintf(stderr, "Six viacalls\n");
+            output_string[agwpe_header_size] = 0x06;
+        }
+        else if (ViaCall[4]) {
+//fprintf(stderr, "Five viacalls\n");
+            output_string[agwpe_header_size] = 0x05;
+        }
+        else if (ViaCall[3]) {
+//fprintf(stderr, "Four viacalls\n");
+            output_string[agwpe_header_size] = 0x04;
+        }
+        else if (ViaCall[2]) {
+//fprintf(stderr, "Three viacalls\n");
+            output_string[agwpe_header_size] = 0x03;
+        }
+        else if (ViaCall[1]) {
+//fprintf(stderr, "Two viacalls\n");
+            output_string[agwpe_header_size] = 0x02;
+        }
+        else {
+//fprintf(stderr, "One viacall\n");
+            output_string[agwpe_header_size] = 0x01;
+        }
+ 
+        // Write the ViaCalls into the Data field
+        switch (output_string[agwpe_header_size]) {
+            case 8:
+                if (ViaCall[7]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+70]), ViaCall[7], 10);
+//fprintf(stderr, "%s\n", ViaCall[7]);
+                }
+                else
+                    return;
+            case 7:
+                if (ViaCall[6]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+60]), ViaCall[6], 10);
+//fprintf(stderr, "%s\n", ViaCall[6]);
+                }
+                else
+                    return;
+            case 6:
+                if (ViaCall[5]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+50]), ViaCall[5], 10);
+//fprintf(stderr, "%s\n", ViaCall[5]);
+                }
+                else
+                    return;
+            case 5:
+                if (ViaCall[4]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+40]), ViaCall[4], 10);
+//fprintf(stderr, "%s\n", ViaCall[4]);
+                }
+                else
+                    return;
+            case 4:
+                if (ViaCall[3]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+30]), ViaCall[3], 10);
+//fprintf(stderr, "%s\n", ViaCall[3]);
+                }
+                else
+                    return;
+            case 3:
+                if (ViaCall[2]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+20]), ViaCall[2], 10);
+//fprintf(stderr, "%s\n", ViaCall[2]);
+                }
+                else
+                    return;
+            case 2:
+                if (ViaCall[1]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+10]), ViaCall[1], 10);
+//fprintf(stderr, "%s\n", ViaCall[1]);
+                }
+                else
+                    return;
+            case 1:
+            default:
+                if (ViaCall[0]) {
+                    strncpy((char *)(&output_string[agwpe_header_size+1+0]),  ViaCall[0], 10);
+//fprintf(stderr, "%s\n", ViaCall[0]);
+                }
+                else
+                    return;
+                break;
+        }
+
+        // Write the Data onto the end.
+        // Doesn't need to be null-terminated, so strncpy is ok to
+        // use here.  strncpy stops at the first null byte though.
+        // Proper for a binary output routine?
+        strncpy((char *)(&output_string[((int)(output_string[agwpe_header_size]) * 10) + agwpe_header_size + 1]),
+            (char *)Data,
+            length);
+
+        //Fill in the data length field.  We're assuming the total
+        //is less than 512 + 37.
+        data_length = length + ((int)(output_string[agwpe_header_size]) * 10) + 1;
+
+//fprintf(stderr, "Via calls: %d\n",
+//(int)(output_string[agwpe_header_size]));
+//fprintf(stderr, "Length: %d\n", length);
+//fprintf(stderr, "Data Length: %d\n", data_length);
+
+        if ( data_length > 512 )
+            return;
+
+        output_string[28] = (unsigned char)(data_length % 256);
+        output_string[29] = (unsigned char)((data_length >> 8) % 256);
+
+/*
+fprintf(stderr,"Length bytes:  %02x %02x %02x %02x\n",
+    output_string[28],
+    output_string[29],
+    output_string[30],
+    output_string[31]);
+*/
+
+        full_length = data_length + agwpe_header_size;
+
+        // Send the packet to AGWPE
+        port_write_binary(xastir_interface,
+            output_string,
+            full_length);
+
+//fprintf(stderr, "Data: %s\n", Data);
+
+    }
+}
+
+
+
+
+
+/*
+// Here is a "monitor" UI packet
+//
+Total Length = 150
+HEX:00 00 00 00 55 00 00 00 4b 4b 31 57 00 ed 12 00 96 ed 41 50 54
+57 30 31 00 00 00 00 72 00 00 00 00 00 00 00 20 31 3a 46 6d 20 4b 4b
+31 57 20 54 6f 20 41 50 54 57 30 31 20 56 69 61 20 57 49 44 45 33 20
+3c 55 49 20 70 69 64 3d 46 30 20 4c 65 6e 3d 35 30 20 3e 5b 31 30 3a
+34 33 3a 34 33 5d 0d 5f 30 38 30 36 31 30 33 39 63 33 35 39 73 30 30
+30 67 30 30 30 74 30 36 32 72 30 30 30 70 30 30 33 50 30 39 36 68 30
+30 62 31 30 30 39 33 74 55 32 6b 0d 0d 00 
+ASC:....U...KK1W......APTW01....r....... 1:Fm KK1W To APTW01 Via WIDE3 <UI pid=F0 Len=50 >[10:43:43]._08061039c359s000g000t062r000p003P096h00b10093tU2k...
+*/
+
+/*
+// And here are some "raw" UI packets
+//
+AGWPE: Got raw frame packet
+3:2e
+Bad KISS packet.  Dropping it.
+Total Length = 135
+HEX:00 00 00 00 4b 00 00 00 4e 32 4c 42 54 2d 37 00 01 00 41 50 58
+31 33 33 00 00 00 00 63 00 00 00 00 00 00 00
+
+c0 82 a0 b0 62 66 66 60
+9c 64 98 84 a8 40 6e 96 82 64 a2 b2 8a f4 ae 92 88 8a 40 40 61 03 f0
+40 30 37 30 30 32 37 7a 34 32 33 39 2e 30 34 4e 5c 30 37 33 34 38 2e
+31 30 57 5f 30 30 30 2f 30 30 30 67 30 30 30 74 30 36 34 72 30 30 30
+50 30 30 30 70 30 30 30 68 35 33 62 31 30 31 32 37 58 55 32 6b 0d 
+ASC:....K...N2LBT-7...APX133....c...........bff`.d... at n..d........@@a.. at 070027z4239.04N\07348.10W_000/000g000t064r000P000p000h53b10127XU2k.
+AGWPE: Got raw frame packet
+3:23
+Bad KISS packet.  Dropping it.
+Total Length = 104
+HEX:00 00 00 00 4b 00 00 00 4e 31 45 44 5a 2d 37 00 01 00 54 52 31
+55 37 58 00 00 00 00 44 00 00 00 00 00 00 00
+
+c0 a8 a4 62 aa 6e b0 60
+9c 62 8a 88 b4 40 ee 96 82 62 a2 8c 8a fe ae 62 a8 9e 9a 40 fe 96 82
+64 a2 b2 8a f5 03 f0 60 64 2a 39 6c 23 22 3e 2f 3e 22 35 6b 7d 6e 31
+65 64 7a 40 61 6d 73 61 74 2e 6f 72 67 0d 
+ASC:....K...N1EDZ-7...TR1U7X....D..........b.n.`.b... at ...b.....b...@...d......`d*9l#">/>"5k}n1edz at amsat.org.
+AGWPE: Got raw frame packet
+3:2e
+Bad KISS packet.  Dropping it.
+Total Length = 103
+HEX:00 00 00 00 4b 00 00 00 4b 32 52 52 54 2d 39 00 01 00 41 50 54
+33 31 31 00 00 00 00 43 00 00 00 00 00 00 00
+
+c0 82 a0 a8 66 62 62 60
+96 64 a4 a4 a8 40 72 ae 82 64 aa 9a b0 e4 ae 92 88 8a 40 40 61 03 f0
+21 34 33 31 39 2e 37 39 4e 2f 30 37 33 34 30 2e 38 37 57 3e 32 36 38
+2f 30 32 30 2f 41 3d 30 30 30 34 38 35 
+ASC:....K...K2RRT-9...APT311....C...........fbb`.d... at r..d........@@a..!4319.79N/07340.87W>268/020/A=000485
+AGWPE: Got raw frame packet
+3:74
+Bad KISS packet.  Dropping it.
+Total Length = 82
+HEX:00 00 00 00 4b 00 00 00 4b 32 52 52 54 2d 39 00 01 00 41 50 54
+33 31 31 00 00 00 00 2e 00 00 00 00 00 00 00
+
+c0 82 a0 a8 66 62 62 60
+96 64 a4 a4 a8 40 72 ae 64 8e ae b2 40 e4 ae 82 64 aa 9a b0 e5 03 f0
+3e 6e 32 79 71 74 40 61 72 72 6c 2e 6e 65 74 
+ASC:....K...K2RRT-9...APT311................fbb`.d... at r.d...@...d......>n2yqt at arrl.net
+AGWPE: Got raw frame packet
+3:2e
+Bad KISS packet.  Dropping it.
+Total Length = 103
+HEX:00 00 00 00 4b 00 00 00 4b 32 52 52 54 2d 39 00 01 00 41 50 54
+33 31 31 00 00 00 00 43 00 00 00 00 00 00 00
+
+c0 82 a0 a8 66 62 62 60
+96 64 a4 a4 a8 40 72 ae 64 8e ae b2 40 e4 96 82 64 a2 b2 8a f5 03 f0
+21 34 33 31 39 2e 37 39 4e 2f 30 37 33 34 30 2e 38 37 57 3e 32 36 38
+2f 30 32 30 2f 41 3d 30 30 30 34 38 35 
+ASC:....K...K2RRT-9...APT311....C...........fbb`.d... at r.d...@...d......!4319.79N/07340.87W>268/020/A=000485
+AGWPE: Got raw frame packet
+3:74
+Bad KISS packet.  Dropping it.
+Total Length = 82
+HEX:00 00 00 00 4b 00 00 00 4b 32 52 52 54 2d 39 00 01 00 41 50 54
+33 31 31 00 00 00 00 2e 00 00 00 00 00 00 00
+
+c0 82 a0 a8 66 62 62 60
+96 64 a4 a4 a8 40 72 ae 64 8e ae b2 40 e4 96 82 64 a2 b2 8a f5 03 f0
+3e 6e 32 79 71 74 40 61 72 72 6c 2e 6e 65 74 
+ASC:....K...K2RRT-9...APT311................fbb`.d... at r.d...@...d......>n2yqt at arrl.net
+AGWPE: Got raw frame packet
+3:2e
+Bad KISS packet.  Dropping it.
+Total Length = 103
+HEX:00 00 00 00 4b 00 00 00 4b 32 52 52 54 2d 39 00 01 00 41 50 54
+33 31 31 00 00 00 00 43 00 00 00 00 00 00 00
+
+c0 82 a0 a8 66 62 62 60
+96 64 a4 a4 a8 40 72 ae 82 64 aa 9a b0 e4 96 82 64 a2 b2 8a f5 03 f0
+21 34 33 31 39 2e 37 39 4e 2f 30 37 33 34 30 2e 38 37 57 3e 32 36 38
+2f 30 32 30 2f 41 3d 30 30 30 34 38 35 
+ASC:....K...K2RRT-9...APT311....C...........fbb`.d... at r..d......d......!4319.79N/07340.87W>268/020/A=000485
+*/
+
+
+// Parse an AGWPE header.  Create a TAPR-2 style header out of the
+// data for feeding into the Xastir parsing code.  Input format is
+// as follows:
+//
+//  RadioPort     4 bytes (0-3)
+//  DataType      4 bytes (4-7)
+//  FromCall     10 bytes (8-17)
+//  ToCall       10 bytes (18-27)
+//  DataLength    4 bytes (28-31)
+//  UserField     4 bytes (32-35)
+//  Data         xx bytes (36-??)
+//
+// Callsigns are null-terminated at end of string, but field width
+// is specified to be 10 bytes in all cases.
+//
+// output_string variable should be quite long, perhaps 1000
+// characters.
+//
+// Someday it would be nice to turn on raw packet format in AGWPE
+// which gives us the AX.25 packet format directly.  We should be
+// able to use our normal KISS decoding functions to parse those
+// types of packets, instead of the mess we have below which is
+// parsing a few things out of the header, a few things out of the
+// text that AGWPE puts after the header, and then snagging the info
+// field of the packet from the tail-end.
+//
+unsigned char *parse_agwpe_packet(unsigned char *input_string,
+                                  int output_string_length,
+                                  unsigned char *output_string,
+                                  int *new_length) {
+    int ii, jj, kk;
+    char *info_ptr;
+    char *via_ptr;
+    char temp_str[512];
+    int special_debug = 0;
+    int data_length;
+
+
+    // Fetch the length of the data portion of the packet
+    data_length = (unsigned char)(input_string[31]);
+    data_length = (data_length << 8) + (unsigned char)(input_string[30]);
+    data_length = (data_length << 8) + (unsigned char)(input_string[29]);
+    data_length = (data_length << 8) + (unsigned char)(input_string[28]);
+
+    // Implementing some special debugging output for the case of
+    // third-party NWS messages, which so far haven't been parsed
+    // properly by this function.
+    //
+    // Check for NWS string past the header part of the AGWPE
+    // packet.
+    //
+
+// Check the data_length here to make sure we don't run off the end.
+//    if (strstr(&input_string[36],"NWS-") || strstr(&input_string[36],"NWS_")) {
+//        special_debug = 1;
+//    }
+
+
+    // Make sure we have a terminating '\0' at the end.
+// Note that this doesn't help for binary packets (like OpenTrac),
+// but doesn't really hurt either.
+    input_string[38+data_length] = '\0';
+
+ 
+    // Check what sort of AGWPE packet it is.
+    switch (input_string[4]) {
+
+        case 'R':
+            //fprintf(stderr,"AGWPE: Got software version packet\n");
+            if (data_length == 8) { 
+                fprintf(stderr,
+                    "\nConnected to AGWPE server, version: %d.%d\n",
+                    (input_string[37] << 8) + input_string[36],
+                    (input_string[41] << 8) + input_string[40]);
+            }
+            return(NULL);   // All done!
+            break;
+
+        case 'G':
+            //fprintf(stderr,"AGWPE: Got port information packet\n");
+
+            // Print out the data, changing all ';' characters to
+            // <CR> and a bunch of spaces to format it nicely.
+            fprintf(stderr, "    Port Info, total ports = ");
+            ii = 36;
+            while (ii < data_length + 36 && input_string[ii] != '\0') {
+                if (input_string[ii] == ';')
+                    fprintf(stderr, "\n    ");
+                else
+                    fprintf(stderr, "%c", input_string[ii]);
+                ii++;
+            }
+            fprintf(stderr,"\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'g':
+            //fprintf(stderr,"AGWPE: Got port capabilities packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'X':
+            //fprintf(stderr,"AGWPE: Got callsign registration results packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'y':
+            //fprintf(stderr,"AGWPE: Got outstanding frames on port packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'Y':
+            //fprintf(stderr,"AGWPE: Got outstanding frames on connection packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'H':
+            //fprintf(stderr,"AGWPE: Got heard stations on port packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'C':
+            //fprintf(stderr,"AGWPE: Got connection results packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'v':
+            //fprintf(stderr,"AGWPE: Got v packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'c':
+            //fprintf(stderr,"AGWPE: Got c packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'D':
+            //fprintf(stderr,"AGWPE: Got connected data packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'd':
+            //fprintf(stderr,"AGWPE: Got disconnection results packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'U':
+            //fprintf(stderr,"AGWPE: Got UI data packet\n");
+            // We can decode this one ok in the below code (after
+            // this switch statement), but we no longer use
+            // "monitor" mode packets in AGWPE, switching to the
+            // "raw" mode instead.
+            return(NULL);   // All done!
+            break;
+
+        case 'I':
+            //fprintf(stderr,"AGWPE: Got connected information data packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'S':
+            //fprintf(stderr,"AGWPE: Got supervisory frame packet\n");
+            return(NULL);   // All done!
+            break;
+
+        case 'T':
+            //fprintf(stderr,"AGWPE: Got our own transmitted packet back\n");
+            //fprintf(stderr, "%s\n", &input_string[37]);
+            // We should decode this one ok in the below code (after
+            // this switch statement), but we no longer use
+            // "monitor" mode packets in AGWPE, switching to the
+            // "raw" mode instead.
+            return(NULL);   // All done!
+            break;
+
+        case 'K':
+            //fprintf(stderr,"AGWPE: Got raw frame packet\n");
+
+            // Code here processes the packet for handing to our
+            // KISS decoding routines.  Chop off the header, add
+            // anything to the beginning/end that we need, then send
+            // it to decode_ax25_header().
+
+            // Try to decode header and checksum.  If bad, break,
+            // else continue through to ASCII logging & decode
+            // routines.  We skip the first byte as it's not part of
+            // the AX.25 packet.
+            //
+            // Note that the packet length often increases here in
+            // decode_ax25_header, as we add '*' characters and such
+            // to the header as it's decoded.
+
+            // This string already has a terminator on the end,
+            // added by the code in port_read().  If we didn't have
+            // one here, we could end up with portions of strings
+            // concatenated on the end of our string by the time
+            // we're done processing the data here.
+            //
+//            input_string[data_length+36] = '\0';
+
+
+// WE7U:
+// We may need to extend input_string by a few characters before it
+// is fed to us.  Something like max_callsigns * 3 or 4 characters,
+// to account for '*' and SSID characters that we might add.  This
+// keeps the string from getting truncated as we add bytes to the
+// header in decode_ax25_header.
+
+
+            if ( !decode_ax25_header( (unsigned char *)&input_string[37], &data_length ) ) {
+//                int zz;
+
+                // Had a problem decoding it.  Drop it on the floor.
+                fprintf(stderr, "AGWPE: Bad KISS packet.  Dropping it.\n");
+
+special_debug++;
+//                for (zz = 0; zz < data_length; zz++) {
+//                    fprintf(stderr, "%02x ", input_string[zz+36]);
+//                }
+//                fprintf(stderr,"\n");
+
+                return(NULL);
+            }
+
+            // Good header.  Compute the new length, again skipping
+            // the first byte.
+            data_length = strlen((const char *)&input_string[37]);
+ 
+// The above strlen() requires it to be printable ascii in the KISS
+// packet, so won't work for OpenTrac protocol or other binary
+// protocols.  The decode_ax25_header() function also looks for
+// PID=0xF0, which again won't work for OpenTrac.  It would be
+// better to have the decode_ax25_header routine return the new
+// length of the packet so that decoding of binary packets is still
+// possible.
+
+// Check for OpenTrac packets.  If found, dump them into
+// OpenTrac-specific decode and skip the other decode below.  Must
+// tweak the above stuff to allow binary-format packets to get
+// through to this point.
+
+            // Do more stuff with the packet here.  The actual
+            // packet itself starts at offset 37.  We can end up
+            // with 0x0d, 0x0d 0x0d, or 0x0d 0x00 0x0d on the end of
+            // it (or none of the above).  Best method should be to
+            // just search for any 0x0d's or 0x0a's starting at the
+            // beginning of the string and overwrite them with
+            // 0x00's.  That's what we do here.
+            //
+            for (ii = 0; ii < data_length; ii++) {
+                if (input_string[ii+37] == 0x0d
+                        || input_string[ii+37] == 0x0a)
+                    input_string[ii+37] = '\0';
+            }
+
+            // Compute data_length again.
+            data_length = strlen((const char *)&input_string[37]);
+
+            // Send the processed string back for decoding
+            xastir_snprintf((char *)output_string,
+                output_string_length,
+                "%s",
+                &input_string[37]);
+ 
+            // Send back the new length. 
+            *new_length = data_length;
+
+            return(output_string);
+            break;
+
+        default:
+            fprintf(stderr,"AGWPE: Got unrecognized '%c' packet\n",input_string[4]);
+            return(NULL);   // All done!
+            break;
+    }
+
+
+// NOTE:  All of the code below gets used in "monitor" mode, which
+// we no longer use.  We might keep this code around for a bit and
+// then delete it, as we've probably switched to "raw" mode for
+// good.  "raw" mode allows us to use our KISS processing routines,
+// plus allows us to support digipeating and OpenTrac (binary)
+// protocol in the future.
+
+
+    if (special_debug) {
+        // Dump the hex & ascii representation of the whole packet
+ 
+        kk = data_length + 36; // Add the header length
+        fprintf(stderr, "Total Length = %d\n", kk);
+
+        fprintf(stderr, "HEX:");
+        for (ii = 0; ii < kk; ii++) {
+            fprintf(stderr, "%02x ", input_string[ii]);
+        }
+        fprintf(stderr, "\n");
+
+        fprintf(stderr, "ASC:");
+        for (ii = 0; ii < kk; ii++) {
+            if (input_string[ii] < ' ' || input_string[ii] > '~')
+                fprintf(stderr, ".");
+            else
+                fprintf(stderr, "%c", input_string[ii]);
+        }
+        fprintf(stderr, "\n");
+    }
+
+    // Clear the output_string (set to binary zeroes)
+    for (ii = 0; ii < output_string_length; ii++) {
+        output_string[ii] = '\0';
+    }
+
+    jj = 0;
+
+    // Copy the source callsign
+    ii = 8;
+    while (input_string[ii] != '\0') {
+        output_string[jj++] = input_string[ii++];
+    }
+
+    // Add a '>' character
+    output_string[jj++] = '>';
+
+    // Copy the destination callsign
+    ii = 18;
+    while (input_string[ii] != '\0') {
+        output_string[jj++] = input_string[ii++];
+    }
+
+    // Search for "]" (0x5d) which is the end of the header string,
+    // beginning of the AX.25 information field.
+    info_ptr = strstr((const char *)&input_string[36], "]");
+
+    // If not found, we can't process anymore
+    if (!info_ptr) {
+        output_string[0] = '\0';
+        new_length = 0;
+        return(NULL);
+    }
+
+    // Copy the first part of the string into a variable.  We'll
+    // look for Via calls in this string, if present.
+    ii = 36;
+    temp_str[0] = '\0';
+
+    while (input_string[ii] != ']') {
+      strncat(temp_str, (char *)(&input_string[ii++]), 1);
+    }
+
+    // Make sure that the protocol ID is "F0".  If not, return.
+    if (strstr(temp_str, "pid=F0") == NULL) {
+        char *pid_ptr;
+
+        // Look for the "pid=" string and print out what we can
+        // figure out about the protocol ID.
+        pid_ptr = strstr(temp_str, "pid=");
+        if (pid_ptr) {
+            pid_ptr +=4;
+            fprintf(stderr,
+                "parse_agwpe_packet: Non-APRS protocol was seen: PID=%2s.  Dropping the packet.\n",
+                pid_ptr);
+        }
+        else {
+            fprintf(stderr,
+                "parse_agwpe_packet: Non-APRS protocol was seen.  Dropping the packet.\n");
+        }
+        output_string[0] = '\0';
+        new_length = 0;
+        return(NULL);
+    }
+
+    // Search for "Via" in temp_str
+    via_ptr = strstr(temp_str, "Via");
+
+    if (via_ptr) {
+        // Found some Via calls.  Copy them into our output string.
+
+        // Add a comma first
+        output_string[jj++] = ',';
+
+        // Skip past "Via " portion of string
+        via_ptr += 4;
+
+        // Copy the string across until we hit a space
+        while (via_ptr[0] != ' ') {
+            output_string[jj++] = via_ptr[0];
+            via_ptr++;
+        }
+    }
+
+    // Add a ':' character
+    output_string[jj++] = ':';
+
+    // Move the pointer past the "]<CR>" to the real info part of the
+    // packet.
+    info_ptr++;
+    info_ptr++;
+
+    // Copy the info field to the output string
+    while (info_ptr[0] != '\0') {
+      strncat((char *)output_string, &info_ptr[0], 1);
+      info_ptr++;
+    }
+
+    // We end up with 0x0d characters on the end.  Get rid of them.
+    // The strtok() function will overwrite the first one found with
+    // a '\0' character.
+    (void)strtok((char *)output_string, "\n");
+    (void)strtok((char *)output_string, "\r");
+
+    *new_length = strlen((const char *)output_string);
+
+    if (special_debug) {
+        // Print out the resulting string
+        fprintf(stderr,"AGWPE RX: %s\n", output_string);
+        fprintf(stderr,"new_length: %d\n",*new_length);
+        for (ii = 0; ii < (int)strlen((const char *)output_string); ii++) {
+            fprintf(stderr,"%02x ",output_string[ii]);
+        }
+        fprintf(stderr,"\n");
+    }
+
+    return(output_string);
+}
+
+/*
+Found complete AGWPE packet, 93 bytes total in frame:
+00 00 00 00
+55 00 00 00                     'U' Packet
+57 45 37 55 2d 33 00 00 ff ff   WE7U-3
+41 50 52 53 00 20 ec e9 6c 00   APRS
+39 00 00 00                     Length
+00 00 00 00
+
+20 31                           .1 (36-37)
+3a 46 6d 20                     :Fm (38-41)
+57 45 37 55 2d 33               WE7U-3 (42-space)
+20 54 6f                        .To
+20 41 50 52 53                  .APRS
+20 3c 55 49                     .<UI
+20 70 69 64 3d 46 30            .pid=F0
+20 4c 65 6e 3d 34               .Len=4
+20 3e 5b 32 33 3a 31 33 3a 32 30 5d 0d  >[23:13:20].
+54 65 73 74 0d 0d 00            Test<CR><CR>.
+....U...WE7U-3....APRS. ..l.9....... 1:Fm WE7U-3 To APRS <UI pid=F0 Len=4 >[23:13:20].Test...
+
+1:Fm WE7U-3 To APRS Via RELAY,SAR1-1,SAR2-1,SAR3-1,SAR4-1,SAR5-1,SAR6-1,SAR7-1 <UI pid=F0 Len=26 >[23:51:46].Testing this darned thing!...
+*/
+
+
+
+
+
+//****************************************************************
+// get device name only (the portion at the end of the full path)
+// device_name current full name of device
+//****************************************************************
+
+char *get_device_name_only(char *device_name) {
+    int i,len,done;
+
+    if (device_name == NULL)
+        return(NULL);
+
+    done = 0;
+    len = (int)strlen(device_name);
+    for(i = len; i > 0 && !done; i--){
+        if(device_name[i] == '/'){
+            device_name += (i+1);
+            done = 1;
+        }
+    }
+    return(device_name);
+}
+
+
+
+
+
+//***********************************************************
+// Get Open Device
+//
+// if device is available this will return the port #
+// otherwise a -1 will be returned in error.
+//***********************************************************
+int get_open_device(void) {
+    int i, found;
+
+begin_critical_section(&devices_lock, "interface.c:get_open_device" );
+
+    found = -1;
+    for(i = 0; i < MAX_IFACE_DEVICES && found == -1; i++) {
+        if (devices[i].device_type == DEVICE_NONE){
+            found = i;
+            break;
+        }
+    }
+
+end_critical_section(&devices_lock, "interface.c:get_open_device" );
+
+    if (found == -1)
+        popup_message(langcode("POPEM00004"),langcode("POPEM00017"));
+
+    return(found);
+}
+
+
+
+
+
+//***********************************************************
+// Get Device Status
+//
+// this will return the device status for the port specified
+//***********************************************************
+int get_device_status(int port) {
+    int stat;
+
+    if (begin_critical_section(&port_data_lock, "interface.c:get_device_status(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    stat = port_data[port].status;
+
+    if (end_critical_section(&port_data_lock, "interface.c:get_device_status(2)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    return(stat);
+}
+
+
+
+
+
+//***********************************************************
+// channel_data()
+//
+// Takes data read in from a port and adds it to the
+// incoming_data_queue.  If queue is full, waits for queue to have
+// space before continuing.
+//
+// port #                                                    
+// string is the string of data
+// length is the length of the string.  If 0 then use strlen()
+// on the string itself to determine the length.
+//
+// Note that decode_ax25_header() and perhaps other routines may
+// increase the length of the string while processing.  We need to
+// send a COPY of our input string off to the decoding routines for
+// this reason, and the size of the buffer must be MAX_LINE_SIZE
+// for this reason also.
+//***********************************************************
+void channel_data(int port, unsigned char *string, volatile int length) {
+    int max;
+    struct timeval tmv;
+    // Some messiness necessary because we're using xastir_mutex's
+    // instead of pthread_mutex_t's.
+    pthread_mutex_t *cleanup_mutex1;
+    pthread_mutex_t *cleanup_mutex2;
+    int process_it = 0;
+
+
+    //fprintf(stderr,"channel_data: %x %d\n",string[0],length);
+
+    // Save backup copies of the incoming string and the previous
+    // string.  Used for debugging purposes.  If we get a segfault,
+    // we can print out the last two messages received.
+    xastir_snprintf((char *)incoming_data_copy_previous,
+        sizeof(incoming_data_copy_previous),
+        "%s",
+        incoming_data_copy);
+    xastir_snprintf((char *)incoming_data_copy,
+        sizeof(incoming_data_copy),
+        "Port%d:%s",
+        port,
+        string);
+
+    max = 0;
+
+    if (string == NULL)
+        return;
+
+    if (string[0] == '\0')
+        return;
+
+    if (length == 0) {
+        // Compute length of string including terminator
+        length = strlen((const char *)string) + 1;
+//fprintf(stderr,"Computing length with strlen, port %d\n", port);
+    }
+
+    // Check for excessively long packets.  These might be TCP/IP
+    // packets or concatenated APRS packets.  In any case it's some
+    // kind of garbage that we don't want to try to parse.
+
+    // Note that for binary data (WX stations and KISS packets), the
+    // strlen() function may not work correctly.
+    if (length > MAX_LINE_SIZE) {   // Too long!
+        if (debug_level & 1) {
+            fprintf(stderr,"\nchannel_data: LONG packet:%d,  Dumping it:\n%s\n",
+            length,
+            string);
+        }
+
+        string[0] = '\0';   // Truncate it to zero length
+        return;
+    }
+
+
+    // Install the cleanup routine for the case where this thread
+    // gets killed while the mutex is locked.  The cleanup routine
+    // initiates an unlock before the thread dies.  We must be in
+    // deferred cancellation mode for the thread to have this work
+    // properly.  We must first get the pthread_mutex_t address:
+    cleanup_mutex1 = &output_data_lock.lock;
+
+    // Then install the cleanup routine:
+    pthread_cleanup_push((void *)pthread_mutex_unlock, (void *)cleanup_mutex1);
+//    pthread_cleanup_push(void (*pthread_mutex_unlock)(void *), (void *)cleanup_mutex1);
+
+
+    // This protects channel_data from being run by more than one
+    // thread at the same time.
+    if (begin_critical_section(&output_data_lock, "interface.c:channel_data(1)" ) > 0)
+        fprintf(stderr,"output_data_lock, Port = %d\n", port);
+
+
+    if (length > 0) {
+
+
+        // Install the cleanup routine for the case where this
+        // thread gets killed while the mutex is locked.  The
+        // cleanup routine initiates an unlock before the thread
+        // dies.  We must be in deferred cancellation mode for the
+        // thread to have this work properly.  We must first get the
+        // pthread_mutex_t address.
+        cleanup_mutex2 = &data_lock.lock;
+
+        // Then install the cleanup routine:
+        pthread_cleanup_push((void *)pthread_mutex_unlock, (void *)cleanup_mutex2);
+//        pthread_cleanup_push(void (*pthread_mutex_unlock)(void *), (void *)cleanup_mutex2);
+
+
+//        if (begin_critical_section(&data_lock, "interface.c:channel_data(2)" ) > 0)
+//            fprintf(stderr,"data_lock, Port = %d\n", port);
+
+
+        // If it's any of three types of GPS ports and is a GPRMC or
+        // GPGGA string, just stick it in one of two global
+        // variables for holding such strings.  UpdateTime() can
+        // come along and process/clear-out those strings at the
+        // gps_time interval.
+        //
+        switch(port_data[port].device_type) {
+
+            case DEVICE_SERIAL_GPS:
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+            case DEVICE_NET_GPSD:
+
+                // One of the three types of interfaces that might
+                // send in a lot of GPS data constantly.  Save only
+                // GPRMC and GPGGA strings into global variables.
+                // Drop other GPS strings on the floor.
+                //
+                if ( (length > 7) && (strncmp((char *)string,"$GPRMC,",7) == 0) ) {
+                    xastir_snprintf(gprmc_save_string,
+                        sizeof(gprmc_save_string),
+                        "%s",
+                        string);
+                    gps_port_save = port;
+                    process_it = 0;
+                }
+                else if ( (length > 7) && (strncmp((char *)string,"$GPGGA,",7) == 0) ) {
+                    xastir_snprintf(gpgga_save_string,
+                        sizeof(gpgga_save_string),
+                        "%s",
+                        string);
+                    gps_port_save = port;
+                    process_it = 0;
+                }
+                else {
+                    // It's not one of the GPS strings we're looking
+                    // for.  It could be another GPS string, a
+                    // partial GPS string, or a full/partial TNC
+                    // string.  Drop the string on the floor unless
+                    // it's an HSP interface.
+                    //
+                    if (port_data[port].device_type == DEVICE_SERIAL_TNC_HSP_GPS) {
+                        // Decode the string normally.
+                        process_it++;
+                        //fprintf(stderr,"data_avail\n");
+                    }
+                }
+                break;
+// We need to make sure that the variables stating that a string is
+// available are reset in any case.  Look at how/where data_avail is
+// reset.  We may not care if we just wait for data_avail to be
+// cleared before writing to the string again.
+
+            default:    // Not one of the above three types, decode
+                        // the string normally.
+                process_it++;
+                //fprintf(stderr,"data_avail\n");
+                break;
+        }
+
+
+//        if (end_critical_section(&data_lock, "interface.c:channel_data(3)" ) > 0)
+//            fprintf(stderr,"data_lock, Port = %d\n", port);
+
+        // Remove the cleanup routine for the case where this thread
+        // gets killed while the mutex is locked.  The cleanup
+        // routine initiates an unlock before the thread dies.  We
+        // must be in deferred cancellation mode for the thread to
+        // have this work properly.
+//
+// NOTE: Ignore the four \"suggest braces\" warnings you see when
+//       compiling, see: http://archive.netbsd.se/?ml=gcc-help&a=2008-06&t=7730779
+//
+        pthread_cleanup_pop(0);
+
+ 
+        if (debug_level & 1)
+            fprintf(stderr,"Channel data on Port %d [%s]\n",port,(char *)string);
+
+        if (process_it) {
+
+            // Wait for empty space in queue
+//fprintf(stderr,"\n== %s", string);
+            while (push_incoming_data(string, length, port) && max < 5400) {
+                sched_yield();  // Yield to other threads
+                tmv.tv_sec = 0;
+                tmv.tv_usec = 2;  // 2 usec
+                (void)select(0,NULL,NULL,NULL,&tmv);
+                max++;
+            }
+        }
+    }
+
+
+    if (end_critical_section(&output_data_lock, "interface.c:channel_data(4)" ) > 0)
+        fprintf(stderr,"output_data_lock, Port = %d\n", port);
+
+    // Remove the cleanup routine for the case where this thread
+    // gets killed while the mutex is locked.  The cleanup routine
+    // initiates an unlock before the thread dies.  We must be in
+    // deferred cancellation mode for the thread to have this work
+    // properly.
+//
+// NOTE: Ignore the four \"suggest braces\" warnings you see when
+//       compiling, see: http://archive.netbsd.se/?ml=gcc-help&a=2008-06&t=7730779
+//
+    pthread_cleanup_pop(0);
+}
+
+
+
+
+
+//********************************* START AX.25 ********************************
+
+#ifdef HAVE_LIBAX25
+// stolen from libax25-0.0.9 and modified to set digipeated bit based on '*'
+int my_ax25_aton_arglist(char *call[], struct full_sockaddr_ax25 *sax)
+{
+    char *bp;
+    char *addrp;
+    int n = 0;
+    int argp = 0;
+    int len = 0;
+    int star = 0;
+
+    addrp = sax->fsa_ax25.sax25_call.ax25_call;
+
+    do {
+        /* Fetch one callsign token */
+        if ((bp = call[argp++]) == NULL)
+            break;
+
+        /* Check for the optional 'via' syntax */
+        if (n == 1 && (strcasecmp(bp, "V") == 0 || strcasecmp(bp, "VIA") == 0))
+            continue;
+
+        /* Process the token (Removes the star before the ax25_aton_entry call
+           because it would call it a bad callsign.) */
+        len = strlen(bp);
+        if (len > 1 && bp[len-1] == '*') {
+            star = 1;
+            bp[len-1] = '\0';
+        }
+        else {
+            star = 0;
+        }
+        if (ax25_aton_entry(bp, addrp) == -1) {
+            popup_message("Bad callsign!", bp);
+            return -1;
+        }
+        if (n >= 1 && star) {
+            addrp[6] |= 0x80; // set digipeated bit if we had found a star
+        }
+
+        n++;
+
+        if (n == 1)
+            addrp  = sax->fsa_digipeater[0].ax25_call;      /* First digipeater address */
+        else
+            addrp += sizeof(ax25_address);
+
+    } while (n < AX25_MAX_DIGIS && call[argp] != NULL);
+
+    /* Tidy up */
+    sax->fsa_ax25.sax25_ndigis = n - 1;
+    sax->fsa_ax25.sax25_family = AF_AX25;
+
+    return sizeof(struct full_sockaddr_ax25);
+}
+#endif  // HAVE_LIBAX25
+
+
+
+
+
+//***********************************************************
+// ui connect: change call and proto paths and reconnect net
+// port device to work with
+//***********************************************************
+int ui_connect( int port, char *to[]) {
+    int    s = -1;
+#ifdef HAVE_LIBAX25
+    int    sockopt;
+    int    addrlen = sizeof(struct full_sockaddr_ax25);
+    struct full_sockaddr_ax25 axbind, axconnect;
+    /* char  *arg[2]; */
+    char  *portcall;
+    char temp[200];
+
+    if (to == NULL)
+        return(-1);
+
+    if (to[0] == '\0')
+        return(-1);
+
+    /*
+     * Handle incoming data
+     *
+     * Parse the passed values for correctness.
+     */
+
+    axconnect.fsa_ax25.sax25_family = AF_AX25;
+    axbind.fsa_ax25.sax25_family    = AF_AX25;
+    axbind.fsa_ax25.sax25_ndigis    = 1;
+
+    if ((portcall = ax25_config_get_addr(port_data[port].device_name)) == NULL) {
+        xastir_snprintf(temp, sizeof(temp), langcode("POPEM00005"),
+                port_data[port].device_name);
+        popup_message(langcode("POPEM00004"),temp);
+        return -1;
+    }
+    if (ax25_aton_entry(portcall, axbind.fsa_digipeater[0].ax25_call) == -1) {
+        xastir_snprintf(temp, sizeof(temp), langcode("POPEM00006"),
+                port_data[port].device_name);
+        popup_message(langcode("POPEM00004"), temp);
+        return -1;
+    }
+
+    if (ax25_aton_entry(port_data[port].ui_call, axbind.fsa_ax25.sax25_call.ax25_call) == -1) {
+        xastir_snprintf(temp, sizeof(temp), langcode("POPEM00007"), port_data[port].ui_call);
+        popup_message(langcode("POPEM00004"),temp);
+        return -1;
+    }
+
+    if (my_ax25_aton_arglist(to, &axconnect) == -1) {
+        popup_message(langcode("POPEM00004"),langcode("POPEM00008"));
+        return -1;
+    }
+
+    /*
+     * Open the socket into the kernel.
+     */
+
+    if ((s = socket(AF_AX25, SOCK_DGRAM, 0)) < 0) {
+        xastir_snprintf(temp, sizeof(temp), langcode("POPEM00009"), strerror(errno));
+        popup_message(langcode("POPEM00004"),temp);
+        return -1;
+    }
+
+    /*
+     * Set our AX.25 callsign and AX.25 port callsign accordingly.
+     */
+    ENABLE_SETUID_PRIVILEGE;
+    if (bind(s, (struct sockaddr *)&axbind, addrlen) != 0) {
+        DISABLE_SETUID_PRIVILEGE;
+        xastir_snprintf(temp, sizeof(temp), langcode("POPEM00010"), strerror(errno));
+        popup_message(langcode("POPEM00004"),temp);
+        return -1;
+    }
+    DISABLE_SETUID_PRIVILEGE;
+
+    if (devices[port].relay_digipeat)
+        sockopt = 1;
+    else
+        sockopt = 0;
+
+    if (setsockopt(s, SOL_AX25, AX25_IAMDIGI, &sockopt, sizeof(int))) {
+        fprintf(stderr,"AX25 IAMDIGI setsockopt FAILED");
+        return -1;
+    }
+
+    if (debug_level & 2)
+       fprintf(stderr,"*** Connecting to UNPROTO port for transmission...\n");
+
+    /*
+     * Lets try and connect to the far end.
+     */
+
+    if (connect(s, (struct sockaddr *)&axconnect, addrlen) != 0) {
+        xastir_snprintf(temp, sizeof(temp), langcode("POPEM00011"), strerror(errno));
+        popup_message(langcode("POPEM00004"),temp);
+        return -1;
+    }
+
+    /*
+     * We got there.
+     */
+#endif /* HAVE_LIBAX25 */
+    return s;
+}
+
+
+
+
+
+//************************************************************
+// data_out_ax25()
+//
+// Send string data out ax25 port
+//************************************************************
+
+static void data_out_ax25(int port, unsigned char *string) {
+    static char ui_mycall[10];
+    char        *temp;
+    char        *to[10];
+    int         quantity;
+
+    if (string == NULL)
+        return;
+
+    if (string[0] == '\0')
+        return;
+
+    if (begin_critical_section(&port_data_lock, "interface.c:data_out_ax25(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    // Check for commands (start with Control-C)
+    if (string[0] == (unsigned char)3) { // Yes, process TNC type commands
+
+        // Look for MYCALL command
+        if (strncmp((char *)&string[1],"MYCALL", 6) == 0) {
+
+            // Found MYCALL.  Snag the callsign and put it into the
+            // structure for the port
+
+            // Look for whitespace/CR/LF (end of "MYCALL")
+            temp = strtok((char *)&string[1]," \t\r\n");
+            if (temp != NULL) {
+
+                // Look for whitespace/CR/LF (after callsign)
+                temp = strtok(NULL," \t\r\n");
+                if (temp != NULL) {
+                    substr(ui_mycall, temp, 9);
+                    xastir_snprintf(port_data[port].ui_call,
+                        sizeof(port_data[port].ui_call),
+                        "%s",
+                        ui_mycall);
+                    if (debug_level & 2)
+                        fprintf(stderr,"*** MYCALL %s\n",port_data[port].ui_call);
+                }
+            }
+        }
+
+        // Look for UNPROTO command
+        else if (strncmp((char *)&string[1],"UNPROTO", 6) == 0) {
+            quantity = 0;   // Number of callsigns found
+
+            // Look for whitespace/CR/LF (end of "UNPROTO")
+            temp = strtok((char *)&string[1]," \t\r\n");
+            if (temp != NULL) { // Found end of "UNPROTO"
+
+                // Find first callsign (destination call)
+                temp = strtok(NULL," \t\r\n");
+                if (temp != NULL) {
+                    to[quantity++] = temp; // Store it
+                    //fprintf(stderr,"Destination call: %s\n",temp);
+
+                    // Look for "via" or "v"
+                    temp = strtok(NULL," \t\r\n");
+                    //fprintf(stderr,"Via: %s\n",temp);
+
+                    while (temp != NULL) {  // Found it
+                        // Look for the rest of the callsigns (up to
+                        // eight of them)
+                        temp = strtok(NULL," ,\t\r\n");
+                        if (temp != NULL) {
+                            //fprintf(stderr,"Call: %s\n",temp);
+                            if (quantity < 9) {
+                                to[quantity++] = temp;
+                            }
+                        }
+                    }
+                    to[quantity] = NULL;
+
+                    if (debug_level & 2) {
+                        int i = 1;
+
+                        fprintf(stderr,"UNPROTO %s VIA ",*to);
+                        while (to[i] != NULL)
+                            fprintf(stderr,"%s,",to[i++]);
+                        fprintf(stderr,"\n");
+                    }
+
+                    if (port_data[port].channel2 != -1) {
+                        if (debug_level & 2)
+                            fprintf(stderr,"Write DEVICE is UP!  Taking it down to reconfigure UI path.\n");
+
+                        (void)close(port_data[port].channel2);
+                        port_data[port].channel2 = -1;
+                    }
+
+                    if ((port_data[port].channel2 = ui_connect(port,to)) < 0) {
+                        popup_message(langcode("POPEM00004"),langcode("POPEM00012"));
+                        port_data[port].errors++;
+                    }
+                    else {    // Port re-opened and re-configured
+                        if (debug_level & 2)
+                            fprintf(stderr,"WRITE port re-opened after UI path change\n");
+                    }
+                }
+            }
+        }
+    }
+
+    // Else not a command, write the data directly out to the port
+    else {
+        if (debug_level & 2)
+            fprintf(stderr,"*** DATA: %s\n",(char *)string);
+
+        if (port_data[port].channel2 != -1)
+            (void)write(port_data[port].channel2, string, strlen((char *)string));
+        else if (debug_level & 2)
+            fprintf(stderr,"\nPort down for writing!\n\n");
+    }
+
+    if (end_critical_section(&port_data_lock, "interface.c:data_out_ax25(2)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+}
+
+
+
+
+
+// fetch16bits
+//
+// Modifies: Nothing.
+//
+int fetch16bits(unsigned char *str) {
+    int i;
+
+    
+    i = *str++;
+    i = i << 8;
+    i = i | *str++;
+    return(i);
+}
+
+
+
+
+
+// fetch32bits
+//
+// Modifies: Nothing.
+//
+int fetch32bits(unsigned char *str) {
+    int i;
+
+ 
+    i = *str++;
+    i = i << 8;
+    i = i | *str++;
+    i = i << 8;
+    i = i | *str++;
+    i = i << 8;
+    i = i | *str;
+    return(i);
+}
+
+
+
+
+
+// 0x00 Sequence number - 16 bit integer
+//
+// Modifies: sequence
+//
+int OpenTrac_decode_sequence(unsigned char *element,
+                             int           element_len,
+                             unsigned int  *sequence) {
+
+    if (element_len != 2 && element_len != 0)
+        return -1;
+
+    // No sequence number, increment by one
+    if (element_len == 0) {
+        *sequence = *sequence + 1;
+    }
+    else {
+        *sequence = fetch16bits(element);
+    }
+
+    fprintf(stderr,"Sequence: %d\n",*sequence);
+
+    return 0;
+}
+
+
+
+
+
+// 0x01 Originating Station - Callsign, SSID, Sequence, and Network
+//
+// Modifies: sequence
+//           callsign
+//           ssid
+//           network
+//
+int OpenTrac_decode_origination(unsigned char *element,
+                                int           element_len,
+                                unsigned int  *sequence,
+                                char          *callsign,
+                                unsigned char *ssid,
+                                unsigned char *network) {
+    unsigned char c;
+
+
+    if (element_len < 6)
+        return -1;
+
+    if (element_len > 8)
+        return -1;
+
+    // Binary routine.  strncpy is ok here as long as nulls not in
+    // data.  We null-terminate it ourselves to make sure it is
+    // terminated.
+    strncpy(callsign, (char *)element, 6);
+    callsign[6]=0;
+    for (c=*ssid=0;c<6;c++) {
+        *ssid |= (callsign[c] & 0x80) >> (c+2);
+        callsign[c] &= 0x7f;
+    }
+
+    *sequence = fetch16bits(element+6);
+    if (element_len == 9) {
+        *network = *(element+8);
+
+        fprintf(stderr, "Origin: %s-%d seq %d net %d\n",
+            callsign,
+            *ssid,
+            *sequence,
+            *network);
+    }
+    else {
+        fprintf(stderr, "Origin: %s-%d seq %d direct\n",
+            callsign,
+            *ssid,
+            *sequence);
+    }
+
+    return 0;
+}
+
+
+
+
+
+// Strip the SSID from the callsign and return it
+// 
+// Modifies: call (Strips top bit from each char)
+//
+int OpenTrac_extract_ssid(unsigned char *call) {
+    int c, ssid;
+
+
+    for (c=ssid=0;c<6;c++) {
+        ssid |= (call[c] & 0x80) >> (c+2);
+        call[c] &= 0x7f;
+    }
+
+    return ssid;
+}
+
+
+
+
+
+// 0x02 Entity ID
+//
+// Modifies: entity_call
+//           entity_ssid
+//           entity_serial
+//           entity_sequence
+//
+int OpenTrac_decode_entityid(unsigned char *element,
+                             int           element_len,
+                             unsigned char *origin_call,
+                             unsigned char origin_ssid,
+                             unsigned char *entity_call,
+                             unsigned char *entity_ssid,
+                             unsigned int  *entity_serial,
+                             unsigned int  *entity_sequence) {
+
+    if (element_len > 10) {
+        return -1;
+    }
+    else if (element_len > 5) {
+        memcpy(entity_call, element, 6);
+        entity_call[6]=0;
+        *entity_ssid = OpenTrac_extract_ssid(entity_call);
+    }
+    else {  // Not enough, so use origin_call instead
+        xastir_snprintf((char *)entity_call,
+            10,
+            "%s",
+            origin_call);
+        *entity_ssid = origin_ssid;
+    }
+
+    switch (element_len) {
+        case 0:
+            *entity_serial = *entity_serial + 1;
+            *entity_sequence = 0;
+            break;
+        case 2:
+            *entity_serial = fetch16bits(element);
+            *entity_sequence = 0;
+            break;
+        case 4:
+            *entity_serial = fetch16bits(element);
+            *entity_sequence = fetch16bits(element+2);
+            break;
+        case 6:
+            *entity_serial = 0;
+            break;
+        case 8:
+            *entity_serial = fetch16bits(element+6);
+            *entity_sequence = 0;
+            break;
+        case 10:
+            *entity_serial = fetch16bits(element+6);
+            *entity_sequence = fetch16bits(element+8);
+            break;
+        default:
+            *entity_sequence = 0;
+            *entity_serial = *entity_serial + 1;
+            break;
+    }
+
+    fprintf(stderr, "Entity %s-%d:%04x #%d\n",
+        entity_call,
+        *entity_ssid,
+        *entity_serial,
+        *entity_sequence);
+
+    return 0;
+}
+
+
+
+
+
+// 0x10 Position Report - Lat/Lon/<Alt>
+// Lat/Lon is WGS84, 180/2^31 degrees,  Alt is 1/100 meter
+//
+// Modifies: lat
+//           lon
+//           alt
+//
+int OpenTrac_decode_position(unsigned char *element,
+                             int           element_len,
+                             double        *lat,
+                             double        *lon,
+                             float         *alt) {
+
+    const double semicircles = 11930464.71111111111;
+
+
+    if (element_len < 8)
+        return -1; // Too short!
+
+    if (element_len > 11)
+        return -1; // Too long!
+
+    *lat = fetch32bits(element) / semicircles;
+    *lon = fetch32bits(element+4) / semicircles;
+
+    if (element_len == 11) {
+        *alt = ( (*(element+8))<<16 ) + fetch16bits(element+9);
+        *alt = (*alt / 100) - 10000;
+    }
+
+    fprintf(stderr, "Position: Lat %f Lon %f Alt %f\n",*lat,*lon,*alt);
+
+    return 0;
+}
+
+
+
+
+
+// 0x11 Timestamp - Unix format time (unsigned)
+//
+// Modifies: rawtime
+// 
+int OpenTrac_decode_timestamp(unsigned char *element,
+                              int           element_len,
+                              long          *rawtime) {
+    time_t rawtime_t;
+
+
+    *rawtime = 0;
+
+    if (element_len != 4)
+        return -1;
+
+    *rawtime = fetch32bits(element);
+
+    rawtime_t = (time_t)rawtime;
+
+    fprintf(stderr, "Time: %s", ctime(&rawtime_t));
+
+    return 0;
+}
+
+
+
+
+
+// 0x12 Freeform Comment - ASCII text
+//
+// Modifies: comment
+// 
+int OpenTrac_decode_comment(unsigned char *element,
+                            int           element_len,
+                            char          *comment) {
+
+    if (element_len > 126)
+        return -1;  // shouldn't be possible
+
+    strncat(comment," ",1);
+    strncat(comment, (char *)element, element_len);
+    comment[element_len + 1] = 0;   // Account for the space char
+
+    fprintf(stderr, "Text: %s\n", comment);
+
+    return 0;
+}
+
+
+
+
+
+// 0x13 Course and Speed - Course in degrees, speed in 1/50 m/s
+//
+// Modifies: course  (degrees true)
+//           speed   (kph)
+//
+int OpenTrac_decode_courseandspeed(unsigned char *element,
+                                   int           element_len,
+                                   int           *course,
+                                   float         *speed) {
+    int rawspeed;
+
+
+    if (element_len != 3)
+        return -1;
+
+    *course = ( (*element) << 1 ) + ( (*(element+1) & 0x80) >> 7);
+    rawspeed = fetch16bits(element+1) & 0x7fff;
+    *speed = (float)(rawspeed * 0.072); // kph
+
+    fprintf(stderr, "Course: %d Speed: %f kph\n", *course, *speed);
+
+    return 0;
+}
+
+
+
+
+
+// 0x14 Positional Ambiguity - 16 bits, in meters
+//
+// Modifies: ambiguity
+// 
+int OpenTrac_decode_ambiguity(unsigned char *element,
+                              int           element_len,
+                              int           *ambiguity) {
+
+    if (element_len != 2)
+        return -1;
+
+    *ambiguity = fetch16bits(element);
+
+    fprintf(stderr, "Position +/- %d meters\n", *ambiguity);
+
+    return 0;
+}
+
+
+
+
+
+// 0x15 Country Code - ISO 3166-1 and optionally -2
+//
+// Modifies: country
+//           subdivision
+// 
+int OpenTrac_decode_country(unsigned char *element,
+                            int           element_len,
+                            char          *country,
+                            char          *subdivision) {
+
+    if (element_len < 2)
+        return -1;
+
+    if (element_len > 5)
+        return -1;
+
+    // Binary routine.  strncpy is ok here as long as nulls not in
+    // data.  We null-terminate it ourselves to make sure it is
+    // terminated.
+    strncpy(country, (char *)element, 2);
+    country[2] = 0;
+    if (element_len > 2) {
+        // Binary routine.  strncpy is ok here as long as nulls not
+        // in data.  We null-terminate it ourselves to make sure it
+        // is terminated.
+        strncpy(subdivision, (char *)(element+2), element_len-2);
+        subdivision[element_len-2] = 0;
+        fprintf(stderr, "Country Code %s-%s\n", country, subdivision);
+    }
+    else {
+        fprintf(stderr, "Country Code %s\n", country);
+    }
+    return 0;
+}
+
+
+
+
+
+// 0x16 Display Name (UTF-8 text)
+//
+// Modifies: displayname
+// 
+int OpenTrac_decode_displayname(unsigned char *element,
+                                int           element_len,
+                                char          *displayname) {
+
+    if (element_len > 30 || !element_len)
+        return -1;
+
+    // Binary routine.  strncpy is ok here as long as nulls not in
+    // data.  We null-terminate it ourselves to make sure it is
+    // terminated.
+    strncpy(displayname, (char *)element, element_len);
+    displayname[element_len] = 0;
+
+    fprintf(stderr, "Display Name: %s\n", displayname);
+    return 0;
+}
+
+
+
+
+
+// 0x17 Waypoint Name (up to 6 chars, uppercase)
+//
+// Modifies: waypoint
+// 
+int OpenTrac_decode_waypoint(unsigned char *element,
+                             int           element_len,
+                             char          *waypoint) {
+
+    if (element_len > 6 || !element_len)
+        return -1;
+
+    // Binary routine.  strncpy is ok here as long as nulls not in
+    // data.  We null-terminate it ourselves to make sure it is
+    // terminated.
+    strncpy(waypoint, (char *)element, element_len);
+    waypoint[element_len] = 0;
+
+    fprintf(stderr, "Waypoint Name: %s\n", waypoint);
+
+    return 0;
+}
+
+
+
+
+
+// Mapping between OpenTrac symbols and APRS symbols
+char symbol_translate[100][14] = {
+    "3 11100000 /S",  // space shuttle
+    "3 12100000 \\S", // satellite
+    "1 10000000 \\S", // *** other space
+    "2 21000000 /O",  // balloon
+    "4 22120000 /g",  // glider
+    "3 22100000 /'",  // small plane
+    "3 22200000 /^",  // large aircraft
+    "3 22300000 /^",  // large aircraft
+    "2 23000000 /X",  // helicopter
+    "1 20000000 /'",  // *** other air
+    "4 31310000 /h",  // hospital
+    "4 31340000 /A",  // aid station
+    "4 31350000 \\X", // pharmacy
+    "4 31410000 /d",  // fire station
+    "4 31440000 /o",  // EOC
+    "4 31460000 /+",  // red cross
+    "4 31620000 \\h", // ham store
+    "3 31700000 /-",  // house
+    "3 31800000 \\+", // church
+    "4 31910000 /H",  // hotel
+    "4 31920000 \\9", // gas station
+    "4 31930000 \\R", // restaurant
+    "4 31940000 \\?", // information
+    "4 31950000 \\P", // parking
+    "4 31960000 /t",  // truck stop
+    "4 31970000 \\r", // restrooms
+    "4 31980000 \\$", // bank/atm
+    "3 31a00000 /K",  // school
+    "4 31c10000 /,",  // boy scouts
+    "4 31c20000 \\,", // girl scouts
+    "4 31d10000 \\;", // park/picnic area
+    "4 31d20000 \\;", // park/picnic area
+    "4 31d30000 /;",  // campground
+    "5 31e13000 \\V", // VORTAC
+    "5 31f12000 /$",  // phone
+    "5 32111000 />",  // car
+    "5 32112000 /v",  // van
+    "5 32113000 /k",  // truck
+    "5 32114000 /j",  // jeep
+    "5 32115000 /R",  // rv
+    "5 32116000 /<",  // motorcycle
+    "5 32117000 /b",  // bicycle
+    "5 32121000 /u",  // 18-wheeler
+    "5 32122000 /U",  // bus
+    "5 32131000 /=",  // railroad engine
+    "5 32141000 /*",  // snowmobile
+    "5 32161000 /!",  // police
+    "5 32162000 /a",  // ambulance
+    "5 32163000 /f",  // fire truck
+    "3 33100000 /(",  // sat station
+    "1 30000000 //",  // *** other ground
+    "3 41200000 /s",  // ship
+    "4 41510000 /C",  // canoe
+    "4 41520000 /C",  // canoe (kayak)
+    "4 41540000 /Y",  // yacht
+    "4 41620000 \\C", // coastguard
+    "3 43100000 \\N", // nav buoy
+    "1 40000000 \\s", // *** other sea
+    "1 50000000 /.",  // ***
+    "4 62110000 /[",  // jogger
+    "3 64200000 /:",  // fire
+    "3 65500000 \\'", // crash site
+    "3 66100000 \\Q", // earthquake
+    "3 66300000 \\w", // flooding
+    "1 60000000 /.",  // *** other activities
+    "4 71610000 \\U", // sunny
+    "4 71620000 \\U", // sunny
+    "4 71630000 \\(", // cloudy
+    "4 71640000 \\(", // cloudy
+    "4 71650000 \\(", // cloudy
+    "4 71660000 \\(", // cloudy
+    "5 71711000 \\I", // rain shower
+    "5 71712000 \\F", // freezing rain
+    "5 71713000 \\D", // drizzle
+    "4 71710000 \\'", // rain
+    "5 71721000 \\G", // snow shower
+    "4 71720000 \\*", // snow
+    "4 71730000 \\:", // hail
+    "5 71812000 \\f", // funnel cloud
+    "5 71813000 \\J", // lightning
+    "4 71810000 \\T", // thunderstorm
+    "5 71822000 /@",  // hurricane
+    "4 71820000 \\@", // storm
+    "4 71920000 \\{", // fog
+    "4 71950000 \\E", // smoke
+    "4 71960000 \\H", // haze
+    "4 71970000 \\b", // blowing dust/sand
+    "1 70000000 \\o", // *** other weather
+    "1 80000000 /.",  // ***
+    "1 90000000 /.",  // ***
+    "1 A0000000 /.",  // ***
+    "1 B0000000 /.",  // ***
+    "1 C0000000 /.",  // ***
+    "1 D0000000 /.",  // ***
+    "1 E0000000 /.",  // ***
+    "1 F0000000 /.",  // ***
+    "0"};
+
+
+
+
+
+// 0x18 Map Symbol - Packed 4-bit integers
+//
+// Modifies: symbol (leaves it in 4-bit packed format)
+//           aprs_symbol_table
+//           aprs_symbol_char
+// 
+int OpenTrac_decode_symbol(unsigned char *element,
+                           int           element_len,
+                           char          *symbol,
+                           char          *aprs_symbol_table,
+                           char          *aprs_symbol_char) {
+    int c, ii, done;
+    unsigned char split[9];
+
+
+    ii = 0;
+    symbol[0] = '\0';
+
+    if (!element_len)
+        return -1;
+
+    if (element_len > 4)
+        return -1;
+
+    fprintf(stderr, "Symbol: ");
+
+    for (c = 0; c < element_len; c++) {
+
+        symbol[c] = element[c];
+
+        // Split nibbles into two bytes
+        split[ii++] = element[c] >> 4;
+        split[ii++] = element[c] & 0x0f;
+
+        if (c > 0) {
+            fprintf(stderr, ".");
+        }
+        fprintf(stderr, "%d", element[c] >> 4);
+
+        if (element[c] & 0x0f) {
+            fprintf(stderr, ".%d", element[c] & 0x0f);
+        }
+    }
+
+    symbol[element_len] = '\0'; // Terminate string
+    split[ii] = '\0';   // Terminate split integers
+
+    // Convert split string chars into hex chars
+    for (c = 0; c < element_len * 2; c++) {
+        if (split[c] < 10) {
+            split[c] += 0x30;
+        }
+        else {
+            split[c] += 0x37;
+        }
+    }
+
+//fprintf(stderr,"\n%s\n",split);
+
+    // Find the symbol from the table above that matches.  Use the
+    // split[] string.
+
+    // Defaults:
+    *aprs_symbol_table = '/';
+    *aprs_symbol_char  = '/';   // A dot
+
+    ii = 0;
+    done = 0;
+
+    while (!done && symbol_translate[ii][0] != '0') {
+        int len;
+
+        // Find out how many chars to compare
+        len = symbol_translate[ii][0] - 0x30;
+
+//fprintf(stderr,"%d:%s\n",len,&symbol_translate[ii][2]);
+
+        // Do a strncasecmp() for "len" chars in the hex part of the
+        // string.  Once we find a match, the last two chars in the
+        // string are our symbol table and symbol.  If we don't find
+        // a match, we use the default "//" symbol (a dot) instead.
+        if ( strncasecmp(&symbol_translate[ii][2],(const char *)split,len) == 0 ) {
+            // Found a match
+//fprintf(stderr,"Found a match: %s in %d", split, ii);
+            len = strlen(&symbol_translate[ii][0]);
+            *aprs_symbol_table = symbol_translate[ii][len-2];
+            *aprs_symbol_char  = symbol_translate[ii][len-1];
+            done++;
+        }
+        else {
+            // No match
+            ii++;
+        }
+    }
+
+    switch (split[0]) {
+        case '1':
+            fprintf(stderr, " (Space Symbol)");
+            break;
+        case '2':
+            fprintf(stderr, " (Air Symbol)");
+            break;
+        case '3':
+            fprintf(stderr, " (Ground Symbol)");
+            break;
+        case '4':
+            fprintf(stderr, " (Sea Symbol)");
+            break;
+        case '5':
+            fprintf(stderr, " (Subsurface Symbol)");
+            break;
+        case '6':
+            fprintf(stderr, " (Activities Symbol)");
+            break;
+        case '7':
+            fprintf(stderr, " (Weather Symbol)");
+            break;
+        default:
+            fprintf(stderr, " (Unknown Symbol)");
+            break;
+    }
+    fprintf(stderr, "\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x20 Path Trace - Call/SSID, Network
+//
+// Modifies:
+// 
+int OpenTrac_decode_pathtrace(unsigned char *element,
+                              int           element_len) {
+
+//WE7U:  Need to pass back and use callsign/ssid/network.
+
+    char callsign[7];
+    int ssid, c, network;
+
+
+    if (element_len % 7)
+        return -1; // Must be multiple of 7 octets
+
+    if (!element_len) {
+        fprintf(stderr, "Empty Path\n");
+        return 0;
+    }
+
+    fprintf(stderr, "Path: ");
+    for (c=0; c<element_len; c+=7) {
+        memcpy(callsign, element+c, 6);
+        ssid = OpenTrac_extract_ssid((unsigned char *)callsign);
+        network = (int)*(element+c+6);
+        fprintf(stderr, " %s-%d (%d)", callsign, ssid, network);
+    }
+    fprintf(stderr, "\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x21 Heard-By List
+//
+// Modifies:
+// 
+int OpenTrac_decode_heardby(unsigned char *element,
+                            int           element_len) {
+
+//WE7U:  Need to pass back "Heard By" string.
+
+    int c;
+
+
+    if (!element_len)
+        return -1;
+ 
+    fprintf(stderr, "Heard By:");
+    for (c=0; c<element_len; c++) {
+        fprintf(stderr, " %d", (int)*(element+c));
+    }
+    fprintf(stderr, "\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x22 Available Networks
+//
+// Modifies:
+// 
+int OpenTrac_decode_availablenets(unsigned char *element,
+                                  int           element_len) {
+
+//WE7U:  Need to pass back "Available Networks" string.
+
+    int c;
+
+
+    if (!element_len)
+        return -1;
+
+    fprintf(stderr, "Available Networks:");
+    for (c=0; c<element_len; c++) {
+        fprintf(stderr, " %d", (int)*(element+c));
+    }
+    fprintf(stderr, "\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x32 Maidenhead Locator (4 or 6 chars)
+//
+// Modifies: maidenhead
+// 
+int OpenTrac_decode_maidenhead(unsigned char *element,
+                               int           element_len,
+                               char          *maidenhead) {
+
+    if (element_len > 6)
+        return -1;
+
+    if (element_len < 4)
+        return -1;
+
+    // Binary routine.  strncpy is ok here as long as nulls not in
+    // data.  We null-terminate it ourselves to make sure it is
+    // terminated.
+    strncpy(maidenhead, (char *)element, element_len);
+    maidenhead[element_len] = 0;
+
+    fprintf(stderr, "Maidenhead Grid: %s\n", maidenhead);
+    return 0;
+}
+
+
+
+
+
+// 0x33 Radio Capabilities
+//
+// Modifies: Nothing yet
+// 
+int OpenTrac_decode_radio_capabilities(unsigned char *element,
+                                       int           element_len) {
+
+//WE7U: Need to decode/pass back values.  This element is still
+//being defined in the spec.
+
+    fprintf(stderr, "Radio Capabilities\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x34 GPS Data Quality - Fix, Validity, Sats, PDOP, HDOP, VDOP
+//
+// Modifies:
+// 
+int OpenTrac_decode_gpsquality(unsigned char *element,
+                               int           element_len) {
+
+//WE7U:  Need to pass back gps quality parameters/strings.
+
+    int fixtype, validity, sats;
+    const char *fixstr[] = {"Unknown Fix", "No Fix", "2D Fix", "3D Fix"};
+    const char *validstr[] = {"Invalid", "Valid SPS", "Valid DGPS", "Valid PPS"};
+
+
+    if (element_len > 4 || !element_len)
+        return -1;
+
+    fixtype = (element[0] & 0xc0) >> 6;
+    validity = (element[0] & 0x30) >> 4;
+    sats = (element[0] & 0x0f);
+    fprintf(stderr, "GPS: %s %s, %d sats", fixstr[fixtype],
+        validstr[validity], sats);
+    if (element_len > 1)
+        fprintf(stderr, " PDOP=%.1f", (float)element[1]/10);
+    if (element_len > 2)
+        fprintf(stderr, " HDOP=%.1f", (float)element[2]/10);
+    if (element_len > 3)
+        fprintf(stderr, " VDOP=%.1f", (float)element[3]/10);
+    fprintf(stderr, "\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x35 Aircraft Registration - ASCII text
+//
+// Modifies: aircraft_id
+// 
+int OpenTrac_decode_acreg(unsigned char *element,
+                          int           element_len,
+                          char          *aircraft_id) {
+
+    if (element_len > 8)
+        return -1;
+
+    // Binary routine.  strncpy is ok here as long as nulls not in
+    // data.  We null-terminate it ourselves to make sure it is
+    // terminated.
+    strncpy(aircraft_id, (char *)element, element_len);
+    aircraft_id[element_len]=0;
+
+    fprintf(stderr, "Aircraft ID: %s\n", aircraft_id);
+
+    return 0;
+}
+
+
+
+
+
+// 0x40 Surface Observation Report
+//
+// Modifies: Nothing
+// 
+int OpenTrac_surface_observation(unsigned char *element,
+                                 int           element_len) {
+
+//WE7U: Need to decode/pass back the data.  This element is still
+//being defined in the spec.
+
+    fprintf(stderr, "Surface Observation Report Element\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x41 Rainfall History
+//
+// Modifies: Nothing
+// 
+int OpenTrac_rainfall_history(unsigned char *element,
+                              int           element_len) {
+
+//WE7U: Need to decode/pass back the data.  This element is still
+//being defined in the spec.
+
+    fprintf(stderr, "Rainfall History Element\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x42 River Flow Gauge - 1/64 m^3/sec, centimeters
+//
+// Modifies: Nothing.
+// 
+int OpenTrac_decode_rivergauge(unsigned char *element,
+                               int           element_len) {
+
+//WE7U:  Need to pass back gauge indications.
+
+    unsigned int flow;
+    unsigned int height;
+    float flowm;
+    float heightm;
+
+
+    if (element_len != 4)
+        return -1;
+
+    flow = fetch16bits(element);
+    height = fetch16bits(element+2);
+    flowm = (float)flow / 64;
+    heightm = (float)height / 100;
+    fprintf(stderr, "River flow rate: %f Cu M/Sec  Height: %f M\n",
+        flowm, heightm);
+
+    return 0;
+}
+
+
+
+
+
+// 0x43 Storm
+//
+// Modifies: Nothing.
+// 
+int OpenTrac_decode_storm(unsigned char *element,
+                          int           element_len) {
+
+// WE7U:  Need to decode/pass back storm info.  This element is
+// still being defined in the spec.
+
+    fprintf(stderr, "Storm Report Element\n");
+    return 0;
+}
+
+
+
+ 
+
+// 0x50 Shape
+//
+// Modifies: Nothing.
+// 
+int OpenTrac_decode_shape(unsigned char *element,
+                          int           element_len) {
+
+// WE7U:  Need to decode/pass back Shape info.  This element is
+// still being defined in the spec.
+
+    fprintf(stderr, "Shape Element\n");
+
+    return 0;
+}
+
+ 
+
+
+
+// 0x0100 Emergency / Distress Call
+//
+// Modifies: nothing
+//
+int OpenTrac_flag_emergency(void) {
+
+    fprintf(stderr, "* * * EMERGENCY * * *\n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x0101 Attention / Ident
+//
+// Modifies: nothing
+//
+int OpenTrac_flag_attention(void) {
+
+    fprintf(stderr, " - ATTENTION - \n");
+
+    return 0;
+}
+
+
+
+
+
+// 0x0300 HAZMAT (UN ID in lower 14 bits)
+//
+// Modifies: hazmat_id
+// 
+int OpenTrac_decode_hazmat(unsigned char *element,
+                           int           element_len,
+                           int           *hazmat_id,
+                           char          *comment,
+                           int           comment_size) {
+
+    if (element_len < 2) {
+        fprintf(stderr, "HAZMAT: Unknown Material\n");
+        strncat(comment,
+            " HAZMAT: Unknown Material",
+            comment_size - 1 - strlen(comment));
+    }
+    else if (element_len > 2) {
+        fprintf(stderr, "HAZMAT: Unknown Material: ID too Long\n");
+        strncat(comment,
+            " HAZMAT: Unknown Material: ID too Long",
+            comment_size - 1 - strlen(comment));
+    }
+    else {
+        char temp[200];
+
+        *hazmat_id = fetch16bits(element) & 0x3fff;
+        fprintf(stderr, "HAZMAT: UN%04d\n", *hazmat_id);
+        xastir_snprintf(temp,
+            sizeof(temp),
+            " HAZMAT: UN%04d",
+            *hazmat_id);
+        strncat(comment,
+            temp,
+            comment_size - 1 - strlen(comment));
+    }
+    return 0;
+}
+
+
+
+
+
+// 0x0500 to 0x05ff Generic Measurement Elements
+// Values may be 8-bit int, 16-bit int, single float, or double
+// float
+//
+// Modifies: Nothing.
+// 
+int OpenTrac_decode_units(int           unitnum,
+                          unsigned char *element,
+                          int           element_len,
+                          char          *comment,
+                          int           comment_size) {
+
+//WE7U:  Need to pass back and use units.
+
+    const char *units[]={"Volts","Amperes","Watts","Kelvins",
+        "Meters","Seconds","Meters/Second","Liters","Kilograms",
+        "Bits/Second","Bytes","Radians","Radians/Second",
+        "Square Meters","Joules","Newtons","Pascals","Hertz",
+        "Meters/Sec^2","Grays","Lumens","Cubic Meters/Second",
+        "Pascal Seconds","Kilograms/Meter^3","Radians/Second^2",
+        "Coulombs","Farads","Siemens","Counts"};
+
+    union measurement {
+        char c;
+        float f;
+        double d;
+    } *mval;
+
+    int ival; // too much variation in byte order and size for union
+    char temp[200];
+
+
+    mval = (void *)element;
+    switch (element_len) {
+        case 1:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                " %d %s",
+                mval->c,
+                units[unitnum]);
+            strncat(comment,
+                temp,
+                comment_size - 1 - strlen(comment));
+            fprintf(stderr, "%s\n",temp);
+            break;
+        case 2:
+            ival = fetch16bits(element);
+            xastir_snprintf(temp,
+                sizeof(temp),
+                " %d %s",
+                ival,
+                units[unitnum]);
+            strncat(comment,
+                temp,
+                comment_size - 1 - strlen(comment));
+            fprintf(stderr, "%s\n", temp);
+            break;
+        case 4:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                " %f %s",
+                mval->f,
+                units[unitnum]);
+            strncat(comment,
+                temp,
+                comment_size - 1 - strlen(comment));
+            fprintf(stderr, "%s\n", temp);
+            break;
+        case 8:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                " %f %s",
+                mval->d,
+                units[unitnum]);
+            strncat(comment,
+                temp,
+                comment_size - 1 - strlen(comment));
+            fprintf(stderr, "%s\n", temp);
+            break;
+        default:
+            return -1;
+    }
+
+    return 0;
+}
+
+
+
+
+
+// Construct a Base-91 compressed APRS-format packet out of
+// the parsed information (to attempt to represent some of
+// the better resolution available with OpenTrac).  We may
+// need to construct several APRS packets out of the
+// OpenTrac packet, as there may be several entity ID's or
+// other types of info that can't fit into one APRS packet.
+// Later we'll change this so that we don't create an APRS
+// packet out of the OpenTrac packet at all, but instead
+// decode and use the OpenTrac information directly.
+//
+// Inputs:   Lots!
+// Outputs:  buffer
+//
+void process_opentrac_aprs(unsigned char *origin_call,
+        unsigned char origin_ssid,
+        char *buffer,
+        unsigned char *dest,
+        unsigned int digis,
+        unsigned char digi[10][10],
+        unsigned char *digi_h,
+        int have_position,
+        double latitude,
+        double longitude,
+        unsigned int entity_serial,
+        char *displayname,
+        char aprs_symbol_table,
+        char aprs_symbol_char,
+        int course,
+        float speed,
+        float altitude,
+        char *comment) {
+
+    int i;
+
+    // Note that if we got an Origination Station element, the path
+    // here is not representative of the entire path the packet
+    // took, and in fact we don't know who the transmitting station
+    // was for this packet anymore, just the originating station for
+    // the packet.
+
+fprintf(stderr,"Origin Call: %s\nOrigin SSID: %d\n",origin_call,origin_ssid);
+
+    // The passed in value includes the SSID, but the
+    // size of the char[] is 7, which is bad - overflow
+    // Either need to fix how we deal with the origin_call
+    // or fix what it means. (with ssid or without)!!
+    // For now, I changed origin_call and source_call
+    // to be 10 bytes since that is what the rest of Xastir uses
+    // FIXME: Check if all of the OpenTrac_decode functions
+    //        expect callsign to have ssid already or not
+    // KJ5O
+
+    strncat(buffer,(char *)origin_call,10);
+
+    strncat(buffer,">",1);
+    strncat(buffer,(char *)dest,10);
+
+    for(i = 0; i < (int)digis; i++) {
+        strncat(buffer,",",1);
+        strncat(buffer,(char *)digi[i],10);
+        /* at the last digi always put a '*' when h_bit is set */
+        if (i == (int)(digis - 1)) {
+            if (digi_h[i] == (unsigned char)0x80) {
+                /* this digi must have transmitted the packet */
+                strncat(buffer,"*",1);
+            }
+        } else {
+            if (digi_h[i] == (unsigned char)0x80) {
+                /* only put a '*' when the next digi has no h_bit */
+                if (digi_h[i + 1] != (unsigned char)0x80) {
+                    /* this digi must have transmitted the packet */
+                    strncat(buffer,"*",1);
+                }
+            }
+        }
+    }
+    strncat(buffer,":",1);
+
+
+    // If we parsed a position, finish creating an APRS packet.
+    if (have_position) {
+        // We have latitude/longitude/altitude
+        // lat/lon are doubles, alt is a float
+        int ok;
+        unsigned long temp_lat, temp_lon;
+        char lat_str[20];
+        char lon_str[20];
+        char alt_str[20];
+
+
+fprintf(stderr, "Decoded this position: %f %f\n", latitude, longitude);
+ 
+        // Format it first in DDMM.MMMMN/DDDMM.MMMMW format
+        // lat/lon are doubles, alt is a float
+        //
+        // Convert lat/long to Xastir coordinate system first.
+        // We pass in floats and get returned longs, which
+        // represent 1/100 sec resolution lat/long.
+        ok = convert_to_xastir_coordinates (
+            &temp_lon,
+            &temp_lat,
+            (float)longitude,
+            (float)latitude);
+
+        if (ok) {
+            // Convert to a Base-91 compressed position so that
+            // we can use part of the extra resolution provided
+            // by OpenTrac.
+
+            // Convert to very high precision format, DDMM.MMMMN
+            convert_lat_l2s( temp_lat, lat_str, 20, CONVERT_VHP_NOSP);
+            convert_lon_l2s( temp_lon, lon_str, 20, CONVERT_VHP_NOSP);
+            if (entity_serial) {
+                // We have an entity that is non-zero.  Create a
+                // compressed APRS "Item" from the data.  NOTE:
+                // Items have to have at minimum 3, maximum 9
+                // characters for the name.
+                char entity_name[10];
+
+                if (strlen(displayname)) {
+                    xastir_snprintf(entity_name,
+                        sizeof(entity_name),
+                        "%s",
+                        displayname);
+                }
+                else {
+                    xastir_snprintf(entity_name,
+                        sizeof(entity_name),
+                        "Ent. %04x",    // Short for "Entity"
+                        entity_serial);
+                }
+
+                strncat(buffer,")",1);          // APRS Item packet
+                strncat(buffer,entity_name,9);  // Entity name
+                strncat(buffer,"!",1);
+
+                // Convert the high-resolution lat/long data to
+                // Base-91 compressed position:
+                strncat(buffer,
+                    compress_posit(lat_str,
+                        aprs_symbol_table,
+                        lon_str,
+                        aprs_symbol_char,
+                        course % 360,           // Course
+                        (int)(speed / 1.852),   // kph -> knots
+                        ""),    // PHG, we don't use it here
+                    13);
+            }
+            else {
+                // Entity is zero.  Create an APRS position packet.
+
+                strncat(buffer,"!",1); // APRS non-messaging position packet
+
+                // Convert the high-resolution lat/long data to
+                // Base-91 compressed position:
+                strncat(buffer,
+                    compress_posit(lat_str,
+                        aprs_symbol_table,
+                        lon_str,
+                        aprs_symbol_char,
+                        course % 360,           // Course
+                        (int)(speed / 1.852),   // kph -> knots
+                        ""),    // PHG, we don't use it here
+                    13);
+
+                if (strlen(displayname)) {
+                    // Add displayname
+                    strncat(buffer," ",1);
+                    strncat(buffer,displayname,40);
+                }
+            }
+
+            // Append the comment to the end.
+
+            // We must check length here.  APRS packets can't
+            // handle much.
+
+            // Altitude should be in feet "/A=001234", and placed in
+            // the comment field of an APRS packet.
+            xastir_snprintf(alt_str,
+                sizeof(alt_str),
+                " /A=%06d",
+                (int)(altitude * 3.28084)); // meters to feet
+            strncat(buffer,alt_str,10);
+
+            // We must limit the length here.  APRS Item packets
+            // can handle 43 chars in the comment field, Base-91
+            // compressed position packets can handle 40.
+            //
+            // Wait a minute!  We don't care how long they are
+            // as long as they fit through our APRS decoding.
+            // We're not transmitting these as APRS packets, so
+            // the max length in the APRS Spec doesn't matter
+            // here!
+            //
+            strncat(buffer,comment,126);
+        }
+    }
+
+    // Null-terminate the buffer string to make sure.
+    buffer[MAX_DEVICE_BUFFER - 1] = '\0';
+
+fprintf(stderr, "\n***** %s\n\n", buffer);
+
+    decode_ax25_line( buffer, DATA_VIA_TNC, 0, 1);
+
+    // Clear the buffer for the next round.
+    buffer[0] = '\0';
+}
+
+
+
+
+
+//WE7U: Protect "buffer" from getting overrun!!!
+//
+//***********************************************************
+// process_OpenTrac_packet()
+//
+// data     raw packet data: Points to first char of info field
+// len      length of info field of AX.25 packet
+// buffer   buffer to write readable packet data to
+// source   source callsign
+// ssid     ssid of source callsign
+// dest     destination callsign
+// digis    number of digi's that we're being passed
+// digi[][] digi list (up to 10 digis, 10 chars each)
+// digi_h   high bit of the digis (up to 10 chars)
+//
+// Function used to process an OpenTrac packet that is not in a
+// KISS frame.  In other words the underlying transport protocol
+// portions have been stripped off by this point, or perhaps the
+// packet was received from an OpenTrac internet feed that didn't
+// have anything to strip off.
+//
+// This is where the majority of the OpenTrac-specific decoding gets
+// done.  Much of the code for this routine and the routines above
+// that deal with OpenTrac packets was generously donated by Scott
+// Miller, N1VG.  He's allowing us to put it under the GPL license.
+//
+// A new sequence or a new entityID should trigger an APRS packet to
+// be generated (with the old sequence/entityID).  A packet should
+// also be generated at the end of processing.  There can be
+// multiple ID's and multiple locations embedded inside an OpenTrac
+// packet.
+//
+//***********************************************************
+
+char *process_OpenTrac_packet( unsigned char *data,
+                               unsigned int  len,
+                               char          *buffer,
+                               unsigned char *source_call,
+                               unsigned int  source_ssid,
+                               unsigned char *dest,
+                               unsigned int  digis,
+                               unsigned char digi[10][10],
+                               unsigned char *digi_h) {
+
+    int           elen;
+    int           etype;
+    unsigned int  decoded         = 0;
+    unsigned char origin_call[10];       // Where the packet originated
+    unsigned char origin_ssid     = 0;
+    unsigned char entity_call[10];       // What the packet is talking about
+    unsigned char entity_ssid     = 0x00;
+    unsigned int  entity_serial   = 0;
+    unsigned int  entity_sequence = 0;
+    unsigned int  temp_entity_sequence = 0;
+    unsigned char network         = 0;
+    long          rawtime         = 0;
+    int           have_position   = 0;
+    double        latitude        = 0.0;
+    double        longitude       = 0.0;
+    float         altitude        = 0;
+    int           course          = 0;
+    float         speed           = 0;
+    int           ambiguity       = 0;
+    char          country[3];
+    char          subdivision[4];
+    char          aircraft_id[9];
+    int           hazmat_id       = 0;
+    char          displayname[31];
+    char          maidenhead[7];
+    char          waypoint[7];
+    char          symbol[5];
+    char          aprs_symbol_table = '/';
+    char          aprs_symbol_char = '/';   // A "dot"
+    char          comment[127];
+
+
+    fprintf(stderr, "process_OpenTrac_packet()\n");
+
+    // Initialize strings
+    entity_call[0] = '\0';
+    country[0]     = '\0';
+    subdivision[0] = '\0';
+    aircraft_id[0] = '\0';
+    displayname[0] = '\0';
+    maidenhead[0]  = '\0';
+    waypoint[0]    = '\0';
+    symbol[0]      = '\0';
+    comment[0]     = '\0';
+
+    // Fill origin with source-call/SSID initially.
+    xastir_snprintf((char *)origin_call,
+        sizeof(origin_call),
+        "%s",
+        source_call);
+    origin_ssid = source_ssid;
+
+
+    // OpenTrac-specific decoding code.  For the moment we'll
+    // construct an APRS-format packet from it and send it through
+    // our regular decoding routines.  Later we'll dissect the
+    // OpenTrac packets and store them into their own data
+    // structures, but then we'll also need code in place for
+    // _displaying_ that data.
+
+
+    fprintf(stderr, "OpenTRAC: %d bytes\n", len);
+
+
+    // Main loop.  Keep decoding elements until we run out of things
+    // to process.
+    //
+    while (decoded < len) {
+        elen = (int)*data;
+        decoded += (elen & 0x7f)+1;
+        if (elen & 0x80) { // See if it's got a 16-bit ID
+            elen = (elen & 0x7f) - 2; // Strip the extid flag
+            etype = fetch16bits(++data);
+        }
+        else {
+            elen--; // Don't count the type byte
+            etype = (int)*(data+1);
+        }
+        data+=2; // Skip to the body
+        fprintf(stderr, "EID 0x%04x len %02d: ", etype, elen);
+        switch (etype) {
+            case (0x00): // Sequence
+                temp_entity_sequence = entity_sequence;
+
+                OpenTrac_decode_sequence(
+                    data,
+                    elen,
+                    &temp_entity_sequence);
+
+                if (temp_entity_sequence != entity_sequence) {
+
+                    process_opentrac_aprs(origin_call,
+                        origin_ssid,
+                        buffer,
+                        dest,
+                        digis,
+                        digi,
+                        digi_h,
+                        have_position,
+                        latitude, longitude,
+                        entity_serial,
+                        displayname,
+                        aprs_symbol_table,
+                        aprs_symbol_char,
+                        course,
+                        speed,
+                        altitude,
+                        comment);
+
+                    entity_sequence = temp_entity_sequence;
+                }
+
+// Problem here:  What to do for multi-sequence OpenTrac packets?
+// Generate a new APRS packet for each so that we get an entire
+// history?
+
+                break;
+            case (0x01): // Originating Station
+                temp_entity_sequence = entity_sequence;
+
+                OpenTrac_decode_origination(
+                    data,
+                    elen,
+                    &temp_entity_sequence,   // Origin sequence?
+                    (char *)origin_call,
+                    &origin_ssid,
+                    &network);
+
+                if (temp_entity_sequence != entity_sequence) {
+
+                    process_opentrac_aprs(origin_call,
+                        origin_ssid,
+                        buffer,
+                        dest,
+                        digis,
+                        digi,
+                        digi_h,
+                        have_position,
+                        latitude, longitude,
+                        entity_serial,
+                        displayname,
+                        aprs_symbol_table,
+                        aprs_symbol_char,
+                        course,
+                        speed,
+                        altitude,
+                        comment);
+
+                    entity_sequence = temp_entity_sequence;
+                }
+
+                // Originating station different from transmitting
+                // station.
+
+                break;
+            case (0x02): // Entity ID
+                temp_entity_sequence = entity_sequence;
+
+                OpenTrac_decode_entityid(
+                    data,
+                    elen,
+                    origin_call,
+                    origin_ssid,
+                    entity_call,
+                    &entity_ssid,
+                    &entity_serial,
+                    &temp_entity_sequence);
+
+                if (temp_entity_sequence != entity_sequence) {
+
+                    process_opentrac_aprs(origin_call,
+                        origin_ssid,
+                        buffer,
+                        dest,
+                        digis,
+                        digi,
+                        digi_h,
+                        have_position,
+                        latitude, longitude,
+                        entity_serial,
+                        displayname,
+                        aprs_symbol_table,
+                        aprs_symbol_char,
+                        course,
+                        speed,
+                        altitude,
+                        comment);
+
+                    entity_sequence = temp_entity_sequence;
+                }
+
+// We're dealing with a different entity than the transmitting or
+// originating station.  Need to do something different here,
+// perhaps creating an object or an item from it?
+
+                break;
+            case (0x10): // Position report
+                OpenTrac_decode_position(
+                    data,
+                    elen,
+                    &latitude,
+                    &longitude,
+                    &altitude);
+                have_position++;
+                break;
+            case (0x11): // Timestamp
+                OpenTrac_decode_timestamp(
+                    data,
+                    elen,
+                    &rawtime);
+                break;
+            case (0x12): // Comment
+                OpenTrac_decode_comment(
+                    data,
+                    elen,
+                    comment);
+                break;
+            case (0x13): // Course and Speed
+                OpenTrac_decode_courseandspeed(
+                    data,
+                    elen,
+                    &course,    // degrees true
+                    &speed);    // kph
+                break;
+            case (0x14): // Positional Ambiguity
+                OpenTrac_decode_ambiguity(
+                    data,
+                    elen,
+                    &ambiguity);
+                break;
+            case (0x15): // Country Code
+                OpenTrac_decode_country(
+                    data,
+                    elen,
+                    country,
+                    subdivision);
+                break;
+            case (0x16): // Display Name
+                OpenTrac_decode_displayname(
+                    data,
+                    elen,
+                    displayname);
+                break;
+            case (0x17): // Waypoint Name
+                OpenTrac_decode_waypoint(
+                    data,
+                    elen,
+                    waypoint);
+                break;
+            case (0x18): // Map Symbol
+                OpenTrac_decode_symbol(
+                    data,
+                    elen,
+                    symbol,
+                    &aprs_symbol_table,
+                    &aprs_symbol_char);
+                break;
+             case (0x20): // Path Trace
+                OpenTrac_decode_pathtrace(
+                    data,
+                    elen);
+                break;
+            case (0x21): // Heard-By List
+                OpenTrac_decode_heardby(
+                    data,
+                    elen);
+                break;
+            case (0x22): // Available Networks
+                OpenTrac_decode_availablenets(
+                    data,
+                    elen);
+                break;
+            case (0x32): // Maidenhead Locator
+                OpenTrac_decode_maidenhead(
+                    data,
+                    elen,
+                    maidenhead);
+                break;
+            case (0x33): // Radio Capabilities
+                OpenTrac_decode_radio_capabilities(
+                    data,
+                    elen);
+                break;
+            case (0x34): // GPS Data Quality
+                OpenTrac_decode_gpsquality(
+                    data,
+                    elen);
+                break;
+            case (0x35): // Aircraft Registration
+                OpenTrac_decode_acreg(
+                    data,
+                    elen,
+                    aircraft_id);
+                break;
+            case (0x40): // Surface Observation Report
+                OpenTrac_surface_observation(
+                    data,
+                    elen);
+                break;
+            case (0x41): // Rainfall History
+                OpenTrac_rainfall_history(
+                    data,
+                    elen);
+                break;
+            case (0x42): // River Flow Gauge
+                OpenTrac_decode_rivergauge(
+                    data,
+                    elen);
+                break;
+            case (0x43): // Storm Report
+                OpenTrac_decode_storm(
+                    data,
+                    elen);
+                break;
+            case (0x50): // Shape
+                OpenTrac_decode_shape(
+                    data,
+                    elen);
+                break;
+            case (0x100): // Emergency/distress flag
+                OpenTrac_flag_emergency();
+                break;
+            case (0x101): // Attention/ident flag
+                OpenTrac_flag_attention();
+                break;
+            case (0x300): // Hazmat
+                OpenTrac_decode_hazmat(
+                    data,
+                    elen,
+                    &hazmat_id,
+                    comment,
+                    sizeof(comment));
+                break;
+            case (0xffff): // Null element
+                fprintf(stderr, "Null element\n");
+                break;
+            default: // Everything else
+
+                // Check for Generic Measurement Units (0x500 to
+                // 0x5ff inclusive) 
+                if ((etype & 0xff00) == 0x500) {
+                    OpenTrac_decode_units(
+                        etype & 0x00ff,
+                        data,
+                        elen,
+                        comment,
+                        sizeof(comment));
+                }
+                else {
+
+                    // Not a measurement unit.  Print out something
+                    // about what we found.
+                    fprintf(stderr,
+                        "Unknown Element Type, ");
+
+                    // Provide more data about the class of element
+                    // if we can, even if we don't know the specific
+                    // element type.
+                    //
+                    if (     (etype & 0xfff0) == 0x0000) {
+                        fprintf(stderr, "Class: Stream Control\n");
+                    }
+                    else if ((etype & 0xfff0) == 0x0010) {
+                        fprintf(stderr, "Class: Common Attribute\n");
+                    }
+                    else if ((etype & 0xfff0) == 0x0020) {
+                        fprintf(stderr, "Class: Network Information\n");
+                    }
+//                    else if ((etype & 0xfff0) == 0x0030) {
+//                        fprintf(stderr, "Class: ??\n");
+//                    }
+                    else if ((etype & 0xfff0) == 0x0040) {
+                        fprintf(stderr, "Class: Weather\n");
+                    }
+//                    else if ((etype & 0xfff0) == 0x0050) {
+//                        fprintf(stderr, "Class: ??\n");
+//                    }
+                    else if ((etype & 0xff00) == 0x0100) {
+                        fprintf(stderr, "Class: Status Flags\n");
+                    }
+                    else if ((etype & 0xff00) == 0x0200) {
+                        fprintf(stderr, "Class: Incident Command System\n");
+                    }
+                    else if ((etype & 0xff00) == 0xf000) {
+                        // Note:  0xffff Null element is caught
+                        // before we get to here.
+                        fprintf(stderr, "Class: Experimental\n");
+                    }
+                    else {
+                        fprintf(stderr, "Class: Unknown\n");
+                    }
+                }
+                break;
+        }
+        data+=elen;
+    }
+
+    process_opentrac_aprs(origin_call,
+        origin_ssid,
+        buffer,
+        dest,
+        digis,
+        digi,
+        digi_h,
+        have_position,
+        latitude, longitude,
+        entity_serial,
+        displayname,
+        aprs_symbol_table,
+        aprs_symbol_char,
+        course,
+        speed,
+        altitude,
+        comment);
+
+    return( buffer );
+}
+ 
+
+
+
+
+//***********************************************************
+// process_ax25_packet()
+//
+// bp           raw packet data
+// len          length of raw packet data
+// buffer       buffer to write readable packet data to
+// buffer_size  max length of buffer
+//
+// Note that db.c:decode_ax25_header does much the same thing for
+// Serial KISS interface packets.  Consider combining the two
+// functions.  process_ax25_packet() would be the earlier and more
+// thought-out function.  This function now has some OpenTrac code
+// as well.
+//***********************************************************
+
+char *process_ax25_packet(unsigned char *bp, unsigned int len, char *buffer, int buffer_size) {
+    int i,j;
+    unsigned int  k,l;
+    unsigned int  digis;
+    unsigned char source[10];
+    unsigned char dest[10];
+    unsigned char digi[10][10];
+    unsigned char digi_h[10];
+    unsigned int  ssid;
+    unsigned char message[513];
+
+    if ( (bp == NULL) || (buffer == NULL) )
+        return(NULL);
+
+    /* clear buffer */
+    buffer[0] = '\0';
+
+    if (*bp != (unsigned char)0)
+        return(NULL); /* not a DATA packet */
+
+    // We have a KISS packet here, so we know that the first
+    // character is a flag character.  Skip over it.
+    bp++;
+    len--;
+
+    // Check the length to make sure that we don't have an empty
+    // packet.
+    if (!bp || !len)
+        return(NULL);
+
+    // Check for minimum KISS frame bytes.
+    if (len < 15)
+        return(NULL);
+
+    if (bp[1] & 1) /* Compressed FlexNet Header */
+        return(NULL);
+
+    /* Destination of frame */
+    j = 0;
+    for(i = 0; i < 6; i++) {
+        if ((bp[i] &0xfe) != (unsigned char)0x40)
+            dest[j++] = bp[i] >> 1;
+    }
+    ssid = (unsigned int)( (bp[6] & 0x1e) >> 1 );
+    if (ssid != 0) {
+        dest[j++] = '-';
+        if ((ssid / 10) != 0) {
+            dest[j++] = '1';
+        }
+        ssid = (ssid % 10);
+        dest[j++] = (unsigned char)ssid + (unsigned char)'0';
+    }
+    dest[j] = '\0';
+    bp += 7;
+    len -= 7;
+
+    /* Source of frame */
+    j = 0;
+    for(i = 0; i < 6; i++) {
+        if ((bp[i] &0xfe) != (unsigned char)0x40)
+            source[j++] = bp[i] >> 1;
+    }
+    ssid = (unsigned int)( (bp[6] & 0x1e) >> 1 );
+    if (ssid != 0) {
+        source[j++] = '-';
+        if ((ssid / 10) != 0) {
+            source[j++] = '1';
+        }
+        // Commented out by Lance KJ5O. Why is this here?
+        // It destroys the ssid value. I moved the calculation
+        // to the source-construction line. But we need to be consistent
+        // in what the variables are. Is "source" including the SSID or not?
+        // This function allocatees 10 bytes, and so assumes that SSID belongs
+        // However, in process_OpenTrac_packet, origin_ssid is 7 bytes.
+        // ssid = (ssid % 10);
+
+        source[j++] = (unsigned char)(ssid % 10) + (unsigned char)'0';
+        // source[j++] = (unsigned char)ssid + (unsigned char)'0';
+    }
+    source[j] = '\0';
+    bp += 7;
+    len -= 7;
+
+    // by KJ5O - test for proper extraction of source call and ssid
+    // fprintf(stderr, "|KJ5O-test| %s-%d\n", source, ssid);
+
+    /* Digipeaters */
+    digis = 0;
+    while ((!(bp[-1] & 1)) && (len >= 7)) {
+        /* Digi of frame */
+        if (digis != 10) {
+            j = 0;
+            for (i = 0; i < 6; i++) {
+                if ((bp[i] &0xfe) != (unsigned char)0x40)
+                    digi[digis][j++] = bp[i] >> 1;
+            }
+            digi_h[digis] = (bp[6] & 0x80);
+            ssid = (unsigned int)( (bp[6] & 0x1e) >> 1 );
+            if (ssid != 0) {
+                digi[digis][j++] = '-';
+                if ((ssid / 10) != 0) {
+                    digi[digis][j++] = '1';
+                }
+                ssid = (ssid % 10);
+                digi[digis][j++] = (unsigned char)ssid + (unsigned char)'0';
+            }
+            digi[digis][j] = '\0';
+            digis++;
+        }
+        bp += 7;
+        len -= 7;
+    }
+    if (!len)
+        return(NULL);
+
+    /* We are now at the primitive bit */
+    i = (int)(*bp++);
+    len--;
+
+    /* strip the poll-bit from the primitive */
+    i = i & (~0x10);
+
+    /* return if this is not an UI frame (= 0x03) */
+    if(i != 0x03)
+        return(NULL);
+
+    /* no data left */
+    if (!len)
+        return(NULL);
+
+    // Check whether we're dealing with an OpenTrac KISS packet.  If
+    // so, go process it and then pass through the return code that
+    // the OpenTrac functions provide.
+    if (*bp == 0x77) {
+        char* ret;
+
+        bp++;
+        len--;
+        // We have an OpenTrac packet.
+        ret = process_OpenTrac_packet(
+                    bp,
+                    len,
+                    buffer,
+                    source,
+                    ssid,
+                    dest,
+                    digis,
+                    digi,
+                    digi_h);
+
+        // If we wish to process some APRS-converted OpenTrac
+        // packet: 
+        return(ret);
+
+        // If we processed it in another manner and just wish to
+        // quit:
+        //return(NULL);
+
+    }
+    else if(*bp != (unsigned char)0xF0) {   // APRS PID
+        // We _don't_ have an APRS packet
+        return(NULL);
+    }
+
+    // We have what looks like a valid KISS-frame containing APRS
+    // protocol data.
+
+    bp++;
+    len--;
+    k = 0;
+    l = 0;
+    while (len) {
+        i = (int)(*bp++);
+        if ((i != (int)'\n') && (i != (int)'\r')) {
+            if (l < 512)
+                message[l++] = (unsigned char)i;
+        }
+        len--;
+    }
+    /* add terminating '\0' to allow handling as a string */
+    message[l] = '\0';
+
+    xastir_snprintf(buffer,
+        buffer_size,
+        "%s",
+        source);
+
+    /*
+     * if there are no digis or the first digi has not handled the
+     * packet then this is directly from the source, mark it with
+     * a "*" in that case
+     */
+
+    /* I don't think we need this just yet, perhaps not at all? */
+    /* I think if we don't have a '*' in the path we can assume direct? -FG */
+    /*
+    if((digis == 0) || (digi_h[0] != 0x80))
+        strncat(buffer, "*", buffer_size - 1 - strlen(buffer));
+     */
+
+    strncat(buffer, ">", buffer_size - 1 - strlen(buffer));
+
+    /* destination is at the begining of the chain, because it is  */
+    /* needed so MIC-E packets can be decoded correctly. */
+    /* this may be changed in the future but for now leave it here -FG */
+    strncat(buffer, (char *)dest, buffer_size - 1 - strlen(buffer));
+
+    for(i = 0; i < (int)digis; i++) {
+        strncat(buffer, ",", buffer_size - 1 - strlen(buffer));
+        strncat(buffer, (char *)digi[i], buffer_size - 1 - strlen(buffer));
+        /* at the last digi always put a '*' when h_bit is set */
+        if (i == (int)(digis - 1)) {
+            if (digi_h[i] == (unsigned char)0x80) {
+                /* this digi must have transmitted the packet */
+                strncat(buffer, "*", buffer_size - 1 - strlen(buffer));
+            }
+        } else {
+            if (digi_h[i] == (unsigned char)0x80) {
+                /* only put a '*' when the next digi has no h_bit */
+                if (digi_h[i + 1] != (unsigned char)0x80) {
+                    /* this digi must have transmitted the packet */
+                    strncat(buffer, "*", buffer_size - 1 - strlen(buffer));
+                }
+            }
+        }
+    }
+    strncat(buffer, ":", buffer_size - 1 - strlen(buffer));
+
+    //Copy into only the free space in buffer.
+    strncat( buffer, (char *)message, MAX_DEVICE_BUFFER - 1 - strlen(buffer));
+
+    // And null-terminate it to make sure.
+    buffer[MAX_DEVICE_BUFFER - 1] = '\0';
+
+    return(buffer);
+}
+
+
+
+
+
+//*********************************************************
+// AX25 port INIT
+//
+// port is port# used
+//*********************************************************
+
+int ax25_init(int port) {
+
+    /*
+        COMMENT:tested this Seems to work fine as ETH_P_AX25
+        on newer linux kernels (and you see your own transmissions
+        but it is not good for older linux kernels and FreeBSD  -FG
+    */
+
+#ifdef HAVE_LIBAX25
+    int proto = PF_AX25;
+    char temp[200];
+    char *dev = NULL;
+#endif  // HAVE_LIBAX25
+
+    if (begin_critical_section(&port_data_lock, "interface.c:ax25_init(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    /* clear port_channel */
+//    port_data[port].channel = -1;
+
+    /* clear port active */
+    port_data[port].active = DEVICE_NOT_IN_USE;
+
+    /* clear port status */
+    port_data[port].status = DEVICE_DOWN;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+#ifdef HAVE_LIBAX25
+    if (ax25_ports_loaded == 0) {
+        /* port file has not been loaded before now */
+        if (ax25_config_load_ports() == 0) {
+            fprintf(stderr, "ERROR: problem with axports file\n");
+            popup_message(langcode("POPEM00004"),langcode("POPEM00013"));
+
+            if (end_critical_section(&port_data_lock, "interface.c:ax25_init(2)" ) > 0)
+                fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+            return -1;
+        }
+        /* we can only load the port file once!!! so do not load again */
+        ax25_ports_loaded = 1;
+    }
+
+    if (port_data[port].device_name != NULL) {
+        if ((dev = ax25_config_get_dev(port_data[port].device_name)) == NULL) {
+            xastir_snprintf(temp, sizeof(temp), langcode("POPEM00014"),
+                    port_data[port].device_name);
+            popup_message(langcode("POPEM00004"),temp);
+
+            if (end_critical_section(&port_data_lock, "interface.c:ax25_init(3)" ) > 0)
+                fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+            return -1;
+        }
+    }
+
+    /* COMMENT: tested this AF_INET is CORRECT -FG */
+    // Commented out sections below.  We keep the old socket number
+    // around now, so have to start a new socket in all cases to make it work.
+//    if (port_data[port].channel == -1) {
+
+    ENABLE_SETUID_PRIVILEGE;
+#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 3
+    port_data[port].channel = socket(PF_INET, SOCK_DGRAM, htons(proto));   // proto = AF_AX25
+#else   // __GLIBC__ >= 2 && __GLIBC_MINOR >= 3
+    port_data[port].channel = socket(PF_INET, SOCK_PACKET, htons(proto));
+#endif      // __GLIBC__ >= 2 && __GLIBC_MINOR >= 3
+    DISABLE_SETUID_PRIVILEGE;
+
+    if (port_data[port].channel == -1) {
+        perror("socket");
+        if (end_critical_section(&port_data_lock, "interface.c:ax25_init(4)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        return -1;
+    }
+
+//    }
+//    else {
+        // Use socket number that is already defined
+//    }
+
+    /* port active */
+    port_data[port].active = DEVICE_IN_USE;
+
+    /* port status */
+    port_data[port].status = DEVICE_UP;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+#else /* HAVE_LIBAX25 */
+    fprintf(stderr,"AX.25 support not compiled into Xastir!\n");
+    popup_message(langcode("POPEM00004"),langcode("POPEM00021"));
+#endif /* HAVE_LIBAX25 */
+    if (end_critical_section(&port_data_lock, "interface.c:ax25_init(5)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    return(1);
+}
+
+//********************************* STOP AX.25 ********************************
+
+
+
+
+
+//*************************** START SERIAL PORT FUNCTIONS ********************************
+
+
+//******************************************************
+// command file to tnc port
+// port to send config data to
+// Filename containing the config data
+//******************************************************
+int command_file_to_tnc_port(int port, char *filename) {
+    FILE *f;
+    char line[MAX_LINE_SIZE+1];
+    char command[MAX_LINE_SIZE+5];
+    int i;
+    char cin;
+    int error;
+    struct stat file_status;
+
+
+    if (filename == NULL)
+        return(-1);
+
+    // Check file status
+    if (stat(filename, &file_status) < 0) {
+        fprintf(stderr,
+            "Couldn't stat file: %s\n",
+            filename);
+        fprintf(stderr,
+            "Skipping send to TNC\n");
+        return(-1);
+    }
+
+    // Check that it is a regular file
+    if (!S_ISREG(file_status.st_mode)) {
+        fprintf(stderr,
+            "File is not a regular file: %s\n",
+            filename);
+        fprintf(stderr,
+            "Skipping send to TNC\n");
+        return(-1);
+    } 
+
+    error = 0;
+    i = 0;
+    f = fopen(filename,"r");
+    if (f != NULL) {
+        int send_ctrl_C = 1;
+
+        line[0] = (char)0;
+        while (!feof(f) && error != -1) {
+
+            if (fread(&cin,1,1,f) == 1) {
+
+                // Check for <LF>/<CR>
+                if (cin != (char)10 && cin != (char)13) {
+
+                    // If NOT <LF> or <CR>
+                    if (i < MAX_LINE_SIZE) {
+
+                        // Add to buffer
+                        line[i++] = cin;
+                        line[i] = (char)0;
+                    }
+                }
+
+                else {  // Found a <LF> or <CR>, process line
+                    i = 0;
+
+                    // Check whether comment or zero-length line
+                    if (line[0] != '#' && strlen(line) > 0) {
+
+                        // Line looks good.  Send it to the TNC.
+
+                        if (send_ctrl_C) {
+                            // Control-C desired
+                            xastir_snprintf(command,
+                                sizeof(command),
+                                "%c%s\r",
+                                (char)03,   // Control-C
+                                line);
+                        }
+                        else {
+                            // No Control-C desired
+                            xastir_snprintf(command,
+                                sizeof(command),
+                                "%s\r",
+                                line);
+                        }
+
+                        if (debug_level & 2)
+                            fprintf(stderr,"CMD:%s\n",command);
+
+                        port_write_string(port,command);
+                        line[0] = (char)0;
+
+                        // Set flag to default condition
+                        send_ctrl_C = 1;
+                    }
+                    else {  // Check comment to see if it is a META
+                            // command
+
+                        // Should we make these ignore white-space?
+
+                        if (strncasecmp(line, "##META <", 8) == 0) {
+                            // Found a META command, process it
+                            if (strncasecmp(line+8, "delay", 5) == 0) {
+                                usleep(500000); // Sleep 500ms
+                            }
+                            else if (strncasecmp(line+8, "no-ctrl-c", 9) == 0) {
+                                // Reset the flag
+                                send_ctrl_C = 0;
+                            }
+                            else {
+                                fprintf(stderr,
+                                    "Unrecognized ##META command: %s\n",
+                                    line);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        (void)fclose(f);
+    } else {
+        if (debug_level & 2)
+            fprintf(stderr,"Could not open TNC command file: %s\n",filename);
+    }
+
+    return(error);
+}
+
+
+
+
+
+//***********************************************************
+// port_dtr INIT
+// port is port# used
+// dtr 1 is down, 0 is normal(up)
+//***********************************************************
+void port_dtr(int port, int dtr) {
+
+// It looks like we have two methods of getting this to compile on
+// CYGWIN, getting rid of the entire procedure contents, and getting
+// rid of the TIO* code.  One method or the other should work to get
+// it compiled.  We shouldn't need both.
+    int sg;
+
+    /* check for 1 or 0 */
+    dtr = (dtr & 0x1);
+
+    if (begin_critical_section(&port_data_lock, "interface.c:port_dtr(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    if (port_data[port].active == DEVICE_IN_USE
+            && port_data[port].status == DEVICE_UP
+            && port_data[port].device_type == DEVICE_SERIAL_TNC_HSP_GPS){
+
+        port_data[port].dtr = dtr;
+        if (debug_level & 2)
+            fprintf(stderr,"DTR %d\n",port_data[port].dtr);
+
+#ifdef TIOCMGET
+            ENABLE_SETUID_PRIVILEGE;
+        (void)ioctl(port_data[port].channel, TIOCMGET, &sg);
+            DISABLE_SETUID_PRIVILEGE;
+#endif  // TIOCMGET
+
+        sg &= 0xff;
+
+#ifdef TIOCM_DTR
+
+// ugly HPUX hack - n8ysz 20041206
+
+#ifndef MDTR 
+#define MDTR 99999
+#if (TIOCM_DTR == 99999)
+#include <sys/modem.h>
+#endif 
+#endif
+
+// end ugly hack
+
+        sg = TIOCM_DTR;
+#endif  // TIOCM_DIR
+
+        if (dtr) {
+            dtr &= ~sg;
+
+#ifdef TIOCMBIC
+            ENABLE_SETUID_PRIVILEGE;
+            (void)ioctl(port_data[port].channel, TIOCMBIC, &sg);
+            DISABLE_SETUID_PRIVILEGE;
+#endif  // TIOCMBIC
+
+            if (debug_level & 2)
+                fprintf(stderr,"Down\n");
+
+            // statusline(langcode("BBARSTA026"),1);
+
+        } else {
+            dtr |= sg;
+
+#ifdef TIOCMBIS
+            ENABLE_SETUID_PRIVILEGE;
+            (void)ioctl(port_data[port].channel, TIOCMBIS, &sg);
+            DISABLE_SETUID_PRIVILEGE;
+#endif  // TIOCMBIS
+
+            if (debug_level & 2)
+                fprintf(stderr,"UP\n");
+
+            // statusline(langcode("BBARSTA027"),1);
+        }
+    }
+
+    if (end_critical_section(&port_data_lock, "interface.c:port_dtr(2)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+}
+
+
+
+
+
+//***********************************************************
+// port_dtr INIT
+// port is port# used
+// dtr 1 is down, 0 is normal(up)
+//***********************************************************
+void dtr_all_set(int dtr) {
+    int i;
+
+//fprintf(stderr,"dtr_all_set(%d)\t",dtr);
+    for (i = 0; i < MAX_IFACE_DEVICES; i++) {
+        if (port_data[i].device_type == DEVICE_SERIAL_TNC_HSP_GPS
+                && port_data[i].status == DEVICE_UP) {
+            port_dtr(i,dtr);
+        }
+    }
+}
+
+
+
+
+
+//***********************************************************
+// Serial port close.  Remove the lockfile as well.
+// port is port# used
+//***********************************************************
+int serial_detach(int port) {
+    char fn[600];
+    int ok;
+    ok = -1;
+
+    if (begin_critical_section(&port_data_lock, "interface.c:serial_detach(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    if (port_data[port].active == DEVICE_IN_USE && port_data[port].status == DEVICE_UP){
+
+        // Close port first
+        (void)tcsetattr(port_data[port].channel, TCSANOW, &port_data[port].t_old);
+        if (close(port_data[port].channel) == 0) {
+            port_data[port].status = DEVICE_DOWN;
+            usleep(200);
+            port_data[port].active = DEVICE_NOT_IN_USE;
+            ok = 1;
+
+            // Show the latest status in the interface control dialog
+            update_interface_list();
+        }
+        else {
+            if (debug_level & 2)
+                fprintf(stderr,"Could not close port %s\n",port_data[port].device_name);
+
+            port_data[port].status = DEVICE_DOWN;
+            usleep(200);
+            port_data[port].active = DEVICE_NOT_IN_USE;
+
+            // Show the latest status in the interface control dialog
+            update_interface_list();
+        }
+
+        // Delete lockfile
+        xastir_snprintf(fn, sizeof(fn), "/var/lock/LCK..%s", get_device_name_only(port_data[port].device_name));
+        if (debug_level & 2)
+            fprintf(stderr,"Delete lock file %s\n",fn);
+
+        ENABLE_SETUID_PRIVILEGE;
+        (void)unlink(fn);
+        DISABLE_SETUID_PRIVILEGE;
+    }
+    else {
+
+        // If we didn't have the port in use, for instance we
+        // weren't able to open it, we should check whether a
+        // lockfile exists for the port and see if another running
+        // process owns the lockfile (the PID of the owner is inside
+        // the lockfile).  If not, remove the lockfile 'cuz it may
+        // have been ours from this or a previous run.  Note that we
+        // can now run multiple Xastir sessions from a single user,
+        // and the lockfiles must be kept straight between them.  If
+        // a lockfile doesn't contain a PID from a running process,
+        // it's fair game to delete the lockfile and/or take over
+        // the port with a new lockfile.
+        //
+        //   if (lockfile exists) {
+        //       PID = read contents of lockfile
+        //       if (PID is running) {
+        //           Do nothing, leave the file alone
+        //       }
+        //       else {
+        //           Delete the lockfile
+        //       }
+        //   }
+    }
+
+    if (end_critical_section(&port_data_lock, "interface.c:serial_detach(2)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    return(ok);
+}
+
+
+
+
+
+//***********************************************************
+// Serial port INIT
+// port is port# used
+//***********************************************************
+int serial_init (int port) {
+    FILE *lock;
+    int speed;
+    pid_t mypid = 0;
+    pid_t lockfile_pid = 0;
+    int lockfile_intpid;
+    char fn[600];
+    uid_t user_id;
+    struct passwd *user_info;
+    char temp[100];
+    char temp1[100];
+    pid_t status;
+    int ii;
+    int myerrno;
+
+    status = -9999;
+
+    if (begin_critical_section(&port_data_lock, "interface.c:serial_init(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    // clear port_channel
+    port_data[port].channel = -1;
+
+    // clear port active
+    port_data[port].active = DEVICE_NOT_IN_USE;
+
+    // clear port status
+    port_data[port].status = DEVICE_DOWN;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+
+    // Check whether we have a port with the same device already
+    // open.  Check all ports except this one and check for
+    // DEVICE_IN_USE.  If found, check whether the device_name
+    // matches.  If a match, skip initializing this port.
+    //
+    for (ii = 0; ii < MAX_IFACE_DEVICES; ii++) {
+        if (ii != port) {
+            if (port_data[ii].active == DEVICE_IN_USE) {
+                if (strcmp(port_data[ii].device_name, port_data[port].device_name) == 0) {
+                    // Found a port with the same device_name which
+                    // is already active.  Skip bringing up another
+                    // interface on the same port.
+                    return(-1);
+                }
+            }
+        }
+    }
+
+
+    // check for lockfile
+    xastir_snprintf(fn, sizeof(fn), "/var/lock/LCK..%s",
+            get_device_name_only(port_data[port].device_name));
+
+    if (filethere(fn) == 1) {
+
+        // Also look for pid of other process and see if it is a valid lock
+        fprintf(stderr,"Found an existing lockfile %s for this port!\n",fn);
+
+        lock = fopen(fn,"r");
+        if (lock != NULL) { // We could open it so it must have
+                            // been created by this userid
+            if (fscanf(lock,"%d %99s %99s",&lockfile_intpid,temp,temp1) == 3) {
+                //fprintf(stderr,"Current lock %d %s %s\n",lockfile_intpid,temp,temp1);
+                lockfile_pid = (pid_t)lockfile_intpid;
+
+#ifdef HAVE_GETPGRP
+  #ifdef GETPGRP_VOID   
+                // Won't this one get our process group instead of
+                // the process group for the lockfile?  Not of that
+                // much use to us here.
+                status = getpgrp();
+  #else // GETPGRP_VOID
+                status = getpgrp(lockfile_pid);
+  #endif // GETPGRP_VOID
+#else   // HAVE_GETPGRP
+                status = getpgid(lockfile_pid);
+#endif // HAVE_GETPGRP
+
+            }
+            else {
+                // fscanf parsed the wrong number of items.
+                // lockfile is different, perhaps created by some
+                // other program.
+            }
+
+            (void)fclose(lock);
+
+            // See whether the existing lockfile is stale.  Remove
+            // the file if it belongs to our process group or if the
+            // PID in the file is no longer running.
+            //
+            // The only time we _shouldn't_ delete the file and
+            // claim the port for our own is when the process that
+            // created the lockfile is still running.
+
+            // Get my process id
+            mypid = getpid();
+
+            // If status = -1, the process that created the lockfile
+            // is no longer running and of course will not match
+            // "lockfile_pid", so we can delete it.
+            //
+            // If "lockfile_pid == mypid", then this currently
+            // running instance of Xastir was the one that created
+            // the lockfile and it is again ok to delete it.
+            //
+            if (status != lockfile_pid || lockfile_pid == mypid) {
+                fprintf(stderr,"Lock is stale!  Removing it.\n");
+                ENABLE_SETUID_PRIVILEGE;
+                (void)unlink(fn);
+                DISABLE_SETUID_PRIVILEGE;
+            }
+            else {
+                fprintf(stderr,"Cannot open port:  Another program has the lock!\n");
+
+                if (end_critical_section(&port_data_lock, "interface.c:serial_init(2)" ) > 0)
+                    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+                return (-1);
+            }
+        }
+        else {    // Couldn't open it, so the lock must have been
+                    // created by another userid
+            fprintf(stderr,"Cannot open port:  Lockfile cannot be opened!\n");
+
+            if (end_critical_section(&port_data_lock, "interface.c:serial_init(3)" ) > 0)
+                fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+            return (-1);
+        }
+    }
+
+    // Try to open the serial port now
+    ENABLE_SETUID_PRIVILEGE;
+    port_data[port].channel = open(port_data[port].device_name, O_RDWR|O_NOCTTY);
+    myerrno = errno;
+    DISABLE_SETUID_PRIVILEGE;
+    if (port_data[port].channel == -1){
+
+        if (end_critical_section(&port_data_lock, "interface.c:serial_init(4)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not open channel on port %d!\n",port);
+
+        switch (myerrno) {
+
+            case EACCES:
+                fprintf(stderr,"\tEACCESS ERROR\n");
+                break;
+
+            case EEXIST:
+                fprintf(stderr,"\tEEXIST ERROR\n");
+                break;
+
+            case EFAULT:
+                fprintf(stderr,"\tEFAULT ERROR\n");
+                break;
+
+            case EISDIR:
+                fprintf(stderr,"\tEISDIR ERROR\n");
+                break;
+
+            case ELOOP:
+                fprintf(stderr,"\tELOOP ERROR\n");
+                break;
+
+            case EMFILE:
+                fprintf(stderr,"\tEMFILE ERROR\n");
+                break;
+
+            case ENAMETOOLONG:
+                fprintf(stderr,"\tENAMETOOLONG ERROR\n");
+                break;
+
+            case ENFILE:
+                fprintf(stderr,"\tEMFILE ERROR\n");
+                break;
+
+            case ENODEV:
+                fprintf(stderr,"\tENODEV ERROR\n");
+                break;
+
+            case ENOENT:
+                fprintf(stderr,"\tENOENT ERROR\n");
+                break;
+
+            case ENOMEM:
+                fprintf(stderr,"\tENOMEM ERROR\n");
+                break;
+
+            case ENOSPC:
+                fprintf(stderr,"\tENOSPC ERROR\n");
+                break;
+
+            case ENOTDIR:
+                fprintf(stderr,"\tENOTDIR ERROR\n");
+                break;
+
+            case ENXIO:
+                fprintf(stderr,"\tENXIO ERROR\n");
+                break;
+
+            case EOVERFLOW:
+                fprintf(stderr,"\tEOVERFLOW ERROR\n");
+                break;
+
+            case EPERM:
+                fprintf(stderr,"\tEPERM ERROR\n");
+                break;
+
+            case EROFS:
+                fprintf(stderr,"\tEROFS ERROR\n");
+                break;
+
+            case ETXTBSY:
+                fprintf(stderr,"\tETXTBSY ERROR\n");
+                break;
+
+            default:
+                fprintf(stderr,"\tOTHER ERROR\n");
+                break;
+        }
+
+        return (-1);
+    }
+
+    // Attempt to create the lockfile
+    xastir_snprintf(fn, sizeof(fn), "/var/lock/LCK..%s", get_device_name_only(port_data[port].device_name));
+    if (debug_level & 2)
+        fprintf(stderr,"Create lock file %s\n",fn);
+
+    ENABLE_SETUID_PRIVILEGE;
+    lock = fopen(fn,"w");
+    DISABLE_SETUID_PRIVILEGE;
+    if (lock != NULL) {
+        // get my process id for lockfile
+        mypid = getpid();
+
+        // get user info
+        user_id = getuid();
+        user_info = getpwuid(user_id);
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s",
+            user_info->pw_name);
+
+        fprintf(lock,"%9d %s %s",(int)mypid,"xastir",temp);
+        (void)fclose(lock);
+        // We've successfully created our own lockfile
+    }
+    else {
+        // lock failed
+        if (debug_level & 2)
+            fprintf(stderr,"Warning:  Failed opening LCK file!  Continuing on...\n");
+
+        /* if we can't create lockfile don't fail!
+
+if (end_critical_section(&port_data_lock, "interface.c:serial_init(5)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        return (-1);*/
+    }
+
+    // get port attributes for new and old
+    if (tcgetattr(port_data[port].channel, &port_data[port].t) != 0) {
+
+    if (end_critical_section(&port_data_lock, "interface.c:serial_init(6)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not get t port attributes for port %d!\n",port);
+
+        // Close the port and remove the lock.
+        serial_detach(port);
+
+        return (-1);
+    }
+
+    if (tcgetattr(port_data[port].channel, &port_data[port].t_old) != 0) {
+
+    if (end_critical_section(&port_data_lock, "interface.c:serial_init(7)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not get t_old port attributes for port %d!\n",port);
+
+        // Close the port and remove the lock.
+        serial_detach(port);
+
+        return (-1);
+    }
+
+    // set time outs
+    port_data[port].t.c_cc[VMIN] = (cc_t)1;
+    port_data[port].t.c_cc[VTIME] = (cc_t)2;
+
+    // set port flags
+    port_data[port].t.c_iflag &= ~(BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
+    port_data[port].t.c_iflag = (tcflag_t)(IGNBRK | IGNPAR);
+
+    port_data[port].t.c_oflag = (0);
+    port_data[port].t.c_lflag = (0);
+
+#ifdef    CBAUD
+    speed = (int)(port_data[port].t.c_cflag & CBAUD);
+#else   // CBAUD
+    speed = 0;
+#endif  // CBAUD
+    port_data[port].t.c_cflag = (tcflag_t)(HUPCL|CLOCAL|CREAD);
+    port_data[port].t.c_cflag &= ~PARENB;
+    switch (port_data[port].style){
+        case(0):
+            // No parity (8N1)
+            port_data[port].t.c_cflag &= ~CSTOPB;
+            port_data[port].t.c_cflag &= ~CSIZE;
+            port_data[port].t.c_cflag |= CS8;
+            break;
+
+        case(1):
+            // Even parity (7E1)
+            port_data[port].t.c_cflag &= ~PARODD;
+            port_data[port].t.c_cflag &= ~CSTOPB;
+            port_data[port].t.c_cflag &= ~CSIZE;
+            port_data[port].t.c_cflag |= CS7;
+            break;
+
+        case(2):
+            // Odd parity (7O1):
+            port_data[port].t.c_cflag |= PARODD;
+            port_data[port].t.c_cflag &= ~CSTOPB;
+            port_data[port].t.c_cflag &= ~CSIZE;
+            port_data[port].t.c_cflag |= CS7;
+            break;
+
+        default:
+            break;
+    }
+
+    port_data[port].t.c_cflag |= speed;
+    // set input and out put speed
+    if (cfsetispeed(&port_data[port].t, port_data[port].sp) == -1) {
+
+    if (end_critical_section(&port_data_lock, "interface.c:serial_init(8)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not set port input speed for port %d!\n",port);
+
+        // Close the port and remove the lock.
+        serial_detach(port);
+
+        return (-1);
+    }
+
+    if (cfsetospeed(&port_data[port].t, port_data[port].sp) == -1) {
+
+        if (end_critical_section(&port_data_lock, "interface.c:serial_init(9)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not set port output speed for port %d!\n",port);
+
+        // Close the port and remove the lock.
+        serial_detach(port);
+
+        return (-1);
+    }
+
+    if (tcflush(port_data[port].channel, TCIFLUSH) == -1) {
+
+        if (end_critical_section(&port_data_lock, "interface.c:serial_init(10)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not flush data for port %d!\n",port);
+
+        // Close the port and remove the lock.
+        serial_detach(port);
+
+        return (-1);
+    }
+
+    if (tcsetattr(port_data[port].channel,TCSANOW, &port_data[port].t) == -1) {
+
+        if (end_critical_section(&port_data_lock, "interface.c:serial_init(11)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (debug_level & 2)
+            fprintf(stderr,"Could not set port attributes for port %d!\n",port);
+
+        // Close the port and remove the lock.
+        serial_detach(port);
+
+        return (-1);
+    }
+
+    // clear port active
+    port_data[port].active = DEVICE_IN_USE;
+
+    // clear port status
+    port_data[port].status = DEVICE_UP;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+    if (end_critical_section(&port_data_lock, "interface.c:serial_init(12)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    // return good condition
+    return (1);
+}
+
+//*************************** STOP SERIAL PORT FUNCTIONS ********************************
+
+
+
+
+
+//***************************** START NETWORK FUNCTIONS *********************************
+
+//**************************************************************
+// net_connect_thread()
+// Temporary thread used to start up a socket.
+//**************************************************************
+static void* net_connect_thread(void *arg) {
+    int port;
+    volatile int ok = -1;
+    int len;
+    int result;
+    int flag;
+    //int stat;
+    struct sockaddr_in address;
+
+    // Some messiness necessary because we're using
+    // xastir_mutex's instead of pthread_mutex_t's.
+    pthread_mutex_t *cleanup_mutex;
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"net_connect_thread start\n");
+
+    port = *((int *) arg);
+    // This call means we don't care about the return code and won't
+    // use pthread_join() later.  Makes threading more efficient.
+    (void)pthread_detach(pthread_self());
+
+//if (begin_critical_section(&port_data_lock, "interface.c:net_connect_thread(1)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    /* set address */
+    address.sin_addr.s_addr = (port_data[port].address);
+
+    // Create a socket if we don't have one yet for this channel
+    if (port_data[port].channel == -1) {
+        pthread_testcancel();   // Check for thread termination request
+        port_data[port].channel = socket(PF_INET, SOCK_STREAM, 0);
+        pthread_testcancel();   // Check for thread termination request
+    }
+
+    if (port_data[port].channel != -1) {
+        if (debug_level & 2)
+            fprintf(stderr,"We have a socket to use\n");
+        address.sin_family = AF_INET;
+        address.sin_port = htons(port_data[port].socket_port);
+        if (debug_level & 2)
+            fprintf(stderr,"after htons\n");
+        len = (int)sizeof(address);
+        flag = 1;
+
+        // Turn on the socket keepalive option
+        (void)setsockopt(port_data[port].channel,  SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int));
+
+        // Disable the Nagle algorithm (speeds things up)
+        (void)setsockopt(port_data[port].channel, IPPROTO_TCP,  TCP_NODELAY, (char *) &flag, sizeof(int));
+
+        if (debug_level & 2)
+            fprintf(stderr,"after setsockopt\n");
+        pthread_testcancel();  // Check for thread termination request
+        if (debug_level & 2)
+            fprintf(stderr,"calling connect(), port: %d\n", port_data[port].socket_port);
+        result = connect(port_data[port].channel, (struct sockaddr *)&address, len);
+        if (debug_level & 2)
+            fprintf(stderr,"connect result was: %d\n", result);
+        ok = 0;
+        pthread_testcancel();  // Check for thread termination request
+        if (result != -1){
+            /* connection up */
+            if (debug_level & 2)
+                fprintf(stderr,"net_connect_thread():Net up, port %d\n",port);
+
+            port_data[port].status = DEVICE_UP;
+            ok = 1;
+
+            // Show the latest status in the interface control dialog
+            update_interface_list();
+        }
+        else {    /* net connection failed */
+            ok = 0;
+            if (debug_level & 2)
+                fprintf(stderr,"net_connect_thread():net connection failed, port %d, DEVICE_ERROR ***\n",port);
+            port_data[port].status = DEVICE_ERROR;
+
+            // Show the latest status in the interface control dialog
+            update_interface_list();
+
+            // Shut down and close the socket
+
+            //pthread_testcancel();   // Check for thread termination request
+            //
+            // Don't do a shutdown!  The socket wasn't connected.  This causes
+            // problems due to the same socket number getting recycled.  It can
+            // shut down another socket.
+            //
+            //stat = shutdown(port_data[port].channel,2);
+            //pthread_testcancel();   // Check for thread termination request
+            //if (debug_level & 2)
+            //    fprintf(stderr,"net_connect_thread():Net Shutdown 1 Returned %d, port %d\n",stat,port);
+
+            usleep(100000); // 100ms
+            //pthread_testcancel();   // Check for thread termination request
+            //stat = close(port_data[port].channel);
+            //pthread_testcancel();   // Check for thread termination request
+            //if (debug_level & 2)
+            //    fprintf(stderr,"net_connect_thread():Net Close 1 Returned %d, port %d\n",stat,port);
+
+            //if (debug_level & 2)
+            //    fprintf(stderr,"net_connect_thread():Net connection 1 failed, port %d\n",port);
+        }
+    } else { /* Could not bind socket */
+        ok = -1;
+        if (debug_level & 2)
+            fprintf(stderr,"net_connect_thread():could not bind socket, port %d, DEVICE_ERROR ***\n",port);
+        port_data[port].status = DEVICE_ERROR;
+
+        // Show the latest status in the interface control dialog
+        update_interface_list();
+
+        // Shut down and close the socket
+        //pthread_testcancel();   // Check for thread termination request
+        //
+        // Don't do a shutdown!  The socket wasn't connected.  This causes
+        // problems due to the same socket number getting recycled.  It can
+        // shut down another socket.
+        //
+        //stat = shutdown(port_data[port].channel,2);
+        //pthread_testcancel();   // Check for thread termination request
+        //if (debug_level & 2)
+        //    fprintf(stderr,"net_connect_thread():Net Shutdown 2 Returned %d, port %d\n",stat,port);
+
+        usleep(100000); // 100ms
+        //pthread_testcancel();   // Check for thread termination request
+        //stat = close(port_data[port].channel);
+        //pthread_testcancel();   // Check for thread termination request
+        //if (debug_level & 2)
+        //    fprintf(stderr,"net_connect_thread():Net Close 2 Returned %d, port %d\n",stat,port);
+
+        //if (debug_level & 2)
+        //    fprintf(stderr,"net_connect_thread():Could not bind socket, port %d\n",port);
+    }
+
+
+    // Install the cleanup routine for the case where this thread
+    // gets killed while the mutex is locked.  The cleanup routine
+    // initiates an unlock before the thread dies.  We must be in
+    // deferred cancellation mode for the thread to have this work
+    // properly.  We must first get the pthread_mutex_t address:
+    cleanup_mutex = &connect_lock.lock;
+
+    // Then install the cleanup routine:
+    pthread_cleanup_push((void *)pthread_mutex_unlock, (void *)cleanup_mutex);
+//    pthread_cleanup_push(void (*pthread_mutex_unlock)(void *), (void *)cleanup_mutex);
+
+
+    if (begin_critical_section(&connect_lock, "interface.c:net_connect_thread(2)" ) > 0)
+        fprintf(stderr,"net_connect_thread():connect_lock, Port = %d\n", port);
+
+    port_data[port].connect_status = ok;
+    port_data[port].thread_status = 0;
+
+    if (end_critical_section(&connect_lock, "interface.c:net_connect_thread(3)" ) > 0)
+        fprintf(stderr,"net_connect_thread():connect_lock, Port = %d\n", port);
+
+    // Remove the cleanup routine for the case where this thread
+    // gets killed while the mutex is locked.  The cleanup routine
+    // initiates an unlock before the thread dies.  We must be in
+    // deferred cancellation mode for the thread to have this work
+    // properly.
+//
+// NOTE: Ignore the four \"suggest braces\" warnings you see when
+//       compiling, see: http://archive.netbsd.se/?ml=gcc-help&a=2008-06&t=7730779
+//
+    pthread_cleanup_pop(0);
+ 
+
+//if (end_critical_section(&port_data_lock, "interface.c:net_connect_thread(4)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    if (debug_level & 2)
+        fprintf(stderr,"net_connect_thread terminating itself\n");
+
+    return(NULL);   // This should kill the thread
+}
+
+
+
+
+
+//**************************************************************
+// net_init()
+//
+// This brings up a network connection
+//
+// returns -1 on hard error, 0 on time out, 1 if ok
+//**************************************************************
+int net_init(int port) {
+    int ok;
+    int have_address = 0;
+    char ip_addrs[400];
+    char ip_addr[40];
+    char st[200];
+    pthread_t connect_thread;
+    int stat;
+    int wait_on_connect;
+    time_t wait_time;
+    struct in_addr ip_test;
+ 
+    if (begin_critical_section(&port_data_lock, "interface.c:net_init(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    /* clear port_channel */
+//    port_data[port].channel = -1;
+
+    /* set port active */
+    port_data[port].active = DEVICE_IN_USE;
+
+    /* clear port status */
+    port_data[port].status = DEVICE_DOWN;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+    ok = -1;
+
+    // Check whether we were passed an IPv4/IPv6 address or a
+    // hostname.  If an address, skip the host_lookup.
+    if (inet_aton(port_data[port].device_host_name, &ip_test)) {
+        // We have an IPv4 or IPv6 address already.  Set a flag so
+        // that the code below can directly use it.
+        have_address = 1;
+    }
+
+    if (!have_address) {
+        xastir_snprintf(st, sizeof(st), langcode("BBARSTA019"), port_data[port].device_host_name);
+        statusline(st,1);   // Looking up host
+
+        //fprintf(stderr,"Hostname Lookup\n");
+
+        // We currently give 13 seconds to look up the hostname
+        (void)host_lookup(port_data[port].device_host_name,
+            ip_addrs,
+            sizeof(ip_addrs),
+            13);
+    }
+    else {
+        //fprintf(stderr,"Skipping Hostname Lookup\n");
+    }
+
+    if (have_address || strcmp(ip_addrs,"NOIP") != 0) {
+        if (have_address || strcmp(ip_addrs,"NOHOST") != 0) {
+            if (have_address || strcmp(ip_addrs,"TIMEOUT") != 0) {    // We found an IP address
+
+                if (have_address) {
+                    // Stuff the address passed to us into our
+                    // working variable.
+                    xastir_snprintf(ip_addr,
+                        sizeof(ip_addr),
+                        "%s",
+                        port_data[port].device_host_name);
+                }
+                else {
+                    // Get the first IP address from the lookup.
+                    if (1 != sscanf(ip_addrs,"%39s",ip_addr)) {
+                        fprintf(stderr,"net_init: sscanf parsing error\n");
+                    }
+                }
+                if (debug_level & 2)
+                    fprintf(stderr,"IP Address: %s\n",ip_addr);
+                /* set address for connection */
+                port_data[port].address = inet_addr(ip_addr);
+
+                /* ok try to connect */
+
+                if (begin_critical_section(&connect_lock, "interface.c:net_init(2)" ) > 0)
+                    fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                port_data[port].thread_status = 1;
+                port_data[port].connect_status = -1;
+
+                // If channel is != -1, we have a socket remaining from a previous
+                // connect attempt.  Shutdown and close that socket, then create
+                // a new one.
+                if (port_data[port].channel != -1) {    // We have a socket already
+
+                    // Shut down and close the socket
+                    pthread_testcancel();   // Check for thread termination request
+                    stat = shutdown(port_data[port].channel,2);
+                    pthread_testcancel();   // Check for thread termination request
+                    if (debug_level & 2)
+                        fprintf(stderr,"net_connect_thread():Net Shutdown 1 Returned %d, port %d\n",stat,port);
+                    usleep(100000);         // 100ms
+                    pthread_testcancel();   // Check for thread termination request
+                    stat = close(port_data[port].channel);
+                    pthread_testcancel();   // Check for thread termination request
+                    if (debug_level & 2)
+                        fprintf(stderr,"net_connect_thread():Net Close 1 Returned %d, port %d\n",stat,port);
+                    usleep(100000);         // 100ms
+                    port_data[port].channel = -1;
+               }
+
+                if (end_critical_section(&connect_lock, "interface.c:net_init(3)" ) > 0)
+                    fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                if (debug_level & 2)
+                    fprintf(stderr,"Creating new thread\n");
+                if (pthread_create(&connect_thread, NULL, net_connect_thread, &port)){
+                    /* error starting thread*/
+                    ok = -1;
+                    fprintf(stderr,"Error creating net_connect thread, port %d\n",port);
+                }
+
+                busy_cursor(appshell);
+                wait_time = sec_now() + NETWORK_WAITTIME;  // Set ending time for wait
+                wait_on_connect = 1;
+                while (wait_on_connect && (sec_now() < wait_time)) {
+
+                    if (begin_critical_section(&connect_lock, "interface.c:net_init(4)" ) > 0)
+                        fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                    wait_on_connect = port_data[port].thread_status;
+
+                    if (end_critical_section(&connect_lock, "interface.c:net_init(5)" ) > 0)
+                        fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                    xastir_snprintf(st, sizeof(st), langcode("BBARSTA025"), wait_time - sec_now() );
+                    statusline(st,1);           // Host found, connecting n
+                    if (debug_level & 2)
+                        fprintf(stderr,"%d\n", (int)(wait_time - sec_now()) );
+
+                    /* update display while waiting */
+                    // XmUpdateDisplay(XtParent(da));
+                    usleep(250000);      // 250mS
+                    //sched_yield();    // Too fast!
+                }
+
+                ok = port_data[port].connect_status;
+                /* thread did not return! kill it */
+                if ( (sec_now() >= wait_time)      // Timed out
+                        || (ok != 1) ) {            // or connection failure of another type
+                    if (debug_level & 2)
+                        fprintf(stderr,"Thread exceeded it's time limit or failed to connect! Port %d\n",port);
+
+                    if (begin_critical_section(&connect_lock, "interface.c:net_init(6)" ) > 0)
+                        fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                    if (debug_level & 2)
+                        fprintf(stderr,"Killing thread\n");
+                    if (pthread_cancel(connect_thread)) {
+                        // The only error code we can get here is ESRCH, which means
+                        // that the thread number wasn't found.  The thread is already
+                        // dead, so let's not print out an error code.
+                        //fprintf(stderr,"Error on termination of connect thread!\n");
+                    }
+
+                    if (sec_now() >= wait_time) {  // Timed out
+                        port_data[port].connect_status = -2;
+                        if (debug_level & 2)
+                            fprintf(stderr,"It was a timeout.\n");
+                    }
+
+                    if (end_critical_section(&connect_lock, "interface.c:net_init(7)" ) > 0)
+                        fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                    port_data[port].status = DEVICE_ERROR;
+                    if (debug_level & 2)
+                        fprintf(stderr,"Thread did not return, port %d, DEVICE_ERROR ***\n",port);
+
+                    // Show the latest status in the interface control dialog
+                    update_interface_list();
+                }
+                if (begin_critical_section(&connect_lock, "interface.c:net_init(8)" ) > 0)
+                    fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                ok = port_data[port].connect_status;
+
+                if (end_critical_section(&connect_lock, "interface.c:net_init(9)" ) > 0)
+                    fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+                if (debug_level & 2)
+                    fprintf(stderr,"Net ok: %d, port %d\n", ok, port);
+
+                switch (ok) {
+
+                    case 1: /* connection up */
+                        xastir_snprintf(st, sizeof(st), langcode("BBARSTA020"), port_data[port].device_host_name);
+                        statusline(st,1);               // Connected to ...
+                        break;
+
+                    case 0:
+                        xastir_snprintf(st, sizeof(st), "%s", langcode("BBARSTA021"));
+                        statusline(st,1);               // Net Connection Failed!
+                        ok = -1;
+                        break;
+
+                    case -1:
+                        xastir_snprintf(st, sizeof(st), "%s", langcode("BBARSTA022"));
+                        statusline(st,1);               // Could not bind socket
+                        break;
+
+                    case -2:
+                        xastir_snprintf(st, sizeof(st), "%s", langcode("BBARSTA018"));
+                        statusline(st,1);               // Net Connection timed out
+                        ok = 0;
+                        break;
+
+                    default:
+                        break;
+                        /*break;*/
+                }
+            } else { /* host lookup time out */
+                xastir_snprintf(st, sizeof(st), "%s", langcode("BBARSTA018"));
+                statusline(st,1);                       // Net Connection timed out
+                port_data[port].status = DEVICE_ERROR;
+                if (debug_level & 2)
+                    fprintf(stderr,"Host lookup timeout, port %d, DEVICE_ERROR ***\n",port);
+
+                // Show the latest status in the interface control dialog
+                update_interface_list();
+
+                ok = 0;
+            }
+        } else {    /* Host ip look up failure (no ip address for that host) */
+            xastir_snprintf(st, sizeof(st), "%s", langcode("BBARSTA023"));
+            statusline(st,1);                           // No IP for Host
+            port_data[port].status = DEVICE_ERROR;
+            if (debug_level & 2)
+                fprintf(stderr,"Host IP lookup failure, port %d, DEVICE_ERROR ***\n",port);
+
+            // Show the latest status in the interface control dialog
+            update_interface_list();
+        }
+    }
+    else {    /* Host look up failure (no host by that name) */
+        xastir_snprintf(st, sizeof(st), "%s", langcode("BBARSTA023"));
+        statusline(st,1);                               // No IP for Host
+        port_data[port].status = DEVICE_ERROR;
+        if (debug_level & 2)
+            fprintf(stderr,"Host lookup failure, port %d, DEVICE_ERROR ***\n",port);
+
+        // Show the latest status in the interface control dialog
+        update_interface_list();
+    }
+
+    if (end_critical_section(&port_data_lock, "interface.c:net_init(10)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    if (debug_level & 2)
+        fprintf(stderr,"*** net_init is returning a %d ***\n",ok);
+
+    return(ok);
+}
+
+
+
+
+
+//**************************************************************
+// This shuts down a network connection
+//
+//**************************************************************
+int net_detach(int port) {
+    int ok;
+    int max;
+    int stat;
+    char quiti[2];
+
+    if (debug_level & 2)
+        fprintf(stderr,"Net detach Start, port %d\n",port);
+
+    ok = -1;
+    max = 0;
+
+    if (begin_critical_section(&port_data_lock, "interface.c:net_detach(1)" ) > 0)
+        fprintf(stderr,"net_detach():port_data_lock, Port = %d\n", port);
+
+    if (port_data[port].active == DEVICE_IN_USE) {
+        if (port_data[port].status == DEVICE_UP && port_data[port].device_type == DEVICE_NET_STREAM){
+
+            if (debug_level & 2)
+                fprintf(stderr,"net_detach():Found port %d up, shutting it down\n",port);
+
+            quiti[0] = (char)4;
+            quiti[1] = (char)0;
+            if (port_data[port].status == DEVICE_UP) {
+                port_write_string(port,quiti);
+                usleep(100000); // 100ms
+            }
+            /* wait to write */
+            while (port_data[port].status == DEVICE_UP && port_data[port].write_in_pos != port_data[port].write_out_pos && max < 25) {
+                if (debug_level & 2)
+                    fprintf(stderr,"net_detach():Waiting to finish writing data to port %d\n",port);
+
+                //(void)sleep(1);
+                usleep(100000);    // 100ms
+                max++;
+            }
+        }
+        /*
+            Shut down and Close were separated but this would cause sockets to
+            just float around
+        */
+
+        // It doesn't matter whether we _think_ the device is up.  It might
+        // be in some other state, but the socket still needs to be closed.
+        //if (port_data[port].status == DEVICE_UP) {
+
+        /* we don't need to do a shut down on AX_25 devices */
+       if ( (port_data[port].status == DEVICE_UP)
+                && (port_data[port].device_type != DEVICE_AX25_TNC) ) {
+            stat = shutdown(port_data[port].channel,2);
+            if (debug_level & 2)
+                fprintf(stderr,"net_detach():Net Shutdown Returned %d, port %d\n",stat,port);
+        }
+
+        usleep(100000); // 100ms
+        // We wish to close down the socket (so both ends of the darn thing
+        // go away), but we want to keep the number on those systems that
+        // re-assign the same file descriptor again.  This is to prevent
+        // cross-connects from one interface to another in Xastir (big pain!).
+
+        // Close it
+        stat = close(port_data[port].channel);
+        if (debug_level & 2)
+            fprintf(stderr,"net_detach():Net Close Returned %d, port %d\n",stat,port);
+
+        usleep(100000); // 100ms
+
+        // Snag a socket again.  We'll use it next time around.
+        port_data[port].channel = socket(PF_INET, SOCK_STREAM, 0);
+
+        ok = 1;
+    }
+    /* close down no matter what */
+    port_data[port].status = DEVICE_DOWN;
+    //usleep(300);
+    port_data[port].active = DEVICE_NOT_IN_USE;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+    if (end_critical_section(&port_data_lock, "interface.c:net_detach(2)" ) > 0)
+        fprintf(stderr,"net_detach():port_data_lock, Port = %d\n", port);
+
+    if (debug_level & 2)
+        fprintf(stderr,"Net detach stop, port %d\n",port);
+
+    return(ok);
+}
+
+
+
+
+
+//***************************** STOP NETWORK FUNCTIONS **********************************
+
+
+
+// This routine changes callsign chars to proper uppercase chars or
+// numerals, fixes the callsign to six bytes, shifts the letters left by
+// one bit, and puts the SSID number into the proper bits in the seventh
+// byte.  The callsign as processed is ready for inclusion in an
+// AX.25 header.
+//
+void fix_up_callsign(unsigned char *data, int data_size) {
+    unsigned char new_call[8] = "       ";  // Start with seven spaces
+    int ssid = 0;
+    int i;
+    int j = 0;
+    int digipeated_flag = 0;
+
+
+    // Check whether we've digipeated through this callsign yet.
+    if (strstr((const char *)data,"*") != 0) {
+         digipeated_flag++;
+    }
+
+    // Change callsign to upper-case and pad out to six places with
+    // space characters.
+    for (i = 0; i < (int)strlen((const char *)data); i++) {
+        toupper(data[i]);
+
+        if (data[i] == '-') {   // Stop at '-'
+            break;
+        }
+        else if (data[i] == '*') {
+        }
+        else {
+            new_call[j++] = data[i];
+        }
+    }
+    new_call[7] = '\0';
+
+    //fprintf(stderr,"new_call:(%s)\n",new_call);
+
+    // Handle SSID.  'i' should now be pointing at a dash or at the
+    // terminating zero character.
+    if ( (i < (int)strlen((const char *)data)) && (data[i++] == '-') ) {   // We might have an SSID
+        if (data[i] != '\0')
+            ssid = atoi((const char *)&data[i]);
+//            ssid = data[i++] - 0x30;    // Convert from ascii to int
+//        if (data[i] != '\0')
+//            ssid = (ssid * 10) + (data[i] - 0x30);
+    }
+
+//fprintf(stderr,"SSID:%d\t",ssid);
+
+    if (ssid >= 0 && ssid <= 15) {
+        new_call[6] = ssid | 0x30;  // Set 2 reserved bits
+    }
+    else {  // Whacko SSID.  Set it to zero
+        new_call[6] = 0x30;     // Set 2 reserved bits
+    }
+
+    if (digipeated_flag) {
+        new_call[6] = new_call[6] | 0x40; // Set the 'H' bit
+    }
+ 
+    // Shift each byte one bit to the left
+    for (i = 0; i < 7; i++) {
+        new_call[i] = new_call[i] << 1;
+        new_call[i] = new_call[i] & 0xfe;
+    }
+
+//fprintf(stderr,"Last:%0x\n",new_call[6]);
+
+    // Write over the top of the input string with the newly
+    // formatted callsign
+    xastir_snprintf((char *)data,
+        data_size,
+        "%s",
+        new_call);
+}
+
+
+
+
+
+//-------------------------------------------------------------------
+// Had to snag code from port_write_string() below because our string
+// needs to have 0x00 chars inside it.  port_write_string() can't
+// handle that case.  It's a good thing the transmit queue stuff
+// could handle it.
+//-------------------------------------------------------------------
+//
+//WE7U
+// Modify the other routines that needed binary output so that they
+// use this routine.
+//
+void port_write_binary(int port, unsigned char *data, int length) {
+    int ii,erd;
+    int write_in_pos_hold;
+
+
+//fprintf(stderr,"Sending to AGWPE:\n");
+
+    erd = 0;
+
+    if (begin_critical_section(&port_data[port].write_lock, "interface.c:port_write_binary(1)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+
+    // Save the current position, just in case we have trouble
+    write_in_pos_hold = port_data[port].write_in_pos;
+
+    for (ii = 0; ii < length && !erd; ii++) {
+
+//fprintf(stderr,"%02x ",data[ii]);
+
+        // Put character into write buffer and advance pointer
+        port_data[port].device_write_buffer[port_data[port].write_in_pos++] = data[ii];
+
+        // Check whether we need to wrap back to the start of the
+        // circular buffer
+        if (port_data[port].write_in_pos >= MAX_DEVICE_BUFFER)
+            port_data[port].write_in_pos = 0;
+
+        // Check whether we just filled our buffer (read/write
+        // pointers are equal).  If so, exit gracefully, dumping
+        // this string and resetting the write pointer.
+        if (port_data[port].write_in_pos == port_data[port].write_out_pos) {
+            if (debug_level & 2)
+                fprintf(stderr,"Port %d Buffer overrun\n",port);
+
+            // Restore original write_in pos and dump this string
+            port_data[port].write_in_pos = write_in_pos_hold;
+            port_data[port].errors++;
+            erd = 1;
+        }
+    }
+
+// Check that the data got placed in the buffer ok
+//for (ii = write_in_pos_hold;  ii < port_data[port].write_in_pos; ii++) {
+//  fprintf(stderr,"%02x ",port_data[port].device_write_buffer[ii]);
+//}
+//fprintf(stderr,"\n");
+
+
+    if (end_critical_section(&port_data[port].write_lock, "interface.c:port_write_binary(2)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+
+//fprintf(stderr,"\n");
+
+}
+
+
+
+
+
+// Create an AX25 frame and then turn it into a KISS packet.  Dump
+// it into the transmit queue.
+//
+void send_ax25_frame(int port, char *source, char *destination, char *path, char *data) {
+    unsigned char temp_source[15];
+    unsigned char temp_dest[15];
+    unsigned char temp[15];
+    unsigned char control[2], pid[2];
+    unsigned char transmit_txt[MAX_LINE_SIZE*2];
+    unsigned char transmit_txt2[MAX_LINE_SIZE*2];
+    unsigned char c;
+    int i, j;
+    int erd;
+    int write_in_pos_hold;
+
+
+//fprintf(stderr,"KISS String:%s>%s,%s:%s\n",source,destination,path,data);
+
+    // Check whether transmits are disabled globally
+    if (transmit_disable) {
+        return;
+    }    
+
+    // Check whether transmit has been enabled for this interface.
+    // If not, get out while the gettin's good.
+    if (devices[port].transmit_data != 1) {
+        return;
+    }
+
+    transmit_txt[0] = '\0';
+
+    // Format the destination callsign
+    xastir_snprintf((char *)temp_dest,
+        sizeof(temp_dest),
+        "%s",
+        destination);
+    fix_up_callsign(temp_dest, sizeof(temp_dest));
+    xastir_snprintf((char *)transmit_txt,
+        sizeof(transmit_txt),
+        "%s",
+        temp_dest);
+
+    // Format the source callsign
+    xastir_snprintf((char *)temp_source,
+        sizeof(temp_source),
+        "%s",
+        source);
+    fix_up_callsign(temp_source, sizeof(temp_source));
+    strncat((char *)transmit_txt,
+        (char *)temp_source,
+        sizeof(transmit_txt) - 1 - strlen((char *)transmit_txt));
+
+    // Break up the path into individual callsigns and send them one
+    // by one to fix_up_callsign().  If we get passed an empty path,
+    // we merely skip this section and no path gets added to
+    // "transmit_txt".
+    j = 0;
+    temp[0] = '\0'; // Start with empty path
+    if ( (path != NULL) && (strlen(path) != 0) ) {
+        while (path[j] != '\0') {
+            i = 0;
+            while ( (path[j] != ',') && (path[j] != '\0') ) {
+                temp[i++] = path[j++];
+            }
+            temp[i] = '\0';
+
+            if (path[j] == ',') {   // Skip over comma
+                j++;
+            }
+
+//fprintf(stderr,"%s\n",temp);
+
+            fix_up_callsign(temp, sizeof(temp));
+            strncat((char *)transmit_txt,
+                (char *)temp,
+                sizeof(transmit_txt) - 1 - strlen((char *)transmit_txt));
+        }
+    }
+
+    // Set the end-of-address bit on the last callsign in the
+    // address field
+    transmit_txt[strlen((const char *)transmit_txt) - 1] |= 0x01;
+
+    // Add the Control byte
+    control[0] = 0x03;
+    control[1] = '\0';
+    strncat((char *)transmit_txt,
+        (char *)control,
+        sizeof(transmit_txt) - 1 - strlen((char *)transmit_txt));
+
+    // Add the PID byte
+    pid[0] = 0xf0;
+    pid[1] = '\0';
+    strncat((char *)transmit_txt,
+        (char *)pid,
+        sizeof(transmit_txt) - 1 - strlen((char *)transmit_txt));
+
+    // Append the information chars
+    strncat((char *)transmit_txt,
+        data,
+        sizeof(transmit_txt) - 1 - strlen((char *)transmit_txt));
+
+    //fprintf(stderr,"%s\n",transmit_txt);
+
+    // Add the KISS framing characters and do the proper escapes.
+    j = 0;
+    transmit_txt2[j++] = KISS_FEND;
+
+    // Note:  This byte is where different interfaces would be
+    // specified:
+    transmit_txt2[j++] = 0x00;
+
+    for (i = 0; i < (int)strlen((const char *)transmit_txt); i++) {
+        c = transmit_txt[i];
+        if (c == KISS_FEND) {
+            transmit_txt2[j++] = KISS_FESC;
+            transmit_txt2[j++] = KISS_TFEND;
+        }
+        else if (c == KISS_FESC) {
+            transmit_txt2[j++] = KISS_FESC;
+            transmit_txt2[j++] = KISS_TFESC;
+        }
+        else {
+            transmit_txt2[j++] = c;
+        }
+    }
+    transmit_txt2[j++] = KISS_FEND;
+
+    // Terminate the string, but don't increment the 'j' counter.
+    // We don't want to send the NULL byte out the KISS interface,
+    // just make sure the string is terminated in all cases.
+    //
+    transmit_txt2[j] = '\0';
+
+//-------------------------------------------------------------------
+// Had to snag code from port_write_string() below because our string
+// needs to have 0x00 chars inside it.  port_write_string() can't
+// handle that case.  It's a good thing the transmit queue stuff
+// could handle it.
+//-------------------------------------------------------------------
+
+    erd = 0;
+
+    if (begin_critical_section(&port_data[port].write_lock, "interface.c:send_ax25_frame(1)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+
+    write_in_pos_hold = port_data[port].write_in_pos;
+
+    for (i = 0; i < j && !erd; i++) {
+        port_data[port].device_write_buffer[port_data[port].write_in_pos++] = transmit_txt2[i];
+        if (port_data[port].write_in_pos >= MAX_DEVICE_BUFFER)
+            port_data[port].write_in_pos = 0;
+
+        if (port_data[port].write_in_pos == port_data[port].write_out_pos) {
+            if (debug_level & 2)
+                fprintf(stderr,"Port %d Buffer overrun\n",port);
+
+            /* clear this restore original write_in pos and dump this string */
+            port_data[port].write_in_pos = write_in_pos_hold;
+            port_data[port].errors++;
+            erd = 1;
+        }
+    }
+
+
+
+// DEBUG.  Dump out the hex codes for the KISS packet we just
+// created.
+/*
+    for (i = 0; i< j; i++) {
+        fprintf(stderr,"%02x ", transmit_txt2[i]);
+    }
+    fprintf(stderr,"\n\n");
+*/
+
+
+
+    if (end_critical_section(&port_data[port].write_lock, "interface.c:send_ax25_frame(2)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+}
+
+
+
+
+
+// Send a KISS configuration command to the selected port.
+// The KISS spec allows up to 16 devices to be configured.  We
+// support that here with the "device" input, which should be
+// between 0 and 15.  The commands accepted are integer values:
+//
+// 0x01 TXDELAY
+// 0x02 P-Persistence
+// 0x03 SlotTime
+// 0x04 TxTail
+// 0x05 FullDuplex
+// 0x06 SetHardware
+// 0xff Exit from KISS mode (not implemented yet)
+//
+void send_kiss_config(int port, int device, int command, int value) {
+    unsigned char transmit_txt[MAX_LINE_SIZE+1];
+    int i, j;
+    int erd;
+    int write_in_pos_hold;
+
+
+    if (device < 0 || device > 15) {
+        fprintf(stderr,"send_kiss_config: out-of-range value for device\n");
+        return;
+    }
+
+    if (command < 1 || command > 6) {
+        fprintf(stderr,"send_kiss_config: out-of-range value for command\n");
+        return;
+    }
+
+    if (value < 0 || value > 255) {
+        fprintf(stderr,"send_kiss_config: out-of-range value for value\n");
+        return;
+    }
+
+    // Add the KISS framing characters and do the proper escapes.
+    j = 0;
+    transmit_txt[j++] = KISS_FEND;
+
+    transmit_txt[j++] = (device << 4) | (command & 0x0f);
+
+    transmit_txt[j++] = value & 0xff;
+
+    transmit_txt[j++] = KISS_FEND;
+
+    // Terminate the string, but don't increment the 'j' counter.
+    // We don't want to send the NULL byte out the KISS interface,
+    // just make sure the string is terminated in all cases.
+    //
+    transmit_txt[j] = '\0';
+
+
+
+
+//-------------------------------------------------------------------
+// Had to snag code from port_write_string() below because our string
+// needs to have 0x00 chars inside it.  port_write_string() can't
+// handle that case.  It's a good thing the transmit queue stuff
+// could handle it.
+//-------------------------------------------------------------------
+
+    erd = 0;
+
+    if (begin_critical_section(&port_data[port].write_lock, "interface.c:send_kiss_config(1)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+
+    write_in_pos_hold = port_data[port].write_in_pos;
+
+    for (i = 0; i < j && !erd; i++) {
+        port_data[port].device_write_buffer[port_data[port].write_in_pos++] = transmit_txt[i];
+        if (port_data[port].write_in_pos >= MAX_DEVICE_BUFFER)
+            port_data[port].write_in_pos = 0;
+
+        if (port_data[port].write_in_pos == port_data[port].write_out_pos) {
+            if (debug_level & 2)
+                fprintf(stderr,"Port %d Buffer overrun\n",port);
+
+            /* clear this restore original write_in pos and dump this string */
+            port_data[port].write_in_pos = write_in_pos_hold;
+            port_data[port].errors++;
+            erd = 1;
+        }
+    }
+
+    if (end_critical_section(&port_data[port].write_lock, "interface.c:send_kiss_config(2)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+}
+
+
+
+
+
+//***********************************************************
+// port_write_string()
+//
+// port is port# used
+// data is the string to write
+//***********************************************************
+
+void port_write_string(int port, char *data) {
+    int i,erd;
+    int write_in_pos_hold;
+
+    if (data == NULL)
+        return;
+
+    if (data[0] == '\0')
+        return;
+
+    erd = 0;
+
+    if (debug_level & 2)
+        fprintf(stderr,"CMD:%s\n",data);
+
+    if (begin_critical_section(&port_data[port].write_lock, "interface.c:port_write_string(1)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+
+    write_in_pos_hold = port_data[port].write_in_pos;
+
+    // Normal Serial/Net output?
+    if (port_data[port].device_type != DEVICE_AX25_TNC) {
+        for (i = 0; i < (int)strlen(data) && !erd; i++) {
+            port_data[port].device_write_buffer[port_data[port].write_in_pos++] = data[i];
+            if (port_data[port].write_in_pos >= MAX_DEVICE_BUFFER)
+                port_data[port].write_in_pos = 0;
+
+            if (port_data[port].write_in_pos == port_data[port].write_out_pos){
+                if (debug_level & 2)
+                    fprintf(stderr,"Port %d Buffer overrun\n",port);
+
+                /* clear this restore original write_in pos and dump this string */
+                port_data[port].write_in_pos = write_in_pos_hold;
+                port_data[port].errors++;
+                erd = 1;
+            }
+        }
+    }
+
+    // AX.25 port output
+    else {
+        port_data[port].bytes_output += strlen(data);
+        data_out_ax25(port,(unsigned char *)data);
+        /* do for interface indicators */
+        if (port_data[port].write_in_pos >= MAX_DEVICE_BUFFER)
+            port_data[port].write_in_pos = 0;
+    }
+
+    if (end_critical_section(&port_data[port].write_lock, "interface.c:port_write_string(2)" ) > 0)
+        fprintf(stderr,"write_lock, Port = %d\n", port);
+}
+
+
+
+
+
+//***********************************************************
+// port_read()
+//
+// port is port# used
+//
+// This function becomes the long-running thread that snags
+// characters from an interface and passes them off to the
+// decoding routines.  One copy of this is run for each read
+// thread for each interface.
+//***********************************************************
+
+void port_read(int port) {
+    unsigned char cin, last;
+    unsigned char buffer[MAX_DEVICE_BUFFER];    // Only used for AX.25 packets
+    int i;
+    struct timeval tmv;
+    fd_set rd;
+    int group;
+    int binary_wx_data = 0;
+    int max;
+    /*
+    * Some local variables used for checking AX.25 data - PE1DNN
+    *
+    * "from"     is used to look up where the data comes from
+    * "from_len" is used to keep the size of sockaddr structure
+    * "dev"      is used to keep the name of the interface that
+    *            belongs to our port/device_name
+    */
+    struct sockaddr from;
+    socklen_t from_len;
+
+#ifdef HAVE_LIBAX25
+    char           *dev;
+#endif /* USE_AX25 */
+
+    if (debug_level & 2)
+        fprintf(stderr,"Port %d read start\n",port);
+
+//    init_critical_section(&port_data[port].read_lock);
+
+    group = 0;
+    max = MAX_DEVICE_BUFFER - 1;
+    cin = (unsigned char)0;
+    last = (unsigned char)0;
+
+    // We stay in this read loop until the port is shut down
+    while(port_data[port].active == DEVICE_IN_USE){
+
+        if (port_data[port].status == DEVICE_UP){
+
+            port_data[port].read_in_pos = 0;
+            port_data[port].scan = 1;
+
+            while (port_data[port].scan
+                    && (port_data[port].read_in_pos < (MAX_DEVICE_BUFFER - 1) )
+                    && (port_data[port].status == DEVICE_UP) ) {
+
+                int skip = 0;
+
+//                pthread_testcancel();   // Check for thread termination request
+ 
+                // Handle all EXCEPT AX25_TNC interfaces here
+                if (port_data[port].device_type != DEVICE_AX25_TNC) {
+                    // Get one character
+                    port_data[port].scan = (int)read(port_data[port].channel,&cin,1);
+//fprintf(stderr," in:%02x ",cin);
+                }
+
+                else {  // Handle AX25_TNC interfaces
+                    /*
+                    * Use recvfrom on a network socket to know from
+                    * which interface the packet came - PE1DNN
+                    */
+
+#ifdef __solaris__
+                    from_len = (unsigned int)sizeof(from);
+#else   // __solaris__
+                    from_len = (socklen_t)sizeof(from);
+#endif  // __solaris__
+
+                    port_data[port].scan = recvfrom(port_data[port].channel,buffer,
+                        sizeof(buffer) - 1,
+                        0,
+                        &from,
+                        &from_len);
+                }
+
+
+                // Below is code for ALL types of interfaces
+                if (port_data[port].scan > 0 && port_data[port].status == DEVICE_UP ) {
+
+                    if (port_data[port].device_type != DEVICE_AX25_TNC)
+                        port_data[port].bytes_input += port_data[port].scan;      // Add character to read buffer
+
+
+// Somewhere between these lock statements the read_lock got unlocked.  How?
+// if (begin_critical_section(&port_data[port].read_lock, "interface.c:port_read(1)" ) > 0)
+//    fprintf(stderr,"read_lock, Port = %d\n", port);
+
+
+                    // Handle all EXCEPT AX25_TNC interfaces here
+                    if (port_data[port].device_type != DEVICE_AX25_TNC){
+
+
+                        // Do special KISS packet processing here.
+                        // We save the last character in
+                        // port_data[port].channel2, as it is
+                        // otherwise only used for AX.25 ports.
+
+                        if ( (port_data[port].device_type == DEVICE_SERIAL_KISS_TNC)
+                                || (port_data[port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+
+                            if (port_data[port].channel2 == KISS_FESC) { // Frame Escape char
+                                if (cin == KISS_TFEND) { // Transposed Frame End char
+
+                                    // Save this char for next time
+                                    // around
+                                    port_data[port].channel2 = cin;
+
+                                    cin = KISS_FEND;
+                                }
+                                else if (cin == KISS_TFESC) { // Transposed Frame Escape char
+
+                                    // Save this char for next time
+                                    // around
+                                    port_data[port].channel2 = cin;
+
+                                    cin = KISS_FESC;
+                                }
+                                else {
+                                    port_data[port].channel2 = cin;
+                                }
+                            }
+                            else if (port_data[port].channel2 == KISS_FEND) { // Frame End char
+                                // Frame start or frame end.  Drop
+                                // the next character which should
+                                // either be another frame end or a
+                                // type byte.
+
+// Note this "type" byte is where it specifies which KISS interface
+// the packet came from.  We may want to use this later for
+// multi-drop KISS or other types of KISS protocols.
+
+                                // Save this char for next time
+                                // around
+                                port_data[port].channel2 = cin;
+//fprintf(stderr,"Byte: %02x\n", cin);
+                                skip++;
+                            }
+                            else if (cin == KISS_FESC) { // Frame Escape char
+                                port_data[port].channel2 = cin;
+                                skip++;
+                            }
+                            else {
+                                port_data[port].channel2 = cin;
+                            }
+                        }   // End of first special KISS processing
+
+
+
+
+
+// AGWPE
+// Process AGWPE packets here.  Massage the frames so that they look
+// like normal serial packets to the Xastir decoding functions?
+//
+// We turn on monitoring of packets when we first connect.  We now
+// need to throw away all but the "U" packets, which are unconnected
+// information packets.
+//
+// Check for enough bytes to complete a header (36 bytes).  If
+// enough, check the datalength to see if an entire packet has been
+// read.  If so, run that packet through a conversion routine to
+// convert it to a TAPR2-style packet.
+//
+// Right now we're not taking into account multiple radio ports that
+// AGWPE is capable of.  Just assume that we'll receive from all
+// radio ports, but transmit out port 0.
+//
+                        if (port_data[port].device_type == DEVICE_NET_AGWPE) {
+                            int bytes_available = 0;
+                            long frame_length = 0;
+
+
+                            skip = 1;   // Keeps next block of code from
+                                        // trying to process this data.
+
+                            // Add it to the buffer
+                            if (port_data[port].read_in_pos < (MAX_DEVICE_BUFFER - 1) ) {
+                                port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)cin;
+                                port_data[port].read_in_pos++;
+                                port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)0;
+                            } else {
+                                if (debug_level & 2)
+                                    fprintf(stderr,"Port read overrun (1) on %d\n",port);
+
+                                port_data[port].read_in_pos = 0;
+                            }
+ 
+                            bytes_available = port_data[port].read_in_pos - port_data[port].read_out_pos;
+                            if (bytes_available < 0)
+                                bytes_available = (bytes_available + MAX_DEVICE_BUFFER) % MAX_DEVICE_BUFFER;
+
+//fprintf(stderr," bytes_avail:%d ",bytes_available);
+ 
+                            if (bytes_available >= 36) {
+                                // We have a full AGWPE header,
+                                // which means we can compute the
+                                // frame length.
+                                unsigned char count[4];
+                                int my_pointer;
+
+                                // Snag bytes 28-32 of the buffer and compute frame_length
+                                my_pointer = (port_data[port].read_out_pos + 28) % MAX_DEVICE_BUFFER;
+                                count[0] = (unsigned char)port_data[port].device_read_buffer[my_pointer];
+                                my_pointer = (my_pointer + 1) % MAX_DEVICE_BUFFER;
+                                count[1] = (unsigned char)port_data[port].device_read_buffer[my_pointer];
+                                my_pointer = (my_pointer + 1) % MAX_DEVICE_BUFFER;
+                                count[2] = (unsigned char)port_data[port].device_read_buffer[my_pointer];
+                                my_pointer = (my_pointer + 1) % MAX_DEVICE_BUFFER;
+                                count[3] = (unsigned char)port_data[port].device_read_buffer[my_pointer];
+
+                                frame_length = 0;
+                                frame_length = frame_length | (count[0]      );
+                                frame_length = frame_length | (count[1] <<  8);
+                                frame_length = frame_length | (count[2] << 16);
+                                frame_length = frame_length | (count[3] << 24);
+
+//fprintf(stderr,"Found complete AGWPE header: DataLength: %d\n",frame_length);
+
+                               // Have a complete AGWPE packet?  If
+                                // so, convert it to a more standard
+                                // packet format then feed it to our
+                                // decoding routines.
+                                //
+                                if (bytes_available >= (frame_length+36)) {
+                                    char input_string[MAX_DEVICE_BUFFER];
+                                    char output_string[MAX_DEVICE_BUFFER];
+                                    int ii,jj,new_length;
+
+//fprintf(stderr,"Found complete AGWPE packet, %d bytes total in frame:\n",frame_length+36);
+
+                                    my_pointer = port_data[port].read_out_pos;
+                                    jj = 0;
+                                    for (ii = 0; ii < frame_length+36; ii++) {
+                                        input_string[jj++] = (unsigned char)port_data[port].device_read_buffer[my_pointer];
+                                        my_pointer = (my_pointer + 1) % MAX_DEVICE_BUFFER;
+                                    }
+
+                                    // Add a terminator.  We need
+                                    // this for the raw packets so
+                                    // that we don't end up getting
+                                    // portions of strings
+                                    // concatenated onto the end of
+                                    // our current packet during
+                                    // later processing.
+                                    input_string[jj] = '\0';
+ 
+                                    my_pointer = port_data[port].read_out_pos;
+
+                                    if ( parse_agwpe_packet((unsigned char *)input_string,
+                                            frame_length+36,
+                                            (unsigned char *)output_string,
+                                            &new_length) ) {
+                                        channel_data(port,
+                                            (unsigned char *)output_string,
+                                            new_length+1); // include terminator
+                                    }
+
+                                    for (i = 0; i <= port_data[port].read_in_pos; i++)
+                                        port_data[port].device_read_buffer[i] = (char)0;
+
+                                    port_data[port].read_in_pos = 0;
+                                }
+                            }
+                            else {
+                                // Not enough for a full header so
+                                // we can't compute frame length
+                                // yet.  Do nothing until we have
+                                // more data.
+                            }
+                        }
+// End of new AGWPE code
+
+
+
+                        // We shouldn't see any AX.25 flag
+                        // characters on a KISS interface because
+                        // they are stripped out by the KISS code.
+                        // What we should see though are KISS_FEND
+                        // characters at the beginning of each
+                        // packet.  These characters are where we
+                        // should break the data apart in order to
+                        // send strings to the decode routines.  It
+                        // may be just fine to still break it on \r
+                        // or \n chars, as the KISS_FEND should
+                        // appear immediately afterwards in
+                        // properly formed packets.
+
+
+                        if ( (!skip)
+                                && (cin == (unsigned char)'\r'
+                                    || cin == (unsigned char)'\n'
+                                    || port_data[port].read_in_pos >= (MAX_DEVICE_BUFFER - 1)
+                                    || ( (cin == KISS_FEND) && (port_data[port].device_type == DEVICE_SERIAL_KISS_TNC) )
+                                    || ( (cin == KISS_FEND) && (port_data[port].device_type == DEVICE_SERIAL_MKISS_TNC) ) )
+                               && port_data[port].data_type == 0) {     // If end-of-line
+
+// End serial/net type data send it to the decoder Put a terminating
+// zero at the end of the read-in data
+
+                            port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)0;
+
+                            if (port_data[port].status == DEVICE_UP && port_data[port].read_in_pos > 0) {
+                                int length;
+
+                                // Compute length of string in
+                                // circular queue
+
+                                //fprintf(stderr,"%d\t%d\n",port_data[port].read_in_pos,port_data[port].read_out_pos);
+
+                                // KISS TNC sends binary data
+                                if ( (port_data[port].device_type == DEVICE_SERIAL_KISS_TNC)
+                                        || (port_data[port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+ 
+                                    length = port_data[port].read_in_pos - port_data[port].read_out_pos;
+                                    if (length < 0)
+                                        length = (length + MAX_DEVICE_BUFFER) % MAX_DEVICE_BUFFER;
+
+length++;
+                                }
+                                else {  // ASCII data
+                                    length = 0;
+                                }
+
+                                channel_data(port,
+                                    (unsigned char *)port_data[port].device_read_buffer,
+                                    length);   // Length of string
+                            }
+
+                            for (i = 0; i <= port_data[port].read_in_pos; i++)
+                                port_data[port].device_read_buffer[i] = (char)0;
+
+                            port_data[port].read_in_pos = 0;
+                        }
+                        else if (!skip) {
+
+                            // Check for binary WX station data
+                            if (port_data[port].data_type == 1 && (port_data[port].device_type == DEVICE_NET_WX ||
+                                    port_data[port].device_type == DEVICE_SERIAL_WX)) {
+
+                                /* BINARY DATA input (WX data ?) */
+                                /* check RS WX200 */
+                                switch (cin) {
+
+                                    case 0x8f:
+                                    case 0x9f:
+                                    case 0xaf:
+                                    case 0xbf:
+                                    case 0xcf:
+
+                                        if (group == 0) {
+                                            port_data[port].read_in_pos = 0;
+                                            group = (int)cin;
+                                            switch (cin) {
+
+                                                case 0x8f:
+                                                    max = 35;
+                                                    binary_wx_data = 1;
+                                                    break;
+
+                                                case 0x9f:
+                                                    max = 34;
+                                                    binary_wx_data = 1;
+                                                    break;
+
+                                                case 0xaf:
+                                                    max = 31;
+                                                    binary_wx_data = 1;
+                                                    break;
+
+                                                case 0xbf:
+                                                    max = 14;
+                                                    binary_wx_data = 1;
+                                                    break;
+
+                                                case 0xcf:
+                                                    max = 27;
+                                                    binary_wx_data = 1;
+                                                    break;
+
+                                                default:
+                                                    break;
+                                            }
+                                        }
+                                        break;
+
+                                    default:
+                                        break;
+                                }
+                                if (port_data[port].read_in_pos < (MAX_DEVICE_BUFFER - 1) ) {
+                                    port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)cin;
+                                    port_data[port].read_in_pos++;
+                                    port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)0;
+                                } else {
+                                    if (debug_level & 2)
+                                        fprintf(stderr,"Port read overrun (1) on %d\n",port);
+
+                                    port_data[port].read_in_pos = 0;
+                                }
+                                if (port_data[port].read_in_pos >= max) {
+                                    if (group != 0) {   /* ok try to decode it */
+                                        int length = 0;
+//int jj;   
+                                        if (binary_wx_data) {                             
+                                            length = port_data[port].read_in_pos - port_data[port].read_out_pos;
+                                            if (length < 0)
+                                                length = (length + MAX_DEVICE_BUFFER) % MAX_DEVICE_BUFFER;
+                                            length++;
+                                        }
+//fprintf(stderr,"\n\n3, length: %d ", length);
+//for (jj = 0; jj < (length-1); jj++) {
+//  fprintf(stderr, "%02x ", 0x0ff & port_data[port].device_read_buffer[jj]);
+//}
+//fprintf(stderr,"\n");
+
+
+                                        channel_data(port,
+                                            (unsigned char *)port_data[port].device_read_buffer,
+                                            length);
+                                    }
+                                    max = MAX_DEVICE_BUFFER - 1;
+                                    group = 0;
+
+                                    port_data[port].read_in_pos = 0;
+                                }
+                            }
+                            else { /* Normal Data input */
+
+                                if (cin == '\0')    // OWW WX daemon sends 0x00's!
+                                    cin = '\n';
+
+                                if (port_data[port].read_in_pos < (MAX_DEVICE_BUFFER - 1) ) {
+                                    port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)cin;
+                                    port_data[port].read_in_pos++;
+                                    port_data[port].device_read_buffer[port_data[port].read_in_pos] = (char)0;
+                                }
+                                else {
+                                    if (debug_level & 2)
+                                        fprintf(stderr,"Port read overrun (2) on %d\n",port);
+
+                                    port_data[port].read_in_pos = 0;
+                                }
+                            }
+                        }
+
+                        // Ascii WX station data but no line-ends?
+                        if (port_data[port].read_in_pos > MAX_DEVICE_BUFFER_UNTIL_BINARY_SWITCH &&
+                                (port_data[port].device_type == DEVICE_NET_WX
+                                || port_data[port].device_type == DEVICE_SERIAL_WX)) {
+
+                            /* normal data on WX not found do look at data for binary WX */
+                            port_data[port].data_type++;
+                            port_data[port].data_type &= 1;
+                            port_data[port].read_in_pos = 0;
+                        }
+                    }   // End of non-AX.25 interface code block
+
+
+                    else {    // Process ax25 interface data and send to the decoder
+                        /*
+                         * Only accept data from our own interface (recvfrom will get
+                         * data from all AX.25 interfaces!) - PE1DNN
+                         */
+#ifdef HAVE_LIBAX25
+                        if (port_data[port].device_name != NULL) {
+                            if ((dev = ax25_config_get_dev(port_data[port].device_name)) != NULL) {
+                                /* if the data is not from our interface, ignore it! PE1DNN */
+                                if(strcmp(dev, from.sa_data) == 0) {
+                                    /* Received data from our interface! - process data */
+                                    if (process_ax25_packet(buffer,
+                                            port_data[port].scan,
+                                            port_data[port].device_read_buffer,
+                                            sizeof(port_data[port].device_read_buffer)) != NULL) {
+                                        port_data[port].bytes_input += strlen(port_data[port].device_read_buffer);
+
+                                        channel_data(port,
+                                            (unsigned char *)port_data[port].device_read_buffer,
+                                             0);
+                                    }
+                                    /*
+                                        do this for interface indicator in this case we only do it for,
+                                        data from the correct AX.25 port
+                                    */
+                                    if (port_data[port].read_in_pos < (MAX_DEVICE_BUFFER - 1) ) {
+                                        port_data[port].read_in_pos += port_data[port].scan;
+                                    } else {
+
+                                       /* no buffer over runs writing a line at a time */
+                                        port_data[port].read_in_pos = 0;
+                                    }
+                                }
+                            }
+                        }
+#endif /* HAVE_LIBAX25 */
+                    }   // End of AX.25 interface code block
+
+
+//if (end_critical_section(&port_data[port].read_lock, "interface.c:port_read(2)" ) > 0)
+//    fprintf(stderr,"read_lock, Port = %d\n", port);
+
+                }
+                else if (port_data[port].status == DEVICE_UP) {    /* error or close on read */
+                    port_data[port].errors++;
+                    if (port_data[port].scan == 0) {
+                        // Should not get this unless the device is down.  NOT TRUE!
+                        // We seem to also be able to get here if we're closing/restarting
+                        // another interface.  For that reason I commented out the below
+                        // statement so that this interface won't go down.  The inactivity
+                        // timer solves that issue now anyway.  --we7u.
+                        port_data[port].status = DEVICE_ERROR;
+
+                        // If the below statement is enabled, it causes an immediate reconnect
+                        // after one time-period of inactivity, currently 7.5 minutes, as set in
+                        // main.c:UpdateTime().  This means the symbol will never change from green
+                        // to red on the status bar, so the operator might not know about a
+                        // connection that is being constantly reconnected.  By leaving it commented
+                        // out we get one time period of red, and then it will reconnect at the 2nd
+                        // time period.  This means we can reconnect within 15 minutes if a line
+                        // goes dead.
+                        //
+                        port_data[port].reconnects = -1;     // Causes an immediate reconnect
+ 
+                        if (debug_level & 2)
+                            fprintf(stderr,"end of file on read, or signal interrupted the read, port %d\n",port);
+
+                        // Show the latest status in the interface control dialog
+                        update_interface_list();
+
+                    } else {
+                        if (port_data[port].scan == -1) {
+                            /* Should only get this if an real error occurs */
+                            port_data[port].status = DEVICE_ERROR;
+
+                            // If the below statement is enabled, it causes an immediate reconnect
+                            // after one time-period of inactivity, currently 7.5 minutes, as set in
+                            // main.c:UpdateTime().  This means the symbol will never change from green
+                            // to red on the status bar, so the operator might not know about a
+                            // connection that is being constantly reconnected.  By leaving it commented
+                            // out we get one time period of red, and then it will reconnect at the 2nd
+                            // time period.  This means we can reconnect within 15 minutes if a line
+                            // goes dead.
+                            //
+                            port_data[port].reconnects = -1;     // Causes an immediate reconnect
+ 
+                            // Show the latest status in the
+                            // interface control dialog
+                            update_interface_list();
+
+                            if (debug_level & 2) {
+                                fprintf(stderr,"error on read with error no %d, or signal interrupted the read, port %d, DEVICE_ERROR ***\n",
+                                    errno,port);
+                                switch (errno) {
+
+                                    case EINTR:
+                                        fprintf(stderr,"EINTR ERROR\n");
+                                        break;
+
+                                    case EAGAIN:
+                                        fprintf(stderr,"EAGAIN ERROR\n");
+                                        break;
+
+                                    case EIO:
+                                        fprintf(stderr,"EIO ERROR\n");
+                                        break;
+
+                                    case EISDIR:
+                                        fprintf(stderr,"EISDIR ERROR\n");
+                                        break;
+
+                                    case EBADF: // Get this one when we terminate nearby threads
+                                        fprintf(stderr,"EBADF ERROR\n");
+                                        break;
+
+                                    case EINVAL:
+                                        fprintf(stderr,"EINVAL ERROR\n");
+                                        break;
+
+                                    case EFAULT:
+                                        fprintf(stderr,"EFAULT ERROR\n");
+                                        break;
+
+                                    default:
+                                        fprintf(stderr,"OTHER ERROR\n");
+                                        break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (port_data[port].active == DEVICE_IN_USE)  {
+
+            // We need to delay here so that the thread doesn't use
+            // high amounts of CPU doing nothing.
+
+// This select that waits on data and a timeout, so that if data
+// doesn't come in within a certain period of time, we wake up to
+// check whether the socket has gone down.  Else, we go back into
+// the select to wait for more data or a timeout.  FreeBSD has a
+// problem if this is less than 1ms.  Linux works ok down to 100us.
+// We don't need it anywhere near that short though.  We just need
+// to check whether the main thread has requested the interface be
+// closed, and so need to have this short enough to have reasonable
+// response time to the user.
+
+//sched_yield();  // Yield to other threads
+
+            // Set up the select to block until data ready or 100ms
+            // timeout, whichever occurs first.
+            FD_ZERO(&rd);
+            FD_SET(port_data[port].channel, &rd);
+            tmv.tv_sec = 0;
+            tmv.tv_usec = 100000;    // 100 ms
+            (void)select(0,&rd,NULL,NULL,&tmv);
+        }
+    }
+
+    if (debug_level & 2)
+        fprintf(stderr,"Thread for port %d read down!\n",port);
+}
+
+
+
+
+
+//***********************************************************
+// port_write()
+//
+// port is port# used
+//
+// This function becomes the long-running thread that sends
+// characters to an interface.  One copy of this is run for
+// each write thread for each interface.
+//***********************************************************
+void port_write(int port) {
+    int retval;
+    struct timeval tmv;
+    fd_set wd;
+    int wait_max;
+    unsigned long bytes_input;
+    char write_buffer[MAX_DEVICE_BUFFER];
+    int quantity;
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"Port %d write start\n",port);
+
+    init_critical_section(&port_data[port].write_lock);
+
+    while(port_data[port].active == DEVICE_IN_USE) {
+
+        if (port_data[port].status == DEVICE_UP) {
+            // Some messiness necessary because we're using
+            // xastir_mutex's instead of pthread_mutex_t's.
+            pthread_mutex_t *cleanup_mutex;
+
+
+            // Install the cleanup routine for the case where this
+            // thread gets killed while the mutex is locked.  The
+            // cleanup routine initiates an unlock before the thread
+            // dies.  We must be in deferred cancellation mode for
+            // the thread to have this work properly.  We must first
+            // get the pthread_mutex_t address:
+            cleanup_mutex = &port_data[port].write_lock.lock;
+
+            // Then install the cleanup routine:
+            pthread_cleanup_push((void *)pthread_mutex_unlock, (void *)cleanup_mutex);
+//            pthread_cleanup_push(void (*pthread_mutex_unlock)(void *), (void *)cleanup_mutex);
+
+
+
+            if (begin_critical_section(&port_data[port].write_lock, "interface.c:port_write(1)" ) > 0)
+                fprintf(stderr,"write_lock, Port = %d\n", port);
+
+            if ( (port_data[port].write_in_pos != port_data[port].write_out_pos)
+                    && port_data[port].status == DEVICE_UP) {
+                // We have something in the buffer to transmit!
+
+
+// Handle control-C delay
+                switch (port_data[port].device_type) {
+
+                    // Use this block for serial interfaces where we
+                    // need special delays for control-C character
+                    // processing in the TNC.
+                    case DEVICE_SERIAL_TNC_HSP_GPS:
+                    case DEVICE_SERIAL_TNC_AUX_GPS:
+                    case DEVICE_SERIAL_TNC:
+
+                        // Are we trying to send a control-C?  If so, wait a
+                        // special amount of time _before_ we send
+                        // it out the serial port.
+                        if (port_data[port].device_write_buffer[port_data[port].write_out_pos] == (char)0x03) {
+                            // Sending control-C.
+
+                            if (debug_level & 128) {
+                                fprintf(stderr,"Writing command [%x] on port %d, at pos %d\n",
+                                    *(port_data[port].device_write_buffer + 
+                                    port_data[port].write_out_pos),
+                                    port, port_data[port].write_out_pos);
+                            }
+
+                            wait_max = 0;
+                            bytes_input = port_data[port].bytes_input + 40;
+                            while ( (port_data[port].bytes_input != bytes_input)
+                                    && (port_data[port].status == DEVICE_UP)
+                                    && (wait_max < 100) ) {
+                                bytes_input = port_data[port].bytes_input;
+                                /*sleep(1);*/
+
+                                /*wait*/
+                                FD_ZERO(&wd);
+                                FD_SET(port_data[port].channel, &wd);
+                                tmv.tv_sec = 0;
+                                tmv.tv_usec = 80000l;   // Delay 80ms
+                                (void)select(0,NULL,&wd,NULL,&tmv);
+                                wait_max++;
+                                /*fprintf(stderr,"Bytes in %ld %ld\n",bytes_input,port_data[port].bytes_input);*/
+                            }
+                            /*fprintf(stderr,"Wait_max %d\n",wait_max);*/
+                        }   // End of command byte wait
+                        break;
+
+                    // Use this block for all other interfaces.
+                    default:
+                        // Do nothing (no delays for control-C's)
+                        break;
+
+                }   // End of switch
+// End of control-C delay code
+
+ 
+                pthread_testcancel();   // Check for thread termination request
+
+
+// Handle method of sending data (1 or multiple chars per TX)
+                switch (port_data[port].device_type) {
+
+                    // Use this block for serial interfaces where we
+                    // need character pacing and so must send one
+                    // character per write.
+                    case DEVICE_SERIAL_TNC_HSP_GPS:
+                    case DEVICE_SERIAL_TNC_AUX_GPS:
+                    case DEVICE_SERIAL_KISS_TNC:
+                    case DEVICE_SERIAL_MKISS_TNC:
+                    case DEVICE_SERIAL_TNC:
+                    case DEVICE_SERIAL_GPS:
+                    case DEVICE_SERIAL_WX:
+                        // Do the actual write here, one character
+                        // at a time for these types of interfaces.
+
+                        retval = (int)write(port_data[port].channel,
+                            &port_data[port].device_write_buffer[port_data[port].write_out_pos],
+                            1);
+
+//fprintf(stderr,"%02x ", (unsigned char)port_data[port].device_write_buffer[port_data[port].write_out_pos]);
+
+                        pthread_testcancel();   // Check for thread termination request
+
+                        if (retval == 1) {  // We succeeded in writing one byte
+
+                            port_data[port].bytes_output++;
+
+                            port_data[port].write_out_pos++;
+                            if (port_data[port].write_out_pos >= MAX_DEVICE_BUFFER)
+                                port_data[port].write_out_pos = 0;
+
+                        }  else {
+                            /* error of some kind */
+                            port_data[port].errors++;
+                            port_data[port].status = DEVICE_ERROR;
+
+                            // If the below statement is enabled, it causes an immediate reconnect
+                            // after one time-period of inactivity, currently 7.5 minutes, as set in
+                            // main.c:UpdateTime().  This means the symbol will never change from green
+                            // to red on the status bar, so the operator might not know about a
+                            // connection that is being constantly reconnected.  By leaving it commented
+                            // out we get one time period of red, and then it will reconnect at the 2nd
+                            // time period.  This means we can reconnect within 15 minutes if a line
+                            // goes dead.
+                            //
+                            port_data[port].reconnects = -1;     // Causes an immediate reconnect
+ 
+                            if (retval == 0) {
+                                /* Should not get this unless the device is down */
+                                if (debug_level & 2)
+                                    fprintf(stderr,"no data written %d, DEVICE_ERROR ***\n",port);
+                            } else {
+                                if (retval == -1) {
+                                    /* Should only get this if an real error occurs */
+                                    if (debug_level & 2)
+                                        fprintf(stderr,"error on write with error no %d, or port %d\n",errno,port);
+                                }
+                            }
+                            // Show the latest status in the interface control dialog
+                            update_interface_list();
+                        }
+//fprintf(stderr,"Char pacing ");
+//                        usleep(25000); // character pacing, 25ms per char.  20ms doesn't work for PicoPacket.
+                        if (serial_char_pacing > 0) {
+                            // Character pacing.  Delay in between
+                            // each character in milliseconds.
+                            // Convert to microseconds for this
+                            // usleep() call .
+                          usleep(serial_char_pacing * 1000);
+                        }
+                        break;
+
+                    // Use this block for all other interfaces where
+                    // we don't need character pacing and we can
+                    // send blocks of data in one write.
+                    default:
+                        // Do the actual write here, one buffer's
+                        // worth at a time.
+
+                        // Copy the data to a linear write buffer so
+                        // that we can send it all in one shot.
+
+// Need to handle the case where only a portion of the data was
+// written by the write() function.  Perhaps just write out an error
+// message?
+                        quantity = 0;
+                        while (port_data[port].write_in_pos != port_data[port].write_out_pos) {
+
+                            write_buffer[quantity] = port_data[port].device_write_buffer[port_data[port].write_out_pos];
+
+                            port_data[port].write_out_pos++;
+                            if (port_data[port].write_out_pos >= MAX_DEVICE_BUFFER)
+                                port_data[port].write_out_pos = 0;
+
+//fprintf(stderr,"%02x ",(unsigned char)write_buffer[quantity]);
+
+                            quantity++;
+                        }
+
+//fprintf(stderr,"\nWriting %d bytes\n\n", quantity);
+
+                        retval = (int)write(port_data[port].channel,
+                            write_buffer,
+                            quantity);
+
+//fprintf(stderr,"%02x ", (unsigned char)port_data[port].device_write_buffer[port_data[port].write_out_pos]);
+
+                        pthread_testcancel();   // Check for thread termination request
+
+                        if (retval == quantity) {  // We succeeded in writing one byte
+                            port_data[port].bytes_output++;
+                        }  else {
+                            /* error of some kind */
+                            port_data[port].errors++;
+                            port_data[port].status = DEVICE_ERROR;
+
+                            // If the below statement is enabled, it causes an immediate reconnect
+                            // after one time-period of inactivity, currently 7.5 minutes, as set in
+                            // main.c:UpdateTime().  This means the symbol will never change from green
+                            // to red on the status bar, so the operator might not know about a
+                            // connection that is being constantly reconnected.  By leaving it commented
+                            // out we get one time period of red, and then it will reconnect at the 2nd
+                            // time period.  This means we can reconnect within 15 minutes if a line
+                            // goes dead.
+                            //
+                            port_data[port].reconnects = -1;     // Causes an immediate reconnect
+ 
+                            if (retval == 0) {
+                                /* Should not get this unless the device is down */
+                                if (debug_level & 2)
+                                    fprintf(stderr,"no data written %d, DEVICE_ERROR ***\n",port);
+                            } else {
+                                if (retval == -1) {
+                                    /* Should only get this if an real error occurs */
+                                    if (debug_level & 2)
+                                        fprintf(stderr,"error on write with error no %d, or port %d\n",errno,port);
+                                }
+                            }
+                            // Show the latest status in the interface control dialog
+                            update_interface_list();
+                        }
+                        break;
+
+                }   // End of switch
+// End of handling method of sending data (1 or multiple char per TX)
+
+
+            }
+
+            if (end_critical_section(&port_data[port].write_lock, "interface.c:port_write(2)" ) > 0)
+                fprintf(stderr,"write_lock, Port = %d\n", port);
+
+            // Remove the cleanup routine for the case where this
+            // thread gets killed while the mutex is locked.  The
+            // cleanup routine initiates an unlock before the thread
+            // dies.  We must be in deferred cancellation mode for
+            // the thread to have this work properly.
+//
+// NOTE: Ignore the four \"suggest braces\" warnings you see when
+//       compiling, see: http://archive.netbsd.se/?ml=gcc-help&a=2008-06&t=7730779
+//
+            pthread_cleanup_pop(0);
+ 
+        }
+
+        if (port_data[port].active == DEVICE_IN_USE) {
+
+            // Delay here so that the thread doesn't use high
+            // amounts of CPU doing _nothing_.  Take this delay out
+            // and the thread will take lots of CPU time.
+
+// Try to change this to a select that waits on data and a timeout,
+// so that if data doesn't come in within a certain period of time,
+// we wake up to check whether the socket has gone down.  Else, we
+// go back into the select to wait for more data or a timeout.
+// FreeBSD has a problem if this is less than 1ms.  Linux works ok
+// down to 100us.  Theoretically we don't need it anywhere near that
+// short, we just need to check whether the main thread has
+// requested the interface be closed, and so need to have this short
+// enough to have reasonable response time to the user.
+// Unfortunately it has been reported that having this at 100ms
+// causes about 9 seconds of delay when transmitting to a KISS TNC,
+// so it's good to keep this short also.
+
+            FD_ZERO(&wd);
+            FD_SET(port_data[port].channel, &wd);
+            tmv.tv_sec = 0;
+            tmv.tv_usec = 2000;  // Delay 2ms
+            (void)select(0,NULL,&wd,NULL,&tmv);
+        }
+    }
+    if (debug_level & 2)
+        fprintf(stderr,"Thread for port %d write down!\n",port);
+}
+
+
+
+
+
+//***********************************************************
+// read_access_port_thread()
+//
+// Port read thread.
+// port is port# used
+//
+// open threads for reading data from this port.
+//***********************************************************
+static void* read_access_port_thread(void *arg) {
+    int port;
+
+    port = *((int *) arg);
+    // This call means we don't care about the return code and won't
+    // use pthread_join() later.  Makes threading more efficient.
+    (void)pthread_detach(pthread_self());
+    port_read(port);
+
+    return(NULL);
+}
+
+
+
+
+
+//***********************************************************
+// write_access_port_thread()
+//
+// Port write thread.
+// port is port# used
+//
+// open threads for writing data to this port.
+//***********************************************************
+static void* write_access_port_thread(void *arg) {
+    int port;
+
+    port = *((int *) arg);
+    // This call means we don't care about the return code and won't
+    // use pthread_join() later.  Makes threading more efficient.
+    (void)pthread_detach(pthread_self());
+    port_write(port);
+
+    return(NULL);
+}
+
+
+
+
+
+//***********************************************************
+// Start port read & write threads
+// port is port# used
+//
+// open threads for reading and writing data to and from this
+// port.
+//***********************************************************
+int start_port_threads(int port) {
+    int ok;
+
+    port_id[port] = port;
+    if (debug_level & 2)
+        fprintf(stderr,"Start port %d threads\n",port);
+
+    ok = 1;
+    if (port_data[port].active == DEVICE_IN_USE && port_data[port].status == DEVICE_UP){
+        if (debug_level & 2)
+            fprintf(stderr,"*** Startup of read/write threads for port %d ***\n",port);
+
+        /* start the two threads */
+        if (pthread_create(&port_data[port].read_thread, NULL, read_access_port_thread, &port_id[port])) {
+            /* error starting read thread*/
+            fprintf(stderr,"Error starting read thread, port %d\n",port);
+            port_data[port].read_thread = 0;
+            ok = -1;
+        }
+        else if (pthread_create(&port_data[port].write_thread, NULL, write_access_port_thread, &port_id[port])) {
+                /* error starting write thread*/
+                fprintf(stderr,"Error starting write thread, port %d\n",port);
+                port_data[port].write_thread = 0;
+                ok = -1;
+        }
+
+    }
+    else if (debug_level & 2) {
+        fprintf(stderr,"*** Skipping startup of read/write threads for port %d ***\n",port);
+    }
+
+    if (debug_level & 2)
+        fprintf(stderr,"End port %d threads\n",port);
+
+    return(ok);
+}
+
+
+
+
+
+//***********************************************************
+// Clear Port Data
+// int port to be cleared
+//***********************************************************
+void clear_port_data(int port, int clear_more) {
+
+    if (begin_critical_section(&port_data_lock, "interface.c:clear_port_data(1)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+    port_data[port].device_type = -1;
+    port_data[port].active = DEVICE_NOT_IN_USE;
+    port_data[port].status = DEVICE_DOWN;
+
+    // Show the latest status in the interface control dialog
+    update_interface_list();
+
+    port_data[port].device_name[0] = '\0';
+    port_data[port].device_host_name[0] = '\0';
+
+    if (begin_critical_section(&connect_lock, "interface.c:clear_port_data(2)" ) > 0)
+        fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+    port_data[port].thread_status = -1;
+    port_data[port].connect_status = -1;
+    port_data[port].read_thread = 0;
+    port_data[port].write_thread = 0;
+
+    if (end_critical_section(&connect_lock, "interface.c:clear_port_data(3)" ) > 0)
+        fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+    port_data[port].decode_errors = 0;
+    port_data[port].data_type = 0;
+    port_data[port].socket_port = -1;
+    port_data[port].device_host_pswd[0] = '\0';
+
+    if (clear_more)
+        port_data[port].channel = -1;
+
+    port_data[port].channel2 = -1;
+    port_data[port].ui_call[0] = '\0';
+    port_data[port].dtr = 0;
+    port_data[port].sp = -1;
+    port_data[port].style = -1;
+    port_data[port].errors = 0;
+    port_data[port].bytes_input = 0l;
+    port_data[port].bytes_output = 0l;
+    port_data[port].bytes_input_last = 0l;
+    port_data[port].bytes_output_last = 0l;
+    port_data[port].port_activity = 1;    // First time-period is a freebie
+    port_data[port].read_in_pos = 0;
+    port_data[port].read_out_pos = 0;
+    port_data[port].write_in_pos = 0;
+    port_data[port].write_out_pos = 0;
+
+    if (end_critical_section(&port_data_lock, "interface.c:clear_port_data(4)" ) > 0)
+        fprintf(stderr,"port_data_lock, Port = %d\n", port);
+}
+
+
+
+
+
+//***********************************************************
+// Clear All Port Data
+//***********************************************************
+void clear_all_port_data(void) {
+    int i;
+
+    for (i = 0; i < MAX_IFACE_DEVICES; i++)
+        clear_port_data(i,1);
+}
+
+
+
+
+
+//***********************************************************
+// INIT Device names Data
+//***********************************************************
+void init_device_names(void) {
+    xastir_snprintf(dtype[DEVICE_NONE].device_name,
+        sizeof(dtype[DEVICE_NONE].device_name),
+        "%s",
+        langcode("IFDNL00000"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_TNC].device_name,
+        sizeof(dtype[DEVICE_SERIAL_TNC].device_name),
+        "%s",
+        langcode("IFDNL00001"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_TNC_HSP_GPS].device_name,
+        sizeof(dtype[DEVICE_SERIAL_TNC_HSP_GPS].device_name),
+        "%s",
+        langcode("IFDNL00002"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_GPS].device_name,
+        sizeof(dtype[DEVICE_SERIAL_GPS].device_name),
+        "%s",
+        langcode("IFDNL00003"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_WX].device_name,
+        sizeof(dtype[DEVICE_SERIAL_WX].device_name),
+        "%s",
+        langcode("IFDNL00004"));
+    xastir_snprintf(dtype[DEVICE_NET_STREAM].device_name,
+        sizeof(dtype[DEVICE_NET_STREAM].device_name),
+        "%s",
+        langcode("IFDNL00005"));
+    xastir_snprintf(dtype[DEVICE_AX25_TNC].device_name,
+        sizeof(dtype[DEVICE_AX25_TNC].device_name),
+        "%s",
+        langcode("IFDNL00006"));
+    xastir_snprintf(dtype[DEVICE_NET_GPSD].device_name,
+        sizeof(dtype[DEVICE_NET_GPSD].device_name),
+        "%s",
+        langcode("IFDNL00007"));
+    xastir_snprintf(dtype[DEVICE_NET_WX].device_name,
+        sizeof(dtype[DEVICE_NET_WX].device_name),
+        "%s",
+        langcode("IFDNL00008"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_TNC_AUX_GPS].device_name,
+        sizeof(dtype[DEVICE_SERIAL_TNC_AUX_GPS].device_name),
+        "%s",
+        langcode("IFDNL00009"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_KISS_TNC].device_name,
+        sizeof(dtype[DEVICE_SERIAL_KISS_TNC].device_name),
+        "%s",
+        langcode("IFDNL00010"));
+    xastir_snprintf(dtype[DEVICE_NET_DATABASE].device_name,
+        sizeof(dtype[DEVICE_NET_DATABASE].device_name),
+        "%s",
+        langcode("IFDNL00011"));
+    xastir_snprintf(dtype[DEVICE_NET_AGWPE].device_name,
+        sizeof(dtype[DEVICE_NET_AGWPE].device_name),
+        "%s",
+        langcode("IFDNL00012"));
+    xastir_snprintf(dtype[DEVICE_SERIAL_MKISS_TNC].device_name,
+        sizeof(dtype[DEVICE_SERIAL_MKISS_TNC].device_name),
+        "%s",
+        langcode("IFDNL00013"));
+
+#ifdef HAVE_DB
+    // SQL Database (experimental)
+    xastir_snprintf(dtype[DEVICE_SQL_DATABASE].device_name,
+        sizeof(dtype[DEVICE_SQL_DATABASE].device_name),
+        "%s",
+        langcode("IFDNL00014"));
+#endif /* HAVE_DB */
+
+}
+
+
+
+
+
+//***********************************************************
+// Delete Device.  Shuts down active port/ports.
+//***********************************************************
+int del_device(int port) {
+    int ok;
+    char temp[300];
+    long wait_time = 0;
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"Delete Device start\n");
+
+    ok = -1;
+    switch (port_data[port].device_type) {
+
+        case(DEVICE_SERIAL_TNC):
+        case(DEVICE_SERIAL_KISS_TNC):
+        case(DEVICE_SERIAL_MKISS_TNC):
+        case(DEVICE_SERIAL_GPS):
+        case(DEVICE_SERIAL_WX):
+        case(DEVICE_SERIAL_TNC_HSP_GPS):
+        case(DEVICE_SERIAL_TNC_AUX_GPS):
+
+            switch (port_data[port].device_type){
+
+                case DEVICE_SERIAL_TNC:
+
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial TNC device\n");
+
+begin_critical_section(&devices_lock, "interface.c:del_device" );
+
+                    xastir_snprintf(temp, sizeof(temp), "config/%s", devices[port].tnc_down_file);
+
+end_critical_section(&devices_lock, "interface.c:del_device" );
+
+                    (void)command_file_to_tnc_port(port,get_data_base_dir(temp));
+                    break;
+
+                case DEVICE_SERIAL_KISS_TNC:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial KISS TNC device\n");
+                        break;
+
+                case DEVICE_SERIAL_MKISS_TNC:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial MKISS TNC device\n");
+                        break;
+
+                case DEVICE_SERIAL_GPS:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial GPS device\n");
+                        if (using_gps_position) {
+                            using_gps_position--;
+                        }
+                        break;
+
+                case DEVICE_SERIAL_WX:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial WX device\n");
+
+                    break;
+
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial TNC w/HSP GPS\n");
+                        if (using_gps_position) {
+                            using_gps_position--;
+                        }
+
+begin_critical_section(&devices_lock, "interface.c:del_device" );
+
+                    xastir_snprintf(temp, sizeof(temp), "config/%s", devices[port].tnc_down_file);
+
+end_critical_section(&devices_lock, "interface.c:del_device" );
+
+                    (void)command_file_to_tnc_port(port,get_data_base_dir(temp));
+                    break;
+
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Serial TNC w/AUX GPS\n");
+                        if (using_gps_position) {
+                            using_gps_position--;
+                        }
+
+begin_critical_section(&devices_lock, "interface.c:del_device");
+
+                    sprintf(temp, "config/%s", devices[port].tnc_down_file);
+
+end_critical_section(&devices_lock, "interface.c:del_device");
+
+                    (void)command_file_to_tnc_port(port,
+                        get_data_base_dir(temp));
+                    break;
+
+                default:
+                    break;
+            }   // End of switch
+
+
+            // Let the write queue empty before we return, to make
+            // sure all of the data gets written out.
+            while ( (port_data[port].write_in_pos != port_data[port].write_out_pos)
+                    && port_data[port].status == DEVICE_UP) {
+
+                // Check whether we're hung waiting on the device
+                if (wait_time > SERIAL_MAX_WAIT)
+                    break;   // Break out of the while loop
+
+                sched_yield();
+                usleep(25000);    // 25ms
+                wait_time = wait_time + 25000;
+            }
+
+
+            if (debug_level & 2)
+                fprintf(stderr,"Serial detach\n");
+
+            ok = serial_detach(port);
+            break;
+
+        case(DEVICE_NET_STREAM):
+        case(DEVICE_AX25_TNC):
+        case(DEVICE_NET_GPSD):
+        case(DEVICE_NET_WX):
+        case(DEVICE_NET_DATABASE):
+        case(DEVICE_NET_AGWPE):
+
+            switch (port_data[port].device_type){
+
+                case DEVICE_NET_STREAM:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Network stream\n");
+                    break;
+
+                case DEVICE_AX25_TNC:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a AX25 TNC device\n");
+                    break;
+
+                case DEVICE_NET_GPSD:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Network GPSd stream\n");
+                        if (using_gps_position) {
+                            using_gps_position--;
+                        }
+                    break;
+
+                case DEVICE_NET_WX:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Network WX stream\n");
+                    break;
+
+                case DEVICE_NET_DATABASE:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Network Database stream\n");
+                    break;
+
+                case DEVICE_NET_AGWPE:
+                    if (debug_level & 2)
+                        fprintf(stderr,"Close a Network AGWPE stream\n");
+                    break;
+
+                default:
+                    break;
+            }
+            if (debug_level & 2)
+                fprintf(stderr,"Net detach\n");
+
+            ok = net_detach(port);
+            break;
+
+#ifdef HAVE_DB
+            case DEVICE_SQL_DATABASE:
+                if (debug_level & 2)
+                    fprintf(stderr,"Close connection to database on device %d\n",port);
+                if (port_data[port].status==DEVICE_UP) { 
+                   ok = closeConnection(&connections[port],port);
+                }
+                // remove the connection from the list of open connections
+                /* clear port active */
+                port_data[port].active = DEVICE_NOT_IN_USE;
+                /* clear port status */
+                port_data[port].active = DEVICE_DOWN;
+                update_interface_list();
+fprintf(stderr,"Closed connection to database on device %d\n",port);
+            break;
+#endif /* HAVE_DB */
+
+        default:
+            break;
+    }
+
+    if (ok) {
+        int retvalue;
+
+        if (debug_level & 2)
+            fprintf(stderr,"port detach OK\n");
+
+        usleep(100000);    // 100ms
+        if (debug_level & 2)
+            fprintf(stderr,"Cancel threads\n");
+
+        if (begin_critical_section(&port_data_lock, "interface.c:del_device(1)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        if (begin_critical_section(&connect_lock, "interface.c:del_device(2)" ) > 0)
+            fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+        if (port_data[port].read_thread != 0) { // If we have a thread defined
+            retvalue = pthread_cancel(port_data[port].read_thread);
+            if (retvalue == ESRCH) {
+                //fprintf(stderr,"ERROR: Could not cancel read thread on port %d\n", port);
+                //fprintf(stderr,"No thread found with that thread ID\n");
+            }
+        }
+
+        if (port_data[port].write_thread != 0) {    // If we have a thread defined
+            retvalue = pthread_cancel(port_data[port].write_thread);
+            if (retvalue == ESRCH) {
+                //fprintf(stderr,"ERROR: Could not cancel write thread on port %d\n", port);
+                //fprintf(stderr,"No thread found with that thread ID\n");
+            }
+        }
+
+        if (end_critical_section(&connect_lock, "interface.c:del_device(3)" ) > 0)
+            fprintf(stderr,"connect_lock, Port = %d\n", port);
+
+        if (end_critical_section(&port_data_lock, "interface.c:del_device(4)" ) > 0)
+            fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+        usleep(100000); // 100ms
+    } else {
+        if (debug_level & 2)
+            fprintf(stderr,"Port %d could not be closed\n",port);
+    }
+    usleep(10);
+
+    // Cover the case where someone plays with a GPS interface or
+    // three and then turns it/them off again: They won't send a
+    // posit again until the next restart or whenever they enable a
+    // GPS interface again that has good data, unless we set this
+    // variable again for them.
+    if (!using_gps_position) {
+        my_position_valid = 1;
+    }
+
+    return(ok);
+}
+
+
+#ifdef HAVE_DB
+/* Add a device, passing it a pointer to the ioparam 
+ * that describes the interface to start up, rather than passing
+ * an extracted list of elements 
+ *
+ * temporary addition for testing sql_database_functionality 
+ * when working, needs to be integrated into add_device
+ */
+int add_device_by_ioparam(int port_avail, ioparam *device) {
+    int ok;
+    int got_conn;
+    int done = 0;
+    DataRow *dr;
+    ok = -1;
+
+    if (port_avail >= 0){
+
+        switch (device->device_type) {
+            case DEVICE_SQL_DATABASE:
+                if (debug_level & 4096)
+                    fprintf(stderr,"Opening a sql db connection to %s\n",device->device_host_name);
+                clear_port_data(port_avail,0);
+
+                port_data[port_avail].device_type = DEVICE_SQL_DATABASE;
+                xastir_snprintf(port_data[port_avail].device_host_name,
+                    sizeof(port_data[port_avail].device_host_name),
+                    "%s",
+                    device->device_host_name);
+                if (connections_initialized==0) { 
+                    if (debug_level & 4096)
+                        fprintf(stderr,"Calling initConnections in add_device_by_ioparam\n");
+fprintf(stderr,"adddevice, initializing connections");
+                   connections_initialized = initConnections();
+                }
+                if (debug_level & 4096) { 
+                    fprintf(stderr,"Opening (in interfaces) device on port [%d] with connection [%p]\n",port_avail,&connections[port_avail]);
+                    fprintf(stderr,"device [%p][%p] device_type=%d\n",device,&device,device->device_type);
+                }
+                got_conn = 0;
+                got_conn=openConnection(device, &connections[port_avail]);
+                if (debug_level & 4096) {
+                    fprintf(stderr,"got_conn connections[%d] [%p] result=%d\n",port_avail,&connections[port_avail],got_conn);
+                    if (got_conn==1) 
+                        fprintf(stderr,"got_conn connection type %d\n",connections[port_avail].type);
+                }
+                if ((got_conn == 1) && (!(connections[port_avail].type==NULL))) { 
+                   if (debug_level & 4096)
+                       fprintf(stderr, "Opened connection [%d] type=[%d]\n",port_avail,connections[port_avail].type);
+                   ok = 1;
+                   port_data[port_avail].active = DEVICE_IN_USE;
+                   port_data[port_avail].status = DEVICE_UP;
+                } else { 
+                   port_data[port_avail].active = DEVICE_IN_USE;
+                   port_data[port_avail].status = DEVICE_ERROR;
+                }
+                // Show the latest status in the interface control dialog
+                update_interface_list();
+                if (ok == 1) {
+                    /* if connected save top of call list */
+                    ok = storeStationSimpleToGisDb(&connections[port_avail], n_first);
+                    if (ok==1) { 
+                         if (debug_level & 4096)
+                             fprintf(stderr,"Stored station n_first\n");
+                         // iterate through station_pointers and write all stations currently known
+                         dr = n_first->n_next;
+                         if (dr!=NULL) { 
+                             while (done==0) { 
+                                 if (debug_level & 4096)
+                                      fprintf(stderr,"storing additional stations\n");
+                                 // Need to check that stations aren't from the database 
+                                 // preventing creation of duplicate round trip records.
+                                 ok = storeStationSimpleToGisDb(&connections[port_avail], dr);
+                                 if (ok==1) {
+                                    dr = dr->n_next;
+                                    if (dr==NULL) { 
+                                        done = 1;
+                                    } 
+                                 } else { 
+                                    done = 1;
+                                 }
+                             }
+                         }
+                    }
+                }
+        }
+    }
+    return ok;
+}
+#endif /* HAVE_DB */
+
+
+//***********************************************************
+// Add Device.  Starts up ports (makes them active).
+// dev_type is the device type to add
+// dev_num is the device name
+// dev_hst is the host name to connect to (network only)
+// dev_sck_p is the socket port to connect to (network only)
+// dev_sp is the baud rate of the port (serial only)
+// dev_sty is the port style (serial only)
+//
+// this will return the port # if one is available
+// otherwise it will return -1 if there is an error
+//***********************************************************
+int add_device(int port_avail,int dev_type,char *dev_nm,char *passwd,int dev_sck_p,
+        int dev_sp,int dev_sty,int reconnect, char *filter_string) {
+    char logon_txt[600];
+    char init_kiss_string[5];   // KISS-mode on startup
+    int ok;
+    char temp[300];
+    char verstr[15];
+
+    if ( (dev_nm == NULL) || (passwd == NULL) )
+        return(-1);
+
+    if (dev_nm[0] == '\0')
+        return(-1);
+
+    xastir_snprintf(verstr,
+        sizeof(verstr),
+        "XASTIR %s",
+        VERSION);
+
+    ok = -1;
+    if (port_avail >= 0){
+        if (debug_level & 2)
+            fprintf(stderr,"Port Available %d\n",port_avail);
+
+        switch(dev_type){
+
+            case DEVICE_SERIAL_TNC:
+            case DEVICE_SERIAL_KISS_TNC:
+            case DEVICE_SERIAL_MKISS_TNC:
+            case DEVICE_SERIAL_GPS:
+            case DEVICE_SERIAL_WX:
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+            case DEVICE_SERIAL_TNC_AUX_GPS:
+
+                switch (dev_type) {
+
+                    case DEVICE_SERIAL_TNC:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial TNC device\n");
+
+                        break;
+
+                    case DEVICE_SERIAL_KISS_TNC:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial KISS TNC device\n");
+
+                        break;
+
+                    case DEVICE_SERIAL_MKISS_TNC:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial MKISS TNC device\n");
+
+                        break;
+
+                    case DEVICE_SERIAL_GPS:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial GPS device\n");
+                        // Must wait for valid GPS parsing after
+                        // sending one posit.
+                        my_position_valid = 1;
+                        using_gps_position++;
+                        statusline(langcode("BBARSTA041"),1);
+//fprintf(stderr,"my_position_valid = 1, using_gps_position:%d\n",using_gps_position);
+ 
+                        break;
+
+                    case DEVICE_SERIAL_WX:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial WX device\n");
+
+                        break;
+
+                    case DEVICE_SERIAL_TNC_HSP_GPS:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial TNC w/HSP GPS device\n");
+                        // Must wait for valid GPS parsing after
+                        // sending one posit.
+                        my_position_valid = 1;
+                        using_gps_position++;
+                        statusline(langcode("BBARSTA041"),1);
+//fprintf(stderr,"my_position_valid = 1, using_gps_position:%d\n",using_gps_position);
+ 
+                        break;
+
+                    case DEVICE_SERIAL_TNC_AUX_GPS:
+                        if (debug_level & 2)
+                            fprintf(stderr,"Opening a Serial TNC w/AUX GPS device\n");
+                        // Must wait for valid GPS parsing after
+                        // sending one posit.
+                        my_position_valid = 1;
+                        using_gps_position++;
+                        statusline(langcode("BBARSTA041"),1);
+//fprintf(stderr,"my_position_valid = 1, using_gps_position:%d\n",using_gps_position);
+ 
+                        break;
+
+                    default:
+                        break;
+                }
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(1)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);    
+
+                port_data[port_avail].device_type = dev_type;
+                xastir_snprintf(port_data[port_avail].device_name,
+                    sizeof(port_data[port_avail].device_name),
+                    "%s",
+                    dev_nm);
+                port_data[port_avail].sp = dev_sp;
+                port_data[port_avail].style = dev_sty;
+                if (dev_type == DEVICE_SERIAL_WX) {
+                    if (strcmp("1",passwd) == 0)
+                        port_data[port_avail].data_type = 1;
+                }
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(2)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);    
+
+                ok = serial_init(port_avail);
+                break;
+
+            case DEVICE_NET_STREAM:
+                if (debug_level & 2)
+                    fprintf(stderr,"Opening a Network stream\n");
+
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(3)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);    
+
+                port_data[port_avail].device_type = DEVICE_NET_STREAM;
+                xastir_snprintf(port_data[port_avail].device_host_name,
+                    sizeof(port_data[port_avail].device_host_name),
+                    "%s",
+                    dev_nm);
+                xastir_snprintf(port_data[port_avail].device_host_pswd,
+                    sizeof(port_data[port_avail].device_host_pswd),
+                    "%s",
+                    passwd);
+                port_data[port_avail].socket_port = dev_sck_p;
+                port_data[port_avail].reconnect = reconnect;
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(4)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                ok = net_init(port_avail);
+
+                if (ok == 1) {
+
+                    /* if connected now send password */
+                    if (strlen(passwd)) {
+
+                        if (filter_string != NULL
+                                && strlen(filter_string) > 0) {    // Filter specified
+
+                            // Please note that "filter" must be the 8th
+                            // parameter on the line in order to be
+                            // parsed properly by the servers.
+                            xastir_snprintf(logon_txt,
+                                sizeof(logon_txt),
+                                "user %s pass %s vers %s filter %s%c%c",
+                                my_callsign,
+                                passwd,
+                                verstr,
+                                filter_string,
+                                '\r',
+                                '\n');
+                        }
+                        else {  // No filter specified
+                            xastir_snprintf(logon_txt,
+                                sizeof(logon_txt),
+                                "user %s pass %s vers %s%c%c",
+                                my_callsign,
+                                passwd,
+                                verstr,
+                                '\r',
+                                '\n');
+                        }
+                    }
+                    else {
+                        xastir_snprintf(logon_txt,
+                            sizeof(logon_txt),
+                            "user %s pass -1 vers %s %c%c",
+                            my_callsign,
+                            verstr,
+                            '\r',
+                            '\n');
+                    }
+
+//fprintf(stderr,"Sending this string: %s\n", logon_txt);
+ 
+                    port_write_string(port_avail,logon_txt);
+                }
+                break;
+
+            case DEVICE_AX25_TNC:
+                if (debug_level & 2)
+                    fprintf(stderr,"Opening a network AX25 TNC\n");
+
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(5)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                port_data[port_avail].device_type = DEVICE_AX25_TNC;
+                xastir_snprintf(port_data[port_avail].device_name,
+                    sizeof(port_data[port_avail].device_name),
+                    "%s",
+                    dev_nm);
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(6)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                ok = ax25_init(port_avail);
+                break;
+
+            case DEVICE_NET_GPSD:
+                if (debug_level & 2)
+                    fprintf(stderr,"Opening a network GPS using gpsd\n");
+
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(7)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                port_data[port_avail].device_type = DEVICE_NET_GPSD;
+                xastir_snprintf(port_data[port_avail].device_host_name,
+                    sizeof(port_data[port_avail].device_host_name),
+                    "%s",
+                    dev_nm);
+                port_data[port_avail].socket_port = dev_sck_p;
+                port_data[port_avail].reconnect = reconnect;
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(8)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                ok = net_init(port_avail);
+                if (ok == 1) {
+
+                    // Pre-2.90 GPSD protocol
+                    xastir_snprintf(logon_txt, sizeof(logon_txt), "R\r\n");
+                    port_write_string(port_avail,logon_txt);
+
+                    // Moved the below section to near the bottom of
+                    // the routine, after the read/write threads are
+                    // started.  The net effect is that the above
+                    // string gets sent, then the below string,
+                    // kick-starting either protocol into sending us
+                    // NMEA strings.
+                    //
+//                  // Post-2.90 GPSD protocol
+//                  xastir_snprintf(logon_txt, sizeof(logon_txt), "?WATCH={\"enable\":true,\"nmea\":true}\r\n");
+//                  port_write_string(port_avail,logon_txt);
+
+                    // Must wait for valid GPS parsing after sending
+                    // one posit.
+                    my_position_valid = 1;
+                    using_gps_position++;
+                    statusline(langcode("BBARSTA041"),1);
+//fprintf(stderr,"my_position_valid = 1, using_gps_position:%d\n",using_gps_position);
+                }
+                break;
+
+            case DEVICE_NET_WX:
+                if (debug_level & 2)
+                    fprintf(stderr,"Opening a network WX\n");
+
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(9)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                port_data[port_avail].device_type = DEVICE_NET_WX;
+                xastir_snprintf(port_data[port_avail].device_host_name,
+                    sizeof(port_data[port_avail].device_host_name),
+                    "%s",
+                    dev_nm);
+                port_data[port_avail].socket_port = dev_sck_p;
+                port_data[port_avail].reconnect = reconnect;
+                if (strcmp("1",passwd) == 0)
+                    port_data[port_avail].data_type = 1;
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(10)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                ok = net_init(port_avail);
+                if (ok == 1) {
+                    /* if connected now send call and program version */
+                    xastir_snprintf(logon_txt, sizeof(logon_txt), "%s %s%c%c", my_callsign, VERSIONTXT, '\r', '\n');
+                    port_write_string(port_avail,logon_txt);
+                }
+                break;
+
+            case DEVICE_NET_DATABASE:
+                if (debug_level & 2)
+                    fprintf(stderr,"Opening a network database stream\n");
+
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(11)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                port_data[port_avail].device_type = DEVICE_NET_DATABASE;
+                xastir_snprintf(port_data[port_avail].device_host_name,
+                    sizeof(port_data[port_avail].device_host_name),
+                    "%s",
+                    dev_nm);
+                port_data[port_avail].socket_port = dev_sck_p;
+                port_data[port_avail].reconnect = reconnect;
+                if (strcmp("1",passwd) == 0)
+                    port_data[port_avail].data_type = 1;
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(12)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                ok = net_init(port_avail);
+                if (ok == 1) {
+                    /* if connected now send call and program version */
+                    xastir_snprintf(logon_txt, sizeof(logon_txt), "%s %s%c%c", my_callsign, VERSIONTXT, '\r', '\n');
+                    port_write_string(port_avail,logon_txt);
+                }
+                break;
+
+            case DEVICE_NET_AGWPE:
+                if (debug_level & 2)
+                    fprintf(stderr,"Opening a network AGWPE stream");
+
+                clear_port_data(port_avail,0);
+
+//if (begin_critical_section(&port_data_lock, "interface.c:add_device(13)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                port_data[port_avail].device_type = DEVICE_NET_AGWPE;
+                xastir_snprintf(port_data[port_avail].device_host_name,
+                    sizeof(port_data[port_avail].device_host_name),
+                    "%s",
+                    dev_nm);
+                port_data[port_avail].socket_port = dev_sck_p;
+                port_data[port_avail].reconnect = reconnect;
+                if (strcmp("1",passwd) == 0)
+                    port_data[port_avail].data_type = 1;
+
+//if (end_critical_section(&port_data_lock, "interface.c:add_device(14)" ) > 0)
+//    fprintf(stderr,"port_data_lock, Port = %d\n", port_avail);
+
+                ok = net_init(port_avail);
+
+                if (ok == 1) {
+
+                    // If password isn't empty, send login
+                    // information
+                    //
+                    if (strlen(passwd) != 0) {
+
+                        // Send the login packet 
+                        send_agwpe_packet(port_avail,
+                            0,                       // AGWPE RadioPort
+                            'P',                     // Login/Password Frame
+                            NULL,                    // FromCall
+                            NULL,                    // ToCall
+                            NULL,                    // Path
+                            (unsigned char *)passwd, // Data
+                            strlen(passwd));         // Length
+                    }
+                }
+                break;
+
+            default:
+                break;
+        }
+
+        if (ok == 1) {  // If port is connected...
+
+            if (debug_level & 2)
+                fprintf(stderr,"*** add_device: ok: %d ***\n",ok);
+
+            /* if all is ok check and start read write threads */
+            (void)start_port_threads(port_avail);
+            usleep(100000); // 100ms
+
+            switch (dev_type) {
+
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+
+                    if (ok == 1) {
+
+// We already have the lock by the time add_device() is called!
+//begin_critical_section(&devices_lock, "interface.c:add_device" );
+
+                        xastir_snprintf(temp, sizeof(temp), "config/%s", devices[port_avail].tnc_up_file);
+
+//end_critical_section(&devices_lock, "interface.c:add_device" );
+
+                        (void)command_file_to_tnc_port(port_avail,get_data_base_dir(temp));
+                    }
+                    break;
+
+                case DEVICE_SERIAL_KISS_TNC:
+
+                    // Initialize KISS-Mode at startup
+                    if (devices[port_avail].init_kiss) {
+                        xastir_snprintf(init_kiss_string,
+                            sizeof(init_kiss_string),
+                            "\x1B at k\r");    // [ESC at K sets tnc from terminal- into kissmode
+                        port_write_string(port_avail,init_kiss_string);
+                        usleep(100000); // wait a little bit...
+                    }
+
+                    // Send the KISS parameters to the TNC
+                    send_kiss_config(port_avail,0,0x01,atoi(devices[port_avail].txdelay));
+                    send_kiss_config(port_avail,0,0x02,atoi(devices[port_avail].persistence));
+                    send_kiss_config(port_avail,0,0x03,atoi(devices[port_avail].slottime));
+                    send_kiss_config(port_avail,0,0x04,atoi(devices[port_avail].txtail));
+                    send_kiss_config(port_avail,0,0x05,devices[port_avail].fullduplex);
+                    break;
+
+//WE7U
+               case DEVICE_SERIAL_MKISS_TNC:
+                    // Send the KISS parameters to the TNC.  We'll
+                    // need to send them to the correct port for
+                    // this MKISS device.
+                    send_kiss_config(port_avail,0,0x01,atoi(devices[port_avail].txdelay));
+                    send_kiss_config(port_avail,0,0x02,atoi(devices[port_avail].persistence));
+                    send_kiss_config(port_avail,0,0x03,atoi(devices[port_avail].slottime));
+                    send_kiss_config(port_avail,0,0x04,atoi(devices[port_avail].txtail));
+                    send_kiss_config(port_avail,0,0x05,devices[port_avail].fullduplex);
+                    break;
+
+                case DEVICE_NET_AGWPE:
+
+                    // Query for the AGWPE version
+                    //
+                    send_agwpe_packet(port_avail,
+                        0,      // AGWPE RadioPort
+                        'R',    // Request SW Version Frame
+                        NULL,   // FromCall
+                        NULL,   // ToCall
+                        NULL,   // Path
+                        NULL,   // Data
+                        0);     // Length
+
+
+                    // Query for port information
+                    //
+                    send_agwpe_packet(port_avail,
+                        0,      // AGWPE RadioPort
+                        'G',    // Request Port Info Frame
+                        NULL,   // FromCall
+                        NULL,   // ToCall
+                        NULL,   // Path
+                        NULL,   // Data
+                        0);     // Length
+
+
+/*
+                    // Ask to receive "Monitor" frames.  Once we
+                    // switch to "raw" mode for decoding, we won't
+                    // need this one anymore.
+                    //
+                    send_agwpe_packet(port_avail,
+                        0,      // AGWPE RadioPort
+                        'm',    // Monitor Packets Frame
+                        NULL,   // FromCall
+                        NULL,   // ToCall
+                        NULL,   // Path
+                        NULL,   // Data
+                        0);     // Length
+*/
+
+
+                    // Ask to receive "raw" frames
+                    //
+                    send_agwpe_packet(port_avail,
+                        0,      // AGWPE RadioPort
+                        'k',    // Request Raw Packets Frame
+                        NULL,   // FromCall
+                        NULL,   // ToCall
+                        NULL,   // Path
+                        NULL,   // Data
+                        0);     // Length
+
+
+/*
+                    // Send a dummy UI frame for testing purposes.
+                    //
+                    send_agwpe_packet(port_avail,
+                        atoi(devices[port_avail].device_host_filter_string) - 1, // AGWPE radio port
+                        '\0',       // type
+                        "TEST-3",   // FromCall
+                        "APRS",     // ToCall
+                        NULL,       // Path
+                        "Test",     // Data
+                        4);         // length
+
+
+                    // Send another dummy UI frame.
+                    //
+                    send_agwpe_packet(port_avail,
+                        atoi(devices[port_avail].device_host_filter_string) - 1, // AGWPE radio port
+                        '\0',       // type
+                        "TEST-3",   // FromCall
+                        "APRS",     // ToCall
+                        "RELAY,SAR1-1,SAR2-1,SAR3-1,SAR4-1,SAR5-1,SAR6-1,SAR7-1", // Path
+                        "Testing this darned thing!",   // Data
+                        26);     // length
+*/
+
+                    break;
+
+                case DEVICE_NET_GPSD:
+ 
+                     // Post-2.90 GPSD protocol
+                    xastir_snprintf(logon_txt, sizeof(logon_txt), "?WATCH={\"enable\":true,\"nmea\":true}\r\n");
+                    port_write_string(port_avail,logon_txt);
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        if (ok == -1) {
+            xastir_snprintf(temp, sizeof(temp), langcode("POPEM00015"), port_avail);
+            popup_message(langcode("POPEM00004"),temp);
+            port_avail = -1;
+        } else {
+            if (ok == 0) {
+                xastir_snprintf(temp, sizeof(temp), langcode("POPEM00016"), port_avail);
+                popup_message(langcode("POPEM00004"),temp);
+                port_avail = -1;
+            }
+        }
+    } else
+        popup_message(langcode("POPEM00004"),langcode("POPEM00017"));
+
+    return(port_avail);
+}
+
+
+
+
+
+//***********************************************************
+// port status
+// port is the port to get status on
+//***********************************************************
+void port_stats(int port) {
+    if (port >= 0) {
+        fprintf(stderr,"Port %d %s Status\n\n",port,dtype[port_data[port].device_type].device_name);
+        fprintf(stderr,"Errors %d\n",port_data[port].errors);
+        fprintf(stderr,"Reconnects %d\n",port_data[port].reconnects);
+        fprintf(stderr,"Bytes in: %ld  out: %ld\n",(long)port_data[port].bytes_input,(long)port_data[port].bytes_output);
+        fprintf(stderr,"\n");
+    }
+}
+
+
+
+
+
+//***********************************************************
+// startup defined ports
+//
+// port = -2: Start all defined interfaces
+// port = -1: Start all interfaces with "Activate on Startup"
+// port = 0 - MAX: Start only the one port specified
+//***********************************************************
+void startup_all_or_defined_port(int port) {
+    int i, override;
+    int start;
+
+    override = 0;
+
+    switch (port) {
+
+        case -1:    // Start if "Activate on Startup" enabled
+            start = 0;
+            break;
+
+        case -2:    // Start all interfaces, period!
+            start = 0;
+            override = 1;
+            break;
+
+        default:    // Start only the interface specified in "port"
+            start = port;
+            override = 1;
+            break;
+    }
+
+begin_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+    for (i = start; i < MAX_IFACE_DEVICES; i++){
+
+        // Only start ports that aren't already up
+        if ( (port_data[i].active != DEVICE_IN_USE)
+                || (port_data[i].status != DEVICE_UP) ) {
+
+            switch (devices[i].device_type) {
+
+                case DEVICE_NET_STREAM:
+                    if (devices[i].connect_on_startup == 1 || override) {
+
+//end_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+                    //(void)del_device(i);    // Disconnect old port if it exists
+//begin_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+                        (void)add_device(i,
+                            DEVICE_NET_STREAM,
+                            devices[i].device_host_name,
+                            devices[i].device_host_pswd,
+                            devices[i].sp,
+                            0,
+                            0,
+                            devices[i].reconnect,
+                            devices[i].device_host_filter_string);
+                    }
+                    break;
+
+                case DEVICE_NET_DATABASE:
+                    if (devices[i].connect_on_startup == 1 || override) {
+
+//end_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+                    //(void)del_device(i);    // Disconnect old port if it exists
+//begin_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+                        (void)add_device(i,
+                            DEVICE_NET_DATABASE,
+                            devices[i].device_host_name,
+                            devices[i].device_host_pswd,
+                            devices[i].sp,
+                            0,
+                            0,
+                            devices[i].reconnect,
+                            devices[i].device_host_filter_string);
+                    }
+                    break;
+
+                case DEVICE_NET_AGWPE:
+                    if (devices[i].connect_on_startup == 1 || override) {
+
+//end_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+                    //(void)del_device(i);    // Disconnect old port if it exists
+//begin_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+                        (void)add_device(i,
+                            DEVICE_NET_AGWPE,
+                            devices[i].device_host_name,
+                            devices[i].device_host_pswd,
+                            devices[i].sp,
+                            0,
+                            0,
+                            devices[i].reconnect,
+                            devices[i].device_host_filter_string);
+                    }
+                    break;
+
+                case DEVICE_NET_GPSD:
+                    if (devices[i].connect_on_startup == 1 || override) {
+
+//end_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+//                    (void)del_device(i);    // Disconnect old port if it exists
+//begin_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+                        (void)add_device(i,
+                            DEVICE_NET_GPSD,
+                            devices[i].device_host_name,
+                            "",
+                            devices[i].sp,
+                            0,
+                            0,
+                            devices[i].reconnect,
+                            "");
+                    }
+                    break;
+
+                case DEVICE_SERIAL_WX:
+                    if (devices[i].connect_on_startup == 1 || override) {
+                        (void)add_device(i,
+                            DEVICE_SERIAL_WX,
+                            devices[i].device_name,
+                            devices[i].device_host_pswd,
+                            -1,
+                            devices[i].sp,
+                            devices[i].style,
+                            0,
+                            "");
+                    }
+                    break;
+
+                case DEVICE_NET_WX:
+                    if (devices[i].connect_on_startup == 1 || override) {
+
+//end_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+//                    (void)del_device(i);    // Disconnect old port if it exists
+//begin_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+                        (void)add_device(i,
+                            DEVICE_NET_WX,
+                            devices[i].device_host_name,
+                            devices[i].device_host_pswd,
+                            devices[i].sp,
+                            0,
+                            0,
+                            devices[i].reconnect,
+                            "");
+                    }
+                    break;
+
+                case DEVICE_SERIAL_GPS:
+                    if (devices[i].connect_on_startup == 1 || override) {
+                        (void)add_device(i,
+                            DEVICE_SERIAL_GPS,
+                            devices[i].device_name,
+                            "",
+                            -1,
+                            devices[i].sp,
+                            devices[i].style,
+                            0,
+                            "");
+                    }
+                    break;
+
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+
+                    if (devices[i].connect_on_startup == 1 || override) {
+                        (void)add_device(i,
+                            devices[i].device_type,
+                            devices[i].device_name,
+                            "",
+                            -1,
+                            devices[i].sp,
+                            devices[i].style,
+                            0,
+                            "");
+                    }
+                    break;
+
+                case DEVICE_AX25_TNC:
+                    if (devices[i].connect_on_startup == 1 || override) {
+                        (void)add_device(i,
+                            DEVICE_AX25_TNC,
+                            devices[i].device_name,
+                            "",
+                            -1,
+                            -1,
+                            -1,
+                            0,
+                            "");
+                    }
+                    break;
+#ifdef HAVE_DB
+                case DEVICE_SQL_DATABASE:
+                    if (debug_level & 4096) 
+                        fprintf(stderr,"Device %d Connect_on_startup=%d\n",i,devices[i].connect_on_startup);
+                    if (devices[i].connect_on_startup == 1 || override) {
+                        ioparam *d = &devices[i];
+                        if (debug_level & 4096) 
+                            fprintf(stderr,"Opening a sql db with device type %d\n",d->device_type);
+                        (void)add_device_by_ioparam(i, &devices[i]);
+                        if (debug_level & 4096) 
+                            fprintf(stderr, "added device by ioparam [%d] type=[%d]\n",i,connections[i].type);
+                    }
+                    break;
+#endif /* HAVE_DB */
+
+                default:
+                    break;
+            }   // End of switch
+        }
+        else if (debug_level & 2) {
+            fprintf(stderr,"Skipping port %d, it's already running\n",i);
+        }
+
+        if (port != -1 && port != -2) {
+            // We're doing a specific port #, so stop the loop
+            i = MAX_IFACE_DEVICES+1;
+        }
+    }
+
+end_critical_section(&devices_lock, "interface.c:startup_all_or_defined_port" );
+
+}
+
+
+
+
+
+//***********************************************************
+// shutdown active ports
+//
+// port = -1:  Shut down all active ports
+// port = 0 to max: Shut down the specified port if active
+//***********************************************************
+void shutdown_all_active_or_defined_port(int port) {
+    int i;
+    int start;
+
+    if (debug_level & 2)
+        fprintf(stderr,"\nshutdown_all_active_or_defined_port: %d\n\n",port);
+
+    if (port == -1)
+        start = 0;
+    else
+        start = port;
+
+    for( i = start; i < MAX_IFACE_DEVICES; i++ ){
+        if ( (port_data[i].active == DEVICE_IN_USE)
+                && ( (port_data[i].status == DEVICE_UP)
+                    || (port_data[i].status == DEVICE_ERROR) ) ) {
+            if (debug_level & 2)
+                fprintf(stderr,"Shutting down port %d \n",i);
+
+            (void)del_device(i);
+        }
+        if (port != -1) // Stop after one iteration if port specified
+            i = MAX_IFACE_DEVICES+1;
+    }
+}
+
+
+
+
+
+//*************************************************************
+// check ports                                               
+//
+// Called periodically by main.c:UpdateTime() function.
+// Attempts to reconnect interfaces that are down.
+//*************************************************************
+void check_ports(void) {
+    int i;
+    int temp;
+
+    for (i = 0; i < MAX_IFACE_DEVICES; i++){
+
+        switch (port_data[i].device_type){
+            case(DEVICE_NET_STREAM):
+            //case(DEVICE_AX25_TNC):
+            case(DEVICE_NET_GPSD):
+            case(DEVICE_NET_WX):
+                if (port_data[i].port_activity == 0) {
+                    // We've seen no activity for one time period.  This variable
+                    // is updated in interface_gui.c
+    
+                    if (port_data[i].status == DEVICE_ERROR) {
+                        // We're already in the error state, so force a reconnect
+                        port_data[i].reconnects = -1;
+                    }
+                    else if (port_data[i].status == DEVICE_UP) {
+                        // No activity on a port that's being used.
+                        // Cause a reconnect at the next iteration
+                        if (debug_level & 2)
+                            fprintf(stderr,"check_ports(): Inactivity on port %d, DEVICE_ERROR ***\n",i);
+                        port_data[i].status = DEVICE_ERROR; // No activity, so force a shutdown
+
+                        // Show the latest status in the interface control dialog
+                        update_interface_list();
+
+
+                        // If the below statement is enabled, it causes an immediate reconnect
+                        // after one time-period of inactivity, currently 7.5 minutes, as set in
+                        // main.c:UpdateTime().  This means the symbol will never change from green
+                        // to red on the status bar, so the operator might not know about a
+                        // connection that is being constantly reconnected.  By leaving it commented
+                        // out we get one time period of red, and then it will reconnect at the 2nd
+                        // time period.  This means we can reconnect within 15 minutes if a line
+                        // goes dead.
+                        //
+                        port_data[i].reconnects = -1;     // Causes an immediate reconnect
+                    }
+
+                }
+                else {  // We saw activity on this port.
+                    port_data[i].port_activity = 0;     // Reset counter for next time
+                }
+                break;
+        }
+
+        if (port_data[i].active == DEVICE_IN_USE && port_data[i].status == DEVICE_ERROR) {
+            if (debug_level & 2)
+                fprintf(stderr,"Found device error on port %d\n",i);
+
+            if (port_data[i].reconnect == 1) {
+                port_data[i].reconnects++;
+                temp = port_data[i].reconnects;
+                if (temp < 1) {
+                    if (debug_level & 2)
+                        fprintf(stderr,"Device asks for reconnect count now at %d\n",temp);
+
+                    if (debug_level & 2)
+                        fprintf(stderr,"Shutdown device %d\n",i);
+
+                    shutdown_all_active_or_defined_port(i);
+
+                    if (debug_level & 2)
+                        fprintf(stderr,"Starting device %d\n",i);
+
+                    startup_all_or_defined_port(i);
+
+                    /* if error on startup */
+                    if (port_data[i].status == DEVICE_ERROR)
+                        port_data[i].reconnects = temp;
+                } else {
+                    if (debug_level & 2)
+                        fprintf(stderr,"Device has either too many errors, or no activity at all!\n");
+
+                    port_data[i].reconnects = temp - 2;
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+static char unproto_path_txt[MAX_LINE_SIZE+5];
+
+
+
+
+ 
+// Function which selects an unproto path in round-robin fashion.
+// Once we select a path, we save the number selected back to
+// devices[port].unprotonum so that the next time around we select
+// the next in the sequence.  If we don't come up with a valid
+// unproto path, we use the unproto path: "WIDE2-2".
+//
+// Input:  Port number
+// Ouput:  String pointer containing unproto path
+//
+// WE7U:  Should we check to make sure that there are printable
+// characters in the path?
+//
+unsigned char *select_unproto_path(int port) {
+    int count;
+    int done;
+    int temp;
+    int bump_up;
+ 
+
+    // Set unproto path:
+    // We look for a non-null path entry starting at the current
+    // value of "unprotonum".  The first non-null path wins.
+    count = 0;
+    done = 0;
+    bump_up = 0;
+
+
+    while (!done && (count < 3)) {
+        temp = (devices[port].unprotonum + count) % 3;
+        switch (temp) {
+
+            case 0:
+                if (strlen(devices[port].unproto1) > 0) {
+                    xastir_snprintf(unproto_path_txt,
+                        sizeof(unproto_path_txt),
+                        "%s",
+                        devices[port].unproto1);
+                    done++;
+                }
+                else {
+                    // No path entered here.  Skip this path in the
+                    // rotation for next time.
+                    bump_up++;
+                }
+                break;
+
+            case 1:
+                    if (strlen(devices[port].unproto2) > 0) {
+                        xastir_snprintf(unproto_path_txt,
+                            sizeof(unproto_path_txt),
+                            "%s",
+                            devices[port].unproto2);
+                        done++;
+                    }
+                    else {
+                        // No path entered here.  Skip this path in
+                        // the rotation for next time.
+                        bump_up++;
+                    }
+                    break;
+
+            case 2:
+                    if (strlen(devices[port].unproto3) > 0) {
+                        xastir_snprintf(unproto_path_txt,
+                            sizeof(unproto_path_txt),
+                            "%s",
+                            devices[port].unproto3);
+                        done++;
+                    }
+                    else {
+                        // No path entered here.  Skip this path in
+                        // the rotation for next time.
+                        bump_up++;
+                    }
+                    break;
+        }   // End of switch
+        count++;
+    }   // End of while loop
+
+    if (done) {
+        // We found an unproto path.  Check it for accepted values.
+        // Output a warning message if it is beyond normal ranges,
+        // but still allow it to be used.
+        //
+        if(check_unproto_path(unproto_path_txt)) {
+            popup_message_always(langcode("WPUPCFT045"),
+                langcode("WPUPCFT043"));
+        }
+    }
+    else {
+        // We found no entries in the unproto fields for the
+        // interface.  Set a default path of "WIDE2-2".
+
+        xastir_snprintf(unproto_path_txt,
+            sizeof(unproto_path_txt),
+            "WIDE2-2");
+    }
+
+    // Increment the path number for the next round of
+    // transmissions.  This will round-robin the paths so that all
+    // entered paths get used.
+    devices[port].unprotonum = (devices[port].unprotonum + 1 + bump_up) % 3;
+
+    // Make sure the path is in upper-case
+    (void)to_upper(unproto_path_txt);
+
+    return((unsigned char *)unproto_path_txt);
+}
+
+
+
+
+
+//***********************************************************
+// output_my_aprs_data
+// This is the function responsible for sending out my own
+// posits.  The next function below this one handles objects,
+// messages and the like (output_my_data).
+//***********************************************************
+void output_my_aprs_data(void) {
+    char header_txt[MAX_LINE_SIZE+5];
+    char header_txt_save[MAX_LINE_SIZE+5];
+    char data_txt[MAX_LINE_SIZE+5];
+    char data_txt_save[MAX_LINE_SIZE+5];
+    char temp[MAX_LINE_SIZE+5];
+    char path_txt[MAX_LINE_SIZE+5];
+    char *unproto_path = "";
+    char data_txt2[5];
+    struct tm *day_time;
+    time_t sec;
+    char my_pos[256];
+    char my_output_lat[MAX_LAT];
+    char my_output_long[MAX_LONG];
+    char output_net[256];
+    char wx_data[200];
+    char output_phg[10];
+    char output_cs[10];
+    char output_alt[20];
+    char output_brk[3];
+    int ok;
+    int port;
+    char my_comment_tx[MAX_COMMENT+1];
+    int interfaces_ok_for_transmit = 0;
+    char logfile_tmp_path[MAX_VALUE];
+
+    // Check whether transmits are disabled globally
+    if (transmit_disable) {
+
+        if (emergency_beacon) {
+
+            // Notify the operator because emergency_beacon mode is on but
+            // nobody will know it 'cuz global transmit is disabled.
+            //
+            // "Warning"
+            // "Global transmit is DISABLED.  Emergency beacons are NOT going out!"
+            popup_message_always( langcode("POPEM00035"),
+                langcode("POPEM00047") );
+	}
+        return;
+    }
+
+    header_txt_save[0] = '\0';
+    data_txt_save[0] = '\0';
+    sec = sec_now();
+
+
+    // Check whether we're in emergency beacon mode.  If so, add
+    // "EMERGENCY" at the beginning of the comment field we'll
+    // transmit.
+    if (emergency_beacon) {
+        xastir_snprintf(my_comment_tx,
+            sizeof(my_comment_tx),
+            "EMERGENCY %s",
+            my_comment);
+    }
+    else {
+        xastir_snprintf(my_comment_tx,
+            sizeof(my_comment_tx),
+            "%s",
+            my_comment);
+    }
+
+
+    // Format latitude string for transmit later
+    if (transmit_compressed_posit) {    // High res version
+        xastir_snprintf(my_output_lat,
+            sizeof(my_output_lat),
+            "%s",
+            my_lat);
+    }
+    else {  // Create a low-res version of the latitude string
+        long my_temp_lat;
+        char temp_data[20];
+
+        // Convert to long
+        my_temp_lat = convert_lat_s2l(my_lat);
+
+        // Convert to low-res string
+        convert_lat_l2s(my_temp_lat,
+            temp_data,
+            sizeof(temp_data),
+            CONVERT_LP_NORMAL);
+
+//fprintf(stderr," Latitude temp_data:%s\n", temp_data);
+
+        xastir_snprintf(my_output_lat,
+            sizeof(my_output_lat),
+            "%c%c%c%c.%c%c%c",
+            temp_data[0],
+            temp_data[1],
+            temp_data[3],
+            temp_data[4],
+            temp_data[6],
+            temp_data[7],
+            temp_data[8]);
+    }
+
+    (void)output_lat(my_output_lat,transmit_compressed_posit);
+    if (debug_level & 128)
+        fprintf(stderr,"OUT LAT <%s>\n",my_output_lat);
+
+    // Format longitude string for transmit later
+    if (transmit_compressed_posit) {    // High res version
+        xastir_snprintf(my_output_long,
+            sizeof(my_output_long),
+            "%s",
+            my_long);
+    }
+    else {  // Create a low-res version of the longitude string
+        long my_temp_long;
+        char temp_data[20];
+
+        // Convert to long
+        my_temp_long = convert_lon_s2l(my_long);
+
+        // Convert to low-res string
+        convert_lon_l2s(my_temp_long,
+            temp_data,
+            sizeof(temp_data),
+            CONVERT_LP_NORMAL);
+
+//fprintf(stderr,"Longitude temp_data:%s\n", temp_data);
+
+        xastir_snprintf(my_output_long,
+            sizeof(my_output_long),
+            "%c%c%c%c%c.%c%c%c",
+            temp_data[0],
+            temp_data[1],
+            temp_data[2],
+            temp_data[4],
+            temp_data[5],
+            temp_data[7],
+            temp_data[8],
+            temp_data[9]);
+    }
+
+    (void)output_long(my_output_long,transmit_compressed_posit);
+    if (debug_level & 128)
+        fprintf(stderr,"OUT LONG <%s>\n",my_output_long);
+
+begin_critical_section(&devices_lock, "interface.c:output_my_aprs_data" );
+
+    // Iterate across the ports, set up each device's headers/paths/handshakes,
+    // then transmit the posit if the port is open and tx is enabled.
+    for (port = 0; port < MAX_IFACE_DEVICES; port++) {
+
+        // First send any header/path info we might need out the port,
+        // set up TNC's to the proper mode, etc.
+        ok = 1;
+        switch (port_data[port].device_type) {
+
+//            case DEVICE_NET_DATABASE:
+
+            case DEVICE_NET_AGWPE:
+
+                output_net[0] = '\0';   // We don't need this header for AGWPE
+                break;
+
+            case DEVICE_NET_STREAM:
+
+                xastir_snprintf(output_net,
+                    sizeof(output_net),
+                    "%s>%s,TCPIP*:",
+                    my_callsign,
+                    VERSIONFRM);
+                break;
+
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+
+                /* make dtr normal (talk to TNC) */
+                if (port_data[port].status == DEVICE_UP) {
+                    port_dtr(port,0);
+                }
+
+            case DEVICE_SERIAL_TNC_AUX_GPS:
+            case DEVICE_SERIAL_KISS_TNC:
+            case DEVICE_SERIAL_MKISS_TNC:
+            case DEVICE_SERIAL_TNC:
+            case DEVICE_AX25_TNC:
+
+                /* clear this for a TNC */
+                output_net[0] = '\0';
+
+                /* Set my call sign */
+                xastir_snprintf(header_txt,
+                    sizeof(header_txt),
+                    "%c%s %s\r",
+                    '\3',
+                    "MYCALL",
+                    my_callsign);
+
+                // Send the callsign out to the TNC only if the interface is up and tx is enabled???
+                // We don't set it this way for KISS TNC interfaces.
+                if ( (port_data[port].device_type != DEVICE_SERIAL_KISS_TNC)
+                        && (port_data[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+                        && (port_data[port].status == DEVICE_UP)
+                        && (devices[port].transmit_data == 1)
+                        && !transmit_disable
+                        && !posit_tx_disable) {
+                    port_write_string(port,header_txt);
+                }
+
+                // Set unproto path:  Get next unproto path in
+                // sequence.
+                unproto_path = (char *)select_unproto_path(port);
+
+                xastir_snprintf(header_txt,
+                        sizeof(header_txt),
+                        "%c%s %s VIA %s\r",
+                        '\3',
+                        "UNPROTO",
+                        VERSIONFRM,
+                        unproto_path);
+
+                xastir_snprintf(header_txt_save,
+                        sizeof(header_txt_save),
+                        "%s>%s,%s:",
+                        my_callsign,
+                        VERSIONFRM,
+                        unproto_path);
+
+                xastir_snprintf(path_txt,
+                        sizeof(path_txt),
+                        "%s",
+                        unproto_path);
+
+
+                // Send the header data to the TNC.  This sets the
+                // unproto path that'll be used by the next packet.
+                // We don't set it this way for KISS TNC interfaces.
+                if ( (port_data[port].device_type != DEVICE_SERIAL_KISS_TNC)
+                        && (port_data[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+                        && (port_data[port].status == DEVICE_UP)
+                        && (devices[port].transmit_data == 1)
+                        && !transmit_disable
+                        && !posit_tx_disable) {
+                    port_write_string(port,header_txt);
+                }
+
+
+                // Set converse mode.  We don't need to do this for
+                // KISS TNC interfaces.  One european TNC (tnc2-ui)
+                // doesn't accept "conv" but does accept the 'k'
+                // command.  A Kantronics KPC-2 v2.71 TNC accepts
+                // the "conv" command but not the 'k' command.
+                // Figures!  The  choice of whether to send "k" or "conv"
+                // is made by the user in the Serial TNC interface properties
+                // dialog.  Older versions of Xastir had this hardcoded here.
+                // 
+                xastir_snprintf(header_txt, sizeof(header_txt), "%c%s\r", '\3', devices[port].device_converse_string);
+//fprintf(stderr,"%s\n", header_txt);
+ 
+                if ( (port_data[port].device_type != DEVICE_SERIAL_KISS_TNC)
+                        && (port_data[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+                        && (port_data[port].status == DEVICE_UP)
+                        && (devices[port].transmit_data == 1)
+                        && !transmit_disable
+                        && !posit_tx_disable) {
+                    port_write_string(port,header_txt);
+                }
+                // Delay a bit if the user clicked on the "Add Delay" 
+                // togglebutton in the port's interface properties dialog.  
+                // This is primarily needed for KAM TNCs, which will fail to 
+                // go into converse mode if there is no delay here.
+                if (devices[port].tnc_extra_delay != 0) {
+                    usleep(devices[port].tnc_extra_delay);
+                }
+                break;
+
+            default: /* port has unknown device_type */
+                ok = 0;
+                break;
+
+        } // End of switch
+
+
+        // Set up some more strings for later transmission
+
+        /* send station info */
+        output_cs[0] = '\0';
+        output_phg[0] = '\0';
+        output_alt[0] = '\0';
+        output_brk[0] = '\0';
+
+
+        if (transmit_compressed_posit)
+            xastir_snprintf(my_pos,
+                sizeof(my_pos),
+                "%s",
+                compress_posit(my_output_lat,
+                    my_group,
+                    my_output_long,
+                    my_symbol,
+                    my_last_course,
+                    my_last_speed,  // In knots
+                    my_phg));
+        else { /* standard non compressed mode */
+            xastir_snprintf(my_pos,
+                sizeof(my_pos),
+                "%s%c%s%c",
+                my_output_lat,
+                my_group,
+                my_output_long,
+                my_symbol);
+            /* get PHG, if used for output */
+            if (strlen(my_phg) >= 6)
+                xastir_snprintf(output_phg,
+                    sizeof(output_phg),
+                    "%s",
+                    my_phg);
+
+            /* get CSE/SPD, Always needed for output even if 0 */
+            xastir_snprintf(output_cs,
+                sizeof(output_cs),
+                "%03d/%03d/",
+                my_last_course,
+                my_last_speed);    // Speed in knots
+
+            /* get altitude */
+            if (my_last_altitude_time > 0)
+                xastir_snprintf(output_alt,
+                    sizeof(output_alt),
+                    "A=%06ld/",
+                     my_last_altitude);
+        }
+
+
+        // And set up still more strings for later transmission
+        switch (output_station_type) {
+            case(1):
+                /* APRS_MOBILE LOCAL TIME */
+
+                if((strlen(output_cs) < 8) && (my_last_altitude_time > 0) &&
+		   (strlen(output_alt) > 0)) {
+                    xastir_snprintf(output_brk,
+                        sizeof(output_brk),
+                        "/");
+                }
+
+                day_time = localtime(&sec);
+
+                xastir_snprintf(data_txt_save,
+                    sizeof(data_txt_save),
+                    "@%02d%02d%02d/%s%s%s%s%s",
+                    day_time->tm_mday,
+                    day_time->tm_hour,
+                    day_time->tm_min,
+                    my_pos,
+                    output_cs,
+                    output_brk,
+                    output_alt,
+                    my_comment_tx);
+
+//WE7U2:
+                // Truncate at max length for this type of APRS
+                // packet.
+                if (transmit_compressed_posit) {
+                    if (strlen(data_txt_save) > 61) {
+                        data_txt_save[61] = '\0';
+                    }
+                }
+                else { // Uncompressed lat/long
+                    if (strlen(data_txt_save) > 70) {
+                        data_txt_save[70] = '\0';
+                    }
+                }
+
+                // Add '\r' onto end.
+                strncat(data_txt_save, "\r", 1);
+
+                xastir_snprintf(data_txt,
+                    sizeof(data_txt),
+                    "%s%s",
+                    output_net,
+                    data_txt_save);
+
+                break;
+
+            case(2):
+                /* APRS_MOBILE ZULU DATE-TIME */
+
+                if((strlen(output_cs) < 8) && (my_last_altitude_time > 0) &&
+                   (strlen(output_alt) > 0)) {
+                    xastir_snprintf(output_brk,
+                        sizeof(output_brk),
+                        "/");
+                }
+
+                day_time = gmtime(&sec);
+
+                xastir_snprintf(data_txt_save,
+                    sizeof(data_txt_save),
+                    "@%02d%02d%02dz%s%s%s%s%s",
+                    day_time->tm_mday,
+                    day_time->tm_hour,
+                    day_time->tm_min,
+                    my_pos,
+                    output_cs,
+                    output_brk,
+                    output_alt,
+                    my_comment_tx);
+
+//WE7U2:
+                // Truncate at max length for this type of APRS
+                // packet.
+                if (transmit_compressed_posit) {
+                    if (strlen(data_txt_save) > 61) {
+                        data_txt_save[61] = '\0';
+                    }
+                }
+                else { // Uncompressed lat/long
+                    if (strlen(data_txt_save) > 70) {
+                        data_txt_save[70] = '\0';
+                    }
+                }
+
+                // Add '\r' onto end.
+                strncat(data_txt_save, "\r", 1);
+
+                xastir_snprintf(data_txt,
+                    sizeof(data_txt),
+                    "%s%s",
+                    output_net,
+                    data_txt_save);
+
+                break;
+
+            case(3):
+                /* APRS_MOBILE ZULU TIME w/SEC */
+
+                if((strlen(output_cs) < 8) && (my_last_altitude_time > 0) &&
+                   (strlen(output_alt) > 0)) {
+                    xastir_snprintf(output_brk,
+                        sizeof(output_brk),
+                        "/");
+                }
+
+                day_time = gmtime(&sec);
+
+                xastir_snprintf(data_txt_save,
+                    sizeof(data_txt_save),
+                    "@%02d%02d%02dh%s%s%s%s%s",
+                    day_time->tm_hour,
+                    day_time->tm_min,
+                    day_time->tm_sec,
+                    my_pos,
+                    output_cs,
+                    output_brk,
+                    output_alt,
+                    my_comment_tx);
+
+//WE7U2:
+                // Truncate at max length for this type of APRS
+                // packet.
+                if (transmit_compressed_posit) {
+                    if (strlen(data_txt_save) > 61) {
+                        data_txt_save[61] = '\0';
+                    }
+                }
+                else { // Uncompressed lat/long
+                    if (strlen(data_txt_save) > 70) {
+                        data_txt_save[70] = '\0';
+                    }
+                }
+
+                // Add '\r' onto end.
+                strncat(data_txt_save, "\r", 1);
+
+                xastir_snprintf(data_txt,
+                    sizeof(data_txt),
+                    "%s%s",
+                    output_net,
+                    data_txt_save);
+
+                break;
+
+            case(4):
+                /* APRS position with WX data, no timestamp */
+                sec = wx_tx_data1(wx_data, sizeof(wx_data));
+                if (sec != 0) {
+
+                    xastir_snprintf(data_txt_save,
+                        sizeof(data_txt_save),
+                        "%c%s%s",
+                        aprs_station_message_type,
+                        my_pos,
+                        wx_data);
+
+// WE7U2:
+// There's no limit on the max size for this kind of packet except
+// for the AX.25 limit of 256 bytes!
+                    //
+                    // Truncate at max length for this type of APRS
+                    // packet.  Left the compressed/uncompressed
+                    // "if" statement here in case we need to change
+                    // this in the future due to spec changes.
+                    // Consistent with the rest of the code in this
+                    // function which does similar things.
+                    //
+                    if (transmit_compressed_posit) {
+                        if (strlen(data_txt_save) > 256) {
+                            data_txt_save[256] = '\0';
+                        }
+                    }
+                    else { // Uncompressed lat/long
+                        if (strlen(data_txt_save) > 256) {
+                            data_txt_save[256] = '\0';
+                        }
+                    }
+
+                    // Add '\r' onto end.
+                    strncat(data_txt_save, "\r", 1);
+
+                    xastir_snprintf(data_txt,
+                        sizeof(data_txt),
+                        "%s%s",
+                        output_net,
+                        data_txt_save);
+                }
+                else {
+                    /* default to APRS FIXED if no wx data. No timestamp */
+
+                    if ((strlen(output_phg) < 6) && (my_last_altitude_time > 0) &&
+                        (strlen(output_alt) > 0)) {
+                        xastir_snprintf(output_brk,
+                            sizeof(output_brk),
+                            "/");
+                    }
+
+                    xastir_snprintf(data_txt_save,
+                        sizeof(data_txt_save),
+                        "%c%s%s%s%s%s",
+                        aprs_station_message_type,
+                        my_pos,
+                        output_phg,
+                        output_brk,
+                        output_alt,
+                        my_comment_tx);
+
+// WE7U2:
+                    // Truncate at max length for this type of APRS
+                    // packet.
+                    if (transmit_compressed_posit) {
+                        if (strlen(data_txt_save) > 54) {
+                            data_txt_save[54] = '\0';
+                        }
+                    }
+                    else { // Uncompressed lat/long
+                        if (strlen(data_txt_save) > 63) {
+                            data_txt_save[63] = '\0';
+                        }
+                    }
+
+                    // Add '\r' onto end.
+                    strncat(data_txt_save, "\r", 1);
+
+                    xastir_snprintf(data_txt,
+                        sizeof(data_txt),
+                        "%s%s",
+                        output_net,
+                        data_txt_save);
+                }
+
+                break;
+
+            case(5):
+                /* APRS position with ZULU DATE-TIME and WX data */
+                sec = wx_tx_data1(wx_data,sizeof(wx_data));
+                if (sec != 0) {
+                    day_time = gmtime(&sec);
+
+                    xastir_snprintf(data_txt_save,
+                        sizeof(data_txt_save),
+                        "@%02d%02d%02dz%s%s",
+                        day_time->tm_mday,
+                        day_time->tm_hour,
+                        day_time->tm_min,
+                        my_pos,
+                        wx_data);
+
+// WE7U2:
+                    // Truncate at max length for this type of APRS
+                    // packet.
+                    if (transmit_compressed_posit) {
+                        if (strlen(data_txt_save) > 61) {
+                            data_txt_save[61] = '\0';
+                        }
+                    }
+                    else { // Uncompressed lat/long
+                        if (strlen(data_txt_save) > 70) {
+                            data_txt_save[70] = '\0';
+                        }
+                    }
+
+                    // Add '\r' onto end.
+                    strncat(data_txt_save, "\r", 1);
+
+                    xastir_snprintf(data_txt,
+                        sizeof(data_txt),
+                        "%s%s",
+                        output_net,
+                        data_txt_save);
+                }
+                else {
+                    /* default to APRS FIXED if no wx data */
+
+                    if((strlen(output_phg) < 6) && (my_last_altitude_time > 0) &&
+                       (strlen(output_alt) > 0)) {
+                        xastir_snprintf(output_brk,
+                            sizeof(output_brk),
+                            "/");
+                    }
+
+                    xastir_snprintf(data_txt_save,
+                        sizeof(data_txt_save),
+                        "%c%s%s%s%s%s",
+                        aprs_station_message_type,
+                        my_pos,
+                        output_phg,
+                        output_brk,
+                        output_alt,
+                        my_comment_tx);
+
+// WE7U2:
+                    // Truncate at max length for this type of APRS
+                    // packet.
+                    if (transmit_compressed_posit) {
+                        if (strlen(data_txt_save) > 54) {
+                            data_txt_save[54] = '\0';
+                        }
+                    }
+                    else { // Uncompressed lat/long
+                        if (strlen(data_txt_save) > 63) {
+                            data_txt_save[63] = '\0';
+                        }
+                    }
+
+                    // Add '\r' onto end.
+                    strncat(data_txt_save, "\r", 1);
+
+                    xastir_snprintf(data_txt,
+                        sizeof(data_txt),
+                        "%s%s",
+                        output_net,
+                        data_txt_save);
+                }
+                break;
+
+                /* default to APRS FIXED if no wx data */
+            case(0):
+
+            default:
+                /* APRS_FIXED */
+
+                if ((strlen(output_phg) < 6) && (my_last_altitude_time > 0) &&
+                    (strlen(output_alt) > 0)) {
+                    xastir_snprintf(output_brk,
+                        sizeof(output_brk),
+                        "/");
+                }
+
+                xastir_snprintf(data_txt_save,
+                        sizeof(data_txt_save),
+                        "%c%s%s%s%s%s",
+                        aprs_station_message_type,
+                        my_pos,
+                        output_phg,
+                        output_brk,
+                        output_alt,
+                        my_comment_tx);
+
+// WE7U2:
+                // Truncate at max length for this type of APRS
+                // packet.
+                if (transmit_compressed_posit) {
+                    if (strlen(data_txt_save) > 54) {
+                        data_txt_save[54] = '\0';
+                    }
+                }
+                else { // Uncompressed lat/long
+                    if (strlen(data_txt_save) > 63) {
+                        data_txt_save[63] = '\0';
+                    }
+                }
+
+                // Add '\r' onto end.
+                strncat(data_txt_save, "\r", 1);
+
+                xastir_snprintf(data_txt,
+                        sizeof(data_txt),
+                        "%s%s",
+                        output_net,
+                        data_txt_save);
+
+                break;
+        }
+
+
+//fprintf(stderr,"data_txt_save: %s\n",data_txt_save);
+
+
+        if (ok) {
+            // Here's where the actual transmit of the posit occurs.  The
+            // transmit string has been set up in "data_txt" by this point.
+
+            // If transmit or posits have been turned off, don't transmit posit
+            if ( (port_data[port].status == DEVICE_UP)
+                    && (devices[port].transmit_data == 1)
+                    && !transmit_disable
+                    && !posit_tx_disable) {
+
+                interfaces_ok_for_transmit++;
+
+// WE7U:  Change so that path is passed as well for KISS TNC
+// interfaces:  header_txt_save would probably be the one to pass,
+// or create a new string just for KISS TNC's.
+
+                if ( (port_data[port].device_type == DEVICE_SERIAL_KISS_TNC)
+                        || (port_data[port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+// Note:  This one has callsign & destination in the string
+
+                    // Transmit the posit out the KISS interface
+                    send_ax25_frame(port,
+                                    my_callsign,    // source
+                                    VERSIONFRM,     // destination
+                                    path_txt,       // path
+                                    data_txt);      // data
+                }
+
+//WE7U:AGWPE
+                else if (port_data[port].device_type == DEVICE_NET_AGWPE) {
+
+                    // Set unproto path:  Get next unproto path in
+                    // sequence.
+                    unproto_path = (char *)select_unproto_path(port);
+
+// We need to remove the complete AX.25 header from data_txt before
+// we call this routine!  Instead put the digipeaters into the
+// ViaCall fields.  We do this above by setting output_net to '\0'
+// before creating the data_txt string.
+                    send_agwpe_packet(port,            // Xastir interface port
+                        atoi(devices[port].device_host_filter_string) - 1, // AGWPE RadioPort
+                        '\0',                          // Type of frame
+                        (unsigned char *)my_callsign,  // source
+                        (unsigned char *)VERSIONFRM,   // destination
+                        (unsigned char *)unproto_path, // Path,
+                        (unsigned char *)data_txt,     // Data
+                        strlen(data_txt) - 1);         // Skip \r
+
+//fprintf(stderr,"Sending this string: \n%s\n", data_txt);
+//fprintf(stderr,"Length was %d\n", strlen(data_txt) - 1);
+
+                }
+
+                else {  // Not a Serial KISS TNC interface
+
+//fprintf(stderr,"Sending this string: \n%s\n\n", data_txt);
+
+                    port_write_string(port, data_txt);  // Transmit the posit
+                }
+
+                if (debug_level & 2)
+                    fprintf(stderr,"TX:%d<%s>\n",port,data_txt);
+
+                /* add new line on network data */
+                if (port_data[port].device_type == DEVICE_NET_STREAM) {
+                    xastir_snprintf(data_txt2, sizeof(data_txt2), "\n");                 // Transmit a newline
+                    port_write_string(port, data_txt2);
+                }
+
+
+                // Put our transmitted packet into the Incoming Data
+                // window as well.  This way we can see both sides of a
+                // conversation.  data_port == -1 for x_spider port,
+                // normal interface number otherwise.  -99 to get a "**"
+                // display meaning all ports.
+                //
+                // For packets that we're igating we end up with a CR or
+                // LF on the end of them.  Remove that so the display
+                // looks nice.
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "%s>%s,%s:%s",
+                    my_callsign,
+                    VERSIONFRM,
+                    unproto_path,
+                    data_txt);
+                makePrintable(temp);
+                packet_data_add("TX ", temp, port);
+//fprintf(stderr,"%s\n", temp);
+
+            }
+            else {
+            }
+        } // End of posit transmit: "if (ok)"
+    } // End of big loop
+
+end_critical_section(&devices_lock, "interface.c:output_my_aprs_data" );
+
+
+    // Check the interfaces_ok_for_transmit variable if we're in
+    // emergency_beacon mode.  If we didn't transmit out any interfaces, alert
+    // the operator so that they can either enable interfaces or get emergency
+    // help in some other manner.
+    //
+    if (emergency_beacon) {
+
+        if (interfaces_ok_for_transmit) {
+
+	    // Beacons are going out in emergency beacon mode.  Alert the
+            // operator so that he/she knows they've enabled that mode.
+            //
+            // "Emergency Beacon Mode"
+            // "EMERGENCY BEACON MODE, transmitting every 60 seconds!"
+            popup_message_always( langcode("POPEM00048"),
+                langcode("POPEM00049") );
+        }
+
+        else {  // Emergency beacons are not going out for some reason
+
+            // Notify the operator because emergency_beacon mode is on but
+            // nobody will know it 'cuz there are no interfaces enabled for
+            // transmit.
+            //
+	    // "Warning"
+            // "Interfaces or posits/transmits DISABLED.  Emergency beacons are NOT going out!"
+            popup_message_always( langcode("POPEM00035"),
+                langcode("POPEM00050") );
+        }
+    }
+
+
+    // This will log a posit in the general format for a network interface
+    // whether or not any network interfaces are currently up.
+    if (log_net_data) {
+        xastir_snprintf(data_txt, sizeof(data_txt), "%s>%s,TCPIP*:%s", my_callsign,
+                VERSIONFRM, data_txt_save);
+        log_data( get_user_base_dir(LOGFILE_NET, logfile_tmp_path, 
+                                    sizeof(logfile_tmp_path)), 
+                  (char *)data_txt );
+    }
+
+
+    if (enable_server_port && !transmit_disable && !posit_tx_disable) {
+// Send data to the x_spider server
+
+        xastir_snprintf(data_txt, sizeof(data_txt), "%s>%s,TCPIP*:%s", my_callsign,
+                VERSIONFRM, data_txt_save);
+ 
+        if (writen(pipe_xastir_to_tcp_server,
+                data_txt,
+                strlen(data_txt)) != (int)strlen(data_txt)) {
+            fprintf(stderr,
+                "my_aprs_data: Writen error: %d\n",
+                errno);
+        }
+        // Terminate it with a linefeed
+        if (writen(pipe_xastir_to_tcp_server, "\n", 1) != 1) {
+            fprintf(stderr,
+                "my_aprs_data: Writen error: %d\n",
+                errno);
+        }
+    }
+// End of x_spider server send code
+
+
+    // Note that this will only log one TNC line per transmission now matter
+    // how many TNC's are defined.  It's a representative sample of what we're
+    // sending out.  At least one TNC interface must be enabled in order to
+    // have anything output to the log file here.
+    if (log_tnc_data) {
+        if (header_txt_save[0] != '\0') {
+            xastir_snprintf(data_txt, sizeof(data_txt), "%s%s", header_txt_save, data_txt_save);
+            log_data( get_user_base_dir(LOGFILE_TNC, logfile_tmp_path, 
+                                        sizeof(logfile_tmp_path)), 
+                      (char *)data_txt );
+        }
+    }
+
+//fprintf(stderr,"Data_txt:%s\n", data_txt);
+}
+
+
+
+
+
+//*****************************************************************************
+// output_my_data()
+//
+// 1) Used to send local messages/objects/items.  Cooked mode.
+// 2) Used from output_igate_net(), igating from RF to the 'net.  Raw mode.
+// 3) Used from output_igate_rf() to igate from the 'net to RF.  Cooked mode.
+// 4) Used from output_nws_igate_rf() to send NWS packets out RF.  Cooked mode.
+// 5) Used for queries and responses.  Cooked mode.
+//
+// Parameters:
+// message: the message data to send
+// port: the port transmitting through, or -1 for all
+// type: 0 for my data, 1 for raw data (Cooked/Raw)
+// loopback_only: 0 for transmit/loopback, 1 for loopback only
+// use_igate_path: 0 for standard unproto paths, 1 for igate path
+// path: Set to non-NULL if special path selected for messaging
+//
+// This function sends out messages/objects/bulletins/etc.
+// This one currently tries to do local logging even if
+// transmit is disabled.
+//*****************************************************************************
+void output_my_data(char *message, int incoming_port, int type, int loopback_only, int use_igate_path, char *path) {
+    char data_txt[MAX_LINE_SIZE+5];
+    char data_txt_save[MAX_LINE_SIZE+5];
+    char temp[MAX_LINE_SIZE+5];
+    char path_txt[MAX_LINE_SIZE+5];
+    char *unproto_path = "";
+    char output_net[256];
+    int ok, start, finish, port;
+    int done;
+    char logfile_tmp_path[MAX_VALUE];
+
+    // Check whether transmits are disabled globally
+    if (transmit_disable && !loopback_only) {
+        return;
+    }
+
+    //// cbell- if path is null, strlen/printf segv in solaris
+    if (path == NULL) { 
+        path = ""; 
+    }
+
+    if (debug_level & 1) {
+        fprintf(stderr,
+            "Sending out port: %d, type: %d, path: %s\n",
+            incoming_port,
+            type,
+            path);
+    }
+
+    if (message == NULL)
+        return;
+
+    if (message[0] == '\0')
+        return;
+
+    data_txt_save[0] = '\0';
+
+    if (incoming_port == -1) {   // Send out all of the interfaces
+        start = 0;
+        finish = MAX_IFACE_DEVICES;
+    }
+    else {  // Only send out the chosen interface
+        start  = incoming_port;
+        finish = incoming_port + 1;
+    }
+
+
+begin_critical_section(&devices_lock, "interface.c:output_my_data" );
+
+    for (port = start; port < finish; port++) {
+
+        ok = 1;
+        if (type == 0) {                        // my data
+            switch (port_data[port].device_type) {
+
+//                case DEVICE_NET_DATABASE:
+
+                case DEVICE_NET_AGWPE:
+//fprintf(stderr,"DEVICE_NET_AGWPE\n");
+                    output_net[0] = '\0';   // Clear header
+                    break;
+
+                case DEVICE_NET_STREAM:
+                    if (debug_level & 1)
+                        fprintf(stderr,"%d Net\n",port);
+                    xastir_snprintf(output_net,
+                        sizeof(output_net),
+                        "%s>%s,TCPIP*:",
+                        my_callsign,
+                        VERSIONFRM);
+                    break;
+
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                    if (port_data[port].status == DEVICE_UP && !loopback_only && !transmit_disable) {
+                        port_dtr(port,0);           // make DTR normal (talk to TNC)
+                    }
+
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_AX25_TNC:
+
+                    if (debug_level & 1)
+                        fprintf(stderr,"%d AX25 TNC\n",port);
+                    output_net[0] = '\0';   // clear this for a TNC
+
+                    /* Set my call sign */
+                    xastir_snprintf(data_txt,
+                        sizeof(data_txt),
+                        "%c%s %s\r",
+                        '\3',
+                        "MYCALL",
+                        my_callsign);
+
+                    if ( (port_data[port].device_type != DEVICE_SERIAL_KISS_TNC)
+                            && (port_data[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+                            && (port_data[port].status == DEVICE_UP)
+                            && (devices[port].transmit_data == 1)
+                            && !transmit_disable
+                            && !loopback_only) {
+                        port_write_string(port,data_txt);
+                        usleep(10000);  // 10ms
+                    }
+ 
+                    done = 0;
+ 
+                    // Set unproto path.  First check whether we're
+                    // to use the igate path.  If so and the path
+                    // isn't empty, skip the rest of the path selection:
+                    if ( (use_igate_path)
+                            && (strlen(devices[port].unproto_igate) > 0) ) {
+
+// WE7U:  Should we check here and in the following path
+// selection code to make sure that there are printable characters
+// in the path?  Also:  Output_my_aprs_data() has nearly identical
+// path selection code.  Fix it in one place, fix it in the other.
+
+                        // Check whether igate path is socially
+                        // acceptable.  Output warning if not, but
+                        // still allow the transmit.
+                        if(check_unproto_path(devices[port].unproto_igate)) {
+                            popup_message_always(langcode("WPUPCFT046"),
+                                langcode("WPUPCFT043"));
+                        }
+
+                        xastir_snprintf(data_txt,
+                            sizeof(data_txt),
+                            "%c%s %s VIA %s\r",
+                            '\3',
+                            "UNPROTO",
+                            VERSIONFRM,
+                            devices[port].unproto_igate);
+
+                        xastir_snprintf(data_txt_save,
+                            sizeof(data_txt_save),
+                            "%s>%s,%s:",
+                            my_callsign,
+                            VERSIONFRM,
+                            devices[port].unproto_igate);
+
+                        xastir_snprintf(path_txt,
+                            sizeof(path_txt),
+                            "%s",
+                            devices[port].unproto_igate);
+
+                        done++;
+                    }
+
+
+                    // Check whether a path was passed to us as a
+                    // parameter:
+                    if ( (path != NULL) && (strlen(path) != 0) ) {
+ 
+                        if (strncmp(path, "DIRECT PATH", 11) == 0) {
+                            // The user has requested a direct path
+
+                            xastir_snprintf(data_txt,
+                                sizeof(data_txt),
+                                "%c%s %s\r",
+                                '\3',
+                                "UNPROTO",
+                                VERSIONFRM);
+
+                            xastir_snprintf(data_txt_save,
+                                sizeof(data_txt_save),
+                                "%s>%s:",
+                                my_callsign,
+                                VERSIONFRM);
+                        }
+                        else {
+
+                            xastir_snprintf(data_txt,
+                                sizeof(data_txt),
+                                "%c%s %s VIA %s\r",
+                                '\3',
+                                "UNPROTO",
+                                VERSIONFRM,
+                                path);
+
+                            xastir_snprintf(data_txt_save,
+                                sizeof(data_txt_save),
+                                "%s>%s,%s:",
+                                my_callsign,
+                                VERSIONFRM,
+                                path);
+                        }
+
+                        if (strncmp(path, "DIRECT PATH", 11) == 0) {
+                            // The user has requested a direct path
+                            path_txt[0] = '\0'; // Empty path
+                        }
+                        else {
+                            xastir_snprintf(path_txt,
+                                sizeof(path_txt),
+                                "%s",
+                                path);
+                        }
+
+                        done++;
+
+                        // If "DEFAULT PATH" was passed to us, then
+                        // we're not done yet.
+                        //
+                        if (strncmp(path, "DEFAULT PATH", 12) == 0) {
+                            done = 0;
+                        }
+                    }
+
+                    if (!done) {
+
+                        // Set unproto path:  Get next unproto path
+                        // in sequence.
+                        unproto_path = (char *)select_unproto_path(port);
+
+                        xastir_snprintf(data_txt,
+                            sizeof(data_txt),
+                            "%c%s %s VIA %s\r",
+                            '\3',
+                            "UNPROTO",
+                            VERSIONFRM,
+                            unproto_path);
+
+                        xastir_snprintf(data_txt_save,
+                            sizeof(data_txt_save),
+                            "%s>%s,%s:",
+                            my_callsign,
+                            VERSIONFRM,
+                            unproto_path);
+
+                        xastir_snprintf(path_txt,
+                            sizeof(path_txt),
+                            "%s",
+                            unproto_path);
+
+                        done++;
+                    }
+
+
+                    if ( (port_data[port].device_type != DEVICE_SERIAL_KISS_TNC)
+                            && (port_data[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+                            && (port_data[port].status == DEVICE_UP)
+                            && (devices[port].transmit_data == 1)
+                            && !transmit_disable
+                            && !loopback_only) {
+                        port_write_string(port,data_txt);
+                        usleep(10000);  // 10ms
+                    }
+ 
+                    // Set converse mode.  One european TNC
+                    // (tnc2-ui) doesn't accept "conv" but does
+                    // accept the 'k' command.  A Kantronics  KPC-2
+                    // v2.71 TNC accepts the "conv" command but not
+                    // the 'k' command.  Figures!
+                    //
+//                    xastir_snprintf(data_txt, sizeof(data_txt), "%c%s\r", '\3', "CONV");
+//                    xastir_snprintf(data_txt, sizeof(data_txt), "%c%s\r", '\3', "k");
+//                    xastir_snprintf(data_txt, sizeof(data_txt), "%c%s\r", '\3', CONVERSE_MODE);
+                    xastir_snprintf(data_txt, sizeof(data_txt), "%c%s\r", '\3', devices[port].device_converse_string);
+
+
+
+                    if ( (port_data[port].device_type != DEVICE_SERIAL_KISS_TNC)
+                            && (port_data[port].device_type != DEVICE_SERIAL_MKISS_TNC)
+                            && (port_data[port].status == DEVICE_UP)
+                            && (devices[port].transmit_data == 1)
+                            && !transmit_disable
+                            && !loopback_only) {
+                        port_write_string(port,data_txt);
+                        usleep(20000); // 20ms
+                    }
+                    break;
+
+                default: /* unknown */
+                    ok = 0;
+                    break;
+            } // End of switch
+        } else {    // Type == 1, raw data.  Probably igating something...
+            output_net[0] = '\0';
+        }
+
+
+        if (ok) {
+            /* send data */
+            xastir_snprintf(data_txt, sizeof(data_txt), "%s%s\r", output_net, message);
+
+//fprintf(stderr,"%s\n",data_txt);
+
+            if ( (port_data[port].status == DEVICE_UP)
+                    && (devices[port].transmit_data == 1)
+                    && !transmit_disable
+                    && !loopback_only) {
+
+// WE7U:  Change so that path is passed as well for KISS TNC
+// interfaces:  data_txt_save would probably be the one to pass,
+// or create a new string just for KISS TNC's.
+
+                if ( (port_data[port].device_type == DEVICE_SERIAL_KISS_TNC)
+                        || (port_data[port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+                    // Transmit
+                    send_ax25_frame(port,
+                                    my_callsign,    // source
+                                    VERSIONFRM,     // destination
+                                    path_txt,       // path
+                                    data_txt);      // data
+                }
+
+//WE7U:AGWPE
+                else if (port_data[port].device_type == DEVICE_NET_AGWPE) {
+
+                    // Set unproto path.  First check whether we're
+                    // to use the igate path.  If so and the path
+                    // isn't empty, skip the rest of the path selection:
+                    if ( (use_igate_path)
+                            && (strlen(devices[port].unproto_igate) > 0) ) {
+
+                        // Check whether igate path is socially
+                        // acceptable.  Output warning if not, but
+                        // still allow the transmit.
+                        if(check_unproto_path(devices[port].unproto_igate)) {
+                            popup_message_always(langcode("WPUPCFT046"),
+                                langcode("WPUPCFT043"));
+                        }
+
+                        xastir_snprintf(path_txt,
+                            sizeof(path_txt),
+                            "%s",
+                            devices[port].unproto_igate);
+                    }
+                    // Check whether a path was passed to us as a
+                    // parameter:
+                    else if ( (path != NULL) && (strlen(path) != 0) ) {
+
+                        if (strncmp(path, "DEFAULT PATH", 12) == 0) {
+                            unproto_path = (char *)select_unproto_path(port);
+
+//fprintf(stderr,"unproto_path: %s\n", unproto_path);
+                            xastir_snprintf(path_txt,
+                                sizeof(path_txt),
+                                "%s",
+                                unproto_path);
+                        }
+
+                        else if (strncmp(path, "DIRECT PATH", 11) == 0) {
+                            // The user has requested a direct path
+                            path_txt[0] = '\0'; // Empty string
+
+// WE7U
+// TEST THIS TO SEE IF IT WORKS ON AGWPE TO HAVE NO PATH
+
+                        }
+                        else {
+                            xastir_snprintf(path_txt,
+                                sizeof(path_txt),
+                                "%s",
+                                path);
+                        }
+                    }
+                    else {
+                        // Set unproto path:  Get next unproto path in
+                        // sequence.
+
+                        unproto_path = (char *)select_unproto_path(port);
+
+//fprintf(stderr,"unproto_path: %s\n", unproto_path);
+                        xastir_snprintf(path_txt,
+                            sizeof(path_txt),
+                            "%s",
+                            unproto_path);
+                    }
+//fprintf(stderr,"path_txt: %s\n", path_txt);
+ 
+
+// We need to remove the complete AX.25 header from data_txt before
+// we call this routine!  Instead put the digipeaters into the
+// ViaCall fields.  We do this above by setting output_net to '\0'
+// before creating the data_txt string.
+
+//fprintf(stderr,"send_agwpe_packet\n");
+
+                    send_agwpe_packet(port,           // Xastir interface port
+                        atoi(devices[port].device_host_filter_string) - 1, // AGWPE RadioPort
+                        '\0',                         // Type of frame
+                        (unsigned char *)my_callsign, // source
+                        (unsigned char *)VERSIONFRM,  // destination
+                        (unsigned char *)path_txt,    // Path,
+                        (unsigned char *)data_txt,    // Data
+                        strlen(data_txt) - 1);        // Skip \r
+                }
+
+                else {  // Not a Serial KISS TNC interface
+
+//fprintf(stderr,"Sending this string: %s\n", data_txt);
+
+                   port_write_string(port, data_txt);  // Transmit
+                }
+
+                if (debug_level & 1)
+                    fprintf(stderr,"Sending to interface:%d, %s\n",
+                        port,
+                        data_txt);
+
+
+                // Put our transmitted packet into the Incoming Data
+                // window as well.  This way we can see both sides of a
+                // conversation.  data_port == -1 for x_spider port,
+                // normal interface number otherwise.  -99 to get a "**"
+                // display meaning all ports.
+                //
+                // For packets that we're igating we end up with a CR or
+                // LF on the end of them.  Remove that so the display
+                // looks nice.
+                //
+                // Check whether a path was passed to us as a
+                // parameter:
+
+                if ( (path != NULL) && (strlen(path) != 0) ) {
+
+                    if (strncmp(path, "DEFAULT PATH", 12) == 0) {
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "%s>%s,%s:%s",
+                            my_callsign,
+                            VERSIONFRM,
+                            unproto_path,
+                            message);
+                    }
+                    else if (strncmp(path, "DIRECT PATH", 11) == 0) {
+                        // The user has requested a direct path
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "%s>%s:%s",
+                            my_callsign,
+                            VERSIONFRM,
+                            message);
+                    }
+                    else {
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "%s>%s,%s:%s",
+                            my_callsign,
+                            VERSIONFRM,
+                            path,
+                            message);
+                    }
+                }
+                else {
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "%s>%s,%s:%s",
+                        my_callsign,
+                        VERSIONFRM,
+                        unproto_path,
+                        message);
+                }
+                makePrintable(temp);
+                packet_data_add("TX ", temp, port);
+//fprintf(stderr,"%s\n", temp);
+
+            }
+
+            if (debug_level & 2)
+                fprintf(stderr,"TX:%d<%s>\n",port,data_txt);
+
+            /* add newline on network data */
+            if (port_data[port].device_type == DEVICE_NET_STREAM) {
+                xastir_snprintf(data_txt, sizeof(data_txt), "\n");
+
+                if ( (port_data[port].status == DEVICE_UP)
+                        && (devices[port].transmit_data == 1)
+                        && !transmit_disable
+                        && !loopback_only) {
+                    port_write_string(port,data_txt);
+                }
+            }
+            else {
+            }
+        }
+//        if (incoming_port != -1)
+//            port = MAX_IFACE_DEVICES+1;    // process only one port
+    }
+
+end_critical_section(&devices_lock, "interface.c:output_my_data" );
+
+    // This will log a posit in the general format for a network interface
+    // whether or not any network interfaces are currently up.
+    xastir_snprintf(data_txt, sizeof(data_txt), "%s>%s,TCPIP*:%s", my_callsign,
+            VERSIONFRM, message);
+    if (debug_level & 2)
+        fprintf(stderr,"output_my_data: Transmitting and decoding: %s\n", data_txt);
+
+    if (log_net_data)
+      log_data( get_user_base_dir(LOGFILE_NET, logfile_tmp_path, 
+                                  sizeof(logfile_tmp_path)), 
+                (char *)data_txt );
+
+
+    // Note that this will only log one TNC line per transmission now matter
+    // how many TNC's are defined.  It's a representative sample of what we're
+    // sending out.  At least one TNC interface must be enabled in order to
+    // have anything output to the log file here.
+    if (data_txt_save[0] != '\0') {
+        xastir_snprintf(data_txt, sizeof(data_txt), "%s%s", data_txt_save, message);
+        if (log_tnc_data)
+            log_data( get_user_base_dir(LOGFILE_TNC, logfile_tmp_path, 
+                                  sizeof(logfile_tmp_path)), 
+                      (char *)data_txt );
+    }
+
+
+    if (enable_server_port && !loopback_only && !transmit_disable) {
+// Send data to the x_spider server
+
+        if (type == 0) {    // My data, add a header
+            xastir_snprintf(data_txt,
+                sizeof(data_txt),
+                "%s>%s,TCPIP*:%s",
+                my_callsign,
+                VERSIONFRM,
+                message);
+        }
+        else {  // Not my data, don't add a header
+            xastir_snprintf(data_txt,
+                sizeof(data_txt),
+                "%s",
+                message);
+        }
+
+//fprintf(stderr,"To 2023:%s", data_txt);
+//fprintf(stderr,"\tport:%d  type:%d  loopback_only:%d use_igate_path:%d\n",
+//    incoming_port, type, loopback_only, use_igate_path);
+
+        if (writen(pipe_xastir_to_tcp_server,
+                data_txt,
+                strlen(data_txt)) != (int)strlen(data_txt)) {
+            fprintf(stderr,
+                "output_my_data: Writen error: %d\n",
+                errno);
+        }
+        // Terminate it with a linefeed
+        if (writen(pipe_xastir_to_tcp_server, "\n", 1) != 1) {
+            fprintf(stderr,
+                "output_my_data: Writen error: %d\n",
+                errno);
+        }
+    }
+// End of x_spider server send code
+
+
+    // Decode our own transmitted packets.
+    // Note that this function call is destructive to the first parameter.
+    // This is why we call it _after_ we call the log_data functions.
+    //
+    // This must be the "L" packet we see in the View->Messages
+    // dialog.  We don't see a "T" packet (for TNC) and we only see
+    // "I" packets if we re-receive our own packet from the internet
+    // feeds.
+    if (incoming_port == -1) {   // We were sending to all ports
+        // Pretend we received it from port 1
+//fprintf(stderr,"output_my_data 1:%s\n", data_txt);
+        decode_ax25_line( data_txt, DATA_VIA_LOCAL, 1, 1);
+    }
+    else {  // We were sending to a specific port
+//fprintf(stderr,"output_my_data 2:%s\n", data_txt);
+        decode_ax25_line( data_txt, DATA_VIA_LOCAL, incoming_port, 1);
+    }
+
+//fprintf(stderr,"Data_txt:%s\n", data_txt);
+}
+
+
+
+
+
+//*****************************************************************************
+// output_waypoint_data()
+//
+// message: the message data to send
+//
+// This function sends out waypoint creation strings to GPS
+// interfaces capable of dealing with it.
+//
+//*****************************************************************************
+void output_waypoint_data(char *message) {
+    char data_txt[MAX_LINE_SIZE+5];
+    char data_txt_save[MAX_LINE_SIZE+5];
+    int ok, start, finish, i;
+
+    if (message == NULL)
+        return;
+
+    if (message[0] == '\0')
+        return;
+ 
+    if (debug_level & 1)
+        fprintf(stderr,"Sending to GPS interfaces: %s\n", message);
+
+    data_txt_save[0] = '\0';
+
+    start = 0;
+    finish = MAX_IFACE_DEVICES;
+
+begin_critical_section(&devices_lock, "interface.c:output_waypoint_data" );
+
+    for (i = start; i < finish; i++) {
+        ok = 1;
+        switch (port_data[i].device_type) {
+
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+                port_dtr(i,1);   // make DTR active (select GPS)
+                break;
+
+            case DEVICE_SERIAL_GPS:
+                break;
+
+            default: /* unknown */
+                ok = 0;
+                break;
+        } // End of switch
+
+        if (ok) {   // Found a GPS interface
+            /* send data */
+            xastir_snprintf(data_txt, sizeof(data_txt), "%s\r\n", message);
+
+            if (port_data[i].status == DEVICE_UP) {
+                port_write_string(i,data_txt);
+                usleep(250000);    // 0.25 secs
+ 
+                if (debug_level & 1)
+                    fprintf(stderr,"Sending to interface:%d, %s\n",i,data_txt);
+            }
+
+            if (debug_level & 2)
+                fprintf(stderr,"TX:%d<%s>\n",i,data_txt);
+
+            if (port_data[i].device_type == DEVICE_SERIAL_TNC_HSP_GPS) {
+                port_dtr(i,0);  // make DTR inactive (select TNC data)
+            }
+        }
+    }
+
+end_critical_section(&devices_lock, "interface.c:output_waypoint_data" );
+
+}
+
+
+
+
+
+// Added by KB6MER for KAM XL(SERIAL_TNC_AUX_GPS) support
+// buf is a null terminated string
+// returns buf as a null terminated string after cleaning.
+// Currently:
+//    removes leading 'cmd:' prompts from TNC if needed
+// Can be used to add any additional data cleaning functions desired.
+// Currently only called for SERIAL_TNC_AUX_GPS, but could be added
+// to other device routines to improve packet decode on other devices.
+//
+// Note that the length of "buf" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+void tnc_data_clean(char *buf) {
+
+    if (debug_level & 1) {
+        char filtered_data[MAX_LINE_SIZE+1];
+
+        // strncpy is ok here as long as nulls not in data.  We
+        // null-terminate it ourselves to make sure it is terminated.
+        strncpy(filtered_data, buf, MAX_LINE_SIZE);
+        filtered_data[MAX_LINE_SIZE] = '\0';    // Terminate it
+
+        makePrintable(filtered_data);
+        fprintf(stderr,"tnc_data_clean: called to clean %s\n", filtered_data);
+    }
+
+    while (!strncmp(buf,"cmd:",4)) {
+        int ii;
+
+        // We're _shortening_ the string here, so we don't need to
+        // know the length of the buffer unless it has no '\0'
+        // terminator to begin with!  In that one case we could run
+        // off the end of the string and get a segfault or cause
+        // other problems.
+        for (ii = 0; ; ii++) {
+            buf[ii] = buf[ii+4];
+            if (buf[ii] == '\0')
+                break;
+        }
+    }
+
+    if (debug_level & 1) {
+        char filtered_data[MAX_LINE_SIZE+1];
+
+        // Binary routine.  strncpy is ok here as long as nulls not
+        // in data.  We null-terminate it ourselves to make sure it
+        // is terminated.
+        strncpy(filtered_data, buf, MAX_LINE_SIZE);
+        filtered_data[MAX_LINE_SIZE] = '\0';    // Terminate it
+
+        makePrintable(filtered_data);
+        fprintf(stderr,"tnc_data_clean: clean result %s\n", filtered_data);
+    }
+}
+
+
+
+
+
+// Added by KB6MER for KAM XL (SERIAL_TNC_AUX_GPS) support
+// buf is a null terminated string.
+// port is integer offset into port_data[] array of iface data (see interface.h)
+// returns int 0=AX25, 1=GPS
+// Tries to guess from the contents of buf whether it represents data from
+// the GPS or data from an AX25 packet.
+//
+// Note that the length of "buf" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+int tnc_get_data_type(char *buf, int port) {
+    register int i;
+    int type=1;      // Don't know what it is yet.  Assume NMEA for now.
+
+    if (debug_level & 1) {
+        char filtered_data[MAX_LINE_SIZE+1];
+
+        // Binary routine.  strncpy is ok here as long as nulls not
+        // in data.  We null-terminate it ourselves to make sure it
+        // is terminated.
+        strncpy(filtered_data, buf, MAX_LINE_SIZE);
+        filtered_data[MAX_LINE_SIZE] = '\0';    // Terminate it
+
+        makePrintable(filtered_data);
+        fprintf(stderr,"tnc_get_data_type: parsing %s\n", filtered_data);
+    }
+
+    // First, let's look for NMEA-ish things.
+    if (buf[0]=='$') {
+        //This looks kind of NMEA-ish, let's check for known message type
+        //headers ($P[A-Z][A-Z][A-Z][A-Z] or $GP[A-Z][A-Z][A-Z])
+        if(buf[1]=='P') {
+            for(i=2; i<=5; i++) {
+                if (buf[i]<'A' || buf[i]>'Z') {
+                    type=0; // Disqualified, not valid NMEA-0183
+                    if (debug_level & 1) {
+                        char filtered_data[MAX_LINE_SIZE+1];
+
+                        // Binary routine.  strncpy is ok here as
+                        // long as nulls not in data.  We
+                        // null-terminate it ourselves to make
+                        // sure it is terminated.
+                        strncpy(filtered_data, buf, MAX_LINE_SIZE);
+                        filtered_data[MAX_LINE_SIZE] = '\0';    // Terminate it
+
+                        makePrintable(filtered_data);
+                        fprintf(stderr,"tnc_get_data_type: Not NMEA %s\n",
+                            filtered_data);
+                    }
+                }
+            }
+        }
+        else if(buf[1]=='G' && buf[2]=='P') {
+            for(i=3; i<=5; i++) {
+                if (buf[i]<'A' || buf[i]>'Z') {
+                    type=0; // Disqualified, not valid NMEA-0183
+                    if (debug_level & 1) {
+                        char filtered_data[MAX_LINE_SIZE+1];
+
+                        // Binary routine.  strncpy is ok here as
+                        // long as nulls not in data.  We
+                        // null-terminate it ourselves to make
+                        // sure it is terminated.
+                        strncpy(filtered_data, buf, MAX_LINE_SIZE);
+                        filtered_data[MAX_LINE_SIZE] = '\0';    // Terminate it
+
+                        makePrintable(filtered_data);
+                        fprintf(stderr,"tnc_get_data_type: Not NMEA %s\n",
+                            filtered_data);
+                    }
+                }
+            }
+        }
+    }
+    else {  // Must be APRS data
+        type = 0;
+    }
+
+    if (debug_level & 1) {
+        if (type == 0)
+            fprintf(stderr,"APRS data\n");
+        else
+            fprintf(stderr,"NMEA data\n");
+    }
+
+    return(type);
+}
+
+
diff --git a/src/interface.h b/src/interface.h
new file mode 100644
index 0000000..7a948de
--- /dev/null
+++ b/src/interface.h
@@ -0,0 +1,276 @@
+/*
+ * $Id: interface.h,v 1.48 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef __XASTIR_INTERFACE_H
+#define __XASTIR_INTERFACE_H
+
+#include <termios.h>
+#include <unistd.h>
+#include "util.h"
+#include "xastir.h"
+
+
+#define MAX_DEVICE_NAME 128
+#define MAX_DEVICE_BUFFER 4096
+#define MAX_DEVICE_BUFFER_UNTIL_BINARY_SWITCH 700
+#define MAX_DEVICE_HOSTNM 40
+#define MAX_DEVICE_HOSTPW 40
+
+#define MAX_IFACE_DEVICES 15
+
+#define NET_CONNECT_TIMEOUT 20
+
+#define DEFAULT_GPS_RETR 0x05 /* CTRL-E */
+
+// Define a 60 second max wait on a serial port (in microseconds)
+#define SERIAL_MAX_WAIT 60000000
+
+// KISS Protocol Special Characters & Commands:
+#define KISS_FEND           0xc0  // Frame End
+#define KISS_FESC           0xdb  // Frame Escape
+#define KISS_TFEND          0xdc  // Transposed Frame End
+#define KISS_TFESC          0xdd  // Transposed Frame Escape
+#define KISS_DATA           0x00
+#define KISS_TXDELAY        0x01
+#define KISS_PERSISTENCE    0x02
+#define KISS_SLOTTIME       0x03
+#define KISS_TXTAIL         0x04
+#define KISS_FULLDUPLEX     0x05
+#define KISS_SETHARDWARE    0x06
+#define KISS_RETURN         0xff
+
+
+
+#define MAX_IFACE_DEVICE_TYPES 15
+
+/* Define Device Types */
+enum Device_Types {
+    DEVICE_NONE,
+    DEVICE_SERIAL_TNC,
+    DEVICE_SERIAL_TNC_HSP_GPS,
+    DEVICE_SERIAL_GPS,
+    DEVICE_SERIAL_WX,
+    DEVICE_NET_STREAM,
+    DEVICE_AX25_TNC,
+    DEVICE_NET_GPSD,
+    DEVICE_NET_WX,
+    DEVICE_SERIAL_TNC_AUX_GPS,  // KB6MER -> KAM XL or other TNC w/GPS on AUX port
+    DEVICE_SERIAL_KISS_TNC,     // KISS TNC on serial port (not ax.25 kernel device)
+    DEVICE_NET_DATABASE,
+    DEVICE_NET_AGWPE,
+    DEVICE_SERIAL_MKISS_TNC,    // Multi-port KISS TNC, like the Kantronics KAM
+    DEVICE_SQL_DATABASE         // SQL server (MySQL/Postgis) database
+};
+
+enum Device_Active {
+    DEVICE_NOT_IN_USE,
+    DEVICE_IN_USE
+};
+
+enum Device_Status {
+    DEVICE_DOWN,
+    DEVICE_UP,
+    DEVICE_ERROR
+};
+
+
+typedef struct {
+    int    device_type;                           /* device type                             */
+    int    active;                                /* channel in use                          */
+    int    status;                                /* current status (up or down)             */
+    char   device_name[MAX_DEVICE_NAME+1];        /* device name                             */
+    char   device_host_name[MAX_DEVICE_HOSTNM+1]; /* device host name for network            */
+    unsigned long int address;                    /* socket address for network              */
+    int    thread_status;                         /* thread status for connect thread        */
+    int    connect_status;                        /* connect status for connect thread       */
+    int    decode_errors;                         /* decode error count, used for data type  */
+    int    data_type;                             /* 0=normal 1=wx_binary                    */
+    int    socket_port;                           /* socket port# for network                */
+    char   device_host_pswd[MAX_DEVICE_HOSTPW+1]; /* host password                           */
+    int    channel;                               /* for serial and net ports                */
+    int    channel2;                              /* for AX25 ports                          */
+    char   ui_call[30];                           /* current call for this port              */
+    struct termios t,t_old;                       /* terminal struct for serial port         */
+    int    dtr;                                   /* dtr signal for HSP cable (status)       */
+    int    sp;                                    /* serial port speed                       */
+    int    style;                                 /* serial port style                       */
+    int    scan;                                  /* data read available                     */
+    int    errors;                                /* errors for this port                    */
+    int    reconnect;                             /* reconnect on net failure                */
+    int    reconnects;                            /* total number of reconnects by this port */
+    unsigned long   bytes_input;                  /* total bytes read by this port           */
+    unsigned long   bytes_output;                 /* total bytes written by this port        */
+    unsigned long   bytes_input_last;             /* total bytes read last check             */
+    unsigned long   bytes_output_last;            /* total bytes read last check             */
+    int    port_activity;                         /* 0 if no activity between checks         */
+    pthread_t read_thread;                        /* read thread                             */
+    int    read_in_pos;                           /* current read buffer input pos           */
+    int    read_out_pos;                          /* current read buffer output pos          */
+    char   device_read_buffer[MAX_DEVICE_BUFFER]; /* read buffer for this port               */
+    xastir_mutex read_lock;                       /* Lock for reading the port data          */
+    pthread_t write_thread;                       /* write thread                            */
+    int    write_in_pos;                          /* current write buffer input pos          */
+    int    write_out_pos;                         /* current write buffer output pos         */
+    xastir_mutex write_lock;                      /* Lock for writing the port data          */
+    char   device_write_buffer[MAX_DEVICE_BUFFER];/* write buffer for this port              */
+} iface;
+
+typedef struct {
+    char device_name[100];
+} iodevices;
+
+
+typedef struct {
+    int    device_type;                           /* device type                             */
+    char   device_name[MAX_DEVICE_NAME+1];        /* device name                             */
+    char   radio_port[3];                         /* port for multi-port TNC's               */
+    char   device_host_name[MAX_DEVICE_HOSTNM+1]; /* device host name for network            */
+    char   device_host_pswd[MAX_DEVICE_HOSTPW+1]; /* host password also WX device data type  */
+    char   device_host_filter_string[201];        /* host filter string                      */
+    char   device_converse_string[10+1];          /* string used to enter converse mode      */
+    char   comment[50];                           /* Local comment or name for port          */
+    char   unproto1[50];                          /* unproto path 1 for this port            */
+    char   unproto2[50];                          /* unproto path 2 for this port            */
+    char   unproto3[50];                          /* unproto path 3 for this port            */
+    char   unproto_igate[50];                     /* unproto igate path for this port        */
+    int    unprotonum;                            /* unproto path selection                  */
+    char   tnc_up_file[100];                      /* file for setting up TNC on this port    */
+    char   tnc_down_file[100];                    /* file for shutting down TNC on this port */
+    int    sp;                                    /* serial port speed/Net port              */
+    int    style;                                 /* serial port style                       */
+    int    igate_options;                         /* Igate options (0=none,1=input,2=in/out) */
+    int    transmit_data;                         /* Data transmit out of this port          */
+    int    reconnect;                             /* reconnect on net failure                */
+    int    connect_on_startup;                    /* connect to this device on startup       */
+    int    gps_retrieve;                          /* Character to cause SERIAL_TNC_AUX_GPS to spit out current GPS data */
+    int    tnc_extra_delay;                       /* Introduces fixed delay when talking to TNC in command-mode */
+    int    set_time;                              /* Set System Time from GPS on this port   */
+    char   txdelay[4];                            /* KISS parameter */
+    char   persistence[4];                        /* KISS parameter */
+    char   slottime[4];                           /* KISS parameter */
+    char   txtail[4];                             /* KISS parameter */
+    int    fullduplex;                            /* KISS parameter */
+    int    relay_digipeat;                        /* If 1: interface should RELAY digipeat */
+    int    init_kiss;				              /* Initialize KISS-Mode on startup */
+#ifdef HAVE_DB
+    // to support connections to sql server databases for db_gis.c 
+    char   database_username[20];                 /* Username to use to connect to database  */
+    int    database_type;                         /* Type of dbms (posgresql, mysql, etc)    */
+    char   database_schema[20];                   /* Name of database or schema to use       */
+    char   database_errormessage[255];            /* Most recent error message from 
+                                                     attempting to make a 
+                                                     connection with using this descriptor.  */
+    int    database_schema_type;                  /* table structures to use in the database
+                                                     A database schema could contain both 
+                                                     APRSWorld and XASTIR table structures, 
+                                                     but a separate database descriptor
+                                                     needs to be defined for each.  */
+    char   database_unix_socket[255];             /* MySQL - unix socket parameter (path and 
+                                                     filename) */
+    // Need a pointer here, and one in connection pointing back here.  How to do????
+    //Connection *database_connection;              
+                                                  /* Pointer to database connection that
+                                                     contains database handle (with type 
+                                                     of handle being dependent on type of 
+                                                     database.  */
+    int    query_on_startup;                      /* Load stations from this database on 
+                                                     startup. */
+    // Use of other ioparam variables for sql server database connections:  
+    // device_host_name = hostname for database server 
+    // sp = port on which to connect to database server 
+    // device_host_pswd =  password to use to connect to database -- security issue needs to be addressed
+#endif  // HAVE_DB
+} ioparam;
+
+
+extern iodevices dtype[];
+
+extern xastir_mutex port_data_lock; // Protects the port_data[] array of structs
+extern xastir_mutex devices_lock;    // Protects the devices[] array
+
+extern iface port_data[];
+extern int port_id[];
+extern int get_device_status(int port);
+extern int del_device(int port);
+extern int get_open_device(void);
+extern int add_device(int port_avail,int dev_type,
+               char *dev_nm,
+               char *passwd,
+               int dev_sck_p, int dev_sp,
+               int dev_sty,
+               int reconnect,
+               char *filter_string);
+
+extern xastir_mutex data_lock;          // Protects incoming_data_queue
+extern xastir_mutex output_data_lock;   // Protects interface.c:channel_data() function only
+extern xastir_mutex connect_lock;       // Protects port_data[].thread_status and port_data[].connect_status
+
+extern ioparam devices[];
+
+#if !HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif
+
+/* from interface_gui.c */
+extern void interface_gui_init(void);
+extern void Configure_interface_destroy_shell(Widget widget, XtPointer clientData, XtPointer callData);
+extern void Configure_interface(Widget w, XtPointer clientData, XtPointer callData);
+extern void output_my_aprs_data(void);
+extern void control_interface(Widget w, XtPointer clientData, XtPointer callData);
+extern void dtr_all_set(int dtr);
+extern void interface_status(Widget w);
+extern void update_interface_list(void);
+extern int WX_rain_gauge_type;
+
+/* interface.c */
+extern int is_local_interface(int port);
+extern int is_network_interface(int port);
+extern void send_agwpe_packet(int xastir_interface, int RadioPort, unsigned char type, unsigned char *FromCall, unsigned char *ToCall, unsigned char *Path, unsigned char *Data, int length);
+
+extern int pop_incoming_data(unsigned char *data_string, int *port);
+extern int push_incoming_data(unsigned char *data_string, int length, int port);
+
+extern unsigned char incoming_data_copy[MAX_LINE_SIZE];
+extern unsigned char incoming_data_copy_previous[MAX_LINE_SIZE];
+extern int NETWORK_WAITTIME;
+extern void startup_all_or_defined_port(int port);
+extern void shutdown_all_active_or_defined_port(int port);
+extern void check_ports(void);
+extern void clear_all_port_data(void);
+extern char aprs_station_message_type;
+extern void port_dtr(int port, int dtr);
+extern void send_kiss_config(int port, int device, int command, int value);
+void port_write_string(int port, char *data);
+extern void init_device_names(void);
+extern void output_my_data(char *message, int port, int type, int loopback_only, int use_igate_path, char *path);
+int tnc_get_data_type(char *buf, int port);
+void tnc_data_clean(char *buf);
+extern void output_waypoint_data(char *message);
+extern void send_ax25_frame(int port, char *source, char *destination, char *path, char *data);
+
+extern pid_t getpgid(pid_t pid);
+
+
+#endif /* XASTIR_INTERFACE_H */
+
diff --git a/src/interface_gui.c b/src/interface_gui.c
new file mode 100644
index 0000000..cbbd16f
--- /dev/null
+++ b/src/interface_gui.c
@@ -0,0 +1,9146 @@
+/*
+ * $Id: interface_gui.c,v 1.127 2012/10/22 23:59:55 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "xa_config.h"
+#include "interface.h"
+#include "wx.h"
+#include "draw_symbols.h"
+#include "util.h"
+#include "db_gis.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+// lesstif (at least as of version 0.94 in 2008), doesn't
+// have full implementation of combo boxes.
+#ifndef USE_COMBO_BOX
+#if (XmVERSION >= 2 && !defined(LESSTIF_VERSION))
+#  define USE_COMBO_BOX 1
+#endif
+#endif  // USE_COMBO_BOX
+
+Widget configure_interface_dialog = NULL;
+Widget choose_interface_dialog = NULL;
+Widget interface_type_list = NULL;
+Widget control_interface_dialog = NULL;
+Widget control_iface_list = NULL;
+
+
+static xastir_mutex control_interface_dialog_lock;
+
+ioparam devices[MAX_IFACE_DEVICES];
+xastir_mutex devices_lock;
+
+void Choose_interface_destroy_shell(Widget widget, XtPointer clientData, XtPointer callData);
+void modify_device_list(int option, int port);
+
+
+
+
+
+void interface_gui_init(void)
+{
+    init_critical_section( &control_interface_dialog_lock );
+    init_critical_section( &devices_lock );
+}
+
+
+
+
+
+/*****************************************************/
+/* Universal Serial GUI                              */
+/*****************************************************/
+int device_speed;
+int device_style;
+int device_igate_options;
+int device_data_type;
+
+
+
+
+
+void speed_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    if (state->set)
+        device_speed = atoi(which);
+    else
+        device_speed = 0;
+}
+
+
+
+
+
+void style_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        device_style = atoi(which);
+    else
+        device_style = 0;
+}
+
+
+
+
+
+void data_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        device_data_type = atoi(which);
+    else
+        device_data_type = 0;
+}
+
+
+
+
+
+void rain_gauge_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        WX_rain_gauge_type = atoi(which);
+    else
+        WX_rain_gauge_type = 0;
+}
+
+
+
+
+
+void igate_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        device_igate_options = atoi(which);
+    else
+        device_igate_options = 0;
+}
+
+
+
+
+
+void set_port_speed(int port) {
+
+    switch (device_speed){
+        case(1):
+            devices[port].sp=B300;
+            break;
+
+        case(2):
+            devices[port].sp=B1200;
+            break;
+
+        case(3):
+            devices[port].sp=B2400;
+            break;
+
+        case(4):
+            devices[port].sp=B4800;
+            break;
+
+        case(5):
+            devices[port].sp=B9600;
+            break;
+
+        case(6):
+            devices[port].sp=B19200;
+            break;
+
+        case(7):
+            devices[port].sp=B38400;
+            break;
+
+#ifndef __LSB__
+        case(8):
+            devices[port].sp=B57600;
+            break;
+
+        case(9):
+            devices[port].sp=B115200;
+            break;
+
+        case(10):
+#ifndef B230400
+            devices[port].sp=B115200;
+#else   // B230400
+            devices[port].sp=B230400;
+#endif  // B230400
+            break;
+#endif  // __LSB__
+
+        default:
+            break;
+    }
+}
+
+
+
+
+
+
+
+/*****************************************************/
+/* Configure Serial TNC GUI                          */
+/*****************************************************/
+
+/**** TNC CONFIGURE ******/
+int TNC_port;
+int TNC_device;
+Widget config_TNC_dialog = (Widget)NULL;
+Widget TNC_active_on_startup;
+Widget TNC_transmit_data;
+Widget TNC_device_name_data;
+Widget TNC_radio_port_data; // Used only for Multi-Port TNC's
+Widget TNC_converse_string;
+Widget TNC_comment;
+Widget TNC_unproto1_data;
+Widget TNC_unproto2_data;
+Widget TNC_unproto3_data;
+Widget TNC_igate_data;
+Widget TNC_up_file_data;
+Widget TNC_down_file_data;
+Widget TNC_txdelay;
+Widget TNC_persistence;
+Widget TNC_slottime;
+Widget TNC_txtail;
+Widget TNC_init_kiss;   // Used to initialize KISS-Mode
+Widget TNC_fullduplex;
+Widget TNC_extra_delay;
+Widget TNC_GPS_set_time;
+Widget TNC_AUX_GPS_Retrieve_Needed;
+Widget TNC_relay_digipeat;
+
+
+
+
+ 
+void Config_TNC_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_TNC_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Config_TNC_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int type;
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+
+    was_up=0;
+    if (get_device_status(TNC_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+
+//WE7U:  Modify for MKISS?
+        (void)del_device(TNC_port);
+
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+    /* device type */
+    type=DEVICE_SERIAL_TNC; // Default in case not defined next
+    if (TNC_device)
+        type=TNC_device; // Modified to support more than two types
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_TNC_change_data" );
+
+    temp_ptr = XmTextFieldGetString(TNC_device_name_data);
+    xastir_snprintf(devices[TNC_port].device_name,
+        sizeof(devices[TNC_port].device_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[TNC_port].device_name);
+
+    temp_ptr = XmTextFieldGetString(TNC_converse_string);
+    xastir_snprintf(devices[TNC_port].device_converse_string,
+        sizeof(devices[TNC_port].device_converse_string),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[TNC_port].device_converse_string);
+
+    temp_ptr = XmTextFieldGetString(TNC_comment);
+    xastir_snprintf(devices[TNC_port].comment,
+        sizeof(devices[TNC_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    
+    (void)remove_trailing_spaces(devices[TNC_port].comment);
+
+    if (devices[TNC_port].device_type == DEVICE_SERIAL_MKISS_TNC) {
+
+        // If MKISS, fetch "radio_port".  If empty, store a zero.
+        temp_ptr = XmTextFieldGetString(TNC_radio_port_data);
+        xastir_snprintf(devices[TNC_port].radio_port,
+            sizeof(devices[TNC_port].radio_port),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(devices[TNC_port].radio_port);
+
+        if (strcmp(devices[TNC_port].radio_port,"") == 0) {
+            xastir_snprintf(devices[TNC_port].radio_port,
+                sizeof(devices[TNC_port].radio_port),
+                "0");
+        }
+//fprintf(stderr,"Radio Port: %s\n",devices[TNC_port].radio_port);
+    }
+
+    if (XmToggleButtonGetState(TNC_active_on_startup))
+        devices[TNC_port].connect_on_startup=1;
+    else
+        devices[TNC_port].connect_on_startup=0;
+
+    if(XmToggleButtonGetState(TNC_transmit_data)) {
+        devices[TNC_port].transmit_data=1;
+        if ( (devices[TNC_port].device_type == DEVICE_SERIAL_KISS_TNC)
+                || (devices[TNC_port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+#ifdef SERIAL_KISS_RELAY_DIGI
+            XtSetSensitive(TNC_relay_digipeat, TRUE);
+#else
+            XtSetSensitive(TNC_relay_digipeat, FALSE);
+#endif  // SERIAL_KISS_RELAY_DIGI
+
+        }
+
+    }
+    else {
+        devices[TNC_port].transmit_data=0;
+        if ( (devices[TNC_port].device_type == DEVICE_SERIAL_KISS_TNC)
+                || (devices[TNC_port].device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+            XtSetSensitive(TNC_relay_digipeat, FALSE);
+        }
+    }
+
+    if ( (type == DEVICE_SERIAL_KISS_TNC)
+            || (type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+        if (XmToggleButtonGetState(TNC_relay_digipeat))
+            devices[TNC_port].relay_digipeat=1;
+        else
+            devices[TNC_port].relay_digipeat=0;
+    }
+
+    switch(type) {
+
+        case DEVICE_SERIAL_TNC:
+        case DEVICE_SERIAL_TNC_HSP_GPS:
+        case DEVICE_SERIAL_TNC_AUX_GPS:
+            if (XmToggleButtonGetState(TNC_extra_delay))
+                devices[TNC_port].tnc_extra_delay=1000000;  // 1,000,000 us
+            else
+                devices[TNC_port].tnc_extra_delay=0;
+            break;
+        default:
+            break;
+    }
+
+    switch(type) {
+
+        case DEVICE_SERIAL_TNC_HSP_GPS:
+        case DEVICE_SERIAL_TNC_AUX_GPS:
+            if (XmToggleButtonGetState(TNC_GPS_set_time))
+                devices[TNC_port].set_time=1;
+            else
+                devices[TNC_port].set_time=0;
+
+            if (type == DEVICE_SERIAL_TNC_AUX_GPS) {
+              if (XmToggleButtonGetState(TNC_AUX_GPS_Retrieve_Needed))
+                devices[TNC_port].gps_retrieve=DEFAULT_GPS_RETR;
+              else
+                devices[TNC_port].gps_retrieve=0;
+            }
+
+            break;
+
+        case DEVICE_SERIAL_TNC:
+        case DEVICE_SERIAL_KISS_TNC:
+        case DEVICE_SERIAL_MKISS_TNC:
+        default:
+            break;
+    }
+
+    set_port_speed(TNC_port);
+
+    devices[TNC_port].style=device_style;
+    devices[TNC_port].igate_options=device_igate_options;
+
+    temp_ptr = XmTextFieldGetString(TNC_unproto1_data);
+    xastir_snprintf(devices[TNC_port].unproto1,
+        sizeof(devices[TNC_port].unproto1),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[TNC_port].unproto1);
+
+    if(check_unproto_path(devices[TNC_port].unproto1)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(TNC_unproto2_data);
+    xastir_snprintf(devices[TNC_port].unproto2,
+        sizeof(devices[TNC_port].unproto2),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[TNC_port].unproto2);
+
+    if(check_unproto_path(devices[TNC_port].unproto2)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(TNC_unproto3_data);
+    xastir_snprintf(devices[TNC_port].unproto3,
+        sizeof(devices[TNC_port].unproto3),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[TNC_port].unproto3);
+
+    if(check_unproto_path(devices[TNC_port].unproto3)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(TNC_igate_data);
+    xastir_snprintf(devices[TNC_port].unproto_igate,
+        sizeof(devices[TNC_port].unproto_igate),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[TNC_port].unproto_igate);
+
+    if(check_unproto_path(devices[TNC_port].unproto_igate)) {
+        popup_message_always(langcode("WPUPCFT044"),
+            langcode("WPUPCFT043"));
+    }
+
+
+    if ( (type == DEVICE_SERIAL_KISS_TNC)
+            || (type == DEVICE_SERIAL_MKISS_TNC) ) {
+
+        // KISS TNC, no up/down files for this one!
+        devices[TNC_port].tnc_up_file[0] = '\0';
+        devices[TNC_port].tnc_down_file[0] = '\0';
+
+        // Instead we have KISS parameters to set
+
+// We really should do some validation of these strings
+
+//WE7U:  Modify for MKISS:  Must send to the proper Radio Port.
+        temp_ptr = XmTextFieldGetString(TNC_txdelay);
+        xastir_snprintf(devices[TNC_port].txdelay,
+            sizeof(devices[TNC_port].txdelay),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        send_kiss_config(TNC_port,0,0x01,atoi(devices[TNC_port].txdelay));
+
+        temp_ptr = XmTextFieldGetString(TNC_persistence);
+        xastir_snprintf(devices[TNC_port].persistence,
+            sizeof(devices[TNC_port].persistence),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        send_kiss_config(TNC_port,0,0x02,atoi(devices[TNC_port].persistence));
+
+        temp_ptr = XmTextFieldGetString(TNC_slottime);
+        xastir_snprintf(devices[TNC_port].slottime,
+            sizeof(devices[TNC_port].slottime),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        send_kiss_config(TNC_port,0,0x03,atoi(devices[TNC_port].slottime));
+
+        temp_ptr = XmTextFieldGetString(TNC_txtail);
+        xastir_snprintf(devices[TNC_port].txtail,
+            sizeof(devices[TNC_port].txtail),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        send_kiss_config(TNC_port,0,0x04,atoi(devices[TNC_port].txtail));
+ 
+        if (XmToggleButtonGetState(TNC_fullduplex))
+            devices[TNC_port].fullduplex=1;
+        else
+            devices[TNC_port].fullduplex=0;
+        send_kiss_config(TNC_port,0,0x05,devices[TNC_port].fullduplex);
+
+        // For KISS-mode
+        if (XmToggleButtonGetState(TNC_init_kiss))
+            devices[TNC_port].init_kiss=1;
+        else
+            devices[TNC_port].init_kiss=0;
+    }
+    else {
+        temp_ptr = XmTextFieldGetString(TNC_up_file_data);
+        xastir_snprintf(devices[TNC_port].tnc_up_file,
+            sizeof(devices[TNC_port].tnc_up_file),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(devices[TNC_port].tnc_up_file);
+
+        temp_ptr = XmTextFieldGetString(TNC_down_file_data);
+        xastir_snprintf(devices[TNC_port].tnc_down_file,
+            sizeof(devices[TNC_port].tnc_down_file),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(devices[TNC_port].tnc_down_file);
+    }
+
+//WE7U:  Modify for MKISS?
+    /* reopen port*/
+    if (was_up) {
+        (void)add_device(TNC_port,
+            type,
+            devices[TNC_port].device_name,
+            "",
+            -1,
+            devices[TNC_port].sp,
+            devices[TNC_port].style,
+            0,
+            "");
+    }
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[TNC_port].device_type=type;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_TNC_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Config_TNC_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_TNC( /*@unused@*/ Widget w, int device_type, int config_type, int port) {
+    static Widget  pane, form, form2, button_ok, button_cancel,
+                frame, frame2, frame3, frame4,
+                setup, setup1, setup2, setup3, setup4,
+                device, converse, comment, speed, speed_box,
+                speed_300, speed_1200, speed_2400, speed_4800, speed_9600,
+                speed_19200, speed_38400;
+#ifndef __LSB__
+    static Widget speed_57600, speed_115200, speed_230400;
+#endif  // __LSB__
+    static Widget style, style_box,
+                style_8n1, style_7e1, style_7o1,
+                igate, igate_box,
+                igate_o_0, igate_o_1, igate_o_2,
+                igate_label,
+                proto, proto1, proto2, proto3,
+                radio_port_label;
+    char temp[50];
+    Atom delw;
+    Arg al[50];                      /* Arg List */
+    register unsigned int ac = 0;   /* Arg Count */
+        register char *tmp;
+
+        tmp=(char *)NULL;
+
+    if(!config_TNC_dialog) {
+        TNC_port=port;
+        TNC_device=device_type;
+/* config_TNC_dialog = XtVaCreatePopupShell(device_type ? langcode("WPUPCFT023"):langcode("WPUPCFT001"),
+ -- replaced by KB6MER with the lines below for adding AUX GPS type TNC
+*/
+        switch(device_type) {
+            case DEVICE_SERIAL_TNC:
+                tmp=langcode("WPUPCFT001");
+                break;
+
+            case DEVICE_SERIAL_KISS_TNC:
+                tmp=langcode("WPUPCFT030");
+                break;
+
+            case DEVICE_SERIAL_MKISS_TNC:
+                tmp=langcode("WPUPCFT040");
+                break;
+
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+                tmp=langcode("WPUPCFT023");
+                break;
+
+            case DEVICE_SERIAL_TNC_AUX_GPS:
+                tmp=langcode("WPUPCFT028");
+                break;
+
+            default:
+                sprintf(tmp, langcode("WPUPCFT029"), (int)device_type);
+                break;
+        }
+
+        config_TNC_dialog = XtVaCreatePopupShell(
+                            tmp,
+                            xmDialogShellWidgetClass, appshell,
+                            XmNdeleteResponse,XmDESTROY,
+                            XmNdefaultPosition, FALSE,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        pane = XtVaCreateWidget("Config_TNC pane",xmPanedWindowWidgetClass, config_TNC_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_TNC form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        TNC_active_on_startup = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_transmit_data = XtVaCreateManagedWidget(langcode("UNIOP00010"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_active_on_startup,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        switch(device_type) {
+            case DEVICE_SERIAL_TNC:
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+            case DEVICE_SERIAL_TNC_AUX_GPS:
+                TNC_extra_delay = XtVaCreateManagedWidget(langcode("UNIOP00038"), xmToggleButtonWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_transmit_data,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        }
+ 
+        switch(device_type) {
+            case DEVICE_SERIAL_TNC_HSP_GPS:
+            case DEVICE_SERIAL_TNC_AUX_GPS:
+                TNC_GPS_set_time  = XtVaCreateManagedWidget(langcode("UNIOP00029"), xmToggleButtonWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_extra_delay,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+// We can only set the time properly on Linux systems
+#ifndef HAVE_SETTIMEOFDAY
+                XtSetSensitive(TNC_GPS_set_time,FALSE);
+#endif  // HAVE_SETTIMEOFDAY
+#ifdef __CYGWIN__
+                XtSetSensitive(TNC_GPS_set_time,FALSE);
+#endif  // __CYGWIN__
+
+                // Let the user turn off the Control-E thing
+                // that only SOME "tnc-with-gps" devices actually 
+                // require, and that confuse the heck out of others.
+                // D700 is among the confused, by the way.  TVR -- 14 Aug 2012
+                if (device_type == DEVICE_SERIAL_TNC_AUX_GPS) {
+                  TNC_AUX_GPS_Retrieve_Needed  = XtVaCreateManagedWidget(langcode("UNIOP00037"), xmToggleButtonWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_GPS_set_time,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+                }
+
+                break;
+            case DEVICE_SERIAL_KISS_TNC:
+            case DEVICE_SERIAL_MKISS_TNC:
+                // Add a "RELAY Digipeat?" button for KISS/MKISS TNC's
+                TNC_relay_digipeat = XtVaCreateManagedWidget(langcode("UNIOP00030"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_transmit_data,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+#ifdef SERIAL_KISS_RELAY_DIGI
+                XtSetSensitive(TNC_relay_digipeat, TRUE);
+#else
+                XtSetSensitive(TNC_relay_digipeat, FALSE);
+#endif  // SERIAL_KISS_RELAY_DIGIPEAT
+
+                break;
+ 
+            case DEVICE_SERIAL_TNC:
+            default:
+                break;
+        }
+
+        device = XtVaCreateManagedWidget(langcode("WPUPCFT003"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_device_name_data = XtVaCreateManagedWidget("Config_TNC device_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 2,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, device,
+                                      XmNleftOffset, 12,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+//        converse = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+        converse = XtVaCreateManagedWidget("Converse CMD:",xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_device_name_data,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_converse_string = XtVaCreateManagedWidget("Config_TNC comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 2,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, converse,
+                                      XmNleftOffset, 12,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_converse_string,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_comment = XtVaCreateManagedWidget("Config_TNC comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 2,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNleftOffset, 12,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        if (device_type ==  DEVICE_SERIAL_MKISS_TNC) {
+            // "Radio Port" field for Multi-Port KISS TNC's.
+
+            radio_port_label = XtVaCreateManagedWidget(langcode("WPUPCFT041"),
+                                      xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_comment,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+            TNC_radio_port_data = XtVaCreateManagedWidget("Config_TNC device_data",
+                                      xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 5,
+                                      XmNwidth, ((5*7)+2),
+                                      XmNmaxLength, 2,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_active_on_startup,
+                                      XmNtopOffset, 2,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, radio_port_label,
+                                      XmNleftOffset, 12,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        }
+
+        frame = XtVaCreateManagedWidget("Config_TNC frame", xmFrameWidgetClass, form,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopOffset, 10,
+                                    XmNtopWidget, device,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_FORM,
+                                    XmNrightOffset, 10,
+                                    XmNbackground, colors[0xff],
+                                    NULL);
+
+        speed = XtVaCreateManagedWidget(langcode("WPUPCFT004"),xmLabelWidgetClass, frame,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+
+        speed_box = XmCreateRadioBox(frame,"Config_TNC Speed_box",al,ac);
+        XtVaSetValues(speed_box,XmNnumColumns,5,NULL);
+
+        speed_300 = XtVaCreateManagedWidget(langcode("WPUPCFT005"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+
+        XtAddCallback(speed_300,XmNvalueChangedCallback,speed_toggle,"1");
+
+        speed_1200 = XtVaCreateManagedWidget(langcode("WPUPCFT006"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_1200,XmNvalueChangedCallback,speed_toggle,"2");
+
+
+        speed_2400 = XtVaCreateManagedWidget(langcode("WPUPCFT007"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_2400,XmNvalueChangedCallback,speed_toggle,"3");
+
+
+        speed_4800 = XtVaCreateManagedWidget(langcode("WPUPCFT008"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_4800,XmNvalueChangedCallback,speed_toggle,"4");
+
+        speed_9600 = XtVaCreateManagedWidget(langcode("WPUPCFT009"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_9600,XmNvalueChangedCallback,speed_toggle,"5");
+
+        speed_19200 = XtVaCreateManagedWidget(langcode("WPUPCFT010"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_19200,XmNvalueChangedCallback,speed_toggle,"6");
+
+        speed_38400 = XtVaCreateManagedWidget(langcode("WPUPCFT019"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_38400,XmNvalueChangedCallback,speed_toggle,"7");
+
+#ifndef __LSB__
+        speed_57600 = XtVaCreateManagedWidget(langcode("WPUPCFT020"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_57600,XmNvalueChangedCallback,speed_toggle,"8");
+
+        speed_115200 = XtVaCreateManagedWidget(langcode("WPUPCFT021"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_115200,XmNvalueChangedCallback,speed_toggle,"9");
+
+        speed_230400 = XtVaCreateManagedWidget(langcode("WPUPCFT022"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_230400,XmNvalueChangedCallback,speed_toggle,"10");
+#endif  // __LSB__
+
+        switch(device_type) {
+            case DEVICE_SERIAL_KISS_TNC:
+            case DEVICE_SERIAL_MKISS_TNC:
+                break;
+            default:
+                frame2 = XtVaCreateManagedWidget("Config_TNC frame2", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+                                     XmNtopWidget, frame,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     NULL);
+
+                style = XtVaCreateManagedWidget(langcode("WPUPCFT015"),xmLabelWidgetClass, frame2,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+
+                style_box = XmCreateRadioBox(frame2,"Config_TNC Style box",al,ac);
+
+                XtVaSetValues(style_box,XmNorientation, XmHORIZONTAL,NULL);
+
+                style_8n1 = XtVaCreateManagedWidget(langcode("WPUPCFT016"),xmToggleButtonGadgetClass,
+                                        style_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                XtAddCallback(style_8n1,XmNvalueChangedCallback,style_toggle,"0");
+
+                style_7e1 = XtVaCreateManagedWidget(langcode("WPUPCFT017"),xmToggleButtonGadgetClass,
+                                        style_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                XtAddCallback(style_7e1,XmNvalueChangedCallback,style_toggle,"1");
+
+                style_7o1 = XtVaCreateManagedWidget(langcode("WPUPCFT018"),xmToggleButtonGadgetClass,
+                                        style_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                XtAddCallback(style_7o1,XmNvalueChangedCallback,style_toggle,"2");
+            break;
+        }
+
+        frame4 = XtVaCreateManagedWidget("Config_TNC frame4", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+XmNtopWidget, (device_type == DEVICE_SERIAL_KISS_TNC || device_type == DEVICE_SERIAL_MKISS_TNC) ? frame : frame2,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     XmNfontList, fontlist1,
+                                     NULL);
+
+        igate = XtVaCreateManagedWidget(langcode("IGPUPCF000"),xmLabelWidgetClass, frame4,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        igate_box = XmCreateRadioBox(frame4,"Config_TNC IGate box",al,ac);
+
+        XtVaSetValues(igate_box,XmNorientation, XmVERTICAL,XmNnumColumns,2,NULL);
+
+        igate_o_0 = XtVaCreateManagedWidget(langcode("IGPUPCF001"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(igate_o_0,XmNvalueChangedCallback,igate_toggle,"0");
+
+        igate_o_1 = XtVaCreateManagedWidget(langcode("IGPUPCF002"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(igate_o_1,XmNvalueChangedCallback,igate_toggle,"1");
+
+        igate_o_2 = XtVaCreateManagedWidget(langcode("IGPUPCF003"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(igate_o_2,XmNvalueChangedCallback,igate_toggle,"2");
+
+        proto = XtVaCreateManagedWidget(langcode("WPUPCFT011"), xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, frame4,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT012"), VERSIONFRM);
+
+        proto1 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 15,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_unproto1_data = XtVaCreateManagedWidget("Config_TNC protopath1", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, proto1,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT013"), VERSIONFRM);
+
+        proto2 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_unproto1_data,
+                                      XmNleftOffset, 15,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_unproto2_data = XtVaCreateManagedWidget("Config_TNC protopath2", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, proto2,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 15,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT014"), VERSIONFRM);
+
+        proto3 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto1,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 15,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_unproto3_data = XtVaCreateManagedWidget("Config_TNC protopath3", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_unproto1_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, proto3,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("IGPUPCF004"));
+        igate_label = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto2,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, TNC_unproto3_data,
+                                      XmNleftOffset, 15,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        TNC_igate_data = XtVaCreateManagedWidget("Config_TNC igate_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, TNC_unproto2_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, igate_label,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+// Draw a different frame3 for Serial KISS/MKISS TNC interfaces
+        switch(device_type) {
+            case DEVICE_SERIAL_KISS_TNC:
+            case DEVICE_SERIAL_MKISS_TNC:
+                frame3 = XtVaCreateManagedWidget("Config_TNC frame3", xmFrameWidgetClass, form,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopOffset,10,
+                                    XmNtopWidget, TNC_igate_data,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_FORM,
+                                    XmNrightOffset, 10,
+                                    XmNbackground, colors[0xff],
+                                    NULL);
+
+                // KISS Parameters
+                setup = XtVaCreateManagedWidget(langcode("WPUPCFT034"),xmLabelWidgetClass, frame3,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                form2 =  XtVaCreateWidget("Config_TNC form2",xmFormWidgetClass, frame3,
+                                    XmNfractionBase, 6,
+                                    XmNbackground, colors[0xff],
+                                    NULL);
+
+                // TXDelay (10 ms units)
+                setup1 = XtVaCreateManagedWidget(langcode("WPUPCFT035"), xmLabelWidgetClass, form2,
+                                    XmNtopAttachment,XmATTACH_FORM,
+                                    XmNtopOffset, 10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                TNC_txdelay = XtVaCreateManagedWidget("Config_TNC TNC_txdelay", xmTextFieldWidgetClass, form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNeditable,   TRUE,
+                                    XmNcursorPositionVisible, TRUE,
+                                    XmNsensitive, TRUE,
+                                    XmNshadowThickness,    1,
+                                    XmNcolumns, 3,
+                                    XmNwidth, ((6*7)+2),
+                                    XmNmaxLength, 3,
+                                    XmNbackground, colors[0x0f],
+                                    XmNtopAttachment,XmATTACH_FORM,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment,XmATTACH_POSITION,
+                                    XmNleftPosition, 2,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                // Persistence (0 to 255)
+                setup2 = XtVaCreateManagedWidget(langcode("WPUPCFT036"), xmLabelWidgetClass, form2,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, setup1,
+                                    XmNtopOffset, 10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                TNC_persistence = XtVaCreateManagedWidget("Config_TNC persistence", xmTextFieldWidgetClass, form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNeditable,   TRUE,
+                                    XmNcursorPositionVisible, TRUE,
+                                    XmNsensitive, TRUE,
+                                    XmNshadowThickness,    1,
+                                    XmNcolumns, 3,
+                                    XmNwidth, ((6*7)+2),
+                                    XmNmaxLength, 3,
+                                    XmNbackground, colors[0x0f],
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, setup1,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment,XmATTACH_POSITION,
+                                    XmNleftPosition, 2,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                // SlotTime (10 ms units)
+                setup3 = XtVaCreateManagedWidget(langcode("WPUPCFT037"), xmLabelWidgetClass, form2,
+                                    XmNtopAttachment,XmATTACH_FORM,
+                                    XmNtopOffset, 10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_POSITION,
+                                    XmNleftPosition, 3,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                TNC_slottime = XtVaCreateManagedWidget("Config_TNC slottime", xmTextFieldWidgetClass, form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNeditable,   TRUE,
+                                    XmNcursorPositionVisible, TRUE,
+                                    XmNsensitive, TRUE,
+                                    XmNshadowThickness,    1,
+                                    XmNcolumns, 3,
+                                    XmNwidth, ((6*7)+2),
+                                    XmNmaxLength, 3,
+                                    XmNbackground, colors[0x0f],
+                                    XmNtopAttachment,XmATTACH_FORM,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment,XmATTACH_POSITION,
+                                    XmNleftPosition, 5,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                // TxTail (10 ms units)
+                setup4 = XtVaCreateManagedWidget(langcode("WPUPCFT038"), xmLabelWidgetClass, form2,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, setup3,
+                                    XmNtopOffset, 10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_POSITION,
+                                    XmNleftPosition, 3,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                TNC_txtail = XtVaCreateManagedWidget("Config_TNC TxTail", xmTextFieldWidgetClass, form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNeditable,   TRUE,
+                                    XmNcursorPositionVisible, TRUE,
+                                    XmNsensitive, TRUE,
+                                    XmNshadowThickness,    1,
+                                    XmNcolumns, 3,
+                                    XmNwidth, ((6*7)+2),
+                                    XmNmaxLength, 3,
+                                    XmNbackground, colors[0x0f],
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, setup3,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment,XmATTACH_POSITION,
+                                    XmNleftPosition, 5,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                // Full Duplex
+                TNC_fullduplex = XtVaCreateManagedWidget(langcode("WPUPCFT039"),xmToggleButtonWidgetClass,form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNtopAttachment, XmATTACH_WIDGET,
+                                    XmNtopWidget, setup4,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment, XmATTACH_FORM,
+                                    XmNbottomOffset, 5,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment, XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                // Button to enable KISS-mode at startup
+                TNC_init_kiss = XtVaCreateManagedWidget(langcode("WPUPCFT047"),xmToggleButtonWidgetClass,form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNtopAttachment, XmATTACH_WIDGET,
+                                    XmNtopWidget, setup4,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment, XmATTACH_FORM,
+                                    XmNbottomOffset, 5,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 135,
+                                    XmNrightAttachment, XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+                break;
+            default:
+                frame3 = XtVaCreateManagedWidget("Config_TNC frame3", xmFrameWidgetClass, form,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopOffset,10,
+                                    XmNtopWidget, TNC_igate_data,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_FORM,
+                                    XmNrightOffset, 10,
+                                    XmNbackground, colors[0xff],
+                                    NULL);
+
+                setup = XtVaCreateManagedWidget(langcode("WPUPCFT031"),xmLabelWidgetClass, frame3,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                form2 =  XtVaCreateWidget("Config_TNC form2",xmFormWidgetClass, frame3,
+                                    XmNfractionBase, 5,
+                                    XmNbackground, colors[0xff],
+                                    NULL);
+
+                setup1 = XtVaCreateManagedWidget(langcode("WPUPCFT032"), xmLabelWidgetClass, form2,
+                                    XmNtopAttachment,XmATTACH_FORM,
+                                    XmNtopOffset, 10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                TNC_up_file_data = XtVaCreateManagedWidget("Config_TNC up_file", xmTextFieldWidgetClass, form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNeditable,   TRUE,
+                                    XmNcursorPositionVisible, TRUE,
+                                    XmNsensitive, TRUE,
+                                    XmNshadowThickness,    1,
+                                    XmNcolumns, 25,
+                                    XmNwidth, ((25*7)+2),
+                                    XmNmaxLength, 80,
+                                    XmNbackground, colors[0x0f],
+                                    XmNtopAttachment,XmATTACH_FORM,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment,XmATTACH_POSITION,
+                                    XmNleftPosition, 2,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                setup2 = XtVaCreateManagedWidget(langcode("WPUPCFT033"), xmLabelWidgetClass, form2,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, setup1,
+                                    XmNtopOffset, 10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                TNC_down_file_data = XtVaCreateManagedWidget("Config_TNC down_file", xmTextFieldWidgetClass, form2,
+                                    XmNnavigationType, XmTAB_GROUP,
+                                    XmNtraversalOn, TRUE,
+                                    XmNeditable,   TRUE,
+                                    XmNcursorPositionVisible, TRUE,
+                                    XmNsensitive, TRUE,
+                                    XmNshadowThickness,    1,
+                                    XmNcolumns, 25,
+                                    XmNwidth, ((25*7)+2),
+                                    XmNmaxLength, 80,
+                                    XmNbackground, colors[0x0f],
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, setup1,
+                                    XmNtopOffset, 5,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment,XmATTACH_POSITION,
+                                    XmNleftPosition, 2,
+                                    XmNrightAttachment,XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+                break;
+        }
+
+
+//------------------------------------------------------------
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, frame3,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, frame3,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Config_TNC_change_data, config_TNC_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Config_TNC_destroy_shell, config_TNC_dialog);
+
+        pos_dialog(config_TNC_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_TNC_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_TNC_dialog, delw, Config_TNC_destroy_shell, (XtPointer)config_TNC_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            devices[TNC_port].gps_retrieve=DEFAULT_GPS_RETR;
+            if (debug_level & 128) {
+                fprintf(stderr,"Storing %d to gps_retrieve for %d\n",
+                DEFAULT_GPS_RETR, port);
+            }
+
+            XmTextFieldSetString(TNC_device_name_data,TNC_PORT);
+
+            XmTextFieldSetString(TNC_converse_string,"k");
+
+            XmTextFieldSetString(TNC_comment,"");
+
+            if (device_type == DEVICE_SERIAL_MKISS_TNC) {
+                XmTextFieldSetString(TNC_radio_port_data,"0");
+//fprintf(stderr,"Assigning default '0' to radio port\n");
+            }
+
+            XmToggleButtonSetState(TNC_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(TNC_transmit_data,TRUE,FALSE);
+
+            switch(device_type) {
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                    XmToggleButtonSetState(TNC_extra_delay, FALSE, FALSE);
+                    break;
+                default:
+                    break;
+            }
+
+            switch(device_type) {
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                    XmToggleButtonSetState(TNC_GPS_set_time, FALSE, FALSE);
+                    if (device_type == DEVICE_SERIAL_TNC_AUX_GPS) 
+                      XmToggleButtonSetState(TNC_AUX_GPS_Retrieve_Needed, 
+                                             TRUE, FALSE);
+                    break;
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                    XmToggleButtonSetState(TNC_relay_digipeat, FALSE, FALSE);
+                    XmToggleButtonSetState(TNC_fullduplex, FALSE, FALSE);
+                    XmToggleButtonSetState(TNC_init_kiss, FALSE, FALSE); // For KISS-Mode
+                    break;
+                case DEVICE_SERIAL_TNC:
+                default:
+                    break;
+            }
+
+            XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+            device_speed=4;
+
+            if ( (device_type != DEVICE_SERIAL_KISS_TNC)
+                    && (device_type != DEVICE_SERIAL_MKISS_TNC) ) {
+                XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+            }
+
+            device_style=0;
+
+            device_igate_options=0;
+            XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+            XmTextFieldSetString(TNC_unproto1_data,"WIDE2-2");
+            XmTextFieldSetString(TNC_unproto2_data,"");
+            XmTextFieldSetString(TNC_unproto3_data,"");
+            XmTextFieldSetString(TNC_igate_data,"");
+
+//WE7U
+            if ( (device_type == DEVICE_SERIAL_KISS_TNC)
+                    || (device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+                // We don't allow changing the selection for KISS
+                // TNC's, as they require 8N1
+                device_style = 0;
+                XmTextFieldSetString(TNC_txdelay,"40");
+                XmTextFieldSetString(TNC_persistence,"63");
+                XmTextFieldSetString(TNC_slottime,"20");
+                XmTextFieldSetString(TNC_txtail,"30");
+            }
+            else {
+                XmTextFieldSetString(TNC_up_file_data,"tnc-startup.sys");
+                XmTextFieldSetString(TNC_down_file_data,"tnc-stop.sys");
+            }
+
+        } else {
+            /* reconfig */
+
+            if (debug_level & 128)
+                fprintf(stderr,"Reconfiguring interface\n");
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_TNC" );
+
+            XmTextFieldSetString(TNC_device_name_data,devices[TNC_port].device_name);
+
+            XmTextFieldSetString(TNC_converse_string,devices[TNC_port].device_converse_string);
+
+            XmTextFieldSetString(TNC_comment,devices[TNC_port].comment);
+
+            if (device_type == DEVICE_SERIAL_MKISS_TNC) {
+                XmTextFieldSetString(TNC_radio_port_data, devices[TNC_port].radio_port);
+//fprintf(stderr,"Reconfig: %s\n", devices[TNC_port].radio_port);
+            }
+
+            if (devices[TNC_port].connect_on_startup)
+                XmToggleButtonSetState(TNC_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(TNC_active_on_startup,FALSE,FALSE);
+
+            if (devices[TNC_port].transmit_data)
+                XmToggleButtonSetState(TNC_transmit_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(TNC_transmit_data,FALSE,FALSE);
+
+            switch(device_type) {
+                case DEVICE_SERIAL_TNC:
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                    if (devices[TNC_port].tnc_extra_delay)
+                        XmToggleButtonSetState(TNC_extra_delay, TRUE, FALSE);
+                    else
+                        XmToggleButtonSetState(TNC_extra_delay, FALSE, FALSE);
+                    break;
+                default:
+                    break;
+            }
+
+            switch(device_type) {
+
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                    if (devices[TNC_port].set_time)
+                        XmToggleButtonSetState(TNC_GPS_set_time, TRUE, FALSE);
+                    else
+                        XmToggleButtonSetState(TNC_GPS_set_time, FALSE, FALSE);
+
+                    if (device_type == DEVICE_SERIAL_TNC_AUX_GPS) {
+                      if (devices[TNC_port].gps_retrieve != 0)
+                        XmToggleButtonSetState(TNC_AUX_GPS_Retrieve_Needed, 
+                                               TRUE, FALSE);
+                      else
+                        XmToggleButtonSetState(TNC_AUX_GPS_Retrieve_Needed, 
+                                               FALSE, FALSE);
+                    }
+
+                    break;
+
+                case  DEVICE_SERIAL_KISS_TNC:
+                case  DEVICE_SERIAL_MKISS_TNC:
+
+                    if (devices[TNC_port].relay_digipeat)
+                        XmToggleButtonSetState(TNC_relay_digipeat, TRUE, FALSE);
+                    else
+                        XmToggleButtonSetState(TNC_relay_digipeat, FALSE, FALSE);
+
+                    if (devices[TNC_port].fullduplex)
+                        XmToggleButtonSetState(TNC_fullduplex, TRUE, FALSE);
+                    else
+                        XmToggleButtonSetState(TNC_fullduplex, FALSE, FALSE);
+
+                    // For KISS-Mode
+                    if (devices[TNC_port].init_kiss)
+                        XmToggleButtonSetState(TNC_init_kiss, TRUE, FALSE);
+                    else
+                        XmToggleButtonSetState(TNC_init_kiss, FALSE, FALSE);
+
+                    if (devices[TNC_port].transmit_data) {
+
+#ifdef SERIAL_KISS_RELAY_DIGI
+                        XtSetSensitive(TNC_relay_digipeat, TRUE);
+#else
+                        XtSetSensitive(TNC_relay_digipeat, FALSE);
+#endif  // SERIAL_KISS_RELAY_DIGI
+
+                    }
+                    else
+                        XtSetSensitive(TNC_relay_digipeat, FALSE);
+                    break;
+
+                case DEVICE_SERIAL_TNC:
+                default:
+                    break;
+            }
+
+            switch (devices[TNC_port].sp) {
+                case(B300):
+                    XmToggleButtonSetState(speed_300,TRUE,FALSE);
+                    device_speed=1;
+                    break;
+
+                case(B1200):
+                    XmToggleButtonSetState(speed_1200,TRUE,FALSE);
+                    device_speed=2;
+                    break;
+
+                case(B2400):
+                    XmToggleButtonSetState(speed_2400,TRUE,FALSE);
+                    device_speed=3;
+                    break;
+
+                case(B4800):
+                    XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+                    device_speed=4;
+                    break;
+
+                case(B9600):
+                    XmToggleButtonSetState(speed_9600,TRUE,FALSE);
+                    device_speed=5;
+                    break;
+
+                case(B19200):
+                    XmToggleButtonSetState(speed_19200,TRUE,FALSE);
+                    device_speed=6;
+                    break;
+
+                case(B38400):
+                    XmToggleButtonSetState(speed_38400,TRUE,FALSE);
+                    device_speed=7;
+                    break;
+
+#ifndef __LSB__
+                case(B57600):
+                    XmToggleButtonSetState(speed_57600,TRUE,FALSE);
+                    device_speed=8;
+                    break;
+
+                case(B115200):
+                    XmToggleButtonSetState(speed_115200,TRUE,FALSE);
+                    device_speed=9;
+                    break;
+
+#ifdef B230400
+                case(B230400):
+                    XmToggleButtonSetState(speed_230400,TRUE,FALSE);
+                    device_speed=10;
+                    break;
+#endif  // B230400
+#endif  // __LSB__
+
+                default:
+                    XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+                    device_speed=4;
+                    break;
+            }
+
+            if ( (device_type == DEVICE_SERIAL_KISS_TNC)
+                    || (device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+                // We don't allow changing the selection for KISS
+                // TNC's, as they require 8N1
+                device_style = 0;
+            }
+            else {
+                switch (devices[TNC_port].style) {
+                    case(0):
+                        XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+                        device_style=0;
+                        break;
+    
+                    case(1):
+                        XmToggleButtonSetState(style_7e1,TRUE,FALSE);
+                        device_style=1;
+                        break;
+
+                    case(2):
+                        XmToggleButtonSetState(style_7o1,TRUE,FALSE);
+                        device_style=2;
+                        break;
+
+                    default:
+                        XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+                        device_style=0;
+                        break;
+                }
+            }
+
+            switch (devices[TNC_port].igate_options) {
+                case(0):
+                    XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+                    device_igate_options=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(igate_o_1,TRUE,FALSE);
+                    device_igate_options=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(igate_o_2,TRUE,FALSE);
+                    device_igate_options=2;
+                    break;
+
+                default:
+                    XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+                    device_igate_options=0;
+                    break;
+            }
+            XmTextFieldSetString(TNC_unproto1_data,devices[TNC_port].unproto1);
+            XmTextFieldSetString(TNC_unproto2_data,devices[TNC_port].unproto2);
+            XmTextFieldSetString(TNC_unproto3_data,devices[TNC_port].unproto3);
+            XmTextFieldSetString(TNC_igate_data,devices[TNC_port].unproto_igate);
+
+            if ( (device_type == DEVICE_SERIAL_KISS_TNC)
+                    || (device_type == DEVICE_SERIAL_MKISS_TNC) ) {
+                XmTextFieldSetString(TNC_txdelay,devices[TNC_port].txdelay);
+                XmTextFieldSetString(TNC_persistence,devices[TNC_port].persistence);
+                XmTextFieldSetString(TNC_slottime,devices[TNC_port].slottime);
+                XmTextFieldSetString(TNC_txtail,devices[TNC_port].txtail);
+            }
+            else {
+                XmTextFieldSetString(TNC_up_file_data,devices[TNC_port].tnc_up_file);
+                XmTextFieldSetString(TNC_down_file_data,devices[TNC_port].tnc_down_file);
+            }
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_TNC" );
+
+        }
+
+        XtManageChild(form);
+
+        XtManageChild(form2);
+
+        XtManageChild(speed_box);
+
+        if ( (device_type != DEVICE_SERIAL_KISS_TNC)
+                && (device_type != DEVICE_SERIAL_MKISS_TNC) ) {
+            XtManageChild(style_box);
+        }
+
+        XtManageChild(igate_box);
+        XtManageChild(pane);
+
+        XtPopup(config_TNC_dialog,XtGrabNone);
+        fix_dialog_size(config_TNC_dialog);
+    }
+    else {
+        (void)XRaiseWindow(XtDisplay(config_TNC_dialog), XtWindow(config_TNC_dialog));
+    }
+}
+
+
+
+
+
+/*****************************************************/
+/* Configure Serial GPS GUI                          */
+/*****************************************************/
+
+/**** GPS CONFIGURE ******/
+int GPS_port;
+Widget config_GPS_dialog = (Widget)NULL;
+Widget GPS_device_name_data;
+Widget GPS_comment;
+Widget GPS_active_on_startup;
+Widget GPS_set_time;
+
+
+
+
+
+void Config_GPS_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_GPS_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Config_GPS_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+    was_up=0;
+    if (get_device_status(GPS_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(GPS_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_GPS_change_data" );
+
+    temp_ptr = XmTextFieldGetString(GPS_device_name_data);
+    xastir_snprintf(devices[GPS_port].device_name,
+        sizeof(devices[GPS_port].device_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[GPS_port].device_name);
+
+    temp_ptr = XmTextFieldGetString(GPS_comment);
+    xastir_snprintf(devices[GPS_port].comment,
+        sizeof(devices[GPS_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[GPS_port].comment);
+
+    if(XmToggleButtonGetState(GPS_active_on_startup))
+        devices[GPS_port].connect_on_startup=1;
+    else
+        devices[GPS_port].connect_on_startup=0;
+
+    if (XmToggleButtonGetState(GPS_set_time))
+        devices[GPS_port].set_time=1;
+    else
+        devices[GPS_port].set_time=0;
+
+    set_port_speed(GPS_port);
+    devices[GPS_port].style=device_style;
+    /* reopen */
+    if ( was_up ) {
+        (void)add_device(GPS_port,
+            DEVICE_SERIAL_GPS,
+            devices[GPS_port].device_name,
+            "",
+            -1,
+            devices[GPS_port].sp,
+            devices[GPS_port].style,
+            0,
+            "");
+    }
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[GPS_port].device_type=DEVICE_SERIAL_GPS;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_GPS_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Config_GPS_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_GPS( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel,
+                frame, frame2,
+                device, comment, speed, speed_box,
+                speed_300, speed_1200, speed_2400, speed_4800, speed_9600,
+                speed_19200, speed_38400;
+#ifndef __LSB__
+    static Widget speed_57600, speed_115200, speed_230400;
+#endif  // __LSB__
+    static Widget style, style_box,
+                style_8n1, style_7e1, style_7o1,
+                sep;
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+    if(!config_GPS_dialog) {
+        GPS_port=port;
+        config_GPS_dialog = XtVaCreatePopupShell(langcode("WPUPCFG001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse,XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_GPS pane",xmPanedWindowWidgetClass, config_GPS_dialog,
+            XmNbackground, colors[0xff],
+            NULL);
+
+        form =  XtVaCreateWidget("Config_GPS form",xmFormWidgetClass, pane,
+            XmNfractionBase, 5,
+            XmNbackground, colors[0xff],
+            XmNautoUnmanage, FALSE,
+            XmNshadowThickness, 1,
+            NULL);
+
+        device = XtVaCreateManagedWidget(langcode("WPUPCFG003"),xmLabelWidgetClass, form,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNtopOffset, 10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset, 10,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        GPS_device_name_data = XtVaCreateManagedWidget("Config_GPS device_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 25,
+            XmNwidth, ((25*7)+2),
+            XmNmaxLength, 40,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment,XmATTACH_FORM,
+            XmNtopOffset, 5,
+            XmNbottomAttachment,XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, device,
+            XmNleftOffset, 10,
+            XmNrightAttachment,XmATTACH_FORM,
+            XmNrightOffset, 5,
+            XmNfontList, fontlist1,
+            NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, device,
+            XmNtopOffset, 10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset, 15,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        GPS_comment = XtVaCreateManagedWidget("Config_GPS comment", xmTextFieldWidgetClass, form,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 25,
+            XmNwidth, ((25*7)+2),
+            XmNmaxLength, 49,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment,XmATTACH_WIDGET,
+            XmNtopWidget, device,
+            XmNtopOffset, 10,
+            XmNbottomAttachment,XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, comment,
+            XmNleftOffset, 10,
+            XmNrightAttachment,XmATTACH_FORM,
+            XmNrightOffset, 5,
+            XmNfontList, fontlist1,
+            NULL);
+
+        GPS_active_on_startup = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, comment,
+            XmNtopOffset, 10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset ,10,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        GPS_set_time  = XtVaCreateManagedWidget(langcode("UNIOP00029"), xmToggleButtonWidgetClass, form,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, GPS_active_on_startup,
+            XmNtopOffset, 7,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset ,10,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+// We can only set the time properly on Linux systems
+#ifndef HAVE_SETTIMEOFDAY
+        XtSetSensitive(GPS_set_time,FALSE);
+#endif  // HAVE_SETTIMEOFDAY
+#ifdef __CYGWIN__
+        XtSetSensitive(GPS_set_time,FALSE);
+#endif  // __CYGWIN__
+
+
+ 
+        frame = XtVaCreateManagedWidget("Config_GPS frame", xmFrameWidgetClass, form,
+            XmNtopAttachment,XmATTACH_WIDGET,
+            XmNtopOffset,10,
+            XmNtopWidget, GPS_set_time,
+            XmNbottomAttachment,XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset, 10,
+            XmNrightAttachment,XmATTACH_FORM,
+            XmNrightOffset, 10,
+            XmNbackground, colors[0xff],
+            NULL);
+
+        speed = XtVaCreateManagedWidget(langcode("WPUPCFT004"),xmLabelWidgetClass, frame,
+            XmNchildType, XmFRAME_TITLE_CHILD,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+
+
+        speed_box = XmCreateRadioBox(frame,"Config_GPS Speed_box",al,ac);
+
+        XtVaSetValues(speed_box,XmNnumColumns,3,NULL);
+
+        speed_300 = XtVaCreateManagedWidget(langcode("WPUPCFT005"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_300,XmNvalueChangedCallback,speed_toggle,"1");
+
+        speed_1200 = XtVaCreateManagedWidget(langcode("WPUPCFT006"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_1200,XmNvalueChangedCallback,speed_toggle,"2");
+
+        speed_2400 = XtVaCreateManagedWidget(langcode("WPUPCFT007"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_2400,XmNvalueChangedCallback,speed_toggle,"3");
+
+        speed_4800 = XtVaCreateManagedWidget(langcode("WPUPCFT008"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_4800,XmNvalueChangedCallback,speed_toggle,"4");
+
+        speed_9600 = XtVaCreateManagedWidget(langcode("WPUPCFT009"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_9600,XmNvalueChangedCallback,speed_toggle,"5");
+
+        speed_19200 = XtVaCreateManagedWidget(langcode("WPUPCFT010"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_19200,XmNvalueChangedCallback,speed_toggle,"6");
+
+        speed_38400 = XtVaCreateManagedWidget(langcode("WPUPCFT019"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_38400,XmNvalueChangedCallback,speed_toggle,"7");
+
+#ifndef __LSB__
+        speed_57600 = XtVaCreateManagedWidget(langcode("WPUPCFT020"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_57600,XmNvalueChangedCallback,speed_toggle,"8");
+
+        speed_115200 = XtVaCreateManagedWidget(langcode("WPUPCFT021"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_115200,XmNvalueChangedCallback,speed_toggle,"9");
+
+        speed_230400 = XtVaCreateManagedWidget(langcode("WPUPCFT022"),xmToggleButtonGadgetClass,
+            speed_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(speed_230400,XmNvalueChangedCallback,speed_toggle,"10");
+#endif  // __LSB__
+
+        frame2 = XtVaCreateManagedWidget("Config_GPS frame2", xmFrameWidgetClass, form,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, frame,
+            XmNtopOffset, 10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset, 10,
+            XmNrightAttachment, XmATTACH_FORM,
+            XmNrightOffset, 10,
+            XmNbackground, colors[0xff],
+            NULL);
+
+        style = XtVaCreateManagedWidget(langcode("WPUPCFT015"),xmLabelWidgetClass, frame2,
+            XmNchildType, XmFRAME_TITLE_CHILD,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        style_box = XmCreateRadioBox(frame2,"Config_GPS Style box",al,ac);
+
+        XtVaSetValues(style_box,
+            XmNorientation, XmHORIZONTAL,
+            NULL);
+
+        style_8n1 = XtVaCreateManagedWidget(langcode("WPUPCFT016"),xmToggleButtonGadgetClass,
+            style_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(style_8n1,XmNvalueChangedCallback,style_toggle,"0");
+
+        style_7e1 = XtVaCreateManagedWidget(langcode("WPUPCFT017"),xmToggleButtonGadgetClass,
+            style_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(style_7e1,XmNvalueChangedCallback,style_toggle,"1");
+
+        style_7o1 = XtVaCreateManagedWidget(langcode("WPUPCFT018"),xmToggleButtonGadgetClass,
+            style_box,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        XtAddCallback(style_7o1,XmNvalueChangedCallback,style_toggle,"2");
+
+        sep = XtVaCreateManagedWidget("Config_GPS sep", xmSeparatorGadgetClass,form,
+            XmNorientation, XmHORIZONTAL,
+            XmNtopAttachment,XmATTACH_WIDGET,
+            XmNtopWidget, frame2,
+            XmNtopOffset, 20,
+            XmNbottomAttachment,XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNrightAttachment,XmATTACH_FORM,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, sep,
+            XmNtopOffset, 10,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_POSITION,
+            XmNleftPosition, 1,
+            XmNrightAttachment, XmATTACH_POSITION,
+            XmNrightPosition, 2,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, sep,
+            XmNtopOffset, 10,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_POSITION,
+            XmNleftPosition, 3,
+            XmNrightAttachment, XmATTACH_POSITION,
+            XmNrightPosition, 4,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Config_GPS_change_data, config_GPS_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Config_GPS_destroy_shell, config_GPS_dialog);
+
+        pos_dialog(config_GPS_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_GPS_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_GPS_dialog, delw, Config_GPS_destroy_shell, (XtPointer)config_GPS_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            XmTextFieldSetString(GPS_device_name_data,GPS_PORT);
+            XmTextFieldSetString(GPS_comment,"");
+            XmToggleButtonSetState(GPS_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(GPS_set_time, FALSE, FALSE);
+            XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+            device_speed=4;
+            XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+            device_style=0;
+        } else {
+            /* reconfig */
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_GPS" );
+
+            XmTextFieldSetString(GPS_device_name_data,devices[GPS_port].device_name);
+            XmTextFieldSetString(GPS_comment,devices[GPS_port].comment);
+ 
+            if (devices[GPS_port].connect_on_startup)
+                XmToggleButtonSetState(GPS_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(GPS_active_on_startup,FALSE,FALSE);
+
+            if (devices[GPS_port].set_time)
+                XmToggleButtonSetState(GPS_set_time,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(GPS_set_time,FALSE,FALSE);
+
+            switch (devices[GPS_port].sp) {
+                case(B300):
+                    XmToggleButtonSetState(speed_300,TRUE,FALSE);
+                    device_speed=1;
+                    break;
+
+                case(B1200):
+                    XmToggleButtonSetState(speed_1200,TRUE,FALSE);
+                    device_speed=2;
+                    break;
+
+                case(B2400):
+                    XmToggleButtonSetState(speed_2400,TRUE,FALSE);
+                    device_speed=3;
+                    break;
+
+                case(B4800):
+                    XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+                    device_speed=4;
+                    break;
+
+                case(B9600):
+                    XmToggleButtonSetState(speed_9600,TRUE,FALSE);
+                    device_speed=5;
+                    break;
+
+                case(B19200):
+                    XmToggleButtonSetState(speed_19200,TRUE,FALSE);
+                    device_speed=6;
+                    break;
+
+                case(B38400):
+                    XmToggleButtonSetState(speed_38400,TRUE,FALSE);
+                    device_speed=7;
+                    break;
+
+#ifndef __LSB__
+                case(B57600):
+                    XmToggleButtonSetState(speed_57600,TRUE,FALSE);
+                    device_speed=8;
+                    break;
+
+                case(B115200):
+                    XmToggleButtonSetState(speed_115200,TRUE,FALSE);
+                    device_speed=9;
+                    break;
+
+#ifdef B230400
+                case(B230400):
+                    XmToggleButtonSetState(speed_230400,TRUE,FALSE);
+                    device_speed=10;
+                    break;
+#endif  // B230400
+#endif  // __LSB__
+
+                default:
+                    XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+                    device_speed=4;
+                    break;
+            }
+            switch (devices[GPS_port].style) {
+                case(0):
+                    XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+                    device_style=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(style_7e1,TRUE,FALSE);
+                    device_style=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(style_7o1,TRUE,FALSE);
+                    device_style=2;
+                    break;
+
+                default:
+                    XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+                    device_style=0;
+                    break;
+            }
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_GPS" );
+
+        }
+        XtManageChild(form);
+        XtManageChild(speed_box);
+        XtManageChild(style_box);
+        XtManageChild(pane);
+
+        XtPopup(config_GPS_dialog,XtGrabNone);
+        fix_dialog_size(config_GPS_dialog);
+    } else
+        (void)XRaiseWindow(XtDisplay(config_GPS_dialog), XtWindow(config_GPS_dialog));
+}
+
+
+
+
+
+/*****************************************************/
+/* Configure Serial WX GUI                          */
+/*****************************************************/
+
+/**** WX CONFIGURE ******/
+int WX_port;
+int WX_rain_gauge_type;
+Widget config_WX_dialog = (Widget)NULL;
+Widget WX_transmit_data;
+Widget WX_device_name_data;
+Widget WX_comment;
+Widget WX_active_on_startup;
+Widget WX_tenths, WX_hundredths, WX_millimeters;
+ 
+
+
+
+
+void Config_WX_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_WX_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+ 
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Config_WX_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+    was_up=0;
+    if (get_device_status(WX_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(WX_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_WX_change_data" );
+
+    temp_ptr = XmTextFieldGetString(WX_device_name_data);
+    xastir_snprintf(devices[WX_port].device_name,
+        sizeof(devices[WX_port].device_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[WX_port].device_name);
+
+    temp_ptr = XmTextFieldGetString(WX_comment);
+    xastir_snprintf(devices[WX_port].comment,
+        sizeof(devices[WX_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[WX_port].comment);
+
+    if(XmToggleButtonGetState(WX_active_on_startup))
+        devices[WX_port].connect_on_startup=1;
+    else
+        devices[WX_port].connect_on_startup=0;
+
+    set_port_speed(WX_port);
+    devices[WX_port].style=device_style;
+
+    xastir_snprintf(devices[WX_port].device_host_pswd,
+            sizeof( devices[WX_port].device_host_pswd), "%d", device_data_type);
+
+    /* reopen */
+    if ( was_up) {
+        (void)add_device(WX_port,
+            DEVICE_SERIAL_WX,
+            devices[WX_port].device_name,
+            devices[WX_port].device_host_pswd,
+            -1,
+            devices[WX_port].sp,
+            devices[WX_port].style,
+            0,
+            "");
+    }
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[WX_port].device_type=DEVICE_SERIAL_WX;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_WX_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Config_WX_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_WX( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel,
+                frame, frame2, frame3, frame4, WX_none,
+                device, comment, speed, speed_box,
+                speed_300, speed_1200, speed_2400, speed_4800, speed_9600,
+                speed_19200, speed_38400;
+#ifndef __LSB__
+    static Widget speed_57600, speed_115200, speed_230400;
+#endif  // __LSB__
+    static Widget style, style_box,
+                style_8n1, style_7e1, style_7o1,
+                data_type, data_box,
+                data_auto, data_bin, data_ascii,
+                gauge_type, gauge_box,
+                sep;
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+    if(!config_WX_dialog) {
+        WX_port=port;
+        config_WX_dialog = XtVaCreatePopupShell(langcode("WPUPCFWX01"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_WX pane",xmPanedWindowWidgetClass, config_WX_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_WX form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        device = XtVaCreateManagedWidget(langcode("WPUPCFWX02"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_device_name_data = XtVaCreateManagedWidget("Config_WX device_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, device,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, device,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_comment = XtVaCreateManagedWidget("Config_WX comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, device,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_active_on_startup = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, comment,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        frame = XtVaCreateManagedWidget("Config_WX frame", xmFrameWidgetClass, form,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopOffset,10,
+                                    XmNtopWidget, WX_active_on_startup,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_FORM,
+                                    XmNrightOffset, 10,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        speed = XtVaCreateManagedWidget(langcode("WPUPCFT004"),xmLabelWidgetClass, frame,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+
+
+        speed_box = XmCreateRadioBox(frame,"Config_WX Speed_box",al,ac);
+
+        XtVaSetValues(speed_box,
+                  XmNnumColumns,3,
+                  NULL);
+
+        speed_300 = XtVaCreateManagedWidget(langcode("WPUPCFT005"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_300,XmNvalueChangedCallback,speed_toggle,"1");
+
+        speed_1200 = XtVaCreateManagedWidget(langcode("WPUPCFT006"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_1200,XmNvalueChangedCallback,speed_toggle,"2");
+
+        speed_2400 = XtVaCreateManagedWidget(langcode("WPUPCFT007"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_2400,XmNvalueChangedCallback,speed_toggle,"3");
+
+        speed_4800 = XtVaCreateManagedWidget(langcode("WPUPCFT008"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_4800,XmNvalueChangedCallback,speed_toggle,"4");
+
+        speed_9600 = XtVaCreateManagedWidget(langcode("WPUPCFT009"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_9600,XmNvalueChangedCallback,speed_toggle,"5");
+
+        speed_19200 = XtVaCreateManagedWidget(langcode("WPUPCFT010"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_19200,XmNvalueChangedCallback,speed_toggle,"6");
+
+        speed_38400 = XtVaCreateManagedWidget(langcode("WPUPCFT019"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_38400,XmNvalueChangedCallback,speed_toggle,"7");
+
+#ifndef __LSB__
+        speed_57600 = XtVaCreateManagedWidget(langcode("WPUPCFT020"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_57600,XmNvalueChangedCallback,speed_toggle,"8");
+
+        speed_115200 = XtVaCreateManagedWidget(langcode("WPUPCFT021"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_115200,XmNvalueChangedCallback,speed_toggle,"9");
+
+        speed_230400 = XtVaCreateManagedWidget(langcode("WPUPCFT022"),xmToggleButtonGadgetClass,
+                                        speed_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(speed_230400,XmNvalueChangedCallback,speed_toggle,"10");
+#endif  // __LSB__
+
+        frame2 = XtVaCreateManagedWidget("Config_WX frame2", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+                                     XmNtopWidget, frame,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     NULL);
+
+        style = XtVaCreateManagedWidget(langcode("WPUPCFT015"),xmLabelWidgetClass, frame2,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        style_box = XmCreateRadioBox(frame2,"Config_WX Style box",al,ac);
+
+        XtVaSetValues(style_box,
+                  XmNorientation, XmHORIZONTAL,
+                  NULL);
+
+        style_8n1 = XtVaCreateManagedWidget(langcode("WPUPCFT016"),xmToggleButtonGadgetClass,
+                                        style_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(style_8n1,XmNvalueChangedCallback,style_toggle,"0");
+
+        style_7e1 = XtVaCreateManagedWidget(langcode("WPUPCFT017"),xmToggleButtonGadgetClass,
+                                        style_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(style_7e1,XmNvalueChangedCallback,style_toggle,"1");
+
+        style_7o1 = XtVaCreateManagedWidget(langcode("WPUPCFT018"),xmToggleButtonGadgetClass,
+                                        style_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(style_7o1,XmNvalueChangedCallback,style_toggle,"2");
+
+        frame3 = XtVaCreateManagedWidget("Config_WX frame3", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+                                     XmNtopWidget, frame2,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     NULL);
+
+        data_type= XtVaCreateManagedWidget(langcode("WPUPCFT024"),xmLabelWidgetClass, frame3,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        data_box = XmCreateRadioBox(frame3,"Config_WX data box",al,ac);
+
+        XtVaSetValues(data_box,
+                  XmNorientation, XmHORIZONTAL,
+                  NULL);
+
+        data_auto = XtVaCreateManagedWidget(langcode("WPUPCFT025"),xmToggleButtonGadgetClass,
+                                        data_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(data_auto,XmNvalueChangedCallback,data_toggle,"0");
+
+        data_bin = XtVaCreateManagedWidget(langcode("WPUPCFT026"),xmToggleButtonGadgetClass,
+                                        data_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(data_bin,XmNvalueChangedCallback,data_toggle,"1");
+
+        data_ascii = XtVaCreateManagedWidget(langcode("WPUPCFT027"),xmToggleButtonGadgetClass,
+                                        data_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(data_ascii,XmNvalueChangedCallback,data_toggle,"2");
+
+        frame4 = XtVaCreateManagedWidget("Config_WX frame4", xmFrameWidgetClass, form,
+                                        XmNtopAttachment, XmATTACH_WIDGET,
+                                        XmNtopWidget, frame3,
+                                        XmNtopOffset, 10,
+                                        XmNbottomAttachment, XmATTACH_NONE,
+                                        XmNleftAttachment, XmATTACH_FORM,
+                                        XmNleftOffset, 10,
+                                        XmNrightAttachment, XmATTACH_FORM,
+                                        XmNrightOffset, 10,
+                                        XmNbackground, colors[0xff],
+                                        NULL);
+
+        // Rain Gauge Type
+        gauge_type= XtVaCreateManagedWidget(langcode("WPUPCFWX03"),xmLabelWidgetClass, frame4,
+                                        XmNchildType, XmFRAME_TITLE_CHILD,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+
+        gauge_box = XmCreateRadioBox(frame4,"Config_WX gauge box",al,ac);
+
+        XtVaSetValues(gauge_box,
+            XmNorientation, XmHORIZONTAL,
+            NULL);
+
+        WX_none = XtVaCreateManagedWidget(langcode("WPUPCFWX07"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        WX_tenths = XtVaCreateManagedWidget(langcode("WPUPCFWX04"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        WX_hundredths = XtVaCreateManagedWidget(langcode("WPUPCFWX05"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        WX_millimeters = XtVaCreateManagedWidget(langcode("WPUPCFWX06"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(WX_none,XmNvalueChangedCallback,rain_gauge_toggle,"0");
+        XtAddCallback(WX_tenths,XmNvalueChangedCallback,rain_gauge_toggle,"1");
+        XtAddCallback(WX_hundredths,XmNvalueChangedCallback,rain_gauge_toggle,"2");
+        XtAddCallback(WX_millimeters,XmNvalueChangedCallback,rain_gauge_toggle,"3");
+
+        sep = XtVaCreateManagedWidget("Config_WX sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, frame4,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Config_WX_change_data, config_WX_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Config_WX_destroy_shell, config_WX_dialog);
+
+        pos_dialog(config_WX_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_WX_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_WX_dialog, delw, Config_WX_destroy_shell, (XtPointer)config_WX_dialog);
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_WX" );
+
+        if (config_type==0) {
+            /* first time port */
+            XmTextFieldSetString(WX_device_name_data,GPS_PORT);
+            XmTextFieldSetString(WX_comment,"");
+            XmToggleButtonSetState(WX_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(speed_2400,TRUE,FALSE);
+            device_speed=3;
+            XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+            device_style=0;
+            device_data_type=0;
+            XmToggleButtonSetState(data_auto,TRUE,FALSE);
+        } else {
+            /* reconfig */
+            XmTextFieldSetString(WX_device_name_data,devices[WX_port].device_name);
+            XmTextFieldSetString(WX_comment,devices[WX_port].comment);
+ 
+            if (devices[WX_port].connect_on_startup)
+                XmToggleButtonSetState(WX_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(WX_active_on_startup,FALSE,FALSE);
+
+            switch (devices[WX_port].sp) {
+                case(B300):
+                    XmToggleButtonSetState(speed_300,TRUE,FALSE);
+                    device_speed=1;
+                    break;
+
+                case(B1200):
+                    XmToggleButtonSetState(speed_1200,TRUE,FALSE);
+                    device_speed=2;
+                    break;
+
+                case(B2400):
+                    XmToggleButtonSetState(speed_2400,TRUE,FALSE);
+                    device_speed=3;
+                    break;
+
+                case(B4800):
+                    XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+                    device_speed=4;
+                    break;
+
+                case(B9600):
+                    XmToggleButtonSetState(speed_9600,TRUE,FALSE);
+                    device_speed=5;
+                    break;
+
+                case(B19200):
+                    XmToggleButtonSetState(speed_19200,TRUE,FALSE);
+                    device_speed=6;
+                    break;
+
+                case(B38400):
+                    XmToggleButtonSetState(speed_38400,TRUE,FALSE);
+                    device_speed=7;
+                    break;
+
+#ifndef __LSB__
+                case(B57600):
+                    XmToggleButtonSetState(speed_57600,TRUE,FALSE);
+                    device_speed=8;
+                    break;
+
+                case(B115200):
+                    XmToggleButtonSetState(speed_115200,TRUE,FALSE);
+                    device_speed=9;
+                    break;
+
+#ifdef B230400
+                case(B230400):
+                    XmToggleButtonSetState(speed_230400,TRUE,FALSE);
+                    device_speed=10;
+                    break;
+#endif  // B230400
+#endif  // __LSB__
+
+                default:
+                    XmToggleButtonSetState(speed_4800,TRUE,FALSE);
+                    device_speed=4;
+                    break;
+            }
+            switch (devices[WX_port].style) {
+                case(0):
+                    XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+                    device_style=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(style_7e1,TRUE,FALSE);
+                    device_style=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(style_7o1,TRUE,FALSE);
+                    device_style=2;
+                    break;
+
+                default:
+                    XmToggleButtonSetState(style_8n1,TRUE,FALSE);
+                    device_style=0;
+                    break;
+            }
+            switch (atoi(devices[WX_port].device_host_pswd)) {
+                case(0):
+                    XmToggleButtonSetState(data_auto,TRUE,FALSE);
+                    device_data_type=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(data_bin,TRUE,FALSE);
+                    device_data_type=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(data_ascii,TRUE,FALSE);
+                    device_data_type=2;
+                    break;
+
+                default:
+                    device_data_type=0;
+                    break;
+            }
+        }
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_WX" );
+
+        XmToggleButtonSetState(WX_none,FALSE,FALSE);
+        XmToggleButtonSetState(WX_tenths,FALSE,FALSE);
+        XmToggleButtonSetState(WX_hundredths,FALSE,FALSE);
+        XmToggleButtonSetState(WX_millimeters,FALSE,FALSE);
+        switch (WX_rain_gauge_type) {
+            case(1):
+                XmToggleButtonSetState(WX_tenths,TRUE,FALSE);
+                break;
+            case(2):
+                XmToggleButtonSetState(WX_hundredths,TRUE,FALSE);
+                break;
+            case(3):
+                XmToggleButtonSetState(WX_millimeters,TRUE,FALSE);
+                break;
+            default:
+                XmToggleButtonSetState(WX_none,TRUE,FALSE);
+                break;
+        }
+
+        XtManageChild(form);
+        XtManageChild(speed_box);
+        XtManageChild(style_box);
+        XtManageChild(data_box);
+        XtManageChild(gauge_box);
+        XtManageChild(pane);
+
+        XtPopup(config_WX_dialog,XtGrabNone);
+        fix_dialog_size(config_WX_dialog);
+    } else
+        (void)XRaiseWindow(XtDisplay(config_WX_dialog), XtWindow(config_WX_dialog));
+
+}
+
+
+
+
+
+/**** net WX CONFIGURE ******/
+int NWX_port;
+Widget config_NWX_dialog = (Widget)NULL;
+Widget NWX_host_name_data;
+Widget NWX_host_port_data;
+Widget NWX_comment;
+Widget NWX_active_on_startup;
+Widget NWX_host_reconnect_data;
+
+
+
+
+
+void Config_NWX_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_NWX_dialog = (Widget)NULL;
+
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Config_NWX_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+
+    was_up=0;
+    if (get_device_status(NWX_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(NWX_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_NWX_change_data" );
+
+    temp_ptr = XmTextFieldGetString(NWX_host_name_data);
+    xastir_snprintf(devices[NWX_port].device_host_name,
+        sizeof(devices[NWX_port].device_host_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[NWX_port].device_host_name);
+
+    temp_ptr = XmTextFieldGetString(NWX_host_port_data);
+    devices[NWX_port].sp=atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(NWX_comment);
+    xastir_snprintf(devices[NWX_port].comment,
+        sizeof(devices[NWX_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[NWX_port].comment);
+
+    if (XmToggleButtonGetState(NWX_active_on_startup))
+        devices[NWX_port].connect_on_startup=1;
+    else
+        devices[NWX_port].connect_on_startup=0;
+
+    if(XmToggleButtonGetState(NWX_host_reconnect_data))
+        devices[NWX_port].reconnect=1;
+    else
+        devices[NWX_port].reconnect=0;
+
+    xastir_snprintf(devices[NWX_port].device_host_pswd,
+            sizeof(devices[NWX_port].device_host_pswd), "%d", device_data_type);
+
+    /* reopen if was up*/
+    if ( was_up) {
+        (void)add_device(NWX_port,
+            DEVICE_NET_WX,
+            devices[NWX_port].device_host_name,
+            devices[NWX_port].device_host_pswd,
+            devices[NWX_port].sp,
+            0,
+            0,
+            devices[NWX_port].reconnect,
+            "");
+    }
+
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[NWX_port].device_type=DEVICE_NET_WX;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_NWX_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Config_NWX_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_NWX( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, frame3, frame4, WX_none,
+                button_ok, button_cancel,
+                hostn, portn, comment,
+                data_type, data_box,
+                data_auto, data_bin, data_ascii,
+                gauge_type, gauge_box,
+                sep;
+    char temp[20];
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+    Atom delw;
+
+    if(!config_NWX_dialog) {
+        NWX_port=port;
+        config_NWX_dialog = XtVaCreatePopupShell(langcode("WPUPCFG021"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_NWX pane",xmPanedWindowWidgetClass, config_NWX_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_NWX form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        hostn = XtVaCreateManagedWidget(langcode("WPUPCFG022"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NWX_host_name_data = XtVaCreateManagedWidget("Config_NWX host_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, hostn,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        portn = XtVaCreateManagedWidget(langcode("WPUPCFG023"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, hostn,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NWX_host_port_data = XtVaCreateManagedWidget("Config_NWX port_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, hostn,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, portn,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, portn,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NWX_comment = XtVaCreateManagedWidget("Config_NWX comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, portn,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NWX_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, comment,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NWX_host_reconnect_data  = XtVaCreateManagedWidget(langcode("WPUPCFG020"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, NWX_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+
+
+        frame3 = XtVaCreateManagedWidget("Config_NWX frame3", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+                                     XmNtopWidget, NWX_host_reconnect_data,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     NULL);
+
+        data_type= XtVaCreateManagedWidget(langcode("WPUPCFT024"),xmLabelWidgetClass, frame3,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        data_box = XmCreateRadioBox(frame3,"Config_NWX data box",al,ac);
+
+        XtVaSetValues(data_box,
+                  XmNorientation, XmHORIZONTAL,
+                  NULL);
+
+        data_auto = XtVaCreateManagedWidget(langcode("WPUPCFT025"),xmToggleButtonGadgetClass,
+                                        data_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(data_auto,XmNvalueChangedCallback,data_toggle,"0");
+
+        data_bin = XtVaCreateManagedWidget(langcode("WPUPCFT026"),xmToggleButtonGadgetClass,
+                                        data_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(data_bin,XmNvalueChangedCallback,data_toggle,"1");
+
+        data_ascii = XtVaCreateManagedWidget(langcode("WPUPCFT027"),xmToggleButtonGadgetClass,
+                                        data_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(data_ascii,XmNvalueChangedCallback,data_toggle,"2");
+
+        frame4 = XtVaCreateManagedWidget("Config_WX frame4", xmFrameWidgetClass, form,
+                                        XmNtopAttachment, XmATTACH_WIDGET,
+                                        XmNtopWidget, frame3,
+                                        XmNtopOffset, 10,
+                                        XmNbottomAttachment, XmATTACH_NONE,
+                                        XmNleftAttachment, XmATTACH_FORM,
+                                        XmNleftOffset, 10,
+                                        XmNrightAttachment, XmATTACH_FORM,
+                                        XmNrightOffset, 10,
+                                        XmNbackground, colors[0xff],
+                                        NULL);
+
+        // Rain Gauge Type
+        gauge_type= XtVaCreateManagedWidget(langcode("WPUPCFWX03"),xmLabelWidgetClass, frame4,
+                                        XmNchildType, XmFRAME_TITLE_CHILD,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+
+        gauge_box = XmCreateRadioBox(frame4,"Config_WX gauge box",al,ac);
+
+        XtVaSetValues(gauge_box,
+            XmNorientation, XmHORIZONTAL,
+            NULL);
+
+        WX_none = XtVaCreateManagedWidget(langcode("WPUPCFWX07"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        WX_tenths = XtVaCreateManagedWidget(langcode("WPUPCFWX04"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        WX_hundredths = XtVaCreateManagedWidget(langcode("WPUPCFWX05"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+        WX_millimeters = XtVaCreateManagedWidget(langcode("WPUPCFWX06"),xmToggleButtonGadgetClass,
+                                      gauge_box,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(WX_none,XmNvalueChangedCallback,rain_gauge_toggle,"0");
+        XtAddCallback(WX_tenths,XmNvalueChangedCallback,rain_gauge_toggle,"1");
+        XtAddCallback(WX_hundredths,XmNvalueChangedCallback,rain_gauge_toggle,"2");
+        XtAddCallback(WX_millimeters,XmNvalueChangedCallback,rain_gauge_toggle,"3");
+
+
+        sep = XtVaCreateManagedWidget("Config_NWX sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, frame4,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Config_NWX_change_data, config_NWX_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Config_NWX_destroy_shell, config_NWX_dialog);
+
+        pos_dialog(config_NWX_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_NWX_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_NWX_dialog, delw, Config_NWX_destroy_shell, (XtPointer)config_NWX_dialog);
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_NWX" );
+
+        if (config_type==0) {
+            /* first time port */
+            XmTextFieldSetString(NWX_host_name_data,"localhost");
+            XmTextFieldSetString(NWX_host_port_data,"1234");
+            XmTextFieldSetString(NWX_comment,"");
+            XmToggleButtonSetState(NWX_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(NWX_host_reconnect_data,TRUE,FALSE);
+            device_data_type=0;
+            XmToggleButtonSetState(data_auto,TRUE,FALSE);
+        } else {
+            /* reconfig */
+
+            XmTextFieldSetString(NWX_host_name_data,devices[NWX_port].device_host_name);
+            xastir_snprintf(temp, sizeof(temp), "%d", devices[NWX_port].sp); /* port number */
+            XmTextFieldSetString(NWX_host_port_data,temp);
+
+            XmTextFieldSetString(NWX_comment,devices[NWX_port].comment);
+ 
+            if (devices[NWX_port].connect_on_startup)
+                XmToggleButtonSetState(NWX_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(NWX_active_on_startup,FALSE,FALSE);
+
+            if (devices[NWX_port].reconnect)
+                XmToggleButtonSetState(NWX_host_reconnect_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(NWX_host_reconnect_data,FALSE,FALSE);
+
+            switch (atoi(devices[NWX_port].device_host_pswd)) {
+                case(0):
+                    XmToggleButtonSetState(data_auto,TRUE,FALSE);
+                    device_data_type=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(data_bin,TRUE,FALSE);
+                    device_data_type=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(data_ascii,TRUE,FALSE);
+                    device_data_type=2;
+                    break;
+
+                default:
+                    device_data_type=0;
+                    break;
+            }
+        }
+
+        XmToggleButtonSetState(WX_none,FALSE,FALSE);
+        XmToggleButtonSetState(WX_tenths,FALSE,FALSE);
+        XmToggleButtonSetState(WX_hundredths,FALSE,FALSE);
+        XmToggleButtonSetState(WX_millimeters,FALSE,FALSE);
+        switch (WX_rain_gauge_type) {
+            case(1):
+                XmToggleButtonSetState(WX_tenths,TRUE,FALSE);
+                break;
+            case(2):
+                XmToggleButtonSetState(WX_hundredths,TRUE,FALSE);
+                break;
+            case(3):
+                XmToggleButtonSetState(WX_millimeters,TRUE,FALSE);
+                break;
+            default:
+                XmToggleButtonSetState(WX_none,TRUE,FALSE);
+                break;
+        }
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_NWX" );
+
+        XtManageChild(form);
+        XtManageChild(data_box);
+        XtManageChild(frame3);
+        XtManageChild(gauge_box);
+        XtManageChild(pane);
+
+        XtPopup(config_NWX_dialog,XtGrabNone);
+        fix_dialog_size(config_NWX_dialog);
+    } else {
+        (void)XRaiseWindow(XtDisplay(config_NWX_dialog), XtWindow(config_NWX_dialog));
+    }
+}
+
+
+
+
+
+/*****************************************************/
+/* Configure net GPS GUI                             */
+/*****************************************************/
+
+/**** net GPS CONFIGURE ******/
+int NGPS_port;
+Widget config_NGPS_dialog = (Widget)NULL;
+Widget NGPS_host_name_data;
+Widget NGPS_host_port_data;
+Widget NGPS_comment;
+Widget NGPS_active_on_startup;
+Widget NGPS_host_reconnect_data;
+Widget NGPS_set_time;
+
+
+
+
+
+
+void Config_NGPS_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_NGPS_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Config_NGPS_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+    was_up=0;
+    if (get_device_status(NGPS_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(NGPS_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_NGPS_change_data" );
+
+    temp_ptr = XmTextFieldGetString(NGPS_host_name_data);
+    xastir_snprintf(devices[NGPS_port].device_host_name,
+        sizeof(devices[NGPS_port].device_host_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[NGPS_port].device_host_name);
+
+    temp_ptr = XmTextFieldGetString(NGPS_host_port_data);
+    devices[NGPS_port].sp=atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(NGPS_comment);
+    xastir_snprintf(devices[NGPS_port].comment,
+        sizeof(devices[NGPS_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[NGPS_port].comment);
+
+    if(XmToggleButtonGetState(NGPS_active_on_startup))
+        devices[NGPS_port].connect_on_startup=1;
+    else
+        devices[NGPS_port].connect_on_startup=0;
+
+    if (XmToggleButtonGetState(NGPS_host_reconnect_data))
+        devices[NGPS_port].reconnect=1;
+    else
+        devices[NGPS_port].reconnect=0;
+
+    if (XmToggleButtonGetState(NGPS_set_time))
+        devices[NGPS_port].set_time=1;
+    else
+        devices[NGPS_port].set_time=0;
+
+    /* reopen */
+    if ( was_up ) {
+        (void)add_device(NGPS_port,
+            DEVICE_NET_GPSD,
+            devices[NGPS_port].device_host_name,
+            "",
+            devices[NGPS_port].sp,
+            0,
+            0,
+            devices[NGPS_port].reconnect,
+            "");
+    }
+
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[NGPS_port].device_type=DEVICE_NET_GPSD;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_NGPS_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Config_NGPS_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_NGPS( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel,
+                hostn, portn, comment,
+                sep;
+    char temp[20];
+    Atom delw;
+
+    if (!config_NGPS_dialog) {
+        NGPS_port=port;
+        config_NGPS_dialog = XtVaCreatePopupShell(langcode("WPUPCFG019"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_NGPS pane",xmPanedWindowWidgetClass, config_NGPS_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_NGPS form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        hostn = XtVaCreateManagedWidget(langcode("WPUPCFG017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NGPS_host_name_data = XtVaCreateManagedWidget("Config_NGPS host_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, hostn,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        portn = XtVaCreateManagedWidget(langcode("WPUPCFG018"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, hostn,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NGPS_host_port_data = XtVaCreateManagedWidget("Config_NGPS port_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, hostn,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, portn,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, portn,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NGPS_comment = XtVaCreateManagedWidget("Config_NGPS comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, portn,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NGPS_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, comment,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NGPS_host_reconnect_data  = XtVaCreateManagedWidget(langcode("WPUPCFG020"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, NGPS_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        NGPS_set_time  = XtVaCreateManagedWidget(langcode("UNIOP00029"), xmToggleButtonWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, NGPS_host_reconnect_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+// We can only set the time properly on Linux systems
+#ifndef HAVE_SETTIMEOFDAY
+        XtSetSensitive(NGPS_set_time,FALSE);
+#endif  // HAVE_SETTIMEOFDAY
+#ifdef __CYGWIN__
+        XtSetSensitive(NGPS_set_time,FALSE);
+#endif  // __CYGWIN__
+
+
+ 
+        sep = XtVaCreateManagedWidget("Config_NGPS sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, NGPS_set_time,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Config_NGPS_change_data, config_NGPS_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Config_NGPS_destroy_shell, config_NGPS_dialog);
+
+        pos_dialog(config_NGPS_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_NGPS_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_NGPS_dialog, delw, Config_NGPS_destroy_shell, (XtPointer)config_NGPS_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            XmTextFieldSetString(NGPS_host_name_data,"localhost");
+            XmTextFieldSetString(NGPS_host_port_data,"2947");
+            XmTextFieldSetString(NGPS_comment,"");
+            XmToggleButtonSetState(NGPS_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(NGPS_host_reconnect_data,TRUE,FALSE);
+            XmToggleButtonSetState(NGPS_set_time, FALSE, FALSE);
+        } else {
+            /* reconfig */
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_NGPS" );
+
+            XmTextFieldSetString(NGPS_host_name_data,devices[NGPS_port].device_host_name);
+            xastir_snprintf(temp, sizeof(temp), "%d", devices[NGPS_port].sp); /* port number */
+            XmTextFieldSetString(NGPS_host_port_data,temp);
+            XmTextFieldSetString(NGPS_comment,devices[NGPS_port].comment);
+
+            if (devices[NGPS_port].connect_on_startup)
+                XmToggleButtonSetState(NGPS_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(NGPS_active_on_startup,FALSE,FALSE);
+
+            if (devices[NGPS_port].reconnect)
+                XmToggleButtonSetState(NGPS_host_reconnect_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(NGPS_host_reconnect_data,FALSE,FALSE);
+
+            if (devices[NGPS_port].set_time)
+                XmToggleButtonSetState(NGPS_set_time, TRUE, FALSE);
+            else
+                XmToggleButtonSetState(NGPS_set_time, FALSE, FALSE);
+ 
+end_critical_section(&devices_lock, "interface_gui.c:Config_NGPS" );
+
+        }
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(config_NGPS_dialog,XtGrabNone);
+        fix_dialog_size(config_NGPS_dialog);
+    } else
+        (void)XRaiseWindow(XtDisplay(config_NGPS_dialog), XtWindow(config_NGPS_dialog));
+}
+
+
+
+
+
+/*****************************************************/
+/* Configure AX.25 TNC GUI                           */
+/*****************************************************/
+
+/**** AX.25 CONFIGURE ******/
+int AX25_port;
+Widget config_AX25_dialog = (Widget)NULL;
+Widget AX25_device_name_data;
+Widget AX25_comment;
+Widget AX25_unproto1_data;
+Widget AX25_unproto2_data;
+Widget AX25_unproto3_data;
+Widget AX25_igate_data;
+Widget AX25_active_on_startup;
+Widget AX25_transmit_data;
+Widget AX25_relay_digipeat;
+
+
+
+
+
+void Config_AX25_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_AX25_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Config_AX25_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+    busy_cursor(appshell);
+
+    was_up=0;
+    if (get_device_status(AX25_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(AX25_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_AX25_change_data" );
+
+    temp_ptr = XmTextFieldGetString(AX25_device_name_data);
+    xastir_snprintf(devices[AX25_port].device_name,
+        sizeof(devices[AX25_port].device_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AX25_port].device_name);
+
+    temp_ptr = XmTextFieldGetString(AX25_comment);
+    xastir_snprintf(devices[AX25_port].comment,
+        sizeof(devices[AX25_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AX25_port].comment);
+
+    if(XmToggleButtonGetState(AX25_active_on_startup))
+        devices[AX25_port].connect_on_startup=1;
+    else
+        devices[AX25_port].connect_on_startup=0;
+
+    if(XmToggleButtonGetState(AX25_transmit_data)) {
+        devices[AX25_port].transmit_data=1;
+        XtSetSensitive(AX25_relay_digipeat, TRUE);
+    }
+    else {
+        devices[AX25_port].transmit_data=0;
+        XtSetSensitive(AX25_relay_digipeat, FALSE);
+    }
+
+    if(XmToggleButtonGetState(AX25_relay_digipeat))
+        devices[AX25_port].relay_digipeat=1;
+    else
+        devices[AX25_port].relay_digipeat=0;
+
+    devices[AX25_port].igate_options=device_igate_options;
+
+    temp_ptr = XmTextFieldGetString(AX25_unproto1_data);
+    xastir_snprintf(devices[AX25_port].unproto1,
+        sizeof(devices[AX25_port].unproto1),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AX25_port].unproto1);
+
+    if(check_unproto_path(devices[AX25_port].unproto1)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(AX25_unproto2_data);
+    xastir_snprintf(devices[AX25_port].unproto2,
+        sizeof(devices[AX25_port].unproto2),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    
+    (void)remove_trailing_spaces(devices[AX25_port].unproto2);
+
+    if(check_unproto_path(devices[AX25_port].unproto2)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(AX25_unproto3_data);
+    xastir_snprintf(devices[AX25_port].unproto3,
+        sizeof(devices[AX25_port].unproto3),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+ 
+    (void)remove_trailing_spaces(devices[AX25_port].unproto3);
+
+    if(check_unproto_path(devices[AX25_port].unproto3)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(AX25_igate_data);
+    xastir_snprintf(devices[AX25_port].unproto_igate,
+        sizeof(devices[AX25_port].unproto_igate),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AX25_port].unproto_igate);
+
+    if(check_unproto_path(devices[AX25_port].unproto_igate)) {
+        popup_message_always(langcode("WPUPCFT044"),
+            langcode("WPUPCFT043"));
+    }
+
+
+    devices[AX25_port].reconnect=1;
+
+// reopen if open before - n8ysz 20041213
+//    if (devices[AX25_port].connect_on_startup==1 || was_up) {
+    if ( was_up) {
+        (void)add_device(AX25_port,
+            DEVICE_AX25_TNC,
+            devices[AX25_port].device_name,
+            "",
+            -1,
+            -1,
+            -1,
+            0,
+            "");
+    }
+
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[AX25_port].device_type=DEVICE_AX25_TNC;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_AX25_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Config_AX25_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_AX25( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel, frame,
+                devn, comment,
+                proto, proto1, proto2, proto3,
+                igate, igate_box,
+                igate_o_0, igate_o_1, igate_o_2,
+                igate_label,
+                sep;
+
+    char temp[50];
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+    if(!config_AX25_dialog) {
+        AX25_port=port;
+        config_AX25_dialog = XtVaCreatePopupShell(langcode("WPUPCAX001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_AX25 pane",xmPanedWindowWidgetClass, config_AX25_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_AX25 form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        AX25_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_transmit_data = XtVaCreateManagedWidget(langcode("UNIOP00010"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AX25_active_on_startup,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_relay_digipeat = XtVaCreateManagedWidget(langcode("UNIOP00030"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AX25_transmit_data,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        devn = XtVaCreateManagedWidget(langcode("WPUPCAX002"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_device_name_data = XtVaCreateManagedWidget("Config_AX25 device_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_active_on_startup,
+                                      XmNtopOffset, 2,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, devn,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AX25_device_name_data,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_comment = XtVaCreateManagedWidget("Config_AX25 comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_active_on_startup,
+                                      XmNtopOffset, 2,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        frame = XtVaCreateManagedWidget("Config_AX25 frame", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+                                     XmNtopWidget, devn,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     NULL);
+
+        igate = XtVaCreateManagedWidget(langcode("IGPUPCF000"),xmLabelWidgetClass, frame,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        /* set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+
+
+        igate_box = XmCreateRadioBox(frame,"Config_AX25 IGate box",al,ac);
+
+        XtVaSetValues(igate_box,
+                  XmNorientation, XmVERTICAL,
+                  XmNnumColumns,2,
+                  NULL);
+
+        igate_o_0 = XtVaCreateManagedWidget(langcode("IGPUPCF001"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+
+        XtAddCallback(igate_o_0,XmNvalueChangedCallback,igate_toggle,"0");
+
+        igate_o_1 = XtVaCreateManagedWidget(langcode("IGPUPCF002"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+
+        XtAddCallback(igate_o_1,XmNvalueChangedCallback,igate_toggle,"1");
+
+        igate_o_2 = XtVaCreateManagedWidget(langcode("IGPUPCF003"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+
+        XtAddCallback(igate_o_2,XmNvalueChangedCallback,igate_toggle,"2");
+
+        proto = XtVaCreateManagedWidget(langcode("WPUPCFT011"), xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, frame,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset,5,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset,5,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT012"), VERSIONFRM);
+
+        proto1 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 60,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_unproto1_data = XtVaCreateManagedWidget("Config_AX25 protopath1", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, proto1,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT013"), VERSIONFRM);
+
+        proto2 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto1,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 60,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_unproto2_data = XtVaCreateManagedWidget("Config_AX25 protopath2", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_unproto1_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, proto2,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT014"), VERSIONFRM);
+
+        proto3 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto2,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 60,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_unproto3_data = XtVaCreateManagedWidget("Config_AX25 protopath3", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_unproto2_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, proto3,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("IGPUPCF004"));
+        igate_label = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto3,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 60,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AX25_igate_data = XtVaCreateManagedWidget("Config_TNC igate_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AX25_unproto3_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, igate_label,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        sep = XtVaCreateManagedWidget("Config_AX25 sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, igate_label,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+#ifdef HAVE_LIBAX25
+        XtAddCallback(button_ok, XmNactivateCallback, Config_AX25_change_data, config_AX25_dialog);
+#endif /* USE_AX25 */
+        XtAddCallback(button_cancel, XmNactivateCallback, Config_AX25_destroy_shell, config_AX25_dialog);
+
+        pos_dialog(config_AX25_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_AX25_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_AX25_dialog, delw, Config_AX25_destroy_shell, (XtPointer)config_AX25_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            XmToggleButtonSetState(AX25_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(AX25_transmit_data,TRUE,FALSE);
+            XmToggleButtonSetState(AX25_relay_digipeat,FALSE,FALSE);
+            XmTextFieldSetString(AX25_device_name_data,"");
+            XmTextFieldSetString(AX25_comment,"");
+            device_igate_options=0;
+            XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+            XmTextFieldSetString(AX25_unproto1_data,"WIDE2-2");
+            XmTextFieldSetString(AX25_unproto2_data,"");
+            XmTextFieldSetString(AX25_unproto3_data,"");
+            XmTextFieldSetString(AX25_igate_data,"");
+        } else {
+            /* reconfig */
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_AX25" );
+
+            if (devices[AX25_port].connect_on_startup)
+                XmToggleButtonSetState(AX25_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(AX25_active_on_startup,FALSE,FALSE);
+
+            switch (devices[AX25_port].igate_options) {
+                case(0):
+                    XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+                    device_igate_options=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(igate_o_1,TRUE,FALSE);
+                    device_igate_options=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(igate_o_2,TRUE,FALSE);
+                    device_igate_options=2;
+                    break;
+
+                default:
+                    XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+                    device_igate_options=0;
+                    break;
+            }
+            if (devices[AX25_port].transmit_data)
+                XmToggleButtonSetState(AX25_transmit_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(AX25_transmit_data,FALSE,FALSE);
+
+            if (devices[AX25_port].relay_digipeat)
+                XmToggleButtonSetState(AX25_relay_digipeat,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(AX25_relay_digipeat,FALSE,FALSE);
+
+            XmTextFieldSetString(AX25_device_name_data,devices[AX25_port].device_name);
+            XmTextFieldSetString(AX25_comment,devices[AX25_port].comment);
+            XmTextFieldSetString(AX25_unproto1_data,devices[AX25_port].unproto1);
+            XmTextFieldSetString(AX25_unproto2_data,devices[AX25_port].unproto2);
+            XmTextFieldSetString(AX25_unproto3_data,devices[AX25_port].unproto3);
+            XmTextFieldSetString(AX25_igate_data,devices[AX25_port].unproto_igate);
+ 
+end_critical_section(&devices_lock, "interface_gui.c:Config_AX25" );
+
+        }
+        XtManageChild(form);
+        XtManageChild(igate_box);
+        XtManageChild(pane);
+
+        XtPopup(config_AX25_dialog,XtGrabNone);
+        fix_dialog_size(config_AX25_dialog);
+    } else {
+        (void)XRaiseWindow(XtDisplay(config_AX25_dialog), XtWindow(config_AX25_dialog));
+    }
+}
+
+
+
+
+
+/*****************************************************/
+/* Configure Network server GUI                      */
+/*****************************************************/
+
+/**** INTERNET CONFIGURE ******/
+Widget config_Inet_dialog = (Widget)NULL;
+Widget Inet_active_on_startup;
+Widget Inet_host_data;
+Widget Inet_port_data;
+Widget Inet_comment;
+Widget Inet_password_data;
+Widget Inet_filter_data;
+Widget Inet_transmit_data;
+Widget Inet_reconnect_data;
+int    Inet_port;
+
+
+
+
+
+void Inet_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_Inet_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Inet_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+    was_up=0;
+    if (get_device_status(Inet_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(Inet_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Inet_change_data" );
+
+    temp_ptr = XmTextFieldGetString(Inet_host_data);
+    xastir_snprintf(devices[Inet_port].device_host_name,
+        sizeof(devices[Inet_port].device_host_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Inet_port].device_host_name);
+
+    temp_ptr = XmTextFieldGetString(Inet_password_data);
+    xastir_snprintf(devices[Inet_port].device_host_pswd,
+        sizeof(devices[Inet_port].device_host_pswd),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Inet_port].device_host_pswd);
+
+    temp_ptr = XmTextFieldGetString(Inet_filter_data);
+    xastir_snprintf(devices[Inet_port].device_host_filter_string,
+        sizeof(devices[Inet_port].device_host_filter_string),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Inet_port].device_host_filter_string);
+
+    temp_ptr = XmTextFieldGetString(Inet_comment);
+    xastir_snprintf(devices[Inet_port].comment,
+        sizeof(devices[Inet_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    
+    (void)remove_trailing_spaces(devices[Inet_port].comment);
+
+    temp_ptr = XmTextFieldGetString(Inet_port_data);
+    devices[Inet_port].sp=atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    if(XmToggleButtonGetState(Inet_active_on_startup))
+        devices[Inet_port].connect_on_startup=1;
+    else
+        devices[Inet_port].connect_on_startup=0;
+
+    if(XmToggleButtonGetState(Inet_transmit_data))
+        devices[Inet_port].transmit_data=1;
+    else
+        devices[Inet_port].transmit_data=0;
+
+    if(XmToggleButtonGetState(Inet_reconnect_data))
+        devices[Inet_port].reconnect=1;
+    else
+        devices[Inet_port].reconnect=0;
+
+//    Changed 20041213 per emails with we7u - n8ysz
+//    if (devices[Inet_port].connect_on_startup==1 || was_up) {
+
+    if ( was_up) {
+        (void)add_device(Inet_port,
+            DEVICE_NET_STREAM,
+            devices[Inet_port].device_host_name,
+            devices[Inet_port].device_host_pswd,
+            devices[Inet_port].sp,
+            0,
+            0,
+            devices[Inet_port].reconnect,
+            devices[Inet_port].device_host_filter_string);
+    }
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[Inet_port].device_type=DEVICE_NET_STREAM;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Inet_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Inet_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_Inet( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel,
+                ihost, iport, password, password_fl,
+                filter, comment, sep;
+
+    Atom delw;
+    char temp[40];
+
+    if(!config_Inet_dialog) {
+        Inet_port=port;
+        config_Inet_dialog = XtVaCreatePopupShell(langcode("WPUPCFI001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_Inet pane",xmPanedWindowWidgetClass, config_Inet_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_Inet form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        Inet_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_transmit_data  = XtVaCreateManagedWidget(langcode("UNIOP00010"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        ihost = XtVaCreateManagedWidget(langcode("WPUPCFI002"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_host_data = XtVaCreateManagedWidget("Config_Inet host_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 30,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, ihost,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        iport = XtVaCreateManagedWidget(langcode("WPUPCFI003"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,Inet_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,Inet_host_data,
+                                      XmNleftOffset, 20,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_port_data = XtVaCreateManagedWidget("Config_Inet port_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 5,
+                                      XmNmaxLength, 6,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, iport,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset,10,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        password = XtVaCreateManagedWidget(langcode("WPUPCFI009"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_password_data = XtVaCreateManagedWidget("Config_Inet password_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 20,
+                                      XmNmaxLength, 20,
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, password,
+                                      XmNleftOffset, 10,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        password_fl = XtVaCreateManagedWidget(langcode("WPUPCFI010"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,Inet_password_data,
+                                      XmNleftOffset,20,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        filter = XtVaCreateManagedWidget(langcode("WPUPCFI015"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_filter_data = XtVaCreateManagedWidget("Config_Inet filter_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 30,
+                                      XmNmaxLength, 190,
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, filter,
+                                      XmNleftOffset, 10,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_filter_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_comment = XtVaCreateManagedWidget("Config_Inet comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_filter_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Inet_reconnect_data = XtVaCreateManagedWidget(langcode("WPUPCFI011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, comment,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        sep = XtVaCreateManagedWidget("Config_Inet sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, Inet_reconnect_data,
+                                      XmNtopOffset, 14,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Inet_change_data, config_Inet_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Inet_destroy_shell, config_Inet_dialog);
+
+        pos_dialog(config_Inet_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_Inet_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_Inet_dialog, delw, Inet_destroy_shell, (XtPointer)config_Inet_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            XmToggleButtonSetState(Inet_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(Inet_transmit_data,TRUE,FALSE);
+
+            // Core APRS-IS Servers
+            XmTextFieldSetString(Inet_host_data,"rotate.aprs.net");
+
+            // Filtered port
+            XmTextFieldSetString(Inet_port_data,"14580");
+
+            // Filter of 500 miles around my location. But only if I
+            // enable transmit on that interface and globally!
+            XmTextFieldSetString(Inet_filter_data,"m/500");
+
+            XmTextFieldSetString(Inet_comment,"Core INET Servers");
+            XmToggleButtonSetState(Inet_reconnect_data,TRUE,FALSE);
+        } else {
+            /* reconfig */
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_Inet" );
+
+           if (devices[Inet_port].connect_on_startup)
+                XmToggleButtonSetState(Inet_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Inet_active_on_startup,FALSE,FALSE);
+
+            if (devices[Inet_port].transmit_data)
+                XmToggleButtonSetState(Inet_transmit_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Inet_transmit_data,FALSE,FALSE);
+
+            XmTextFieldSetString(Inet_host_data,devices[Inet_port].device_host_name);
+            xastir_snprintf(temp, sizeof(temp), "%d", devices[Inet_port].sp);
+            XmTextFieldSetString(Inet_port_data,temp);
+            XmTextFieldSetString(Inet_password_data,devices[Inet_port].device_host_pswd);
+            XmTextFieldSetString(Inet_filter_data,devices[Inet_port].device_host_filter_string);
+            XmTextFieldSetString(Inet_comment,devices[Inet_port].comment);
+
+            if (devices[Inet_port].reconnect)
+                XmToggleButtonSetState(Inet_reconnect_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Inet_reconnect_data,FALSE,FALSE);
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_Inet" );
+
+        }
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(config_Inet_dialog,XtGrabNone);
+        fix_dialog_size(config_Inet_dialog);
+    } else {
+        (void)XRaiseWindow(XtDisplay(config_Inet_dialog), XtWindow(config_Inet_dialog));
+    }
+}
+
+
+
+
+
+//WE7U-DATABASE
+/*****************************************************/
+/* Configure Database Server GUI                     */
+/*****************************************************/
+
+/**** DATABASE CONFIGURE ******/
+Widget config_Database_dialog = (Widget)NULL;      
+Widget Database_active_on_startup;
+Widget Database_host_data;
+Widget Database_port_data;
+Widget Database_comment;
+Widget Database_password_data;
+Widget Database_filter_data;
+Widget Database_transmit_data;
+Widget Database_reconnect_data;
+int    Database_port;
+
+
+
+
+
+void Database_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_Database_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Database_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+    was_up=0;
+    if (get_device_status(Database_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(Database_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:Database_change_data" );
+
+    temp_ptr = XmTextFieldGetString(Database_host_data);
+    xastir_snprintf(devices[Database_port].device_host_name,
+        sizeof(devices[Database_port].device_host_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Database_port].device_host_name);
+
+    temp_ptr = XmTextFieldGetString(Database_password_data);
+    xastir_snprintf(devices[Database_port].device_host_pswd,
+        sizeof(devices[Database_port].device_host_pswd),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Database_port].device_host_pswd);
+
+    temp_ptr = XmTextFieldGetString(Database_filter_data);
+    xastir_snprintf(devices[Database_port].device_host_filter_string,
+        sizeof(devices[Database_port].device_host_filter_string),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Database_port].device_host_filter_string);
+
+    temp_ptr = XmTextFieldGetString(Database_comment);
+    xastir_snprintf(devices[Database_port].comment,
+        sizeof(devices[Database_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[Database_port].comment);
+
+    temp_ptr = XmTextFieldGetString(Database_port_data);
+    devices[Database_port].sp=atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    if(XmToggleButtonGetState(Database_active_on_startup))
+        devices[Database_port].connect_on_startup=1;
+    else
+        devices[Database_port].connect_on_startup=0;
+
+    if(XmToggleButtonGetState(Database_transmit_data))
+        devices[Database_port].transmit_data=1;
+    else
+        devices[Database_port].transmit_data=0;
+
+    if(XmToggleButtonGetState(Database_reconnect_data))
+        devices[Database_port].reconnect=1;
+    else
+        devices[Database_port].reconnect=0;
+
+//    n8ysz 20041213
+//    if (devices[Database_port].connect_on_startup==1 || was_up) {  
+    if ( was_up) {
+        (void)add_device(Database_port,
+            DEVICE_NET_DATABASE,
+            devices[Database_port].device_host_name,
+            devices[Database_port].device_host_pswd,
+            devices[Database_port].sp,
+            0,
+            0,
+            devices[Database_port].reconnect,
+            devices[Database_port].device_host_filter_string);
+    }
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[Database_port].device_type=DEVICE_NET_DATABASE;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:Database_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    Database_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_Database( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel,
+                ihost, iport, password, password_fl,
+                filter, sep, comment;
+
+    Atom delw;
+    char temp[40];
+
+    if(!config_Database_dialog) {
+        Database_port=port;
+        config_Database_dialog = XtVaCreatePopupShell(langcode("WPUPCFID01"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_Database pane",xmPanedWindowWidgetClass, config_Database_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_Database form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        Database_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_transmit_data  = XtVaCreateManagedWidget(langcode("UNIOP00010"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Database_active_on_startup,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        ihost = XtVaCreateManagedWidget(langcode("WPUPCFID02"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Database_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_host_data = XtVaCreateManagedWidget("Config_Database host_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 30,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, Database_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, ihost,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        iport = XtVaCreateManagedWidget(langcode("WPUPCFID03"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,Database_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,Database_host_data,
+                                      XmNleftOffset, 20,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_port_data = XtVaCreateManagedWidget("Config_Database port_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 5,
+                                      XmNmaxLength, 6,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, Database_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, iport,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset,10,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        password = XtVaCreateManagedWidget(langcode("WPUPCFID09"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_password_data = XtVaCreateManagedWidget("Config_Database password_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 20,
+                                      XmNmaxLength, 20,
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, password,
+                                      XmNleftOffset, 10,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        password_fl = XtVaCreateManagedWidget(langcode("WPUPCFID10"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,Database_password_data,
+                                      XmNleftOffset,20,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        filter = XtVaCreateManagedWidget(langcode("WPUPCFID15"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_filter_data = XtVaCreateManagedWidget("Config_Database filter_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 30,
+                                      XmNmaxLength, 190,
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, filter,
+                                      XmNleftOffset, 10,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, filter,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_comment = XtVaCreateManagedWidget("Config_Database comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, filter,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        Database_reconnect_data = XtVaCreateManagedWidget(langcode("WPUPCFID11"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, comment,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        sep = XtVaCreateManagedWidget("Config_Database sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, Database_reconnect_data,
+                                      XmNtopOffset, 14,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Database_change_data, config_Database_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Database_destroy_shell, config_Database_dialog);
+
+        pos_dialog(config_Database_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_Database_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_Database_dialog, delw, Database_destroy_shell, (XtPointer)config_Database_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            XmToggleButtonSetState(Database_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(Database_transmit_data,TRUE,FALSE);
+            //XmTextFieldSetString(Database_host_data,"first.aprs.net");
+            XmTextFieldSetString(Database_host_data,"");
+            XmTextFieldSetString(Database_port_data,"");
+            XmTextFieldSetString(Database_filter_data,"");
+            XmTextFieldSetString(Database_comment,"");
+            XmToggleButtonSetState(Database_reconnect_data,FALSE,FALSE);
+        } else {
+            /* reconfig */
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_Database" );
+
+           if (devices[Database_port].connect_on_startup)
+                XmToggleButtonSetState(Database_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Database_active_on_startup,FALSE,FALSE);
+
+            if (devices[Database_port].transmit_data)
+                XmToggleButtonSetState(Database_transmit_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Database_transmit_data,FALSE,FALSE);
+
+            XmTextFieldSetString(Database_host_data,devices[Database_port].device_host_name);
+            xastir_snprintf(temp, sizeof(temp), "%d", devices[Database_port].sp);
+            XmTextFieldSetString(Database_port_data,temp);
+            XmTextFieldSetString(Database_password_data,devices[Database_port].device_host_pswd);
+            XmTextFieldSetString(Database_filter_data,devices[Database_port].device_host_filter_string);
+            XmTextFieldSetString(Database_comment,devices[Database_port].comment);
+
+            if (devices[Database_port].reconnect)
+                XmToggleButtonSetState(Database_reconnect_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Database_reconnect_data,FALSE,FALSE);
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_Database" );
+
+        }
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(config_Database_dialog,XtGrabNone);
+        fix_dialog_size(config_Database_dialog);
+    } else {
+        (void)XRaiseWindow(XtDisplay(config_Database_dialog), XtWindow(config_Database_dialog));
+    }
+}
+
+
+#ifdef HAVE_DB
+//AA3SD-SQL SERVER DATABASE, for db_gis spatial databases
+/*****************************************************/
+/* Configure SQL Database Server GUI                 */
+/*****************************************************/
+
+/**** DATABASE CONFIGURE ******/
+Widget config_Sql_Database_dialog = (Widget)NULL;  // dialog for sql server database connections used in db_gis.c
+Widget Sql_Database_active_on_startup;
+Widget Sql_Database_query_on_startup_data;
+Widget Sql_Database_host_data;
+Widget Sql_Database_iport_data;   // = sp, tcp port number on which to connect to database server
+Widget Sql_Database_comment;
+Widget Sql_Database_password_data;
+Widget Sql_Database_transmit_data;
+Widget Sql_Database_reconnect_data;
+int    Sql_Database_port;   // xastir interface port number, not tcp/ip port
+Widget Sql_Database_username_data;
+Widget Sql_Database_schema_name_data;
+
+// lesstif combo boxes are not fully implemented.
+// replace combo box with a fake combo box made out of a menu when only lesstif is available
+#ifdef USE_COMBO_BOX
+Widget Sql_Database_dbms_data;
+#else
+int    sddd_value;  // integer value of the currently selected item (replicating ordinal position in picklist)
+Widget sddd_button;  // button to bring up the picklist
+Widget sddd_buttons[3];
+Widget sddd_menuPane;  /// menu that acts as the picklist of dbms types
+Widget sddd_menu;  /// menu top level
+#endif // USE_COMBO_BOX
+Widget sddd_widget; // widget used to bind next control in either use combo box or not cases.
+
+Widget Sql_Database_unix_socket_data;
+Widget Sql_Database_schema_type_data;
+Widget Sql_Database_errormessage_data;   // display most recent error message on connection
+
+
+
+
+
+#ifdef HAVE_MYSQL
+// Set the values on the user interface to an appropriate set 
+// of defaults for connecting to a mysql database.
+void Sql_Database_set_defaults_mysql(/*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+   XmString cb_item;
+   //cb_item = XmStringCreateLtoR("MySQL (lat/long)", XmFONTLIST_DEFAULT_TAG);
+   cb_item = XmStringCreateLtoR(&xastir_dbms_type[DB_MYSQL][0], XmFONTLIST_DEFAULT_TAG);
+   //cb_item = XmStringCreateLtoR("MySQL (spatial)", XmFONTLIST_DEFAULT_TAG);
+#ifdef HAVE_MYSQL_SPATIAL
+   cb_item = XmStringCreateLtoR(&xastir_dbms_type[DB_MYSQL_SPATIAL][0], XmFONTLIST_DEFAULT_TAG);
+#endif /* HAVE_MYSQL_SPATIAL */
+#ifdef USE_COMBO_BOX
+   XmComboBoxSelectItem(Sql_Database_dbms_data,cb_item);
+#else
+   XtVaSetValues(sddd_menu, XmNmenuHistory, sddd_buttons[DB_MYSQL_SPATIAL], NULL);
+   sddd_value = DB_MYSQL_SPATIAL;
+#endif // USE_COMBO_BOX   
+   XmStringFree(cb_item);
+   //cb_item = XmStringCreateLtoR("Xastir - simple", XmFONTLIST_DEFAULT_TAG);
+   cb_item = XmStringCreateLtoR(&xastir_schema_type[XASTIR_SCHEMA_SIMPLE][0], XmFONTLIST_DEFAULT_TAG);
+   XmComboBoxSelectItem(Sql_Database_schema_type_data,cb_item);  
+   XmStringFree(cb_item);
+   XmToggleButtonSetState(Sql_Database_active_on_startup,TRUE,FALSE);
+   XmToggleButtonSetState(Sql_Database_transmit_data,TRUE,FALSE);
+   XmTextFieldSetString(Sql_Database_host_data,"localhost");
+   XmTextFieldSetString(Sql_Database_iport_data,"3306");
+   XmTextFieldSetString(Sql_Database_username_data,"xastir_user");
+   XmTextFieldSetString(Sql_Database_schema_name_data,"xastir");
+   // **  get default from mysql_config at configure time 
+   XmTextFieldSetString(Sql_Database_unix_socket_data,"/var/lib/mysql/mysql.sock");
+   XmTextFieldSetString(Sql_Database_comment,"");
+   XmToggleButtonSetState(Sql_Database_reconnect_data,FALSE,FALSE);
+   // don't set Sql_Database_errormessage_data - leave most recent error message visible
+}
+#endif /* HAVE_MYSQL */
+
+
+
+
+
+#ifdef HAVE_POSTGIS
+// Set the values on the user interface to an appropriate set 
+// of defaults for connecting to a postgresql database.
+void Sql_Database_set_defaults_postgis(/*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+   XmString cb_item;
+   //cb_item = XmStringCreateLtoR("Postgres/Postgis", XmFONTLIST_DEFAULT_TAG);
+   cb_item = XmStringCreateLtoR(&xastir_dbms_type[DB_POSTGIS][0], XmFONTLIST_DEFAULT_TAG);
+#ifdef USE_COMBO_BOX
+   XmComboBoxSelectItem(Sql_Database_dbms_data,cb_item);
+#else
+   XtVaSetValues(sddd_menu, XmNmenuHistory, sddd_buttons[DB_POSTGIS], NULL);
+   sddd_value = DB_POSTGIS;
+#endif // USE_COMBO_BOX
+   XmStringFree(cb_item);
+   //cb_item = XmStringCreateLtoR("Xastir - simple", XmFONTLIST_DEFAULT_TAG);
+   cb_item = XmStringCreateLtoR(&xastir_schema_type[XASTIR_SCHEMA_SIMPLE][0], XmFONTLIST_DEFAULT_TAG);
+   XmComboBoxSelectItem(Sql_Database_schema_type_data,cb_item);  
+   XmStringFree(cb_item);
+   XmToggleButtonSetState(Sql_Database_active_on_startup,TRUE,FALSE);
+   XmToggleButtonSetState(Sql_Database_transmit_data,TRUE,FALSE);
+   XmTextFieldSetString(Sql_Database_host_data,"localhost");
+   XmTextFieldSetString(Sql_Database_iport_data,"5432");
+   XmTextFieldSetString(Sql_Database_username_data,"xastir_user");
+   XmTextFieldSetString(Sql_Database_schema_name_data,"xastir");
+   // **  get default from mysql_config at configure time 
+   XmTextFieldSetString(Sql_Database_unix_socket_data,"");
+   XmTextFieldSetString(Sql_Database_comment,"");
+   XmToggleButtonSetState(Sql_Database_reconnect_data,FALSE,FALSE);
+   // don't set Sql_Database_errormessage_data - leave most recent error message visible
+}
+#endif /* HAVE_POSTGIS */
+
+
+
+
+
+// Destroy the dialog used to set properties for a SQL database interface.
+void Sql_Database_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_Sql_Database_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+
+/* Callback for OK button on SQL database interface properties dialog.
+   Creates a new interface with the parameters provided in the dialog, or
+   alters the values of the selected interface that was displayed in the
+   dialog.
+   Differs from other interfaces in that an active database connection needs
+   to be started from the interface parameters.
+*/
+void Sql_Database_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;      // flag to restart connection with new parameters 
+    char *temp_ptr;  // temporary variable for retrieving string data from XmTextFields
+    int cb_selected; // temporary variable for retrieving combo box selections
+
+    // change to use code from db_gis.c 
+
+    busy_cursor(appshell);
+    was_up=0;
+
+    if (debug_level & 2)
+         fprintf(stderr,"Storing SQL Database interface on port %d\n",Sql_Database_port);
+    // determine if there is an active connection based on this interface,
+    // if so, stop it and restart after changes have been made.
+    if (get_device_status(Sql_Database_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        fprintf(stderr,"Device is up, disconnecting from database \n");
+        was_up=1;
+
+        // close connection
+
+    }
+
+// This needs to be a unitary transaction for other interfaces as we don't 
+// want to read/write data from an interface while its configuration is in an
+// inconsistent state.  In this case (SQL databases, we still need this to be
+// a unitary transaction in case a new connection is created while the 
+// configuration is in an inconsistent state.  
+begin_critical_section(&devices_lock, "interface_gui.c:Sql_Database_change_data" );
+
+    // ** set the interface values needed to make a connection to a database **
+
+    // hostname
+    temp_ptr = XmTextFieldGetString(Sql_Database_host_data);
+    xastir_snprintf(devices[Sql_Database_port].device_host_name,
+        sizeof(devices[Sql_Database_port].device_host_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(devices[Sql_Database_port].device_host_name);
+
+    //port
+    temp_ptr = XmTextFieldGetString(Sql_Database_iport_data);
+    devices[Sql_Database_port].sp=atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    //username
+    temp_ptr = XmTextFieldGetString(Sql_Database_username_data);
+    xastir_snprintf(devices[Sql_Database_port].database_username,
+        sizeof(devices[Sql_Database_port].database_username),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(devices[Sql_Database_port].device_host_pswd);
+
+    //password
+    temp_ptr = XmTextFieldGetString(Sql_Database_password_data);
+    xastir_snprintf(devices[Sql_Database_port].device_host_pswd,
+        sizeof(devices[Sql_Database_port].device_host_pswd),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(devices[Sql_Database_port].device_host_pswd);
+
+    // schema name
+    temp_ptr = XmTextFieldGetString(Sql_Database_schema_name_data);
+    xastir_snprintf(devices[Sql_Database_port].database_schema,
+        sizeof(devices[Sql_Database_port].database_schema),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(devices[Sql_Database_port].database_schema);
+
+    // database type
+    cb_selected = FALSE;
+#ifdef USE_COMBO_BOX
+    XtVaGetValues(Sql_Database_dbms_data,XmNselectedPosition, &cb_selected, NULL);
+#else
+    // find out the value of the latest selection from the Sql_Databas_dbms_data_menu
+    cb_selected = sddd_value;
+#endif
+    
+    if (cb_selected) { 
+        devices[Sql_Database_port].database_type = cb_selected;
+    } else {  
+        // If no selection,
+        // default to mysql non-spatial, unless postgis is available.
+#ifdef HAVE_POSTGIS
+        devices[Sql_Database_port].database_type = DB_POSTGIS;
+#endif /* HAVE_POSTGIS */
+#ifdef HAVE_MYSQL 
+        devices[Sql_Database_port].database_type = DB_MYSQL;
+#endif /* HAVE_MYSQL */
+    }
+
+    // schema type
+    cb_selected = FALSE;
+    XtVaGetValues(Sql_Database_schema_type_data,XmNselectedPosition, &cb_selected, NULL);
+    
+    if (cb_selected) { 
+        devices[Sql_Database_port].database_schema_type = cb_selected;
+    } else {  
+        // If no selection, default to simple schema.
+        devices[Sql_Database_port].database_schema_type = XASTIR_SCHEMA_SIMPLE;
+    }
+
+    // unix socket 
+    temp_ptr = XmTextFieldGetString(Sql_Database_unix_socket_data);
+    xastir_snprintf(devices[Sql_Database_port].database_unix_socket,
+        sizeof(devices[Sql_Database_port].database_unix_socket),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(devices[Sql_Database_port].database_unix_socket);
+
+    // reset the error message to a blank
+    xastir_snprintf(devices[Sql_Database_port].database_errormessage,
+        sizeof(devices[Sql_Database_port].database_errormessage),
+        " ");
+
+    // ** set additional interface values **
+
+    // comment to display on interface list
+    temp_ptr = XmTextFieldGetString(Sql_Database_comment);
+    xastir_snprintf(devices[Sql_Database_port].comment,
+        sizeof(devices[Sql_Database_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(devices[Sql_Database_port].comment);
+
+    // activate on startup
+    if(XmToggleButtonGetState(Sql_Database_active_on_startup))
+        devices[Sql_Database_port].connect_on_startup=1;
+    else
+        devices[Sql_Database_port].connect_on_startup=0;
+    
+    // query on startup
+    if(XmToggleButtonGetState(Sql_Database_query_on_startup_data))
+        devices[Sql_Database_port].query_on_startup=1;
+    else
+        devices[Sql_Database_port].query_on_startup=0;
+
+    // allow saving data 
+    if(XmToggleButtonGetState(Sql_Database_transmit_data))
+        devices[Sql_Database_port].transmit_data=1;
+    else
+        devices[Sql_Database_port].transmit_data=0;
+
+    // reconnect on database connection failure 
+    if(XmToggleButtonGetState(Sql_Database_reconnect_data))
+        devices[Sql_Database_port].reconnect=1;
+    else
+        devices[Sql_Database_port].reconnect=0;
+
+    if (was_up) {
+        // If the connection was allready open when we started then reconnect
+        // and reopen the database connection with the new parameters.
+        if (openConnection(&devices[Sql_Database_port],&connections[Sql_Database_port])==1) { 
+           port_data[Sql_Database_port].status = DEVICE_UP;
+        } else { 
+           port_data[Sql_Database_port].status = DEVICE_ERROR;
+        }
+    }
+
+    /* add device type */
+    devices[Sql_Database_port].device_type=DEVICE_SQL_DATABASE;
+
+end_critical_section(&devices_lock, "interface_gui.c:Sql_Database_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    // close the dialog
+    Sql_Database_destroy_shell(widget,clientData,callData);
+    if (debug_level & 2)
+       fprintf(stderr,"Done storing sql interface parameters\n");
+}
+
+
+
+#ifndef USE_COMBO_BOX 
+void sddd_menuCallback(Widget widget, XtPointer ptr, XtPointer callData) {
+    XtPointer userData;
+
+    XtVaGetValues(widget, XmNuserData, &userData, NULL);
+    //sddd_menu is zero based, constants for database types are one based.
+    sddd_value = (int)userData + 1;
+    if (debug_level & 4096) 
+        fprintf(stderr,"Selected value on dbms pulldown: %d\n",sddd_value);
+}
+#endif // USE_COMBO_BOX
+
+
+
+
+
+/* dialog to obtain connection parameters for a SQL server (MySQL/Postgresql)
+ * database for spatialy enabled database support 
+ */
+void Config_sql_Database( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel, label_dbms, label_schema_type,
+                ihost, iport, password, unix_socket, error_message,
+                sep, comment, username, schema_name;
+    static Widget button_mysql_defaults;    // set form values to defaults for mysql
+    static Widget button_postgis_defaults;  // set form values to deaults for postgresql/postgis
+    int defaults_set;  // Have defaults been set on form for new interface?
+                       // Used to make only a single set defaults call when 
+                       // support for multiple types of dbms are available.
+
+    Atom delw;
+    char temp[40];
+    XmString cb_item;
+    XmString *cb_items[2];
+    int x; 
+#ifndef USE_COMBO_BOX
+    int i; // loop counter
+    Arg args[12]; // available for XtSetArguments 
+    char buf[18];
+    char *tmp;
+#endif // !USE_COMBO_BOX
+    /*
+    // configuration parameters for a sql server database 
+    char   database_username[20];                 // username to use to connect to database  
+                                                  // default xastir
+    int    database_type;                         // type of dbms (posgresql, mysql, etc)    
+                                                  // default mysql
+    char   database_schema[20];                   // name of database or schema to use       
+                                                  // default xastir
+    char   database_errormessage[255];            // most recent error message from 
+                                                     attempting to make a 
+                                                     connection with using this descriptor.  
+    int    database_schema_type;         // table structures to use in the database
+                                             A database schema could contain both APRSWorld 
+                                             and XASTIR table structures, but a separate database
+                                             descriptor should be defined for each.  
+                                         // default simple
+    char   database_unix_socket[255];             // MySQL - unix socket parameter (path and 
+                                                     filename) 
+    // device_host_name = hostname for database server 
+    // sp = port on which to connect to database server (Not database_port)
+    // device_host_password =  password to use to connect to database -- security issue needs to be addressed
+    */
+
+    if(!config_Sql_Database_dialog) {
+        // port is position in xastir interface list, not tcp port on which to connect
+        Sql_Database_port=port;
+
+        // SQL Server Database
+        config_Sql_Database_dialog = XtVaCreatePopupShell("SQL Server Database",
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse,        XmDESTROY,
+            XmNdefaultPosition,       FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_Database pane",xmPanedWindowWidgetClass, config_Sql_Database_dialog,
+            XmNbackground, colors[0xff],
+            NULL);
+
+        form =  XtVaCreateWidget("Config_Database form",xmFormWidgetClass, pane,
+            XmNfractionBase,    13,
+            XmNbackground,      colors[0xff],
+            XmNautoUnmanage,    FALSE,
+            XmNshadowThickness, 1,
+            NULL);
+
+        // Activate on startup
+        Sql_Database_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_FORM,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        // DMBS
+        label_dbms = XtVaCreateManagedWidget("Database:",xmLabelWidgetClass, form,
+            XmNtopAttachment,     XmATTACH_FORM,
+            XmNtopOffset,         15,
+            XmNbottomAttachment,  XmATTACH_NONE,
+            XmNleftAttachment,    XmATTACH_WIDGET,
+            XmNleftWidget,        Sql_Database_active_on_startup,
+            XmNleftOffset,        10,
+            XmNrightAttachment,   XmATTACH_NONE,
+            XmNbackground,        colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        // Combo box to pick dbms
+        cb_items [0] = (XmString *) XtMalloc ( sizeof (XmString) * 4 );
+        // Combo box items are defined by xastir_dbms_type, defined in db_gis.c
+        cb_items[0][0] = XmStringCreateLtoR( &xastir_dbms_type[1][0] , XmFONTLIST_DEFAULT_TAG);
+        cb_items[0][1] = XmStringCreateLtoR( &xastir_dbms_type[2][0] , XmFONTLIST_DEFAULT_TAG);
+        cb_items[0][2] = XmStringCreateLtoR( &xastir_dbms_type[3][0] , XmFONTLIST_DEFAULT_TAG);
+        // mysql
+        //cb_items[0][0] = XmStringCreateLtoR("MySQL (lat/long)", XmFONTLIST_DEFAULT_TAG);
+        // postgresql
+        //cb_items[0][1] = XmStringCreateLtoR("Postgres/Postgis", XmFONTLIST_DEFAULT_TAG);
+        // mysql with spatial extensions
+        //cb_items[0][2] = XmStringCreateLtoR("MySQL (spatial)", XmFONTLIST_DEFAULT_TAG);
+        cb_items[0][3] = NULL;
+#ifdef USE_COMBO_BOX
+        Sql_Database_dbms_data = XtVaCreateManagedWidget("select dbms", xmComboBoxWidgetClass, form,
+            XmNtopAttachment,     XmATTACH_FORM,
+            XmNtopOffset,         5,
+            XmNbottomAttachment,  XmATTACH_NONE,
+            XmNleftAttachment,    XmATTACH_WIDGET,
+            XmNleftWidget,        label_dbms,
+            XmNleftOffset,        1,
+            XmNrightAttachment,   XmATTACH_NONE,
+            XmNitems,             cb_items[0],
+            XmNitemCount,         3,
+            XmNnavigationType,    XmTAB_GROUP,
+            XmNcomboBoxType,      XmDROP_DOWN_LIST,
+            XmNpositionMode,      XmONE_BASED, 
+            XmNmatchBehavior,     XmQUICK_NAVIGATE,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            XmNfontList, fontlist1,
+            NULL);
+        sddd_widget = Sql_Database_dbms_data;
+#else
+        // lesstif, at least as of version 0.95 in 2008, doesn't fully support combo boxes.
+        //
+        // lesstif 0.94 doesn't support adding items to the list on creation through XmNitems
+        // lesstif 0.94 combo boxes don't have means to set currently selected value
+        // or to retrieve currently selected value.
+        //
+        // Need to replace combo boxes with a pull down menu when lesstif is used.
+        // See xpdf's  XPDFViewer.cc/XPDFViewer.h for an example.
+        //
+        // Fake a combo box with a menu, as done by xpdf in in XPDFViewer.cc
+        //
+        // create widgets and populate menu
+        // sddd_ abbreviates name of single control that is being replaced: Sql_Database_dbms_data
+        // sddd_value  // numberic value for the database dbms type
+        // sddd_button  // picklist item
+        // sddd_menu  // menu that acts as the picklist of dbms types
+        x = 0;
+        XtSetArg(args[x], XmNmarginWidth, 0); ++x;
+        XtSetArg(args[x], XmNmarginHeight, 0); ++x;
+        sddd_menuPane = XmCreatePulldownMenu(form,"sddd_menuPane", args, x);
+        //sddd_menu is zero based, constants for database types are one based.
+        //sddd_value is set to match constants in callback.
+        for (i=0;i<3;i++) { 
+            x = 0;
+            XmStringGetLtoR(cb_items[0][i],XmFONTLIST_DEFAULT_TAG,&tmp);
+            XtSetArg(args[x], XmNlabelString, cb_items[0][i]); x++;
+            XtSetArg(args[x], XmNuserData, (XtPointer)i); x++;
+            XtSetArg(args[x], XmNfontList, fontlist1); x++;
+            sprintf(buf,"button%d",i);
+            sddd_button = XmCreatePushButton(sddd_menuPane, buf, args, x);
+            XtManageChild(sddd_button);
+            XtAddCallback(sddd_button, XmNactivateCallback, sddd_menuCallback, config_Sql_Database_dialog);
+            sddd_buttons[i] = sddd_button;
+        }
+        x = 0;
+        XtSetArg(args[x], XmNleftAttachment, XmATTACH_WIDGET); ++x;
+        XtSetArg(args[x], XmNleftWidget, label_dbms); ++x;
+        XtSetArg(args[x], XmNtopAttachment, XmATTACH_FORM); ++x;
+        XtSetArg(args[x], XmNmarginWidth, 0); ++x;
+        XtSetArg(args[x], XmNmarginHeight, 0); ++x;
+        XtSetArg(args[x], XmNtopOffset, 7); ++x;
+        XtSetArg(args[x], XmNleftOffset, 1); ++x;
+        XtSetArg(args[x], XmNsubMenuId, sddd_menuPane); ++x;
+        sddd_menu = XmCreateOptionMenu(form, "sddd_Menu", args, x);
+        XtManageChild(sddd_menu);
+        sddd_widget = sddd_menu;
+#endif
+        // free up the XmStrings used to create the picklist
+        x=0;
+        while ( cb_items[0][x] )
+            XmStringFree ( cb_items[0][x++] );
+        x=0;
+        XtFree ( (char *) cb_items[0] );
+
+        // *** when localizing these strings propagate the localizations to 
+        // the set default functions above and to constants for picklist 
+        // selection recognition.  ***
+        //cb_item = XmStringCreateLtoR(&xastir_dbms_type[DB_MYSQL][0], XmFONTLIST_DEFAULT_TAG);
+        //XmComboBoxAddItem(Sql_Database_dbms_data,cb_item,1,1);  
+        //XmStringFree(cb_item);
+        //cb_item = XmStringCreateLtoR(&xastir_dbms_type[DB_POSTGIS][0], XmFONTLIST_DEFAULT_TAG);
+        //XmComboBoxAddItem(Sql_Database_dbms_data,cb_item,2,1);  
+        //XmStringFree(cb_item);
+        //cb_item = XmStringCreateLtoR(&xastir_dbms_type[DB_MYSQL_SPATIAL][0], XmFONTLIST_DEFAULT_TAG);
+        //XmComboBoxAddItem(Sql_Database_dbms_data,cb_item,3,1);  
+        //XmStringFree(cb_item);
+
+        // Schema Type
+        label_schema_type = XtVaCreateManagedWidget("With Tables for",xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_FORM,
+            XmNtopOffset,        15,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       sddd_widget,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        // Combo box to pick schema
+        Sql_Database_schema_type_data = XtVaCreateManagedWidget("Tables to use", xmComboBoxWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_FORM,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       label_schema_type,
+            XmNleftOffset,       1,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNcomboBoxType,     XmDROP_DOWN_LIST,
+            XmNpositionMode,     XmONE_BASED, 
+            XmNvisibleItemCount, 3,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            XmNfontList, fontlist1,
+            NULL);
+        // *** need to add constants for order and localization *** 
+        // ? use an array - schm_typ[XASTIR_SCHEMA_SIMPLE]=langcode("codeforxastirsimple").... ? 
+        // ?or some other form of key-value pairs? 
+
+        // simple
+        //cb_item = XmStringCreateLtoR("Xastir - simple", XmFONTLIST_DEFAULT_TAG);
+        cb_item = XmStringCreateLtoR(&xastir_schema_type[XASTIR_SCHEMA_SIMPLE][0], XmFONTLIST_DEFAULT_TAG);
+        XmComboBoxAddItem(Sql_Database_schema_type_data,cb_item,1,1);  
+        XmStringFree(cb_item);
+
+/* not yet implemented
+        // aprs world
+        cb_item = XmStringCreateLtoR("APRSWorld", XmFONTLIST_DEFAULT_TAG);
+        XmComboBoxAddItem(cad_line_style_data,cb_item,2,1);  
+        XmStringFree(cb_item);
+
+        // full
+        cb_item = XmStringCreateLtoR("Xastir - full", XmFONTLIST_DEFAULT_TAG);
+        XmComboBoxAddItem(cad_line_style_data,cb_item,2,1);  
+        XmStringFree(cb_item);
+
+        // cad
+        cb_item = XmStringCreateLtoR("Xastir - CAD", XmFONTLIST_DEFAULT_TAG);
+        XmComboBoxAddItem(cad_line_style_data,cb_item,2,1);  
+        XmStringFree(cb_item);
+*/
+
+        // Store data
+        Sql_Database_transmit_data  = XtVaCreateManagedWidget("Store incoming data",xmToggleButtonWidgetClass,form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        sddd_widget,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        // Retrieve data on start
+        Sql_Database_query_on_startup_data  = XtVaCreateManagedWidget("Load data on start",xmToggleButtonWidgetClass,form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        sddd_widget,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       Sql_Database_transmit_data,
+            XmNleftOffset,       15,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        // put retieve now button here.
+
+        // hostname
+        ihost = XtVaCreateManagedWidget(langcode("WPUPCFID02"),xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_transmit_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        Sql_Database_host_data = XtVaCreateManagedWidget("Config_Database host_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          55,
+            XmNmaxLength,        255,
+            XmNbackground,       colors[0x0f],
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_transmit_data,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       ihost,
+            XmNleftOffset,       1,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // tcp port for server, not xastir interface port
+        // port
+        iport = XtVaCreateManagedWidget(langcode("WPUPCFID03"),xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_transmit_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       Sql_Database_host_data,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        
+        Sql_Database_iport_data = XtVaCreateManagedWidget("Config_Database port_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          5,
+            XmNmaxLength,        6,
+            XmNbackground,       colors[0x0f],
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_transmit_data,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       iport,
+            XmNleftOffset,       1,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+        
+        // Username 
+        username = XtVaCreateManagedWidget("Username",xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_host_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        
+        Sql_Database_username_data = XtVaCreateManagedWidget("Config_Database username_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          15,
+            XmNmaxLength,        25,
+            XmNbackground,       colors[0x0f],
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_host_data,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       username,
+            XmNleftOffset,       1,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+        // Password
+        password = XtVaCreateManagedWidget("Password",xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_host_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       Sql_Database_username_data, 
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        Sql_Database_password_data = XtVaCreateManagedWidget("Config_Database password_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          15,
+            XmNmaxLength,        20,
+            XmNbackground,       colors[0x0f],
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       password,
+            XmNleftOffset,       1,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_host_data,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+        //  Schema/Database name
+        schema_name = XtVaCreateManagedWidget("Schema/Database name",xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_username_data,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        Sql_Database_schema_name_data= XtVaCreateManagedWidget("Config_Database schema_name_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          25,
+            XmNmaxLength,        50,
+            XmNbackground,       colors[0x0f],
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       schema_name,
+            XmNleftOffset,       1,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_username_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // MySQL unix socket
+        unix_socket = XtVaCreateManagedWidget("MySQL unix socket",xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_username_data,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       Sql_Database_schema_name_data,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        Sql_Database_unix_socket_data = XtVaCreateManagedWidget("Config_Database unix_socket_data", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          30,
+            XmNmaxLength,        190,
+            XmNbackground,       colors[0x0f],
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       unix_socket,
+            XmNleftOffset,       1,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_username_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // comment
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_schema_name_data,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        Sql_Database_comment = XtVaCreateManagedWidget("Config_Database comment", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          25,
+            XmNwidth,            ((25*7)+2),
+            XmNmaxLength,        49,
+            XmNbackground,       colors[0x0f],
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_schema_name_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       comment,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // reconnect on network failure
+        Sql_Database_reconnect_data = XtVaCreateManagedWidget(langcode("WPUPCFID11"),xmToggleButtonWidgetClass,form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_comment,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        // most recent error 
+        error_message = XtVaCreateManagedWidget("Most Recent Error:",xmLabelWidgetClass, form,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_reconnect_data,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNleftOffset,       10,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        // error message isn't editable and isn't saved
+        Sql_Database_errormessage_data = XtVaCreateManagedWidget("Config_Database error_message", xmTextFieldWidgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNeditable,         FALSE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive,        TRUE,
+            XmNshadowThickness,  1,
+            XmNcolumns,          79,
+            XmNwidth,            ((79*7)+2),
+            XmNmaxLength,        255,
+            XmNbackground,       colors[0x0f],
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_reconnect_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_WIDGET,
+            XmNleftWidget,       error_message,
+            XmNrightAttachment,  XmATTACH_NONE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // separator line 
+        sep = XtVaCreateManagedWidget("Config_Database sep", xmSeparatorGadgetClass,form,
+            XmNorientation,      XmHORIZONTAL,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        Sql_Database_errormessage_data,
+            XmNtopOffset,        5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment,   XmATTACH_FORM,
+            XmNrightAttachment,  XmATTACH_FORM,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        // button: MySQL Defaults
+        button_mysql_defaults = XtVaCreateManagedWidget("MySQL Defaults",xmPushButtonGadgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        sep,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset,     5,
+            XmNleftAttachment,   XmATTACH_POSITION,
+            XmNleftPosition,     1,
+            XmNrightAttachment,  XmATTACH_POSITION,
+            XmNrightPosition,    3,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        // button: Postgis Defaults
+        button_postgis_defaults = XtVaCreateManagedWidget("Postgis Defaults",xmPushButtonGadgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        sep,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset,     5,
+            XmNleftAttachment,   XmATTACH_POSITION,
+            XmNleftPosition,     4,
+            XmNrightAttachment,  XmATTACH_POSITION,
+            XmNrightPosition,    6,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        // button: OK
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        sep,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset,     5,
+            XmNleftAttachment,   XmATTACH_POSITION,
+            XmNleftPosition,     7,
+            XmNrightAttachment,  XmATTACH_POSITION,
+            XmNrightPosition,    9,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+        // button: Cancel
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+            XmNnavigationType,   XmTAB_GROUP,
+            XmNtraversalOn,      TRUE,
+            XmNtopAttachment,    XmATTACH_WIDGET,
+            XmNtopWidget,        sep,
+            XmNtopOffset,        10,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset,     5,
+            XmNleftAttachment,   XmATTACH_POSITION,
+            XmNleftPosition,     10,
+            XmNrightAttachment,  XmATTACH_POSITION,
+            XmNrightPosition,    12,
+            XmNbackground,       colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+       XtSetSensitive(button_mysql_defaults,FALSE);
+#ifdef HAVE_MYSQL
+       XtSetSensitive(button_mysql_defaults,TRUE);
+        XtAddCallback(button_mysql_defaults, 
+            XmNactivateCallback, Sql_Database_set_defaults_mysql, config_Sql_Database_dialog);
+#endif /* HAVE_MYSQL */
+       XtSetSensitive(button_postgis_defaults,FALSE);
+#ifdef HAVE_POSTGIS
+       XtSetSensitive(button_postgis_defaults,TRUE);
+        XtAddCallback(button_postgis_defaults, 
+            XmNactivateCallback, Sql_Database_set_defaults_postgis, config_Sql_Database_dialog);
+#endif /* HAVE_POSTGIS */
+        XtAddCallback(button_ok, 
+            XmNactivateCallback, Sql_Database_change_data, config_Sql_Database_dialog);
+        XtAddCallback(button_cancel, 
+            XmNactivateCallback, Sql_Database_destroy_shell, config_Sql_Database_dialog);
+
+        pos_dialog(config_Sql_Database_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_Sql_Database_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_Sql_Database_dialog, 
+            delw, Sql_Database_destroy_shell, (XtPointer)config_Sql_Database_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            // Default settings for a new interface.
+            defaults_set = 0;
+#ifdef HAVE_MYSQL
+            Sql_Database_set_defaults_mysql(config_Sql_Database_dialog,NULL,NULL);
+            defaults_set = 1;
+#endif /* HAVE_MYSQL */
+#ifdef HAVE_POSTGIS
+            if (defaults_set==0) { 
+               // mysql support not available, use postgis
+               Sql_Database_set_defaults_postgis(config_Sql_Database_dialog,NULL,NULL);
+            }
+#endif /* HAVE_POSTGIS */
+        } else {
+            /* reconfigure an existing interface */
+
+// why critical section here?  We are reading data from an existing configuration, 
+// not changing the configuration while the interface might be in use.
+begin_critical_section(&devices_lock, "interface_gui.c:Config_sql_Database" );
+
+            // *** need to look up localized string for database_type *** 
+            cb_item = XmStringCreateLtoR(&xastir_dbms_type[devices[Sql_Database_port].database_type][0], XmFONTLIST_DEFAULT_TAG);
+#ifdef USE_COMBO_BOX
+            XmComboBoxSelectItem(Sql_Database_dbms_data,cb_item);
+            XmComboBoxSetItem(Sql_Database_dbms_data,cb_item);
+#else
+            //sddd_menu is zero based, constants for database types are one based.
+            //sddd_value matches constants.
+            XtVaSetValues(sddd_menu, XmNmenuHistory,
+                          sddd_buttons[devices[Sql_Database_port].database_type - 1 ], NULL);
+            sddd_value = devices[Sql_Database_port].database_type;
+#endif
+            XmStringFree(cb_item);
+
+            cb_item = XmStringCreateLtoR(&xastir_schema_type[devices[Sql_Database_port].database_schema_type][0], XmFONTLIST_DEFAULT_TAG);
+            XmComboBoxSelectItem(Sql_Database_schema_type_data,cb_item);  
+            XmComboBoxSetItem(Sql_Database_schema_type_data,cb_item);  
+            XmStringFree(cb_item);
+
+            if (devices[Sql_Database_port].connect_on_startup)
+                XmToggleButtonSetState(Sql_Database_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Sql_Database_active_on_startup,FALSE,FALSE);
+
+            if (devices[Sql_Database_port].query_on_startup)
+                XmToggleButtonSetState(Sql_Database_query_on_startup_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Sql_Database_query_on_startup_data,FALSE,FALSE);
+
+
+            if (devices[Sql_Database_port].transmit_data)
+                XmToggleButtonSetState(Sql_Database_transmit_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Sql_Database_transmit_data,FALSE,FALSE);
+
+            XmTextFieldSetString(Sql_Database_host_data,devices[Sql_Database_port].device_host_name);
+            XmTextFieldSetString(Sql_Database_schema_name_data,devices[Sql_Database_port].database_schema);
+            xastir_snprintf(temp, sizeof(temp), "%d", devices[Sql_Database_port].sp);
+            XmTextFieldSetString(Sql_Database_iport_data,temp);
+            XmTextFieldSetString(Sql_Database_username_data,devices[Sql_Database_port].database_username);
+            XmTextFieldSetString(Sql_Database_password_data,devices[Sql_Database_port].device_host_pswd);
+            XmTextFieldSetString(Sql_Database_unix_socket_data,devices[Sql_Database_port].database_unix_socket);
+            XmTextFieldSetString(Sql_Database_comment,devices[Sql_Database_port].comment);
+            // display most recent error message
+            XmTextFieldSetString(Sql_Database_errormessage_data,devices[Sql_Database_port].database_errormessage);
+
+            if (devices[Sql_Database_port].reconnect)
+                XmToggleButtonSetState(Sql_Database_reconnect_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(Sql_Database_reconnect_data,FALSE,FALSE);
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_sql_Database" );
+
+        }
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(config_Sql_Database_dialog,XtGrabNone);
+        fix_dialog_size(config_Sql_Database_dialog);
+    } else {
+        (void)XRaiseWindow(XtDisplay(config_Sql_Database_dialog), XtWindow(config_Sql_Database_dialog));
+    }
+}
+#endif /* HAVE_DB */
+
+
+
+
+/*****************************************************/
+/* Configure AGWPE Server GUI                        */
+/*****************************************************/
+
+/**** AGWPE CONFIGURE ******/
+Widget config_AGWPE_dialog = (Widget)NULL;
+Widget AGWPE_active_on_startup;
+Widget AGWPE_host_data;
+Widget AGWPE_port_data;
+Widget AGWPE_comment;
+Widget AGWPE_password_data;
+Widget AGWPE_transmit_data;
+Widget AGWPE_igate_data;
+Widget AGWPE_reconnect_data;
+Widget AGWPE_unproto1_data;
+Widget AGWPE_unproto2_data;
+Widget AGWPE_unproto3_data;
+Widget AGWPE_relay_digipeat;
+Widget AGWPE_radioport_data;
+int    AGWPE_port;
+
+
+
+
+
+void AGWPE_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    config_AGWPE_dialog = (Widget)NULL;
+    if (choose_interface_dialog != NULL)
+        Choose_interface_destroy_shell(choose_interface_dialog,choose_interface_dialog,NULL);
+
+    choose_interface_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void AGWPE_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int was_up;
+    char *temp_ptr;
+
+
+    busy_cursor(appshell);
+    was_up=0;
+    if (get_device_status(AGWPE_port) == DEVICE_IN_USE) {
+        /* if active shutdown before changes are made */
+        /*fprintf(stderr,"Device is up, shutting down\n");*/
+        (void)del_device(AGWPE_port);
+        was_up=1;
+        usleep(1000000); // Wait for one second
+    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:AGWPE_change_data" );
+
+    devices[AGWPE_port].igate_options=device_igate_options;
+
+    temp_ptr = XmTextFieldGetString(AGWPE_host_data);
+    xastir_snprintf(devices[AGWPE_port].device_host_name,
+        sizeof(devices[AGWPE_port].device_host_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AGWPE_port].device_host_name);
+
+    temp_ptr = XmTextFieldGetString(AGWPE_password_data);
+    xastir_snprintf(devices[AGWPE_port].device_host_pswd,
+        sizeof(devices[AGWPE_port].device_host_pswd),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AGWPE_port].device_host_pswd);
+
+    temp_ptr = XmTextFieldGetString(AGWPE_comment);
+    xastir_snprintf(devices[AGWPE_port].comment,
+        sizeof(devices[AGWPE_port].comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AGWPE_port].comment);
+
+    temp_ptr = XmTextFieldGetString(AGWPE_port_data);
+    devices[AGWPE_port].sp=atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(AGWPE_unproto1_data);
+    xastir_snprintf(devices[AGWPE_port].unproto1,
+        sizeof(devices[AGWPE_port].unproto1),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    
+    (void)remove_trailing_spaces(devices[AGWPE_port].unproto1);
+
+    if(check_unproto_path(devices[AGWPE_port].unproto1)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(AGWPE_unproto2_data);
+    xastir_snprintf(devices[AGWPE_port].unproto2,
+        sizeof(devices[AGWPE_port].unproto2),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AGWPE_port].unproto2);
+
+    if(check_unproto_path(devices[AGWPE_port].unproto2)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(AGWPE_unproto3_data);
+    xastir_snprintf(devices[AGWPE_port].unproto3,
+        sizeof(devices[AGWPE_port].unproto3),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+        
+    (void)remove_trailing_spaces(devices[AGWPE_port].unproto3);
+
+    if(check_unproto_path(devices[AGWPE_port].unproto3)) {
+        popup_message_always(langcode("WPUPCFT042"),
+            langcode("WPUPCFT043"));
+    }
+
+    temp_ptr = XmTextFieldGetString(AGWPE_igate_data);
+    xastir_snprintf(devices[AGWPE_port].unproto_igate,
+        sizeof(devices[AGWPE_port].unproto_igate),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AGWPE_port].unproto_igate);
+
+    if(check_unproto_path(devices[AGWPE_port].unproto_igate)) {
+        popup_message_always(langcode("WPUPCFT044"),
+            langcode("WPUPCFT043"));
+    }
+
+
+    temp_ptr = XmTextFieldGetString(AGWPE_radioport_data);
+    xastir_snprintf(devices[AGWPE_port].device_host_filter_string,
+        sizeof(devices[AGWPE_port].device_host_filter_string),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(devices[AGWPE_port].device_host_filter_string);
+ 
+    if(XmToggleButtonGetState(AGWPE_active_on_startup))
+        devices[AGWPE_port].connect_on_startup=1;
+    else
+        devices[AGWPE_port].connect_on_startup=0;
+
+    if(XmToggleButtonGetState(AGWPE_transmit_data))
+        devices[AGWPE_port].transmit_data=1;
+    else
+        devices[AGWPE_port].transmit_data=0;
+
+//WE7U
+//    if(XmToggleButtonGetState(AGWPE_relay_digipeat))
+//        devices[AGWPE_port].relay_digipeat=1;
+//    else
+        devices[AGWPE_port].relay_digipeat=0;
+
+    if(XmToggleButtonGetState(AGWPE_reconnect_data))
+        devices[AGWPE_port].reconnect=1;
+    else
+        devices[AGWPE_port].reconnect=0;
+
+//  n8ysz 20041213
+//    if (devices[AGWPE_port].connect_on_startup==1 || was_up) {
+    if ( was_up) {
+        (void)add_device(AGWPE_port,
+            DEVICE_NET_AGWPE,
+            devices[AGWPE_port].device_host_name,
+            devices[AGWPE_port].device_host_pswd,
+            devices[AGWPE_port].sp,
+            0,
+            0,
+            devices[AGWPE_port].reconnect,
+            "");
+    }
+
+    /* delete list */
+//    modify_device_list(4,0);
+
+
+    /* add device type */
+    devices[AGWPE_port].device_type=DEVICE_NET_AGWPE;
+
+    /* rebuild list */
+//    modify_device_list(3,0);
+
+
+end_critical_section(&devices_lock, "interface_gui.c:AGWPE_change_data" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+    AGWPE_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Config_AGWPE( /*@unused@*/ Widget w, int config_type, int port) {
+    static Widget  pane, form, button_ok, button_cancel,
+                ihost, iport, password, password_fl, sep,
+                igate, igate_box, igate_o_0, igate_o_1, igate_o_2,
+                igate_label, frame, proto, proto1, proto2, proto3,
+                radioport_label, comment;
+    Atom delw;
+    char temp[40];
+    Arg al[50];                      // Arg list
+    register unsigned int ac = 0;    // Arg Count
+
+    if(!config_AGWPE_dialog) {
+        AGWPE_port=port;
+        config_AGWPE_dialog = XtVaCreatePopupShell(langcode("WPUPCFIA01"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Config_AGWPE pane",xmPanedWindowWidgetClass, config_AGWPE_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Config_AGWPE form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        AGWPE_active_on_startup  = XtVaCreateManagedWidget(langcode("UNIOP00011"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_transmit_data  = XtVaCreateManagedWidget(langcode("UNIOP00010"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AGWPE_active_on_startup,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_relay_digipeat = XtVaCreateManagedWidget(langcode("UNIOP00030"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AGWPE_transmit_data,
+                                      XmNleftOffset ,35,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        ihost = XtVaCreateManagedWidget(langcode("WPUPCFIA02"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_host_data = XtVaCreateManagedWidget("Config_AGWPE host_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 30,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, ihost,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        iport = XtVaCreateManagedWidget(langcode("WPUPCFIA03"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,AGWPE_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,AGWPE_host_data,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_port_data = XtVaCreateManagedWidget("Config_AGWPE port_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 5,
+                                      XmNwidth, ((5*7)+2),
+                                      XmNmaxLength, 6,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, iport,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_transmit_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AGWPE_port_data,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_comment = XtVaCreateManagedWidget("Config_AGWPE comment", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 49,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_transmit_data,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, comment,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        password = XtVaCreateManagedWidget(langcode("WPUPCFIA09"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_password_data = XtVaCreateManagedWidget("Config_AGWPE password_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 20,
+                                      XmNmaxLength, 20,
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, password,
+                                      XmNleftOffset, 10,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        password_fl = XtVaCreateManagedWidget(langcode("WPUPCFIA10"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, ihost,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,AGWPE_password_data,
+                                      XmNleftOffset,20,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      NULL);
+
+        AGWPE_reconnect_data = XtVaCreateManagedWidget(langcode("WPUPCFIA11"),xmToggleButtonWidgetClass,form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        radioport_label = XtVaCreateManagedWidget(langcode("WPUPCFIA15"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 25,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, AGWPE_reconnect_data,
+                                      XmNleftOffset, 50,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_radioport_data = XtVaCreateManagedWidget("Config_AGWPE radioport_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 3,
+                                      XmNmaxLength, 3 ,
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, radioport_label,
+                                      XmNleftOffset, 10,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, password,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        frame = XtVaCreateManagedWidget("Config_AGWPE frame", xmFrameWidgetClass, form,
+                                     XmNtopAttachment, XmATTACH_WIDGET,
+                                     XmNtopWidget, AGWPE_reconnect_data,
+                                     XmNtopOffset, 10,
+                                     XmNbottomAttachment, XmATTACH_NONE,
+                                     XmNleftAttachment, XmATTACH_FORM,
+                                     XmNleftOffset, 10,
+                                     XmNrightAttachment, XmATTACH_FORM,
+                                     XmNrightOffset, 10,
+                                     XmNbackground, colors[0xff],
+                                     NULL);
+
+        igate = XtVaCreateManagedWidget(langcode("IGPUPCF000"),xmLabelWidgetClass, frame,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                    NULL);
+
+        // Set args for color
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+
+
+        igate_box = XmCreateRadioBox(frame,"Config_AGWPE IGate box",al,ac);
+
+        XtVaSetValues(igate_box,XmNorientation, XmVERTICAL,XmNnumColumns,2,NULL);
+
+        igate_o_0 = XtVaCreateManagedWidget(langcode("IGPUPCF001"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(igate_o_0,XmNvalueChangedCallback,igate_toggle,"0");
+
+        igate_o_1 = XtVaCreateManagedWidget(langcode("IGPUPCF002"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(igate_o_1,XmNvalueChangedCallback,igate_toggle,"1");
+
+        igate_o_2 = XtVaCreateManagedWidget(langcode("IGPUPCF003"),xmToggleButtonGadgetClass,
+                                        igate_box,
+                                        XmNbackground, colors[0xff],
+                                        XmNfontList, fontlist1,
+                                        NULL);
+        XtAddCallback(igate_o_2,XmNvalueChangedCallback,igate_toggle,"2");
+
+        proto = XtVaCreateManagedWidget(langcode("WPUPCFT011"), xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, frame,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT012"), VERSIONFRM);
+
+        proto1 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 45,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_unproto1_data = XtVaCreateManagedWidget("Config_AGWPE protopath1", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, proto1,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT013"), VERSIONFRM);
+
+        proto2 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto1,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 45,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_unproto2_data = XtVaCreateManagedWidget("Config_AGWPE protopath2", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_unproto1_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, proto2,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        xastir_snprintf(temp, sizeof(temp), langcode("WPUPCFT014"), VERSIONFRM);
+
+        proto3 = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto2,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 45,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        AGWPE_unproto3_data = XtVaCreateManagedWidget("Config_AGWPE protopath3", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_unproto2_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, proto3,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("IGPUPCF004"));
+        igate_label = XtVaCreateManagedWidget(temp, xmLabelWidgetClass, form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, proto3,
+                                      XmNtopOffset, 15,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 45,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        AGWPE_igate_data = XtVaCreateManagedWidget("Config_AGWPE igate_data", xmTextFieldWidgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 25,
+                                      XmNwidth, ((25*7)+2),
+                                      XmNmaxLength, 40,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_unproto3_data,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, igate_label,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        sep = XtVaCreateManagedWidget("Config_AGWPE sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, AGWPE_igate_data,
+                                      XmNtopOffset, 14,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, AGWPE_change_data, config_AGWPE_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, AGWPE_destroy_shell, config_AGWPE_dialog);
+
+        pos_dialog(config_AGWPE_dialog);
+
+        delw = XmInternAtom(XtDisplay(config_AGWPE_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(config_AGWPE_dialog, delw, AGWPE_destroy_shell, (XtPointer)config_AGWPE_dialog);
+
+        if (config_type==0) {
+            /* first time port */
+            XmToggleButtonSetState(AGWPE_active_on_startup,TRUE,FALSE);
+            XmToggleButtonSetState(AGWPE_transmit_data,TRUE,FALSE);
+            //XmTextFieldSetString(AGWPE_host_data,"first.aprs.net");
+            XmTextFieldSetString(AGWPE_host_data,"localhost");
+            XmTextFieldSetString(AGWPE_port_data,"8000");
+            XmTextFieldSetString(AGWPE_comment,"");
+            XmToggleButtonSetState(AGWPE_reconnect_data,FALSE,FALSE);
+            XmToggleButtonSetState(AGWPE_relay_digipeat, FALSE, FALSE);
+            device_igate_options=0;
+            XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+            XmTextFieldSetString(AGWPE_unproto1_data,"WIDE2-2");
+            XmTextFieldSetString(AGWPE_unproto2_data,"");
+            XmTextFieldSetString(AGWPE_unproto3_data,"");
+            XmTextFieldSetString(AGWPE_igate_data,"");
+            XmTextFieldSetString(AGWPE_radioport_data,"1");
+
+//WE7U
+// Keep this statement until we get relay digipeating functional for
+// this interface.
+XtSetSensitive(AGWPE_relay_digipeat, FALSE);
+
+        }
+        else {
+            /* reconfig */
+
+begin_critical_section(&devices_lock, "interface_gui.c:Config_AGWPE" );
+
+           if (devices[AGWPE_port].connect_on_startup)
+                XmToggleButtonSetState(AGWPE_active_on_startup,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(AGWPE_active_on_startup,FALSE,FALSE);
+
+            if (devices[AGWPE_port].transmit_data)
+                XmToggleButtonSetState(AGWPE_transmit_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(AGWPE_transmit_data,FALSE,FALSE);
+
+//            if (devices[AGWPE_port].relay_digipeat)
+//                XmToggleButtonSetState(AGWPE_relay_digipeat, TRUE, FALSE);
+//            else
+                XmToggleButtonSetState(AGWPE_relay_digipeat, FALSE, FALSE);
+
+//            if (devices[AGWPE_port].transmit_data) {
+//                XtSetSensitive(AGWPE_relay_digipeat, TRUE);
+//            }
+//            else
+                XtSetSensitive(AGWPE_relay_digipeat, FALSE);
+
+            XmTextFieldSetString(AGWPE_host_data,devices[AGWPE_port].device_host_name);
+            xastir_snprintf(temp, sizeof(temp), "%d", devices[AGWPE_port].sp);
+            XmTextFieldSetString(AGWPE_port_data,temp);
+            XmTextFieldSetString(AGWPE_password_data,devices[AGWPE_port].device_host_pswd);
+            XmTextFieldSetString(AGWPE_comment,devices[AGWPE_port].comment);
+
+            if (devices[AGWPE_port].reconnect)
+                XmToggleButtonSetState(AGWPE_reconnect_data,TRUE,FALSE);
+            else
+                XmToggleButtonSetState(AGWPE_reconnect_data,FALSE,FALSE);
+
+            XmTextFieldSetString(AGWPE_radioport_data,devices[AGWPE_port].device_host_filter_string);
+ 
+            switch (devices[AGWPE_port].igate_options) {
+                case(0):
+                    XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+                    device_igate_options=0;
+                    break;
+
+                case(1):
+                    XmToggleButtonSetState(igate_o_1,TRUE,FALSE);
+                    device_igate_options=1;
+                    break;
+
+                case(2):
+                    XmToggleButtonSetState(igate_o_2,TRUE,FALSE);
+                    device_igate_options=2;
+                    break;
+
+                default:
+                    XmToggleButtonSetState(igate_o_0,TRUE,FALSE);
+                    device_igate_options=0;
+                    break;
+            }
+
+            XmTextFieldSetString(AGWPE_unproto1_data,devices[AGWPE_port].unproto1);
+            XmTextFieldSetString(AGWPE_unproto2_data,devices[AGWPE_port].unproto2);
+            XmTextFieldSetString(AGWPE_unproto3_data,devices[AGWPE_port].unproto3);
+            XmTextFieldSetString(AGWPE_igate_data,devices[AGWPE_port].unproto_igate);
+
+end_critical_section(&devices_lock, "interface_gui.c:Config_AGWPE" );
+
+        }
+        XtManageChild(igate_box);
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(config_AGWPE_dialog,XtGrabNone);
+        fix_dialog_size(config_AGWPE_dialog);
+    } else {
+        (void)XRaiseWindow(XtDisplay(config_AGWPE_dialog), XtWindow(config_AGWPE_dialog));
+    }
+}
+
+
+
+
+
+/*****************************************************/
+/* Configure Interface GUI                           */
+/*****************************************************/
+
+int are_shells_up(void) {
+    int up;
+
+    up=1;
+    if (config_TNC_dialog) {
+        (void)XRaiseWindow(XtDisplay(config_TNC_dialog), XtWindow(config_TNC_dialog));
+    } else {
+        if (config_GPS_dialog) {
+            (void)XRaiseWindow(XtDisplay(config_GPS_dialog), XtWindow(config_GPS_dialog));
+        } else {
+            if (config_WX_dialog) {
+                (void)XRaiseWindow(XtDisplay(config_WX_dialog), XtWindow(config_WX_dialog));
+            } else {
+                if (config_NGPS_dialog) {
+                    (void)XRaiseWindow(XtDisplay(config_NGPS_dialog), XtWindow(config_NGPS_dialog));
+                } else {
+                    if (config_AX25_dialog) {
+                        (void)XRaiseWindow(XtDisplay(config_AX25_dialog), XtWindow(config_AX25_dialog));
+                    } else {
+                        if (config_Inet_dialog) {
+                            (void)XRaiseWindow(XtDisplay(config_Inet_dialog), XtWindow(config_Inet_dialog));
+                        } else {
+                            if (config_NWX_dialog) {
+                                (void)XRaiseWindow(XtDisplay(config_NWX_dialog), XtWindow(config_NWX_dialog));
+                            } else {
+                                if (config_Database_dialog) {
+                                    (void)XRaiseWindow(XtDisplay(config_Database_dialog), XtWindow(config_Database_dialog));
+                                } else {
+#ifdef HAVE_DB
+                                    if (config_Sql_Database_dialog) {
+                                        (void)XRaiseWindow(XtDisplay(config_Sql_Database_dialog), XtWindow(config_Sql_Database_dialog));
+                                    } else {
+
+#endif /* HAVE_DB */
+                                        if (config_AGWPE_dialog) {
+                                            (void)XRaiseWindow(XtDisplay(config_AGWPE_dialog), XtWindow(config_AGWPE_dialog));
+                                        } else up=0;
+#ifdef HAVE_DB
+                                    }
+#endif /* HAVE_DB */
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return(up);
+}
+
+
+
+
+
+void Choose_interface_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    if (are_shells_up()==0) {
+        XtPopdown(shell);
+        XtDestroyWidget(shell);
+        choose_interface_dialog = (Widget)NULL;
+    }
+}
+
+
+
+
+
+void modify_device_list(int option, int port) {
+    int i,n;
+    char temp[150];
+    char temp2[150];
+    XmString str_ptr;
+
+
+    n=1;
+    for (i=0; i < MAX_IFACE_DEVICES; i++) {
+        if (devices[i].device_type!=DEVICE_NONE) {
+            switch (option) {
+                case 0 :
+                    /* delete entire list available */
+                    XmListDeleteAllItems(control_iface_list);
+                    return; // Exit routine
+                    break;
+
+                case 1 :
+                    /* delete item pointed to by port */
+                    if (i==port)
+                        XmListDeletePos(control_iface_list,n);
+                    n++;
+                    break;
+
+                case 2 :
+                    /* create item list */
+                    /* format list for device modify*/
+                    switch (devices[i].device_type) {
+                        case DEVICE_SERIAL_TNC:
+                        case DEVICE_SERIAL_TNC_HSP_GPS:
+                        case DEVICE_SERIAL_TNC_AUX_GPS:
+                        case DEVICE_SERIAL_KISS_TNC:
+                        case DEVICE_SERIAL_GPS:
+                        case DEVICE_SERIAL_WX:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00000"),
+                                langcode("UNIOP00006"),
+                                i,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_name,
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        case DEVICE_SERIAL_MKISS_TNC:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00001"),
+                                langcode("UNIOP00006"),
+                                i,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_name,
+                                atoi(devices[i].radio_port),
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        case DEVICE_NET_DATABASE:
+                        case DEVICE_SQL_DATABASE:
+                        case DEVICE_NET_STREAM:
+                        case DEVICE_NET_GPSD:
+                        case DEVICE_NET_WX:
+                        case DEVICE_NET_AGWPE:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00001"),
+                                langcode("UNIOP00006"),
+                                i,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_host_name,
+                                devices[i].sp,
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        case DEVICE_AX25_TNC:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00002"),
+                                langcode("UNIOP00006"),
+                                i,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_name,
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        default:
+                            break;
+                    }
+                    /* look at list data (Must be "Device" port#) */
+                    XmListAddItem(control_iface_list, str_ptr = XmStringCreateLtoR(temp,XmFONTLIST_DEFAULT_TAG),n++);
+ 
+                    XmStringFree(str_ptr);
+                    break;
+
+                case 3 :
+                    /* create item list */
+                    /* format list for device control*/
+                    if (port_data[i].active==DEVICE_IN_USE) {
+                        switch (port_data[i].status) {
+                            case DEVICE_DOWN:
+                                xastir_snprintf(temp2,
+                                    sizeof(temp2),
+                                    "%s",
+                                    langcode("IFDIN00006"));
+                                break;
+
+                            case DEVICE_UP:
+                                xastir_snprintf(temp2,
+                                    sizeof(temp2),
+                                    "%s",
+                                    langcode("IFDIN00007"));
+                                break;
+
+                            case DEVICE_ERROR:
+                                xastir_snprintf(temp2,
+                                    sizeof(temp2),
+                                    "%s",
+                                    langcode("IFDIN00008"));
+                                break;
+
+                            default:
+                                xastir_snprintf(temp2,
+                                    sizeof(temp2),
+                                    "%s",
+                                    langcode("IFDIN00009"));
+                                break;
+                        }
+                    } else {
+                        xastir_snprintf(temp2,
+                            sizeof(temp2),
+                            "%s",
+                            langcode("IFDIN00006"));
+                    }
+                    switch (devices[i].device_type) {
+                        case DEVICE_SERIAL_TNC:
+                        case DEVICE_SERIAL_KISS_TNC:
+                        case DEVICE_SERIAL_TNC_HSP_GPS:
+                        case DEVICE_SERIAL_TNC_AUX_GPS:
+                        case DEVICE_SERIAL_GPS:
+                        case DEVICE_SERIAL_WX:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00003"),
+                                langcode("UNIOP00006"),
+                                i,
+                                temp2,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_name,
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        case DEVICE_SERIAL_MKISS_TNC:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00004"),
+                                langcode("UNIOP00006"),
+                                i,
+                                temp2,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_name,
+                                atoi(devices[i].radio_port),
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        case DEVICE_NET_DATABASE:
+                        case DEVICE_SQL_DATABASE:
+                        case DEVICE_NET_STREAM:
+                        case DEVICE_NET_GPSD:
+                        case DEVICE_NET_WX:
+                        case DEVICE_NET_AGWPE:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00004"),
+                                langcode("UNIOP00006"),
+                                i,
+                                temp2,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_host_name,
+                                devices[i].sp,
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        case DEVICE_AX25_TNC:
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                langcode("IFDIN00005"),
+                                langcode("UNIOP00006"),
+                                i,
+                                temp2,
+                                dtype[devices[i].device_type].device_name,
+                                devices[i].device_name,
+                                devices[i].comment);
+                            strncat(temp,
+                                "    ",
+                                sizeof(temp) - 1 - strlen(temp));
+                            break;
+
+                        default:
+                            break;
+                    }
+                    /* look at list data (Must be "Device" port#) */
+                    XmListAddItem(control_iface_list, str_ptr = XmStringCreateLtoR(temp,XmFONTLIST_DEFAULT_TAG),n++);
+                    XmStringFree(str_ptr);
+                    break;
+
+                case 4 :
+                    /* delete entire list available */
+                    XmListDeleteAllItems(control_iface_list);
+                    return; // Exit routine
+                    break;
+
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+
+
+
+
+// Rebuild the list in the interface control dialog so that the
+// current status of each interface is shown.
+//
+void update_interface_list(void) {
+
+    // If the interface control dialog exists
+    if (control_interface_dialog) {
+
+        // Delete the entire list
+        modify_device_list(4,0);
+
+        // Create the list again with updated values
+        modify_device_list(3,0);
+    }
+}
+
+
+
+
+
+void interface_setup(Widget w, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    char *what = (char *)clientData;
+    int x,i,do_w;
+    char *temp;
+    /*char temp2[100];*/
+    XmString *list;
+    int port;
+    int found;
+
+    port=-1;
+    found=0;
+    do_w=atoi(what);
+
+    /* get option selected */
+    XtVaGetValues(interface_type_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    for (x=1; x<=i;x++) {
+        if (XmListPosSelected(interface_type_list,x)) {
+            found=x;
+            if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&temp))
+                x=i+1;
+        }
+    }
+
+    /* if selection was made */
+    if (found) {
+        if (do_w==0) {  // Add an interface
+            /* add */
+            /*fprintf(stderr,"ADD DEVICE\n");*/
+
+            /* delete list */
+
+begin_critical_section(&devices_lock, "interface_gui.c:interface_setup" );
+            modify_device_list(0,0);
+end_critical_section(&devices_lock, "interface_gui.c:interface_setup" );
+
+            port=get_open_device();     // Find an unused port number
+            /*fprintf(stderr,"Open_port %d\n",port);*/
+
+            if(port!=-1) {
+                /*devices[port].device_type=found;*/
+                /*fprintf(stderr,"adding device %s on port %d\n",dtype[found].device_name,port);*/
+
+                switch (found) {
+
+//WE7U:  Set up for new KISS device type
+                    case DEVICE_SERIAL_KISS_TNC:
+                        // configure this port
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL KISS TNC\n");
+                        Config_TNC(w, DEVICE_SERIAL_KISS_TNC, 0, port);
+                        break;
+
+                    case DEVICE_SERIAL_MKISS_TNC:
+                        // configure this port
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL MKISS TNC\n");
+                        Config_TNC(w, DEVICE_SERIAL_MKISS_TNC, 0, port);
+                        break;
+
+                    case DEVICE_SERIAL_TNC:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL TNC\n");
+                        Config_TNC(w, DEVICE_SERIAL_TNC, 0, port);
+                        break;
+
+                    case DEVICE_SERIAL_TNC_HSP_GPS:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL TNC w HSP GPS\n");
+                        Config_TNC(w, DEVICE_SERIAL_TNC_HSP_GPS, 0, port);
+                        break;
+
+                    case DEVICE_SERIAL_TNC_AUX_GPS:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL TNC w AUX GPS\n");
+                        Config_TNC(w, DEVICE_SERIAL_TNC_AUX_GPS, 0, port);
+                        break;
+
+                    case DEVICE_SERIAL_GPS:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL GPS\n");
+                        Config_GPS(w, 0, port);
+                        break;
+
+                    case DEVICE_SERIAL_WX:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SERIAL WX\n");
+                        Config_WX(w, 0, port);
+                        break;
+
+                    case DEVICE_NET_WX:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD Network WX\n");
+                        Config_NWX(w, 0, port);
+                        break;
+
+                    case DEVICE_NET_GPSD:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD Network GPS\n");
+                        Config_NGPS(w, 0, port);
+                        break;
+
+                    case DEVICE_AX25_TNC:
+                        /* configure this port */
+                        if (debug_level & 1)
+#ifdef HAVE_LIBAX25
+                            fprintf(stderr,"ADD AX.25 TNC\n");
+                        Config_AX25(w, 0, port);
+#else   // HAVE_LIBAX25
+                        fprintf(stderr,"AX.25 support not compiled into Xastir!\n");
+                        popup_message(langcode("POPEM00004"),langcode("POPEM00021"));
+
+#endif  // HAVE_LIBAX25
+                        break;
+
+                    case DEVICE_NET_STREAM:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD NET STREAM\n");
+                        Config_Inet(w, 0, port);
+                        break;
+
+                    case DEVICE_NET_DATABASE:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD NET DATABASE\n");
+                        Config_Database(w, 0, port);
+                        break;
+#ifdef HAVE_DB
+                    case DEVICE_SQL_DATABASE:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD SQL DATABASE\n");
+                        Config_sql_Database(w, 0, port);
+                        break;
+#endif /* HAVE_DB */
+                    case DEVICE_NET_AGWPE:
+                        /* configure this port */
+                        if (debug_level & 1)
+                            fprintf(stderr,"ADD NET AGWPE\n");
+                        Config_AGWPE(w, 0, port);
+                        break;
+
+                    default:
+                        break;
+                }
+            }
+
+            /* rebuild list */
+
+begin_critical_section(&devices_lock, "interface_gui.c:interface_setup" );
+            modify_device_list(2,0);
+end_critical_section(&devices_lock, "interface_gui.c:interface_setup" );
+
+        }
+        /*fprintf(stderr,"SELECTION is %s\n",temp);*/
+        XtFree(temp);
+    }
+}
+
+
+
+
+
+// clientData:
+//      0 = Add
+//      1 = Delete
+//      2 = Properties
+//
+void interface_option(Widget w, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget pane, form, label, button_add, button_cancel;
+    char *what = (char *)clientData;
+    int i,x,n,do_w;
+    char *temp;
+    char temp2[50];
+    int port;
+    XmString *list;
+    int data_on,pos;
+    int found;
+    Atom delw;
+    XmString str_ptr;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+    data_on=0;
+    pos=0;
+    found=0;
+    do_w=atoi(what);
+    switch (do_w) {
+        case 0:/* add interface */
+            if (!choose_interface_dialog) {
+                choose_interface_dialog = XtVaCreatePopupShell(langcode("WPUPCIF002"),
+                    xmDialogShellWidgetClass, appshell,
+                    XmNdeleteResponse, XmDESTROY,
+                    XmNdefaultPosition, FALSE,
+                    XmNresize, FALSE,
+                    XmNfontList, fontlist1,
+                    NULL);
+
+                pane = XtVaCreateWidget("interface_option pane",xmPanedWindowWidgetClass, choose_interface_dialog,
+                    XmNbackground, colors[0xff],
+                    NULL);
+
+                form =  XtVaCreateWidget("interface_option form",xmFormWidgetClass, pane,
+                        XmNfractionBase, 5,
+                        XmNbackground, colors[0xff],
+                        XmNautoUnmanage, FALSE,
+                        XmNshadowThickness, 1,
+                        NULL);
+
+                label = XtVaCreateManagedWidget(langcode("WPUPCIF002"),xmLabelWidgetClass, form,
+                                XmNtopAttachment, XmATTACH_FORM,
+                                XmNtopOffset, 10,
+                                XmNbottomAttachment, XmATTACH_NONE,
+                                XmNleftAttachment, XmATTACH_FORM,
+                                XmNleftOffset, 5,
+                                XmNrightAttachment, XmATTACH_NONE,
+                                XmNbackground, colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+
+                /*set args for color */
+                ac=0;
+                XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+                XtSetArg(al[ac], XmNvisibleItemCount, MAX_IFACE_DEVICE_TYPES); ac++;
+                XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+                XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+                XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+                XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+                XtSetArg(al[ac], XmNtopWidget, label); ac++;
+                XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+                XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+                XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+                XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+                XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+                interface_type_list = XmCreateScrolledList(form,"interface_option list",al,ac);
+                n=1;
+                for (i=1; i<MAX_IFACE_DEVICE_TYPES; i++) {
+                    XmListAddItem(interface_type_list, str_ptr = XmStringCreateLtoR(dtype[i].device_name,XmFONTLIST_DEFAULT_TAG),n++);
+                    XmStringFree(str_ptr);
+                }
+                button_add = XtVaCreateManagedWidget(langcode("UNIOP00007"),xmPushButtonGadgetClass, form,
+                                XmNnavigationType, XmTAB_GROUP,
+                                XmNtraversalOn, TRUE,
+                                XmNtopAttachment, XmATTACH_WIDGET,
+                                XmNtopWidget, XtParent(interface_type_list),
+                                XmNtopOffset,10,
+                                XmNbottomAttachment, XmATTACH_FORM,
+                                XmNbottomOffset, 5,
+                                XmNleftAttachment, XmATTACH_POSITION,
+                                XmNleftPosition, 1,
+                                XmNrightAttachment, XmATTACH_POSITION,
+                                XmNrightPosition, 2,
+                                XmNbackground, colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+
+                button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, form,
+                                XmNnavigationType, XmTAB_GROUP,
+                                XmNtraversalOn, TRUE,
+                                XmNtopAttachment, XmATTACH_WIDGET,
+                                XmNtopWidget, XtParent(interface_type_list),
+                                XmNtopOffset,10,
+                                XmNbottomAttachment, XmATTACH_FORM,
+                                XmNbottomOffset, 5,
+                                XmNleftAttachment, XmATTACH_POSITION,
+                                XmNleftPosition, 3,
+                                XmNrightAttachment, XmATTACH_POSITION,
+                                XmNrightPosition, 4,
+                                XmNbackground, colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+
+                XtAddCallback(button_cancel, XmNactivateCallback, Choose_interface_destroy_shell, choose_interface_dialog);
+                XtAddCallback(button_add, XmNactivateCallback, interface_setup, "0");
+
+                pos_dialog(choose_interface_dialog);
+
+                delw = XmInternAtom(XtDisplay(choose_interface_dialog),"WM_DELETE_WINDOW", FALSE);
+                XmAddWMProtocolCallback(choose_interface_dialog, delw, Choose_interface_destroy_shell, (XtPointer)configure_interface_dialog);
+
+                XtManageChild(form);
+                XtManageChild(interface_type_list);
+                XtVaSetValues(interface_type_list, XmNbackground, colors[0x0f], NULL);
+                XtManageChild(pane);
+
+                XtPopup(choose_interface_dialog,XtGrabNone);
+                fix_dialog_size(choose_interface_dialog);
+
+                // Move focus to the Cancel button.  This appears to highlight the
+                // button fine, but we're not able to hit the <Enter> key to
+                // have that default function happen.  Note:  We _can_ hit the
+                // <SPACE> key, and that activates the option.
+//                XmUpdateDisplay(choose_interface_dialog);
+                XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+           } else {
+                (void)XRaiseWindow(XtDisplay(choose_interface_dialog), XtWindow(choose_interface_dialog));
+            }
+            break;
+
+        case 1:/* delete interface */
+
+        case 2:/* interface properties */
+            /* get option selected */
+            XtVaGetValues(control_iface_list,
+                    XmNitemCount,&i,
+                    XmNitems,&list,
+                    NULL);
+
+            for (x=1; x<=i;x++) {
+                if(XmListPosSelected(control_iface_list,x)) {
+                    found=1;
+                    if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&temp))
+                        x=i+1;
+                }
+            }
+
+            /* if selection was made */
+            if (found) {
+                /* look at list data (Must be "Device" port#) */
+                if (2 != sscanf(temp,"%49s %d",temp2,&port)) {
+                    fprintf(stderr,"interface_option:sscanf parsing error\n");
+                }
+                if(do_w==1) {
+                    /* delete interface */
+                    /*fprintf(stderr,"delete interface port %d\n",port);*/
+
+                    if (port_data[port].active==DEVICE_IN_USE) {
+                        /* shut down and delete port */
+                        /*fprintf(stderr,"Shutting down port %d\n",port);*/
+                        (void)del_device(port);
+                    }
+
+begin_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                    /* delete item at that port */
+                    modify_device_list(1,port);
+                    /* Clear device */
+                    devices[port].device_type=DEVICE_NONE;
+                    devices[port].device_name[0] = '\0';
+                    devices[port].radio_port[0] = '\0';
+                    devices[port].device_converse_string[0] = '\0';
+                    devices[port].device_host_name[0] = '\0';
+                    devices[port].device_host_pswd[0] = '\0';
+                    devices[port].device_host_filter_string[0] = '\0';
+                    devices[port].comment[0] = '\0';
+                    devices[port].unproto1[0] = '\0';
+                    devices[port].unproto2[0] = '\0';
+                    devices[port].unproto3[0] = '\0';
+                    devices[port].unproto_igate[0] = '\0';
+                    devices[port].style=0;
+                    devices[port].igate_options=0;
+                    devices[port].transmit_data=0;
+                    devices[port].reconnect=0;
+                    devices[port].connect_on_startup=0;
+
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                } else {
+                    /* Properties */
+
+begin_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                    if (debug_level & 1) {
+                        fprintf(stderr,"Changing device  %s on port %d\n",
+                            dtype[devices[port].device_type].device_name,port);
+                    }
+                    switch (devices[port].device_type) {
+                        case DEVICE_SERIAL_TNC:
+
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL TNC\n");
+                            Config_TNC(w, DEVICE_SERIAL_TNC, 1, port);
+                            break;
+
+                        case DEVICE_SERIAL_KISS_TNC:
+
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL KISS TNC\n");
+                            Config_TNC(w, DEVICE_SERIAL_KISS_TNC, 1, port);
+                            break;
+
+                        case DEVICE_SERIAL_MKISS_TNC:
+
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL MKISS TNC\n");
+                            Config_TNC(w, DEVICE_SERIAL_MKISS_TNC, 1, port);
+                            break;
+
+                        case DEVICE_SERIAL_TNC_HSP_GPS:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL TNC with HSP GPS\n");
+                            Config_TNC(w, DEVICE_SERIAL_TNC_HSP_GPS, 1, port);
+                            break;
+
+                        case DEVICE_SERIAL_TNC_AUX_GPS:
+
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL TNC with AUX GPS\n");
+                            Config_TNC(w, DEVICE_SERIAL_TNC_AUX_GPS, 1, port);
+                            break;
+
+                        case DEVICE_SERIAL_GPS:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL GPS\n");
+                            Config_GPS(w, 1, port);
+                            break;
+
+                        case DEVICE_SERIAL_WX:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SERIAL WX\n");
+                            Config_WX(w, 1, port);
+                            break;
+
+                        case DEVICE_NET_WX:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify Network WX\n");
+                            Config_NWX(w, 1, port);
+                            break;
+
+                        case DEVICE_NET_GPSD:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify Network GPS\n");
+                            Config_NGPS(w, 1, port);
+                            break;
+
+                        case DEVICE_AX25_TNC:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify AX.25 TNC\n");
+                            Config_AX25(w, 1, port);
+                            break;
+
+                        case DEVICE_NET_STREAM:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify NET STREAM\n");
+                            Config_Inet(w, 1, port);
+                            break;
+
+                        case DEVICE_NET_DATABASE:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify NET DATABASE\n");
+                            Config_Database(w, 1, port);
+                            break;
+#ifdef HAVE_DB
+                        case DEVICE_SQL_DATABASE:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify SQL DATABASE\n");
+                            Config_sql_Database(w, 1, port);
+                            break;
+#endif /* HAVE_DB */
+                        case DEVICE_NET_AGWPE:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            /* configure this port */
+                            if (debug_level & 1)
+                                fprintf(stderr,"Modify NET AGWPE\n");
+                            Config_AGWPE(w, 1, port);
+                            break;
+
+                        default:
+ 
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+                            break;
+                    }
+                }
+                /*fprintf(stderr,"interface - %s\n",temp);*/
+                XtFree(temp);
+            }
+            break;
+
+        default:
+            break;
+    }
+}
+
+
+
+
+
+/*****************************************************/
+/* Control Interface GUI                           */
+/*****************************************************/
+extern void startup_all_or_defined_port(int port);
+extern void shutdown_all_active_or_defined_port(int port);
+
+
+
+
+
+void start_stop_interface( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    char *which = (char *)clientData;
+    int do_w;
+    char temp2[50];
+    int i,x;
+    char *temp;
+    int port;
+    XmString *list;
+    int found;
+
+    busy_cursor(appshell);
+
+    found=0;
+    /* get option selected */
+    XtVaGetValues(control_iface_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    for (x=1; x<=i;x++) {
+        if (XmListPosSelected(control_iface_list,x)) {
+            found=1;
+            if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&temp))
+                x=i+1;
+        }
+    }
+
+    /* if selection was made */
+    if (found) {
+
+        /* delete list */
+
+//begin_critical_section(&devices_lock, "interface_gui.c:start_stop_interface" );
+//        modify_device_list(4,0);
+//end_critical_section(&devices_lock, "interface_gui.c:start_stop_interface" );
+
+        /* look at list data (Must be "Device" port#) */
+        if (2 != sscanf(temp,"%49s %d",temp2,&port)) {
+            fprintf(stderr,"start_stop_interface:sscanf parsing error\n");
+        }
+        /*fprintf(stderr,"Port to change %d\n",port);*/
+        do_w = atoi(which);
+        if (do_w) {
+            shutdown_all_active_or_defined_port(port);
+        } else {
+            /*fprintf(stderr,"DO port up\n");*/
+            if (port_data[port].active==DEVICE_IN_USE) {
+                /*fprintf(stderr,"Device was up, Shutting down\n");*/
+                shutdown_all_active_or_defined_port(port);
+            }
+            /* now start port */
+            startup_all_or_defined_port(port);
+        }
+        /* rebuild list */
+
+//begin_critical_section(&devices_lock, "interface_gui.c:start_stop_interface" );
+//        modify_device_list(3,0);
+//end_critical_section(&devices_lock, "interface_gui.c:start_stop_interface" );
+
+        // Rebuild the interface control list
+        update_interface_list();
+
+        XtFree(temp);
+    }
+}
+
+
+
+
+
+void start_stop_all_interfaces( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    char *which = (char *)clientData;   // Whether to start or stop the interfaces
+    int do_w;
+
+    busy_cursor(appshell);
+
+//begin_critical_section(&devices_lock, "interface_gui.c:start_stop_all_interfaces" );
+//    modify_device_list(4,0);
+//end_critical_section(&devices_lock, "interface_gui.c:start_stop_all_interfaces" );
+
+    do_w = atoi(which);
+    if (do_w) {     // We wish to shut down all ports
+        shutdown_all_active_or_defined_port(-1);
+    }
+    else {        // We wish to start up all ports
+        startup_all_or_defined_port(-2);
+    }
+    /* rebuild list */
+
+//begin_critical_section(&devices_lock, "interface_gui.c:start_stop_all_interfaces" );
+//    modify_device_list(3,0);
+//end_critical_section(&devices_lock, "interface_gui.c:start_stop_all_interfaces" );
+
+    // Rebuild the interface control list
+    update_interface_list();
+
+}
+
+
+
+
+
+void Control_interface_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&control_interface_dialog_lock, "interface_gui.c:Control_interface_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    control_interface_dialog = (Widget)NULL;
+
+end_critical_section(&control_interface_dialog_lock, "interface_gui.c:Control_interface_destroy_shell" );
+
+}
+
+
+
+
+
+void control_interface( /*@unused@*/ Widget w,  /*@unused@*/ XtPointer clientData,  /*@unused@*/ XtPointer callData) {
+    static Widget rowcol, form, button_start, button_stop, button_start_all, button_stop_all, button_cancel;
+    static Widget button_add, button_delete, button_properties;
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+
+    if(!control_interface_dialog) {
+
+begin_critical_section(&control_interface_dialog_lock, "interface_gui.c:control_interface" );
+
+        control_interface_dialog = XtVaCreatePopupShell(langcode("IFPUPCT000"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNresize, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        rowcol =  XtVaCreateWidget("control_interface rowcol",xmRowColumnWidgetClass, control_interface_dialog,
+                            XmNorientation, XmVERTICAL,
+                            XmNnumColumns, 1,
+                            XmNpacking, XmPACK_TIGHT,
+                            XmNisAligned, TRUE,
+                            XmNentryAlignment, XmALIGNMENT_CENTER,
+                            XmNkeyboardFocusPolicy, XmEXPLICIT,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+ 
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+        XtSetArg(al[ac], XmNvisibleItemCount, MAX_IFACE_DEVICES); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+        control_iface_list = XmCreateScrolledList(rowcol,"control_interface list",al,ac);
+
+        /* build device list */
+
+begin_critical_section(&devices_lock, "interface_gui.c:control_interface" );
+        modify_device_list(3,0);
+end_critical_section(&devices_lock, "interface_gui.c:control_interface" );
+
+        form =  XtVaCreateWidget("control_interface form",xmFormWidgetClass, rowcol,
+                    XmNfractionBase, 4,
+                    XmNbackground, colors[0xff],
+                    XmNautoUnmanage, FALSE,
+                    XmNshadowThickness, 1,
+                    NULL);
+
+        button_start = XtVaCreateManagedWidget(langcode("IFPUPCT001"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_FORM,
+                            XmNtopOffset, 5,
+                            XmNleftAttachment, XmATTACH_FORM,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 1,
+                            XmNbottomAttachment, XmATTACH_NONE,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_start_all = XtVaCreateManagedWidget(langcode("IFPUPCT003"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_FORM,
+                            XmNtopOffset, 5,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 1,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 2,
+                            XmNbottomAttachment, XmATTACH_NONE,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_add = XtVaCreateManagedWidget(langcode("UNIOP00007"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_FORM,
+                            XmNtopOffset,5,
+                            XmNbottomAttachment, XmATTACH_NONE,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 2,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 3,
+                            XmNbackground, colors[0xff],
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_delete = XtVaCreateManagedWidget(langcode("UNIOP00008"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_FORM,
+                            XmNtopOffset,5,
+                            XmNbottomAttachment, XmATTACH_NONE,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 3,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 4,
+                            XmNbackground, colors[0xff],
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_stop = XtVaCreateManagedWidget(langcode("IFPUPCT002"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_WIDGET,
+                            XmNtopWidget, button_start,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 0,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 1,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_stop_all = XtVaCreateManagedWidget(langcode("IFPUPCT004"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_WIDGET,
+                            XmNtopWidget, button_start,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 1,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 2,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_properties = XtVaCreateManagedWidget(langcode("UNIOP00009"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_WIDGET,
+                            XmNtopWidget, button_start,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 2,
+                            XmNrightAttachment, XmATTACH_POSITION,
+                            XmNrightPosition, 3,
+                            XmNbackground, colors[0xff],
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, form,
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNtraversalOn, TRUE,
+                            XmNtopAttachment, XmATTACH_WIDGET,
+                            XmNtopWidget, button_start,
+                            XmNrightAttachment, XmATTACH_FORM,
+                            XmNleftAttachment, XmATTACH_POSITION,
+                            XmNleftPosition, 3,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNbackground, colors[0xff],
+                            XmNnavigationType, XmTAB_GROUP,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+        XtAddCallback(button_add, XmNactivateCallback, interface_option, "0");
+        XtAddCallback(button_delete, XmNactivateCallback, interface_option, "1");
+        XtAddCallback(button_properties, XmNactivateCallback, interface_option, "2");
+
+        XtAddCallback(button_cancel, XmNactivateCallback, Control_interface_destroy_shell, control_interface_dialog);
+        XtAddCallback(button_start, XmNactivateCallback, start_stop_interface, "0");
+        XtAddCallback(button_stop, XmNactivateCallback, start_stop_interface, "1");
+
+        XtAddCallback(button_start_all, XmNactivateCallback, start_stop_all_interfaces, "0");
+        XtAddCallback(button_stop_all, XmNactivateCallback, start_stop_all_interfaces, "1");
+
+        delw = XmInternAtom(XtDisplay(control_interface_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(control_interface_dialog, delw, Control_interface_destroy_shell, (XtPointer)control_interface_dialog);
+
+        XtVaSetValues(control_iface_list, XmNbackground, colors[0x0f], NULL);
+ 
+        pos_dialog(control_interface_dialog);
+
+        XtManageChild(control_iface_list);
+        XtManageChild(form);
+        XtManageChild(rowcol);
+
+end_critical_section(&control_interface_dialog_lock, "interface_gui.c:control_interface" );
+
+        XtPopup(control_interface_dialog,XtGrabNone);
+        fix_dialog_size(control_interface_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(control_interface_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+   } else {
+        (void)XRaiseWindow(XtDisplay(control_interface_dialog), XtWindow(control_interface_dialog));
+    }
+}
+
+
+
+
+
+void interface_status(Widget w) {
+    int i;
+    char s;
+    char opt;
+    int read_data;
+    int write_data;
+
+    read_data=0;
+    write_data=0;
+    s='\0';
+
+begin_critical_section(&devices_lock, "interface_gui.c:interface_status" );
+
+    for (i=0; i < MAX_IFACE_DEVICES; i++) {
+        read_data=0;
+        write_data=0;
+        opt='\0';
+
+        if (devices[i].device_type!=DEVICE_NONE) {
+            switch(devices[i].device_type) {
+                case DEVICE_SERIAL_TNC:
+                    s='0';  // Select icon for status bar
+                    break;
+
+                case DEVICE_SERIAL_TNC_HSP_GPS:
+                    s='1';  // Select icon for status bar
+                    break;
+
+                case DEVICE_SERIAL_GPS:
+                    s='2';  // Select icon for status bar
+                    break;
+
+                case DEVICE_SERIAL_WX:
+                case DEVICE_NET_WX:
+                    s='3';  // Select icon for status bar
+                    break;
+
+                case DEVICE_SQL_DATABASE:
+                    s='8';  // Select icon for status bar
+                    break;
+
+                case DEVICE_NET_DATABASE:
+                case DEVICE_NET_STREAM:
+                case DEVICE_NET_AGWPE:
+                    s='4';  // Select icon for status bar
+                    break;
+
+                case DEVICE_AX25_TNC:
+                case DEVICE_SERIAL_KISS_TNC:
+                case DEVICE_SERIAL_MKISS_TNC:
+                    s='5';  // Select icon for status bar
+                    break;
+
+                case DEVICE_NET_GPSD:
+                    s='6';  // Select icon for status bar
+                    break;
+
+                case DEVICE_SERIAL_TNC_AUX_GPS:
+                    s='7';  // Select icon for status bar
+                    break;
+
+                default:
+                    break;
+            }
+            if (port_data[i].active==DEVICE_IN_USE) {
+                if (port_data[i].status==DEVICE_UP) {
+                    if (port_data[i].bytes_input_last != port_data[i].bytes_input) {
+if (begin_critical_section(&port_data_lock, "interface_gui.c:interface_status(1)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", i);
+                        port_data[i].bytes_input_last = port_data[i].bytes_input;
+                        port_data[i].port_activity = 1;
+if (end_critical_section(&port_data_lock, "interface_gui.c:interface_status(2)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", i);
+                        read_data=1;
+                    }
+                    if (port_data[i].bytes_output_last != port_data[i].bytes_output) {
+if (begin_critical_section(&port_data_lock, "interface_gui.c:interface_status(3)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", i);
+                        port_data[i].bytes_output_last = port_data[i].bytes_output;
+                        port_data[i].port_activity = 1;
+if (end_critical_section(&port_data_lock, "interface_gui.c:interface_status(4)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", i);
+                        write_data=1;
+                    }
+                    if (write_data)
+                        opt='>';
+                    else {
+                        if (read_data)
+                            opt='<';
+                        else
+                            opt='^';
+                    }
+                } else
+                    opt='*';
+            } else
+                opt='\0';
+            symbol(w,0,'~',s,opt,XtWindow(iface_da),0,(i*10),0,' ');
+        } else
+            symbol(w,0,'~','#','\0',XtWindow(iface_da),0,(i*10),0,' ');
+    }
+
+end_critical_section(&devices_lock, "interface_gui.c:interface_option" );
+
+}
+
+
diff --git a/src/io-common.c b/src/io-common.c
new file mode 100644
index 0000000..d7d734a
--- /dev/null
+++ b/src/io-common.c
@@ -0,0 +1,70 @@
+
+// $Id: io-common.c,v 1.11 2012/08/25 16:38:29 tvrusso Exp $
+
+
+/* Copyright 2002 Daniel Egnor.  See LICENSE.geocoder file.
+ * Portions Copyright (C) 2004-2012  The Xastir Group
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "io.h"
+#include <ctype.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+int io_out_i4(struct io_file *f,int pos,int o) {
+        unsigned char x[4];
+        x[0] = o >> 24;
+        x[1] = o >> 16;
+        x[2] = o >> 8;
+        x[3] = o;
+        return io_out(f,pos,x,sizeof x);
+}
+
+int io_out_i2(struct io_file *f,int pos,short int o) {
+        unsigned char x[2];
+        x[0] = o >> 8;
+        x[1] = o;
+        return io_out(f,pos,x,sizeof x);
+}
+
+int io_out_i1(struct io_file *f,int pos,signed char o) {
+        return io_out(f,pos,&o,sizeof o);
+}
+
+int io_in_i4(struct io_file *f,int pos,int *i) {
+	unsigned char x[4];
+	const int r = io_in(f,pos,x,sizeof x);
+	if (i) *i = (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3];
+	return r;
+}
+
+int io_in_i2(struct io_file *f,int pos,short *i) {
+	unsigned char x[2];
+	const int r = io_in(f,pos,x,sizeof x);
+	if (i) *i = (x[0] << 8) | x[1];
+	return r;
+}
+
+int io_in_i1(struct io_file *f,int pos,signed char *i) {
+	return io_in(f,pos,i,sizeof *i);
+}
+
+int io_strntoi(const char *str,int len) {
+	int r = 0;
+	int sign = 1;
+	const char * const end = str + len;
+	while (end != str && isspace((int)*str)) ++str;
+	if (end != str && *str == '-') (sign *= -1),++str;
+	if (end != str && *str == '+') ++str;
+	while (end != str && isdigit((int)*str)) r = *str++ - '0' + 10 * r;
+	return r * sign;
+}
diff --git a/src/io-mmap.c b/src/io-mmap.c
new file mode 100644
index 0000000..ab561fc
--- /dev/null
+++ b/src/io-mmap.c
@@ -0,0 +1,218 @@
+
+// $Id: io-mmap.c,v 1.12 2012/08/25 16:38:29 tvrusso Exp $
+
+
+/* Copyright 2002 Daniel Egnor.  See LICENSE.geocoder file.
+ * Portions Copyright (C) 2004-2012  The Xastir Group
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "io.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <string.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+struct io_file {
+	int fd;
+        int prot;
+	off_t file_size;
+	void *map;
+	off_t map_offset;
+	size_t map_size,map_page;
+	char buffer[4096];
+	off_t buffer_offset;
+	size_t buffer_size;
+};
+
+/* Writes any buffered append data. 
+   Returns nonzero iff failed. */
+static int unbuffer(struct io_file *f) {
+	int r;
+	if (!f->buffer_size) return 0;
+	r = write(f->fd,f->buffer,f->buffer_size);
+	if (r > 0) {
+		f->buffer_offset += r;
+		f->buffer_size -= r;
+		if (f->buffer_offset > f->file_size)
+			f->file_size = f->buffer_offset;
+	}
+
+	if (0 != f->buffer_size) {
+		perror("write");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Resets f->file_size to the actual size of the file. 
+   Returns nonzero iff failed. */
+static int checksize(struct io_file *f) {
+	struct stat buf;
+	if (unbuffer(f)) return -1;
+	if (fstat(f->fd,&buf)) {
+		perror("fstat");
+		return -1;
+	}
+
+	f->file_size = buf.st_size;
+	return 0;
+}
+
+struct io_file *io_open(const char *fname) {
+	struct io_file * const f = malloc(sizeof *f);
+
+	if (NULL == f) return NULL;
+	f->fd = open(fname,O_RDWR|O_CREAT,0666);
+        f->prot = PROT_READ|PROT_WRITE;
+        if (f->fd < 0) {
+                f->fd = open(fname,O_RDONLY);
+                f->prot = PROT_READ;
+        }
+	if (f->fd < 0) {
+		perror(fname);
+		free(f);
+		return NULL;
+	}
+
+	f->map = NULL;
+	f->map_offset = 0;
+	f->map_size = 0;
+	f->map_page = getpagesize();
+	f->file_size = 0;
+	f->buffer_offset = 0;
+	f->buffer_size = 0;
+	if (checksize(f)) {
+		close(f->fd);
+		free(f);
+		return NULL;
+	}
+
+	return f;
+}
+
+void io_close(struct io_file *f) {
+	if (NULL != f) {
+		unbuffer(f);
+		close(f->fd);
+		if (NULL != f->map) munmap(f->map,f->map_size);
+		free(f);
+	}
+}
+
+/* Attempts to make the mapping cover [pos,pos+len), or at least [pos].
+   Returns nonzero iff failed. */
+static int remap(struct io_file *f,int pos,int len) {
+	if (pos < (int)f->map_offset || pos >= (int)(f->map_offset + f->map_size) ) {
+		const int flags = MAP_SHARED;
+
+		const off_t b1 = pos / f->map_page * f->map_page;
+		const off_t e1 = b1 + f->map_page;
+
+		off_t b2 = f->map_offset;
+		off_t e2 = b2 + f->map_size;
+		if (b2 > b1) b2 = b1 - (b2 - b1);
+		if (b2 < 0) b2 = 0;
+		if (e2 < e1) e2 = e1 + (e1 - e2);
+
+		if (NULL != f->map) munmap(f->map,f->map_size);
+		if (MAP_FAILED != (f->map = mmap(NULL,e2 - b2,f->prot,flags,f->fd,b2))) {
+			f->map_size = e2 - b2;
+			f->map_offset = b2;
+		}
+		else if (MAP_FAILED != (f->map = mmap(NULL,e1 - b1,f->prot,flags,f->fd,b1))) {
+			f->map_size = e1 - b1;
+			f->map_offset = b1;
+		}
+		else {
+			perror("mmap");
+			f->map = NULL;
+			f->map_size = 0;
+			f->map_offset = 0;
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+int io_out(struct io_file *f,int pos,const void *o,int len) {
+	int end = pos + len;
+	if (0 == len) return pos;
+	if (NULL == f || -1 == pos) return -1;
+	if (NULL == o) return pos + len;
+	if (remap(f,pos,len)) return -1;
+
+	if (pos < f->file_size) {
+		assert(pos >= f->map_offset);
+		if (pos >= f->buffer_offset && unbuffer(f))
+			return -1;
+		if (end > (int)(f->map_offset + f->map_size))
+			end = f->map_offset + f->map_size;
+		if (end > f->file_size)
+			end = f->file_size;
+		memcpy(pos - f->map_offset + (char *) f->map,o,end - pos);
+	}
+	else {
+		if (pos < f->buffer_offset
+		||  pos > (int)(f->buffer_offset + f->buffer_size)) {
+			if (unbuffer(f)) return -1;
+			if (lseek(f->fd,pos,SEEK_SET) == (off_t) -1) {
+				perror("lseek");
+				return -1;
+			}
+
+			assert(0 == f->buffer_size);
+			f->buffer_offset = pos;
+		}
+		else if (pos == (int)(f->buffer_offset + sizeof f->buffer))
+			if (unbuffer(f)) return -1;
+
+		assert(pos >= f->buffer_offset 
+                    && pos <= (int)(f->buffer_offset + f->buffer_size));
+		if (end > (int)(f->buffer_offset + sizeof f->buffer))
+			end = f->buffer_offset + sizeof f->buffer;
+		memcpy(&f->buffer[pos - f->buffer_offset],o,end - pos);
+		if ((int)(end - f->buffer_offset) > (int)f->buffer_size)
+			f->buffer_size = end - f->buffer_offset;
+	}
+
+	return io_out(f,end,end - pos + (char *) o,len + pos - end);
+}
+
+int io_in(struct io_file *f,int pos,void *i,int len) {
+	int end = pos + len;
+	if (0 == len) return pos;
+	if (NULL == f || -1 == pos) return -1;
+	if (NULL == i) return pos + len;
+	if (remap(f,pos,len)) return -1;
+	if (unbuffer(f)) return -1;
+
+	if (pos >= f->file_size && checksize(f)) return -1;
+	if (pos >= f->file_size) {
+/* TODO: fill with zeroes instead */
+		fputs("read: EOF\n",stderr);
+		return -1;
+	}
+
+	if (end > (int)(f->map_offset + f->map_size))
+		end = f->map_offset + f->map_size;
+	if (end > f->file_size)
+		end = f->file_size;
+	memcpy(i,pos - f->map_offset + (char *) f->map,end - pos);
+	return io_in(f,end,end - pos + (char *) i,len + pos - end);
+}
diff --git a/src/io.h b/src/io.h
new file mode 100644
index 0000000..4c6a155
--- /dev/null
+++ b/src/io.h
@@ -0,0 +1,54 @@
+
+// $Id: io.h,v 1.8 2012/11/01 18:57:19 we7u Exp $
+
+
+/* Copyright 2002 Daniel Egnor.  See LICENSE.geocoder file.
+ * Portions Copyright (C)  2004-2012  The Xastir Group
+ *
+ * This file defines the I/O interface used for access to index files.
+ * There are two implementations of this interface; io-mmap.c uses Unix
+ * mmap() and is quite efficient, and io-stdio.c uses C stdio and is slower
+ * but more portable.  Which one is used depends on which file is compiled. */
+
+#ifndef GEOCODER_IO_H
+#define GEOCODER_IO_H
+
+struct io_file;
+
+/* Open a file.  The file will be created if it did not exist. 
+ * It will be opened R/W if possible, R/O otherwise. 
+ * Returns NULL on error.*/
+
+struct io_file *io_open(const char *fname);
+void io_close(struct io_file *);
+
+/* In general, all I/O is done with an offset ("pos") directly.  There is
+ * no "current position" associated with the file handle.  This is really
+ * a lot more convenient for random access.
+ *
+ * Functions almost always return the position just after the data that was
+ * read or written, so they may be easily "chained" to read or write several
+ * contiguous items; this makes it almost as easy to do this as it would be
+ * with a file pointer, which keeping things more flexible.
+ *
+ * If an error occurs, the return value will be -1.  If the input "pos"
+ * is -1, these functions will silently return -1, so you can safely wait
+ * until the end of a "chain" to check for errors, if you want. 
+ *
+ * Integer values are written in byte-order-independent fashion. */
+
+int io_out(struct io_file *,int pos,const void *o,int len); /* Write data */
+int io_out_i4(struct io_file *,int pos,int o);              /* Write an int */
+int io_out_i2(struct io_file *,int pos,short o);            /* Write a short */
+int io_out_i1(struct io_file *,int pos,signed char o);      /* Write a char */
+
+int io_in(struct io_file *,int pos,void *i,int len);        /* Read data */
+int io_in_i4(struct io_file *,int pos,int *i);              /* Read an int */
+int io_in_i2(struct io_file *,int pos,short *i);            /* Read a short */
+int io_in_i1(struct io_file *,int pos,signed char *i);      /* Read a char */
+
+/* Convert a string to integer.  Like strtol(), only with a count.
+ * Kept here, 'cuz ... where else? */
+int io_strntoi(const char *str,int len);
+
+#endif
diff --git a/src/lang.c b/src/lang.c
new file mode 100644
index 0000000..e8ea176
--- /dev/null
+++ b/src/lang.c
@@ -0,0 +1,255 @@
+/*
+ * $Id: lang.c,v 1.20 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "lang.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+char lang_code[MAX_LANG_ENTRIES][MAX_LANG_CODE+1];
+char *lang_code_ptr[MAX_LANG_ENTRIES];
+char lang_buffer[MAX_LANG_BUFFER];
+char lang_hotkey[MAX_LANG_ENTRIES];
+
+int lang_code_number;
+long buffer_len;
+char invalid_code[50];
+
+
+
+
+
+char *langcode(char *code) {
+    int i;
+
+    // Create an invalid code string to return in case we can't find the proper string
+    if (strlen(code) <= MAX_LANG_CODE) {    // Code is ok
+        xastir_snprintf(invalid_code, sizeof(invalid_code), "IC>%s", code);
+    }
+    else {  // Code is too long
+        xastir_snprintf(invalid_code, sizeof(invalid_code), "IC>TOO LONG:%s",code);
+        fprintf(stderr,"IC>TOO LONG:%s\n",code);
+        return(invalid_code);
+    }
+
+    if(lang_code_number>0) {
+        for(i=0;i<lang_code_number;i++) {
+            if(strcmp(code,lang_code[i])==0) {  // Found a match
+                if (strlen(lang_code[i]) < MAX_LANG_LINE_SIZE) {
+                    return(lang_code_ptr[i]);   // Found it, length ok
+                }
+                else {
+                    fprintf(stderr,"String size: %d,  Max size: %d, %s\n",
+                        (int)strlen(lang_code[i]),
+                        MAX_LANG_LINE_SIZE,code);
+                    return(invalid_code);       // Found it, but string too long
+                }
+            }
+        }
+        fprintf(stderr,"Language String not found:%s\n",code);
+        return(invalid_code);
+    }
+
+    fprintf(stderr,"No language strings loaded:%s\n",code);
+    return(invalid_code);   // No strings loaded in language file
+}
+
+
+
+
+
+char langcode_hotkey(char *code) {
+    int i;
+
+    if(lang_code_number>0) {
+        for(i=0;i<lang_code_number;i++) {
+            if(strcmp(code,lang_code[i])==0) {
+                return(lang_hotkey[i]); // Found it
+            }
+        }
+    }
+
+    fprintf(stderr,"No hotkey for:%s\n",code);
+    return(' ');    // No strings loaded in language file
+}
+
+
+
+
+
+int load_language_file(char *filename) {
+    FILE *f;
+    char line[MAX_LANG_LINE_SIZE+1];
+    char *temp_ptr;
+    int i,lt,lcok;
+    char cin;
+    int ok;
+    int line_num;
+    int data_len;
+
+    lang_code_number=0;
+    buffer_len=0l;
+    ok=1;
+    line_num=1;
+    i=0;
+    f=fopen(filename,"r");
+    if(f != NULL) {
+        line[0]='\0';
+        while(!feof(f)) {
+            if(fread(&cin,1,1,f)==1) {
+                if(cin != (char)10 && cin != (char)13) {
+                    if(i<MAX_LANG_LINE_SIZE) {
+                        line[i++]=cin;
+                        line[i]='\0';
+                    } else {
+                        ok=0;
+                        fprintf(stderr,"Error! Line %d too long in language file\n",line_num);
+                    }
+                } else {
+                    i=0;
+                    if (line[0]!='#' && strlen(line)>0) {
+                        /* data line */
+                        if(lang_code_number < MAX_LANG_ENTRIES) {
+                            if(buffer_len < MAX_LANG_BUFFER) {
+                                if(strchr(line,'|')!=NULL) {
+                                    temp_ptr=strtok(line,"|");            /* get code */
+                                    if (temp_ptr!=NULL) {
+                                        if(strlen(temp_ptr)<=MAX_LANG_CODE) {
+                                            lcok=1;
+                                            for (lt=0; lt <lang_code_number && lcok; lt++) {
+                                                if(strcmp(lang_code[lt],temp_ptr)==0) {
+                                                    lcok=0;
+                                                    break;
+                                                }
+                                            }
+                                            if(lcok) {
+                                                xastir_snprintf(lang_code[lang_code_number],
+                                                    MAX_LANG_CODE+1,
+                                                    "%s",
+                                                    temp_ptr);
+                                                temp_ptr=strtok(NULL,"|");         /* get string */
+                                                if (temp_ptr!=NULL) {
+                                                    data_len=(int)strlen(temp_ptr);
+                                                    if ((buffer_len+data_len+1)< MAX_LANG_BUFFER) {
+                                                        lang_code_ptr[lang_code_number]=lang_buffer+buffer_len;
+                                                        xastir_snprintf(lang_buffer+buffer_len,
+                                                            MAX_LANG_BUFFER-buffer_len,
+                                                            "%s",
+                                                            temp_ptr);
+                                                        lang_buffer[buffer_len+data_len]='\0';
+                                                        buffer_len+=data_len+1;
+                                                        temp_ptr=strtok(NULL,"|");      /* get hotkey */
+                                                        if (temp_ptr!=NULL) {
+                                                            lang_hotkey[lang_code_number]=temp_ptr[0];
+                                                            /*fprintf(stderr,"HOTKEY %c\n",lang_hotkey[lang_code_number]);*/
+                                                        }
+                                                    } else {
+                                                        ok=0;
+                                                        fprintf(stderr,"Language data buffer full error on line %d\n",line_num);
+                                                    }
+                                                } else {
+                                                    ok=0;
+                                                    fprintf(stderr,"Language string parse error on line %d\n",line_num);
+                                                }
+                                            } else {
+                                                ok=0;
+                                                fprintf(stderr,"Duplicate code! <%s> on line %d\n",temp_ptr,line_num);
+                                            }
+                                        } else {
+                                            ok=0;
+                                            fprintf(stderr,"Language code on line %d is too long\n",line_num);
+                                        }
+                                    } else {
+                                        ok=0;
+                                        fprintf(stderr,"Missing Language code data on line %d\n",line_num);
+                                    }
+                                } else {
+                                    ok=0;
+                                    fprintf(stderr,"Language code parse error on line %d\n",line_num);
+                                }
+                            } else {
+                                ok=0;
+                                fprintf(stderr,"Language data buffer full error on line %d\n",line_num);
+                            }
+                        } else {
+                            ok=0;
+                            fprintf(stderr,"Too many Language codes error on line %d\n",line_num);
+                        }
+                        if (ok) {
+                            if (debug_level & 32)
+                                fprintf(stderr,"Code #%d <%s> data <%s> hotkey <%c>\n",lang_code_number,
+                                    lang_code[lang_code_number],lang_code_ptr[lang_code_number],
+                                    lang_hotkey[lang_code_number]);
+                                lang_code_number++;
+                        }
+                        line[0]='\0';
+                    }
+                    line_num++;
+                }
+            }
+        }
+        (void)fclose(f);
+    } else {
+        ok=0;
+        fprintf(stderr,"Could not read Language file: %s!\n",filename);
+    }
+    if (debug_level & 32)
+        fprintf(stderr,"LANG %d\n",lang_code_number);
+
+    return(ok);
+}
+
+
diff --git a/src/lang.h b/src/lang.h
new file mode 100644
index 0000000..ba57aea
--- /dev/null
+++ b/src/lang.h
@@ -0,0 +1,39 @@
+/*
+ * $Id: lang.h,v 1.11 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_LANG_H
+#define XASTIR_LANG_H
+
+#define MAX_LANG_LINE_SIZE 800
+#define MAX_LANG_CODE 10
+#define MAX_LANG_ENTRIES 3000
+#define MAX_LANG_BUFFER 30000
+
+extern int load_language_file(char *filename);
+extern char *langcode(char *code);
+extern char langcode_hotkey(char *code);
+
+
+
+#endif  /* XASTIR_LANG_H */
diff --git a/src/leak_detection.h b/src/leak_detection.h
new file mode 100644
index 0000000..08f2604
--- /dev/null
+++ b/src/leak_detection.h
@@ -0,0 +1,101 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: leak_detection.h,v 1.9 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2005-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/* All of the misc entry points to be included for all packages */
+
+#ifndef _LEAK_DETECTION_H
+#define _LEAK_DETECTION_H
+
+
+// If libgc is installed, uncomment this next line to enable memory
+// leak detection:
+#define DETECT_MEMORY_LEAKS
+
+
+// Defines for including the libgc garbage collection library.
+// This enables automatic garbage collection of unused memory,
+// very similar to the garbage collection in Java.  Get libgc from
+// here:  http://www.hpl.hp.com/personal/Hans_Boehm/gc/
+//
+// This will cause stats to be printed every 60 seconds, 'cuz we
+// call GC_collect via a macro from UpdateTime() once per minute:
+// export GC_PRINT_STATS=1; xastir &
+//
+// Compile libgc with this option for more debugging output.  I
+// didn't do so:  --enable-full_debug 
+//
+// If we enable these thread options, Xastir won't link with the
+// library.  Since we don't allocate dynamic memory in the child
+// threads anyway, skip them.
+// --enable-threads=posix --enable-thread-local-alloc --enable-parallel-mark
+//
+// Call GC_gcollect at appropriate points to check for leaks.  We do
+// this via the CHECK_LEAKS macro called from main.c:UpdateTime.
+//
+//
+// Note:  The thread includes must be done before the libgc includes
+// as libgc redefines some thread stuff so that it cooperates with
+// the garbage collector routines.  Any code module that does
+// malloc's/free's or thread operations should include
+// leak_detection.h as the last include if at all possible, and
+// should not include pthread.h themselves.
+//
+#include <pthread.h>
+#include <stdlib.h> /* Where malloc/free definitions reside */
+#ifdef HAVE_DMALLOC
+#include <dmalloc.h>
+#endif  // HAVE_DMALLOC
+//
+#ifdef HAVE_GC_H
+  #ifdef HAVE_LIBGC
+
+    // We use this define to enable code in *.c files
+    #define USING_LIBGC
+
+    // Set up for threads
+    #define GC_THREADS
+
+    #ifdef __LINUX__
+      #define GC_LINUX_THREADS
+    #endif  // __LINUX__
+
+//    #define _REENTRANT
+ 
+    // Ask for more debugging
+    #define GC_DEBUG
+
+    #include <gc.h>
+    #define malloc(n) GC_MALLOC(n)
+    #define calloc(m,n) GC_MALLOC((m)*(n))
+    #define free(p) GC_FREE(p)
+    #define realloc(p,n) GC_REALLOC((p),(n))
+    #define CHECK_LEAKS() GC_gcollect()
+
+  #endif    // HAVE_LIBGC
+#endif  // HAVE_GC_H
+ 
+
+
+#endif /* LEAK_DETECTION_H */
+
+
diff --git a/src/list_gui.c b/src/list_gui.c
new file mode 100644
index 0000000..3067392
--- /dev/null
+++ b/src/list_gui.c
@@ -0,0 +1,2489 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: list_gui.c,v 1.57 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef  HAVE_LOCALE_H
+#include <locale.h>
+#endif  // HAVE_LOCALE_H
+
+#ifdef  HAVE_LIBINTL_H
+#include <libintl.h>
+#define _(x)        gettext(x)
+#else   // HAVE_LIBINTL_H
+#define _(x)        (x)
+#endif  // HAVE_LIBINTL_H
+
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_XBAE_MATRIX_H
+#include <Xbae/Matrix.h>
+#endif  // HAVE_XBAE_MATRIX_H
+
+#include "xastir.h"
+#include "main.h"
+#include "messages.h"
+#include "draw_symbols.h"
+#include "list_gui.h"
+#include "database.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+#define SL_MAX 20
+#define ROWS 17
+
+// List Numbers (defined in list_gui.h)
+// 0: LST_ALL   - all stations list
+// 1: LST_MOB   - mobile stations list
+// 2: LST_WX    - WX stations list
+// 3: LST_TNC   - local stations list
+// 4: LST_TIM   - last stations
+// 5: LST_OBJ   - Objects/Items
+// 6: LST_MYOBJ - My Objects/Items
+// 7: LST_NUM   - Number of lists; for use in array definitions below
+
+Widget station_list_dialog[LST_NUM];           // store list definitions
+static xastir_mutex station_list_dialog_lock;  // Mutex lock for above
+
+Widget SL_list[LST_NUM][SL_MAX];
+Widget SL_da[LST_NUM][SL_MAX];
+Widget SL_call[LST_NUM][SL_MAX];
+char * SL_callback[LST_NUM][SL_MAX];
+Pixmap SL_icon[LST_NUM][SL_MAX];        // icons for different lists and list rows
+Pixmap blank_icon;                      // holds an empty icon
+Widget SL_scroll[LST_NUM];
+Widget SL_wx_wind_course[LST_NUM][SL_MAX];
+Widget SL_wx_wind_speed[LST_NUM][SL_MAX];
+Widget SL_wx_wind_gust[LST_NUM][SL_MAX];
+Widget SL_wx_temp[LST_NUM][SL_MAX];
+Widget SL_wx_hum[LST_NUM][SL_MAX];
+Widget SL_wx_baro[LST_NUM][SL_MAX];
+Widget SL_wx_rain_h[LST_NUM][SL_MAX];
+Widget SL_wx_rain_00[LST_NUM][SL_MAX];
+Widget SL_wx_rain_24[LST_NUM][SL_MAX];
+Widget SL_course[LST_NUM][SL_MAX];
+Widget SL_speed[LST_NUM][SL_MAX];
+Widget SL_alt[LST_NUM][SL_MAX];
+Widget SL_lat_long[LST_NUM][SL_MAX];
+Widget SL_packets[LST_NUM][SL_MAX];
+Widget SL_sats[LST_NUM][SL_MAX];
+Widget SL_my_course[LST_NUM][SL_MAX];
+Widget SL_my_distance[LST_NUM][SL_MAX];
+Widget SL_pos_time[LST_NUM][SL_MAX];
+Widget SL_node_path[LST_NUM][SL_MAX];
+Widget SL_power_gain[LST_NUM][SL_MAX];
+Widget SL_comments[LST_NUM][SL_MAX];
+int station_list_first = 1;
+int list_size_h[LST_NUM];       // height of entire list widget
+int list_size_w[LST_NUM];       // width  of entire list widget
+int list_size_i[LST_NUM];       // size initialized, dirty hack, but works...
+
+int last_offset[LST_NUM];
+char top_call[LST_NUM][MAX_CALLSIGN+1]; // call of first list entry or empty string for always first call
+time_t top_time;                // time of first list entry or 0 for always newest station
+int top_sn;                     // serial number for unique time index
+time_t last_list_upd;           // time of last list update
+int units_last;
+
+#define LIST_UPDATE_CYCLE 2     /* Minimum time between list updates in seconds, we want */
+                                /* immediate update, but not in high traffic situations  */
+
+
+
+
+
+void list_gui_init(void)
+{
+    init_critical_section( &station_list_dialog_lock );
+}
+
+
+
+
+
+// get a valid list member, starting from current station in the desired direction
+// returns pointer to found member or NULL
+void get_list_member(int type, DataRow **p_station, int skip, int forward) {
+    char found;
+
+    if ((*p_station) == NULL) {                         // default start value
+        if (type == LST_TIM)
+            (*p_station) = t_newest;
+        else
+            (*p_station) = n_first;
+    }
+
+    if (skip == 1) {                                    // skip before searching
+        if (type != LST_TIM) {
+            if (forward == 1)
+                (void)next_station_name(p_station);
+            else
+                (void)prev_station_name(p_station);
+        } else {
+            if (forward == 1)
+                (void)prev_station_time(p_station);
+            else
+                (void)next_station_time(p_station);
+        }
+    }
+
+    found = (char)FALSE;
+    switch (type) {             // DK7IN: here I'm trading code size for speed...
+        case LST_ALL:
+            if (forward == 1)
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0)  // ignore deleted objects
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_next;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_prev;
+                }
+            break;
+        case LST_MOB:
+            if (forward == 1)
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0 && (*p_station)->newest_trackpoint != NULL)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_next;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0 && (*p_station)->newest_trackpoint != NULL)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_prev;
+                }
+            break;
+        case LST_WX:
+            if (forward == 1)
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0 && (*p_station)->weather_data != NULL)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_next;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0 && (*p_station)->weather_data != NULL)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_prev;
+                }
+            break;
+        case LST_TNC:
+            if (forward == 1)
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0
+                     && ((*p_station)->flag & ST_VIATNC) != 0)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_next;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0
+                     && ((*p_station)->flag & ST_VIATNC) != 0)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_prev;
+                }
+            break;
+        case LST_TIM:
+            if (forward == 1)           // forward in list, backward in time
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0)  // ignore deleted objects
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->t_older;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0)
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->t_newer;
+                }
+            break;
+        case LST_OBJ:
+            if (forward == 1)
+                while (!found && (*p_station) != NULL) {
+                    // Show deleted objects/items as well
+                    if ( ( (((*p_station)->flag & ST_OBJECT) != 0)
+                            || (((*p_station)->flag & ST_ITEM) != 0) ) )
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_next;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0
+                     && ( (((*p_station)->flag & ST_VIATNC) != 0)
+                            || (((*p_station)->flag & ST_ITEM) != 0) ) )
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_prev;
+                }
+            break;
+        case LST_MYOBJ:
+
+// We should really show the active AND inactive objects.  This is
+// so that inactive ones can be resurrected.  Probably should do
+// this for all objects, not just ones we own.
+
+            if (forward == 1)
+                while (!found && (*p_station) != NULL) {
+                    // Show deleted objects/items as well
+                    if ( ( (((*p_station)->flag & ST_OBJECT) != 0)
+                                || (((*p_station)->flag & ST_ITEM) != 0) )
+//                            && ( is_my_call( (*p_station)->origin,1)) ) // Exact match include SSID
+                            && ( is_my_object_item(*p_station)) ) // Exact match include SSID
+
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_next;
+                }
+            else
+                while (!found && (*p_station) != NULL) {
+                    if (((*p_station)->flag & ST_ACTIVE) != 0
+                            && ( (((*p_station)->flag & ST_VIATNC) != 0)
+                                || (((*p_station)->flag & ST_ITEM) != 0) )
+//                            && ( is_my_call( (*p_station)->origin,1)) ) // Exact match includes SSID
+                            && ( is_my_object_item(*p_station)) ) // Exact match include SSID
+
+                        found = (char)TRUE;
+                    else
+                        (*p_station) = (*p_station)->n_prev;
+                }
+            break;
+        default:
+            break;
+    }
+}
+
+
+
+
+
+// initialization of station list at very first Station List call
+void init_station_lists(void) {
+    int type,i;
+
+    blank_icon = XCreatePixmap(XtDisplay(appshell),RootWindowOfScreen(XtScreen(appshell)),20,20,
+                    DefaultDepthOfScreen(XtScreen(appshell)));
+
+begin_critical_section(&station_list_dialog_lock, "list_gui.c:init_station_lists" );
+
+    for (type=0;type<LST_NUM;type++) {
+        station_list_dialog[type] = NULL;       // set list to undefined
+        for (i=0;i<ROWS;i++) {
+            SL_icon[type][i] = XCreatePixmap(XtDisplay(appshell),RootWindowOfScreen(XtScreen(appshell)),20,20,
+                                DefaultDepthOfScreen(XtScreen(appshell)));
+        }
+    }
+    memset(SL_callback, 0, sizeof(SL_callback));
+
+end_critical_section(&station_list_dialog_lock, "list_gui.c:init_station_lists" );
+
+}
+
+
+
+
+
+// check if there is at least one station of a specific type      now used only in db.c
+int stations_types(int type) {
+    int st;
+    DataRow *p_station;
+
+    st=0;
+    for (p_station=n_first;p_station != NULL;p_station=p_station->n_next) {
+        if ((p_station->flag & ST_ACTIVE) != 0) {      // ignore deleted objects
+            switch (type) {
+                case 0:         // all stations list
+                case 4:         // last stations
+                    st++;
+                    break;
+                case 1:         // mobile stations list
+                    if (p_station->newest_trackpoint != NULL)
+                        st++;
+                    break;
+                case 2:         // WX stations list
+                    if (p_station->weather_data != NULL)
+                        st++;
+                    break;
+                case 3:         // local stations list
+                    if ((p_station->flag & ST_VIATNC) != 0)
+                        st++;
+                    break;
+                case 5:         // Object/Item list
+                    if ( ((p_station->flag & ST_OBJECT) != 0) ||
+                            ((p_station->flag & ST_ITEM) != 0) )
+                        st++;
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+    if (st==0)
+        st=1;
+    return(st);
+}
+
+
+
+
+
+void station_list_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int type;
+    int i;
+
+    type = atoi((char *)clientData);
+    XtPopdown(station_list_dialog[type]);
+
+    begin_critical_section(&station_list_dialog_lock, "list_gui.c:station_list_destroy_shell" );
+
+    for (i = 0; i < ROWS; i++) {
+        if (SL_callback[type][i]) {
+            XtFree(SL_callback[type][i]);
+            SL_callback[type][i] = NULL;
+        }
+    }
+
+    XtDestroyWidget(station_list_dialog[type]);
+    station_list_dialog[type] = (Widget)NULL;           // clear list definition
+
+    end_critical_section(&station_list_dialog_lock, "list_gui.c:station_list_destroy_shell" );
+
+}
+
+
+
+/* 
+ * Callback for station icon in list.
+ * Calls a function to center the map on the selected station from the list.
+ */
+void Call_locate_station(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    if (clientData != NULL && strlen(clientData) > 0) { 
+       locate_station(w, clientData, 1,1,1); 
+    } 
+}
+
+
+
+/* 
+ * *** This callback is not linked to a control on list yet. ***
+ * Invokes the station information dialog for the selected station from the list.
+ */
+void Call_Station_data(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    if (clientData != NULL && strlen(clientData) > 0) { 
+       Station_data(w, clientData, NULL); 
+    } 
+}
+
+
+
+/*
+ *  Fill list with new data
+ */
+void Station_List_fill(int type, int new_offset) {
+    int row;
+    char temp[8];
+    char *temp_ptr;
+    Dimension w,h;            // size of scrollbar in pixel
+    Dimension ww,wh;          // size of entire widget in pixel
+    Dimension new_h;          // overall height in pixel
+    char stemp[400];
+    char stemp1[60];
+    char stemp2[60];
+    char temp_call[MAX_CALLSIGN+1];
+    long l_lat, l_lon;
+    float value;
+    WeatherRow *weather;
+    DataRow *p_station;
+    DataRow *p_name;
+    int cur_offset;
+    Dimension count, inview;
+    int to_move, rows;
+    int strwid;
+
+    assert(ROWS <= SL_MAX);
+#define HGT 26
+#define FUDGE 78
+    // type 0 all, 1: mobile, 2: WX, 3: local, 4: time, 5: Objects/Items
+    // offset is the entry that should be displayed in the first line
+    
+    w = h = ww = wh = 0;
+    if (station_list_dialog[type] != NULL) {            // if list is defined
+        // the list is first drawn very big then gets initialized to the correct size
+        // I don't want the first wrong draw but don't know how to avoid it.  DK7IN
+        
+        // there are wrong icons drawn on the first time...  ????
+        if (list_size_i[type]) {        // we are initialized...
+            // ww, wh  get width and height of entire widget:
+            XtVaGetValues(station_list_dialog[type], XmNwidth,  &ww, XmNheight, &wh, NULL);
+            // w, h    get width and height of scrollbar:
+            XtVaGetValues(SL_scroll[type], XmNwidth,  &w, XmNheight, &h, NULL);
+            rows = (h+10) / HGT;         // number of rows we can display, HGT pixel per row
+//            fprintf(stderr,"fill: %d %d %d\n",wh, h, rows);
+        } else {
+            if (list_size_w[type] > 0 && list_size_h[type] > 0) {
+                wh = list_size_h[type];         // restore size
+                ww = list_size_w[type];
+                rows = (wh -FUDGE+10) / HGT;              // Fudge Factor ???
+//                fprintf(stderr,"load: %d       %d\n",wh, rows);
+            } else {
+                wh = 500;                       // start with this... ???
+                ww = 700;
+                rows = (wh -FUDGE+10) / HGT;              // Fudge Factor ???
+//                fprintf(stderr,"set:  %d       %d\n",wh, rows);
+            }
+            XtVaSetValues(station_list_dialog[type], XmNwidth, ww, NULL); // set widget width
+        }
+        if (rows > ROWS)          // limit vertical size to data structure size for widgets
+            rows = ROWS;
+        if (rows < 1)
+            rows = 1;
+        // new_h = (rows*HGT) + (wh-h);    // (rows + border) in pixel
+        new_h = (rows*HGT) + FUDGE;    // (rows + border) in pixel
+        XtVaSetValues(station_list_dialog[type], XmNheight, new_h, NULL);       // correct widget height
+
+        list_size_h[type] = new_h;                      // remember current size
+        list_size_w[type] = ww;
+        list_size_i[type] = (int)TRUE;                       // don't init next time
+
+        // look for the station to display on the first row...
+        p_station = NULL;
+        if (type == LST_TIM)
+            (void)search_station_time(&p_station,top_time,top_sn);  // gives match or next station
+        else
+            (void)search_station_name(&p_station,top_call[type],1); // gives match or next station
+        get_list_member(type, &p_station, 0, 1);        // get member in list for first row
+
+        // get updated statistics, database may have changed since last call
+        count = 0;
+        cur_offset = 0;
+        p_name = NULL;
+        get_list_member(type, &p_name, 0, 1);           // get first member in list
+        
+        while (p_name != NULL) {
+            if (p_name == p_station)
+                cur_offset = count;                     // got offset of first row entry
+            count++;                                    // count valid list member
+            get_list_member(type, &p_name, 1, 1);       // get next member in list
+        }
+
+        // check boundaries
+        new_offset += cur_offset - last_offset[type];   // adjust for database changes
+
+        if (count == 0) count = 1;                      // empty
+        if (count - new_offset < rows)                  // bottom
+            new_offset = count - rows;                  // keep page filled, if possible
+        if (new_offset < 0)                             // top
+            new_offset = 0;
+        inview = rows;                                  // number of stations in view
+        if (inview > count)                             // partially filled
+            inview = count;
+            
+        // update scrollbar parameters
+        XtVaSetValues(SL_scroll[type],
+            XmNmaximum, count,
+            XmNpageIncrement, inview,
+            XmNvalue, new_offset,
+            XmNsliderSize, inview,
+            NULL);
+        
+        if (new_offset == 0) {                          // stay at first member
+            p_station = NULL;
+            get_list_member(type, &p_station, 0, 1);    // get first member in list
+        } else {
+            // if database changed, adjust first entry accordingly
+            to_move = new_offset - cur_offset;
+            while (to_move > 0) {                               // move down, if neccessary
+                if (p_station != 0)
+                    get_list_member(type, &p_station, 1, 1);    // gets next member in list
+                to_move--;
+            }
+            while (to_move < 0) {                               // move up, if neccessary
+                if (p_station != 0)
+                    get_list_member(type, &p_station, 1, 0);    // gets previous member in list
+                to_move++;
+            }
+        }
+
+        // store current start position, we need a unique index for this to work (time?)
+        if (new_offset == 0 || p_station == NULL) {             // keep it at top
+            if (type != LST_TIM)
+                top_call[type][0] = '\0';
+            else {
+                top_time =  0;
+                top_sn   = -1;
+            }
+        } else {
+            if (type != LST_TIM) {
+                xastir_snprintf(top_call[type],
+                    MAX_CALLSIGN+1,
+                    "%s",
+                    p_station->call_sign);  // remember call at list top
+            }
+            else {
+                top_time = p_station->sec_heard;                // remember time station was heard
+                top_sn   = p_station->time_sn;                  // remember time serial number
+            }
+        }
+        last_offset[type] = new_offset;
+
+        // now fill the list rows
+        xastir_snprintf(temp, sizeof(temp), "%d", (rows+new_offset));                   // calculate needed string width
+        strwid = (int)strlen(temp);                             // to keep it right justified
+
+begin_critical_section(&station_list_dialog_lock, "list_gui.c:Station_List_fill" );
+
+        // Start filling in the rows of the widget
+        for (row=0; row<rows; row++) {                          // loop over display lines
+            if (p_station != NULL) {                            // we have data...
+                int ghost;
+
+                // icon
+                XtVaSetValues(SL_da[type][row],XmNlabelPixmap, blank_icon,NULL);
+                XtManageChild(SL_da[type][row]);
+
+                if (type == LST_OBJ || type == LST_MYOBJ) {
+                    if (p_station->flag & ST_ACTIVE) {
+                        ghost = 0;      // Active object/item
+                    }
+                    else {
+                        ghost = 1;      // Deleted object/item
+                    }
+                }
+                else {
+                    ghost = 0;          // Not an object
+                }
+
+                // Blank out the icon first
+                XtVaSetValues(SL_da[type][row],XmNlabelPixmap, blank_icon,NULL);
+                XtManageChild(SL_da[type][row]);
+                symbol(SL_da[type][row],0,'~','$','\0',SL_icon[type][row],0,0,0,' ');
+                XtVaSetValues(SL_da[type][row],XmNlabelPixmap, SL_icon[type][row],NULL);
+                XtManageChild(SL_da[type][row]);
+
+                // Now redraw it
+                symbol(SL_da[type][row],ghost,p_station->aprs_symbol.aprs_type,
+                    p_station->aprs_symbol.aprs_symbol,
+                    p_station->aprs_symbol.special_overlay,SL_icon[type][row],ghost,0,0,' ');
+
+                XtVaSetValues(SL_da[type][row],XmNlabelPixmap, SL_icon[type][row],NULL);
+                XtManageChild(SL_da[type][row]);
+
+                if (SL_callback[type][row]) XtFree(SL_callback[type][row]);
+                SL_callback[type][row] = XmTextFieldGetString(SL_call[type][row]);
+
+                // Pressing the icon button centers the map on the station.
+                XtAddCallback( (XtPointer)SL_da[type][row],
+                      XmNactivateCallback, 
+                      Call_locate_station, 
+                      SL_callback[type][row]
+                      );
+
+                // number in list
+                xastir_snprintf(temp, sizeof(temp), "%*d", strwid, (row+1+new_offset));
+                XmTextFieldSetString(SL_list[type][row],temp);
+                XtManageChild(SL_list[type][row]);
+
+                // call (or object/item name)
+                /* check to see if string changed and over write */
+                temp_ptr = XmTextFieldGetString(SL_call[type][row]);
+                xastir_snprintf(temp_call, sizeof(temp_call), "%s", temp_ptr);
+                XtFree(temp_ptr);
+
+                if (strcmp(temp_call,p_station->call_sign) !=0 ) {
+                    XmTextFieldSetString(SL_call[type][row],p_station->call_sign);
+                    if (ghost)
+                        XtSetSensitive(SL_call[type][row],FALSE);
+                    else
+                        XtSetSensitive(SL_call[type][row],TRUE);
+                    XtManageChild(SL_call[type][row]);
+                }
+
+                switch (type) {
+                    case LST_TNC:                       // local stations list
+                    case LST_TIM:                       // last stations list
+                    case LST_ALL:                       // stations list
+                    case LST_OBJ:                       // objects/items
+                    case LST_MYOBJ:                     // my objects/items
+                        xastir_snprintf(stemp, sizeof(stemp), "%5d",
+                                (int)p_station->num_packets);
+                        XmTextFieldSetString(SL_packets[type][row],stemp);
+                        XtManageChild(SL_packets[type][row]);
+
+                        if (strlen(p_station->pos_time) > 13) {
+                            xastir_snprintf(stemp, sizeof(stemp), "%c%c/%c%c %c%c:%c%c",
+                            //sprintf(stemp,"%c%c/%c%c/%c%c%c%c %c%c:%c%c",
+                                 p_station->pos_time[0],
+                                 p_station->pos_time[1],
+                                 p_station->pos_time[2],
+                                 p_station->pos_time[3],
+                                 //p_station->pos_time[4],
+                                 //p_station->pos_time[5],
+                                 //p_station->pos_time[6],
+                                 //p_station->pos_time[7],
+                                 p_station->pos_time[8],
+                                 p_station->pos_time[9],
+                                 p_station->pos_time[10],
+                                 p_station->pos_time[11]);
+                        } else
+                            xastir_snprintf(stemp, sizeof(stemp), " ");
+
+                        XmTextFieldSetString(SL_pos_time[type][row],stemp);
+                        XtManageChild(SL_pos_time[type][row]);
+
+                        xastir_snprintf(stemp, sizeof(stemp), "%s", p_station->node_path_ptr);
+                        XmTextFieldSetString(SL_node_path[type][row],stemp);
+                        XtManageChild(SL_node_path[type][row]);
+
+                        xastir_snprintf(stemp, sizeof(stemp), "%s", p_station->power_gain);
+                        XmTextFieldSetString(SL_power_gain[type][row],stemp);
+                        XtManageChild(SL_power_gain[type][row]);
+
+// Should we display only the first comment field we have stored, or
+// concatenate all of them up to the limit of stemp?
+                        //xastir_snprintf(stemp, sizeof(stemp), "%s", p_station->comments);
+                        if ( (p_station->comment_data != NULL)
+                                && (p_station->comment_data->text_ptr != NULL) )
+                            xastir_snprintf(stemp, sizeof(stemp), "%s", p_station->comment_data->text_ptr);
+                        else
+                            stemp[0] = '\0';    // Empty string
+
+                        XmTextFieldSetString(SL_comments[type][row],stemp);
+                        XtManageChild(SL_comments[type][row]);
+
+                        break;
+
+                    case LST_MOB:                       // mobile stations list
+                        if (strlen(p_station->course)>0)
+                            XmTextFieldSetString(SL_course[type][row],p_station->course);
+                        else
+                            XmTextFieldSetString(SL_course[type][row],"");
+
+                        XtManageChild(SL_course[type][row]);
+                        if (strlen(p_station->speed)>0) {
+                            if (!english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%.1f",
+                                        atof(p_station->speed)*1.852);
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%.1f",
+                                        atof(p_station->speed)*1.1508);
+
+                            XmTextFieldSetString(SL_speed[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_speed[type][row],"");
+
+                        XtManageChild(SL_speed[type][row]);
+
+                        if (strlen(p_station->altitude)>0) {
+                            if (!english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%s", p_station->altitude);
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%.1f", atof(p_station->altitude)*3.28084);
+
+                            XmTextFieldSetString(SL_alt[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_alt[type][row],"");
+
+                        XtManageChild(SL_alt[type][row]);
+
+                        if (coordinate_system == USE_UTM
+                                || coordinate_system == USE_UTM_SPECIAL) {
+                            // Create a UTM string from coordinates
+                            // in Xastir coordinate system.
+                            convert_xastir_to_UTM_str(stemp, sizeof(stemp), p_station->coord_lon, p_station->coord_lat);
+                            XmTextFieldSetString(SL_lat_long[type][row],stemp);
+                            XtManageChild(SL_lat_long[type][row]);
+                        }
+                        else if (coordinate_system == USE_MGRS) {
+                            // Create an MGRS string from
+                            // coordinates in Xastir coordinate
+                            // system.
+                            convert_xastir_to_MGRS_str(stemp,
+                                sizeof(stemp),
+                                p_station->coord_lon,
+                                p_station->coord_lat,
+                                0);
+                            XmTextFieldSetString(SL_lat_long[type][row],stemp);
+                            XtManageChild(SL_lat_long[type][row]);
+                        }
+                        else {
+                            // Create lat/lon strings from coordinates
+                            // in Xastir coordinate system.
+                            if (coordinate_system == USE_DDDDDD) {
+                                convert_lat_l2s(p_station->coord_lat, stemp1, sizeof(stemp1), CONVERT_DEC_DEG);
+                                convert_lon_l2s(p_station->coord_lon, stemp2, sizeof(stemp2), CONVERT_DEC_DEG);
+                            } else if (coordinate_system == USE_DDMMSS) {
+                                convert_lat_l2s(p_station->coord_lat, stemp1, sizeof(stemp1), CONVERT_DMS_NORMAL);
+                                convert_lon_l2s(p_station->coord_lon, stemp2, sizeof(stemp2), CONVERT_DMS_NORMAL);
+                            } else {    // Assume coordinate_system == USE_DDMMMM
+                                convert_lat_l2s(p_station->coord_lat, stemp1, sizeof(stemp1), CONVERT_HP_NORMAL);
+                                convert_lon_l2s(p_station->coord_lon, stemp2, sizeof(stemp2), CONVERT_HP_NORMAL);
+                            }
+                            xastir_snprintf(stemp, sizeof(stemp), "%s  %s", stemp1, stemp2);
+                            XmTextFieldSetString(SL_lat_long[type][row],stemp);
+                            XtManageChild(SL_lat_long[type][row]);
+                        }
+
+                        xastir_snprintf(stemp, sizeof(stemp), "%d",
+                                (int)p_station->num_packets);
+                        XmTextFieldSetString(SL_packets[type][row],stemp);
+                        XtManageChild(SL_packets[type][row]);
+
+                        if (strlen(p_station->sats_visible)>0){
+                            xastir_snprintf(stemp, sizeof(stemp), "%d", atoi(p_station->sats_visible));
+                            XmTextFieldSetString(SL_sats[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_sats[type][row],"");
+
+                        XtManageChild(SL_sats[type][row]);
+
+                        l_lat = convert_lat_s2l(my_lat);
+                        l_lon = convert_lon_s2l(my_long);
+
+                        // Get distance in nautical miles
+                        value = (float)calc_distance_course(l_lat,l_lon,
+                            p_station->coord_lat,p_station->coord_lon,stemp,sizeof(stemp));
+
+                        if (english_units)
+                            xastir_snprintf(stemp1, sizeof(stemp1), "%0.1f", (value * 1.15078));
+                        else
+                            xastir_snprintf(stemp1, sizeof(stemp1), "%0.1f", (value * 1.852));
+
+                        XmTextFieldSetString(SL_my_course[type][row],stemp);
+                        XtManageChild(SL_my_course[type][row]);
+                        XmTextFieldSetString(SL_my_distance[type][row],stemp1);
+                        XtManageChild(SL_my_distance[type][row]);
+
+                        break;
+
+                    case LST_WX:                        // weather stations list
+
+                        weather = p_station->weather_data;
+
+                        if ((int)(((sec_old + weather->wx_sec_time)) < sec_now()))
+                            break;  // Weather data is too old
+
+                        if (strlen(weather->wx_course) > 0)
+                            XmTextFieldSetString(SL_wx_wind_course[type][row],weather->wx_course);
+                        else
+                            XmTextFieldSetString(SL_wx_wind_course[type][row],"");
+
+                        XtManageChild(SL_wx_wind_course[type][row]);
+
+                        if (strlen(weather->wx_speed) > 0) {
+                            if (english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%d", (int)atoi(weather->wx_speed));
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%d", (int)(atof(weather->wx_speed)*1.6094));
+
+                            XmTextFieldSetString(SL_wx_wind_speed[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_wx_wind_speed[type][row],"");
+
+                        XtManageChild(SL_wx_wind_speed[type][row]);
+
+                        if (strlen(weather->wx_gust) > 0) {
+                            if (english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%d", atoi(weather->wx_gust));
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%d", (int)(atof(weather->wx_gust)*1.6094));
+
+                            XmTextFieldSetString(SL_wx_wind_gust[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_wx_wind_gust[type][row],"");
+
+                        XtManageChild(SL_wx_wind_gust[type][row]);
+
+                        if (strlen(weather->wx_temp) > 0) {
+                            if (english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%d", atoi(weather->wx_temp));
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%d", (int)(((atof(weather->wx_temp)-32)*5.0)/9.0));
+
+                            XmTextFieldSetString(SL_wx_temp[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_wx_temp[type][row],"");
+
+                        XtManageChild(SL_wx_temp[type][row]);
+
+                        if (strlen(weather->wx_hum) > 0)
+                            XmTextFieldSetString(SL_wx_hum[type][row],weather->wx_hum);
+                        else
+                            XmTextFieldSetString(SL_wx_hum[type][row],"");
+
+                        XtManageChild(SL_wx_hum[type][row]);
+
+//WE7U
+// Change this to inches mercury when English Units is selected
+                        if (strlen(weather->wx_baro) > 0) {
+                            if (!english_units) {    // hPa
+                                XmTextFieldSetString(SL_wx_baro[type][row],
+                                    weather->wx_baro);
+                            }
+                            else {  // Inches Mercury
+                                float temp;
+                                char temp2[15];
+
+                                temp = atof(weather->wx_baro)*0.02953;
+                                xastir_snprintf(temp2,
+                                    sizeof(temp2),
+                                    "%0.2f",
+                                    temp);
+                                XmTextFieldSetString(SL_wx_baro[type][row],
+                                    temp2);
+                            }
+                        }
+                        else {
+                            XmTextFieldSetString(SL_wx_baro[type][row],"");
+                        }
+
+                        XtManageChild(SL_wx_baro[type][row]);
+
+                        if (strlen(weather->wx_rain) > 0) {
+                            if (english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%0.2f", atof(weather->wx_rain)/100.0);
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%0.2f", atof(weather->wx_rain)*.254);
+
+                            XmTextFieldSetString(SL_wx_rain_h[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_wx_rain_h[type][row],"");
+
+                        XtManageChild(SL_wx_rain_h[type][row]);
+
+                        if (strlen(weather->wx_prec_00) > 0) {
+                            if (english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%0.2f", atof(weather->wx_prec_00)/100.0);
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%0.2f", atof(weather->wx_prec_00)*.254);
+
+                            XmTextFieldSetString(SL_wx_rain_00[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_wx_rain_00[type][row],"");
+
+                        XtManageChild(SL_wx_rain_00[type][row]);
+
+                        if (strlen(weather->wx_prec_24) > 0) {
+                            if (english_units)
+                                xastir_snprintf(stemp, sizeof(stemp), "%0.2f", atof(weather->wx_prec_24)/100.0);
+                            else
+                                xastir_snprintf(stemp, sizeof(stemp), "%0.2f", atof(weather->wx_prec_24)*.254);
+
+                            XmTextFieldSetString(SL_wx_rain_24[type][row],stemp);
+                        } else
+                            XmTextFieldSetString(SL_wx_rain_24[type][row],"");
+
+                        XtManageChild(SL_wx_rain_24[type][row]);
+                        break;
+
+                    default:
+                        break;
+                }
+            } else {                                            // no data, empty row
+                XtVaSetValues(SL_da[type][row],XmNlabelPixmap, blank_icon,NULL);
+                XtManageChild(SL_da[type][row]);
+                symbol(SL_da[type][row],0,'~','$','\0',SL_icon[type][row],0,0,0,' ');
+                XtVaSetValues(SL_da[type][row],XmNlabelPixmap, SL_icon[type][row],NULL);
+                XtManageChild(SL_da[type][row]);
+
+                xastir_snprintf(temp, sizeof(temp), "%*d", strwid, (row+1+new_offset));
+                XmTextFieldSetString(SL_list[type][row],temp);
+                XtManageChild(SL_list[type][row]);
+
+                XmTextFieldSetString(SL_call[type][row],"");
+                XtManageChild(SL_call[type][row]);
+
+                switch (type) {
+                    case LST_TNC:       // local stations list
+                    case LST_TIM:
+                    case LST_ALL:       // stations list
+                    case LST_OBJ:       // Objects/Items list
+                    case LST_MYOBJ:     // My objects/Items
+                        XmTextFieldSetString(SL_packets[type][row],"");
+                        XtManageChild(SL_packets[type][row]);
+                        XmTextFieldSetString(SL_pos_time[type][row],"");
+                        XtManageChild(SL_pos_time[type][row]);
+                        XmTextFieldSetString(SL_node_path[type][row],"");
+                        XtManageChild(SL_node_path[type][row]);
+                        XmTextFieldSetString(SL_power_gain[type][row],"");
+                        XtManageChild(SL_power_gain[type][row]);
+                        XmTextFieldSetString(SL_comments[type][row],"");
+                        XtManageChild(SL_comments[type][row]);
+                        break;
+
+                    case LST_MOB:       // mobile stations list
+                        XmTextFieldSetString(SL_course[type][row],"");
+                        XtManageChild(SL_course[type][row]);
+                        XmTextFieldSetString(SL_speed[type][row],"");
+                        XtManageChild(SL_speed[type][row]);
+                        XmTextFieldSetString(SL_alt[type][row],"");
+                        XtManageChild(SL_alt[type][row]);
+                        XmTextFieldSetString(SL_lat_long[type][row],"");
+                        XtManageChild(SL_lat_long[type][row]);
+                        XmTextFieldSetString(SL_packets[type][row],"");
+                        XtManageChild(SL_packets[type][row]);
+                        XmTextFieldSetString(SL_sats[type][row],"");
+                        XtManageChild(SL_sats[type][row]);
+                        XmTextFieldSetString(SL_my_course[type][row],"");
+                        XtManageChild(SL_my_course[type][row]);
+                        XmTextFieldSetString(SL_my_distance[type][row],"");
+                        XtManageChild(SL_my_distance[type][row]);
+                        break;
+
+                    case LST_WX:   /*WX stations list */
+                        XmTextFieldSetString(SL_wx_wind_course[type][row],"");
+                        XtManageChild(SL_wx_wind_course[type][row]);
+                        XmTextFieldSetString(SL_wx_wind_speed[type][row],"");
+                        XtManageChild(SL_wx_wind_speed[type][row]);
+                        XmTextFieldSetString(SL_wx_wind_gust[type][row],"");
+                        XtManageChild(SL_wx_wind_gust[type][row]);
+                        XmTextFieldSetString(SL_wx_temp[type][row],"");
+                        XtManageChild(SL_wx_temp[type][row]);
+                        XmTextFieldSetString(SL_wx_hum[type][row],"");
+                        XtManageChild(SL_wx_hum[type][row]);
+                        XmTextFieldSetString(SL_wx_baro[type][row],"");
+                        XtManageChild(SL_wx_baro[type][row]);
+                        XmTextFieldSetString(SL_wx_rain_h[type][row],"");
+                        XtManageChild(SL_wx_rain_h[type][row]);
+                        XmTextFieldSetString(SL_wx_rain_00[type][row],"");
+                        XtManageChild(SL_wx_rain_00[type][row]);
+                        XmTextFieldSetString(SL_wx_rain_24[type][row],"");
+                        XtManageChild(SL_wx_rain_24[type][row]);
+                        break;
+
+                    default:
+                        break;
+                }
+            }           // empty line
+            if (p_station != NULL)
+                get_list_member(type, &p_station, 1, 1);        // get next member in list
+        }  // loop over display lines
+
+end_critical_section(&station_list_dialog_lock, "list_gui.c:Station_List_fill" );
+
+    }  // if list is defined
+}
+
+
+
+
+
+/*
+ *  Check if we have to update an active list, do it if necessary
+ */
+void update_station_scroll_list(void) {         // called from UpdateTime() [main.c] in timing loop
+    int i;
+    int pos;
+    Dimension last_h, last_w;
+    int last;
+    int ok;
+
+    last_h = last_w = 0;
+    ok = 0;
+    for (i=0;i<LST_NUM;i++) {                 // update all active lists
+        if (station_list_dialog[i] != NULL) {
+            XtVaGetValues(station_list_dialog[i], XmNheight, &last_h, XmNwidth, &last_w, NULL);
+            XtVaGetValues(SL_scroll[i], XmNmaximum,&last,XmNvalue, &pos, NULL);
+            if ((redo_list && (sec_now() - last_list_upd > LIST_UPDATE_CYCLE))
+                  || (last_h!=list_size_h[i]) || (last_w!=list_size_w[i])
+                  || units_last!=english_units) {
+                Station_List_fill(i,pos);     // update list contents
+                ok = 1;
+            }
+        }
+    }
+    if (ok == 1) {
+        last_list_upd = sec_now();
+        redo_list = FALSE;
+    }
+    units_last = english_units;
+}
+
+
+
+
+
+void dragCallback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    int i;
+
+    XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)callData;
+    i = atoi((char *)clientData);
+    // DK7IN:
+    // todo: We should only do the update if no other list navigation command is
+    //       waiting, otherwise we only should update the offset value.
+    //       Same with all other callbacks below...
+    Station_List_fill(i,cbs->value);
+}
+
+
+
+
+
+void decrementCallback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    int i;
+
+    XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)callData;
+    i = atoi((char *)clientData);
+    Station_List_fill(i,cbs->value);
+}
+
+
+
+
+
+void incrementCallback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    int i;
+
+    XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)callData;
+    i = atoi((char *)clientData);
+    Station_List_fill(i,cbs->value);
+}
+
+
+
+
+
+void pageDecrementCallback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    int i;
+
+    XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)callData;
+    i = atoi((char *)clientData);
+    Station_List_fill(i,cbs->value);
+}
+
+
+
+
+
+void pageIncrementCallback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    int i;
+
+    XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)callData;
+    i = atoi((char *)clientData);
+    Station_List_fill(i,cbs->value);
+}
+
+
+
+
+
+void mouseScrollHandler(Widget w, XtPointer clientData, XButtonEvent* event, Boolean* continueToDispatch) {
+    int i = atoi((char*)clientData);
+    int lines = 2;
+    // no modifier moves 2 lines
+    // shift moves 1 line
+    // control moves 10 lines
+
+    if (event->type == ButtonRelease) {
+        if (event->state & ControlMask)
+            lines = 10;
+        else if (event->state & ShiftMask)
+            lines = 1;
+
+        if (event->button == Button4) {         // Scroll up
+            if (last_offset[i] > 0) {
+                if ((last_offset[i] - lines) < 0)
+                    Station_List_fill(i, 0);
+                else
+                    Station_List_fill(i, last_offset[i] - lines);
+            }
+        }
+        else if (event->button == Button5) {    // Scroll down
+            Station_List_fill(i, last_offset[i] + lines);
+        }
+    }
+}
+
+
+
+
+
+void valueChangedCallback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    int i;
+
+    XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)callData;
+    i = atoi((char *)clientData);
+    Station_List_fill(i,cbs->value);
+}
+
+
+
+
+
+/*
+ *  Setup the various list layouts
+ */
+void Station_List(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int i;
+    Widget pane, form, win_list, form2, button_close;
+    Widget numl,call,sep,sep2;
+    Widget it1, it2, it3, it4, it5, it6, it7, it8, it9;
+    Widget seps[40];
+    Atom delw;
+    int type;
+    char temp[400];
+
+    if (station_list_first) {
+        memset(&SL_scroll, 0, sizeof(SL_scroll));
+        init_station_lists();           // init icons at very first list call
+        station_list_first=0;
+    }
+    type=atoi((char *)clientData);
+    switch(type) {
+        case LST_ALL:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI000"));        // All Stations
+            break;
+
+        case LST_MOB:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI001"));        // Mobile Stations
+            break;
+
+        case LST_WX:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI002"));        // Weather Stations
+            break;
+
+        case LST_TNC:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI003"));        // Local Stations
+            break;
+
+        case LST_TIM:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI004"));        // Last Stations
+            break;
+
+        case LST_OBJ:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI005"));        // Objects/Items
+            break;
+
+        case LST_MYOBJ:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                langcode("LHPUPNI006"));        // My Objects/Items
+            break;
+
+        default:
+            return;
+    }
+
+    if (!station_list_dialog[type]) {   // setup list area if not previously done
+                                        // DK7IN: we should destroy those Widgets to get the
+                                        // memory back, and rebuild it on the next call.   ????
+                                        // I don't exactly know what's going on, but we lose memory
+                                        // every time we call it.
+
+begin_critical_section(&station_list_dialog_lock, "list_gui.c:Station_List" );
+
+        station_list_dialog[type]= XtVaCreatePopupShell(temp,
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse,      XmDESTROY,
+            XmNdefaultPosition,     FALSE,
+            XmNminWidth,            274,
+            XmNmaxHeight,           ROWS*HGT+FUDGE,
+            XmNminHeight,           95,
+//          XmNheight,             230,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Station_List pane",xmPanedWindowWidgetClass, station_list_dialog[type],
+                                XmNbackground, colors[0xff],
+                                NULL);
+
+        form = XtVaCreateWidget("Station_List form",xmFormWidgetClass, pane,
+                                XmNfractionBase,        5,
+                                XmNshadowType,          XmSHADOW_OUT,
+                                XmNshadowThickness,     1,
+                                XmNbackground,          colors[0xff],
+                                XmNautoUnmanage,        FALSE,
+                                XmNshadowThickness,     1,
+                                NULL);
+
+        // station number in list
+        numl = XtVaCreateManagedWidget(langcode("LHPUPNI010"), xmTextFieldWidgetClass, form,
+                                XmNeditable,            FALSE,
+                                XmNcursorPositionVisible, FALSE,
+                                XmNtraversalOn,         FALSE,
+                                XmNsensitive,           STIPPLE,
+                                XmNshadowThickness,     0,
+                                XmNcolumns,             5,
+                                XmNtopAttachment,       XmATTACH_FORM,
+                                XmNtopOffset,           2,
+                                XmNbottomAttachment,    XmATTACH_NONE,
+                                XmNleftAttachment,      XmATTACH_FORM,
+                                XmNleftOffset,          3,
+                                XmNrightAttachment,     XmATTACH_NONE,
+                                XmNbackground,          colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+        XmTextFieldSetString(numl,langcode("LHPUPNI010"));              // #
+
+        // icon
+
+        // call
+        call = XtVaCreateManagedWidget(langcode("LHPUPNI011"), xmTextFieldWidgetClass, form,
+                                XmNeditable,            FALSE,
+                                XmNcursorPositionVisible, FALSE,
+                                XmNtraversalOn,         FALSE,
+                                XmNsensitive,           STIPPLE,
+                                XmNshadowThickness,     0,
+                                XmNcolumns,             9,      // 12,
+                                XmNtopAttachment,       XmATTACH_FORM,
+                                XmNtopOffset,           2,
+                                XmNbottomAttachment,    XmATTACH_NONE,
+                                XmNleftAttachment,      XmATTACH_WIDGET,
+                                XmNleftWidget,          numl,
+                                XmNleftOffset,          23,     // 22,
+                                XmNrightAttachment,     XmATTACH_NONE,
+                                XmNbackground,          colors[0xff],
+                                XmNfontList, fontlist1,
+                                NULL);
+        XmTextFieldSetString(call,langcode("LHPUPNI011"));              // Call Sign
+
+        switch (type) {
+            case LST_ALL:       // All Stations
+            case LST_TNC:       // Local Stations [via TNC]
+            case LST_TIM:       // Last Stations
+            case LST_OBJ:       // Objects/Item
+            case LST_MYOBJ:     // My objects/items
+
+                // number of packets heard
+                it1 = XtVaCreateManagedWidget(langcode("LHPUPNI012"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,                   FALSE,
+                                 XmNcursorPositionVisible,      FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive,                  STIPPLE,
+                                 XmNshadowThickness,            0,
+                                 XmNcolumns,                    5,
+                                 XmNtopAttachment,              XmATTACH_FORM,
+                                 XmNtopOffset,                  2,
+                                 XmNbottomAttachment,           XmATTACH_NONE,
+                                 XmNleftAttachment,             XmATTACH_WIDGET,
+                                 XmNleftWidget,                 call,
+                                 XmNleftOffset,                 1,
+                                 XmNrightAttachment,            XmATTACH_NONE,
+                                 XmNbackground,                 colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+                XmTextFieldSetString(it1,langcode("LHPUPNI012"));       // #Pack
+
+                // Last time of position
+                it2 = XtVaCreateManagedWidget(langcode("LHPUPNI013"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,                   FALSE,
+                                 XmNcursorPositionVisible,      FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive,                  STIPPLE,
+                                 XmNshadowThickness,            0,
+                                 XmNcolumns,                    11,     //16,        //17,
+                                 XmNtopAttachment,              XmATTACH_FORM,
+                                 XmNtopOffset,                  2,
+                                 XmNbottomAttachment,           XmATTACH_NONE,
+                                 XmNleftAttachment,             XmATTACH_WIDGET,
+                                 XmNleftWidget,                 it1,
+                                 XmNleftOffset,                 0,      // 1,
+                                 XmNrightAttachment,            XmATTACH_NONE,
+                                 XmNbackground,                 colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+                XmTextFieldSetString(it2,langcode("LHPUPNI013"));       // Last Position Time
+
+                // Path
+                it3 = XtVaCreateManagedWidget(langcode("LHPUPNI014"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,                   FALSE,
+                                 XmNcursorPositionVisible,      FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive,                  STIPPLE,
+                                 XmNshadowThickness,            0,
+                                 XmNcolumns,                    30,
+                                 XmNtopAttachment,              XmATTACH_FORM,
+                                 XmNtopOffset,                  2,
+                                 XmNbottomAttachment,           XmATTACH_NONE,
+                                 XmNleftAttachment,             XmATTACH_WIDGET,
+                                 XmNleftWidget,                 it2,
+                                 XmNleftOffset,                 0,      // 1,
+                                 XmNrightAttachment,            XmATTACH_NONE,
+                                 XmNbackground,                 colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+                XmTextFieldSetString(it3,langcode("LHPUPNI014"));       // Path
+
+                // PHG
+                it4 = XtVaCreateManagedWidget(langcode("LHPUPNI015"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,                   FALSE,
+                                 XmNcursorPositionVisible,      FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive,                  STIPPLE,
+                                 XmNshadowThickness,            0,
+                                 XmNcolumns,                    7,
+                                 XmNtopAttachment,              XmATTACH_FORM,
+                                 XmNtopOffset,                  2,
+                                 XmNbottomAttachment,           XmATTACH_NONE,
+                                 XmNleftAttachment,             XmATTACH_WIDGET,
+                                 XmNleftWidget,                 it3,
+                                 XmNleftOffset,                 0,      // 1,
+                                 XmNrightAttachment,            XmATTACH_NONE,
+                                 XmNbackground,                 colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+                XmTextFieldSetString(it4,langcode("LHPUPNI015"));       // PHG
+
+                // Comments
+                it5 = XtVaCreateManagedWidget(langcode("LHPUPNI016"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,                   FALSE,
+                                 XmNcursorPositionVisible,      FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive,                  STIPPLE,
+                                 XmNshadowThickness,            0,
+                                 XmNcolumns,                    40,
+                                 XmNtopAttachment,              XmATTACH_FORM,
+                                 XmNtopOffset,                  2,
+                                 XmNbottomAttachment,           XmATTACH_NONE,
+                                 XmNleftAttachment,             XmATTACH_WIDGET,
+                                 XmNleftWidget,                 it4,
+                                 XmNleftOffset,                 0,      // 1,
+                                 XmNrightAttachment,            XmATTACH_NONE,
+                                 XmNbackground,                 colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+                XmTextFieldSetString(it5,langcode("LHPUPNI016"));       // Comments
+                break;
+
+            case LST_MOB:  /*mobile list */
+                it1 = XtVaCreateManagedWidget(langcode("LHPUPNI100"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 3,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, call,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it1,langcode("LHPUPNI100"));       // CSE
+
+                it2 = XtVaCreateManagedWidget(langcode("LHPUPNI101"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 4,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it1,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it2,langcode("LHPUPNI101"));       // SPD
+
+                it3 = XtVaCreateManagedWidget(langcode("LHPUPNI102"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 8,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it2,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it3,langcode("LHPUPNI102"));       // ALT.
+
+                it4 = XtVaCreateManagedWidget(langcode("LHPUPNI103"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 25,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it3,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it4,langcode("LHPUPNI209")); // Lat/Lon or UTM
+
+                it6 = XtVaCreateManagedWidget(langcode("LHPUPNI105"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 5,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it4,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it6,langcode("LHPUPNI105"));       // #Pack
+
+                it7 = XtVaCreateManagedWidget(langcode("LHPUPNI106"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 3,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it6,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it7,langcode("LHPUPNI106"));       // LSV
+
+                it8 = XtVaCreateManagedWidget(langcode("LHPUPNI107"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 5,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it7,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it8,langcode("LHPUPNI107"));       // CFMS
+
+                it9 = XtVaCreateManagedWidget(langcode("LHPUPNI108"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 6,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it8,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it9,langcode("LHPUPNI108"));       // DFMS
+
+                break;
+
+            case LST_WX:   /*wx list */
+                it1 = XtVaCreateManagedWidget(langcode("LHPUPNI200"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 3,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, call,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it1,langcode("LHPUPNI200"));       // CSE
+
+                it2 = XtVaCreateManagedWidget(langcode("LHPUPNI201"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 3,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it1,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it2,langcode("LHPUPNI201"));       // SPD
+
+                it3 = XtVaCreateManagedWidget(langcode("LHPUPNI202"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 3,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it2,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it3,langcode("LHPUPNI202"));       // GST
+
+                it4 = XtVaCreateManagedWidget(langcode("LHPUPNI203"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 4,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it3,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it4,langcode("LHPUPNI203"));       // Temp
+
+                it5 = XtVaCreateManagedWidget(langcode("LHPUPNI204"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 3,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it4,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it5,langcode("LHPUPNI204"));       // Hum
+
+                it6 = XtVaCreateManagedWidget(langcode("LHPUPNI205"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 6,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it5,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it6,langcode("LHPUPNI205"));       // Baro
+
+                it7 = XtVaCreateManagedWidget(langcode("LHPUPNI206"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 5,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it6,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it7,langcode("LHPUPNI206"));       // RN-H
+
+                it8 = XtVaCreateManagedWidget(langcode("LHPUPNI207"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 5,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it7,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it8,langcode("LHPUPNI207"));       // RNSM
+
+                it9 = XtVaCreateManagedWidget(langcode("LHPUPNI208"), xmTextFieldWidgetClass, form,
+                                 XmNeditable,   FALSE,
+                                 XmNcursorPositionVisible, FALSE,
+                                 XmNtraversalOn,         FALSE,
+                                 XmNsensitive, STIPPLE,
+                                 XmNshadowThickness, 0,
+                                 XmNcolumns, 5,
+                                 XmNtopAttachment, XmATTACH_FORM,
+                                 XmNtopOffset,2,
+                                 XmNbottomAttachment, XmATTACH_NONE,
+                                 XmNleftAttachment, XmATTACH_WIDGET,
+                                 XmNleftWidget, it8,
+                                 XmNleftOffset, 1,
+                                 XmNrightAttachment, XmATTACH_NONE,
+                                 XmNbackground, colors[0xff],
+                                 XmNfontList, fontlist1,
+                                 NULL);
+
+                XmTextFieldSetString(it9,langcode("LHPUPNI208"));       // RN24
+
+                break;
+
+            default:
+                break;
+        } // if (!station_list_dialog[type])...    from some kilometers above...  ;-)
+
+        sep = XtVaCreateManagedWidget("Station_List sep", xmSeparatorGadgetClass,form,
+                                    XmNorientation,             XmHORIZONTAL,
+                                    XmNtopAttachment,           XmATTACH_WIDGET,
+                                    XmNtopWidget,               numl,
+                                    XmNtopOffset,               2,
+                                    XmNbottomAttachment,        XmATTACH_NONE,
+                                    XmNleftAttachment,          XmATTACH_FORM,
+                                    XmNrightAttachment,         XmATTACH_FORM,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        SL_scroll[type] = XtVaCreateManagedWidget("Station_List SL_scroll", xmScrollBarWidgetClass,form,
+                                    XmNorientation,             XmVERTICAL,
+                                    XmNtraversalOn,             TRUE,
+                                    XmNmaximum,                 10,
+//                                    XmNmaximum,                 stations_types(type),
+//                                    XmNsliderSize,              rows,        //
+//                                    XmNpageIncrement,           rows,      // was 18
+                                    XmNheight,                  145,        // test
+                                    XmNsliderSize,              10,        //
+                                    XmNpageIncrement,           10,      // was 18
+                                    XmNprocessingDirection,     XmMAX_ON_BOTTOM,
+                                    XmNtopAttachment,           XmATTACH_WIDGET,
+                                    XmNtopWidget,               sep,
+                                    XmNtopOffset,               0,
+                                    XmNbottomAttachment,        XmATTACH_FORM,
+                                    XmNbottomOffset,            42,
+                                    XmNleftAttachment,          XmATTACH_NONE,
+                                    XmNrightAttachment,         XmATTACH_FORM,
+                                    XmNbackground,              colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+        XtAddEventHandler(SL_scroll[type], ButtonReleaseMask, FALSE,
+                          (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+        win_list =  XtVaCreateWidget("Station_List win_list",xmFormWidgetClass, form,
+                                    XmNtopAttachment,           XmATTACH_WIDGET,
+                                    XmNtopWidget,               sep,
+                                    XmNtopOffset,               2,
+                                    XmNbottomAttachment,        XmATTACH_FORM,
+                                    XmNbottomOffset,            42,
+                                    XmNleftAttachment,          XmATTACH_FORM,
+                                    XmNleftOffset,              2,
+                                    XmNrightAttachment,         XmATTACH_WIDGET,
+                                    XmNrightWidget,             SL_scroll[type],
+                                    XmNbackground,              colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+        XtAddEventHandler(win_list, ButtonReleaseMask, FALSE,
+                          (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+        for (i=0; i<ROWS;i++) {   // setup widgets for maximum number of rows
+            if (i != 0) {         // not first row
+
+                seps[i] = XtVaCreateManagedWidget("Station_List seps", xmSeparatorGadgetClass, win_list,
+                                      XmNorientation,           XmHORIZONTAL,
+                                      XmNleftAttachment,        XmATTACH_FORM,
+                                      XmNrightAttachment,       XmATTACH_FORM,
+                                      XmNtopAttachment,         XmATTACH_WIDGET,
+                                      XmNtopWidget,             SL_list[type][i-1],
+                                      XmNbackground,            colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+                // line
+                SL_list[type][i]= XtVaCreateManagedWidget("Station_List line data", xmTextFieldWidgetClass, win_list,
+                                      XmNeditable,              FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNtraversalOn,           FALSE,
+                                      XmNsensitive,             STIPPLE,
+                                      XmNalignment,             XmALIGNMENT_END,
+                                      XmNshadowThickness,       0,
+                                      XmNcolumns,               5,
+                                      XmNleftAttachment,        XmATTACH_FORM,
+                                      XmNleftOffset,            2,
+                                      XmNtopAttachment,         XmATTACH_WIDGET,
+                                      XmNtopWidget,             seps[i],
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNbackground,            colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+            } else {            // all except first row
+                // station number in list
+                SL_list[type][i]= XtVaCreateManagedWidget("Station_List line data", xmTextFieldWidgetClass, win_list,
+                                      XmNeditable,              FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNtraversalOn,           FALSE,
+                                      XmNsensitive,             STIPPLE,
+                                      XmNalignment,             XmALIGNMENT_END,
+                                      XmNshadowThickness,       0,
+                                      XmNcolumns,               5,
+                                      XmNleftAttachment,        XmATTACH_FORM,
+                                      XmNleftOffset,            2,
+                                      XmNtopAttachment,         XmATTACH_FORM,
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNbackground,            colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+            }
+            XtAddEventHandler(SL_list[type][i], ButtonReleaseMask, FALSE,
+                              (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+            // station symbol graphics
+            SL_da[type][i] = XtVaCreateManagedWidget("Station_List icon", xmPushButtonWidgetClass, win_list,
+                                      XmNtopAttachment,         XmATTACH_OPPOSITE_WIDGET,
+                                      XmNtopWidget,             SL_list[type][i],
+                                      XmNtopOffset,             -5,             // Align with top of row, not top of text.
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNleftAttachment,        XmATTACH_WIDGET,
+                                      XmNleftWidget,            SL_list[type][i],
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNlabelType,             XmPIXMAP,
+                                      XmNlabelPixmap,           SL_icon[type][i],
+                                      XmNbackground,            colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+            //XtAddEventHandler(SL_da[type][i], ButtonReleaseMask, FALSE,
+            //                  (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+            // call sign
+            SL_call[type][i]= XtVaCreateManagedWidget("Station_List call data", xmTextFieldWidgetClass, win_list,
+                                      XmNeditable,              FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNtraversalOn,           FALSE,
+                                      XmNsensitive,             TRUE,
+                                      XmNshadowThickness,       0,
+                                      XmNcolumns,               9,      // 12,
+                                      XmNbackground,            colors[0x0f],
+                                      XmNleftAttachment,        XmATTACH_WIDGET,
+                                      XmNleftWidget,            SL_da[type][i],
+                                      XmNleftOffset,            0,      // 1,
+                                      XmNtopAttachment,         XmATTACH_OPPOSITE_WIDGET,
+                                      XmNtopWidget,             SL_list[type][i],
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+            XtAddEventHandler(SL_da[type][i], ButtonReleaseMask, FALSE,
+                             (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+            switch (type) {
+                case LST_ALL:   // station list
+                case LST_TNC:   // local station list
+                case LST_TIM:
+                case LST_OBJ:   // Objects/Items
+                case LST_MYOBJ: // My objects/items
+                    // number of packets received
+                    SL_packets[type][i] = XtVaCreateManagedWidget("Station_List packets", xmTextFieldWidgetClass, win_list,
+                                      XmNeditable,              FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNtraversalOn,           FALSE,
+                                      XmNsensitive,             STIPPLE,
+                                      XmNshadowThickness,       0,
+                                      XmNcolumns,               5,
+                                      XmNbackground,            colors[0x0f],
+                                      XmNalignment,             XmALIGNMENT_END,
+                                      XmNleftAttachment,        XmATTACH_WIDGET,
+                                      XmNleftWidget,            SL_call[type][i],
+                                      XmNleftOffset,            0,      //1,
+                                      XmNtopAttachment,         XmATTACH_OPPOSITE_WIDGET,
+                                      XmNtopWidget,             SL_list[type][i],
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+                    XtAddEventHandler(SL_packets[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    // Last time of position report
+                    SL_pos_time[type][i] = XtVaCreateManagedWidget("Station_List pos_time", xmTextFieldWidgetClass, win_list,
+                                      XmNeditable,              FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNtraversalOn,           FALSE,
+                                      XmNsensitive,             STIPPLE,
+                                      XmNshadowThickness,       0,
+                                      XmNcolumns,               11,     //16,     // 17,
+                                      XmNbackground,            colors[0x0f],
+                                      XmNalignment,             XmALIGNMENT_END,
+                                      XmNleftAttachment,        XmATTACH_WIDGET,
+                                      XmNleftWidget,            SL_packets[type][i],
+                                      XmNleftOffset,            0,      // 1,
+                                      XmNtopAttachment,         XmATTACH_OPPOSITE_WIDGET,
+                                      XmNtopWidget,             SL_list[type][i],
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+                    XtAddEventHandler(SL_pos_time[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    // path
+                    SL_node_path[type][i] = XtVaCreateManagedWidget("Station_List node_path", xmTextFieldWidgetClass, win_list,
+                                      XmNeditable,              FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNtraversalOn,           FALSE,
+                                      XmNsensitive,             STIPPLE,
+                                      XmNshadowThickness,       0,
+                                      XmNcolumns,               30,
+                                      XmNbackground,            colors[0x0f],
+                                      XmNalignment,             XmALIGNMENT_END,
+                                      XmNleftAttachment,        XmATTACH_WIDGET,
+                                      XmNleftWidget,            SL_pos_time[type][i],
+                                      XmNleftOffset,            0,      // 1,
+                                      XmNtopAttachment,         XmATTACH_OPPOSITE_WIDGET,
+                                      XmNtopWidget,             SL_list[type][i],
+                                      XmNbottomAttachment,      XmATTACH_NONE,
+                                      XmNrightAttachment,       XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+                    XtAddEventHandler(SL_node_path[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    // PHG
+                    SL_power_gain[type][i] = XtVaCreateManagedWidget("Station_List packets", xmTextFieldWidgetClass, win_list,
+                                    XmNeditable,                FALSE,
+                                    XmNcursorPositionVisible,   FALSE,
+                                    XmNtraversalOn,           FALSE,
+                                    XmNsensitive,               STIPPLE,
+                                    XmNshadowThickness,         0,
+                                    XmNcolumns,                 7,
+                                    XmNbackground,              colors[0x0f],
+                                    XmNalignment,               XmALIGNMENT_END,
+                                    XmNleftAttachment,          XmATTACH_WIDGET,
+                                    XmNleftWidget,              SL_node_path[type][i],
+                                    XmNleftOffset,              0,      // 1,
+                                    XmNtopAttachment,           XmATTACH_OPPOSITE_WIDGET,
+                                    XmNtopWidget,               SL_list[type][i],
+                                    XmNbottomAttachment,        XmATTACH_NONE,
+                                    XmNrightAttachment,         XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+                    XtAddEventHandler(SL_power_gain[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    // Comment
+                    SL_comments[type][i] = XtVaCreateManagedWidget("Station_List comments", xmTextFieldWidgetClass, win_list,
+                                    XmNeditable,                FALSE,
+                                    XmNcursorPositionVisible,   FALSE,
+                                    XmNtraversalOn,             FALSE,
+                                    XmNsensitive,               STIPPLE,
+                                    XmNshadowThickness,         0,
+                                    XmNcolumns,                 40,
+                                    XmNbackground,              colors[0x0f],
+                                    XmNalignment,               XmALIGNMENT_END,
+                                    XmNleftAttachment,          XmATTACH_WIDGET,
+                                    XmNleftWidget,              SL_power_gain[type][i],
+                                    XmNleftOffset,              0,      // 1,
+                                    XmNtopAttachment,           XmATTACH_OPPOSITE_WIDGET,
+                                    XmNtopWidget,               SL_list[type][i],
+                                    XmNbottomAttachment,        XmATTACH_NONE,
+                                    XmNrightAttachment,         XmATTACH_NONE,
+                                    XmNfontList, fontlist1,
+                                    NULL);
+                    XtAddEventHandler(SL_comments[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+                    break;
+
+                case LST_MOB:   /*mobile list */
+                    SL_course[type][i] = XtVaCreateManagedWidget("Station_List course", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn,             FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 3,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_call[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_course[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_speed[type][i] = XtVaCreateManagedWidget("Station_List speed", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 4,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_course[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_speed[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_alt[type][i] = XtVaCreateManagedWidget("Station_List alt", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 8,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_speed[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_alt[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_lat_long[type][i] = XtVaCreateManagedWidget("Station_List lat/lon", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 25,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_alt[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_lat_long[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_packets[type][i] = XtVaCreateManagedWidget("Station_List packets", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 5,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_lat_long[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_packets[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_sats[type][i] = XtVaCreateManagedWidget("Station_List sats", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 3,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_packets[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_sats[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_my_course[type][i] = XtVaCreateManagedWidget("Station_List my course", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 5,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_sats[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_my_course[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_my_distance[type][i] = XtVaCreateManagedWidget("Station_List my distance", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 6,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_my_course[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_my_distance[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    break;
+
+                case LST_WX:   /*wx list */
+                    SL_wx_wind_course[type][i] = XtVaCreateManagedWidget("Station_List wind course", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 3,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_call[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_wind_course[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_wind_speed[type][i] = XtVaCreateManagedWidget("Station_List wind speed", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 3,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_wind_course[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_wind_speed[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+
+                    SL_wx_wind_gust[type][i] = XtVaCreateManagedWidget("Station_List wind gust", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 3,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_wind_speed[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_wind_gust[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_temp[type][i] = XtVaCreateManagedWidget("Station_List temp", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 4,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_wind_gust[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_temp[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_hum[type][i] = XtVaCreateManagedWidget("Station_List humidity", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 3,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_temp[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_hum[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_baro[type][i] = XtVaCreateManagedWidget("Station_List wx baro", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 6,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_hum[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_baro[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_rain_h[type][i] = XtVaCreateManagedWidget("Station_List rain hour", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 5,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_baro[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_rain_h[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_rain_00[type][i] = XtVaCreateManagedWidget("Station_List rain since mid", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 5,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_rain_h[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_rain_00[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    SL_wx_rain_24[type][i] = XtVaCreateManagedWidget("Station_List rain last 24", xmTextFieldWidgetClass, win_list,
+                                        XmNeditable,   FALSE,
+                                        XmNcursorPositionVisible, FALSE,
+                                        XmNtraversalOn, FALSE,
+                                        XmNsensitive, STIPPLE,
+                                        XmNshadowThickness, 0,
+                                        XmNcolumns, 5,
+                                        XmNbackground, colors[0x0f],
+                                        XmNalignment, XmALIGNMENT_END,
+                                        XmNleftAttachment,XmATTACH_WIDGET,
+                                        XmNleftWidget, SL_wx_rain_00[type][i],
+                                        XmNleftOffset, 1,
+                                        XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+                                        XmNtopWidget, SL_list[type][i],
+                                        XmNbottomAttachment,XmATTACH_NONE,
+                                        XmNrightAttachment,XmATTACH_NONE,
+                                        XmNfontList, fontlist1,
+                                        NULL);
+                    XtAddEventHandler(SL_wx_rain_24[type][i], ButtonReleaseMask, FALSE,
+                                      (XtEventHandler)mouseScrollHandler, (char*)clientData);
+
+                    break;
+
+                default:
+                    break;
+            }
+        }  // each row
+       
+        form2 = XtVaCreateWidget("Station_List form2",xmFormWidgetClass, form,
+                                    XmNfractionBase,            5,
+                                    XmNtopAttachment,           XmATTACH_WIDGET,
+                                    XmNtopWidget,               SL_scroll[type],
+                                    XmNbottomAttachment,        XmATTACH_FORM,
+                                    XmNrightAttachment,         XmATTACH_FORM,
+                                    XmNleftAttachment,          XmATTACH_FORM,
+                                    XmNbackground,              colors[0xff],
+                                    NULL);
+
+        sep2 = XtVaCreateManagedWidget("Station_List sep2", xmSeparatorGadgetClass,form2,
+                                    XmNorientation,             XmHORIZONTAL,
+                                    XmNtopAttachment,           XmATTACH_FORM,
+                                    XmNbottomAttachment,        XmATTACH_NONE,
+                                    XmNrightAttachment,         XmATTACH_FORM,
+                                    XmNleftAttachment,          XmATTACH_FORM,
+                                    XmNbackground,              colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass,form2,
+                                    XmNtopAttachment,   XmATTACH_WIDGET,
+                                    XmNtopWidget,               sep2,
+                                    XmNtopOffset,               4,
+                                    XmNbottomAttachment,        XmATTACH_FORM,
+                                    XmNbottomOffset,            2,
+                                    XmNleftAttachment,          XmATTACH_POSITION,
+                                    XmNleftPosition,            2,
+                                    XmNrightAttachment,         XmATTACH_POSITION,
+                                    XmNrightPosition,           3,
+                                    XmNbackground,              colors[0xff],
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        pos_dialog(station_list_dialog[type]);  // calculate position
+        delw = XmInternAtom(XtDisplay(station_list_dialog[type]), "WM_DELETE_WINDOW", FALSE);
+
+        /* call backs */
+        XtAddCallback(SL_scroll[type], XmNdecrementCallback,     decrementCallback,     (char *)clientData);
+        XtAddCallback(SL_scroll[type], XmNdragCallback,          dragCallback,          (char *)clientData);
+        XtAddCallback(SL_scroll[type], XmNincrementCallback,     incrementCallback,     (char *)clientData);
+        XtAddCallback(SL_scroll[type], XmNpageDecrementCallback, pageDecrementCallback, (char *)clientData);
+        XtAddCallback(SL_scroll[type], XmNpageIncrementCallback, pageIncrementCallback, (char *)clientData);
+        XtAddCallback(SL_scroll[type], XmNvalueChangedCallback,  valueChangedCallback,  (char *)clientData);
+
+        XtAddCallback(button_close, XmNactivateCallback, station_list_destroy_shell,    (char *)clientData);
+        XmAddWMProtocolCallback(station_list_dialog[type], delw, station_list_destroy_shell, (char *)clientData);
+
+        XtManageChild(form);
+        XtManageChild(win_list);
+        XtManageChild(form2);
+        XtManageChild(pane);
+
+end_critical_section(&station_list_dialog_lock, "list_gui.c:Station_List" );
+
+        XtPopup(station_list_dialog[type], XtGrabNone);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(station_list_dialog[type]);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+     
+ 
+// Note:  If adding new lists, make sure to tweak xa_config.c to
+// increment the number.  If not, you'll get an X-Windows error at
+// this point when trying to resize the window:
+ 
+        /* set last size if there was one */    // done in list_fill
+        if (list_size_w[type] > 0 && list_size_h[type] > 0)
+                    XtVaSetValues(station_list_dialog[type], 
+                    XmNwidth,  list_size_w[type], 
+                    XmNheight, list_size_h[type], 
+                    NULL);
+
+        if (type != LST_TIM)
+            top_call[type][0] = '\0';             // start at top
+        else {
+            top_time =  0;
+            top_sn   = -1;
+        }
+        last_offset[type] = 0;
+        last_list_upd = sec_now();
+        list_size_i[type] = FALSE;
+        redo_list = (int)TRUE;        
+
+        Station_List_fill(type,0);      // start with top of list
+
+    } else          //  if (!station_list_dialog[type])
+        // we already have an initialized widget
+        (void)XRaiseWindow(XtDisplay(station_list_dialog[type]), XtWindow(station_list_dialog[type]));
+}
+
+
diff --git a/src/list_gui.h b/src/list_gui.h
new file mode 100644
index 0000000..38d64cf
--- /dev/null
+++ b/src/list_gui.h
@@ -0,0 +1,50 @@
+/*
+ * $Id: list_gui.h,v 1.13 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_LIST_GUI_H
+#define __XASTIR_LIST_GUI_H
+
+// different list types:
+#define LST_ALL 0
+#define LST_MOB 1
+#define LST_WX  2
+#define LST_TNC 3
+#define LST_TIM 4
+#define LST_OBJ 5
+#define LST_MYOBJ 6
+#define LST_NUM 7
+
+extern int list_size_h[];
+extern int list_size_w[];
+
+/* from list_gui.c */
+extern void list_gui_init(void);
+extern void update_station_scroll_list(void);
+extern int stations_types(int type);
+extern void Station_List_fill(int type, int new_offset);
+
+#endif  // __XASTIR_LIST_GUI_H
+
+
diff --git a/src/locate_gui.c b/src/locate_gui.c
new file mode 100644
index 0000000..de5a6a9
--- /dev/null
+++ b/src/locate_gui.c
@@ -0,0 +1,1220 @@
+/*
+ * $Id: locate_gui.c,v 1.32 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+
+#include <Xm/XmAll.h>
+#ifdef HAVE_XBAE_MATRIX_H
+#include <Xbae/Matrix.h>
+#endif  // HAVE_XBAE_MATRIX_H
+
+#include "xastir.h"
+#include "main.h"
+#include "lang.h"
+#include "maps.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+Widget locate_station_dialog = (Widget)NULL;
+Widget locate_station_data = (Widget)NULL;
+
+char locate_station_call[30];
+static xastir_mutex locate_station_dialog_lock;
+
+Widget locate_place_dialog = (Widget)NULL;
+Widget locate_place_data = (Widget)NULL;
+Widget locate_state_data = (Widget)NULL;
+Widget locate_county_data = (Widget)NULL;
+Widget locate_quad_data = (Widget)NULL;
+Widget locate_type_data = (Widget)NULL;
+Widget locate_gnis_file_data = (Widget)NULL;
+char locate_place_name[50];
+char locate_state_name[50];
+char locate_county_name[50];
+char locate_quad_name[50];
+char locate_type_name[50];
+char locate_gnis_filename[200];
+static xastir_mutex locate_place_dialog_lock;
+
+
+/* locate station values */
+Widget locate_case_data, locate_match_data;
+
+/* locate place values */
+Widget locate_place_case_data, locate_place_match_data;
+Widget locate_place_list;
+Widget  locate_place_chooser = (Widget)NULL;
+static xastir_mutex locate_place_chooser_lock;
+char match_array_name[50][200];
+long match_array_lat[50];
+long match_array_long[50];
+int match_quantity = 0;
+ 
+
+
+
+
+void locate_gui_init(void)
+{
+    init_critical_section( &locate_station_dialog_lock );
+    init_critical_section( &locate_place_dialog_lock );
+    init_critical_section( &locate_place_chooser_lock );
+    locate_station_call[0] = '\0';
+    locate_place_name[0] = '\0';
+    locate_state_name[0] = '\0';
+    locate_county_name[0] = '\0';
+    locate_quad_name[0] = '\0';
+    locate_type_name[0] = '\0';
+}
+
+
+
+
+
+/**** LOCATE STATION ******/
+
+void Locate_station_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&locate_station_dialog_lock, "locate_gui.c:Locate_station_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    locate_station_dialog = (Widget)NULL;
+
+end_critical_section(&locate_station_dialog_lock, "locate_gui.c:Locate_station_destroy_shell" );
+
+}
+
+
+
+
+
+/*
+ * Look up detailed FCC/RAC info about the station
+ */
+
+// Determine whether it is a U.S. or Canadian callsign then search
+// through the appropriate database and present the results.
+
+void fcc_rac_lookup(Widget w, XtPointer clientData, XtPointer callData) {
+    char station_call[200];
+    char temp[1000];
+    char temp2[300];
+    char *temp_ptr;
+    FccAppl my_fcc_data;
+    rac_record my_rac_data;
+
+
+    // Snag station call
+    temp_ptr = XmTextFieldGetString(locate_station_data);
+    xastir_snprintf(station_call,
+        sizeof(station_call),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(station_call);
+    (void)remove_trailing_dash_zero(station_call);
+
+    to_upper(station_call);
+
+    switch (station_call[0]) {
+        case 'A':
+        case 'K':
+        case 'N':
+        case 'W':
+            if (search_fcc_data_appl(station_call, &my_fcc_data) == 1) {
+
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "%s\n%s %s\n%s %s %s\n%s %s, %s %s, %s %s\n\n",
+                    langcode("STIFCC0001"),
+                    langcode("STIFCC0003"),
+                    my_fcc_data.name_licensee,
+                    langcode("STIFCC0004"),
+                    my_fcc_data.text_street,
+                    my_fcc_data.text_pobox,
+                    langcode("STIFCC0005"),
+                    my_fcc_data.city,
+                    langcode("STIFCC0006"),
+                    my_fcc_data.state,
+                    langcode("STIFCC0007"),
+                    my_fcc_data.zipcode);
+
+                popup_message_always(langcode("WPUPLSP007"),temp);
+            }
+            else {
+                xastir_snprintf(temp2,
+                    sizeof(temp2),
+                    "Callsign Not Found!\n");
+                popup_message_always(langcode("POPEM00001"),temp2);
+            }
+            break;
+        case 'V':
+            if (search_rac_data(station_call, &my_rac_data) == 1) {
+
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "%s\n%s %s\n%s\n%s, %s\n%s\n",
+                    langcode("STIFCC0002"),
+                    my_rac_data.first_name,
+                    my_rac_data.last_name,
+                    my_rac_data.address,
+                    my_rac_data.city,
+                    my_rac_data.province,
+                    my_rac_data.postal_code);
+
+                    if (my_rac_data.qual_a[0] == 'A')
+                        strncat(temp,
+                            langcode("STIFCC0008"),
+                            sizeof(temp) - 1 - strlen(temp));
+
+                    if (my_rac_data.qual_d[0] == 'D')
+                        strncat(temp,
+                            langcode("STIFCC0009"),
+                            sizeof(temp) - 1 - strlen(temp));
+
+                    if (my_rac_data.qual_b[0] == 'B' && my_rac_data.qual_c[0] != 'C')
+                        strncat(temp,
+                            langcode("STIFCC0010"),
+                            sizeof(temp) - 1 - strlen(temp));
+
+                    if (my_rac_data.qual_c[0] == 'C')
+                        strncat(temp,
+                            langcode("STIFCC0011"),
+                            sizeof(temp) - 1 - strlen(temp));
+
+                    strncat(temp,
+                        "\n",
+                        sizeof(temp) - 1 - strlen(temp));
+
+                    if (strlen(my_rac_data.club_name) > 1) {
+                        xastir_snprintf(temp2,
+                            sizeof(temp2),
+                            "%s\n%s\n%s, %s\n%s\n",
+                            my_rac_data.club_name,
+                            my_rac_data.club_address,
+                            my_rac_data.club_city,
+                            my_rac_data.club_province,
+                            my_rac_data.club_postal_code);
+                        strncat(temp,
+                            temp2,
+                            sizeof(temp) - 1 - strlen(temp));
+                    }
+
+
+                popup_message_always(langcode("WPUPLSP007"),temp);
+            }
+            else {
+                // RAC code does its own popup in this case?
+                //fprintf(stderr, "Callsign not found\n");
+            }
+            break;
+        default:
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "Not an FCC or RAC callsign!\n");
+            popup_message_always(langcode("POPEM00001"),temp2);
+            break;
+    }
+
+    // Don't enable this as then we can't click on the Locate button
+    // later.
+    //Locate_station_destroy_shell(w, clientData, callData);
+}
+
+
+
+
+
+/*
+ *  Locate a station by centering the map at its position
+ */
+void Locate_station_now(Widget w, XtPointer clientData, XtPointer callData) {
+    char temp2[200];
+    char *temp_ptr;
+
+
+    /* find station and go there */
+    temp_ptr = XmTextFieldGetString(locate_station_data);
+    xastir_snprintf(locate_station_call,
+        sizeof(locate_station_call),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(locate_station_call);
+    (void)remove_trailing_dash_zero(locate_station_call);
+
+    /*fprintf(stderr,"looking for %s\n",locate_station_call);*/
+    if (locate_station(da, locate_station_call, (int)XmToggleButtonGetState(locate_case_data),
+                    (int)XmToggleButtonGetState(locate_match_data),1) ==0) {
+        xastir_snprintf(temp2, sizeof(temp2), langcode("POPEM00002"), locate_station_call);
+        popup_message_always(langcode("POPEM00001"),temp2);
+    }
+
+    // Don't enable this as then we can't click on the FCC/RAC
+    // button later, and we'll lose the callsign info if we want to
+    // see it again.
+    //Locate_station_destroy_shell(w, clientData, callData);
+}
+
+
+
+
+
+// Here we pass in a 1 in callData if it's an emergency locate,
+// for when we've received a Mic-E emergency packet.
+//
+void Locate_station(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, XtPointer callData) {
+    static Widget pane, form, button_locate, button_cancel, call,
+        button_lookup, sep;
+    Atom delw;
+    int emergency_flag = XTPOINTER_TO_INT(callData);
+
+ 
+    if (!locate_station_dialog) {
+
+begin_critical_section(&locate_station_dialog_lock, "locate_gui.c:Locate_station" );
+
+        // Check whether it is an emergency locate function
+        if (emergency_flag == 1) {
+                locate_station_dialog = XtVaCreatePopupShell(langcode("WPUPLSP006"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+        }
+        else {  // Non-emergency locate
+            locate_station_dialog = XtVaCreatePopupShell(langcode("WPUPLSP001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+        }
+
+
+        pane = XtVaCreateWidget("Locate_station pane",xmPanedWindowWidgetClass, locate_station_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+        form =  XtVaCreateWidget("Locate_station form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 3,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+        call = XtVaCreateManagedWidget(langcode("WPUPLSP002"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        locate_station_data = XtVaCreateManagedWidget("Locate_station data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 15,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, call,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 10,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        locate_case_data  = XtVaCreateManagedWidget(langcode("WPUPLSP003"),xmToggleButtonWidgetClass,form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, call,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        locate_match_data  = XtVaCreateManagedWidget(langcode("WPUPLSP004"),xmToggleButtonWidgetClass,form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, call,
+                                      XmNtopOffset, 20,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget,locate_case_data,
+                                      XmNleftOffset ,20,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        sep = XtVaCreateManagedWidget("Locate_station sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget,locate_case_data,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_lookup = XtVaCreateManagedWidget(langcode("WPUPLSP007"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 0,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 1,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_locate = XtVaCreateManagedWidget(langcode("WPUPLSP005"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 3,
+                                      XmNrightOffset, 5,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_lookup, XmNactivateCallback, fcc_rac_lookup, locate_station_dialog);
+        XtAddCallback(button_locate, XmNactivateCallback, Locate_station_now, locate_station_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Locate_station_destroy_shell, locate_station_dialog);
+
+        XmToggleButtonSetState(locate_case_data,FALSE,FALSE);
+        XmToggleButtonSetState(locate_match_data,TRUE,FALSE);
+
+        XmTextFieldSetString(locate_station_data,locate_station_call);
+
+        pos_dialog(locate_station_dialog);
+
+        delw = XmInternAtom(XtDisplay(locate_station_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(locate_station_dialog, delw, Locate_station_destroy_shell, (XtPointer)locate_station_dialog);
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+end_critical_section(&locate_station_dialog_lock, "locate_gui.c:Locate_station" );
+
+        XtPopup(locate_station_dialog,XtGrabNone);
+        fix_dialog_size(locate_station_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(locate_station_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    }
+    else {
+        (void)XRaiseWindow(XtDisplay(locate_station_dialog), XtWindow(locate_station_dialog));
+    }
+}
+
+
+
+
+
+/*******************************************************************/
+/* Locate Place Chooser routines */
+
+
+
+/*
+ *  Locate Place Chooser PopUp window: Cancelled
+ */
+void Locate_place_chooser_destroy_shell(Widget widget, XtPointer clientData, XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+begin_critical_section(&locate_place_chooser_lock, "locate_gui.c:Locate_place_chooser_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    locate_place_chooser = (Widget)NULL;
+
+end_critical_section(&locate_place_chooser_lock, "locate_gui.c:Locate_place_chooser_destroy_shell" );
+
+}
+
+
+
+
+
+/*
+ *  Locate Place Selection PopUp window: Map selected place
+ */
+void Locate_place_chooser_select(Widget widget,
+        XtPointer clientData,
+        XtPointer callData) {
+
+    int ii, xx;
+    char *temp;
+    XmString *list;
+    int found = 0;
+    int index = 0;
+
+begin_critical_section(&locate_place_chooser_lock, "locate_gui.c:Locate_place_chooser_select" );
+
+    if (locate_place_chooser) {
+        XtVaGetValues(locate_place_list,
+            XmNitemCount,
+            &ii,
+            XmNitems,
+            &list,
+            NULL);
+
+        for (xx=1; xx<=ii; xx++) {
+            if (XmListPosSelected(locate_place_list, xx)) {
+                found = 1;
+                index = xx;
+                if (XmStringGetLtoR(list[(xx-1)], XmFONTLIST_DEFAULT_TAG, &temp))
+                    xx=ii+1;
+            }
+        }
+
+        if (found) {
+
+            // Center the map at the chosen location
+            set_map_position(widget,
+                match_array_lat[index-1],
+                match_array_long[index-1]);
+
+            XtFree(temp);
+        }
+    }
+
+end_critical_section(&locate_place_chooser_lock, "locate_gui.c:Locate_place_chooser_select" );
+
+}
+
+
+
+
+
+void Locate_place_chooser(/*@unused@*/ Widget widget,
+        XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+
+    Widget pane, form, button_ok, button_cancel;
+    Arg al[50];
+    register unsigned int ac = 0;
+    int ii, nn;
+    XmString str_ptr;
+    Atom delw;
+
+
+    if (locate_place_chooser != NULL)
+        Locate_place_chooser_destroy_shell(locate_place_chooser, locate_place_chooser, NULL);
+
+begin_critical_section(&locate_place_chooser_lock, "locate_gui.c:Locate_place_chooser");
+
+    if (locate_place_chooser == NULL) {
+
+        // Set up a selection box:
+        locate_place_chooser = XtVaCreatePopupShell(langcode("WPUPCFS028"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNbackground, colors[0xff],
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Locate_place_chooser pane",xmPanedWindowWidgetClass, locate_place_chooser,
+            XmNbackground, colors[0xff],
+            NULL);
+
+        form =  XtVaCreateWidget("Locate_place_chooser form",xmFormWidgetClass, pane,
+            XmNfractionBase, 5,
+            XmNbackground, colors[0xff],
+            XmNautoUnmanage, FALSE,
+            XmNshadowThickness, 1,
+            NULL);
+
+
+        // Attach buttons first to the bottom of the form,
+        // so that we'll be able to stretch this thing
+        // vertically to see all of the entries.
+        //
+        button_ok = XtVaCreateManagedWidget(langcode("WPUPCFS028"),xmPushButtonGadgetClass, form,
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_POSITION,
+            XmNleftPosition, 1,
+            XmNrightAttachment, XmATTACH_POSITION,
+            XmNrightPosition, 2,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNfontList, fontlist1,
+            NULL);
+
+        XtAddCallback(button_ok,
+            XmNactivateCallback,
+            Locate_place_chooser_select,
+            locate_place_chooser);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, form,
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_POSITION,
+            XmNleftPosition, 3,
+            XmNrightAttachment, XmATTACH_POSITION,
+            XmNrightPosition, 4,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNfontList, fontlist1,
+            NULL);
+
+        XtAddCallback(button_cancel,
+            XmNactivateCallback,
+            Locate_place_chooser_destroy_shell,
+            locate_place_chooser);
+
+        // set args for color
+        ac = 0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+        XtSetArg(al[ac], XmNvisibleItemCount, 6); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
+        XtSetArg(al[ac], XmNbottomWidget, button_ok); ac++;
+        XtSetArg(al[ac], XmNbottomOffset, 5); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        locate_place_list = XmCreateScrolledList(form,"Locate_place_chooser list",al,ac);
+
+        nn = 1;
+        for (ii = 0; ii < match_quantity; ii++) {
+            XmListAddItem(locate_place_list,
+                str_ptr = XmStringCreateLtoR(match_array_name[ii],
+                XmFONTLIST_DEFAULT_TAG),
+                (int)nn++);
+            XmStringFree(str_ptr);
+        }
+
+        pos_dialog(locate_place_chooser);
+
+        delw = XmInternAtom(XtDisplay(locate_place_chooser),
+            "WM_DELETE_WINDOW",
+            FALSE);
+
+        XmAddWMProtocolCallback(locate_place_chooser,
+            delw,
+            Locate_place_chooser_destroy_shell,
+            (XtPointer)locate_place_chooser);
+
+        XtManageChild(form);
+        XtManageChild(locate_place_list);
+        XtVaSetValues(locate_place_list, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+        XtPopup(locate_place_chooser,XtGrabNone);
+
+        // Move focus to the Cancel button.  This appears to
+        // highlight t
+        // button fine, but we're not able to hit the
+        // <Enter> key to
+        // have that default function happen.  Note:  We
+        // _can_ hit the
+        // <SPACE> key, and that activates the option.
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+    }
+
+end_critical_section(&locate_place_chooser_lock, "locate_gui.c:Locate_place_chooser" );
+
+}
+/*******************************************************************/
+ 
+
+
+
+
+/**** LOCATE PLACE ******/
+
+void Locate_place_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&locate_place_dialog_lock, "locate_gui.c:Locate_place_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    locate_place_dialog = (Widget)NULL;
+
+end_critical_section(&locate_place_dialog_lock, "locate_gui.c:Locate_place_destroy_shell" );
+
+}
+
+
+
+
+
+/*
+ *  Locate a place by centering the map at its position
+ */
+void Locate_place_now(Widget w, XtPointer clientData, XtPointer callData) {
+    char *temp_ptr;
+//    int ii;
+
+
+    /* find place and go there */
+    temp_ptr = XmTextFieldGetString(locate_place_data);
+    xastir_snprintf(locate_place_name,
+        sizeof(locate_place_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(locate_state_data);
+    xastir_snprintf(locate_state_name,
+        sizeof(locate_state_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(locate_county_data);
+    xastir_snprintf(locate_county_name,
+        sizeof(locate_county_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(locate_quad_data);
+    xastir_snprintf(locate_quad_name,
+        sizeof(locate_quad_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(locate_type_data);
+    xastir_snprintf(locate_type_name,
+        sizeof(locate_type_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(locate_gnis_file_data);
+    xastir_snprintf(locate_gnis_filename,
+        sizeof(locate_gnis_filename),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(locate_place_name);
+    (void)remove_trailing_spaces(locate_state_name);
+    (void)remove_trailing_spaces(locate_county_name);
+    (void)remove_trailing_spaces(locate_quad_name);
+    (void)remove_trailing_spaces(locate_type_name);
+
+    /*fprintf(stderr,"looking for %s\n",locate_place_name);*/
+
+    match_quantity = gnis_locate_place(da, locate_place_name,
+        locate_state_name, locate_county_name, locate_quad_name,
+        locate_type_name, locate_gnis_filename,
+        (int)XmToggleButtonGetState(locate_place_case_data),
+        (int)XmToggleButtonGetState(locate_place_match_data),
+        match_array_name, match_array_lat, match_array_long);
+
+    if (0 == match_quantity) // Try population centers.
+	    match_quantity = pop_locate_place(da, locate_place_name,
+        	locate_state_name, locate_county_name, locate_quad_name,
+        	locate_type_name, locate_gnis_filename,
+		(int)XmToggleButtonGetState(locate_place_case_data),
+       		(int)XmToggleButtonGetState(locate_place_match_data),
+        	match_array_name, match_array_lat, match_array_long);
+
+    if (match_quantity) {
+        // Found some matches!
+
+        // Have a Chooser dialog if more than one match is found,
+        // plus the associated callbacks.  Don't center the map
+        // unless the user chooses one of the matches.  Leave the
+        // chooser dialog up so that the user can click on the
+        // matches one at a time until the correct one is found,
+        // then he/she can hit the Close button on that dialog to
+        // make it go away.
+
+        // Bring up a chooser dialog with the results from the
+        // match_array and a close button.  Allow the user to choose
+        // which one to center the map to.  Could also allow the
+        // user to find out more about each match if we fill the
+        // array with more data from the GNIS file.
+
+// Debug:  Print out the contents of the match arrays.
+//fprintf(stderr,"Found %d matches!\n", match_quantity);
+
+/*
+set_dangerous("printing");
+for (ii = 0; ii < match_quantity; ii++) {
+    fprintf(stderr,
+        "%d, %s, %ld, %ld\n",
+        ii,
+        match_array_name[ii],
+        match_array_lat[ii],
+        match_array_long[ii]);
+}
+clear_dangerous();
+*/
+
+        // This one pops up the names of whatever we found.
+        // "Found It!"
+        //popup_message_always( langcode("POPEM00029"), match_array_name[0]);
+
+        // Bring up the new Chooser dialog
+        (void)Locate_place_chooser(w, clientData, callData);
+    }
+    else {
+        // No matches found.
+        popup_message_always(langcode("POPEM00025"),locate_place_name);
+    }
+
+    Locate_place_destroy_shell(w, clientData, callData);
+}
+
+
+
+
+
+void Locate_place(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget pane, form, button_ok, button_cancel, sep,
+        place, state, county, quad, place_type, gnis_file;
+    Atom delw;
+
+    if (!locate_place_dialog) {
+
+begin_critical_section(&locate_place_dialog_lock, "locate_gui.c:Locate_place" );
+
+        locate_place_dialog = XtVaCreatePopupShell(langcode("PULDNMP014"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Locate_place pane",xmPanedWindowWidgetClass, locate_place_dialog,
+                XmNbackground, colors[0xff],
+                NULL);
+
+        form =  XtVaCreateWidget("Locate_place form",xmFormWidgetClass, pane,
+                XmNfractionBase, 2,
+                XmNbackground, colors[0xff],
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                NULL);
+
+        place = XtVaCreateManagedWidget(langcode("FEATURE001"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_place_data = XtVaCreateManagedWidget("Locate_place_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 32,
+                XmNwidth, ((32*7)+2),
+                XmNmaxLength, 30,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, place,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        state = XtVaCreateManagedWidget(langcode("FEATURE002"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, place,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_state_data = XtVaCreateManagedWidget("Locate_state_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 4,
+                XmNwidth, ((4*7)+2),
+                XmNmaxLength, 2,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, place,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, state,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        county = XtVaCreateManagedWidget(langcode("FEATURE003"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, state,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_county_data = XtVaCreateManagedWidget("Locate_county_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 32,
+                XmNwidth, ((32*7)+2),
+                XmNmaxLength, 30,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, state,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, county,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        quad = XtVaCreateManagedWidget(langcode("FEATURE004"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, county,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_quad_data = XtVaCreateManagedWidget("Locate_quad_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 32,
+                XmNwidth, ((32*7)+2),
+                XmNmaxLength, 30,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, county,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, quad,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        place_type = XtVaCreateManagedWidget(langcode("FEATURE005"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, quad,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_type_data = XtVaCreateManagedWidget("Locate_type_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 32,
+                XmNwidth, ((32*7)+2),
+                XmNmaxLength, 30,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, quad,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, place_type,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        gnis_file = XtVaCreateManagedWidget(langcode("FEATURE006"),xmLabelWidgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, place_type,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_gnis_file_data = XtVaCreateManagedWidget("locate_gnis_file_data", xmTextFieldWidgetClass, form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 40,
+                XmNwidth, ((40*7)+2),
+                XmNmaxLength, 199,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, place_type,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, gnis_file,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        locate_place_case_data  = XtVaCreateManagedWidget(langcode("WPUPLSP003"),xmToggleButtonWidgetClass,form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, gnis_file,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        locate_place_match_data  = XtVaCreateManagedWidget(langcode("WPUPLSP004"),xmToggleButtonWidgetClass,form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, gnis_file,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget,locate_place_case_data,
+                XmNleftOffset ,20,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNbackground, colors[0xff],
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sep = XtVaCreateManagedWidget("Locate_place sep", xmSeparatorGadgetClass,form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,locate_place_case_data,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNbackground, colors[0xff],
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("WPUPLSP005"),xmPushButtonGadgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNbackground, colors[0xff],
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 5,
+                XmNbackground, colors[0xff],
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Locate_place_now, locate_place_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Locate_place_destroy_shell, locate_place_dialog);
+
+        XmToggleButtonSetState(locate_place_case_data,FALSE,FALSE);
+        XmToggleButtonSetState(locate_place_match_data,FALSE,FALSE);
+//        XtSetSensitive(locate_place_match_data,FALSE);
+
+        XmTextFieldSetString(locate_place_data,locate_place_name);
+        XmTextFieldSetString(locate_state_data,locate_state_name);
+        XmTextFieldSetString(locate_county_data,locate_county_name);
+        XmTextFieldSetString(locate_quad_data,locate_quad_name);
+        XmTextFieldSetString(locate_type_data,locate_type_name);
+        XmTextFieldSetString(locate_gnis_file_data,locate_gnis_filename);
+
+        pos_dialog(locate_place_dialog);
+
+        delw = XmInternAtom(XtDisplay(locate_place_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(locate_place_dialog, delw, Locate_place_destroy_shell, (XtPointer)locate_place_dialog);
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+end_critical_section(&locate_place_dialog_lock, "locate_gui.c:Locate_place" );
+
+        XtPopup(locate_place_dialog,XtGrabNone);
+        fix_dialog_size(locate_place_dialog);
+
+        // Move focus to the Locate Now! button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(locate_place_dialog);
+        XmProcessTraversal(button_ok, XmTRAVERSE_CURRENT);
+
+    } else {
+        (void)XRaiseWindow(XtDisplay(locate_place_dialog), XtWindow(locate_place_dialog));
+    }
+}
+
+
diff --git a/src/location.c b/src/location.c
new file mode 100644
index 0000000..5321dd3
--- /dev/null
+++ b/src/location.c
@@ -0,0 +1,104 @@
+/*
+ * $Id: location.c,v 1.16 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <netinet/in.h>
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "track_gui.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+static long last_center_longitude;     // remember last screen settings
+static long last_center_latitude;
+static long last_scale_x;
+static long last_scale_y;
+
+
+/***********************************************************/
+/* set last map position                                   */
+/* store lat long and zoom                                 */
+/***********************************************************/
+void set_last_position(void) {
+    last_center_longitude=center_longitude;
+    last_center_latitude=center_latitude;
+    last_scale_x = scale_x;     // we don't restore this...
+    last_scale_y = scale_y;
+}
+
+
+
+/***********************************************************/
+/* reset map to last position                              */
+/*                                                         */
+/***********************************************************/
+void map_pos_last_position(void) {
+
+    map_pos(last_center_latitude,last_center_longitude,last_scale_y);
+}
+
+
+
+/***********************************************************/
+/* Jump map to position                                    */
+/*                                                         */
+/***********************************************************/
+void map_pos(long mid_y, long mid_x, long sz) {
+    // see also set_map_position() in db.c
+
+    // Set interrupt_drawing_now because conditions have changed
+    // (new map center).
+    interrupt_drawing_now++;
+
+    set_last_position();
+    center_longitude = mid_x;
+    center_latitude  = mid_y;
+    scale_y = sz;
+    scale_x = get_x_scale(mid_x,mid_y,scale_y);
+    setup_in_view();  // flag all stations in screen view
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+    
+//    if (create_image(da)) {
+//        // We don't care whether or not this succeeds?
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//        display_zoom_status();
+//    }
+}
+
diff --git a/src/location_gui.c b/src/location_gui.c
new file mode 100644
index 0000000..fffc64e
--- /dev/null
+++ b/src/location_gui.c
@@ -0,0 +1,592 @@
+/*
+ * $Id: location_gui.c,v 1.26 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "xa_config.h"
+#include "util.h"
+#include "lang.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+Widget location_dialog = (Widget)NULL;
+Widget location_list;
+
+static xastir_mutex location_dialog_lock;
+
+
+
+
+
+void location_gui_init(void)
+{
+    init_critical_section( &location_dialog_lock );
+}
+
+
+
+
+
+/************************************************/
+/* button fuction for last location             */
+/************************************************/
+void Last_location(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    map_pos_last_position();
+}
+
+
+
+
+
+/************************************************/
+/* manage jump locations                        */
+/************************************************/
+void location_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&location_dialog_lock, "location_gui.c:location_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    location_dialog = (Widget)NULL;
+
+end_critical_section(&location_dialog_lock, "location_gui.c:location_destroy_shell" );
+
+}
+
+
+
+
+
+/************************************************/
+/* jump to chosen location/zoom                 */
+/************************************************/
+void location_view(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int i,x;
+    char *location;
+    XmString *list;
+    int found,done;
+    FILE *f;
+    char temp[200];
+    char name[100];
+    char pos[100];
+    char *temp_ptr;
+    char s_lat[20];
+    char s_long[20];
+    char s_sz[10];
+    char location_file_path[MAX_VALUE];
+
+    found=0;
+    XtVaGetValues(location_list,XmNitemCount,&i,XmNitems,&list,NULL);
+
+    for (x=1; x<=i;x++) {
+        if (XmListPosSelected(location_list,x)) {
+            found=1;
+            if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&location))
+                x=i+1;
+        }
+    }
+    get_user_base_dir("config/locations.sys", location_file_path, 
+                      sizeof(location_file_path));
+    if (found) {
+        f=fopen(location_file_path,"r");
+        if (f!=NULL) {
+            done=0;
+            while (!feof(f) & !done) {
+                (void)get_line(f,temp,200);
+                if (!feof(f) && strlen(temp)>8) {
+                    temp_ptr=strtok(temp,"|");  /* get the name */
+                    if (temp_ptr!=NULL) {
+                        xastir_snprintf(name,
+                            sizeof(name),
+                            "%s",
+                            temp);
+                        temp_ptr=strtok(NULL,"|");  /* get the pos */
+                        xastir_snprintf(pos,
+                            sizeof(pos),
+                            "%s",
+                            temp_ptr);
+                        if (strcmp(location,name)==0) {
+                            if (3 != sscanf(pos,"%19s %19s %9s", s_lat, s_long, s_sz)) {
+                                fprintf(stderr,"location_view:sscanf parsing error\n");
+                            }
+                            map_pos(convert_lat_s2l(s_lat),convert_lon_s2l(s_long),atol(s_sz));
+                            done=1;
+                        }
+                    }
+                }
+            }
+            (void)fclose(f);
+        }
+        else {
+            fprintf(stderr,"Couldn't open file: %s\n", location_file_path );
+        }
+        XtFree(location);
+    }
+}
+
+
+
+
+
+/************************************************/
+/* sort and jump locations                      */
+/************************************************/
+void jump_sort(void) {
+    char temp[200];
+    char name[100];
+    char *temp_ptr;
+    FILE *f;
+    char location_file_path[MAX_VALUE];
+    char location_db_file_path[MAX_VALUE];
+
+    get_user_base_dir("config/locations.sys", location_file_path, 
+                      sizeof(location_file_path));
+    get_user_base_dir("data/locations_db.dat", location_db_file_path, 
+                      sizeof(location_db_file_path));
+    f=fopen(location_file_path,"r");
+    if (f!=NULL) {
+        while (!feof(f)) {
+            (void)get_line(f,temp,200);
+            if (!feof(f) && strlen(temp)>8) {
+                temp_ptr=strtok(temp,"|");  /* get the name */
+                if (temp_ptr!=NULL) {
+                    xastir_snprintf(name,
+                        sizeof(name),
+                        "%s",
+                        temp);
+                    (void)sort_input_database(location_db_file_path,name,200);
+                }
+            }
+        }
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", location_file_path );
+}
+
+
+
+
+
+/************************************************/
+/* delete location/zoom                         */
+/************************************************/
+void location_delete(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int i,x;
+    char *location;
+    XmString *list;
+    int found,ok;
+    FILE *f,*fout;
+    char temp[200];
+    char name[100];
+    char pos[100];
+    char *temp_ptr;
+    char filen[400];
+    char filen_bak[400];
+    char location_file_path[MAX_VALUE];
+    char location_sys_path[MAX_VALUE];
+
+    get_user_base_dir("config/locations.sys", location_file_path, 
+                      sizeof(location_file_path));
+    get_user_base_dir("config/locations.sys-tmp", location_sys_path, 
+                      sizeof(location_sys_path));
+
+    found=0;
+    ok=0;
+    XtVaGetValues(location_list,XmNitemCount,&i,XmNitems,&list,NULL);
+
+    for (x=1; x<=i;x++) {
+        if (XmListPosSelected(location_list,x)) {
+            found=1;
+            if (XmStringGetLtoR(list[(x-1)],XmFONTLIST_DEFAULT_TAG,&location)) {
+                XmListDeletePos(location_list,x);
+                x=i+1;
+            }
+        }
+    }
+    if(found) {
+        f=fopen(location_file_path,"r");
+        if (f!=NULL) {
+            fout=fopen(location_sys_path,"a");
+            if (fout!=NULL) {
+                while (!feof(f)) {
+                    (void)get_line(f,temp,200);
+                    if (!feof(f) && strlen(temp)>8) {
+                        temp_ptr=strtok(temp,"|");  /* get the name */
+                        if (temp_ptr!=NULL) {
+                            xastir_snprintf(name,
+                                sizeof(name),
+                                "%s",
+                                temp);
+                            temp_ptr=strtok(NULL,"|");  /* get the pos */
+                            xastir_snprintf(pos,
+                                sizeof(pos),
+                                "%s",
+                                temp_ptr);
+                            if (strcmp(location,name)!=0) {
+                                fprintf(fout,"%s|%s\n",name,pos);
+                            }
+                        }
+                    }
+                }
+                (void)fclose(fout);
+                ok=1;
+            }
+            else
+              fprintf(stderr,"Couldn't open file: %s\n", location_sys_path );
+
+            (void)fclose(f);
+        }
+        else {
+            fprintf(stderr,"Couldn't open file: %s\n", location_file_path );
+        }
+        XtFree(location);
+    }
+
+    if (ok==1){
+
+        xastir_snprintf(filen,
+            sizeof(filen),
+            "%s",
+            location_file_path);
+
+        xastir_snprintf(filen_bak,
+            sizeof(filen_bak),
+            "%s",
+            location_sys_path);
+
+        (void)unlink(filen);
+        (void)rename(filen_bak,filen);
+    }
+
+}
+
+
+
+
+
+/************************************************/
+/* add location/zoom                            */
+/************************************************/
+void location_add(/*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char name[100];
+    char s_long[20];
+    char s_lat[20];
+    FILE *f, *fout;
+    char temp[200];
+    char *temp_ptr;
+    Widget my_text = (Widget) clientData;
+    int len,n,found;
+    char location_file_path[MAX_VALUE];
+    char location_db_path[MAX_VALUE];
+
+    get_user_base_dir("config/locations.sys", location_file_path, 
+                      sizeof(location_file_path));
+
+    get_user_base_dir("data/locations_db.dat", location_db_path, 
+                      sizeof(location_db_path));
+
+
+    temp_ptr = XmTextFieldGetString(my_text);
+    xastir_snprintf(name,
+        sizeof(name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(name);
+    XmTextFieldSetString(my_text,"");
+    /* should check for name used already */
+    found=0;
+    f=fopen(location_file_path,"r");
+    if (f!=NULL) {
+        while (!feof(f) && !found) {
+            (void)get_line(f,temp,200);
+            if (!feof(f) && strlen(temp)>8) {
+                temp_ptr=strtok(temp,"|");  /* get the name */
+                if (temp_ptr!=NULL) {
+                    if (strcmp(name,temp)==0)
+                        found=1;
+                }
+            }
+        }
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", location_file_path );
+
+    if (!found) {
+        /* delete entire list available */
+        XmListDeleteAllItems(location_list);
+        len = (int)strlen(name);
+        if (len>0 && len<100){
+            fout = fopen(location_file_path,"a");
+            if (fout!=NULL) {
+                convert_lat_l2s(center_latitude, s_lat, sizeof(s_lat), CONVERT_HP_NOSP);
+                convert_lon_l2s(center_longitude, s_long, sizeof(s_long), CONVERT_HP_NOSP);
+                fprintf(fout,"%s|%s %s %ld\n",name,s_lat,s_long,scale_y);
+                (void)fclose(fout);
+            }
+            else
+                fprintf(stderr,"Couldn't open file: %s\n", location_file_path );
+        } else
+            popup_message_always(langcode("POPEM00022"),langcode("POPEM00023"));
+
+        /* resort the list and put it back up */
+        n=1;
+        clear_sort_file(location_db_path);
+        jump_sort();
+        sort_list(location_db_path,200,location_list,&n);
+    } else
+        popup_message_always(langcode("POPEM00022"),langcode("POPEM00024")); /* dupe name */
+}
+
+
+
+
+
+/************************************************/
+/* manage jump locations                        */
+/************************************************/
+void Jump_location(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane,form, button_ok, button_add, button_delete, button_cancel, locdata, location_name;
+    int n;
+    Arg al[50];           /* Arg List */
+    unsigned int ac = 0;           /* Arg Count */
+    Atom delw;
+    char location_db_path[MAX_VALUE];
+
+    get_user_base_dir("data/locations_db.dat", location_db_path, 
+                      sizeof(location_db_path));
+
+    if(!location_dialog) {
+
+begin_critical_section(&location_dialog_lock, "location_gui.c:Jump_location" );
+
+        location_dialog = XtVaCreatePopupShell(langcode("JMLPO00001"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNresize, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Jump_location pane",
+                xmPanedWindowWidgetClass,
+                location_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        form =  XtVaCreateWidget("Jump_location form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNvisibleItemCount, 11); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNbackground, colors[0x0ff]); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+ 
+        location_list = XmCreateScrolledList(form,
+                "Jump_location list",
+                al,
+                ac);
+
+        n=1;
+        clear_sort_file(location_db_path);
+        jump_sort();
+        sort_list(location_db_path,200,location_list,&n);
+
+        locdata = XtVaCreateManagedWidget(langcode("JMLPO00003"),
+                xmLabelWidgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, XtParent(location_list),
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        location_name = XtVaCreateManagedWidget("Jump_location Location_name", 
+                xmTextFieldWidgetClass, 
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,      1,
+                XmNcolumns,21,
+                XmNwidth,((21*7)+2),
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, XtParent(location_list),
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget,locdata,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("JMLPO00002"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, locdata,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_add = XtVaCreateManagedWidget(langcode("UNIOP00007"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, locdata,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_delete = XtVaCreateManagedWidget(langcode("UNIOP00008"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, locdata,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, locdata,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 4,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 5,
+                XmNrightOffset, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, location_destroy_shell, location_dialog);
+        XtAddCallback(button_ok, XmNactivateCallback, location_view, NULL);
+        XtAddCallback(button_add, XmNactivateCallback, location_add, location_name);
+        XtAddCallback(button_delete, XmNactivateCallback, location_delete, NULL);
+
+        pos_dialog(location_dialog);
+
+        delw = XmInternAtom(XtDisplay(location_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(location_dialog, delw, location_destroy_shell, (XtPointer)location_dialog);
+
+        XtManageChild(form);
+        XtManageChild(location_list);
+        XtVaSetValues(location_list, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+end_critical_section(&location_dialog_lock, "location_gui.c:location_destroy_shell" );
+
+        XtPopup(location_dialog,XtGrabNone);
+        fix_dialog_size(location_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(location_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else {
+        XtPopup(location_dialog,XtGrabNone);
+        (void)XRaiseWindow(XtDisplay(location_dialog), XtWindow(location_dialog));
+    }
+}
+
+
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..90b7513
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,28028 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: main.c,v 1.810 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+
+// This is for debug.  If defined to 1, Xastir will display
+// coordinates in the Xastir coordinate system inside the text2
+// widget.
+//
+static int DISPLAY_XASTIR_COORDINATES = 0;
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <signal.h>
+#include <termios.h>
+#include <pwd.h>
+#include <locale.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <sys/wait.h>
+#include <errno.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+// TVR -- stupid, stupid ImageMagick
+char *xastir_package=PACKAGE;
+char *xastir_version=VERSION;
+#undef PACKAGE
+#undef VERSION
+
+#ifdef HAVE_MAGICK
+#include <sys/types.h>
+#undef RETSIGTYPE
+/* JMT - stupid ImageMagick */
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#include <magick/api.h>
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#endif // HAVE_MAGICK
+
+#ifdef  HAVE_LIBINTL_H
+#include <libintl.h>
+#define _(x)        gettext(x)
+#else   // HAVE_LIBINTL_H
+#define _(x)        (x)
+#endif  // HAVE_LIBINTL_H
+
+//#ifdef HAVE_NETAX25_AXLIB_H
+//#include <netax25/axlib.h>
+//#endif    // HAVE_NETAX25_AXLIB_H
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif
+
+#ifdef HAVE_LIBGDAL
+// WE7U - stupid ImageMagick
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#include <ogr_api.h>
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#include <gdal.h>
+#endif
+
+#include "xastir.h"
+#include "draw_symbols.h"
+#include "main.h"
+#include "xa_config.h"
+#include "maps.h"
+#include "alert.h"
+#include "interface.h"
+#include "wx.h"
+#include "popup.h"
+#include "track_gui.h"
+#include "list_gui.h"
+#include "util.h"
+#include "color.h"
+#include "gps.h"
+#include "bulletin_gui.h"
+#include "rotated.h"
+#include "datum.h"
+#include "igate.h"
+#include "objects.h"
+#include "db_gis.h"
+
+#include "map_OSM.h"
+
+#ifdef HAVE_LIBSHP
+  #include "shp_hash.h"
+#endif  // HAVE_LIBSHP
+
+#include "x_spider.h"
+#include "map_cache.h"
+
+#include <Xm/XmAll.h>
+#include <X11/cursorfont.h>
+#include <Xm/ComboBox.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+// Copyright 2008.
+// Added the above "Copyright" just so that grep would find these
+// lines and we could update the years in the Help->About message
+// each time.  Otherwise it often gets missed when we're updating
+// the years.
+#define ABOUT_MSG "X Amateur Station Tracking and Information Reporting\n\n        http://www.xastir.org\n\nCopyright (C) 1999-2000  Frank Giannandrea\nCopyright (C) 1999-2012  The Xastir Group\nSee the \"LICENSE\" file for other applicable copyrights"
+
+// OpenStreetMap attribution
+#define ABOUT_OSM "Maps, tiles, and data from the OpenStreetMap project are\nCopyright OpenStreetMap and contributors, CC-BY-SA.\nMaps and tiles from CloudMade are Copyright CloudMade, CC-BY-SA.\n  http://www.openstreetmap.org/\n  http://creativecommons.org/licenses/by-sa/2.0/\n  http://www.cloudmade.com/\n"
+
+
+// Define this if you want an xastir.pid file created in the
+// ~/.xastir directory and want to check that there's not another
+// copy of Xastir running before a new one starts up.  You can also
+// use this to send SIGHUP or SIGUSR1 signals to a running Xastir
+// from scripts.
+#define USE_PID_FILE_CHECK 1
+
+
+#define DOS_HDR_LINES 8
+
+#define STATUSLINE_ACTIVE 10    /* status line is cleared after 10 seconds */
+#define REPLAY_DELAY       0    /* delay between replayed packets in sec, 0 is ok */
+#define REDRAW_WAIT        3    /* delay between consecutive redraws in seconds (file load) */
+
+
+
+// FONTS FONTS FONTS FONTS FONTS
+//
+// NOTE:  See the main() function at the bottom of this module for
+// the default font definition.  xa_config.c is where fonts get
+// saved/restored for user-defined fonts.
+// This one is not used anymore:
+//#define XmFONTLIST_DEFAULT_MY "-misc-fixed-*-r-*-*-10-*-*-*-*-*-*-*"
+
+
+// This one goes right along with smaller system fonts on fixed-size
+// LCD screens.  Fix new dialogs to the upper left of the main
+// window, don't have them cycle through multiple possible positions
+// as each new dialog is drawn.
+//
+//#define FIXED_DIALOG_STARTUP
+
+// Yet another useful item:  Puts the mouse menu on button 1 instead
+// of button3.  Useful for one-button devices like touchscreens.
+//
+//#define SWAP_MOUSE_BUTTONS
+ 
+// If next line uncommented, Xastir will display the status line
+// in 2 rows instead of the normal single row.  Formatted especially
+// for 640 pixel wide screens.  It also gives a little extra room for 
+// the number of stations and the Zoom factor.
+// #define USE_TWO_STATUS_LINES
+
+// Enable this next line to set all flags properly for a 640x480
+// touch-screen:  Makes the main window smaller due to the reduced
+// font sizes, makes all dialogs come up at the upper-left of the
+// main Xastir screen, reverses buttons 1 and 3 so that the more
+// important mouse menus are accessible via the touch-screen, and
+// sets it for 2 status lines.  Make sure to change the system font
+// size smaller than the default.
+//
+//#define LCD640x480TOUCH
+//
+#ifdef LCD640x480TOUCH
+  #define FIXED_DIALOG_STARTUP
+  #define SWAP_MOUSE_BUTTONS
+  #define USE_TWO_STATUS_LINES
+#endif
+
+
+#define LINE_WIDTH 1
+
+#define ARROWS     1            // Arrow buttons on menubar
+
+// TVR 26 July 2005
+// Moved this magic number to a #define --- there were numerous places 
+// where this constant was hard coded, making it difficult to change the
+// map properties line format without breaking something.  Now it can live
+// in one place that needs to be updated when the properties line is changed.
+// At the time of writing, the properties line had the followign format:
+// min max lyr fil drg amap name
+// %5d %5d %5d %5c %5c %5c  %s
+// placing the name at offset 37
+#define MPD_FILENAME_OFFSET 37
+
+
+// Define the ICON, created with the "bitmap" editor:
+#include "icon.xbm"
+
+// lesstif (at least as of version 0.94 in 2008), doesn't
+// have full implementation of combo boxes.
+#ifndef USE_COMBO_BOX
+#if (XmVERSION >= 2 && !defined(LESSTIF_VERSION))
+#  define USE_COMBO_BOX 1
+#endif
+#endif  // USE_COMBO_BOX
+
+int geometry_x, geometry_y;
+unsigned int geometry_width, geometry_height;
+int geometry_flags;
+
+static int initial_load = 1;
+int first_time_run = 0;
+
+/* JMT - works under FreeBSD */
+uid_t euid;
+gid_t egid;
+
+
+int   my_argc;
+char **my_argv;
+char **my_envp;
+int  restart_xastir_now = 0;
+
+
+// A count of the stations currently on the screen.  Counted by
+// db.c:display_file() routine.
+int currently_selected_stations      = 0;
+int currently_selected_stations_save = 0;
+
+// If my_trail_diff_color is 0, all my calls (SSIDs) will use MY_TRAIL_COLOR.
+// If my_trail_diff_color = 1 then each different ssid for my callsign will use a different color.
+int my_trail_diff_color = 0;  
+
+
+// Used in segfault handler
+char dangerous_operation[200];
+
+FILE *file_wx_test;
+
+int tcp_server_pid = 0;
+int udp_server_pid = 0;
+
+int serial_char_pacing;  // Inter-char delay in ms for serial ports.
+int dtr_on = 1;
+time_t sec_last_dtr = (time_t)0;
+
+time_t last_updatetime = (time_t)0;
+int time_went_backwards = 0;
+
+/* language in use */
+char lang_to_use[30];
+
+/* version info in main.h */
+int  altnet;
+char altnet_call[MAX_CALLSIGN+1];
+
+static void Window_Quit(Widget w, XtPointer client, XtPointer call);
+static void save_state(Widget w, XtPointer client, XtPointer call);
+
+void da_input(Widget w, XtPointer client_data, XtPointer call_data);
+void da_resize(Widget w, XtPointer client_data, XtPointer call_data);
+void da_expose(Widget w, XtPointer client_data, XtPointer call_data);
+
+void BuildPredefinedSARMenu_UI(Widget *parent_menu);
+Widget *predefined_object_menu_parent;
+Widget sar_object_sub;
+Widget predefined_object_menu_items[MAX_NUMBER_OF_PREDEFINED_OBJECTS];
+
+int debug_level;
+
+//Widget hidden_shell;
+Widget appshell;
+Widget form;
+Widget da;
+Widget text;
+Widget text2;
+Widget text3;
+Widget text4;
+Widget log_indicator;
+Widget iface_da;
+Widget menubar;
+Widget toolbar;
+
+Widget configure_station_dialog     = (Widget)NULL;
+Widget right_menu_popup              = (Widget)NULL;    // Button one or left mouse button
+//Widget middle_menu_popup=(Widget)NULL;  // Button two or middle mouse button
+//Widget right_menu_popup=(Widget)NULL;   // Button three or right mouse button
+Widget trackme_button;
+Widget measure_button;
+Widget move_button;
+Widget cad_draw_button;
+
+Widget CAD_close_polygon_menu_item;
+
+int Station_transmit_type;
+int Igate_type;
+
+Widget Display_data_dialog  = (Widget)NULL;
+Widget Display_data_text;
+int Display_packet_data_type;
+int show_only_station_capabilities = 0;
+int Display_packet_data_mine_only = 0;
+
+Widget configure_defaults_dialog = (Widget)NULL;
+Widget configure_timing_dialog = (Widget)NULL;
+Widget configure_coordinates_dialog = (Widget)NULL;
+Widget coordinate_calc_button_ok = (Widget)NULL;
+Widget change_debug_level_dialog = (Widget)NULL;
+
+
+Widget coordinate_calc_dialog = (Widget)NULL;
+Widget coordinate_calc_zone = (Widget)NULL;
+Widget coordinate_calc_latitude_easting = (Widget)NULL;
+Widget coordinate_calc_longitude_northing = (Widget)NULL;
+Widget coordinate_calc_result_text = (Widget)NULL;
+static char coordinate_calc_lat_deg[5];
+static char coordinate_calc_lat_min[15];
+static char coordinate_calc_lat_dir[5];
+static char coordinate_calc_lon_deg[5];
+static char coordinate_calc_lon_min[15];
+static char coordinate_calc_lon_dir[5];
+coordinate_calc_array_type coordinate_calc_array;
+
+
+
+// --------------------------- help menu -----------------------------
+Widget help_list;
+Widget help_index_dialog = (Widget)NULL;
+Widget help_view_dialog  = (Widget)NULL;
+Widget emergency_beacon_toggle;
+int emergency_beacon = 0;
+static void Help_About(Widget w, XtPointer clientData, XtPointer callData);
+static void Help_Index(Widget w, XtPointer clientData, XtPointer callData);
+void  Emergency_beacon_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+
+// ----------------------------- map ---------------------------------
+Widget map_list;
+Widget map_properties_list;
+void map_index_update_temp_select(char *filename, map_index_record **current);
+void map_index_temp_select_clear(void);
+ 
+void map_chooser_fill_in (void);
+int map_chooser_expand_dirs = 0;
+
+void map_chooser_init (void);
+
+Widget map_chooser_dialog = (Widget)NULL;
+Widget map_chooser_button_ok = (Widget)NULL;
+Widget map_chooser_button_cancel = (Widget)NULL;
+ 
+Widget map_properties_dialog = (Widget)NULL;
+static void Map_chooser(Widget w, XtPointer clientData, XtPointer callData);
+Widget map_chooser_maps_selected_data = (Widget)NULL;
+int re_sort_maps = 1;
+
+#ifdef HAVE_MAGICK
+static void Config_tiger(Widget w, XtPointer clientData, XtPointer callData);
+#endif  // HAVE_MAGICK
+
+#ifdef HAVE_LIBGEOTIFF
+static void Config_DRG(Widget w, XtPointer clientData, XtPointer callData);
+#endif  // HAVE_LIBGEOTIFF
+
+Widget grid_on, grid_off;
+static void Grid_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+int long_lat_grid;              // Switch for Map Lat and Long grid display
+
+void Map_border_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData);
+int draw_labeled_grid_border = FALSE;   // Toggle labeled border around map.
+
+
+static void CAD_draw_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+
+int map_lock_pan_zoom = 0;
+static void Map_lock_pan_zoom_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+
+int disable_all_maps = 0;
+static void Map_disable_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Map_auto_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+int map_auto_maps;              /* toggle use of auto_maps */
+static void Map_auto_skip_raster_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+int auto_maps_skip_raster;
+Widget map_auto_skip_raster_button;
+Widget map_border_button;
+
+Widget map_levels_on, map_levels_off;
+static void Map_levels_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+int map_color_levels;           /* toggle use of map_color_levels */
+
+Widget map_labels_on, map_labels_off;
+static void Map_labels_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+int map_labels;                 // toggle use of map_labels */
+
+Widget map_fill_on, map_fill_off;
+static void Map_fill_toggle( Widget w, XtPointer clientData, XtPointer calldata);
+int map_color_fill;             /* Whether or not to fill in map polygons with solid color */
+
+int index_maps_on_startup;      // Index maps on startup
+static void Index_maps_on_startup_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+Widget map_bgcolor[12];
+static void Map_background(Widget w, XtPointer clientData, XtPointer calldata);
+int map_background_color;       /* Background color for maps */
+
+#if !defined(NO_GRAPHICS)
+Widget raster_intensity[11];
+static void Raster_intensity(Widget w, XtPointer clientData, XtPointer calldata);
+#if defined(HAVE_MAGICK)
+Widget gamma_adjust_dialog = (Widget)NULL;
+Widget gamma_adjust_text;
+#endif  // HAVE_MAGICK
+#endif  // NO_GRAPHICS
+
+Widget map_font_dialog = (Widget)NULL;
+Widget map_font_text[FONT_MAX];
+
+
+Widget map_station_label0,map_station_label1,map_station_label2;
+static void Map_station_label(Widget w, XtPointer clientData, XtPointer calldata);
+int letter_style;               /* Station Letter style */
+
+Widget map_icon_outline0,map_icon_outline1,map_icon_outline2,map_icon_outline3;
+static void Map_icon_outline(Widget w, XtPointer clientData, XtPointer calldata);
+int icon_outline_style;         /* Icon Outline style */
+
+Widget map_wx_alerts_0,map_wx_alerts_1;
+static void Map_wx_alerts_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+int wx_alert_style;             /* WX alert map style */
+time_t map_refresh_interval = 0; /* how often to refresh maps, seconds */
+time_t map_refresh_time = 0;     /* when to refresh maps next, seconds */
+
+// ------------------------ Filter and Display menus -----------------------------
+Selections Select_ = { 0, // none
+                       1, // mine
+                       1, // tnc
+                       1, // direct
+                       1, // via_digi
+                       1, // net
+                       0, // tactical only 
+                       1, // old_data
+
+                       1, // stations
+                       1, // fixed_stations
+                       1, // moving_stations
+                       1, // weather_stations
+                       1, // CWOP_wx_stations
+                       1, // objects
+                       1, // weather_objects
+                       1, // gauge_objects
+                       1, // other_objects
+};
+
+What_to_display Display_ = { 1, // callsign
+                             1, // label_all_trackpoints
+                             1, // symbol
+                             1, // symbol_rotate
+                             1, // trail
+
+                             1, // course
+                             1, // speed
+                             1, // speed_short
+                             1, // altitude
+
+                             1, // weather
+                             1, // weather_text
+                             1, // temperature_only
+                             1, // wind_barb
+
+                             1, // aloha_circle
+                             1, // ambiguity
+                             1, // phg
+                             1, // default_phg
+                             1, // phg_of_moving
+
+                             1, // df_data
+                             1, // df_beamwidth_data
+                             1, // df_bearing_data
+                             1, // dr_data
+                             1, // dr_arc
+                             1, // dr_course
+                             1, // dr_symbol
+
+                             1, // dist_bearing
+                             1, // last_heard
+};
+
+Widget select_none_button;
+Widget select_mine_button;
+Widget select_tnc_button;
+Widget select_direct_button;
+Widget select_via_digi_button;
+Widget select_net_button;
+Widget select_tactical_button;
+Widget select_old_data_button;
+
+Widget select_stations_button;
+Widget select_fixed_stations_button;
+Widget select_moving_stations_button;
+Widget select_weather_stations_button;
+Widget select_CWOP_wx_stations_button;
+Widget select_objects_button;
+Widget select_weather_objects_button;
+Widget select_gauge_objects_button;
+Widget select_other_objects_button;
+
+
+Widget display_callsign_button;
+Widget display_label_all_trackpoints_button;
+Widget display_symbol_button;
+Widget display_symbol_rotate_button;
+Widget display_trail_button;
+
+Widget display_course_button;
+Widget display_speed_button;
+Widget display_speed_short_button;
+Widget display_altitude_button;
+
+Widget display_weather_button;
+Widget display_weather_text_button;
+Widget display_temperature_only_button;
+Widget display_wind_barb_button;
+
+Widget display_aloha_circle_button;
+Widget display_ambiguity_button;
+Widget display_phg_button;
+Widget display_default_phg_button;
+Widget display_phg_of_moving_button;
+
+Widget display_df_data_button;
+Widget display_df_beamwidth_data_button;
+Widget display_df_bearing_data_button;
+Widget display_dr_data_button;
+Widget display_dr_arc_button;
+Widget display_dr_course_button;
+Widget display_dr_symbol_button;
+
+Widget display_dist_bearing_button;
+Widget display_last_heard_button;
+
+
+static void Select_none_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_mine_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_tnc_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_direct_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_via_digi_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_net_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_tactical_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_old_data_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Select_stations_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_fixed_stations_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_moving_stations_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_weather_stations_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_CWOP_wx_stations_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_objects_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_weather_objects_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_other_objects_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Select_gauge_objects_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+
+static void Display_callsign_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_label_all_trackpoints_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_symbol_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_symbol_rotate_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_trail_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Display_course_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_speed_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_speed_short_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_altitude_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Display_weather_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_weather_text_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_temperature_only_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_wind_barb_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Display_aloha_circle_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_ambiguity_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_phg_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_default_phg_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_phg_of_moving_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Display_df_data_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_df_beamwidth_data_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_df_bearing_data_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_dr_data_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_dr_arc_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_dr_course_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_dr_symbol_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Display_dist_bearing_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void Display_last_heard_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+
+// ------------------------ Interfaces --------------------------
+static void  Transmit_disable_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+static void  Posit_tx_disable_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+static void  Object_tx_disable_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+static void  Server_port_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+int transmit_disable;
+int posit_tx_disable;
+int object_tx_disable;
+int enable_server_port = 0;
+Widget iface_transmit_now, posit_tx_disable_toggle, object_tx_disable_toggle;
+Widget server_port_toggle;
+
+#ifdef HAVE_GPSMAN
+Widget Fetch_gps_track, Fetch_gps_route, Fetch_gps_waypoints;
+Widget Fetch_RINO_waypoints;
+Widget Send_gps_track, Send_gps_route, Send_gps_waypoints;
+int gps_got_data_from = 0;          // We got data from a GPS
+int gps_operation_pending = 0;      // A GPS transfer is happening
+int gps_details_selected = 0;       // Whether name/color have been selected yet
+Widget gpsfilename_text;            // Short name of gps map (no color/type)
+char gps_map_filename[MAX_FILENAME];// Chosen name of gps map (including color)
+char gps_map_filename_base[MAX_FILENAME];   // Same minus ".shp"
+char gps_map_filename_base2[MAX_FILENAME];   // Same minus ".shp" and color
+char gps_temp_map_filename[MAX_FILENAME];
+char gps_temp_map_filename_base[MAX_FILENAME];  // Same minus ".shp"
+char gps_dbfawk_format[]="BEGIN_RECORD {key=\"\"; lanes=3; color=%d; name=\"%s\"; filled=0; pattern=1; display_level=65536; label_level=128; label_color=8; symbol=\"\"}\n";
+int gps_map_color = 0;              // Chosen color of gps map
+int gps_map_color_offset;           // offset into colors array of that color.
+char gps_map_type[30];              // Type of GPS download
+void check_for_new_gps_map(int curr_sec);
+Widget GPS_operations_dialog = (Widget)NULL;
+#endif  // HAVE_GPSMAN
+
+// ------------------------ unit conversion --------------------------
+static void Units_choice_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+// 0: metric, 1: english, (2: nautical, not fully implemented)
+int english_units;
+
+char un_alt[2+1];   // m / ft
+char un_dst[2+1];   // mi / km      (..nm)
+char un_spd[4+1];   // mph / km/h   (..kn)
+double cvt_m2len;   // from meter
+double cvt_kn2len;  // from knots
+double cvt_mi2len;  // from miles
+double cvt_dm2len;  // from decimeter
+double cvt_hm2len;  // from hectometer
+
+void update_units(void);
+
+// dist/bearing on status line
+static void Dbstatus_choice_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+int do_dbstatus;
+
+
+// Coordinate System
+int coordinate_system = USE_DDMMMM; // Default, used for most APRS systems
+
+
+// ------------------------- audio alarms ----------------------------
+Widget configure_audio_alarm_dialog = (Widget)NULL;
+Widget audio_alarm_config_play_data,
+       audio_alarm_config_play_on_new_station, audio_alarm_config_play_ons_data,
+       audio_alarm_config_play_on_new_message, audio_alarm_config_play_onm_data,
+       audio_alarm_config_play_on_prox, audio_alarm_config_play_onpx_data,
+       audio_alarm_config_play_on_bando, audio_alarm_config_play_onbo_data,
+       prox_min_data, prox_max_data, bando_min_data, bando_max_data,
+       audio_alarm_config_play_on_wx_alert, audio_alarm_config_wx_alert_data;
+static void Configure_audio_alarms(Widget w, XtPointer clientData, XtPointer callData);
+
+// ---------------------------- speech -------------------------------
+Widget configure_speech_dialog      = (Widget)NULL;
+Widget speech_config_play_on_new_station,
+       speech_config_play_on_new_message_alert,
+       speech_config_play_on_new_message_body,
+       speech_config_play_on_prox,
+       speech_config_play_on_trak,
+       speech_config_play_on_bando,
+       speech_config_play_on_new_wx_alert;
+
+static void Configure_speech(Widget w, XtPointer clientData, XtPointer callData);
+
+//#ifdef HAVE_FESTIVAL
+/* WARNING - new station is initialized to FALSE for a reason            */
+/* If you're tempted to make it something that can be saved and restored */
+/* beware, Speech cannot keep up with the initial flow of data from an   */
+/* Internet connection that has buffered data. An unbuffered connection  */
+/* yes, but not a buffered one.  Ken,  N7IPB                             */
+int festival_speak_new_station = FALSE;
+int festival_speak_proximity_alert;
+int festival_speak_tracked_proximity_alert;
+int festival_speak_band_opening;
+int festival_speak_new_message_alert;
+int festival_speak_new_message_body;
+int festival_speak_new_weather_alert;
+int festival_speak_ID;
+//#endif    // HAVE_FESTIVAL
+int ATV_screen_ID;
+
+#ifdef HAVE_MAGICK //N0VH
+Widget configure_tiger_dialog = (Widget) NULL;
+Widget tiger_cities,
+       tiger_grid,
+       tiger_counties,
+       tiger_majroads,
+       tiger_places,
+       tiger_railroad,
+       tiger_streets,
+       tiger_interstate,
+       tiger_statehwy,
+       tiger_states,
+       tiger_ushwy,
+       tiger_water,
+       tiger_lakes,
+       tiger_misc;
+
+int tiger_show_grid = TRUE;
+int tiger_show_counties = TRUE;
+int tiger_show_cities = TRUE;
+int tiger_show_places = TRUE;
+int tiger_show_majroads = TRUE;
+int tiger_show_streets = FALSE;
+int tiger_show_railroad = TRUE;
+int tiger_show_states = FALSE;
+int tiger_show_interstate = TRUE;
+int tiger_show_ushwy = TRUE;
+int tiger_show_statehwy = TRUE;
+int tiger_show_water = TRUE;
+int tiger_show_lakes = TRUE;
+int tiger_show_misc = TRUE;
+#endif  // HAVE_MAGICK
+
+
+#ifdef HAVE_LIBGEOTIFF
+Widget configure_DRG_dialog = (Widget) NULL;
+Widget DRG_XOR,
+       DRG_color0,
+       DRG_color1,
+       DRG_color2,
+       DRG_color3,
+       DRG_color4,
+       DRG_color5,
+       DRG_color6,
+       DRG_color7,
+       DRG_color8,
+       DRG_color9,
+       DRG_color10,
+       DRG_color11,
+       DRG_color12;
+
+int DRG_XOR_colors = 0;
+int DRG_show_colors[13];
+#endif  // HAVE_LIBGEOTIFF
+
+
+// -------------------------------------------------------------------
+
+
+Widget read_selection_dialog = (Widget)NULL;
+
+// config station values
+Widget station_config_call_data, station_config_slat_data_deg, station_config_slat_data_min,
+       station_config_slat_data_ns, station_config_slong_data_deg, station_config_slong_data_min,
+       station_config_slong_data_ew, station_config_group_data, station_config_symbol_data,
+       station_config_icon, station_config_comment_data;
+Pixmap CS_icon0, CS_icon;
+
+/* defaults*/
+#ifdef TRANSMIT_RAW_WX
+Widget raw_wx_tx;
+#endif  // TRANSMIT_RAW_WX
+Widget compressed_posit_tx;
+Widget compressed_objects_items_tx;
+Widget new_bulletin_popup_enable;
+Widget zero_bulletin_popup_enable;
+Widget warn_about_mouse_modifiers_enable;
+Widget my_trail_diff_color_enable;
+Widget load_predefined_objects_menu_from_file_enable;
+#ifdef USE_COMBO_BOX
+Widget load_predefined_objects_menu_from_file; // combo box widget
+#else
+int lpomff_value;  // replacement value for predefined menu file combo box
+#endif // USE_COMBO_BOX
+int pop_up_new_bulletins = 0;
+int view_zero_distance_bulletins = 0;
+int warn_about_mouse_modifiers = 1;
+Widget altnet_active;
+Widget altnet_text;
+Widget disable_dupe_check;
+Widget new_map_layer_text = (Widget)NULL;
+Widget new_max_zoom_text = (Widget)NULL;
+Widget new_min_zoom_text = (Widget)NULL;
+Widget debug_level_text;
+static int sec_last_dr_update = 0;
+
+
+FILE *f_xfontsel_pipe[FONT_MAX];
+int xfontsel_query = 0;
+
+
+// -------------------------------------------------------------------
+static void UpdateTime( XtPointer clientData, XtIntervalId id );
+void pos_dialog(Widget w);
+
+static void Zoom_in(Widget w, XtPointer clientData, XtPointer calldata);
+static void Zoom_in_no_pan(Widget w, XtPointer clientData, XtPointer calldata);
+static void Zoom_out(Widget w, XtPointer clientData, XtPointer calldata);
+static void Zoom_out_no_pan(Widget w, XtPointer clientData, XtPointer calldata);
+static void Zoom_level(Widget w, XtPointer clientData, XtPointer calldata);
+static void display_zoom_image(int recenter);
+static void Track_Me( Widget w, XtPointer clientData, XtPointer calldata);
+static void Measure_Distance( Widget w, XtPointer clientData, XtPointer calldata);
+
+static void SetMyPosition( Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Pan_ctr(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_up(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_up_less(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_down(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_down_less(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_left(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_left_less(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_right(Widget w, XtPointer clientData, XtPointer calldata);
+static void Pan_right_less(Widget w, XtPointer clientData, XtPointer calldata);
+void Center_Zoom(Widget w, XtPointer clientData, XtPointer calldata);
+void Go_Home(Widget w, XtPointer clientData, XtPointer calldata);
+int center_zoom_override = 0;
+Widget center_zoom_dialog = (Widget)NULL;
+Widget custom_zoom_dialog = (Widget)NULL;
+
+static void Menu_Quit(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void TNC_Logging_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+static void TNC_Transmit_now(Widget w, XtPointer clientData, XtPointer calldata);
+
+#ifdef HAVE_GPSMAN
+static void GPS_operations(Widget w, XtPointer clientData, XtPointer calldata);
+#endif  // HAVE_GPSMAN
+
+static void Net_Logging_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void IGate_Logging_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void Message_Logging_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void WX_Logging_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+static void WX_Alert_Logging_toggle(Widget w, XtPointer clientData, XtPointer calldata);
+
+void on_off_switch(int switchpos, Widget first, Widget second);
+void sel3_switch(int switchpos, Widget first, Widget second, Widget third);
+void sel4_switch(int switchpos, Widget first, Widget second, Widget third, Widget fourth);
+
+static void Configure_station(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Configure_defaults(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Configure_timing(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Configure_coordinates(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Stations_Clear(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Test(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Save_Config(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Read_File_Selection(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Display_data(Widget w, XtPointer clientData, XtPointer callData);
+
+static void Auto_msg_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+static void  Satellite_msg_ack_toggle( Widget widget, XtPointer clientData, XtPointer callData);
+
+Widget auto_msg_toggle;
+Widget satellite_msg_ack_toggle;
+Widget posamb0,posamb1,posamb2,posamb3,posamb4;
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/* GLOBAL DEFINES */
+GC gc=0;                // Used for drawing maps
+GC gc2=0;               // Used for drawing symbols
+GC gc_tint=0;           // Used for tinting maps & symbols
+GC gc_stipple=0;        // Used for drawing symbols
+GC gc_bigfont=0;
+Pixmap  pixmap;
+Pixmap  pixmap_alerts;
+Pixmap  pixmap_final;
+
+// Global variable, so we can set it up once check it from then on,
+// preventing memory leaks from repeatedly setting up the same
+// XFontStruct.
+XFontStruct *station_font = NULL;   // Station font
+XFontStruct *font1;                 // Menu/System font
+XmFontList fontlist1;               // Menu/System fontlist
+
+Pixmap  pixmap_50pct_stipple; // 50% pixels used for position ambiguity, DF circle, etc.
+Pixmap  pixmap_25pct_stipple; // 25% pixels used for large position ambiguity
+Pixmap  pixmap_13pct_stipple; // 12.5% pixels used for larger position ambiguity
+Pixmap  pixmap_wx_stipple;  // Used for weather alerts
+
+int interrupt_drawing_now = 0;  // Flag used to interrupt map drawing
+int request_resize = 0;         // Flag used to request a resize operation
+int request_new_image = 0;      // Flag used to request a create_image operation
+//time_t last_input_event = (time_t)0;  // Time of last mouse/keyboard event
+void new_image(Widget da);
+
+
+typedef struct XastirGlobal {
+    Widget  top;    // top level shell
+} XastirGlobal;
+XastirGlobal Global;
+
+
+char *database_ptr;             /* database pointers */
+
+
+//---------------------------------------------------------------------------------------------
+//
+// These describe the current map window.  They must be kept
+// up-to-date when we zoom/pan/resize the window.
+//
+float f_center_longitude;    // Floating point map center longitude, updated by new_image()
+float f_center_latitude;     // Floating point map center latitude , updated by new_image()
+float f_NW_corner_longitude; // longitude of NW corner, updated by create_image(), refresh_image()
+float f_NW_corner_latitude;  // latitude  of NW corner, updated by create_image(), refresh_image()
+float f_SE_corner_longitude; // longitude of SE corner, updated by create_image(), refresh_image()
+float f_SE_corner_latitude;  // latitude  of SE corner, updated by create_image(), refresh_image()
+
+long center_longitude;       // Longitude at center of map, updated by display_zoom_image()
+long center_latitude;        // Latitude  at center of map, updated by display_zoom_image()
+long NW_corner_longitude;    // Longitude at NW corner, updated by create_image(), refresh_image()
+long NW_corner_latitude;     // Latitude  at NW corner, updated by create_image(), refresh_image()
+long SE_corner_longitude;    // Longitude at SE corner, updated by create_image(), refresh_image()
+long SE_corner_latitude;     // Latitude  at SE corner, updated by create_image(), refresh_image()
+
+long scale_x;                // x scaling in 1/100 sec per pixel, calculated from scale_y
+long scale_y;                // y scaling in 1/100 sec per pixel
+
+long new_mid_x, new_mid_y;   // Check values used before applying real change
+long new_scale_x;
+long new_scale_y;
+long screen_width;           // Screen width,  map area without border (in pixels)
+long screen_height;          // Screen height, map area without border (in pixels)
+Position screen_x_offset;
+Position screen_y_offset;
+float d_screen_distance;     // Diag screen distance
+float x_screen_distance;     // x screen distance
+//---------------------------------------------------------------------------------------------
+
+char user_dir[1000];            /* user directory file */
+int delay_time;                 /* used to delay display data */
+time_t last_weather_cycle;      // Time of last call to cycle_weather()
+Pixel colors[256];              /* screen colors */
+Pixel trail_colors[MAX_TRAIL_COLORS]; /* station trail colors, duh */
+int current_trail_color;        /* what color to draw station trails with */
+Pixel_Format visual_type = NOT_TRUE_NOR_DIRECT;
+int install_colormap;           /* if visual_type == NOT_TRUE..., should we install priv cmap */
+Colormap cmap;                  /* current colormap */
+
+int redo_list;                  // Station List update request
+int redraw_on_new_data;         // Station redraw request
+int wait_to_redraw;             /* wait to redraw until system is up */
+int display_up = 0;             /* display up? */
+int display_up_first = 0;       /* display up first */
+
+time_t max_transmit_time;       /* max time between transmits */
+time_t last_alert_redraw;       /* last time alert caused a redraw */
+time_t sec_next_gps;            /* next gps check */
+time_t gps_time;                /* gps delay time */
+char gprmc_save_string[MAX_LINE_SIZE+1];
+char gpgga_save_string[MAX_LINE_SIZE+1];
+int gps_port_save;
+time_t POSIT_rate;              // Posit TX rate timer
+time_t OBJECT_rate;             // Object/Item TX rate timer
+time_t update_DR_rate;          // How often to call draw_symbols if DR enabled
+time_t remove_ID_message_time;  // Time to get rid of large msg on screen.
+int pending_ID_message = 0;     // Variable turning on/off this function
+
+
+// SmartBeaconing(tm) stuff.  If enabled, POSIT_rate won't be used
+// for timing posits. sb_POSIT_rate computed via SmartBeaconing(tm)
+// will be used instead.
+int smart_beaconing;            // Master enable/disable for SmartBeaconing(tm) mode
+int sb_POSIT_rate = 30 * 60;    // Computed SmartBeaconing(tm) posit rate (secs)
+int sb_last_heading = -1;       // Heading at time of last posit
+int sb_current_heading = -1;    // Most recent heading parsed from GPS sentence
+int sb_turn_min = 20;           // Min threshold for corner pegging (degrees)
+int sb_turn_slope = 25;         // Threshold slope for corner pegging (degrees/mph)
+int sb_turn_time = 5;           // Time between other beacon & turn beacon (secs)
+int sb_posit_fast = 90;         // Fast beacon rate (secs)
+int sb_posit_slow = 30;         // Slow beacon rate (mins)
+int sb_low_speed_limit = 2;     // Speed below which SmartBeaconing(tm) is disabled &
+                                // we'll beacon at the POSIT_slow rate (mph)
+int sb_high_speed_limit = 60;   // Speed above which we'll beacon at the
+                                // POSIT_fast rate (mph)
+Widget smart_beacon_dialog = (Widget)NULL;
+Widget smart_beacon_enable = (Widget)NULL;
+Widget sb_hi_rate_data = (Widget)NULL;
+Widget sb_hi_mph_data = (Widget)NULL;
+Widget sb_lo_rate_data = (Widget)NULL;
+Widget sb_lo_mph_data = (Widget)NULL;
+Widget sb_min_turn_data = (Widget)NULL;
+Widget sb_turn_slope_data = (Widget)NULL;
+Widget sb_wait_time_data = (Widget)NULL;
+
+
+Widget ghosting_time = (Widget)NULL;
+Widget clearing_time = (Widget)NULL;
+Widget removal_time = (Widget)NULL;
+Widget posit_interval = (Widget)NULL;
+Widget gps_interval = (Widget)NULL;
+Widget dead_reckoning_time = (Widget)NULL;
+Widget object_item_interval = (Widget)NULL;
+Widget serial_pacing_time = (Widget)NULL;
+Widget trail_segment_timeout = (Widget)NULL;
+Widget trail_segment_distance_max = (Widget)NULL;
+Widget RINO_download_timeout = (Widget)NULL;
+Widget net_map_slider = (Widget)NULL;
+Widget snapshot_interval_slider = (Widget)NULL;
+int net_map_timeout = 120;
+
+
+
+time_t GPS_time;                /* gps time out */
+time_t last_statusline;         // last update of statusline or 0 if inactive
+time_t last_id_time;            // Time of last ID message to statusline
+time_t sec_old;                 /* station old after */
+time_t sec_clear;               /* station cleared after */
+time_t sec_remove;              /* Station removed after */
+int trail_segment_time;         // Segment missing if above this time (mins)
+int trail_segment_distance;     // Segment missing if greater distance
+int RINO_download_interval;     // Interval at which to download RINO waypoints,
+                                // creating APRS Objects from them.
+time_t last_RINO_download = (time_t)0;
+time_t sec_next_raw_wx;         /* raw wx transmit data */
+int dead_reckoning_timeout = 60 * 10;   // 10 minutes;
+
+#ifdef TRANSMIT_RAW_WX
+int transmit_raw_wx;            /* transmit raw wx data? */
+#endif  // TRANSMIT_RAW_WX
+
+int transmit_compressed_posit;  // transmit location in compressed format?
+int transmit_compressed_objects_items;  // Same for objects & items
+
+int output_station_type;        /* Broadcast station type */
+
+int Configure_station_pos_amb;  /* Broadcast station position ambiguity */
+
+long max_vectors_allowed;       /* max map vectors allowed */
+long max_text_labels_allowed;   /* max map text labels allowed */
+long max_symbol_labels_allowed; /* max map symbol labels allowed */
+
+time_t net_last_time;           /* reconnect last time in seconds */
+time_t net_next_time;           /* reconnect Next update delay time */
+
+#ifdef USING_LIBGC
+time_t gc_next_time = 0L;       // Garbage collection next time
+#endif  // USING_LIBGC
+
+time_t posit_last_time;
+time_t posit_next_time;         /* time at which next posit TX will occur */
+
+time_t last_time;               /* last time in seconds */
+time_t next_time;               /* Next update delay time */
+
+time_t next_redraw;             /* Next update time */
+time_t last_redraw;             /* Time of last redraw */
+
+char aprs_station_message_type = '='; // station message-capable or not
+
+int transmit_now;               /* set to transmit now (push on moment) */
+int my_position_valid = 1;      /* Don't send posits if this is zero */
+int using_gps_position = 0;     /* Set to one if a GPS port is active */
+int operate_as_an_igate;        /* toggle igate operations for net connections */
+unsigned igate_msgs_tx;         /* current total of igate messages transmitted */
+
+int log_tnc_data;               /* log data */
+int log_net_data;               /* log data */
+int log_igate;                  /* toggle to allow igate logging */
+int log_wx;                     /* toggle to allow wx logging */
+int log_message_data;           /* toggle to allow message logging */
+int log_wx_alert_data;          /* toggle to allow wx alert logging */
+
+
+int snapshots_enabled = 0;      // toggle to allow creating .png snapshots on a regular basis
+int kmlsnapshots_enabled = 0;   // toggle to allow creating .kml snapshots on a regular basis 
+
+time_t WX_ALERTS_REFRESH_TIME;  /* Minimum WX alert map refresh time in seconds */
+
+/* button zoom */
+int menu_x;
+int menu_y;
+int possible_zoom_function = 0;
+int zoom_box_x1 = -1;           // Stores one corner of zoom box
+int zoom_box_y1 = -1;
+int zoom_box_x2 = -1;           // Stores one corner of zoom box
+int zoom_box_y2 = -1;
+int mouse_zoom = 0;
+
+// log file replay
+int read_file;
+FILE *read_file_ptr;
+time_t next_file_read;
+
+// Data for own station
+char my_callsign[MAX_CALLSIGN+1];
+char my_lat[MAX_LAT];
+char my_long[MAX_LONG];
+char my_group;
+char my_symbol;
+char my_phg[MAX_PHG+1];
+char my_comment[MAX_COMMENT+1];
+int  my_last_course;
+int  my_last_speed;
+long my_last_altitude;
+time_t my_last_altitude_time;
+
+/* Symbols */
+SymbolData symbol_data[MAX_SYMBOLS];
+
+/* sound run */
+pid_t last_sound_pid;
+
+/* Default directories */
+
+char AUTO_MAP_DIR[400];
+char ALERT_MAP_DIR[400];
+char SELECTED_MAP_DIR[400];
+char SELECTED_MAP_DATA[400];
+char MAP_INDEX_DATA[400];
+char SYMBOLS_DIR[400];
+char HELP_FILE[400];
+char SOUND_DIR[400];
+
+char LOGFILE_TNC[400];
+char LOGFILE_NET[400];
+char LOGFILE_IGATE[400];
+char LOGFILE_MESSAGE[400];
+char LOGFILE_WX[400];
+char LOGFILE_WX_ALERT[400];
+
+/* sound data */
+char sound_command[90];
+int  sound_play_new_station;
+char sound_new_station[90];
+int  sound_play_new_message;
+char sound_new_message[90];
+
+int  sound_play_prox_message;
+char sound_prox_message[90];
+char prox_min[30];
+char prox_max[30];
+int  sound_play_band_open_message;
+char sound_band_open_message[90];
+char bando_min[30];
+char bando_max[30];
+int  sound_play_wx_alert_message;
+char sound_wx_alert_message[90];
+
+
+int input_x = 0;
+int input_y = 0;
+
+XtAppContext app_context;
+Display *display;       /*  Display             */
+
+/* dialog popup last */
+int last_popup_x;
+int last_popup_y;
+
+int disable_all_popups = 0;
+char temp_tracking_station_call[30] = "";
+
+time_t program_start_time;
+int measuring_distance = 0;
+int moving_object = 0;
+
+
+
+
+/////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+void Smart_Beacon_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    smart_beacon_dialog = (Widget)NULL;
+}
+
+
+
+
+
+// Still need to do some bounds checking on the values here.
+//
+// If the user enters 0's or non-numeric data, this function sets the
+// values to reasonable defaults.
+//
+// Another thing that'd be good to do is to recalculate the next
+// beacon time if one of the posit rates is shortened.  Otherwise we
+// might be waiting a while to get into the "right rhythm".
+//
+void Smart_Beacon_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    // Snag the XmTextString data and write it into the variables
+    if (smart_beacon_dialog != NULL) {
+        char *str_ptr1;
+        int i;
+
+        smart_beaconing = (int)XmToggleButtonGetState(smart_beacon_enable);
+
+        str_ptr1 = XmTextGetString(sb_hi_rate_data);
+        i = atoi(str_ptr1);
+        if (i == 0)
+            i = 90;
+        sb_posit_fast = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        str_ptr1 = XmTextGetString(sb_hi_mph_data);
+        i = atoi(str_ptr1);
+        switch (english_units) {
+            case 0: // Metric:  Convert from KPH to MPH for storage
+                i = (int)((i * 0.62137) + 0.5);
+                break;
+            case 1: // English
+            case 2: // Nautical
+            default:    // No conversion necessary
+                break;
+        }
+        if (i == 0)
+            i = 60;
+        sb_high_speed_limit = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        str_ptr1 = XmTextGetString(sb_lo_rate_data);
+        i = atoi(str_ptr1);
+        if (i == 0)
+            i = 30;
+        sb_posit_slow = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        str_ptr1 = XmTextGetString(sb_lo_mph_data);
+        i = atoi(str_ptr1);
+        switch (english_units) {
+            case 0: // Metric:  Convert from KPH to MPH for storage
+                i = (int)((i * 0.62137) + 0.5);
+                break;
+            case 1: // English
+            case 2: // Nautical
+            default:    // No conversion necessary
+                break;
+        }
+        if (i == 0)
+            i = 2;
+        sb_low_speed_limit = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        str_ptr1 = XmTextGetString(sb_min_turn_data);
+        i = atoi(str_ptr1);
+        if (i == 0)
+            i = 20;
+        sb_turn_min = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        str_ptr1 = XmTextGetString(sb_turn_slope_data);
+        i = atoi(str_ptr1);
+        if (i == 0)
+            i = 25;
+        sb_turn_slope = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        str_ptr1 = XmTextGetString(sb_wait_time_data);
+        i = atoi(str_ptr1);
+        if (i == 0)
+            i = 5;
+        sb_turn_time = i;
+        // Free the space.
+        XtFree(str_ptr1);
+
+        Smart_Beacon_destroy_shell(widget,clientData,callData);
+    }
+}
+
+
+
+
+
+void Smart_Beacon(Widget w, XtPointer clientData, XtPointer callData) {
+    static Widget  pane, form, label1, label2, label3,
+        label4, label5, label6, label7,
+        button_ok, button_cancel;
+
+    Atom delw;
+    char temp_string[10];
+    char temp_label_string[100];
+
+
+    // Destroy the dialog if it exists.  This is to make sure the
+    // title is correct based on the last dialog that called us.
+    if (smart_beacon_dialog) {
+        Smart_Beacon_destroy_shell( w, smart_beacon_dialog, callData);
+    }
+
+    if (!smart_beacon_dialog) {
+
+        smart_beacon_dialog = XtVaCreatePopupShell(langcode("SMARTB001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Smart_Beacon pane",
+                xmPanedWindowWidgetClass,
+                smart_beacon_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        form =  XtVaCreateWidget("Smart_Beacon form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 2,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        smart_beacon_enable = XtVaCreateManagedWidget(langcode("SMARTB011"),
+                xmToggleButtonWidgetClass,form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset,5,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label1 = XtVaCreateManagedWidget(langcode("SMARTB002"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, smart_beacon_enable,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_hi_rate_data = XtVaCreateManagedWidget("Smart_Beacon hi_rate_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 5,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, smart_beacon_enable,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        switch (english_units) {
+            case 0: // Metric
+                xastir_snprintf(temp_label_string,
+                    sizeof(temp_label_string),
+                    "%s",
+                    langcode("SMARTB004") );
+                break;
+            case 1: // English
+            case 2: // Nautical
+            default:
+                xastir_snprintf(temp_label_string,
+                    sizeof(temp_label_string),
+                    "%s",
+                    langcode("SMARTB003") );
+                break;
+        }
+
+        // High Speed (mph) / (kph)
+        label2 = XtVaCreateManagedWidget(temp_label_string,
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label1,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_hi_mph_data = XtVaCreateManagedWidget("Smart_Beacon hi_mph_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 3,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label1,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label3 = XtVaCreateManagedWidget(langcode("SMARTB005"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label2,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_lo_rate_data = XtVaCreateManagedWidget("Smart_Beacon lo_rate_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 3,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label2,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        switch (english_units) {
+            case 0: // Metric
+                xastir_snprintf(temp_label_string,
+                    sizeof(temp_label_string),
+                    "%s",
+                    langcode("SMARTB007") );
+                break;
+            case 1: // English
+            case 2: // Nautical
+            default:
+                xastir_snprintf(temp_label_string,
+                    sizeof(temp_label_string),
+                    "%s",
+                    langcode("SMARTB006") );
+                break;
+        }
+
+        // Low Speed (mph) / (kph)
+        label4 = XtVaCreateManagedWidget(temp_label_string,
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label3,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_lo_mph_data = XtVaCreateManagedWidget("Smart_Beacon lo_mph_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 3,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label3,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label5 = XtVaCreateManagedWidget(langcode("SMARTB008"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label4,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_min_turn_data = XtVaCreateManagedWidget("Smart_Beacon min_turn_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 3,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label4,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label6 = XtVaCreateManagedWidget(langcode("SMARTB009"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label5,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_turn_slope_data = XtVaCreateManagedWidget("Smart_Beacon turn_slope_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 5,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label7 = XtVaCreateManagedWidget(langcode("SMARTB010"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label6,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sb_wait_time_data = XtVaCreateManagedWidget("Smart_Beacon wait_time_data",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((6*7)+2),
+                XmNmaxLength, 3,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label6,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sb_wait_time_data,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_ok, XmNactivateCallback, Smart_Beacon_change_data, smart_beacon_dialog);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sb_wait_time_data,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_cancel, XmNactivateCallback, Smart_Beacon_destroy_shell, smart_beacon_dialog);
+
+        pos_dialog(smart_beacon_dialog);
+
+        delw = XmInternAtom(XtDisplay(smart_beacon_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(smart_beacon_dialog, delw, Smart_Beacon_destroy_shell, (XtPointer)smart_beacon_dialog);
+
+        XtManageChild(form);
+        XtManageChild(pane);
+        XtPopup(smart_beacon_dialog,XtGrabNone);
+        fix_dialog_size(smart_beacon_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(smart_beacon_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else {
+        (void)XRaiseWindow(XtDisplay(smart_beacon_dialog), XtWindow(smart_beacon_dialog));
+    }
+
+    // Fill in the current values
+    if (smart_beacon_dialog != NULL) {
+
+        if(smart_beaconing)
+            XmToggleButtonSetState(smart_beacon_enable,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(smart_beacon_enable,FALSE,FALSE);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%d", sb_posit_fast);
+        XmTextSetString(sb_hi_rate_data, temp_string);
+
+        switch (english_units) {
+            case 0: // Metric:  Convert from MPH to KPH for display
+                xastir_snprintf(temp_string,
+                    sizeof(temp_string),
+                    "%d",
+                    (int)((sb_high_speed_limit * 1.6094) + 0.5) );
+                break;
+            case 1: // English
+            case 2: // Nautical
+            default:    // No conversion necessary
+                xastir_snprintf(temp_string,
+                    sizeof(temp_string),
+                    "%d",
+                    sb_high_speed_limit);
+                break;
+        }
+        XmTextSetString(sb_hi_mph_data, temp_string);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%d", sb_posit_slow);
+        XmTextSetString(sb_lo_rate_data, temp_string);
+
+        switch (english_units) {
+            case 0: // Metric:  Convert from MPH to KPH for display
+                xastir_snprintf(temp_string,
+                    sizeof(temp_string),
+                    "%d",
+                    (int)((sb_low_speed_limit * 1.6094) + 0.5) );
+                break;
+            case 1: // English
+            case 2: // Nautical
+            default:    // No conversion necessary
+                xastir_snprintf(temp_string,
+                    sizeof(temp_string),
+                    "%d",
+                    sb_low_speed_limit);
+                break;
+        }
+        XmTextSetString(sb_lo_mph_data, temp_string);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%d", sb_turn_min);
+        XmTextSetString(sb_min_turn_data, temp_string);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%d", sb_turn_slope);
+        XmTextSetString(sb_turn_slope_data, temp_string);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%d", sb_turn_time);
+        XmTextSetString(sb_wait_time_data, temp_string);
+    }
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+// Causes the current set of internet-based maps to be snagged from
+// the 'net instead of from cache.  Once downloaded they get written
+// to the cache, overwriting possibly corrupted maps already in the
+// cache (why else would you invoke this function?).  This is a
+// method of getting rid of corrupted maps without having to wipe
+// out the entire cache.
+//
+void Re_Download_Maps_Now(Widget w, XtPointer clientData, XtPointer callData) {
+
+#ifdef USE_MAP_CACHE
+    // Disable reads from the map cache
+    map_cache_fetch_disable = 1;
+#endif
+
+    // Show a busy cursor while the map is being downloaded
+    busy_cursor(appshell);
+
+    // Cause maps to be refreshed
+    new_image(da);
+
+#ifdef USE_MAP_CACHE
+    //Enable reads from the map cache
+    map_cache_fetch_disable = 0;
+#endif
+}
+
+
+
+
+
+// Removes all files in the ~/.xastir/map_cache directory.  Does not
+// recurse down into subdirectories, but it shouldn't have to.
+//
+void Flush_Entire_Map_Queue(Widget w, XtPointer clientData, XtPointer callData) {
+    struct dirent *dl = NULL;
+    DIR *dm;
+    char fullpath[MAX_FILENAME];
+    char dir[MAX_FILENAME];
+    struct stat nfile;
+
+
+    get_user_base_dir("map_cache", dir, sizeof(dir));
+
+    dm = opendir(dir);
+    if (!dm) {  // Couldn't open directory
+        fprintf(stderr,"Flush_Entire_Map_Queue: Couldn't open directory\n");
+        return;
+    }
+
+    // Read the directory contents, delete each file found, skip
+    // directories.
+    //
+    while ((dl = readdir(dm))) {
+
+        //Construct the entire path/filename
+        xastir_snprintf(fullpath,
+            sizeof(fullpath),
+            "%s/%s",
+            dir,
+            dl->d_name);
+
+        if (stat(fullpath, &nfile) == 0) {
+            if ((nfile.st_mode & S_IFMT) == S_IFREG) {
+                // It's a regular file
+
+                // Remove the file
+                if (debug_level & 512)                
+                    fprintf(stderr,"Deleting file:  %s\n", fullpath);
+
+                unlink(fullpath);
+            }
+        }
+    }
+    (void)closedir(dm);
+}
+
+
+
+
+
+// Find the extents of every map we have.  This is the callback for
+// the "Re-Index Maps" button.
+//
+// If passed a NULL in the callback, we do a smart reindexing:  Only
+// reindex the files that are new or have changed.
+// If passed a "1" in the callback, we do a full reindexing:  Delete
+// the in-memory index and start indexing from scratch.
+// 
+void Index_Maps_Now(Widget w, XtPointer clientData, XtPointer callData) {
+    int parameter = 0;  // Default:  Smart timestamp-checking indexing
+
+
+    if (clientData != NULL) {
+
+        parameter = atoi((char *)clientData);
+
+        if (parameter != 1) {   // Our only option
+            parameter = 0;
+        }
+    }
+
+    // Update the list and write it to file.
+    map_indexer(parameter);
+}
+
+
+
+
+
+void check_weather_symbol(void) {
+    // Check for weather station, if so, make sure symbol is proper type
+    if ( (output_station_type == 4) || (output_station_type == 5) ) {
+        // Need one of these symbols if a weather station: /_   \_   /W   \W
+        if ( ( (my_symbol != '_') && (my_symbol != 'W') )
+            || ( (my_group != '\\') && (my_group != '/') ) ) {
+
+            // Force it to '/_'
+            my_group = '/';
+            my_symbol = '_';
+
+            // Update my station data with the new symbol
+            my_station_add(my_callsign,my_group,my_symbol,my_long,my_lat,my_phg,my_comment,(char)position_amb_chars);
+            redraw_on_new_data=2;
+
+            // Notify the operator that the symbol has been changed
+            // "Weather Station", "Changed to WX symbol '/_', other option is '\\_'"
+            popup_message_always( langcode("POPEM00030"), langcode("POPEM00031") );
+        }
+    }
+}
+
+
+
+
+
+void check_nws_weather_symbol(void) {
+    if ( (my_symbol == 'W')
+            && ( (my_group == '\\') || (my_group == '/') ) ) {
+
+        // Notify the operator that they're trying to be an NWS
+        // weather station.
+        popup_message_always( langcode("POPEM00030"), langcode("POPEM00032") );
+    }
+}
+
+
+
+
+
+void Coordinate_calc_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    coordinate_calc_dialog = (Widget)NULL;
+}
+
+
+
+
+
+// Clears out the dialog's input textFields
+void Coordinate_calc_clear_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    XmTextSetString(coordinate_calc_zone, "");
+    XmTextSetString(coordinate_calc_latitude_easting, "");
+    XmTextSetString(coordinate_calc_longitude_northing, "");
+    XmTextSetString(coordinate_calc_result_text, "");
+    XtSetSensitive(coordinate_calc_button_ok,FALSE);
+}
+
+
+
+
+
+// Computes all five coordinate representations for displaying in
+// the "result" textField.  Also fills in the global variables for
+// possible later use when passing results back to the calling
+// dialog.  We can't use the util.c:*_l2s routines for the
+// conversions here because the util.c routines use Xastir
+// coordinate system as inputs instead of normal lat/lon.  Had to
+// home-grow our solution here.
+//
+// Inputs:  full_zone, northing, easting, latitude, longitude.  UTM
+// inputs are output directly.  Latitude/longitude are converted to
+// the various different lat/lon representations.
+//
+// Outputs: global variables and "result" textField, full_zone.
+// full_zone should be a string of at least size 4.
+//
+void Coordinate_calc_output(char *full_zone, long northing,
+            long easting, double latitude, double longitude) {
+    char temp_string[1024];
+    int south = 0;
+    int west = 0;
+    double lat_min,lon_min,lat_sec,lon_sec;
+    int lat_deg_int,lat_min_int;
+    int lon_deg_int,lon_min_int;
+    char maidenhead_grid[50];
+    long temp;
+    long xastir_lat;
+    long xastir_lon;
+    char MGRS_str[50];
+    double double_easting, double_northing;
+ 
+
+    // Latitude:  Switch to integer arithmetic to avoid
+    // floating-point rounding errors.
+    // We _do_ need to round it first though so that we don't lose
+    // accuracy.
+    xastir_snprintf(temp_string,sizeof(temp_string),"%8.0f",latitude * 100000.0);
+    temp = atol(temp_string);
+    if (temp < 0) {
+        south++;
+        temp = labs(temp);
+    }
+    lat_deg_int = (int)temp / 100000;
+    lat_min = (temp % 100000) * 60.0 / 100000.0;
+
+    // Again switch to integer arithmetic to avoid floating-point
+    // rounding errors.
+    temp = (long)(lat_min * 1000);
+    lat_min_int = (int)(temp / 1000);
+    lat_sec = (temp % 1000) * 60.0 / 1000.0;
+
+
+    // Longitude:  Switch to integer arithmetic to avoid
+    // floating-point rounding errors.
+    // We _do_ need to round it first though so that we don't lose
+    // accuracy.
+    xastir_snprintf(temp_string,sizeof(temp_string),"%9.0f",longitude * 100000.0);
+    temp = atol(temp_string);
+    if (temp < 0) {
+        west++;
+        temp = labs(temp);
+    }
+    lon_deg_int = (int)temp / 100000;
+    lon_min = (temp % 100000) * 60.0 / 100000.0;
+
+    // Again switch to integer arithmetic to avoid floating-point
+    // rounding errors.
+    temp = (long)(lon_min * 1000);
+    lon_min_int = (int)(temp / 1000);
+    lon_sec = (temp % 1000) * 60.0 / 1000.0;
+
+
+    double_easting = (double)easting;
+    double_northing = (double)northing;
+    convert_UTM_to_xastir(double_easting,
+        double_northing,
+        full_zone,
+        &xastir_lon,
+        &xastir_lat);
+
+//fprintf(stderr,"%s  %f  %f\t\t%lu %lu\n",
+//full_zone,
+//double_easting,
+//double_northing,
+//xastir_lat,
+//xastir_lon);
+
+ 
+    // Compute MGRS coordinates.
+    convert_xastir_to_MGRS_str(MGRS_str,
+        sizeof(MGRS_str),
+        xastir_lon,
+        xastir_lat,
+        1); // Format with leading spaces plus spaces between
+            // easting and northing, so that it lines up with UTM
+            // strings.
+
+
+    // Compute Maidenhead Grid Locator.  Note that the sec_to_loc()
+    // function expects lat/lon in Xastir coordinate system.
+    xastir_snprintf(maidenhead_grid,
+        sizeof(maidenhead_grid),
+        "%s",
+        sec_to_loc( xastir_lon, xastir_lat ) );
+
+
+    if (strlen(full_zone) == 1) {
+        xastir_snprintf(temp_string,
+            sizeof(temp_string),
+            "  %s",
+            full_zone);
+        xastir_snprintf(full_zone,
+            4,
+            "%s",
+            temp_string);
+    }
+    else if (strlen(full_zone) == 2) {
+        xastir_snprintf(temp_string,
+            sizeof(temp_string),
+            " %s",
+            full_zone);
+        xastir_snprintf(full_zone,
+            4,
+            "%s",
+            temp_string);
+    }
+        
+
+    // Put the four different representations of the coordinate into
+    // the "result" textField.
+    xastir_snprintf(temp_string,
+        sizeof(temp_string),
+        "%s%8.5f%c   %9.5f%c\n%s%02d %06.3f%c  %03d %06.3f%c\n%s%02d %02d %04.1f%c %03d %02d %04.1f%c\n%s%3s  %07lu  %07lu\n%s%s\n%s%s",
+        langcode("COORD011"), // "Decimal Degrees:",
+        lat_deg_int+lat_min/60.0, (south) ? 'S':'N',
+        lon_deg_int+lon_min/60.0, (west) ?  'W':'E',
+        langcode("COORD012"), // "Degrees/Decimal Minutes:",
+        lat_deg_int, lat_min, (south) ? 'S':'N',
+        lon_deg_int, lon_min, (west) ?  'W':'E',
+        langcode("COORD013"), // "Degrees/Minutes/Dec. Seconds:",
+        lat_deg_int, lat_min_int, lat_sec, (south) ? 'S':'N',
+        lon_deg_int, lon_min_int, lon_sec, (west) ?  'W':'E',
+        langcode("COORD014"), // "Universal Transverse Mercator:",
+        full_zone, easting, northing,
+        langcode("COORD015"), // "Military Grid Reference System:",
+        MGRS_str,
+        langcode("COORD016"), // "Maidenhead Grid Locator:",
+        maidenhead_grid);
+    XmTextSetString(coordinate_calc_result_text, temp_string);
+
+    // Fill in the global dd mm.mmm values in case we wish to write
+    // the result back to the calling dialog.
+    xastir_snprintf(coordinate_calc_lat_deg, sizeof(coordinate_calc_lat_deg),
+        "%02d", lat_deg_int);
+    xastir_snprintf(coordinate_calc_lat_min, sizeof(coordinate_calc_lat_min),
+        "%06.3f", lat_min);
+    xastir_snprintf(coordinate_calc_lat_dir, sizeof(coordinate_calc_lat_dir),
+        "%c", (south) ? 'S':'N');
+    xastir_snprintf(coordinate_calc_lon_deg, sizeof(coordinate_calc_lon_deg),
+        "%03d", lon_deg_int);
+    xastir_snprintf(coordinate_calc_lon_min, sizeof(coordinate_calc_lon_min),
+        "%06.3f", lon_min);
+    xastir_snprintf(coordinate_calc_lon_dir, sizeof(coordinate_calc_lon_dir),
+        "%c", (west) ? 'W':'E');
+}
+
+
+
+
+
+// Coordinate_calc_compute
+//
+// Inputs:  coordinate_calc_zone textField
+//          coordinate_calc_latitude_easting textField
+//          coordinate_calc_longitude_northing textField
+//
+// Output:  coordinate_calc_result_text only if the inputs are not
+// recognized, then it outputs help text to the textField.  If
+// inputs are good it calls Coordinate_calc_output() to format and
+// save/output the results.
+//
+void Coordinate_calc_compute(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *str_ptr;
+    char zone_letter;
+    int zone_number = 0;
+    char full_zone[5];
+    int i;
+    int have_utm;
+    int have_lat_lon;
+    long easting = 0;
+    long northing = 0;
+    double double_easting;
+    double double_northing;
+    double latitude;
+    double longitude;
+    char temp_string[1024];
+
+
+    // Goal is to suck in the format provided, figure out what
+    // format it is, then convert to the four major formats we
+    // support and put all four into the output window, each on a
+    // different line.
+
+    // These are the formats that I'd like to be able to
+    // auto-recognize and support:
+
+    // ddN          dddW            IMPLEMENTED
+    // dd N         ddd W           IMPLEMENTED
+    // -dd          -ddd            IMPLEMENTED
+
+    // dd.ddddN     ddd.ddddW       IMPLEMENTED
+    // dd.dddd N    ddd.dddd W      IMPLEMENTED
+    // -dd.dddd     -ddd.dddd       IMPLEMENTED
+
+    // dd mmN       ddd mmW         IMPLEMENTED
+    // dd mm N      ddd mm W        IMPLEMENTED
+    // -dd mm       -ddd mm         IMPLEMENTED
+
+    // dd mm.mmmN   ddd mm.mmmW     IMPLEMENTED
+    // dd mm.mmm N  ddd mm.mmm W    IMPLEMENTED
+    // -dd mm.mmm   -ddd mm.mmm     IMPLEMENTED
+
+    // dd mm ssN    ddd mm ssW      IMPLEMENTED
+    // dd mm ss N   ddd mm ss W     IMPLEMENTED
+    // -dd mm ss    -ddd mm ss      IMPLEMENTED
+
+    // dd mm ss.sN  ddd mm ss.sW    IMPLEMENTED
+    // dd mm ss.s N ddd mm ss.s W   IMPLEMENTED
+    // -dd mm ss.s  -ddd mm ss.s    IMPLEMENTED
+
+    // 10T  0123456     1234567     IMPLEMENTED
+    // 10T   123456     1234567     IMPLEMENTED
+    // 10T  012 3456    123 4567
+    // 10T   12 3456    123 4567
+
+    // Once the four major formats are created and written to the
+    // output test widget, the dd mm.mmmN/ddd mm.mmmW formatted
+    // output should also be saved for later pasting into the
+    // calling dialog's input fields.  DONE!
+    //
+    // Must also make sure that the calling dialog is still up and
+    // active before we try to write to it's widgets.  DONE!
+
+
+    // Check for something in the zone field that looks like a valid
+    // UTM zone.
+    str_ptr = XmTextGetString(coordinate_calc_zone);
+    i = strlen(str_ptr);
+    have_utm = 1;   // Wishful thinking.  We'll zero it later if not.
+    if ( (i >= 1) && (i <= 3) ) {
+        // String is the correct length.  Can have just A/B/Y/Z, or
+        // else one or two digits plus one letter.
+        int j;
+
+        for (j = 0; j < (i-1); j++) {
+            if ( (str_ptr[j] < '0') && (str_ptr[j] > '9') ) {
+                // Not UTM, need either one or two digits first if
+                // we have 2 or 3 chars.
+                have_utm = 0;
+            }
+        }
+        if ( ( (str_ptr[i-1] < 'A') || (str_ptr[i-1] > 'Z') )
+            && ( (str_ptr[i-1] < 'a') || (str_ptr[i-1] > 'z') ) ) {
+            // Not UTM, zone character isn't correct
+            have_utm = 0;
+        }
+    }
+    else {  // Not a valid UTM zone, wrong length.
+        have_utm = 0;
+    }
+
+    // If we've made it to this point and have_utm == 1, then zone looks
+    // like a UTM zone.
+    if (have_utm) {
+        zone_letter = toupper(str_ptr[i-1]);
+        zone_number = atoi(str_ptr);
+        //fprintf(stderr,"Zone Number: %d,  Zone Letter: %c\n", zone_number, zone_letter);
+        // Save it away for later use
+        if (zone_number == 0) { // We're in a UPS area
+            xastir_snprintf(full_zone,
+                sizeof(full_zone),
+                "  %c",
+                zone_letter);
+        }
+        else {  // UTM area
+            xastir_snprintf(full_zone,
+                sizeof(full_zone),
+                "%02d%c",
+                zone_number,
+                zone_letter);
+        }
+        have_lat_lon = 0;
+    }
+    else {
+        //fprintf(stderr,"Bad zone, not a UTM coordinate\n");
+        // Skip zone widget for lat/lon, it's not used.
+        have_lat_lon = 1;   // Wishful thinking.  We'll zero it later if not.
+    }
+    // We're done with that variable.  Free the space.
+    XtFree(str_ptr);
+
+
+    str_ptr = XmTextGetString(coordinate_calc_latitude_easting);
+    i = strlen(str_ptr);
+    // Check for exactly six or seven chars.  If seven, first one must
+    // be a zero (Not true!  UPS coordinates have digits there!).
+    if ( have_utm && (i != 6) && (i != 7) ) {
+        have_utm = 0;
+        //fprintf(stderr,"Bad Easting value: Not 6 or 7 chars\n");
+    }
+//    if ( have_utm && (i == 7) && (str_ptr[0] != '0') ) {
+//        have_utm = 0;
+//        //fprintf(stderr,"Bad Easting value: 7 chars but first one not 0\n");
+//    }
+    if (have_utm) {
+        int j;
+
+        // Might be good to get rid of spaces at this point as we think
+        // it's a UTM number.  Might have to put it in our own string
+        // first though to do that.
+
+        for (j = 0; j < i; j++) {
+            if ( (str_ptr[j] < '0') || (str_ptr[j] > '9') ) {
+                // Not UTM, found a non-number
+                have_utm = 0;
+            }
+        }
+
+        if (have_utm) { // If we still think it's a valid UTM number
+            easting = atol(str_ptr);
+            //fprintf(stderr,"Easting: %lu\n",easting);
+        }
+        else {
+            //fprintf(stderr,"Bad Easting value\n");
+        }
+    }
+    else if (have_lat_lon) {
+        // Process the string to see if it's a valid latitude value.
+        // Convert it into a double if so and store it in
+        // "latitude".
+        int j, substring;
+        int south = 0;
+        int temp[10];  // indexes to substrings
+        char *ptr;
+        char temp_string[30];
+        int piece;
+
+        // Copy the string so we can change it.
+        xastir_snprintf(temp_string,sizeof(temp_string),"%s",str_ptr);
+
+        for (j = 0; j < i; j++) {
+           temp_string[j] = toupper(temp_string[j]);
+        }
+
+        // Search for 'N' or 'S'.
+        ptr = rindex(temp_string, 'N');
+        if (ptr != NULL) {  // Found an 'N'
+            *ptr = ' ';     // Convert it to a space
+            //fprintf(stderr,"Found an 'N', converted to %s\n", temp_string);
+        }
+        ptr = rindex(temp_string, 'S');
+        if (ptr != NULL) {  // Found an 'S'
+            *ptr = ' ';     // Convert it to a space
+            south++;
+            //fprintf(stderr,"Found an 'S', converted to %s\n", temp_string);
+        }
+        ptr = rindex(temp_string, '-');
+        if (ptr != NULL) {  // Found an '-'
+            *ptr = ' ';     // Convert it to a space
+            south++;
+            //fprintf(stderr,"Found an '-', converted to %s\n", temp_string);
+        }
+
+        // Tokenize the string
+
+        // Find the space characters
+        temp[0] = 0;        // First index is to start of entire string
+        substring = 1;
+        for (j = 1; j < i; j++) {
+            if (temp_string[j] == ' ') {        // Found a space
+                temp_string[j] = '\0';          // Terminate the substring
+                if ( (j + 1) < i) {             // If not at the end
+                    temp[substring++] = j + 1;  // Save an index to the new substring
+                    //fprintf(stderr,"%s",&temp_string[j+1]);
+                }
+            }
+        }
+
+        // temp[] array now contains indexes into all of the
+        // substrings.  Some may contain empty strings.
+
+        //fprintf(stderr,"Substrings: %d\n", substring);
+        //fprintf(stderr,"temp_string: %s\n",temp_string);
+
+
+        //for (j = 0; j < substring; j++) {
+        //    if (strlen(&temp_string[temp[j]]) > 0) {
+        //        fprintf(stderr,"%s\n", &temp_string[temp[j]]);
+        //    }
+        //}
+
+        piece = 0;
+        have_lat_lon = 0;
+
+        for (j = 0; j < substring; j++) {
+            if (strlen(&temp_string[temp[j]]) > 0) {
+                double kk;
+
+                piece++;    // Found the next piece
+                kk = atof(&temp_string[temp[j]]);
+
+                switch (piece) {
+                    case (1) :  // Degrees
+                        latitude = kk;
+                        have_lat_lon = 1;
+                        break;
+                    case (2) :  // Minutes
+                        if ( (kk < 0.0) || (kk >= 60.0) ) {
+                            fprintf(stderr,"Warning:  Bad latitude minutes value\n");
+                            // Set variables so that we'll get error output.
+                            have_lat_lon = 0;
+                            have_utm = 0;
+                        }
+                        else {
+                            latitude = latitude + ( kk / 60.0 );
+                        }
+                        break;
+                    case (3) :  // Seconds
+                        if ( (kk < 0.0) || (kk >= 60.0)) {
+                            fprintf(stderr,"Warning:  Bad latitude seconds value\n");
+                            // Set variables so that we'll get error output.
+                            have_lat_lon = 0;
+                            have_utm = 0;
+                        }
+                        else {
+                            latitude = latitude + ( kk / 3600.0 );
+                        }
+                        break;
+                    default :
+                        break;
+                }
+            }
+        }
+
+        if (south) {
+            latitude = -latitude;
+        }
+        //fprintf(stderr,"%f\n", latitude);
+
+        // Test for valid values of latitude
+        if ( have_lat_lon && ((latitude < -90.0) || (latitude > 90.0)) ) {
+            have_lat_lon = 0;
+        }
+        if (strlen(str_ptr) == 0) {
+            have_lat_lon = 0;
+        }
+    }
+    // We're done with that variable.  Free the space.
+    XtFree(str_ptr);
+
+
+    str_ptr = XmTextGetString(coordinate_calc_longitude_northing);
+    i = strlen(str_ptr);
+    // Check for exactly seven chars.
+    if (have_utm && (i != 7) ) {
+        have_utm = 0;
+        //fprintf(stderr,"Bad Northing value: Not 7 chars\n");
+    }
+    if (have_utm) {
+        int j;
+
+        // Might be good to get rid of spaces at this point as we think
+        // it's a UTM number.  Might have to put it in our own string
+        // first though to do that.
+
+        for (j = 0; j< i; j++) {
+            if ( (str_ptr[j] < '0') || (str_ptr[j] > '9') ) {
+                // Not UTM, found a non-number
+                have_utm = 0;
+            }
+        }
+        if (have_utm) { // If we still think it's a valid UTM number
+            northing = atol(str_ptr);
+            //fprintf(stderr,"Northing: %lu\n",northing);
+        }
+        else {
+            //fprintf(stderr,"Bad Northing value\n");
+        }
+    }
+    else if (have_lat_lon) {
+        // Process the string to see if it's a valid longitude
+        // value.  Convert it into a double if so and store it in
+        // "longitude".
+        int j, substring;
+        int west = 0;
+        int temp[10];  // indexes to substrings
+        char *ptr;
+        char temp_string[30];
+        int piece;
+
+        // Copy the string so we can change it.
+        xastir_snprintf(temp_string,sizeof(temp_string),"%s",str_ptr);
+
+        for (j = 0; j < i; j++) {
+           temp_string[j] = toupper(temp_string[j]);
+        }
+
+        // Search for 'W' or 'E'.
+        ptr = rindex(temp_string, 'W');
+        if (ptr != NULL) {  // Found an 'W'
+            *ptr = ' ';     // Convert it to a space
+            west++;
+            //fprintf(stderr,"Found an 'W', converted to %s\n", temp_string);
+        }
+        ptr = rindex(temp_string, 'E');
+        if (ptr != NULL) {  // Found an 'E'
+            *ptr = ' ';     // Convert it to a space
+            //fprintf(stderr,"Found an 'E', converted to %s\n", temp_string);
+        }
+        ptr = index(temp_string, '-');
+        if (ptr != NULL) {  // Found an '-'
+            *ptr = ' ';     // Convert it to a space
+            west++;
+            //fprintf(stderr,"Found an '-', converted to %s\n", temp_string);
+        }
+
+        // Tokenize the string
+
+        // Find the space characters
+        temp[0] = 0;        // First index is to start of entire string
+        substring = 1;
+        for (j = 1; j < i; j++) {
+            if (temp_string[j] == ' ') {        // Found a space
+                temp_string[j] = '\0';          // Terminate the substring
+                if ( (j + 1) < i) {             // If not at the end
+                    temp[substring++] = j + 1;  // Save an index to the new substring
+                    //fprintf(stderr,"%s",&temp_string[j+1]);
+                }
+            }
+        }
+
+        // temp[] array now contains indexes into all of the
+        // substrings.  Some may contain empty strings.
+
+        //fprintf(stderr,"Substrings: %d\n", substring);
+        //fprintf(stderr,"temp_string: %s\n",temp_string);
+
+
+        //for (j = 0; j < substring; j++) {
+        //    if (strlen(&temp_string[temp[j]]) > 0) {
+        //        fprintf(stderr,"%s\n", &temp_string[temp[j]]);
+        //    }
+        //}
+        piece = 0;
+        have_lat_lon = 0;
+
+        for (j = 0; j < substring; j++) {
+            if (strlen(&temp_string[temp[j]]) > 0) {
+                double kk;
+
+                piece++;    // Found the next piece
+                kk = atof(&temp_string[temp[j]]);
+
+                switch (piece) {
+                    case (1) :  // Degrees
+                        longitude = kk;
+                        have_lat_lon = 1;
+                        break;
+                    case (2) :  // Minutes
+                        if ( (kk < 0.0) || (kk >= 60.0) ) {
+                            fprintf(stderr,"Warning:  Bad longitude minutes value\n");
+                            // Set variables so that we'll get error output.
+                            have_lat_lon = 0;
+                            have_utm = 0;
+                        }
+                        else {
+                            longitude = longitude + ( kk / 60.0 );
+                        }
+                        break;
+                    case (3) :  // Seconds
+                        if ( (kk < 0.0) || (kk >= 60.0) ) {
+                            fprintf(stderr,"Warning:  Bad longitude seconds value\n");
+                            // Set variables so that we'll get error output.
+                            have_lat_lon = 0;
+                            have_utm = 0;
+                        }
+                        else {
+                            longitude = longitude + ( kk / 3600.0 );
+                        }
+                        break;
+                    default :
+                        break;
+                }
+            }
+        }
+
+        if (west) {
+            longitude = -longitude;
+        }
+        //fprintf(stderr,"%f\n", longitude);
+
+
+        // Test for valid values of longitude
+        if (have_lat_lon && ((longitude < -180.0) || (longitude > 180.0)) ) {
+            have_lat_lon = 0;
+        }
+        if (strlen(str_ptr) == 0) {
+            have_lat_lon = 0;
+        }
+    }
+    // We're done with that variable.  Free the space.
+    XtFree(str_ptr);
+
+    // If we get to this point and have_utm == 1, then we're fairly sure
+    // we have a good value and can convert it to the other formats for
+    // display.
+    if (have_utm) {
+//fprintf(stderr,"Processing 'good' UTM values\n");
+        // Process UTM values
+        utm_ups_to_ll(E_WGS_84,
+            (double)northing,
+            (double)easting,
+            full_zone,
+            &latitude,
+            &longitude);
+        if (debug_level & 1)
+            fprintf(stderr,"Latitude: %f, Longitude: %f\n",latitude,longitude);
+        Coordinate_calc_output(full_zone,
+            northing,
+            easting,
+            latitude,
+            longitude);
+        XtSetSensitive(coordinate_calc_button_ok,TRUE);
+    }
+    else if (have_lat_lon) {
+        // Process lat/lon values
+        double_northing = (double)northing;
+        double_easting = (double)easting;
+        ll_to_utm_ups(E_WGS_84,
+            (double)latitude,
+            (double)longitude,
+            &double_northing,
+            &double_easting,
+            full_zone,
+            sizeof(full_zone));
+        if (debug_level & 1)
+            fprintf(stderr,"Zone: %s, Easting: %f, Northing: %f\n", full_zone, double_easting, double_northing);
+        // Round the UTM values as we convert them to longs
+        xastir_snprintf(temp_string,sizeof(temp_string),"%7.0f",double_northing);
+        northing = (long)(atof(temp_string));
+        xastir_snprintf(temp_string,sizeof(temp_string),"%7.0f",double_easting);
+        easting  = (long)(atof(temp_string));
+        Coordinate_calc_output(full_zone,
+            (long)northing,
+            (long)easting,
+            latitude,
+            longitude);
+        XtSetSensitive(coordinate_calc_button_ok,TRUE);
+    }
+    else {  // Dump out some helpful text
+        xastir_snprintf(temp_string,
+            sizeof(temp_string),
+            "%s\n%s\n%s\n%s",
+//            " **       Sorry, your input was not recognized!        **",
+            langcode("COORD017"),
+//            " **   Please use one of the following input formats:   **",
+            langcode("COORD018"),
+            " ** 47.99999N  121.99999W,   47 59.999N   121 59.999W  **",
+            " ** 10T  0574599  5316887,   47 59 59.9N  121 59 59.9W **");
+        XmTextSetString(coordinate_calc_result_text, temp_string);
+        XtSetSensitive(coordinate_calc_button_ok,FALSE);
+    }
+}
+
+
+
+
+
+// Input:  Values from the coordinate_calc_array struct.
+//
+// Output:  Writes data back to the calling dialog's input fields if
+// the calling dialog still exists at this point.
+//
+// Make sure that if an error occurs during computation we don't
+// write a bad value back to the calling widget.  DONE.
+//
+void Coordinate_calc_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    // Write output directly to the XmTextStrings pointed to by our array
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lat_deg != NULL) )
+        XmTextSetString(coordinate_calc_array.input_lat_deg, coordinate_calc_lat_deg);
+    //fprintf(stderr,"%s\n",coordinate_calc_lat_deg);
+
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lat_min != NULL) )
+        XmTextSetString(coordinate_calc_array.input_lat_min, coordinate_calc_lat_min);
+    //fprintf(stderr,"%s\n",coordinate_calc_lat_min);
+
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lat_dir != NULL) )
+        XmTextSetString(coordinate_calc_array.input_lat_dir, coordinate_calc_lat_dir);
+    //fprintf(stderr,"%s\n",coordinate_calc_lat_dir);
+
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lon_deg != NULL) )
+        XmTextSetString(coordinate_calc_array.input_lon_deg, coordinate_calc_lon_deg);
+    //fprintf(stderr,"%s\n",coordinate_calc_lon_deg);
+
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lon_min != NULL) )
+        XmTextSetString(coordinate_calc_array.input_lon_min, coordinate_calc_lon_min);
+    //fprintf(stderr,"%s\n",coordinate_calc_lon_min);
+
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lon_dir != NULL) )
+        XmTextSetString(coordinate_calc_array.input_lon_dir, coordinate_calc_lon_dir);
+    //fprintf(stderr,"%s\n",coordinate_calc_lon_dir);
+
+    Coordinate_calc_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+// Coordinate Calculator
+//
+// Change the title based on what dialog is calling us?
+//
+// We want all four possible coordinate formats displayed
+// simultaneously.  DONE.
+//
+// Hitting enter or "Calculate" will cause all of the fields to be
+// updated.  DONE (for Calculate button).
+//
+// The fields should be filled in when this is first called.
+// When done, this routine will pass back values via a static array
+// of Widget pointers to the calling dialog's fields.  DONE.
+//
+// We could grey-out the OK button until we have a successful
+// calculation, and when the "Clear" button is pressed.  This
+// would make sure that an invalid location doesn't
+// get written to the calling dialog.  Would have to have a
+// successful conversion before we could write the value back.
+//
+void Coordinate_calc(Widget w, XtPointer clientData, XtPointer callData) {
+    static Widget  pane, form, label1, label2, label3,
+        label4, label5, label6,
+        button_clear, button_calculate, button_cancel;
+    Atom delw;
+    Arg args[50];                    // Arg List
+    register unsigned int n = 0;    // Arg Count
+    char temp_string[50];
+
+    // Destroy the dialog if it exists.  This is to make sure the
+    // title is correct based on the last dialog that called us.
+    if (coordinate_calc_dialog) {
+        Coordinate_calc_destroy_shell( w, coordinate_calc_dialog, callData);
+    }
+
+    if (!coordinate_calc_dialog) {
+
+        // We change the title based on who's calling us.
+        // clientData supplies the string we use for the label, and
+        // is sent to us by the calling dialog.
+        xastir_snprintf( temp_string, sizeof(temp_string), "%s %s", (char *)clientData, langcode("COORD001") );
+
+        coordinate_calc_dialog = XtVaCreatePopupShell(temp_string,
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                NULL);
+
+        pane = XtVaCreateWidget("Coordinate_calc pane",
+                xmPanedWindowWidgetClass,
+                coordinate_calc_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        form =  XtVaCreateWidget("Coordinate_calc form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 4,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        label1 = XtVaCreateManagedWidget(langcode("COORD005"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label2 = XtVaCreateManagedWidget(langcode("COORD006"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 70,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label3 = XtVaCreateManagedWidget(langcode("COORD007"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 200,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label4 = XtVaCreateManagedWidget(langcode("COORD008"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label1,
+                XmNtopOffset, 2,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label5 = XtVaCreateManagedWidget(langcode("COORD009"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label1,
+                XmNtopOffset, 2,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 70,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label6 = XtVaCreateManagedWidget(langcode("COORD010"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label1,
+                XmNtopOffset, 2,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 200,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        /*set args for color */
+        n=0;
+        XtSetArg(args[n], XmNforeground, MY_FG_COLOR); n++;
+        XtSetArg(args[n], XmNbackground, MY_BG_COLOR); n++;
+
+
+        coordinate_calc_zone = XtVaCreateManagedWidget("Coordinate_calc zone",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 4,
+                XmNwidth, ((5*7)+2),
+                XmNmaxLength, 3,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label4,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+       coordinate_calc_latitude_easting = XtVaCreateManagedWidget("Coordinate_calc lat",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 13,
+                XmNwidth, ((13*7)+2),
+                XmNmaxLength, 12,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label4,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 65,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        coordinate_calc_longitude_northing = XtVaCreateManagedWidget("Coordinate_calc lon",
+                xmTextWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 13,
+                XmNwidth, ((14*7)+2),
+                XmNmaxLength, 13,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, label4,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 195,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+//        xastir_snprintf(temp_string, sizeof(temp_string), "%d", temp);
+//        XmTextSetString(coordinate_calc_text, temp_string);
+
+        coordinate_calc_result_text = NULL;
+        coordinate_calc_result_text = XtVaCreateManagedWidget("Coordinate_calc results",
+                xmTextWidgetClass,
+                form,
+                XmNrows, 6,
+                XmNcolumns, 58,
+                XmNeditable, FALSE,
+                XmNtraversalOn, FALSE,
+                XmNeditMode, XmMULTI_LINE_EDIT,
+                XmNwordWrap, TRUE,
+//                XmNscrollHorizontal, FALSE,
+                XmNcursorPositionVisible, FALSE,
+                XmNautoShowCursorPosition, True,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, coordinate_calc_zone,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_clear = XtVaCreateManagedWidget(langcode("COORD004"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, coordinate_calc_result_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_clear, XmNactivateCallback, Coordinate_calc_clear_data, coordinate_calc_dialog);
+
+        button_calculate = XtVaCreateManagedWidget(langcode("COORD003"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, coordinate_calc_result_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_calculate, XmNactivateCallback, Coordinate_calc_compute, coordinate_calc_dialog);
+
+        coordinate_calc_button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, coordinate_calc_result_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coordinate_calc_button_ok, XmNactivateCallback, Coordinate_calc_change_data, coordinate_calc_dialog);
+        XtSetSensitive(coordinate_calc_button_ok,FALSE);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, coordinate_calc_result_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_cancel, XmNactivateCallback, Coordinate_calc_destroy_shell, coordinate_calc_dialog);
+
+        pos_dialog(coordinate_calc_dialog);
+
+        delw = XmInternAtom(XtDisplay(coordinate_calc_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(coordinate_calc_dialog, delw, Coordinate_calc_destroy_shell, (XtPointer)coordinate_calc_dialog);
+
+        XtManageChild(form);
+        XtManageChild(pane);
+        XtPopup(coordinate_calc_dialog,XtGrabNone);
+        fix_dialog_size(coordinate_calc_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(coordinate_calc_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else {
+        (void)XRaiseWindow(XtDisplay(coordinate_calc_dialog), XtWindow(coordinate_calc_dialog));
+    }
+
+    // Fill in the latitude values if they're available
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lat_deg != NULL)
+            && (coordinate_calc_array.input_lat_min != NULL)
+            && (coordinate_calc_array.input_lat_dir != NULL) )
+    {
+        char *str_ptr1;
+        char *str_ptr2;
+        char *str_ptr3;
+
+        str_ptr1 = XmTextGetString(coordinate_calc_array.input_lat_deg);
+        str_ptr2 = XmTextGetString(coordinate_calc_array.input_lat_min);
+        str_ptr3 = XmTextGetString(coordinate_calc_array.input_lat_dir);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%s %s%s",
+            str_ptr1, str_ptr2, str_ptr3);
+        XmTextSetString(coordinate_calc_latitude_easting, temp_string);
+        //fprintf(stderr,"String: %s\n", temp_string);
+        // We're done with these variables.  Free the space.
+        XtFree(str_ptr1);
+        XtFree(str_ptr2);
+        XtFree(str_ptr3);
+    }
+
+    // Fill in the longitude values if they're available
+    if ( (coordinate_calc_array.calling_dialog != NULL)
+            && (coordinate_calc_array.input_lon_deg != NULL)
+            && (coordinate_calc_array.input_lon_min != NULL)
+            && (coordinate_calc_array.input_lon_dir != NULL) )
+    {
+        char *str_ptr1;
+        char *str_ptr2;
+        char *str_ptr3;
+
+        str_ptr1 = XmTextGetString(coordinate_calc_array.input_lon_deg);
+        str_ptr2 = XmTextGetString(coordinate_calc_array.input_lon_min);
+        str_ptr3 = XmTextGetString(coordinate_calc_array.input_lon_dir);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%s %s%s",
+            str_ptr1, str_ptr2, str_ptr3);
+        XmTextSetString(coordinate_calc_longitude_northing, temp_string);
+        //fprintf(stderr,"String: %s\n", temp_string);
+        // We're done with these variables.  Free the space.
+        XtFree(str_ptr1);
+        XtFree(str_ptr2);
+        XtFree(str_ptr3);
+    }
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+void HandlePendingEvents( XtAppContext app) {
+    XEvent event;
+
+    while(XtAppPending(app)) {
+        XtAppNextEvent(app,&event);
+        (void)XtDispatchEvent(&event);
+    }
+}
+
+
+
+
+
+Boolean unbusy_cursor(XtPointer clientdata) {
+    Widget w = (Widget)clientdata;
+
+    (void)XUndefineCursor(XtDisplay(w),XtWindow(w));
+    return((Boolean)TRUE);
+}
+
+
+
+
+static Cursor cs = (Cursor)NULL;
+
+void busy_cursor(Widget w) {
+
+    if(!cs) {
+        cs=XCreateFontCursor(XtDisplay(w),XC_watch);
+    }
+
+    (void)XDefineCursor(XtDisplay(w),XtWindow(w),cs);
+    (void)XFlush(XtDisplay(w));
+
+    // This X11 function gets invoked when X11 decides that it has
+    // some free time.  We use that to advantage in making the busy
+    // cursor go away "magically" when we're not so busy.
+    //
+    (void)XtAppAddWorkProc(XtWidgetToApplicationContext(w),unbusy_cursor,(XtPointer)w);
+}
+
+
+
+
+
+// This function:
+// Draws the map data into "pixmap", copies "pixmap" to
+// "pixmap_alerts", draws alerts into "pixmap_alerts", copies
+// "pixmap_alerts" to "pixmap_final", draws symbols/tracks into
+// "pixmap_final" via a call to display_file().
+//
+// Other functions which call this function are responsible for
+// copying the image from pixmap_final() to the screen's drawing
+// area.
+//
+// We check for interrupt_drawing_now flag being set, and exit
+// nicely if so.  That flag means that some other drawing operation
+// needs to happen.
+//
+// Returns 0 if it gets interrupted, 1 if it completes.
+//
+int create_image(Widget w) {
+    Dimension width, height, margin_width, margin_height;
+    long lat_offset_temp;
+    long long_offset_temp;
+    char temp_course[20];
+    unsigned char   unit_type;
+    char medium_dashed[2] = {(char)5,(char)5};
+    long pos1_lat, pos1_lon, pos2_lat, pos2_lon;
+
+
+    //busy_cursor(w);
+    busy_cursor(appshell);
+
+    if (debug_level & 4)
+        fprintf(stderr,"Create image start\n");
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+
+    // If we're in the middle of ID'ing, wait a bit.
+    if (ATV_screen_ID && pending_ID_message)
+        usleep(2000000);    // 2 seconds
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+
+    /* First get the various dimensions */
+    XtVaGetValues(w,
+              XmNwidth,         &width,
+              XmNheight,        &height,
+              XmNmarginWidth,   &margin_width,
+              XmNmarginHeight,  &margin_height,
+              XmNunitType,      &unit_type,
+              NULL);
+
+    (void)XSetDashes(XtDisplay(w), gc, 0, medium_dashed , 2);
+
+    screen_width  = (long)width;
+    screen_height = (long)height;
+    long_offset_temp = NW_corner_longitude = center_longitude - (screen_width  * scale_x / 2);  // NW corner
+    lat_offset_temp  = NW_corner_latitude  = center_latitude  - (screen_height * scale_y / 2);
+
+    SE_corner_longitude = center_longitude + (screen_width * scale_x / 2);
+    SE_corner_latitude = center_latitude + (screen_height * scale_y / 2);
+
+    // Set up floating point lat/long values to match Xastir
+    // coordinates.
+    convert_from_xastir_coordinates(&f_NW_corner_longitude,
+        &f_NW_corner_latitude,
+        NW_corner_longitude,
+        NW_corner_latitude);
+    convert_from_xastir_coordinates(&f_SE_corner_longitude,
+        &f_SE_corner_latitude,
+        SE_corner_longitude,
+        SE_corner_latitude);
+
+    /* map default background color */
+    switch (map_background_color){
+        case 0 :
+            colors[0xfd] = GetPixelByName(appshell,"gray73");
+            break;
+
+        case 1 :
+            colors[0xfd] = GetPixelByName(w,"MistyRose");
+            break;
+
+        case 2 :
+            colors[0xfd] = GetPixelByName(w,"NavyBlue");
+            break;
+
+        case 3 :
+            colors[0xfd] = GetPixelByName(w,"SteelBlue");
+            break;
+
+        case 4 :
+            colors[0xfd] = GetPixelByName(w,"MediumSeaGreen");
+            break;
+
+        case 5 :
+            colors[0xfd] = GetPixelByName(w,"PaleGreen");
+            break;
+
+        case 6 :
+            colors[0xfd] = GetPixelByName(w,"PaleGoldenrod");
+            break;
+
+        case 7 :
+            colors[0xfd] = GetPixelByName(w,"LightGoldenrodYellow");
+            break;
+
+        case 8 :
+            colors[0xfd] = GetPixelByName(w,"RosyBrown");
+            break;
+
+        case 9 :
+            colors[0xfd] = GetPixelByName(w,"firebrick");
+            break;
+
+        case 10 :
+            colors[0xfd] = GetPixelByName(w,"white");
+            break;
+
+        case 11 :
+            colors[0xfd] = GetPixelByName(w, "black");
+            break;
+
+        default:
+            colors[0xfd] = GetPixelByName(appshell,"gray73");
+            map_background_color=0;
+            break;
+    }
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    (void)XSetForeground(XtDisplay(w),gc,colors[0xfd]);
+    (void)XSetBackground(XtDisplay(w),gc,colors[0xfd]);
+
+    (void)XFillRectangle(XtDisplay(w),
+        pixmap,
+        gc,
+        0,
+        0,
+        (unsigned int)screen_width,
+        (unsigned int)screen_height);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    statusline(langcode("BBARSTA003"),1);       // Loading Maps
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    if (display_up_first != 0) {
+        // clear the OSM function keys. If an OSM
+        // map is selected they will get re-initialized when
+        // the map is loaded.
+        init_OSM_values();
+        if (map_auto_maps && !disable_all_maps)
+            load_auto_maps(w,AUTO_MAP_DIR);
+        else if (!disable_all_maps)
+            load_maps(w);
+    }
+
+    if (!wx_alert_style)
+        statusline(langcode("BBARSTA034"),1);
+
+    // Update to screen
+//    (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    /* copy map data to alert pixmap */
+    (void)XCopyArea(XtDisplay(w),pixmap,pixmap_alerts,gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    if (!wx_alert_style && !disable_all_maps)
+        load_alert_maps(w, ALERT_MAP_DIR);  // These write onto pixmap_alerts
+
+    // Update to screen
+//    (void)XCopyArea(XtDisplay(da),pixmap_alerts,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    /* copy map and alert data to final pixmap */
+    (void)XCopyArea(XtDisplay(w),pixmap_alerts,pixmap_final,gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    wx_alert_update_list();
+
+    /* Compute distance */
+    if (lat_offset_temp<0l)
+        lat_offset_temp=0l;                     // max 90�N
+    else
+        if (lat_offset_temp>64800000l)
+            lat_offset_temp=64800000l;          // max 90�S
+
+    if(long_offset_temp<0l)
+        long_offset_temp=0l;                    // max 180�W
+    else
+        if (long_offset_temp>129600000l)
+            long_offset_temp=129600000l;        // max 180�E
+
+    pos1_lat = lat_offset_temp;
+    pos1_lon = long_offset_temp;
+    pos2_lat = lat_offset_temp;      // ??
+    pos2_lon = long_offset_temp+(50.0*scale_x);
+
+//    long_offset_temp = long_offset_temp+(50*scale_x);  // ??
+
+    if(pos2_lat < 0l)     // ??
+        pos2_lat = 0l;
+    else
+        if (pos2_lat > 64799999l)
+            pos2_lat = 64799999l;
+
+    if (pos2_lon < 0l)
+        pos2_lon = 0l;
+    else
+        if (pos2_lon > 129599999l)
+            pos2_lon = 129599999l;
+
+    // Get distance in nautical miles
+    x_screen_distance = (float)calc_distance_course(pos1_lat,
+        pos1_lon,
+        pos2_lat,
+        pos2_lon,
+        temp_course,
+        sizeof(temp_course) );
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    draw_grid(w);                       // Draw grid if enabled
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return(0);
+ 
+    display_file(w);                    // display stations (symbols, info, trails)
+
+    last_alert_redraw=sec_now();        // set last time of screen redraw
+
+    if (debug_level & 4)
+        fprintf(stderr,"Create image stop\n");
+
+    return(1);
+}
+
+
+
+
+
+// Routine used to refresh image WITHOUT reading regular map files
+// from disk.  It starts with the map data already in "pixmap",
+// copies "pixmap" to "pixmap_alerts", draws alerts into
+// "pixmap_alerts", copies "pixmap_alerts" to "pixmap_final", draws
+// symbols/tracks into "pixmap_final" via a call to display_file().
+//
+// Other functions which call this function are responsible for
+// copying the image from pixmap_final() to the screen's drawing
+// area.
+//
+void refresh_image(Widget w) {
+    Dimension width, height, margin_width, margin_height;
+    long lat_offset_temp;
+    long long_offset_temp;
+    char temp_course[20];
+    unsigned char   unit_type;
+    char medium_dashed[2] = {(char)5,(char)5};
+    long pos1_lat, pos1_lon, pos2_lat, pos2_lon;
+
+
+    //busy_cursor(w);
+    busy_cursor(appshell);
+
+    if (debug_level & 4)
+        fprintf(stderr,"Refresh image start\n");
+
+    // If we're in the middle of ID'ing, wait a bit.
+    if (ATV_screen_ID && pending_ID_message) 
+        usleep(2000000);    // 2 seconds
+
+    /* First get the various dimensions */
+    XtVaGetValues(w,
+              XmNwidth,         &width,
+              XmNheight,        &height,
+              XmNmarginWidth,   &margin_width,
+              XmNmarginHeight,  &margin_height,
+              XmNunitType,      &unit_type,
+              NULL);
+
+    (void)XSetDashes(XtDisplay(w), gc, 0, medium_dashed , 2);
+
+    screen_width  = (long)width;
+    screen_height = (long)height;
+
+    long_offset_temp = NW_corner_longitude = center_longitude - (screen_width * scale_x / 2);
+    NW_corner_latitude     = center_latitude - (screen_height * scale_y / 2);
+    lat_offset_temp  = center_latitude;
+
+    SE_corner_longitude = center_longitude + (screen_width * scale_x / 2);
+    SE_corner_latitude = center_latitude + (screen_height * scale_y / 2);
+
+    // Set up floating point lat/long values to match Xastir
+    // coordinates.
+    convert_from_xastir_coordinates(&f_NW_corner_longitude,
+        &f_NW_corner_latitude,
+        NW_corner_longitude,
+        NW_corner_latitude);
+    convert_from_xastir_coordinates(&f_SE_corner_longitude,
+        &f_SE_corner_latitude,
+        SE_corner_longitude,
+        SE_corner_latitude);
+
+    (void)XSetForeground(XtDisplay(w),gc,colors[0xfd]);
+    (void)XSetBackground(XtDisplay(w),gc,colors[0xfd]);
+
+    /* copy over map data to alert pixmap */
+    (void)XCopyArea(XtDisplay(w),pixmap,pixmap_alerts,gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+    if (!wx_alert_style && !disable_all_maps) {
+            statusline(langcode("BBARSTA034"),1);
+            load_alert_maps(w, ALERT_MAP_DIR);  // These write onto pixmap_alerts
+    }
+
+    /* copy over map and alert data to final pixmap */
+    (void)XCopyArea(XtDisplay(w),pixmap_alerts,pixmap_final,gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+//    statusline("Weather Alert Maps Loaded",1);
+
+    wx_alert_update_list();
+
+    /* Compute distance */
+    if (lat_offset_temp<0l)
+        lat_offset_temp=0l;                     // max 90�N
+    else
+        if (lat_offset_temp>64800000l)
+            lat_offset_temp=64800000l;          // max 90�S
+
+    if(long_offset_temp<0l)
+        long_offset_temp=0l;                    // max 180�W
+    else
+        if (long_offset_temp>129600000l)
+            long_offset_temp=129600000l;        // max 180�E
+
+    pos1_lat = lat_offset_temp;
+    pos1_lon = long_offset_temp;
+    pos2_lat = lat_offset_temp;      // ??
+    pos2_lon = long_offset_temp+(50.0*scale_x);
+
+//    long_offset_temp = long_offset_temp+(50*scale_x);  // ??
+
+    if(pos2_lat < 0l)     // ??
+        pos2_lat = 0l;
+    else
+        if (pos2_lat > 64799999l)
+            pos2_lat = 64799999l;
+
+    if (pos2_lon < 0l)
+        pos2_lon = 0l;
+    else
+        if (pos2_lon > 129599999l)
+            pos2_lon = 129599999l;
+
+    // Get distance in nautical miles
+    x_screen_distance = (float)calc_distance_course(pos1_lat,
+        pos1_lon,
+        pos2_lat,
+        pos2_lon,
+        temp_course,
+        sizeof(temp_course) );
+
+    // Draw grid if enabled
+    draw_grid(w);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return;
+ 
+    /* display icons */
+    display_file(w);
+
+    /* set last time of screen redraw*/
+    last_alert_redraw=sec_now();
+
+    // We just refreshed the screen, so don't try to erase any
+    // zoom-in boxes via XOR.
+    zoom_box_x1 = -1;
+
+    if (debug_level & 4)
+        fprintf(stderr,"Refresh image stop\n");
+}
+
+
+
+
+
+// And this function is even faster yet.  It snags "pixmap_alerts",
+// which already has map and alert data drawn into it, copies it to
+// pixmap_final, then draws symbols and tracks on top of it.  When
+// done it copies the image to the drawing area, making it visible.
+void redraw_symbols(Widget w) {
+
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now)
+        return;
+
+    // If we're in the middle of ID'ing, wait a bit.
+    if (ATV_screen_ID && pending_ID_message)
+        usleep(2000000);    // 2 seconds
+
+    /* copy over map and alert data to final pixmap */
+    if(!wait_to_redraw) {
+
+        (void)XCopyArea(XtDisplay(w),pixmap_alerts,pixmap_final,gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+
+        draw_grid(w);           // draw grid if enabled
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now)
+            return;
+
+        display_file(w);        // display stations (symbols, info, trails)
+
+        (void)XCopyArea(XtDisplay(w),pixmap_final,XtWindow(w),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+    }
+    else {
+        fprintf(stderr,"wait_to_redraw\n");
+    }
+
+    // We just refreshed the screen, so don't try to erase any
+    // zoom-in boxes via XOR.
+    zoom_box_x1 = -1;
+}
+
+
+
+
+
+static void TrackMouse( /*@unused@*/ Widget w, XtPointer clientData, XEvent *event, /*@unused@*/ Boolean *flag) {
+    char my_text[70];
+    char str_lat[20];
+    char str_long[20];
+    long x, y;
+    //beg
+    char temp_my_distance[20];
+    char temp_my_course[20];
+    char temp1_my_course[20];
+    long ml_lat, ml_lon;
+    float value;
+    //end
+
+
+    Widget textarea = (Widget) clientData;
+
+    x = (center_longitude - ((screen_width  * scale_x)/2) + (event->xmotion.x * scale_x));
+    y = (center_latitude  - ((screen_height * scale_y)/2) + (event->xmotion.y * scale_y));
+
+    if (x < 0)
+//        x = 0l;                 // 180�W
+        return;
+
+    if (x > 129600000l)
+//        x = 129600000l;         // 180�E
+        return;
+
+    if (y < 0)
+//        y = 0l;                 //  90�N
+        return;
+
+    if (y > 64800000l)
+//        y = 64800000l;          //  90�S
+        return;
+
+    if (DISPLAY_XASTIR_COORDINATES) {
+        xastir_snprintf(my_text, sizeof(my_text), "%ld  %ld", y, x);
+    }
+    else if (coordinate_system == USE_UTM
+            || coordinate_system == USE_UTM_SPECIAL) {
+        // Create a UTM string from coordinate in Xastir coordinate
+        // system.
+        convert_xastir_to_UTM_str(my_text, sizeof(my_text), x, y);
+    }
+    else if (coordinate_system == USE_MGRS) {
+        // Create an MGRS string from coordinate in Xastir
+        // coordinate system.
+        convert_xastir_to_MGRS_str(my_text, sizeof(my_text), x, y, 0);
+    }
+    else {
+        // Create a lat/lon string from coordinate in Xastir
+        // coordinate system.
+        if (coordinate_system == USE_DDDDDD) {
+            convert_lat_l2s(y, str_lat, sizeof(str_lat), CONVERT_DEC_DEG);
+            convert_lon_l2s(x, str_long, sizeof(str_long), CONVERT_DEC_DEG);
+        } else if (coordinate_system == USE_DDMMSS) {
+            convert_lat_l2s(y, str_lat, sizeof(str_lat), CONVERT_DMS_NORMAL_FORMATED);
+            convert_lon_l2s(x, str_long, sizeof(str_long), CONVERT_DMS_NORMAL_FORMATED);
+            //str_lat[2]='�'; str_long[3]='�';
+            //str_lat[5]='\''; str_long[6]='\'';
+        } else {    // Assume coordinate_system == USE_DDMMMM
+            convert_lat_l2s(y, str_lat, sizeof(str_lat), CONVERT_HP_NORMAL_FORMATED);
+            convert_lon_l2s(x, str_long, sizeof(str_long), CONVERT_HP_NORMAL_FORMATED);
+            //str_lat[2]='�'; str_long[3]='�';
+        }
+        xastir_snprintf(my_text, sizeof(my_text), "%s  %s", str_lat, str_long);
+    }
+
+    strncat(my_text,
+        "  ",
+        sizeof(my_text) - 1 - strlen(my_text));
+
+    strncat(my_text,
+        sec_to_loc(x,y),
+        sizeof(my_text) - 1 - strlen(my_text));
+
+    // begin dist/bearing
+    if ( do_dbstatus ) {
+        ml_lat = convert_lat_s2l(my_lat);
+        ml_lon = convert_lon_s2l(my_long);
+
+        // Get distance in nautical miles.
+        value = (float)calc_distance_course(ml_lat,ml_lon,y,x,
+                temp1_my_course,sizeof(temp1_my_course));
+
+        // n7tap: This is a quick hack to get some more useful values for
+        //        distance to near ojects.
+        // (copied from db.c:station_data_fill_in)
+        if (english_units) {
+            if (value*1.15078 < 0.99) {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    "%d %s",
+                    (int)(value*1.15078*1760),
+                    langcode("SPCHSTR004"));    // yards
+            } 
+            else {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    langcode("WPUPSTI020"),     // miles
+                    value*1.15078);
+            }
+        }
+        else {
+            if (value*1.852 < 0.99) {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    "%d %s",
+                    (int)(value*1.852*1000),
+                    langcode("UNIOP00031"));    // 'm' as in meters
+            }
+            else {
+                xastir_snprintf(temp_my_distance,
+                    sizeof(temp_my_distance),
+                    langcode("WPUPSTI021"),     // km
+                    value*1.852);
+            }
+        }
+        xastir_snprintf(temp_my_course, sizeof(temp_my_course), "%s�",temp1_my_course);
+
+
+        strncat(my_text,
+            " ",
+            sizeof(my_text) - 1 - strlen(my_text));
+
+        strncat(my_text,
+            temp_my_distance,
+            sizeof(my_text) - 1 - strlen(my_text));
+
+        strncat(my_text,
+            " ",
+            sizeof(my_text) - 1 - strlen(my_text));
+
+        strncat(my_text,
+            temp_my_course,
+            sizeof(my_text) - 1 - strlen(my_text));
+    }
+
+    XmTextFieldSetString(textarea, my_text);
+    XtManageChild(textarea);
+}
+
+
+
+
+
+static void ClearTrackMouse( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XEvent *event, /*@unused@*/ Boolean *flag) {
+// N7TAP: In my opinion, it is handy to have the cursor position still displayed
+//        in the xastir window when I switch to another (like to write it down...)
+//    Widget textarea = (Widget) clientData;
+//    XmTextFieldSetString(textarea," ");
+//    XtManageChild(textarea);
+}
+
+
+
+
+
+/*
+ *  Delete tracks of all stations
+ */
+void Tracks_All_Clear( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    DataRow *p_station;
+
+    p_station = n_first;
+    while (p_station != 0) {
+        if (delete_trail(p_station))
+        redraw_on_new_data=2;
+        p_station = p_station->n_next;
+    }
+}
+
+
+
+
+
+// Get a pointer to the first station record.  Loop through all
+// station records and clear out the tactical_call_sign fields in
+// each.
+// 
+void clear_all_tactical(void) {
+    DataRow *p_station = n_first;
+
+    // Run through the name-ordered list of records
+    while (p_station != 0) {
+        if (p_station->tactical_call_sign) {
+            // One found.  Free it.
+            free(p_station->tactical_call_sign);
+            p_station->tactical_call_sign = NULL;
+        }
+        p_station = p_station->n_next;
+    }
+    fprintf(stderr,"Cleared all tactical calls\n");
+}
+
+
+
+
+
+/*
+ *  Clear all tactical callsigns from the station records.  Comment
+ *  out the active records in the log file.
+ */
+void Tactical_Callsign_Clear( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char *ptr;
+    char file[200];
+    char file_temp[200];
+    FILE *f;
+    FILE *f_temp;
+    char line[300];
+    int ret;
+
+
+    // Loop through all station records and clear out the
+    // tactical_call_sign fields in each.
+    clear_all_tactical();
+
+    // Get rid of the tactical callsign hash here
+    destroy_tactical_hash();
+
+    get_user_base_dir("config/tactical_calls.log", file, sizeof(file));
+
+    get_user_base_dir("config/tactical_calls-temp.log", file_temp, 
+                            sizeof(file_temp));
+
+    // Our own internal function from util.c
+    ret = copy_file(file, file_temp);
+    if (ret) {
+        fprintf(stderr,"\n\nCouldn't create temp file %s!\n\n\n",
+            file_temp);
+        return;
+    }
+
+    // Comment out all active lines in the log file via a '#' mark.
+    // Read one line at a time from the temp file.  Add a '#'
+    // mark to the line if it doesn't already have it, then write
+    // that line to the original file.
+    f_temp=fopen(file_temp,"r");
+    f=fopen(file,"w");
+
+    if (f == NULL) {
+        fprintf(stderr,"Couldn't open %s\n",file);
+        return;
+    }
+    if (f_temp == NULL) {
+        fprintf(stderr,"Couldn't open %s\n",file_temp);
+        return;
+    }
+
+    // Read lines from the temp file and write them to the standard
+    // file, modifying them as necessary.
+    while (fgets(line, 300, f_temp) != NULL) {
+
+        if (line[0] != '#') {
+            fprintf(f,"#%s",line);
+        }
+        else {
+            fprintf(f,"%s",line);
+        }
+    }
+    fclose(f);
+    fclose(f_temp);
+}
+
+
+
+
+
+/*
+ *  Clear out tactical callsign log file
+ */
+void Tactical_Callsign_History_Clear( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char file[MAX_VALUE];
+    FILE *f;
+
+    // Loop through all station records and clear out the
+    // tactical_call_sign fields in each.
+    clear_all_tactical();
+
+    // Get rid of the tactical callsign hash here
+    destroy_tactical_hash();
+
+    // Wipe out the log file.
+    get_user_base_dir("config/tactical_calls.log", file, sizeof(file));
+
+    f=fopen(file,"w");
+    if (f!=NULL) {
+        (void)fclose(f);
+
+        if (debug_level & 1)
+            fprintf(stderr,"Clearing tactical callsign file...\n");
+    }
+    else {
+        fprintf(stderr,"Couldn't open file for writing: %s\n", file);
+    }
+
+    fprintf(stderr,"Cleared tactical call history file\n");
+}
+
+
+
+
+
+/*
+ *  Display text in the status line, text is removed after timeout
+ */
+void statusline(char *status_text,int update) {
+
+    XmTextFieldSetString (text, status_text);
+    last_statusline = sec_now();    // Used for auto-ID timeout
+//    if (update != 0)
+//        XmUpdateDisplay(text);      // do an immediate update
+}
+
+
+
+
+
+/*  print a message on standard error and display the same message
+ *   on the status line of the user interface.
+*/
+void stderr_and_statusline(char *message) { 
+   fprintf(stderr,"%s",message);
+   if (message[strlen(message)-1]=='\n') { 
+       // if there is a terminal new line character remove it.
+       message[strlen(message)-1]='\0';
+   }
+   statusline(message,1);
+   XmUpdateDisplay(text);      // force an immediate update
+}
+
+
+
+
+
+//
+// Check for statusline timeout and replace statusline text with a
+// station identification message.
+//
+// ID was requested so that Xastir could be used for a live fast-scan
+// TV display over amateur radio without having to identify the
+// station in some other manner.  As long as we guarantee that we'll
+// see this line for a few seconds each 10 minutes (30 minutes for
+// Canada), we should be within the ID rules.
+//
+void check_statusline_timeout(int curr_sec) {
+    char status_text[100];
+    int id_interval = (int)(9.5 * 60);
+//    int id_interval = (int)(1 * 5);  // Debug
+
+
+    if ( (last_statusline != 0
+            && (last_statusline < curr_sec - STATUSLINE_ACTIVE))
+        || (last_id_time < curr_sec - id_interval) ) {
+
+
+        // We save last_id_time and identify for a few seconds if
+        // we haven't identified for the last nine minutes or so.
+
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA040"),
+            my_callsign);
+
+        XmTextFieldSetString(text, status_text);
+
+        if (last_id_time < curr_sec - id_interval) {
+            popup_ID_message(langcode("BBARSTA040"),status_text);
+#ifdef HAVE_FESTIVAL
+            if (festival_speak_ID) {
+                char my_speech_callsign[100];
+
+                xastir_snprintf(my_speech_callsign,
+                    sizeof(my_speech_callsign),
+                    "%s",
+                    my_callsign);
+                spell_it_out(my_speech_callsign, 100);
+                xastir_snprintf(status_text,
+                    sizeof(status_text),
+                    langcode ("BBARSTA040"),
+                    my_speech_callsign);
+                SayText(status_text);
+            }
+#endif  // HAVE_FESTIVAL
+        }
+
+        last_statusline = 0;    // now inactive
+
+        // Guarantee that the ID text will be viewable for a few
+        // seconds if we haven't identified recently.  Note that the
+        // sleep statement puts the entire main thread to sleep for
+        // that amount of time.  The application will be unresponsive
+        // during that time.
+
+        if (last_id_time < (curr_sec - (9 * 60))) {
+            //fprintf(stderr,"Identifying at nine minutes\n");
+            //sleep(1);
+        }
+
+        last_id_time = curr_sec;
+    }
+}
+
+
+
+
+
+/*
+ *  Display current zoom factor
+ *
+ *  DK7IN: we should find a new measure, we now have different x/y scaling!
+ *         I now only use the y value
+ */
+void display_zoom_status(void) {
+    char zoom[30];
+    char siz_str[6];
+
+    if (scale_y < 9000)
+        xastir_snprintf(siz_str, sizeof(siz_str), "%ld", scale_y);
+    else
+        xastir_snprintf(siz_str, sizeof(siz_str), "%ldk", scale_y/1024);
+
+    if (track_station_on == 1)
+        xastir_snprintf(zoom, sizeof(zoom), langcode("BBARZM0002"), siz_str);
+    else
+        xastir_snprintf(zoom, sizeof(zoom), langcode("BBARZM0001"), siz_str);
+
+    XmTextFieldSetString(text4,zoom);
+}
+
+
+
+
+
+void Change_debug_level_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    change_debug_level_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Change_debug_level_reset(Widget widget, XtPointer clientData, XtPointer callData) {
+    debug_level = 0;
+    XmTextSetString(debug_level_text, "0");
+//    Change_debug_level_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Change_debug_level_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp;
+    char temp_string[10];
+
+    temp = XmTextGetString(debug_level_text);
+
+    debug_level = atoi(temp);
+    if ( (debug_level < 0) || (debug_level > 32767) )
+        debug_level = 0;
+
+    XtFree(temp);
+
+    // Fill in the current value of debug_level
+    xastir_snprintf(temp_string, sizeof(temp_string), "%d", debug_level);
+    XmTextSetString(debug_level_text, temp_string);
+
+//    Change_debug_level_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Change_Debug_Level(Widget w, XtPointer clientData, XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_close,
+        button_reset;
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+    char temp_string[10];
+
+    if (!change_debug_level_dialog) {
+        change_debug_level_dialog = XtVaCreatePopupShell(langcode("PULDNFI007"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                NULL);
+
+        pane = XtVaCreateWidget("Change Debug Level pane",
+                xmPanedWindowWidgetClass,
+                change_debug_level_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Change Debug Level my_form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 3,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+
+
+        debug_level_text = XtVaCreateManagedWidget("Change_Debug_Level debug text",
+                xmTextWidgetClass,
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 4,
+                XmNwidth, ((5*7)+2),
+                XmNmaxLength, 4,
+                XmNbackground, colors[0x0f],
+                XmNtopOffset, 5,
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Fill in the current value of debug_level
+        xastir_snprintf(temp_string, sizeof(temp_string), "%d", debug_level);
+        XmTextSetString(debug_level_text, temp_string);
+
+        button_reset = XtVaCreateManagedWidget(langcode("UNIOP00033"),
+                xmPushButtonGadgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, debug_level_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, debug_level_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, debug_level_text,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_reset, XmNactivateCallback, Change_debug_level_reset, change_debug_level_dialog);
+        XtAddCallback(button_ok, XmNactivateCallback, Change_debug_level_change_data, change_debug_level_dialog);
+        XtAddCallback(button_close, XmNactivateCallback, Change_debug_level_destroy_shell, change_debug_level_dialog);
+
+        pos_dialog(change_debug_level_dialog);
+
+        delw = XmInternAtom(XtDisplay(change_debug_level_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(change_debug_level_dialog, delw, Change_debug_level_destroy_shell, (XtPointer)change_debug_level_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(change_debug_level_dialog,XtGrabNone);
+        fix_dialog_size(change_debug_level_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(change_debug_level_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(change_debug_level_dialog), XtWindow(change_debug_level_dialog));
+}
+
+
+
+
+
+#if !defined(NO_GRAPHICS) && defined(HAVE_MAGICK)
+void Gamma_adjust_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    gamma_adjust_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Gamma_adjust_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp;
+    char temp_string[10];
+
+    temp = XmTextGetString(gamma_adjust_text);
+
+    imagemagick_gamma_adjust = atof(temp);
+    if (imagemagick_gamma_adjust < -9.9)
+        imagemagick_gamma_adjust = -9.9;
+    else if (imagemagick_gamma_adjust > 9.9)
+        imagemagick_gamma_adjust = 9.9;
+
+    XtFree(temp);
+
+    xastir_snprintf(temp_string, sizeof(temp_string), "%+.1f", imagemagick_gamma_adjust);
+    XmTextSetString(gamma_adjust_text, temp_string);
+
+    // Set interrupt_drawing_now because conditions have changed
+    // (new map center).
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+void Gamma_adjust(Widget w, XtPointer clientData, XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_close;
+    Atom delw;
+    char temp_string[10];
+
+    if (!gamma_adjust_dialog) {
+        // Gamma Correction
+        gamma_adjust_dialog = XtVaCreatePopupShell(langcode("GAMMA002"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,        XmDESTROY,
+                XmNdefaultPosition,       FALSE,
+                NULL);
+
+        pane = XtVaCreateWidget("Adjust Gamma pane",
+                xmPanedWindowWidgetClass, gamma_adjust_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Adjust Gamma my_form",
+                xmFormWidgetClass,  pane,
+                XmNfractionBase,    5,
+                XmNautoUnmanage,    FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        gamma_adjust_text = XtVaCreateManagedWidget("Adjust Gamma text",
+                xmTextWidgetClass,        my_form,
+                XmNeditable,              TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive,             TRUE,
+                XmNshadowThickness,       1,
+                XmNcolumns,               4,
+                XmNwidth,                 4*10,
+                XmNmaxLength,             4,
+                XmNbackground,            colors[0x0f],
+                XmNtopOffset,             5,
+                XmNtopAttachment,         XmATTACH_FORM,
+                XmNbottomAttachment,      XmATTACH_NONE,
+                XmNleftAttachment,        XmATTACH_POSITION,
+                XmNleftPosition,          2,
+                XmNrightAttachment,       XmATTACH_POSITION,
+                XmNrightPosition,         3,
+                XmNnavigationType,        XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        xastir_snprintf(temp_string, sizeof(temp_string), "%+.1f", imagemagick_gamma_adjust);
+        XmTextSetString(gamma_adjust_text, temp_string);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, my_form,
+                XmNtopAttachment,        XmATTACH_WIDGET,
+                XmNtopWidget,            gamma_adjust_text,
+                XmNtopOffset,            5,
+                XmNbottomAttachment,     XmATTACH_FORM,
+                XmNbottomOffset,         5,
+                XmNleftAttachment,       XmATTACH_POSITION,
+                XmNleftPosition,         1,
+                XmNrightAttachment,      XmATTACH_POSITION,
+                XmNrightPosition,        2,
+                XmNnavigationType,       XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, my_form,
+                XmNtopAttachment,        XmATTACH_WIDGET,
+                XmNtopWidget,            gamma_adjust_text,
+                XmNtopOffset,            5,
+                XmNbottomAttachment,     XmATTACH_FORM,
+                XmNbottomOffset,         5,
+                XmNleftAttachment,       XmATTACH_POSITION,
+                XmNleftPosition,         3,
+                XmNrightAttachment,      XmATTACH_POSITION,
+                XmNrightPosition,        4,
+                XmNnavigationType,       XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok,
+                      XmNactivateCallback, Gamma_adjust_change_data,   gamma_adjust_dialog);
+        XtAddCallback(button_close,
+                      XmNactivateCallback, Gamma_adjust_destroy_shell, gamma_adjust_dialog);
+
+        pos_dialog(gamma_adjust_dialog);
+
+        delw = XmInternAtom(XtDisplay(gamma_adjust_dialog), "WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(gamma_adjust_dialog,
+                                delw, Gamma_adjust_destroy_shell, (XtPointer)gamma_adjust_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(gamma_adjust_dialog, XtGrabNone);
+        fix_dialog_size(gamma_adjust_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(gamma_adjust_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(gamma_adjust_dialog), XtWindow(gamma_adjust_dialog));
+}
+#endif  // NO_GRAPHICS && HAVE_MAGICK
+
+
+
+
+
+void Load_station_font(void) {
+    // Assign a font (or a different font) to the GC
+
+    // Free any old font first.  If we fail to assign a new font in
+    // the code here, can we get in a sitation where we are trying
+    // to draw without a font?
+    if (station_font != NULL) {
+        XFreeFont(XtDisplay(da), station_font);
+    }
+
+    // Load the new font from the FONT_STATION string
+    station_font = (XFontStruct *)XLoadQueryFont(XtDisplay(da), rotated_label_fontname[FONT_STATION]);
+
+    if (station_font == NULL) {    // Couldn't get the font!!!
+        char tempy[100];
+
+        fprintf(stderr,"Map_font_change_data: Couldn't load station font %s.  ",
+            rotated_label_fontname[FONT_STATION]);
+        fprintf(stderr,"Loading default station font instead.\n");
+
+        xastir_snprintf(tempy,
+            sizeof(tempy),
+            "Couldn't get font %s.  Loading default font instead.",
+            rotated_label_fontname[FONT_STATION]);
+        popup_message_always(langcode("POPEM00035"), tempy);
+
+        station_font = (XFontStruct *)XLoadQueryFont(XtDisplay(da), "fixed");
+        if (station_font == NULL) {    // Couldn't get the font!!!
+            fprintf(stderr,"Map_font_change_data: Couldn't load default station font.\n");
+
+            popup_message_always(langcode("POPEM00035"),
+                "Couldn't load default station font.");
+        }
+    }
+
+    // Assign the font to the GC.
+    if (station_font != NULL) {
+        XSetFont(XtDisplay(da), gc, station_font->fid);
+    }
+}
+
+
+
+
+
+// chose map label font
+void Map_font_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+    xfontsel_query = 0;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    map_font_dialog = (Widget)NULL;
+}
+
+
+
+
+
+// Function called by UpdateTime when xfontsel_query is non-zero.
+// Checks the pipe to see if xfontsel has sent anything to us yet.
+// If we get anything from the read, we should wait a small amount
+// of time and try another read, to make sure we don't get a partial
+// read the first time and quit.
+//
+void Query_xfontsel_pipe (void) {
+    char xfontsel_font[FONT_MAX][sizeof(rotated_label_fontname[0])];
+    struct timeval tmv;
+    fd_set rd;
+    int retval;
+    int fd;
+    int i;
+
+    for (i = 0; i < FONT_MAX; i++) {
+
+        //    if (fgets(xfontsel_font,sizeof(xfontsel_font),f_xfontsel_pipe)) {
+
+        // Find out the file descriptor associated with our pipe.
+        if (!f_xfontsel_pipe[i])
+            continue;
+        fd = fileno(f_xfontsel_pipe[i]);
+
+        FD_ZERO(&rd);
+        FD_SET(fd, &rd);
+        tmv.tv_sec = 0;
+        tmv.tv_usec = 1;    // 1 usec
+
+        // Do a non-blocking check of the read end of the pipe.
+        retval = select(fd+1,&rd,NULL,NULL,&tmv);
+
+        //fprintf(stderr,"1\n");
+
+        if (retval) {
+            int l = strlen(xfontsel_font[i]);
+
+            // We have something to process.  Wait a bit, then snag the
+            // data.
+            usleep(250000); // 250ms
+            
+            fgets(xfontsel_font[i],sizeof(xfontsel_font[0]),f_xfontsel_pipe[i]);
+ 
+            if (xfontsel_font[i][l-1] == '\n')
+                xfontsel_font[i][l-1] = '\0';
+            if (map_font_text[i] != NULL) {
+                XmTextSetString(map_font_text[i], xfontsel_font[i]);
+            }
+            pclose(f_xfontsel_pipe[i]);
+            f_xfontsel_pipe[i] = 0;
+            //fprintf(stderr,"Resetting xfontset_query\n");
+            xfontsel_query = 0;
+        }
+        else {
+            // Read nothing.  Let UpdateTime run this function again
+            // shortly.
+        }
+    }
+}
+
+
+
+
+ 
+void Map_font_xfontsel(Widget widget, XtPointer clientData, XtPointer callData) {
+
+#if defined(HAVE_XFONTSEL)
+ 
+    int fontsize = XTPOINTER_TO_INT(clientData);
+    char xfontsel[50];
+
+    /* invoke xfontsel -print and stick into map_font_text */
+    sprintf(xfontsel,
+        "%s -print -title \"xfontsel %d\"",
+        XFONTSEL_PATH,
+        fontsize);
+    if ((f_xfontsel_pipe[fontsize] = popen(xfontsel,"r"))) {
+
+        // Request UpdateTime to keep checking the pipe periodically
+        // using non-blocking reads.
+//fprintf(stderr,"Setting xfontsel_query\n");
+        xfontsel_query++;
+
+    } else {
+        perror("xfontsel");
+    }
+#endif  // HAVE_XFONTSEL
+}
+
+
+
+
+
+void Map_font_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp;
+    Widget shell = (Widget) clientData;
+    int i;
+
+
+    xfontsel_query = 0;
+
+    for (i = 0; i < FONT_MAX; i++) {
+        temp = XmTextGetString(map_font_text[i]);
+
+        xastir_snprintf(rotated_label_fontname[i],
+            sizeof(rotated_label_fontname[i]),
+            "%s",
+            temp);
+
+        XtFree(temp);
+        XmTextSetString(map_font_text[i], rotated_label_fontname[i]);
+    }
+
+    // Load a new font into the GC for the station font
+    Load_station_font();
+
+    // Set interrupt_drawing_now because conditions have changed
+    // (new map center).
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    map_font_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Map_font(Widget w, XtPointer clientData, XtPointer callData) {
+    static Widget  pane, my_form, fontname[FONT_MAX], button_ok,
+                button_cancel,button_xfontsel[FONT_MAX];
+    Atom delw;
+    int i;
+    Arg al[50];                 /* Arg List */
+    register unsigned int ac = 0; /* Arg Count */
+
+
+    if (!map_font_dialog) {
+        map_font_dialog = XtVaCreatePopupShell(langcode("MAPFONT002"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,        XmDESTROY,
+                XmNdefaultPosition,       FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Choose map labels font",
+                xmPanedWindowWidgetClass, map_font_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Map font my_form",
+                xmFormWidgetClass,  pane,
+                XmNfractionBase,    3,
+                XmNautoUnmanage,    FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        //        ac=0;
+        //        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        //        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+
+
+        for (i = 0; i < FONT_MAX; i++) {
+            char *fonttitle[FONT_MAX] = {"MAPFONT009","MAPFONT010","MAPFONT003",
+                                         "MAPFONT004","MAPFONT005","MAPFONT006",
+                                         "MAPFONT007","MAPFONT008","MAPFONT011"};
+            ac = 0;
+            if (i == 0) {
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNtopOffset, 10); ac++;
+            } else {
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+                XtSetArg(al[ac], XmNtopWidget, fontname[i-1]); ac++;
+            }
+            XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+            XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+            XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+            XtSetArg(al[ac], XmNwidth, 150); ac++;
+            XtSetArg(al[ac], XmNheight, 40); ac++;
+            XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
+            XtSetArg(al[ac], XmNforeground,colors[0x08]); ac++;
+            XtSetArg(al[ac], XmNbackground,colors[0xff]); ac++;
+            XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+            fontname[i] = XtCreateManagedWidget(langcode(fonttitle[i]),
+                                                xmLabelWidgetClass, 
+                                                my_form,
+                                                al, ac);
+            ac = 0;
+            if (i == 0) {
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNtopOffset, 10); ac++;
+            } else {
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+                XtSetArg(al[ac], XmNtopWidget, map_font_text[i-1]); ac++;
+            }
+            XtSetArg(al[ac], XmNeditable,              TRUE); ac++;
+            XtSetArg(al[ac], XmNcursorPositionVisible, TRUE); ac++;
+            XtSetArg(al[ac], XmNsensitive,             TRUE); ac++;
+            XtSetArg(al[ac], XmNshadowThickness,       1); ac++;
+            XtSetArg(al[ac], XmNcolumns,               60); ac++;
+            XtSetArg(al[ac], XmNwidth,                 (60*7)+2); ac++;
+            XtSetArg(al[ac], XmNmaxLength,             128); ac++;
+            XtSetArg(al[ac], XmNbackground,            colors[0x0f]); ac++;
+            XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_NONE); ac++;
+            XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
+            XtSetArg(al[ac], XmNleftWidget, fontname[i]); ac++;
+            XtSetArg(al[ac], XmNleftOffset, 10); ac++;
+            XtSetArg(al[ac], XmNheight, 40); ac++;
+            XtSetArg(al[ac], XmNrightAttachment,XmATTACH_NONE); ac++;
+            XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+            XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+            XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+            map_font_text[i] = XtCreateManagedWidget("Map font text",
+                                                       xmTextFieldWidgetClass, my_form,
+                                                       al, ac);
+
+            XmTextSetString(map_font_text[i], rotated_label_fontname[i]);
+
+            // Xfontsel
+            ac = 0;
+            if (i == 0) {
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+                XtSetArg(al[ac], XmNtopOffset, 10); ac++;
+            } else {
+                XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+                XtSetArg(al[ac], XmNtopWidget, button_xfontsel[i-1]); ac++;
+            }
+            XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+            XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
+            XtSetArg(al[ac], XmNleftWidget, map_font_text[i]); ac++;
+            XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+            XtSetArg(al[ac], XmNrightOffset, 10); ac++;
+            XtSetArg(al[ac], XmNheight, 40); ac++;
+            XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+            XtSetArg(al[ac], XmNforeground,colors[0x08]); ac++;
+            XtSetArg(al[ac], XmNbackground,colors[0xff]); ac++;
+            XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+            button_xfontsel[i] = XtCreateManagedWidget(langcode("PULDNMP015"),
+                                                         xmPushButtonGadgetClass, my_form,
+                                                         al,ac);
+
+#if defined(HAVE_XFONTSEL)
+            XtSetSensitive(button_xfontsel[i],TRUE);
+#else   // HAVE_FONTSEL
+            XtSetSensitive(button_xfontsel[i],FALSE);
+#endif  // HAVE_FONTSEL
+ 
+            XtAddCallback(button_xfontsel[i],
+                XmNactivateCallback,
+                Map_font_xfontsel,
+                INT_TO_XTPOINTER(i) );
+
+        }
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, my_form,
+                XmNtopAttachment,        XmATTACH_WIDGET,
+                XmNtopWidget,            map_font_text[FONT_MAX-1],
+                XmNtopOffset,            10,
+                XmNbottomAttachment,     XmATTACH_FORM,
+                XmNbottomOffset,         5,
+                XmNleftAttachment,       XmATTACH_POSITION,
+                XmNleftPosition,         1,
+                XmNrightAttachment,      XmATTACH_POSITION,
+                XmNrightPosition,        2,
+                XmNnavigationType,       XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, my_form,
+                XmNtopAttachment,        XmATTACH_WIDGET,
+                XmNtopWidget,            map_font_text[FONT_MAX-1],
+                XmNtopOffset,            10,
+                XmNbottomAttachment,     XmATTACH_FORM,
+                XmNbottomOffset,         5,
+                XmNleftAttachment,       XmATTACH_POSITION,
+                XmNleftPosition,         2,
+                XmNrightAttachment,      XmATTACH_POSITION,
+                XmNrightPosition,        3,
+                XmNnavigationType,       XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok,
+                      XmNactivateCallback, Map_font_change_data,   map_font_dialog);
+        XtAddCallback(button_cancel,
+                      XmNactivateCallback, Map_font_destroy_shell, map_font_dialog);
+
+        pos_dialog(map_font_dialog);
+
+        delw = XmInternAtom(XtDisplay(map_font_dialog), "WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(map_font_dialog,
+                                delw, Map_font_destroy_shell, (XtPointer)map_font_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(map_font_dialog, XtGrabNone);
+        fix_dialog_size(map_font_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(map_font_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(map_font_dialog), XtWindow(map_font_dialog));
+}
+
+
+
+
+
+// Used by view_gps_status() function below.  We must either expire
+// this data or associate a time with it on the display.
+char gps_status_save[100];
+time_t gps_status_save_time = 0;
+
+
+
+
+
+char *report_gps_status(void) {
+    static char gps_temp[100];
+    char temp2[20];
+
+    switch (gps_valid) {
+
+        case 8: // Simulation Mode
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS008") );  // "Simulation"
+            break;
+
+        case 7: // Manual Input Mode
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS009") );  // "Manual"
+            break;
+ 
+        case 6: // Estimated Fix (dead reckoning)
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS010") );  // "Estimated"
+            break;
+
+        case 5: // Float RTK
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS011") );  // "Float RTK"
+            break;
+
+        case 4: // RTK
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS012") );  // "RTK"
+            break;
+ 
+        case 3: // WAAS or PPS Fix
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS001") );  // "WAAS or PPS"
+            break;
+
+        case 2: // DGPS Fix
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS002") );  // "DGPS"
+            break;
+
+        case 1: // Valid SPS Fix
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS003") );  // "Valid SPS"
+            break;
+
+        case 0: // Invalid
+        default:
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                langcode("GPSS004") );  // "Invalid"
+            break;
+    }
+
+    xastir_snprintf(gps_temp,
+        sizeof(gps_temp),
+        "%s:%s %s:%s",
+        langcode("GPSS005"),    // "Sats/View"
+        gps_sats,
+        langcode("GPSS006"),    // "Fix"
+        temp2);
+
+    // Save it in global variable in case we request status via the
+    // menus.
+    xastir_snprintf(gps_status_save,
+        sizeof(gps_status_save),
+        "%s",
+        gps_temp);
+
+    gps_status_save_time = sec_now();
+ 
+    // Reset the variables.
+    xastir_snprintf(gps_sats, sizeof(gps_sats), "00");
+    gps_valid = 0;
+
+    return(gps_temp);
+}
+
+
+
+
+
+void view_gps_status(Widget w, XtPointer clientData, XtPointer callData) {
+
+    // GPS status data too old?
+    if ((gps_status_save_time + 30) >= sec_now()) {
+        // Nope, within 30 seconds
+        popup_message_always(langcode("PULDNVI015"),
+            gps_status_save);
+    }
+    else {
+        // Yes, GPS status data is old
+        popup_message_always(langcode("PULDNVI015"),
+            langcode("GPSS007") );
+            // "!GPS data is older than 30 seconds!"
+    }
+}
+
+
+
+
+
+void Compute_Uptime(Widget w, XtPointer clientData, XtPointer callData) {
+    char temp[200];
+    unsigned long runtime;
+    int days, hours, minutes, seconds;
+    char Days[6];
+    char Hours[7];
+    char Minutes[9];
+    char Seconds[9];
+
+    runtime = sec_now() - program_start_time;
+    days = runtime / 86400;
+    runtime = runtime - (days * 86400);
+    hours = runtime / 3600;
+    runtime = runtime - (hours * 3600);
+    minutes = runtime / 60;
+    seconds = runtime - (minutes * 60);
+
+    if (days == 1)
+        xastir_snprintf(Days,sizeof(Days),"%s",langcode("TIME001")); // Day
+    else
+        xastir_snprintf(Days,sizeof(Days),"%s",langcode("TIME002")); // Days
+
+
+    if (hours == 1)
+        xastir_snprintf(Hours,sizeof(Hours),"%s",langcode("TIME003")); // Hour
+    else
+        xastir_snprintf(Hours,sizeof(Hours),"%s",langcode("TIME004")); // Hours
+
+
+    if (minutes == 1)
+        xastir_snprintf(Minutes,sizeof(Minutes),"%s",langcode("TIME005")); // Minute
+    else
+        xastir_snprintf(Minutes,sizeof(Minutes),"%s",langcode("TIME006")); // Minutes
+ 
+
+    if (seconds == 1)
+        xastir_snprintf(Seconds,sizeof(Seconds),"%s",langcode("TIME007")); // Second
+    else
+        xastir_snprintf(Seconds,sizeof(Seconds),"%s",langcode("TIME008")); // Seconds
+
+
+    if (days != 0) {
+        xastir_snprintf(temp, sizeof(temp), "%d %s, %d %s, %d %s, %d %s",
+            days, Days, hours, Hours, minutes, Minutes, seconds, Seconds);
+    } else if (hours != 0) {
+        xastir_snprintf(temp, sizeof(temp), "%d %s, %d %s, %d %s",
+           hours, Hours, minutes, Minutes, seconds, Seconds);
+    } else if (minutes != 0) {
+        xastir_snprintf(temp, sizeof(temp), "%d %s, %d %s", minutes, Minutes, seconds, Seconds);
+    } else {
+        xastir_snprintf(temp, sizeof(temp), "%d %s", seconds, Seconds);
+    }
+    popup_message_always(langcode("PULDNVI014"),temp);
+}
+
+
+
+
+
+void Mouse_button_handler (Widget w, Widget popup, XButtonEvent *event) {
+
+    // Snag the current pointer position
+    input_x = event->x;
+    input_y = event->y;
+
+    if (event->type == ButtonPress) {
+        //fprintf(stderr,"Mouse_button_handler, button pressed %d\n", event->button);
+    }
+
+    if (event->type == ButtonRelease) {
+        //fprintf(stderr,"Mouse_button_handler, button released %d\n", event->button);
+        return;
+    }
+
+#ifdef SWAP_MOUSE_BUTTONS
+    if (event->button != Button1) {
+        //fprintf(stderr,"Pressed a mouse button, but not Button1: %x\n",event->button);
+#else   // SWAP_MOUSE_BUTTONS
+    if (event->button != Button3) {
+        //fprintf(stderr,"Pressed a mouse button, but not Button3: %x\n",event->button);
+#endif  // SWAP_MOUSE_BUTTONS
+        return;
+    }
+
+    // Right mouse button press
+    menu_x=input_x;
+    menu_y=input_y;
+    if (right_menu_popup != NULL) { // If popup menu defined
+
+#ifdef SWAP_MOUSE_BUTTONS
+        // This gets the menus out of the way that are on pointer
+        // button1 if SWAP_MOUSE_BUTTONS is enabled.  If it's not
+        // enabled, they don't interfere with each other anyway.
+        if (!measuring_distance && !moving_object) {
+#else   // SWAP_MOUSE_BUTTONS
+        if (1) {    // Always bring up the menu if SWAP is disabled
+#endif  // SWAP_MOUSE_BUTTONS
+
+            // Bring up the popup menu
+            XmMenuPosition(right_menu_popup,(XButtonPressedEvent *)event);
+            XtManageChild(right_menu_popup);
+
+            // Check whether any modifiers are pressed.
+            // If so, pop up a warning message.
+            if ( (event->state != 0) && warn_about_mouse_modifiers) {
+                popup_message_always(langcode("POPUPMA023"),langcode("POPUPMA024"));
+            }
+        }
+    }
+}
+
+
+
+
+
+void menu_link_for_mouse_menu(Widget w, XtPointer clientData, XtPointer callData) {
+    if (right_menu_popup!=NULL) {
+        //XmMenuPosition(right_menu_popup,(XButtonPressedEvent *)event);
+        XtManageChild(right_menu_popup);
+    }
+}
+
+
+
+
+
+void store_all_kml_callback(/*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    export_trail_as_kml(NULL);
+    last_kmlsnapshot = sec_now();
+}
+
+
+
+
+void KML_Snapshots_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    // Whether we're setting or unsetting it, set the timer such
+    // that a snapshot will occur immediately once the button is set
+    // again.
+    last_kmlsnapshot = 0;
+
+    if(state->set)
+        kmlsnapshots_enabled = atoi(which);
+    else
+        kmlsnapshots_enabled = 0;
+}
+
+
+
+
+
+void Snapshots_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    // Whether we're setting or unsetting it, set the timer such
+    // that a snapshot will occur immediately once the button is set
+    // again.
+    last_snapshot = 0;
+
+    if(state->set)
+        snapshots_enabled = atoi(which);
+    else
+        snapshots_enabled = 0;
+}
+
+
+
+
+
+inline int no_data_selected(void)
+{
+    return (
+        Select_.none || (
+            !Select_.mine &&
+            !Select_.net  && (
+                !Select_.tnc || (
+                    !Select_.direct && !Select_.via_digi
+                )
+            )
+        )
+    );
+}
+
+
+
+
+
+#ifdef ARROWS
+Widget pan_up_menu, pan_down_menu,
+        pan_left_menu, pan_right_menu,
+        zoom_in_menu, zoom_out_menu;
+#endif // ARROWS
+
+
+
+
+ 
+void create_appshell( /*@unused@*/ Display *display, char *app_name, /*@unused@*/ int app_argc, char ** app_argv) {
+    Pixmap icon_pixmap;
+    Atom WM_DELETE_WINDOW;
+    Widget children[9];         /* Children to manage */
+    Arg al[100];                 /* Arg List */
+    register unsigned int ac;   /* Arg Count */
+    /*popup menu widgets */
+    Widget zoom_in, zoom_out, zoom_sub, zoom_level, zl1, zl2, zl3,
+        zl4, zl5, zl6, zl7, zl8, zl9, zlC;
+    Widget sar_object_menu;
+    Widget CAD_sub, CAD1, CAD3, CAD4;
+    Widget pan_sub, pan_menu;
+    Widget move_my_sub, move_my_menu;
+    Widget pan_ctr, last_loc, station_info, send_message_to;
+    Widget set_object, modify_object;
+    Widget setmyposition, pan_up, pan_down, pan_left, pan_right;
+    /*menu widgets */
+    Widget sep;
+    Widget filepane, configpane, exitpane, mappane, viewpane,
+        stationspane, messagepane, ifacepane, helppane,
+        filter_data_pane, filter_display_pane, map_config_pane,
+        station_config_pane,
+        help_emergency_pane, help_emergency_button;
+
+    Widget display_button,
+        track_button, download_trail_button, station_clear_button,
+        tracks_clear_button, object_history_refresh_button,
+        object_history_clear_button, tactical_clear_button,
+        tactical_history_clear_button, uptime_button, aloha_button,
+        save_button,
+        file_button, open_file_button, exit_button,
+        view_button, view_messages_button, gps_status_button,
+        bullet_button, packet_data_button, mobile_button,
+        stations_button, localstations_button, laststations_button,
+        objectstations_button, objectmystations_button,
+        weather_button, wx_station_button, locate_button, geocode_place_button,
+        locate_place_button, jump_button, jump_button2, alert_button,
+        config_button, defaults_button, timing_button,
+        coordinates_button, station_button, map_lock_pan_zoom_button, map_disable_button,
+        map_button, map_auto_button, map_chooser_button,
+        map_grid_button, map_levels_button, map_labels_button,
+        map_fill_button, coordinate_calculator_button,
+        center_zoom_button,
+        Map_background_color_Pane, map_background_button,
+        map_pointer_menu_button, map_config_button,
+        station_config_button,
+        cad_draw_button, cad_show_label_button,
+        cad_show_probability_button, cad_show_area_button,
+        cad_show_comment_button,
+#if !defined(NO_GRAPHICS)
+        Raster_intensity_Pane, raster_intensity_button,
+#if defined(HAVE_MAGICK)
+        gamma_adjust_button, tiger_config_button,
+#endif  // HAVE_MAGICK
+#ifdef HAVE_LIBGEOTIFF
+        drg_config_button,
+#endif  // HAVE_LIBGEOTIFF
+#endif  // NO_GRAPHICS
+        font_button,
+        Map_station_label_Pane, map_station_label_button,
+        Map_icon_outline_Pane, map_icon_outline_button,
+        map_wx_alerts_button, index_maps_on_startup_button,
+        redownload_maps_button, flush_map_cache_button,
+        units_choice_button, dbstatus_choice_button,
+        iface_button, iface_connect_button,
+        tnc_logging, transmit_disable_toggle, net_logging,
+        igate_logging, wx_logging, message_logging,
+        wx_alert_logging, enable_snapshots, print_button,
+        test_button, debug_level_button, aa_button, speech_button,
+        smart_beacon_button, map_indexer_button,
+        map_all_indexer_button, auto_msg_set_button,
+        message_button, send_message_to_button,
+        show_pending_messages_button, enable_kmlsnapshots,
+        open_messages_group_button, clear_messages_button,
+        General_q_button, IGate_q_button, WX_q_button,
+        filter_data_button, filter_display_button,
+        draw_CAD_objects_menu,
+        store_data_pane, store_data_button, store_all_kml_button,
+#ifdef HAVE_DB        
+        store_all_db_button,
+#endif  // HAVE_DB
+        help_button, help_about, help_help;
+
+    char *title, *t;
+    int t_size;
+//    XWMHints *wm_hints; // Used for window manager hints
+    Dimension my_appshell_width, my_appshell_height;
+    Dimension da_width, da_height;
+    static XmFontListEntry font_entry;
+
+
+    if(debug_level & 8)
+        fprintf(stderr,"Create appshell start\n");
+
+/*
+    wm_hints = XAllocWMHints();
+    if (!wm_hints) {
+        fprintf(stderr,"Failure allocating memory: wm_hints\n");
+        exit(0);
+    }
+
+    // Set up the wm_hints struct
+    wm_hints->initial_state = NormalState;
+    wm_hints->input = True;
+    wm_hints->flags = StateHint | InputHint;
+*/
+
+
+    t = _("X Amateur Station Tracking and Information Reporting");
+    title = (char *)malloc(t_size = (strlen(t) + 42 + strlen(xastir_package)));
+    if (!title) {
+        fprintf(stderr,"Couldn't allocate memory for title\n");
+    }
+    else {
+        xastir_snprintf(title, t_size, "XASTIR");
+        strncat(title, " - ", t_size - 1 - strlen(title));
+        strncat(title, t, t_size - 1 - strlen(title));
+        strncat(title, " @ ", t_size - 1 - strlen(title));
+        (void)gethostname(&title[strlen(title)], 28);
+    }
+
+    // Allocate a couple of colors that we'll need before we get
+    // around to calling create_gc(), which creates the rest.
+    //
+    colors[0x08] = GetPixelByName(appshell,"black");
+    colors[0x0c] = GetPixelByName(appshell,"red");
+    colors[0xff] = GetPixelByName(appshell,"gray73");
+
+
+    ac = 0;
+
+
+
+// Snag border widths so that we can use them in the calculations
+// below.  If we fail to do this the size and offsets will be off by
+// the width of the borders added by the window manager.
+//
+// if (XGetGeometry(XtDisplay(da),
+//     XtWindow(appshell),
+//     &root_return,
+//     &x_return,
+//     &y_return,
+//     &width_return,
+//     &height_return,
+//     &border_width_return,
+//     &depth_return) ) == False) {
+//     fprintf(stderr,"Couldn't get window attributes\n");
+// }
+//
+// Another method:
+//
+// XWindowAttributes windowattr; // Defined in Xlib.h
+// Struct has x/y/width/height/border_width/depth fields.
+// if (XGetWindowAttributes(display,XtWindow(appshell),&windowattr) == 0) {
+//     fprintf(stderr,"Couldn't get window attributes\n")
+// }
+
+
+
+    // Set up the main window X/Y sizes and the minimum sizes
+    // allowable.
+    //
+    if ( (WidthValue|HeightValue) & geometry_flags ) {
+        //
+        // Size of Xastir was specified with a -geometry setting.
+        // Set up the window size.
+        //
+
+        my_appshell_width = (Dimension)geometry_width; // Used in offset equations below
+        my_appshell_height = (Dimension)geometry_height; // Used in offset equations below
+//fprintf(stderr,"gW:%d  gH:%d\n", geometry_width, geometry_height);
+//fprintf(stderr,"tW:%d  tH:%d\n", (int)my_appshell_width, (int)my_appshell_height);
+        if (my_appshell_width < 61)
+            my_appshell_width = 61;
+        if (my_appshell_height < 61)
+            my_appshell_height = 61;
+//fprintf(stderr,"tW:%d  tH:%d\n", (int)my_appshell_width, (int)my_appshell_height);
+        XtSetArg(al[ac], XmNwidth,  my_appshell_width);    ac++;
+        XtSetArg(al[ac], XmNheight, my_appshell_height);   ac++;
+//        XtSetArg(al[ac], XmNminWidth,         61);             ac++;
+//        XtSetArg(al[ac], XmNminHeight,        61);             ac++;
+// Lock the min size to the specified initial size for now, release
+// later after creating initial window.  Snagged this idea from the
+// Lincity project where they do similar things in "lcx11.c"
+//        XtSetArg(al[ac], XmNminWidth,  my_appshell_width);  ac++;
+//        XtSetArg(al[ac], XmNminHeight, my_appshell_height); ac++;
+    }
+    else {
+        // Size was NOT specified in a -geometry string.  Set to the
+        // size specified in the config file instead.
+        //
+        my_appshell_width = (Dimension)screen_width;
+        my_appshell_height = (Dimension)(screen_height + 60);
+        XtSetArg(al[ac], XmNwidth,  my_appshell_width);  ac++;
+        XtSetArg(al[ac], XmNheight, my_appshell_height); ac++;
+//        XtSetArg(al[ac], XmNminWidth,         61);             ac++;
+//        XtSetArg(al[ac], XmNminHeight,        61);             ac++;
+// Lock the min size to the specified initial size for now, release
+// later after creating initial window.  Got this idea from the
+// Lincity project where they do the similar things in "lcx11.c"
+//        XtSetArg(al[ac], XmNminWidth,  my_appshell_width);  ac++;
+//        XtSetArg(al[ac], XmNminHeight, my_appshell_height); ac++;
+    }
+
+
+// Set up default font
+    font1 = XLoadQueryFont(display, rotated_label_fontname[FONT_SYSTEM]);
+
+    if (font1 == NULL) {    // Couldn't get the font!!!
+        fprintf(stderr,"create_appshell: Couldn't load system font %s.  ",
+            rotated_label_fontname[FONT_SYSTEM]);
+        fprintf(stderr,"Loading default system font instead.\n");
+        font1 = XLoadQueryFont(display, "fixed");
+        if (font1 == NULL) {    // Couldn't get the font!!!
+            fprintf(stderr,"create_appshell: Couldn't load default system font, exiting.\n");
+            exit(1);
+        }
+        else {
+            // _Now_ we can do a popup message about the first error
+            // as we have a font to work with!
+            char tempy[100];
+
+            xastir_snprintf(tempy,
+                sizeof(tempy),
+                "Couldn't get font %s.  Loading default font instead.",
+                rotated_label_fontname[FONT_SYSTEM]);
+            popup_message_always(langcode("POPEM00035"), tempy);
+        }
+    }
+
+    font_entry = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONT, font1);
+    fontlist1 = XmFontListAppendEntry(NULL, font_entry);
+    XmFontListEntryFree(&font_entry);
+    XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+
+    // Set up the X/Y offsets for the main window
+    //
+    if ( (XValue|YValue) & geometry_flags ) {
+        Position my_x, my_y;
+
+        //
+        // Position of Xastir was specified with a -geometry setting.
+        // 
+        if (XNegative & geometry_flags) {
+            geometry_x = DisplayWidth(display, DefaultScreen(display) )
+                + geometry_x - (int)my_appshell_width;
+        }
+        if (YNegative & geometry_flags) {
+            geometry_y = DisplayHeight(display, DefaultScreen(display) )
+                + geometry_y - (int)my_appshell_height;
+        }
+        my_x = (Position)geometry_x;
+        my_y = (Position)geometry_y;
+        XtSetArg(al[ac], XmNx, my_x); ac++;
+        XtSetArg(al[ac], XmNy, my_y); ac++;
+    }
+    else {
+        //
+        // Position of Xastir was not specified.  Use the values
+        // from the config file
+        //
+/*
+// This doesn't position the widget in fvwm2.  Would hate to go back
+// to XSizeHints in order to make this work.
+fprintf(stderr,"Setting up widget's X/Y position at X:%d  Y:%d\n",
+    (int)screen_x_offset,
+    (int)screen_y_offset);
+
+        XtSetArg(al[ac], XmNx, screen_x_offset); ac++;  // Doesn't work here
+        XtSetArg(al[ac], XmNy, screen_y_offset); ac++;  // Doesn't work here
+*/
+    }
+
+
+    XtSetArg(al[ac], XmNallowShellResize, TRUE);            ac++;
+
+    if (title)
+        XtSetArg(al[ac], XmNtitle,        title);           ac++;
+ 
+    XtSetArg(al[ac], XmNdefaultPosition,  FALSE);           ac++;
+    XtSetArg(al[ac], XmNfontList,         fontlist1);       ac++;
+    XtSetArg(al[ac], XmNforeground,       MY_FG_COLOR);     ac++;
+    XtSetArg(al[ac], XmNbackground,       MY_BG_COLOR);     ac++;
+    //
+    // Set the above values into the appshell widget
+    //
+    XtSetValues(appshell, al, ac);
+
+
+    // Make at least one Motif call so that the next function won't
+    // result in this problem:  'Error: atttempt to add non-widget
+    // child "DropSiteManager" to parent "xastir"'.
+    //
+    (void) XmIsMotifWMRunning(appshell);
+
+
+    form = XtVaCreateWidget("create_appshell form",
+            xmFormWidgetClass,
+            appshell,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    /* Menu Bar */
+    ac = 0;
+    XtSetArg(al[ac], XmNshadowThickness, 1);                     ac++;
+    XtSetArg(al[ac], XmNalignment,       XmALIGNMENT_BEGINNING); ac++;
+    XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM);         ac++;
+    XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM);         ac++;
+    XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE);         ac++;
+    XtSetArg(al[ac], XmNbottomAttachment,XmATTACH_NONE);         ac++;
+    XtSetArg(al[ac], XmNforeground,      MY_FG_COLOR);           ac++;
+    XtSetArg(al[ac], XmNbackground,      MY_BG_COLOR);           ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    menubar = XmCreateMenuBar(form,
+            "create_appshell menubar",
+            al,
+            ac);
+
+    /*set args for color */
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground,   MY_FG_COLOR);        ac++;
+    XtSetArg(al[ac], XmNbackground,   MY_BG_COLOR);        ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,     fontlist1);          ac++;
+
+
+    /* menu bar */
+    filepane    = XmCreatePulldownMenu(menubar,"filepane",    al, ac);
+    viewpane    = XmCreatePulldownMenu(menubar,"viewpane",    al, ac);
+    mappane     = XmCreatePulldownMenu(menubar,"mappane",     al, ac);
+    stationspane= XmCreatePulldownMenu(menubar,"stationspane",al, ac);
+    messagepane = XmCreatePulldownMenu(menubar,"messagepane", al, ac);
+    ifacepane   = XmCreatePulldownMenu(menubar,"ifacepane",   al, ac);
+    helppane    = XmCreatePulldownMenu(menubar,"helppane",    al, ac);
+
+    file_button = XtVaCreateManagedWidget(langcode("MENUTB0001"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId, filepane,
+            XmNmnemonic,langcode_hotkey("MENUTB0001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    view_button = XtVaCreateManagedWidget(langcode("MENUTB0002"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId,viewpane,
+            XmNmnemonic,langcode_hotkey("MENUTB0002"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_button = XtVaCreateManagedWidget(langcode("MENUTB0004"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId,mappane,
+            XmNmnemonic,langcode_hotkey("MENUTB0004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    display_button = XtVaCreateManagedWidget(langcode("MENUTB0005"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId,stationspane,
+            XmNmnemonic,langcode_hotkey("MENUTB0005"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    message_button = XtVaCreateManagedWidget(langcode("MENUTB0006"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId,messagepane,
+            XmNmnemonic,langcode_hotkey("MENUTB0006"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    iface_button = XtVaCreateManagedWidget(langcode("MENUTB0010"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId,ifacepane,
+            XmNmnemonic,langcode_hotkey("MENUTB0010"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    help_button = XtVaCreateManagedWidget(langcode("MENUTB0009"),
+            xmCascadeButtonGadgetClass,
+            menubar,
+            XmNsubMenuId,helppane,
+            XmNmnemonic,langcode_hotkey("MENUTB0009"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtVaSetValues (menubar,XmNmenuHelpWidget,help_button,NULL);
+    /* end bar */
+
+    /* File */
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,     fontlist1);          ac++;
+
+
+    configpane  = XmCreatePulldownMenu(filepane,
+            "configpane",
+            al,
+            ac);
+
+    // Print button
+    print_button = XtVaCreateManagedWidget(langcode("PULDNFI015"),
+            xmPushButtonWidgetClass,
+            filepane,
+            XmNmnemonic, langcode_hotkey("PULDNFI015"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback( print_button, XmNactivateCallback, Print_Postscript, NULL );
+
+    config_button = XtVaCreateManagedWidget(langcode("PULDNFI001"),
+            xmCascadeButtonGadgetClass,
+            filepane,
+            XmNsubMenuId,configpane,
+            XmNmnemonic,langcode_hotkey("PULDNFI001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+   (void)XtVaCreateManagedWidget("create_appshell sep1",
+            xmSeparatorGadgetClass,
+            filepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    open_file_button = XtVaCreateManagedWidget(langcode("PULDNFI002"),
+            xmPushButtonGadgetClass,
+            filepane,
+            XmNmnemonic,langcode_hotkey("PULDNFI002"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    tnc_logging = XtVaCreateManagedWidget(langcode("PULDNFI010"),
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(tnc_logging,XmNvalueChangedCallback,TNC_Logging_toggle,"1");
+    if (log_tnc_data) 
+        XmToggleButtonSetState(tnc_logging,TRUE,FALSE);
+
+
+
+    net_logging = XtVaCreateManagedWidget(langcode("PULDNFI011"),
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(net_logging,XmNvalueChangedCallback,Net_Logging_toggle,"1");
+    if (log_net_data)
+        XmToggleButtonSetState(net_logging,TRUE,FALSE);
+
+
+    igate_logging = XtVaCreateManagedWidget(langcode("PULDNFI012"),
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(igate_logging,XmNvalueChangedCallback,IGate_Logging_toggle,"1");
+    if (log_igate)
+        XmToggleButtonSetState(igate_logging,TRUE,FALSE);
+
+//    message_logging = XtVaCreateManagedWidget(langcode("PULDNFI012"),
+    message_logging = XtVaCreateManagedWidget("Message Logging",
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(message_logging,XmNvalueChangedCallback,Message_Logging_toggle,"1");
+    if (log_message_data)
+        XmToggleButtonSetState(message_logging,TRUE,FALSE);
+
+    wx_logging = XtVaCreateManagedWidget(langcode("PULDNFI013"),
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(wx_logging,XmNvalueChangedCallback,WX_Logging_toggle,"1");
+    if (log_wx)
+        XmToggleButtonSetState(wx_logging,TRUE,FALSE);
+
+//    wx_alert_logging = XtVaCreateManagedWidget(langcode("PULDNFI013"),
+    wx_alert_logging = XtVaCreateManagedWidget("WX Alert Logging",
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(wx_alert_logging,XmNvalueChangedCallback,WX_Alert_Logging_toggle,"1");
+    if (log_wx_alert_data)
+        XmToggleButtonSetState(wx_alert_logging,TRUE,FALSE);
+
+    enable_snapshots = XtVaCreateManagedWidget(langcode("PULDNFI014"),
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(enable_snapshots,XmNvalueChangedCallback,Snapshots_toggle,"1");
+    if (snapshots_enabled)
+        XmToggleButtonSetState(enable_snapshots,TRUE,FALSE);
+
+    // enable kml snapshots
+    enable_kmlsnapshots = XtVaCreateManagedWidget(langcode("PULDNFI016"),
+            xmToggleButtonGadgetClass,
+            filepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(enable_kmlsnapshots,XmNvalueChangedCallback,KML_Snapshots_toggle,"1");
+    if (kmlsnapshots_enabled)
+        XmToggleButtonSetState(enable_kmlsnapshots,TRUE,FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep1a",
+            xmSeparatorGadgetClass,
+            filepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep1b",
+            xmSeparatorGadgetClass,
+            filepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    exitpane  = XmCreatePulldownMenu(filepane,
+            "exitpane",
+            al,
+            ac);
+
+    exit_button = XtVaCreateManagedWidget(langcode("PULDNFI004"),
+            xmPushButtonWidgetClass,
+            filepane,
+            XmNmnemonic,langcode_hotkey("PULDNFI004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    /* View */
+    packet_data_button = XtVaCreateManagedWidget(langcode("PULDNVI002"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI002"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    view_messages_button = XtVaCreateManagedWidget(langcode("PULDNVI011"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI011"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    bullet_button = XtVaCreateManagedWidget(langcode("PULDNVI001"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+ 
+    (void)XtVaCreateManagedWidget("create_appshell sep?",
+            xmSeparatorGadgetClass,
+            viewpane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    mobile_button = XtVaCreateManagedWidget(langcode("PULDNVI003"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI003"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    stations_button = XtVaCreateManagedWidget(langcode("PULDNVI004"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    localstations_button = XtVaCreateManagedWidget(langcode("PULDNVI009"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI009"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    laststations_button = XtVaCreateManagedWidget(langcode("PULDNVI012"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI012"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep1?",
+            xmSeparatorGadgetClass,
+            viewpane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    objectstations_button = XtVaCreateManagedWidget(langcode("LHPUPNI005"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("LHPUPNI005"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    objectmystations_button = XtVaCreateManagedWidget(langcode("LHPUPNI006"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("LHPUPNI006"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // "List All CAD Polygons"
+    CAD1 = XtVaCreateManagedWidget(langcode("POPUPMA046"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("POPUPMA046"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep2?",
+            xmSeparatorGadgetClass,
+            viewpane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    weather_button = XtVaCreateManagedWidget(langcode("PULDNVI005"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI005"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    wx_station_button = XtVaCreateManagedWidget(langcode("PULDNVI008"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI008"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    alert_button = XtVaCreateManagedWidget(langcode("PULDNVI007"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI007"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3?",
+            xmSeparatorGadgetClass,
+            viewpane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    gps_status_button = XtVaCreateManagedWidget(langcode("PULDNVI015"),
+            xmPushButtonGadgetClass,
+            viewpane,
+            XmNmnemonic,langcode_hotkey("PULDNVI015"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    uptime_button = XtVaCreateManagedWidget(langcode("PULDNVI013"),
+            xmPushButtonWidgetClass,
+            viewpane,
+            XmNmnemonic, langcode_hotkey("PULDNVI013"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    aloha_button = XtVaCreateManagedWidget(langcode("PULDNVI016"),
+            xmPushButtonWidgetClass,
+            viewpane,
+            XmNmnemonic, langcode_hotkey("PULDNVI016"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    /* Configure */
+    station_button = XtVaCreateManagedWidget(langcode("PULDNCF004"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("PULDNCF004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    defaults_button = XtVaCreateManagedWidget(langcode("PULDNCF001"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("PULDNCF001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    timing_button = XtVaCreateManagedWidget(langcode("PULDNCF003"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("PULDNCF003"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    coordinates_button = XtVaCreateManagedWidget(langcode("PULDNCF002"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("PULDNCF002"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    aa_button = XtVaCreateManagedWidget(langcode("PULDNCF006"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("PULDNCF006"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    speech_button = XtVaCreateManagedWidget(langcode("PULDNCF007"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("PULDNCF007"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    smart_beacon_button = XtVaCreateManagedWidget(langcode("SMARTB001"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic,langcode_hotkey("SMARTB001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // map label font select
+    font_button = XtVaCreateManagedWidget(langcode("PULDNMP025"),
+            xmPushButtonWidgetClass, configpane,
+            XmNmnemonic,langcode_hotkey("PULDNMP025"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(font_button, XmNactivateCallback, Map_font, NULL);
+
+    test_button = XtVaCreateManagedWidget(langcode("PULDNFI003"),
+            xmPushButtonWidgetClass,
+            configpane,
+            XmNmnemonic, langcode_hotkey("PULDNFI003"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    debug_level_button = XtVaCreateManagedWidget(langcode("PULDNFI007"),
+            xmPushButtonWidgetClass,
+            configpane,
+            XmNmnemonic, langcode_hotkey("PULDNFI007"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    units_choice_button = XtVaCreateManagedWidget(langcode("PULDNUT001"),
+            xmToggleButtonGadgetClass,
+            configpane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(units_choice_button,XmNvalueChangedCallback,Units_choice_toggle,"1");
+    if (english_units)
+        XmToggleButtonSetState(units_choice_button,TRUE,FALSE);
+
+    dbstatus_choice_button = XtVaCreateManagedWidget(langcode("PULDNDB001"),
+            xmToggleButtonGadgetClass,
+            configpane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(dbstatus_choice_button,XmNvalueChangedCallback,Dbstatus_choice_toggle,"1");
+    if (do_dbstatus)
+        XmToggleButtonSetState(dbstatus_choice_button,TRUE,FALSE);
+
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep1d",
+            xmSeparatorGadgetClass,
+            configpane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    save_button = XtVaCreateManagedWidget(langcode("PULDNCF008"),
+            xmPushButtonGadgetClass,
+            configpane,
+            XmNmnemonic, langcode_hotkey("PULDNCF008"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+
+//- Maps -------------------------------------------------------------
+
+    map_chooser_button = XtVaCreateManagedWidget(langcode("PULDNMP001"),
+            xmPushButtonGadgetClass,
+            mappane,
+            XmNmnemonic,langcode_hotkey("PULDNMP001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_chooser_button,   XmNactivateCallback,Map_chooser,NULL);
+
+    // Map Display Bookmarks
+    jump_button = XtVaCreateManagedWidget(langcode("PULDNMP012"),
+            xmPushButtonGadgetClass,
+            mappane,
+            XmNmnemonic,langcode_hotkey("PULDNMP012"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    locate_place_button = XtVaCreateManagedWidget(langcode("PULDNMP014"),
+            xmPushButtonGadgetClass,
+            mappane,
+            XmNmnemonic,langcode_hotkey("PULDNMP014"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    geocode_place_button = XtVaCreateManagedWidget(langcode("PULDNMP029"),
+            xmPushButtonGadgetClass,
+            mappane,
+            XmNmnemonic,langcode_hotkey("PULDNMP029"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    coordinate_calculator_button = XtVaCreateManagedWidget(langcode("COORD001"),
+            xmPushButtonGadgetClass,mappane,
+            XmNmnemonic, langcode_hotkey("COORD001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    center_zoom_button=XtVaCreateManagedWidget(langcode("POPUPMA026"),
+            xmPushButtonGadgetClass, mappane,
+            XmNmnemonic, langcode_hotkey("POPUPMA026"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(center_zoom_button,XmNactivateCallback,Center_Zoom,NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    CAD_sub=XmCreatePulldownMenu(mappane,
+            "create_appshell CAD sub",
+            al,
+            ac);
+
+    // "Draw CAD Objects"
+    draw_CAD_objects_menu=XtVaCreateManagedWidget(langcode("POPUPMA029"),
+            xmCascadeButtonGadgetClass,
+            mappane,
+            XmNsubMenuId,CAD_sub,
+//            XmNmnemonic,langcode_hotkey("POPUPMA029"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // "Draw Mode"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+//    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA031")); ac++;
+
+    // "Close Polygon"
+    CAD_close_polygon_menu_item=XtCreateManagedWidget(langcode("POPUPMA031"),
+            xmPushButtonGadgetClass,
+            CAD_sub,
+            al,
+            ac);
+    XtAddCallback(CAD_close_polygon_menu_item,XmNactivateCallback,Draw_CAD_Objects_close_polygon,NULL);
+    // disable the close polygon menu item if not in draw mode
+    if (draw_CAD_objects_flag==1)
+        XtSetSensitive(CAD_close_polygon_menu_item,TRUE);
+    if (draw_CAD_objects_flag==0)
+        XtSetSensitive(CAD_close_polygon_menu_item,FALSE);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+//    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA032")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    // "Erase CAD Polygons"
+    CAD3=XtCreateManagedWidget(langcode("POPUPMA032"),
+            xmPushButtonGadgetClass,
+            CAD_sub,
+            al,
+            ac);
+    XtAddCallback(CAD3,XmNactivateCallback,Draw_CAD_Objects_erase_dialog,NULL);
+
+    // "List All CAD Polygons"
+    CAD4 = XtVaCreateManagedWidget(langcode("POPUPMA046"),
+            xmPushButtonGadgetClass,
+            CAD_sub,
+            XmNmnemonic,langcode_hotkey("POPUPMA046"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(CAD4,XmNactivateCallback,Draw_CAD_Objects_list_dialog,NULL);
+   
+    // Toggles for CAD object information display on map
+    // Draw CAD Objects 
+    cad_draw_button = XtVaCreateManagedWidget(langcode("POPUPMA047"),
+            xmToggleButtonGadgetClass,
+            CAD_sub,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(cad_draw_button,XmNvalueChangedCallback,CAD_draw_toggle,"CAD_draw_objects");
+    if (CAD_draw_objects==TRUE)
+        XmToggleButtonSetState(cad_draw_button,TRUE,FALSE);
+
+    // Draw CAD Labels 
+    cad_show_label_button = XtVaCreateManagedWidget(langcode("POPUPMA048"),
+            xmToggleButtonGadgetClass,
+            CAD_sub,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(cad_show_label_button,XmNvalueChangedCallback,CAD_draw_toggle,"CAD_show_label");
+    if (CAD_show_label==TRUE)
+        XmToggleButtonSetState(cad_show_label_button,TRUE,FALSE);
+
+    // Draw CAD Probability
+    cad_show_probability_button = XtVaCreateManagedWidget(langcode("POPUPMA050"),
+            xmToggleButtonGadgetClass,
+            CAD_sub,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(cad_show_probability_button,XmNvalueChangedCallback,CAD_draw_toggle,"CAD_show_raw_probability");
+    if (CAD_show_raw_probability==TRUE)
+        XmToggleButtonSetState(cad_show_probability_button,TRUE,FALSE);
+
+    // Draw CAD Comments
+    cad_show_comment_button = XtVaCreateManagedWidget(langcode("POPUPMA049"),
+            xmToggleButtonGadgetClass,
+            CAD_sub,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(cad_show_comment_button,XmNvalueChangedCallback,CAD_draw_toggle,"CAD_show_comment");
+    if (CAD_show_comment==TRUE)
+        XmToggleButtonSetState(cad_show_comment_button,TRUE,FALSE);
+
+    // Draw CAD Size of Area
+    cad_show_area_button = XtVaCreateManagedWidget(langcode("POPUPMA051"),
+            xmToggleButtonGadgetClass,
+            CAD_sub,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(cad_show_area_button,XmNvalueChangedCallback,CAD_draw_toggle,"CAD_show_area");
+    if (CAD_show_area==TRUE)
+        XmToggleButtonSetState(cad_show_area_button,TRUE,FALSE);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep2",
+            xmSeparatorGadgetClass,
+            mappane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    map_lock_pan_zoom_button = XtVaCreateManagedWidget(langcode("PULDNMP016"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_lock_pan_zoom_button, XmNvalueChangedCallback, Map_lock_pan_zoom_toggle, "1");
+    if (map_lock_pan_zoom)
+        XmToggleButtonSetState(map_lock_pan_zoom_button, TRUE, FALSE);
+  
+ 
+    map_disable_button = XtVaCreateManagedWidget(langcode("PULDNMP013"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_disable_button, XmNvalueChangedCallback, Map_disable_toggle, "1");
+    if (disable_all_maps)
+        XmToggleButtonSetState(map_disable_button, TRUE, FALSE);
+
+
+    map_auto_button = XtVaCreateManagedWidget(langcode("PULDNMP002"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_auto_button,XmNvalueChangedCallback,Map_auto_toggle,"1");
+    if (map_auto_maps)
+        XmToggleButtonSetState(map_auto_button,TRUE,FALSE);
+
+
+    map_auto_skip_raster_button = XtVaCreateManagedWidget(langcode("PULDNMP021"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_auto_skip_raster_button,XmNvalueChangedCallback,Map_auto_skip_raster_toggle,"1");
+    if (auto_maps_skip_raster)
+        XmToggleButtonSetState(map_auto_skip_raster_button,TRUE,FALSE);
+    if (!map_auto_maps)
+        XtSetSensitive(map_auto_skip_raster_button,FALSE);
+
+
+    map_grid_button = XtVaCreateManagedWidget(langcode("PULDNMP003"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_grid_button,XmNvalueChangedCallback,Grid_toggle,"1");
+    if (long_lat_grid)
+        XmToggleButtonSetState(map_grid_button,TRUE,FALSE);
+
+    // Enable Map Border
+    map_border_button = XtVaCreateManagedWidget(langcode("PULDNMP031"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_border_button,XmNvalueChangedCallback,Map_border_toggle,"1");
+    if (draw_labeled_grid_border)  
+        XmToggleButtonSetState(map_border_button,TRUE,FALSE);
+    if (!long_lat_grid) 
+        XtSetSensitive(map_border_button,FALSE);
+    else 
+        XtSetSensitive(map_border_button,TRUE);
+
+
+    map_levels_button = XtVaCreateManagedWidget(langcode("PULDNMP004"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_levels_button,XmNvalueChangedCallback,Map_levels_toggle,"1");
+    if (map_color_levels)
+        XmToggleButtonSetState(map_levels_button,TRUE,FALSE);
+
+
+    map_labels_button = XtVaCreateManagedWidget(langcode("PULDNMP010"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_labels_button,XmNvalueChangedCallback,Map_labels_toggle,"1");
+    if (map_labels)
+        XmToggleButtonSetState(map_labels_button,TRUE,FALSE);
+
+
+    map_fill_button = XtVaCreateManagedWidget(langcode("PULDNMP009"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_fill_button,XmNvalueChangedCallback,Map_fill_toggle,"1");
+    if (map_color_fill)
+        XmToggleButtonSetState(map_fill_button,TRUE,FALSE);
+
+
+    map_wx_alerts_button = XtVaCreateManagedWidget(langcode("PULDNMP007"),
+            xmToggleButtonGadgetClass,
+            mappane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(map_wx_alerts_button,XmNvalueChangedCallback,Map_wx_alerts_toggle,"1");
+    if (!wx_alert_style)
+        XmToggleButtonSetState(map_wx_alerts_button,TRUE,FALSE);
+#ifndef HAVE_LIBSHP
+    // If we don't have Shapelib compiled in, grey-out the weather
+    // alerts button.
+    XtSetSensitive(map_wx_alerts_button, FALSE);
+#endif  // HAVE_LIBSHP
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep2b",
+            xmSeparatorGadgetClass,
+            mappane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep2c",
+            xmSeparatorGadgetClass,
+            mappane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    map_config_pane  = XmCreatePulldownMenu(mappane,
+            "map_config_pane",
+            al,
+            ac);
+
+    map_config_button = XtVaCreateManagedWidget(langcode("PULDNFI001"),
+            xmCascadeButtonGadgetClass,
+            mappane,
+            XmNsubMenuId,map_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNFI001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    // These go into the map config submenu
+    Map_background_color_Pane = XmCreatePulldownMenu(map_config_pane,
+            "create_appshell map_background_color",
+            al,
+            ac);
+
+    map_background_button = XtVaCreateManagedWidget(langcode("PULDNMP005"),
+            xmCascadeButtonWidgetClass,
+            map_config_pane,
+            XmNsubMenuId, Map_background_color_Pane,
+            XmNmnemonic, langcode_hotkey("PULDNMP005"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[10] = XtVaCreateManagedWidget(langcode("PULDNMBC11"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC11"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[11] = XtVaCreateManagedWidget(langcode("PULDNMBC12"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC12"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[0] = XtVaCreateManagedWidget(langcode("PULDNMBC01"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC01"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[1] = XtVaCreateManagedWidget(langcode("PULDNMBC02"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC02"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[2] = XtVaCreateManagedWidget(langcode("PULDNMBC03"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC03"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[3] = XtVaCreateManagedWidget(langcode("PULDNMBC04"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC04"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[4] = XtVaCreateManagedWidget(langcode("PULDNMBC05"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC05"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[5] = XtVaCreateManagedWidget(langcode("PULDNMBC06"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC06"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[6] = XtVaCreateManagedWidget(langcode("PULDNMBC07"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC07"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[7] = XtVaCreateManagedWidget(langcode("PULDNMBC08"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC08"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[8] = XtVaCreateManagedWidget(langcode("PULDNMBC09"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC09"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_bgcolor[9] = XtVaCreateManagedWidget(langcode("PULDNMBC10"),
+            xmPushButtonGadgetClass,
+            Map_background_color_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMBC10"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtSetSensitive(map_bgcolor[map_background_color],FALSE);
+    XtAddCallback(map_bgcolor[10], XmNactivateCallback,Map_background,"10");
+    XtAddCallback(map_bgcolor[11], XmNactivateCallback,Map_background,"11");
+    XtAddCallback(map_bgcolor[0],  XmNactivateCallback,Map_background,"0");
+    XtAddCallback(map_bgcolor[1],  XmNactivateCallback,Map_background,"1");
+    XtAddCallback(map_bgcolor[2],  XmNactivateCallback,Map_background,"2");
+    XtAddCallback(map_bgcolor[3],  XmNactivateCallback,Map_background,"3");
+    XtAddCallback(map_bgcolor[4],  XmNactivateCallback,Map_background,"4");
+    XtAddCallback(map_bgcolor[5],  XmNactivateCallback,Map_background,"5");
+    XtAddCallback(map_bgcolor[6],  XmNactivateCallback,Map_background,"6");
+    XtAddCallback(map_bgcolor[7],  XmNactivateCallback,Map_background,"7");
+    XtAddCallback(map_bgcolor[8],  XmNactivateCallback,Map_background,"8");
+    XtAddCallback(map_bgcolor[9],  XmNactivateCallback,Map_background,"9");
+
+#if !defined(NO_GRAPHICS)
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    Raster_intensity_Pane = XmCreatePulldownMenu(map_config_pane,
+            "create_appshell raster_intensity",
+            al,
+            ac);
+
+    raster_intensity_button = XtVaCreateManagedWidget(langcode("PULDNMP008"),
+            xmCascadeButtonWidgetClass,
+            map_config_pane,
+            XmNsubMenuId,
+            Raster_intensity_Pane,
+            XmNmnemonic, langcode_hotkey("PULDNMP008"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[0] = XtVaCreateManagedWidget("0%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"0%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[1] = XtVaCreateManagedWidget("10%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"10%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[2] = XtVaCreateManagedWidget("20%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"20%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[3] = XtVaCreateManagedWidget("30%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"30%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[4] = XtVaCreateManagedWidget("40%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"40%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[5] = XtVaCreateManagedWidget("50%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"50%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[6] = XtVaCreateManagedWidget("60%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"60%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[7] = XtVaCreateManagedWidget("70%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"70%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[8] = XtVaCreateManagedWidget("80%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"80%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[9] = XtVaCreateManagedWidget("90%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"90%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    raster_intensity[10] = XtVaCreateManagedWidget("100%",
+            xmPushButtonGadgetClass,
+            Raster_intensity_Pane,
+            XmNmnemonic,"100%",
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtSetSensitive(raster_intensity[(int)(raster_map_intensity * 10.0)],FALSE);
+
+    //fprintf(stderr,"raster index = %d\n",
+    //    (int)(raster_map_intensity * 10.01) );
+
+    XtAddCallback(raster_intensity[0],  XmNactivateCallback,Raster_intensity,"0.0");
+    XtAddCallback(raster_intensity[1],  XmNactivateCallback,Raster_intensity,"0.1");
+    XtAddCallback(raster_intensity[2],  XmNactivateCallback,Raster_intensity,"0.2");
+    XtAddCallback(raster_intensity[3],  XmNactivateCallback,Raster_intensity,"0.3");
+    XtAddCallback(raster_intensity[4],  XmNactivateCallback,Raster_intensity,"0.4");
+    XtAddCallback(raster_intensity[5],  XmNactivateCallback,Raster_intensity,"0.5");
+    XtAddCallback(raster_intensity[6],  XmNactivateCallback,Raster_intensity,"0.6");
+    XtAddCallback(raster_intensity[7],  XmNactivateCallback,Raster_intensity,"0.7");
+    XtAddCallback(raster_intensity[8],  XmNactivateCallback,Raster_intensity,"0.8");
+    XtAddCallback(raster_intensity[9],  XmNactivateCallback,Raster_intensity,"0.9");
+    XtAddCallback(raster_intensity[10], XmNactivateCallback,Raster_intensity,"1.0");
+#if defined(HAVE_MAGICK)
+    // Adjust Gamma Correction
+    gamma_adjust_button = XtVaCreateManagedWidget(langcode("GAMMA001"),
+            xmPushButtonWidgetClass, map_config_pane,
+            XmNmnemonic,langcode_hotkey("GAMMA001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(gamma_adjust_button, XmNactivateCallback, Gamma_adjust, NULL);
+#endif  // HAVE_MAGICK
+#endif  // NO_GRAPHICS
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    Map_station_label_Pane = XmCreatePulldownMenu(map_config_pane,
+            "create_appshell map_station_label",
+            al,
+            ac);
+    map_station_label_button = XtVaCreateManagedWidget(langcode("PULDNMP006"),
+            xmCascadeButtonWidgetClass,
+            map_config_pane,
+            XmNsubMenuId, Map_station_label_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMP006"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_station_label0 = XtVaCreateManagedWidget(langcode("PULDNMSL01"),
+            xmPushButtonGadgetClass,
+            Map_station_label_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMSL01"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_station_label1 = XtVaCreateManagedWidget(langcode("PULDNMSL02"),
+            xmPushButtonGadgetClass,
+            Map_station_label_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMSL02"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_station_label2 = XtVaCreateManagedWidget(langcode("PULDNMSL03"),
+            xmPushButtonGadgetClass,
+            Map_station_label_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMSL03"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    sel3_switch(letter_style,map_station_label2,map_station_label1,map_station_label0);
+    XtAddCallback(map_station_label0,   XmNactivateCallback,Map_station_label,"0");
+    XtAddCallback(map_station_label1,   XmNactivateCallback,Map_station_label,"1");
+    XtAddCallback(map_station_label2,   XmNactivateCallback,Map_station_label,"2");
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    Map_icon_outline_Pane = XmCreatePulldownMenu(map_config_pane,
+            "create_appshell map_icon_outline",
+            al,
+            ac);
+    map_icon_outline_button = XtVaCreateManagedWidget(langcode("PULDNMP026"),
+            xmCascadeButtonWidgetClass,
+            map_config_pane,
+            XmNsubMenuId, Map_icon_outline_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMP026"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_icon_outline0 = XtVaCreateManagedWidget(langcode("PULDNMIO01"),
+            xmPushButtonGadgetClass,
+            Map_icon_outline_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMIO01"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_icon_outline1 = XtVaCreateManagedWidget(langcode("PULDNMIO02"),
+            xmPushButtonGadgetClass,
+            Map_icon_outline_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMIO02"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_icon_outline2 = XtVaCreateManagedWidget(langcode("PULDNMIO03"),
+            xmPushButtonGadgetClass,
+            Map_icon_outline_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMIO03"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    map_icon_outline3 = XtVaCreateManagedWidget(langcode("PULDNMIO04"),
+            xmPushButtonGadgetClass,
+            Map_icon_outline_Pane,
+            XmNmnemonic,langcode_hotkey("PULDNMIO04"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    sel4_switch(icon_outline_style,map_icon_outline3,map_icon_outline2,map_icon_outline1,map_icon_outline0);
+    XtAddCallback(map_icon_outline0,   XmNactivateCallback,Map_icon_outline,"0");
+    XtAddCallback(map_icon_outline1,   XmNactivateCallback,Map_icon_outline,"1");
+    XtAddCallback(map_icon_outline2,   XmNactivateCallback,Map_icon_outline,"2");
+    XtAddCallback(map_icon_outline3,   XmNactivateCallback,Map_icon_outline,"3");
+
+
+#if defined(HAVE_MAGICK)
+    tiger_config_button= XtVaCreateManagedWidget(langcode("PULDNMP020"),
+            xmPushButtonGadgetClass,
+            map_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNMP020"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(tiger_config_button,   XmNactivateCallback,Config_tiger,NULL);
+#endif  // HAVE_MAGICK
+
+#ifdef HAVE_LIBGEOTIFF
+    drg_config_button= XtVaCreateManagedWidget(langcode("PULDNMP030"),
+            xmPushButtonGadgetClass,
+            map_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNMP030"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(drg_config_button, XmNactivateCallback,Config_DRG,NULL);
+#endif  // HAVE_LIBGEOTIFF
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep2d",
+            xmSeparatorGadgetClass,
+            map_config_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+// Re-download Maps (Not from cache)
+    redownload_maps_button = XtVaCreateManagedWidget(langcode("PULDNMP027"),
+          xmPushButtonGadgetClass,
+          map_config_pane,
+          XmNmnemonic,langcode_hotkey("PULDNMP027"),
+          XmNfontList, fontlist1,
+          MY_FOREGROUND_COLOR,
+          MY_BACKGROUND_COLOR,
+          NULL);
+    XtAddCallback(redownload_maps_button, XmNactivateCallback,Re_Download_Maps_Now,NULL);
+ 
+
+// Flush Entire Map Cache!
+    flush_map_cache_button = XtVaCreateManagedWidget(langcode("PULDNMP028"),
+          xmPushButtonGadgetClass,
+          map_config_pane,
+          XmNmnemonic,langcode_hotkey("PULDNMP028"),
+          XmNfontList, fontlist1,
+          MY_FOREGROUND_COLOR,
+          MY_BACKGROUND_COLOR,
+          NULL);
+    XtAddCallback(flush_map_cache_button, XmNactivateCallback,Flush_Entire_Map_Queue,NULL);
+ 
+
+    //Index Maps on startup
+    index_maps_on_startup_button = XtVaCreateManagedWidget(langcode("PULDNMP022"),
+            xmToggleButtonGadgetClass,
+            map_config_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(index_maps_on_startup_button,XmNvalueChangedCallback,Index_maps_on_startup_toggle,"1");
+    if (index_maps_on_startup)
+        XmToggleButtonSetState(index_maps_on_startup_button,TRUE,FALSE);
+
+
+        map_indexer_button = XtVaCreateManagedWidget(langcode("PULDNMP023"),
+          xmPushButtonGadgetClass,
+          map_config_pane,
+          XmNmnemonic,langcode_hotkey("PULDNMP023"),
+          XmNfontList, fontlist1,
+          MY_FOREGROUND_COLOR,
+          MY_BACKGROUND_COLOR,
+          NULL);
+
+        map_all_indexer_button = XtVaCreateManagedWidget(langcode("PULDNMP024"),
+          xmPushButtonGadgetClass,
+          map_config_pane,
+          XmNmnemonic,langcode_hotkey("PULDNMP024"),
+          XmNfontList, fontlist1,
+          MY_FOREGROUND_COLOR,
+          MY_BACKGROUND_COLOR,
+          NULL);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep2e",
+            xmSeparatorGadgetClass,
+            mappane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    map_pointer_menu_button = XtVaCreateManagedWidget(langcode("PULDNMP011"),
+            xmPushButtonGadgetClass,
+            mappane,
+            XmNmnemonic,langcode_hotkey("PULDNMP011"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+//- Stations Menu -----------------------------------------------------
+    locate_button = XtVaCreateManagedWidget(langcode("PULDNDP014"),
+            xmPushButtonGadgetClass,
+            stationspane,
+            XmNmnemonic,langcode_hotkey("PULDNDP014"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    track_button = XtVaCreateManagedWidget(langcode("PULDNDP001"),
+            xmPushButtonGadgetClass,
+            stationspane,
+            XmNmnemonic,langcode_hotkey("PULDNDP001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(track_button, XmNactivateCallback,Track_station,NULL);
+
+    download_trail_button = XtVaCreateManagedWidget(langcode("PULDNDP022"),
+            xmPushButtonGadgetClass,
+            stationspane,
+            XmNmnemonic,langcode_hotkey("PULDNDP022"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(download_trail_button, XmNactivateCallback,Download_findu_trail,NULL);
+
+ 
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+
+    // Store Data pulldown/tearoff
+    store_data_pane = XmCreatePulldownMenu(stationspane,
+            "store_data_pane",
+            al,
+            ac);
+
+    // Export all > 
+    store_data_button = XtVaCreateManagedWidget(langcode("PULDNDP055"),
+            xmCascadeButtonGadgetClass,
+            stationspane,
+            XmNsubMenuId, store_data_pane,
+            XmNmnemonic, langcode_hotkey("PULDNDP055"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Export to KML file
+    store_all_kml_button = XtVaCreateManagedWidget(langcode("PULDNDP056"),
+            xmPushButtonGadgetClass,
+            store_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(store_all_kml_button, XmNactivateCallback, store_all_kml_callback, NULL);
+    
+#ifdef HAVE_DB
+    // store to  open databases
+    store_all_db_button = XtVaCreateManagedWidget("Store to open databases",
+            xmPushButtonGadgetClass,
+            store_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    //XtAddCallback(store_all_db_button, XmNvalueChangedCallback, store_all_db_button_callback, "1");
+    XtSetSensitive(store_all_db_button,FALSE);
+#endif // HAVE_DB
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3",
+            xmSeparatorGadgetClass,
+            stationspane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    // Filter Data pulldown/tearoff
+    filter_data_pane = XmCreatePulldownMenu(stationspane,
+            "filter_data_pane",
+            al,
+            ac);
+
+    filter_data_button = XtVaCreateManagedWidget(langcode("PULDNDP032"),
+            xmCascadeButtonGadgetClass,
+            stationspane,
+            XmNsubMenuId, filter_data_pane,
+            XmNmnemonic, langcode_hotkey("PULDNDP032"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    select_none_button = XtVaCreateManagedWidget(langcode("PULDNDP040"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_none_button, XmNvalueChangedCallback, Select_none_toggle, "1");
+    if (Select_.none)
+        XmToggleButtonSetState(select_none_button, TRUE, FALSE);
+
+
+    select_mine_button = XtVaCreateManagedWidget(langcode("PULDNDP041"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_mine_button, XmNvalueChangedCallback, Select_mine_toggle, "1");
+    if (Select_.mine)
+        XmToggleButtonSetState(select_mine_button, TRUE, FALSE);
+    if (Select_.none)
+        XtSetSensitive(select_mine_button, FALSE);
+
+
+    select_tnc_button = XtVaCreateManagedWidget(langcode("PULDNDP042"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_tnc_button, XmNvalueChangedCallback, Select_tnc_toggle, "1");
+    if (Select_.tnc)
+        XmToggleButtonSetState(select_tnc_button, TRUE, FALSE);
+    if (Select_.none)
+        XtSetSensitive(select_tnc_button, FALSE);
+
+
+    select_direct_button = XtVaCreateManagedWidget(langcode("PULDNDP027"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_direct_button, XmNvalueChangedCallback, Select_direct_toggle, "1");
+    if (Select_.direct)
+        XmToggleButtonSetState(select_direct_button, TRUE, FALSE);
+    if (!Select_.tnc || Select_.none)
+        XtSetSensitive(select_direct_button, FALSE);
+
+
+    select_via_digi_button = XtVaCreateManagedWidget(langcode("PULDNDP043"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_via_digi_button, XmNvalueChangedCallback, Select_via_digi_toggle, "1");
+    if (Select_.via_digi)
+        XmToggleButtonSetState(select_via_digi_button, TRUE, FALSE);
+    if (!Select_.tnc || Select_.none)
+        XtSetSensitive(select_via_digi_button, FALSE);
+
+
+    select_net_button = XtVaCreateManagedWidget(langcode("PULDNDP034"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_net_button, XmNvalueChangedCallback, Select_net_toggle, "1");
+    if (Select_.net)
+        XmToggleButtonSetState(select_net_button, TRUE, FALSE);
+    if (Select_.none)
+        XtSetSensitive(select_net_button, FALSE);
+
+
+    // "Select Tactical Calls Only"
+    select_tactical_button = XtVaCreateManagedWidget(langcode("PULDNDP051"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_tactical_button, XmNvalueChangedCallback, Select_tactical_toggle, "1");
+    if (Select_.tactical)
+        XmToggleButtonSetState(select_tactical_button, TRUE, FALSE);
+    if (Select_.none)
+        XtSetSensitive(select_tactical_button, FALSE);
+
+
+    select_old_data_button = XtVaCreateManagedWidget(langcode("PULDNDP019"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_old_data_button, XmNvalueChangedCallback, Select_old_data_toggle, "1");
+    if (Select_.old_data)
+        XmToggleButtonSetState(select_old_data_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(select_old_data_button, FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3a",
+            xmSeparatorGadgetClass,
+            filter_data_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    select_stations_button = XtVaCreateManagedWidget(langcode("PULDNDP044"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_stations_button, XmNvalueChangedCallback,
+                  Select_stations_toggle, "1");
+    if (Select_.stations)
+        XmToggleButtonSetState(select_stations_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(select_stations_button, FALSE);
+
+
+    select_fixed_stations_button = XtVaCreateManagedWidget(langcode("PULDNDP028"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_fixed_stations_button, XmNvalueChangedCallback,
+                  Select_fixed_stations_toggle, "1");
+    if (Select_.fixed_stations)
+        XmToggleButtonSetState(select_fixed_stations_button, TRUE, FALSE);
+    if (!Select_.stations || no_data_selected())
+        XtSetSensitive(select_fixed_stations_button, FALSE);
+
+
+    select_moving_stations_button = XtVaCreateManagedWidget(langcode("PULDNDP029"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_moving_stations_button, XmNvalueChangedCallback,
+                  Select_moving_stations_toggle, "1");
+    if (Select_.moving_stations)
+        XmToggleButtonSetState(select_moving_stations_button, TRUE, FALSE);
+    if (!Select_.stations || no_data_selected())
+        XtSetSensitive(select_moving_stations_button, FALSE);
+
+
+    select_weather_stations_button = XtVaCreateManagedWidget(langcode("PULDNDP030"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_weather_stations_button, XmNvalueChangedCallback,
+                  Select_weather_stations_toggle, "1");
+    if (Select_.weather_stations)
+        XmToggleButtonSetState(select_weather_stations_button, TRUE, FALSE);
+    if (!Select_.stations || no_data_selected())
+        XtSetSensitive(select_weather_stations_button, FALSE);
+
+
+    select_CWOP_wx_stations_button = XtVaCreateManagedWidget(langcode("PULDNDP053"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_CWOP_wx_stations_button, XmNvalueChangedCallback,
+                  Select_CWOP_wx_stations_toggle, "1");
+    if (Select_.CWOP_wx_stations)
+        XmToggleButtonSetState(select_CWOP_wx_stations_button, TRUE, FALSE);
+    if (!Select_.stations || no_data_selected() || !Select_.weather_stations)
+        XtSetSensitive(select_CWOP_wx_stations_button, FALSE);
+    else
+        XtSetSensitive(select_CWOP_wx_stations_button, TRUE);
+
+
+    select_objects_button = XtVaCreateManagedWidget(langcode("PULDNDP045"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_objects_button, XmNvalueChangedCallback,
+                  Select_objects_toggle, "1");
+    if (Select_.objects)
+        XmToggleButtonSetState(select_objects_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(select_objects_button, FALSE);
+
+
+    select_weather_objects_button = XtVaCreateManagedWidget(langcode("PULDNDP026"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_weather_objects_button, XmNvalueChangedCallback,
+                  Select_weather_objects_toggle, "1");
+    if (Select_.weather_objects)
+        XmToggleButtonSetState(select_weather_objects_button, TRUE, FALSE);
+    if (!Select_.objects || no_data_selected())
+        XtSetSensitive(select_weather_objects_button, FALSE);
+
+
+    select_gauge_objects_button = XtVaCreateManagedWidget(langcode("PULDNDP039"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_gauge_objects_button, XmNvalueChangedCallback,
+                  Select_gauge_objects_toggle, "1");
+    if (Select_.gauge_objects)
+        XmToggleButtonSetState(select_gauge_objects_button, TRUE, FALSE);
+    if (!Select_.objects || no_data_selected())
+        XtSetSensitive(select_gauge_objects_button, FALSE);
+
+
+    select_other_objects_button = XtVaCreateManagedWidget(langcode("PULDNDP031"),
+            xmToggleButtonGadgetClass,
+            filter_data_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(select_other_objects_button, XmNvalueChangedCallback,
+                  Select_other_objects_toggle, "1");
+    if (Select_.other_objects)
+        XmToggleButtonSetState(select_other_objects_button, TRUE, FALSE);
+    if (!Select_.objects || no_data_selected())
+        XtSetSensitive(select_other_objects_button, FALSE);
+
+
+    // End of Data Filtering
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    // Displayed Info Filtering
+    filter_display_pane = XmCreatePulldownMenu(stationspane,
+            "filter_display_pane",
+            al,
+            ac);
+
+    filter_display_button = XtVaCreateManagedWidget(langcode("PULDNDP033"),
+            xmCascadeButtonGadgetClass,
+            stationspane,
+            XmNsubMenuId, filter_display_pane,
+            XmNmnemonic, langcode_hotkey("PULDNDP033"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    display_callsign_button = XtVaCreateManagedWidget(langcode("PULDNDP010"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_callsign_button, XmNvalueChangedCallback, Display_callsign_toggle, "1");
+    if (Display_.callsign)
+        XmToggleButtonSetState(display_callsign_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_callsign_button, FALSE);
+
+    display_label_all_trackpoints_button = XtVaCreateManagedWidget(langcode("PULDNDP052"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_label_all_trackpoints_button, XmNvalueChangedCallback, Display_label_all_trackpoints_toggle, "1");
+    if (Display_.label_all_trackpoints)
+        XmToggleButtonSetState(display_label_all_trackpoints_button, TRUE, FALSE);
+    if (!Display_.callsign || no_data_selected())
+        XtSetSensitive(display_label_all_trackpoints_button, FALSE);
+
+    display_symbol_button = XtVaCreateManagedWidget(langcode("PULDNDP012"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_symbol_button, XmNvalueChangedCallback, Display_symbol_toggle, "1");
+    if (Display_.symbol)
+        XmToggleButtonSetState(display_symbol_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_symbol_button, FALSE);
+
+
+    display_symbol_rotate_button = XtVaCreateManagedWidget(langcode("PULDNDP011"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_symbol_rotate_button, XmNvalueChangedCallback, Display_symbol_rotate_toggle, "1");
+    if (Display_.symbol_rotate)
+        XmToggleButtonSetState(display_symbol_rotate_button, TRUE, FALSE);
+    if (!Display_.symbol || no_data_selected())
+        XtSetSensitive(display_symbol_rotate_button, FALSE);
+
+
+    display_trail_button = XtVaCreateManagedWidget(langcode("PULDNDP007"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_trail_button, XmNvalueChangedCallback, Display_trail_toggle, "1");
+    if (Display_.trail)
+        XmToggleButtonSetState(display_trail_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_trail_button, FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3b",
+            xmSeparatorGadgetClass,
+            filter_display_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    display_course_button = XtVaCreateManagedWidget(langcode("PULDNDP003"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_course_button, XmNvalueChangedCallback, Display_course_toggle, "1");
+    if (Display_.course)
+        XmToggleButtonSetState(display_course_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_course_button, FALSE);
+
+
+    display_speed_button = XtVaCreateManagedWidget(langcode("PULDNDP004"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_speed_button, XmNvalueChangedCallback, Display_speed_toggle, "1");
+    if (Display_.speed)
+        XmToggleButtonSetState(display_speed_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_speed_button, FALSE);
+
+
+    display_speed_short_button = XtVaCreateManagedWidget(langcode("PULDNDP017"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_speed_short_button, XmNvalueChangedCallback, Display_speed_short_toggle, "1");
+    if (Display_.speed_short)
+        XmToggleButtonSetState(display_speed_short_button, TRUE, FALSE);
+    if (!Display_.speed || no_data_selected())
+        XtSetSensitive(display_speed_short_button, FALSE);
+
+
+    display_altitude_button = XtVaCreateManagedWidget(langcode("PULDNDP002"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_altitude_button, XmNvalueChangedCallback, Display_altitude_toggle, "1");
+    if (Display_.altitude)
+        XmToggleButtonSetState(display_altitude_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_altitude_button, FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3c",
+            xmSeparatorGadgetClass,
+            filter_display_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    display_weather_button = XtVaCreateManagedWidget(langcode("PULDNDP009"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_weather_button, XmNvalueChangedCallback, Display_weather_toggle, "1");
+    if (Display_.weather)
+        XmToggleButtonSetState(display_weather_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_weather_button, FALSE);
+
+
+    display_weather_text_button = XtVaCreateManagedWidget(langcode("PULDNDP046"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_weather_text_button, XmNvalueChangedCallback, Display_weather_text_toggle, "1");
+    if (Display_.weather_text)
+        XmToggleButtonSetState(display_weather_text_button, TRUE, FALSE);
+    if (!Display_.weather || no_data_selected())
+        XtSetSensitive(display_weather_text_button, FALSE);
+
+
+    display_temperature_only_button = XtVaCreateManagedWidget(langcode("PULDNDP018"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_temperature_only_button, XmNvalueChangedCallback, Display_temperature_only_toggle, "1");
+    if (Display_.temperature_only)
+        XmToggleButtonSetState(display_temperature_only_button, TRUE, FALSE);
+    if (!Display_.weather || !Display_.weather_text || no_data_selected())
+        XtSetSensitive(display_temperature_only_button, FALSE);
+
+
+    display_wind_barb_button = XtVaCreateManagedWidget(langcode("PULDNDP047"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_wind_barb_button, XmNvalueChangedCallback, Display_wind_barb_toggle, "1");
+    if (Display_.wind_barb)
+        XmToggleButtonSetState(display_wind_barb_button, TRUE, FALSE);
+    if (!Display_.weather || no_data_selected())
+        XtSetSensitive(display_wind_barb_button, FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3d",
+            xmSeparatorGadgetClass,
+            filter_display_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    display_aloha_circle_button = XtVaCreateManagedWidget(langcode("PULDNDP054"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_aloha_circle_button, XmNvalueChangedCallback, Display_aloha_circle_toggle, "1");
+    if (Display_.aloha_circle)
+        XmToggleButtonSetState(display_aloha_circle_button, TRUE, FALSE);
+
+
+    display_ambiguity_button = XtVaCreateManagedWidget(langcode("PULDNDP013"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_ambiguity_button, XmNvalueChangedCallback, Display_ambiguity_toggle, "1");
+    if (Display_.ambiguity)
+        XmToggleButtonSetState(display_ambiguity_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_ambiguity_button, FALSE);
+
+
+    display_phg_button = XtVaCreateManagedWidget(langcode("PULDNDP008"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_phg_button, XmNvalueChangedCallback, Display_phg_toggle, "1");
+    if (Display_.phg)
+        XmToggleButtonSetState(display_phg_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_phg_button, FALSE);
+
+
+    display_default_phg_button = XtVaCreateManagedWidget(langcode("PULDNDP021"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_default_phg_button, XmNvalueChangedCallback, Display_default_phg_toggle, "1");
+    if (Display_.default_phg)
+        XmToggleButtonSetState(display_default_phg_button, TRUE, FALSE);
+    if (!Display_.phg || no_data_selected())
+        XtSetSensitive(display_default_phg_button, FALSE);
+
+
+    display_phg_of_moving_button = XtVaCreateManagedWidget(langcode("PULDNDP020"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_phg_of_moving_button, XmNvalueChangedCallback, Display_phg_of_moving_toggle, "1");
+    if (Display_.phg_of_moving)
+        XmToggleButtonSetState(display_phg_of_moving_button, TRUE, FALSE);
+    if (!Display_.phg || no_data_selected())
+        XtSetSensitive(display_phg_of_moving_button, FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3e",
+            xmSeparatorGadgetClass,
+            filter_display_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    display_df_data_button = XtVaCreateManagedWidget(langcode("PULDNDP023"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_df_data_button, XmNvalueChangedCallback, Display_df_data_toggle, "1");
+    if (Display_.df_data)
+        XmToggleButtonSetState(display_df_data_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_df_data_button, FALSE);
+
+    display_df_beamwidth_data_button = XtVaCreateManagedWidget(langcode("PULDNDP123"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_df_beamwidth_data_button, XmNvalueChangedCallback, Display_df_beamwidth_data_toggle, "1");
+    if (Display_.df_beamwidth_data)
+        XmToggleButtonSetState(display_df_beamwidth_data_button, TRUE, FALSE);
+    if (!Display_.df_data || no_data_selected())
+        XtSetSensitive(display_df_beamwidth_data_button, FALSE);
+
+    display_df_bearing_data_button = XtVaCreateManagedWidget(langcode("PULDNDP223"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_df_bearing_data_button, XmNvalueChangedCallback, Display_df_bearing_data_toggle, "1");
+    if (Display_.df_bearing_data)
+        XmToggleButtonSetState(display_df_bearing_data_button, TRUE, FALSE);
+    if (!Display_.df_data || no_data_selected())
+        XtSetSensitive(display_df_bearing_data_button, FALSE);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3e",
+            xmSeparatorGadgetClass,
+            filter_display_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    display_dr_data_button = XtVaCreateManagedWidget(langcode("PULDNDP035"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_dr_data_button, XmNvalueChangedCallback, Display_dr_data_toggle, "1");
+    if (Display_.dr_data)
+        XmToggleButtonSetState(display_dr_data_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_dr_data_button, FALSE);
+
+
+    display_dr_arc_button = XtVaCreateManagedWidget(langcode("PULDNDP036"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_dr_arc_button, XmNvalueChangedCallback, Display_dr_arc_toggle, "1");
+    if (Display_.dr_arc)
+        XmToggleButtonSetState(display_dr_arc_button, TRUE, FALSE);
+    if (!Display_.dr_data || no_data_selected())
+        XtSetSensitive(display_dr_arc_button, FALSE);
+
+
+    display_dr_course_button = XtVaCreateManagedWidget(langcode("PULDNDP037"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_dr_course_button, XmNvalueChangedCallback, Display_dr_course_toggle, "1");
+    if (Display_.dr_course)
+        XmToggleButtonSetState(display_dr_course_button, TRUE, FALSE);
+    if (!Display_.dr_data || no_data_selected())
+        XtSetSensitive(display_dr_course_button, FALSE);
+
+
+    display_dr_symbol_button = XtVaCreateManagedWidget(langcode("PULDNDP038"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_dr_symbol_button, XmNvalueChangedCallback, Display_dr_symbol_toggle, "1");
+    if (Display_.dr_symbol)
+        XmToggleButtonSetState(display_dr_symbol_button, TRUE, FALSE);
+    if (!Display_.dr_data || no_data_selected())
+        XtSetSensitive(display_dr_symbol_button, FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3f",
+            xmSeparatorGadgetClass,
+            filter_display_pane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    display_dist_bearing_button = XtVaCreateManagedWidget(langcode("PULDNDP005"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_dist_bearing_button, XmNvalueChangedCallback, Display_dist_bearing_toggle, "1");
+    if (Display_.dist_bearing)
+        XmToggleButtonSetState(display_dist_bearing_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_dist_bearing_button, FALSE);
+
+
+    display_last_heard_button = XtVaCreateManagedWidget(langcode("PULDNDP024"),
+            xmToggleButtonGadgetClass,
+            filter_display_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(display_last_heard_button, XmNvalueChangedCallback, Display_last_heard_toggle, "1");
+    if (Display_.last_heard)
+        XmToggleButtonSetState(display_last_heard_button, TRUE, FALSE);
+    if (no_data_selected())
+        XtSetSensitive(display_last_heard_button, FALSE);
+
+
+    // End of Displayed Info Filtering
+
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3g",
+            xmSeparatorGadgetClass,
+            stationspane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep3h",
+            xmSeparatorGadgetClass,
+            stationspane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    station_config_pane  = XmCreatePulldownMenu(stationspane,
+            "stations_config_pane",
+            al,
+            ac);
+
+    station_config_button = XtVaCreateManagedWidget(langcode("PULDNFI001"),
+            xmCascadeButtonGadgetClass,
+            stationspane,
+            XmNsubMenuId,station_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNFI001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    object_history_refresh_button = XtVaCreateManagedWidget(langcode("PULDNDP048"),
+            xmPushButtonGadgetClass,
+            station_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNDP048"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    object_history_clear_button = XtVaCreateManagedWidget(langcode("PULDNDP025"),
+            xmPushButtonGadgetClass,
+            station_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNDP025"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // "Clear All Tactical Calls"
+    tactical_clear_button = XtVaCreateManagedWidget(langcode("PULDNDP049"),
+            xmPushButtonGadgetClass,
+            station_config_pane,
+//            XmNmnemonic,langcode_hotkey("PULDNDP049"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    // "Clear Tactical Call History"
+    tactical_history_clear_button = XtVaCreateManagedWidget(langcode("PULDNDP050"),
+            xmPushButtonGadgetClass,
+            station_config_pane,
+//            XmNmnemonic,langcode_hotkey("PULDNDP050"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    tracks_clear_button = XtVaCreateManagedWidget(langcode("PULDNDP016"),
+            xmPushButtonGadgetClass,
+            station_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNDP016"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    station_clear_button = XtVaCreateManagedWidget(langcode("PULDNDP015"),
+            xmPushButtonGadgetClass,
+            station_config_pane,
+            XmNmnemonic,langcode_hotkey("PULDNDP015"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+//--------------------------------------------------------------------
+
+    /* Messages */
+    send_message_to_button = XtVaCreateManagedWidget(langcode("PULDNMG001"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDNMG001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    show_pending_messages_button = XtVaCreateManagedWidget(langcode("PULDNMG007"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDNMG007"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    open_messages_group_button = XtVaCreateManagedWidget(langcode("PULDNMG002"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDNMG002"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    clear_messages_button= XtVaCreateManagedWidget(langcode("PULDNMG003"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDNMG003"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep4",
+            xmSeparatorGadgetClass,
+            messagepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    General_q_button = XtVaCreateManagedWidget(langcode("PULDQUS001"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDQUS001"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    IGate_q_button = XtVaCreateManagedWidget(langcode("PULDQUS002"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDQUS002"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    WX_q_button = XtVaCreateManagedWidget(langcode("PULDQUS003"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDQUS003"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+   (void)XtVaCreateManagedWidget("create_appshell sep4a",
+            xmSeparatorGadgetClass,
+            messagepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    auto_msg_set_button = XtVaCreateManagedWidget(langcode("PULDNMG004"),
+            xmPushButtonGadgetClass,
+            messagepane,
+            XmNmnemonic,langcode_hotkey("PULDNMG004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    auto_msg_toggle = XtVaCreateManagedWidget(langcode("PULDNMG005"),
+            xmToggleButtonGadgetClass,
+            messagepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(auto_msg_toggle,XmNvalueChangedCallback,Auto_msg_toggle,"1");
+
+   (void)XtVaCreateManagedWidget("create_appshell sep5",
+            xmSeparatorGadgetClass,
+            messagepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    satellite_msg_ack_toggle = XtVaCreateManagedWidget(langcode("PULDNMG006"),
+            xmToggleButtonGadgetClass,
+            messagepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(satellite_msg_ack_toggle,XmNvalueChangedCallback,Satellite_msg_ack_toggle,"1");
+
+
+
+    /* Interface */
+    iface_connect_button = XtVaCreateManagedWidget(langcode("PULDNTNT04"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("PULDNTNT04"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sep5a",
+            xmSeparatorGadgetClass,
+            ifacepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    transmit_disable_toggle =  XtVaCreateManagedWidget(langcode("PULDNTNT03"),
+            xmToggleButtonGadgetClass,
+            ifacepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(transmit_disable_toggle,XmNvalueChangedCallback,Transmit_disable_toggle,"1");
+    if (transmit_disable)
+        XmToggleButtonSetState(transmit_disable_toggle,TRUE,FALSE);
+
+
+    posit_tx_disable_toggle = XtVaCreateManagedWidget(langcode("PULDNTNT05"),
+            xmToggleButtonGadgetClass,
+            ifacepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(posit_tx_disable_toggle,XmNvalueChangedCallback,Posit_tx_disable_toggle,"1");
+    if (posit_tx_disable)
+        XmToggleButtonSetState(posit_tx_disable_toggle,TRUE,FALSE);
+    if (transmit_disable)
+        XtSetSensitive(posit_tx_disable_toggle,FALSE);
+
+
+    object_tx_disable_toggle = XtVaCreateManagedWidget(langcode("PULDNTNT06"),
+            xmToggleButtonGadgetClass,
+            ifacepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(object_tx_disable_toggle,XmNvalueChangedCallback,Object_tx_disable_toggle,"1");
+    if (object_tx_disable)
+        XmToggleButtonSetState(object_tx_disable_toggle,TRUE,FALSE);
+    if (transmit_disable)
+        XtSetSensitive(object_tx_disable_toggle,FALSE);
+
+
+    server_port_toggle = XtVaCreateManagedWidget(langcode("PULDNTNT11"),
+            xmToggleButtonGadgetClass,
+            ifacepane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(server_port_toggle,XmNvalueChangedCallback,Server_port_toggle,"1");
+    if (enable_server_port)
+        XmToggleButtonSetState(server_port_toggle,TRUE,FALSE);
+
+
+    (void)XtVaCreateManagedWidget("create_appshell sep5b",
+            xmSeparatorGadgetClass,
+            ifacepane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+    iface_transmit_now = XtVaCreateManagedWidget(langcode("PULDNTNT01"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("PULDNTNT01"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    if (transmit_disable)
+        XtSetSensitive(iface_transmit_now,FALSE);
+
+#ifdef HAVE_GPSMAN
+    Fetch_gps_track = XtVaCreateManagedWidget(langcode("PULDNTNT07"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("PULDNTNT07"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    Fetch_gps_route = XtVaCreateManagedWidget(langcode("PULDNTNT08"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("PULDNTNT08"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    Fetch_gps_waypoints = XtVaCreateManagedWidget(langcode("PULDNTNT09"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("PULDNTNT09"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+/*
+    Send_gps_track = XtVaCreateManagedWidget(langcode("Send_Tr"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("Send_Tr"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    Send_gps_route = XtVaCreateManagedWidget(langcode("Send_Rt"), 
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("Send_Rt"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    Send_gps_waypoints = XtVaCreateManagedWidget(langcode("Send_Wp"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("Send_Wp"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+*/
+
+    Fetch_RINO_waypoints = XtVaCreateManagedWidget(langcode("PULDNTNT10"),
+            xmPushButtonGadgetClass,
+            ifacepane,
+            XmNmnemonic,langcode_hotkey("PULDNTNT10"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+#endif  // HAVE_GPSMAN 
+
+    /* Help*/
+    help_about = XtVaCreateManagedWidget(langcode("PULDNHEL01"),
+            xmPushButtonGadgetClass,
+            helppane,
+            XmNmnemonic,langcode_hotkey("PULDNHEL01"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    help_help = XtVaCreateManagedWidget(langcode("PULDNHEL02"),
+            xmPushButtonGadgetClass,
+            helppane,
+            XmNmnemonic,langcode_hotkey("PULDNHEL02"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    (void)XtVaCreateManagedWidget("create_appshell sephelp",
+            xmSeparatorGadgetClass,
+            helppane,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    help_emergency_pane = XmCreatePulldownMenu(helppane,
+            "help_emergency_pane",
+            al,
+            ac);
+
+    help_emergency_button = XtVaCreateManagedWidget(langcode("PULDNHEL03"),
+            xmCascadeButtonGadgetClass,
+            helppane,
+            XmNsubMenuId,help_emergency_pane,
+            XmNmnemonic,langcode_hotkey("PULDNHEL03"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    emergency_beacon_toggle =  XtVaCreateManagedWidget(langcode("PULDNHEL04"),
+            xmToggleButtonGadgetClass,
+            help_emergency_pane,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(emergency_beacon_toggle,XmNvalueChangedCallback,Emergency_beacon_toggle,"1");
+    if (emergency_beacon)
+        XmToggleButtonSetState(emergency_beacon_toggle,TRUE,FALSE);
+
+
+    /* view */
+    XtAddCallback(stations_button,      XmNactivateCallback,Station_List,"0");
+    XtAddCallback(mobile_button,        XmNactivateCallback,Station_List,"1");
+    XtAddCallback(weather_button,       XmNactivateCallback,Station_List,"2");
+    XtAddCallback(localstations_button, XmNactivateCallback,Station_List,"3");
+    XtAddCallback(laststations_button,  XmNactivateCallback,Station_List,"4");
+    XtAddCallback(objectstations_button,XmNactivateCallback,Station_List,"5");
+    XtAddCallback(objectmystations_button,XmNactivateCallback,Station_List,"6");
+    XtAddCallback(CAD1,XmNactivateCallback,Draw_CAD_Objects_list_dialog,NULL);
+
+    /* button callbacks */
+    XtAddCallback(General_q_button,     XmNactivateCallback,General_query,"");
+    XtAddCallback(IGate_q_button,       XmNactivateCallback,IGate_query,NULL);
+    XtAddCallback(WX_q_button,          XmNactivateCallback,WX_query,NULL);
+    XtAddCallback(station_clear_button, XmNactivateCallback,Stations_Clear,NULL);
+    XtAddCallback(tracks_clear_button,  XmNactivateCallback,Tracks_All_Clear,NULL);
+    XtAddCallback(object_history_refresh_button, XmNactivateCallback,Object_History_Refresh,NULL);
+    XtAddCallback(object_history_clear_button, XmNactivateCallback,Object_History_Clear,NULL);
+    XtAddCallback(tactical_clear_button, XmNactivateCallback,Tactical_Callsign_Clear,NULL);
+    XtAddCallback(tactical_history_clear_button, XmNactivateCallback,Tactical_Callsign_History_Clear,NULL);
+    XtAddCallback(exit_button,   XmNactivateCallback,Menu_Quit,NULL);
+
+    XtAddCallback(defaults_button,      XmNactivateCallback,Configure_defaults,NULL);
+    XtAddCallback(timing_button,        XmNactivateCallback,Configure_timing,NULL);
+    XtAddCallback(coordinates_button,   XmNactivateCallback,Configure_coordinates,NULL);
+    XtAddCallback(aa_button,            XmNactivateCallback,Configure_audio_alarms,NULL);
+    XtAddCallback(speech_button,        XmNactivateCallback,Configure_speech,NULL);
+    XtAddCallback(smart_beacon_button,  XmNactivateCallback,Smart_Beacon,NULL);
+    XtAddCallback(map_indexer_button,   XmNactivateCallback,Index_Maps_Now,NULL);
+    XtAddCallback(map_all_indexer_button,XmNactivateCallback,Index_Maps_Now,"1");
+    XtAddCallback(station_button,       XmNactivateCallback,Configure_station,NULL);
+
+    XtAddCallback(help_about,           XmNactivateCallback,Help_About,NULL);
+    XtAddCallback(help_help,            XmNactivateCallback,Help_Index,NULL);
+
+    /* TNC */
+    XtAddCallback(iface_transmit_now,   XmNactivateCallback,TNC_Transmit_now,NULL);
+
+#ifdef HAVE_GPSMAN
+    XtAddCallback(Fetch_gps_track,      XmNactivateCallback,GPS_operations,"1");
+    XtAddCallback(Fetch_gps_route,      XmNactivateCallback,GPS_operations,"2");
+    XtAddCallback(Fetch_gps_waypoints,  XmNactivateCallback,GPS_operations,"3");
+//    XtAddCallback(Send_gps_track,       XmNactivateCallback,GPS_operations,"4");
+//    XtAddCallback(Send_gps_route,       XmNactivateCallback,GPS_operations,"5");
+//    XtAddCallback(Send_gps_waypoints,   XmNactivateCallback,GPS_operations,"6");
+    XtAddCallback(Fetch_RINO_waypoints, XmNactivateCallback,GPS_operations,"7");
+#endif  // HAVE_GPSMAN
+
+    XtAddCallback(auto_msg_set_button,XmNactivateCallback,Auto_msg_set,NULL);
+
+    XtAddCallback(iface_connect_button, XmNactivateCallback,control_interface,NULL);
+
+    XtAddCallback(open_file_button,     XmNactivateCallback,Read_File_Selection,NULL);
+
+    XtAddCallback(bullet_button,        XmNactivateCallback,Bulletins,NULL);
+    XtAddCallback(packet_data_button,   XmNactivateCallback,Display_data,NULL);
+    XtAddCallback(locate_button,        XmNactivateCallback,Locate_station,NULL);
+    XtAddCallback(alert_button,         XmNactivateCallback,Display_Wx_Alert,NULL);
+    XtAddCallback(view_messages_button, XmNactivateCallback,view_all_messages,NULL);
+    XtAddCallback(gps_status_button,XmNactivateCallback,view_gps_status,NULL);
+
+    XtAddCallback(map_pointer_menu_button, XmNactivateCallback,menu_link_for_mouse_menu,NULL);
+
+    XtAddCallback(wx_station_button,    XmNactivateCallback,WX_station,NULL);
+    XtAddCallback(jump_button,          XmNactivateCallback, Jump_location, NULL);
+    XtAddCallback(locate_place_button,  XmNactivateCallback,Locate_place,NULL);
+    XtAddCallback(geocode_place_button,  XmNactivateCallback,Geocoder_place,NULL);
+    XtAddCallback(coordinate_calculator_button, XmNactivateCallback,Coordinate_calc,"");
+
+    XtAddCallback(send_message_to_button,       XmNactivateCallback,Send_message,NULL);
+    XtAddCallback(show_pending_messages_button, XmNactivateCallback,Show_pending_messages,NULL);
+    XtAddCallback(open_messages_group_button,   XmNactivateCallback,Send_message,"*");
+    XtAddCallback(clear_messages_button,XmNactivateCallback,Clear_messages,NULL);
+    XtAddCallback(save_button,          XmNactivateCallback,Save_Config,NULL);
+    XtAddCallback(test_button,          XmNactivateCallback,Test,NULL);
+    if (!debug_level) {
+            XtSetSensitive(test_button, False);
+    }
+
+    XtAddCallback(debug_level_button,   XmNactivateCallback, Change_Debug_Level,NULL);
+//    XtSetSensitive(debug_level_button, False);
+
+    XtAddCallback(uptime_button,   XmNactivateCallback, Compute_Uptime,NULL);
+    XtAddCallback(aloha_button,   XmNactivateCallback, Show_Aloha_Stats,NULL);
+    //XtSetSensitive(uptime_button, False);
+
+
+
+    // Toolbar
+    toolbar = XtVaCreateWidget("Toolbar form",
+            xmFormWidgetClass,
+            form,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNtopOffset, 0,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, menubar,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNautoUnmanage, FALSE,
+            XmNshadowThickness, 1,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    trackme_button=XtVaCreateManagedWidget(langcode("POPUPMA022"),
+            xmToggleButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNtopOffset, -5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNbottomOffset, 0,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNrightOffset, 0,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(trackme_button,XmNvalueChangedCallback,Track_Me,"1");
+
+    measure_button=XtVaCreateManagedWidget(langcode("POPUPMA020"),
+            xmToggleButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, trackme_button,
+            XmNtopOffset, -7,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset, -5,
+            XmNleftAttachment, XmATTACH_FORM,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNrightOffset, 0,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(measure_button,XmNvalueChangedCallback,Measure_Distance,"1");
+
+    cad_draw_button=XtVaCreateManagedWidget(langcode("POPUPMA030"),
+            xmToggleButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNtopOffset, -5,
+            XmNbottomAttachment, XmATTACH_NONE,
+            XmNbottomOffset, 0,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, trackme_button,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNrightOffset, 0,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(cad_draw_button,XmNvalueChangedCallback,Draw_CAD_Objects_mode,NULL);
+ 
+    move_button=XtVaCreateManagedWidget(langcode("POPUPMA021"),
+            xmToggleButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, cad_draw_button,
+            XmNtopOffset, -7,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNbottomOffset, -5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, trackme_button,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNrightOffset, 0,
+            XmNvisibleWhenOff, TRUE,
+            XmNindicatorSize, 12,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(move_button,XmNvalueChangedCallback,Move_Object,"1");
+
+
+
+#ifdef ARROWS
+    zoom_in_menu=XtVaCreateManagedWidget(langcode("POPUPMA002"),
+            xmPushButtonWidgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, cad_draw_button,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(zoom_in_menu,XmNactivateCallback,Zoom_in_no_pan,NULL);
+    if (map_lock_pan_zoom) XtSetSensitive(zoom_in_menu, FALSE);
+
+    zoom_out_menu=XtVaCreateManagedWidget(langcode("POPUPMA003"),
+            xmPushButtonWidgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, zoom_in_menu,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+    XtAddCallback(zoom_out_menu,XmNactivateCallback,Zoom_out_no_pan,NULL);
+    if (map_lock_pan_zoom) XtSetSensitive(zoom_out_menu, FALSE);
+
+    pan_left_menu=XtVaCreateManagedWidget("create_appshell arrow1_menu",
+            xmArrowButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, zoom_out_menu,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNarrowDirection,  XmARROW_LEFT,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            NULL);
+    XtAddCallback(pan_left_menu,XmNactivateCallback,Pan_left,NULL);
+    if (map_lock_pan_zoom) XtSetSensitive(pan_left_menu, FALSE);
+
+    pan_up_menu=XtVaCreateManagedWidget("create_appshell arrow2_menu",
+            xmArrowButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, pan_left_menu,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNarrowDirection,  XmARROW_UP,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            NULL);
+    XtAddCallback(pan_up_menu,XmNactivateCallback,Pan_up,NULL);
+    if (map_lock_pan_zoom) XtSetSensitive(pan_up_menu, FALSE);
+
+    pan_down_menu=XtVaCreateManagedWidget("create_appshell arrow3_menu",
+            xmArrowButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, pan_up_menu,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNarrowDirection,  XmARROW_DOWN,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            NULL);
+    XtAddCallback(pan_down_menu,XmNactivateCallback,Pan_down,NULL);
+    if (map_lock_pan_zoom) XtSetSensitive(pan_down_menu, FALSE);
+
+    pan_right_menu=XtVaCreateManagedWidget("create_appshell arrow4_menu",
+            xmArrowButtonGadgetClass,
+            toolbar,
+            XmNtopAttachment, XmATTACH_FORM,
+            XmNbottomAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, pan_down_menu,
+            XmNleftOffset, 0,
+            XmNrightAttachment, XmATTACH_NONE,
+            XmNarrowDirection,  XmARROW_RIGHT,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, FALSE,
+            NULL);
+    XtAddCallback(pan_right_menu,XmNactivateCallback,Pan_right,NULL);
+    if (map_lock_pan_zoom) XtSetSensitive(pan_right_menu, FALSE);
+#endif // ARROWS
+
+
+
+#define FONT_WIDTH 9
+
+    // Create bottom text area
+    //
+#ifdef USE_TWO_STATUS_LINES
+
+    // Quantity of stations box, Bottom left corner
+    text3 = XtVaCreateWidget("create_appshell text_output3",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             14,
+            XmNwidth,               ((22*FONT_WIDTH)+2),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_FORM,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Zoom level box, Bottom second from left
+    text4 = XtVaCreateWidget("create_appshell text_output4",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             10,
+            XmNwidth,               ((15*FONT_WIDTH)+2),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text3,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Log indicator box, Bottom second from right
+    log_indicator = XtVaCreateWidget(langcode("BBARSTA043"),
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             8,
+            XmNwidth,               ((8*FONT_WIDTH)),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text4,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Interface status indicators, Bottom right corner
+    iface_da = XtVaCreateWidget("create_appshell iface",
+            xmDrawingAreaWidgetClass,
+            form,
+            XmNwidth,               22*(MAX_IFACE_DEVICES/2),
+            XmNheight,              20,
+            XmNunitType,            XmPIXELS,
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNbottomOffset,        5,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          log_indicator,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Message box, on Top left
+    text = XtVaCreateWidget("create_appshell text_output",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             30,
+            XmNwidth,               ((29*FONT_WIDTH)+2),
+            XmNtopOffset,           4,
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_WIDGET,
+            XmNbottomWidget,        text3,
+            XmNleftAttachment,      XmATTACH_FORM,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Coordinate display box, Top right
+    text2 = XtVaCreateWidget("create_appshell text_output2",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             35,
+            XmNwidth,   do_dbstatus?((37*FONT_WIDTH)+2):((24*FONT_WIDTH)+2),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_WIDGET,
+            XmNbottomWidget,        text3,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+#else
+
+    // Message box, on left
+    text = XtVaCreateWidget("create_appshell text_output",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             30,
+            XmNwidth,               ((29*FONT_WIDTH)+2),
+            XmNtopOffset,           4,
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_FORM,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Coordinate display box, 2nd from left
+    text2 = XtVaCreateWidget("create_appshell text_output2",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             35,
+            XmNwidth,   do_dbstatus?((37*FONT_WIDTH)+2):((24*FONT_WIDTH)+2),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Quantity of stations box, 3rd from left
+    text3 = XtVaCreateWidget("create_appshell text_output3",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             14,
+            XmNwidth,               ((10*FONT_WIDTH)+2),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text2,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Zoom level box, 3rd from right
+    text4 = XtVaCreateWidget("create_appshell text_output4",
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             10,
+            XmNwidth,               ((8*FONT_WIDTH)+2),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text3,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Log indicator box, 2nd from right
+    log_indicator = XtVaCreateWidget(langcode("BBARSTA043"),
+            xmTextFieldWidgetClass,
+            form,
+            XmNeditable,            FALSE,
+            XmNcursorPositionVisible, FALSE,
+            XmNsensitive,           STIPPLE,
+            XmNshadowThickness,     1,
+            XmNcolumns,             8,
+            XmNwidth,               ((8*FONT_WIDTH)),
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          text4,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Interface status indicators, on right
+    iface_da = XtVaCreateWidget("create_appshell iface",
+            xmDrawingAreaWidgetClass,
+            form,
+            XmNwidth,               22*(MAX_IFACE_DEVICES/2),
+            XmNheight,              20,
+            XmNunitType,            XmPIXELS,
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_FORM,
+            XmNbottomOffset,        5,
+            XmNleftAttachment,      XmATTACH_WIDGET,
+            XmNleftWidget,          log_indicator,
+            XmNrightAttachment,     XmATTACH_NONE,
+            XmNnavigationType,      XmTAB_GROUP,
+            XmNtraversalOn,         FALSE,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+#endif // USE_TWO_STATUS_LINES
+
+    // The separator goes on top of the text box no matter how
+    // many lines the status bar is, so I'm putting if after the
+    // endif statement  - DCR
+    sep = XtVaCreateManagedWidget("create_appshell sep6",
+            xmSeparatorGadgetClass,
+            form,
+            XmNorientation,         XmHORIZONTAL,
+            XmNtopAttachment,       XmATTACH_NONE,
+            XmNbottomAttachment,    XmATTACH_WIDGET,
+            XmNbottomWidget,        text,
+            XmNleftAttachment,      XmATTACH_FORM,
+            XmNrightAttachment,     XmATTACH_FORM,
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Map drawing area
+    da_width = (Dimension)screen_width;
+    da_height = (Dimension)screen_height;
+    da = XtVaCreateWidget("create_appshell da",
+            xmDrawingAreaWidgetClass,
+            form,
+            XmNwidth,               da_width,
+            XmNheight,              da_height,
+            XmNunitType,            XmPIXELS,
+            XmNtopAttachment,       XmATTACH_WIDGET,
+            XmNtopWidget,           menubar,
+            XmNbottomAttachment,    XmATTACH_WIDGET,
+            XmNbottomWidget,        sep,
+            XmNleftAttachment,      XmATTACH_FORM,
+            XmNrightAttachment,     XmATTACH_FORM,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+
+//-------------------------------------------------------------------------
+
+
+    // Create the mouse menus here
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+
+#ifdef SWAP_MOUSE_BUTTONS
+    //
+    // Motif 2.2.2 (and perhaps earlier, back to version 2.0) has a
+    // problem where the XmNmenuPost doesn't work properly for
+    // modifiers (CapsLock/ScrollLock/NumLock/etc).  We're reverting
+    // back to the Motif 1.x method of doing things.  It works!
+    //
+    //XtSetArg(al[ac], XmNmenuPost, "<Btn1Down>"); ac++;  // Set for popup menu on button 1
+    XtSetArg(al[ac], XmNwhichButton, 1); ac++;  // Enable popup menu on button 1
+
+#else   // SWAP_MOUSE_BUTTONS
+    //
+    // Motif 2.2.2 (and perhaps earlier, back to version 2.0) has a
+    // problem where the XmNmenuPost doesn't work properly for
+    // modifiers (CapsLock/ScrollLock/NumLock/etc).  We're reverting
+    // back to the Motif 1.x method of doing things.  It works!
+    //
+    //XtSetArg(al[ac], XmNmenuPost, "<Btn3Down>"); ac++;  // Set for popup menu on button 3
+    XtSetArg(al[ac], XmNwhichButton, 3); ac++;  // Enable popup menu on button 3
+#endif  // SWAP_MOUSE_BUTTONS
+
+
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+
+    // Right menu popup (right mouse button or button 3)
+    right_menu_popup = XmCreatePopupMenu(da,
+            "create_appshell Menu Popup",
+            al,
+            ac);
+#ifdef XASTIR_XORG_SERVER_175_BUG
+    // This hack is to deal with a bug that was introduced in Xorg server 
+    // version 1.7.5 and promptly fixed right after several distros adopted
+    // that version as their long-term supported version.  This server version
+    // was common in 2010, but should no longer be in the wild much.
+    
+#if XmVersion >= 2000
+    XtVaSetValues(right_menu_popup, XmNpopupEnabled, XmPOPUP_DISABLED, NULL);
+    XtUngrabButton(da, AnyButton, AnyModifier);
+#else
+    XtVaSetValues(right_menu_popup, XmNpopupEnabled, False, NULL);
+#endif
+#endif
+    //XtVaSetValues(right_menu_popup, XmNwhichButton, 3, NULL);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+
+    // "Options"
+    (void)XtCreateManagedWidget(langcode("POPUPMA001"),
+            xmLabelWidgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    (void)XtCreateManagedWidget("create_appshell sep7",
+            xmSeparatorWidgetClass,
+            right_menu_popup,
+            al,
+            ac);
+
+    // "Center"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA00c")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    pan_ctr=XtCreateManagedWidget(langcode("POPUPMA00c"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(pan_ctr,XmNactivateCallback,Pan_ctr,NULL);
+
+    // "Station info"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA015")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    station_info=XtCreateManagedWidget(langcode("POPUPMA015"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(station_info,XmNactivateCallback,Station_info,NULL);
+
+    // Send Message To
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("PULDNMG001")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    send_message_to=XtCreateManagedWidget(langcode("PULDNMG001"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(send_message_to,XmNactivateCallback,Station_info,"4");
+
+    // Map Bookmarks
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("PULDNMP012")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    jump_button2=XtCreateManagedWidget(langcode("PULDNMP012"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(jump_button2,XmNactivateCallback,Jump_location, NULL);
+ 
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zoom_sub=XmCreatePulldownMenu(right_menu_popup,
+            "create_appshell zoom sub",
+            al,
+            ac);
+
+    // "Zoom level"
+    zoom_level=XtVaCreateManagedWidget(langcode("POPUPMA004"),
+            xmCascadeButtonGadgetClass,
+            right_menu_popup,
+            XmNsubMenuId,zoom_sub,
+            XmNmnemonic,langcode_hotkey("POPUPMA004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // Zoom in"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA002")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zoom_in=XtCreateManagedWidget(langcode("POPUPMA002"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zoom_in,XmNactivateCallback,Zoom_in,NULL);
+
+    // Zoom out"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA003")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zoom_out=XtCreateManagedWidget(langcode("POPUPMA003"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zoom_out,XmNactivateCallback,Zoom_out,NULL);
+
+    // "1"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA005")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl1=XtCreateManagedWidget(langcode("POPUPMA005"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl1,XmNactivateCallback,Zoom_level,"1");
+
+    // "16"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA006")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl2=XtCreateManagedWidget(langcode("POPUPMA006"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl2,XmNactivateCallback,Zoom_level,"2");
+
+    // "64"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA007")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl3=XtCreateManagedWidget(langcode("POPUPMA007"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl3,XmNactivateCallback,Zoom_level,"3");
+
+    // "256"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA008")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl4=XtCreateManagedWidget(langcode("POPUPMA008"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl4,XmNactivateCallback,Zoom_level,"4");
+
+    // "1024"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA009")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl5=XtCreateManagedWidget(langcode("POPUPMA009"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl5,XmNactivateCallback,Zoom_level,"5");
+
+    // "8192"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA010")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl6=XtCreateManagedWidget(langcode("POPUPMA010"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl6,XmNactivateCallback,Zoom_level,"6");
+
+    // "Entire World"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA017")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl7=XtCreateManagedWidget(langcode("POPUPMA017"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl7,XmNactivateCallback,Zoom_level,"7");
+
+    // "10% out"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, 'o'); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl8=XtCreateManagedWidget(langcode("POPUPMA035"),   // 10% out
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl8,XmNactivateCallback,Zoom_level,"8");
+
+    // "10% in"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, 'i'); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zl9=XtCreateManagedWidget(langcode("POPUPMA036"),   // 10% in
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zl9,XmNactivateCallback,Zoom_level,"9");
+
+    // "Custom Zoom Level"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, 'i'); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    zlC=XtCreateManagedWidget(langcode("POPUPMA034"),
+            xmPushButtonGadgetClass,
+            zoom_sub,
+            al,
+            ac);
+    XtAddCallback(zlC,XmNactivateCallback,Zoom_level,"10");
+
+    // "Last map pos/zoom"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA016")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    last_loc=XtCreateManagedWidget(langcode("POPUPMA016"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(last_loc,XmNactivateCallback,Last_location,NULL);
+
+    (void)XtCreateManagedWidget("create_appshell sep7a",
+            xmSeparatorWidgetClass,
+            right_menu_popup,
+            al,
+            ac);
+
+    // "Object -> Create"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA018")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    set_object=XtCreateManagedWidget(langcode("POPUPMA018"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(set_object,XmNactivateCallback,Set_Del_Object,NULL);
+
+    // "Object -> Modify"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA019")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    modify_object=XtCreateManagedWidget(langcode("POPUPMA019"),
+            xmPushButtonGadgetClass,
+            right_menu_popup,
+            al,
+            ac);
+    XtAddCallback(modify_object,XmNactivateCallback,Station_info,"1");
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    // Display a list of predefined SAR or Public service event objects.
+    sar_object_sub=XmCreatePulldownMenu(right_menu_popup,
+            "create_appshell sar_object_sub",
+            al,
+            ac);
+
+    // "Predefined Objects"
+    sar_object_menu=XtVaCreateManagedWidget(langcode("POPUPMA045"),
+            xmCascadeButtonGadgetClass,
+            right_menu_popup,
+            XmNsubMenuId,sar_object_sub,
+//            XmNmnemonic,langcode_hotkey("POPUPMA045"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    BuildPredefinedSARMenu_UI(&sar_object_sub);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    XtCreateManagedWidget("create_appshell sep7b",
+            xmSeparatorWidgetClass,
+            right_menu_popup,
+            al,
+            ac);
+
+    XtCreateManagedWidget("create_appshell sep7c",
+            xmSeparatorWidgetClass,
+            right_menu_popup,
+            al,
+            ac);
+
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNtearOffModel, XmTEAR_OFF_ENABLED); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+
+    pan_sub=XmCreatePulldownMenu(right_menu_popup,
+            "create_appshell pan sub",
+            al,
+            ac);
+
+    // "Pan"
+//    pan_menu=XtVaCreateManagedWidget(langcode(""),
+    pan_menu=XtVaCreateManagedWidget("Pan",
+            xmCascadeButtonGadgetClass,
+            right_menu_popup,
+            XmNsubMenuId,pan_sub,
+//            XmNmnemonic,langcode_hotkey("POPUPMA004"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // "Pan Up"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA011")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    pan_up=XtCreateManagedWidget(langcode("POPUPMA011"),
+            xmPushButtonGadgetClass,
+            pan_sub,
+            al,
+            ac);
+    //pan_up=XtVaCreateManagedWidget("create_appshell arrow1",
+    //    xmArrowButtonGadgetClass,
+    //    right_menu_popup,
+    //    XmNarrowDirection,  XmARROW_UP,
+    //    NULL);
+    XtAddCallback(pan_up,XmNactivateCallback,Pan_up,NULL);
+
+    // "Pan Left"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA013")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    pan_left=XtCreateManagedWidget(langcode("POPUPMA013"),
+            xmPushButtonGadgetClass,
+            pan_sub,
+            al,
+            ac);
+    //pan_left=XtVaCreateManagedWidget("create_appshell arrow3",
+    //    xmArrowButtonGadgetClass,
+    //    right_menu_popup,
+    //    XmNarrowDirection,  XmARROW_LEFT,
+    //    NULL);
+    XtAddCallback(pan_left,XmNactivateCallback,Pan_left,NULL);
+
+    // "Pan Right"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA014")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    pan_right=XtCreateManagedWidget(langcode("POPUPMA014"),
+            xmPushButtonGadgetClass,
+            pan_sub,
+            al,
+            ac);
+    //pan_right=XtVaCreateManagedWidget("create_appshell arrow4",
+    //    xmArrowButtonGadgetClass,
+    //    right_menu_popup,
+    //    XmNarrowDirection,  XmARROW_RIGHT,
+    //    NULL);
+    XtAddCallback(pan_right,XmNactivateCallback,Pan_right,NULL);
+
+    // "Pan Down"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA012")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    pan_down=XtCreateManagedWidget(langcode("POPUPMA012"),
+            xmPushButtonGadgetClass,
+            pan_sub,
+            al,
+            ac);
+    //pan_down=XtVaCreateManagedWidget("create_appshell arrow2",
+    //    xmArrowButtonGadgetClass,
+    //    right_menu_popup,
+    //    XmNarrowDirection,  XmARROW_DOWN,
+    //    NULL);
+    XtAddCallback(pan_down,XmNactivateCallback,Pan_down,NULL);
+
+    XtCreateManagedWidget("create_appshell sep7d",
+            xmSeparatorWidgetClass,
+            right_menu_popup,
+            al,
+            ac);
+
+    move_my_sub=XmCreatePulldownMenu(right_menu_popup,
+            "create_appshell move_my sub",
+            al,
+            ac);
+
+    move_my_menu=XtVaCreateManagedWidget(langcode("POPUPMA025"),
+            xmCascadeButtonGadgetClass,
+            right_menu_popup,
+            XmNsubMenuId,move_my_sub,
+            XmNmnemonic,langcode_hotkey("POPUPMA025"),
+            XmNfontList, fontlist1,
+            MY_FOREGROUND_COLOR,
+            MY_BACKGROUND_COLOR,
+            NULL);
+
+    // "Move my station here"
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNmnemonic, langcode_hotkey("POPUPMA025")); ac++;
+    XtSetArg(al[ac], XmNfontList,        fontlist1);             ac++;
+    setmyposition=XtCreateManagedWidget(langcode("POPUPMA025"),
+            xmPushButtonGadgetClass,
+            move_my_sub,
+            al,
+            ac);
+    XtAddCallback(setmyposition,XmNactivateCallback,SetMyPosition,"1");
+
+
+//-------------------------------------------------------------------------
+
+
+    /* mouse tracking */
+    XtAddEventHandler(da,LeaveWindowMask,FALSE,ClearTrackMouse,(XtPointer)text2);
+    XtAddEventHandler(da,PointerMotionMask,FALSE,TrackMouse,(XtPointer)text2);
+
+    // Popup menus
+    XtAddEventHandler(da, ButtonPressMask, FALSE, (XtEventHandler)Mouse_button_handler, NULL);
+    //XtAddEventHandler(da,ButtonReleaseMask,FALSE,(XtEventHandler)Mouse_button_handler,NULL);
+
+
+    // If adding any more widgets here, increase the size of the
+    // children[] array above.
+    ac = 0;
+    children[ac++] = text;
+    children[ac++] = text2;
+    children[ac++] = text3;
+    children[ac++] = text4;
+    children[ac++] = log_indicator;
+    children[ac++] = iface_da;
+    children[ac++] = menubar;
+    children[ac++] = toolbar;
+    children[ac++] = da;
+
+    XtManageChildren(children, ac);
+    ac = 0;
+
+    // This one needs to be done after all of
+    // the above 'cuz it contains all of them.
+    XtManageChild(form);
+
+    WM_DELETE_WINDOW = XmInternAtom(XtDisplay(appshell),"WM_DELETE_WINDOW", FALSE);
+    XmAddWMProtocolCallback(appshell, WM_DELETE_WINDOW, Window_Quit, (XtPointer) NULL);
+    XtAddCallback(appshell,XtNsaveCallback, save_state, (XtPointer) NULL);
+    XtAddCallback(appshell,XtNdieCallback, Window_Quit, (XtPointer) NULL);
+
+    XmTextFieldSetString(text,"");
+    XtManageChild(text);
+
+    display_zoom_status();
+
+    XtManageChild(text);
+
+// We get this error on some systems if XtRealizeWidget() is called
+// without setting width/height values first:
+// "Error: Shell widget xastir has zero width and/or height"
+
+    XtRealizeWidget (appshell);
+
+
+    // Flush all pending requests to the X server.
+    XFlush(display);
+
+
+    create_gc(da);
+
+    // Fill the drawing area with the background color.
+    (void)XSetForeground(XtDisplay(da),gc,MY_BG_COLOR); // Not a mistake!
+    (void)XSetBackground(XtDisplay(da),gc,MY_BG_COLOR);
+    (void)XFillRectangle(XtDisplay(appshell),
+        XtWindow(da),
+        gc,
+        0,
+        0,
+        (unsigned int)screen_width,
+        (unsigned int)screen_height);
+
+
+    XtAddCallback (da, XmNinputCallback,  da_input,NULL);
+    XtAddCallback (da, XmNresizeCallback, da_resize,NULL);
+    XtAddCallback (da, XmNexposeCallback, da_expose,(XtPointer)text);
+
+
+    // Don't discard events in X11 queue, but wait for the X11
+    // server to catch up.
+    (void)XSync(XtDisplay(appshell), False);
+
+
+    // Send the window manager hints
+//    XSetWMHints(display, XtWindow(appshell), wm_hints);
+
+
+    // Set up the icon
+    icon_pixmap = XCreateBitmapFromData(display,
+                        XtWindow(appshell),
+                        (char *)icon_bits,
+                        icon_width,     // icon_bitmap_width,
+                        icon_height);   // icon_bitmap_height
+
+    XSetStandardProperties(display,
+        XtWindow(appshell),
+        title ? title: "Xastir", // window name
+        "Xastir",       // icon name
+        icon_pixmap,    // pixmap for icon
+        0, 0,           // argv and argc for restarting
+        NULL);          // size hints
+
+    if (title) {
+        free(title);
+	title = NULL;
+    }
+
+    if (track_me)
+        XmToggleButtonSetState(trackme_button,TRUE,TRUE);
+    else
+        XmToggleButtonSetState(trackme_button,FALSE,TRUE);
+
+
+
+    // Flush all pending requests to the X server.
+    XFlush(display);
+
+    // Don't discard events in X11 queue, but wait for the X11
+    // server to catch up.
+    (void)XSync(XtDisplay(appshell), False);
+
+
+
+    // Reset the minimum window size so that we can adjust the
+    // window downwards again, but only down to size 61.  If we go
+    // any smaller height-wise then we end up getting segfaults,
+    // probably because we're trying to update some widgets that
+    // aren't visible at that point.
+    //
+    XtVaSetValues(appshell,
+        XmNminWidth,  61,
+        XmNminHeight, 61,
+        XmNwidth,     my_appshell_width,
+        XmNheight,    my_appshell_height,
+//        XmNx,         screen_x_offset,    // Doesn't work here
+//        XmNy,         screen_y_offset,    // Doesn't work here
+        NULL);
+// Lincity method of locking down the min_width/height when
+// instantiating the window, then releasing it later:
+// http://pingus.seul.org/~grumbel/tmp/lincity-source/lcx11_8c-source.html
+
+
+
+     // Actually show the draw and show the window on the display
+    XMapRaised(XtDisplay(appshell), XtWindow(appshell));
+
+
+    // Free the allocated struct.  We won't need it again.
+//    XFree(wm_hints);    // We're not currently using this struct
+
+    if(debug_level & 8)
+        fprintf(stderr,"Create appshell stop\n");
+}   // end of create_appshell()
+
+
+
+
+
+void BuildPredefinedSARMenu_UI(Widget *parent_menu) {
+    int i;   // number of items in menu
+    int ac;  // number of arguments
+    Arg al[100];  // arguments
+
+
+    // Set standard menu item arguments to use with each widget.
+    ac = 0;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
+    XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+    XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+    // Before building menu, make sure that any existing menu items are removed
+    // this allows the menu to be changed on the fly while the program is running.
+    //
+    for (i = 0; i < MAX_NUMBER_OF_PREDEFINED_OBJECTS; i++) {
+        if (predefined_object_menu_items[i] != NULL) {
+             XtDestroyWidget(predefined_object_menu_items[i]);
+             predefined_object_menu_items[i] = NULL;
+        }
+    }
+    // Now build a menu item for each entry in the predefinedObjects array.
+    for (i = 0; i < number_of_predefined_objects; i++) {
+
+        // Walk through array of predefined objects and
+        // build a menu item for each predefined object.
+        //
+        if (predefinedObjects[i].show_on_menu == 1) {
+
+            // Some predefined objects are hidden to allow construction
+            // of two predefined objects in the same place at the same
+            // time with one menu item.
+
+            if(debug_level & 1)
+                fprintf(stderr,
+                    "Menu item with name: %s and index_of_child=%d\n",
+                    predefinedObjects[i].menu_call, predefinedObjects[i].index_of_child);
+
+            predefined_object_menu_items[i]=XtCreateManagedWidget(predefinedObjects[i].menu_call,
+                xmPushButtonGadgetClass,
+                *parent_menu,
+                al,
+                ac);
+
+            XtAddCallback(predefined_object_menu_items[i],
+                XmNactivateCallback,
+                Create_SAR_Object,
+                (intptr_t *)predefinedObjects[i].index);
+
+            if (predefinedObjects[i].index_of_child > -1) {
+
+                // This second callback allows stacking of two
+                // objects such as a PLS with 0.25 and 0.5 and a
+                // PLS_ with 0.75 and 1.0 mile probability circles.
+                //
+                if (predefinedObjects[i].index_of_child < number_of_predefined_objects) {
+                    XtAddCallback(predefined_object_menu_items[i],
+                        XmNactivateCallback,
+                        Create_SAR_Object,
+                        (intptr_t *)predefinedObjects[predefinedObjects[i].index_of_child].index);
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+void create_gc(Widget w) {
+    XGCValues values;
+    Display *my_display = XtDisplay(w);
+    int mask = 0;
+    Pixmap pix;
+    unsigned int _w, _h;
+    int _xh, _yh;
+    char xbm_path[500];
+    int ret_val;
+
+
+    if (debug_level & 8)
+        fprintf(stderr,"Create gc start\n");
+
+    if (gc != 0)
+        return;
+
+    memset(&values, 0, sizeof(values));
+
+    // Allocate colors
+    // Note that the names here are the ones given in xastir.rgb
+    colors[0x00] = GetPixelByName(w,"DarkGreen");  // was darkgreen (same)
+    colors[0x01] = GetPixelByName(w,"purple");
+    colors[0x02] = GetPixelByName(w,"DarkGreen");  // was darkgreen (same)
+    colors[0x03] = GetPixelByName(w,"cyan");
+    colors[0x04] = GetPixelByName(w,"brown");
+    colors[0x05] = GetPixelByName(w,"plum");       // light magenta
+    colors[0x06] = GetPixelByName(w,"orange");
+    colors[0x07] = GetPixelByName(w,"darkgray");
+    colors[0x08] = GetPixelByName(w,"black");      // Foreground font color
+    colors[0x09] = GetPixelByName(w,"blue");
+    colors[0x0a] = GetPixelByName(w,"green");              // PHG (old)
+    colors[0x0b] = GetPixelByName(w,"mediumorchid"); // light purple
+    colors[0x0c] = GetPixelByName(w,"red");
+    colors[0x0d] = GetPixelByName(w,"magenta");
+    colors[0x0e] = GetPixelByName(w,"yellow");
+    colors[0x0f] = GetPixelByName(w,"white");              //
+    colors[0x10] = GetPixelByName(w,"black");
+    colors[0x11] = GetPixelByName(w,"black");
+    colors[0x12] = GetPixelByName(w,"black");
+    colors[0x13] = GetPixelByName(w,"black");
+    colors[0x14] = GetPixelByName(w,"lightgray");
+    colors[0x15] = GetPixelByName(w,"magenta");
+    colors[0x16] = GetPixelByName(w,"mediumorchid"); // light purple
+    colors[0x17] = GetPixelByName(w,"lightblue");
+    colors[0x18] = GetPixelByName(w,"purple");
+    colors[0x19] = GetPixelByName(w,"orange2");    // light orange
+    colors[0x1a] = GetPixelByName(w,"SteelBlue");
+    colors[0x20] = GetPixelByName(w,"white");
+
+    // Area object colors.  Order must not be changed. If beginning moves,
+    // update draw_area and draw_map.
+    // High
+    colors[0x21] = GetPixelByName(w,"black");   // AREA_BLACK_HI
+    colors[0x22] = GetPixelByName(w,"blue");    // AREA_BLUE_HI
+    colors[0x23] = GetPixelByName(w,"green");   // AREA_GREEN_HI
+    colors[0x24] = GetPixelByName(w,"cyan3");    // AREA_CYAN_HI
+    colors[0x25] = GetPixelByName(w,"red");     // AREA_RED_HI
+    colors[0x26] = GetPixelByName(w,"magenta"); // AREA_VIOLET_HI
+    colors[0x27] = GetPixelByName(w,"yellow");  // AREA_YELLOW_HI
+    colors[0x28] = GetPixelByName(w,"gray35");  // AREA_GRAY_HI
+    // Low
+    colors[0x29] = GetPixelByName(w,"gray27");   // AREA_BLACK_LO
+    colors[0x2a] = GetPixelByName(w,"blue4");    // AREA_BLUE_LO
+    colors[0x2b] = GetPixelByName(w,"green4");   // AREA_GREEN_LO
+    colors[0x2c] = GetPixelByName(w,"cyan4");    // AREA_CYAN_LO
+    colors[0x2d] = GetPixelByName(w,"red4");     // AREA_RED_LO
+    colors[0x2e] = GetPixelByName(w,"magenta4"); // AREA_VIOLET_LO
+    colors[0x2f] = GetPixelByName(w,"yellow4");  // AREA_YELLOW_LO
+    colors[0x30] = GetPixelByName(w,"gray53"); // AREA_GRAY_LO
+
+    colors[0x40] = GetPixelByName(w,"yellow");     // symbols ...
+    colors[0x41] = GetPixelByName(w,"DarkOrange3");
+    colors[0x42] = GetPixelByName(w,"purple");
+    colors[0x43] = GetPixelByName(w,"gray80");
+    colors[0x44] = GetPixelByName(w,"red3");
+    colors[0x45] = GetPixelByName(w,"brown1");
+    colors[0x46] = GetPixelByName(w,"brown3");
+    colors[0x47] = GetPixelByName(w,"blue4");
+    colors[0x48] = GetPixelByName(w,"DeepSkyBlue");
+    colors[0x49] = GetPixelByName(w,"DarkGreen");
+    colors[0x4a] = GetPixelByName(w,"red2");
+    colors[0x4b] = GetPixelByName(w,"green3");
+    colors[0x4c] = GetPixelByName(w,"MediumBlue");
+    colors[0x4d] = GetPixelByName(w,"white");
+    colors[0x4e] = GetPixelByName(w,"gray53");
+    colors[0x4f] = GetPixelByName(w,"gray35");
+    colors[0x50] = GetPixelByName(w,"gray27");
+    colors[0x51] = GetPixelByName(w,"black");      // ... symbols
+
+    colors[0x52] = GetPixelByName(w,"LimeGreen");  // PHG, symbols
+
+    colors[0xfe] = GetPixelByName(w,"pink");
+
+    // map solid colors
+    colors[0x60] = GetPixelByName(w,"HotPink");
+    colors[0x61] = GetPixelByName(w,"RoyalBlue");
+    colors[0x62] = GetPixelByName(w,"orange3");
+    colors[0x63] = GetPixelByName(w,"yellow3");
+    colors[0x64] = GetPixelByName(w,"ForestGreen");
+    colors[0x65] = GetPixelByName(w,"DodgerBlue");
+    colors[0x66] = GetPixelByName(w,"cyan2");
+    colors[0x67] = GetPixelByName(w,"plum2");
+    colors[0x68] = GetPixelByName(w,"MediumBlue"); // was blue3 (the same!)
+    colors[0x69] = GetPixelByName(w,"gray86");
+
+    // These colors added to make it possible to color local shapefile tiger
+    //  maps similar to on-line ones.
+    colors[0x70] = GetPixelByName(w,"RosyBrown2");
+    colors[0x71] = GetPixelByName(w,"gray81");
+    colors[0x72] = GetPixelByName(w,"tgr_park_1");
+    colors[0x73] = GetPixelByName(w,"tgr_city_1");
+    colors[0x74] = GetPixelByName(w,"tgr_forest_1");
+    colors[0x75] = GetPixelByName(w,"tgr_water_1");
+
+    // tracking trail colors
+    // set color for your own station with  #define MY_TRAIL_COLOR  in db.c
+    trail_colors[0x00] = GetPixelByName(w,"yellow");
+    trail_colors[0x01] = GetPixelByName(w,"blue");
+    trail_colors[0x02] = GetPixelByName(w,"green");
+    trail_colors[0x03] = GetPixelByName(w,"red");
+    trail_colors[0x04] = GetPixelByName(w,"magenta");
+    trail_colors[0x05] = GetPixelByName(w,"black");
+    trail_colors[0x06] = GetPixelByName(w,"white");
+    trail_colors[0x07] = GetPixelByName(w,"DarkOrchid");
+    trail_colors[0x08] = GetPixelByName(w,"purple");      // very similar to DarkOrchid...
+    trail_colors[0x09] = GetPixelByName(w,"OrangeRed");
+    trail_colors[0x0a] = GetPixelByName(w,"brown");
+    trail_colors[0x0b] = GetPixelByName(w,"DarkGreen");    // was darkgreen (same)
+    trail_colors[0x0c] = GetPixelByName(w,"MediumBlue");
+    trail_colors[0x0d] = GetPixelByName(w,"ForestGreen");
+    trail_colors[0x0e] = GetPixelByName(w,"chartreuse");
+    trail_colors[0x0f] = GetPixelByName(w,"cornsilk");
+    trail_colors[0x10] = GetPixelByName(w,"LightCyan");
+    trail_colors[0x11] = GetPixelByName(w,"cyan");
+    trail_colors[0x12] = GetPixelByName(w,"DarkSlateGray");
+    trail_colors[0x13] = GetPixelByName(w,"NavyBlue");
+    trail_colors[0x14] = GetPixelByName(w,"DarkOrange3");
+    trail_colors[0x15] = GetPixelByName(w,"gray27");
+    trail_colors[0x16] = GetPixelByName(w,"RoyalBlue");
+    trail_colors[0x17] = GetPixelByName(w,"yellow2");
+    trail_colors[0x18] = GetPixelByName(w,"DodgerBlue");
+    trail_colors[0x19] = GetPixelByName(w,"cyan2");
+    trail_colors[0x1a] = GetPixelByName(w,"MediumBlue"); // was blue3 (the same!)
+    trail_colors[0x1b] = GetPixelByName(w,"gray86");
+    trail_colors[0x1c] = GetPixelByName(w,"SteelBlue");
+    trail_colors[0x1d] = GetPixelByName(w,"PaleGreen");
+    trail_colors[0x1e] = GetPixelByName(w,"RosyBrown");
+    trail_colors[0x1f] = GetPixelByName(w,"DeepSkyBlue");
+
+    values.background=GetPixelByName(w,"darkgray");
+
+    gc = XCreateGC(my_display, XtWindow(w), mask, &values);
+
+    // Load a new font into the GC for the station font
+    Load_station_font();
+
+    gc_tint = XCreateGC(my_display, XtWindow(w), mask, &values);
+
+    gc_stipple = XCreateGC(my_display, XtWindow(w), mask, &values);
+
+    gc_bigfont = XCreateGC(my_display, XtWindow(w), mask, &values);
+
+    pix =  XCreatePixmap(XtDisplay(w), RootWindowOfScreen(XtScreen(w)), 20, 20, 1);
+    values.function = GXcopy;
+    gc2 = XCreateGC(XtDisplay(w), pix,GCForeground|GCBackground|GCFunction, &values);
+
+    pixmap=XCreatePixmap(XtDisplay(w),
+                        DefaultRootWindow(XtDisplay(w)),
+                        (unsigned int)screen_width,(unsigned int)screen_height,
+                        DefaultDepthOfScreen(XtScreen(w)));
+
+    pixmap_final=XCreatePixmap(XtDisplay(w),
+                        DefaultRootWindow(XtDisplay(w)),
+                        (unsigned int)screen_width,(unsigned int)screen_height,
+                        DefaultDepthOfScreen(XtScreen(w)));
+
+    pixmap_alerts=XCreatePixmap(XtDisplay(w),
+                        DefaultRootWindow(XtDisplay(w)),
+                        (unsigned int)screen_width,(unsigned int)screen_height,
+                        DefaultDepthOfScreen(XtScreen(w)));
+
+    xastir_snprintf(xbm_path, sizeof(xbm_path), "%s/%s", SYMBOLS_DIR, "2x2.xbm");
+    ret_val = XReadBitmapFile(XtDisplay(w), DefaultRootWindow(XtDisplay(w)),
+                    xbm_path, &_w, &_h, &pixmap_50pct_stipple, &_xh, &_yh);
+
+    if (ret_val != 0) {
+        fprintf(stderr,"XReadBitmapFile() failed: Bitmap not found? %s\n",xbm_path);
+        exit(1);    // 2x2.xbm couldn't be loaded
+    }
+
+    xastir_snprintf(xbm_path, sizeof(xbm_path), "%s/%s", SYMBOLS_DIR, "25pct.xbm");
+    ret_val = XReadBitmapFile(XtDisplay(w), DefaultRootWindow(XtDisplay(w)),
+                    xbm_path, &_w, &_h, &pixmap_25pct_stipple, &_xh, &_yh);
+
+    if (ret_val != 0) {
+        fprintf(stderr,"XReadBitmapFile() failed: Bitmap not found? %s\n",xbm_path);
+        exit(1);    // 25pct.xbm couldn't be loaded
+    }
+
+    xastir_snprintf(xbm_path, sizeof(xbm_path), "%s/%s", SYMBOLS_DIR, "13pct.xbm");
+    ret_val = XReadBitmapFile(XtDisplay(w), DefaultRootWindow(XtDisplay(w)),
+                    xbm_path, &_w, &_h, &pixmap_13pct_stipple, &_xh, &_yh);
+
+    if (ret_val != 0) {
+        fprintf(stderr,"XReadBitmapFile() failed: Bitmap not found? %s\n",xbm_path);
+        exit(1);    // 13pct.xbm couldn't be loaded
+    }
+
+    xastir_snprintf(xbm_path, sizeof(xbm_path), "%s/%s", SYMBOLS_DIR, "alert.xbm");
+    ret_val = XReadBitmapFile(XtDisplay(w), DefaultRootWindow(XtDisplay(w)),
+                    xbm_path, &_w, &_h, &pixmap_wx_stipple, &_xh, &_yh);
+
+    if (ret_val != 0) {
+        fprintf(stderr,"XReadBitmapFile() failed: Bitmap not found? %s\n",xbm_path);
+        exit(1);    // alert.xbm couldn't be loaded
+    }
+
+    display_up=1;
+
+    wait_to_redraw=0;
+
+    if (debug_level & 8)
+        fprintf(stderr,"Create gc stop\n");
+}   // create_gc()
+
+
+
+
+
+// This routine just copies an area from pixmap_final to the
+// display, so we won't go through all the trouble of making this
+// interruptable.  Just get on with it, perform the operation, and
+// return to X.  If it did any map drawing, we'd make it
+// interruptable.
+//
+void da_expose(Widget w, /*@unused@*/ XtPointer client_data, XtPointer call_data) {
+    Dimension width, height, margin_width, margin_height;
+    XmDrawingAreaCallbackStruct *db = (XmDrawingAreaCallbackStruct *)call_data;
+    XExposeEvent *event = (XExposeEvent *) db->event;
+    unsigned char   unit_type;
+
+    //fprintf(stderr,"Expose event\n");*/
+
+    /* Call a routine to create a Graphics Context */
+    create_gc(w);
+
+    /* First get the various dimensions */
+    XtVaGetValues(w,
+        XmNwidth, &width,
+        XmNheight, &height,
+        XmNmarginWidth, &margin_width,
+        XmNmarginHeight, &margin_height,
+        XmNunitType, &unit_type,
+        NULL);
+
+    (void)XCopyArea(XtDisplay(w),
+        pixmap_final,
+        XtWindow(w),
+        gc,
+        event->x,
+        event->y,
+        event->width,
+        event->height,
+        event->x,
+        event->y);
+
+    // We just refreshed the screen, so don't try to erase any
+    // zoom-in boxes via XOR.
+    zoom_box_x1 = -1;
+}
+
+
+
+
+
+// The work function for resizing.  This one will be called by
+// UpdateTime if certain flags have been set my da_resize.  This
+// function and the functions it calls that are CPU intensive should
+// be made interruptable:  They should check interrupt_drawing_now
+// flag periodically and exit nicely if it is set.
+//
+void da_resize_execute(Widget w) {
+    Dimension width, height;
+
+
+    busy_cursor(appshell);
+
+    // Reset the flags that may have brought us here.
+    interrupt_drawing_now = 0;
+    request_resize = 0;
+
+    if (XtIsRealized(w)){
+        /* First get the various dimensions */
+        XtVaGetValues(w,
+            XmNwidth,   &width,
+            XmNheight,  &height,
+            NULL);
+
+        screen_width  = (long)width;
+        screen_height = (long)height;
+        XtVaSetValues(w,
+            XmNwidth,  width,
+            XmNheight, height,
+            NULL);
+
+        /*  fprintf(stderr,"Size x:%ld, y:%ld\n",screen_width,screen_height);*/
+        if (pixmap)
+            (void)XFreePixmap(XtDisplay(w),pixmap);
+
+        if(pixmap_final)
+            (void)XFreePixmap(XtDisplay(w),pixmap_final);
+
+        if(pixmap_alerts)
+            (void)XFreePixmap(XtDisplay(w),pixmap_alerts);
+
+        pixmap=XCreatePixmap(XtDisplay(w),
+                DefaultRootWindow(XtDisplay(w)),
+                (unsigned int)width,(unsigned int)height,
+                DefaultDepthOfScreen(XtScreen(w)));
+
+        pixmap_final=XCreatePixmap(XtDisplay(w),
+                DefaultRootWindow(XtDisplay(w)),
+                (unsigned int)width,(unsigned int)height,
+                DefaultDepthOfScreen(XtScreen(w)));
+
+        pixmap_alerts=XCreatePixmap(XtDisplay(w),
+                DefaultRootWindow(XtDisplay(w)),
+                (unsigned int)width,(unsigned int)height,
+                DefaultDepthOfScreen(XtScreen(w)));
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now)
+            return;
+
+        setup_in_view();    // flag stations that are in screen view
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now)
+            return;
+
+        // Reload maps
+        // Set interrupt_drawing_now because conditions have
+        // changed.
+        interrupt_drawing_now++;
+
+        // Request that a new image be created.  Calls create_image,
+        // XCopyArea, and display_zoom_status.
+        request_new_image++;
+
+//        if (create_image(w)) {
+//            (void)XCopyArea(XtDisplay(w),pixmap_final,XtWindow(w),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//        }
+    }
+}
+
+
+
+
+
+// We got a resize callback.  Set flags.  UpdateTime will come
+// along in a bit and perform the resize.  With this method, the
+// resize can be made interruptable.  We merely need to check for
+// the interrupt_drawing_now flag periodically while doing the
+// resize drawing.
+//
+void da_resize(Widget w, /*@unused@*/ XtPointer client_data, /*@unused@*/ XtPointer call_data) {
+
+    // Set the interrupt_drawing_now flag
+    interrupt_drawing_now++;
+
+    // Set the request_resize flag
+    request_resize++;
+//    last_input_event = sec_now() + 2;
+}
+
+
+
+
+
+// We got a mouse or keyboard callback.  Set flags.  UpdateTime
+// will come along in a bit and perform the screen redraw.  With
+// this method, the redraw can be made interruptable.  We merely
+// need to check for the interrupt_drawing_now flag periodically
+// while doing the redraw.
+//
+void da_input(Widget w, XtPointer client_data, XtPointer call_data) {
+    XEvent *event = ((XmDrawingAreaCallbackStruct *) call_data)->event;
+    Dimension width, height;
+    int redraw;
+    char buffer[20];
+    int bufsize = 20;
+    char temp[200];
+    char temp_course[20];
+    KeySym key;
+    XComposeStatus compose;
+    int x_center;
+    int y_center;
+    int x_distance;
+    int y_distance;
+    float x_distance_real;
+    float y_distance_real;
+    float full_distance;
+    double area;
+    float area_acres; // area in acres
+    long a_x, a_y, b_x, b_y;
+    char str_lat[20];
+    char str_long[20];
+    long x,y;
+    int done = 0;
+    long lat, lon;
+
+
+    XtVaGetValues(w,
+            XmNwidth, &width,
+            XmNheight, &height,
+            NULL);
+
+    /*fprintf(stderr,"input event %d %d\n",event->type,ButtonPress);*/
+    redraw=0;
+
+    // Snag the current pointer position
+    input_x = event->xbutton.x;
+    input_y = event->xbutton.y;
+
+
+/////////////////
+// CAD OBJECTS //
+/////////////////
+
+    // Start of CAD Objects code.  We have both ButtonPress and
+    // ButtonRelease code handlers here, for this mode only.
+    // Check whether we're in CAD Object draw mode first
+    if (draw_CAD_objects_flag && event->xbutton.button == Button2) {
+
+        if (event->type == ButtonRelease) {
+            // We don't want to do anything for ButtonRelease.  Most
+            // of all, we don't want another point drawn for both
+            // press and release, and we don't want other GUI
+            // actions performed on release when in CAD Draw mode.
+            done++;
+        }
+        else {  // ButtonPress for Button2
+
+            // We need to check to see whether we're dragging the
+            // pointer, and then need to save the points away (in
+            // Xastir lat/long format), drawing lines between the
+            // points whenever we do a pixmap_final refresh to the
+            // screen.
+
+            // Check whether we just did the first mouse button down
+            // while in CAD draw mode.  If so, save away the mouse
+            // pointer and get out.  We'll use that mouse pointer
+            // the next time a mouse button gets pressed in order to
+            // draw a line.
+
+            // We're going to use gc_tint with an XOR bitblit here
+            // to make sure that any lines we draw will be easily
+            // seen, no matter what colors we're drawing on top of.
+            //
+
+            // If we have a valid saved position already from our
+            // first click, then we must be on the 2nd or later
+            // click.  Draw a line.
+            if (polygon_last_x != -1 && polygon_last_y != -1) {
+
+                // Convert from screen coordinates to Xastir
+                // coordinate system and save in the object->vertice
+                // list.
+                convert_screen_to_xastir_coordinates(input_x,
+                    input_y,
+                    &lat,
+                    &lon);
+                CAD_vertice_allocate(lat, lon);
+                // Reload symbols/tracks/CAD objects
+                redraw_symbols(da);
+            }
+            else {  // First point of a polygon.  Save it.
+
+                // Figure out the real lat/long from the screen
+                // coordinates.  Create a new object to hold the
+                // point.
+                convert_screen_to_xastir_coordinates(input_x,
+                    input_y,
+                    &lat,
+                    &lon);
+                CAD_object_allocate(lat, lon);
+            }
+
+            // Save current point away for the next draw.
+            polygon_last_x = input_x;
+            polygon_last_y = input_y;
+
+            done++;
+        }
+    }
+// End of CAD Objects code.
+
+
+/////////////////////////////////
+// Start of ButtonRelease code //
+/////////////////////////////////
+
+    if (!done && event->type == ButtonRelease) {
+        //fprintf(stderr,"ButtonRelease %d %d\n",event->xbutton.button,Button3);
+
+#ifdef SWAP_MOUSE_BUTTONS
+        if (event->xbutton.button == Button3) {
+            // Right mouse button release
+#else   // SWAP_MOUSE_BUTTONS
+        if (event->xbutton.button == Button1) {
+            // Left mouse button release
+#endif  // SWAP_MOUSE_BUTTONS
+
+            // If no drag, Center the map on the mouse pointer
+            // If drag, compute new zoom factor/center and redraw
+            // -OR- measure distances.
+
+
+/////////////////////////
+// CENTER MAP FUNCTION //
+/////////////////////////
+
+            // Check for "Center Map" function.  Must be within 15
+            // pixels of where the button press occurred to qualify.
+            if ( mouse_zoom && !measuring_distance && !moving_object
+                    && (abs(menu_x - input_x) < 15)
+                    && (abs(menu_y - input_y) < 15) ) {
+           /*     if(display_up) {
+                    XtVaGetValues(da,XmNwidth, &width,XmNheight, &height,NULL);
+                    new_mid_x = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+                    new_mid_y = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+                    new_scale_y = scale_y;          // keep size
+                    display_zoom_image(1);          // check range and do display, recenter
+                }
+            */
+                // Reset the zoom-box variables
+                possible_zoom_function = 0;
+                zoom_box_x1 = -1;
+            }
+            // It's not the center function because the mouse moved more than 15 pixels.
+            // It must be either the "Compute new zoom/center" -OR- the "Measure distance"
+            // -OR- "Move distance" functions..  The "measuring_distance" or "moving_object"
+            // variables will tell us.
+
+            else {
+                // At this stage we have menu_x/menu_y where the button press occurred,
+                // and input_x/input_y where the button release occurred.
+
+
+//////////////////////
+// MEASURE DISTANCE //
+//////////////////////
+
+                if (measuring_distance) {   // Measure distance function
+                    double R = EARTH_RADIUS_METERS;
+
+
+                    // Check whether we already have a box on screen
+                    // that we need to erase.
+                    if (zoom_box_x1 != -1) {
+//fprintf(stderr,"erasing\n");
+                        // Remove the last box drawn via the XOR
+                        // function.
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x1),    // Keep x constant
+                            l16(zoom_box_y1),
+                            l16(zoom_box_x1),
+                            l16(zoom_box_y2));
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x1),
+                            l16(zoom_box_y1),    // Keep y constant
+                            l16(zoom_box_x2),
+                            l16(zoom_box_y1));
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x2),    // Keep x constant
+                            l16(zoom_box_y1),
+                            l16(zoom_box_x2),
+                            l16(zoom_box_y2));
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x1),
+                            l16(zoom_box_y2),    // Keep y constant
+                            l16(zoom_box_x2),
+                            l16(zoom_box_y2));
+                    }
+
+                    // Reset the zoom-box variables
+                    possible_zoom_function = 0;
+                    zoom_box_x1 = -1;
+
+                    x_distance = abs(menu_x - input_x);
+                    y_distance = abs(menu_y - input_y);
+
+                    // Here we need to convert to either English or Metric units of distance.
+
+                    //(temp,"Distance x:%d pixels,  y:%d pixels\n",x_distance,y_distance);
+                    //popup_message_always(langcode("POPUPMA020"),temp);
+
+                    XtVaGetValues(da,XmNwidth, &width,XmNheight, &height,NULL);
+                    a_x = center_longitude  - ((width *scale_x)/2) + (menu_x*scale_x);
+                    a_y = center_latitude   - ((height*scale_y)/2) + (menu_y*scale_y);
+
+                    b_x = center_longitude  - ((width *scale_x)/2) + (input_x*scale_x);
+                    b_y = center_latitude   - ((height*scale_y)/2) + (input_y*scale_y);
+
+                    // Keep y constant to get x distance.  Convert
+                    // to the current measurement units for display.
+                    x_distance_real = cvt_kn2len * calc_distance_course(a_y,a_x,a_y,b_x,temp_course,sizeof(temp_course));
+                    // Keep x constant to get y distance.  Convert
+                    // to the current measurement units for display.
+                    y_distance_real = cvt_kn2len * calc_distance_course(a_y,a_x,b_y,a_x,temp_course,sizeof(temp_course));
+                    // Compute the total distance and course.
+                    // Convert to the current measurement units for
+                    // display.
+                    full_distance = cvt_kn2len * calc_distance_course(a_y,a_x,b_y,b_x,temp_course,sizeof(temp_course));
+
+                    if (full_distance < 1.0) {
+                        switch (english_units) {
+                            case 1:     // English
+                                full_distance   = full_distance   * 5280;   // convert from miles to feet
+                                x_distance_real = x_distance_real * 5280;   // convert from miles to feet
+                                y_distance_real = y_distance_real * 5280;   // convert from miles to feet
+                                break;
+                            case 2:     // Nautical miles and knots
+                                full_distance   = full_distance   * 6076;   // convert from miles to feet
+                                x_distance_real = x_distance_real * 6076;   // convert from miles to feet
+                                y_distance_real = y_distance_real * 6076;   // convert from miles to feet
+                                break;
+                            default:    // Metric
+                                full_distance   = full_distance   * 1000;   // convert from kilometers to meters
+                                x_distance_real = x_distance_real * 1000;   // convert from kilometers to meters
+                                y_distance_real = y_distance_real * 1000;   // convert from kilometers to meters
+                                break;
+                        }
+
+// See this URL for a method of calculating the area of a lat/long
+// rectangle on a sphere:
+// http://mathforum.org/library/drmath/view/63767.html
+// area = (pi/180)*R^2 * abs(sin(lat1)-sin(lat2)) * abs(lon1-lon2)
+//
+// Their formula is incorrect due to the mistake of mixing radians
+// and degrees.  The correct formula is (WE7U):
+// area = R^2 * abs(sin(lat1)-sin(lat2)) * abs(lon1-lon2)
+
+                        // Compute correct units
+                        switch (english_units) {
+                            case 1:     // English
+                                R = EARTH_RADIUS_MILES * 5280.0;    // feet
+                                break;
+                            case 2:     // Nautical miles and knots
+                                R = EARTH_RADIUS_MILES * 5280.0;    // feet
+                                break;
+                            default:    // Metric
+                                R = EARTH_RADIUS_METERS; // Meters
+                                break;
+                        }
+
+                        // Compute the total area in feet or meters
+
+                        // New method using area on a sphere:
+                        area = R*R
+                            * fabs( sin(convert_lat_l2r(a_y)) - sin(convert_lat_l2r(b_y)) )
+                            * fabs( convert_lon_l2r(a_x) - convert_lon_l2r(b_x) );
+
+                        // Old method using planar geometry:
+                        //area = x_distance_real * y_distance_real;
+
+                        // calculate area in acres
+                        switch (english_units) { 
+                           case 1:
+                           case 2:
+                               area_acres = area * 2.2956749e-05;
+                               break;
+                           default:  // Metric
+                               area_acres = area * 2.4710439e-04;
+                               break;
+                        }
+                        //if (area_acres<0.1) 
+                        //     area_acres = 0;
+
+//fprintf(stderr,"Old method: %f\nNew method: %f\n\n",
+//    x_distance_real * y_distance_real,
+//    area);
+
+                        
+
+// NOTE:  Angles currently change at zoom==1, so we purposely don't
+// give an angle in that measurement instance below.
+//
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "%0.2f %s, x=%0.2f %s, y=%0.2f %s, %0.2f %s %s (%0.2f %s), %s: %s %s",
+                            full_distance, un_alt,      // feet/meters
+                            x_distance_real, un_alt,    // feet/meters
+                            y_distance_real, un_alt,    // feet/meters
+                            area,
+                            langcode("POPUPMA038"), // square
+                            un_alt,
+                            area_acres,
+                            "acres",
+                            langcode("POPUPMA041"), // Bearing
+                            (scale_y == 1) ? "??" : temp_course, // Fix for zoom==1
+                            langcode("POPUPMA042") );   // degrees
+                    }
+                    else {
+                        // Compute the total area in miles or
+                        // kilometers
+
+                        // Compute correct units
+                        switch (english_units) {
+                            case 1:     // English
+                                R = EARTH_RADIUS_MILES; // Statute miles
+                                break;
+                            case 2:     // Nautical miles and knots
+                                R = EARTH_RADIUS_KILOMETERS/1.852; // Nautical miles
+                                break;
+                            default:    // Metric
+                                R = EARTH_RADIUS_KILOMETERS; // kilometers
+                                break;
+                        }
+
+                        // New method, area on a sphere:
+                        area = R*R
+                            * fabs(sin(convert_lat_l2r(a_y))-sin(convert_lat_l2r(b_y)))
+                            * fabs(convert_lon_l2r(a_x)-convert_lon_l2r(b_x));
+
+                        // Old method using planar geometry:
+                        //area = x_distance_real * y_distance_real;
+
+//fprintf(stderr,"Old method: %f\nNew method: %f\n\n",
+//    x_distance_real * y_distance_real,
+//    area);
+
+                        xastir_snprintf(temp,
+                            sizeof(temp),
+                            "%0.2f %s, x=%0.2f %s, y=%0.2f %s, %0.2f %s %s, %s: %s %s",
+                            full_distance, un_dst,      // miles/kilometers
+                            x_distance_real, un_dst,    // miles/kilometers
+                            y_distance_real, un_dst,    // miles/kilometers
+                            area,
+                            langcode("POPUPMA038"), // square
+                            un_dst,
+                            langcode("POPUPMA041"), // Bearing
+                            temp_course,
+                            langcode("POPUPMA042") ); // degrees
+                    }
+                    popup_message_always(langcode("POPUPMA020"),temp);
+                }
+
+
+///////////////////
+// MOVING OBJECT //
+///////////////////
+
+                else if (moving_object) {   // Move function
+                    // For this function we need to:
+                    //   Determine which icon is closest to the mouse pointer press position.
+                    //     We'll use Station_info to select the icon for us.
+                    //   Determine whether it is our object.  If not, force
+                    //     the user to "adopt" the object before moving it.
+                    //   Compute the lat/lon of the mouse pointer release position.
+                    //   Put the new value of lat/lon into the object data.
+                    //   Cause symbols to get redrawn.
+
+                    // Reset the zoom-box variables
+                    possible_zoom_function = 0;
+                    zoom_box_x1 = -1;
+
+                    x = (center_longitude - ((screen_width  * scale_x)/2) + (event->xmotion.x * scale_x));
+                    y = (center_latitude  - ((screen_height * scale_y)/2) + (event->xmotion.y * scale_y));
+
+                    if (x < 0)
+                    x = 0l;                 // 180�W
+
+                    if (x > 129600000l)
+                    x = 129600000l;         // 180�E
+
+                    if (y < 0)
+                    y = 0l;                 //  90�N
+
+                    if (y > 64800000l)
+                    y = 64800000l;          //  90�S
+
+                    if (debug_level & 1) {
+                        // This math is only used for the debug mode printf below.
+                        if (coordinate_system == USE_DDDDDD) {
+                            convert_lat_l2s(y, str_lat, sizeof(str_lat), CONVERT_DEC_DEG);
+                            convert_lon_l2s(x, str_long, sizeof(str_long), CONVERT_DEC_DEG);
+                        } else if (coordinate_system == USE_DDMMSS) {
+                            convert_lat_l2s(y, str_lat, sizeof(str_lat), CONVERT_DMS_NORMAL);
+                            convert_lon_l2s(x, str_long, sizeof(str_long), CONVERT_DMS_NORMAL);
+                        } else {    // Assume coordinate_system == USE_DDMMMM
+                            convert_lat_l2s(y, str_lat, sizeof(str_lat), CONVERT_HP_NORMAL);
+                            convert_lon_l2s(x, str_long, sizeof(str_long), CONVERT_HP_NORMAL);
+                        }
+                        //fprintf(stderr,"%s  %s\n", str_lat, str_long);
+                    }
+
+                    // Effect the change in the object/item's
+                    // position.
+                    //
+                    doing_move_operation++;
+                    Station_info(w, "2", NULL);
+                    doing_move_operation = 0;
+                }
+
+
+/////////////////////////////
+// COMPUTE NEW CENTER/ZOOM //
+/////////////////////////////
+
+                else {  // Must be "Compute new center/zoom" function
+                    float ratio;
+
+                    if (!map_lock_pan_zoom) {
+
+                        // We need to compute a new center and a new scale, then
+                        // cause the new image to be created.
+                        // Compute new center.  It'll be the average of the two points
+                        x_center = (menu_x + input_x) /2;
+                        y_center = (menu_y + input_y) /2;
+
+                        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height,NULL);
+                        new_mid_x = center_longitude - ((width *scale_x)/2) + (x_center*scale_x);
+                        new_mid_y = center_latitude  - ((height*scale_y)/2) + (y_center*scale_y);
+
+                        //
+                        // What Rolf had to say:
+                        //
+                        // Calculate center of mouse-marked area and get the scaling relation
+                        // between x and y for that position. This position will be the new
+                        // center, so that lattitude-dependent relation does not change with
+                        // a zoom-in. For both x and y calculate a new zoom factor necessary
+                        // to fit that screen direction. Select the one that allows both x
+                        // and y part to fall into the screen area. Draw the new screen with
+                        // new center and new zoom factor.
+                        //
+
+                        // Compute the new scale, or as close to it as we can get
+                        //new_scale_y = scale_y / 2;    // Zoom in by a factor of 2
+                        new_scale_y = (long)( (((float)abs(menu_y - input_y) / (float)height ) * (float)scale_y ) + 0.5);
+                        new_scale_x = (long)( (((float)abs(menu_x - input_x) / (float)width  ) * (float)scale_x ) + 0.5);
+
+                        if (new_scale_y < 1)
+                            new_scale_y = 1;            // Don't go further in than zoom 1
+
+                        if (new_scale_x < 1)
+                            new_scale_x = 1;            // Don't go further in than zoom 1
+
+                        // We now know approximately the scales we need
+                        // in order to view all of the pixels just
+                        // selected in the drag operation.  Now set
+                        // new_scale_y to the highest number of the two,
+                        // which will make sure the entire drag
+                        // selection will be seen at the new zoom level.
+                        // Use the new ratio between scales to compute
+                        // this, computed from the new midpoint.
+                        //
+                        //fprintf(stderr,"scale_x:%ld\tscale_y:%ld\n", get_x_scale(new_mid_x, new_mid_y, scale_y), scale_y );
+                        ratio = ((float)get_x_scale(new_mid_x,new_mid_y,scale_y) / (float)scale_y);
+
+                        //fprintf(stderr,"Ratio: %f\n", ratio);
+                        //fprintf(stderr,"x:%ld\ty:%ld\n", new_scale_x, new_scale_y);
+                        if ( new_scale_y < (long)((new_scale_x / ratio) + 0.5) ) {
+                            new_scale_y =  (long)((new_scale_x / ratio) + 0.5);
+                            //fprintf(stderr,"Changed y\n");
+                        }
+                        //fprintf(stderr,"x:%ld\ty:%ld\n", new_scale_x, new_scale_y);
+
+                        display_zoom_image(1);          // Check range and do display, recenter
+
+                        menu_x = input_x;
+                        menu_y = input_y;
+                        //fprintf(stderr,"Drag/zoom/center happened\n");
+
+                        // Reset the zoom-box variables
+                        possible_zoom_function = 0;
+                        zoom_box_x1 = -1;
+                    }
+                }
+            }
+            mouse_zoom = 0;
+        }   // End of Button1 release code
+
+
+//////////////
+// ZOOM OUT //
+//////////////
+
+        else if (event->xbutton.button == Button2 && !map_lock_pan_zoom) {
+            // Middle mouse button release
+
+            // Zoom out 2x with panning
+            menu_x=input_x;
+            menu_y=input_y;
+            Zoom_out( w, client_data, call_data );
+
+            // Simple zoom out, keeping map center at current position
+            //Zoom_out_no_pan( w, client_data, call_data );
+            mouse_zoom = 0;
+        }   // End of Button2 release code
+
+
+////////////////////////////////
+// THIRD MOUSE BUTTON RELEASE // 
+////////////////////////////////
+
+#ifdef SWAP_MOUSE_BUTTONS
+        else if (event->xbutton.button == Button1) {
+            // Left mouse button release
+#else   // SWAP_MOUSE_BUTTONS
+        else if (event->xbutton.button == Button3) {
+            // Right mouse button release
+#endif  // SWAP_MOUSE_BUTTONS
+
+            // Do nothing.  We have a popup tied into the button press anyway.
+            // (Mouse_button_handler & right_menu_popup).
+            // Leave the button release alone in this case.
+            mouse_zoom = 0;
+        }   // End of Button3 release code
+
+
+///////////////
+// SCROLL UP //
+///////////////
+
+        else if (event->xbutton.button == Button4 && !map_lock_pan_zoom) {
+// Scroll up
+            menu_x=input_x;
+            menu_y=input_y;
+            Pan_up(w, client_data, call_data);
+        }   // End of Button4 release code
+
+
+/////////////////
+// SCROLL DOWN //
+/////////////////
+
+        else if (event->xbutton.button == Button5 && !map_lock_pan_zoom) {
+// Scroll down
+            menu_x=input_x;
+            menu_y=input_y;
+            Pan_down(w, client_data, call_data);
+        }   // End of Button5 release code
+
+
+////////////////////////////////////
+// YET MORE MOUSE BUTTON RELEASES //
+////////////////////////////////////
+
+        else if (event->xbutton.button == 6 && !map_lock_pan_zoom) {
+// Mouse button 6 release
+            menu_x=input_x;
+            menu_y=input_y;
+            Zoom_out_no_pan(w, client_data, call_data);
+            mouse_zoom = 0;
+        }   // End of Button6 code
+
+        else if (event->xbutton.button == 7 && !map_lock_pan_zoom) {
+// Mouse button 7 release
+            menu_x=input_x;
+            menu_y=input_y;
+            Zoom_in_no_pan(w, client_data, call_data);
+            mouse_zoom = 0;
+        }   // End of Button7 release code
+    }
+// End of ButtonRelease code
+
+
+
+///////////////////////////////
+// Start of ButtonPress code //
+///////////////////////////////
+
+    else if (!done && event->type == ButtonPress) {
+        //fprintf(stderr,"ButtonPress %d %d\n",event->xbutton.button,Button3);
+
+#ifdef SWAP_MOUSE_BUTTONS
+        if (event->xbutton.button == Button3) {
+// Right mouse button press
+#else   // SWAP_MOUSE_BUTTONS
+        if (event->xbutton.button == Button1) {
+// Left mouse button press
+#endif  // SWAP_MOUSE_BUTTONS
+
+            // Mark the position for possible drag function
+            menu_x=input_x;
+            menu_y=input_y;
+            mouse_zoom = 1;
+
+            if (!moving_object) {  // Can be "Measure" or "Zoom-in"
+                if  (!map_lock_pan_zoom || (map_lock_pan_zoom && measuring_distance)) {
+                    // Not moving an object/item, so allow the
+                    // zoom-in box to display.
+                    possible_zoom_function++;
+                }
+            }
+        }   // End of Button1 Press code
+
+        else if (event->xbutton.button == Button2) {
+// Middle mouse button or both right/left mouse buttons press
+
+            // Nothing attached here.
+            mouse_zoom = 0;
+        }   // End of Button2 Press code
+
+#ifdef SWAP_MOUSE_BUTTONS
+        else if (event->xbutton.button == Button1) {
+// Left mouse button press
+#else   // SWAP_MOUSE_BUTTONS
+        else if (event->xbutton.button == Button3) {
+// Right mouse button press
+#endif  // SWAP_MOUSE_BUTTONS
+
+            // Nothing attached here.
+            mouse_zoom = 0;
+        }   // End of Button3 Press code
+    }
+// End of ButtonPress code
+
+
+////////////////////////////
+// Start of KeyPress code //
+////////////////////////////
+
+    else if (!done && event->type == KeyPress) {
+
+        // We want to branch from the keysym instead of the keycode
+        (void)XLookupString( (XKeyEvent *)event, buffer, bufsize, &key, &compose );
+	//fprintf(stderr,"main.c:da_input():keycode %d\tkeysym %ld\t%s\n", event->xkey.keycode, key, buffer);
+
+        // keycode ??, keysym 65360 is Home (0x???? on sun kbd)
+//        if ((key == 65360) || (key == 0x????)) {
+        if (key == 65360) {
+            if (!map_lock_pan_zoom) {
+                Go_Home(w, NULL, NULL);
+            }
+        }
+
+        // keycode 99, keysym 65365 is PageUp (0xffda on sun kbd)
+        if ((key == 65365) || (key == 0xffda)) {
+            menu_x=input_x;
+            menu_y=input_y;
+            Zoom_out_no_pan( w, client_data, call_data );
+            TrackMouse(w, (XtPointer)text2, event, NULL);
+        }
+
+        // keycode 105, keysym 65366 is PageDown (0xffe0 on sun kbd)
+        if ((key == 65366) || (key == 0xffe0)) {
+            menu_x=input_x;
+            menu_y=input_y;
+            Zoom_in_no_pan( w, client_data, call_data );
+            TrackMouse(w, (XtPointer)text2, event, NULL);
+        }
+
+        // keycode 100, keysym 65361 is left-arrow
+        if ( (key == 65361)
+            || ( (key == 65361) && (event->xkey.state & ShiftMask) ) ) {    // Doesn't work yet.
+            if (!map_lock_pan_zoom) {
+                menu_x=input_x;
+                menu_y=input_y;
+                if (event->xbutton.state & ShiftMask)   // This doesn't work yet
+                    Pan_left_less( w, client_data, call_data);
+                else
+                    Pan_left( w, client_data, call_data );
+                TrackMouse(w, (XtPointer)text2, event, NULL);
+            }
+        }
+
+        // keycode 102, keysym 65363 is right-arrow
+        if ( (key == 65363)
+            || ( (key == 65363) && (event->xkey.state & ShiftMask) ) ) {    // Doesn't work yet.
+            if (!map_lock_pan_zoom) {
+                menu_x=input_x;
+                menu_y=input_y;
+                if (event->xbutton.state & ShiftMask)   // This doesn't work yet
+                    Pan_right_less( w, client_data, call_data);
+                else
+                    Pan_right( w, client_data, call_data );
+                TrackMouse(w, (XtPointer)text2, event, NULL);
+            }
+        }
+
+        // keycode 98, keysym 65362 is up-arrow
+        if ( (key == 65362)
+            || ( (key == 65362) && (event->xkey.state & ShiftMask) ) ) {    // Doesn't work yet.
+            if (!map_lock_pan_zoom) {
+                menu_x=input_x;
+                menu_y=input_y;
+                if (event->xbutton.state & ShiftMask)   // This doesn't work yet
+                    Pan_up_less( w, client_data, call_data);
+                else
+                    Pan_up( w, client_data, call_data );
+                TrackMouse(w, (XtPointer)text2, event, NULL);
+            }
+        }
+
+        // keycode 105, keysym 65364 is down-arrow
+        if ( (key == 65364)
+            || ( (key == 65364) && (event->xkey.state & ShiftMask) ) ) {    // Doesn't work yet.
+            if (!map_lock_pan_zoom) {
+                menu_x=input_x;
+                menu_y=input_y;
+                if (event->xbutton.state & ShiftMask)   // This doesn't work yet
+                    Pan_down_less( w, client_data, call_data);
+                else
+                    Pan_down( w, client_data, call_data );
+                TrackMouse(w, (XtPointer)text2, event, NULL);
+            }
+        }
+
+        // keycode 35, keysym 61 is Equals
+        // keycode 35, keysim 43 is Plus
+        // keycode 86, keysim 65451 is KP_Add
+        if (key == 61 || key == 43 || key == 65451) {
+            grid_size++;
+            redraw = 1;
+        }
+
+        // keycode 48, keysym 45 is Minus
+        // keycode 82, keysym 65453 is KP_Subtract
+        if (key == 45 || key == 65453) {
+            grid_size--;
+            redraw = 1;
+        }
+
+        // Adjust map scale, execpt when pan/zoom locked
+        if (!map_lock_pan_zoom && OSM_optimize_key(key)) {
+            if (debug_level & 512) {
+                fprintf(stderr, "Initial scale, before adjustment sx/sy = %li/%li\n", scale_x, scale_y);
+            }
+
+            adj_to_OSM_level(&scale_x, &scale_y);
+
+            if (debug_level & 512) {
+                fprintf(stderr, "Scale adjusted for OSM, sx/sy = %li/%li\n", scale_x, scale_y);
+            }
+            redraw = 1;
+        }
+
+        if ((debug_level & 512) && OSM_report_scale_key(key)) {
+            fprintf(stderr, "scale_x = %li, scale_y = %li, OSM zoom = %i\n",
+                scale_x, scale_y, osm_zoom_level(scale_x));
+        }
+    }
+// End of KeyPress code
+
+
+//////////////////////////////////
+// START OF SOMETHING ELSE CODE //
+//////////////////////////////////
+    else if (!done) {  // Something else
+        if (event->type == MotionNotify) {
+            input_x = event->xmotion.x;
+            input_y = event->xmotion.y;
+//fprintf(stderr,"da_input2 x %d y %d\n",input_x,input_y);
+        }
+    }   // End of SomethingElse code
+
+
+
+    if (redraw) {
+        /*fprintf(stderr,"Current x %ld y * %ld\n",center_longitude,center_latitude);*/
+
+        // Set the interrupt_drawing_now flag
+        interrupt_drawing_now++;
+
+        // Request that a new image be created.  Calls create_image,
+        // XCopyArea, and display_zoom_status.
+        request_new_image++;
+//        last_input_event = sec_now() + 2;
+    }
+}
+
+
+
+
+
+
+
+// DK7IN: this function is unused...
+//void wait_sec(int dt) {
+//    time_t ct;
+//
+//    ct = sec_now() + dt;
+//    while (ct < sec_now()) {
+//    }
+//}
+
+
+
+
+
+// This function snags the current pointer information and tries to
+// determine whether we're doing some sort of draw or zoom function.
+// If so, draws the appropriate temporary squares or lines that the
+// operator expects.
+//
+void check_pointer_position(void) {
+    Window  root_return, child_return;
+    int rootx_return, rooty_return;
+    int win_x_return, win_y_return;
+    unsigned int mask_return;
+    Bool ret;
+    int x_return;
+    int y_return;
+    unsigned int width_return;
+    unsigned int height_return;
+    unsigned int border_width_return;
+    unsigned int depth_return;
+
+
+    // If this variable has not been set, we should not display the
+    // box.
+    if (!possible_zoom_function) {
+        return;
+    }
+
+    // Snag the current pointer info
+    ret = XQueryPointer(XtDisplay(da),
+            XtWindow(da),  // Window we are interested in
+            &root_return,  // Root window that pointer is in
+            &child_return, // Child windows that pointer is in, if any
+            &rootx_return, // Pointer coord. relative to root window
+            &rooty_return, // Pointer coord. relative to root window
+            &win_x_return, // Pointer coord. relative to specified window
+            &win_y_return, // Pointer coord. relative to specified window
+            &mask_return); // State of modifier keys and pointer buttons
+
+    switch (ret) {
+
+        case True:
+            // If we made it here, we're on the same screen as the
+            // specified window.  It's a good start anyway.
+//fprintf(stderr, "x:%d  y:%d  ", win_x_return, win_y_return);
+//fprintf(stderr, "root:%lx  child:%lx  ", root_return, child_return);
+//fprintf(stderr, "mask:%03x  ret:%02x\n", mask_return, ret);
+
+            // Check mask_return to see if button one is being
+            // pressed down (a drag operation).  If so, we're doing
+            // a zoom-in operation and need to draw a box.  0x100
+
+            // Check if button two (middle button) is being pressed
+            // down (a drag operation).  If so, we're doing a CAD
+            // Object draw and need to draw a line.  0x200
+
+            // Figure out how to erase previous lines/boxes so that
+            // only the current object is shown.  We might need to
+            // keep track of earlier vectors and then redraw them
+            // with an XOR function to erase.
+
+            // Get the dimensions for the drawing area
+            // XGetGeometry(Display *display,
+            //     Drawable d,
+            //     Window *root_return,
+            //     int *x_return,
+            //     int *y_return,
+            //     unsigned int *width_return,
+            //     unsigned int *height_return,
+            //     unsigned int *border_width_return,
+            //     unsigned int *depth_return);
+            XGetGeometry(XtDisplay(da),
+                XtWindow(da),
+                &root_return,
+                &x_return,
+                &y_return,
+                &width_return,
+                &height_return,
+                &border_width_return,
+                &depth_return);
+
+            // Check that X/Y are positive and below the max size of
+            // the child window.
+            if ( win_x_return >= (int)width_return
+                    || win_y_return >= (int)height_return) {
+
+                /*
+                fprintf(stderr, "Out of bounds: %d:%d  %d:%d\n",
+                    win_x_return,
+                    width_return,
+                    win_y_return,
+                    height_return);
+                */
+                return;
+            }
+            else {
+                // Draw what we need to.
+                // For CAD objects, polygon_last_x and
+                // polygon_last_y contain the last position.
+                // For the zoom-in function, menu_x and menu_y
+                // contain the last position.
+
+                if (draw_CAD_objects_flag) {
+                    // Check if button two (middle button) is being
+                    // pressed down (a drag operation).  If so,
+                    // we're doing a CAD Object draw and need to
+                    // draw a line.  0x200
+                    if ( (mask_return & 0x200) == 0) {
+                        return;
+                    }
+
+                    // Remove the last line drawn (if any).  Draw a
+                    // line from polygon_last_x and polygon_last_y
+                    // to the current pointer position.
+/*
+                    (void)XSetLineAttributes(XtDisplay(da), gc_tint, 0, LineSolid, CapButt,JoinMiter);
+                    (void)XSetForeground(XtDisplay(da), gc_tint, colors[(int)0x0e]); // yellow
+                    XDrawLine(XtDisplay(da),
+                        XtWindow(da),
+                        gc_tint,
+                        l16(polygon_last_x),
+                        l16(polygon_last_y),
+                        l16(win_x_return),
+                        l16(win_y_return));
+*/
+                    return;
+                }
+                else {  // Zoom-in function?
+                    // Check mask_return to see if button one is
+                    // being pressed down (a drag operation).  If
+                    // so, we're doing a zoom-in operation and need
+                    // to draw a box.  0x100
+#ifdef SWAP_MOUSE_BUTTONS
+                    if ( (mask_return & 0x400) == 0) {  // Button3
+#else   // SWAP_MOUSE_BUTTONS
+                    if ( (mask_return & 0x100) == 0) {  // Button1
+#endif  // SWAP_MOUSE_BUTTONS
+                        return;
+                    }
+
+                    (void)XSetLineAttributes(XtDisplay(da), gc_tint, 1, LineSolid, CapButt,JoinMiter);
+                    (void)XSetForeground(XtDisplay(da), gc_tint, colors[(int)0x0e]); // yellow
+                    (void)XSetFunction(XtDisplay(da), gc_tint, GXxor);
+ 
+                    // Check whether we already have a box on screen
+                    // that we need to erase.
+                    if (zoom_box_x1 != -1) {
+//fprintf(stderr,"erasing\n");
+                        // Remove the last box drawn via the XOR
+                        // function.
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x1),    // Keep x constant
+                            l16(zoom_box_y1),
+                            l16(zoom_box_x1),
+                            l16(zoom_box_y2));
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x1),
+                            l16(zoom_box_y1),    // Keep y constant
+                            l16(zoom_box_x2),
+                            l16(zoom_box_y1));
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x2),    // Keep x constant
+                            l16(zoom_box_y1),
+                            l16(zoom_box_x2),
+                            l16(zoom_box_y2));
+                        XDrawLine(XtDisplay(da),
+                            XtWindow(da),
+                            gc_tint,
+                            l16(zoom_box_x1),
+                            l16(zoom_box_y2),    // Keep y constant
+                            l16(zoom_box_x2),
+                            l16(zoom_box_y2));
+                    }
+
+                    // Draw a box around the current zoom area.
+                    XDrawLine(XtDisplay(da),
+                        XtWindow(da),
+                        gc_tint,
+                        l16(menu_x),         // Keep x constant
+                        l16(menu_y),
+                        l16(menu_x),
+                        l16(win_y_return));
+                    XDrawLine(XtDisplay(da),
+                        XtWindow(da),
+                        gc_tint,
+                        l16(menu_x),
+                        l16(menu_y),         // Keep y constant
+                        l16(win_x_return),
+                        l16(menu_y));
+                    XDrawLine(XtDisplay(da),
+                        XtWindow(da),
+                        gc_tint,
+                        l16(win_x_return),   // Keep x constant
+                        l16(menu_y),
+                        l16(win_x_return),
+                        l16(win_y_return));
+                    XDrawLine(XtDisplay(da),
+                        XtWindow(da),
+                        gc_tint,
+                        l16(menu_x),
+                        l16(win_y_return),   // Keep y constant
+                        l16(win_x_return),
+                        l16(win_y_return));
+
+                    // Save the values away so that we can erase the
+                    // box later.
+                    zoom_box_x1 = menu_x;
+                    zoom_box_y1 = menu_y;
+                    zoom_box_x2 = win_x_return;
+                    zoom_box_y2 = win_y_return;
+
+                    return;
+                }
+
+            }
+
+        break;
+
+        case BadWindow: // A window passed to the function was no
+                        // good.
+            fprintf(stderr, "check_pointer_position: BadWindow\n");
+            return;
+            break;
+
+        case False: // Pointer is not on the same screen as the
+                    // specified window.
+        default:
+            return;
+            break;
+ 
+    }
+}   // End of check_pointer_position()
+
+
+
+
+
+// Release ApplicationContext when we are asked to leave
+//
+void clear_application_context(void)
+{
+    if (app_context)
+      XtDestroyApplicationContext(app_context);
+    app_context = NULL;
+}
+
+
+
+time_t stations_status_time = 0;
+static int last_alert_on_screen = -1;
+ 
+
+// This is the periodic process that updates the maps/symbols/tracks.
+// At the end of the function it schedules itself to be run again.
+void UpdateTime( XtPointer clientData, /*@unused@*/ XtIntervalId id ) {
+    Widget w = (Widget) clientData;
+    time_t nexttime;
+    int do_time;
+    int max;
+    int i;
+    char station_num[30];
+    char line[MAX_LINE_SIZE+1];
+    int line_offset = 0;
+    int n;
+    time_t current_time;
+    int data_length;
+    int data_port;
+    unsigned char data_string[MAX_LINE_SIZE];
+#ifdef HAVE_DB
+    int got_conn;   // holds result from openConnection() 
+#endif // HAVE_DB
+
+    char temp_file_name[MAX_VALUE];
+
+    do_time = 0;
+
+    // Start UpdateTime again 10 milliseconds after we've completed.
+    // Note:  Setting this too low can cause // some systems
+    // (RedHat/FreeBSD) to spin their wheels a lot, using up great
+    // amounts of CPU time.  This is heavily dependent on the true
+    // value of the "HZ" value, which is reported as "100" on some
+    // systems even if the kernel is using another value.
+#ifdef __CYGWIN__
+    // Cygwin performance is abysmal if nexttime is lower than 50, almost
+    // acceptable at 200.
+    nexttime = 200;
+#else
+    // Changed from 2 to 10 to fix high CPU usage problems on
+    // FreeBSD.
+    nexttime = 10;
+#endif // __CYGWIN__
+
+
+
+    if (restart_xastir_now) {
+        char bin_path[250];
+
+        clear_application_context();
+        // Restart Xastir in this process space.  This is triggered
+        // by receiving a SIGHUP signal to the main process, which
+        // causes the signal handler restart() to run.  restart()
+        // shuts down most things nicely and then sets the
+        // restart_xastir_now  global variable.
+        //
+        // We need to snag the path to the executable from somewhere
+        // so that we can start up again on a variety of systems.
+        // Trying to get it from argv[0] doesn't work as that ends
+        // up as "xastir" with no path.  We therefore get it from
+        // XASTIR_BIN_PATH which we define in configure.ac
+        //
+//        execve("/usr/local/bin/xastir", my_argv, my_envp);
+        xastir_snprintf(bin_path,
+            sizeof(bin_path),
+            "%s/bin/xastir",
+            XASTIR_BIN_PATH);
+
+        // Restart this Xastir instance
+        execve(bin_path, my_argv, my_envp);
+    }
+
+
+
+    current_time = sec_now();
+
+    if (last_updatetime > current_time) {
+        // Time just went in the wrong direction.  Sleep for a bit
+        // so that we don't use massive CPU until the time catches
+        // up again.
+        //
+        if (time_went_backwards == 0) {
+            char temp[110];
+
+            // This is our first time through UpdateTime() since the
+            // time went in the wrong direction.  Dump out a
+            // message to the user.
+            time_went_backwards++;
+            get_timestamp(temp);
+
+            fprintf(stderr,"\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+            fprintf(stderr,    "!!  System time jumped backwards %d seconds!\n",
+                (int)(last_updatetime - current_time) );
+            fprintf(stderr,    "!! Xastir sleeping, else will use excessive CPU\n");
+            fprintf(stderr,    "!! %s\n",
+                temp);
+            fprintf(stderr,    "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");
+            time_went_backwards++;
+        }
+        usleep(1);   // Sleep for 1uS.
+    }
+    else {
+        // Time is behaving normally.
+        last_updatetime = current_time;
+        if (time_went_backwards) {
+            fprintf(stderr,
+                "Xastir is done sleeping due to time reversal.\n\n");
+        }
+        time_went_backwards = 0;
+    }
+
+
+    (void)sound_done();
+
+    if(display_up) {
+
+        if(display_up_first == 0) {             // very first call, do initialization
+
+            display_up_first = 1;
+            statusline(langcode("BBARSTA045"), 1); // Loading symbols...
+            load_pixmap_symbol_file("symbols.dat", 0);
+            statusline(langcode("BBARSTA047"), 1); // Initialize my station...
+            my_station_add(my_callsign,my_group,my_symbol,my_long,my_lat,my_phg,my_comment,(char)position_amb_chars);
+            da_resize(w, NULL,NULL);            // make sure the size is right after startup & create image
+            set_last_position();                // init last map position
+
+#ifdef HAVE_DB
+//uncomment to enable hardcoded test of writing station to db
+//simpleDbTest();
+#endif /* HAVE_DB */
+            // Restore weather alerts so that we have a clear
+            // picture of the current state.  Do this before we
+            // start the interfaces.
+            load_wx_alerts_from_log();
+
+            statusline(langcode("BBARSTA048"), 1); // Start interfaces...
+            startup_all_or_defined_port(-1);    // start interfaces
+        }
+
+        else {  // Not the first time UpdateTime was called.
+                // Perform the regular updates.
+
+            if (first_time_run) {
+                first_time_run = 0;
+                Configure_station(NULL, NULL, NULL);
+            }
+
+            popup_time_out_check(current_time);         // clear popup windows after timeout
+            check_statusline_timeout(current_time);     // clear statusline after timeout
+            check_station_remove(current_time);         // remove old stations
+            check_message_remove(current_time);         // remove old messages
+
+#ifdef USE_RTREE
+  #ifdef HAVE_LIBSHP
+            purge_shp_hash(current_time);               // purge stale rtrees
+  #endif // HAVE_LIBSHP
+#endif // USE_RTREE
+
+
+            // We need to always calculate the Aloha circle so that
+            // if it is turned on by the user it will be accurate.
+            calc_aloha(current_time);
+
+
+            //if ( (new_message_data > 0) && ( (delay_time % 2) == 0) )
+            //update_messages(0);                 // Check Messages, no forced update
+
+
+            // Check whether it's time to expire some weather
+            // alerts.  This function will set redraw_on_new_data
+            // and alert_redraw_on_update if any alerts are expired
+            // from the list.
+            (void)alert_expire(current_time);
+
+
+#ifdef HAVE_GPSMAN
+            // Check whether we've just completed a GPS transfer and
+            // have new maps to draw because of it.  This function
+            // can cause a complete redraw of the maps.
+            check_for_new_gps_map(current_time);
+
+
+            // Check whether it is time to snag RINO waypoints
+            // again, creating APRS Objects out of them.  "0" for
+            // the download interval disables this function.
+            if (RINO_download_interval > 0) {
+                int rino_time = RINO_download_interval * 60;
+
+                if (last_RINO_download + rino_time < current_time) {
+                    last_RINO_download = current_time;
+                    GPS_operations(NULL, "7", NULL);
+                }
+            }
+#endif  // HAVE_GPSMAN
+
+
+            if (xfontsel_query) {
+                Query_xfontsel_pipe();
+            }
+
+
+            // Check on resize requests
+            if (request_resize) {
+//                if (last_input_event < current_time) {
+                    da_resize_execute(w);
+//                }
+            }
+
+
+            if (request_new_image) {
+//                if (last_input_event < current_time) {
+                    new_image(w);
+//                }
+            }
+
+
+            // check on Redraw requests
+            if (         ( (redraw_on_new_data > 1)
+                        || (redraw_on_new_data && (current_time > last_redraw + REDRAW_WAIT))
+                        || (current_time > next_redraw)
+                        || (pending_ID_message && (current_time > remove_ID_message_time)) )
+                    && !wait_to_redraw) {
+
+                int temp_alert_count;
+
+
+                //fprintf(stderr,"Redraw on new data\n");
+
+                // Cause refresh_image() to happen if no other
+                // triggers occurred, but enough time has passed.
+                if (current_time > next_redraw) {
+                    alert_redraw_on_update++;
+                }
+
+                // check if alert_redraw_on_update is set and it has been at least xx seconds since
+                // last weather alert redraw.
+                if ( (alert_redraw_on_update
+                        && !pending_ID_message
+                        && ( current_time > ( last_alert_redraw + WX_ALERTS_REFRESH_TIME ) ))
+                      || (pending_ID_message && (current_time > remove_ID_message_time)) ) {
+
+
+                    // If we got here because of the ID_message
+                    // stuff, clear the variable.
+                    if (pending_ID_message && (current_time > remove_ID_message_time)) {
+                        pending_ID_message = 0;
+                    }
+
+                //if (alert_redraw_on_update) {
+                    //fprintf(stderr,"Alert redraw on update: %ld\t%ld\t%ld\n",
+                    //          current_time, last_alert_redraw, WX_ALERTS_REFRESH_TIME);
+
+                    if (!pending_ID_message) {
+                        refresh_image(da);  // Much faster than create_image.
+                        (void)XCopyArea(XtDisplay(da),
+                            pixmap_final,
+                            XtWindow(da),
+                            gc,
+                            0,
+                            0,
+                            (unsigned int)screen_width,
+                            (unsigned int)screen_height,
+                            0,
+                            0);
+
+                        // We just refreshed the screen, so don't
+                        // try to erase any zoom-in boxes via XOR.
+                        zoom_box_x1 = -1;
+                    }
+
+                    // Here we use temp_alert_count as a temp holding place for the
+                    // count of active alerts. Sound alarm if new alerts are displayed.
+                    if ((temp_alert_count = alert_on_screen()) > last_alert_on_screen) {
+                        if (sound_play_wx_alert_message)
+                            play_sound(sound_command, sound_wx_alert_message);
+#ifdef HAVE_FESTIVAL
+                        if (festival_speak_new_weather_alert) {
+                            char station_id[50];
+                            xastir_snprintf(station_id,
+                                sizeof(station_id), "%s, %d",
+                                langcode("SPCHSTR009"),
+                                temp_alert_count);
+                            SayText(station_id);
+                        }
+#endif // HAVE_FESTIVAL
+                    }
+                    last_alert_on_screen = temp_alert_count;
+                    alert_redraw_on_update = 0;
+                } else {
+                    if (!pending_ID_message)
+                        redraw_symbols(w);
+                }
+
+                redraw_on_new_data = 0;
+                next_redraw = current_time+60; // redraw every minute
+                last_redraw = current_time;
+
+                // This assures that we periodically check for expired alerts
+                // and schedule a screen update if we find any.
+                if (alert_display_request())                            // should nor be placed in redraw loop !!???
+                    alert_redraw_on_update = redraw_on_new_data = 1;    // ????
+
+            }
+
+
+            if (initial_load) {
+
+                // Reload saved objects and items from previous runs.
+                // This implements persistent objects.
+                reload_object_item();
+
+#ifdef HAVE_DB
+                // load data from SQL database connections
+                // step through interface list
+                for (i = 0; i < MAX_IFACE_DEVICES; i++){
+                     // if interface is a database and is set to load on start then load
+                     if (connections_initialized==0) { 
+fprintf(stderr,"main, initializing connections");
+                           connections_initialized = initConnections();
+                     }
+                     if (devices[i].device_type == DEVICE_SQL_DATABASE && devices[i].query_on_startup && port_data[i].status==DEVICE_UP) { 
+                          // load data
+                          if (devices[i].connect_on_startup == 1) { 
+                              // there should be an open connection already
+                              if (debug_level & 4096) 
+                                  fprintf(stderr,"Opening (in main) connection [%d] with existing connection [%p]",i,&connections[i]); 
+                              if (pingConnection(&connections[i])==True) { 
+                                  got_conn = 1;
+                              } else { 
+                                // if (debug_level & 4096) 
+                                     fprintf(stderr,"Ping failed opening new connection [%p]",&connections[i]);                          
+                                 got_conn = openConnection(&devices[i],&connections[i]); 
+                              }
+                          } else { 
+                              if (debug_level & 4096) 
+                                  fprintf(stderr,"Opening (in main) connection [%d] with new connection [%p]",i,&connections[i]);                          
+                              got_conn = openConnection(&devices[i],&connections[i]); 
+                          }
+                          if ((got_conn == 1) && (!(connections[i].type==0))) { 
+                              getAllSimplePositions(&connections[i]);
+                              // if connection worked, it is a oneshot upload of data, so we don't 
+                              // need to set port_data[].active and .status values here.
+                          } else {
+                              // report error on this port
+                              port_data[i].active = DEVICE_IN_USE;
+                              port_data[i].status = DEVICE_ERROR;
+                              update_interface_list();
+                          }
+                     }
+                }
+#endif /* HAVE_DB */
+
+                // Reload any CAD objects from file.  This implements
+                // persistent objects.
+                Restore_CAD_Objects_from_file();
+
+                initial_load = 0;   // All done!
+            }
+
+
+            if (Display_.dr_data
+                    && ((current_time - sec_last_dr_update) > update_DR_rate) ) {
+
+//WE7U:  Possible slow-down here w.r.t. dead-reckoning?  If
+//update_DR_rate is too quick, we end up looking through all of the
+//stations in station list much too often and using a lot of CPU.
+
+                redraw_on_new_data = 1;
+                sec_last_dr_update = current_time;
+            }
+
+
+            // Look for packet data and check port status
+            display_packet_data();
+            if (delay_time > 15) {
+                interface_status(w);
+                delay_time = 0;
+                // check station lists
+                update_station_scroll_list();   // maybe update lists
+            }
+            delay_time++;
+
+
+            // If active HSP ports, check whether we've been sitting
+            // for longer than XX seconds waiting for GPS data.  If
+            // so, the GPS is powered-down, lost lock, or become
+            // disconnected.  Go back to listening on the TNC port.
+            //
+            if (current_time > (sec_last_dtr + 2)) {   // 2-3 secs
+
+                if (!gps_stop_now) {    // No GPS strings parsed
+
+                    // GPS listen timeout!  Pop us out of GPS listen
+                    // mode on all HSP ports.  Listen to the TNC for
+                    // a while.
+//fprintf(stderr,"1:calling dtr_all_set(0)\n");
+                    dtr_all_set(0);
+                    sec_last_dtr = current_time;
+                }
+            }
+
+
+            // If we parsed valid GPS data, bring all DTR lines back
+            // to normal for all HSP interfaces (set to receive from
+            // TNC now).
+            if (gps_stop_now) {
+//fprintf(stderr,"2:calling dtr_all_set(0)\n");
+                dtr_all_set(0); // Go back to TNC listen mode
+                sec_last_dtr = current_time;
+            }
+
+
+            // Start the GPS listening process again
+
+            // check gps start up, GPS on GPSPORT
+            if(current_time > sec_next_gps) {
+
+                // Reset the gps good-data flag
+                if (gps_stop_now) {
+                    gps_stop_now = 0;
+                }
+
+                //fprintf(stderr,"Check GPS\n");
+
+                // Set dtr lines down
+                // works for SERIAL_GPS and SERIAL_TNC_HSP_GPS?
+
+                // HSP interfaces:  Set DTR line for all.  DTR will
+                // get reset for each line as valid GPS data gets
+                // parsed on that interface.
+//fprintf(stderr,"3:calling dtr_all_set(1)\n");
+                dtr_all_set(1);
+                sec_last_dtr = current_time;   // GPS listen timeout
+
+                for(i=0; i<MAX_IFACE_DEVICES; i++) {
+                    if (port_data[i].status) {
+                        char tmp[3];
+                        int ret1 = 0;
+                        int ret2 = 0;
+
+                        switch (port_data[i].device_type) {
+                            case DEVICE_SERIAL_TNC_AUX_GPS:
+                                if (devices[i].gps_retrieve != 0) {
+                                    // Tell TNC to send GPS data
+  
+                                    // Device is correct type and is UP
+                                    // (or ERROR).  Send character to
+                                    // device (prefixed with CTRL-C so
+                                    // that we exit CONV if necessary).
+                                    //
+                                    if (debug_level & 128) {
+                                        fprintf(stderr,"Retrieving GPS AUX port %d\n", i);
+                                    }
+                                    sprintf(tmp, "%c%c",
+                                            '\3',
+                                            devices[i].gps_retrieve);
+                                    
+                                    if (debug_level & 1) {
+                                        fprintf(stderr,"Using 0x%02x 0x%02x to retrieve GPS\n",
+                                                '\3',
+                                                devices[i].gps_retrieve);
+                                    }
+                                    port_write_string(i, tmp);
+                                }
+
+                                // GPS strings are processed in
+                                // UpdateTime function via
+                                // gps_data_find(), if the incoming
+                                // data is GPS data instead of TNC
+                                // data.  We need to do nothing
+                                // further here.
+
+                                break;
+
+                            case DEVICE_SERIAL_TNC_HSP_GPS:
+                                // Check for GPS timing being too
+                                // short for HSP interfaces.  If to
+                                // short, we'll never receive any
+                                // TNC data, just GPS data.
+                                if (gps_time < 3) {
+                                    gps_time = 3;
+                                    popup_message_always(langcode("POPEM00036"),
+                                        langcode("POPEM00037"));
+                                }
+
+                                // GPS strings are processed in
+                                // UpdateTime function via
+                                // gps_data_find(), if the incoming
+                                // data is GPS data instead of TNC
+                                // data.  We need to do nothing
+                                // further here.
+
+                                break;
+
+                            case DEVICE_SERIAL_GPS:
+                            case DEVICE_NET_GPSD:
+
+// For each of these we wish to dump their queue to be processed at
+// the gps_time interval.  At other times they should be overwriting
+// old data with new and not processing the strings.
+
+                                // Process the GPS strings saved by
+                                // the channel_data() function.
+                                if (gprmc_save_string[0] != '\0')
+                                    ret1 = gps_data_find(gprmc_save_string,
+                                        gps_port_save);
+                                if (gpgga_save_string[0] != '\0')
+                                    ret2 = gps_data_find(gpgga_save_string,
+                                        gps_port_save);
+
+                                // Blank out the global variables
+                                // (we just processed them).
+                                gprmc_save_string[0] = '\0';
+                                gpgga_save_string[0] = '\0';
+
+                                if (ret1 && ret2) {
+                                    char temp[200];
+
+                                    xastir_snprintf(temp,
+                                        sizeof(temp),
+                                        "GPS:GPRMC,GPGGA ");
+                                    strncat(temp,
+                                        report_gps_status(),
+                                        sizeof(temp) - 1 - strlen(temp));
+                                    statusline(temp, 0);
+                                }
+                                else if (ret1) {
+                                    char temp[200];
+ 
+                                    xastir_snprintf(temp,
+                                        sizeof(temp),
+                                        "GPS:GPRMC ");
+                                    strncat(temp,
+                                        report_gps_status(),
+                                        sizeof(temp) - 1 - strlen(temp));
+                                    statusline(temp, 0);
+                                }
+                                else if (ret2) {
+                                    char temp[200];
+
+                                    xastir_snprintf(temp,
+                                        sizeof(temp), 
+                                        "GPS:GPGGA ");
+                                    strncat(temp,
+                                        report_gps_status(),
+                                        sizeof(temp) - 1 - strlen(temp));
+                                    statusline(temp, 0);
+                                }
+                                else {
+                                    char temp[200];
+
+                                    xastir_snprintf(temp,
+                                        sizeof(temp),
+                                        "GPS: ");
+                                    strncat(temp,
+                                        report_gps_status(),
+                                        sizeof(temp) - 1 - strlen(temp));
+                                    statusline(temp, 0);
+                                }
+
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                }
+                sec_next_gps = current_time+gps_time;
+            }
+
+            // Check to reestablish a connection
+            if(current_time > net_next_time) {
+                net_last_time = current_time;
+                net_next_time = net_last_time + 300;    // Check every five minutes
+                //net_next_time = net_last_time + 30;   // This statement is for debug
+
+                //fprintf(stderr,"Checking for reconnects\n");
+                check_ports();
+            }
+
+#ifdef USING_LIBGC
+            // Check for leaks?
+            if(current_time > gc_next_time) {
+                gc_next_time = current_time + 60;  // Check every minute
+//fprintf(stderr,"Checking for leaks\n");
+                CHECK_LEAKS();
+            }
+#endif  // USING_LIBGC
+
+            // Check to see if it is time to spit out data
+            if(!wait_to_redraw) {
+                if (last_time == 0) {
+                    // first update
+                    next_time = 120;
+                    last_time = current_time;
+                    do_time = 1;
+                } else {
+                    // check for update
+                    //fprintf(stderr,"Checking --- time %ld time to update %ld\n",current_time,last_time+next_time);
+                    if(current_time >= (last_time + next_time)) {
+                        next_time += next_time;
+                        if (next_time > max_transmit_time)
+                            next_time = max_transmit_time;
+
+                        last_time = current_time;
+                        do_time = 1;
+                    }
+                }
+            }
+
+            // Time to spit out a posit?   If emergency_beacon is enabled
+            // change to a relatively fast fixed beacon rate.  Should be
+            // more than a 30-second interval though to avoid digipeater
+            // dupe intervals of 30 seconds.
+            //
+            if ( my_position_valid
+                    && (   transmit_now
+                        || (emergency_beacon && (current_time > (posit_last_time + 60) ) )
+                        || (current_time > posit_next_time && POSIT_rate) ) ) {
+
+                //fprintf(stderr,"Transmitting posit\n");
+
+                // Check for proper symbol in case we're a weather station
+                (void)check_weather_symbol();
+
+                posit_last_time = current_time;
+
+                if (smart_beaconing) {
+                    // Schedule next computed posit time based on
+                    // speed/turns, etc.
+                    posit_next_time = posit_last_time + sb_POSIT_rate;
+                    sb_last_heading = sb_current_heading;
+                    //fprintf(stderr,"Sending Posit\n");
+                }
+                else {
+                    // Schedule next fixed posit time, set in
+                    // Configure->Defaults dialog
+                    posit_next_time = posit_last_time + POSIT_rate;
+                }
+
+                transmit_now = 0;
+                // Output to ALL net/tnc ports that are enabled & have tx enabled
+//fprintf(stderr,"Sending posit\n");
+                output_my_aprs_data();
+
+                // Decrement the my_position_valid variable if we're
+                // using GPS.  This will make sure that positions
+                // are valid, as we'll only get four positions out
+                // maximum per valid GPS position.  If the GPS
+                // position goes stale, we'll stop sending posits.
+                // We initialize it to one if we turn on a GPS
+                // interface, so we'll get at the very most one
+                // posit sent out with a stale position, each time
+                // we open a GPS interface.
+                if (using_gps_position && my_position_valid) {
+                    my_position_valid--;
+//fprintf(stderr,"my_position_valid:%d\n",my_position_valid);
+
+                    if (!my_position_valid) {   // We just went to zero!
+                        // Waiting for GPS data..
+                        statusline(langcode("BBARSTA041"),1);
+
+                        // If the user intends to send posits, GPS
+                        // interface is enabled, and we're not
+                        // getting GPS data, warn the user that
+                        // posits are disabled.
+                        if (!transmit_disable && !posit_tx_disable) {
+                            popup_message_always(langcode("POPEM00033"),
+                                langcode("POPEM00034"));
+                        }
+//fprintf(stderr,"my_position_valid just went to zero!\n");
+                    }
+                }
+            }
+//          if (do_time || transmit_now) {
+//              transmit_now = 0;
+//              // output to ALL net/tnc ports
+//              //fprintf(stderr,"Output data\n");
+//              output_my_aprs_data();
+//          }
+
+            // Must compute rain on a periodic basis, as some
+            // weather daemons don't put out data often enough
+            // to rotate through our queues.
+            // We also refresh the Station_info dialog here if
+            // it is currently drawn.
+            if (current_time >= (last_weather_cycle + 30)) {    // Every 30 seconds
+                // Note that we also write timestamps out to all of the log files
+                // from this routine.  It works out well with the 30 second update
+                // rate of cycle_weather().
+                (void)cycle_weather();
+                last_weather_cycle = current_time;
+
+                if (station_data_auto_update)
+                    update_station_info(w);  // Go refresh the Station Info display
+
+                // Time to put out raw WX data ?
+                if (current_time > sec_next_raw_wx) {
+                    sec_next_raw_wx = current_time+600;
+
+#ifdef TRANSMIT_RAW_WX
+                    if (transmit_raw_wx)
+                        tx_raw_wx_data();
+#endif  // TRANSMIT_RAW_WX
+
+                    // check wx data last received
+                    wx_last_data_check();
+                }
+            }
+
+            // is it time to spit out messages?
+            check_and_transmit_messages(current_time);
+
+            // Is it time to spit out any delayed ack's?
+            check_delayed_transmit_queue(current_time);
+
+            // Is it time to spit out objects/items?
+            check_and_transmit_objects_items(current_time);
+
+            // Do we have any new bulletins to display?
+            check_for_new_bulletins(current_time);
+
+            // Is it time to create a JPG snapshot?
+            if (snapshots_enabled)
+                (void)Snapshot();
+            
+            // Is it time to create a kml dump of all current stations
+            if (kmlsnapshots_enabled) { 
+                 if (sec_now() > (last_kmlsnapshot + (snapshot_interval * 60)) ) { 
+                    last_kmlsnapshot = sec_now(); // Set up timer for next time
+                    export_trail_as_kml(NULL);
+                 }
+            }
+
+            // Is it time to refresh maps? 
+            if ( map_refresh_interval && (current_time > map_refresh_time) ) {
+
+                // Reload maps
+                // Set interrupt_drawing_now because conditions have
+                // changed.
+                interrupt_drawing_now++;
+
+                // Request that a new image be created.  Calls
+                // create_image, XCopyArea, and display_zoom_status.
+                request_new_image++;
+
+//                if (create_image(da)) {
+//                    (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//                }
+
+                map_refresh_time = current_time + map_refresh_interval;
+            }
+
+            // get data from interfaces
+            max=0;
+            // Allow multiple packets to be processed inside this
+            // loop.  Well, it was a nice idea anyway.  See the
+            // below note.
+
+// CAREFUL HERE:  If we try to send to the Spider pipes faster than
+// it's reading from the pipes we corrupt the data out our server
+// ports.  Having too high of a number here or putting too small of
+// a delay down lower causes our server port to server up junk!
+
+            while (max < 1 && !XtAppPending(app_context)) {
+                struct timeval tmv;
+
+
+// Check the x_spider server for incoming data
+                if (enable_server_port) {
+                    // Check whether the x_spider server pipes have
+                    // any data for us.  Process if found.
+
+
+// Check the TCP pipe
+                    n = readline(pipe_tcp_server_to_xastir, line, MAX_LINE_SIZE);
+                    if (n == 0) {
+                        // Do nothing, empty packet
+                    }
+                    else if (n < 0) {
+                        //fprintf(stderr,"UpdateTime: Readline error: %d\n",errno);
+                        if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                            // This is normal if we have no data to read
+                            //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
+                        }
+                        else {  // Non-normal error.  Report it.
+                            fprintf(stderr,"UpdateTime: Readline error: %d\n",errno);
+                        }
+                    }
+                    else {  // We have a good packet
+                        // Knock off the linefeed at the end
+                        line[n-1] = '\0';
+
+                        if (log_net_data)
+                            log_data( get_user_base_dir(LOGFILE_NET, 
+                                                        temp_file_name,
+                                                        sizeof(temp_file_name)),
+                                (char *)line);
+
+//fprintf(stderr,"TCP server data:%d: %s\n", n, line);
+
+                        packet_data_add(langcode("WPUPDPD006"),
+                            (char *)line,
+                            -1);    // data_port -1 signifies x_spider
+
+                        // Set port to -2 here to designate that it
+                        // came from x_spider.  -1 = from a log
+                        // file, 0 - 14 = from normal interfaces.
+                        decode_ax25_line((char *)line,
+                            'I',
+                            -2, // Port -2 signifies x_spider data
+                            1);
+
+                        max++;  // Count the number of packets processed
+                    }
+
+
+// Check the UDP pipe
+                    n = readline(pipe_udp_server_to_xastir, line, MAX_LINE_SIZE);
+                    if (n == 0) {
+                        // Do nothing, empty packet
+                    }
+                    else if (n < 0) {
+                        //fprintf(stderr,"UpdateTime: Readline error: %d\n",errno);
+                        if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                            // This is normal if we have no data to read
+                            //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
+                        }
+                        else {  // Non-normal error.  Report it.
+                            fprintf(stderr,"UpdateTime: Readline error: %d\n",errno);
+                        }
+                    }
+                    else {  // We have a good packet
+                        char temp_call[10];
+                        int skip_decode = 0;
+
+
+                        // Knock off the linefeed at the end
+                        line[n-1] = '\0';
+
+                        // Check for "TO_INET," prefix, then check
+                        // for "TO_RF," prefix.  Set appropriate
+                        // flags and remove the prefixes if found.
+                        // x_spider.c will always put them in that
+                        // order if both flags are present, so we
+                        // don't need to check for the reverse
+                        // order.
+
+                        // Check for "TO_INET," string
+                        if (strncmp(line, "TO_INET,", 8) == 0) {
+//                            fprintf(stderr,"Xastir received UDP packet with \"TO_INET,\" prefix\n");
+                            line_offset += 8;
+//
+// "TO_INET" found.
+// This packet should be gated to the internet if and only if
+// igating is enabled.  This may happen automatically as-is, due to
+// the decode_ax25_line() call below.  Check whether that's true.
+//
+// We can always add "NOGATE" or "RFONLY" to the path before we dump
+// it to decode_ax25_line() in order to stop this igating...
+//
+                        }
+
+                        // Check for "TO_RF," string
+                        if (strncmp((char *)(line+line_offset), "TO_RF,", 6) == 0) {
+//                            fprintf(stderr,"Xastir received UDP packet with \"TO_RF,\" prefix\n");
+                            line_offset += 6;
+//
+// "TO_RF" found.
+// This packet should be sent out the local RF ports.  If the
+// callsign matches Xastir's (without the SSID), then send it out
+// first-person format.  If it doesn't, send it out third-party
+// format?
+//
+                            // Snag FROM callsign and do a non-exact
+                            // match on it against "my_callsign"
+                            xastir_snprintf(temp_call,
+                                sizeof(temp_call),
+                                "%s",
+                                (char *)(line+line_offset));
+                            if (strchr(temp_call,'>')) {
+                                *strchr(temp_call,'>') = '\0';
+                            }
+
+//                            if (is_my_call(temp_call, 0)) { // Match ignoring SSID
+//                            exact match
+                                // Send to RF as direct packet
+//fprintf(stderr,"\tBase callsigns Match!  Send to RF as direct packet\n");
+//fprintf(stderr,"\t%s\n", line);
+
+// Change this to go out only RF interfaces so we don't double-up on
+// the INET interfaces?  This would require looping on the
+// interfaces and checking type and transmit_enable for each, as is
+// done in output_igate_rf().  If we change to that method,
+// re-enable the decode_ax25_line() call below.
+//
+
+// Change to a third-party packet.  In this case we know we have a
+// line_offset, so backing up one to insert a char is ok.
+*(line + line_offset - 1) = '}';
+
+                            output_my_data(
+                                (char *)(line + line_offset - 1),  // Raw data line
+                                -1,    // ports, -1=send out all interfaces
+                                0,     // type: 0=cooked, 1=raw
+                                0,     // loopback_only
+                                0,     // use_igate_path
+                                NULL); // path
+
+//skip_decode++;
+
+                                igate_msgs_tx++;
+//                            }
+//                            else {  // Send to RF as 3rd party packet
+//fprintf(stderr,
+//    "\tBase callsigns don't match. Could send to RF as 3rd party packet, but dropping packet for now...\n");
+//fprintf(stderr,"\t%s\n", line);
+
+// Drop the packet for now, until we get more code added to turn it
+// into a 3rd party packet
+
+/*
+                                output_igate_rf(temp_call,
+                                    addr,
+                                    path,
+                                    (char *)(line + line_offset),
+                                    port,
+                                    1,
+                                    NULL);
+
+                            igate_msgs_tx++;
+*/
+//continue;
+//                            }
+                        }
+
+                        if (log_net_data)
+                            log_data( get_user_base_dir(LOGFILE_NET, 
+                                                        temp_file_name,
+                                                        sizeof(temp_file_name)),
+                                (char *)(line + line_offset));
+
+//fprintf(stderr,"UDP server data:  %s\n", line);
+//fprintf(stderr,"\tUDP server data2: %s\n\n", (char *)(line + line_offset));
+
+                        packet_data_add(langcode("WPUPDPD006"),
+                            (char *)(line + line_offset),
+                            -1);    // data_port -1 signifies x_spider
+
+// We don't need the below if we call output_my_data with -1 for the
+// port, as in that case it calls decode_ax25_line directly.
+
+if (!skip_decode) {
+
+                            // Set port to -2 here to designate that it
+                            // came from x_spider.  -1 = from a log
+                            // file, 0 - 14 = from normal interfaces.
+                            decode_ax25_line((char *)(line + line_offset),
+                                'I',
+                                -2, // Port -2 signifies x_spider data
+                                1);
+
+                            max++;  // Count the number of packets processed
+}
+
+                    }
+
+
+                }
+// End of x_spider server check code
+
+
+//if (begin_critical_section(&data_lock, "main.c:UpdateTime(1)" ) > 0)
+//    fprintf(stderr,"data_lock\n");
+
+
+// Check the rest of the ports for incoming data.  Process up to
+// 1000 packets here in a loop.
+
+                data_length = pop_incoming_data(data_string, &data_port);
+ 
+                if (data_length != 0) {
+                    int data_type;              // 0=AX25, 1=GPS
+
+                    // Terminate the string
+                    data_string[data_length] = '\0';
+
+                    //fprintf(stderr,"device_type: %d\n",port_data[data_port].device_type);
+
+                    switch (port_data[data_port].device_type) {
+                        // NET Data stream
+                        case DEVICE_NET_STREAM:
+
+                            if (log_net_data)
+                              log_data(get_user_base_dir(LOGFILE_NET,
+                                                         temp_file_name,
+                                                         sizeof(temp_file_name)),
+                                       (char *)data_string);
+
+                            packet_data_add(langcode("WPUPDPD006"),
+                                (char *)data_string,
+                                data_port);
+
+//fprintf(stderr,"\n-1 %s", data_string);
+
+                            if (enable_server_port) {
+                                char new_string[MAX_LINE_SIZE+1];
+
+                                // Terminate it with a linefeed
+                                xastir_snprintf(new_string,
+                                    data_length+1,
+                                    "%s\n",
+                                    data_string);
+
+//fprintf(stderr,"\n-2 %s", new_string);
+
+                                // Send data to the x_spider server
+                                if (writen(pipe_xastir_to_tcp_server,
+                                        new_string,
+                                        data_length+1) != data_length+1) {
+                                    if (errno != EPIPE) {
+                                        fprintf(stderr,
+                                            "UpdateTime: Writen error (Net send x_spider): %d\n",
+                                            errno);
+                                    }
+                                }
+//fprintf(stderr,"\n-3 %s", new_string);
+
+                            }
+                            // End of x_spider server send code
+
+                            decode_ax25_line((char *)data_string,
+                                'I',
+                                data_port,
+                                1);
+                            break;
+
+                        // TNC Devices
+                        case DEVICE_SERIAL_KISS_TNC:
+                        case DEVICE_SERIAL_MKISS_TNC:
+
+                            // Try to decode header and checksum.  If
+                            // bad, break, else continue through to
+                            // ASCII logging & decode routines.
+                            // Note that the length of data_string
+                            // can increase within decode_ax25_header().
+                            if ( !decode_ax25_header( (unsigned char *)data_string,
+                                    &data_length ) ) {
+                                // Had a problem decoding it.  Drop
+                                // it on the floor.
+                                break;
+                            }
+                            else {
+                                // Good decode.  Drop through to the
+                                // next block to log and decode the
+                                // packet.
+                            }
+
+                        case DEVICE_SERIAL_TNC:
+                            tnc_data_clean((char *)data_string);
+
+                        case DEVICE_AX25_TNC:
+                        case DEVICE_NET_AGWPE:
+                            if (log_tnc_data)
+                                log_data( get_user_base_dir(LOGFILE_TNC,
+                                                            temp_file_name,
+                                                            sizeof(temp_file_name)),
+                                    (char *)data_string);
+
+                            packet_data_add(langcode("WPUPDPD005"),
+                                (char *)data_string,
+                                data_port);
+
+                            if (enable_server_port) {
+                                char new_string[MAX_LINE_SIZE+1];
+
+                                // Terminate it with a linefeed
+                                xastir_snprintf(new_string,
+                                    MAX_LINE_SIZE+1,
+                                    "%s\n",
+                                    data_string);
+
+                                // Send data to the x_spider server
+                                if (writen(pipe_xastir_to_tcp_server,
+                                        new_string,
+                                        data_length+1) != data_length+1) {
+                                    fprintf(stderr,
+                                        "UpdateTime: Writen error (TNC Send x_spider): %d\n",
+                                        errno);
+                                }
+                            }
+                            // End of x_spider server send code
+
+                            decode_ax25_line((char *)data_string,
+                                'T',
+                                data_port,
+                                1);
+                            break;
+
+                        case DEVICE_SERIAL_TNC_HSP_GPS:
+                            if (port_data[data_port].dtr==1) { // get GPS data
+                                char temp[200];
+
+                                (void)gps_data_find((char *)data_string,
+                                    data_port);
+
+                                xastir_snprintf(temp,
+                                    sizeof(temp),
+                                    "GPS: ");
+                                strncat(temp,
+                                    report_gps_status(),
+                                    sizeof(temp) - 1 - strlen(temp));
+                                statusline(temp, 0);
+                            }
+                            else {
+                                // get TNC data
+                                if (log_tnc_data)
+                                    log_data( get_user_base_dir(LOGFILE_TNC,
+                                                                temp_file_name,
+                                                                sizeof(temp_file_name)),
+                                        (char *)data_string);
+
+                                packet_data_add(langcode("WPUPDPD005"),
+                                    (char *)data_string,
+                                    data_port);
+
+                                if (enable_server_port) {
+                                    char new_string[MAX_LINE_SIZE+1];
+
+                                    // Terminate it with a linefeed
+                                    xastir_snprintf(new_string,
+                                        MAX_LINE_SIZE+1,
+                                        "%s\n",
+                                        data_string);
+
+                                    // Send data to the x_spider server
+                                    if (writen(pipe_xastir_to_tcp_server,
+                                            new_string,
+                                            data_length+1) != data_length+1) {
+                                        fprintf(stderr,
+                                            "UpdateTime: Writen error(HSP data): %d\n",
+                                            errno);
+                                    }
+                                }
+                                // End of x_spider server send code
+
+                                decode_ax25_line((char *)data_string,
+                                    'T',
+                                    data_port,
+                                    1);
+                            }
+                            break;
+
+                        case DEVICE_SERIAL_TNC_AUX_GPS:
+                            tnc_data_clean((char *)data_string);
+                            data_type=tnc_get_data_type((char *)data_string,
+                                data_port);
+                            if (data_type) {  // GPS Data
+                                char temp[200];
+
+                                (void)gps_data_find((char *)data_string,
+                                    data_port);
+
+                                xastir_snprintf(temp,
+                                    sizeof(temp),
+                                    "GPS: ");
+                                strncat(temp,
+                                    report_gps_status(),
+                                    sizeof(temp) - 1 - strlen(temp));
+                                statusline(temp, 0);
+                            }
+                            else {          // APRS Data
+                                if (log_tnc_data)
+                                    log_data( get_user_base_dir(LOGFILE_TNC,
+                                                                temp_file_name,
+                                                                sizeof(temp_file_name)),
+                                        (char *)data_string);
+
+                                packet_data_add(langcode("WPUPDPD005"),
+                                    (char *)data_string,
+                                    data_port);
+
+                                if (enable_server_port) {
+                                    char new_string[MAX_LINE_SIZE+1];
+
+                                    // Terminate it with a linefeed
+                                    xastir_snprintf(new_string,
+                                        MAX_LINE_SIZE+1,
+                                        "%s\n",
+                                        data_string);
+
+                                    // Send data to the x_spider server
+                                    if (writen(pipe_xastir_to_tcp_server,
+                                            new_string,
+                                            data_length+1) != data_length+1) {
+                                        fprintf(stderr,
+                                            "UpdateTime: Writen error(TNC/GPS data): %d\n",
+                                            errno);
+                                    }
+                                }
+                                // End of x_spider server send code
+
+                                decode_ax25_line((char *)data_string,
+                                    'T',
+                                    data_port,
+                                    1);
+                            }
+                            break;
+
+                        // GPS Devices
+                        case DEVICE_SERIAL_GPS:
+
+                        case DEVICE_NET_GPSD:
+                            //fprintf(stderr,"GPS Data <%s>\n",data_string);
+                            (void)gps_data_find((char *)data_string,
+                                data_port);
+                            {
+                                char temp[200];
+
+                                xastir_snprintf(temp,
+                                    sizeof(temp),
+                                    "GPS: ");
+                                strncat(temp,
+                                    report_gps_status(),
+                                    sizeof(temp) - 1 - strlen(temp));
+                                statusline(temp, 0);
+                            }
+                            break;
+
+                        // WX Devices
+                        case DEVICE_SERIAL_WX:
+
+                        case DEVICE_NET_WX:
+                            if (log_wx)
+// TODO:  Probably only logs to the first 0x00 byte...  Need another
+// logging function that accepts a size, perhaps converting it to
+// 0x00 or similar as it writes to file.
+                                log_data( get_user_base_dir(LOGFILE_WX,
+                                                            temp_file_name,
+                                                            sizeof(temp_file_name)),
+                                    (char *)data_string);
+
+                            wx_decode(data_string, data_length, data_port);
+                            break;
+
+                        default:
+                            fprintf(stderr,"Data from unknown source\n");
+                            break;
+                    }
+                    max++;  // Count the number of packets processed
+                } else {
+                    max=1000;   // Go straight to "max": Exit loop
+                }
+
+//if (end_critical_section(&data_lock, "main.c:UpdateTime(2)" ) > 0)
+//    fprintf(stderr,"data_lock\n");
+
+                // Do a usleep() here to give the interface threads
+                // time to put something in the queue if they still
+                // have data to process.  We also need a delay here
+                // to allow the x_spider code to process packets
+                // we've sent to it.
+
+// NOTE:  There's a very delicate balance here between x_spider
+// server, sched_yield(), the delay below, and nexttime.  If we feed
+// packets to the x_spider server faster than it gets to process
+// them, we end up with blank lines and corrupted lines going to the
+// connected clients.
+
+                sched_yield();  // Yield to the other threads
+
+                if (enable_server_port) {
+                    tmv.tv_sec = 0;
+                    tmv.tv_usec = 2000; // Delay 2ms
+                    (void)select(0,NULL,NULL,NULL,&tmv);
+                }
+
+            }   // End of packet processing loop
+
+            // END- get data from interface
+            // READ FILE IF OPENED
+            if (read_file) {
+                if (current_time >= next_file_read) {
+                    read_file_line(read_file_ptr);
+                    next_file_read = current_time + REPLAY_DELAY;
+                }
+            }
+            // END- READ FILE IF OPENED
+        }
+
+        // If number of stations has changed, update the status
+        // line, but only once per second max.
+        if (station_count != station_count_save
+                && stations_status_time != current_time) {
+            // show number of stations in status line
+            xastir_snprintf(station_num,
+                sizeof(station_num),
+                langcode("BBARSTH001"),
+                currently_selected_stations,
+                station_count);
+            XmTextFieldSetString(text3, station_num);
+
+            // Set up for next time
+            station_count_save = station_count;
+            stations_status_time = current_time;
+        }
+
+        check_pointer_position();
+    }
+
+    sched_yield();  // Yield the processor to another thread
+
+    (void)XtAppAddTimeOut(XtWidgetToApplicationContext(w),
+        nexttime,
+        (XtTimerCallbackProc)UpdateTime,
+        (XtPointer)w);
+}
+
+
+
+
+
+void shut_down_server(void) {
+
+    // Shut down the server if it was enabled
+    if (tcp_server_pid || udp_server_pid) {
+
+        // Send a kill to the main server process
+        if (tcp_server_pid)
+            kill(tcp_server_pid, SIGHUP);
+
+        if (udp_server_pid)
+            kill(udp_server_pid, SIGHUP);
+
+        wait(NULL); // Reap the status of the process
+
+        // Send to all processes in our process group.  This will
+        // cause the server and all of its children to die.  Also
+        // causes Xastir to die!  Don't do it!
+        //kill(0, 1);
+
+        sleep(1);
+
+        // Send a more forceful kill signal in case the "nice" kill
+        // signal didn't work.
+        if (tcp_server_pid)
+            kill(tcp_server_pid, SIGKILL);
+
+        if (udp_server_pid)
+            kill(udp_server_pid, SIGKILL);
+    }
+}
+
+
+
+
+
+// This is the SIGHUP handler.  We restart Xastir if we receive a
+// SIGHUP, hopefully with the same environment that the original
+// Xastir had.  We set a global variable, then UpdateTime() is the
+// process that actually calls execve() in order to replace our
+// current process with the new one.  This assures that the signal
+// handler gets reset.  We can't call execve() from inside the
+// signal handler and have the restart work more than once.
+//
+// This function should be nearly identical to the quit() function
+// below.
+//
+// One strangeness is that this routine gets called when any of the
+// spawned processes get a SIGHUP also, which means when we shut
+// down the TCP/UDP servers or similar.  For some reason it still
+// appears to work, even though restart() gets called multiple
+// times when we shut down Xastir or the servers.  We probably need
+// to call signal() from outside any signal handlers to tell it to
+// ignore further SIGHUP's.
+//
+static void restart(int sig) {
+
+    char temp_file_name[MAX_VALUE];
+
+//    if (debug_level & 1)
+        fprintf(stderr,"Shutting down Xastir...\n");
+
+    save_data();
+
+    // shutdown all interfaces
+    shutdown_all_active_or_defined_port(-1);
+
+    shut_down_server();
+
+#ifdef USE_PID_FILE_CHECK 
+    // remove the PID file
+    unlink(get_user_base_dir("xastir.pid", temp_file_name, 
+                             sizeof(temp_file_name))); 
+#endif
+
+#ifdef HAVE_LIBCURL
+    curl_global_cleanup();
+#endif
+
+#ifdef USING_LIBGC
+    CHECK_LEAKS();
+#endif  // USING LIBGC
+
+//    if (debug_level & 1)
+        fprintf(stderr,"Attempting to restart Xastir...\n");
+
+    // Set the global variable which tells UpdateTime() to do a
+    // restart.
+    //
+    restart_xastir_now++;
+}
+
+
+
+
+
+static void quit(int sig) {
+
+    char temp_file_name[MAX_VALUE];
+
+    if(debug_level & 15)
+        fprintf(stderr,"Caught %d\n",sig);
+
+    save_data();
+
+    // shutdown all interfaces
+    shutdown_all_active_or_defined_port(-1);
+
+    shut_down_server();
+
+
+#ifdef USE_PID_FILE_CHECK 
+    // remove the PID file
+    unlink(get_user_base_dir("xastir.pid",temp_file_name, 
+                             sizeof(temp_file_name))); 
+#endif
+
+    if (debug_level & 1)
+        fprintf(stderr,"Exiting Xastir...\n");
+
+#ifdef HAVE_LIBCURL
+    curl_global_cleanup();
+#endif
+
+    clear_application_context();
+#ifdef USING_LIBGC
+    CHECK_LEAKS();
+#endif  // USING LIBGC
+
+    exit(sig);  // Main exit from the program
+}
+
+
+
+
+
+#ifdef USE_PID_FILE_CHECK
+
+static int pid_file_check(int hold){
+
+    int killret=0; 
+    int other_pid=0;
+    char temp[32] ; 
+    FILE * PIDFILE ; 
+    char temp_file_name[MAX_VALUE];
+
+    /* Save our PID */
+    
+    char pidfile_name[MAX_FILENAME];
+
+    xastir_snprintf(pidfile_name, sizeof(pidfile_name),
+        "%s",
+        get_user_base_dir("xastir.pid", temp_file_name, 
+                          sizeof(temp_file_name))); 
+
+    if (filethere(pidfile_name)){
+        fprintf(stderr,"Found pid file: %s\n",pidfile_name);
+        PIDFILE=fopen(pidfile_name,"r");
+        if (PIDFILE!=NULL) {
+            if(!feof(PIDFILE)) {
+                (void)get_line(PIDFILE,temp,32);
+            }
+            (void)fclose(PIDFILE);
+            other_pid=atoi(temp);
+        } else {
+            fprintf(stderr,"Couldn't open file: %s\n", pidfile_name);
+        }
+
+        // send a ping 
+        killret = kill(other_pid,0); 
+
+#ifdef N8YSZ
+            fprintf(stderr, "other_pid = <%d> killret == <%d> errno == <%d>\n",
+                other_pid,killret,errno); 
+#endif
+        if ((killret == -1) && (errno == ESRCH ) && !hold){
+            fprintf(stderr,
+                "Other Xastir process, pid: %d does not appear be running. \n",
+                other_pid);
+	    // nuke from orbit
+	    if (unlink(pidfile_name)) {
+	            fprintf(stderr,"Error unlinking pid file: %s, %d\n",
+                        pidfile_name,errno);
+            }
+        } else {
+            fprintf(stderr,
+                "Other Xastir process, pid: %d may be running. Exiting..\n",
+                other_pid);
+        
+#ifdef USING_LIBGC
+            CHECK_LEAKS();
+#endif  // USING LIBGC
+            exit(-1);  // Quick exit from the program
+        }
+
+    } else {
+    	
+    // if we're here - ok to truncate & open pidfile. 
+
+#ifdef N8YSZ
+        fprintf(stderr, "other_pid = <%d> killret == <%d> errno == <%d>\n",
+                other_pid,killret,errno); 
+#endif
+
+        PIDFILE = fopen(pidfile_name,"w");
+        if(PIDFILE != NULL){
+            fprintf(PIDFILE, "%d",getpid()); 
+            (void) fclose (PIDFILE);
+            return(0); 
+        } else {
+            fprintf(stderr, "Error opening pidfile: %s\n", strerror(errno) );
+            return(errno); 
+        } 
+        return(0);
+    }
+    return(0); 
+} // end pid_file_check
+
+#endif 
+
+
+/* handle segfault signal */
+void segfault(/*@unused@*/ int sig) {
+    fprintf(stderr, "Caught Segfault! Xastir will terminate\n");
+    fprintf(stderr, "Previous incoming line was: %s\n", incoming_data_copy_previous);
+    fprintf(stderr, "    Last incoming line was: %s\n", incoming_data_copy);
+    if (dangerous_operation[0] != '\0')
+        fprintf(stderr, "Possibly died at: %s\n", dangerous_operation);
+    fprintf(stderr, "%02d:%02d:%02d\n", get_hours(), get_minutes(), get_seconds() );
+
+    shut_down_server();
+
+    quit(-1);
+}
+
+
+
+
+
+/*  
+   Added by KB4AMA
+   Handle USR1 signal.  This will cause
+   a snapshot to be generated.
+*/
+#ifndef OLD_PTHREADS
+void usr1sig(int sig) {
+    if (debug_level & 512)
+        fprintf(stderr, "Caught Signal USR1, Doing a snapshot! Signal No %d\n", sig);
+
+    last_snapshot = 0;
+    (void)Snapshot();
+}
+void usr2sig(int sig) {
+    if (debug_level & 512)
+        fprintf(stderr, "Caught Signal USR2, Transmitting now! Signal No %d\n", sig);
+
+    transmit_now = 1;
+}
+#endif  // OLD_PTHREADS
+
+
+
+
+
+/*********************  dialog position *************************/
+
+void pos_dialog(Widget w) {
+    static Position x,y;
+    Dimension wd, ht;
+    int max_x, max_y;
+
+    XtVaGetValues(appshell, XmNx, &x, XmNy, &y, NULL);
+    XtVaGetValues(appshell, XmNwidth, &wd, XmNheight, &ht, NULL);
+
+    if (x > 1280)   // We sometimes get strange values for X/Y
+        x = 300;
+
+    if (y > 1024)   // We sometimes get strange values for X/Y
+        y = 200;
+
+    if (wd > 1280)  // And for width and height
+        wd = 640;
+
+    if (ht > 1024)  // And for width and height
+        ht = 480;
+
+    max_x = x + wd - (wd / 5);
+//    max_y = y + ht - (ht / 5);
+    max_y = y + ht/3;
+
+    // Check for proper values for last stored position
+    if (   (last_popup_x < x)
+        || (last_popup_y < y)
+        || (last_popup_x > max_x)
+        || (last_popup_y > max_y) ) {
+        last_popup_x = x + 20;  // Go to initial position again
+        last_popup_y = y + 30;  // Go to initial position again
+    } else {
+        last_popup_x += 10;     // Increment slightly for next dialog
+        last_popup_y += 20;     // Increment slightly for next dialog
+    }
+
+    if ((last_popup_y+50) > max_y) {
+        last_popup_x = x + 20;  // Go to initial position again
+        last_popup_y = y + 30;  // Go to initial position again
+    }
+
+    if ((last_popup_x+50) > max_x) {
+        last_popup_x = x + 20;  // Go to initial position again
+        last_popup_y = y + 30;  // Go to initial position again
+    }
+
+#ifdef FIXED_DIALOG_STARTUP
+    XtVaSetValues(w,XmNx,x,XmNy,y,NULL);
+#else
+    XtVaSetValues(w,XmNx,last_popup_x,XmNy,last_popup_y,NULL);
+#endif // FIXED_DIALOG_STARTUP
+
+    //fprintf(stderr,"max_x:%d max_y:%d x:%d y:%d wd:%d ht:%d last_x:%d last_y:%d\n",
+        //max_x,max_y,x,y,wd,ht,last_popup_x,last_popup_y);
+}
+
+
+
+/*********************  fix dialog size *************************/
+
+void fix_dialog_size(Widget w) {
+    Dimension wd, ht;
+
+    if (XtIsRealized(w)){
+        XtVaGetValues(w,
+                  XmNwidth, &wd,
+                  XmNheight, &ht,
+                  NULL);
+
+        XtVaSetValues(w,
+                  XmNminWidth,wd,
+                  XmNminHeight,ht,
+                  XmNmaxWidth,wd,
+                  XmNmaxHeight,ht,
+                  NULL);
+    }
+}
+
+
+
+/******************** fix dialog size vertically only *************/
+
+void fix_dialog_vsize(Widget w) {
+    Dimension ht;
+
+    if (XtIsRealized(w)){
+        XtVaGetValues(w,
+                  XmNheight, &ht,
+                  NULL);
+
+        XtVaSetValues(w,
+                  XmNminHeight,ht,
+                  XmNmaxHeight,ht,
+                  NULL);
+    }
+}
+
+
+
+/**************************************** Button CallBacks *************************************/
+/***********************************************************************************************/
+
+
+/*
+ *  Button callback for 1 out of 2 selection
+ */
+void on_off_switch(int switchpos, Widget first, Widget second) {
+    if(switchpos) {
+        XtSetSensitive(first, FALSE);
+        XtSetSensitive(second,TRUE);
+    } else {
+        XtSetSensitive(first, TRUE);
+        XtSetSensitive(second,FALSE);
+    }
+}
+
+
+
+
+
+/*
+ *  Button callback for 1 out of 3 selection
+ */
+void sel3_switch(int switchpos, Widget first, Widget second, Widget third) {
+    if(switchpos == 2) {
+        XtSetSensitive(first, FALSE);
+        XtSetSensitive(second,TRUE);
+        XtSetSensitive(third, TRUE);
+    } else if(switchpos == 1) {
+        XtSetSensitive(first, TRUE);
+        XtSetSensitive(second,FALSE);
+        XtSetSensitive(third, TRUE);
+    } else {
+        XtSetSensitive(first, TRUE);
+        XtSetSensitive(second,TRUE);
+        XtSetSensitive(third, FALSE);
+    }
+}
+
+
+/*
+ *  Button callback for 1 out of 4 selection
+ */
+void sel4_switch(int switchpos, Widget first, Widget second, Widget third, Widget fourth) {
+    if(switchpos == 3) {
+        XtSetSensitive(first, FALSE);
+        XtSetSensitive(second,TRUE);
+        XtSetSensitive(third, TRUE);
+        XtSetSensitive(fourth, TRUE);
+    } else if(switchpos == 2) {
+        XtSetSensitive(first, TRUE);
+        XtSetSensitive(second,FALSE);
+        XtSetSensitive(third, TRUE);
+        XtSetSensitive(fourth, TRUE);
+    } else if(switchpos == 1) {
+        XtSetSensitive(first, TRUE);
+        XtSetSensitive(second,TRUE);
+        XtSetSensitive(third, FALSE);
+        XtSetSensitive(fourth, TRUE);
+    } else {
+        XtSetSensitive(first, TRUE);
+        XtSetSensitive(second,TRUE);
+        XtSetSensitive(third, TRUE);
+        XtSetSensitive(fourth, FALSE);
+    }
+}
+
+
+
+
+
+// Called by UpdateTime when request_new_image flag is set.
+void new_image(Widget da) {
+
+
+    busy_cursor(appshell);
+
+    // Reset flags
+    interrupt_drawing_now = 0;
+    request_new_image = 0;
+
+
+    // Set up floating point lat/long values to match Xastir
+    // coordinates (speeds things up when dealing with lat/long
+    // values later).
+    convert_from_xastir_coordinates(&f_center_longitude,
+        &f_center_latitude,
+        center_longitude,
+        center_latitude);
+
+    if (create_image(da)) {
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now)
+            return;
+
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+
+        // We just refreshed the screen, so don't try to erase any
+        // zoom-in boxes via XOR.
+        zoom_box_x1 = -1;
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now)
+            return;
+
+        display_zoom_status();
+    }
+}
+
+
+
+
+
+/*
+ *  Keep map in real world space, readjust center and scaling if neccessary
+ */
+void check_range(void) {
+    Dimension width, height;
+
+
+    XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+
+    // Check the window itself to see if our new y-scale fits it
+    //
+    if ((height*new_scale_y) > 64800000l) {
+
+        // Center between 90�N and 90�S
+        new_mid_y  =  64800000l/2;
+
+        // Adjust y-scaling so that we fit perfectly in the window
+        new_scale_y = 64800000l / height;
+    }
+
+    if ((new_mid_y < (height*new_scale_y)/2))
+            new_mid_y  = (height*new_scale_y)/2;    // upper border max 90�N
+
+    if ((new_mid_y + (height*new_scale_y)/2) > 64800000l)
+        new_mid_y = 64800000l-((height*new_scale_y)/2); // lower border max 90�S
+
+    // Adjust scaling based on latitude of new center
+    new_scale_x = get_x_scale(new_mid_x,new_mid_y,new_scale_y);  // recalc x scaling depending on position
+
+    if (debug_level & 512) {
+        fprintf(stderr,"checkrange- x:%ld\ty:%ld\n\n",new_scale_x,new_scale_y);
+    }
+
+//    // scale_x will always be bigger than scale_y, so no problem here...
+//    if ((width*new_scale_x) > 129600000l) {
+//        // Center between 180�W and 180�E
+//        new_mid_x = 129600000l/2;
+//    }
+
+
+// The below code causes the map image to snap to the left or right
+// of the display.  I'd rather see the scale factor changed so that
+// the map fits perfectly left/right in the display, so that we
+// cannot go past the edges of the earth.  Change the code to work
+// this way later.  We'll have to compute new_y_scale from the
+// new_x_scale once we scale X appropriately, then will probably
+// have to test the y scaling again?
+
+
+/*
+    // Check against left border
+    if ((new_mid_x < (width*new_scale_x)/2)) {
+        // This will cause the map image to snap to the left of the
+        // display.
+        new_mid_x = (width*new_scale_x)/2;  // left border max 180�W
+    }
+    else {
+        // Check against right border
+        if ((new_mid_x + (width*new_scale_x)/2) > 129600000l)
+            // This will cause the map image to snap to the right of
+            // the display.
+            new_mid_x = 129600000l-((width*new_scale_x)/2); // right border max 180�E
+    }
+*/
+
+
+// long NW_corner_longitude;             // Longitude at top NW corner of map screen
+// long NW_corner_latitude;              // Latitude  at top NW corner of map screen
+
+/*
+if (NW_corner_longitude < 0l) {
+//    fprintf(stderr,"left\n");
+    NW_corner_longitude = 0l;         // New left viewpoint edge
+    new_mid_x = 0l + ((width*new_scale_x) / 2); // New midpoint
+}
+if ( (NW_corner_longitude + (width*new_scale_x) ) > 129600000l) {
+//    fprintf(stderr,"right\n");
+    NW_corner_longitude = 129600000l - (width*new_scale_x);   // New left viewpoint edge
+    new_mid_x = 129600000l - ((width*new_scale_x) / 2); // New midpoint
+}
+*/
+
+// Find the four corners of the map in the new scale system.  Make
+// sure they are on the display, but not well inside the borders of
+// the display.
+
+// We keep getting center_longitude out of range when zooming out
+// and having the edge of the world map to the right of the middle
+// of the window.  This shows up in new_image() above during the
+// convert_from_xastir_coordinates() call.  new_mid_x is the data of
+// interest in this routine.
+
+}
+
+
+
+
+
+/*
+ *  Display a new map view after checking the view and scaling
+ */
+void display_zoom_image(int recenter) {
+    Dimension width, height;
+
+    XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+//fprintf(stderr,"Before,  x: %lu,  y: %lu\n",new_scale_x,new_scale_y);
+    check_range();              // keep map inside world and calc x scaling
+//fprintf(stderr,"After,   x: %lu,  y: %lu\n\n",new_scale_x,new_scale_y);
+    if (new_mid_x != center_longitude
+            || new_mid_y != center_latitude
+            || new_scale_x != scale_x
+            || new_scale_y != scale_y) {    // If there's been a change in zoom or center
+
+        set_last_position();
+
+        if (recenter) {
+            center_longitude = new_mid_x;      // new map center
+            center_latitude  = new_mid_y;
+        }
+        scale_x = new_scale_x;
+        scale_y = new_scale_y;
+
+        setup_in_view();    // update "in view" flag for all stations
+
+        // Set the interrupt_drawing_now flag
+        interrupt_drawing_now++;
+
+        // Request that a new image be created.  Calls create_image,
+        // XCopyArea, and display_zoom_status.
+        request_new_image++;
+//        last_input_event = sec_now() + 2;
+        
+    } else {    // No change in zoom or center.  Don't update ANYTHING.
+    }
+}
+
+
+
+
+
+void Zoom_in( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+        new_mid_y = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+        new_scale_y = scale_y / 2;
+        if (new_scale_y < 1)
+            new_scale_y = 1;            // don't go further in
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Zoom_in_no_pan( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up && !map_lock_pan_zoom) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude;
+        new_mid_y = center_latitude;
+        new_scale_y = scale_y / 2;
+        if (new_scale_y < 1)
+            new_scale_y = 1;            // don't go further in, scale_x always bigger than scale_y
+        display_zoom_image(0);          // check range and do display, keep center
+    }
+}
+
+
+
+
+
+void Zoom_out(  /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+        new_mid_y = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+        if (width*scale_x < 129600000l || height*scale_y < 64800000l)
+            new_scale_y = scale_y * 2;
+        else
+            new_scale_y = scale_y;      // don't zoom out if whole world could be shown
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Zoom_out_no_pan( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up && !map_lock_pan_zoom) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude;
+        new_mid_y = center_latitude;
+        if (width*scale_x < 129600000l || height*scale_y < 64800000l)
+            new_scale_y = scale_y * 2;
+        else
+            new_scale_y = scale_y;      // don't zoom out if whole world could be shown
+        display_zoom_image(0);          // check range and do display, keep center
+    }
+}
+
+
+
+
+
+void Custom_Zoom_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    custom_zoom_dialog = (Widget)NULL;
+}
+
+
+
+
+
+static Widget custom_zoom_zoom_level;
+
+
+
+
+
+void Custom_Zoom_do_it( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char *temp_ptr;
+
+    temp_ptr = XmTextFieldGetString(custom_zoom_zoom_level);
+    scale_y = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    new_scale_y = scale_y;
+    display_zoom_image(1);
+}
+
+
+
+
+
+// Function to bring up a dialog.  User can then select zoom for the
+// display directly.
+//
+void Custom_Zoom( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    static Widget  pane,form, button_ok, button_cancel, zoom_label;
+//    Arg al[50];           /* Arg List */
+//    unsigned int ac = 0;           /* Arg Count */
+    Atom delw;
+    char temp[50];
+
+    if(!custom_zoom_dialog) {
+
+        // "Custom Zoom"
+        custom_zoom_dialog = XtVaCreatePopupShell(langcode("POPUPMA034"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNresize, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Jump_location pane",
+                xmPanedWindowWidgetClass,
+                custom_zoom_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        form =  XtVaCreateWidget("Jump_location form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 2,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // "Zoom Level"
+        zoom_label = XtVaCreateManagedWidget(langcode("POPUPMA004"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        custom_zoom_zoom_level = XtVaCreateManagedWidget("Custom_Zoom zoom_level",
+                xmTextFieldWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,      1,
+                XmNcolumns,6,
+                XmNwidth,((6*7)+2),
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, zoom_label,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("JMLPO00002"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zoom_label,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zoom_label,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, Custom_Zoom_destroy_shell, custom_zoom_dialog);
+        XtAddCallback(button_ok, XmNactivateCallback, Custom_Zoom_do_it, NULL);
+
+        pos_dialog(custom_zoom_dialog);
+
+        delw = XmInternAtom(XtDisplay(custom_zoom_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(custom_zoom_dialog, delw, Custom_Zoom_destroy_shell, (XtPointer)custom_zoom_dialog);
+
+
+        // Snag the current zoom value, convert them to
+        // displayable values, and fill in the fields.
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%ld",
+            scale_y);
+        XmTextFieldSetString(custom_zoom_zoom_level, temp); 
+
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(custom_zoom_dialog,XtGrabNone);
+        fix_dialog_size(custom_zoom_dialog);
+
+        // Move focus to the Close button.  This appears to
+        // highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit
+        // the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(custom_zoom_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else {
+        XtPopup(custom_zoom_dialog,XtGrabNone);
+        (void)XRaiseWindow(XtDisplay(custom_zoom_dialog), XtWindow(custom_zoom_dialog));
+    }
+}
+
+
+
+
+
+void Zoom_level( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+    int level;
+
+    level=atoi((char *)clientData);
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+        new_mid_y = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+        switch(level) {
+            case(1):
+                new_scale_y = 1;
+                break;
+
+            case(2):
+                new_scale_y = 16;
+                break;
+
+            case(3):
+                new_scale_y = 64;
+                break;
+
+            case(4):
+                new_scale_y = 256;
+                break;
+
+            case(5):
+                new_scale_y = 1024;
+                break;
+
+            case(6):
+                new_scale_y = 8192;
+                break;
+
+            case(7):
+
+//WE7U
+// Here it'd be good to calculate what zoom level the entire world
+// would best fit in, instead of fixing the scale to a particular
+// amount.  Figure out which zoom level would fit in the X and the Y
+// direction, and then pick the higher zoom level of the two (to
+// make sure the world fits in both).  We should probably center at
+// 0.0N/0.0W as well.
+
+                new_scale_y = 500000;
+
+                // Center on Earth (0/0)
+//                new_mid_x = 12900000l / 2;
+//                new_mid_y = 6480000l  / 2;
+                break;
+
+            case(8):    // 10% out
+                new_scale_y = (int)(scale_y * 1.1);
+                if (new_scale_y == scale_y)
+                  new_scale_y++;
+                break;
+
+            case(9):    // 10% in
+                new_scale_y = (int)(scale_y * 0.9);
+                // Don't allow the user to go in further than zoom 1
+                if (new_scale_y < 1)
+                    new_scale_y = 1;
+                break;
+
+            // Pop up a new dialog that allows the user to select
+            // the zoom level, then causes that zoom level and the
+            // right-click mouse location to take effect on the map
+            // window.  Similar to the Center_Zoom function but with
+            // the mouse coordinates instead of the center of the
+            // screen.
+            case(10):   // Custom Zoom Level
+
+                // Pop up a new dialog that allows the user to
+                // select the zoom level, then causes that zoom
+                // level and the right-click mouse location to take
+                // effect on the map window.  Similar to the
+                // Center_Zoom function but with the mouse
+                // coordinates instead of the center of the screen.
+
+                // Set up new_scale_y for whatever custom zoom level
+                // the user has chosen, then call
+                // display_zoom_image() from the callback there.
+                //
+                Custom_Zoom( w, clientData, calldata);
+                return;
+                break;
+
+            default:
+                break;
+        }
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_ctr( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+        new_mid_y = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_up( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude;
+        new_mid_y = center_latitude  - (height*scale_y/4);
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_up_less( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up && !map_lock_pan_zoom) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude;
+        new_mid_y = center_latitude  - (height*scale_y/10);
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_down( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude;
+        new_mid_y = center_latitude  + (height*scale_y/4);
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_down_less( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up && !map_lock_pan_zoom) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude;
+        new_mid_y = center_latitude  + (height*scale_y/10);
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_left( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude - (width*scale_x/4);
+        new_mid_y = center_latitude;
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_left_less( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up && !map_lock_pan_zoom) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude - (width*scale_x/10);
+        new_mid_y = center_latitude;
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_right( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude + (width*scale_x/4);
+        new_mid_y = center_latitude;
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Pan_right_less( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    Dimension width, height;
+
+    if(display_up && !map_lock_pan_zoom) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        new_mid_x = center_longitude + (width*scale_x/10);
+        new_mid_y = center_latitude;
+        new_scale_y = scale_y;          // keep size
+        display_zoom_image(1);          // check range and do display, recenter
+    }
+}
+
+
+
+
+
+void Center_Zoom_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    center_zoom_dialog = (Widget)NULL;
+}
+
+
+
+
+
+static Widget center_zoom_latitude,
+            center_zoom_longitude,
+            center_zoom_zoom_level;
+
+
+
+
+
+void Center_Zoom_do_it( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    unsigned long x, y;
+    char *temp_ptr;
+
+
+    temp_ptr = XmTextFieldGetString(center_zoom_latitude);
+    f_center_latitude  = atof(temp_ptr); 
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(center_zoom_longitude);
+    f_center_longitude = atof(temp_ptr);
+    XtFree(temp_ptr);
+
+    //Convert to Xastir coordinate system for lat/long
+    convert_to_xastir_coordinates(&x,
+        &y,
+        f_center_longitude,
+        f_center_latitude);
+
+    temp_ptr = XmTextFieldGetString(center_zoom_zoom_level);
+    scale_y = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    new_mid_x = x;
+    new_mid_y = y;
+    new_scale_y = scale_y;
+    display_zoom_image(1);
+}
+
+
+
+
+
+void Go_Home( Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    DataRow *p_station;
+
+    if (!map_lock_pan_zoom) {
+        if (search_station_name(&p_station,my_callsign,1)) {
+            set_map_position(w, p_station->coord_lat, p_station->coord_lon);
+        }
+    }
+}
+
+
+
+
+
+// Function to bring up a dialog.  User can then select the center
+// and zoom for the display directly.
+//
+// Later it would be nice to have a "Calc" button so that the user
+// could input lat/long in any of the supported formats.  Right now
+// it is DD.DDDD format only.
+//
+void Center_Zoom( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    static Widget  pane,form, button_ok, button_cancel,
+            lat_label, lon_label, zoom_label;
+//    Arg al[50];           /* Arg List */
+//    unsigned int ac = 0;           /* Arg Count */
+    Atom delw;
+    char temp[50];
+
+    if(!center_zoom_dialog) {
+
+        // "Center & Zoom"
+        center_zoom_dialog = XtVaCreatePopupShell(langcode("POPUPMA026"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNresize, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Jump_location pane",
+                xmPanedWindowWidgetClass,
+                center_zoom_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        form =  XtVaCreateWidget("Jump_location form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 2,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // "Latitude"
+        lat_label = XtVaCreateManagedWidget(langcode("POPUPMA027"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        center_zoom_latitude = XtVaCreateManagedWidget("Center_Zoom latitude",
+                xmTextFieldWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,      1,
+                XmNcolumns,21,
+                XmNwidth,((21*7)+2),
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, lat_label,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Longitude"
+        lon_label = XtVaCreateManagedWidget(langcode("POPUPMA028"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, lat_label,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        center_zoom_longitude = XtVaCreateManagedWidget("Center_Zoom longitude",
+                xmTextFieldWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,      1,
+                XmNcolumns,21,
+                XmNwidth,((21*7)+2),
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, lat_label,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, lon_label,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Zoom Level"
+        zoom_label = XtVaCreateManagedWidget(langcode("POPUPMA004"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, lon_label,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        center_zoom_zoom_level = XtVaCreateManagedWidget("Center_Zoom zoom_level",
+                xmTextFieldWidgetClass,
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,      1,
+                XmNcolumns,21,
+                XmNwidth,((21*7)+2),
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, lon_label,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, zoom_label,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("JMLPO00002"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zoom_label,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zoom_label,
+                XmNtopOffset,15,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, Center_Zoom_destroy_shell, center_zoom_dialog);
+        XtAddCallback(button_ok, XmNactivateCallback, Center_Zoom_do_it, NULL);
+
+        pos_dialog(center_zoom_dialog);
+
+        delw = XmInternAtom(XtDisplay(center_zoom_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(center_zoom_dialog, delw, Center_Zoom_destroy_shell, (XtPointer)center_zoom_dialog);
+
+
+        if (center_zoom_override) { // We've found a Map View
+                                    // "eyeball" object and are
+                                    // doing a center/zoom based on
+                                    // that object's info.  Grab the
+                                    // pointer to the object which
+                                    // is in calldata.
+            DataRow *p_station = (DataRow *)calldata;
+            float f_latitude, f_longitude;
+            int range;
+            Dimension width, height;
+            long x, x0, y, y0;
+            double x_miles, y_miles, distance;
+            char temp_course[10];
+            double scale_factor;
+            long my_scale_y;
+            int fell_off = 0;
+
+
+//fprintf(stderr,"Map View Object: %s\n",p_station->call_sign);
+
+            center_zoom_override = 0;
+
+
+            // Snag the objects values, convert them to displayable
+            // values, and fill in the fields.
+            convert_from_xastir_coordinates(&f_longitude,
+                &f_latitude,
+                p_station->coord_lon,
+                p_station->coord_lat);
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%f",
+                f_latitude);
+            XmTextFieldSetString(center_zoom_latitude, temp); 
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%f",
+                f_longitude);
+            XmTextFieldSetString(center_zoom_longitude, temp); 
+
+            // Compute the approximate zoom level we need from the
+            // range value in the object.  Range is in miles.
+            range = atoi(&p_station->power_gain[3]);
+
+            // We should be able to compute the distance across the
+            // screen that we currently have, then compute an
+            // accurate zoom level that will give us the range we
+            // want.
+
+            // Find out the screen values
+            XtVaGetValues(da,XmNwidth, &width, XmNheight, &height, NULL);
+
+            // Convert points to Xastir coordinate system
+
+            // X
+            x = center_longitude  - ((width *scale_x)/2);
+
+            // Check for the edge of the earth
+            if (x < 0) {
+                x = 0;
+                fell_off++; // Fell off the edge of the earth
+            }
+
+            x0 = center_longitude; // Center of screen
+
+            // Y
+            y = center_latitude   - ((height*scale_y)/2);
+
+            // Check for the edge of the earth
+            if (y < 0) {
+                y = 0;
+                fell_off++; // Fell off the edge of the earth
+            }
+
+            y0 = center_latitude;  // Center of screen
+
+            // Compute distance from center to each edge
+
+            // X distance.  Keep Y constant.
+            x_miles = cvt_kn2len
+                * calc_distance_course(y0,
+                    x0,
+                    y0,
+                    x,
+                    temp_course,
+                    sizeof(temp_course));
+
+            // Y distance.  Keep X constant.
+            y_miles = cvt_kn2len
+                * calc_distance_course(y0,
+                    x0,
+                    y,
+                    x0,
+                    temp_course,
+                    sizeof(temp_course));
+
+            // Choose the smaller distance
+            if (x_miles < y_miles) {
+                distance = x_miles;
+            }
+            else {
+                distance = y_miles;
+            }
+//fprintf(stderr,"Current screen range: %f\n", distance);
+//fprintf(stderr,"Desired screen range: %d\n", range);
+
+// Note that these numbers will be off if we're zoomed out way too
+// far (edges of the earth are inside the screen view).
+
+            // Now we know the range of the current screen
+            // (distance) in miles.  Compute what we need from
+            // "distance" (screen) and "range" (object) in order to
+            // get a scale factor we can apply to our zoom numbers.
+            if (distance < range) {
+//fprintf(stderr,"Zooming out\n");
+                scale_factor = (range * 1.0)/distance;
+//                fprintf(stderr,"Scale Factor: %f\n", scale_factor);
+                my_scale_y = (long)(scale_y * scale_factor);
+            }
+            else {  // distance > range
+//fprintf(stderr,"Zooming in\n");
+                scale_factor = distance/(range * 1.0);
+//fprintf(stderr,"Scale Factor: %f\n", scale_factor);
+                my_scale_y = (long)(scale_y / scale_factor);
+            }
+
+            if (my_scale_y < 1)
+                my_scale_y = 1;
+
+//fprintf(stderr,"my_scale_y: %ld\n", my_scale_y);
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%ld",
+                my_scale_y);
+            XmTextFieldSetString(center_zoom_zoom_level, temp); 
+        }
+        else {
+            // Normal user-initiated center/zoom function
+
+            // Snag the current lat/long/center values, convert them to
+            // displayable values, and fill in the fields.
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%f",
+                f_center_latitude);
+            XmTextFieldSetString(center_zoom_latitude, temp); 
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%f",
+                f_center_longitude);
+            XmTextFieldSetString(center_zoom_longitude, temp); 
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%ld",
+                scale_y);
+            XmTextFieldSetString(center_zoom_zoom_level, temp); 
+        }
+
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+        XtPopup(center_zoom_dialog,XtGrabNone);
+        fix_dialog_size(center_zoom_dialog);
+
+        // Move focus to the Close button.  This appears to
+        // highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit
+        // the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(center_zoom_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else {
+        XtPopup(center_zoom_dialog,XtGrabNone);
+        (void)XRaiseWindow(XtDisplay(center_zoom_dialog), XtWindow(center_zoom_dialog));
+    }
+}
+
+
+
+
+
+void SetMyPosition( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    
+    Dimension width, height;
+    long my_new_latl, my_new_lonl;
+
+    // check for fixed station
+    //if ( (output_station_type == 0) || (output_station_type > 3)) {
+    //  popup_message( "Modify fixed position", "Are you sure you want to modify your position?");
+    //}
+    // check for position abiguity
+    if ( position_amb_chars > 0 ) { // popup warning that ambiguity is on
+        popup_message_always(langcode("POPUPMA043"), // "Modify ambiguous position"
+            langcode("POPUPMA044") );   // "Position abiguity is on, your new position may appear to jump."
+    }
+
+    if(display_up) {
+        XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+        my_new_lonl = (center_longitude - ((width *scale_x)/2) + (menu_x*scale_x));
+        my_new_latl = (center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y));
+        // Check if we are still on the planet... 
+        if ( my_new_latl > 64800000l  ) my_new_latl = 64800000l;
+        if ( my_new_latl < 0 ) my_new_latl = 0;
+        if ( my_new_lonl > 129600000l ) my_new_lonl = 129600000l;
+        if ( my_new_lonl < 0 ) my_new_lonl = 0;
+
+        convert_lon_l2s( my_new_lonl, my_long, sizeof(my_long), CONVERT_HP_NOSP);
+        convert_lat_l2s( my_new_latl,  my_lat,  sizeof(my_lat),  CONVERT_HP_NOSP);
+
+        // Update my station data with the new lat/lon
+            my_station_add(my_callsign,my_group,my_symbol,my_long,my_lat,my_phg,my_comment,(char)position_amb_chars);
+            redraw_on_new_data=2;
+    }
+}
+
+
+
+
+
+void Window_Quit( /*@unused@*/ Widget w, /*@unused@*/ XtPointer client, /*@unused@*/ XtPointer calldata) {
+    quit(0);
+}
+
+
+
+
+
+void Menu_Quit( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    quit(0);
+}
+
+
+
+
+
+void save_state( /*@unused@*/ Widget w, /*@unused@*/ XtPointer client, /*@unused@*/ XtPointer calldata) {
+    if (((XtCheckpointToken)calldata)->shutdown) {
+	save_data();
+
+	// shutdown all interfaces
+	shutdown_all_active_or_defined_port(-1);
+
+	shut_down_server();
+    }
+
+}
+
+
+
+
+
+// Turn on or off map border, callback from map_border_button.
+void Map_border_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    
+    if(state->set)
+        draw_labeled_grid_border = TRUE;
+    else
+        draw_labeled_grid_border = FALSE;
+
+    redraw_symbols(da);
+}
+
+
+
+void Grid_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        long_lat_grid = atoi(which);
+    else
+        long_lat_grid = 0;
+
+    if (long_lat_grid) {
+        statusline(langcode("BBARSTA005"),1);   // Map Lat/Long Grid On
+        XtSetSensitive(map_border_button,TRUE);
+    }
+    else {
+        statusline(langcode("BBARSTA006"),2);   // Map Lat/Long Grid Off
+        XtSetSensitive(map_border_button,FALSE);
+    }
+
+    redraw_symbols(da);
+    (void)XCopyArea(XtDisplay(da),
+        pixmap_final,
+        XtWindow(da),
+        gc,
+        0,
+        0,
+        (unsigned int)screen_width,
+        (unsigned int)screen_height,
+        0,
+        0);
+}
+
+
+
+
+// Callback from menu buttons that allow user to turn on or off the 
+// global display of CAD objects and their metadata on the map.
+void  CAD_draw_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    // turn on or off display of cad objects 
+    if (strcmp(which,"CAD_draw_objects")==0) { 
+         CAD_draw_objects = state->set;
+    }
+
+    // turn on or off display of standard metadata
+    if (strcmp(which,"CAD_show_label")==0) { 
+         CAD_show_label = state->set;
+    }
+    if (strcmp(which,"CAD_show_raw_probability")==0) { 
+         CAD_show_raw_probability = state->set;
+    }
+    if (strcmp(which,"CAD_show_comment")==0) { 
+         CAD_show_comment = state->set;
+    }
+    if (strcmp(which,"CAD_show_area")==0) { 
+         CAD_show_area = state->set;
+    }
+
+    // redraw objects on the current base maps
+    redraw_symbols(da);
+}
+
+
+
+
+
+void  Map_lock_pan_zoom_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        map_lock_pan_zoom = atoi(which);
+        XtSetSensitive(zoom_in_menu, FALSE);
+        XtSetSensitive(zoom_out_menu, FALSE);
+        XtSetSensitive(pan_left_menu, FALSE);
+        XtSetSensitive(pan_up_menu, FALSE);
+        XtSetSensitive(pan_down_menu, FALSE);
+        XtSetSensitive(pan_right_menu, FALSE);
+    }
+    else {
+        map_lock_pan_zoom = 0;
+        XtSetSensitive(zoom_in_menu, TRUE);
+        XtSetSensitive(zoom_out_menu, TRUE);
+        XtSetSensitive(pan_left_menu, TRUE);
+        XtSetSensitive(pan_up_menu, TRUE);
+        XtSetSensitive(pan_down_menu, TRUE);
+        XtSetSensitive(pan_right_menu, TRUE);
+    }
+}
+
+
+
+
+
+void  Map_disable_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        disable_all_maps = atoi(which);
+    }
+    else {
+        disable_all_maps = 0;
+    }
+
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+void  Map_auto_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        map_auto_maps = atoi(which);
+        XtSetSensitive(map_auto_skip_raster_button,TRUE);
+    }
+    else {
+        map_auto_maps = 0;
+        XtSetSensitive(map_auto_skip_raster_button,FALSE);
+    }
+
+    re_sort_maps = 1;
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+
+    if (map_auto_maps)
+        statusline(langcode("BBARSTA007"),1);   // The use of Auto Maps is now on
+    else
+        statusline(langcode("BBARSTA008"),2);   // The use of Auto Maps is now off
+}
+
+
+
+
+
+void  Map_auto_skip_raster_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        auto_maps_skip_raster = atoi(which);
+    else
+        auto_maps_skip_raster = 0;
+
+    re_sort_maps = 1;
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+void  Map_levels_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        map_color_levels = atoi(which);
+    else
+        map_color_levels = 0;
+
+    if (map_color_levels)
+        statusline(langcode("BBARSTA009"),1);   // The use of Auto Maps is now on
+    else
+        statusline(langcode("BBARSTA010"),2);   // The use of Auto Maps is now off
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+void  Map_labels_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        map_labels = atoi(which);
+    else
+        map_labels = 0;
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+void  Map_fill_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        map_color_fill = atoi(which);
+    else
+        map_color_fill = 0;
+
+    if (map_color_fill)
+        statusline(langcode("BBARSTA009"),1);       // The use of Map Color Fill is now On
+    else
+        statusline(langcode("BBARSTA010"),1);       // The use of Map Color Fill is now Off
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+void Map_background( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    int bgcolor;
+    int i;
+
+    bgcolor=atoi((char *)clientData);
+
+    if(display_up){
+        for (i=0;i<12;i++){
+            if (i == bgcolor)
+                XtSetSensitive(map_bgcolor[i],FALSE);
+            else
+                XtSetSensitive(map_bgcolor[i],TRUE);
+        }
+        map_background_color=bgcolor;
+
+        // Set interrupt_drawing_now because conditions have changed.
+        interrupt_drawing_now++;
+
+        // Request that a new image be created.  Calls create_image,
+        // XCopyArea, and display_zoom_status.
+        request_new_image++;
+
+//        if (create_image(da)) {
+//            (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//        }
+    }
+}
+
+
+
+
+
+#if !defined(NO_GRAPHICS)
+void Raster_intensity(Widget w, XtPointer clientData, XtPointer calldata) {
+    float my_intensity;
+    int i;
+
+    my_intensity=atof((char *)clientData);
+
+    if(display_up){
+        for (i=0;i<11;i++){
+            if (i == (int)((float)(my_intensity * 10.01)) )
+                XtSetSensitive(raster_intensity[i],FALSE);
+            else
+                XtSetSensitive(raster_intensity[i],TRUE);
+
+            //fprintf(stderr,"Change to index: %d\n", (int)((float)(my_intensity * 10.01)));
+        }
+
+        raster_map_intensity=my_intensity;
+        //fprintf(stderr,"raster_map_intensity = %f\n", raster_map_intensity);
+
+        // Set interrupt_drawing_now because conditions have changed.
+        interrupt_drawing_now++;
+
+        // Request that a new image be created.  Calls create_image,
+        // XCopyArea, and display_zoom_status.
+        request_new_image++;
+
+//        if (create_image(da)) {
+//            XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//        }
+    }
+}
+#endif  // NO_GRAPHICS
+
+
+
+
+
+void Map_station_label( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    int style;
+
+    style=atoi((char *)clientData);
+
+    if(display_up){
+        letter_style = style;
+        sel3_switch(letter_style,map_station_label2,map_station_label1,map_station_label0);
+        redraw_symbols(da);
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    }
+}
+
+
+
+
+
+void Map_icon_outline( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    int style;
+
+    style=atoi((char *)clientData);
+
+    if(display_up){
+        icon_outline_style = style;
+        sel4_switch(icon_outline_style,map_icon_outline3,map_icon_outline2,map_icon_outline1,map_icon_outline0);
+        redraw_symbols(da);
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    }
+    statusline( langcode("BBARSTA046"), 1);   // Reloading symbols...
+    load_pixmap_symbol_file("symbols.dat", 1);
+    redraw_symbols(da);
+    (void)XCopyArea(XtDisplay(da),
+        pixmap_final,
+        XtWindow(da),
+        gc,
+        0,
+        0,
+        (unsigned int)screen_width,
+        (unsigned int)screen_height,
+        0,
+        0);
+}
+
+
+
+
+
+void  Map_wx_alerts_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        wx_alert_style = !(atoi(which));
+    else
+        wx_alert_style = 1;
+
+    if (display_up) {
+        refresh_image(da);
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    }
+}
+
+
+
+
+
+void  Index_maps_on_startup_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        index_maps_on_startup = 1;
+    else
+        index_maps_on_startup = 0;
+}
+
+
+
+
+
+void TNC_Transmit_now( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    transmit_now = 1;              /* toggle transmission of station now*/
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+// GPS operations
+/////////////////////////////////////////////////////////////////////
+
+
+
+
+
+#ifdef HAVE_GPSMAN
+
+// Function to process the RINO.gpstrans file.  We'll create APRS
+// objects out of them as if our own callsign created them.  Lines
+// in the file look like this (spaces removed):
+//
+// W  N3EG3  20-JUN-02 17:55  07/08/2004 13:03:29  46.1141682  -122.9384817
+// W  N3JGI  20-JUN-02 18:29  07/08/2004 13:03:29  48.0021644  -116.0118324
+//
+// Fields are:
+// W  name   Comment          Date/Time            Latitude    Longitude
+//
+void process_RINO_waypoints(void) {
+    FILE *f;
+    char temp[MAX_FILENAME * 2];
+    char line[301];
+    float UTC_Offset;
+    char temp_file_name[MAX_VALUE];
+
+//    char datum[50];
+
+
+    // Just to be safe
+    line[300] = '\0';
+
+    // Create the full path/filename
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s/RINO.gpstrans",
+        get_user_base_dir("gps", temp_file_name, sizeof(temp_file_name)));
+
+    f=fopen(temp,"r"); // Open for reading
+
+    if (f == NULL) {
+        fprintf(stderr,
+            "Couldn't open %s file for reading\n",
+            temp);
+        return;
+    }
+ 
+    // Process the file line-by-line here.  The format for gpstrans
+    // files as written by GPSMan appears to be:
+    //
+    //   "W"
+    //   Waypoint name
+    //   Comment field (Date/Time is default on Garmins)
+    //   Date/Time
+    //   Decimal latitude
+    //   Decimal longitude
+    //
+    while (fgets(line, 300, f) != NULL) {
+
+        // Snag the "Format:" line at the top of the file:
+        // Format: DDD  UTC Offset:  -8.00 hrs  Datum[100]: WGS 84
+        //
+        if (strncmp(line,"Format:",7) == 0) {
+            int i = 7;
+            char temp2[50];
+
+
+            // Find the ':' after "UTC Offset"
+            while (line[i] != ':'
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+            i++;
+
+            // Skip white space
+            while (line[i] == ' '
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+
+            // Copy UTC offset chars into temp2
+            temp2[0] = '\0';
+            while (line[i] != '\t'
+                    && line[i] != ' '
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                strncat(temp2,&line[i],1);
+                i++;
+            }
+
+            UTC_Offset = atof(temp2);
+
+//fprintf(stderr,"UTC Offset: %f\n", UTC_Offset);
+
+// NOTE:  This would be the place to snag the datum as well.
+
+        }
+
+        // Check for a waypoint entry
+        else if (line[0] == 'W') {
+            char name[50];
+            char datetime[50];
+            char lat_c[20];
+            char lon_c[20];
+            int i = 1;
+
+
+// NOTE:  We should check for the end of the string, skipping this
+// iteration of the loop if we haven't parsed enough fields.
+
+            // Find non-white-space character
+            while ((line[i] == '\t' || line[i] == ' ')
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+
+            // Copy into name until tab or whitespace char.  We're
+            // assuming that a waypoint name can't have spaces in
+            // it.
+            name[0] = '\0';
+            while (line[i] != '\t'
+                    && line[i] != ' '
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                strncat(name,&line[i],1);
+                i++;
+            }
+
+            // Find tab character at end of name field
+            while (line[i] != '\t'
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+            i++;
+
+            // We skip the comment field, doing nothing with the
+            // data.
+            //
+            // Find tab character at end of comment field
+            while (line[i] != '\t'
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+            i++;
+
+            // Find non-white-space character
+            while ((line[i] == '\t' || line[i] == ' ')
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+
+// Snag date/time.  Use it in the object date/time field.
+            // Copy into datetime until tab char.  Include the space
+            // between the time and date portions.
+            datetime[0] = '\0';
+            while (line[i] != '\t'
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                strncat(datetime,&line[i],1);
+                i++;
+            }
+
+            // Find tab character at end of date/time field
+            while (line[i] != '\t'
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+            i++;
+
+            // Find non-white-space character
+            while ((line[i] == '\t' || line[i] == ' ')
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+
+            // Copy into lat_c until white space char
+            lat_c[0] = '\0';
+            while (line[i] != '\t'
+                    && line[i] != ' '
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                strncat(lat_c,&line[i],1);
+                i++;
+            }
+
+            // Find non-white-space character
+            while ((line[i] == '\t' || line[i] == ' ')
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                i++;
+            }
+
+            // Copy into lon_c until tab character
+            lon_c[0] = '\0';
+            while (line[i] != '\t'
+                    && line[i] != ' '
+                    && line[i] != '\0'
+                    && line[i] != '\n'
+                    && line[i] != '\r') {
+                strncat(lon_c,&line[i],1);
+                i++;
+            }
+            i++;
+
+/*
+            fprintf(stderr,
+                "%s\t%f\t%f\n",
+                name,
+                atof(lat_c),
+                atof(lon_c));
+*/
+
+
+// For now we're hard-coding the RINO group to "APRS".  Any RINO
+// waypoints that begin with these four characters will have those
+// four characters chopped and will be turned into our own APRS
+// object, which we will then attempt to transmit.
+    
+            if (strncmp(name,"APRS",4) == 0) {
+                // We have a match.  Turn this into an APRS Object
+                char line2[100];
+                int lat_deg, lon_deg;
+                float lat_min, lon_min;
+                char lat_dir, lon_dir;
+                char temp2[50];
+                int date;
+                int hour;
+                int minute;
+// Three variables used for Base-91 compressed strings.  We have a
+// bug in this code at the moment so the Base-91 compressed code in
+// this routine is commented out.
+//                char *compressed_string;
+//                char lat_s[50];
+//                char lon_s[50];
+
+
+                // Strip off the "APRS" at the beginning of the
+                // name.  Add spaces to flush out the length of an
+                // APRS object name.
+                xastir_snprintf(temp2,
+                    sizeof(temp2),
+                    "%s         ",
+                    &name[4]);
+
+                // Copy it back to the "name" variable.
+                xastir_snprintf(name,
+                    sizeof(name),
+                    "%s",
+                    temp2);
+
+                // Truncate the name at nine characters.
+                name[9] = '\0';
+
+                // We can either snag the UTC Offset from the top of
+                // the file, or we can put the date/time format into
+                // local time.  The spec suggests using zulu time
+                // for all future implementations, so we snagged the
+                // UTC Offset earlier in this routine.
+
+                // 07/09/2004 09:22:28
+//fprintf(stderr,"%s %s", name, datetime);
+
+                xastir_snprintf(temp2,
+                    sizeof(temp2),
+                    "%s",
+                    &datetime[3]);
+                temp2[2] = '\0';
+                date = atoi(temp2);
+//fprintf(stderr, "%02d\n", date);
+
+                xastir_snprintf(temp2,
+                    sizeof(temp2),
+                    "%s",
+                    &datetime[11]);
+                temp2[2] = '\0';
+                hour = atoi(temp2);
+
+                xastir_snprintf(temp2,
+                    sizeof(temp2),
+                    "%s",
+                    &datetime[14]);
+                temp2[2] = '\0';
+                minute = atoi(temp2);
+//fprintf(stderr,"\t\t%02d%02d%02d/\n", date, hour, minute);
+
+                // We need to remember to bump the date up if we go
+                // past midnight adding the UTC offset.  In that
+                // case we may need to bump the day as well if we're
+                // near the end of the month.  Use the Unix time
+                // facilities for this?
+
+                // Here we're assuming that the UTC offset is
+                // divisible by one hour.  Always correct?
+
+//                hour = (int)(hour - UTC_Offset);
+
+
+                lat_deg = atoi(lat_c);
+                if (lat_deg < 0)
+                    lat_deg = -lat_deg;
+
+                lon_deg = atoi(lon_c);
+                if (lon_deg < 0)
+                    lon_deg = -lon_deg;
+
+                lat_min = atof(lat_c);
+                if (lat_min < 0.0)
+                    lat_min = -lat_min;
+                lat_min = (lat_min - lat_deg) * 60.0;
+
+                lon_min = atof(lon_c);
+                if (lon_min < 0.0)
+                    lon_min = -lon_min;
+                lon_min = (lon_min - lon_deg) * 60.0;
+
+                if (lat_c[0] == '-')
+                    lat_dir = 'S';
+                else
+                    lat_dir = 'N';
+
+                if (lon_c[0] == '-')
+                    lon_dir = 'W';
+                else
+                    lon_dir = 'E';
+
+                // Non-Compressed version
+                xastir_snprintf(line2,
+                    sizeof(line2),
+                    ";%-9s*%02d%02d%02d/%02d%05.2f%c%c%03d%05.2f%c%c",
+                    name,
+                    date,
+                    hour,
+                    minute,
+                    lat_deg,    // Degrees
+                    lat_min,    // Minutes
+                    lat_dir,    // N/S
+                    '/',        // Primary symbol table
+                    lon_deg,    // Degrees
+                    lon_min,    // Minutes
+                    lon_dir,    // E/W
+                    '[');       // Hiker symbol
+
+/*
+                // Compressed version.  Gives us more of the
+                // resolution inherent in the RINO waypoints.
+                // Doesn't have an affect on whether we transmit
+                // compressed objects from Xastir over RF.  That is
+                // selected from the File->Configure->Defaults
+                // dialog.
+                //
+                // compress_posit expects its lat/long in //
+                // APRS-like format:
+                // "%2d%lf%c", &deg, &minutes, &ext
+
+                xastir_snprintf(lat_s,
+                    sizeof(lat_s),
+                    "%02d%8.5f%c",
+                    lat_deg,
+                    lat_min,
+                    lat_dir);
+ 
+                xastir_snprintf(lon_s,
+                    sizeof(lon_s),
+                    "%02d%8.5f%c",
+                    lon_deg,
+                    lon_min,
+                    lon_dir);
+                    
+                compressed_string = compress_posit(lat_s,
+                    '/',    // group character
+                    lon_s,
+                    '[',    // symbol,
+                    0,      // course,
+                    0,      // speed,
+                    "");    // phg
+
+//fprintf(stderr, "compressed: %s\n", compressed_string);
+
+                xastir_snprintf(line2,
+                    sizeof(line2),
+                    ";%-9s*%02d%02d%02d/%s",
+                    name,
+                    date,
+                    hour,
+                    minute,
+                    compressed_string);
+*/
+
+/*
+                fprintf(stderr,
+                    "%-9s\t%f\t%f\t\t\t\t\t\t",
+                    name,
+                    atof(lat_c),
+                    atof(lon_c));
+                fprintf(stderr,"%s\n",line2);
+*/
+
+                // Update this object in our save file
+                log_object_item(line2,0,name);
+
+                if (object_tx_disable)
+                    output_my_data(line2,-1,0,1,0,NULL);    // Local loopback only, not igating
+                else
+                    output_my_data(line2,-1,0,0,0,NULL);    // Transmit/loopback object data, not igating
+            }
+        }
+    }
+
+//fprintf(stderr,"\n");
+
+    (void)fclose(f);
+}
+
+
+
+
+ 
+void GPS_operations_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    GPS_operations_dialog = (Widget)NULL;
+}
+
+
+
+
+
+// Set up gps_map_filename based on user preferences for filename
+// and map color.
+void GPS_operations_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp;
+    char short_filename[MAX_FILENAME];
+    char color_text[50];
+
+
+    temp = XmTextGetString(gpsfilename_text);
+    xastir_snprintf(short_filename,
+        sizeof(short_filename),
+        "%s",
+        temp);
+    XtFree(temp);
+
+    // Add date/time to filename if no filename is given
+    if (strlen(short_filename) == 0) {
+        int ii;
+
+        // Compute the date/time and put in string
+        get_timestamp(short_filename);
+
+        // Change spaces to underlines
+        // Wed Mar  5 15:24:48 PST 2003
+        for (ii = 0; ii < (int)strlen(short_filename); ii++) {
+            if (short_filename[ii] == ' ')
+                short_filename[ii] = '_';
+        }
+    }
+    
+    (void)remove_trailing_spaces(short_filename);
+
+    switch (gps_map_color) {
+        case 0: {
+            xastir_snprintf(color_text,sizeof(color_text),"Red");
+            gps_map_color_offset=0x0c;
+            break;
+        }
+        case 1: {
+            xastir_snprintf(color_text,sizeof(color_text),"Green");
+            gps_map_color_offset=0x23;
+            break;
+        }
+        case 2: {
+            xastir_snprintf(color_text,sizeof(color_text),"Black");
+            gps_map_color_offset=0x08;
+            break;
+        }
+        case 3: {
+            xastir_snprintf(color_text,sizeof(color_text),"White");
+            gps_map_color_offset=0x0f;
+            break;
+        }
+        case 4: {
+            xastir_snprintf(color_text,sizeof(color_text),"Orange");
+            gps_map_color_offset=0x62;
+            break;
+        }
+        case 5: {
+            xastir_snprintf(color_text,sizeof(color_text),"Blue");
+            gps_map_color_offset=0x03;
+            break;
+        }
+        case 6: {
+            xastir_snprintf(color_text,sizeof(color_text),"Yellow");
+            gps_map_color_offset=0x0e;
+            break;
+        }
+        case 7: {
+            xastir_snprintf(color_text,sizeof(color_text),"Purple");
+            gps_map_color_offset=0x0b;
+            break;
+        }
+        default: {
+            xastir_snprintf(color_text,sizeof(color_text),"Red");
+            gps_map_color_offset=0x0c;
+            break;
+        }
+    }
+
+    // If doing waypoints, don't add the color onto the end
+    if (strcmp("Waypoints",gps_map_type) == 0) {
+        xastir_snprintf(gps_map_filename,
+            sizeof(gps_map_filename),
+            "%s_%s.shp",
+            short_filename,
+            gps_map_type);
+
+        // Same without ".shp"
+        xastir_snprintf(gps_map_filename_base,
+            sizeof(gps_map_filename_base),
+            "%s_%s",
+            short_filename,
+            gps_map_type);
+    }
+    else {  // Doing Tracks/Routes
+        xastir_snprintf(gps_map_filename,
+            sizeof(gps_map_filename),
+            "%s_%s_%s.shp",
+            short_filename,
+            gps_map_type,
+            color_text);
+
+        // Same without ".shp"
+        xastir_snprintf(gps_map_filename_base,
+            sizeof(gps_map_filename_base),
+            "%s_%s_%s",
+            short_filename,
+            gps_map_type,
+            color_text);
+
+        // Same without ".shp" *or* color
+        xastir_snprintf(gps_map_filename_base2,
+            sizeof(gps_map_filename_base2),
+            "%s_%s",
+            short_filename,
+            gps_map_type);
+    }
+
+//fprintf(stderr,"%s\t%s\n",gps_map_filename,gps_map_filename_base);
+
+    // Signify that the user has selected the filename and color for
+    // the downloaded file.
+    gps_details_selected++;
+
+    GPS_operations_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void GPS_operations_cancel(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    // Destroy the GPS selection dialog
+    GPS_operations_destroy_shell(widget,clientData,callData);
+
+    // Wait for the GPS operation to be finished, then clear out all
+    // of the variables.
+    while (!gps_got_data_from && gps_operation_pending) {
+        usleep(1000000);    // 1 second
+    }
+
+    gps_details_selected = 0;
+    gps_got_data_from = 0;
+    gps_operation_pending = 0;
+}
+
+
+
+
+
+void  GPS_operations_color_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        gps_map_color = atoi(which);
+    else
+        gps_map_color = 0;
+}
+
+
+
+
+
+// This routine should be called while the transfer is progressing,
+// or perhaps just after it ends.  If we can do it while the
+// transfer is ocurring we can save time overall.  Here we'll select
+// the color and name for the resulting file, then cause it to be
+// selected and displayed on the map screen.
+//
+void GPS_transfer_select( void ) {
+    static Widget pane, my_form, button_select, button_cancel,
+                  frame,  color_type, type_box, ctyp0, ctyp1,
+                  ctyp2, ctyp3, ctyp4, ctyp5, ctyp6, ctyp7,
+                  gpsfilename_label;
+    Atom delw;
+    Arg al[50];                      // Arg List
+    register unsigned int ac = 0;   // Arg Count
+
+
+    if (!GPS_operations_dialog) {
+
+        // Set args for color
+        ac = 0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        GPS_operations_dialog = XtVaCreatePopupShell(
+                langcode("GPS001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget(
+                "GPS_transfer_select pane",
+                xmPanedWindowWidgetClass, 
+                GPS_operations_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget(
+                "GPS_transfer_select my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+
+        gpsfilename_label = XtVaCreateManagedWidget(    // Filename
+                langcode("GPS002"),
+                xmLabelWidgetClass,
+                my_form,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        gpsfilename_text = XtVaCreateManagedWidget(
+                "GPS_transfer_select gpsfilename_text", 
+                xmTextWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 20,
+                XmNwidth, ((20*7)+2),
+                XmNmaxLength, 200,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, gpsfilename_label,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        frame = XtVaCreateManagedWidget(
+                "GPS_transfer_select frame", 
+                xmFrameWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, gpsfilename_label,
+                XmNtopOffset,15,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        color_type  = XtVaCreateManagedWidget(  // Select Color
+                langcode("GPS003"),
+                xmLabelWidgetClass,
+                frame,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        type_box = XmCreateRadioBox(
+                frame,
+                "GPS_transfer_select Transmit Options box",
+                al,
+                ac);
+
+        XtVaSetValues(type_box,
+                XmNnumColumns,2,
+                NULL);
+
+        ctyp0 = XtVaCreateManagedWidget(    // Red
+                langcode("GPS004"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp0,XmNvalueChangedCallback,GPS_operations_color_toggle,"0");
+
+        ctyp1 = XtVaCreateManagedWidget(    // Green
+                langcode("GPS005"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp1,XmNvalueChangedCallback,GPS_operations_color_toggle,"1");
+
+        ctyp2 = XtVaCreateManagedWidget(    // Black
+                langcode("GPS006"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp2,XmNvalueChangedCallback,GPS_operations_color_toggle,"2");
+
+        ctyp3 = XtVaCreateManagedWidget(    // White
+                langcode("GPS007"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp3,XmNvalueChangedCallback,GPS_operations_color_toggle,"3");
+
+        ctyp4 = XtVaCreateManagedWidget(    // Orange
+                langcode("GPS008"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp4,XmNvalueChangedCallback,GPS_operations_color_toggle,"4");
+
+        ctyp5 = XtVaCreateManagedWidget(    // Blue
+                langcode("GPS009"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp5,XmNvalueChangedCallback,GPS_operations_color_toggle,"5");
+
+        ctyp6 = XtVaCreateManagedWidget(    // Yellow
+                langcode("GPS010"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp6,XmNvalueChangedCallback,GPS_operations_color_toggle,"6");
+
+        ctyp7 = XtVaCreateManagedWidget(    // Violet
+                langcode("GPS011"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ctyp7,XmNvalueChangedCallback,GPS_operations_color_toggle,"7");
+
+
+        button_select = XtVaCreateManagedWidget(
+                langcode("WPUPCFS028"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        button_cancel = XtVaCreateManagedWidget(
+                langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_select,
+            XmNactivateCallback,
+            GPS_operations_change_data,
+            GPS_operations_dialog);
+
+        XtAddCallback(button_cancel,
+            XmNactivateCallback,
+            GPS_operations_cancel,
+            GPS_operations_dialog);
+
+        // Set default color to first selection
+        XmToggleButtonSetState(ctyp0,TRUE,FALSE);
+        gps_map_color = 0;
+
+        // De-sensitize the color selections if we're doing
+        // waypoints.
+        if (strcmp("Waypoints",gps_map_type) == 0) {
+            XtSetSensitive(frame, FALSE);
+        }
+
+        pos_dialog(GPS_operations_dialog);
+
+        delw = XmInternAtom(
+            XtDisplay(GPS_operations_dialog),
+            "WM_DELETE_WINDOW",
+            FALSE);
+
+        XmAddWMProtocolCallback(
+            GPS_operations_dialog,
+            delw,
+            GPS_operations_destroy_shell,
+            (XtPointer)GPS_operations_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(type_box);
+        XtManageChild(pane);
+
+        XtPopup(GPS_operations_dialog,XtGrabNone);
+        fix_dialog_size(GPS_operations_dialog);
+
+        // Move focus to the Select button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(GPS_operations_dialog);
+        XmProcessTraversal(button_select, XmTRAVERSE_CURRENT);
+
+    } else {
+        (void)XRaiseWindow(
+            XtDisplay(GPS_operations_dialog),
+            XtWindow(GPS_operations_dialog));
+    }
+}
+
+
+
+
+time_t check_gps_map_time = (time_t)0;
+
+
+// Function called by UpdateTime periodically.  Checks whether
+// we've just completed a GPS transfer and need to redraw maps as a
+// result.
+//
+void check_for_new_gps_map(int curr_sec) {
+
+    // Only check once per second
+    if (check_gps_map_time == curr_sec) {
+        return; // Skip it, we already checked once this second.
+    }
+    check_gps_map_time = curr_sec;
+
+
+    if ( (gps_operation_pending || gps_got_data_from)
+            && !gps_details_selected) {
+
+        // A transfer is underway or has just completed.  The user
+        // hasn't selected the filename/color yet.  Bring up the
+        // selection dialog so that the user can do so.
+        GPS_transfer_select();
+    }
+    else if (gps_details_selected
+            && gps_got_data_from
+            && !gps_operation_pending) {
+        FILE *f;
+        char temp[MAX_FILENAME * 2];
+        char gps_base_dir[MAX_VALUE];
+        char temp_file_name[MAX_VALUE];
+
+        get_user_base_dir("gps",gps_base_dir, sizeof(gps_base_dir));
+//fprintf(stderr,"check_for_new_gps_map()\n");
+
+
+        // We have new data from a GPS!  Add the file to the
+        // selected maps file, cause a reload of the maps to occur,
+        // and then re-index maps (so that map may be deselected by
+        // the user).
+
+//
+// It would be good to verify that we're not duplicating entries.
+// Add code here to read through the file first looking for a
+// match before attempting to append any new lines.
+//
+
+        // We don't rename if Garmin RINO waypoint file
+        if (strcmp(gps_map_type,"RINO") != 0) {
+            // Rename the temporary file to the new filename.  We must
+            // do this three times, once for each piece of the Shapefile
+            // map.
+#if defined(HAVE_MV)
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s %s/%s %s/%s",
+                MV_PATH,
+                gps_base_dir,
+                gps_temp_map_filename,
+                gps_base_dir,
+                gps_map_filename);
+
+            if ( system(temp) ) {
+                fprintf(stderr,"Couldn't rename the downloaded GPS map file\n");
+                fprintf(stderr,"%s\n",temp);
+                gps_got_data_from = 0;
+                gps_details_selected = 0;
+                return;
+            }
+            // Done for the ".shp" file.  Now repeat for the ".shx" and
+            // ".dbf" files.
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s %s/%s.shx %s/%s.shx",
+                MV_PATH,
+                gps_base_dir,
+                gps_temp_map_filename_base,
+                gps_base_dir,
+                gps_map_filename_base);
+
+            if ( system(temp) ) {
+                fprintf(stderr,"Couldn't rename the downloaded GPS map file\n");
+                fprintf(stderr,"%s\n",temp);
+                gps_got_data_from = 0;
+                gps_details_selected = 0;
+                return;
+            }
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s %s/%s.dbf %s/%s.dbf",
+                MV_PATH,
+                gps_base_dir,
+                gps_temp_map_filename_base,
+                gps_base_dir,
+                gps_map_filename_base);
+
+            if ( system(temp) ) {
+                fprintf(stderr,"Couldn't rename the downloaded GPS map file\n");
+                fprintf(stderr,"%s\n",temp);
+                gps_got_data_from = 0;
+                gps_details_selected = 0;
+                return;
+            }
+#endif  // HAVE_MV
+
+
+            // Write out a WKT in a .prj file to go with this shapefile.
+            xastir_snprintf(temp,
+                            sizeof(temp),
+                            "%s/%s.prj",
+                            gps_base_dir,
+                            gps_map_filename_base);
+            xastirWriteWKT(temp);
+
+            if (strcmp(gps_map_type,"Waypoints") != 0) {
+                // KM5VY: Create a really, really simple dbfawk file to
+                // go with the shapefile.  This is a dbfawk file of the
+                // "per file" type, with the color hardcoded into it.
+                // This will enable downloaded gps shapefiles to have
+                // the right color even when they're not placed in the
+                // GPS directory.
+                // We don't do this for waypoint files, because all we need to
+                // do for those is associate the name with the waypoint, and 
+                // that can be done by a generic signature-based file.
+                xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%s/%s.dbfawk",
+                                gps_base_dir,
+                                gps_map_filename_base);
+                f=fopen(temp,"w"); // open for write
+                if (f != NULL) {
+                    fprintf(f,gps_dbfawk_format,gps_map_color_offset,
+                            gps_map_filename_base2);
+                    fclose(f);
+                }
+            }
+            // Add the new gps map to the list of selected maps
+            f=fopen( get_user_base_dir(SELECTED_MAP_DATA, temp_file_name,
+                                       sizeof(temp_file_name)), "a" ); // Open for appending
+            if (f!=NULL) {
+
+//WE7U:  Change this:
+                fprintf(f,"GPS/%s\n",gps_map_filename);
+
+                (void)fclose(f);
+
+                // Reindex maps.  Use the smart timestamp-checking indexing.
+                map_indexer(0);     // Have to have the new map in the index first before we can select it
+                map_chooser_init(); // Re-read the selected_maps.sys file
+                re_sort_maps = 1;   // Creates a new sorted list from the selected maps
+
+//
+// We should set some flags here instead of doing the map redraw
+// ourselves, so that multiple map reloads don't occur sometimes in
+// UpdateTime.
+//
+
+                // Reload maps
+                // Set interrupt_drawing_now because conditions have changed.
+                interrupt_drawing_now++;
+
+                // Request that a new image be created.  Calls create_image,
+                // XCopyArea, and display_zoom_status.
+                request_new_image++;
+
+//                if (create_image(da)) {
+//                    (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//                }
+            }
+            else {
+                fprintf(stderr,"Couldn't open file: %s\n", get_user_base_dir(SELECTED_MAP_DATA, temp_file_name, sizeof(temp_file_name)) );
+            }
+        }
+        else {
+            // We're dealing with Garmin RINO waypoints.  Go process
+            // the RINO.gpstrans file, creating objects out of them.
+            process_RINO_waypoints();
+        }
+
+        // Set up for the next GPS run
+        gps_got_data_from = 0;
+        gps_details_selected = 0;
+    }
+}
+
+
+
+
+
+// This is the separate execution thread that transfers the data
+// to/from the GPS.  The thread is started up by the
+// GPS_operations() function below.
+//
+static void* gps_transfer_thread(void *arg) {
+    int input_param;
+    char temp[500];
+    char prefix[100];
+    char postfix[100];
+    char gps_base_dir[MAX_VALUE];
+
+    get_user_base_dir("gps", gps_base_dir, sizeof(gps_base_dir));
+
+    // Set up the prefix string.  Note that we depend on the correct
+    // setup of serial ports and such in GPSMan's configs.
+    xastir_snprintf(prefix, sizeof(prefix),
+        "%s",
+        GPSMAN_PATH);
+
+    // Set up the postfix string.  The files will be created in the
+    // "~/.xastir/gps/" directory.
+    xastir_snprintf(postfix, sizeof(postfix),
+        "Shapefile dim=2 %s/",
+        gps_base_dir);
+
+    input_param = atoi((char *)arg);
+
+    // The pthread_detach() call means we don't care about the
+    // return code and won't use pthread_join() later.  Makes
+    // threading more efficient.
+    (void)pthread_detach(pthread_self());
+
+    switch (input_param) {
+
+        case 1: // Fetch track from GPS
+            // gpsman.tcl -dev /dev/ttyS0 getwrite TR Shapefile dim=2 track.date
+
+//            fprintf(stderr,"Fetch track from GPS\n");
+
+            xastir_snprintf(gps_temp_map_filename,
+                sizeof(gps_temp_map_filename),
+                "Unnamed_Track_Red.shp");
+            xastir_snprintf(gps_temp_map_filename_base,
+                sizeof(gps_temp_map_filename_base),
+                "Unnamed_Track_Red");
+
+
+            xastir_snprintf(gps_map_type,
+                sizeof(gps_map_type),
+                "Track");
+ 
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s getwrite TR %s%s",
+                prefix,
+                postfix,
+                gps_temp_map_filename);
+
+            if ( system(temp) ) {
+                fprintf(stderr,"Couldn't download the gps track\n");
+                gps_operation_pending = 0;  // We're done
+                return(NULL);
+            }
+            // Set the got_data flag
+            gps_got_data_from++;
+            break;
+
+        case 2: // Fetch route from GPS
+            // gpsman.tcl -dev /dev/ttyS0 getwrite RT Shapefile dim=2 routes.date
+
+//            fprintf(stderr,"Fetch routes from GPS\n");
+
+            xastir_snprintf(gps_temp_map_filename,
+                sizeof(gps_temp_map_filename),
+                "Unnamed_Routes_Red.shp");
+            xastir_snprintf(gps_temp_map_filename_base,
+                sizeof(gps_temp_map_filename_base),
+                "Unnamed_Routes_Red");
+ 
+            xastir_snprintf(gps_map_type,
+                sizeof(gps_map_type),
+                "Routes");
+ 
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s getwrite RT %s%s",
+                prefix,
+                postfix,
+                gps_temp_map_filename);
+
+            if ( system(temp) ) {
+                fprintf(stderr,"Couldn't download the gps routes\n");
+                gps_operation_pending = 0;  // We're done
+                return(NULL);
+            }
+            // Set the got_data flag
+            gps_got_data_from++;
+            break;
+
+        case 3: // Fetch waypoints from GPS
+            // gpsman.tcl -dev /dev/ttyS0 getwrite WP Shapefile dim=2 waypoints.date
+ 
+//            fprintf(stderr,"Fetch waypoints from GPS\n");
+
+            xastir_snprintf(gps_temp_map_filename,
+                sizeof(gps_temp_map_filename),
+                "Unnamed_Waypoints.shp");
+            xastir_snprintf(gps_temp_map_filename_base,
+                sizeof(gps_temp_map_filename_base),
+                "Unnamed_Waypoints");
+ 
+            xastir_snprintf(gps_map_type,
+                sizeof(gps_map_type),
+                "Waypoints");
+ 
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s getwrite WP %s%s",
+                prefix,
+                postfix,
+                gps_temp_map_filename);
+
+            if ( system(temp) ) {
+                fprintf(stderr,"Couldn't download the gps waypoints\n");
+                gps_operation_pending = 0;  // We're done
+                return(NULL);
+            }
+            // Set the got_data flag
+            gps_got_data_from++;
+            break;
+
+        case 4: // Send track to GPS
+            // gpsman.tcl -dev /dev/ttyS0 readput Shapefile dim=2 track.date TR 
+
+            fprintf(stderr,"Send track to GPS\n");
+            fprintf(stderr,"Not implemented yet\n");
+            gps_operation_pending = 0;  // We're done
+            return(NULL);
+            break;
+
+        case 5: // Send route to GPS
+            // gpsman.tcl -dev /dev/ttyS0 readput Shapefile dim=2 routes.date RT 
+
+            fprintf(stderr,"Send route to GPS\n");
+            fprintf(stderr,"Not implemented yet\n");
+            gps_operation_pending = 0;  // We're done
+            return(NULL);
+            break;
+
+        case 6: // Send waypoints to GPS
+            // gpsman.tcl -dev /dev/ttyS0 readput Shapefile dim=2 waypoints.date WP 
+
+            fprintf(stderr,"Send waypoints to GPS\n");
+            fprintf(stderr,"Not implemented yet\n");
+            gps_operation_pending = 0;  // We're done
+            return(NULL);
+            break;
+
+       case 7: // Fetch waypoints from GPS in GPSTrans format
+            // gpsman.tcl -dev /dev/ttyS0 getwrite WP GPStrans waypoints.date
+
+//            fprintf(stderr,"Fetch Garmin RINO waypoints\n");
+
+            // The files will be created in the "~/.xastir/gps/"
+            // directory.
+
+            xastir_snprintf(gps_temp_map_filename,
+                sizeof(gps_temp_map_filename),
+                "RINO.gpstrans");
+ 
+            xastir_snprintf(gps_temp_map_filename_base,
+                sizeof(gps_temp_map_filename_base),
+                "RINO");
+ 
+            xastir_snprintf(gps_map_type,
+                sizeof(gps_map_type),
+                "RINO");
+ 
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "(%s getwrite WP GPStrans %s/%s 2>&1) >/dev/null",
+                prefix,
+                gps_base_dir,
+                gps_temp_map_filename);
+
+// Execute the command
+system(temp);
+//            if ( system(temp) ) {
+//                fprintf(stderr,"Couldn't download the gps waypoints\n");
+//                gps_operation_pending = 0;  // We're done
+//                return(NULL);
+//            }
+            // Set the got_data flag
+            gps_got_data_from++;
+            break;
+
+        default:
+            fprintf(stderr,"Illegal parameter %d passed to gps_transfer_thread!\n",
+                input_param);
+            gps_operation_pending = 0;  // We're done
+            break;
+    }   // End of switch
+
+
+    // Signal to the main thread that we're all done with the
+    // GPS operation.
+    gps_operation_pending = 0;  // We're done
+
+    // End the thread
+    return(NULL);
+}
+
+
+
+
+
+// GPSMan can't handle multiple '.'s in the filename.  It chops at
+// the first one.
+//
+// Note that the permissions on the "~/.xastir/gps/" directory have to be
+// set so that this user (or the root user?) can create files in
+// that directory.  The permissions on the resulting files may need
+// to be tweaked.
+//
+// When creating files, we should warn the user of a conflict if the
+// filename already exists, then if the user wishes to overwrite it,
+// delete the old set of files before downloading the new ones.  We
+// should also make sure we're not adding the filename to the
+// selected_maps.sys more than once.
+//
+// Set up default filenames for each, with an autoincrementing
+// number at the end?  That'd be one way of getting a maps
+// downloaded in a hurry.  Could also ask for a filename after the
+// download is complete instead of at the start of the download.  In
+// that case, download to a temporary filename and then rename it
+// later and reload maps.
+//
+// Dialog should ask the user to put the unit into Garmin-Garmin
+// mode before proceeding.
+//
+// We could de-sensitize the GPS transfer menu items during a
+// transfer operation, to make sure we're not called again until the
+// first operation is over.
+//
+void GPS_operations( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    pthread_t gps_operations_thread;
+    int parameter;
+
+
+    if (clientData != NULL) {
+
+        // Check whether we're already doing a GPS operation.
+        // Return if so.
+        if (gps_operation_pending) {
+            fprintf(stderr,"GPS Operation is already pending, can't start another one!\n");
+            return;
+        }
+
+        parameter = atoi((char *)clientData);
+
+        if ( ((parameter < 1) || (parameter > 3)) && parameter != 7) {
+            fprintf(stderr,"GPS_operations: Parameter out-of-range: %d",parameter);
+            return;
+        }
+
+
+        gps_operation_pending++;
+        gps_got_data_from = 0;
+
+        // We don't need to select filename/color if option 7
+        if (parameter == 7) {
+            gps_details_selected++;
+        }
+
+
+//----- Start New Thread -----
+ 
+        // Here we start a new thread.  We'll communicate with the
+        // main thread via global variables.  Use mutex locks if
+        // there might be a conflict as to when/how we're updating
+        // those variables.
+        //
+        if (pthread_create(&gps_operations_thread, NULL, gps_transfer_thread, clientData)) {
+            fprintf(stderr,"Error creating gps transfer thread\n");
+            gps_got_data_from = 0;      // No data to present
+            gps_operation_pending = 0;  // We're done
+        }
+        else {
+            // We're off and running with the new thread!
+        }
+    }
+}
+#endif  // HAVE_GPSMAN
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+// End of GPS operations
+/////////////////////////////////////////////////////////////////////
+
+
+
+
+
+void Set_Log_Indicator(void) {
+    if (       (1==log_tnc_data)
+            || (1==log_net_data)
+            || (1==log_wx)
+            || (1==log_igate)
+            || (1==log_wx_alert_data)
+            || (1==log_message_data) ) {
+        XmTextFieldSetString(log_indicator, langcode("BBARSTA043")); // Logging
+        XtVaSetValues(log_indicator,
+            XmNbackground, GetPixelByName(appshell,"RosyBrown"),
+	    NULL);
+    } else {
+        XmTextFieldSetString(log_indicator, NULL);
+        XtVaSetValues(log_indicator, MY_BACKGROUND_COLOR, NULL);
+    }
+}
+
+
+
+
+
+void  TNC_Logging_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) 
+        log_tnc_data = atoi(which);
+    else 
+        log_tnc_data = 0;
+    Set_Log_Indicator();
+}
+
+
+
+
+
+void Net_Logging_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        log_net_data = atoi(which);
+    else
+        log_net_data = 0;
+    Set_Log_Indicator();
+}
+
+
+
+
+
+void IGate_Logging_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        log_igate = atoi(which);
+    else
+        log_igate = 0;
+    Set_Log_Indicator();
+}
+
+
+
+
+
+void Message_Logging_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        log_message_data = atoi(which);
+    else
+        log_message_data = 0;
+    Set_Log_Indicator();
+}
+
+
+
+
+
+void WX_Logging_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        log_wx = atoi(which);
+    else
+        log_wx = 0;
+    Set_Log_Indicator();
+}
+
+
+
+
+
+void WX_Alert_Logging_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        log_wx_alert_data = atoi(which);
+    else
+        log_wx_alert_data = 0;
+    Set_Log_Indicator();
+}
+
+
+
+
+
+// Filter Data Menu button callbacks
+
+// support functions
+void set_sensitive_select_sources(int sensitive)
+{
+    XtSetSensitive(select_mine_button,     sensitive);
+    XtSetSensitive(select_tnc_button,      sensitive);
+    if (!Select_.tnc) {
+        XtSetSensitive(select_direct_button,   FALSE);
+        XtSetSensitive(select_via_digi_button, FALSE);
+    }
+    else {
+        XtSetSensitive(select_direct_button,   sensitive);
+        XtSetSensitive(select_via_digi_button, sensitive);
+    }
+    XtSetSensitive(select_net_button,      sensitive);
+    if (no_data_selected())
+        XtSetSensitive(select_old_data_button, FALSE);
+    else
+        XtSetSensitive(select_old_data_button, sensitive);
+}
+
+void set_sensitive_select_types(int sensitive)
+{
+    XtSetSensitive(select_stations_button, sensitive);
+    if (!Select_.stations) {
+        XtSetSensitive(select_fixed_stations_button, FALSE);
+        XtSetSensitive(select_moving_stations_button,     FALSE);
+        XtSetSensitive(select_weather_stations_button,    FALSE);
+        XtSetSensitive(select_CWOP_wx_stations_button,       FALSE);
+    }
+    else {
+        XtSetSensitive(select_fixed_stations_button, sensitive);
+        XtSetSensitive(select_moving_stations_button,     sensitive);
+        XtSetSensitive(select_weather_stations_button,    sensitive);
+        if (Select_.weather_stations) {
+            XtSetSensitive(select_CWOP_wx_stations_button, sensitive);
+        }
+    }
+
+    XtSetSensitive(select_objects_button, sensitive);
+
+    if (!Select_.objects) {
+        XtSetSensitive(select_weather_objects_button, FALSE);
+        XtSetSensitive(select_gauge_objects_button,   FALSE);
+        XtSetSensitive(select_other_objects_button,   FALSE);
+    }
+    else {
+        XtSetSensitive(select_weather_objects_button, sensitive);
+        XtSetSensitive(select_gauge_objects_button,   sensitive);
+        XtSetSensitive(select_other_objects_button,   sensitive);
+    }
+}
+
+
+
+
+
+void set_sensitive_display(int sensitive)
+{
+    XtSetSensitive(display_callsign_button,      sensitive);
+
+    if (!Display_.callsign) {
+        XtSetSensitive(display_label_all_trackpoints_button, FALSE);
+    }
+    else {
+        XtSetSensitive(display_label_all_trackpoints_button, sensitive);
+    }
+ 
+    XtSetSensitive(display_symbol_button,        sensitive);
+
+    if (!Display_.symbol) {
+        XtSetSensitive(display_symbol_rotate_button, FALSE);
+    }
+    else {
+        XtSetSensitive(display_symbol_rotate_button, sensitive);
+    }
+
+    XtSetSensitive(display_phg_button,           sensitive);
+
+    if (!Display_.phg) {
+        XtSetSensitive(display_default_phg_button,   FALSE);
+        XtSetSensitive(display_phg_of_moving_button, FALSE);
+    }
+    else {
+        XtSetSensitive(display_default_phg_button,   sensitive);
+        XtSetSensitive(display_phg_of_moving_button, sensitive);
+    }
+    XtSetSensitive(display_altitude_button, sensitive);
+    XtSetSensitive(display_course_button,   sensitive);
+    XtSetSensitive(display_speed_button,    sensitive);
+    if (!Display_.speed) {
+        XtSetSensitive(display_speed_short_button, FALSE);
+    }
+    else {
+        XtSetSensitive(display_speed_short_button, sensitive);
+    }
+    XtSetSensitive(display_dist_bearing_button, sensitive);
+    XtSetSensitive(display_weather_button,      sensitive);
+    if (!Display_.weather) {
+        XtSetSensitive(display_weather_text_button,     FALSE);
+        XtSetSensitive(display_temperature_only_button, FALSE);
+        XtSetSensitive(display_wind_barb_button,        FALSE);
+    }
+    else {
+        XtSetSensitive(display_weather_text_button, sensitive);
+        if (!Display_.weather_text) {
+            XtSetSensitive(display_temperature_only_button, FALSE);
+        }
+        else {
+            XtSetSensitive(display_temperature_only_button, sensitive);
+        }
+        XtSetSensitive(display_wind_barb_button, sensitive);
+    }
+    XtSetSensitive(display_trail_button,      sensitive);
+    XtSetSensitive(display_last_heard_button, sensitive);
+    XtSetSensitive(display_ambiguity_button,  sensitive);
+    XtSetSensitive(display_df_data_button,    sensitive);
+    if (!Display_.df_data) {
+        XtSetSensitive(display_df_beamwidth_data_button,    FALSE);
+        XtSetSensitive(display_df_bearing_data_button,      FALSE);
+    }
+    else {
+        XtSetSensitive(display_df_beamwidth_data_button,    sensitive);
+        XtSetSensitive(display_df_bearing_data_button,      sensitive);
+    }
+
+    XtSetSensitive(display_dr_data_button,    sensitive);
+    if (!Display_.dr_data) {
+        XtSetSensitive(display_dr_arc_button,    FALSE);
+        XtSetSensitive(display_dr_course_button, FALSE);
+        XtSetSensitive(display_dr_symbol_button, FALSE);
+    }
+    else {
+        XtSetSensitive(display_dr_arc_button,    sensitive);
+        XtSetSensitive(display_dr_course_button, sensitive);
+        XtSetSensitive(display_dr_symbol_button, sensitive);
+    }
+}
+
+
+
+
+
+void Select_none_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.none = atoi(which);
+        set_sensitive_select_sources(FALSE);
+        set_sensitive_select_types(FALSE);
+        set_sensitive_display(FALSE);
+    }
+    else {
+        Select_.none = 0;
+        set_sensitive_select_sources(TRUE);
+        if (no_data_selected()) {
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+        else {
+            set_sensitive_select_types(TRUE);
+            set_sensitive_display(TRUE);
+        }
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+
+void Select_mine_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.mine = atoi(which);
+        XtSetSensitive(select_old_data_button, TRUE);
+        set_sensitive_select_types(TRUE);
+        set_sensitive_display(TRUE);
+    }
+    else {
+        Select_.mine = 0;
+        if (no_data_selected()) {
+            XtSetSensitive(select_old_data_button, FALSE);
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_tnc_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.tnc = atoi(which);
+        XtSetSensitive(select_direct_button,   TRUE);
+        XtSetSensitive(select_via_digi_button, TRUE);
+
+        if (!no_data_selected()) {
+            XtSetSensitive(select_old_data_button, TRUE);
+            set_sensitive_select_types(TRUE);
+            set_sensitive_display(TRUE);
+        }
+    }
+    else {
+        Select_.tnc = 0;
+        XtSetSensitive(select_direct_button,   FALSE);
+        XtSetSensitive(select_via_digi_button, FALSE);
+        if (no_data_selected()) {
+            XtSetSensitive(select_old_data_button, FALSE);
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_direct_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.direct = atoi(which);
+        XtSetSensitive(select_old_data_button, TRUE);
+        set_sensitive_select_types(TRUE);
+        set_sensitive_display(TRUE);
+    }
+    else {
+        Select_.direct = 0;
+        if (no_data_selected()) {
+            XtSetSensitive(select_old_data_button, FALSE);
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_via_digi_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.via_digi = atoi(which);
+        XtSetSensitive(select_old_data_button, TRUE);
+        set_sensitive_select_types(TRUE);
+        set_sensitive_display(TRUE);
+    }
+    else {
+        Select_.via_digi = 0;
+        if (no_data_selected()) {
+            XtSetSensitive(select_old_data_button, FALSE);
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_net_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.net = atoi(which);
+        XtSetSensitive(select_old_data_button, TRUE);
+        set_sensitive_select_types(TRUE);
+        set_sensitive_display(TRUE);
+    }
+    else {
+        Select_.net = 0;
+        if (no_data_selected()) {
+            XtSetSensitive(select_old_data_button, FALSE);
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+    }
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_tactical_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.tactical = atoi(which);
+        XtSetSensitive(select_old_data_button, TRUE);
+        set_sensitive_select_types(TRUE);
+        set_sensitive_display(TRUE);
+    }
+    else {
+        Select_.tactical = 0;
+        if (no_data_selected()) {
+            XtSetSensitive(select_old_data_button, FALSE);
+            set_sensitive_select_types(FALSE);
+            set_sensitive_display(FALSE);
+        }
+    }
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_old_data_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.old_data = atoi(which);
+    else
+        Select_.old_data = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_stations_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.stations = atoi(which);
+        XtSetSensitive(select_fixed_stations_button,   TRUE);
+        XtSetSensitive(select_moving_stations_button,  TRUE);
+        XtSetSensitive(select_weather_stations_button, TRUE);
+        if (Select_.weather_stations) {
+            XtSetSensitive(select_CWOP_wx_stations_button, TRUE);
+        }
+    }
+    else {
+        Select_.stations = 0;
+        XtSetSensitive(select_fixed_stations_button,   FALSE);
+        XtSetSensitive(select_moving_stations_button,  FALSE);
+        XtSetSensitive(select_weather_stations_button, FALSE);
+        XtSetSensitive(select_CWOP_wx_stations_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_fixed_stations_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.fixed_stations = atoi(which);
+    else
+        Select_.fixed_stations = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_moving_stations_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.moving_stations = atoi(which);
+    else
+        Select_.moving_stations = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_weather_stations_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.weather_stations = atoi(which);
+        XtSetSensitive(select_CWOP_wx_stations_button, atoi(which));
+    }
+    else {
+        Select_.weather_stations = 0;
+        XtSetSensitive(select_CWOP_wx_stations_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_CWOP_wx_stations_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.CWOP_wx_stations = atoi(which);
+    else
+        Select_.CWOP_wx_stations = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_objects_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Select_.objects = atoi(which);
+        XtSetSensitive(select_weather_objects_button, TRUE);
+        XtSetSensitive(select_gauge_objects_button,   TRUE);
+        XtSetSensitive(select_other_objects_button,   TRUE);
+    }
+    else {
+        Select_.objects = 0;
+        XtSetSensitive(select_weather_objects_button, FALSE);
+        XtSetSensitive(select_gauge_objects_button,   FALSE);
+        XtSetSensitive(select_other_objects_button,   FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_weather_objects_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.weather_objects = atoi(which);
+    else
+        Select_.weather_objects = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_gauge_objects_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.gauge_objects = atoi(which);
+    else
+        Select_.gauge_objects = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Select_other_objects_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Select_.other_objects = atoi(which);
+    else
+        Select_.other_objects = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+// Display Menu button callbacks
+
+void Display_callsign_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.callsign = atoi(which);
+        XtSetSensitive(display_label_all_trackpoints_button, TRUE);
+    }
+    else {
+        Display_.callsign = 0;
+        XtSetSensitive(display_label_all_trackpoints_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_label_all_trackpoints_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.label_all_trackpoints = atoi(which);
+    else
+        Display_.label_all_trackpoints = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_symbol_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.symbol = atoi(which);
+        XtSetSensitive(display_symbol_rotate_button, TRUE);
+    }
+    else {
+        Display_.symbol = 0;
+        XtSetSensitive(display_symbol_rotate_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_symbol_rotate_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.symbol_rotate = atoi(which);
+    else
+        Display_.symbol_rotate = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_trail_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.trail = atoi(which);
+    else
+        Display_.trail = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_course_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.course = atoi(which);
+    else
+        Display_.course = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_speed_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.speed = atoi(which);
+        XtSetSensitive(display_speed_short_button, TRUE);
+    }
+    else {
+        Display_.speed = 0;
+        XtSetSensitive(display_speed_short_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_speed_short_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.speed_short = atoi(which);
+    else
+        Display_.speed_short = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_altitude_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.altitude = atoi(which);
+    else
+        Display_.altitude = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_weather_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.weather = atoi(which);
+        XtSetSensitive(display_weather_text_button,     TRUE);
+        XtSetSensitive(display_temperature_only_button, TRUE);
+        XtSetSensitive(display_wind_barb_button,        TRUE);
+    }
+    else {
+        Display_.weather = 0;
+        XtSetSensitive(display_weather_text_button,     FALSE);
+        XtSetSensitive(display_temperature_only_button, FALSE);
+        XtSetSensitive(display_wind_barb_button,        FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_weather_text_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.weather_text = atoi(which);
+        XtSetSensitive(display_temperature_only_button, TRUE);
+    }
+    else {
+        Display_.weather_text = 0;
+        XtSetSensitive(display_temperature_only_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_temperature_only_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.temperature_only = atoi(which);
+    else
+        Display_.temperature_only = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_wind_barb_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.wind_barb = atoi(which);
+    else
+        Display_.wind_barb = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_aloha_circle_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.aloha_circle = atoi(which);
+    else
+        Display_.aloha_circle = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_ambiguity_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.ambiguity = atoi(which);
+    else
+        Display_.ambiguity = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_phg_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.phg = atoi(which);
+        XtSetSensitive(display_default_phg_button,   TRUE);
+        XtSetSensitive(display_phg_of_moving_button, TRUE);
+    }
+    else {
+        Display_.phg = 0;
+        XtSetSensitive(display_default_phg_button,   FALSE);
+        XtSetSensitive(display_phg_of_moving_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_default_phg_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.default_phg = atoi(which);
+    else
+        Display_.default_phg = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_phg_of_moving_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.phg_of_moving = atoi(which);
+    else
+        Display_.phg_of_moving = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_df_data_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.df_data = atoi(which);
+        XtSetSensitive(display_df_beamwidth_data_button,  TRUE);
+        XtSetSensitive(display_df_bearing_data_button,    TRUE);
+    }
+    else {
+        Display_.df_data = 0;
+        XtSetSensitive(display_df_beamwidth_data_button,  FALSE);
+        XtSetSensitive(display_df_bearing_data_button,    FALSE);
+    }
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+void Display_df_beamwidth_data_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.df_beamwidth_data = atoi(which);
+    else
+        Display_.df_beamwidth_data = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+void Display_df_bearing_data_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.df_bearing_data = atoi(which);
+    else
+        Display_.df_bearing_data = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_dr_data_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set) {
+        Display_.dr_data = atoi(which);
+        XtSetSensitive(display_dr_arc_button,    TRUE);
+        XtSetSensitive(display_dr_course_button, TRUE);
+        XtSetSensitive(display_dr_symbol_button, TRUE);
+    }
+    else {
+        Display_.dr_data = 0;
+        XtSetSensitive(display_dr_arc_button,    FALSE);
+        XtSetSensitive(display_dr_course_button, FALSE);
+        XtSetSensitive(display_dr_symbol_button, FALSE);
+    }
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_dr_arc_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.dr_arc = atoi(which);
+    else
+        Display_.dr_arc = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_dr_course_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.dr_course = atoi(which);
+    else
+        Display_.dr_course = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_dr_symbol_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.dr_symbol = atoi(which);
+    else
+        Display_.dr_symbol = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_dist_bearing_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.dist_bearing = atoi(which);
+    else
+        Display_.dist_bearing = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+void Display_last_heard_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        Display_.last_heard = atoi(which);
+    else
+        Display_.last_heard = 0;
+
+    redraw_on_new_data = 2;     // Immediate screen update
+}
+
+
+
+
+
+/*
+ *  Toggle unit system (button callbacks)
+ */
+void  Units_choice_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        english_units = atoi(which);
+    else
+        english_units = 0;
+
+    redraw_on_new_data=2;
+    update_units();                     // setup conversion
+    fill_wx_data();
+}
+
+
+
+
+
+/*
+ *  Toggle dist/bearing status (button callbacks)
+ */
+void  Dbstatus_choice_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        do_dbstatus = atoi(which);
+    else
+        do_dbstatus = 0;
+    // we need to rebuild main window now???
+    XtVaSetValues(text2, XmNwidth, do_dbstatus?((37*FONT_WIDTH)+2):((24*FONT_WIDTH)+2), NULL);
+
+    redraw_on_new_data=2;
+}
+
+
+
+
+
+
+/*
+ *  Update global variables for unit conversion
+ *
+ * Be careful using these, as they change based on the value of
+ * english_units!  These variable should only be used when
+ * DISPLAYING data, not when converting numbers for use in internal
+ * storage or equations.
+ *
+ */
+void update_units(void) {
+
+    switch (english_units) {
+        case 1:     // English
+            xastir_snprintf(un_alt,sizeof(un_alt),"ft");
+            xastir_snprintf(un_dst,sizeof(un_dst),"mi");
+            xastir_snprintf(un_spd,sizeof(un_spd),"mph");
+            cvt_m2len  = 3.28084;   // m to ft
+            cvt_dm2len = 0.328084;  // dm to ft
+            cvt_hm2len = 0.0621504; // hm to mi
+            cvt_kn2len = 1.1508;    // knots to mph
+            cvt_mi2len = 1.0;       // mph to mph
+            break;
+        case 2:     // Nautical
+            // add nautical miles and knots for future use
+            xastir_snprintf(un_alt,sizeof(un_alt),"ft");
+            xastir_snprintf(un_dst,sizeof(un_dst),"nm");
+            xastir_snprintf(un_spd,sizeof(un_spd),"kn");
+            cvt_m2len  = 3.28084;   // m to ft
+            cvt_dm2len = 0.328084;  // dm to ft
+            cvt_hm2len = 0.0539957; // hm to nm
+            cvt_kn2len = 1.0;       // knots to knots
+            cvt_mi2len = 0.8689607; // mph to knots / mi to nm
+            break;
+        default:    // Metric
+            xastir_snprintf(un_alt,sizeof(un_alt),"m");
+            xastir_snprintf(un_dst,sizeof(un_dst),"km");
+            xastir_snprintf(un_spd,sizeof(un_spd),"km/h");
+            cvt_m2len  = 1.0;       // m to m
+            cvt_dm2len = 0.1;       // dm to m
+            cvt_hm2len = 0.1;       // hm to km
+            cvt_kn2len = 1.852;     // knots to km/h
+            cvt_mi2len = 1.609;     // mph to km/h
+            break;
+    }
+}
+
+
+
+
+
+void  Auto_msg_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        auto_reply = atoi(which);
+    else
+        auto_reply = 0;
+}
+
+
+
+
+
+void  Satellite_msg_ack_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        satellite_ack_mode = atoi(which);
+    else
+        satellite_ack_mode = 0;
+}
+
+
+
+
+
+void  Transmit_disable_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        transmit_disable = atoi(which);
+        XtSetSensitive(iface_transmit_now,FALSE);
+        XtSetSensitive(object_tx_disable_toggle,FALSE);
+        XtSetSensitive(posit_tx_disable_toggle,FALSE);
+    }
+    else {
+        transmit_disable = 0;
+        XtSetSensitive(iface_transmit_now,TRUE);
+        XtSetSensitive(object_tx_disable_toggle,TRUE);
+        XtSetSensitive(posit_tx_disable_toggle,TRUE);
+    }
+}
+
+
+
+
+
+void  Posit_tx_disable_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        posit_tx_disable = atoi(which);
+    else
+        posit_tx_disable = 0;
+}
+
+
+
+
+
+void  Object_tx_disable_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        object_tx_disable = atoi(which);
+    else
+        object_tx_disable = 0;
+}
+
+
+
+
+
+void  Emergency_beacon_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        emergency_beacon = atoi(which);
+
+//WE7U
+// We need to send a posit or two immediately, shorten the interval
+// between posits, and add the string "EMERGENCY" to the posit
+// before anything else in the comment field.
+
+        transmit_now = 1;
+
+    }
+    else {
+        emergency_beacon = 0;
+    }
+}
+
+
+
+
+
+void  Server_port_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        // Start the listening socket.  If we fork it early we end
+        // up with much smaller process memory allocated for it and
+        // all its children.  The server will authenticate each
+        // client that connects.  We'll share all of our data with
+        // the server, which will send it to all
+        // connected/authenticated clients.  Anything transmitted by
+        // the clients will come back to us and standard igating
+        // rules should apply from there.
+        //
+        enable_server_port = atoi(which);
+        tcp_server_pid = Fork_TCP_server(my_argc, my_argv, my_envp);
+        udp_server_pid = Fork_UDP_server(my_argc, my_argv, my_envp);
+    }
+    else {
+        enable_server_port = 0;
+        shut_down_server();
+    }
+}
+
+
+
+
+void Help_About( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget d;
+    Widget child;
+    XmString xms, xa, xb;
+    Arg al[400];
+    unsigned int ac;
+    float version;
+    char string1[200];
+    char string2[200];
+    extern char compiledate[];
+   
+    xastir_snprintf(string2, sizeof(string2),"\nXastir V%s \n",xastir_version);
+    xb = XmStringCreateLocalized(string2);
+    xa = XmStringCreateLocalized(compiledate);
+    xms = XmStringConcat(xb, xa);
+    XmStringFree(xa);
+    XmStringFree(xb);
+    //xms is still defined
+
+    xa = XmStringCreateLocalized("\n\n" ABOUT_MSG "\n\nLibraries used: " XASTIR_INSTALLED_LIBS "\n\n" ABOUT_OSM);  // Add some newlines
+    xb = XmStringConcat(xms, xa);
+    XmStringFree(xa);
+    XmStringFree(xms);
+    //xb is still defined
+
+    xa = XmStringCreateLocalized("\n" XmVERSION_STRING);  // Add the Motif version string
+    xms = XmStringConcat(xb, xa);
+    XmStringFree(xa);
+    XmStringFree(xb);
+    //xms is still defined
+
+    xa = XmStringCreateLocalized("\n");  // Add a newline
+    xb = XmStringConcat(xms, xa);
+    XmStringFree(xa);
+    XmStringFree(xms);
+    //xb is still defined
+
+    xms = XmStringCopy(xb);
+    XmStringFree(xb);
+    //xms is still defined
+
+#ifdef HAVE_NETAX25_AXLIB_H
+    //if (libax25_version != NULL) {
+    xb = XmStringCreateLocalized("\n");
+    xa = XmStringConcat(xb, xms);
+    XmStringFree(xb);
+    XmStringFree(xms);
+    xb = XmStringCreateLocalized("@(#)LibAX25 (ax25lib_version is broken. Complain to the authors.)\n");
+    xms = XmStringConcat(xa, xb);
+    XmStringFree(xa);
+    XmStringFree(xb);
+    //}
+#endif  // AVE_NETAX25_AXLIB_H
+
+#ifdef HAVE_MAGICK
+    xb = XmStringCreateLocalized("\n");  // Add a newline
+    xa = XmStringConcat(xb, xms);
+    XmStringFree(xb);
+    XmStringFree(xms);
+    //xa is still defined
+
+    xb = XmStringCreateLocalized( MagickVersion);    // Add ImageMagick version string
+    xms = XmStringConcat(xa, xb);
+    XmStringFree(xa);
+    XmStringFree(xb);
+    //xms is still defined
+#endif  // HAVE_MAGICK
+    xb = XmStringCreateLocalized("\n");  // Add a newline
+    xa = XmStringConcat(xb, xms);
+    XmStringFree(xb);
+    XmStringFree(xms);
+    //xa is still defined
+
+    version = XRotVersion( string1, 99 );
+    xastir_snprintf(string2, sizeof(string2), "\n%s, Version %0.2f", string1, version);
+    xb = XmStringCreateLocalized( string2);    // Add Xvertext version string
+    xms = XmStringConcat(xa, xb);
+    XmStringFree(xa);
+    XmStringFree(xb);
+    //xms is still defined
+
+    ac = 0;
+    XtSetArg(al[ac], XmNmessageString, xms); ac++;
+    // "About Xastir"
+    XtSetArg(al[ac], XmNtitle, langcode("PULDNHEL05") ); ac++;
+    XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+    XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+    XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+    // "About Xastir" 
+    d = XmCreateInformationDialog(appshell, langcode("PULDNHEL05"), al, ac);
+    XmStringFree(xms);
+    XtDestroyWidget(XmMessageBoxGetChild(d, (unsigned char)XmDIALOG_CANCEL_BUTTON));
+    XtDestroyWidget(XmMessageBoxGetChild(d, (unsigned char)XmDIALOG_HELP_BUTTON));
+
+    child = XmMessageBoxGetChild(d, XmDIALOG_MESSAGE_LABEL);
+    XtVaSetValues(child, XmNfontList, fontlist1, NULL);
+
+    XtManageChild(d);
+    pos_dialog(d);
+    fix_dialog_size(d);
+}
+
+
+
+
+
+Widget GetTopShell(Widget w) {
+    while(w && !XtIsWMShell(w))
+        w = XtParent(w);
+
+    return(w);
+}
+
+
+
+
+
+/*********************** Display incoming data*******************************/
+/****************************************************************************/
+
+void Display_data_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    Display_data_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void  Display_packet_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        Display_packet_data_type = atoi(which);
+    else
+        Display_packet_data_type = 0;
+
+    redraw_on_new_packet_data=1;
+}
+
+
+
+
+
+// Turn on or off "Station Capabilities", callback for capabilities
+// button.
+//
+void Capabilities_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        show_only_station_capabilities = TRUE;
+    else
+        show_only_station_capabilities = FALSE;
+}
+
+
+
+
+
+// Turn on or off "Mine Only"
+//
+void Display_packet_mine_only_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        Display_packet_data_mine_only = TRUE;
+    else
+        Display_packet_data_mine_only = FALSE;
+}
+
+
+
+
+
+void Display_data( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget pane, my_form, button_close, option_box, tnc_data,
+        net_data, tnc_net_data, capabilities_button,
+        mine_only_button;
+    unsigned int n;
+    Arg args[50];
+    Atom delw;
+
+    if (!Display_data_dialog) {
+        Display_data_dialog = XtVaCreatePopupShell(langcode("WPUPDPD001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Display_data pane",
+                xmPanedWindowWidgetClass, 
+                Display_data_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Display_data my_form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+
+        /* set colors */
+        n=0;
+        XtSetArg(args[n],XmNforeground, MY_FG_COLOR); n++;
+        XtSetArg(args[n],XmNbackground, MY_BG_COLOR); n++;
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNtopOffset, 5); n++;
+        XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNleftOffset, 5); n++;
+        XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+ 
+        option_box = XmCreateRadioBox(my_form,
+                "Display_data option box",
+                args,
+                n);
+
+        XtVaSetValues(option_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                NULL);
+
+        tnc_data = XtVaCreateManagedWidget(langcode("WPUPDPD002"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(tnc_data,XmNvalueChangedCallback,Display_packet_toggle,"1");
+
+        net_data = XtVaCreateManagedWidget(langcode("WPUPDPD003"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(net_data,XmNvalueChangedCallback,Display_packet_toggle,"2");
+
+        tnc_net_data = XtVaCreateManagedWidget(langcode("WPUPDPD004"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(tnc_net_data,XmNvalueChangedCallback,Display_packet_toggle,"0");
+
+        capabilities_button = XtVaCreateManagedWidget(langcode("WPUPDPD007"),
+                xmToggleButtonGadgetClass,
+                my_form,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, option_box,
+                XmNleftOffset, 20,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(capabilities_button, XmNvalueChangedCallback,Capabilities_toggle,"1");
+ 
+        mine_only_button = XtVaCreateManagedWidget(langcode("WPUPDPD008"),
+                xmToggleButtonGadgetClass,
+                my_form,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, capabilities_button,
+                XmNleftOffset, 20,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(mine_only_button, XmNvalueChangedCallback,Display_packet_mine_only_toggle,"1");
+
+        n=0;
+        XtSetArg(args[n], XmNrows, 15); n++;
+        XtSetArg(args[n], XmNcolumns, 100); n++;
+        XtSetArg(args[n], XmNeditable, FALSE); n++;
+        XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
+        XtSetArg(args[n], XmNwordWrap, TRUE); n++;
+        XtSetArg(args[n], XmNforeground, MY_FG_COLOR); n++;
+        XtSetArg(args[n], XmNbackground, MY_BG_COLOR); n++;
+        XtSetArg(args[n], XmNscrollHorizontal, TRUE); n++;
+        XtSetArg(args[n], XmNscrollVertical, TRUE); n++;
+        XtSetArg(args[n], XmNcursorPositionVisible, FALSE); n++;
+        XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
+        XtSetArg(args[n], XmNtopWidget, option_box); n++;
+        XtSetArg(args[n], XmNtopOffset, 5); n++;
+        XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNbottomOffset, 30); n++;
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNleftOffset, 5); n++;
+        XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNrightOffset, 5); n++;
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+
+ 
+//        XtSetArg(args[n], XmNnavigationType, XmTAB_GROUP); n++;
+        Display_data_text=NULL;
+        Display_data_text = XmCreateScrolledText(my_form,
+                "Display_data text",
+                args,
+                n);
+ 
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_close, XmNactivateCallback, Display_data_destroy_shell, Display_data_dialog);
+
+
+// I haven't figured out how to get the scrollbars to allow keyboard traversal.
+// When the ScrolledText widget is in the tab group, once you get there you can't
+// get out and it beeps at you when you try.  Frustrating.   For this dialog it's
+// probably not important enough to worry about.
+// I now have it set to allow TAB'ing into the ScrolledText widget, but to get
+// out you must do a <Shift><TAB>.  This sucks.  Even if you enable the
+// ScrolledText widget in the tab group, the scrollbars don't work with the
+// arrow keys.
+// ScrolledList works.  I need to convert to ScrolledList if
+// possible for output-only windows.
+
+
+        pos_dialog(Display_data_dialog);
+
+        delw = XmInternAtom(XtDisplay(Display_data_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(Display_data_dialog,
+                            delw,
+                            Display_data_destroy_shell,
+                            (XtPointer)Display_data_dialog);
+
+        switch (Display_packet_data_type) {
+            case(0):
+                XmToggleButtonSetState(tnc_net_data,TRUE,FALSE);
+                break;
+
+            case(1):
+                XmToggleButtonSetState(tnc_data,TRUE,FALSE);
+                break;
+
+            case(2):
+                XmToggleButtonSetState(net_data,TRUE,FALSE);
+                break;
+
+            default:
+                XmToggleButtonSetState(tnc_net_data,TRUE,FALSE);
+                break;
+        }
+
+        if (show_only_station_capabilities)
+            XmToggleButtonSetState(capabilities_button,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(capabilities_button,FALSE,FALSE);
+
+        if (Display_packet_data_mine_only)
+            XmToggleButtonSetState(mine_only_button,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(mine_only_button,FALSE,FALSE);
+
+        XtManageChild(option_box);
+        XtManageChild(Display_data_text);
+        XtVaSetValues(Display_data_text, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        redraw_on_new_packet_data=1;
+        XtPopup(Display_data_dialog,XtGrabNone);
+
+//        fix_dialog_vsize(Display_data_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(Display_data_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    }  else
+        (void)XRaiseWindow(XtDisplay(Display_data_dialog), XtWindow(Display_data_dialog));
+
+}
+
+
+
+
+
+/****************************** Help menu ***********************************/
+/****************************************************************************/
+
+void help_view_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    help_view_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void help_index_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+    if (help_view_dialog)
+        help_view_destroy_shell(help_view_dialog, help_view_dialog, NULL);
+
+    help_view_dialog = (Widget)NULL;
+
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    help_index_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void help_view( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget pane, my_form, button_close,help_text;
+    int i;
+    Position x, y;
+    unsigned int n;
+    char *temp = NULL;
+    char title[200];
+    char temp2[200];
+    char temp3[200];
+    FILE *f;
+    XmString *list;
+    int open;
+    Arg args[50];
+    int data_on,pos;
+    int found;
+    Atom delw;
+    char help_file_path[MAX_VALUE];
+
+    data_on=0;
+    pos=0;
+    found=0;
+
+    XtVaGetValues(help_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    for (x=1; x<=i;x++) {
+        if (XmListPosSelected(help_list,x)) {
+            found=1;
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+            x=i+1;
+        }
+    }
+    open=0;
+
+    if (found) {
+        if (help_view_dialog) {
+            XtVaGetValues(help_view_dialog, XmNx, &x, XmNy, &y, NULL);
+            help_view_destroy_shell(help_view_dialog, help_view_dialog, NULL);
+            help_view_dialog = (Widget)NULL;
+            open=1;
+        }
+        if (!help_view_dialog) {
+            xastir_snprintf(title, sizeof(title), "%s - %s", langcode("MENUTB0009"), temp);
+            help_view_dialog = XtVaCreatePopupShell(title,
+                    xmDialogShellWidgetClass, appshell,
+                    XmNdeleteResponse,XmDESTROY,
+                    XmNdefaultPosition, FALSE,
+                    XmNfontList, fontlist1,
+                    NULL);
+            pane = XtVaCreateWidget("help_view pane",
+                    xmPanedWindowWidgetClass, 
+                    help_view_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                    NULL);
+
+            my_form =  XtVaCreateWidget("help_view my_form",
+                    xmFormWidgetClass, 
+                    pane,
+                    XmNfractionBase, 5,
+                    XmNautoUnmanage, FALSE,
+                    XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                    NULL);
+
+            n=0;
+            XtSetArg(args[n], XmNrows, 20); n++;
+            XtSetArg(args[n], XmNcolumns, 80); n++;
+            XtSetArg(args[n], XmNeditable, FALSE); n++;
+            XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
+            XtSetArg(args[n], XmNwordWrap, TRUE); n++;
+            XtSetArg(args[n], XmNscrollHorizontal, FALSE); n++;
+            XtSetArg(args[n], XmNcursorPositionVisible, FALSE); n++;
+            XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
+            XtSetArg(args[n], XmNtopOffset, 5); n++;
+            XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
+            XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+            XtSetArg(args[n], XmNleftOffset, 5); n++;
+            XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
+            XtSetArg(args[n], XmNrightOffset, 5); n++;
+            XtSetArg(args[n], XmNforeground, MY_FG_COLOR); n++;
+            XtSetArg(args[n], XmNbackground, MY_BG_COLOR); n++;
+            XtSetArg(args[n], XmNfontList, fontlist1); n++;
+
+            help_text=NULL;
+            help_text = XmCreateScrolledText(my_form,
+                    "help_view help text",
+                    args,
+                    n);
+
+            get_user_base_dir(HELP_FILE, help_file_path, sizeof(help_file_path));
+
+            f=fopen( help_file_path , "r" );
+            if (f!=NULL) {
+                while(!feof(f)) {
+                    (void)get_line(f,temp2,200);
+                    if (strncmp(temp2,"HELP-INDEX>",11)==0) {
+                        if(strcmp((temp2+11),temp)==0)
+                            data_on=1;
+                        else
+                            data_on=0;
+                    } else {
+                        if (data_on) {
+                            xastir_snprintf(temp3, sizeof(temp3), "%s\n", temp2);
+                            XmTextInsert(help_text,pos,temp3);
+                            pos += strlen(temp3);
+                            XmTextShowPosition(help_text,0);
+                        }
+                    }
+                }
+                (void)fclose(f);
+            }
+            else
+                fprintf(stderr,"Couldn't open file: %s\n", help_file_path);
+
+            button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                    xmPushButtonGadgetClass, 
+                    my_form,
+                    XmNtopAttachment, XmATTACH_WIDGET,
+                    XmNtopWidget, XtParent(help_text),
+                    XmNtopOffset, 5,
+                    XmNbottomAttachment, XmATTACH_FORM,
+                    XmNbottomOffset, 5,
+                    XmNleftAttachment, XmATTACH_POSITION,
+                    XmNleftPosition, 2,
+                    XmNrightAttachment, XmATTACH_POSITION,
+                    XmNrightPosition, 3,
+                    XmNfontList, fontlist1,
+                    NULL);
+
+            XtAddCallback(button_close, XmNactivateCallback, help_view_destroy_shell, help_view_dialog);
+
+            if (!open)
+                pos_dialog(help_view_dialog);
+            else
+                XtVaSetValues(help_view_dialog, XmNx, x, XmNy, y, NULL);
+
+            delw = XmInternAtom(XtDisplay(help_view_dialog),"WM_DELETE_WINDOW", FALSE);
+            XmAddWMProtocolCallback(help_view_dialog, delw, help_view_destroy_shell, (XtPointer)help_view_dialog);
+
+            XtManageChild(my_form);
+            XtManageChild(help_text);
+            XtVaSetValues(help_text, XmNbackground, colors[0x0f], NULL);
+            XtManageChild(pane);
+
+            XtPopup(help_view_dialog,XtGrabNone);
+            fix_dialog_size(help_view_dialog);
+            XmTextShowPosition(help_text,0);
+        }
+        XtFree(temp);   // Free up the space allocated
+    }
+
+}
+
+
+
+
+
+void Help_Index( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel;
+    int n;
+    char temp[600];
+    FILE *f;
+    Arg al[50];           /* Arg List */
+    unsigned int ac = 0;           /* Arg Count */
+    Atom delw;
+    XmString str_ptr;
+    char help_file_path[MAX_VALUE];
+
+    if(!help_index_dialog) {
+        help_index_dialog = XtVaCreatePopupShell(langcode("WPUPHPI001"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNresize, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Help_Index pane",
+                xmPanedWindowWidgetClass, 
+                help_index_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Help_Index my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNvisibleItemCount, 11); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNbackground, colors[0x0ff]); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        help_list = XmCreateScrolledList(my_form,
+                "Help_Index list",
+                al,
+                ac);
+
+        n=1;
+
+        get_user_base_dir(HELP_FILE, help_file_path, sizeof(help_file_path));
+
+        f=fopen( help_file_path, "r" );
+        if (f!=NULL) {
+            while (!feof(f)) {
+                (void)get_line(f,temp,600);
+                if (strncmp(temp,"HELP-INDEX>",11)==0) {
+                    XmListAddItem(help_list, str_ptr = XmStringCreateLocalized((temp+11)),n++);
+                    XmStringFree(str_ptr);
+                }
+            }
+            (void)fclose(f);
+        }
+        else
+            fprintf(stderr,"Couldn't open file: %s\n", help_file_path );
+
+        button_ok = XtVaCreateManagedWidget(langcode("WPUPHPI002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, XtParent(help_list),
+                XmNtopOffset,5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, XtParent(help_list),
+                XmNtopOffset,5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset,5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, help_index_destroy_shell, help_index_dialog);
+        XtAddCallback(button_ok, XmNactivateCallback, help_view, NULL);
+
+        pos_dialog(help_index_dialog);
+
+        delw = XmInternAtom(XtDisplay(help_index_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(help_index_dialog, delw, help_index_destroy_shell, (XtPointer)help_index_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(help_list);
+        XtVaSetValues(help_list, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+        XtPopup(help_index_dialog,XtGrabNone);
+        fix_dialog_size(help_index_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(help_index_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else {
+        XtPopup(help_index_dialog,XtGrabNone);
+        (void)XRaiseWindow(XtDisplay(help_index_dialog), XtWindow(help_index_dialog));
+    }
+}
+
+
+
+
+
+/************************** Clear stations *******************************/
+/*************************************************************************/
+
+void Stations_Clear( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+
+    delete_all_stations();
+
+    my_station_add(my_callsign,my_group,my_symbol,my_long,my_lat,my_phg,my_comment,(char)position_amb_chars);
+
+    current_trail_color = 0x00;  // restart
+
+    // Reload saved objects and items from previous runs.
+    // This implements persistent objects.
+    reload_object_item();
+
+    redraw_on_new_data=2;
+}
+
+
+
+
+
+/************************* Map Properties*********************************/
+/*************************************************************************/
+
+// Destroys the Map Properties dialog
+void map_properties_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    map_properties_dialog = (Widget)NULL;
+    re_sort_maps = 1;
+
+    if (map_chooser_dialog) {
+        XtSetSensitive(map_chooser_button_ok, TRUE);
+        XtSetSensitive(map_chooser_button_cancel, TRUE);
+    }
+}
+
+
+
+
+
+//WE7U
+// Possible changes:
+// *) Save/restore the map selections while changing properties.
+//    Malloc a char array the size of the map_properties_list and
+//    fill it in based on the current highlighting.  Free it when
+//    we're done.
+// *) Change the labels at the top into buttons?  Zoom/Layer buttons
+//    would pop up a dialog asking for the number.  Others would
+//    just toggle the feature.
+// *) Change to a single "Apply" button.  This won't allow us to
+//    easily change only some parameters unless we skip input fields
+//    that are blank.  Run through highlighted items, fill in input
+//    fields if the parameter is the same for all.  If different for
+//    some, leave input field blank.
+// *) Bring up an "Abandon Changes?" confirmation dialog if input
+//    fields are filled in but "Cancel" was pressed instead of
+//    "Apply".
+
+
+
+// Fills in the map properties file entries.
+//
+void map_properties_fill_in (void) {
+    int n,i;
+    XmString str_ptr;
+    map_index_record *current = map_index_head;
+    int top_position;
+
+
+    busy_cursor(appshell);
+
+    i=0;
+    if (map_properties_dialog) {
+        char *current_selections = NULL;
+        int kk, mm;
+
+
+        // Save our current place in the dialog
+        XtVaGetValues(map_properties_list,
+            XmNtopItemPosition, &top_position,
+            NULL);
+
+        // Get the list count from the dialog
+        XtVaGetValues(map_properties_list,
+            XmNitemCount,&kk,
+            NULL);
+
+        if (kk) {   // If list is not empty
+            // Allocate enough chars to hold the highlighting info
+            current_selections = (char *)malloc(sizeof(char) * kk);
+//fprintf(stderr,"List entries:%d\n", kk);
+
+            // Iterate over the list, saving the highlighting values
+            for (mm = 0; mm < kk; mm++) {
+                if (XmListPosSelected(map_properties_list, mm))
+                    current_selections[mm] = 1;
+                else
+                    current_selections[mm] = 0;
+            }
+        }
+
+//        fprintf(stderr,"Top Position: %d\n",top_position);
+
+        // Empty the map_properties_list widget first
+        XmListDeleteAllItems(map_properties_list);
+
+        // Put all the map files/dirs in the map_index into the Map
+        // Properties dialog list (map_properties_list).  Include
+        // the map_layer and draw_filled variables on the line.
+        n=1;
+
+
+//
+// We wish to only show the files that are currently selected in the
+// map_chooser_dialog's map_list widget.  We'll need to run down
+// that widget's entries, checking whether each line is selected,
+// and only display it in the map_properties_list widget if selected
+// and a match with our string.
+//
+// One method would be to make the Map Chooser selections set a bit
+// in the in-memory index, so that we can tell which ones are
+// selected without a bunch of string compares.  The bit would need
+// to be tweaked on starting up the map chooser (setting the
+// selected entries that match the selected_maps.sys file), and when
+// the user tweaked a selection.
+//
+// What we don't want to get into is an n*n set of string compares
+// between two lists, which would be very slow.  If they're both
+// ordered lists though, we'll end up with at most a 2n multiplier,
+// which is much better.  If we can pass the info between the lists
+// with a special entry in the record, we don't slow down at all.
+//
+// Reasonably fast method:  Create a new list that contains only the
+// selected items from map_list.  Run through this list as we
+// populate map_properties_list from the big linked list.
+//
+// Actually, it's probably just as fast to run down through
+// map_list, looking up records for every line that's selected.
+// Just keep the pointers incrementing for each list instead of
+// running through the entire in-memory linked list for every
+// selected item in map_list.
+//
+// For selected directories, we need to add each file that has that
+// initial directory name.  We should be able to do this with a
+// match that stops at the end of the directory name.
+//
+// We need to grey-out the buttons in the Map Chooser until the
+// Properties dialog closes.  Otherwise we might not able to get to
+// to the map_list widget to re-do the Properties list when a button
+// is pressed in the Properties dialog (if the user closes the Map
+// Chooser).
+//
+
+
+        // Set all of the temp_select bits to zero in the in-memory
+        // map index.
+        map_index_temp_select_clear();
+
+        if (map_chooser_dialog) {
+            map_index_record *ptr = map_index_head;
+            int jj, x;
+            XmString *list;
+            char *temp;
+
+            // Get the list and list count from the Map Chooser
+            // dialog.
+            XtVaGetValues(map_list,
+                XmNitemCount,&jj,
+                XmNitems,&list,
+                NULL);
+
+            // Find all selected files/directories in the Map
+            // Chooser.  Set the "temp_select" bits in the in-memory
+            // map index to correspond.
+            //
+            for(x=1; x<=jj; x++)
+            {
+                if (XmListPosSelected(map_list,x)) {
+                    // Snag the filename portion from the line
+		    temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+                    if (temp) {
+
+                        // Update this file or directory in the in-memory
+                        // map index, setting the "temp_select" field to 1.
+                        map_index_update_temp_select(temp, &ptr);
+                        XtFree(temp);
+                    }
+                }
+            }
+        }
+
+        // We should now have all of the files/directories marked in
+        // the in-memory map index.  Files underneath selected
+        // directories should also be marked by this point, as the
+        // map_index_update_temp_select() routine should assure
+        // this.
+
+        while (current != NULL) {
+
+if (current->temp_select) {
+
+            //fprintf(stderr,"%s\n",current->filename);
+
+            // Make sure it's a file and not a directory
+            if (current->filename[strlen(current->filename)-1] != '/') {
+                char temp[MAX_FILENAME];
+                char temp_layer[10];
+                char temp_max_zoom[10];
+                char temp_min_zoom[10];
+                char temp_filled[20];
+                char temp_drg[20];
+                char temp_auto[20];
+                int len, start;
+
+
+                // We have a file.  Construct the line that we wish
+                // to place in the list
+
+                // JMT - this is a guess
+                if (current->max_zoom == 0) {
+                    xastir_snprintf(temp_max_zoom,
+                        sizeof(temp_max_zoom),
+                        "  -  ");
+                }
+                else {
+                    xastir_snprintf(temp_max_zoom,
+                    sizeof(temp_max_zoom),
+                    "%5d",
+                    current->max_zoom);
+                }
+
+                if (current->min_zoom == 0) {
+                    xastir_snprintf(temp_min_zoom,
+                        sizeof(temp_min_zoom),
+                        "  -  ");
+                }
+                else {
+                    xastir_snprintf(temp_min_zoom,
+                    sizeof(temp_min_zoom),
+                    "%5d",
+                    current->min_zoom);
+                }
+
+                if (current->map_layer == 0) {
+                    xastir_snprintf(temp_layer,
+                        sizeof(temp_layer),
+                        "  -  ");
+                }
+                else {
+                    xastir_snprintf(temp_layer,
+                    sizeof(temp_layer),
+                    "%5d",
+                    current->map_layer);
+                }
+
+                xastir_snprintf(temp_filled,
+                    sizeof(temp_filled),
+                    "     ");
+
+                switch (current->draw_filled) {
+
+                    case 0: // Global No-Fill (vector)
+
+                        // Center the string in the column
+                        len = strlen(langcode("MAPP007"));
+                        start = (int)( (5 - len) / 2 + 0.5);
+
+                        if (start < 0)
+                            start = 0;
+
+                        // Insert the string.  Fill with spaces
+                        // on the end.
+                        xastir_snprintf(&temp_filled[start],
+                            sizeof(temp_filled)-start,
+                            "%s     ",
+                            langcode("MAPP007"));   // "No"
+
+                        break;
+
+                    case 1: // Global Fill
+
+                        // Center the string in the column
+                        len = strlen(langcode("MAPP006"));
+                        start = (int)( (5 - len) / 2 + 0.5);
+
+                        if (start < 0)
+                            start = 0;
+
+                        // Insert the string.  Fill with spaces
+                        // on the end.
+                        xastir_snprintf(&temp_filled[start],
+                            sizeof(temp_filled)-start,
+                            "%s     ",
+                            langcode("MAPP006"));   // "Yes"
+
+                        break;
+
+                    case 2: // Auto
+                    default:
+
+                        // Center the string in the column
+                        len = strlen(langcode("MAPP011"));
+                        start = (int)( (5 - len) / 2 + 1.5);
+
+                        if (start < 0)
+                            start = 0;
+
+                        // Insert the string.  Fill with spaces
+                        // on the end.
+                        xastir_snprintf(&temp_filled[start],
+                            sizeof(temp_filled)-start,
+                            "%s     ",
+                            langcode("MAPP011"));   // "Auto"
+
+                        break;
+
+                    }   // End of switch
+
+                    // Truncate it so it fits our column width.
+                    temp_filled[5] = '\0';
+
+                xastir_snprintf(temp_drg,
+                    sizeof(temp_drg),
+                    "     ");
+
+                switch (current->usgs_drg) {
+
+                    case 0: // No
+
+                        // Center the string in the column
+                        len = strlen(langcode("MAPP007"));
+                        start = (int)( (5 - len) / 2 + 0.5);
+
+                        if (start < 0)
+                            start = 0;
+
+                        // Insert the string.  Fill with spaces
+                        // on the end.
+                        xastir_snprintf(&temp_drg[start],
+                            sizeof(temp_drg)-start,
+                            "%s     ",
+                            langcode("MAPP007"));   // "No"
+
+                        break;
+
+                    case 1: // Yes
+
+                        // Center the string in the column
+                        len = strlen(langcode("MAPP006"));
+                        start = (int)( (5 - len) / 2 + 0.5);
+
+                        if (start < 0)
+                            start = 0;
+
+                        // Insert the string.  Fill with spaces
+                        // on the end.
+                        xastir_snprintf(&temp_drg[start],
+                            sizeof(temp_drg)-start,
+                            "%s     ",
+                            langcode("MAPP006"));   // "Yes"
+
+                        break;
+
+                    case 2: // Auto
+                    default:
+
+                        // Center the string in the column
+                        len = strlen(langcode("MAPP011"));
+                        start = (int)( (5 - len) / 2 + 1.5);
+
+                        if (start < 0)
+                            start = 0;
+
+                        // Insert the string.  Fill with spaces
+                        // on the end.
+                        xastir_snprintf(&temp_drg[start],
+                            sizeof(temp_drg)-start,
+                            "%s     ",
+                            langcode("MAPP011"));   // "Auto"
+
+                        break;
+
+                    }   // End of switch
+
+                    // Truncate it so it fits our column width.
+                    temp_drg[5] = '\0';
+
+                xastir_snprintf(temp_auto,
+                    sizeof(temp_auto),
+                    "     ");
+
+                if (current->auto_maps) {
+                    int len, start;
+
+                    // Center the string in the column
+                    len = strlen(langcode("MAPP006"));
+                    start = (int)( (5 - len) / 2 + 0.5);
+
+                    if (start < 0)
+                        start = 0;
+
+                    // Insert the string.  Fill with spaces on the
+                    // end.
+                    xastir_snprintf(&temp_auto[start],
+                        sizeof(temp_filled)-start,
+                        "%s     ",
+                        langcode("MAPP006"));
+
+                    // Truncate it so it fits our column width.
+                    temp_auto[5] = '\0';
+                }
+
+                //WARNING WARNING WARNING --- changing this format string
+                // REQUIRES changing the defined constant MPD_FILENAME_OFFSET
+                // at the top of this file, or all the routines that try
+                // to decode the string will be wrong!
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "%s %s %s %s %s %s  %s",
+                    temp_max_zoom,
+                    temp_min_zoom,
+                    temp_layer,
+                    temp_filled,
+                    temp_drg,
+                    temp_auto,
+                    current->filename);
+
+                str_ptr = XmStringCreateLocalized(temp);
+		XmListAddItem(map_properties_list, str_ptr, n);
+                n++;
+                XmStringFree(str_ptr);
+            }
+}
+
+            current = current->next;
+        }
+
+        if (kk) {   // If list is not empty
+            // Restore the highlighting values
+            for (mm = 0; mm < kk; mm++) {
+                if (current_selections[mm])
+                    XmListSelectPos(map_properties_list,mm,TRUE);
+            }
+            // Free the highlighting array we allocated
+            free(current_selections);
+        }
+
+        // Restore our place in the dialog
+        XtVaSetValues(map_properties_list,
+            XmNtopItemPosition, top_position,
+            NULL);
+    }
+}
+
+
+
+
+
+// Removes the highlighting for maps in the current view of the map
+// properties list.
+//
+void map_properties_deselect_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, deselecting every line
+    for(x=1; x<=i;x++) {
+        if (XmListPosSelected(map_properties_list,x)) {
+            XmListDeselectPos(map_properties_list,x);
+        }
+    }
+}
+
+
+
+
+
+// Selects all maps in the current view of the map properties list.
+//
+void map_properties_select_all_maps(Widget widget, XtPointer clientData, XtPointer
+ callData) {
+    int i, x;
+    XmString *list;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, selecting every line
+    for(x=1; x<=i;x++) {
+        // Deselect each one first, in case already selected
+        XmListDeselectPos(map_properties_list,x);
+
+        // Select/highlight that position
+        XmListSelectPos(map_properties_list,x,TRUE);
+    }
+}
+
+
+
+
+
+// Change the "draw_filled" field in the in-memory map_index to a
+// two.
+void map_index_update_filled_auto(char *filename) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->draw_filled = 2;
+            break;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+// Change the "draw_filled" field in the in-memory map_index to a
+// one.
+void map_index_update_filled_yes(char *filename) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->draw_filled = 1;
+            break;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+// Change the "draw_filled" field in the in-memory map_index to a
+// zero.
+void map_index_update_filled_no(char *filename) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->draw_filled = 0;
+            break;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+void map_properties_filled_auto(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+    char *temp;
+
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the filled field on
+    // every one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting the "draw_filled" field to 2.
+                map_index_update_filled_auto(&temp[MPD_FILENAME_OFFSET]);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+void map_properties_filled_yes(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+    char *temp;
+
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the filled field on
+    // every one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting the "draw_filled" field to 1.
+                map_index_update_filled_yes(&temp[MPD_FILENAME_OFFSET]);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+void map_properties_filled_no(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+    char *temp;
+
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the filled field on
+    // every one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting the "draw_filled" field to 0.
+                map_index_update_filled_no(&temp[MPD_FILENAME_OFFSET]);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+// Change the "usgs_drg" field in the in-memory map_index to a
+// specified value.
+void map_index_update_usgs_drg(char *filename, int drg_setting) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->usgs_drg = drg_setting;
+            break;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+// common functionality of all the callbacks.  Probably don't even need 
+// all the X data here, either
+void map_properties_usgs_drg(Widget widget, XtPointer clientData, XtPointer callData, int drg_setting) {
+    int i, x;
+    XmString *list;
+    char *temp;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the usgs_drg field on
+    // every one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting the "usgs_drg" field to drg_setting.
+                map_index_update_usgs_drg(&temp[MPD_FILENAME_OFFSET],drg_setting);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+// the real callbacks
+void map_properties_usgs_drg_auto(Widget widget, XtPointer clientData, XtPointer callData) {
+    map_properties_usgs_drg(widget, clientData, callData, 2);
+}
+void map_properties_usgs_drg_yes(Widget widget, XtPointer clientData, XtPointer callData) {
+    map_properties_usgs_drg(widget, clientData, callData, 1);
+}
+void map_properties_usgs_drg_no(Widget widget, XtPointer clientData, XtPointer callData) {
+    map_properties_usgs_drg(widget, clientData, callData, 0);
+}
+
+
+
+
+
+// Change the "auto_maps" field in the in-memory map_index to a one.
+void map_index_update_auto_maps_yes(char *filename) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->auto_maps = 1;
+            return;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+// Change the "auto_maps" field in the in-memory map_index to a
+// zero.
+void map_index_update_auto_maps_no(char *filename) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->auto_maps = 0;
+            return;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+void map_properties_auto_maps_yes(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+    char *temp;
+
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the auto_maps field
+    // on every one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting the "auto_maps" field to 1.
+                map_index_update_auto_maps_yes(&temp[MPD_FILENAME_OFFSET]);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+void map_properties_auto_maps_no(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+    char *temp;
+
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the auto_maps field
+    // on every one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting the "auto_maps" field to 0.
+                map_index_update_auto_maps_no(&temp[MPD_FILENAME_OFFSET]);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+// Update the "map_layer" field in the in-memory map_index based on
+// the "map_layer" input parameter.
+void map_index_update_layer(char *filename, int map_layer) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->map_layer = map_layer;
+            return;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+void map_properties_layer_change(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x, new_layer;
+    XmString *list;
+    char *temp;
+
+
+    // Get new layer selection in the form of an int
+    temp = XmTextGetString(new_map_layer_text);
+    new_layer = atoi(temp);
+    XtFree(temp);
+
+//fprintf(stderr,"New layer selected is: %d\n", new_layer);
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the layer on every
+    // one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting/resetting the "selected" field
+                // as appropriate.
+                map_index_update_layer(&temp[MPD_FILENAME_OFFSET], new_layer);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+// Update the "max_zoom" field in the in-memory map_index based on
+// the "max_zoom" input parameter.
+void map_index_update_max_zoom(char *filename, int max_zoom) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->max_zoom = max_zoom;
+            return;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+void map_properties_max_zoom_change(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x, new_max_zoom;
+    XmString *list;
+    char *temp;
+
+
+    // Get new layer selection in the form of an int
+    temp = XmTextGetString(new_max_zoom_text);
+    new_max_zoom = atoi(temp);
+    XtFree(temp);
+
+//    fprintf(stderr,"New max_zoom selected is: %d\n", new_max_zoom);
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the layer on every
+    // one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting/resetting the "selected" field
+                // as appropriate.
+                map_index_update_max_zoom(&temp[MPD_FILENAME_OFFSET], new_max_zoom);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+// Update the "min_zoom" field in the in-memory map_index based on
+// the "min_zoom" input parameter.
+void map_index_update_min_zoom(char *filename, int min_zoom) {
+    map_index_record *current = map_index_head;
+
+    while (current != NULL) {
+        if (strcmp(current->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            current->min_zoom = min_zoom;
+            return;
+        }
+        current = current->next;
+    }
+}
+
+
+
+
+
+void map_properties_min_zoom_change(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x, new_min_zoom;
+    XmString *list;
+    char *temp;
+
+
+    // Get new layer selection in the form of an int
+    temp = XmTextGetString(new_min_zoom_text);
+    new_min_zoom = atoi(temp);
+    XtFree(temp);
+
+//fprintf(stderr,"New layer selected is: %d\n", new_layer);
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_properties_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, changing the layer on every
+    // one that is selected.
+    for(x=1; x<=i;x++)
+    {
+        // If the line was selected
+        if ( XmListPosSelected(map_properties_list,x) ) {
+ 
+            // Snag the filename portion from the line
+            temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_END);
+            if (temp) {
+                // Update this file or directory in the in-memory
+                // map index, setting/resetting the "selected" field
+                // as appropriate.
+                map_index_update_min_zoom(&temp[MPD_FILENAME_OFFSET], new_min_zoom);
+                XtFree(temp);
+            }
+        }
+    }
+
+    // Delete all entries in the list and re-create anew.
+    map_properties_fill_in();
+
+    // Save the updated index to the file
+    index_save_to_file();
+}
+
+
+
+
+
+// JMT -- now supports max and min zoom levels
+
+// Allows setting map layer and filled polygon properties for maps
+// selected in the map chooser.  Show a warning or bring up a
+// confirmation dialog if more than one map is selected when this
+// function is entered.  This is the callback function for the
+// Properties button in the Map Chooser.
+//
+// If the map_layer is a range of values, inform the user here
+// via a popup, so that they don't make a mistake and change too
+// many different types of maps to the same map layer.
+//
+// We could either show all maps here and allow changing each
+// one, or just show min/max map_layer draw_filled properties
+// for the maps selected in the Map Chooser.
+//
+// Create the properties dialog.  Show the map_layer and
+// draw_filled properties for the maps.
+//
+// Could still create Cancel and OK buttons.  Cancel would wipe the
+// in-memory list and fetch it from file again.  OK would write the
+// in-memory list to disk.
+//
+void map_properties( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int i;
+//    int x;
+//    char *temp;
+//    XmString *list;
+    static Widget pane, my_form, button_clear, button_close,
+        rowcol1, rowcol2, rowcol3, label1, label2, label3, label4, label5,
+        button_filled_auto, button_filled_yes, button_filled_no,
+        button_usgs_drg_auto, button_usgs_drg_yes, button_usgs_drg_no,
+        button_layer_change,
+        button_auto_maps_yes, button_auto_maps_no,
+        button_max_zoom_change, button_min_zoom_change,
+        button_select_all;
+    Atom delw;
+    Arg al[50];                     // Arg List
+    register unsigned int ac = 0;   // Arg Count
+
+
+    busy_cursor(appshell);
+
+    if (map_chooser_dialog) {
+        XtSetSensitive(map_chooser_button_ok, FALSE);
+        XtSetSensitive(map_chooser_button_cancel, FALSE);
+    }
+
+    i=0;
+    if (!map_properties_dialog) {
+
+        map_properties_dialog = XtVaCreatePopupShell(langcode("MAPP001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Map_properties pane",
+                xmPanedWindowWidgetClass, 
+                map_properties_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Map_properties my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 7,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNvisibleItemCount, 13); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmMULTIPLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        map_properties_list = XmCreateScrolledList(my_form,
+                "Map_properties list",
+                al,
+                ac);
+
+        // Find the names of all the map files on disk and put them
+        // into map_properties_list
+        map_properties_fill_in();
+
+        // Attach a rowcolumn manager widget to my_form to handle
+        // the third button row.  Attach it to the bottom of the
+        // form.
+        rowcol3 = XtVaCreateManagedWidget("Map properties rowcol3", 
+                xmRowColumnWidgetClass, 
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNkeyboardFocusPolicy, XmEXPLICIT,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Attach a rowcolumn manager widget to my_form to handle
+        // the second button row.  Attach it to the top of rowcol3.
+        rowcol2 = XtVaCreateManagedWidget("Map properties rowcol2", 
+                xmRowColumnWidgetClass, 
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, rowcol3,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNkeyboardFocusPolicy, XmEXPLICIT,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Attach a rowcolumn manager widget to my_form to handle
+        // the first button row.
+        rowcol1 = XtVaCreateManagedWidget("Map properties rowcol1", 
+                xmRowColumnWidgetClass, 
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, rowcol2,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNkeyboardFocusPolicy, XmEXPLICIT,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label1  = XtVaCreateManagedWidget(langcode("MAPP002"),
+                xmLabelWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label2  = XtVaCreateManagedWidget(langcode("MAPP003"),
+ 
+                xmLabelWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label1,
+                XmNtopOffset, 0,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtVaSetValues(XtParent(map_properties_list),
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, label2,
+                XmNtopOffset, 2,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, rowcol1,
+                XmNbottomOffset, 2,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // JMT -- this is a guess
+// "Max Zoom" stolen from "Change Layer"
+        button_max_zoom_change = XtVaCreateManagedWidget(langcode("MAPP009"),
+                xmPushButtonGadgetClass, 
+                rowcol1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        new_max_zoom_text = XtVaCreateManagedWidget("Map Properties max zoom number",
+                xmTextWidgetClass,
+                rowcol1,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((7*7)+2),
+                XmNmaxLength, 5,
+                XmNbackground, colors[0x0f],
+                XmNrightOffset, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Min Zoom" stolen from "Change Layer"
+        button_min_zoom_change = XtVaCreateManagedWidget(langcode("MAPP010"),
+                xmPushButtonGadgetClass, 
+                rowcol1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        new_min_zoom_text = XtVaCreateManagedWidget("Map Properties min zoom number",
+                xmTextWidgetClass,
+                rowcol1,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((7*7)+2),
+                XmNmaxLength, 5,
+                XmNbackground, colors[0x0f],
+                XmNrightOffset, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+// "Change Layer"
+        button_layer_change = XtVaCreateManagedWidget(langcode("MAPP004"),
+                xmPushButtonGadgetClass, 
+                rowcol1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        new_map_layer_text = XtVaCreateManagedWidget("Map Properties new layer number",
+                xmTextWidgetClass,
+                rowcol1,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 6,
+                XmNwidth, ((7*7)+2),
+                XmNmaxLength, 5,
+                XmNbackground, colors[0x0f],
+                XmNrightOffset, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        label3  = XtVaCreateManagedWidget(langcode("MAPP005"),
+                xmLabelWidgetClass,
+                rowcol2,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Filled-Auto"
+        button_filled_auto = XtVaCreateManagedWidget(langcode("MAPP011"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Filled-Yes"
+        button_filled_yes = XtVaCreateManagedWidget(langcode("MAPP006"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Filled-No"
+        button_filled_no = XtVaCreateManagedWidget(langcode("MAPP007"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Automaps
+        label4  = XtVaCreateManagedWidget(langcode("MAPP008"),
+                xmLabelWidgetClass,
+                rowcol2,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Automaps-Yes"
+        button_auto_maps_yes = XtVaCreateManagedWidget(langcode("MAPP006"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Automaps-No"
+        button_auto_maps_no = XtVaCreateManagedWidget(langcode("MAPP007"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// USGS DRG->
+        label5  = XtVaCreateManagedWidget(langcode("MAPP012"),
+                xmLabelWidgetClass,
+                rowcol2,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "USGS DRG Auto"
+        button_usgs_drg_auto = XtVaCreateManagedWidget(langcode("MAPP011"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "USGS DRG Yes"
+        button_usgs_drg_yes = XtVaCreateManagedWidget(langcode("MAPP006"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "USGS DRG No"
+        button_usgs_drg_no = XtVaCreateManagedWidget(langcode("MAPP007"),
+                xmPushButtonGadgetClass, 
+                rowcol2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Select All"
+        button_select_all = XtVaCreateManagedWidget(langcode("PULDNMMC09"),
+                xmPushButtonGadgetClass,
+                rowcol3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Clear"
+        button_clear = XtVaCreateManagedWidget(langcode("PULDNMMC01"),
+                xmPushButtonGadgetClass, 
+                rowcol3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Close"
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                rowcol3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_close, XmNactivateCallback, map_properties_destroy_shell, map_properties_dialog);
+        XtAddCallback(button_clear, XmNactivateCallback, map_properties_deselect_maps, map_properties_dialog);
+        XtAddCallback(button_select_all, XmNactivateCallback, map_properties_select_all_maps, map_properties_dialog);
+        XtAddCallback(button_filled_auto, XmNactivateCallback, map_properties_filled_auto, map_properties_dialog);
+        XtAddCallback(button_filled_yes, XmNactivateCallback, map_properties_filled_yes, map_properties_dialog);
+        XtAddCallback(button_filled_no, XmNactivateCallback, map_properties_filled_no, map_properties_dialog);
+        XtAddCallback(button_usgs_drg_auto, XmNactivateCallback, map_properties_usgs_drg_auto, map_properties_dialog);
+        XtAddCallback(button_usgs_drg_yes, XmNactivateCallback, map_properties_usgs_drg_yes, map_properties_dialog);
+        XtAddCallback(button_usgs_drg_no, XmNactivateCallback, map_properties_usgs_drg_no, map_properties_dialog);
+        XtAddCallback(button_max_zoom_change, XmNactivateCallback, map_properties_max_zoom_change, map_properties_dialog);
+        XtAddCallback(button_min_zoom_change, XmNactivateCallback, map_properties_min_zoom_change, map_properties_dialog);
+        XtAddCallback(button_layer_change, XmNactivateCallback, map_properties_layer_change, map_properties_dialog);
+        XtAddCallback(button_auto_maps_yes, XmNactivateCallback, map_properties_auto_maps_yes, map_properties_dialog);
+        XtAddCallback(button_auto_maps_no, XmNactivateCallback, map_properties_auto_maps_no, map_properties_dialog);
+
+        pos_dialog(map_properties_dialog);
+
+        delw = XmInternAtom(XtDisplay(map_properties_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(map_properties_dialog, delw, map_properties_destroy_shell, (XtPointer)map_properties_dialog);
+
+        XtManageChild(rowcol1);
+        XtManageChild(rowcol2);
+        XtManageChild(rowcol3);
+        XtManageChild(my_form);
+        XtManageChild(map_properties_list);
+        XtVaSetValues(map_properties_list, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+        XmTextSetString(new_map_layer_text, "0");
+
+        XtPopup(map_properties_dialog,XtGrabNone);
+
+        // Move focus to the OK button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(map_properties_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    } else {
+        (void)XRaiseWindow(XtDisplay(map_properties_dialog), XtWindow(map_properties_dialog));
+    }
+}
+
+
+
+
+
+/************************* Map Chooser ***********************************/
+/*************************************************************************/
+
+// Destroys the Map Chooser dialog
+void map_chooser_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    map_chooser_dialog = (Widget)NULL;
+}
+
+
+
+
+
+// Update the "selected" field in the in-memory map_index based on
+// the "selected" input parameter.
+void map_index_update_selected(char *filename, int selected, map_index_record **current) {
+
+    // If we're passed a NULL pointer, start at the head of the
+    // in-memory linked list.
+    //
+    if ( (*current) == NULL) {
+        (*current) = map_index_head;
+    }
+
+    // Start searching through the list at the pointer we were
+    // given.
+    //
+    while ( (*current) != NULL) {
+        if (strcmp( (*current)->filename,filename) == 0) {
+            // Found a match.  Update the field and return.
+            (*current)->selected = selected;
+            return;
+        }
+        (*current) = (*current)->next;
+    }
+}
+
+
+
+
+
+// Update the "temp_select" field in the in-memory map_index.
+void map_index_update_temp_select(char *filename, map_index_record **current) {
+    int result;
+
+    // If we're passed a NULL pointer, start at the head of the
+    // in-memory linked list.
+    //
+    if ( (*current) == NULL) {
+        (*current) = map_index_head;
+    }
+
+    // Start searching through the list at the pointer we were
+    // given.  We need to do a loose match here for directories.  If
+    // a selected directory is contained in a filepath, select that
+    // file as well.  For the directory case, once we find a match
+    // in the file path, keep walking down the list until we get a
+    // non-match.
+    //
+    while ( (*current) != NULL) {
+
+        result = strncmp( (*current)->filename,filename,strlen(filename));
+
+        if (result == 0) {
+            // Found a match.  Update the field.
+            (*current)->temp_select = 1;
+        }
+        else if (result > 0) {  // We passsed the relevant area.
+                                // All done for now.
+            return;
+        }
+        (*current) = (*current)->next;
+    }
+}
+
+
+
+
+
+// Clear all of the temp_select bits in the in-memory map index
+void map_index_temp_select_clear(void) {
+    map_index_record *current;
+
+    current = map_index_head;
+    while (current != NULL) {
+        current->temp_select = 0;
+        current = current->next;
+    }
+}
+
+
+
+
+
+// Gets the list of selected maps out of the dialog, writes them to
+// the selected maps disk file, destroys the dialog, then calls
+// create_image() with the newly selected map set in place.  This
+// should be the _only_ routine in this set of functions that
+// actually changes the selected maps disk file.  The others should
+// merely manipulate the list in the map chooser dialog.  This
+// function is attached to the "OK" button in the Map Chooser dialog.
+//
+// What we'll do here is set/reset the "selected" field in the
+// in-memory map_index list, then write the info out to the
+// selected_maps.sys file.  Only set the file entries if in file
+// mode, dir entries if in dir mode.  When writing out to file,
+// write them both out.
+//
+// In order to make this fast, we'll send a start pointer to
+// map_index_update_selected() which is the "next" pointer from the
+// previous hit.  We're relying on the fact that the Map Chooser
+// list and the in-memory linked list are in the same search order,
+// so this way we don't search through the entire linked list for
+// each update.  With 30,000 maps, it ended up being up to 30,000 *
+// 30,000 for the loop iterations, which was unwieldy.
+//
+void map_chooser_select_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    char *temp;
+    XmString *list;
+    FILE *f;
+    map_index_record *ptr = map_index_head;
+    char selected_map_path[MAX_VALUE];
+
+    get_user_base_dir(SELECTED_MAP_DATA, selected_map_path, 
+                      sizeof(selected_map_path));
+
+// It'd be nice to turn off auto-maps here, or better perhaps would
+// be if any button were chosen other than "Cancel".
+
+    // reset map_refresh in case we no longer have a refreshed map selected
+    map_refresh_interval = 0;
+
+    // Cause load_maps() and load_automaps() to re-sort the selected
+    // maps by layer.
+    re_sort_maps = 1;
+
+    // Get the list and the list count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the list, updating the equivalent entries in the
+    // in-memory map index.  If we're in "directory" mode we'll only
+    // update the directory entries.  In "Expanded dirs" mode, we'll
+    // update both file and directory entries.
+    // The end result is that both directories and files may be
+    // selected, not either/or as the code was written earlier.
+    //
+    // Here we basically walk both lists together, the List widget
+    // and the in-memory linked list, as they're both in the same
+    // sort order.  We do this by passing "ptr" back and forth, and
+    // updating it to point to one after the last one found each
+    // time.  That turns and N*N search into an N search and is a
+    // big speed improvement when you have 1000's of maps.
+    //
+    for(x=1; x<=i;x++) {
+	temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+        if (temp) {
+            // Update this file or directory in the in-memory map
+            // index, setting/resetting the "selected" field as
+            // appropriate.
+            map_index_update_selected(temp,
+                XmListPosSelected(map_list,x),
+                &ptr);
+            XtFree(temp);
+        }
+	//fprintf(stderr,"Passed back: %s\n", ptr->filename);
+        ptr = ptr->next;
+    }
+
+    // Now we have all of the updates done to the in-memory map
+    // index.  Write out the selected maps to disk, overwriting
+    // whatever was there before.
+
+    ptr = map_index_head;
+    f=fopen( selected_map_path , "w+" );
+    if (f!=NULL) {
+
+        while (ptr != NULL) {
+            // Write only selected files/directories out to the disk
+            // file.
+            if (ptr->selected) {
+                fprintf(f,"%s\n",ptr->filename);
+            }
+            ptr = ptr->next;
+        }
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", selected_map_path );
+
+    map_chooser_destroy_shell(widget,clientData,callData);
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0;
+//    }
+}
+
+
+
+
+
+// Same as map_chooser_select_maps, but doesn't destroy the Map
+// Chooser dialog.
+void map_chooser_apply_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    char *temp;
+    XmString *list;
+    FILE *f;
+    map_index_record *ptr = map_index_head;
+    char selected_map_path[MAX_VALUE];
+
+    get_user_base_dir(SELECTED_MAP_DATA, selected_map_path, 
+                      sizeof(selected_map_path));
+
+// It'd be nice to turn off auto-maps here, or better perhaps would
+// be if any button were chosen other than "Cancel".
+
+    // reset map_refresh in case we no longer have a refreshed map selected
+    map_refresh_interval = 0;
+
+    // Cause load_maps() and load_automaps() to re-sort the selected
+    // maps by layer.
+    re_sort_maps = 1;
+
+    // Get the list and the list count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the list, updating the equivalent entries in the
+    // in-memory map index.  If we're in "directory" mode we'll only
+    // update the directory entries.  In "Expanded dirs" mode, we'll
+    // update both file and directory entries.
+    // The end result is that both directories and files may be
+    // selected, not either/or as the code was written earlier.
+    //
+    // Here we basically walk both lists together, the List widget
+    // and the in-memory linked list, as they're both in the same
+    // sort order.  We do this by passing "ptr" back and forth, and
+    // updating it to point to one after the last one found each
+    // time.  That turns and N*N search into an N search and is a
+    // big speed improvement when you have 1000's of maps.
+    //
+    for(x=1; x<=i;x++) {
+	temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+        if (temp) {
+            // Update this file or directory in the in-memory map
+            // index, setting/resetting the "selected" field as
+            // appropriate.
+            map_index_update_selected(temp,
+                XmListPosSelected(map_list,x),
+                &ptr);
+            XtFree(temp);
+        }
+//fprintf(stderr,"Passed back: %s\n", ptr->filename);
+        ptr = ptr->next;
+    }
+
+    // Now we have all of the updates done to the in-memory map
+    // index.  Write out the selected maps to disk, overwriting
+    // whatever was there before.
+
+    ptr = map_index_head;
+
+    f=fopen( selected_map_path, "w+" );
+    if (f!=NULL) {
+
+        while (ptr != NULL) {
+            // Write only selected files/directories out to the disk
+            // file.
+            if (ptr->selected) {
+                fprintf(f,"%s\n",ptr->filename);
+            }
+            ptr = ptr->next;
+        }
+        (void)fclose(f);
+    }
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", selected_map_path );
+
+//    map_chooser_destroy_shell(widget,clientData,callData);
+
+    // Set interrupt_drawing_now because conditions have changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+// Counts the number of "selected" fields with a value of 1 in the
+// in-memory map index.  Updates the "Dirs/Maps Selected" count in
+// the map chooser.
+void map_chooser_update_quantity(void) {
+    int dir_quantity = 0;
+    int map_quantity = 0;
+    static char str_quantity[100];
+    map_index_record *current = map_index_head;
+    XmString x_str;
+
+    // Count the "selected" fields in the map index with value of 1
+    while (current != NULL) {
+        if (current->selected) {
+
+            if (current->filename[strlen(current->filename)-1] == '/') {
+                // It's a directory
+                dir_quantity++;
+            }
+            else {
+                // It's a map
+                map_quantity++;
+            }
+        }
+        current = current->next;
+    }
+   
+    // Update the "Dirs/Maps Selected" label in the Map Chooser
+    xastir_snprintf(str_quantity,
+        sizeof(str_quantity),
+        "%d/%d",
+        dir_quantity,
+        map_quantity);
+    x_str = XmStringCreateLocalized(str_quantity);
+    XtVaSetValues(map_chooser_maps_selected_data,
+        XmNlabelString, x_str,
+        NULL);
+    XmStringFree(x_str);
+}
+ 
+ 
+
+
+
+void map_chooser_select_vector_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    char *temp;
+    char *ext;
+    XmString *list;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the list looking for matching file extensions
+    for(x=1; x<=i;x++) {
+
+//        // Deselect all currently selected maps
+//        if (XmListPosSelected(map_list,x)) {
+//            XmListDeselectPos(map_list,x);
+//        }
+
+	temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+        if(temp) {
+            ext = get_map_ext (temp);
+            if ( (ext != NULL)
+                    && (   (strcasecmp(ext,"map") == 0)
+                        || (strcasecmp(ext,"shp") == 0)
+                        || (strcasecmp(ext,"pdb") == 0)
+                        || (strcasecmp(ext,"gnis") == 0)
+                        || (strcasecmp(ext,"rt1") == 0)
+                        || (strcasecmp(ext,"rt2") == 0)
+                        || (strcasecmp(ext,"rt4") == 0)
+                        || (strcasecmp(ext,"rt5") == 0)
+                        || (strcasecmp(ext,"rt6") == 0)
+                        || (strcasecmp(ext,"rt7") == 0)
+                        || (strcasecmp(ext,"rt8") == 0)
+                        || (strcasecmp(ext,"rta") == 0)
+                        || (strcasecmp(ext,"rtc") == 0)
+                        || (strcasecmp(ext,"rth") == 0)
+                        || (strcasecmp(ext,"rti") == 0)
+                        || (strcasecmp(ext,"rtp") == 0)
+                        || (strcasecmp(ext,"rtr") == 0)
+                        || (strcasecmp(ext,"rts") == 0)
+                        || (strcasecmp(ext,"rtt") == 0)
+                        || (strcasecmp(ext,"rtz") == 0)
+                        || (strcasecmp(ext,"tab") == 0) ) ) {
+                XmListSelectPos(map_list,x,TRUE);
+            }
+            XtFree(temp);
+        }
+    }
+
+    map_chooser_update_quantity();
+}
+
+
+
+
+
+void map_chooser_select_250k_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x, length;
+    char *temp;
+    char *ext;
+    XmString *list;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the list looking for matching file extensions
+    for(x=1; x<=i;x++) {
+
+//        // Deselect all currently selected maps
+//        if (XmListPosSelected(map_list,x)) {
+//            XmListDeselectPos(map_list,x);
+//        }
+
+	temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+        if(temp) {
+            ext = get_map_ext (temp);
+            length = (int)strlen(temp);
+            if ( (ext != NULL) && (strcasecmp (ext, "tif") == 0)
+                    && (length >= 12)   // "o48122h3.tif", we might have subdirectories also
+                    && ( (temp[length - 12] == 'c') || (temp[length - 12] == 'C') ) ) {
+                XmListSelectPos(map_list,x,TRUE);
+            }
+            XtFree(temp);
+        }
+    }
+
+    map_chooser_update_quantity();
+}
+
+
+
+
+
+void map_chooser_select_100k_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x, length;
+    char *temp;
+    char *ext;
+    XmString *list;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the list looking for matching file extensions
+    for(x=1; x<=i;x++) {
+
+//        // Deselect all currently selected maps
+//        if (XmListPosSelected(map_list,x)) {
+//            XmListDeselectPos(map_list,x);
+//        }
+
+	temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+        if(temp) {
+            ext = get_map_ext (temp);
+            length = (int)strlen(temp);
+            if ( (ext != NULL) && (strcasecmp (ext, "tif") == 0)
+                    && (length >= 12)   // "o48122h3.tif", we might have subdirectories also
+                    && ( (temp[length - 12] == 'f') || (temp[length - 12] == 'F') ) ) {
+                XmListSelectPos(map_list,x,TRUE);
+            }
+            XtFree(temp);
+        }
+    }
+
+    map_chooser_update_quantity();
+}
+
+
+
+
+
+void map_chooser_select_24k_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x, length;
+    char *temp;
+    char *ext;
+    XmString *list;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the list looking for matching file extensions
+    for(x=1; x<=i;x++) {
+
+//        // Deselect all currently selected maps
+//        if (XmListPosSelected(map_list,x)) {
+//            XmListDeselectPos(map_list,x);
+//        }
+
+	temp = XmStringUnparse(list[(x-1)], NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+        if(temp) {
+            ext = get_map_ext (temp);
+            length = (int)strlen(temp);
+            if ( (ext != NULL) && (strcasecmp (ext, "tif") == 0)
+                        && (length >= 12)   // "o48122h3.tif", we might have subdirectories also
+                        && ( (temp[length - 12] == 'o') || (temp[length - 12] == 'O')
+                            || (temp[length - 12] == 'k') || (temp[length - 12] == 'K') ) ) {
+                XmListSelectPos(map_list,x,TRUE);
+            }
+            XtFree(temp);
+        }
+    }
+
+    map_chooser_update_quantity();
+}
+
+
+
+
+
+// Removes the highlighting for maps in the current view of the map
+// chooser.  In order to de-select all maps, must flip through both
+// map chooser views and hit the "none" button each time, then hit
+// the "ok" button.
+//
+// Changed the code to clear all of the "selected" bits in the
+// in-memory map index as well.  The "None" and "OK" buttons take
+// immediate effect, all others do not (until the "OK" button is
+// pressed).  Decided that this was too inconsistent, so changed it
+// back and changed "None" to "Clear", which means to clear the
+// currently seen selections, but not the selections in the other
+// mode.
+//
+void map_chooser_deselect_maps(Widget widget, XtPointer clientData, XtPointer callData) {
+    int i, x;
+    XmString *list;
+//    map_index_record *current = map_index_head;
+
+    // Get the list and the count from the dialog
+    XtVaGetValues(map_list,
+               XmNitemCount,&i,
+               XmNitems,&list,
+               NULL);
+
+    // Run through the widget's list, deselecting every line
+    for(x=1; x<=i;x++)
+    {
+        if (XmListPosSelected(map_list,x)) {
+            XmListDeselectPos(map_list,x);
+        }
+    }
+
+/*
+    // Run through the in-memory map list, deselecting every line
+    while (current != NULL) {
+        current->selected = 0;    // Not Selected
+        current = current->next;
+    }
+*/
+
+    map_chooser_update_quantity();
+}
+
+
+
+
+
+void sort_list(char *filename,int size, Widget list, int *item) {
+    FILE *f_data;
+    FILE *f_pointer;
+    char fill[2000];
+    long file_ptr;
+    long ptr;
+    char ptr_filename[400];
+    XmString str_ptr;
+
+    // Clear the list widget first
+    XmListDeleteAllItems(list);
+
+    xastir_snprintf(ptr_filename, sizeof(ptr_filename), "%s-ptr", filename);
+    f_pointer=fopen(ptr_filename,"r");
+    f_data=fopen(filename,"r");
+    if (f_pointer!=NULL && f_data !=NULL) {
+        while (!feof(f_pointer)) {
+            ptr=ftell(f_pointer);
+            if (fread(&file_ptr,sizeof(file_ptr),1,f_pointer)==1) {
+                (void)fseek(f_data,file_ptr,SEEK_SET);
+                if (fread(fill,(size_t)size,1,f_data)==1) {
+		    str_ptr = XmStringCreateLocalized(fill);
+                    XmListAddItem(list, str_ptr,*item);
+                    XmStringFree(str_ptr);
+                    (*item)++;
+                }
+            }
+        }
+    }
+    if(f_pointer!=NULL)
+        (void)fclose(f_pointer);
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", ptr_filename);
+
+
+    if(f_data!=NULL)
+        (void)fclose(f_data);
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", filename);
+}
+
+
+
+
+
+// Mark the "selected" field in the in-memory map index based on the
+// contents of the selected_maps.sys file.  Called from main() right
+// after map_indexer() is called on startup.
+void map_chooser_init (void) {
+    FILE *f;
+    char temp[600];
+    map_index_record *current;
+    char selected_map_path[MAX_VALUE];
+
+    get_user_base_dir(SELECTED_MAP_DATA, selected_map_path, 
+                      sizeof(selected_map_path));
+
+
+    busy_cursor(appshell);
+
+    // First run through our in-memory map index, clearing all of
+    // the selected bits.
+    current = map_index_head;
+    while (current != NULL) {
+        current->selected = 0;
+        current = current->next;
+    }
+
+    (void)filecreate( selected_map_path );   // Create empty file if it doesn't exist
+
+    f=fopen( selected_map_path, "r" );
+    if (f!=NULL) {
+        while(!feof(f)) {
+            int done;
+
+            (void)get_line(f,temp,600);
+
+            // We have a line from the file.  Find the matching line
+            // in the in-memory map index.
+            current = map_index_head;
+            done = 0;
+            while (current != NULL && !done) {
+                //fprintf(stderr,"%s\n",current->filename);
+
+                if (strcmp(temp,current->filename) == 0) {
+                    current->selected = 1;
+                    done++;
+                }
+                current = current->next;
+            }
+        }
+        (void)fclose(f);
+    }
+    else {
+        fprintf(stderr,"Couldn't open file: %s\n", selected_map_path );
+    }
+}
+
+
+
+
+
+// Fills in the map chooser file/directory entries based on the
+// current view and whether the "selected" field in the in-memory
+// map_index is set for each file/directory.
+//
+// We also check the XmStringPtr field in the map index records.  If
+// NULL, then we call XmStringCreateLocalized() to allocate and fill in
+// the XmString value corresponding to the filename.  We use that to
+// speed up Map Chooser later.
+//
+void map_chooser_fill_in (void) {
+    int n,i;
+    map_index_record *current = map_index_head;
+
+
+    busy_cursor(appshell);
+
+    i=0;
+    if (map_chooser_dialog) {
+
+        // Empty the map_list widget first
+        XmListDeleteAllItems(map_list);
+
+        // Put all the map files/dirs in the map_index into the Map
+        // Chooser dialog list (map_list).
+        n=1;
+
+        while (current != NULL) {
+
+            //fprintf(stderr,"%s\n",current->filename);
+
+            // Check whether we're supposed to show dirs and files or
+            // just dirs.  Directories are always shown.
+            if (map_chooser_expand_dirs // Show all
+                    || current->filename[strlen(current->filename)-1] == '/') {
+
+
+// Try XmListAddItems() here?  Could also create XmString's for each
+// filename and keep them in the map index.  Then we wouldn't have to
+// free that malloc/free that storage space all the time.
+// XmListAddItems()
+// XmListAddItemsUnselected()
+// XmListReplaceItems()
+// XmListReplaceItemsUnselected()
+
+
+                // If pointer is NULL, malloc and create the
+                // XmString corresponding to the filename, attach it
+                // to the record.  The 2nd and succeeding times we
+                // bring up Map Chooser, things will be faster.
+                if (current->XmStringPtr == NULL) {
+                    current->XmStringPtr = XmStringCreateLocalized(current->filename);
+                }
+
+                XmListAddItem(map_list,
+                    current->XmStringPtr,
+                    n);
+
+                // If a selected map, hilight it in the list
+                if (current->selected) {
+                    XmListSelectPos(map_list,i,TRUE);
+                }
+ 
+                n++;
+            }
+            current = current->next;
+        }
+    }
+}
+
+
+
+
+
+///////////////////////////////////////  Configure Tigermaps Dialog //////////////////////////////////////////////
+//N0VH
+#if defined(HAVE_MAGICK)
+
+
+
+void Configure_tiger_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    configure_tiger_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Configure_tiger_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if(XmToggleButtonGetState(tiger_grid))
+        tiger_show_grid=TRUE;
+    else
+        tiger_show_grid=FALSE;
+
+    if(XmToggleButtonGetState(tiger_counties))
+        tiger_show_counties=TRUE;
+    else
+        tiger_show_counties=FALSE;
+
+    if(XmToggleButtonGetState(tiger_cities))
+        tiger_show_cities=TRUE;
+    else
+        tiger_show_cities=FALSE;
+
+    if(XmToggleButtonGetState(tiger_places))
+        tiger_show_places=TRUE;
+    else
+        tiger_show_places=FALSE;
+
+    if(XmToggleButtonGetState(tiger_majroads))
+        tiger_show_majroads=TRUE;
+    else
+        tiger_show_majroads=FALSE;
+
+    if(XmToggleButtonGetState(tiger_streets))
+        tiger_show_streets=TRUE;
+    else
+        tiger_show_streets=FALSE;
+
+    if(XmToggleButtonGetState(tiger_railroad))
+        tiger_show_railroad=TRUE;
+    else
+        tiger_show_railroad=FALSE;
+
+    if(XmToggleButtonGetState(tiger_water))
+        tiger_show_water=TRUE;
+    else
+        tiger_show_water=FALSE;
+
+    if(XmToggleButtonGetState(tiger_lakes))
+        tiger_show_lakes=TRUE;
+    else
+        tiger_show_lakes=FALSE;
+
+    if(XmToggleButtonGetState(tiger_misc))
+        tiger_show_misc=TRUE;
+    else
+        tiger_show_misc=FALSE;
+
+    if(XmToggleButtonGetState(tiger_states))
+        tiger_show_states=TRUE;
+    else
+        tiger_show_states=FALSE;
+
+    if(XmToggleButtonGetState(tiger_interstate))
+        tiger_show_interstate=TRUE;
+    else
+        tiger_show_interstate=FALSE;
+
+    if(XmToggleButtonGetState(tiger_ushwy))
+        tiger_show_ushwy=TRUE;
+    else
+        tiger_show_ushwy=FALSE;
+
+    if(XmToggleButtonGetState(tiger_statehwy))
+        tiger_show_statehwy=TRUE;
+    else
+        tiger_show_statehwy=FALSE;
+
+    Configure_tiger_destroy_shell(widget,clientData,callData);
+
+    // Reload maps
+    // Set interrupt_drawing_now because conditions have
+    // changed.
+    interrupt_drawing_now++;
+
+    // Request that a new image be created.  Calls
+    // create_image,
+    // XCopyArea, and display_zoom_status.
+    request_new_image++;
+
+//    if (create_image(da)) {
+//        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+//    }
+}
+
+
+
+
+
+////////////////////////////////////////////// Config_tiger//////////////////////////////////////////////////////
+//
+//
+void Config_tiger( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget tiger_pane, tiger_form, button_ok, button_cancel, tiger_label1, sep;
+
+    Atom delw;
+
+    if (!configure_tiger_dialog) {
+
+        configure_tiger_dialog = XtVaCreatePopupShell(langcode("PULDNMP020"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_pane = XtVaCreateWidget("Configure_tiger pane",
+                xmPanedWindowWidgetClass, 
+                configure_tiger_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        tiger_form =  XtVaCreateWidget("Configure_tiger tiger_form",
+                xmFormWidgetClass, 
+                tiger_pane,
+                XmNfractionBase, 3,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        tiger_label1  = XtVaCreateManagedWidget(langcode("MPUPTGR012"),
+                xmLabelWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_grid  = XtVaCreateManagedWidget(langcode("MPUPTGR001"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_label1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_counties  = XtVaCreateManagedWidget(langcode("MPUPTGR002"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_label1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_states  = XtVaCreateManagedWidget(langcode("MPUPTGR008"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_label1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_cities  = XtVaCreateManagedWidget(langcode("MPUPTGR003"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_grid,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_places  = XtVaCreateManagedWidget(langcode("MPUPTGR004"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_grid,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_interstate  = XtVaCreateManagedWidget(langcode("MPUPTGR009"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_grid,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_majroads  = XtVaCreateManagedWidget(langcode("MPUPTGR005"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_cities,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_streets  = XtVaCreateManagedWidget(langcode("MPUPTGR006"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_cities,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_ushwy  = XtVaCreateManagedWidget(langcode("MPUPTGR010"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_cities,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_railroad  = XtVaCreateManagedWidget(langcode("MPUPTGR007"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_majroads,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_water  = XtVaCreateManagedWidget(langcode("MPUPTGR013"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_majroads,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        tiger_statehwy  = XtVaCreateManagedWidget(langcode("MPUPTGR011"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_majroads,
+                XmNtopOffset, 4,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+       tiger_lakes  = XtVaCreateManagedWidget(langcode("MPUPTGR014"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_railroad,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+       tiger_misc  = XtVaCreateManagedWidget(langcode("MPUPTGR015"),
+                xmToggleButtonWidgetClass,
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, tiger_railroad,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sep = XtVaCreateManagedWidget("Config Tigermap sep", 
+                xmSeparatorGadgetClass,
+                tiger_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, tiger_lakes,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 0,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                tiger_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNleftOffset, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_tiger_change_data, configure_tiger_dialog);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_tiger_destroy_shell, configure_tiger_dialog);
+
+        pos_dialog(configure_tiger_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_tiger_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(configure_tiger_dialog, delw, Configure_tiger_destroy_shell,
+                (XtPointer)configure_tiger_dialog);
+
+        if(tiger_show_grid)
+            XmToggleButtonSetState(tiger_grid,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_grid,FALSE,FALSE);
+
+        if(tiger_show_counties)
+            XmToggleButtonSetState(tiger_counties,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_counties,FALSE,FALSE);
+
+        if(tiger_show_cities)
+            XmToggleButtonSetState(tiger_cities,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_cities,FALSE,FALSE);
+
+        if(tiger_show_places)
+            XmToggleButtonSetState(tiger_places,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_places,FALSE,FALSE);
+
+        if(tiger_show_majroads)
+            XmToggleButtonSetState(tiger_majroads,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_majroads,FALSE,FALSE);
+
+        if(tiger_show_streets)
+            XmToggleButtonSetState(tiger_streets,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_streets,FALSE,FALSE);
+
+        if(tiger_show_railroad)
+            XmToggleButtonSetState(tiger_railroad,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_railroad,FALSE,FALSE);
+
+        if(tiger_show_water)
+            XmToggleButtonSetState(tiger_water,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_water,FALSE,FALSE);
+
+        if(tiger_show_lakes)
+            XmToggleButtonSetState(tiger_lakes,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_lakes,FALSE,FALSE);
+
+        if(tiger_show_misc)
+            XmToggleButtonSetState(tiger_misc,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_misc,FALSE,FALSE);
+
+        if(tiger_show_states)
+            XmToggleButtonSetState(tiger_states,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_states,FALSE,FALSE);
+
+        if(tiger_show_interstate)
+            XmToggleButtonSetState(tiger_interstate,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_interstate,FALSE,FALSE);
+
+        if(tiger_show_ushwy)
+            XmToggleButtonSetState(tiger_ushwy,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_ushwy,FALSE,FALSE);
+
+        if(tiger_show_statehwy)
+            XmToggleButtonSetState(tiger_statehwy,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(tiger_statehwy,FALSE,FALSE);
+
+        XtManageChild(tiger_form);
+        XtManageChild(tiger_pane);
+
+        XtPopup(configure_tiger_dialog,XtGrabNone);
+        fix_dialog_size(configure_tiger_dialog);
+
+        XmProcessTraversal(button_ok, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_tiger_dialog), XtWindow(configure_tiger_dialog));
+}
+#endif // HAVE_MAGICK
+///////////////////////// End of Configure Tiger code ///////////////////////////////////
+
+
+
+
+
+///////////////////////////////////////  Configure DRG Dialog //////////////////////////////////////////////
+#if defined(HAVE_LIBGEOTIFF)
+void Configure_DRG_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+    if (configure_DRG_dialog) {
+        XtPopdown(shell);
+        XtDestroyWidget(shell);
+        configure_DRG_dialog = (Widget)NULL;
+    }
+}
+
+
+
+
+
+void Configure_DRG_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if (configure_DRG_dialog) {
+ 
+        if(XmToggleButtonGetState(DRG_XOR))
+            DRG_XOR_colors=TRUE;
+        else
+            DRG_XOR_colors=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color0))
+            DRG_show_colors[0]=TRUE;
+        else
+            DRG_show_colors[0]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color1))
+            DRG_show_colors[1]=TRUE;
+        else
+            DRG_show_colors[1]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color2))
+            DRG_show_colors[2]=TRUE;
+        else
+            DRG_show_colors[2]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color3))
+            DRG_show_colors[3]=TRUE;
+        else
+            DRG_show_colors[3]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color4))
+            DRG_show_colors[4]=TRUE;
+        else
+            DRG_show_colors[4]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color5))
+            DRG_show_colors[5]=TRUE;
+        else
+            DRG_show_colors[5]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color6))
+            DRG_show_colors[6]=TRUE;
+        else
+            DRG_show_colors[6]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color7))
+            DRG_show_colors[7]=TRUE;
+        else
+            DRG_show_colors[7]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color8))
+            DRG_show_colors[8]=TRUE;
+        else
+            DRG_show_colors[8]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color9))
+            DRG_show_colors[9]=TRUE;
+        else
+            DRG_show_colors[9]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color10))
+            DRG_show_colors[10]=TRUE;
+        else
+            DRG_show_colors[10]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color11))
+            DRG_show_colors[11]=TRUE;
+        else
+            DRG_show_colors[11]=FALSE;
+
+        if(XmToggleButtonGetState(DRG_color12))
+            DRG_show_colors[12]=TRUE;
+        else
+            DRG_show_colors[12]=FALSE;
+
+        Configure_DRG_destroy_shell(widget,clientData,callData);
+
+        // Reload maps
+        // Set interrupt_drawing_now because conditions have
+        // changed.
+        interrupt_drawing_now++;
+
+        // Request that a new image be created.  Calls
+        // create_image,
+        // XCopyArea, and display_zoom_status.
+        request_new_image++;
+
+    //    if (create_image(da)) {
+    //        (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+    //    }
+
+    }
+}
+
+
+
+
+
+void Configure_DRG_all(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if (configure_DRG_dialog) {
+        XmToggleButtonSetState(DRG_color0,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color1,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color2,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color3,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color4,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color5,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color6,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color7,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color8,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color9,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color10,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color11,TRUE,FALSE);
+        XmToggleButtonSetState(DRG_color12,TRUE,FALSE);
+    }
+}
+
+
+
+
+
+void Configure_DRG_none(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if (configure_DRG_dialog) {
+        XmToggleButtonSetState(DRG_color0,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color1,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color2,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color3,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color4,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color5,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color6,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color7,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color8,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color9,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color10,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color11,FALSE,FALSE);
+        XmToggleButtonSetState(DRG_color12,FALSE,FALSE);
+    }
+}
+
+
+
+
+
+void Config_DRG( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget DRG_pane, DRG_form, button_ok, button_cancel,
+        DRG_label1, sep1, sep2, button_all, button_none;
+
+    Atom delw;
+
+    if (!configure_DRG_dialog) {
+
+        configure_DRG_dialog = XtVaCreatePopupShell(langcode("PULDNMP030"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        DRG_pane = XtVaCreateWidget("Configure_DRG pane",
+                xmPanedWindowWidgetClass, 
+                configure_DRG_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        DRG_form =  XtVaCreateWidget("Configure_DRG DRG_form",
+                xmFormWidgetClass, 
+                DRG_pane,
+                XmNfractionBase, 3,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        DRG_XOR  = XtVaCreateManagedWidget(langcode("MPUPDRG002"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sep1 = XtVaCreateManagedWidget("Config Tigermap sep1", 
+                xmSeparatorGadgetClass,
+                DRG_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, DRG_XOR,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        DRG_label1  = XtVaCreateManagedWidget(langcode("MPUPDRG001"),
+                xmLabelWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+// Column 1
+        // Black
+        DRG_color0  = XtVaCreateManagedWidget(langcode("MPUPDRG003"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_label1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Blue
+        DRG_color2  = XtVaCreateManagedWidget(langcode("MPUPDRG005"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color0,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Red
+        DRG_color3  = XtVaCreateManagedWidget(langcode("MPUPDRG006"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color2,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Brown
+        DRG_color4  = XtVaCreateManagedWidget(langcode("MPUPDRG007"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color3,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Purple
+        DRG_color6  = XtVaCreateManagedWidget(langcode("MPUPDRG009"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color4,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Column 2
+         // Light Gray
+        DRG_color11  = XtVaCreateManagedWidget(langcode("MPUPDRG014"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_label1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Light Blue
+        DRG_color8  = XtVaCreateManagedWidget(langcode("MPUPDRG011"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color11,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Light Red
+        DRG_color9  = XtVaCreateManagedWidget(langcode("MPUPDRG012"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color8,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Light Brown
+        DRG_color12  = XtVaCreateManagedWidget(langcode("MPUPDRG015"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color9,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Light Purple
+        DRG_color10  = XtVaCreateManagedWidget(langcode("MPUPDRG013"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color12,
+                XmNtopOffset, 4,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Column 3
+        // White
+        DRG_color1  = XtVaCreateManagedWidget(langcode("MPUPDRG004"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_label1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Green
+        DRG_color5  = XtVaCreateManagedWidget(langcode("MPUPDRG008"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color1,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Yellow
+        DRG_color7  = XtVaCreateManagedWidget(langcode("MPUPDRG010"),
+                xmToggleButtonWidgetClass,
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color5,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sep2 = XtVaCreateManagedWidget("Config Tigermap sep2", 
+                xmSeparatorGadgetClass,
+                DRG_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, DRG_color6,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_all = XtVaCreateManagedWidget(langcode("PULDNMMC09"),
+                xmPushButtonGadgetClass, 
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep2,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_none = XtVaCreateManagedWidget(langcode("PULDNDP040"),
+                xmPushButtonGadgetClass, 
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep2,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, button_all,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep2,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, button_none,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                DRG_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep2,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, button_ok,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_all,
+            XmNactivateCallback,
+            Configure_DRG_all,
+            configure_DRG_dialog);
+
+        XtAddCallback(button_none,
+            XmNactivateCallback,
+            Configure_DRG_none,
+            configure_DRG_dialog);
+
+        XtAddCallback(button_ok,
+            XmNactivateCallback,
+            Configure_DRG_change_data,
+            configure_DRG_dialog);
+
+        XtAddCallback(button_cancel,
+            XmNactivateCallback,
+            Configure_DRG_destroy_shell,
+            configure_DRG_dialog);
+
+        pos_dialog(configure_DRG_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_DRG_dialog),
+            "WM_DELETE_WINDOW",
+            FALSE);
+        XmAddWMProtocolCallback(configure_DRG_dialog,
+            delw,
+            Configure_DRG_destroy_shell,
+            (XtPointer)configure_DRG_dialog);
+
+        if(DRG_XOR_colors)
+            XmToggleButtonSetState(DRG_XOR,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_XOR,FALSE,FALSE);
+
+        if(DRG_show_colors[0])
+            XmToggleButtonSetState(DRG_color0,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color0,FALSE,FALSE);
+
+        if(DRG_show_colors[1])
+            XmToggleButtonSetState(DRG_color1,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color1,FALSE,FALSE);
+
+        if(DRG_show_colors[2])
+            XmToggleButtonSetState(DRG_color2,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color2,FALSE,FALSE);
+
+        if(DRG_show_colors[3])
+            XmToggleButtonSetState(DRG_color3,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color3,FALSE,FALSE);
+
+        if(DRG_show_colors[4])
+            XmToggleButtonSetState(DRG_color4,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color4,FALSE,FALSE);
+
+        if(DRG_show_colors[5])
+            XmToggleButtonSetState(DRG_color5,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color5,FALSE,FALSE);
+
+        if(DRG_show_colors[6])
+            XmToggleButtonSetState(DRG_color6,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color6,FALSE,FALSE);
+
+        if(DRG_show_colors[7])
+            XmToggleButtonSetState(DRG_color7,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color7,FALSE,FALSE);
+
+        if(DRG_show_colors[8])
+            XmToggleButtonSetState(DRG_color8,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color8,FALSE,FALSE);
+
+        if(DRG_show_colors[9])
+            XmToggleButtonSetState(DRG_color9,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color9,FALSE,FALSE);
+
+        if(DRG_show_colors[10])
+            XmToggleButtonSetState(DRG_color10,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color10,FALSE,FALSE);
+
+        if(DRG_show_colors[11])
+            XmToggleButtonSetState(DRG_color11,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color11,FALSE,FALSE);
+
+        if(DRG_show_colors[12])
+            XmToggleButtonSetState(DRG_color12,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(DRG_color12,FALSE,FALSE);
+
+        XtManageChild(DRG_form);
+        XtManageChild(DRG_pane);
+
+        XtPopup(configure_DRG_dialog,XtGrabNone);
+        fix_dialog_size(configure_DRG_dialog);
+
+        XmProcessTraversal(button_ok, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_DRG_dialog),
+            XtWindow(configure_DRG_dialog));
+}
+#endif // HAVE_LIBGEOTIFF
+///////////////////////// End of Configure DRG code ///////////////////////////////////
+
+
+
+
+
+void Expand_Dirs_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        map_chooser_expand_dirs = atoi(which);
+    else
+        map_chooser_expand_dirs = 0;
+
+    // Kill/resurrect the Map Chooser so that the changes take
+    // effect.
+    map_chooser_destroy_shell( w, map_chooser_dialog, (XtPointer) NULL);
+    Map_chooser( w, (XtPointer)NULL, (XtPointer) NULL);
+
+    map_chooser_update_quantity();
+}
+
+
+
+
+
+void Map_chooser( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_clear, button_V,
+            button_C, button_F, button_O,
+            rowcol, expand_dirs_button, button_properties,
+            maps_selected_label, button_apply;
+    Atom delw;
+    int i;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+
+    busy_cursor(appshell);
+
+    i=0;
+    if (!map_chooser_dialog) {
+        map_chooser_dialog = XtVaCreatePopupShell(langcode("WPUPMCP001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Map_chooser pane",
+                xmPanedWindowWidgetClass, 
+                map_chooser_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Map_chooser my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 7,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNvisibleItemCount, 13); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmMULTIPLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        map_list = XmCreateScrolledList(my_form,
+                "Map_chooser list",
+                al,
+                ac);
+
+        // Find the names of all the map files on disk and put them into map_list
+        map_chooser_fill_in();
+
+        expand_dirs_button = XtVaCreateManagedWidget(langcode("PULDNMMC06"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNsensitive, TRUE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(expand_dirs_button,XmNvalueChangedCallback,Expand_Dirs_toggle,"1");
+        if(map_chooser_expand_dirs)
+            XmToggleButtonSetState(expand_dirs_button,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(expand_dirs_button,FALSE,FALSE);
+
+        maps_selected_label = XtVaCreateManagedWidget(langcode("PULDNMMC07"),
+                xmLabelWidgetClass,
+                my_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              expand_dirs_button,
+                XmNleftOffset,              15,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        map_chooser_maps_selected_data = XtVaCreateManagedWidget("0/0",
+                xmLabelWidgetClass,
+                my_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              maps_selected_label,
+                XmNleftOffset,              2,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Button for configuring properties
+        button_properties = XtVaCreateManagedWidget(langcode("UNIOP00009"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_NONE,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNsensitive, TRUE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_properties, XmNactivateCallback, map_properties, map_chooser_dialog);
+ 
+        // Attach a rowcolumn manager widget to my_form to handle all of the buttons
+        rowcol = XtVaCreateManagedWidget("Map Chooser rowcol", 
+                xmRowColumnWidgetClass, 
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNkeyboardFocusPolicy, XmEXPLICIT,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtVaSetValues(XtParent(map_list),
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, expand_dirs_button,
+                XmNtopOffset, 2,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, rowcol,
+                XmNbottomOffset, 2,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Clear"
+        if(map_chooser_expand_dirs) {   // "Clear"
+            button_clear = XtVaCreateManagedWidget(langcode("PULDNMMC01"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        }
+        else {  // "Clear Dirs"
+            button_clear = XtVaCreateManagedWidget(langcode("PULDNMMC08"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        }
+
+
+// "Vector Maps"
+        button_V = XtVaCreateManagedWidget(langcode("PULDNMMC02"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "250k Topos"
+        button_C = XtVaCreateManagedWidget(langcode("PULDNMMC03"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+#ifndef HAVE_LIBGEOTIFF
+                XmNsensitive, FALSE,
+#endif /* HAVE_LIBGEOTIFF */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "100k Topos"
+        button_F = XtVaCreateManagedWidget(langcode("PULDNMMC04"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+#ifndef HAVE_LIBGEOTIFF
+                XmNsensitive, FALSE,
+#endif /* HAVE_LIBGEOTIFF */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "24k Topos"
+        button_O = XtVaCreateManagedWidget(langcode("PULDNMMC05"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+#ifndef HAVE_LIBGEOTIFF
+                XmNsensitive, FALSE,
+#endif /* HAVE_LIBGEOTIFF */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Apply"
+        button_apply = XtVaCreateManagedWidget(langcode("UNIOP00032"),
+                xmPushButtonGadgetClass,
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "OK"
+        map_chooser_button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// "Cancel"
+        map_chooser_button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                rowcol,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_apply, XmNactivateCallback, map_chooser_apply_maps, map_chooser_dialog);
+        XtAddCallback(map_chooser_button_cancel, XmNactivateCallback, map_chooser_destroy_shell, map_chooser_dialog);
+        XtAddCallback(map_chooser_button_ok, XmNactivateCallback, map_chooser_select_maps, map_chooser_dialog);
+        XtAddCallback(button_clear, XmNactivateCallback, map_chooser_deselect_maps, map_chooser_dialog);
+        XtAddCallback(button_V, XmNactivateCallback, map_chooser_select_vector_maps, map_chooser_dialog);
+#ifdef HAVE_LIBGEOTIFF
+        XtAddCallback(button_C, XmNactivateCallback, map_chooser_select_250k_maps, map_chooser_dialog);
+        XtAddCallback(button_F, XmNactivateCallback, map_chooser_select_100k_maps, map_chooser_dialog);
+        XtAddCallback(button_O, XmNactivateCallback, map_chooser_select_24k_maps, map_chooser_dialog);
+#endif /* HAVE_LIBGEOTIFF */
+
+        if(!map_chooser_expand_dirs) {
+            XtSetSensitive(button_V, FALSE);
+            XtSetSensitive(button_C, FALSE);
+            XtSetSensitive(button_F, FALSE);
+            XtSetSensitive(button_O, FALSE);
+        }
+ 
+        pos_dialog(map_chooser_dialog);
+
+        delw = XmInternAtom(XtDisplay(map_chooser_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(map_chooser_dialog, delw, map_chooser_destroy_shell, (XtPointer)map_chooser_dialog);
+
+        XtManageChild(rowcol);
+        XtManageChild(my_form);
+        XtManageChild(map_list);
+        XtVaSetValues(map_list, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(pane);
+
+        XtPopup(map_chooser_dialog,XtGrabNone);
+
+        // Fix the dialog height only, allow the width to vary.
+//        fix_dialog_vsize(map_chooser_dialog);
+
+        // Move focus to the OK button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(map_chooser_dialog);
+        XmProcessTraversal(map_chooser_button_ok, XmTRAVERSE_CURRENT);
+
+   } else {
+        (void)XRaiseWindow(XtDisplay(map_chooser_dialog), XtWindow(map_chooser_dialog));
+    }
+
+   map_chooser_update_quantity();
+}
+
+
+
+
+
+/****** Read in file **********/
+
+void read_file_selection_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtDestroyWidget(shell);
+    read_selection_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void read_file_selection_now(Widget w, XtPointer clientData, XtPointer callData) {
+    char *file;
+    XmFileSelectionBoxCallbackStruct *cbs =(XmFileSelectionBoxCallbackStruct*)callData;
+
+    file = XmStringUnparse(cbs->value, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_BEGINNING);
+    if(file) {
+        // fprintf(stderr,"FILE is %s\n",file);
+
+        // Make sure we're not already reading a file and the user actually
+        // selected a file (if not, the last character will be a '/').
+        if ( (!read_file) && (file[strlen(file) - 1] != '/') ) {
+
+            /* do read file start */
+            read_file_ptr = fopen(file,"r");
+            if (read_file_ptr != NULL)
+                read_file = 1;
+            else
+                fprintf(stderr,"Couldn't open file: %s\n", file);
+
+        }
+        XtFree(file);
+    }
+    read_file_selection_destroy_shell(w, clientData, callData);
+
+    // Note that we leave the file in the "open" state.  UpdateTime
+    // comes along shortly and reads the file.
+}
+
+
+
+
+
+void Read_File_Selection( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+    Widget fs;
+    Widget child;
+    char temp_base_dir[MAX_VALUE];
+
+    if (read_selection_dialog!=NULL)
+        read_file_selection_destroy_shell(read_selection_dialog, read_selection_dialog, NULL);
+
+    if(read_selection_dialog==NULL) {
+
+        // This is necessary because the resources for setting the
+        // directory in the FileSelectionDialog aren't working in Lesstif.
+        chdir( get_user_base_dir("logs", temp_base_dir, sizeof(temp_base_dir)) );
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNtitle, langcode("PULDNFI002")); ac++;  // Open Log File
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+        //XtSetArg(al[ac], XmNdirMask, "/home/hacker/.xastir/logs/*"); ac++;
+        //XtSetArg(al[ac], XmNdirectory, "/home/hacker/.xastir/logs/"); ac++;
+        //XtSetArg(al[ac], XmNpattern, "*"); ac++;
+        //XtSetArg(al[ac], XmNdirMask, ".xastir/logs/*"); ac++;
+        read_selection_dialog = XmCreateFileSelectionDialog(appshell,
+                "filesb",
+                al,
+                ac);
+
+        // Change back to the base directory 
+        chdir( get_user_base_dir("", temp_base_dir, sizeof(temp_base_dir)) );
+
+        fs=XmFileSelectionBoxGetChild(read_selection_dialog,(unsigned char)XmDIALOG_TEXT);
+        XtVaSetValues(fs,XmNbackground, colors[0x0f],NULL);
+        XtVaSetValues(fs,XmNfontList,fontlist1,NULL);
+
+        fs=XmFileSelectionBoxGetChild(read_selection_dialog,(unsigned char)XmDIALOG_FILTER_TEXT);
+        XtVaSetValues(fs,XmNbackground, colors[0x0f],NULL);
+        XtVaSetValues(fs,XmNfontList,fontlist1,NULL);
+
+        fs=XmFileSelectionBoxGetChild(read_selection_dialog,(unsigned char)XmDIALOG_DIR_LIST);
+        XtVaSetValues(fs,XmNbackground, colors[0x0f],NULL);
+        XtVaSetValues(fs,XmNfontList,fontlist1,NULL);
+
+        fs=XmFileSelectionBoxGetChild(read_selection_dialog,(unsigned char)XmDIALOG_LIST);
+        XtVaSetValues(fs,XmNbackground, colors[0x0f],NULL);
+        XtVaSetValues(fs,XmNfontList,fontlist1,NULL);
+
+        //XtVaSetValues(read_selection_dialog, XmNdirMask, "/home/hacker/.xastir/logs/*", NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_FILTER_LABEL);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_DIR_LIST_LABEL);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_LIST_LABEL);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_SELECTION_LABEL);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_OK_BUTTON);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_APPLY_BUTTON);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_CANCEL_BUTTON);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        child = XmFileSelectionBoxGetChild(read_selection_dialog, XmDIALOG_HELP_BUTTON);
+        XtVaSetValues(child,XmNfontList,fontlist1,NULL);
+
+        XtAddCallback(read_selection_dialog, XmNcancelCallback,read_file_selection_destroy_shell,read_selection_dialog);
+        XtAddCallback(read_selection_dialog, XmNokCallback,read_file_selection_now,read_selection_dialog);
+
+        XtAddCallback(read_selection_dialog, XmNhelpCallback, Help_Index, read_selection_dialog);
+
+        XtManageChild(read_selection_dialog);
+        pos_dialog(read_selection_dialog);
+    }
+}
+
+
+
+
+
+void Test(Widget w, XtPointer clientData, XtPointer callData) {
+//    static char temp[256];
+//    int port = 7;
+
+
+    mdisplay_file(0);
+//    mem_display();
+    alert_print_list();
+
+/*
+    draw_wind_barb(50000000l,   // long x_long,
+        32000000l,              // long y_lat,
+        "169",                  // char *speed,
+        "005",                  // char *course,
+        sec_now(),              // time_t sec_heard,
+        pixmap_final);          // Pixmap where);
+
+    draw_wind_barb(60000000l,   // long x_long,
+        32000000l,              // long y_lat,
+        "009",                  // char *speed,
+        "123",                  // char *course,
+        sec_now(),              // time_t sec_heard,
+        pixmap_final);          // Pixmap where);
+
+    draw_wind_barb(70000000l,   // long x_long,
+        32000000l,              // long y_lat,
+        "109",                  // char *speed,
+        "185",                  // char *course,
+        sec_now(),              // time_t sec_heard,
+        pixmap_final);          // Pixmap where);
+
+    draw_wind_barb(80000000l,   // long x_long,
+        32000000l,              // long y_lat,
+        "079",                  // char *speed,
+        "275",                  // char *course,
+        sec_now(),              // time_t sec_heard,
+        pixmap_final);          // Pixmap where);
+*/
+
+//    fprintf(stderr,"view_zero_distance_bulletins = %d\n",
+//        view_zero_distance_bulletins);
+
+
+/*
+    // Simulate data coming in from a TNC in order to test igating.
+    // Port 7 in this case is a serial TNC port (in my current test
+    // configuration).
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "WE7U-4>APOT01,SUMAS*,WIDE2-2:!4757.28N/12212.00Wv178/057/A=000208 14.0V 30C\r");
+
+    if (begin_critical_section(&data_lock, "main.c" ) > 0)
+        fprintf(stderr,"data_lock, Port = %d\n", port);
+
+    incoming_data=temp;
+    incoming_data_length = strlen(temp);
+    data_port = port;
+    data_avail = 1;
+
+    if (end_critical_section(&data_lock, "main.c" ) > 0)
+        fprintf(stderr,"data_lock, Port = %d\n", port);
+
+    fprintf(stderr, "Sent: %s\n", temp);
+*/
+
+
+//    (void)XCopyArea(XtDisplay(da),pixmap_final,XtWindow(da),gc,0,0,(unsigned int)screen_width,(unsigned int)screen_height,0,0);
+}
+
+
+
+
+
+/****** Save Config data **********/
+
+void Save_Config( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    save_data();
+}
+
+
+
+
+
+///////////////////////////////////   Configure Defaults Dialog   //////////////////////////////////
+
+
+void Configure_defaults_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    configure_defaults_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Configure_defaults_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp;
+    int load_predefined_cb_selected;
+    XmString load_predefined_cb_selection;
+
+
+    output_station_type = Station_transmit_type;
+    if ((output_station_type >= 1) && (output_station_type <= 3)) {
+        next_time = 60;
+        max_transmit_time = (time_t)120l;       // shorter beacon interval for mobile stations
+    }
+    else {
+        max_transmit_time = (time_t)900l;
+    }
+
+    // Check for proper symbol in case we're a weather station
+    (void)check_weather_symbol();
+
+    // Check for NWS symbol and print warning if so
+    (void)check_nws_weather_symbol();
+
+#ifdef TRANSMIT_RAW_WX
+    transmit_raw_wx = (int)XmToggleButtonGetState(raw_wx_tx);
+#endif  // TRANSMIT_RAW_WX
+
+    transmit_compressed_objects_items = (int)XmToggleButtonGetState(compressed_objects_items_tx);
+
+    pop_up_new_bulletins = (int)XmToggleButtonGetState(new_bulletin_popup_enable);
+    view_zero_distance_bulletins = (int)XmToggleButtonGetState(zero_bulletin_popup_enable);
+
+    // user interface refers to all my trails in one color
+    // my trail diff color as 0 means my trails in one color, so select
+    // button when my trail diff color is 0 rather than 1.
+    my_trail_diff_color = !(int)XmToggleButtonGetState(my_trail_diff_color_enable);
+
+    // Predefined (SAR/EVENT) objects menu loading (default hardcoded SAR objects or objects from file)
+    predefined_menu_from_file = (int)XmToggleButtonGetState(load_predefined_objects_menu_from_file_enable);
+
+    // Use the file specified on the picklist if one is selected.
+    load_predefined_cb_selected = 0;
+#ifdef USE_COMBO_BOX
+    XtVaGetValues(load_predefined_objects_menu_from_file, 
+        XmNselectedPosition,
+        &load_predefined_cb_selected,
+        NULL);
+#else
+    load_predefined_cb_selected = lpomff_value;
+#endif //USE_COMBO_BOX
+
+    // Use the file specified on the picklist if one is selected.
+    if (load_predefined_cb_selected > 0) {
+
+        // XtVaGetValues() expects to be able to write into
+        // allocated memory.
+        //
+        load_predefined_cb_selection = (XmString)malloc(MAX_FILENAME);
+
+#ifdef USE_COMBO_BOX
+        XtVaGetValues(load_predefined_objects_menu_from_file, 
+            XmNselectedItem,
+            &load_predefined_cb_selection,
+            NULL);
+#else
+        switch (load_predefined_cb_selected) { 
+           case 1:
+               load_predefined_cb_selection = XmStringCreateLocalized("predefined_SAR.sys");
+              break;
+           case 2:
+               load_predefined_cb_selection = XmStringCreateLocalized("predefined_EVENT.sys");
+               break;
+           case 3:
+               load_predefined_cb_selection = XmStringCreateLocalized("predefined_USER.sys");
+               break;
+           case 4:
+               load_predefined_cb_selection = XmStringCreateLocalized(predefined_object_definition_filename);
+               break;
+           default:
+               load_predefined_cb_selection = XmStringCreateLocalized("predefined_SAR.sys");
+        }
+#endif //USE_COMBO_BOX
+    }
+    else {
+
+        load_predefined_cb_selection = XmStringCreateLocalized("predefined_SAR.sys");
+    }
+
+    xastir_snprintf(predefined_object_definition_filename,
+        sizeof(predefined_object_definition_filename),
+        "%s",
+        temp = XmStringUnparse(load_predefined_cb_selection,
+            NULL,
+            XmCHARSET_TEXT,
+            XmCHARSET_TEXT,
+            NULL,
+            0,
+            XmOUTPUT_ALL) );
+
+    XtFree(temp);
+    XmStringFree(load_predefined_cb_selection);
+
+    // Repopulate the predefined object (SAR/Public service) struct
+    Populate_predefined_objects(predefinedObjects); 
+
+    // Rebuild the predefined objects SAR/Public service menu.
+    BuildPredefinedSARMenu_UI(&sar_object_sub);
+
+    warn_about_mouse_modifiers = (int)XmToggleButtonGetState(warn_about_mouse_modifiers_enable);
+
+    altnet = (int)(XmToggleButtonGetState(altnet_active));
+
+    skip_dupe_checking = (int)(XmToggleButtonGetState(disable_dupe_check));
+
+    temp = XmTextGetString(altnet_text);
+    xastir_snprintf(altnet_call,
+        sizeof(altnet_call),
+        "%s",
+        temp);
+    XtFree(temp);
+    
+    (void)remove_trailing_spaces(altnet_call);
+    if (strlen(altnet_call)==0) {
+        altnet = FALSE;
+        xastir_snprintf(altnet_call,
+            sizeof(altnet_call),
+            "XASTIR");
+    }
+
+    operate_as_an_igate=Igate_type;
+
+    redraw_on_new_data=2;
+    Configure_defaults_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+/* Station_transmit type radio buttons */
+void station_type_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        Station_transmit_type = atoi(which);
+    else
+        Station_transmit_type = 0;
+
+}
+
+
+
+
+
+/* Igate type radio buttons */
+void igate_type_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        Igate_type = atoi(which);
+    else
+        Igate_type = 0;
+}
+
+
+#ifndef USE_COMBO_BOX
+void lpomff_menuCallback(Widget widget, XtPointer ptr, XtPointer callData) {
+    XtPointer userData;
+
+    XtVaGetValues(widget, XmNuserData, &userData, NULL);
+    //clsd_menu is zero based, cad_line_style_data constants are one based. 
+    lpomff_value = (int)userData + 1;
+    if (debug_level & 1)
+        fprintf(stderr,"Selected value on cad line type pulldown: %d\n",lpomff_value);
+}
+#endif  // !USE_COMBO_BOX
+
+
+
+
+
+void Configure_defaults( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel,
+                frame4, frame5,
+                station_type, type_box,
+                styp1, styp2, styp3, styp4, styp5, styp6,
+                igate_option, igate_box,
+                igtyp0, igtyp1, igtyp2, altnet_label;
+    Atom delw;
+    Arg al[50];                      /* Arg List */
+    register unsigned int ac = 0;   /* Arg Count */
+#ifndef USE_COMBO_BOX
+    Widget lpomff_menuPane;  
+    Widget lpomff_button;
+    Widget lpomff_buttons[4];
+    Widget lpomff_menu;
+    char buf[18];   
+    int x;
+#endif // !USE_COMBO_BOX
+    Widget lpomff_widget;
+    int i;
+    XmString cb_items[4];
+    char temp_base_dir[MAX_VALUE];
+
+                                                                                                                        
+
+    if (!configure_defaults_dialog) {
+        char loadfrom[300];
+
+        // Set args for color
+        ac = 0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        configure_defaults_dialog = XtVaCreatePopupShell(langcode("WPUPCFD001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Configure_defaults pane",
+                xmPanedWindowWidgetClass, 
+                configure_defaults_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Configure_defaults my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // Transmit Station Options
+        frame4 = XtVaCreateManagedWidget("Configure_defaults frame4", 
+                xmFrameWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset,10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        station_type  = XtVaCreateManagedWidget(langcode("WPUPCFD015"),
+                xmLabelWidgetClass,
+                frame4,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        type_box = XmCreateRadioBox(frame4,
+                "Configure_defaults Transmit Options box",
+                al,
+                ac);
+
+        XtVaSetValues(type_box,
+                XmNnumColumns,2,
+                NULL);
+
+        styp1 = XtVaCreateManagedWidget(langcode("WPUPCFD016"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(styp1,XmNvalueChangedCallback,station_type_toggle,"0");
+
+        styp2 = XtVaCreateManagedWidget(langcode("WPUPCFD017"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(styp2,XmNvalueChangedCallback,station_type_toggle,"1");
+
+        styp3 = XtVaCreateManagedWidget(langcode("WPUPCFD018"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(styp3,XmNvalueChangedCallback,station_type_toggle,"2");
+
+        styp4 = XtVaCreateManagedWidget(langcode("WPUPCFD019"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(styp4,XmNvalueChangedCallback,station_type_toggle,"3");
+
+        styp5 = XtVaCreateManagedWidget(langcode("WPUPCFD021"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(styp5,XmNvalueChangedCallback,station_type_toggle,"4");
+
+        styp6 = XtVaCreateManagedWidget(langcode("WPUPCFD022"),
+                xmToggleButtonGadgetClass,
+                type_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(styp6,XmNvalueChangedCallback,station_type_toggle,"5");
+
+
+        // Igate Options
+        frame5 = XtVaCreateManagedWidget("Configure_defaults frame5", 
+                xmFrameWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, frame4,
+                XmNtopOffset,10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        igate_option  = XtVaCreateManagedWidget(langcode("IGPUPCF000"),
+                xmLabelWidgetClass,
+                frame5,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        igate_box = XmCreateRadioBox(frame5,
+                "Configure_defaults Igate Options box",
+                al,
+                ac);
+
+        XtVaSetValues(igate_box,
+                XmNnumColumns,2,
+                NULL);
+
+        igtyp0 = XtVaCreateManagedWidget(langcode("IGPUPCF001"),
+                xmToggleButtonGadgetClass,
+                igate_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(igtyp0,XmNvalueChangedCallback,igate_type_toggle,"0");
+
+        igtyp1 = XtVaCreateManagedWidget(langcode("IGPUPCF002"),
+                xmToggleButtonGadgetClass,
+                igate_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(igtyp1,XmNvalueChangedCallback,igate_type_toggle ,"1");
+
+        igtyp2 = XtVaCreateManagedWidget(langcode("IGPUPCF003"),
+                xmToggleButtonGadgetClass,
+                igate_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(igtyp2,XmNvalueChangedCallback,igate_type_toggle,"2");
+
+
+        // Miscellaneous Options
+        compressed_objects_items_tx = XtVaCreateManagedWidget(langcode("WPUPCFD024"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame5,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        new_bulletin_popup_enable = XtVaCreateManagedWidget(langcode("WPUPCFD027"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, compressed_objects_items_tx,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        zero_bulletin_popup_enable = XtVaCreateManagedWidget(langcode("WPUPCFD029"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, new_bulletin_popup_enable,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        warn_about_mouse_modifiers_enable = XtVaCreateManagedWidget(langcode("WPUPCFD028"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, new_bulletin_popup_enable,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, zero_bulletin_popup_enable,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Show all My trails in one color
+        my_trail_diff_color_enable = XtVaCreateManagedWidget(langcode("WPUPCFD032"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, new_bulletin_popup_enable,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, warn_about_mouse_modifiers_enable,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+       
+       
+        // Check box to load predefined (SAR/Event) objects menu from a file or not.
+        xastir_snprintf(loadfrom,
+                        sizeof(loadfrom),
+                        "%s %s",
+                        langcode("WPUPCFD031"),
+#ifdef OBJECT_DEF_FILE_USER_BASE
+                        get_user_base_dir("config", temp_base_dir, sizeof(temp_base_dir)));
+#else   // OBJECT_DEF_FILE_USER_BASE
+                        get_data_base_dir("config"));
+#endif  // OBJECT_DEF_FILE_USER_BASE
+
+        load_predefined_objects_menu_from_file_enable = XtVaCreateManagedWidget(loadfrom,
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zero_bulletin_popup_enable,
+                XmNtopOffset,5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+         
+        // lesstif as of 0.95 in 2008 doesn't fully support combo boxes
+        // 
+        // Need to replace combo boxes with a pull down menu when lesstif is used.
+        // See xpdf's  XPDFViewer.cc/XPDFViewer.h for an example.
+
+        cb_items[0] = XmStringCreateLocalized("predefined_SAR.sys");
+        cb_items[1] = XmStringCreateLocalized("predefined_EVENT.sys");
+        cb_items[2] = XmStringCreateLocalized("predefined_USER.sys");
+#ifdef USE_COMBO_BOX
+        // Combo box to pick file from which to load predefined objects menu
+        load_predefined_objects_menu_from_file = XtVaCreateManagedWidget("Load objects menu filename ComboBox",
+                xmComboBoxWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, zero_bulletin_popup_enable,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, load_predefined_objects_menu_from_file_enable,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNcomboBoxType, XmDROP_DOWN_LIST,
+                XmNpositionMode, XmONE_BASED, 
+                XmNvisibleItemCount, 3,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmComboBoxAddItem(load_predefined_objects_menu_from_file,cb_items[0],1,1);  
+        XmComboBoxAddItem(load_predefined_objects_menu_from_file,cb_items[1],2,1);  
+        XmComboBoxAddItem(load_predefined_objects_menu_from_file,cb_items[2],3,1);  
+
+        lpomff_widget = load_predefined_objects_menu_from_file;
+#else
+        // Menu replacement for combo box when using lesstif.
+        // Not a full replacement, as combo box in motif can have editable values, 
+        // not just selection from predefined list as is the case here.
+        ac = 0;
+        XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
+        XtSetArg(al[ac], XmNmarginHeight, 0); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+        lpomff_menuPane = XmCreatePulldownMenu(my_form,"lpomff_menuPane", al, ac);
+        //lpomff_menu is zero based, constants for filenames are one based
+        //lpomff_value is set to match constants in callback.
+        for (i=0;i<3;i++) { 
+            ac = 0;
+            XtSetArg(al[ac], XmNlabelString, cb_items[i]); ac++;
+            XtSetArg(al[ac], XmNuserData, (XtPointer)i); ac++;
+            sprintf(buf,"button%d",i);
+            lpomff_button = XmCreatePushButton(lpomff_menuPane, buf, al, ac);
+            XtManageChild(lpomff_button);
+            XtAddCallback(lpomff_button, XmNactivateCallback, lpomff_menuCallback, Configure_defaults);
+            lpomff_buttons[i] = lpomff_button;
+        }
+        ac = 0;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ++ac;
+        XtSetArg(al[ac], XmNleftWidget, load_predefined_objects_menu_from_file_enable); ++ac;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ++ac;
+        XtSetArg(al[ac], XmNtopWidget, zero_bulletin_popup_enable); ++ac;
+        XtSetArg(al[ac], XmNmarginWidth, 0); ++ac;
+        XtSetArg(al[ac], XmNmarginHeight, 0); ++ac;
+        XtSetArg(al[ac], XmNtopOffset, 5); ++ac;
+        XtSetArg(al[ac], XmNleftOffset, 10); ++ac;
+        XtSetArg(al[ac], XmNsubMenuId, lpomff_menuPane); ++ac;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+        lpomff_menu = XmCreateOptionMenu(my_form, "sddd_Menu", al, ac);
+        XtManageChild(lpomff_menu);
+        lpomff_value = 2;   // set a default value (line on off dash)
+        lpomff_widget = lpomff_menu;
+#endif  // USE_COMBO_BOX
+        // free up space from combo box strings 
+        for (i=0;i<3;i++) {
+           XmStringFree(cb_items[i]);
+        }
+
+
+#ifdef TRANSMIT_RAW_WX
+        raw_wx_tx  = XtVaCreateManagedWidget(langcode("WPUPCFD023"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, lpomff_widget,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+#endif  // TRANSMIT_RAW_WX
+
+        altnet_active  = XtVaCreateManagedWidget(langcode("WPUPCFD025"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame5,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, compressed_objects_items_tx,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "ALTNET:"
+        altnet_label = XtVaCreateManagedWidget(langcode("WPUPCFD033"),
+                xmLabelWidgetClass,
+                my_form,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, altnet_active,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, compressed_objects_items_tx,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        altnet_text = XtVaCreateManagedWidget("Configure_defaults Altnet_text", 
+                xmTextWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 9,
+                XmNwidth, ((10*7)+2),
+                XmNmaxLength, 9,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, altnet_active,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, altnet_label,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNfontList, fontlist1,
+                NULL);
+
+        disable_dupe_check = XtVaCreateManagedWidget(langcode("WPUPCFD030"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame5,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, altnet_active,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+#ifdef TRANSMIT_RAW_WX
+                XmNtopWidget, raw_wx_tx,
+#else   // TRANSMIT_RAW_WX
+                XmNtopWidget, lpomff_widget,
+#endif  // TRANSMIT_RAW_WX
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+#ifdef TRANSMIT_RAW_WX
+                XmNtopWidget, raw_wx_tx,
+#else   // TRANSMIT_RAW_WX
+                XmNtopWidget, lpomff_widget,
+#endif  // TRANSMIT_RAW_WX
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_defaults_change_data, configure_defaults_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_defaults_destroy_shell, configure_defaults_dialog);
+
+        switch(output_station_type) {
+            case(0):
+                XmToggleButtonSetState(styp1,TRUE,FALSE);
+                Station_transmit_type=0;
+                break;
+
+            case(1):
+                XmToggleButtonSetState(styp2,TRUE,FALSE);
+                Station_transmit_type=1;
+                break;
+
+            case(2):
+                XmToggleButtonSetState(styp3,TRUE,FALSE);
+                Station_transmit_type=2;
+                break;
+
+            case(3):
+                XmToggleButtonSetState(styp4,TRUE,FALSE);
+                Station_transmit_type=3;
+                break;
+
+            case(4):
+                XmToggleButtonSetState(styp5,TRUE,FALSE);
+                Station_transmit_type=4;
+                break;
+
+            case(5):
+                XmToggleButtonSetState(styp6,TRUE,FALSE);
+                Station_transmit_type=5;
+                break;
+
+            default:
+                XmToggleButtonSetState(styp1,TRUE,FALSE);
+                Station_transmit_type=0;
+                break;
+        }
+
+#ifdef TRANSMIT_RAW_WX
+        if (transmit_raw_wx)
+            XmToggleButtonSetState(raw_wx_tx,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(raw_wx_tx,FALSE,FALSE);
+#endif  // TRANSMIT_RAW_WX
+
+        if(transmit_compressed_objects_items)
+            XmToggleButtonSetState(compressed_objects_items_tx,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(compressed_objects_items_tx,FALSE,FALSE);
+
+        if(pop_up_new_bulletins)
+            XmToggleButtonSetState(new_bulletin_popup_enable,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(new_bulletin_popup_enable,FALSE,FALSE);
+
+        if(view_zero_distance_bulletins)
+            XmToggleButtonSetState(zero_bulletin_popup_enable,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(zero_bulletin_popup_enable,FALSE,FALSE);
+
+        if(warn_about_mouse_modifiers)
+            XmToggleButtonSetState(warn_about_mouse_modifiers_enable,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(warn_about_mouse_modifiers_enable,FALSE,FALSE);
+
+        // user interface refers to all my trails in one color
+        // my trail diff color as 0 means my trails in one color, so select
+        // button when my trail diff color is 0 rather than 1.
+        if(my_trail_diff_color)  
+            XmToggleButtonSetState(my_trail_diff_color_enable,FALSE,FALSE);
+        else
+            XmToggleButtonSetState(my_trail_diff_color_enable,TRUE,FALSE);
+
+        if(predefined_menu_from_file) {
+            // Option to load the predefined SAR objects menu items from a file.
+            // Display the filename if one is currently selected and option is enabled.
+            if (predefined_object_definition_filename != NULL ) { 
+
+#ifdef USE_COMBO_BOX            
+                XmString tempSelection = XmStringCreateLocalized(predefined_object_definition_filename);
+                XmComboBoxSelectItem(load_predefined_objects_menu_from_file, tempSelection);
+                XmStringFree(tempSelection);
+#else
+                x = -1;
+                if (strncmp(predefined_object_definition_filename,"predefined_SAR.sys",strlen(predefined_object_definition_filename)) == 0) 
+                    x = 0;
+                if (strncmp(predefined_object_definition_filename,"predefined_EVENT.sys",strlen(predefined_object_definition_filename)) == 0)
+                    x = 1;
+                if (strncmp(predefined_object_definition_filename,"predefined_USER.sys",strlen(predefined_object_definition_filename)) == 0)
+                    x = 2;
+                i = 3;
+                // allow display of another filename from the config file.
+                // user won't be able to edit it, but they will see it.
+                if (x==-1) { 
+                    ac = 0;
+                    cb_items[i] = XmStringCreateLocalized(predefined_object_definition_filename);
+                    XtSetArg(al[ac], XmNlabelString, cb_items[i]); ac++;
+                    XtSetArg(al[ac], XmNuserData, (XtPointer)i); ac++;
+                    XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+                    sprintf(buf,"button%d",i);
+                    lpomff_button = XmCreatePushButton(lpomff_menuPane, buf, al, ac);
+                    XtManageChild(lpomff_button);
+                    XtAddCallback(lpomff_button, XmNactivateCallback, lpomff_menuCallback, Configure_defaults);
+                    lpomff_buttons[i] = lpomff_button;
+                    XmStringFree(cb_items[i]);
+                    x = i;
+                }
+                XtVaSetValues(lpomff_menu, XmNmenuHistory, lpomff_buttons[x], NULL);
+                lpomff_value = x+1;
+#endif // USE_COMBO_BOX
+
+            }
+            XmToggleButtonSetState(load_predefined_objects_menu_from_file_enable,TRUE,FALSE);
+        } else {
+            // by default combo box is created with no selection
+            // make sure that toggle button is unchecked
+            XmToggleButtonSetState(load_predefined_objects_menu_from_file_enable,FALSE,FALSE);
+        }
+ 
+        XmToggleButtonSetState(altnet_active, altnet, FALSE);
+
+        XmToggleButtonSetState(disable_dupe_check, skip_dupe_checking, FALSE);
+
+        // Known to have memory leaks in some Motif versions:
+        //XmTextSetString(altnet_text, altnet_call);
+        XmTextReplace(altnet_text, (XmTextPosition) 0,
+            XmTextGetLastPosition(altnet_text), altnet_call);
+
+        switch(operate_as_an_igate) {
+            case(0):
+                XmToggleButtonSetState(igtyp0,TRUE,FALSE);
+                Igate_type=0;
+                break;
+
+            case(1):
+                XmToggleButtonSetState(igtyp1,TRUE,FALSE);
+                Igate_type=1;
+                break;
+
+            case(2):
+                XmToggleButtonSetState(igtyp2,TRUE,FALSE);
+                Igate_type=2;
+                break;
+
+            default:
+                XmToggleButtonSetState(igtyp0,TRUE,FALSE);
+                Igate_type=0;
+                break;
+        }
+        pos_dialog(configure_defaults_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_defaults_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(configure_defaults_dialog, delw, Configure_defaults_destroy_shell, (XtPointer)configure_defaults_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(type_box);
+        XtManageChild(igate_box);
+        XtManageChild(pane);
+
+        XtPopup(configure_defaults_dialog,XtGrabNone);
+        fix_dialog_size(configure_defaults_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(configure_defaults_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_defaults_dialog), XtWindow(configure_defaults_dialog));
+}
+
+
+
+
+
+///////////////////////////////////   Configure Timing Dialog   //////////////////////////////////
+
+
+void Configure_timing_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    configure_timing_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Configure_timing_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    int value;
+
+
+    XmScaleGetValue(ghosting_time, &value);     // Minutes
+    sec_old = (time_t)(value * 60);             // Convert to seconds
+
+    XmScaleGetValue(clearing_time, &value);     // Hours
+    sec_clear = (time_t)(value * 60 * 60);      // Convert to seconds
+
+    XmScaleGetValue(posit_interval, &value);    // Minutes * 10
+    POSIT_rate = (long)(value * 60 / 10);       // Convert to seconds
+
+    XmScaleGetValue(gps_interval, &value);      // Seconds
+    gps_time = (long)value;
+
+    XmScaleGetValue(dead_reckoning_time, &value);// Minutes
+    dead_reckoning_timeout = value * 60;        // Convert to seconds
+
+    XmScaleGetValue(object_item_interval, &value);// Minutes
+    OBJECT_rate = value * 60;                   // Convert to seconds
+
+    XmScaleGetValue(removal_time, &value);      // Days
+    sec_remove = (time_t)(value * 60 * 60 * 24);// Convert to seconds
+
+    // Set the new posit rate into effect immediately
+    posit_next_time = posit_last_time + POSIT_rate;
+
+    // Set the new GPS rate into effect immediately
+    sec_next_gps = sec_now() + gps_time;
+
+    // Set the serial port inter-character delay
+    XmScaleGetValue(serial_pacing_time, &serial_char_pacing);     // Milliseconds
+
+    XmScaleGetValue(trail_segment_timeout, &value); // Minutes
+    trail_segment_time = (int)value;
+
+    XmScaleGetValue(trail_segment_distance_max, &value); // Degrees
+    trail_segment_distance = (int)value;
+
+#ifdef HAVE_GPSMAN
+    XmScaleGetValue(RINO_download_timeout, &value); // Degrees
+    RINO_download_interval = (int)value;
+#endif  // HAVE_GPSMAN
+
+    XmScaleGetValue(net_map_slider, &net_map_timeout);
+
+    XmScaleGetValue(snapshot_interval_slider, &snapshot_interval);
+
+    redraw_on_new_data=2;
+    Configure_timing_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Configure_timing( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel;
+    Atom delw;
+    XmString x_str;
+
+
+    if (!configure_timing_dialog) {
+        configure_timing_dialog = XtVaCreatePopupShell(langcode("WPUPCFTM01"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Configure_timing pane",
+                xmPanedWindowWidgetClass, 
+                configure_timing_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Configure_timing my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 2,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // Posit Time
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM02"));
+        posit_interval = XtVaCreateManagedWidget("Posit Interval",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 0,          // Zero minutes (disables the function)
+                XmNmaximum, 60*10,      // 60 minutes
+                XmNdecimalPoints, 1,    // Move decimal point over one
+	        XmNscaleMultiple, 5,	// Move 30 seconds per left mouse
+                XmNshowValue, TRUE,
+                XmNvalue, (int)((POSIT_rate * 10) / 60),  // Minutes * 10
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+
+        // Interval for stations being considered old (symbol ghosting)
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM03"));
+        ghosting_time = XtVaCreateManagedWidget("Station Ghosting Time",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 10,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,      // One minute
+                XmNmaximum, 3*60,   // Three hours
+                XmNshowValue, TRUE,
+                XmNvalue, (int)(sec_old/60),
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Object Item Transmit Interval
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM04"));
+        object_item_interval = XtVaCreateManagedWidget("Object/Item Transmit Interval (min)",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, posit_interval,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 5,      // Five minutes
+                XmNmaximum, 120,    // 120 minutes
+	        XmNscaleMultiple, 5,	// Move 5 minutes per left mouse
+                XmNshowValue, TRUE,
+                XmNvalue, (int)(OBJECT_rate / 60),
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Interval for station not being displayed
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM05"));
+        clearing_time = XtVaCreateManagedWidget("Station Clear Time",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, posit_interval,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 10,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,      // One hour
+                XmNmaximum, 24*7,   // One week
+                XmNshowValue, TRUE,
+                XmNvalue, (int)(sec_clear/(60*60)),
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // GPS Time
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM06"));
+        gps_interval = XtVaCreateManagedWidget("GPS Interval",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, object_item_interval,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,      // One second
+                XmNmaximum, 60,     // Sixty seconds
+                XmNshowValue, TRUE,
+                XmNvalue, (int)gps_time,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Interval for station being removed from database
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM07"));
+        removal_time = XtVaCreateManagedWidget("Station Delete Time",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, object_item_interval,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 10,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,      // One Day
+                XmNmaximum, 14,     // Two weeks
+                XmNshowValue, TRUE,
+                XmNvalue, (int)(sec_remove/(60*60*24)),
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Dead Reckoning Timeout
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM08"));
+        dead_reckoning_time = XtVaCreateManagedWidget("DR Time (min)",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, gps_interval,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,      // One minute
+                XmNmaximum, 60,     // Sixty minutes
+                XmNshowValue, TRUE,
+                XmNvalue, (int)(dead_reckoning_timeout / 60),
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Serial Pacing Time (delay between each serial character)
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM09"));
+        serial_pacing_time = XtVaCreateManagedWidget("Serial Pacing Time (ms)",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, removal_time,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 0,      // Zero
+                XmNmaximum, 50,     // Fifty milliseconds
+                XmNshowValue, TRUE,
+                XmNvalue, (int)(serial_char_pacing),
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Time below which track segment will get drawn, in minutes
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM10"));
+        trail_segment_timeout = XtVaCreateManagedWidget("Trail segment timeout",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, dead_reckoning_time,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 0,     // Zero minutes
+                XmNmaximum, 12*60, // 12 hours
+                XmNshowValue, TRUE,
+                XmNvalue, trail_segment_time,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Interval at track segment will not get drawn, in degrees
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM11"));
+        trail_segment_distance_max = XtVaCreateManagedWidget("Trail segment interval degrees",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, dead_reckoning_time,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 0,  // Zero degrees
+                XmNmaximum, 45, // 90 degrees
+                XmNshowValue, TRUE,
+                XmNvalue, trail_segment_distance,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Time below which track segment will get drawn, in minutes
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM12"));
+        RINO_download_timeout = XtVaCreateManagedWidget("RINO download interval",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, trail_segment_timeout,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 0,      // Zero minutes (disables the function)
+                XmNmaximum, 30,     // 30 minutes
+                XmNshowValue, TRUE,
+                XmNvalue, RINO_download_interval,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+#ifndef HAVE_GPSMAN
+XtSetSensitive(RINO_download_timeout, FALSE);
+#endif  // HAVE_GPSMAN
+
+       x_str = XmStringCreateLocalized(langcode("MPUPTGR017"));
+       net_map_slider  = XtVaCreateManagedWidget("Net Map Timeout",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, trail_segment_timeout,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 10,
+                XmNmaximum, 300,
+                XmNshowValue, TRUE,
+                XmNvalue, net_map_timeout,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        // Interval at which snapshots will be taken, in minutes
+        x_str = XmStringCreateLocalized(langcode("WPUPCFTM13"));
+        snapshot_interval_slider = XtVaCreateManagedWidget("Snapshot interval",
+                xmScaleWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, RINO_download_timeout,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNrightOffset, 5,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,    // 0.5 minutes
+                XmNmaximum, 30,     // 30 minutes
+                XmNshowValue, TRUE,
+                XmNvalue, snapshot_interval,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, snapshot_interval_slider,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, snapshot_interval_slider,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_timing_change_data, configure_timing_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_timing_destroy_shell, configure_timing_dialog);
+
+        pos_dialog(configure_timing_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_timing_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(configure_timing_dialog, delw, Configure_timing_destroy_shell, (XtPointer)configure_timing_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(configure_timing_dialog,XtGrabNone);
+        fix_dialog_size(configure_timing_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(configure_timing_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_timing_dialog), XtWindow(configure_timing_dialog));
+}
+
+
+
+
+
+///////////////////////////////////   Configure Coordinates Dialog   //////////////////////////////////
+
+void coordinates_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if (state->set)
+        coordinate_system = atoi(which);
+    else
+        coordinate_system = USE_DDMMMM;
+
+    // Update any active view lists so their coordinates get updated
+    Station_List_fill(1,0);     // Update View->Mobile Station list (has lat/lon or UTM info on it)
+    // Force redraw
+    redraw_on_new_data = 2;
+}
+
+
+
+
+
+void Configure_coordinates_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    configure_coordinates_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Configure_coordinates( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel, frame,
+                label, coord_box, coord_0, coord_1, coord_2,
+                coord_3, coord_4, coord_5;
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+    if (!configure_coordinates_dialog) {
+        configure_coordinates_dialog = XtVaCreatePopupShell(langcode("WPUPCFC001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Configure_coordinates pane",
+                xmPanedWindowWidgetClass, 
+                configure_coordinates_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Configure_coordinates my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+
+        // Interval for station being considered old
+        frame = XtVaCreateManagedWidget("Configure_coordinates frame", 
+                xmFrameWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset,10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        label = XtVaCreateManagedWidget(langcode("WPUPCFC002"),
+                xmLabelWidgetClass,
+                frame,
+                XmNchildType, XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        coord_box = XmCreateRadioBox(frame,"Configure_coordinates coord_box",
+                al,
+                ac);
+
+        XtVaSetValues(coord_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNnumColumns,5,
+                NULL);
+
+
+        coord_0 = XtVaCreateManagedWidget(langcode("WPUPCFC003"),
+                xmToggleButtonGadgetClass,
+                coord_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coord_0,XmNvalueChangedCallback,coordinates_toggle,"0");
+
+
+        coord_1 = XtVaCreateManagedWidget(langcode("WPUPCFC004"),
+                xmToggleButtonGadgetClass,
+                coord_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coord_1,XmNvalueChangedCallback,coordinates_toggle,"1");
+
+
+        coord_2 = XtVaCreateManagedWidget(langcode("WPUPCFC005"),
+                xmToggleButtonGadgetClass,
+                coord_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coord_2,XmNvalueChangedCallback,coordinates_toggle,"2");
+
+
+        coord_3 = XtVaCreateManagedWidget(langcode("WPUPCFC006"),
+                xmToggleButtonGadgetClass,
+                coord_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coord_3,XmNvalueChangedCallback,coordinates_toggle,"3");
+
+
+        coord_4 = XtVaCreateManagedWidget(langcode("WPUPCFC008"),
+                xmToggleButtonGadgetClass,
+                coord_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coord_4,XmNvalueChangedCallback,coordinates_toggle,"4");
+
+
+        coord_5 = XtVaCreateManagedWidget(langcode("WPUPCFC007"),
+                xmToggleButtonGadgetClass,
+                coord_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coord_5,XmNvalueChangedCallback,coordinates_toggle,"5");
+
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, frame,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_coordinates_destroy_shell, configure_coordinates_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_coordinates_destroy_shell, configure_coordinates_dialog);
+
+        // Set the toggle buttons based on current data
+        switch (coordinate_system) {
+            case(USE_DDDDDD):
+                XmToggleButtonSetState(coord_0,TRUE,FALSE);
+                break;
+
+            case(USE_DDMMSS):
+                XmToggleButtonSetState(coord_2,TRUE,FALSE);
+                break;
+
+            case(USE_UTM):
+                XmToggleButtonSetState(coord_3,TRUE,FALSE);
+                break;
+
+            case(USE_UTM_SPECIAL):
+                XmToggleButtonSetState(coord_4,TRUE,FALSE);
+                break;
+
+            case(USE_MGRS):
+                XmToggleButtonSetState(coord_5,TRUE,FALSE);
+                break;
+
+            case(USE_DDMMMM):
+            default:
+                XmToggleButtonSetState(coord_1,TRUE,FALSE);
+                break;
+        }
+
+        pos_dialog(configure_coordinates_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_coordinates_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(configure_coordinates_dialog, delw, Configure_coordinates_destroy_shell, (XtPointer)configure_coordinates_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(coord_box);
+        XtManageChild(pane);
+
+        XtPopup(configure_coordinates_dialog,XtGrabNone);
+        fix_dialog_size(configure_coordinates_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(configure_coordinates_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_coordinates_dialog), XtWindow(configure_coordinates_dialog));
+}
+
+
+
+
+
+
+/////////////////////////////////   Configure Audio Alarms Dialog   ////////////////////////////////
+
+void Configure_audio_alarm_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    configure_audio_alarm_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Configure_audio_alarm_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp_ptr;
+
+
+    temp_ptr = XmTextFieldGetString(audio_alarm_config_play_data);
+    xastir_snprintf(sound_command,
+        sizeof(sound_command),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(sound_command);
+
+    temp_ptr = XmTextFieldGetString(audio_alarm_config_play_ons_data);
+    xastir_snprintf(sound_new_station,
+        sizeof(sound_new_station),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(sound_new_station);
+
+    temp_ptr = XmTextFieldGetString(audio_alarm_config_play_onm_data);
+    xastir_snprintf(sound_new_message,
+        sizeof(sound_new_message),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(sound_new_message);
+
+    temp_ptr = XmTextFieldGetString(audio_alarm_config_play_onpx_data);
+    xastir_snprintf(sound_prox_message,
+        sizeof(sound_prox_message),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(sound_prox_message);
+
+    temp_ptr = XmTextFieldGetString(prox_min_data);
+    xastir_snprintf(prox_min,
+        sizeof(prox_min),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(prox_min);
+
+    temp_ptr = XmTextFieldGetString(prox_max_data);
+    xastir_snprintf(prox_max,
+        sizeof(prox_max),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(prox_max);
+
+    temp_ptr = XmTextFieldGetString(audio_alarm_config_play_onbo_data);
+    xastir_snprintf(sound_band_open_message,
+        sizeof(sound_band_open_message),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(sound_band_open_message);
+
+    temp_ptr = XmTextFieldGetString(bando_min_data);
+    xastir_snprintf(bando_min,
+        sizeof(bando_min),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(bando_min);
+
+    temp_ptr = XmTextFieldGetString(bando_max_data);
+    xastir_snprintf(bando_max,
+        sizeof(bando_max),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(bando_max);
+
+    temp_ptr = XmTextFieldGetString(audio_alarm_config_wx_alert_data);
+    xastir_snprintf(sound_wx_alert_message,
+        sizeof(sound_wx_alert_message),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(sound_wx_alert_message);
+
+    if(XmToggleButtonGetState(audio_alarm_config_play_on_new_station))
+        sound_play_new_station=1;
+    else
+        sound_play_new_station=0;
+
+    if(XmToggleButtonGetState(audio_alarm_config_play_on_new_message))
+        sound_play_new_message=1;
+    else
+        sound_play_new_message=0;
+
+    if(XmToggleButtonGetState(audio_alarm_config_play_on_prox))
+        sound_play_prox_message=1;
+    else
+        sound_play_prox_message=0;
+
+    if(XmToggleButtonGetState(audio_alarm_config_play_on_bando))
+        sound_play_band_open_message=1;
+    else
+        sound_play_band_open_message=0;
+
+    if(XmToggleButtonGetState(audio_alarm_config_play_on_wx_alert))
+        sound_play_wx_alert_message=1;
+    else
+        sound_play_wx_alert_message=0;
+
+    Configure_audio_alarm_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+void Configure_audio_alarms( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel,
+                audio_play, file1, file2,
+                min1, min2, max1, max2,
+                minb1, minb2, maxb1, maxb2,
+                sep;
+    Atom delw;
+
+    if (!configure_audio_alarm_dialog) {
+        configure_audio_alarm_dialog = XtVaCreatePopupShell(langcode("WPUPCFA001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Configure_audio_alarms pane",
+                xmPanedWindowWidgetClass, 
+                configure_audio_alarm_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Configure_audio_alarms my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 3,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        audio_play = XtVaCreateManagedWidget(langcode("WPUPCFA002"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_data = XtVaCreateManagedWidget("Configure_audio_alarms Play Command", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 40,
+                XmNwidth, ((40*7)+2),
+                XmNmaxLength, 80,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        file1 = XtVaCreateManagedWidget(langcode("WPUPCFA003"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_play,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        file2 = XtVaCreateManagedWidget(langcode("WPUPCFA004"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_play,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_on_new_station = XtVaCreateManagedWidget(langcode("WPUPCFA005"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, file1,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_ons_data = XtVaCreateManagedWidget("Configure_audio_alarms Play Command NS", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 25,
+                XmNwidth, ((25*7)+2),
+                XmNmaxLength, 80,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, file2,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNleftWidget, audio_alarm_config_play_on_new_station,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_on_new_message  = XtVaCreateManagedWidget(langcode("WPUPCFA006"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_new_station,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_onm_data = XtVaCreateManagedWidget("Configure_audio_alarms Play Command NM", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 25,
+                XmNwidth, ((25*7)+2),
+                XmNmaxLength, 80,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_new_station,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_on_prox  = XtVaCreateManagedWidget(langcode("WPUPCFA007"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_new_message,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_onpx_data = XtVaCreateManagedWidget("Configure_audio_alarms Play Command PROX", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 25,
+                XmNwidth, ((25*7)+2),
+                XmNmaxLength, 80,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_new_message,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNfontList, fontlist1,
+                NULL);
+
+        min1 = XtVaCreateManagedWidget(langcode("WPUPCFA009"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_prox,
+                XmNtopOffset, 8,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        prox_min_data = XtVaCreateManagedWidget("Configure_audio_alarms prox min", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 10,
+                XmNwidth, ((10*7)+2),
+                XmNmaxLength, 20,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_onpx_data,
+                XmNtopOffset, 2,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNfontList, fontlist1,
+                NULL);
+
+        min2 = XtVaCreateManagedWidget(english_units?langcode("UNIOP00004"):langcode("UNIOP00005"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_prox,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        max1 = XtVaCreateManagedWidget(langcode("WPUPCFA010"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, min1,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        prox_max_data = XtVaCreateManagedWidget("Configure_audio_alarms prox max", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 10,
+                XmNwidth, ((10*7)+2),
+                XmNmaxLength, 20,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, prox_min_data,
+                XmNtopOffset, 2,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNfontList, fontlist1,
+                NULL);
+
+        max2 = XtVaCreateManagedWidget(english_units?langcode("UNIOP00004"):langcode("UNIOP00005"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, min1,
+                XmNtopOffset, 14,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_on_bando  = XtVaCreateManagedWidget(langcode("WPUPCFA008"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, max1,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_onbo_data = XtVaCreateManagedWidget("Configure_audio_alarms Play Command BAND", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 25,
+                XmNwidth, ((25*7)+2),
+                XmNmaxLength, 80,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, prox_max_data,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNfontList, fontlist1,
+                NULL);
+
+        minb1 = XtVaCreateManagedWidget(langcode("WPUPCFA009"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_bando,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        bando_min_data = XtVaCreateManagedWidget("Configure_audio_alarms bando min", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 12,
+                XmNwidth, ((10*7)+2),
+                XmNmaxLength, 20,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_onbo_data,
+                XmNtopOffset, 2,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNfontList, fontlist1,
+                NULL);
+
+        minb2 = XtVaCreateManagedWidget(english_units?langcode("UNIOP00004"):langcode("UNIOP00005"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_bando,
+                XmNtopOffset, 14,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        maxb1 = XtVaCreateManagedWidget(langcode("WPUPCFA010"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, minb1,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        bando_max_data = XtVaCreateManagedWidget("Configure_audio_alarms bando max", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 10,
+                XmNwidth, ((10*7)+2),
+                XmNmaxLength, 20,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, bando_min_data,
+                XmNtopOffset, 2,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment,XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNfontList, fontlist1,
+                NULL);
+
+        maxb2 = XtVaCreateManagedWidget(english_units?langcode("UNIOP00004"):langcode("UNIOP00005"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, minb1,
+                XmNtopOffset, 14,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_play_on_wx_alert  = XtVaCreateManagedWidget(langcode("WPUPCFA011"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, maxb2,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        audio_alarm_config_wx_alert_data = XtVaCreateManagedWidget("Configure_audio_alarms Play Command WxAlert", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable, TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness, 1,
+                XmNcolumns, 25,
+                XmNwidth, ((25*7)+2),
+                XmNmaxLength, 80,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, bando_max_data,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sep = XtVaCreateManagedWidget("Configure_audio_alarms sep", 
+                xmSeparatorGadgetClass,
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, audio_alarm_config_play_on_wx_alert,
+                XmNtopOffset, 20,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_audio_alarm_change_data, configure_audio_alarm_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_audio_alarm_destroy_shell, configure_audio_alarm_dialog);
+
+        pos_dialog(configure_audio_alarm_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_audio_alarm_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(configure_audio_alarm_dialog, delw, Configure_audio_alarm_destroy_shell,
+                (XtPointer)configure_audio_alarm_dialog);
+
+        XmTextFieldSetString(audio_alarm_config_play_data,sound_command);
+        XmTextFieldSetString(audio_alarm_config_play_ons_data,sound_new_station);
+        XmTextFieldSetString(audio_alarm_config_play_onm_data,sound_new_message);
+        XmTextFieldSetString(audio_alarm_config_play_onpx_data,sound_prox_message);
+        XmTextFieldSetString(prox_min_data,prox_min);
+        XmTextFieldSetString(prox_max_data,prox_max);
+        XmTextFieldSetString(audio_alarm_config_play_onbo_data,sound_band_open_message);
+        XmTextFieldSetString(bando_min_data,bando_min);
+        XmTextFieldSetString(bando_max_data,bando_max);
+        XmTextFieldSetString(audio_alarm_config_wx_alert_data, sound_wx_alert_message);
+
+        if(sound_play_new_station)
+            XmToggleButtonSetState(audio_alarm_config_play_on_new_station,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(audio_alarm_config_play_on_new_station,FALSE,FALSE);
+
+        if(sound_play_new_message)
+            XmToggleButtonSetState(audio_alarm_config_play_on_new_message,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(audio_alarm_config_play_on_new_message,FALSE,FALSE);
+
+        if(sound_play_prox_message)
+            XmToggleButtonSetState(audio_alarm_config_play_on_prox,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(audio_alarm_config_play_on_prox,FALSE,FALSE);
+
+        if(sound_play_band_open_message)
+            XmToggleButtonSetState(audio_alarm_config_play_on_bando,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(audio_alarm_config_play_on_bando,FALSE,FALSE);
+
+        if (sound_play_wx_alert_message)
+            XmToggleButtonSetState(audio_alarm_config_play_on_wx_alert, TRUE, FALSE);
+        else
+            XmToggleButtonSetState(audio_alarm_config_play_on_wx_alert, FALSE, FALSE);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(configure_audio_alarm_dialog,XtGrabNone);
+        fix_dialog_size(configure_audio_alarm_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(configure_audio_alarm_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_audio_alarm_dialog), XtWindow(configure_audio_alarm_dialog));
+
+}
+
+
+
+
+
+/////////////////////////////////////   Configure Speech Dialog   //////////////////////////////////
+
+
+void Configure_speech_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    XtDestroyWidget(shell);
+    configure_speech_dialog = (Widget)NULL;
+}
+
+
+
+
+
+void Test_speech(Widget widget, XtPointer clientData, XtPointer callData) {
+    SayText(SPEECH_TEST_STRING);
+}
+
+
+
+
+
+void Configure_speech_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if(XmToggleButtonGetState(speech_config_play_on_new_station))
+        festival_speak_new_station=1;
+    else
+        festival_speak_new_station=0;
+
+    if(XmToggleButtonGetState(speech_config_play_on_new_message_alert))
+        festival_speak_new_message_alert=1;
+    else
+        festival_speak_new_message_alert=0;
+
+    if(XmToggleButtonGetState(speech_config_play_on_new_message_body))
+        festival_speak_new_message_body=1;
+    else
+        festival_speak_new_message_body=0;
+
+    if(XmToggleButtonGetState(speech_config_play_on_prox))
+        festival_speak_proximity_alert=1;
+    else
+        festival_speak_proximity_alert=0;
+
+    if(XmToggleButtonGetState(speech_config_play_on_trak))
+        festival_speak_tracked_proximity_alert=1;
+    else
+        festival_speak_tracked_proximity_alert=0;
+
+    if(XmToggleButtonGetState(speech_config_play_on_bando))
+        festival_speak_band_opening=1;
+    else
+        festival_speak_band_opening=0;
+
+    if(XmToggleButtonGetState(speech_config_play_on_new_wx_alert))
+        festival_speak_new_weather_alert=1;
+    else
+        festival_speak_new_weather_alert=0;
+
+    Configure_speech_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+//Make it helpful - Gray the config selections, but add a choice
+//that basicly pops up a box that says where to get Festival, have
+//it be ungrayed if Festival isn't installed.
+
+void Configure_speech( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel, file1,
+        sep, button_test;
+    Atom delw;
+
+    if (!configure_speech_dialog) {
+        configure_speech_dialog = XtVaCreatePopupShell(langcode("WPUPCFSP01"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Configure_speech pane",
+                xmPanedWindowWidgetClass, 
+                configure_speech_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Configure_speech my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        file1 = XtVaCreateManagedWidget(langcode("WPUPCFSP02"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_new_station  = XtVaCreateManagedWidget(langcode("WPUPCFSP03"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, file1,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_new_message_alert  = XtVaCreateManagedWidget(langcode("WPUPCFSP04"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_new_station,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_new_message_body  = XtVaCreateManagedWidget(langcode("WPUPCFSP05"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_new_message_alert,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_prox  = XtVaCreateManagedWidget(langcode("WPUPCFSP06"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_new_message_body,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_trak  = XtVaCreateManagedWidget(langcode("WPUPCFSP09"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_prox,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_bando  = XtVaCreateManagedWidget(langcode("WPUPCFSP07"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_trak,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        speech_config_play_on_new_wx_alert  = XtVaCreateManagedWidget(langcode("WPUPCFSP08"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_bando,
+                XmNtopOffset, 12,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+#ifndef HAVE_FESTIVAL
+                XmNsensitive, FALSE,
+#endif /* HAVE_FESTIVAL */
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        sep = XtVaCreateManagedWidget("Configure_speech sep", 
+                xmSeparatorGadgetClass,
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, speech_config_play_on_new_wx_alert,
+                XmNtopOffset, 20,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_test = XtVaCreateManagedWidget(langcode("PULDNFI003"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 4,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_test, XmNactivateCallback, Test_speech, configure_speech_dialog);
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_speech_change_data, configure_speech_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_speech_destroy_shell, configure_speech_dialog);
+
+        pos_dialog(configure_speech_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_speech_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(configure_speech_dialog, delw, Configure_speech_destroy_shell,
+                (XtPointer)configure_speech_dialog);
+
+
+        if(festival_speak_new_station)
+            XmToggleButtonSetState(speech_config_play_on_new_station,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_new_station,FALSE,FALSE);
+
+        if(festival_speak_new_message_alert)
+            XmToggleButtonSetState(speech_config_play_on_new_message_alert,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_new_message_alert,FALSE,FALSE);
+
+        if(festival_speak_new_message_body)
+            XmToggleButtonSetState(speech_config_play_on_new_message_body,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_new_message_body,FALSE,FALSE);
+
+        if(festival_speak_proximity_alert)
+            XmToggleButtonSetState(speech_config_play_on_prox,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_prox,FALSE,FALSE);
+
+        if(festival_speak_tracked_proximity_alert)
+            XmToggleButtonSetState(speech_config_play_on_trak,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_trak,FALSE,FALSE);
+
+        if(festival_speak_band_opening)
+            XmToggleButtonSetState(speech_config_play_on_bando,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_bando,FALSE,FALSE);
+
+        if(festival_speak_new_weather_alert)
+            XmToggleButtonSetState(speech_config_play_on_new_wx_alert,TRUE,FALSE);
+        else
+            XmToggleButtonSetState(speech_config_play_on_new_wx_alert,FALSE,FALSE);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(configure_speech_dialog,XtGrabNone);
+        fix_dialog_size(configure_speech_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(configure_speech_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_speech_dialog), XtWindow(configure_speech_dialog));
+
+}
+
+
+
+
+
+/*
+ *  Track_Me
+ *
+ */
+void Track_Me( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        xastir_snprintf(tracking_station_call,
+            sizeof(tracking_station_call),
+            "%s",
+            my_callsign);
+        track_me = atoi(which);
+        track_station_on = atoi(which);
+        display_zoom_status();
+    }
+    else {
+        track_me = 0;
+        track_station_on = 0;
+        display_zoom_status();
+    }
+}
+
+
+
+
+
+// Pointer to the Move/Measure cursor object
+static Cursor cs_move_measure = (Cursor)NULL;
+
+/*
+ *  Move_Object
+ *
+ */
+void  Move_Object( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        moving_object = atoi(which);
+        XmToggleButtonSetState(measure_button, FALSE, FALSE);
+        measuring_distance = 0;
+
+        // Change the cursor
+        if(!cs_move_measure) {
+            cs_move_measure=XCreateFontCursor(XtDisplay(da),XC_crosshair);
+        }
+
+        (void)XDefineCursor(XtDisplay(da),XtWindow(da),cs_move_measure);
+        (void)XFlush(XtDisplay(da));
+    }
+    else {
+        moving_object = 0;
+
+        // Remove the special "crosshair" cursor
+        (void)XUndefineCursor(XtDisplay(da),XtWindow(da));
+        (void)XFlush(XtDisplay(da));
+    }
+}
+
+
+
+
+
+/*
+ *  Measure_Distance
+ *
+ */
+void  Measure_Distance( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        measuring_distance = atoi(which);
+        XmToggleButtonSetState(move_button, FALSE, FALSE);
+        moving_object = 0;
+
+        // Change the cursor
+        if(!cs_move_measure) {
+            cs_move_measure=XCreateFontCursor(XtDisplay(da),XC_crosshair);
+        }
+
+        (void)XDefineCursor(XtDisplay(da),XtWindow(da),cs_move_measure);
+        (void)XFlush(XtDisplay(da));
+    }
+    else {
+        measuring_distance = 0;
+
+        // Remove the special "crosshair" cursor
+        (void)XUndefineCursor(XtDisplay(da),XtWindow(da));
+        (void)XFlush(XtDisplay(da));
+    }
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////
+
+
+
+/*
+ *  Destroy Configure Station Dialog Popup Window
+ */
+void Configure_station_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    (void)XFreePixmap(XtDisplay(appshell),CS_icon0);  // ???? DK7IN: avoid possible memory leak ?
+    (void)XFreePixmap(XtDisplay(appshell),CS_icon);
+    XtDestroyWidget(shell);
+    configure_station_dialog = (Widget)NULL;
+
+    // Take down the symbol selection dialog as well (if it's up)
+    if (select_symbol_dialog) {
+        Select_symbol_destroy_shell( widget, select_symbol_dialog, callData);
+    }
+
+    // NULL out the dialog field in the global struct used for
+    // Coordinate Calculator.  Prevents segfaults if the calculator is
+    // still up and trying to write to us.
+    coordinate_calc_array.calling_dialog = NULL;
+}
+
+
+
+
+
+void  Configure_station_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        Configure_station_pos_amb = atoi(which);
+    else
+        Configure_station_pos_amb = 0;
+}
+
+
+
+
+
+/*
+ *  Process changes to station data
+ */
+void Configure_station_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+    char temp[40];
+    char old_callsign[MAX_CALLSIGN+1];
+    int ok = 1;
+    int temp2;
+    int temp3;
+    char *temp_ptr;
+    char *temp_ptr2;
+
+
+    transmit_compressed_posit = (int)XmToggleButtonGetState(compressed_posit_tx);
+
+    xastir_snprintf(old_callsign,
+        sizeof(old_callsign),
+        "%s",
+        my_callsign);
+
+    /*fprintf(stderr,"Changing Configure station data\n");*/
+
+    temp_ptr = XmTextFieldGetString(station_config_call_data);
+    xastir_snprintf(my_callsign,
+        sizeof(my_callsign),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(my_callsign);
+    (void)to_upper(my_callsign);
+    (void)remove_trailing_dash_zero(my_callsign);
+
+    // Enter NOCALL if there's nothing left.
+    if (my_callsign[0] == '\0')
+        xastir_snprintf(my_callsign,
+            sizeof(my_callsign),
+            "NOCALL");
+
+    temp_ptr = XmTextFieldGetString(station_config_slat_data_ns);
+    if((char)toupper((int)temp_ptr[0])=='S')
+        temp[0]='S';
+    else
+        temp[0]='N';
+    XtFree(temp_ptr);
+
+    // Check latitude for out-of-bounds
+    temp_ptr = XmTextFieldGetString(station_config_slat_data_deg);
+    temp2 = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    if ( (temp2 > 90) || (temp2 < 0) )
+        ok = 0;
+
+    temp_ptr = XmTextFieldGetString(station_config_slat_data_min);
+    temp3 = atof(temp_ptr);
+    XtFree(temp_ptr);
+
+    if ( (temp3 >= 60.0) || (temp3 < 0.0) )
+        ok = 0;
+
+    if ( (temp2 == 90) && (temp3 != 0.0) )
+        ok = 0;
+
+    temp_ptr = XmTextFieldGetString(station_config_slat_data_deg);
+    temp_ptr2 = XmTextFieldGetString(station_config_slat_data_min);
+    xastir_snprintf(my_lat, sizeof(my_lat), "%02d%06.3f%c",
+        atoi(temp_ptr),
+        atof(temp_ptr2),temp[0]);
+    XtFree(temp_ptr);
+    XtFree(temp_ptr2);
+
+    temp_ptr = XmTextFieldGetString(station_config_slong_data_ew);
+    if((char)toupper((int)temp_ptr[0])=='E')
+        temp[0]='E';
+    else
+        temp[0]='W';
+    XtFree(temp_ptr);
+
+    // Check longitude for out-of-bounds
+    temp_ptr = XmTextFieldGetString(station_config_slong_data_deg);
+    temp2 = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    if ( (temp2 > 180) || (temp2 < 0) )
+        ok = 0;
+
+    temp_ptr = XmTextFieldGetString(station_config_slong_data_min);
+    temp3 = atof(temp_ptr);
+    XtFree(temp_ptr);
+
+    if ( (temp3 >= 60.0) || (temp3 < 0.0) )
+        ok = 0;
+
+    if ( (temp2 == 180) && (temp3 != 0.0) )
+        ok = 0;
+
+    temp_ptr = XmTextFieldGetString(station_config_slong_data_deg);
+    temp_ptr2 = XmTextFieldGetString(station_config_slong_data_min);
+    xastir_snprintf(my_long, sizeof(my_long), "%03d%06.3f%c",
+            atoi(temp_ptr),
+            atof(temp_ptr2),temp[0]);
+    XtFree(temp_ptr);
+    XtFree(temp_ptr2);
+
+    temp_ptr = XmTextFieldGetString(station_config_group_data);
+    my_group=temp_ptr[0];
+    if(isalpha((int)my_group))
+        my_group = toupper((int)temp_ptr[0]);
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(station_config_symbol_data);
+    my_symbol = temp_ptr[0];
+    XtFree(temp_ptr);
+
+    if(isdigit((int)my_phg[3]) && isdigit((int)my_phg[4]) && isdigit((int)my_phg[5]) && isdigit((int)my_phg[6])) {
+        my_phg[0] = 'P';
+        my_phg[1] = 'H';
+        my_phg[2] = 'G';
+        my_phg[7] = '\0';
+    } else
+        my_phg[0]='\0';
+
+    /* set station ambiguity*/
+    position_amb_chars = Configure_station_pos_amb;
+
+    if (transmit_compressed_posit) {
+        position_amb_chars = 0;
+    }
+
+    temp_ptr = XmTextFieldGetString(station_config_comment_data);
+    xastir_snprintf(my_comment,
+        sizeof(my_comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(my_comment);
+
+    /* TO DO: KILL only my station data? */
+    if (ok) {   // If entered data was valid
+
+        // Check whether we changed our callsign
+        if (strcasecmp(old_callsign,my_callsign) != 0) {
+            station_del(old_callsign);  // move to new sort location...
+
+            // If TrackMe is enabled, copy the new callsign into the
+            // track_station_call variable.  If we don't do this, we
+            // will still be tracking our old callsign.
+            if (track_me) {
+                xastir_snprintf(tracking_station_call,
+                    sizeof(tracking_station_call),
+                    "%s",
+                    my_callsign);
+            }
+        }
+
+        // Update our parameters
+        my_station_add(my_callsign,my_group,my_symbol,my_long,my_lat,my_phg,my_comment,(char)position_amb_chars);
+
+        redraw_on_new_data=2;
+        Configure_station_destroy_shell(widget,clientData,callData);
+    }
+
+    // Check for proper weather symbols if a weather station
+    (void)check_weather_symbol();
+
+    // Check for use of NWS symbols
+    (void)check_nws_weather_symbol();
+}
+
+
+
+
+
+/*
+ *  Update symbol picture for changed symbol or table
+ */
+void updateSymbolPictureCallback( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char table, overlay;
+    char symb, group;
+    char *temp_ptr;
+
+
+    XtVaSetValues(station_config_icon, XmNlabelPixmap, CS_icon0, NULL);         // clear old icon
+    XtManageChild(station_config_icon);
+
+    temp_ptr = XmTextFieldGetString(station_config_group_data);
+    group = temp_ptr[0];
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(station_config_symbol_data);
+    symb  = temp_ptr[0];
+    XtFree(temp_ptr);
+
+    if (group == '/' || group == '\\') {
+        table   = group;
+        overlay = ' ';
+    } else {
+        table   = '\\';
+        overlay = group;
+    }
+    symbol(station_config_icon,0,table,symb,overlay,CS_icon,0,0,0,' ');         // create icon
+
+    XtVaSetValues(station_config_icon,XmNlabelPixmap,CS_icon,NULL);             // draw new icon
+    XtManageChild(station_config_icon);
+}
+
+
+
+
+
+/* Power radio buttons */
+void Power_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+
+        my_phg[3] = which[0];   // Set to power desired
+
+        if (which[0] == 'x') {     // Disable PHG field if 'x' found
+            my_phg[0] = '\0';
+        }
+    } else {
+        my_phg[3] = '3';  // 10 Watts (default in spec if none specified)
+    }
+    my_phg[8] = '\0';
+
+    //fprintf(stderr,"PHG: %s\n",my_phg);
+}
+
+
+
+
+
+/* Height radio buttons */
+void Height_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        my_phg[4] = which[0];    // Set to height desired
+    } else {
+        my_phg[4] = '1';  // 20 Feet above average terrain (default in spec if none specified)
+    }
+    my_phg[8] = '\0';
+
+    //fprintf(stderr,"PHG: %s\n",my_phg);
+}
+
+
+
+
+
+
+/* Gain radio buttons */
+void Gain_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        my_phg[5] = which[0];    // Set to gain desired
+    } else {
+        my_phg[5] = '3';  // 3dB gain antenna (default in spec if none specified)
+    }
+    my_phg[8] = '\0';
+
+    //fprintf(stderr,"PHG: %s\n",my_phg);
+}
+
+
+
+
+
+
+/* Directivity radio buttons */
+void Directivity_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        my_phg[6] = which[0];    // Set to directivity desired
+    } else {
+        my_phg[6] = '0';  // Omni-directional antenna (default in spec if none specified)
+    }
+    my_phg[8] = '\0';
+
+    //fprintf(stderr,"PHG: %s\n",my_phg);
+}
+
+
+
+
+
+void Posit_compressed_toggle( /*@unused@*/ Widget w, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        transmit_compressed_posit = atoi(which);
+    else
+        transmit_compressed_posit = 0;
+
+    if(transmit_compressed_posit) {
+        // Compressed posits don't allow position ambiguity
+        position_amb_chars = 0;
+        XtSetSensitive(posamb0,FALSE);
+        XtSetSensitive(posamb1,FALSE);
+        XtSetSensitive(posamb2,FALSE);
+        XtSetSensitive(posamb3,FALSE);
+        XtSetSensitive(posamb4,FALSE);
+    }
+    else {  // Position ambiguity ok for this mode
+        XtSetSensitive(posamb0,TRUE);
+        XtSetSensitive(posamb1,TRUE);
+        XtSetSensitive(posamb2,TRUE);
+        XtSetSensitive(posamb3,TRUE);
+        XtSetSensitive(posamb4,TRUE);
+    }
+}
+
+
+
+
+
+/*
+ *  Select a symbol graphically
+ */
+void Configure_change_symbol(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+
+    //fprintf(stderr,"Trying to change a symbol\n");
+    symbol_change_requested_from = 1;   // Tell Select_symbol who to return the data to
+    Select_symbol(widget, clientData, callData);
+}
+
+
+
+
+
+
+/*
+ *  Setup Configure Station dialog
+ */
+void Configure_station( /*@unused@*/ Widget ww, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, cs_form, cs_form1, button_ok, button_cancel, call, frame, frame2,
+                framephg, pg2, formphg,
+                power_box,poption0,poption1,poption2,poption3,poption4,poption5,poption6,poption7,poption8,poption9,poption10,
+                height_box,hoption1,hoption2,hoption3,hoption4,hoption5,hoption6,hoption7,hoption8,hoption9,hoption10,
+                gain_box,goption1,goption2,goption3,goption4,goption5,goption6,goption7,goption8,goption9,goption10,
+                directivity_box,doption1,doption2,doption3,doption4,doption5,doption6,doption7,doption8,doption9,
+                slat,
+                slat_deg,  slat_min, slat_ns,
+                slong,
+                slong_deg, slong_min, slong_ew,
+                sts, group, st_symbol, comment,
+                posamb,option_box,
+                sep, configure_button_symbol, compute_button;
+    char temp_data[40];
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+
+    if(!configure_station_dialog) {
+        configure_station_dialog = XtVaCreatePopupShell(langcode("WPUPCFS001"),
+                xmDialogShellWidgetClass,   appshell,
+                XmNdeleteResponse,          XmDESTROY,
+                XmNdefaultPosition,         FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Configure_station pane",
+                xmPanedWindowWidgetClass, 
+                configure_station_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        cs_form =  XtVaCreateWidget("Configure_station cs_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase,            5,
+                XmNautoUnmanage,            FALSE,
+                XmNshadowThickness,         1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        call = XtVaCreateManagedWidget(langcode("WPUPCFS002"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_call_data = XtVaCreateManagedWidget("Configure_station call_data", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 10,
+                XmNwidth,                   ((10*7)+2),
+                XmNmaxLength,               9,
+                XmNbackground,              colors[0x0f],
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            1,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        compressed_posit_tx = XtVaCreateManagedWidget(langcode("WPUPCFS029"),
+                xmToggleButtonWidgetClass,
+                cs_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            3,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(compressed_posit_tx,XmNvalueChangedCallback,Posit_compressed_toggle,"1");
+ 
+        slat = XtVaCreateManagedWidget(langcode("WPUPCFS003"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNtopOffset,               25,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_slat_data_deg = XtVaCreateManagedWidget("Configure_station lat_deg", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               2,
+                XmNtopOffset,               20,
+                XmNbackground,              colors[0x0f],
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            1,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slat_deg = XtVaCreateManagedWidget(langcode("WPUPCFS004"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNtopOffset,               25,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_slat_data_deg,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_slat_data_min = XtVaCreateManagedWidget("Configure_station lat_min", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 6,
+                XmNmaxLength,               6,
+                XmNtopOffset,               20,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              slat_deg,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slat_min = XtVaCreateManagedWidget(langcode("WPUPCFS005"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNtopOffset,               25,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_slat_data_min,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_slat_data_ns = XtVaCreateManagedWidget("Configure_station lat_ns", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               20,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              slat_min,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slat_ns = XtVaCreateManagedWidget(langcode("WPUPCFS006"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               call,
+                XmNtopOffset,               25,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_slat_data_ns,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slong = XtVaCreateManagedWidget(langcode("WPUPCFS007"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_slong_data_deg = XtVaCreateManagedWidget("Configure_station long_deg", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               3,
+                XmNtopOffset,               14,
+                XmNbackground,              colors[0x0f],
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            1,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slong_deg = XtVaCreateManagedWidget(langcode("WPUPCFS004"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_slong_data_deg,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_slong_data_min = XtVaCreateManagedWidget("Configure_station long_min", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 6,
+                XmNmaxLength,               6,
+                XmNtopOffset,               14,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              slong_deg,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slong_min = XtVaCreateManagedWidget(langcode("WPUPCFS005"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_slong_data_min,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        station_config_slong_data_ew = XtVaCreateManagedWidget("Configure_station long_ew", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               14,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              slong_min,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        slong_ew = XtVaCreateManagedWidget(langcode("WPUPCFS008"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_slong_data_ew,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        compute_button = XtVaCreateManagedWidget(langcode("COORD002"),
+                xmPushButtonGadgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              slong_ew,
+                XmNleftOffset,              15,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Fill in the pointers to our input textfields so that the
+        // coordinate calculator can fiddle with them.
+        coordinate_calc_array.calling_dialog = configure_station_dialog;
+        coordinate_calc_array.input_lat_deg = station_config_slat_data_deg;
+        coordinate_calc_array.input_lat_min = station_config_slat_data_min;
+        coordinate_calc_array.input_lat_dir = station_config_slat_data_ns;
+        coordinate_calc_array.input_lon_deg = station_config_slong_data_deg;
+        coordinate_calc_array.input_lon_min = station_config_slong_data_min;
+        coordinate_calc_array.input_lon_dir = station_config_slong_data_ew;
+//        XtAddCallback(compute_button, XmNactivateCallback, Coordinate_calc, configure_station_dialog);
+//        XtAddCallback(compute_button, XmNactivateCallback, Coordinate_calc, "Configure_station");
+        XtAddCallback(compute_button, XmNactivateCallback, Coordinate_calc, langcode("WPUPCFS001"));
+
+
+
+
+//----- Frame for table / symbol
+        frame = XtVaCreateManagedWidget("Configure_station frame", 
+                xmFrameWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               slong_ew,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+        // "Station Symbol"
+        sts  = XtVaCreateManagedWidget(langcode("WPUPCFS009"),
+                xmLabelWidgetClass,
+                frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        cs_form1 =  XtVaCreateWidget("Configure_station cs_form1",
+                xmFormWidgetClass, 
+                frame,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Group/overlay"
+        group = XtVaCreateManagedWidget(langcode("WPUPCFS010"),
+                xmLabelWidgetClass, 
+                cs_form1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              100,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // table
+        station_config_group_data = XtVaCreateManagedWidget("Configure_station group", 
+                xmTextFieldWidgetClass, 
+                cs_form1,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               6,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              group,
+                XmNleftOffset,              5,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Symbol"
+        st_symbol = XtVaCreateManagedWidget(langcode("WPUPCFS011"),
+                xmLabelWidgetClass, 
+                cs_form1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_group_data,
+                XmNleftOffset,              20,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // symbol
+        station_config_symbol_data = XtVaCreateManagedWidget("Configure_station symbol", 
+                xmTextFieldWidgetClass, 
+                cs_form1,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               6,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              st_symbol,
+                XmNleftOffset,              5,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // icon
+        CS_icon0 = XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                DefaultDepthOfScreen(XtScreen(appshell)));
+        CS_icon  = XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                DefaultDepthOfScreen(XtScreen(appshell)));
+        station_config_icon = XtVaCreateManagedWidget("Configure_station icon", 
+                xmLabelWidgetClass, 
+                cs_form1,
+                XmNlabelType,               XmPIXMAP,
+                XmNlabelPixmap,             CS_icon,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_symbol_data,
+                XmNleftOffset,              15,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        configure_button_symbol = XtVaCreateManagedWidget(langcode("WPUPCFS028"),
+                xmPushButtonGadgetClass, 
+                cs_form1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               6,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              station_config_icon,
+                XmNleftOffset,              15,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(configure_button_symbol, XmNactivateCallback, Configure_change_symbol, configure_station_dialog);
+
+ 
+//----- Frame for Power-Gain
+        framephg = XtVaCreateManagedWidget("Configure_station framephg", 
+                xmFrameWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               frame,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        pg2  = XtVaCreateManagedWidget(langcode("WPUPCFS012"),
+                xmLabelWidgetClass,
+                framephg,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        formphg =  XtVaCreateWidget("Configure_station power_form",
+                xmFormWidgetClass,
+                framephg,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // Power
+        ac = 0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        power_box = XmCreateRadioBox(formphg,
+                "Configure_station Power Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(power_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,11,
+                NULL);
+
+        poption0 = XtVaCreateManagedWidget(langcode("WPUPCFS013"),
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption0,XmNvalueChangedCallback,Power_toggle,"x");
+
+        // 0 Watts
+        poption1 = XtVaCreateManagedWidget("0W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption1,XmNvalueChangedCallback,Power_toggle,"0");
+
+        // 1 Watt
+        poption2 = XtVaCreateManagedWidget("1W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption2,XmNvalueChangedCallback,Power_toggle,"1");
+
+        // 4 Watts
+        poption3 = XtVaCreateManagedWidget("4W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption3,XmNvalueChangedCallback,Power_toggle,"2");
+
+        // 9 Watts
+        poption4 = XtVaCreateManagedWidget("9W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption4,XmNvalueChangedCallback,Power_toggle,"3");
+
+        // 16 Watts
+        poption5 = XtVaCreateManagedWidget("16W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption5,XmNvalueChangedCallback,Power_toggle,"4");
+
+        // 25 Watts
+        poption6 = XtVaCreateManagedWidget("25W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption6,XmNvalueChangedCallback,Power_toggle,"5");
+
+        // 36 Watts
+        poption7 = XtVaCreateManagedWidget("36W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption7,XmNvalueChangedCallback,Power_toggle,"6");
+
+        // 49 Watts
+        poption8 = XtVaCreateManagedWidget("49W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption8,XmNvalueChangedCallback,Power_toggle,"7");
+
+        // 64 Watts
+        poption9 = XtVaCreateManagedWidget("64W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption9,XmNvalueChangedCallback,Power_toggle,"8");
+
+        // 81 Watts
+        poption10 = XtVaCreateManagedWidget("81W",
+                xmToggleButtonGadgetClass,
+                power_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(poption10,XmNvalueChangedCallback,Power_toggle,"9");
+
+
+        // Height
+        height_box = XmCreateRadioBox(formphg,
+                "Configure_station Height Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(height_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,power_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,10,
+                NULL);
+
+
+        // 10 Feet
+        hoption1 = XtVaCreateManagedWidget(
+                (english_units) ? "10ft" : "3m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption1,XmNvalueChangedCallback,Height_toggle,"0");
+
+        // 20 Feet
+        hoption2 = XtVaCreateManagedWidget(
+                (english_units) ? "20ft" : "6m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption2,XmNvalueChangedCallback,Height_toggle,"1");
+
+        // 40 Feet
+        hoption3 = XtVaCreateManagedWidget(
+                (english_units) ? "40ft" : "12m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption3,XmNvalueChangedCallback,Height_toggle,"2");
+
+        // 80 Feet
+        hoption4 = XtVaCreateManagedWidget(
+                (english_units) ? "80ft" : "24m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption4,XmNvalueChangedCallback,Height_toggle,"3");
+
+        // 160 Feet
+        hoption5 = XtVaCreateManagedWidget(
+                (english_units) ? "160ft" : "49m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption5,XmNvalueChangedCallback,Height_toggle,"4");
+
+        // 320 Feet
+        hoption6 = XtVaCreateManagedWidget(
+                (english_units) ? "320ft" : "98m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption6,XmNvalueChangedCallback,Height_toggle,"5");
+
+        // 640 Feet
+        hoption7 = XtVaCreateManagedWidget(
+                (english_units) ? "640ft" : "195m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption7,XmNvalueChangedCallback,Height_toggle,"6");
+
+        // 1280 Feet
+        hoption8 = XtVaCreateManagedWidget(
+                (english_units) ? "1280ft" : "390m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption8,XmNvalueChangedCallback,Height_toggle,"7");
+
+        // 2560 Feet
+        hoption9 = XtVaCreateManagedWidget(
+                (english_units) ? "2560ft" : "780m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption9,XmNvalueChangedCallback,Height_toggle,"8");
+
+        // 5120 Feet
+        hoption10 = XtVaCreateManagedWidget(
+                (english_units) ? "5120ft" : "1561m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption10,XmNvalueChangedCallback,Height_toggle,"9");
+
+
+        // Gain
+        gain_box = XmCreateRadioBox(formphg,
+                "Configure_station Gain Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(gain_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,height_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,10,
+                NULL);
+
+
+        // 0 dB
+        goption1 = XtVaCreateManagedWidget("0dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption1,XmNvalueChangedCallback,Gain_toggle,"0");
+
+        // 1 dB
+        goption2 = XtVaCreateManagedWidget("1dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption2,XmNvalueChangedCallback,Gain_toggle,"1");
+
+        // 2 dB
+        goption3 = XtVaCreateManagedWidget("2dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption3,XmNvalueChangedCallback,Gain_toggle,"2");
+
+        // 3 dB
+        goption4 = XtVaCreateManagedWidget("3dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption4,XmNvalueChangedCallback,Gain_toggle,"3");
+
+        // 4 dB
+        goption5 = XtVaCreateManagedWidget("4dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption5,XmNvalueChangedCallback,Gain_toggle,"4");
+
+        // 5 dB
+        goption6 = XtVaCreateManagedWidget("5dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption6,XmNvalueChangedCallback,Gain_toggle,"5");
+
+        // 6 dB
+        goption7 = XtVaCreateManagedWidget("6dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption7,XmNvalueChangedCallback,Gain_toggle,"6");
+
+        // 7 dB
+        goption8 = XtVaCreateManagedWidget("7dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption8,XmNvalueChangedCallback,Gain_toggle,"7");
+
+        // 8 dB
+        goption9 = XtVaCreateManagedWidget("8dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption9,XmNvalueChangedCallback,Gain_toggle,"8");
+
+        // 9 dB
+        goption10 = XtVaCreateManagedWidget("9dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption10,XmNvalueChangedCallback,Gain_toggle,"9");
+
+
+        // Gain
+        directivity_box = XmCreateRadioBox(formphg,
+                "Configure_station Directivity Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(directivity_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,gain_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,10,
+                NULL);
+
+
+        // Omni-directional
+        doption1 = XtVaCreateManagedWidget(langcode("WPUPCFS016"), // Omni
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption1,XmNvalueChangedCallback,Directivity_toggle,"0");
+
+        // 45 NE
+        doption2 = XtVaCreateManagedWidget("45�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption2,XmNvalueChangedCallback,Directivity_toggle,"1");
+
+        // 90 E
+        doption3 = XtVaCreateManagedWidget("90�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption3,XmNvalueChangedCallback,Directivity_toggle,"2");
+
+        // 135 SE
+        doption4 = XtVaCreateManagedWidget("135�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption4,XmNvalueChangedCallback,Directivity_toggle,"3");
+
+        // 180 S
+        doption5 = XtVaCreateManagedWidget("180�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption5,XmNvalueChangedCallback,Directivity_toggle,"4");
+
+        // 225 SW
+        doption6 = XtVaCreateManagedWidget("225�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption6,XmNvalueChangedCallback,Directivity_toggle,"5");
+
+        // 270 W
+        doption7 = XtVaCreateManagedWidget("270�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption7,XmNvalueChangedCallback,Directivity_toggle,"6");
+
+        // 315 NW
+        doption8 = XtVaCreateManagedWidget("315�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption8,XmNvalueChangedCallback,Directivity_toggle,"7");
+
+        // 360 N
+        doption9 = XtVaCreateManagedWidget("360�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption9,XmNvalueChangedCallback,Directivity_toggle,"8");
+
+ 
+//-----------------------
+        comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),
+                xmLabelWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               framephg,
+                XmNtopOffset,               15,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        station_config_comment_data = XtVaCreateManagedWidget("Configure_station comment", 
+                xmTextFieldWidgetClass, 
+                cs_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 60,
+                XmNwidth,                   ((60*7)+2),
+                XmNmaxLength,               MAX_COMMENT,
+                XmNtopOffset,               11,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              comment,
+                XmNleftOffset,              5,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               framephg,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+//Position Ambiguity Frame
+        frame2 = XtVaCreateManagedWidget("Configure_station frame2", 
+                xmFrameWidgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               comment,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        posamb  = XtVaCreateManagedWidget(langcode("WPUPCFS018"),
+                xmLabelWidgetClass,
+                frame2,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        /*set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        option_box = XmCreateRadioBox(frame2,
+                "Configure_station Option box",
+                al,
+                ac);
+
+        XtVaSetValues(option_box,
+                XmNnumColumns,5,
+                NULL);
+
+        posamb0 = XtVaCreateManagedWidget(langcode("WPUPCFS019"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(posamb0,XmNvalueChangedCallback,Configure_station_toggle,"0");
+
+        posamb1 = XtVaCreateManagedWidget(english_units?langcode("WPUPCFS020"):langcode("WPUPCFS024"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(posamb1,XmNvalueChangedCallback,Configure_station_toggle,"1");
+
+
+        posamb2 = XtVaCreateManagedWidget(english_units?langcode("WPUPCFS021"):langcode("WPUPCFS025"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(posamb2,XmNvalueChangedCallback,Configure_station_toggle,"2");
+
+        posamb3 = XtVaCreateManagedWidget(english_units?langcode("WPUPCFS022"):langcode("WPUPCFS026"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(posamb3,XmNvalueChangedCallback,Configure_station_toggle,"3");
+
+        posamb4 = XtVaCreateManagedWidget(english_units?langcode("WPUPCFS023"):langcode("WPUPCFS027"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(posamb4,XmNvalueChangedCallback,Configure_station_toggle,"4");
+
+        sep = XtVaCreateManagedWidget("Configure_station sep", 
+                xmSeparatorGadgetClass,
+                cs_form,
+                XmNorientation,             XmHORIZONTAL,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               frame2,
+                XmNtopOffset,               14,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               sep,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            5,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            1,
+                XmNrightAttachment,         XmATTACH_POSITION,
+                XmNrightPosition,           2,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                cs_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               sep,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            5,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            3,
+                XmNrightAttachment,         XmATTACH_POSITION,
+                XmNrightPosition,           4,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Configure_station_change_data, configure_station_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Configure_station_destroy_shell, configure_station_dialog);
+
+        // fill in current data
+        XmTextFieldSetString(station_config_call_data,my_callsign);
+
+        substr(temp_data,my_lat,2);
+        XmTextFieldSetString(station_config_slat_data_deg,temp_data);
+        substr(temp_data,my_lat+2,6);
+        XmTextFieldSetString(station_config_slat_data_min,temp_data);
+        substr(temp_data,my_lat+8,1);
+        XmTextFieldSetString(station_config_slat_data_ns,temp_data);
+
+        substr(temp_data,my_long,3);
+        XmTextFieldSetString(station_config_slong_data_deg,temp_data);
+        substr(temp_data,my_long+3,6);
+        XmTextFieldSetString(station_config_slong_data_min,temp_data);
+        substr(temp_data,my_long+9,1);
+        XmTextFieldSetString(station_config_slong_data_ew,temp_data);
+
+        temp_data[0] = my_group;
+        temp_data[1] = '\0';
+        XmTextFieldSetString(station_config_group_data,temp_data);
+        XtAddCallback(station_config_group_data, XmNvalueChangedCallback, updateSymbolPictureCallback, configure_station_dialog);
+
+        temp_data[0] = my_symbol;
+        temp_data[1] = '\0';
+        XmTextFieldSetString(station_config_symbol_data,temp_data);
+        XtAddCallback(station_config_symbol_data, XmNvalueChangedCallback, updateSymbolPictureCallback, configure_station_dialog);
+
+        // update symbol picture
+        (void)updateSymbolPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+
+
+        if (my_phg[0]=='P') {
+            switch (my_phg[3]) {
+                case '0':
+                    XmToggleButtonGadgetSetState(poption1, TRUE, TRUE);
+                    break;
+                case '1':
+                    XmToggleButtonGadgetSetState(poption2, TRUE, TRUE);
+                    break;
+                case '2':
+                    XmToggleButtonGadgetSetState(poption3, TRUE, TRUE);
+                    break;
+                case '3':
+                    XmToggleButtonGadgetSetState(poption4, TRUE, TRUE);
+                    break;
+                case '4':
+                    XmToggleButtonGadgetSetState(poption5, TRUE, TRUE);
+                    break;
+                case '5':
+                    XmToggleButtonGadgetSetState(poption6, TRUE, TRUE);
+                    break;
+                case '6':
+                    XmToggleButtonGadgetSetState(poption7, TRUE, TRUE);
+                    break;
+                case '7':
+                    XmToggleButtonGadgetSetState(poption8, TRUE, TRUE);
+                    break;
+                case '8':
+                    XmToggleButtonGadgetSetState(poption9, TRUE, TRUE);
+                    break;
+                case '9':
+                    XmToggleButtonGadgetSetState(poption10, TRUE, TRUE);
+                    break;
+                case 'x':
+                default:
+                    XmToggleButtonGadgetSetState(poption0, TRUE, TRUE);
+                    break;
+            }
+            switch (my_phg[4]) {
+                case '0':
+                    XmToggleButtonGadgetSetState(hoption1, TRUE, TRUE);
+                    break;
+                case '1':
+                    XmToggleButtonGadgetSetState(hoption2, TRUE, TRUE);
+                    break;
+                case '2':
+                    XmToggleButtonGadgetSetState(hoption3, TRUE, TRUE);
+                    break;
+                case '3':
+                    XmToggleButtonGadgetSetState(hoption4, TRUE, TRUE);
+                    break;
+                case '4':
+                    XmToggleButtonGadgetSetState(hoption5, TRUE, TRUE);
+                    break;
+                case '5':
+                    XmToggleButtonGadgetSetState(hoption6, TRUE, TRUE);
+                    break;
+                case '6':
+                    XmToggleButtonGadgetSetState(hoption7, TRUE, TRUE);
+                    break;
+                case '7':
+                    XmToggleButtonGadgetSetState(hoption8, TRUE, TRUE);
+                    break;
+                case '8':
+                    XmToggleButtonGadgetSetState(hoption9, TRUE, TRUE);
+                    break;
+                case '9':
+                    XmToggleButtonGadgetSetState(hoption10, TRUE, TRUE);
+                    break;
+                default:
+                    break;
+            }
+            switch (my_phg[5]) {
+                case '0':
+                    XmToggleButtonGadgetSetState(goption1, TRUE, TRUE);
+                    break;
+                case '1':
+                    XmToggleButtonGadgetSetState(goption2, TRUE, TRUE);
+                    break;
+                case '2':
+                    XmToggleButtonGadgetSetState(goption3, TRUE, TRUE);
+                    break;
+                case '3':
+                    XmToggleButtonGadgetSetState(goption4, TRUE, TRUE);
+                    break;
+                case '4':
+                    XmToggleButtonGadgetSetState(goption5, TRUE, TRUE);
+                    break;
+                case '5':
+                    XmToggleButtonGadgetSetState(goption6, TRUE, TRUE);
+                    break;
+                case '6':
+                    XmToggleButtonGadgetSetState(goption7, TRUE, TRUE);
+                    break;
+                case '7':
+                    XmToggleButtonGadgetSetState(goption8, TRUE, TRUE);
+                    break;
+                case '8':
+                    XmToggleButtonGadgetSetState(goption9, TRUE, TRUE);
+                    break;
+                case '9':
+                    XmToggleButtonGadgetSetState(goption10, TRUE, TRUE);
+                    break;
+                default:
+                    break;
+            }
+            switch (my_phg[6]) {
+                case '0':
+                    XmToggleButtonGadgetSetState(doption1, TRUE, TRUE);
+                    break;
+                case '1':
+                    XmToggleButtonGadgetSetState(doption2, TRUE, TRUE);
+                    break;
+                case '2':
+                    XmToggleButtonGadgetSetState(doption3, TRUE, TRUE);
+                    break;
+                case '3':
+                    XmToggleButtonGadgetSetState(doption4, TRUE, TRUE);
+                    break;
+                case '4':
+                    XmToggleButtonGadgetSetState(doption5, TRUE, TRUE);
+                    break;
+                case '5':
+                    XmToggleButtonGadgetSetState(doption6, TRUE, TRUE);
+                    break;
+                case '6':
+                    XmToggleButtonGadgetSetState(doption7, TRUE, TRUE);
+                    break;
+                case '7':
+                    XmToggleButtonGadgetSetState(doption8, TRUE, TRUE);
+                    break;
+                case '8':
+                    XmToggleButtonGadgetSetState(doption9, TRUE, TRUE);
+                    break;
+                default:
+                    break;
+            }
+        } else {  // PHG field disabled
+            XmToggleButtonGadgetSetState(poption0, TRUE, TRUE);
+        }
+
+
+        XmTextFieldSetString(station_config_comment_data,my_comment);
+
+
+        if(transmit_compressed_posit) {
+            // Compressed posits don't allow position ambiguity
+            XmToggleButtonSetState(compressed_posit_tx,TRUE,FALSE);
+            position_amb_chars = 0;
+            XtSetSensitive(posamb0,FALSE);
+            XtSetSensitive(posamb1,FALSE);
+            XtSetSensitive(posamb2,FALSE);
+            XtSetSensitive(posamb3,FALSE);
+            XtSetSensitive(posamb4,FALSE);
+        }
+        else {  // Position ambiguity ok for this mode
+            XmToggleButtonSetState(compressed_posit_tx,FALSE,FALSE);
+
+            XtSetSensitive(posamb0,TRUE);
+            XtSetSensitive(posamb1,TRUE);
+            XtSetSensitive(posamb2,TRUE);
+            XtSetSensitive(posamb3,TRUE);
+            XtSetSensitive(posamb4,TRUE);
+        }
+ 
+        Configure_station_pos_amb = position_amb_chars;
+        switch (Configure_station_pos_amb) {
+            case(0):
+                XmToggleButtonSetState(posamb0,TRUE,FALSE);
+                break;
+
+            case(1):
+                XmToggleButtonSetState(posamb1,TRUE,FALSE);
+                break;
+
+            case(2):
+                XmToggleButtonSetState(posamb2,TRUE,FALSE);
+                break;
+
+            case(3):
+                XmToggleButtonSetState(posamb3,TRUE,FALSE);
+                break;
+
+            case(4):
+                XmToggleButtonSetState(posamb4,TRUE,FALSE);
+                break;
+
+            default:
+                XmToggleButtonSetState(posamb0,TRUE,FALSE);
+                break;
+        }
+
+        pos_dialog(configure_station_dialog);
+
+        delw = XmInternAtom(XtDisplay(configure_station_dialog),"WM_DELETE_WINDOW", FALSE);
+
+        XmAddWMProtocolCallback(configure_station_dialog, delw, Configure_station_destroy_shell, (XtPointer)configure_station_dialog);
+
+        XtManageChild(cs_form);
+        XtManageChild(cs_form1);
+        XtManageChild(option_box);
+        XtManageChild(power_box);
+        XtManageChild(height_box);
+        XtManageChild(gain_box);
+        XtManageChild(directivity_box);
+        XtManageChild(formphg);
+        XtManageChild(pane);
+
+        XtPopup(configure_station_dialog,XtGrabNone);
+
+        fix_dialog_size(configure_station_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(configure_station_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(configure_station_dialog), XtWindow(configure_station_dialog));
+}
+
+
+
+
+
+// Borrowed from the libiberty library, a GPL'ed program.
+//
+void freeargv (char **vector) {
+    register char **scan;
+
+    if (vector != NULL) {
+        for (scan = vector; *scan != NULL; scan++) {
+            free (*scan);
+        }
+        free (vector);
+    }
+}
+
+
+
+
+
+// Borrowed from the libiberty library, a GPL'ed program.
+//
+char **dupargv (char **argv) {
+    int argc;
+    char **copy;
+  
+    if (argv == NULL)
+        return NULL;
+  
+    /* the vector */
+    for (argc = 0; argv[argc] != NULL; argc++);
+
+    copy = (char **) calloc ((argc + 1), sizeof (char *));
+
+    if (copy == NULL)
+        return NULL;
+  
+    /* the strings */
+    for (argc = 0; argv[argc] != NULL; argc++) {
+        int len = strlen (argv[argc]);
+
+        copy[argc] = malloc (sizeof (char *) * (len + 1));
+        if (copy[argc] == NULL) {
+            freeargv (copy);
+            return NULL;
+        }
+        strcpy (copy[argc], argv[argc]);
+    }
+    copy[argc] = NULL;
+    return copy;
+}
+
+
+
+
+
+/////////////////////////////////////////////   main   /////////////////////////////////////////////
+
+
+// Third argument is now deprecated
+//int main(int argc, char *argv[], char *envp[]) {
+
+int main(int argc, char *argv[], char *envp[]) {
+    int ag, ag_error, trap_segfault, deselect_maps_on_startup;
+    uid_t user_id;
+    struct passwd *user_info;
+    static char lang_to_use_or[30];
+    char temp[100];
+    static char *Geometry = NULL;
+    static int xt = 0;
+    char temp_base_dir[MAX_VALUE];
+
+    // Define some overriding resources for the widgets.
+    // Look at files in /usr/X11/lib/X11/app-defaults for ideas.
+    String fallback_resources[] = {
+
+//        "Mwm*iconImageForeground: #000000000000\n",
+
+        "*initialResourcesPersistent: False\n",
+
+// Default font if nothing else overrides it:
+        "*.fontList:    fixed\n",
+
+        "*List.Translations: #override \n\
+        <Key>Return:    Select(children)\n\
+        <Key>space:     Select(children)\n",
+ 
+        "*List.baseTranslations: #override \n\
+        <Key>Return:    Select(children)\n\
+        <Key>space:     Select(children)\n",
+ 
+        "*XmTextField.translations: #override \
+        <Key>Return:    activate()\n\
+        <Key>Enter:     activate()\n",
+
+        "*.Text.Translations: #override\n\
+        Ctrl<Key>S:     no-op(RingBell)\n\
+        Ctrl<Key>R:     no-op(RingBell)\n\
+        <Key>space:     next-page()\n\
+        <Key>F:         next-page()\n\
+        Ctrl<Key>B:     previous-page()\n\
+        <Key>B:         previous-page()\n\
+        <Key>K:         scroll-one-line-down()\n\
+        <Key>Y:         scroll-one-line-down()\n\
+        <Key>J:         scroll-one-line-up()\n\
+        <Key>E:         scroll-one-line-up()\n\
+        <Key>Return:    scroll-one-line-up()\n\
+        <Key>q:         quit()\n",
+ 
+        "*.Text.baseTranslations: #override\n\
+        <Key>space:     next-page()\n\
+        <Key>F:         next-page()\n\
+        Ctrl<Key>B:     previous-page()\n\
+        <Key>K:         scroll-one-line-down()\n\
+        <Key>Y:         scroll-one-line-down()\n\
+        <Key>J:         scroll-one-line-up()\n\
+        <Key>E:         scroll-one-line-up()\n\
+        <Key>Return:    scroll-one-line-up()\n\
+        <Key>q:         quit()\n",
+ 
+        "*.vertical.Translations: #override\n\
+        <Key>space: StartScroll(Forward)  NotifyScroll(FullLength) EndScroll() \n\
+        <Key>Delete: StartScroll(Backward) NotifyScroll(FullLength) EndScroll() \n\
+        Ctrl<Key>Up:        KbdScroll(up,50) EndScroll()\n\
+        Ctrl<Key>Down:      KbdScroll(down,50) EndScroll()\n\
+        <Key>Up:            KbdScroll(up,10) EndScroll()\n\
+        <Key>Down:          KbdScroll(down,10) EndScroll()\n\
+        <Key>Page_Up:       KbdScroll(up,90) EndScroll()\n\
+        <Key>Page_Down:     KbdScroll(down,90) EndScroll()\n",
+
+        "*.horizontal.translations:      #override \n\
+        Ctrl<Key>Left:      KbdScroll(left,50) EndScroll()\n\
+        Ctrl<Key>Right:     KbdScroll(right,50) EndScroll()\n\
+        <Key>Left:          KbdScroll(left,10) EndScroll()\n\
+        <Key>Right:         KbdScroll(right,10) EndScroll()\n",
+
+        "*.horizontal.accelerators:      #override \n\
+        Ctrl<Key>Left:      KbdScroll(left,50) EndScroll()\n\
+        Ctrl<Key>Right:     KbdScroll(right,50) EndScroll()\n\
+        <Key>Left:          KbdScroll(left,10) EndScroll()\n\
+        <Key>Right:         KbdScroll(right,10) EndScroll()\n",
+
+        "*.vertical.accelerators:        #override \n\
+        Ctrl<Key>Up:        KbdScroll(up,50) EndScroll()\n\
+        Ctrl<Key>Down:      KbdScroll(down,50) EndScroll()\n\
+        <Key>Up:            KbdScroll(up,10) EndScroll()\n\
+        <Key>Down:          KbdScroll(down,10) EndScroll()\n\
+        <Key>Page_Up:       KbdScroll(up,90) EndScroll()\n\
+        <Key>Page_Down:     KbdScroll(down,90) EndScroll()\n",
+
+        "*.nodeText.Translations: #override \n\
+        None<Key>b:     beginning-of-file() \n\
+        <Key>Home:      beginning-of-file() \n\
+        <Key>Delete:    previous-page() \n\
+        <Key>Prior:     previous-page() \n\
+        <Key>Next:      next-page() \n\
+        <Key>space:     next-page() \n\
+        None<Btn1Down>: select-end() info_click() \n",
+
+        "*.arg.translations:    #override \n\
+        <Key>Return: confirm() \n\
+        Ctrl<Key>G:  abort() \n",
+
+        "*.pane.text.translations:         #override \n\
+        None<Key>q:     MenuPopdown(help) \n\
+        None<Key>b:     beginning-of-file() \n\
+        <Key>Home:      beginning-of-file() \n\
+        <Key>Delete:    previous-page() \n\
+        <Key>Prior:     previous-page() \n\
+        <Key>Next:      next-page() \n\
+        <Key>space:     next-page() \n",
+
+        "*.dialog.value.translations:     #override \n\
+        <Key>Return: confirm() \n\
+        Ctrl<Key>G:  abort() \n\
+        <Key>Tab: Complete()\n",
+
+        "*.dialog.value.baseTranslations:     #override \n\
+        <Key>Return: confirm() \n\
+        Ctrl<Key>G:  abort() \n",
+
+        "*.baseTranslations: #override \n\
+        Ctrl<Key>q: Quit()\n\
+        Ctrl<Key>c: Quit()\n\
+        <Key>Return: Accept()\n",
+
+        "*Translations: #override \n\
+        <Key>q: Quit()\n\
+        <Key>c: Quit()\n\
+        Ctrl <Key>n: Next()\n\
+        Ctrl <Key>p: Prev()\n",
+
+        "*minWidth: 200\n",
+
+        "*minHeight: 100\n",
+
+        NULL
+    };
+
+
+#ifndef optarg
+    extern char *optarg;
+#endif  // optarg
+
+#ifdef USING_LIBGC
+    GC_find_leak = 1;
+    GC_INIT();
+#endif  // USING_LIBGC
+
+
+    // Make copies of argc/argv/envp so that we can start other
+    // processes and know the environment we were started with. 
+    //
+    my_argc = argc;
+//    my_argv = argv;
+    my_argv = dupargv(argv);
+    my_envp = (void *)&envp[0];
+
+
+
+    euid = geteuid();
+    egid = getegid();
+
+    DISABLE_SETUID_PRIVILEGE;
+
+    program_start_time = sec_now(); // For use by "Display Uptime"
+
+    (void)setlocale(LC_NUMERIC, "C");
+    (void)setlocale(LC_CTYPE, "C");
+
+#ifdef HAVE_LIBCURL
+    curl_global_init(CURL_GLOBAL_ALL);
+#endif
+
+
+#ifdef HAVE_GRAPHICSMAGICK
+    InitializeMagick(*argv);
+#else   // HAVE_GRAPHICSMAGICK
+    #ifdef HAVE_IMAGEMAGICK
+        #if (MagickLibVersion < 0x0538)
+            MagickIncarnate(*argv);
+        #else   // MagickLibVersion < 0x0538
+            InitializeMagick(*argv);
+        #endif  // MagickLibVersion < 0x0538
+    #endif  // HAVE_IMAGEMAGICK
+#endif  //HAVE_GRAPHICSMAGICK
+
+
+    /* check fhs directories ?*/
+
+    /* setup values */
+    redo_list = FALSE;          // init lists
+
+    xa_config_dir[0]='\0';
+
+    delay_time = 0;
+    last_weather_cycle = sec_now();
+    redraw_on_new_packet_data = 0;
+    next_file_read = sec_now();         // init file replay timing
+    redraw_on_new_data = 0;
+    display_up = 0;
+    display_up_first = 0;
+    max_transmit_time = (time_t)900l;
+    sec_next_gps = 0l;
+    gprmc_save_string[0] = '\0';
+    gpgga_save_string[0] = '\0';
+    sec_next_raw_wx = 0l;
+    auto_reply = 0;
+    satellite_ack_mode = 0;
+    last_time = 0l;
+    next_time = (time_t)120l;
+    net_last_time = 0l;
+    net_next_time = (time_t)120l;
+    posit_last_time = 0l;
+    posit_next_time = 0l;
+    wait_to_redraw=1;
+
+    last_popup_x = 0;
+    last_popup_y = 0;
+    trap_segfault = 0;          // Default is to dump core
+    deselect_maps_on_startup = 0;
+    debug_level = 0;
+    install_colormap = 0;
+    last_sound_pid = 0;
+
+    my_last_course = 0;
+    my_last_speed = 0;
+    my_last_altitude = 0l;
+    my_last_altitude_time = 0l;
+
+    wx_station_type[0] = '\0';
+    last_alert_redraw = 0;
+    igate_msgs_tx = 0;
+    last_statusline = 0;        // inactive statusline
+    
+    last_object[0] = '\0';      // initialize object dialog
+    last_obj_grp   = '\\';
+    last_obj_sym   = '!';
+
+    clear_rain_data();          // init weather data
+    clear_local_wx_data();
+
+    next_redraw = sec_now()+60; // init redraw timing
+    last_redraw = sec_now();
+
+    lang_to_use_or[0] = '\0';
+    ag_error=0;
+
+    // Reset the gps variables.
+    xastir_snprintf(gps_sats,
+        sizeof(gps_sats),
+        "00");
+    gps_valid = 0;
+
+    memset(&appshell, 0, sizeof(appshell));
+
+    // Here we had to add "g:" in order to allow -geometry to be
+    // used and x: to allow xt arguments, which is actually parsed out
+    // by the XtIntrinsics code, not directly in Xastir code.
+    //
+    while ((ag = getopt(argc, argv, "c:f:v:l:g:x:012346789timp")) != EOF) {
+
+        switch (ag) {
+            
+            case 'c': 
+                if (optarg) {
+                    xastir_snprintf(xa_config_dir,sizeof(xa_config_dir),"%s", optarg);
+                    fprintf(stderr,"Using config dir %s\n",xa_config_dir);
+                }
+                break;
+
+            case 'f':   // Track callsign
+                if (optarg) {
+                    xastir_snprintf(temp_tracking_station_call,
+                        sizeof(temp_tracking_station_call),
+                        "%s",
+                        optarg);
+                    fprintf(stderr,
+                        "Tracking callsign %s\n",
+                        temp_tracking_station_call);
+                    (void)remove_leading_spaces(temp_tracking_station_call);
+                    (void)remove_trailing_spaces(temp_tracking_station_call);
+                    (void)remove_trailing_dash_zero(temp_tracking_station_call);
+                    (void)to_upper(temp_tracking_station_call);
+                }
+                break;
+
+            case 't':
+                fprintf(stderr,"Internal SIGSEGV handler enabled\n");
+                trap_segfault = 1;
+                break;
+
+            case 'v':
+                fprintf(stderr,"debug");
+                if (optarg) {
+                    debug_level = atoi(optarg);
+                    fprintf(stderr," level %d", debug_level);
+                }
+                fprintf(stderr,"\n");
+                break;
+
+            case 'l':
+                fprintf(stderr,"Language is");
+                if (optarg) {
+                    lang_to_use_or[0] = '\0';
+                    if        (strncasecmp(optarg,"ENGLISH",    7) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "English");
+                    } else if (strncasecmp(optarg,"DUTCH",      5) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "Dutch");
+                    } else if (strncasecmp(optarg,"FRENCH",     6) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "French");
+                    } else if (strncasecmp(optarg,"GERMAN",     6) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "German");
+                    } else if (strncasecmp(optarg,"SPANISH",    7) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "Spanish");
+                    } else if (strncasecmp(optarg,"ITALIAN",    7) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "Italian");
+                    } else if (strncasecmp(optarg,"PORTUGUESE",10) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "Portuguese");
+                    } else if (strncasecmp(optarg,"ELMERFUDD",10) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "ElmerFudd");
+                    } else if (strncasecmp(optarg,"MUPPETSCHEF",10) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "MuppetsChef");
+                    } else if (strncasecmp(optarg,"OLDEENGLISH",10) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "OldeEnglish");
+                    } else if (strncasecmp(optarg,"PIGLATIN",10) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "PigLatin");
+                    } else if (strncasecmp(optarg,"PIRATEENGLISH",10) == 0) {
+                        xastir_snprintf(lang_to_use_or, sizeof(lang_to_use_or), "PirateEnglish");
+                    } else {
+                        ag_error++;
+                        fprintf(stderr," INVALID");
+                    }
+                    if (!ag_error)
+                        fprintf(stderr," %s", lang_to_use_or);
+                    }
+                fprintf(stderr,"\n");
+                break;
+
+            case 'i':
+                fprintf(stderr,"Install Colormap\n");
+                install_colormap = (int)TRUE;
+                break;
+
+            case 'm':
+                fprintf(stderr,"De-select Maps\n");
+                deselect_maps_on_startup = (int)TRUE;
+                break;
+
+            case 'g':   // -geometry
+                    Geometry = argv[optind++];
+                break;
+
+	    case 'x':   // -xtsessionID
+		optind++; // swallow argument, let XtIntrinsics deal with it.
+		xt = 1;
+		break;
+
+            case 'p':   // Disable popups
+                disable_all_popups = 1;
+                pop_up_new_bulletins = 0;
+                warn_about_mouse_modifiers = 0;
+                break;
+
+            default:
+                ag_error++;
+                break;
+        }
+    }
+
+
+    if (ag_error){
+        fprintf(stderr,"\nXastir Command line Options\n\n");
+        fprintf(stderr,"-c /path/dir       Xastir config dir\n");
+        fprintf(stderr,"-f callsign        Track callsign\n");
+        fprintf(stderr,"-i                 Install private Colormap\n");
+        fprintf(stderr,"-geometry WxH+X+Y  Set Window Geometry\n");
+        fprintf(stderr,"-l Dutch           Set the language to Dutch\n");
+        fprintf(stderr,"-l English         Set the language to English\n");
+        fprintf(stderr,"-l French          Set the language to French\n");
+        fprintf(stderr,"-l German          Set the language to German\n");
+        fprintf(stderr,"-l Italian         Set the language to Italian\n");
+        fprintf(stderr,"-l Portuguese      Set the language to Portuguese\n");
+        fprintf(stderr,"-l Spanish         Set the language to Spanish\n");
+        fprintf(stderr,"-l ElmerFudd       Set the language to ElmerFudd\n");
+        fprintf(stderr,"-l MuppetsChef     Set the language to MuppetsChef\n");
+        fprintf(stderr,"-l OldeEnglish     Set the language to OldeEnglish\n");
+        fprintf(stderr,"-l PigLatin        Set the language to PigLatin\n");
+        fprintf(stderr,"-l PirateEnglish   Set the language to PirateEnglish\n");
+        fprintf(stderr,"-m                 Deselect Maps\n");
+        fprintf(stderr,"-p                 Disable popups\n");
+        fprintf(stderr,"-t                 Internal SIGSEGV handler enabled\n");
+        fprintf(stderr,"-v level           Set the debug level\n\n");
+        fprintf(stderr,"\n");
+        exit(0);    // Exiting after dumping out command-line options
+    }
+
+
+    // If we don't make this call, we can't access Xt or
+    // Xlib calls from multiple threads at the same time.
+    // Note that Motif from the OSF (including OpenMotif)
+    // still can't handle multiple threads talking to it at
+    // the same time.  See:
+    // http://www.faqs.org/faqs/x-faq/part7/section-46.html
+    // We'll probably have to add in a global mutex lock in
+    // order to keep from accessing the widget set from more
+    // than one thread.
+    //
+    XInitThreads();
+
+
+    // Set language attribs.  Must be called prior to
+    // XtVaOpenApplication().
+    (void)XtSetLanguageProc((XtAppContext) NULL,
+                            XtSetLanguageProc(NULL, NULL, NULL),
+                            (XtPointer) NULL );
+
+
+    if (Geometry) {
+        //
+        // Really we should be merging with the RDB database as well
+        // and then parsing the final geometry (Xlib Programming
+        // Manual section 14.4.3 and 14.4.4).
+        //
+        geometry_flags = XParseGeometry(Geometry,
+            &geometry_x,
+            &geometry_y,
+            &geometry_width,
+            &geometry_height);
+
+/*
+        if ((WidthValue|HeightValue) & geometry_flags) {
+            fprintf(stderr,"Found width/height\n");
+        }
+        if (XValue & geometry_flags) {
+            fprintf(stderr,"Found X-offset\n");
+        }
+        if (YValue & geometry_flags) {
+            fprintf(stderr,"Found Y-offset\n");
+        }
+        fprintf(stderr,
+            "appshell:  Width:%4d  Height:%4d  X-offset:%4d  Y-offset:%4d\n",
+            (int)geometry_width,
+            (int)geometry_height,
+            (int)geometry_x,
+            (int)geometry_y);
+*/
+    }
+
+
+    /* get User info */
+    user_id   = getuid();
+    user_info = getpwuid(user_id);
+    xastir_snprintf(user_dir,
+        sizeof(user_dir),
+        "%s",
+        user_info->pw_dir);
+
+    /*
+        fprintf(stderr,"User %s, Dir %s\n",user_info->pw_name,user_dir);
+        fprintf(stderr,"User dir %s\n",get_user_base_dir(""));
+        fprintf(stderr,"Data dir %s\n",get_data_base_dir(""));
+    */
+
+    /* check user directories */
+    if (filethere(get_user_base_dir("", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user dir\n");
+        if (mkdir(get_user_base_dir("", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0){
+                fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                        get_user_base_dir("", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+
+               	// Creature to feep later? 
+               	// needs <libgen.h> 
+                // fprintf(stderr,"Check to see if '%s' exists \n", 
+                //    dirname(get_user_base_dir("")) );
+
+            exit(errno);
+        }
+       
+    }
+
+    if (filethere(get_user_base_dir("config", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user config dir\n");
+        if (mkdir(get_user_base_dir("config", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                get_user_base_dir("config", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }        	
+    }
+
+    if (filethere(get_user_base_dir("data", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user data dir\n");
+        if (mkdir(get_user_base_dir("data", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                    get_user_base_dir("data", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }
+    }
+
+    if (filethere(get_user_base_dir("logs", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user log dir\n");
+        if (mkdir(get_user_base_dir("logs", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0 ){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                get_user_base_dir("logs", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }
+    }
+
+    if (filethere(get_user_base_dir("tracklogs", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user tracklogs dir\n");
+        if (mkdir(get_user_base_dir("tracklogs", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0 ){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                get_user_base_dir("tracklogs", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }        	
+    }
+
+    if (filethere(get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user tmp dir\n");
+        if (mkdir(get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0 ){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }        	
+    }
+
+    if (filethere(get_user_base_dir("gps", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making user gps dir\n");
+        if ( mkdir(get_user_base_dir("gps", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0 ){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                get_user_base_dir("gps", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }
+    }
+
+    if (filethere(get_user_base_dir("map_cache", temp_base_dir, sizeof(temp_base_dir))) != 1) {
+        fprintf(stderr,"Making map_cache dir\n");
+        if (mkdir(get_user_base_dir("map_cache", temp_base_dir, sizeof(temp_base_dir)),S_IRWXU) !=0 ){
+            fprintf(stderr,"Fatal error making user dir '%s':\n\t%s \n", 
+                get_user_base_dir("map_cache", temp_base_dir, sizeof(temp_base_dir)), strerror(errno) );
+            exit(errno);
+        }
+    }
+
+
+    /* done checking user dirs */
+
+
+
+
+
+#ifdef USE_PID_FILE_CHECK
+
+    if (pid_file_check(xt) !=0 ){
+        fprintf(stderr,"pid_file_check failed:\t%s \n", strerror(errno) );
+            exit(errno);
+    }
+
+#endif 
+
+
+
+    // initialize interfaces
+    init_critical_section(&port_data_lock);   // Protects the port_data[] array of structs
+    init_critical_section(&output_data_lock); // Protects interface.c:channel_data() function only
+    init_critical_section(&data_lock);        // Protects global incoming_data_queue
+    init_critical_section(&connect_lock);     // Protects port_data[].thread_status and port_data[].connect_status
+// We should probably protect redraw_on_new_data, alert_redraw_on_update, and
+// redraw_on_new_packet_data variables as well?
+// Also need to protect dialogs.
+
+#ifdef HAVE_DB
+   connections_initialized = 0;
+#endif // HAVE_DB
+
+#ifdef USE_MAP_CACHE
+    map_cache_init();
+#endif  // USE_MAP_CACHE
+
+    (void)bulletin_gui_init();
+    (void)db_init();
+    (void)draw_symbols_init();
+    (void)interface_gui_init();
+    (void)list_gui_init();
+    (void)locate_gui_init();
+    (void)geocoder_gui_init();
+    (void)location_gui_init();
+    (void)maps_init();
+    (void)map_gdal_init();
+    (void)messages_gui_init();
+    (void)popup_gui_init();
+    (void)track_gui_init();
+    (void)view_message_gui_init();
+    (void)wx_gui_init();
+    (void)igate_init();
+
+    clear_all_port_data();              // clear interface port data
+
+    (void) signal(SIGINT,quit);         // set signal on stop
+    (void) signal(SIGQUIT,quit);
+    (void) signal(SIGTERM,quit);
+
+
+    // Make sure that we reset to SIG_DFL handler any time we spawn
+    // a child process.  This is so the child process doesn't call
+    // restart() as well.  Only the main process needs to call
+    // restart() on receiving a SIGHUP.  We can do this via the
+    // following call:
+    //
+    //          (void)signal(SIGHUP,SIG_DFL);
+    //
+    (void) signal(SIGHUP,restart);      // Shut down/restart if SIGHUP received
+
+
+#ifndef OLD_PTHREADS
+    (void) signal(SIGUSR1,usr1sig);     // take a snapshot on demand
+    (void) signal(SIGUSR2,usr2sig);     // transmit now on demand
+#else   // OLD_PTHREADS
+#   warning ***** Old kernel detected: Disabling SIGUSR1 handler (snapshot on demand) *****
+#endif  // OLD_PTHREADS
+
+#ifdef HAVE_SIGIGNORE
+    (void) sigignore(SIGPIPE);
+#else   // HAVE_SIGIGNORE
+    (void) signal(SIGPIPE,SIG_IGN);     // set sigpipe signal to ignore
+#endif  // HAVE_SIGIGNORE
+
+    if (trap_segfault)
+        (void) signal(SIGSEGV,segfault);// set segfault signal to check
+
+
+    // Load program parameters or set to default values
+    load_data_or_default();
+
+
+    // Start the listening socket.  If we fork it early we end up
+    // with much smaller process memory allocated for it and all its
+    // children.  The server will authenticate each client that
+    // connects.  We'll share all of our data with the server, which
+    // will send it to all connected/authenticated clients.
+    // Anything transmitted by the clients will come back to us and
+    // standard igating rules should apply from there.
+    if (enable_server_port) {
+        tcp_server_pid = Fork_TCP_server(my_argc, my_argv, my_envp);
+        udp_server_pid = Fork_UDP_server(my_argc, my_argv, my_envp);
+    }
+
+
+    if (deselect_maps_on_startup) {
+        unlink( get_user_base_dir(SELECTED_MAP_DATA, temp_base_dir, sizeof(temp_base_dir)) );  // Remove the selected_maps.sys file
+    }
+
+    update_units(); // set up conversion factors and strings
+
+    /* do language links */
+    if (strlen(lang_to_use_or) > 0)
+        xastir_snprintf(lang_to_use,
+            sizeof(lang_to_use),
+            "%s",
+            lang_to_use_or);
+
+    xastir_snprintf(temp, sizeof(temp), "help/help-%s.dat", lang_to_use);
+    (void)unlink(get_user_base_dir("config/help.dat", temp_base_dir, sizeof(temp_base_dir)));
+
+    // Note that this symlink will probably not fail.  It's easy to
+    // create a symlink that points to nowhere.
+    if (symlink(get_data_base_dir(temp),get_user_base_dir("config/help.dat", temp_base_dir, sizeof(temp_base_dir))) == -1) {
+        fprintf(stderr,"Error creating database link for help.dat\n");
+        fprintf(stderr,
+            "Couldn't create symlink: %s -> %s\n",
+            get_user_base_dir("config/help.dat", temp_base_dir, sizeof(temp_base_dir)),
+            get_data_base_dir(temp));
+        exit(0);  // Exiting 'cuz online help won't work.
+    }
+
+    xastir_snprintf(temp, sizeof(temp), "config/language-%s.sys", lang_to_use);
+    (void)unlink(get_user_base_dir("config/language.sys", temp_base_dir, sizeof(temp_base_dir)));
+
+    // Note that this symlink will probably not fail.  It's easy to
+    // create a symlink that points to nowhere.
+    if (symlink(get_data_base_dir(temp),get_user_base_dir("config/language.sys", temp_base_dir, sizeof(temp_base_dir))) == -1) {
+        fprintf(stderr,"Error creating database link for language.sys\n");
+        fprintf(stderr,
+            "Couldn't create symlink: %s -> %s\n",
+            get_user_base_dir("config/language.sys", temp_base_dir, sizeof(temp_base_dir)),
+            get_data_base_dir(temp));
+        exit(0);    // We can't set our language, so exit.
+    }
+
+    /* (NEW) set help file area */
+    xastir_snprintf(HELP_FILE,
+        sizeof(HELP_FILE),
+        "%s",
+        "config/help.dat");
+
+#ifdef HAVE_FESTIVAL
+    /* Initialize the festival speech synthesis port */
+    if (SayTextInit())
+    {
+        fprintf(stderr,"Error connecting to Festival speech server.\n");
+        //exit(0);  // Not worth exiting just because we can't talk!
+    }  
+#endif  // HAVE_FESTIVAL
+
+
+    /* populate the predefined object (SAR/Public service) struct */
+    Populate_predefined_objects(predefinedObjects); 
+
+    if (load_color_file()) {
+        if (load_language_file(get_user_base_dir("config/language.sys", temp_base_dir, sizeof(temp_base_dir)))) {
+            init_device_names();                // set interface names
+            clear_message_windows();
+            clear_popup_message_windows();
+            init_station_data();                // init station storage
+            init_message_data();                // init messages
+            reset_outgoing_messages();
+
+
+            // This convenience function calls (in turn):
+            //      XtToolkitInitialize()
+            //      XtCreateApplicationContext()
+            //      XtOpenDisplay()
+            //      XtAppCreateShell().
+            //
+            appshell = XtVaOpenApplication(
+                &app_context,
+                "Xastir",
+                NULL,
+                0,
+                &argc,
+                argv,
+                fallback_resources,
+                sessionShellWidgetClass,
+                XmNmappedWhenManaged, FALSE,
+                NULL);
+
+            display = XtDisplay(appshell);
+
+            if (!display) {
+                fprintf(stderr,"%s: can't open display, exiting...\n", argv[0]);
+                exit(-1);   // Must exit here as we can't get our display.
+            }
+
+            XtSetValues(XmGetXmDisplay(display), NULL, 0);
+
+            // DK7IN: now scanf and printf use "," instead of "."
+            // that leads to several problems in the initialization.
+            //
+            // DK7IN: inserted next line here for avoiding scanf
+            // errors during init!
+            //
+//            (void)setlocale(LC_NUMERIC, "C");       // DK7IN: It's now ok
+            (void)setlocale(LC_CTYPE, "C");         // K4INT: Make sure strings work OK.
+
+
+            setup_visual_info(display, DefaultScreen(display));
+
+
+            // Get colormap (N7TAP: do we need this if the screen
+            // visual is TRUE or DIRECT?
+            //
+            cmap = DefaultColormapOfScreen(XtScreen(appshell));
+            if (visual_type == NOT_TRUE_NOR_DIRECT) {
+                if (install_colormap) {
+                    cmap = XCopyColormapAndFree(display, cmap);
+                    XtVaSetValues(appshell, XmNcolormap, cmap, NULL);
+                }
+            }
+
+
+//fprintf(stderr,"***index_restore_from_file\n");
+
+            // Read the current map index file into the index linked list
+            index_restore_from_file();
+
+
+            // Reload tactical calls.  This implements persistence
+            // for this type.
+            reload_tactical_calls();
+
+
+//fprintf(stderr,"***create_appshell\n");
+
+
+            // This call fills in the top-level window and then
+            // calls XtRealize.
+            //
+            create_appshell(display, argv[0], argc, argv);
+
+
+            // reset language attribs for numeric, program needs
+            // decimal in US for all data!
+            (void)setlocale(LC_NUMERIC, "C");
+            (void)setlocale(LC_CTYPE, "C");
+            // DK7IN: now scanf and printf work as wanted...
+
+
+//fprintf(stderr,"***check_fcc_data\n");
+
+            /* check for ham databases */
+            (void)check_rac_data();
+            (void)check_fcc_data();
+
+
+            // Find the extents of every map we have.  Use the smart
+            // timestamp-checking reindexing (quicker).
+            if ( index_maps_on_startup ) {
+              map_indexer(0);
+            }
+
+
+            // Check whether we're running Xastir for the first time.
+            // If so, my_callsign will be "NOCALL".   In this case
+            // write "worldhi.map" into ~/.xastir/config/selected_maps.sys
+            // so that we get the default map on startup.  Also
+            // request to bring up the Configure->Station dialog in
+            // this case.
+            //
+            if (strncasecmp(my_callsign,"NOCALL",6) == 0) {
+                FILE *ff;
+ 
+//                fprintf(stderr,"***** First time run *****\n");
+
+                // Set the flag
+                first_time_run = 1;
+ 
+                // Write the default map into the selected map file
+                ff = fopen( get_user_base_dir(SELECTED_MAP_DATA, temp_base_dir, sizeof(temp_base_dir)), "a");
+                if (ff != NULL) {
+                    fprintf(ff,"worldhi.map\n");
+                    (void)fclose(ff);
+                }
+            }
+
+
+            // Mark the "selected" field in the in-memory map index
+            // to correspond to the selected_maps.sys file.
+            map_chooser_init();
+
+
+            // Warn the user if altnet is enabled on startup.  This
+            // is so that the people who are button pushers/knob turners
+            // will know what's wrong when they don't see stations on their
+            // screen anymore.
+            //
+            if (altnet) {
+                // "Warning"
+                // "Altnet is enabled (File->Configure->Defaults dialog)");
+                popup_message_always( langcode("POPEM00035"),
+                    langcode("POPEM00051") );
+            }
+
+
+            // Start UpdateTime.  It schedules itself to be run
+            // again each time.  This is also the process that
+            // starts up the interfaces.
+            UpdateTime( (XtPointer) da , (XtIntervalId) NULL );
+
+
+            // Update the logging indicator 
+            Set_Log_Indicator();
+
+ 
+            XtAppMainLoop(app_context);
+
+
+        } else
+            fprintf(stderr,"Error in language file! Exiting...\n");
+
+    } else
+        fprintf(stderr,"Error in Color file! Exiting...\n");
+
+    quit(0);
+    return 0;
+}
+
+
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 0000000..f9e085a
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,463 @@
+/*
+ * $Id: main.h,v 1.110 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_MAIN_H
+#define XASTIR_MAIN_H
+
+#include <X11/Intrinsic.h>
+
+// For mutex debugging with Linux threads only
+#ifdef __linux__
+  #define MUTEX_DEBUG 1
+#endif  // __linux__
+
+
+// This gets defined if pthreads implementation uses SIGUSR1/SIGUSR2
+// signals.  This disables our SIGUSR1 handler which disallows
+// creating snapshots on receipt of that signal.  Old kernels (2.0
+// and early 2.1) had only 32 signals available so only USR1/USR2
+// were available for LinuxThreads use.  Newer kernels have more
+// signals available, making USR1/USR2 available to programs again.
+// _NSIG is defined in /usr/include/bits/signum.h
+//
+#ifdef __linux__
+# ifdef _NSIG
+#  if (_NSIG <= 32)
+#   define OLD_PTHREADS
+//#   warning ***** OLD_PTHREADS DETECTED *****
+#  else
+//#   warning ***** NEW_PTHREADS DETECTED *****
+#  endif // if (_NSIG...)
+# endif  // _NSIG
+#endif  // __linux__
+
+
+// To enable the "Transmit Raw WX data" button in
+// Configure->Defaults dialog.  Warning:  If you enable this, enable
+// the button in Configure->Defaults, and are running a weather
+// station that puts out raw data that is NOT allowed by the APRS
+// spec, you'll be putting out garbage and trashing the channel.
+//
+//#define TRANSMIT_RAW_WX
+
+// To use predefined object configuration files from within the 
+// user's base directory e.g. ~/.xastir/config/predefined_SAR.sys
+// rather than from the main base directory, enable this definition.
+//#define OBJECT_DEF_FILE_USER_BASE
+
+extern int enable_server_port;
+
+
+extern char altnet_call[MAX_CALLSIGN+1];
+extern int altnet;
+extern Widget iface_da;
+extern FILE *read_file_ptr;
+extern int interrupt_drawing_now;
+
+ 
+#define VERSIONFRM  (!altnet?XASTIR_TOCALL:altnet_call) /* Packet version info */
+
+
+#ifdef __LCLINT__
+#define PACKAGE "xastir"
+#define VERSION "lclint"
+#define VERSIONTXT "xastir lclint debug version"
+#else   // __LCLINT__
+#define VERSIONTXT PACKAGE " " VERSION
+#endif  // __LCLINT__
+
+
+#define VERSIONLABEL VERSIONTXT
+
+// NOTE:  This is out of date and not used anymore anyway.
+#define VERSIONMESSAGE "XASTIR Version: " VERSION "\n\nAmateur Station Tracking and Information Reporting\nby Frank Giannandrea, KC2GJS was KC0DGE\n   Code added by:\n   Richard Hagemeyer - VE3UNW,  Curt Mills - WE7U,\n   Mike Sims - KA9KIM,   Gerald Stueve - K4INT was KE4NFJ,\n   Mark Grennan - KD5AMB,  Henk de Groot - PE1DNN,\n   Jim Sevilla - KD6VPE,  Jose R. Marte A. - HI8GN,\n   Michael G. Petry - N3NYN,   Lloyd Miller - VE6LFM,\n   Alessandro Frigeri - IK0YUP,\n   Chuck Byam - KG4I [...]
+
+// NOTE:  This is out of date and not used anymore anyway.
+#define ABOUTGNUL "XASTIR, Copyright (C) 1999, 2000 Frank Giannandrea\nXASTIR comes with ABSOLUTELY NO WARRANTY;\nThis is free software, and you are welcome\nto redistribute it under certain conditions;\nsee the GNU LICENSE for details.\n"
+
+#define MAX_PHG      8
+#define MAX_COMMENT  80
+
+
+
+//////////////////////////////////////////////////////////////////////
+// These globals and prototypes are from:
+// http://lightconsulting.com/~thalakan/process-title-notes.html
+// They seems to work fine on Linux, but they only change the "ps"
+// listings, not the top listings.  I don't know why yet.
+
+/* Globals */
+//extern char **Argv = ((void *)0);
+//extern char *__progname, *__progname_full;
+//extern char *LastArgv = ((void *)0);
+
+/* Prototypes */
+extern void set_proc_title(char *fmt,...);
+extern void init_set_proc_title(int argc, char *argv[], char *envp[]);
+
+// New stuff defined by Xastir project:
+extern int my_argc;
+extern char **my_argv;
+extern char **my_envp;
+//////////////////////////////////////////////////////////////////////
+
+extern int input_x;
+extern int input_y;
+
+#define MAX_RELAY_DIGIPEATER_CALLS 50
+extern char relay_digipeater_calls[10*MAX_RELAY_DIGIPEATER_CALLS];
+extern int skip_dupe_checking;
+extern int serial_char_pacing;  // Inter-character delay in ms.
+extern int disable_all_maps;
+extern int re_sort_maps;
+extern Widget trackme_button;
+extern Widget CAD_close_polygon_menu_item;
+extern int debug_level;
+extern int my_position_valid;
+extern int using_gps_position;
+extern int transmit_now;
+extern char DATABASE_FILE[];
+extern char DATABASE_POINTER_FILE[];
+extern char DATABASE_POINTER_TEMP[];
+extern char ALERT_MAP_DIR[400];
+extern char SELECTED_MAP_DIR[400];
+extern char SELECTED_MAP_DATA[400];
+extern char MAP_INDEX_DATA[400];
+extern char AUTO_MAP_DIR[400];
+extern char SYMBOLS_DIR[400];
+extern char LOGFILE_IGATE[400];
+extern char LOGFILE_TNC[400];
+extern char LOGFILE_NET[400];
+extern char LOGFILE_MESSAGE[400];
+extern char LOGFILE_WX[400];
+extern char LOGFILE_WX_ALERT[400];
+extern char HELP_FILE[];
+extern char SOUND_DIR[400];
+extern time_t WX_ALERTS_REFRESH_TIME;
+extern time_t remove_ID_message_time;
+extern int pending_ID_message;
+extern time_t gps_time;
+extern time_t POSIT_rate;
+extern time_t OBJECT_rate;
+extern time_t update_DR_rate;
+
+extern time_t posit_last_time;
+extern time_t posit_next_time;
+
+extern int smart_beaconing;
+extern int sb_POSIT_rate;
+extern int sb_last_heading;
+extern int sb_current_heading;
+extern time_t sb_last_posit_time;
+extern int sb_turn_min;
+extern int sb_turn_slope;
+extern int sb_turn_time;
+extern int sb_posit_fast;
+extern int sb_posit_slow;
+extern int sb_low_speed_limit;
+extern int sb_high_speed_limit;
+
+extern int pop_up_new_bulletins;
+extern int view_zero_distance_bulletins;
+extern int warn_about_mouse_modifiers;
+extern int predefined_menu_from_file;
+
+extern int draw_labeled_grid_border;  // used to turn on or off border on map
+
+extern int my_trail_diff_color;  // trails for mycall with different ssids have the same or a different color
+
+extern int output_station_type;
+
+extern int emergency_beacon;
+
+typedef struct _selections {
+    int none;
+    int mine;
+    int tnc;
+    int direct;
+    int via_digi;
+    int net;
+    int tactical;
+    int old_data;
+
+    int stations;
+    int fixed_stations;
+    int moving_stations;
+    int weather_stations;
+    int CWOP_wx_stations;
+    int objects;
+    int weather_objects;
+    int gauge_objects;
+    int other_objects;
+} Selections;
+extern Selections Select_;
+
+typedef struct _what_to_display {
+    int callsign;
+    int label_all_trackpoints;
+    int symbol;
+    int symbol_rotate;
+    int trail;
+
+    int course;
+    int speed;
+    int speed_short;
+    int altitude;
+
+    int weather;
+    int weather_text;
+    int temperature_only;
+    int wind_barb;
+
+    int aloha_circle;
+    int ambiguity;
+    int phg;
+    int default_phg;
+    int phg_of_moving;
+
+    int df_data;
+    int df_beamwidth_data;
+    int df_bearing_data;
+    int dr_data;
+    int dr_arc;
+    int dr_course;
+    int dr_symbol;
+
+    int dist_bearing;
+    int last_heard;
+} What_to_display;
+extern What_to_display Display_;
+
+extern int currently_selected_stations;
+extern int currently_selected_stations_save;
+extern Pixel colors[256];
+#define MAX_TRAIL_COLORS 32
+extern Pixel trail_colors[MAX_TRAIL_COLORS];
+extern int current_trail_color;
+extern int english_units;
+extern int do_dbstatus;
+extern int redraw_on_new_data;
+extern int redo_list;
+extern int operate_as_an_igate;
+
+#ifdef TRANSMIT_RAW_WX
+extern int transmit_raw_wx;
+#endif  // TRANSMIT_RAW_WX
+
+extern int transmit_compressed_posit;
+extern int transmit_compressed_objects_items;
+extern int log_igate;
+extern int log_tnc_data;
+extern int log_net_data;
+extern int log_message_data;
+extern int log_wx_alert_data;
+extern int log_wx;
+extern int snapshots_enabled;
+extern int kmlsnapshots_enabled;
+extern char user_dir[];
+extern char lang_to_use[30];
+extern char my_group;
+extern char my_symbol;
+extern char my_phg[MAX_PHG+1];
+extern char my_comment[MAX_COMMENT+1];
+extern int map_background_color;
+extern int map_color_fill;
+extern int letter_style;
+extern int icon_outline_style;
+extern int wx_alert_style;
+extern time_t map_refresh_interval;
+extern time_t map_refresh_time;
+extern char sound_command[90];
+extern pid_t last_sound_pid;
+extern int sound_play_new_station;
+extern int sound_play_new_message;
+extern int sound_play_prox_message;
+extern int sound_play_band_open_message;
+extern int sound_play_wx_alert_message;
+extern char sound_new_station[90];
+extern char sound_new_message[90];
+extern char sound_prox_message[90];
+extern char sound_band_open_message[90];
+extern char sound_wx_alert_message[90];
+extern int ATV_screen_ID;
+extern int festival_speak_ID;
+extern int festival_speak_new_station;
+extern int festival_speak_proximity_alert;
+extern int festival_speak_tracked_proximity_alert;
+extern int festival_speak_band_opening;
+extern int festival_speak_new_message_alert;
+extern int festival_speak_new_message_body;
+extern int festival_speak_new_weather_alert;
+extern char prox_min[30];
+extern char prox_max[30];
+extern time_t sec_old;
+extern time_t sec_clear;
+extern int trail_segment_time;
+extern int trail_segment_distance;
+extern int RINO_download_interval;
+extern int dead_reckoning_timeout;
+extern char bando_min[30];
+extern char bando_max[30];
+extern int Display_packet_data_type;
+extern int show_only_station_capabilities;
+extern int Display_packet_data_mine_only;
+extern int menu_x;
+extern int menu_y;
+extern long my_last_altitude;
+extern time_t my_last_altitude_time;
+extern int my_last_course;
+extern int my_last_speed;   // in knots
+extern unsigned igate_msgs_tx;
+extern int symbols_loaded;
+extern GC gc2;
+extern GC gc_tint;
+extern GC gc_stipple;
+extern GC gc_bigfont;
+extern int read_file;
+extern float x_screen_distance;
+extern time_t max_transmit_time;
+extern int transmit_disable;
+extern int posit_tx_disable;
+extern int object_tx_disable;
+extern int map_chooser_expand_dirs;
+extern int request_new_image;
+extern int disable_all_popups;
+extern char temp_tracking_station_call[30];
+
+extern int coordinate_system;
+#define USE_DDDDDD      0
+#define USE_DDMMMM      1
+#define USE_DDMMSS      2
+#define USE_UTM         3
+#define USE_UTM_SPECIAL 4
+#define USE_MGRS        5
+
+typedef struct {
+    Widget calling_dialog;  // NULL if the calling dialog has been closed.
+    Widget input_lat_deg;   // Pointers to calling dialog's widgets
+    Widget input_lat_min;   // (Where to get/put the data)
+    Widget input_lat_dir;
+    Widget input_lon_deg;
+    Widget input_lon_min;
+    Widget input_lon_dir;
+} coordinate_calc_array_type;
+extern coordinate_calc_array_type coordinate_calc_array;
+extern void Coordinate_calc(Widget w, XtPointer clientData, XtPointer callData);
+
+
+extern void HandlePendingEvents(XtAppContext app);
+extern void create_gc(Widget w);
+extern void Station_info(Widget w, XtPointer clientData, XtPointer calldata);
+extern void Station_List(Widget w, XtPointer clientData, XtPointer calldata);
+extern void Tracks_All_Clear(Widget w, XtPointer clientData, XtPointer callData);
+extern void Locate_station(Widget w, XtPointer clientData, XtPointer callData);
+extern void Locate_place(Widget w, XtPointer clientData, XtPointer callData);
+extern void Geocoder_place(Widget w, XtPointer clientData, XtPointer callData);
+extern void Display_Wx_Alert(Widget w, XtPointer clientData, XtPointer callData);
+extern void Auto_msg_option(Widget w, XtPointer clientData, XtPointer calldata);
+extern void Auto_msg_set(Widget w, XtPointer clientData, XtPointer calldata);
+extern void Bulletins(Widget w, XtPointer clientData, XtPointer callData);
+extern void on_off_switch(int switchpos, Widget first, Widget second);
+extern void busy_cursor(Widget w);
+extern void pos_dialog(Widget w);
+extern int create_image(Widget w);
+extern void draw_tiger_map (Widget w, char *filenm, int destination_pixmap, int nocache);
+
+typedef struct _transparent_color_record{
+    unsigned long trans_color;
+    struct _transparent_color_record *next;
+} transparent_color_record;
+
+extern int check_trans (XColor c, transparent_color_record *c_trans_color_head);
+
+extern void draw_WMS_map (Widget w, char *filenm, int destination_pixmap, char *URL, transparent_color_record *c_trans_color_head, int nocache);
+
+extern void locate_gui_init(void);
+extern void geocoder_gui_init(void);
+extern void location_gui_init(void);
+extern void view_message_gui_init(void);
+extern void wx_gui_init(void);
+extern long get_x_scale(long x, long y, long ysc);
+
+extern Widget Display_data_dialog;
+extern Widget Display_data_text;
+extern Widget text3;
+extern Widget text4;
+extern Widget log_indicator;
+extern void display_zoom_status(void);
+extern void Center_Zoom(Widget w, XtPointer clientData, XtPointer calldata);
+extern int center_zoom_override;
+extern void statusline(char *status_text,int update);
+extern void stderr_and_statusline(char *message);
+extern int SayTextInit(void);
+extern int SayText(char *text);
+extern Widget auto_msg_toggle;
+
+// Symbol update stuff
+extern Widget configure_station_dialog;
+extern Widget station_config_group_data;
+extern Widget station_config_symbol_data;
+extern void updateSymbolPictureCallback(Widget w,XtPointer clientData,XtPointer callData);
+
+extern Widget object_dialog;
+extern Widget object_group_data;
+extern Widget object_symbol_data;
+extern void updateObjectPictureCallback(Widget w,XtPointer clientData,XtPointer callData);
+
+extern void Draw_All_CAD_Objects(Widget w);
+
+// unit conversion
+extern char un_alt[2+1];
+extern char un_dst[2+1];
+extern char un_spd[4+1];
+extern double cvt_m2len;
+extern double cvt_dm2len;
+extern double cvt_hm2len;
+extern double cvt_kn2len;
+extern double cvt_mi2len;
+
+// euid and egid
+extern uid_t euid;
+extern gid_t egid;
+
+/* JMT - works in FreeBSD */
+#define DISABLE_SETUID_PRIVILEGE do { \
+seteuid(getuid()); \
+setegid(getgid()); \
+if (debug_level & 4) { fprintf(stderr, "Changing euid to %d and egid to %d\n", (int)getuid(), (int)getgid()); } \
+} while(0)
+#define ENABLE_SETUID_PRIVILEGE do { \
+seteuid(euid); \
+setegid(egid); \
+if (debug_level & 4) { fprintf(stderr, "Changing euid to %d and egid to %d\n", (int)euid, (int)egid); } \
+} while(0)
+
+#ifdef HAVE_LIBSHP
+extern void create_map_from_trail(char *call_sign);
+#endif  // HAVE_LIBSHP
+
+
+#endif /* XASTIR_MAIN_H */
+
+
diff --git a/src/map_OSM.c b/src/map_OSM.c
new file mode 100644
index 0000000..a417a4f
--- /dev/null
+++ b/src/map_OSM.c
@@ -0,0 +1,1655 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ *
+ * $Id: map_OSM.c,v 1.16 2012/11/01 18:57:19 we7u Exp $
+ *
+ * Copyright (C) 2010-2012 The Xastir Group
+ *
+ * This file was contributed by Jerry Dunmire, KA6HLD.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ * This file derived from map_tiger.c which has the following copyrights:
+ *    Copyright (C) 1999,2000  Frank Giannandrea
+ *    Copyright (C) 2000-2012  The Xastir Group
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "fetch_remote.h"
+#include "util.h"
+#include "main.h"
+#include "color.h"
+#include "xa_config.h"
+
+#include "map_cache.h"
+
+#include "tile_mgmnt.h"
+#include "map_OSM.h"
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+#ifdef HAVE_MAGICK
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+#undef RETSIGTYPE
+// TVR: "stupid ImageMagick"
+// The problem is that magick/api.h includes Magick's config.h file, and that
+// pulls in all the same autoconf-generated defines that we use.
+// plays those games below, but I don't think in the end that they actually 
+// make usable macros with our own data in them.
+// Fortunately, we don't need them, so I'll just undef the ones that are
+// causing problems today.  See main.c for fixes that preserve our values.
+#undef PACKAGE
+#undef VERSION
+/* JMT - stupid ImageMagick */
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#ifdef HAVE_GRAPHICSMAGICK
+/*#include <GraphicsMagick/magick/api.h>*/
+#include <magick/api.h>
+#else   // HAVE_GRAPHICSMAGICK
+#include <magick/api.h>
+#endif  // HAVE_GRAPHICSMAGICK 
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+
+// This matte color was chosen emphirically to work well with the
+// contours from topOSM.
+#if (QuantumDepth == 8)
+#define MATTE_RED   (0xa7)
+#define MATTE_GREEN (0xa7)
+#define MATTE_BLUE  (0xa7)
+#define MATTE_OPACITY (0x00)
+#define MATTE_COLOR_STRING "xc:#a7a7a7"
+//#define MATTE_COLOR_STRING "xc:#a7a7a700"
+//#define MATTE_OPACITY (0xff)
+//#define MATTE_COLOR_STRING "xc:#a7a7a7ff"
+#elif (QuantumDepth == 16)
+#define MATTE_RED   (0xa700)
+#define MATTE_GREEN (0xa700)
+#define MATTE_BLUE  (0xa700)
+#define MATTE_OPACITY (0x0000)
+#define MATTE_COLOR_STRING "xc:#a700a700a700"
+//#define MATTE_COLOR_STRING "xc:#a700a700a700ffff"
+#else
+#error "QuantumDepth != 16 or 8"
+#endif // QuantumDepth
+
+#endif // HAVE_MAGICK
+
+// Must be last include file
+#include "leak_detection.h"
+
+#define xastirColorsMatch(p,q) (((p).red == (q).red) && ((p).blue == (q).blue) \
+        && ((p).green == (q).green))
+
+// osm_scale_x - map Xastir scale_x value to an OSM binned value
+// 
+// Note that the terms 'higher' and 'lower' are confusing because a
+// smaller Xastir scale number is a larger OSM zoom level. OSM zoom level
+// 0 would show the whole world in a 256x256 pixel tile, OSM zoom level
+// 18 (the max) would require 2^18 tiles to simple wrap the equator.
+//
+// On the equator, OSM zoom level 0 equates to ~97 miles/pixel
+// and OSM zoom level 18 equates to ~2 ft/pixel
+//
+// direction = -1, zoom in
+// direction = 1, zoom out
+// direction = 0, nearst level out from the xastir scale
+//
+#define MAX_OSM_ZOOM_LEVEL 18
+#define OSM_ZOOM_LEVELS    (MAX_OSM_ZOOM_LEVEL + 1)
+
+static long osm_scale_x(long xastir_scale_x) {
+
+    long osm_level[OSM_ZOOM_LEVELS] = {1, 2, 4, 8, 15, 31, 62, 124, \
+                          247, 494, 989, 1978, 3955, 7910, 15820, 31641,\
+                          63281, 126563, 253125};
+    long osm_scale_x = osm_level[0];
+    int i = 0;
+
+    for (i=1; i <= MAX_OSM_ZOOM_LEVEL; i++) {
+       if (xastir_scale_x > osm_level[i]) {
+            continue;
+        } else {
+            if (abs(osm_level[i - 1] - xastir_scale_x) < abs(osm_level[i] - xastir_scale_x)) {
+                osm_scale_x = osm_level[i - 1];
+            } else {
+                osm_scale_x = osm_level[i];
+            }
+            break;
+        }
+    }
+
+    if (i > MAX_OSM_ZOOM_LEVEL) {
+        i = MAX_OSM_ZOOM_LEVEL;
+        osm_scale_x = osm_level[i];
+    }
+
+    return(osm_scale_x);
+
+} // osm_scale_x()
+
+
+/*
+ * adj_to_OSM_level - adjust scale_x and scale_y to approximate an OSM zoom level
+ *
+ * The OSM zoom level closest to the scale_x value will be chosen and scale_x is modified.
+ * The scale_y value (pointed to by the second argument) is scaled proportionaly. Both
+ * values pointed to by the arguments are modified.
+ */
+void adj_to_OSM_level( long *new_scale_x, long *new_scale_y) {
+
+    long scale;
+
+    scale = osm_scale_x(*new_scale_x);
+
+    // the y scale must also be adjusted.
+    *new_scale_y = (int)(((double)(*new_scale_y) * ((double)scale / (double)(*new_scale_x)) + 0.5));
+    *new_scale_x = scale;
+
+    return;
+
+} // adj_to_OSM_level()
+
+
+/*
+ * osm_zoom_level - translate the longitude scale to the nearest OSM zoom level
+ *
+ * OSM tile scaling is based on the number of tiles needed to wrap the earth at the equator.
+ * A tile is 256x256 pixels.
+ */
+unsigned int osm_zoom_level(long scale_x) {
+    double circumference = 360.0*3600.0*100.0; // Xastir Units = 1/100 second.
+    double zf;
+    int z;
+    zf = (log(circumference / (double)scale_x) / log(2.0)) - 8.0;
+    z = (int)(zf + 0.5);
+    
+    // OSM levels run from 0 to 18. Not all levels are available for all views.
+    if (z < 0) {
+      z = 0;
+    }
+    if (z > 18) {
+      z = 18;
+    }
+
+    return((unsigned int)z);
+
+} // osm_zoom_level()
+
+
+static KeySym OptimizeKey = 0;
+static KeySym ReportScaleKey = 0;
+
+void init_OSM_values(void) {
+    OptimizeKey = 0;
+    ReportScaleKey = 0;
+    return;
+}
+
+int OSM_optimize_key(KeySym key) {
+    return (key == OptimizeKey ? TRUE : FALSE);
+}
+
+void set_OSM_optimize_key(KeySym key) {
+    OptimizeKey = key;
+    return;
+}
+
+int OSM_report_scale_key(KeySym key) {
+    return (key == ReportScaleKey ? TRUE : FALSE);
+}
+
+void set_OSM_report_scale_key(KeySym key) {
+    ReportScaleKey = key;
+    return;
+}
+
+static void get_OSM_local_file(char * local_filename, char * fileimg){
+#ifdef HAVE_MAGICK
+    time_t query_start_time, query_end_time; 
+
+#ifdef USE_MAP_CACHE 
+    int map_cache_return = 1; // Default = cache miss
+    char *cache_file_id;
+#endif  // USE_MAP_CACHE
+
+    char temp_file_path[MAX_VALUE];
+
+    if (debug_level & 512) {
+        query_start_time=time(&query_start_time); 
+    }
+
+
+#ifdef USE_MAP_CACHE 
+
+    if (!map_cache_fetch_disable) {
+
+        // Delete old copy from the cache
+        if (map_cache_fetch_disable && fileimg[0] != '\0') {
+            if (map_cache_del(fileimg)) {
+                if (debug_level & 512) {
+                    fprintf(stderr,"Couldn't delete old map from cache\n");
+                }
+            }
+        }
+
+set_dangerous("map_OSM: map_cache_get");
+	map_cache_return = map_cache_get(fileimg,local_filename); 
+clear_dangerous();
+    }
+
+    if (debug_level & 512) {
+            fprintf(stderr,"map_cache_return: <%d> bytes returned: %d\n",
+                map_cache_return,
+                (int) strlen(local_filename));
+    }
+   
+    if (map_cache_return != 0 ) {
+
+set_dangerous("map_OSM: map_cache_fileid");
+        cache_file_id = map_cache_fileid();
+        xastir_snprintf(local_filename,
+            MAX_FILENAME,           // hardcoded to avoid sizeof()
+            "%s/map_%s.%s",
+            get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)),
+            cache_file_id,
+            "png");
+        free(cache_file_id);
+clear_dangerous();
+
+#else   // USE_MAP_CACHE
+
+    xastir_snprintf(local_filename,
+        MAX_FILENAME,               // hardcoded to avoid sizeof()
+        "%s/map.%s",
+         get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),
+        "png");
+
+#endif  // USE_MAP_CACHE
+
+
+    // Erase any previously existing local file by the same name.
+    // This avoids the problem of having an old map image here and
+    // the code trying to display it when the download fails.
+
+    unlink( local_filename );
+
+    if (fetch_remote_file(fileimg, local_filename)) {
+        // Had trouble getting the file.  Abort.
+        return;
+    }
+
+    // For debugging the MagickError/MagickWarning segfaults.
+    //system("cat /dev/null >/var/tmp/xastir_hacker_map.png");
+   
+ 
+#ifdef USE_MAP_CACHE
+
+set_dangerous("map_OSM: map_cache_put");
+	map_cache_put(fileimg,local_filename); 
+clear_dangerous();
+
+        } // end if is cached  DHBROWN
+
+#endif // MAP_CACHE
+
+
+    if (debug_level & 512) {
+        fprintf (stderr, "Fetch or query took %d seconds\n", 
+            (int) (time(&query_end_time) - query_start_time)); 
+    }
+
+    // Set permissions on the file so that any user can overwrite it.
+    chmod(local_filename, 0666);
+
+#endif  //HAVE_MAGICK
+
+} // end get_OSM_local_file
+
+
+static long xastirLat2pixelLat(
+        long xlat, int osm_zoom ) {
+    double lat;  // in radians
+    double projection, y;
+    long pixelLat;
+
+    lat = convert_lat_l2r(xlat);
+
+    // xastir latitude values can exceed +/- 90.0 degrees because
+    // the latitude is the extent of the display window. Limit the
+    // OSM latitute to less than +/- 90.0 degrees so that the projection
+    // calculation does not blow up or return unreasonable values.
+    if (lat > ((89.0/180.0) * M_PI)) {
+        lat = ((89.0/180.0) * M_PI);
+    } else if (lat < ((-89.0/180.0) * M_PI)) {
+        lat = ((-89.0/180.0) * M_PI);
+    }
+
+
+    projection = log(tan(lat) + (1.0 / cos(lat)));
+    y = projection / M_PI;
+    y = 1.0 - y;
+    pixelLat = (long)((y * (double)(1<<(osm_zoom + 8))) / 2.0);
+    return(pixelLat);
+} // xastirLat2pixelLat()
+  
+
+static double pixelLat2Lat(long osm_lat, int osm_zoom){
+    double lat, projection, y;
+    y = (double)osm_lat * 2.0 / (double)(1<<(osm_zoom + 8));
+    y = 1.0 - y;
+    projection = y * M_PI;
+    lat = 2.0 * atan(exp(projection)) - (M_PI / 2.0);
+    lat = (lat * 180.0 ) / M_PI;
+    return(lat);
+} // pixelLat2Lat()
+
+
+static long pixelLat2xastirLat(long osm_lat, int osm_zoom) {
+    double lat;
+    long xastirLat;
+    lat = pixelLat2Lat(osm_lat, osm_zoom);
+    xastirLat = (long)((90.0 - lat) * 3600.0 * 100.0);
+    return (xastirLat);
+} // pixelLat2xastirLat()
+
+
+static long xastirLon2pixelLon(
+        long xlon, int osm_zoom) {
+    double lon;
+    long pixelLon;
+    lon = xlon / (3600.0 * 100.0);
+    lon = lon * (1<<(osm_zoom +8));
+    lon = lon / 360.0;
+    pixelLon = lon;
+    return(pixelLon);
+} // xastirLon2pixelLon()
+
+
+static double pixelLon2Lon(long osm_lon, int osm_zoom) {
+    double lon;
+    lon = osm_lon * 360.0 ;
+    lon = lon / (1<<(osm_zoom + 8));
+    return(lon);
+} // pixelLon2Lon()
+
+
+static long pixelLon2xastirLon(long osm_lon, int osm_zoom) {
+    long xastirLon;
+    xastirLon = (long)(pixelLon2Lon(osm_lon, osm_zoom) * 3600.0 * 100.0);
+    return(xastirLon);
+} // pixelLon2xastirLon()
+
+
+#ifdef HAVE_MAGICK
+/**********************************************************
+ * draw_image() - copy a image onto the display
+ **********************************************************/
+static void draw_image(
+        Widget w,
+        Image *image,
+        ExceptionInfo *except_ptr,
+        unsigned offsetx,
+        unsigned offsety) {
+    int l;
+    XColor my_colors[256];
+    PixelPacket *pixel_pack;
+    PixelPacket temp_pack;
+    IndexPacket *index_pack;
+    unsigned image_row;
+    unsigned image_col;
+    unsigned scr_x, scr_y;             // screen pixel plot positions
+
+    //if (debug_level & 512)
+    //    fprintf(stderr,"Color depth is %i \n", (int)image->depth);
+
+    if (image->colorspace != RGBColorspace) {
+        fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB");
+        return;
+    }
+
+    // If were are drawing to a low bpp display (typically < 8bpp)
+    // try to reduce the number of colors in an image.
+    // This may take some time, so it would be best to do ahead of
+    // time if it is a static image.
+#if (MagickLibVersion < 0x0540)
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) {
+#else   // MagickLib >= 540
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, except_ptr) > 128) {
+#endif  // MagickLib Version
+
+        if (image->storage_class == PseudoClass) {
+#if (MagickLibVersion < 0x0549)
+            CompressColormap(image); // Remove duplicate colors
+#else // MagickLib >= 0x0549
+            CompressImageColormap(image); // Remove duplicate colors
+#endif  // MagickLibVersion < 0x0549
+        }
+
+        // Quantize down to 128 will go here...
+    }
+
+
+    pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows);
+    if (!pixel_pack) {
+        fprintf(stderr,"pixel_pack == NULL!!!");
+        return;
+    }
+
+    index_pack = GetIndexes(image);
+    if (image->storage_class == PseudoClass && !index_pack) {
+        fprintf(stderr,"PseudoClass && index_pack == NULL!!!");
+        return;
+    }
+
+
+    if (image->storage_class == PseudoClass && image->colors <= 256) {
+        for (l = 0; l < (int)image->colors; l++) {
+            // Need to check how to do this for ANY image, as
+            // ImageMagick can read in all sorts of image files
+            temp_pack = image->colormap[l];
+            //if (debug_level & 512)
+            //    fprintf(stderr,"Colormap color is %i  %i  %i \n",
+            //           temp_pack.red, temp_pack.green, temp_pack.blue);
+
+            // Here's a tricky bit:  PixelPacket entries are defined as
+            // Quantum's.  Quantum is defined in
+            // /usr/include/magick/image.h as either an unsigned short
+            // or an unsigned char, depending on what "configure"
+            // decided when ImageMagick was installed.  We can determine
+            // which by looking at MaxRGB or QuantumDepth.
+            //
+            if (QuantumDepth == 16) {  // Defined in /usr/include/magick/image.h
+                if (debug_level & 512)
+                    fprintf(stderr,"Color quantum is [0..65535]\n");
+                my_colors[l].red   = temp_pack.red * raster_map_intensity;
+                my_colors[l].green = temp_pack.green * raster_map_intensity;
+                my_colors[l].blue  = temp_pack.blue * raster_map_intensity;
+            }
+            else {  // QuantumDepth = 8
+                if (debug_level & 512)
+                    fprintf(stderr,"Color quantum is [0..255]\n");
+                my_colors[l].red   = (temp_pack.red << 8) * raster_map_intensity;
+                my_colors[l].green = (temp_pack.green << 8) * raster_map_intensity;
+                my_colors[l].blue  = (temp_pack.blue << 8) * raster_map_intensity;
+            }
+
+            // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
+            if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+            }
+            else {
+                pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                &my_colors[l].pixel);
+            }
+
+            //if (debug_level & 512)
+            //    fprintf(stderr,"Color allocated is %li  %i  %i  %i \n", my_colors[l].pixel,
+            //           my_colors[l].red, my_colors[l].blue, my_colors[l].green);
+        }
+    }
+
+    // loop over image pixel rows
+    for (image_row = 0; image_row < image->rows; image_row++) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        scr_y = image_row + offsety;
+
+        // loop over image pixel colums
+        for (image_col = 0; image_col < image->columns; image_col++) {
+            scr_x = image_col + offsetx;
+            // now copy a pixel from the image to the screen
+            l = image_col + (image_row * image->columns);
+            if (image->storage_class == PseudoClass) {
+                // Make matte transparent
+                if (xastirColorsMatch(pixel_pack[l],image->matte_color)) {
+                    continue;
+                }
+                XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel);
+            }
+            else {
+                // Skip transparent pixels
+                if (pixel_pack[l].opacity == TransparentOpacity) {
+                    continue;
+                }
+
+                // It is not safe to assume that the red/green/blue
+                // elements of pixel_pack of type Quantum are the
+                // same as the red/green/blue of an XColor!
+                if (QuantumDepth==16) {
+                    my_colors[0].red=pixel_pack[l].red;
+                    my_colors[0].green=pixel_pack[l].green;
+                    my_colors[0].blue=pixel_pack[l].blue;
+                }
+                else { // QuantumDepth=8
+                    // shift the bits of the 8-bit quantity so that
+                    // they become the high bigs of my_colors.*
+                    my_colors[0].red=pixel_pack[l].red<<8;
+                    my_colors[0].green=pixel_pack[l].green<<8;
+                    my_colors[0].blue=pixel_pack[l].blue<<8;
+                }
+                // NOW my_colors has the right r,g,b range for
+                // pack_pixel_bits
+                pack_pixel_bits(my_colors[0].red * raster_map_intensity,
+                                my_colors[0].green * raster_map_intensity,
+                                my_colors[0].blue * raster_map_intensity,
+                                &my_colors[0].pixel);
+                XSetForeground(XtDisplay(w), gc, my_colors[0].pixel);
+            }
+            // write the pixel from the map image to the
+            // screen.
+            (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,1,1);
+        } // loop over map pixel columns
+    } // loop over map pixel rows
+
+    return;
+}  // end draw_image()
+
+
+/**********************************************************
+ * draw_OSM_image() - copy map image to display
+ **********************************************************/
+static void draw_OSM_image(
+        Widget w,
+        Image *image,
+        ExceptionInfo *except_ptr,
+        tiepoint *tpNW,
+        tiepoint *tpSE,
+        int osm_zl)
+{
+    int l;
+    XColor my_colors[256];
+    PixelPacket *pixel_pack;
+    PixelPacket temp_pack;
+    IndexPacket *index_pack;
+    long map_image_row;
+    long map_image_col;
+    long map_x_min, map_x_max;      // map boundaries for in screen part of map
+    long map_y_min, map_y_max;
+    int map_seen = 0;
+    int map_act;
+    int map_done;
+
+    long scr_x,  scr_y;             // screen pixel plot positions
+    long scr_xp, scr_yp;            // previous screen plot positions
+    int  scr_dx, scr_dy;            // increments in screen plot positions
+
+    //if (debug_level & 512)
+    //    fprintf(stderr,"Color depth is %i \n", (int)image->depth);
+
+    if (image->colorspace != RGBColorspace) {
+        fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB");
+        return;
+    }
+
+    // If were are drawing to a low bpp display (typically < 8bpp)
+    // try to reduce the number of colors in an image.
+    // This may take some time, so it would be best to do ahead of
+    // time if it is a static image.
+#if (MagickLibVersion < 0x0540)
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) {
+#else   // MagickLib >= 540
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, except_ptr) > 128) {
+#endif  // MagickLib Version
+
+        if (image->storage_class == PseudoClass) {
+#if (MagickLibVersion < 0x0549)
+            CompressColormap(image); // Remove duplicate colors
+#else // MagickLib >= 0x0549
+            CompressImageColormap(image); // Remove duplicate colors
+#endif  // MagickLibVersion < 0x0549
+        }
+
+        // Quantize down to 128 will go here...
+    }
+
+
+    pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows);
+    if (!pixel_pack) {
+        fprintf(stderr,"pixel_pack == NULL!!!");
+        return;
+    }
+
+    index_pack = GetIndexes(image);
+    if (image->storage_class == PseudoClass && !index_pack) {
+        fprintf(stderr,"PseudoClass && index_pack == NULL!!!");
+        return;
+    }
+
+
+    if (image->storage_class == PseudoClass && image->colors <= 256) {
+        for (l = 0; l < (int)image->colors; l++) {
+            // Need to check how to do this for ANY image, as
+            // ImageMagick can read in all sorts of image files
+            temp_pack = image->colormap[l];
+            //if (debug_level & 512)
+            //    fprintf(stderr,"Colormap color is %i  %i  %i \n",
+            //           temp_pack.red, temp_pack.green, temp_pack.blue);
+
+            // Here's a tricky bit:  PixelPacket entries are defined as
+            // Quantum's.  Quantum is defined in
+            // /usr/include/magick/image.h as either an unsigned short
+            // or an unsigned char, depending on what "configure"
+            // decided when ImageMagick was installed.  We can determine
+            // which by looking at MaxRGB or QuantumDepth.
+            //
+            if (QuantumDepth == 16) {  // Defined in /usr/include/magick/image.h
+                //if (debug_level & 512)
+                //    fprintf(stderr,"Color quantum is [0..65535]\n");
+                my_colors[l].red   = temp_pack.red * raster_map_intensity;
+                my_colors[l].green = temp_pack.green * raster_map_intensity;
+                my_colors[l].blue  = temp_pack.blue * raster_map_intensity;
+            }
+            else {  // QuantumDepth = 8
+                //if (debug_level & 512)
+                //    fprintf(stderr,"Color quantum is [0..255]\n");
+                my_colors[l].red   = (temp_pack.red << 8) * raster_map_intensity;
+                my_colors[l].green = (temp_pack.green << 8) * raster_map_intensity;
+                my_colors[l].blue  = (temp_pack.blue << 8) * raster_map_intensity;
+            }
+
+            // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
+            if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+            }
+            else {
+                pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                &my_colors[l].pixel);
+            }
+
+            //if (debug_level & 512)
+            //    fprintf(stderr,"Color allocated is %li  %i  %i  %i \n", my_colors[l].pixel,
+            //           my_colors[l].red, my_colors[l].blue, my_colors[l].green);
+        }
+    }
+
+    /*
+    * Here are the corners of our viewport, using the Xastir
+    * coordinate system.  Notice that Y is upside down:
+    *
+    *   left edge of view = NW_corner_longitude
+    *  right edge of view = SE_corner_longitude
+    *    top edge of view = NW_corner_latitude
+    * bottom edge of view = SE_corner_latitude
+    *
+    * The corners of our image were calculated and stored
+    * above as tiepoints using OSM units (pixels/circle). They are:
+    *
+    *   left edge of map = tp[0].x_long
+    *  right edge of map = tp[1].x_long
+    *    top edge of map = tp[0].y_lat
+    * bottom edge of map = tp[1].y_lat
+    *
+    */
+
+    scr_dx = 1;
+    scr_dy = 1;
+
+    // calculate map pixel range in y direction that falls into screen area
+    map_y_min = map_y_max = 0l;
+    for (map_image_row = 0; map_image_row < (long)image->rows; map_image_row++){
+        scr_y = (pixelLat2xastirLat(map_image_row + tpNW->y_lat, osm_zl) - NW_corner_latitude) / scale_y;
+        if (scr_y > 0) {
+            if (scr_y < screen_height) {
+                map_y_max = map_image_row;  // update last map pixel in y
+            } else
+                break;                      // done, reached bottom screen border
+        } else {                            // pixel is above screen
+            map_y_min = map_image_row;     // update first map pixel in y
+        }
+    }
+
+    // Calculate the position of the map image relative to the screen
+    map_x_min = map_x_max = 0l;
+    for (map_image_col = 0; map_image_col < (long)image->columns; map_image_col++) {
+        scr_x = (pixelLon2xastirLon(map_image_col + tpNW->x_long, osm_zl) - NW_corner_longitude) / scale_x;
+        if (scr_x > 0) {
+            if (scr_x < screen_width)
+                map_x_max = map_image_col;          // update last map pixel in x
+            else
+                break;                      // done, reached right screen border
+        } else {                            // pixel is left from screen
+            map_x_min = map_image_col;              // update first map pixel in x
+        }
+    }
+
+    scr_yp = -1;
+    map_done = 0;
+    map_act  = 0;
+    map_seen = 0;
+
+    // loop over map pixel rows
+    for (map_image_row = map_y_min; (map_image_row <= map_y_max); map_image_row++) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        scr_y = (pixelLat2xastirLat(map_image_row + tpNW->y_lat, osm_zl)
+                                    - NW_corner_latitude) / scale_y;
+
+        // image rows do not match 1:1 with screen rows due to Mercator
+        // scaling, so scr_dy will be passed to XFillRectangle to 
+        // handle that issue.
+        // scr_dy is in rows and must be a minimum of 1 row.
+        scr_dy = ((  pixelLat2xastirLat(map_image_row + 1 + tpNW->y_lat, osm_zl)
+                   - NW_corner_latitude) / scale_y) - scr_y;
+        if (scr_dy < 1)
+            scr_dy = 1;
+
+        if (scr_y != scr_yp) {                  // don't do a row twice
+            scr_yp = scr_y;                     // remember as previous y
+            scr_xp = -1;
+            // loop over map pixel columns
+            map_act = 0;
+            for (map_image_col = map_x_min; map_image_col <= map_x_max; map_image_col++) {
+                scr_x = (  pixelLon2xastirLon(map_image_col + tpNW->x_long, osm_zl)
+                         - NW_corner_longitude) / scale_x;
+                // handle the case when here the horizontal resolution
+                // of the image is less than the horizontal resolution
+                // displayed. scr_dx is passed to XFillRectangle() below
+                // and must be at least 1 column.
+                scr_dx = ( (pixelLon2xastirLon(map_image_col + 1 + tpNW->x_long, osm_zl)
+                          - NW_corner_longitude) / scale_x) - scr_x;
+                if (scr_dx < 1)
+                    scr_dx = 1;
+                if (scr_x != scr_xp) {      // don't do a pixel twice
+                    scr_xp = scr_x;         // remember as previous x
+
+                    // check map boundaries in y direction
+                    if (map_image_row >= 0 && map_image_row <= tpSE->img_y) {
+                        map_seen = 1;
+                        map_act = 1;   // detects blank screen rows (end of map)
+
+                        // now copy a pixel from the map image to the screen
+                        l = map_image_col + map_image_row * image->columns;
+                        if (image->storage_class == PseudoClass) {
+                            // Make matte transparent by skipping pixels
+                            if (xastirColorsMatch(pixel_pack[l],image->matte_color)) {
+                                continue;
+                            }
+                            XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel);
+                        }
+                        else {
+                            // Skip transparent pixels and make matte
+                            // colored pixels transparent (by skipping)
+                            if ((pixel_pack[l].opacity == TransparentOpacity)
+                                || (xastirColorsMatch(pixel_pack[l], image->matte_color))){
+                                continue;
+                            }
+
+                            // It is not safe to assume that the red/green/blue
+                            // elements of pixel_pack of type Quantum are the
+                            // same as the red/green/blue of an XColor!
+                            if (QuantumDepth==16) {
+                                my_colors[0].red=pixel_pack[l].red;
+                                my_colors[0].green=pixel_pack[l].green;
+                                my_colors[0].blue=pixel_pack[l].blue;
+                            }
+                            else { // QuantumDepth=8
+                                // shift the bits of the 8-bit quantity so that
+                                // they become the high bigs of my_colors.*
+                                my_colors[0].red=pixel_pack[l].red<<8;
+                                my_colors[0].green=pixel_pack[l].green<<8;
+                                my_colors[0].blue=pixel_pack[l].blue<<8;
+                            }
+                            // NOW my_colors has the right r,g,b range for
+                            // pack_pixel_bits
+                            pack_pixel_bits(my_colors[0].red * raster_map_intensity,
+                                            my_colors[0].green * raster_map_intensity,
+                                            my_colors[0].blue * raster_map_intensity,
+                                            &my_colors[0].pixel);
+                            XSetForeground(XtDisplay(w), gc, my_colors[0].pixel);
+                        }
+                        // write the pixel from the map image to the
+                        // screen. Strech to a rectangle as needed
+                        // specified by scr_dx and scr_dy.
+                        (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,scr_dx,scr_dy);
+                    } // check map boundaries in y direction
+                }  // don't do a screen pixel twice (in the same row)
+            } // loop over map pixel columns
+
+            if (map_seen && !map_act)
+                map_done = 1;
+        } // don't do a screen row twice.
+    } // loop over map pixel rows
+}  // end draw_OSM_image()
+
+
+/**********************************************************
+ * draw_OSM_tiles() - retrieve enough map tiles to fill the display
+ **********************************************************/
+// MaxTextExtent is an ImageMagick/GraphicMagick constant
+#define MAX_TMPSTRING MaxTextExtent
+
+void draw_OSM_tiles (Widget w,
+        char *filenm,           // this is the name of the xastir map file
+        int destination_pixmap,
+        char *server_url,      // if specified in xastir map file
+        char *tileCacheDir,    // if specified in xastir map file
+        char *mapName,         // if specified in xastir map file
+        char *tileExt) {       // if specified in xastir map file
+
+    char serverURL[MAX_FILENAME];
+    char tileRootDir[MAX_FILENAME];
+    char map_it[MAX_FILENAME];
+    char short_filenm[MAX_FILENAME];
+    int osm_zl;
+    tileArea_t tiles;
+    coord_t corner;
+    tiepoint NWcorner;
+    tiepoint SEcorner;
+    unsigned long tilex, tiley;
+    unsigned long tileCnt = 0;
+    unsigned long numTiles;
+    int interrupted = 0;
+
+    ExceptionInfo exception;
+    Image *canvas = NULL;
+    Image *tile = NULL;
+    ImageInfo *canvas_info = NULL;
+    ImageInfo *tile_info = NULL;
+    unsigned int row, col;
+    unsigned int offset_x, offset_y;
+    char tmpString[MAX_TMPSTRING];
+
+#ifdef HAVE_LIBCURL
+    CURL *mySession;
+    char errBuf[CURL_ERROR_SIZE];
+    int curl_result;
+#endif // HAVE_LIBCURL
+    char temp_file_path[MAX_VALUE];
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        // Force the extents to the edges of the earth for the
+        // index file.
+        index_update_xastir(filenm, // Filename only
+            64800000l,      // Bottom
+            0l,             // Top
+            0l,             // Left
+            129600000l,     // Right
+            0);             // Default Map Level
+
+        // Update statusline
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),  // Indexing %s
+            short_filenm);
+        statusline(map_it,0);       // Indexing
+
+        return; // Done indexing this file
+    }
+
+    if (tileCacheDir[0] != '\0') {
+        if (tileCacheDir[0] == '/') {
+            xastir_snprintf(tileRootDir, sizeof(tileRootDir),
+                    "%s", tileCacheDir);
+        } else {
+            xastir_snprintf(tileRootDir, sizeof(tileRootDir),
+                    "%s", get_user_base_dir(tileCacheDir, temp_file_path, sizeof(temp_file_path)));
+        }
+    } else {
+        xastir_snprintf(tileRootDir, sizeof(tileRootDir),
+                "%s", get_user_base_dir("OSMtiles", temp_file_path, sizeof(temp_file_path)));
+    }
+    
+    if (mapName[0] != '\0') {
+        xastir_snprintf(tmpString, sizeof(tmpString), "/%s", mapName);
+        strncat(tileRootDir, tmpString, sizeof(tileRootDir) - 1 - strlen(tileRootDir));
+    }
+
+    if (server_url[0] != '\0') {
+        xastir_snprintf(serverURL, sizeof(serverURL),
+                "%s", server_url);
+    } else {
+        xastir_snprintf(serverURL, sizeof(serverURL),
+                "%s", "http://tile.openstreetmap.org");
+    }
+
+    if (server_url[strlen(serverURL) - 1] == '/') {
+        serverURL[strlen(serverURL) - 1] = '\0';
+    }
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Allow space for the
+    // "Indexing " or "Loading " strings.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    GetExceptionInfo(&exception);
+
+    if (debug_level & 512) {
+        unsigned long lat, lon;
+        (void)convert_to_xastir_coordinates(&lon, &lat,
+                                 f_NW_corner_longitude, f_NW_corner_latitude);
+        fprintf(stderr, "NW_corner_longitude = %f, %ld, %ld\n",
+                f_NW_corner_longitude, NW_corner_longitude, lon);
+        fprintf(stderr, "NW_corner_latitude = %f, %ld, %ld\n",
+                f_NW_corner_latitude, NW_corner_latitude, lat);
+
+        (void)convert_to_xastir_coordinates(&lon, &lat,
+                                 f_SE_corner_longitude, f_SE_corner_latitude);
+        fprintf(stderr, "SE_corner_longitude = %f, %ld, %ld\n",
+                f_SE_corner_longitude, SE_corner_longitude, lon);
+        fprintf(stderr, "SE_corner_latitude = %f, %ld, %ld\n",
+                f_SE_corner_latitude, SE_corner_latitude, lat);
+    }
+
+    osm_zl = osm_zoom_level(scale_x);
+    calcTileArea(f_NW_corner_longitude, f_NW_corner_latitude,
+                 f_SE_corner_longitude, f_SE_corner_latitude,
+                 osm_zl, &tiles);
+
+    xastir_snprintf(map_it, sizeof(map_it), "%s",
+            langcode ("BBARSTA050")); // Downloading tiles...
+    statusline(map_it,0);
+    XmUpdateDisplay(text);
+    
+    // make sure all the map directories exist
+    mkOSMmapDirs(tileRootDir, tiles.startx, tiles.endx, osm_zl);
+
+    // Check to see how many tiles need to be downloaded
+    // A simple calculation doesn't work well here because some
+    // (possibly all) of the tiles may exist in the cache.
+    numTiles = tilesMissing(tiles.startx, tiles.endx, tiles.starty,
+                            tiles.endy, osm_zl, tileRootDir,
+                            tileExt[0] != '\0' ? tileExt : "png");
+
+#ifdef HAVE_LIBCURL
+    mySession = xastir_curl_init(errBuf);
+#endif // HAVE_LIBCURL
+
+    // get the tiles
+    tileCnt = 1;
+    for (tilex = tiles.startx; tilex <= tiles.endx; tilex++) {
+        for (tiley = tiles.starty; tiley <= tiles.endy; tiley++) {
+            if ((numTiles > 0) & (tileCnt <= numTiles)) {
+                xastir_snprintf(map_it, sizeof(map_it), langcode("BBARSTA051"),
+                        tileCnt, numTiles);  // Downloading tile %ls of %ls
+                statusline(map_it,0);
+                XmUpdateDisplay(text);
+            }
+
+#ifdef HAVE_LIBCURL
+            curl_result = getOneTile(mySession, serverURL, tilex, tiley,
+                    osm_zl, tileRootDir, tileExt[0] != '\0' ? tileExt : "png");
+            if (curl_result < 0) {
+               fprintf(stderr, "Download error for tile: %s/%i/%li/%li.%s\n",
+                       serverURL, osm_zl, tilex, tiley,
+                       tileExt[0] != '\0' ? tileExt : "png");
+               fprintf(stderr, "curl told us %d\n", -1 * curl_result);
+               fprintf(stderr, "curlerr: %s\n", errBuf);
+            } else {
+                tileCnt += curl_result;
+            }
+#else
+            tileCnt += getOneTile(serverURL, tilex, tiley,
+                    osm_zl, tileRootDir, tileExt[0] != '\0' ? tileExt : "png");
+#endif // HAVE_LIBCURL
+
+            HandlePendingEvents(app_context);
+            if (interrupt_drawing_now) {
+                interrupted = 1;
+                break;
+            }
+        }
+        if (interrupted == 1) {
+            break;
+        }
+    }
+
+#ifdef HAVE_LIBCURL
+    curl_easy_cleanup(mySession);
+#endif // HAVE_LIBCURL
+
+    if (interrupted != 1) {
+        // calculate tie points
+        NWcorner.img_x = 0;
+        NWcorner.img_y = 0;
+        NWcorner.x_long = tiles.startx * 256;
+        NWcorner.y_lat = tiles.starty * 256;
+
+        if (debug_level & 512) {
+            fprintf(stderr, "scale = %ld, zoom = %d\n", scale_x, osm_zl);
+            fprintf(stderr, "NW corner:\n");
+            fprintf(stderr, "  img_x = %d, img_y = %d\n", NWcorner.img_x, NWcorner.img_y);
+            fprintf(stderr, "  x_long = %ld, y_lat = %ld\n", NWcorner.x_long, NWcorner.y_lat);
+            fprintf(stderr, "req. lon = %f, lat = %f\n", f_NW_corner_longitude,
+                    f_NW_corner_latitude);
+            tile2coord(tiles.startx, tiles.starty, osm_zl, &corner);
+            fprintf(stderr, "ret. lon = %f, lat = %f\n", corner.lon, corner.lat);
+            fprintf(stderr, "tile x = %li, y = %li\n", tiles.startx, tiles.starty);
+        }
+
+        // The NW corner of the next tile is the SE corner of the last tile
+        // we fetched. So add one to the end tile numbers before calculating
+        // the coordinates.
+        SEcorner.img_x = (256 * ((tiles.endx + 1) - tiles.startx)) - 1;
+        SEcorner.img_y = (256 * ((tiles.endy + 1) - tiles.starty)) - 1;
+        SEcorner.x_long = (tiles.endx + 1) * 256;
+        SEcorner.y_lat = (tiles.endy + 1) * 256;
+        
+        if (debug_level & 512) {
+            fprintf(stderr, "SE corner:\n");
+            fprintf(stderr, "  img_x = %d, img_y = %d\n", SEcorner.img_x, SEcorner.img_y);
+            fprintf(stderr, "  x_long = %ld, y_lat = %ld\n", SEcorner.x_long, SEcorner.y_lat);
+            fprintf(stderr, "req. lon = %f, lat = %f\n", f_SE_corner_longitude,
+                    f_SE_corner_latitude);
+            tile2coord(tiles.endx + 1, tiles.endy + 1, osm_zl, &corner);
+            fprintf(stderr, "ret. lon = %f, lat = %f\n", corner.lon, corner.lat);
+            fprintf(stderr, "tile x = %li, y = %li\n", tiles.endx, tiles.endy);
+        }
+
+        /*
+         * Create a canvas upon which the tiles will be composited.
+        */
+        canvas_info=CloneImageInfo((ImageInfo *)NULL);
+
+        // Set canvas dimensions in pixels
+        xastir_snprintf(tmpString, sizeof(tmpString), "%lix%li",
+                ((tiles.endx + 1) - tiles.startx) * 256,
+                ((tiles.endy + 1) - tiles.starty) * 256);
+        (void)CloneString(&canvas_info->size, tmpString);
+
+        /*
+         * A file name based on a color creates an image filled
+         * with that color. The matte color will be treated as
+         * transparent when the completed OSM map gets copied to the X
+         * display.
+         */
+        FormatString(canvas_info->filename, "%s", MATTE_COLOR_STRING);
+        canvas = ReadImage(canvas_info, &exception);
+        if (exception.severity != UndefinedException) {
+            CatchException(&exception);
+            fprintf(stderr, "Could not allocate canvas to hold tiles.\n");
+            if (canvas_info != NULL) {
+                DestroyImageInfo(canvas_info);
+            }
+            return;
+        }
+        // Make sure that the canvas is an image type that uses the
+        // opacity channel for compositing.
+        SetImageType(canvas, PaletteMatteType);
+
+        // Fill the image with an opaque color. Ultimately pixels that
+        // are this color will be skipped when the image is written to
+        // the screen.
+        canvas->background_color.red = MATTE_RED;
+        canvas->background_color.green = MATTE_GREEN;
+        canvas->background_color.blue = MATTE_BLUE;
+        canvas->background_color.opacity = MATTE_OPACITY;
+        SetImage(canvas, MATTE_OPACITY);
+
+        xastir_snprintf(map_it, sizeof(map_it), "%s",
+                langcode ("BBARSTA049")); // Reading tiles...
+        statusline(map_it,0);
+        XmUpdateDisplay(text);
+
+        tile_info = CloneImageInfo((ImageInfo *)NULL);
+
+        // Read the tile and composite them onto the canvas
+        for (col = tiles.starty, offset_y = 0;
+             col <= tiles.endy;
+             col++, offset_y += 256) {
+            for (row = tiles.startx, offset_x = 0;
+                 row <= tiles.endx;
+                 row++, offset_x += 256) {
+                xastir_snprintf(tmpString, sizeof(tmpString),
+                        "%s/%d/%d/%d.%s", tileRootDir, osm_zl, row, col,
+                        tileExt[0] != '\0' ? tileExt : "png");
+                strncpy(tile_info->filename, tmpString, MaxTextExtent);
+
+                tile = ReadImage(tile_info,&exception);
+                if (exception.severity != UndefinedException) {
+                    CatchException(&exception);
+                    xastir_snprintf(tmpString, sizeof(tmpString), "%s/%d/%d/%d.%s",
+                            tileRootDir, osm_zl, row, col,
+                            tileExt[0] != '\0' ? tileExt : "png");
+                    if (debug_level & 512) {
+                        fprintf(stderr, "%s NOT removed.\n", tmpString);
+                    } else {
+                        fprintf(stderr, "Removing %s\n", tmpString);
+                        unlink(tmpString);
+                    }
+                    // clear exception so next iteration doesn't fail
+                    GetExceptionInfo(&exception);
+
+                    // replace the missing tile with a place holder
+                    //(void)strcpy(tile_info->filename, "xc:red");
+                    //tile = ReadImage(tile_info, &exception);
+                }
+                if (tile) {
+                    (void)CompositeImage(canvas, OverCompositeOp,
+                            tile, offset_x, offset_y);
+                    DestroyImage(tile);
+                }
+            }
+        }
+
+        // Set the matte color for use in transparentency testing
+        canvas->matte_color.red = MATTE_RED;
+        canvas->matte_color.green = MATTE_GREEN;
+        canvas->matte_color.blue = MATTE_BLUE;
+
+        if (debug_level & 512) {
+            DescribeImage(canvas, stderr, 0);
+            WriteImages(canvas_info, canvas, "/tmp/xastirOSMTiledMap.png", &exception);
+        }
+
+        draw_OSM_image(w, canvas, &exception, &NWcorner, &SEcorner, osm_zl);
+
+        // Display the OpenStreetMap attribution
+        // Just resuse the tile structure rather than creating another.
+        xastir_snprintf(tmpString, sizeof(tmpString),
+                "%s/CC_OpenStreetMap.png", get_data_base_dir("maps"));
+        strncpy(tile_info->filename, tmpString, MaxTextExtent);
+
+        tile = ReadImage(tile_info,&exception);
+        if (exception.severity != UndefinedException) {
+            CatchException(&exception);
+        } else {
+            draw_image(w, tile, &exception, 4, 4);
+            DestroyImage(tile);
+        }
+    } else {
+        // map draw was interrupted
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    }
+
+    /*
+     * Release resources
+    */
+    if (tile_info != NULL)
+        DestroyImageInfo(tile_info);
+    if (canvas_info != NULL)
+        DestroyImageInfo(canvas_info);
+    if (canvas != NULL)
+        DestroyImage(canvas);
+    DestroyExceptionInfo(&exception);
+    return;
+
+} // draw_OSM_tiles()
+
+
+/**********************************************************
+ * draw_OSM_map() - retreive an image that is the size of the display
+ **********************************************************/
+void draw_OSM_map (Widget w,
+        char *filenm,
+        int destination_pixmap,
+        char *url,
+        char *style,
+        int nocache) {  // For future implementation of a "refresh cached map" option
+    char file[MAX_FILENAME];        // Complete path/name of image file
+    char short_filenm[MAX_FILENAME];
+    FILE *f;                        // Filehandle of image file
+    char fileimg[MAX_FILENAME];     // Ascii name of image file, read from GEO file
+    char OSMtmp[MAX_FILENAME*2];    // Used for putting together the OSMmap query
+    tiepoint tp[2];                 // Calibration points for map
+
+    char local_filename[MAX_FILENAME];
+    
+    ExceptionInfo exception;
+    Image *image;
+    ImageInfo *image_info;
+    double left, right, top, bottom;
+    double lat_center  = 0;
+    double long_center = 0;
+
+    char map_it[MAX_FILENAME];
+    char tmpstr[1001];
+    int osm_zl = 18;                 // OSM zoom level, at 18, the whole
+                                     // world fits in one 256x256 tile.
+    unsigned map_image_width;        // Image width
+    unsigned map_image_height;       // Image height
+    // TODO: put the max_image_* limits in the .geo/.osm file because it could change on a by-server
+    //       basis and the server URL can be specified in the .geo/.osm file.
+    unsigned max_image_width = 2000;  // This value is for the default server
+    unsigned max_image_height = 2000; // This value is for the default server
+
+    // initialize this
+    local_filename[0]='\0';
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    xastir_snprintf(map_it,
+        sizeof(map_it),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(map_it,0);       // Loading ...
+    XmUpdateDisplay(text);
+        
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        // Force the extents to the edges of the earth for the
+        // index file.
+        index_update_xastir(filenm, // Filename only
+            64800000l,      // Bottom
+            0l,             // Top
+            0l,             // Left
+            129600000l,     // Right
+            0);             // Default Map Level
+
+        // Update statusline
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(map_it,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+
+    // calculate the OSM zoom level (osm_zl) that is nearest the xastir scale
+    osm_zl = osm_zoom_level(scale_x);
+
+    // Calculate the image size to request. The size will be saved as tiepoints
+    // for the top-left and bottom-right of the image.
+    tp[0].x_long = xastirLon2pixelLon(NW_corner_longitude, osm_zl); // OSM pixels
+    tp[1].x_long = xastirLon2pixelLon(SE_corner_longitude, osm_zl); // OSM pixels
+    tp[0].y_lat = xastirLat2pixelLat(NW_corner_latitude, osm_zl);  // OSM pixels
+    tp[1].y_lat = xastirLat2pixelLat(SE_corner_latitude, osm_zl);  // OSM pixels
+
+    map_image_height = tp[1].y_lat - tp[0].y_lat;
+    map_image_width = tp[1].x_long - tp[0].x_long;
+
+    // Limit dimensions to the max the server will allow.
+    if (map_image_width > max_image_width) {
+        int tmp = ((map_image_width - map_image_height) / 2) + 1;
+        tp[0].x_long += tmp;
+        tp[1].x_long -= tmp;
+        map_image_width = tp[1].x_long - tp[0].x_long;
+    }
+
+    if (map_image_height > max_image_height) {
+        int tmp = ((map_image_height - max_image_height) / 2) + 1;
+        tp[0].y_lat += tmp;
+        tp[1].y_lat -= tmp;
+        map_image_height = tp[1].y_lat - tp[0].y_lat;
+    }
+
+    // Size and coordinates for the tiepoints in pixels
+    tp[0].img_x = 0;
+    tp[0].img_y = 0;
+    tp[1].img_x = map_image_width - 1;
+    tp[1].img_y = map_image_height - 1;
+
+    // calculate the center coordinates for the image request
+    left = (double)((NW_corner_longitude - 64800000l )/360000.0);   // Lat/long Coordinates, degrees
+    top = (double)(-((NW_corner_latitude - 32400000l )/360000.0));  // Lat/long Coordinates, degrees
+    right = (double)((SE_corner_longitude - 64800000l)/360000.0);   //Lat/long Coordinates, degrees
+    bottom = (double)(-((SE_corner_latitude - 32400000l)/360000.0));//Lat/long Coordinates, degrees
+
+    long_center = (left + right)/2.0l; // degrees
+
+    // The vertical center of the image must be calculated from the OSM image size to
+    // compensate for latitude scaling (Mercator). This is particularly important for small image/screen
+    // sizes and may not be apparent on large displays.
+    lat_center = pixelLat2Lat((map_image_height / 2) + tp[0].y_lat, osm_zl);
+
+    /*
+     * Query format to the StaticMap
+     * See: http://ojw.dev.openstreetmap.org/StaticMap/?mode=API&
+     *
+     * http://ojw.dev.openstreetmap.org/StaticMap/?lat=LL.LLLLLL&lon=-LLL.LLLLL&z=15& \
+     *     w=WWW&h=HHH&layer=osmarender&mode=Export&att=none&show=1
+     */
+
+    if (url[0] != '\0') {
+        xastir_snprintf(OSMtmp, sizeof(OSMtmp), "%s", url);
+    } else {
+        xastir_snprintf(OSMtmp, sizeof(OSMtmp), "http://ojw.dev.openstreetmap.org/StaticMap/");
+    }
+    //xastir_snprintf(tmpstr, sizeof(tmpstr), "?mode=Export&att=text&show=1&");
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "?mode=Export&show=1&");
+    strncat (OSMtmp, tmpstr, sizeof(OSMtmp) - 1 - strlen(OSMtmp));
+
+    if (style[0] != '\0') {
+        xastir_snprintf(tmpstr, sizeof(tmpstr), "%s", style);
+        strncat (OSMtmp, tmpstr, sizeof(OSMtmp) - 1 - strlen(OSMtmp));
+    } else {
+        xastir_snprintf(tmpstr, sizeof(tmpstr), "layer=osmarender&");
+        strncat (OSMtmp, tmpstr, sizeof(OSMtmp) - 1 - strlen(OSMtmp));
+    }
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "&lat=%f\046lon=%f\046", lat_center, long_center);    
+    strncat (OSMtmp, tmpstr, sizeof(OSMtmp) - 1 - strlen(OSMtmp));
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "w=%i\046h=%i\046", map_image_width, map_image_height);
+    strncat (OSMtmp, tmpstr, sizeof(OSMtmp) - 1 - strlen(OSMtmp));
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "z=%d", osm_zl);
+    strncat (OSMtmp, tmpstr, sizeof(OSMtmp) - 1 - strlen(OSMtmp));
+
+    xastir_snprintf(fileimg, sizeof(fileimg), "%s", OSMtmp);
+
+    if (debug_level & 512) {
+          fprintf(stderr,"left side is %f\n", left);
+          fprintf(stderr,"right side is %f\n", right);
+          fprintf(stderr,"top  is %f\n", top);
+          fprintf(stderr,"bottom is %f\n", bottom);
+          fprintf(stderr,"lat center is %f\n", lat_center);
+          fprintf(stderr,"long center is %f\n", long_center);
+          fprintf(stderr,"screen width is %li\n", screen_width);
+          fprintf(stderr,"screen height is %li\n", screen_height);
+          fprintf(stderr,"OSM image width is %i\n", map_image_width);
+          fprintf(stderr,"OSM image height is %i\n", map_image_height);
+          fprintf(stderr,"scale_y = %li\n", scale_y);
+          fprintf(stderr,"scale_x = %li\n", scale_x);
+          fprintf(stderr,"OSM zoom level = %i\n", osm_zl);
+          fprintf(stderr,"fileimg is %s\n", fileimg);
+          fprintf(stderr,"ftp or http file: %s\n", fileimg);
+    }
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    get_OSM_local_file(local_filename,fileimg); 
+
+    // Tell ImageMagick where to find it
+    xastir_snprintf(file,
+        sizeof(file),
+        "%s",
+        local_filename);
+
+    GetExceptionInfo(&exception);
+
+    image_info=CloneImageInfo((ImageInfo *) NULL);
+
+    xastir_snprintf(image_info->filename,
+        sizeof(image_info->filename),
+        "%s",
+        file);
+
+    if (debug_level & 512) {
+           fprintf(stderr,"Copied %s into image info.\n", file);
+           fprintf(stderr,"image_info got: %s\n", image_info->filename);
+           fprintf(stderr,"Entered ImageMagick code.\n");
+           fprintf(stderr,"Attempting to open: %s\n", image_info->filename);
+    }
+
+    // We do a test read first to see if the file exists, so we
+    // don't kill Xastir in the ReadImage routine.
+    f = fopen (image_info->filename, "r");
+    if (f == NULL) {
+        if (debug_level & 512)
+            fprintf(stderr,"File could not be read\n");
+
+#ifdef USE_MAP_CACHE
+
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete unreadable map from cache\n");
+            }
+        }
+#endif
+         
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+    (void)fclose (f);
+
+
+    image = ReadImage(image_info, &exception);
+
+    if (image == (Image *) NULL) {
+        MagickWarning(exception.severity, exception.reason, exception.description);
+        //fprintf(stderr,"MagickWarning\n");
+
+#ifdef USE_MAP_CACHE
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete map from cache\n");
+            }
+        }
+#endif
+
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+
+    } else if ( (image->columns != map_image_width)
+               || (image->rows != map_image_height)) {
+        fprintf(stderr, "Server returned an image size different than requested!\n");
+
+#ifdef USE_MAP_CACHE
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete map from cache\n");
+            }
+        }
+#endif
+        if (image) {
+            DestroyImage(image);
+        }
+        if (image_info) {
+            DestroyImageInfo(image_info);
+        }
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    if (debug_level & 512) {
+        fprintf(stderr,"Image: %s\n", file);
+        fprintf(stderr,"Image size %d %d\n", map_image_width, map_image_height);
+#if (MagickLibVersion < 0x0540)
+        fprintf(stderr,"Unique colors = %d\n", GetNumberColors(image, NULL));
+#else // MagickLib < 540
+        fprintf(stderr,"Unique colors = %ld\n", GetNumberColors(image, NULL, &exception));
+#endif // MagickLib < 540
+        fprintf(stderr,"image matte is %i\n", image->matte);
+    } // debug_level & 512
+
+    draw_OSM_image(w, image, &exception, &(tp[0]), &(tp[1]), osm_zl);
+    DestroyImage(image);
+    
+    // Display the OpenStreetMap attribution
+    xastir_snprintf(OSMtmp, sizeof(OSMtmp),
+            "%s/CC_OpenStreetMap.png", get_data_base_dir("maps"));
+    strncpy(image_info->filename, OSMtmp, MaxTextExtent);
+
+    image = ReadImage(image_info,&exception);
+    if (exception.severity != UndefinedException) {
+        CatchException(&exception);
+    } else {
+        draw_image(w, image, &exception, 4, 4);
+    }
+
+
+    // Clean up
+    if (image) {
+        DestroyImage(image);
+    }
+    if (image_info) {
+        DestroyImageInfo(image_info);
+    }
+    DestroyExceptionInfo(&exception);
+
+}  // end draw_OSM_map()
+
+
+#endif //HAVE_MAGICK
+///////////////////////////////////////////// End of OpenStreetMap code ///////////////////////////////////////
+
+
+
diff --git a/src/map_OSM.h b/src/map_OSM.h
new file mode 100644
index 0000000..8324ff2
--- /dev/null
+++ b/src/map_OSM.h
@@ -0,0 +1,60 @@
+/*
+ * $Id: map_OSM.h,v 1.6 2012/11/01 18:57:19 we7u Exp $
+ *
+ * Copyright (C) 2012 The Xastir Group
+ *
+ * This file was contributed by Jerry Dunmire, KA6HLD.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ */
+#ifndef OSM_H
+#define OSM_H
+
+#include <X11/X.h>           // for KeySym
+
+#define MAX_OSMSTYLE 1000  // max characters in the a OSM style argument
+#define MAX_OSM_URL  1000  // max characters for a OSM URL
+#define MAX_OSMEXT     10  // max characters for a tilename extension
+
+void adj_to_OSM_level(
+        long *new_scale_x,
+        long *new_scale_y);
+
+void draw_OSM_map(Widget w,
+        char *filenm,
+        int destination_pixmap,
+        char *url,
+        char *style,
+        int nocache);
+
+void draw_OSM_tiles(Widget w,
+        char *filenm,
+        int destination_pixmap,
+        char *server_url,
+        char *tileCacheDir,
+        char *mapName,
+        char *tileExt);
+
+unsigned int osm_zoom_level(long scale_x);
+void init_OSM_values(void);
+int OSM_optimize_key(KeySym key);
+void set_OSM_optimize_key(KeySym key);
+int OSM_report_scale_key(KeySym key);
+void set_OSM_report_scale_key(KeySym key);
+
+#endif //OSM_H
diff --git a/src/map_WMS.c b/src/map_WMS.c
new file mode 100644
index 0000000..db1359b
--- /dev/null
+++ b/src/map_WMS.c
@@ -0,0 +1,1042 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_WMS.c,v 1.42 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "fetch_remote.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+#include "map_cache.h"
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+#ifdef HAVE_MAGICK
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+#undef RETSIGTYPE
+// TVR: "stupid ImageMagick"
+// The problem is that magick/api.h includes Magick's config.h file, and that
+// pulls in all the same autoconf-generated defines that we use.
+// plays those games below, but I don't think in the end that they actually 
+// make usable macros with our own data in them.
+// Fortunately, we don't need them, so I'll just undef the ones that are
+// causing problems today.  See main.c for fixes that preserve our values.
+#undef PACKAGE
+#undef VERSION
+/* JMT - stupid ImageMagick */
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#ifdef HAVE_GRAPHICSMAGICK
+/*#include <GraphicsMagick/magick/api.h>*/
+#include <magick/api.h>
+#else   // HAVE_GRAPHICSMAGICK
+#include <magick/api.h>
+#endif  // HAVE_GRAPHICSMAGICK 
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#endif // HAVE_MAGICK
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+/**********************************************************
+ * draw_WMS_map()
+ **********************************************************/
+#ifdef HAVE_MAGICK
+void draw_WMS_map (Widget w,
+        char *filenm,
+        int destination_pixmap,
+        char *URL,
+        transparent_color_record *c_trans_color_head,
+        int nocache) {  // If non-zero, don't use cached version
+
+
+    char file[MAX_FILENAME];        // Complete path/name of image file
+    char short_filenm[MAX_FILENAME];
+    FILE *f;                        // Filehandle of image file
+    char fileimg[MAX_FILENAME];     // Ascii name of image file, read from GEO file
+    char WMStmp[MAX_FILENAME*2];  // Used for putting together the WMS map query
+    int width, height;
+    tiepoint tp[2];                 // Calibration points for map, read in from .geo file
+    register long map_c_T, map_c_L; // map delta NW edge coordinates, DNN: these should be signed
+    register long tp_c_dx, tp_c_dy; // tiepoint coordinate differences
+    unsigned long c_x_min,  c_y_min;// top left coordinates of map inside screen
+    unsigned long c_y_max;          // bottom right coordinates of map inside screen
+    double c_x;                     // Xastir coordinates 1/100 sec, 0 = 180�W
+    double c_y;                     // Xastir coordinates 1/100 sec, 0 =  90�N
+
+    long map_y_0;                   // map pixel pointer prior to TM adjustment
+    register long map_x, map_y;     // map pixel pointers, DNN: this was a float, chg to long
+    long map_x_min, map_x_max;      // map boundaries for in screen part of map
+    long map_y_min, map_y_max;      //
+    long map_x_ctr;                 // half map width in pixel
+    long map_y_ctr;                 // half map height in pixel
+    int map_seen = 0;
+    int map_act;
+    int map_done;
+
+    long map_c_yc;                  // map center, vert coordinate
+    long map_c_xc;                  // map center, hor  coordinate
+    double map_c_dx, map_c_dy;      // map coordinates increment (pixel width)
+    double c_dx;                    // adjusted map pixel width
+
+    long scr_x,  scr_y;             // screen pixel plot positions
+    long scr_xp, scr_yp;            // previous screen plot positions
+    int  scr_dx, scr_dy;            // increments in screen plot positions
+    long scr_x_mc;                  // map center in screen units
+
+    long scr_c_xr;
+
+    long scale_xa;                  // adjusted for topo maps
+    double scale_x_nm;              // nm per Xastir coordinate unit
+    long scale_x0;                  // at widest map area
+
+    char local_filename[MAX_FILENAME];
+    ExceptionInfo exception;
+    Image *image;
+    ImageInfo *image_info;
+    PixelPacket *pixel_pack;
+    PixelPacket temp_pack;
+    IndexPacket *index_pack;
+    int l;
+    XColor my_colors[256];
+    int trans_skip = 0;             // skip transparent pixel
+    double left, right, top, bottom, map_width, map_height;
+    double lat_center  = 0;
+    double long_center = 0;
+
+    char map_it[MAX_FILENAME];
+    char tmpstr[100];
+    int geo_image_width;        // Image width  from GEO file
+    int geo_image_height;       // Image height from GEO file
+
+    time_t query_start_time, query_end_time; 
+
+#ifdef USE_MAP_CACHE 
+    int map_cache_return;
+    char * cache_file_id;
+#endif  // USE_MAP_CACHE
+
+    char temp_file_path[MAX_VALUE];
+
+    if (debug_level & 512) {
+        if (nocache)
+            fprintf(stderr,"draw_WMS_map: NOCACHE selected\n");
+        else
+            fprintf(stderr,"draw_WMS_map: CACHING if enabled\n");
+    }
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    xastir_snprintf(map_it,
+        sizeof(map_it),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(map_it,0);       // Loading ...
+
+
+        
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        // Force the extents to the edges of the earth for the
+        // index file.
+        index_update_xastir(filenm, // Filename only
+            64800000l,      // Bottom
+            0l,             // Top
+            0l,             // Left
+            129600000l,     // Right
+            0);             // Default Map Level
+
+        // Update statusline
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(map_it,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+
+
+    // Tiepoint for upper left screen corner
+    //
+    tp[0].img_x = 0;                // Pixel Coordinates
+    tp[0].img_y = 0;                // Pixel Coordinates
+    tp[0].x_long = NW_corner_longitude;   // Xastir Coordinates
+    tp[0].y_lat  = NW_corner_latitude;    // Xastir Coordinates
+
+
+    // Tiepoint for lower right screen corner
+    //
+    // Here we must use scale_x for both directions because we have
+    // square pixels returned by the WMS server.
+
+
+// Really what we want to do here is to change our bounding box for
+// our request to fit square pixels, using scale_x for both
+// dimensions, and to change our tiepoints to match.  WMS servers
+// currently feed us back square pixels but the spec says that the
+// servers should be capable of sending back rectangular pixels, so
+// the images we get back may change if we don't request square
+// pixels each time.
+//
+// TODO:  Change our imagesize, bounding rectangle requested, and
+// tiepoints to fit square pixels and to use scale_x for both
+// dimensions.
+//
+// Actually, looking at the changes that were made, it looks like we
+// _are_ using square pixels and requesting a bounding box based on
+// scale_x for both dimensions, so we might be good to go as-is.
+
+
+    //
+    tp[1].img_x =  screen_width - 1; // Pixel Coordinates
+    tp[1].img_y = screen_height - 1; // Pixel Coordinates 
+    tp[1].x_long = SE_corner_longitude; // Xastir Coordinates
+
+// Modified to use same scale (scale_x) for both dimensions, square
+// pixels.  Don't use SE_corner_latitude here as it uses scale_y!
+//    tp[1].y_lat  =  NW_corner_latitude + ((screen_height) * scale_y); // Xastir Coordinates
+    tp[1].y_lat  =  NW_corner_latitude + ((screen_height) * scale_x); // Xastir Coordinates
+
+
+    // Again, use scale_x for both directions due to the square
+    // pixels returned from the WMS server.
+    //
+    left = (double)((NW_corner_longitude - 64800000l )/360000.0);   // Lat/long Coordinates
+    top = (double)(-((NW_corner_latitude - 32400000l )/360000.0));  // Lat/long Coordinates
+    right = (double)((SE_corner_longitude - 64800000l)/360000.0);//Lat/long Coordinates
+
+// Modified to use same scale (scale_x) for both dimensions, square
+// pixels.  Don't use SE_corner_latitude here as it uses scale_y!
+//    bottom = (double)(-(((NW_corner_latitude + ((screen_height) * scale_y) ) - 32400000l)/360000.0));//Lat/long Coordinates
+    bottom = (double)(-(((NW_corner_latitude + ((screen_height) * scale_x) ) - 32400000l)/360000.0));//Lat/long Coordinates
+
+
+    map_width = right - left;   // Lat/long Coordinates
+    map_height = top - bottom;  // Lat/long Coordinates
+
+    geo_image_width  = screen_width;
+    geo_image_height = screen_height;
+
+    long_center = (left + right)/2.0l;
+    lat_center  = (top + bottom)/2.0l;
+
+
+//  Example query for a WMS map server....
+//  xastir_snprintf(fileimg, sizeof(fileimg), 
+//  "\'http://mesonet.tamu.edu/cgi-bin/p-warn?SERVICE=WMS&VERSION=1.1.1&REQUEST=getmap&layers=radar&BBOX=-129.000,52.500,-111.000,42.500&HEIGHT=1000&WIDTH=1800&FORMAT=image/png\'");
+
+
+//    xastir_snprintf(WMStmp, sizeof(WMStmp),
+//        "http://mesonet.tamu.edu/cgi-bin/p-warn?SERVICE=WMS&VERSION=1.1.1&REQUEST=getmap");
+
+
+    xastir_snprintf(WMStmp, sizeof(WMStmp), "%s", URL);
+    strncat(WMStmp, "&REQUEST=getmap", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    strncat(WMStmp, "&EXCEPTIONS=INIMAGE", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+// This specifies a bounding box based on square pixels.
+    xastir_snprintf(tmpstr, sizeof(tmpstr),
+        "&BBOX=%8.5f,%7.5f,%8.5f,%7.5f",
+        left,   // Lower left
+        bottom, // Lower left
+        right,  // Upper right
+        top);   // Upper right
+    strncat (WMStmp, tmpstr, sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "&HEIGHT=%d", geo_image_height);
+    strncat (WMStmp, tmpstr, sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "&WIDTH=%d", geo_image_width);    
+    strncat (WMStmp, tmpstr, sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+
+// These should be specified in the .geo file instead of hard-coded:
+//
+//    strncat(WMStmp, "&VERSION=1.0.0", sizeof(WMStmp) - 1 - strlen(WMStmp));
+//    strncat(WMStmp, "&FORMAT=image/png", sizeof(WMStmp) - 1 - strlen(WMStmp));
+//    strncat(WMStmp, "&TRANSPARENT=TRUE", sizeof(WMStmp) - 1 - strlen(WMStmp));
+//    strncat(WMStmp, "&BGCOLOR=0xffffff", sizeof(WMStmp) - 1 - strlen(WMStmp));
+//    strncat(WMStmp, "&BGCOLOR=0x000000", sizeof(WMStmp) - 1 - strlen(WMStmp));
+//    strncat(WMStmp, "&CRS=CRS:84", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+
+
+
+
+/*
+    xastir_snprintf(WMStmp, sizeof(WMStmp), "http://tiger.census.gov/cgi-bin/mapper/map.png?");
+
+    if (tiger_show_grid)
+        strncat(WMStmp, "&on=GRID", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=GRID", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_counties)
+        strncat(WMStmp, "&on=counties", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=counties", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_cities)
+        strncat(WMStmp, "&on=CITIES", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=CITIES", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_places)
+        strncat(WMStmp, "&on=places", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=places", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_majroads)
+        strncat(WMStmp, "&on=majroads", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=majroads", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_streets)
+        strncat(WMStmp, "&on=streets", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    // Don't turn streets off since this will automagically show up as you zoom in.
+
+    if (tiger_show_railroad)
+        strncat(WMStmp, "&on=railroad", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=railroad", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_states)
+        strncat(WMStmp, "&on=states", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=states", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_interstate)
+        strncat(WMStmp, "&on=interstate", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=interstate", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_ushwy)
+        strncat(WMStmp, "&on=ushwy", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=ushwy", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_statehwy)
+        strncat(WMStmp, "&on=statehwy", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=statehwy", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_water)
+        strncat(WMStmp, "&on=water", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=water", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_lakes)
+        strncat(WMStmp, "&on=shorelin", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=shorelin", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    if (tiger_show_misc)
+        strncat(WMStmp, "&on=miscell", sizeof(WMStmp) - 1 - strlen(WMStmp));
+    else
+        strncat(WMStmp, "&off=miscell", sizeof(WMStmp) - 1 - strlen(WMStmp));
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "&lat=%f\046lon=%f\046", lat_center, long_center);    
+    strncat (WMStmp, tmpstr, sizeof(WMStmp) - 1 - strlen(WMStmp));
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "wid=%f\046ht=%f\046", map_width, map_height);
+    strncat (WMStmp, tmpstr, sizeof(WMStmp) - 1 - strlen(WMStmp));
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "iwd=%i\046iht=%i", tp[1].img_x + 1, tp[1].img_y + 1);
+    strncat (WMStmp, tmpstr, sizeof(WMStmp) - 1 - strlen(WMStmp)); */
+
+
+    xastir_snprintf(fileimg, sizeof(fileimg), "%s", WMStmp);
+
+    if (debug_level & 512) {
+          fprintf(stderr,"left side is %f\n", left);
+          fprintf(stderr,"right side is %f\n", right);
+          fprintf(stderr,"top  is %f\n", top);
+          fprintf(stderr,"bottom is %f\n", bottom);
+          fprintf(stderr,"lat center is %f\n", lat_center);
+          fprintf(stderr,"long center is %f\n", long_center);
+          fprintf(stderr,"screen width is %li\n", screen_width);
+          fprintf(stderr,"screen height is %li\n", screen_height);
+          fprintf(stderr,"map width is %f\n", map_width);
+          fprintf(stderr,"map height is %f\n", map_height);
+          fprintf(stderr,"fileimg is %s\n", fileimg);
+          fprintf(stderr,"ftp or http file: %s\n", fileimg);
+    }
+
+    if (debug_level & 512) {
+        query_start_time=time(&query_start_time); 
+    }
+
+
+#ifdef USE_MAP_CACHE 
+
+    if (nocache || map_cache_fetch_disable) {
+
+        // Delete old copy from the cache
+        if (map_cache_fetch_disable && fileimg[0] != '\0') {
+            if (map_cache_del(fileimg)) {
+                if (debug_level & 512) {
+                    fprintf(stderr,"Couldn't delete old map from cache\n");
+                }
+            }
+        }
+
+        // Simulate a cache miss
+        map_cache_return = 1;
+    }
+    else {
+        // Else look for the file in the cache
+    	map_cache_return = map_cache_get(fileimg,local_filename); 
+    }
+
+	if (debug_level & 512) {
+		fprintf(stderr,"map_cache_return: %d\n", map_cache_return);
+	}
+ 
+
+    // Don't use cached version if "nocache" is non-zero
+    //	   
+    if (nocache || map_cache_return != 0 ) {
+        // Caching has not been requested or cached file not found.
+        // We must snag the remote file via libcurl or wget.
+
+        if (nocache) {
+            xastir_snprintf(local_filename,
+                sizeof(local_filename),
+                "%s/map.%s",
+                 get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),
+                "png");
+        }
+        else {
+            cache_file_id = map_cache_fileid();
+            xastir_snprintf(local_filename,
+                sizeof(local_filename),
+                "%s/map_%s.%s",
+                get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)),
+                cache_file_id,
+                "png");
+            free(cache_file_id);
+        }
+
+#else   // USE_MAP_CACHE
+
+    xastir_snprintf(local_filename,
+        sizeof(local_filename),
+        "%s/map.%s",
+         get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),
+        "png");
+
+#endif  // USE_MAP_CACHE
+
+
+    // Erase any previously existing local file by the same name.
+    // This avoids the problem of having an old map image here and
+    // the code trying to display it when the download fails.
+
+    unlink( local_filename );
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    if (fetch_remote_file(fileimg, local_filename)) {
+        // Had trouble getting the file.  Abort.
+        return;
+    }
+
+    // For debugging the MagickError/MagickWarning segfaults.
+    //system("cat /dev/null >/var/tmp/xastir_hacker_map.png");
+
+    
+#ifdef USE_MAP_CACHE
+
+    // Cache this map only if nocache is zero
+    if (!nocache) {
+        map_cache_put(fileimg,local_filename);
+    }
+
+        } // end if is cached  DHBROWN
+#endif // USE_MAP_CACHE
+
+
+    if (debug_level & 512) {
+        fprintf (stderr, "Fetch or query took %d seconds\n", 
+            (int) (time(&query_end_time) - query_start_time)); 
+    }
+
+    // Set permissions on the file so that any user can overwrite it.
+    chmod(local_filename, 0666);
+
+    // Tell ImageMagick where to find it
+    xastir_snprintf(file,
+        sizeof(file),
+        "%s",
+        local_filename);
+
+    GetExceptionInfo(&exception);
+
+    image_info=CloneImageInfo((ImageInfo *) NULL);
+
+    xastir_snprintf(image_info->filename,
+        sizeof(image_info->filename),
+        "%s",
+        file);
+
+    if (debug_level & 512) {
+           fprintf(stderr,"Copied %s into image info.\n", file);
+           fprintf(stderr,"image_info got: %s\n", image_info->filename);
+           fprintf(stderr,"Entered ImageMagick code.\n");
+           fprintf(stderr,"Attempting to open: %s\n", image_info->filename);
+    }
+
+    // We do a test read first to see if the file exists, so we
+    // don't kill Xastir in the ReadImage routine.
+    f = fopen (image_info->filename, "r");
+    if (f == NULL) {
+        if (debug_level & 512)
+            fprintf(stderr,"File could not be read\n");
+        
+#ifdef USE_MAP_CACHE
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete map from cache\n");
+            }
+        }
+#endif
+         
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+    (void)fclose (f);
+
+
+    image = ReadImage(image_info, &exception);
+
+    if (image == (Image *) NULL) {
+        MagickWarning(exception.severity, exception.reason, exception.description);
+        //fprintf(stderr,"MagickWarning\n");
+
+#ifdef USE_MAP_CACHE
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete map from cache\n");
+            }
+        }
+#endif
+
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+
+
+    if (debug_level & 512)
+        fprintf(stderr,"Color depth is %i \n", (int)image->depth);
+
+    if (image->colorspace != RGBColorspace) {
+        fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    width = image->columns;
+    height = image->rows;
+
+    //  Code to mute the image so it's not as bright.
+/*    if (raster_map_intensity < 1.0) {
+        char tempstr[30];
+
+        if (debug_level & 512)
+            fprintf(stderr,"level=%s\n", tempstr);
+
+        xastir_snprintf(tempstr,
+            sizeof(tempstr),
+            "%d, 100, 100",
+            (int)(raster_map_intensity * 100.0));
+
+        ModulateImage(image, tempstr);
+    }
+*/
+
+
+    // If were are drawing to a low bpp display (typically < 8bpp)
+    // try to reduce the number of colors in an image.
+    // This may take some time, so it would be best to do ahead of
+    // time if it is a static image.
+#if (MagickLibVersion < 0x0540)
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) {
+#else   // MagickLib >= 540
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, &exception) > 128) {
+#endif  // MagickLib Version
+
+        if (image->storage_class == PseudoClass) {
+#if (MagickLibVersion < 0x0549)
+            CompressColormap(image); // Remove duplicate colors
+#else // MagickLib >= 0x0549
+            CompressImageColormap(image); // Remove duplicate colors
+#endif  // MagickLibVersion < 0x0549
+        }
+
+        // Quantize down to 128 will go here...
+    }
+
+
+    pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows);
+    if (!pixel_pack) {
+        fprintf(stderr,"pixel_pack == NULL!!!");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+
+    index_pack = GetIndexes(image);
+    if (image->storage_class == PseudoClass && !index_pack) {
+        fprintf(stderr,"PseudoClass && index_pack == NULL!!!");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+
+    if (image->storage_class == PseudoClass && image->colors <= 256) {
+        for (l = 0; l < (int)image->colors; l++) {
+            // Need to check how to do this for ANY image, as ImageMagick can read in all sorts
+            // of image files
+            temp_pack = image->colormap[l];
+            if (debug_level & 512)
+                fprintf(stderr,"Colormap color is %i  %i  %i \n",
+                       temp_pack.red, temp_pack.green, temp_pack.blue);
+
+            // Here's a tricky bit:  PixelPacket entries are defined as Quantum's.  Quantum
+            // is defined in /usr/include/magick/image.h as either an unsigned short or an
+            // unsigned char, depending on what "configure" decided when ImageMagick was installed.
+            // We can determine which by looking at MaxRGB or QuantumDepth.
+            //
+            if (QuantumDepth == 16) {   // Defined in /usr/include/magick/image.h
+                if (debug_level & 512)
+                    fprintf(stderr,"Color quantum is [0..65535]\n");
+                my_colors[l].red   = temp_pack.red * raster_map_intensity;
+                my_colors[l].green = temp_pack.green * raster_map_intensity;
+                my_colors[l].blue  = temp_pack.blue * raster_map_intensity;
+            }
+            else {  // QuantumDepth = 8
+                if (debug_level & 512)
+                    fprintf(stderr,"Color quantum is [0..255]\n");
+                my_colors[l].red   = (temp_pack.red << 8) * raster_map_intensity;
+                my_colors[l].green = (temp_pack.green << 8) * raster_map_intensity;
+                my_colors[l].blue  = (temp_pack.blue << 8) * raster_map_intensity;
+            }
+
+            // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
+            if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+            }
+            else {
+                pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                &my_colors[l].pixel);
+            }
+
+            if (debug_level & 512)
+                fprintf(stderr,"Color allocated is %li  %i  %i  %i \n", my_colors[l].pixel,
+                       my_colors[l].red, my_colors[l].blue, my_colors[l].green);
+        }
+    }
+
+
+
+    /*
+    * Here are the corners of our viewport, using the Xastir
+    * coordinate system.  Notice that Y is upside down:
+    *
+    *   left edge of view = NW_corner_longitude
+    *  right edge of view = SE_corner_longitude
+    *    top edge of view =  NW_corner_latitude
+    * bottom edge of view =  SE_corner_latitude
+    *
+    * The corners of our map will soon be (after translating the
+    * tiepoints to the corners if they're not already there):
+    *
+    *   left edge of map = tp[0].x_long   in Xastir format
+    *  right edge of map = tp[1].x_long
+    *    top edge of map = tp[0].y_lat
+    * bottom edge of map = tp[1].y_lat
+    *
+    */
+    map_c_L = tp[0].x_long - NW_corner_longitude;     // map left coordinate
+    map_c_T = tp[0].y_lat  - NW_corner_latitude;      // map top  coordinate
+
+    tp_c_dx = (long)(tp[1].x_long - tp[0].x_long);//  Width between tiepoints
+    tp_c_dy = (long)(tp[1].y_lat  - tp[0].y_lat); // Height between tiepoints
+
+
+    // Check for tiepoints being in wrong relation to one another
+    if (tp_c_dx < 0) 
+        tp_c_dx = -tp_c_dx;       // New  width between tiepoints
+    if (tp_c_dy < 0) 
+        tp_c_dy = -tp_c_dy;       // New height between tiepoints
+
+    // Calculate step size per pixel
+    map_c_dx = ((double) tp_c_dx / abs(tp[1].img_x - tp[0].img_x));
+    map_c_dy = ((double) tp_c_dy / abs(tp[1].img_y - tp[0].img_y));
+
+    // Scaled screen step size for use with XFillRectangle below
+    scr_dx = (int) (map_c_dx / scale_x) + 1;
+    scr_dy = (int) (map_c_dy / scale_y) + 1;
+
+    // calculate top left map corner from tiepoints
+    if (tp[0].img_x != 0) {
+        tp[0].x_long -= (tp[0].img_x * map_c_dx);   // map left edge longitude
+        map_c_L = tp[0].x_long - NW_corner_longitude;     // delta ??
+        tp[0].img_x = 0;
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_0 x: %d\t%lu\n", tp[0].img_x, tp[0].x_long);
+    }
+    if (tp[0].img_y != 0) {
+        tp[0].y_lat -= (tp[0].img_y * map_c_dy);    // map top edge latitude
+        map_c_T = tp[0].y_lat - NW_corner_latitude;
+        tp[0].img_y = 0;
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_0 y: %d\t%lu\n", tp[0].img_y, tp[0].y_lat);
+    }
+
+    // calculate bottom right map corner from tiepoints
+    // map size is geo_image_width / geo_image_height
+    if (tp[1].img_x != (geo_image_width - 1) ) {
+        tp[1].img_x = geo_image_width - 1;
+        tp[1].x_long = tp[0].x_long + (tp[1].img_x * map_c_dx); // right
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_1 x: %d\t%lu\n", tp[1].img_x, tp[1].x_long);
+    }
+    if (tp[1].img_y != (geo_image_height - 1) ) {
+        tp[1].img_y = geo_image_height - 1;
+        tp[1].y_lat = tp[0].y_lat + (tp[1].img_y * map_c_dy);   // bottom
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_1 y: %d\t%lu\n", tp[1].img_y, tp[1].y_lat);
+    }
+
+    if (debug_level & 512) {
+        fprintf(stderr,"X tiepoint width: %ld\n", tp_c_dx);
+        fprintf(stderr,"Y tiepoint width: %ld\n", tp_c_dy);
+        fprintf(stderr,"Loading imagemap: %s\n", file);
+        fprintf(stderr,"\nImage: %s\n", file);
+        fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height);
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n",
+            map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+        fprintf(stderr,"Image size %d %d\n", width, height);
+#if (MagickLibVersion < 0x0540)
+        fprintf(stderr,"Unique colors = %d\n", GetNumberColors(image, NULL));
+#else // MagickLib < 540
+        fprintf(stderr,"Unique colors = %ld\n", GetNumberColors(image, NULL, &exception));
+#endif // MagickLib < 540
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T,
+            map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+        fprintf(stderr,"image matte is %i\n", image->matte);
+    } // debug_level & 512
+
+    // draw the image from the file out to the map screen
+
+    // Get the border values for the X and Y for loops used
+    // for the XFillRectangle call later.
+
+    map_c_yc = (tp[0].y_lat + tp[1].y_lat) / 2;     // vert center of map as reference
+    map_y_ctr = (long)(height / 2 +0.499);
+    scale_x0 = get_x_scale(0,map_c_yc,scale_y);     // reference scaling at vert map center
+
+    map_c_xc  = (tp[0].x_long + tp[1].x_long) / 2;  // hor center of map as reference
+    map_x_ctr = (long)(width  / 2 +0.499);
+    scr_x_mc  = (map_c_xc - NW_corner_longitude) / scale_x; // screen coordinates of map center
+
+    // calculate map pixel range in y direction that falls into screen area
+    c_y_max = 0ul;
+    map_y_min = map_y_max = 0l;
+    for (map_y_0 = 0, c_y = tp[0].y_lat; map_y_0 < (long)height; map_y_0++, c_y += map_c_dy) {
+        scr_y = (c_y - NW_corner_latitude) / scale_y;   // current screen position
+        if (scr_y > 0) {
+            if (scr_y < screen_height) {
+                map_y_max = map_y_0;          // update last map pixel in y
+                c_y_max = (unsigned long)c_y;// bottom map inside screen coordinate
+            } else
+                break;                      // done, reached bottom screen border
+        } else {                            // pixel is above screen
+            map_y_min = map_y_0;              // update first map pixel in y
+        }
+    }
+    c_y_min = (unsigned long)(tp[0].y_lat + map_y_min * map_c_dy);   // top map inside screen coordinate
+
+        map_x_min = map_x_max = 0l;
+        for (map_x = 0, c_x = tp[0].x_long; map_x < (long)width; map_x++, c_x += map_c_dx) {
+            scr_x = (c_x - NW_corner_longitude)/ scale_x;  // current screen position
+            if (scr_x > 0) {
+                if (scr_x < screen_width)
+                    map_x_max = map_x;          // update last map pixel in x
+                else
+                    break;                      // done, reached right screen border
+            } else {                            // pixel is left from screen
+                map_x_min = map_x;              // update first map pixel in x
+            }
+        }
+        c_x_min = (unsigned long)(tp[0].x_long + map_x_min * map_c_dx);   // left map inside screen coordinate
+
+    scr_yp = -1;
+    scr_c_xr = SE_corner_longitude;
+    c_dx = map_c_dx;                            // map pixel width
+    scale_xa = scale_x0;                        // the compiler likes it ;-)
+
+    map_done = 0;
+    map_act  = 0;
+    map_seen = 0;
+    scr_y = screen_height - 1;
+
+
+    // loop over map pixel rows
+    for (map_y_0 = map_y_min, c_y = (double)c_y_min; (map_y_0 <= map_y_max); map_y_0++, c_y += map_c_dy) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            if (image)
+                DestroyImage(image);
+            if (image_info)
+                DestroyImageInfo(image_info);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        scr_y = (c_y - NW_corner_latitude) / scale_y;
+        if (scr_y != scr_yp) {                  // don't do a row twice
+            scr_yp = scr_y;                     // remember as previous y
+            scr_xp = -1;
+            // loop over map pixel columns
+            map_act = 0;
+            scale_x_nm = calc_dscale_x(0,(long)c_y) / 1852.0;  // nm per Xastir coordinate
+            for (map_x = map_x_min, c_x = (double)c_x_min; map_x <= map_x_max; map_x++, c_x += c_dx) {
+                scr_x = (c_x - NW_corner_longitude) / scale_x;
+                if (scr_x != scr_xp) {      // don't do a pixel twice
+                    scr_xp = scr_x;         // remember as previous x
+                    map_y = map_y_0;
+
+                    if (map_y >= 0 && map_y <= tp[1].img_y) { // check map boundaries in y direction
+                        map_seen = 1;
+                        map_act = 1;    // detects blank screen rows (end of map)
+
+                        // now copy a pixel from the map image to the screen
+                        l = map_x + map_y * image->columns;
+                        trans_skip = 1; // possibily transparent
+                        if (image->storage_class == PseudoClass) {
+                            if ( c_trans_color_head &&
+                                    check_trans(my_colors[index_pack[l]],c_trans_color_head)) {
+                                trans_skip = 1; // skip it
+                            }
+                            else {
+                                XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel);
+                                trans_skip = 0; // draw it
+                            }
+                        }
+                        else {
+                            // It is not safe to assume that the red/green/blue
+                            // elements of pixel_pack of type Quantum are the
+                            // same as the red/green/blue of an XColor!
+                            if (QuantumDepth==16) {
+                                my_colors[0].red=pixel_pack[l].red;
+                                my_colors[0].green=pixel_pack[l].green;
+                                my_colors[0].blue=pixel_pack[l].blue;
+                            }
+                            else { // QuantumDepth=8
+                                // shift the bits of the 8-bit quantity so that
+                                // they become the high bigs of my_colors.*
+                                my_colors[0].red=pixel_pack[l].red<<8;
+                                my_colors[0].green=pixel_pack[l].green<<8;
+                                my_colors[0].blue=pixel_pack[l].blue<<8;
+                            }
+                            // NOW my_colors has the right r,g,b range for
+                            // pack_pixel_bits
+                            pack_pixel_bits(my_colors[0].red * raster_map_intensity,
+                                            my_colors[0].green * raster_map_intensity,
+                                            my_colors[0].blue * raster_map_intensity,
+                                            &my_colors[0].pixel);
+                            if ( c_trans_color_head &&
+                                    check_trans(my_colors[0],c_trans_color_head)) {
+                                trans_skip = 1; // skip it
+                            }
+                            else {
+                                XSetForeground(XtDisplay(w), gc, my_colors[0].pixel);
+                                trans_skip = 0; // draw it
+                            }
+                        }
+
+                        // Skip drawing if a transparent pixel
+                        if (!trans_skip) {
+                            (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,scr_dx,scr_dy);
+                        }
+
+                    } // check map boundaries in y direction
+                }
+            } // loop over map pixel columns
+            if (map_seen && !map_act)
+                map_done = 1;
+        }
+    } // loop over map pixel rows
+
+    if (image)
+       DestroyImage(image);
+    if (image_info)
+       DestroyImageInfo(image_info);
+    DestroyExceptionInfo(&exception);
+}
+#endif //HAVE_MAGICK
diff --git a/src/map_cache.c b/src/map_cache.c
new file mode 100644
index 0000000..2a074ea
--- /dev/null
+++ b/src/map_cache.c
@@ -0,0 +1,1059 @@
+/*
+ * $Id: map_cache.c,v 1.35 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+/*
+ *   The code in this file is used to cache maps downloaded
+ *   from tiger.census.gov, and to manage that cache. It was written
+ *   to use Berkeley DB version 4 or better. 
+ *
+ *   Dan Brown N8YSZ. 
+ *
+ */
+
+
+// Need this one before the #ifdef in order to get the definition of
+// USE_MAP_CACHE, if defined.
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+
+#ifdef  USE_MAP_CACHE
+//#warning USE_MAP_CACHE Defined
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> 
+#include <time.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "snprintf.h" 
+#include "xastir.h"
+#include "xa_config.h" 
+#include "main.h"
+#include "maps.h" 
+#include "map_cache.h" 
+#include <db.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+// This is used to temporarily disable fetching from the map cache.
+// Used for refreshing corrupted maps in the cache.
+int map_cache_fetch_disable = 0;
+
+
+// Used to disable map caching entirely if the header and dblib
+// versions don't match, in order to avoid segfaults when the map
+// caching is used.
+int map_cache_disabled = 0;
+
+
+
+
+
+// Here we do a run-time check to verify that the header file we
+// used to compile with is the same version as the shared library
+// we're currently linked with.  To do otherwise often results in
+// segfaults.
+//
+void map_cache_init(void) {
+    int warn_now = 0;
+
+    if (strcmp( DB_VERSION_STRING, db_version(NULL,NULL,NULL) ) != 0) {
+        fprintf(stderr,
+            "\n\n***** WARNING *****\n");
+        fprintf(stderr,
+            "Berkeley DB header files/shared library file do NOT match!\n");
+        fprintf(stderr,
+            "Disabling use of the map cache.\n");
+
+
+// Can't bring up a popup here 'cuz we don't have any GUI running
+// yet by this point.
+// popup_message_always(langcode("POPEM00034"),langcode("POPEM00046"));
+
+
+        warn_now++;
+        map_cache_disabled++;
+    }
+
+    if (debug_level & 5 || warn_now) {
+
+        //fprintf(stderr,
+        //    "Berkeley DB Library Header File Version %d.%d.%d\n",
+        //    DB_VERSION_MAJOR,
+        //    DB_VERSION_MINOR,
+        //    DB_VERSION_PATCH);
+
+        fprintf(stderr,
+            " Header file: %s\n",
+            DB_VERSION_STRING);
+
+        fprintf(stderr,
+            "Library file: %s\n",
+            db_version(NULL,NULL,NULL) );
+    }
+
+    if (warn_now) {
+        fprintf(stderr,
+            "***** WARNING *****\n");
+    }
+}
+
+
+
+
+
+// map_cache_put()
+//
+// Inputs:
+//
+// Outputs:
+//
+int map_cache_put( char * map_cache_url, char * map_cache_file ){
+
+// Puts an entry into the url->filename database
+// Tracks space used in "CACHE_SPACE_USED" 
+
+    char mc_database_filename[MAX_FILENAME]; 
+    int mc_ret, mc_t_ret, mc_file_stat, mc_space_used ;
+    DBT mc_key, mc_data ; 
+    DB *dbp; 
+    struct stat file_status;
+    char mc_buf[128];
+    char temp_file_path[MAX_VALUE];
+
+    if (map_cache_disabled) {
+        return(1);
+    }
+
+    mc_space_used=0; 
+
+    xastir_snprintf(mc_database_filename,
+    sizeof(mc_database_filename),
+    "%s/map_cache.db", 
+    get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)));
+
+    // check for reasonable filename
+    // expects file name like /home/brown/.xastir/map_cache/map_1100052372.gif
+    //                                   1234567890123456789012345678901234567
+
+    mc_ret=strlen(map_cache_file);
+    
+    if ( mc_ret < 37 ) { 
+        if (debug_level & 512 ) {
+            fprintf(stderr,
+            	"map_cache_put: Unusable filename: %s. Skipping encaching\n",
+            	(map_cache_file == NULL) ? "(null)" : map_cache_file);
+        }
+        return (-1 * mc_ret); 
+    } 
+            
+// stat the file to see if we even need to bother 
+
+    if ((mc_file_stat=stat(map_cache_file, &file_status)) !=0) {
+        if (debug_level & 512 ) {
+            fprintf(stderr,
+            	"map_cache_put: File Error: %s. Skipping encaching\n",
+            	(map_cache_file == NULL) ? "(null)" : map_cache_file);
+        } 
+       
+        return (mc_file_stat); 
+    }
+
+    if ( debug_level & 512) {
+        fprintf (stderr, "map_cache_put: file_status.st_size %d\n",
+                        (int) file_status.st_size);        
+    }
+
+// Create handle to db
+
+    if ((mc_ret = db_create(&dbp, NULL, 0)) != 0) {
+        fprintf(stderr, "map_cache_put db_create:%s\n", db_strerror(mc_ret)); 
+        return(1);
+    }
+
+// open the db 
+
+#if  (DB_VERSION_MAJOR<4)   /** DB_VERSION Check **/
+#error DB_VERSION_MAJOR < 4 
+
+#elif (DB_VERSION_MAJOR==4 && DB_VERSION_MINOR<=0 )
+
+    if ((mc_ret = dbp->open(dbp,
+            mc_database_filename , NULL, DB_CREATE, DB_BTREE, 0664)) != 0) {
+
+        dbp->err(dbp, mc_ret, "%s", mc_database_filename);
+        db_strerror(mc_ret); 
+    }
+#elif	 (DB_VERSION_MAJOR==4 && DB_VERSION_MINOR>=1 )
+
+    if ((mc_ret = dbp->open(dbp,
+            NULL,mc_database_filename, NULL, DB_CREATE, DB_BTREE, 0664)) != 0) {
+
+        dbp->err(dbp, mc_ret, "%s", mc_database_filename);
+        db_strerror(mc_ret); 
+    }
+
+#endif  /** DB_VERSION Check **/
+
+// Before we put something in we need to see if we got space
+
+// if mc_cache_size_limit
+
+// Setup for get 
+
+    memset(&mc_key, 0, sizeof(mc_key));
+    memset(&mc_data, 0, sizeof(mc_data));
+
+    mc_key.data = "CACHE_SPACE_USED";
+    mc_key.size = sizeof("CACHE_SPACE_USED"); 
+
+// check "CACHE_SPACE_USED" record in db
+
+// mc_ret is assigned here but not used.  Commented it out for now.
+    if (((/* mc_ret = */ dbp->get(dbp, NULL, &mc_key, &mc_data, 0)) == 0) &&  ( mc_data.data != NULL ) ) {
+
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_put: %s: key retrieved: data was %s.\n",
+                (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data,
+                (mc_data.data == NULL) ? "(null)" : (char *)mc_data.data);
+        }
+
+        if (mc_data.data == NULL)
+            mc_space_used = 0;
+        else
+            mc_space_used = atoi( (char *)mc_data.data);
+
+        if ( debug_level & 512 ) {
+            fprintf (stderr, "map_cache_put: CACHE_SPACE_USED = %.2f mb\n",
+                (mc_space_used/1024/1024.0));
+        }
+
+    }
+    else {
+
+        if (mc_data.data == NULL) {
+            if ( debug_level & 512 ) {
+                fprintf (stderr, "map_cache_put: CACHE_SPACE_USED get returned null \n"); 
+            }
+        }
+        else { 
+            if ( debug_level & 512 ) {
+                fprintf (stderr, "map_cache_put: Unable to check CACHE_SPACE_USED: %s\n",
+                            db_strerror(mc_ret)); 
+            }
+	}
+
+        // for now let us assume this is the first map entry and  we
+        // just flag an error. Better procedure for later might be to
+        // return(mc_ret) indicating a database error of some sort
+         
+    }
+      
+//      xastir_snprintf(map_cache_file, MAX_FILENAME, "%s",(char *)mc_data.data);
+
+    if ( debug_level & 512 ) {
+            fprintf (stderr, "map_cache_put: mc_space_used before = %d bytes file_status.st_size %d\n",
+                        mc_space_used,
+                        (int) file_status.st_size);
+    }
+
+    mc_space_used += (int) file_status.st_size;
+
+    if ( debug_level & 512 ) {
+            fprintf (stderr, "map_cache_put: mc_space_used after = %d bytes \n",
+                        mc_space_used);
+    }
+
+    if ( mc_space_used > MAP_CACHE_SPACE_LIMIT) { 
+        if ( debug_level & 512 ) {
+            fprintf (stderr, "map_cache_put: Warning cache space used: %.2f mb NOW OVER LIMIT: %.2f mb\n",
+                            (mc_space_used/1024/1024.0),
+                            (MAP_CACHE_SPACE_LIMIT/1024/1024.0));
+        }
+
+// Cache Cleanup
+// The warning is nice, but we should do something here
+// Needs LRU and or FIFO db structures
+
+    }
+    else {
+
+// else put cache_space_used
+
+// setup 
+
+        memset(&mc_key, 0, sizeof(mc_key));
+        memset(&mc_data, 0, sizeof(mc_data));
+
+// data
+
+        mc_key.data = "CACHE_SPACE_USED";
+        mc_key.size = sizeof("CACHE_SPACE_USED"); 
+
+        xastir_snprintf(mc_buf, sizeof(mc_buf), "%d", mc_space_used);
+
+        if ( debug_level & 512 ) { 
+                fprintf (stderr, "map_cache_put: mc_buf: %s len %d\n",
+                        mc_buf,(int) sizeof(mc_buf));
+        }
+
+        mc_data.data = mc_buf ; 
+        mc_data.size = sizeof(mc_buf);
+
+// put 
+
+        if ((mc_ret = dbp->put(dbp, NULL, &mc_key, &mc_data, 0)) == 0) {
+
+            if ( debug_level & 512 ) {
+                fprintf(stderr, "map_cache_put: %s: key stored.\n",
+                    (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data);
+            }
+
+        }
+        else {
+
+            if ( debug_level & 512 ) {
+                 dbp->err(dbp, mc_ret, "DB->put");
+            }
+//            db_strerror(mc_ret); 
+
+            return(mc_ret);
+
+        } 
+
+    } 
+
+// Setup for put of data
+
+    memset(&mc_key, 0, sizeof(mc_key));
+    memset(&mc_data, 0, sizeof(mc_data));
+
+// Real data at last 
+
+    mc_key.data = map_cache_url;
+    mc_key.size = strlen(map_cache_url); 
+    mc_data.data = map_cache_file;
+    mc_data.size = strlen(map_cache_file)+1; /* +1 includes  \0 */ 
+
+// do the actual put 
+
+    if ((mc_ret = dbp->put(dbp, NULL, &mc_key, &mc_data, 0)) == 0) {
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_put: %s: key stored.\n",
+                (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data);
+        }
+    }
+    else {
+        if ( debug_level & 512 ) {
+            dbp->err(dbp, mc_ret, "DB->put") ;
+        }
+        // db_strerror(mc_ret); 
+        return(mc_ret); 
+    } 
+
+    // Map now cached
+    statusline(langcode("CACHE001"), 1);
+
+// close the db 
+
+    // Only try the close if we have a valid handle
+    if (dbp != NULL) {
+        if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0) {
+            mc_ret = mc_t_ret;
+            db_strerror(mc_ret); 
+        }
+    }
+
+/* end map_cache_put */
+
+    return (0) ; 
+}
+
+
+
+
+
+// map_cache_get()
+//
+// Queries URL->Filename db 
+// Calls map_cache_del to cleanup expired maps 
+//
+// Inputs:
+//
+// Outputs: 0 if cached file is retrieved successfully
+//          1 if db can't be created
+//          negative number if unusable filename or bad filestat
+//          positive number if map has expired
+//          return value from dbp->get if record not found
+//
+int map_cache_get( char * map_cache_url, char * map_cache_file ){
+    DBT mc_key, mc_data ; 
+    DB *dbp;
+    int mc_ret, mc_t_ret, mc_file_stat ;
+    char mc_database_filename[MAX_FILENAME]; 
+    struct stat file_status;
+    char temp_file_path[MAX_VALUE];
+
+    if (map_cache_disabled) {
+        return(1);
+    }
+
+set_dangerous("map_cache_get: xastir_snprintf 1");
+    xastir_snprintf(mc_database_filename,
+        sizeof(mc_database_filename),   // change to max_filename?
+        "%s/map_cache.db",
+        get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)));
+clear_dangerous();
+ 
+set_dangerous("map_cache_get: db_create");
+    if ((mc_ret = db_create(&dbp, NULL, 0)) != 0) {
+        fprintf(stderr, "map_cache_get db_create:%s\n", db_strerror(mc_ret)); 
+        return(1);
+    }
+clear_dangerous();
+
+#if  (DB_VERSION_MAJOR<4)   /** DB_VERSION Check **/
+#error DB_VERSION_MAJOR < 4 
+
+#elif (DB_VERSION_MAJOR==4 && DB_VERSION_MINOR<=0 )
+
+set_dangerous("map_cache_get:dbp->open 1");
+    if ((mc_ret = dbp->open(dbp,
+        mc_database_filename, NULL, DB_CREATE, DB_BTREE, 0664)) != 0) {
+            ( debug_level & 512 ) ?  dbp->err(dbp, mc_ret, "%s", mc_database_filename):0;
+            // db_strerror(mc_ret);
+    }
+clear_dangerous();
+
+#elif	 (DB_VERSION_MAJOR==4 && DB_VERSION_MINOR>=1 )
+
+set_dangerous("map_cache_get:dbp->open 2");
+    if ((mc_ret = dbp->open(dbp,
+            NULL,mc_database_filename, NULL, DB_CREATE, DB_BTREE, 0664)) != 0) {
+        if (debug_level & 512) {
+            dbp->err(dbp, mc_ret, "%s", mc_database_filename);
+            // db_strerror(mc_ret);
+        }
+    }
+clear_dangerous();
+
+#endif  /** DB_VERSION Check **/
+
+    memset(&mc_key, 0, sizeof(mc_key));
+    memset(&mc_data, 0, sizeof(mc_data));
+
+    mc_key.data=map_cache_url ; 
+    mc_key.size=strlen(map_cache_url); 
+
+    statusline("Checking Map Cache",1);
+    if (debug_level & 512 ) {
+        fprintf(stderr, "map_cache_get: Checking Map Cache\n");
+    }
+
+
+set_dangerous("map_cache_get:dbp->get");
+    if ((mc_ret = dbp->get(dbp, NULL, &mc_key, &mc_data, 0)) == 0) {
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_get: %s: key retrieved: data was %s.\n",
+                (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data,
+                (mc_data.data == NULL) ? "(null)" : (char *)mc_data.data);
+        }
+set_dangerous("map_cache_get: xastir_snprintf 2");
+        xastir_snprintf(map_cache_file, MAX_FILENAME, "%s",(char *)mc_data.data);
+clear_dangerous();
+
+    // check for reasonable filename
+    // expects file name like /home/brown/.xastir/map_cache/map_1100052372.gif
+    //                                   1234567890123456789012345678901234567
+
+    	mc_ret=strlen(map_cache_file);
+	
+        if ( mc_ret < 37 ) { 
+ 
+            if (debug_level & 512 ) {
+                fprintf(stderr,
+                    "map_cache_get: Unusable filename: %s. Deleting key %s from cache\n",
+                    (map_cache_file == NULL) ? "(null)" : map_cache_file,
+                    (map_cache_url == NULL) ? "(null)" : map_cache_url);
+            }
+set_dangerous("map_cache_get: map_cache_del 1");
+            map_cache_del(map_cache_url);
+            if (dbp != NULL) {
+                if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0){
+                    mc_ret = mc_t_ret;
+                   // db_strerror(mc_ret);
+                }
+            }
+clear_dangerous();
+  
+            return (-1 * mc_ret); 
+        } 
+            
+
+    // check age of file - based on name - delete if too old
+     
+        if (debug_level & 512 ) {
+            fprintf(stderr, "map_cache_get: Checking age\n");
+        }
+
+set_dangerous("map_cache_get: map_cache_expired");   
+        if ( (mc_ret=map_cache_expired(map_cache_file, (MC_MAX_FILE_AGE)))){
+            if ( debug_level & 512 ) {
+                fprintf(stderr, "map_cache_get: deleting expired key: %s.\n",
+                    (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data); 
+            }
+set_dangerous("map_cache_get: map_cache_del 2");
+            map_cache_del(map_cache_url);
+            if (dbp != NULL) {
+                if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0){
+                    mc_ret = mc_t_ret;
+                   // db_strerror(mc_ret);
+                }
+            }
+clear_dangerous();
+            return (mc_ret);
+        } 
+clear_dangerous();
+
+    // check if the file exists 
+        if ( debug_level & 512 ) {
+            fprintf(stderr,"map_cache_get: checking for existence of map_cache_file:  %s.\n",
+                (map_cache_file == NULL) ? "(null)" : map_cache_file);
+        }
+
+        mc_file_stat=stat(map_cache_file, &file_status);
+
+        if ( debug_level & 512 ) {
+            fprintf(stderr,"map_cache_get: map_cache_file %s stat returned:%d.\n",
+                (map_cache_file == NULL) ? "(null)" : map_cache_file,
+                mc_file_stat);
+        }
+
+        if ( mc_file_stat == -1 ) {
+	// 		
+            if ( debug_level & 512 ) {
+                fprintf(stderr,"map_cache_get: attempting to delete map_cache_file %s \n",
+                    (map_cache_file == NULL) ? "(null)" : map_cache_file);
+            }
+
+set_dangerous("map_cache_get: dbp->del");
+            if ((mc_ret = dbp->del(dbp, NULL, &mc_key, 0)) == 0) {
+                if ( debug_level & 512 ) {
+                    fprintf(stderr, "map_cache_get: File stat failed %s: key was deleted.\n",
+                        (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data);
+                }
+            }
+            else {
+                if ( debug_level & 512 ) {
+                    dbp->err(dbp, mc_ret, "DB->del");
+                }
+                // db_strerror(mc_ret);
+            }
+clear_dangerous();
+
+set_dangerous("map_cache_get: dbp->close 1");
+            // Only try the close if we have a valid handle
+            if (dbp != NULL) {
+                if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0){
+                    mc_ret = mc_t_ret;
+                   // db_strerror(mc_ret);
+                }
+            }
+clear_dangerous();
+  
+            // db_strerror(mc_ret);
+            // Return the file stat if there was a file problem
+            return (mc_file_stat);
+        }
+        else {
+
+set_dangerous("map_cache_get: dbp->close 2");
+            // Only try the close if we have a valid handle
+            if (dbp != NULL) {
+                if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0){
+                    mc_ret = mc_t_ret;
+                    // db_strerror(mc_ret);
+                }
+            }
+clear_dangerous();
+            // If we made it here all is good
+
+            // Loading Cached Map
+            statusline(langcode("CACHE002"), 1);
+            return (0); 
+        }
+		
+    }
+    else {
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_get: Get failed. Key was: %s.\n",
+                (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data);
+        }
+
+        if (debug_level & 512) {
+            dbp->err(dbp, mc_ret, "DB->get");
+            // db_strerror(mc_ret);
+        }
+
+        // there was some problem getting things from the db
+        // return the return from the get 
+
+        // Map not found in cache...
+        statusline(langcode("CACHE003"), 1);
+	set_dangerous("map_cache_get: dbp->close 3");
+	// Only try the close if we have a valid handle
+	if (dbp != NULL) {
+	    if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0){
+		mc_ret = mc_t_ret;
+		// db_strerror(mc_ret);
+	    }
+	}
+	clear_dangerous();
+        return (mc_ret); 
+    }
+
+clear_dangerous();
+
+/** end map_cache_get **/  
+}
+
+
+
+
+
+// map_cache_del()
+//
+// Delete entry from the cache and unlink associated file from disk
+//
+// Inputs:  Map URL
+//
+// Outputs: 0 if successful deleting the item from the cache
+//          1 if error in creating/opening DB file
+//          mc_ret if unlink failed or if error in DB->del
+//
+int map_cache_del( char * map_cache_url ){
+    DBT mc_key, mc_data, mc_size_key, mc_size_data ; 
+    DB *dbp;
+    int mc_ret, mc_t_ret, mc_file_stat, mc_space_used;
+    char mc_database_filename[MAX_FILENAME]; 
+    char mc_delete_file[MAX_FILENAME]; 
+    struct stat file_status;
+    char mc_buf[128];
+    char temp_file_path[MAX_VALUE];
+
+    if (map_cache_disabled) {
+        return(1);
+    }
+
+    mc_space_used = 0 ; 
+
+    xastir_snprintf(mc_database_filename,
+        MAX_FILENAME,
+        "%s/map_cache.db",
+        get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)));
+
+    if ((mc_ret = db_create(&dbp, NULL, 0)) != 0) {
+        fprintf(stderr, "map_cache_del db_create:%s\n", db_strerror(mc_ret)); 
+        return(1);
+    }
+
+#if  (DB_VERSION_MAJOR<4)   /** DB_VERSION Check **/
+#error DB_VERSION_MAJOR < 4 
+
+#elif (DB_VERSION_MAJOR==4 && DB_VERSION_MINOR<=0 )
+
+    if ((mc_ret = dbp->open(dbp, mc_database_filename, NULL, DB_CREATE, DB_BTREE, 0664)) != 0) {
+        ( debug_level & 512 ) ?  dbp->err(dbp, mc_ret, "%s", mc_database_filename):0;
+        // db_strerror(mc_ret);
+        return(1);
+    }
+#elif	 (DB_VERSION_MAJOR==4 && DB_VERSION_MINOR>=1 )
+	
+    if ((mc_ret = dbp->open(dbp,
+            NULL,mc_database_filename, NULL, DB_CREATE, DB_BTREE, 0664)) != 0) {
+        if (debug_level & 512) {
+            dbp->err(dbp, mc_ret, "%s", mc_database_filename);
+            // db_strerror(mc_ret);
+        }
+        return(1);
+    }
+
+#endif  /** DB_VERSION Check **/
+
+    memset(&mc_key, 0, sizeof(mc_key));
+    memset(&mc_data, 0, sizeof(mc_data));
+	
+    mc_key.data=map_cache_url ; 
+    mc_key.size=strlen(map_cache_url); 
+
+    // Try to get the key from the cache
+    if ((mc_ret = dbp->get(dbp, NULL, &mc_key, &mc_data, 0)) != 0) {
+        // Couldn't get the key from the cache
+
+        if ( debug_level & 512 ) {
+            dbp->err(dbp, mc_ret, "DB->del");
+        }
+        // db_strerror(mc_ret);
+
+        // Only try the close if we have a valid handle
+        if (dbp != NULL) {
+set_dangerous("map_cache_del: dbp->close 1");
+            dbp->close(dbp, 0);
+clear_dangerous();
+        }
+        return (mc_ret); 
+    }
+
+    if ( debug_level & 512 ) {
+        fprintf(stderr, "map_cache_del: %s: key retrieved: data was %s.\n",
+            (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data,
+            (mc_data.data == NULL) ? "(null)" : (char *)mc_data.data);
+    }
+
+    // stat the file 
+
+    xastir_snprintf(mc_delete_file,
+        MAX_FILENAME,
+        "%s",
+        (char *) mc_data.data);
+
+set_dangerous("map_cache_del: stat");
+    mc_file_stat = stat(mc_delete_file, &file_status);
+clear_dangerous();
+
+    if ( debug_level & 512 ) {
+        fprintf(stderr,"map_cache_del: file %s stat returned:%d.\n",
+            (mc_data.data == NULL) ? "(null)" : (char *) mc_data.data,
+            mc_file_stat);
+    }
+
+    if (mc_file_stat != 0 ) {
+
+// file stat was not good - do something here
+// RETURN() HERE?
+
+    }
+
+
+// Setup for get CACHE_SPACE_USED
+
+    memset(&mc_size_key, 0, sizeof(mc_size_key));
+    memset(&mc_size_data, 0, sizeof(mc_size_data));
+
+    mc_size_key.data = "CACHE_SPACE_USED";
+    mc_size_key.size = sizeof("CACHE_SPACE_USED"); 
+
+// check "CACHE_SPACE_USED" record in db
+	
+    if (((mc_ret = dbp->get(dbp, NULL, &mc_size_key, &mc_size_data, 0)) == 0)
+            && ( mc_size_data.data != NULL )
+            && ( strlen(mc_size_data.data) != 0 ) ) {
+
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_del: %s: key retrieved: data was %s.\n",
+                (mc_size_key.data == NULL) ? "(null)" : (char *)mc_size_key.data,
+                (mc_size_data.data == NULL) ? "(null)" : (char *)mc_size_data.data);
+        }
+
+set_dangerous("map_cache_del: atoi");
+        if (mc_size_data.data == NULL)
+            mc_space_used = 0;
+        else
+            mc_space_used = atoi( (char *)mc_size_data.data);
+clear_dangerous();
+
+        if ( debug_level & 512 ) {
+            fprintf (stderr, "map_cache_del: CACHE_SPACE_USED = %.2f mb\n",
+                (mc_space_used/1024/1024.0));
+        }
+    }
+    else {
+        // Failed the "dpb->get" operation
+
+        if (mc_size_data.data == NULL) {
+
+            if ( debug_level & 512 ) {
+                fprintf (stderr, "map_cache_del: CACHE_SPACE_USED get returned null \n"); 
+            }
+        }
+        else {
+
+            if ( debug_level & 512 ) {
+                fprintf (stderr, "map_cache_del: Unable to check CACHE_SPACE_USED: %s\n",
+                    db_strerror(mc_ret)); 
+            }
+        }
+
+// RETURN() HERE?
+
+    }
+
+
+    if ( debug_level & 512 ) {
+        fprintf (stderr, "map_cache_del: mc_space_used before = %d bytes file_status.st_size %d\n",
+            mc_space_used,
+            (int) file_status.st_size);
+    }
+
+    mc_ret = unlink( mc_delete_file );
+
+    if ( debug_level & 512 ) {
+        fprintf(stderr,"map_cache_del: file %s unlink returned:%d.\n",
+            (mc_delete_file == NULL) ? "(null)" : mc_delete_file,
+            mc_ret);
+    }
+
+    if (mc_ret != 0 ) {
+
+        if ( debug_level & 512 ) { 
+            fprintf (stderr, "map_cache_del: unlink failed mc_space_used = %d bytes \n",
+                mc_space_used);
+        }        
+        return(mc_ret);
+    }
+
+	
+// Update cache_space_used
+
+// setup 
+
+    mc_space_used -= (int) file_status.st_size;
+
+    if (mc_space_used < 0) {
+        mc_space_used = 0;
+    }
+
+    if ( debug_level & 512 ) {
+        fprintf (stderr, "map_cache_del: unlink succeeded mc_space_used = %d bytes \n",
+            mc_space_used);        
+    }
+
+    memset(&mc_size_key, 0, sizeof(mc_size_key));
+    memset(&mc_size_data, 0, sizeof(mc_size_data));
+
+// data
+
+    mc_size_key.data = "CACHE_SPACE_USED";
+    mc_size_key.size = sizeof("CACHE_SPACE_USED"); 
+
+    xastir_snprintf(mc_buf, sizeof(mc_buf), "%d", mc_space_used);
+
+    if ( debug_level & 512 ) {
+        fprintf (stderr, "map_cache_del: mc_buf: %s len %d\n",
+            mc_buf, (int)sizeof(mc_buf));
+    }
+
+    mc_size_data.data = mc_buf ; 
+    mc_size_data.size = sizeof(mc_buf);
+
+// put 
+                
+    if ((mc_ret = dbp->put(dbp, NULL, &mc_size_key, &mc_size_data, 0)) != 0) {
+        // Failed the "dbp->put" operation
+
+        if ( debug_level & 512 ) {
+            dbp->err(dbp, mc_ret, "DB->put");
+        }
+
+        // db_strerror(mc_ret); 
+
+// RETURN() HERE?
+
+    } 
+
+    if ( debug_level & 512 ) {
+        fprintf(stderr,"map_cache_del: %s: key stored.\n",
+            (mc_size_key.data == NULL) ? "(null)" : (char *)mc_size_key.data);
+    }
+
+	
+    // remove entry from cache url->filename database 
+	
+    if ((mc_ret = dbp->del(dbp, NULL, &mc_key, 0)) != 0){
+        // Failed the "dbp->del" operation
+
+        if ( debug_level & 512 ) {
+            dbp->err(dbp, mc_ret, "DB->del");
+        }
+        // db_strerror(mc_ret);
+
+// RETURN() HERE?
+
+    }							
+
+    if ( debug_level & 512 ) {
+        fprintf(stderr, "map_cache_del: %s: key was deleted.\n",
+            (mc_key.data == NULL) ? "(null)" : (char *)mc_key.data);
+    }
+
+    // close  the db. 
+
+    // Only try the close if we have a valid handle
+    if (dbp != NULL) {
+
+set_dangerous("map_cache_del: dbp->close 2");
+        if ((mc_t_ret = dbp->close(dbp, 0)) != 0 && mc_ret == 0){
+clear_dangerous();
+
+            mc_ret = mc_t_ret;
+            // db_strerror(mc_ret);
+
+// RETURN() HERE?
+
+        }
+    }
+
+    return (0); // All is well
+
+/** end map_cache_del **/
+}
+
+
+
+
+
+char * map_cache_fileid(void) {
+
+    // returns a unique identifier 
+    // used for generating filenames for cached files
+
+    time_t t; 
+    char * mc_time_buf;
+
+
+    mc_time_buf = malloc (16); 
+    sprintf( mc_time_buf, "%d",(int) time(&t)); 
+    return (mc_time_buf);
+}
+
+
+
+
+
+// check for files old enough to expire 
+// this is lame but it should work for now. 
+// expects file name like /home/brown/.xastir/map_cache/map_1100052372.gif
+//
+// writing this proved a good example of why pointer arithmetic is tricky
+// and a good example of why I should avoid it - n8ysz 20041110
+// 
+int map_cache_expired( char * mc_filename, time_t mc_max_age ){
+    time_t mc_t,mc_file_age; 
+    char *mc_filename_tmp, *mc_time_buf_tmp, *mc_time_buf;
+
+
+    if (map_cache_disabled) {
+        return(0);
+    }
+
+    mc_time_buf=malloc(MAX_FILENAME);
+    mc_time_buf_tmp=mc_time_buf; 
+
+    // grab filename
+    mc_filename_tmp=strrchr(mc_filename,'/'); 
+
+    // clean up map_
+    mc_filename_tmp=strchr(mc_filename_tmp,'_'); 
+    ++mc_filename_tmp; 
+    
+    // save up to .gif 
+    while ((*mc_time_buf_tmp++ = *mc_filename_tmp++) != '.' )
+        ;
+ 
+   *(--mc_time_buf_tmp) ='\0';
+
+//    if ( debug_level & 512 ) {
+//          fprintf(stderr, "map_cache_expired: mc_filename is: %s mc_time_buf is: %s.\n", mc_filename, mc_time_buf);
+//      }
+
+    mc_file_age=(time(&mc_t) - ((time_t) atoi(mc_time_buf)) ); 
+    
+    if ( mc_file_age <  mc_max_age ) {
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_expired: mc_filename %s is NOT expired. mc_time_buf is: %s.\n",
+                (mc_filename == NULL) ? "(null)" : mc_filename,
+                (mc_time_buf == NULL) ? "(null)" : mc_time_buf);
+        }
+        free(mc_time_buf); 
+        return (0); 
+    }
+    else {
+        if ( debug_level & 512 ) {
+            fprintf(stderr, "map_cache_expired: mc_filename %s IS expired. mc_time_buf is: %s.\n",
+                (mc_filename == NULL) ? "(null)" : mc_filename,
+                (mc_time_buf == NULL) ? "(null)" : mc_time_buf);
+        }
+        free(mc_time_buf); 
+        return ((int)mc_file_age); 
+    }
+
+
+   // sprintf( mc_time_buf, "%d",(int)
+
+    return (0);
+}
+
+
+
+
+
+// Functions that need writing 
+
+int mc_check_space_used (void) {
+
+    if (map_cache_disabled) {
+        return(0);
+    }
+    
+    return(0); 
+}
+
+
+
+
+
+int mc_update_space_used (void) {
+
+    if (map_cache_disabled) {
+        return(0);
+    }
+    
+    return(0); 
+}
+
+
+#endif // USE_MAP_CACHE
+
+
diff --git a/src/map_cache.h b/src/map_cache.h
new file mode 100644
index 0000000..1b052ca
--- /dev/null
+++ b/src/map_cache.h
@@ -0,0 +1,79 @@
+/*
+ * $Id: map_cache.h,v 1.14 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef XASTIR_MAP_CACHE_H
+#define XASTIR_MAP_CACHE_H
+
+// Global variable declarations
+extern int map_cache_fetch_disable;
+
+
+// External function declarations
+
+extern void map_cache_init(void);
+
+// Saves file and puts entries into cache db
+extern int map_cache_put( char * map_cache_url, char * map_cache_file );
+
+// Retrieves entry from cache db - checks existance of file
+extern int map_cache_get( char * map_cache_url, char * map_cache_file );
+
+// Deletes cached map file and the entry from cache
+extern int map_cache_del( char * map_cache_url );
+
+// Checks to see if map is expired based on date embedded in filename 
+extern int map_cache_expired( char * mc_filename, time_t mc_max_age );
+
+// Generates filename based on current time
+extern char * map_cache_fileid(void);
+
+
+// Static variable definitions
+// These should probably be runtime options 
+
+// Cache expiration times
+// about 6mo
+#define MC_MAX_FILE_AGE 6*30*24*60*60
+
+// 1 hr
+//#define MC_MAX_FILE_AGE 60*60
+
+// 5 seconds -- don't do this except for testing 
+//#define MC_MAX_FILE_AGE 5
+
+// Cache Space Limit in bytes
+
+// 1 megabytes == about ten 1024x768 map gifs n8ysz
+// MAP_CACHE_SPACE_LIMIT=1024*1024
+
+// 16 megabytes
+// MAP_CACHE_SPACE_LIMIT=16*1024*1024
+
+// 128 megabytes
+#define MAP_CACHE_SPACE_LIMIT 128*1024*1024
+
+
+#endif /* XASTIR_MAP_CACHE_H */
diff --git a/src/map_dos.c b/src/map_dos.c
new file mode 100644
index 0000000..f1668e5
--- /dev/null
+++ b/src/map_dos.c
@@ -0,0 +1,1364 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_dos.c,v 1.30 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+#define DOS_HDR_LINES 8
+#define GRID_MORE 5000
+
+extern int npoints;		/* tsk tsk tsk -- globals */
+extern int mag;
+
+/* MAP pointers */
+
+static map_vectors *map_vectors_ptr;
+static text_label *map_text_label_ptr;
+static symbol_label *map_symbol_label_ptr;
+
+/* MAP counters */
+
+//static long vectors_num;
+//static long text_label_num;
+//static long object_label_num;
+
+
+
+
+/**********************************************************
+ * map_plot()
+ *
+ * Plots vectors on the map.  If "color" is non-zero,
+ * then it draws filled polygons in the color of
+ * "object_behavior"?  Weird.
+ **********************************************************/
+void map_plot (Widget w, long max_x, long max_y, long x_long_cord,
+        long y_lat_cord, unsigned char color, long object_behavior,
+        int destination_pixmap, int draw_filled) {
+
+    static int redraw_check;
+    static XPoint points[MAX_MAP_POINTS];
+    static unsigned char last_color = (unsigned char)0;
+    static unsigned char last_behavior = (unsigned char)0, first_behavior = (unsigned char)0;
+    long x, y;
+    int draw_ok;
+    unsigned char line_behavior, fill_color;
+    char warning[200];
+
+    /* don't ever go over MAX_MAP_POINTS have a bad map not a crashed program */
+    if (npoints > MAX_MAP_POINTS) {
+        xastir_snprintf(warning, sizeof(warning), "Warning line point count overflow: map_plot\b\n");
+        XtAppWarning (app_context, warning);
+        npoints = MAX_MAP_POINTS;
+    }
+
+    /* if map_color_levels are on see if we should draw the line? */
+    draw_ok = 0;
+    if (map_color_levels)   // Decide which colors to display at this zoom level
+
+        switch (color) {
+
+            case (0x01):
+            case (0x14):
+            case (0x18):
+                if (mag < 100)
+                    draw_ok = 1;
+                break;
+
+            case (0x15):
+            case (0x19):
+                if (mag < 600)
+                    draw_ok = 1;
+                break;
+
+            case (0x16):
+                if (mag < 800)
+                    draw_ok = 1;
+                break;
+
+            default:
+                draw_ok = 1;
+                break;
+
+    }   // end of switch
+    else {    // Display all colors
+        draw_ok = 1;
+    }
+
+    if (draw_ok) {
+        x = ((x_long_cord - NW_corner_longitude) / scale_x);
+        y = ((y_lat_cord  - NW_corner_latitude)  / scale_y);
+        if (x < -MAX_OUTBOUND)
+            x = -MAX_OUTBOUND;
+
+        if (y < -MAX_OUTBOUND)
+            y = -MAX_OUTBOUND;
+
+        if (x > max_x)
+            x = max_x;
+
+        if (y > max_y)
+            y = max_y;
+
+        if (debug_level & 16)
+            fprintf(stderr," MAP Plot - max_x: %ld, max_y: %ld, x: %ld, y: %ld, color: %d, behavior: %lx, points: %d\n",
+                    max_x, max_y, x, y, (int)color, (unsigned long)object_behavior, npoints);
+
+        if ( (last_color != color) || (color == (unsigned char)0xff) ) {
+            if (npoints && (last_color != (unsigned char)0xff) ) {
+                line_behavior = last_behavior;
+                if (last_behavior & 0x80) {
+                    if (color) {
+                        fill_color = (last_behavior & ~0x80) + (unsigned char)0x60;
+                        if (fill_color > (unsigned char)0x69)
+                            fill_color = (unsigned char)0x60;
+                    }
+                    else {
+                        fill_color = (unsigned char)object_behavior;
+                    }
+
+
+                    // Here's where we draw filled areas using fill_color.
+
+                    (void)XSetForeground (XtDisplay (w), gc, colors[(int)fill_color]);
+
+                    switch (destination_pixmap) {
+
+                        case DRAW_TO_PIXMAP:
+                            // We must be drawing maps 'cuz this is the pixmap we use for it.
+                            if (map_color_fill && draw_filled) {
+
+                                if (npoints >= 3) {
+                                    (void)XFillPolygon(XtDisplay(w),
+                                        pixmap,
+                                        gc,
+                                        points,
+                                        npoints,
+                                        Nonconvex,
+                                        CoordModeOrigin);
+                                }
+                                else {
+//                                    fprintf(stderr,
+//                                        "map_plot:Too few points:%d, Skipping XFillPolygon()",
+//                                        npoints);
+                                }
+                            }
+                            break;
+
+                        case DRAW_TO_PIXMAP_ALERTS:
+                            fprintf(stderr,"You're calling the wrong routine to draw weather alerts!\n");
+                            break;
+
+                        case DRAW_TO_PIXMAP_FINAL:
+                            // We must be drawing symbols/tracks 'cuz this is the pixmap we use for it.
+
+                            if (npoints >= 3) {
+                                (void)XFillPolygon(XtDisplay(w),
+                                    pixmap_final,
+                                    gc,
+                                    points,
+                                    npoints,
+                                    Nonconvex,
+                                    CoordModeOrigin);
+                            }
+                            else {
+//                                fprintf(stderr,
+//                                    "map_plot:Too few points:%d, Skipping XFillPolygon()",
+//                                    npoints);
+                            }
+                            break;
+
+                    }   // end of switch
+
+                    line_behavior = first_behavior;
+                }
+                if (line_behavior & 0x01)
+                    (void)XSetLineAttributes (XtDisplay (w), gc, 2, LineSolid, CapButt,JoinMiter);
+                else
+                    (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineSolid, CapButt,JoinMiter);
+
+                if (color == (unsigned char)0x56)
+                    (void)XSetLineAttributes (XtDisplay (w), gc, 10, LineSolid, CapButt,JoinMiter);
+
+                // Set the color for drawing lines/borders
+                (void)XSetForeground (XtDisplay (w), gc, colors[(int)last_color]);
+
+                switch (destination_pixmap) {
+
+                    case DRAW_TO_PIXMAP_FINAL:
+                        (void)XDrawLines (XtDisplay (w),
+                            pixmap_final,
+                            gc,
+                            points,
+                            l16(npoints),
+                            CoordModeOrigin);
+                        break;
+
+                    case DRAW_TO_PIXMAP:
+                        (void)XDrawLines (XtDisplay (w),
+                            pixmap,
+                            gc,
+                            points,
+                            l16(npoints),
+                            CoordModeOrigin);
+                        break;
+
+                    case DRAW_TO_PIXMAP_ALERTS:
+                        fprintf(stderr,"You're calling the wrong routine to draw weather alerts!\n");
+                        break;
+                }   // end of switch
+
+                npoints = 0;
+
+                /* check to see if we have been away from the screen too long */
+                if (redraw_check > 1000) {
+                    redraw_check = 0;
+                    XmUpdateDisplay (XtParent (da));
+                }
+                redraw_check++;
+            }
+            last_color = color;
+            if (color == (unsigned char)0xff) {
+                npoints = 0;
+                first_behavior = (unsigned char)object_behavior;
+            }
+            points[npoints].x = l16(x);
+            points[npoints].y = l16(y);
+            if (    (points[npoints].x > (-MAX_OUTBOUND))
+                 && (points[npoints].x < (short)max_x)
+                 && (points[npoints].y > (-MAX_OUTBOUND))
+                 && (points[npoints].y < (short)max_y)
+                 && (color != (unsigned char)0) )
+
+                npoints++;
+
+            last_behavior = (unsigned char)object_behavior;
+            return;
+        }
+        points[npoints].x = l16(x);
+        points[npoints].y = l16(y);
+        last_behavior = (unsigned char)object_behavior;
+
+        if (points[npoints].x != points[npoints - 1].x || points[npoints].y != points[npoints - 1].y) {
+            if (last_behavior & 0x80) {
+                npoints++;
+            }
+            else if (points[npoints].x > (-MAX_OUTBOUND)
+                     && points[npoints].x < (short)max_x
+                     && points[npoints].y > (-MAX_OUTBOUND)
+                     && points[npoints].y < (short)max_y) {
+                npoints++;
+            }
+        }
+    }
+    else {
+        npoints = 0;
+    }
+}   /* map_plot */
+
+
+
+
+
+void draw_dos_map(Widget w,
+                  char *dir,
+                  char *filenm,
+                  alert_entry *alert,
+                  u_char alert_color,
+                  int destination_pixmap,
+                  map_draw_flags *mdf) {  
+
+    FILE *f;
+    char file[MAX_FILENAME];
+    char short_filenm[MAX_FILENAME];
+    char map_it[MAX_FILENAME];
+
+    /* map header info */
+    char map_type[5];
+    char map_version[5];
+    char file_name[33];
+//    char *ext;
+    char map_title[33];
+    char map_creator[9];
+    unsigned long creation_date;
+    unsigned long left_boundary;
+    unsigned long right_boundary;
+    unsigned long top_boundary;
+    unsigned long bottom_boundary;
+    char map_reserved1[9];
+    long total_vector_points;
+    long total_labels;
+    char map_reserved2[141];
+    char Buffer[2049];
+    char *ptr;
+    int dos_labels;
+    int dos_flag;
+    long temp;
+    int points_per_degree;
+    int map_range;
+  
+    /* vector info */
+    unsigned char vector_start;
+    unsigned char object_behavior;
+    unsigned long x_long_cord;
+    unsigned long y_lat_cord;
+  
+    /* label data */
+    char label_type[3];
+    unsigned long label_x_cord;
+    unsigned long label_y_cord;
+    int temp_mag;
+    int label_mag;
+    char label_symbol_del;
+    char label_symbol_char;
+    char label_text_color;
+    char label_text[50];
+  
+    unsigned long year;
+    unsigned long days;
+    long count;
+    int label_length;
+    int i;
+    int map_maxed_vectors;
+    int map_maxed_text_labels;
+    int map_maxed_symbol_labels;
+    map_vectors *vectors_ptr;
+    text_label *text_ptr;
+    symbol_label *symbol_ptr;
+    int line_width;
+    int x, y;
+    int color;
+    long max_x, max_y;
+    int in_window = 0;
+    char symbol_table;
+    char symbol_id;
+    char symbol_color;
+    int embedded_object;
+
+    int draw_filled;
+    unsigned char last_behavior, special_fill = (unsigned char)FALSE;
+
+
+    draw_filled=mdf->draw_filled;
+
+    x = 0;
+    y = 0;
+    color = -1;
+    line_width = 1;
+    mag = (1 * scale_y) / 2;    // determines if details are drawn
+  
+    /* MAP counters */
+    vectors_ptr = map_vectors_ptr;
+    text_ptr = map_text_label_ptr;
+    symbol_ptr = map_symbol_label_ptr;
+  
+    map_maxed_vectors = 0;
+    map_maxed_text_labels = 0;
+    map_maxed_symbol_labels = 0;
+    npoints = 0;
+  
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    f = fopen (file, "r");
+    if (f == NULL) {
+        fprintf(stderr,"Couldn't open file: %s\n", file);
+        return;
+    }
+
+    (void)fread (map_type, 4, 1, f);
+    map_type[4] = '\0';
+    dos_labels = FALSE;
+    points_per_degree = 300;
+    
+
+// DOS-type map header portion of the code.
+
+    if (strtod (map_type, &ptr) > 0.01 && (*ptr == '\0' || *ptr == ' ' || *ptr == ',')) {
+        int j;
+      
+        if (debug_level & 512)
+            fprintf(stderr,"\nDOS Map\n");
+      
+        top_boundary = left_boundary = bottom_boundary = right_boundary = 0;
+        rewind (f);
+        map_title[0] = map_creator[0] = Buffer[0] = '\0';
+        // set map_type for DOS ASCII maps
+        xastir_snprintf(map_type,sizeof(map_type),"DOS ");
+        map_type[4] = '\0';
+        xastir_snprintf(file_name,sizeof(file_name),"%s",filenm);
+        total_vector_points = 200000;
+        total_labels = 2000;
+
+        for (j = 0; j < DOS_HDR_LINES; strlen(Buffer) ? 1 : j++) {
+
+            (void)fgets (&Buffer[strlen (Buffer)],(int)sizeof (Buffer) - (strlen (Buffer)), f);
+
+//            if (!strlen(Buffer))
+//                j++;
+ 
+	        while ((ptr = strpbrk (Buffer, "\r\n")) != NULL && j < DOS_HDR_LINES) {
+
+                *ptr = '\0';
+
+                for (ptr++; *ptr == '\r' || *ptr == '\n'; ptr++) ;
+
+                switch (j) {
+
+                    case 0:
+//fprintf(stderr,"top_boundary: %s\n", Buffer);
+                	    top_boundary = (unsigned long) (-atof (Buffer) * 360000 + 32400000);
+                	    break;
+	      
+                    case 1:
+//fprintf(stderr,"left_boundary: %s\n", Buffer);
+                	    left_boundary = (unsigned long) (-atof (Buffer) * 360000 + 64800000);
+                	    break;
+	      
+                    case 2:
+//fprintf(stderr,"points_per_degree: %s\n", Buffer);
+                	    points_per_degree = (int) atof (Buffer);
+                	    break;
+	      
+                    case 3:
+//fprintf(stderr,"bottom_boundary: %s\n", Buffer);
+                	    bottom_boundary = (unsigned long) (-atof (Buffer) * 360000 + 32400000);
+                	    bottom_boundary = bottom_boundary + bottom_boundary - top_boundary;
+                	    break;
+	      
+                    case 4:
+//fprintf(stderr,"right_boundary: %s\n", Buffer);
+                	    right_boundary = (unsigned long) (-atof (Buffer) * 360000 + 64800000);
+                	    right_boundary = right_boundary + right_boundary - left_boundary;
+                	    break;
+	      
+                	case 5:
+//fprintf(stderr,"map_range: %s\n", Buffer);
+                	    map_range = (int) atof (Buffer);
+                	    break;
+	      
+                	case 7:
+//fprintf(stderr,"Map Version: %s\n", Buffer);
+                        xastir_snprintf(map_version,sizeof(map_version),"%s",Buffer);
+//fprintf(stderr,"MAP VERSION: %s\n", map_version);
+                	    break;
+                } // end of switch
+
+                xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr);
+
+//                if (strlen (Buffer))
+//                    j++;
+
+            }
+        }   // End of DOS-type map header portion
+    }
+    else {
+
+// Windows-type map header portion
+	
+        if (debug_level & 512)
+            fprintf(stderr,"\nWindows map\n");
+	
+        (void)fread (map_version, 4, 1, f);
+        map_version[4] = '\0';
+      
+        (void)fread (file_name, 32, 1, f);
+        file_name[32] = '\0';
+      
+        (void)fread (map_title, 32, 1, f);
+        map_title[32] = '\0';
+        if (debug_level & 16)
+            fprintf(stderr,"Map Title %s\n", map_title);
+      
+        (void)fread (map_creator, 8, 1, f);
+        map_creator[8] = '\0';
+        if (debug_level & 16)
+            fprintf(stderr,"Map Creator %s\n", map_creator);
+      
+        (void)fread (&temp, 4, 1, f);
+        creation_date = ntohl (temp);
+        if (debug_level & 16)
+            fprintf(stderr,"Creation Date %lX\n", creation_date);
+      
+        year = creation_date / 31536000l;
+        days = (creation_date - (year * 31536000l)) / 86400l;
+        if (debug_level & 16)
+            fprintf(stderr,"year is %ld + days %ld\n", 1904l + year, (long)days);
+      
+        (void)fread (&temp, 4, 1, f);
+        left_boundary = ntohl (temp);
+      
+        (void)fread (&temp, 4, 1, f);
+        right_boundary = ntohl (temp);
+      
+        (void)fread (&temp, 4, 1, f);
+        top_boundary = ntohl (temp);
+      
+        (void)fread (&temp, 4, 1, f);
+        bottom_boundary = ntohl (temp);
+      
+        if (strcmp (map_version, "2.00") != 0) {
+            left_boundary *= 10;
+            right_boundary *= 10;
+            top_boundary *= 10;
+            bottom_boundary *= 10;
+        }
+
+        (void)fread (map_reserved1, 8, 1, f);
+        (void)fread (&temp, 4, 1, f);
+        total_vector_points = (long)ntohl (temp);
+        (void)fread (&temp, 4, 1, f);
+        total_labels = (long)ntohl (temp);
+        (void)fread (map_reserved2, 140, 1, f);
+
+    }   // End of Windows-type map header portion
+      
+      
+    // Done processing map header info.  The rest of this
+    // function performs the actual drawing of both DOS-type
+    // and Windows-type maps to the screen.
+    
+    
+    if (debug_level & 16) {
+        fprintf(stderr,"Map Type: %s, Version: %s, Filename: %s\n", map_type, map_version, file_name);
+        fprintf(stderr,"Left Boundary: %ld, Right Boundary: %ld\n", (long)left_boundary,(long)right_boundary);
+        fprintf(stderr,"Top Boundary: %ld, Bottom Boundary: %ld\n", (long)top_boundary,(long)bottom_boundary);
+        fprintf(stderr,"Total vector points: %ld, total labels: %ld\n",total_vector_points, total_labels);
+    }
+
+ 
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+      
+        // We're indexing only.  Save the extents in the index.
+        index_update_xastir(filenm, // Filename only
+                            bottom_boundary,  // Bottom
+                            top_boundary,     // Top
+                            left_boundary,    // Left
+                            right_boundary,   // Right
+                            1000);            // Default Map Level
+      
+        (void)fclose (f);
+
+        // Update the statusline 
+        xastir_snprintf(map_it,
+                        sizeof(map_it),
+                        langcode ("BBARSTA039"),
+                        short_filenm);
+        statusline(map_it,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+      
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        (void)fclose(f);
+
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+  
+    // Check to see if we should draw the map
+    in_window = map_onscreen(left_boundary, right_boundary, top_boundary, bottom_boundary, 1);
+
+    if (!in_window) {
+        (void)fclose (f);
+        return;
+    }
+
+    // Update the statusline
+    xastir_snprintf(map_it,
+        sizeof(map_it),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(map_it,0);       // Loading/Indexing ...
+
+    object_behavior = '\0';
+	
+    if (debug_level & 16)
+        fprintf(stderr,"in Boundary %s\n", map_it);
+      
+    (void)XSetLineAttributes (XtDisplay (w), gc, line_width, LineSolid, CapButt,JoinMiter);
+      
+    /* read vectors */
+    max_x = screen_width  + MAX_OUTBOUND;
+    max_y = screen_height + MAX_OUTBOUND;
+ 
+    x_long_cord = 0;
+    y_lat_cord  = 0;
+    color = 0;
+    dos_flag = 0;
+
+    for (count = 0l;count < total_vector_points && !feof (f) && !dos_labels; count++) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            (void)fclose(f);
+
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+// DOS type map
+ 
+        if (strncmp ("DOS ", map_type, 4) == 0) {
+
+            (void)fgets (&Buffer[strlen (Buffer)],(int)sizeof (Buffer) - (strlen (Buffer)), f);
+
+            while ((ptr = strpbrk (Buffer, "\r\n")) != NULL && !dos_labels) {
+                long LatHld = 0, LongHld;
+                char *trailer;
+
+                *ptr = '\0';
+
+                for (ptr++; *ptr == '\r' || *ptr == '\n'; ptr++) ;
+            
+process:        if (strncasecmp ("Line", map_version, 4) == 0) {
+                    int k;
+
+                    color = (int)strtol (Buffer, &trailer, 0);
+
+                    if (trailer && (*trailer == ',' || *trailer == ' ')) {
+                        trailer++;
+
+                        if (color == -1) {
+                            dos_labels = (int)TRUE;
+                            xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr);
+                            break;
+                        }
+
+                        for (k = strlen (trailer) - 1; k >= 0; k--) {
+                            trailer[k] = (char)( (int)trailer[k] - 27 );
+                        }
+                
+                        while (*trailer) {
+                            LongHld = (long)( (int)(*(unsigned char *)trailer) * 16);
+                            trailer++;
+                            LatHld = (long)( (int)(*(unsigned char *)trailer) * 8);
+                            trailer++;
+                            LongHld += (long)((*trailer >> 3) & 0xf);
+                            LatHld += (long)( (*trailer) & 0x7);
+                            trailer++;
+                            LatHld = ((double)LatHld * 360000.0) / points_per_degree;
+                            LongHld = ((double)LongHld * 360000.0) / points_per_degree;
+                            x_long_cord = LongHld + left_boundary;
+                            y_lat_cord = LatHld + top_boundary;
+                            map_plot (w,
+                                max_x,
+                                max_y,
+                                (long)x_long_cord,
+                                (long)y_lat_cord,
+                                (unsigned char)color,
+                                0,
+                                destination_pixmap,
+                                draw_filled);
+                        }
+                        map_plot (w,
+                            max_x,
+                            max_y,
+                            (long)x_long_cord,
+                            (long)y_lat_cord,
+                            '\0',
+                            0,
+                            destination_pixmap,
+                            draw_filled);
+                    }
+                }
+
+                else if (strncasecmp ("ASCII", map_version, 4) == 0) {
+
+                    if (color == 0) {
+                        color = (int)strtol (Buffer, &trailer, 0);
+                        if (trailer && strpbrk (trailer, ", ")) {
+
+                            for (; *trailer == ',' || *trailer == ' '; trailer++) ;
+
+                            dos_flag = (int)strtol (trailer, &trailer, 0);
+                            if (dos_flag == -1)
+                            dos_labels = (int)TRUE;
+                        }
+                    }
+                    else {
+                        LongHld = strtol (Buffer, &trailer, 0);
+
+                        if (trailer && strpbrk (trailer, ", ")) {
+
+                            for (; *trailer == ',' || *trailer == ' '; trailer++) ;
+
+                            LatHld = strtol (trailer, &trailer, 0);
+                        }
+                        else if (LongHld == 0 && *trailer != '\0') {
+                            xastir_snprintf(map_version,sizeof(map_version),"Comp");
+                            map_version[4] = '\0';
+                            goto process;
+                        }
+                        if (LongHld == 0 && LatHld == 0) {
+                            color = 0;
+                            map_plot (w,
+                                max_x,
+                                max_y,
+                                (long)x_long_cord,
+                                (long)y_lat_cord,
+                                (unsigned char)color,
+                                0,
+                                destination_pixmap,
+                                draw_filled);
+                        }
+                        else if (LongHld == 0 && LatHld == -1) {
+                            dos_labels = (int)TRUE;
+                            map_plot (w,
+                                max_x,
+                                max_y,
+                                (long)x_long_cord,
+                                (long)y_lat_cord,
+                                '\0',
+                                0,
+                                destination_pixmap,
+                                draw_filled);
+                        }
+                        else {
+                            LatHld = ((double)LatHld * 360000.0) / points_per_degree;
+                            LongHld = ((double)LongHld * 360000.0) / points_per_degree;
+                            x_long_cord = LongHld + left_boundary;
+                            y_lat_cord = LatHld + top_boundary;
+                            map_plot (w,
+                                max_x,
+                                max_y,
+                                (long)x_long_cord,
+                                (long)y_lat_cord,
+                                (unsigned char)color,
+                                0,
+                                destination_pixmap,
+                                draw_filled);
+                        }
+                    }
+                }
+                else if (strncasecmp ("Comp", map_version, 4) == 0) {
+                    char Tag[81];
+                    int k;
+
+                    Tag[80] = '\0';
+                    if (color == 0) {
+                        color = (int)strtol (Buffer, &trailer, 0);
+                        if (trailer && strpbrk (trailer, ", ")) {
+
+                            for (; *trailer == ',' || *trailer == ' '; trailer++) ;
+
+                            dos_flag = (int)strtol (trailer, &trailer, 0);
+                            xastir_snprintf(Tag,sizeof(Tag),"%s",trailer);
+                            Tag[79] = '\0';
+                            if (dos_flag == -1)
+                            dos_labels = (int)TRUE;
+                        }
+                    }
+                    else {
+                        LongHld = strtol (Buffer, &trailer, 0);
+
+                        for (; *trailer == ',' || *trailer == ' '; trailer++) ;
+
+                        LatHld = strtol (trailer, &trailer, 0);
+                        if (LatHld == 0 && *trailer != '\0') {
+                            LatHld = 1;
+                        }
+
+                        if (LongHld == 0 && LatHld == 0) {
+                            color = 0;
+                            map_plot (w,
+                                max_x,
+                                max_y,
+                                (long)x_long_cord,
+                                (long)y_lat_cord,
+                                (unsigned char)color,
+                                0,
+                                destination_pixmap,
+                                draw_filled);
+                        }
+                        else if (LongHld == 0 && LatHld == -1) {
+                            dos_labels = (int)TRUE;
+                            map_plot (w,
+                                max_x,
+                                max_y,
+                                (long)x_long_cord,
+                                (long)y_lat_cord,
+                                (unsigned char)color,
+                                0,
+                                destination_pixmap,
+                                draw_filled);
+                        }
+                
+                        if (color && !dos_labels) {
+                            trailer = Buffer;
+
+                            for (k = strlen (trailer) - 1; k >= 0; k--) {
+                                trailer[k] = (char)((int)trailer[k] - 27);
+                            }
+                  
+                            while (*trailer) {
+
+                                LongHld = (long)( (int)(*(unsigned char *)trailer) * 16);
+                                trailer++;
+                                LatHld = (long)( (int)(*(unsigned char *)trailer) * 8);
+                                trailer++;
+                                LongHld += (long)((*(unsigned char *)trailer >> 3) & 0xf);
+                                LatHld += (*trailer) & 7l;
+                                trailer++;
+                                LatHld = ((double)LatHld * 360000.0) / points_per_degree;
+                                LongHld = ((double)LongHld * 360000.0) / points_per_degree;
+                                x_long_cord = LongHld + left_boundary;
+                                y_lat_cord = LatHld + top_boundary;
+                                map_plot (w,
+                                    max_x,
+                                    max_y,
+                                    (long)x_long_cord,
+                                    (long)y_lat_cord,
+                                    (unsigned char)color,
+                                    0,
+                                    destination_pixmap,
+                                    draw_filled);
+                            }
+                        }
+                    }
+                }
+                else {
+                    LongHld = strtol (Buffer, &trailer, 0);
+                    if (trailer) {
+                        if (*trailer == ',' || *trailer == ' ') {
+                            if (LongHld == 0) {
+                                xastir_snprintf(map_version,sizeof(map_version),"ASCII");
+                            }
+    
+                            map_version[4] = '\0';
+                  
+                            trailer++;
+
+                            dos_flag = (int)strtol (trailer, &trailer, 0);
+                            if (dos_flag == -1) {
+                                dos_labels = (int)TRUE;
+                            }
+                  
+                            if (dos_flag == 0 && *trailer != '\0') {
+                                xastir_snprintf(map_version,sizeof(map_version),"Line");
+                                map_version[4] = '\0';
+                                goto process;
+                            }
+                            color = (int)LongHld;
+                        }
+                    }
+                    else {
+                        xastir_snprintf(map_version,sizeof(map_version),"Comp");
+                   }
+                    map_version[4] = '\0';
+                }
+                xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr);
+            }
+        }
+        else {
+
+// Windows type map...
+
+            last_behavior = object_behavior;
+            (void)fread (&vector_start, 1, 1, f);
+            (void)fread (&object_behavior, 1, 1, f);      // Fill Color?
+
+            if (strcmp (map_type, "COMP") == 0) {
+                short temp_short;
+                long LatOffset, LongOffset;
+
+                LatOffset  = (long)(top_boundary  - top_boundary  % 6000);
+                LongOffset = (long)(left_boundary - left_boundary % 6000);
+                (void)fread (&temp_short, 2, 1, f);
+                x_long_cord = (ntohs (temp_short) * 10 + LongOffset);
+                (void)fread (&temp_short, 2, 1, f);
+                y_lat_cord  = (ntohs (temp_short) * 10 + LatOffset);
+            }
+            else {
+                (void)fread (&temp, 4, 1, f);
+                x_long_cord = ntohl (temp);
+                if (strcmp (map_version, "2.00") != 0)
+                x_long_cord *= 10;
+            
+                (void)fread (&temp, 4, 1, f);
+                y_lat_cord = ntohl (temp);
+                if (strcmp (map_version, "2.00") != 0)
+                y_lat_cord *= 10;
+            }
+
+            if (alert_color && last_behavior & 0x80 && (int)vector_start == 0xff) {
+                map_plot (w,
+                    max_x,
+                    max_y,
+                    (long)x_long_cord,
+                    (long)y_lat_cord,
+                    '\0',
+                    (long)alert_color,
+                    destination_pixmap,
+                    draw_filled);
+                //special_fill = TRUE;
+            }
+            map_plot (w,
+                max_x,
+                max_y,
+                (long)x_long_cord,
+                (long)y_lat_cord,
+                vector_start,
+                (long)object_behavior,
+                destination_pixmap,
+                draw_filled);
+        }
+    }
+    if (alert_color) {
+        map_plot (w,
+            max_x,
+            max_y,
+            0,
+            0,
+            '\0',
+            special_fill ? (long)0xfd : (long)alert_color,
+            destination_pixmap,
+            draw_filled);
+    }
+    else {
+        map_plot (w,
+            max_x,
+            max_y,
+            0,
+            0,
+            (unsigned char)0xff,
+            0,
+            destination_pixmap,
+            draw_filled);
+    }
+      
+    (void)XSetForeground (XtDisplay (w), gc, colors[20]);
+    line_width = 2;
+    (void)XSetLineAttributes (XtDisplay (w), gc, line_width, LineSolid, CapButt,JoinMiter);
+
+      
+    // Here is the map label section of the code for both DOS & Windows-type maps
+    if (map_labels) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            (void)fclose(f);
+
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        /* read labels */
+        for (count = 0l; count < total_labels && !feof (f); count++) {
+
+//DOS-Type Map Labels
+
+            embedded_object = 0;
+
+            if (strcmp (map_type, "DOS ") == 0) {   // Handle DOS-type map labels/embedded objects
+                char *trailer;
+
+                (void)fgets (&Buffer[strlen (Buffer)],(int)sizeof (Buffer) - (strlen (Buffer)), f);
+
+                for (; (ptr = strpbrk (Buffer, "\r\n")) != NULL;xastir_snprintf(Buffer,sizeof(Buffer),"%s",ptr)) {
+
+                    *ptr = '\0';
+                    label_type[0] = (char)0x08;
+
+                    for (ptr++; *ptr == '\r' || *ptr == '\n'; ptr++) ;
+
+                    trailer = strchr (Buffer, ',');
+                    if (trailer && strncmp (Buffer, "0", 1) != 0) {
+                        *trailer = '\0';
+                        trailer++;
+                        xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer);
+                
+                        // Check for '#' or '$' as the first character of the label.
+                        // If found, we have an embedded symbol and colored text to display.
+                        symbol_table = ' ';
+                        symbol_id = ' ';
+                        symbol_color = '0';
+
+                        if ( (label_text[0] == '$') || (label_text[0] == '#') ) {
+                            // We found an embedded map object
+                            embedded_object = 1;                        // Set the flag
+                            if (label_text[0] == '$') {                  // Old format: $xC
+                                symbol_table = '/';
+                                symbol_id = label_text[1];
+                                symbol_color = label_text[2];
+                                // Take the object out of the label text
+                                xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer+3);
+                            }
+                            else {  // Could be in new or old format with a leading '#' character
+                                symbol_table = label_text[1];
+                                if (symbol_table == '/' || symbol_table == '\\') {  // New format: #/xC
+                                    symbol_id = label_text[2];
+                                    symbol_color = label_text[3];
+                                    // Take the object out of the label text
+                                    xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer+4);
+                                }
+                                else {                                  // Old format: #xC
+                                    symbol_table = '\\';
+                                    symbol_id = label_text[1];
+                                    symbol_color = label_text[2];
+                                    // Take the object out of the label text
+                                    xastir_snprintf(label_text,sizeof(label_text),"%s",Buffer+3);
+                                }
+                            }
+                            if (debug_level & 512)
+                                fprintf(stderr,"Found embedded object: %c %c %c %s\n",symbol_table,symbol_id,symbol_color,label_text);
+                        }
+                
+                
+                        label_length = (int)strlen (label_text);
+                        label_y_cord = (unsigned long) (-strtod (trailer, &trailer) * 360000) + 32400000;
+                        trailer++;
+                        label_x_cord = (unsigned long) (-strtod (trailer, &trailer) * 360000) + 64800000;
+                        trailer++;
+                        label_mag = (int)strtol (trailer, &trailer, 0) * 20;
+
+                        if ((label_type[0] & 0x80) == '\0') /* left of coords */
+                            x = ((label_x_cord - NW_corner_longitude) / scale_x) - (label_length * 6);
+                        else  /* right of coords */
+                            x = ((label_x_cord - NW_corner_longitude) / scale_x);
+                
+                        y = ((label_y_cord - NW_corner_latitude) / scale_y);
+                        if (x > (0) && (x < (int)screen_width)) {
+                            if (y > (0) && (y < (int)screen_height)) {
+                                /*fprintf(stderr,"Label mag %d mag %d\n",label_mag,(scale_x*2)-1); */
+                                //if (label_mag > (int)((scale_x * 2) - 1) || label_mag == 0)
+                                if (label_mag > (int)((scale_x) - 1) || label_mag == 0) {
+                                    if (embedded_object) {
+                                        // NOTE: 0x21 is the first color for the area object or "DOS" colors
+                                        draw_label_text (w, x+10, y+5, label_length,colors[0x21 + symbol_color],label_text);
+                                        symbol(w,0,symbol_table,symbol_id,' ',pixmap,1,x-10,y-10,' ');
+                                    }
+                                    else {
+                                        draw_label_text (w, x, y, label_length,colors[(int)(label_type[0] & 0x7f)],label_text);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            else {    // Handle Windows-type map labels/embedded objects
+                int rotation = 0;
+                char rotation_factor[5];
+            
+// Windows-Type Map Labels
+
+                char label_type_1[2], label_type_2[2];
+            
+                // Snag first two bytes of label
+                (void)fread (label_type_1, 1, 1, f);
+                (void)fread (label_type_2, 1, 1, f);
+            
+                if (label_type_2[0] == '\0') {  // Found a label
+              
+                    // Found text label
+                    (void)fread (&temp, 4, 1, f);           /* x */
+                    label_x_cord = ntohl (temp);
+                    if (strcmp (map_version, "2.00") != 0)
+                        label_x_cord *= 10;
+              
+                    (void)fread (&temp, 4, 1, f);           /* y */
+                    label_y_cord = ntohl (temp);
+                    if (strcmp (map_version, "2.00") != 0)
+                        label_y_cord *= 10;
+              
+                    (void)fread (&temp_mag, 2, 1, f);       /* mag */
+                    label_mag = (int)ntohs (temp_mag);
+                    if (strcmp (map_version, "2.00") != 0)
+                        label_mag *= 10;
+              
+                    if (strcmp (map_type, "COMP") == 0) {
+
+                        for (i = 0; i < 32; i++) {
+                            (void)fread (&label_text[i], 1, 1, f);
+                            if (label_text[i] == '\0') {
+                                break;
+                            }
+                        }
+                        label_text[32] = '\0';  // Make sure we have a terminator
+                    }
+                    else {
+                        (void)fread (label_text, 32, 1, f);   /* text */
+                        label_text[32] = '\0';  // Make sure we have a terminator
+                    }
+              
+              
+                    // Special strings like: "#123" are rotation factors for labels
+                    // in degrees.  This is not documented in the windows-type map
+                    // format documents that I could find.
+                    if (label_text[0] == '#') {
+                        int i,j;
+
+                        if (debug_level & 512)
+                            fprintf(stderr,"%s\n",label_text);
+                
+                        // Save the rotation factor in "rotation"
+                        for ( i=1; i<4; i++ ) {
+                            rotation_factor[i-1] = label_text[i];
+                        }
+
+                        rotation_factor[3] = '\0';
+                        rotation = atoi(rotation_factor);
+                
+                        // Take rotation factor out of label string
+                        for ( i=4, j=0; i < (int)(strlen(label_text)+1); i++,j++) {
+                            label_text[j] = label_text[i];
+                        }
+                
+                        //fprintf(stderr,"Windows label: %s, rotation factor: %d\n",label_text, rotation);
+                    }
+              
+                    label_length = (int)strlen (label_text);
+
+                    for (i = (label_length - 1); i > 0; i--) {
+                        if (label_text[i] == ' ') {
+                            label_text[i] = '\0';
+                        }
+                        else {
+                            break;
+                        }
+                    }
+              
+                    label_length = (int)strlen (label_text);
+                    /*fprintf(stderr,"labelin:%s\n",label_text); */
+              
+                    if ((label_type_1[0] & 0x80) == '\0') {
+                        /* left of coords */
+                        x = ((label_x_cord - NW_corner_longitude) / scale_x) - (label_length * 6);
+                        x = 0;  // ??????
+                    }
+                    else {
+                        /* right of coords */
+                        x = ((label_x_cord - NW_corner_longitude) / scale_x);
+                    }
+              
+                    y = ((label_y_cord - NW_corner_latitude) / scale_y);
+              
+                    if (x > (0) && (x < (int)screen_width)) {
+
+                        if (y > (0) && (y < (int)screen_height)) {
+
+                            /*fprintf(stderr,"Label mag %d mag %d\n",label_mag,(scale_x*2)-1); */
+                            //if (label_mag > (int)((scale_x * 2) - 1) || label_mag == 0)
+                            if (label_mag > (int)((scale_x) - 1) || label_mag == 0) {
+                                // Note: We're not drawing the labels in the right colors
+                                if (rotation == 0) {    // Non-rotated label
+//                                    draw_label_text (w,
+//                                        x,
+//                                        y,
+//                                        label_length,
+//                                        colors[(int)(label_type_1[0] & 0x7f)],
+//                                        label_text);
+                                    draw_rotated_label_text (w,
+                                        -90.0,
+                                        x,
+                                        y,
+                                        label_length,
+                                        colors[(int)(label_type_1[0] & 0x7f)],
+                                        label_text,
+                                        FONT_DEFAULT);
+                                }
+                                else {  // Rotated label
+                                    draw_rotated_label_text (w,
+                                        rotation,
+                                        x,
+                                        y,
+                                        label_length,
+                                        colors[(int)(label_type_1[0] & 0x7f)],
+                                        label_text,
+                                        FONT_DEFAULT);
+                                }
+                            }
+                        }
+                    }
+                }
+                else if (label_type_2[0] == '\1' && label_type_1[0] == '\0') { // Found an embedded object
+              
+                    //fprintf(stderr,"Found windows embedded symbol\n");
+              
+                    /* label is an embedded symbol */
+                    (void)fread (&temp, 4, 1, f);
+                    label_x_cord = ntohl (temp);
+                    if (strcmp (map_version, "2.00") != 0)
+                        label_x_cord *= 10;
+          
+                    (void)fread (&temp, 4, 1, f);
+                    label_y_cord = ntohl (temp);
+                    if (strcmp (map_version, "2.00") != 0)
+                        label_y_cord *= 10;
+              
+                    (void)fread (&temp_mag, 2, 1, f);
+                    label_mag = (int)ntohs (temp_mag);
+                    if (strcmp (map_version, "2.00") != 0)
+                        label_mag *= 10;
+              
+                    (void)fread (&label_symbol_del, 1, 1, f);   // Snag symbol table char
+                    (void)fread (&label_symbol_char, 1, 1, f);  // Snag symbol char
+                    (void)fread (&label_text_color, 1, 1, f);   // Snag text color (should be 1-9, others should default to black)
+                    if (label_text_color < '1' && label_text_color > '9')
+                        label_text_color = '0'; // Default to black
+              
+                    x = ((label_x_cord - NW_corner_longitude) / scale_x);
+                    y = ((label_y_cord - NW_corner_latitude) / scale_y);
+              
+                    // Read the label text portion
+                    if (strcmp (map_type, "COMP") == 0) {
+
+                        for (i = 0; i < 32; i++) {
+                            (void)fread (&label_text[i], 1, 1, f);
+                            if (label_text[i] == '\0')
+                                break;
+                        }
+                    }
+                    else {
+                        (void)fread (label_text, 29, 1, f);
+                    }
+              
+                    // NOTE: 0x21 is the first color for the area object or "DOS" colors
+                    draw_label_text (w, x+10, y+5, strlen(label_text),colors[0x21 + label_text_color],label_text);
+                    symbol(w,0,label_symbol_del,label_symbol_char,' ',pixmap,1,x-10,y-10,' ');
+              
+                    if (debug_level & 512)
+                        fprintf(stderr,"Windows map, embedded object: %c %c %c %s\n",
+
+                    label_symbol_del,label_symbol_char,label_text_color,label_text);
+                }
+                else {
+                    if (debug_level & 512)
+                        fprintf(stderr,"Weird label in Windows map, neither a plain label nor an object: %d %d\n",
+                            label_type_1[0],label_type_2[0]);
+                }
+            }
+        }
+    }       // if (map_labels)
+
+    (void)fclose (f);
+}
+
+
diff --git a/src/map_gdal.c b/src/map_gdal.c
new file mode 100644
index 0000000..e712bd3
--- /dev/null
+++ b/src/map_gdal.c
@@ -0,0 +1,5087 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_gdal.c,v 1.159 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2004-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ *
+ */
+
+
+#define TIGER_POLYGONS
+
+
+//
+// NOTE:  GDAL sample data can be found here:
+//
+//          ftp://ftp.remotesensing.org/gdal/data
+// or here: http://gdal.maptools.org/dl/data/
+//
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+//#include <stdio.h>
+#include <stdlib.h>
+//#include <unistd.h>
+//#include <sys/stat.h>
+//#include <ctype.h>
+//#include <sys/types.h>
+//#include <pwd.h>
+//#include <errno.h>
+
+// Needed for Solaris
+//#ifdef HAVE_STRINGS_H
+//#include <strings.h>
+//#endif  // HAVE_STRINGS_H
+
+//#include <dirent.h>
+//#include <netinet/in.h>
+//#include <Xm/XmAll.h>
+
+//#ifdef HAVE_X11_XPM_H
+//#include <X11/xpm.h>
+//#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+//#undef HAVE_XM_XPMI_H
+//#endif // HAVE_LIBXPM
+//#endif // HAVE_X11_XPM_H
+
+//#ifdef HAVE_XM_XPMI_H
+//#include <Xm/XpmI.h>
+//#endif // HAVE_XM_XPMI_H
+
+//#include <X11/Xlib.h>
+
+//#include <math.h>
+
+#include "maps.h"
+#include "alert.h"
+//#include "util.h"
+#include "main.h"
+//#include "datum.h"
+#include "draw_symbols.h"
+//#include "rotated.h"
+//#include "color.h"
+//#include "xa_config.h"
+
+#ifdef TIGER_POLYGONS
+#include "hashtable.h"
+#include "hashtable_itr.h"
+#endif  // TIGER_POLYGONS
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+
+
+#ifdef HAVE_LIBGDAL
+
+//#warning
+//#warning
+//#warning GDAL/OGR library support is not fully implemented yet!
+//#warning Preliminary TIGER/Line, Shapefile, mid/mif/tab (MapInfo),
+//#warning and SDTS support is functional, including on-the-fly
+//#warning coordinate conversion for both indexing and drawing.
+//#warning
+//#warning
+
+// Getting rid of stupid compiler warnings in GDAL
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+
+#include "gdal.h"
+#include "ogr_api.h"
+#include "ogr_srs_api.h"
+//#include "cpl_string.h"
+
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#endif  // HAVE_LIBGDAL
+
+
+// Needs to be down here so that the LIB_GC stuff will compile in
+// ok.
+#include "xastir.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+void map_gdal_init(void) {
+
+#ifdef HAVE_LIBGDAL
+
+    GDALDriverH  gDriver;   // GDAL driver
+    OGRSFDriverH oDriver;   // OGR driver
+    int ii;
+    int jj;
+
+
+    // Register all known GDAL drivers
+    GDALAllRegister();
+
+    // Register all known OGR drivers
+    OGRRegisterAll();
+
+    // Print out each supported GDAL driver.
+    //
+    ii = GDALGetDriverCount();
+
+//    fprintf(stderr,"  GDAL Registered Drivers:\n");
+    for (jj = 0; jj < ii; jj++) {
+        gDriver = GDALGetDriver(jj);
+//        fprintf(stderr,"%10s   %s\n",
+//            GDALGetDriverShortName(gDriver),
+//            GDALGetDriverLongName(gDriver) );
+    }
+//    fprintf(stderr,"             (none)\n");
+
+
+    // Print out each supported OGR driver
+    //
+    ii = OGRGetDriverCount();
+
+//    fprintf(stderr,"  OGR Registered Drivers:\n");
+
+    for  (jj = 0; jj < ii; jj++) {
+        char *drv_name;
+
+
+        oDriver = OGRGetDriver(jj);
+        drv_name = (char *)OGR_Dr_GetName(oDriver);
+
+        if (strstr(drv_name,"Shapefile")) {
+#ifdef GDAL_SHAPEFILES
+            fprintf(stderr,"       shp   ESRI Shapefile (via GDAL)\n");
+#endif  // GDAL_SHAPEFILES
+        }
+        else if (strstr(drv_name,"NTF")) {
+            // Not enabled in Xastir yet
+        }
+        else if (strstr(drv_name,"SDTS")) {
+            fprintf(stderr,"       ddf   Spatial Data Transfer Standard (SDTS)\n");
+        }
+        else if (strstr(drv_name,"TIGER")) {
+            fprintf(stderr,"       rt1   US Census Bureau TIGER/Line\n");
+        }
+        else if (strstr(drv_name,"S57")) {
+            fprintf(stderr,"       s57   International Hydrographic Organization (IHO) S-57\n");
+        }
+        else if (strstr(drv_name,"MapInfo")) {
+            fprintf(stderr,"       tab   MapInfo TAB\n");
+            fprintf(stderr,"       mid   MapInfo MID\n");
+            fprintf(stderr,"       mif   MapInfo MIF\n");
+        }
+        else if (strstr(drv_name,"DGN")) {
+            fprintf(stderr,"       dgn   MicroStation DGN\n");
+        }
+        else if (strstr(drv_name,"VRT")) {
+            // Not enabled in Xastir yet
+        }
+        else if (strstr(drv_name,"AVCBin")) {
+            // Not enabled in Xastir yet
+        }
+        else if (strstr(drv_name,"REC")) {
+            // Not enabled in Xastir yet
+        }
+        else if (strstr(drv_name,"Memory")) {
+            // Not enabled in Xastir yet
+        }
+        else if (strstr(drv_name,"GML")) {
+            // Not enabled in Xastir yet
+        }
+        else if (strstr(drv_name,"PostgreSQL")) {
+            // Not enabled in Xastir yet
+        }
+    }
+    fprintf(stderr,"\n");
+
+    atexit(GDALDestroyDriverManager);
+#endif  // HAVE_LIBGDAL
+
+}
+
+
+
+
+
+/*  TODO: 
+ *    projections
+ *    multiple bands 
+ *    colormaps 
+ *    .geo files vs. .wld
+ *    map index
+ */
+
+
+#ifdef HAVE_LIBGDAL
+
+void draw_gdal_map(Widget w,
+                   char *dir,
+                   char *filenm,
+                   alert_entry *alert,
+                   u_char alert_color,
+                   int destination_pixmap,
+                   map_draw_flags *mdf) {
+
+    GDALDatasetH hDataset;
+    char file[MAX_FILENAME];    // Complete path/name of image
+    GDALDriverH   hDriver;
+    double adfGeoTransform[6];
+//    double map_x_mind, map_x_maxd, map_dxd; // decimal degrees
+//    double map_y_mind, map_y_maxd, map_dyd; // decimal degrees
+    unsigned long map_x_min, map_x_max; // xastir units
+    unsigned long map_y_min, map_y_max; // xastir units
+    long map_dx, map_dy; // xastir units
+    double scr_m_dx, scr_m_dy; // screen pixels per map pixel
+    unsigned long map_s_x_min, map_s_x_max, map_s_x; // map pixels
+//    unsigned long map_s_y_min, map_s_y_max, map_s_y; // map pixels
+    unsigned long scr_s_x_min, scr_s_x_max, scr_s_x; // screen pixels
+//    unsigned long scr_s_y_min, scr_s_y_max, scr_s_y; // screen pixels
+        
+    // 
+    GDALRasterBandH hBand = NULL;
+    int numBand, hBandc;
+    int nBlockXSize, nBlockYSize;
+    //    int bGotMin, bGotMax;
+    //    double adfMinMax[2];
+    //
+    const char *pszProjection;
+    float *pafScanline;
+    int nXSize;
+    unsigned int width,height;
+    GDALColorTableH hColorTable;
+    GDALColorInterp hColorInterp;
+    GDALPaletteInterp hPalInterp;
+    GDALColorEntry colEntry;
+    GDALDataType hType;
+    double dfNoData;
+    int bGotNodata;
+    int i;
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    if ( debug_level & 16 ) 
+        fprintf(stderr,"Calling GDALOpen on file: %s\n", file);
+
+    hDataset = GDALOpenShared( file, GA_ReadOnly );
+
+    if( hDataset == NULL ) {
+        fprintf(stderr,"GDAL couldn't open file: %s\n", file);
+    }
+
+
+    if ( debug_level & 16 ) {
+        hDriver = GDALGetDatasetDriver( hDataset );
+        fprintf( stderr, "Driver: %s/%s\n",
+                 GDALGetDriverShortName( hDriver ),
+                 GDALGetDriverLongName( hDriver ) );
+        
+        fprintf( stderr,"Size is %dx%dx%d\n",
+                 GDALGetRasterXSize( hDataset ), 
+                 GDALGetRasterYSize( hDataset ),
+                 GDALGetRasterCount( hDataset ) );
+    
+        if( GDALGetProjectionRef( hDataset ) != NULL )
+            fprintf( stderr,"Projection is `%s'\n", GDALGetProjectionRef( hDataset ) );
+    
+        if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) {
+                fprintf( stderr,"Origin = (%.6f,%.6f)\n",
+                         adfGeoTransform[0], adfGeoTransform[3] );
+            
+                fprintf( stderr,"Pixel Size = (%.6f,%.6f)\n",
+                         adfGeoTransform[1], adfGeoTransform[5] );
+            }
+    }
+    pszProjection = GDALGetProjectionRef( hDataset );
+    GDALGetGeoTransform( hDataset, adfGeoTransform );    
+    numBand = GDALGetRasterCount( hDataset );
+    width = GDALGetRasterXSize( hDataset );
+    height = GDALGetRasterYSize( hDataset );
+    // will have to delay these calcs until after a proj call
+    map_x_min = 64800000l + (360000.0 * adfGeoTransform[0]);
+    map_x_max = 64800000l + (360000.0 * (adfGeoTransform[0] + adfGeoTransform[1] * width));
+    map_y_min = 32400000l + (360000.0 * (-adfGeoTransform[3] ));
+    map_y_max = 32400000l + (360000.0 * (-adfGeoTransform[3] + adfGeoTransform[5] * height));
+    map_dx = adfGeoTransform[1] * 360000.0;
+    map_dy = adfGeoTransform[5] * 360000.0;
+    scr_m_dx = scale_x / map_dx;
+    scr_m_dy = scale_y / map_dy;
+
+    /*
+     * Here are the corners of our viewport, using the Xastir
+     * coordinate system.  Notice that Y is upside down:
+     *
+     *   left edge of view = NW_corner_longitude
+     *  right edge of view = SE_corner_longitude
+     *    top edge of view =  NW_corner_latitude
+     * bottom edge of view =  SE_corner_latitude
+     *
+     * The corners of our map:
+     *
+     *   left edge of map = map_x_min   in Xastir format
+     *  right edge of map = map_x_max
+     *    top edge of map = map_y_min
+     * bottom edge of map = map_y_max
+     * 
+     * Map scale in xastir units per pixel: map_dx and map_dy
+     * Map scale in screen pixels per map pixel: scr_m_dx and scr_m_dy
+     *
+     * map pixel offsets that are on screen:
+     *   left edge of map = map_s_x_min
+     *  right edge of map = map_s_x_max
+     *    top edge of map = map_s_y_min
+     * bottom edge of map = map_s_y_max
+     * 
+     * screen pixel offsets for map edges:
+     *   left edge of map = scr_s_x_min
+     *  right edge of map = scr_s_x_max
+     *    top edge of map = scr_s_y_min
+     * bottom edge of map = scr_s_y_max
+     * 
+     */
+
+
+// Setting some variables that haven't been set yet.
+map_s_x_min = 0;
+scr_s_x_min = 0;
+
+
+    // calculate map range on screen
+    scr_s_x_max = map_s_x_max = 0ul;
+    for ( map_s_x = 0, scr_s_x = 0; map_s_x_min < width; map_s_x_min++, scr_s_x_min += scr_m_dx) {
+        if ((NW_corner_longitude + (scr_s_x_min * scale_x)) > (map_x_min + (map_s_x_min * map_dx))) 
+            map_s_x_min = map_s_x;
+        
+        
+    }
+
+    for (hBandc = 0; hBandc < numBand; hBandc++) {
+        hBand = GDALGetRasterBand( hDataset, hBandc + 1 );
+        dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata );
+        GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
+        hType = GDALGetRasterDataType(hBand);
+        
+        if ( debug_level & 16 ) {
+            fprintf(stderr, "Band %d (/%d):\n", hBandc, numBand); 
+            fprintf( stderr, " Block=%dx%d Type=%s.\n",
+                     nBlockXSize, nBlockYSize,
+                     GDALGetDataTypeName(hType) );
+            if( GDALGetDescription( hBand ) != NULL 
+                && strlen(GDALGetDescription( hBand )) > 0 )
+                fprintf(stderr, " Description = %s\n", GDALGetDescription(hBand) );
+            if( strlen(GDALGetRasterUnitType(hBand)) > 0 )
+                fprintf(stderr, " Unit Type: %s\n", GDALGetRasterUnitType(hBand) );
+            if( bGotNodata )
+                fprintf(stderr, " NoData Value=%g\n", dfNoData );
+        }
+        // handle colormap stuff
+
+        hColorInterp = GDALGetRasterColorInterpretation ( hBand );
+        if ( debug_level & 16 ) 
+            fprintf ( stderr, " Band's Color is interpreted as %s.\n", 
+                      GDALGetColorInterpretationName (hColorInterp));
+
+        if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex ) {
+
+            hColorTable = GDALGetRasterColorTable( hBand );
+            hPalInterp = GDALGetPaletteInterpretation ( hColorTable );
+
+            if ( debug_level & 16 ) 
+                fprintf( stderr, " Band has a color table (%s) with %d entries.\n", 
+                         GDALGetPaletteInterpretationName( hPalInterp),
+                         GDALGetColorEntryCount( hColorTable ) );
+
+            for( i = 0; i < GDALGetColorEntryCount( hColorTable ); i++ ) {
+                    GDALGetColorEntryAsRGB( hColorTable, i, &colEntry );
+                    fprintf( stderr, "  %3d: %d,%d,%d,%d\n", 
+                             i, 
+                             colEntry.c1,
+                             colEntry.c2,
+                             colEntry.c3,
+                             colEntry.c4 );
+                }
+        } // PaletteIndex
+        
+
+    }
+    //
+
+        if ( numBand == 1) { // single band
+
+        }
+        if ( numBand == 3) { // seperate RGB bands
+        
+        }
+
+
+
+
+    
+    nXSize = GDALGetRasterBandXSize( hBand );
+
+    pafScanline = (float *) malloc(sizeof(float)*nXSize);
+    CHECKMALLOC(pafScanline);
+
+    GDALRasterIO( hBand, GF_Read, 0, 0, nXSize, 1, 
+                  pafScanline, nXSize, 1, GDT_Float32, 
+                  0, 0 );
+
+    /* The raster is */
+
+
+
+
+    // Check for map draw interrupts.  Clean up and exit if found.
+    // Put this also inside the raster-line processing loop so that
+    // it gets check once per raster line.  That makes for fast
+    // zooming/panning even with a lot of maps selected.
+    //
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        return; // Exit early
+    }
+
+
+
+
+    GDALClose(hDataset);
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// Above this point is GDAL code (raster), below is OGR code
+// (vector).
+/////////////////////////////////////////////////////////////////////
+
+
+
+//WE7U
+//
+// Possible Optimizations:
+// -----------------------
+//
+// For Tiger and/or SDTS:  If we can figure out what type of map we
+// have, only load those layers that make sense.  Skip the rest.
+//
+// Only change the drawing style/color if it is different than the
+// last specified one.  Have the drawing routines actually make the
+// X11 calls instead of the "guess" function, in order to eliminate
+// extra calls.
+//
+// Compute the spatial transforms for a layer only if it has a
+// different spatial reference from the last layer.
+//
+// Break the "guess" function into one for files, one for layers,
+// and perhaps one for features.  Call the "features" one sparingly
+// if it exists, so that we can skip that code most of the time.
+//
+// Re-write the "guess" function so that it turns into a general map
+// preferences feature.  Make sure to use hash tables to keep it
+// fast.
+//
+// Tie the Tigermap config buttons into the TIGER/Line layers as
+// well, skip those layers that we don't have selected.  Perhaps tie
+// Tiger/Shapefiles into the same scheme as those have specific
+// filenames we can key off of.
+
+
+
+int label_color_guess;
+int sdts_elevation_in_meters = 1;   // Default meters
+int hypsography_layer = 0;          // Topo contours
+int hydrography_layer = 0;          // Underwater contours
+int water_layer = 0;
+int roads_trails_layer = 0;
+int railroad_layer = 0;
+int misc_transportation_layer = 0;
+
+
+
+// guess_vector_attributes()
+//
+// Feel free to change the name.  At the moment it's somewhat
+// appropriate, but I would hope that in the future it won't be.
+// This should tie in nicely to the dbfawk stuff, and perhaps other
+// schemes for the user to determine drawing attributes.  Basically,
+// if dbfawk is compiled in, go do that instead of doing what this
+// routine does.
+//
+// What we need to do:  Come up with a signature match for the
+// driver type, filename, layer, and sometimes object_type and
+// file_attributes.  Use that to determine drawing width, label
+// size/placement, color, etc.  If the signature could also specify
+// how often the signature needs to be re-examined, that would be a
+// plus.  If it only needs to be set once per file, we could save a
+// lot of time.
+//
+// Note that draw_polygon_with_mask() uses gc_temp instead of gc.
+// This means we have to pass colors down to it so that it can set
+// the color itself.  We currently just use the label_color variable
+// to do this, but we really should use a different variable, as
+// label color and object color can be different.
+//
+// Depending on what needs to be done for different file
+// types/layers/geometries, we might want to break this function up
+// into several, so that we can optimize for speed.  If something
+// only needs to be set once per file, or once per layer, do so.
+// Don't set it over and over again (Don't set it once per object
+// drawn).
+//
+// Consider trying GXxor function with gc_tint someday to see what
+// the contour lines look like with that method:  Should make them
+// quite readable no matter what the underlying map colors.
+//
+// Set attributes based on what sort of file/layer/shape we're
+// dealing with.  driver_type may be any of:
+//
+// "AVCbin"
+// "DGN"
+// "FMEObjects Gateway"
+// "GML"
+// "Memory"
+// "MapInfo File"
+// "UK .NTF"
+// "OCI"
+// "ODBC"
+// "OGDI"
+// "PostgreSQL"
+// "REC"
+// "S57"
+// "SDTS"
+// "ESRI Shapefile"
+// "TIGER"
+// "VRT"
+//
+// Shapefiles:  If Mapshots or ESRI tiger->Shapefiles, guess the
+// coloring and line widths based on the filename and the associated
+// field contents.
+//
+// SDTS:  Guess the coloring/line widths based on the ENTITY_LABEL.
+//
+// TIGER:  Guess coloring/line widths based on the CFCC field.
+//
+// MapInfo:  Guess based on layer?
+//
+// DGN: ??
+//
+//
+void guess_vector_attributes( Widget w,
+                              const char *driver_type,
+                              char *full_filename,
+                              OGRLayerH layerH,
+                              OGRFeatureH featureH,
+                              int geometry_type ) {
+    int ii;
+    const char *pii = NULL;
+
+    label_color_guess = -1; // Default = don't draw the feature
+
+
+//fprintf(stderr,"guess: %s\n", full_filename);
+
+
+    // Default line type
+    (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineSolid, CapButt,JoinMiter);
+
+ 
+/*
+    switch (driver_type) {
+        default:
+            break;
+    }
+
+ 
+    switch (layerH) {
+        case 0:
+        case 1:
+        default:
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+            break;
+    }
+*/
+
+
+
+    // SDTS FILES
+    // ----------
+    // Check the ENTITY_LABEL.  That gives us very detailed info
+    // about the type of feature we're dealing with so that we can
+    // decide how to draw it.
+    //
+    if (strstr(driver_type,"SDTS")) {
+ 
+        ii = OGR_F_GetFieldIndex( featureH, "ENTITY_LABEL");
+        if (ii != -1) {
+            const char *entity_num;
+
+            entity_num = OGR_F_GetFieldAsString( featureH, ii);
+
+//fprintf(stderr,"ENTITY_LABEL: %s\n", entity_num);
+
+            if (strncmp(entity_num,"020",3) == 0) {
+                // Contour lines
+                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0e]);  // yellow
+                label_color_guess = 0x0e;   // yellow
+            }
+            else if (strncmp(entity_num,"050",3) == 0) {
+                // hydrography
+                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0e]);  // yellow
+                label_color_guess = 0x0e;   // yellow
+            }
+            else if (strncmp(entity_num,"070",3) == 0) {
+                // vegetative surface cover
+                label_color_guess = -1;
+                return; // Don't display it
+            }
+            else if (strncmp(entity_num,"080",3) == 0) {
+                // non-vegetative features
+                label_color_guess = -1;
+                return; // Don't display it
+            }
+            else if (strncmp(entity_num,"090",3) == 0) {
+                // boundaries
+                label_color_guess = -1;
+                return; // Don't display it
+            }
+            else if (strncmp(entity_num,"150",3) == 0) {
+                // survey control and markers
+                label_color_guess = -1;
+                return; // Don't display it
+            }
+            else if (strncmp(entity_num,"170",3) == 0) {
+                // roads and trails
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x08]);  // black
+                label_color_guess = 0x08;
+            }
+            else if (strncmp(entity_num,"180",3) == 0) {
+                // railroads
+                (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineOnOffDash, CapButt,JoinMiter);
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x01]);  // purple
+                label_color_guess = 0x01;
+            }
+            else if (strncmp(entity_num,"190",3) == 0) {
+                // pipelines, transmissions lines, misc transportation
+                (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x4d]);  // white
+                label_color_guess = 0x4d;
+            }
+            else if (strncmp(entity_num,"200",3) == 0) {
+                // man-made features
+                label_color_guess = -1;
+                return; // Don't display it
+            }
+            else if (strncmp(entity_num,"300",3) == 0) {
+                // public land survey system
+                label_color_guess = -1;
+                return; // Don't display it
+            }
+        }
+        return;
+    }   // End of SDTS
+ 
+
+
+    // RAW TIGER FILES
+    // ---------------
+    // Attempt to snag the CFCC field.  This tells us what the
+    // feature is and we can get clues from it as to how to draw the
+    // feature.
+    //
+    if (strstr(driver_type,"TIGER")) {
+ 
+        ii = OGR_F_GetFieldIndex(featureH, "CFCC");
+
+        if (ii != -1) {  // Found one of the fields
+
+            pii = OGR_F_GetFieldAsString(featureH, ii);
+
+//fprintf(stderr,"CFCC: %s\n", pii);
+
+            if (!pii)
+                return;
+
+            switch (pii[0]) {
+
+                case 'A':   // Road
+                case 'P':   // Provisional Road
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                    label_color_guess = 0x08;   // black
+                    break;
+
+                case 'B':   // Railroad
+                    (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineOnOffDash, CapButt,JoinMiter);
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x01]);  // purple
+                    label_color_guess = 0x01;   // purple
+                    break;
+
+                case 'C':   // Misc Ground Transportation
+                    (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x4d]);  // white
+                    label_color_guess = 0x4d;   // white
+                    break;
+
+                case 'D':   // Landmark
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                    label_color_guess = 0x08;   // black
+                    break;
+
+                case 'E':   // Physical Feature
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                    label_color_guess = 0x08;   // black
+                    break;
+
+                case 'F':   // Non-visible Feature
+                    label_color_guess = -1;
+                    return; // Don't display it!
+                    break;
+    
+                case 'H':   // Hydrography (water)
+                    water_layer++;
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x1a]);  // Steel Blue
+                    label_color_guess = 0x1a;   // Steel Blue
+                    break;
+
+                case 'X':   // Feature not yet classified
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                    label_color_guess = 0x08;   // black
+                    break;
+
+                default:
+                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                    label_color_guess = 0x08;   // black
+                    break;
+
+            }   // End of switch
+        } // End of if
+
+        return;
+
+    }   // End of TIGER
+ 
+
+
+    // SHAPEFILES
+    // ----------
+    //
+    ii = OGR_F_GetFieldIndex(featureH, "LANDNAME");
+    if (ii != -1) {
+        (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x1a]);  // Steel Blue
+        label_color_guess = 0x1a;
+    }
+
+
+
+    switch (geometry_type) {
+
+
+        case 1:             // Point
+        case 4:             // MultiPoint
+        case 0x80000001:    // Point25D
+        case 0x80000004:    // MultiPoint25D
+
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+            label_color_guess = 0x08;   // black
+ 
+            break;
+
+
+        case 2:             // LineString (polyline)
+        case 5:             // MultiLineString
+        case 0x80000002:    // LineString25D
+        case 0x80000005:    // MultiLineString25D
+
+            if (hypsography_layer || hydrography_layer) {
+
+                // Set color for SDTS hypsography layer (contours)
+//                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x43]);  // gray80
+                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0e]);  // yellow
+//                label_color_guess = 0x4d;   // white
+                label_color_guess = 0x0e;   // yellow
+            }
+            else if (roads_trails_layer) {
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x08]);  // black
+                label_color_guess = 0x08;
+            }
+            else if (railroad_layer) {
+                (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineOnOffDash, CapButt,JoinMiter);
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x01]);  // purple
+                label_color_guess = 0x01;
+            }
+            else if (misc_transportation_layer) {
+                (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x4d]);  // white
+                label_color_guess = 0x4d;
+            }
+            else if (strstr(full_filename,"lkH")) {
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x1a]);  // Steel Blue
+                label_color_guess = 0x1a;
+            }
+            else if (strstr(full_filename,"lkB")) {
+                // Railroad
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x01]);  // purple
+                label_color_guess = 0x01;
+            }
+            else {
+                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                label_color_guess = 0x08;   // black
+            }
+            break;
+
+
+        case 3:             // Polygon
+        case 6:             // MultiPolygon
+        case 0x80000003:    // Polygon25D
+        case 0x80000006:    // MultiPolygon25D
+
+            if (hypsography_layer || hydrography_layer) {
+
+                // Set color for SDTS hypsography layer (contours)
+//                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x43]);  // gray80
+                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0e]);  // yellow
+//                label_color_guess = 0x4d;   // white
+                label_color_guess = 0x0e;   // yellow
+            }
+            else if (roads_trails_layer) {
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x08]);  // black
+                label_color_guess = 0x08;
+            }
+            else if (railroad_layer) {
+                (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineOnOffDash, CapButt,JoinMiter);
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x01]);  // purple
+                label_color_guess = 0x01;
+            }
+            else if (misc_transportation_layer) {
+                (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x4d]);  // white
+                label_color_guess = 0x4d;
+            }
+            else if (strstr(full_filename,"wat")) {
+                (void)XSetForeground(XtDisplay(da), gc, colors[(int)0x1a]);  // Steel Blue
+                label_color_guess = 0x1a;
+            }
+            else {
+                (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]);  // black
+                label_color_guess = 0x08;   // black
+            }
+            break;
+
+
+        case 7:             // GeometryCollection
+        case 0x80000007:    // GeometryCollection25D
+        default:            // Unknown/Unimplemented
+
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0e]);  // yellow
+            label_color_guess = 0x08;   // black
+            break;
+    }
+
+
+//fprintf(stderr,"label_color_guess:%02x\n",label_color_guess);
+
+}
+
+
+
+
+
+void Draw_OGR_Labels( Widget w,
+                      Pixmap pixmap,
+                      OGRFeatureH featureH,
+                      OGRGeometryH geometryH,
+                      XPoint *xpoints,
+                      int num_points,
+                      int color) {
+
+    int ii;
+    const char *pii = NULL;
+    char label[200] = "";
+    float angle = 0.0;  // Angle for the beginning of this polyline
+    int scale_factor = 10;
+
+
+//fprintf(stderr,"Draw_OGR_Labels start\n");
+
+    if (featureH == NULL)
+        return; // Exit early
+
+
+    // Recursively call this routine if we have a lot of points, so
+    // that we draw labels at multiple points along the line.  The
+    // number of points skipped should probably be tied to the zoom
+    // level so that we get an appropriate number of labels at each
+    // scale.  The goal should probably be two or three labels max
+    // per object.
+    //
+    if (num_points > ((scale_factor * scale_y)+1)) {
+        int skip = scale_factor * scale_y;
+
+        Draw_OGR_Labels(w,
+            pixmap,
+            featureH,
+            geometryH,
+            &xpoints[skip],
+            num_points - skip,
+            color);
+    }
+
+
+    if (num_points > 1) {
+        // Compute the label rotation angle
+        float diff_X = (int)xpoints[1].x - xpoints[0].x;
+        float diff_Y = (int)xpoints[1].y - xpoints[0].y;
+
+        if (diff_X == 0.0) {  // Avoid divide by zero errors
+            diff_X = 0.0000001;
+        }
+        if (diff_Y == 0.0) {  // Avoid divide by zero errors
+            diff_Y = 0.0000001;
+        }
+ 
+        angle = atan( diff_X / diff_Y ); // Compute in radians
+
+        // Convert to degrees
+        angle = angle / (2.0 * M_PI );
+        angle = angle * 360.0;
+
+        // Change to fit our rotate label function's idea of angle
+        angle = 360.0 - angle;
+
+        if (angle >= 360.0 || angle <= 0.0)
+            angle = 0.0;
+    }
+
+
+    //fprintf(stderr,"Y: %f\tX:
+    //%f\tAngle: %f ==>
+    //",diff_Y,diff_X,angle);
+
+    if ( angle > 90.0 ) {angle += 180.0;}
+    if ( angle >= 360.0 ) {angle -= 360.0;}
+
+    //fprintf(stderr,"%f\t%s\n",angle,temp);
+
+
+    // Debug code
+    //OGR_F_DumpReadable( featureH, stderr );
+    //OGR_G_DumpReadable(geometryH, stderr, "Shape: ");
+
+    // Snag a few special features, use for labels
+    //
+    ii = OGR_F_GetFieldIndex(featureH, "NAME");
+    if (ii == -1) {
+        ii = OGR_F_GetFieldIndex(featureH, "FENAME");
+    }
+    if (ii == -1) {
+
+        ii = OGR_F_GetFieldIndex(featureH, "ELEVATION");
+
+        if (ii != -1) {  // Found an elevation field
+
+            // Convert to the user's desired units based on the
+            // setting of the "english_units" global variable, which
+            // is set by the Enable English Units toggle.
+            //
+            if (english_units) {    // We desire English Units (feet)
+                if (sdts_elevation_in_meters) {
+                    // Map file is in meters, convert to feet for
+                    // display
+                    xastir_snprintf(label,
+                        sizeof(label),
+                        "%ift",
+                        (int)((OGR_F_GetFieldAsInteger(featureH, ii) * 3.28084) + 0.5));
+                }
+                else {
+                    // Map file is already in feet
+                    xastir_snprintf(label,
+                        sizeof(label),
+                        "%sft",
+                        OGR_F_GetFieldAsString(featureH, ii));
+                }
+            }
+            else {  // We desire metric Units (meters)
+                if (!sdts_elevation_in_meters) {
+                    // Map file is in feet, convert to meters for
+                    // display
+                    xastir_snprintf(label,
+                        sizeof(label),
+                        "%im",
+                        (int)((OGR_F_GetFieldAsInteger(featureH, ii) * 0.3048) + 0.5));
+                }
+                else {
+                    // Map file is already in meters
+                    xastir_snprintf(label,
+                        sizeof(label),
+                        "%sm",
+                        OGR_F_GetFieldAsString(featureH, ii));
+                }
+            }
+
+            // Test for empty value
+            if (label[0] == 'f' || label[0] == 'm')
+                return;
+
+//fprintf(stderr,"Elevation label: %s, angle: %2.1f\n", label, angle);
+        }
+    }
+
+
+    // Check whether we found a field and if we haven't already
+    // created a label.  If so, snag the field.
+    if (ii != -1 && label[0] == '\0') {
+        pii = OGR_F_GetFieldAsString(featureH, ii);
+
+        if (pii && pii[0] != '\0') {
+            xastir_snprintf(label,
+                sizeof(label),
+                "%s",
+                pii);
+        }
+    }
+
+
+    // Draw at least one label.  In the future we can pick and
+    // choose among the points passed to us and draw the quantity of
+    // labels that are appropriate for the zoom level.  Whether to
+    // draw labels for more minor objects as we zoom out is another
+    // problem that must be solved.
+    //
+    // Here "label" will always evaluate as true:  It's an address!
+    //if (label && map_labels /* && !skip_label */ ) {
+    if (map_labels /* && !skip_label */ ) {
+
+        // Check that we're not trying to draw the label out of
+        // bounds for the X11 calls.
+        //
+        if (       xpoints[0].x+10 <  screen_width
+                && xpoints[0].x+10 > 0
+                && xpoints[0].y+5  <  screen_height
+                && xpoints[0].y+5  > 0) {
+
+/*
+            if (angle == 0.0) {   // Non-rotated label
+
+                draw_rotated_label_text (w,
+                    -90.0,
+                    xpoints[0].x+10,
+                    xpoints[0].y+5,
+                    strlen(label),
+                    colors[color],
+                    label,
+                    FONT_DEFAULT);
+            }
+
+            else {  // Rotated label
+*/
+                draw_rotated_label_text (w,
+                    angle,
+                    xpoints[0].x+10,
+                    xpoints[0].y+5,
+                    strlen(label),
+                    colors[color],
+                    label,
+                    FONT_DEFAULT);
+//            }
+        }
+    }
+
+//fprintf(stderr,"Draw_OGR_Labels end\n");
+
+}
+
+
+
+
+
+// Draw_OGR_Points().
+//
+// A function which can be recursively called.  Tracks the recursion
+// depth so that we can recover if we exceed the maximum.  If we
+// keep finding geometries below us, keep calling the same function.
+// Simple and efficient.
+//
+// Really the important thing here is not to draw a tiny dot on the
+// screen, but to draw a symbol and/or a label at that point on the
+// screen.  We'll need more code to handle that stuff though, to
+// determine which field in the file to use as a label and the
+// font/color/placement/size/etc.
+// 
+void Draw_OGR_Points( Widget w,
+                      OGRFeatureH featureH,
+                      OGRGeometryH geometryH,
+                      int level,
+                      OGRCoordinateTransformationH transformH) {
+ 
+    int kk;
+    int object_num = 0;
+    int num_points;
+    int ii;
+    int skip_duplicates = 0;
+
+
+//fprintf(stderr, "Draw_OGR_Points\n");
+
+    if (geometryH == NULL)
+        return; // Exit early
+
+    // Check for more objects below this one, recursing into any
+    // objects found.  "level" keeps us from recursing too far (we
+    // don't want infinite recursion here).
+    // 
+    object_num = OGR_G_GetGeometryCount(geometryH);
+    // Iterate through the objects found.  If another geometry is
+    // detected, call this function again recursively.  That will
+    // cause all of the lower objects to get drawn.
+    //
+    if (object_num) {
+
+        //fprintf(stderr, "DrawPoints: Found %d geometries\n", object_num);
+ 
+        for ( kk = 0; kk < object_num; kk++ ) {
+            OGRGeometryH child_geometryH;
+            int sub_object_num;
+
+
+            // See if we have geometries below this one.
+            child_geometryH = OGR_G_GetGeometryRef(geometryH, kk);
+
+            sub_object_num = OGR_G_GetGeometryCount(child_geometryH);
+
+            if (sub_object_num) {
+                // We found geometries below this.  Recurse.
+                if (level < 5) {
+                    //fprintf(stderr, "DrawPoints: Recursing level %d\n", level);
+                    Draw_OGR_Points(w,
+                        featureH,
+                        child_geometryH,
+                        level+1,
+                        transformH);
+                }
+            }
+        }
+        return;
+    }
+
+
+    // Draw
+
+    // Get number of elements (points)
+    num_points = OGR_G_GetPointCount(geometryH);
+    //fprintf(stderr,"  Number of elements: %d\n",num_points);
+
+    // Draw the points
+    for ( ii = 0; ii < num_points; ii++ ) {
+        double X1, Y1, Z1;
+        XPoint xpoint;
+
+
+        // Get the point!
+        OGR_G_GetPoint(geometryH,
+            ii,
+            &X1,
+            &Y1,
+            &Z1);
+
+        if (transformH) {
+            // Convert to WGS84 coordinates.
+            if (!OCTTransform(transformH, 1, &X1, &Y1, &Z1)) {
+                fprintf(stderr,
+                    "Couldn't convert point to WGS84\n");
+                // Draw it anyway.  It _might_ be in WGS84 or
+                // NAD83!
+            }
+        }
+
+
+        // Skip the map_visible_lat_lon() check:
+        // draw_point_ll() does the check for us.
+        //
+        draw_point_ll(da,
+            (float)Y1,
+            (float)X1,
+            gc,
+            pixmap,
+            skip_duplicates);
+
+        skip_duplicates = 1;
+
+// We could use a flag back from draw_point_ll() that tells us
+// whether the point was within the view.  That way we know whether
+// or not to draw the label.
+
+        xpoint.x = (short)X1;
+        xpoint.y = (short)Y1;
+
+/*
+        // Draw the corresponding label
+        Draw_OGR_Labels(w,
+            pixmap,
+            featureH,
+            geometryH,
+            &xpoint,
+            1,   // Number of points
+            label_color_guess);
+*/
+    }
+}
+
+ 
+
+
+
+// Draw_OGR_Lines().
+//
+// A function which can be recursively called.  Tracks the recursion
+// depth so that we can recover if we exceed the maximum.  If we
+// keep finding geometries below us, keep calling the same function.
+// Simple and efficient.
+//
+// In the case of !fast_extents, it might be faster to convert the
+// entire object to Xastir coordinates, then check whether it is
+// visible.  That would elimate two conversions in the case that the
+// object gets drawn.  For the fast_extents case, we're just
+// snagging the extents instead of the entire object, so we might
+// just leave it as-is.
+//
+void Draw_OGR_Lines( Widget w,
+                     OGRFeatureH featureH,
+                     OGRGeometryH geometryH,
+                     int level,
+                     OGRCoordinateTransformationH transformH,
+                     int fast_extents) {
+ 
+    int kk;
+    int object_num = 0;
+    int num_points;
+    OGREnvelope envelopeH;
+
+
+//fprintf(stderr, "Draw_OGR_Lines\n");
+
+    if (geometryH == NULL)
+        return; // Exit early
+
+    // Check for more objects below this one, recursing into any
+    // objects found.  "level" keeps us from recursing too far (we
+    // don't want infinite recursion here).
+    // 
+    object_num = OGR_G_GetGeometryCount(geometryH);
+
+    // Iterate through the objects found.  If another geometry is
+    // detected, call this function again recursively.  That will
+    // cause all of the lower objects to get drawn.
+    //
+    if (object_num) {
+
+        //fprintf(stderr, "DrawLines: Found %d geometries\n", object_num);
+ 
+        for ( kk = 0; kk < object_num; kk++ ) {
+            OGRGeometryH child_geometryH;
+            int sub_object_num;
+
+
+            // Check for more geometries below this one.
+            child_geometryH = OGR_G_GetGeometryRef(geometryH, kk);
+
+            sub_object_num = OGR_G_GetGeometryCount(child_geometryH);
+
+            if (sub_object_num) {
+                // We found geometries below this.  Recurse.
+                if (level < 5) {
+                    //fprintf(stderr, "DrawLines: Recursing level %d\n", level);
+                    Draw_OGR_Lines(w,
+                        featureH,
+                        child_geometryH,
+                        level+1,
+                        transformH,
+                        fast_extents);
+                }
+            }
+        }
+        return;
+    }
+
+
+    // Draw it.  Standard linestring files return 0 for object_num.
+    // Multilinestring must return more, so we recurse?
+    // Yet to be tested!
+
+
+    // If we have fast_extents available, take advantage of it to
+    // escape this routine as quickly as possible, should the object
+    // not be within our view.
+    //
+    if (fast_extents) {
+
+        // Get the extents for this Polyline
+        OGR_G_GetEnvelope(geometryH, &envelopeH);
+
+        // Convert the extents to WGS84/Geographic coordinate system
+        if (transformH) {
+//fprintf(stderr,"Converting to WGS84\n");
+            // Convert to WGS84 coordinates.
+            if (!OCTTransform(transformH, 2, &envelopeH.MinX, &envelopeH.MinY, NULL)) {
+                fprintf(stderr,
+                    "Couldn't convert point to WGS84\n");
+            }
+        }
+
+/*
+fprintf(stderr,"MinY:%f, MaxY:%f, MinX:%f, MaxX:%f\n",
+    envelopeH.MinY,
+    envelopeH.MaxY,
+    envelopeH.MinX,
+    envelopeH.MaxX);
+*/
+
+        if (map_visible_lat_lon( envelopeH.MinY,    // bottom
+                envelopeH.MaxY,     // top
+                envelopeH.MinX,     // left
+                envelopeH.MaxX) ) { // right
+//fprintf(stderr, "Fast Extents: Line is visible\n");
+        }
+        else {
+//fprintf(stderr, "Fast Extents: Line is NOT visible\n");
+            return; // Exit early
+        }
+
+        // If we made it this far with an object with
+        // fast_extents , the feature is within our view.
+    }
+
+    else { // Fast extents are not available.  Compute the
+           // extents ourselves once we have all the points,
+           // then check whether this object is within our
+           // view.
+    }
+
+
+    num_points = OGR_G_GetPointCount(geometryH);
+//fprintf(stderr,"  Number of elements: %d\n",num_points);
+
+
+    // Draw the polyline
+    //
+    if (num_points > 0) {
+        int ii;
+        double *vectorX;
+        double *vectorY;
+        double *vectorZ;
+        unsigned long *XL = NULL;
+        unsigned long *YL = NULL;
+        long *XI = NULL;
+        long *YI = NULL;
+        XPoint *xpoints = NULL;
+
+
+        // Get some memory to hold the vectors
+        vectorX = (double *)malloc(sizeof(double) * num_points);
+        vectorY = (double *)malloc(sizeof(double) * num_points);
+        vectorZ = (double *)malloc(sizeof(double) * num_points);
+        CHECKMALLOC(vectorX);
+        CHECKMALLOC(vectorY);
+        CHECKMALLOC(vectorZ);
+
+        // Get the points, fill in the vectors
+        for ( ii = 0; ii < num_points; ii++ ) {
+
+            OGR_G_GetPoint(geometryH,
+                ii,
+                &vectorX[ii],
+                &vectorY[ii],
+                &vectorZ[ii]);
+        }
+
+        if (transformH) {
+//fprintf(stderr,"Converting to WGS84\n");
+            // Convert all vectors to WGS84 coordinates.
+            if (!OCTTransform(transformH, num_points, vectorX, vectorY, vectorZ)) {
+                fprintf(stderr,
+                    "Couldn't convert vectors to WGS84\n");
+            }
+        }
+        else {
+//fprintf(stderr,"No transform available\n");
+        }
+
+        // For the non-fast_extents case, we need to compute the
+        // extents and check whether this object is within our
+        // view.
+        //
+
+// WE7U
+// Replace with draw_vector_ll() and we won't have to compute
+// extents here.
+
+        if (!fast_extents) {
+            double MinX, MaxX, MinY, MaxY;
+
+            MinX = vectorX[0];
+            MaxX = vectorX[0];
+            MinY = vectorY[0];
+            MaxY = vectorY[0];
+
+            for ( ii = 1; ii < num_points; ii++ ) {
+                if (vectorX[ii] < MinX) MinX = vectorX[ii];
+                if (vectorX[ii] > MaxX) MaxX = vectorX[ii];
+                if (vectorY[ii] < MinY) MinY = vectorY[ii];
+                if (vectorY[ii] > MaxY) MaxY = vectorY[ii];
+            }
+
+/*
+fprintf(stderr,"MinY:%f, MaxY:%f, MinX:%f, MaxX:%f\n",
+    MinY,
+    MaxY,
+    MinX,
+    MaxX);
+*/
+
+            // We have the extents now in geographic/WGS84
+            // datum.  Check for visibility.
+            //
+            if (map_visible_lat_lon( MinY,    // bottom
+                    MaxY, // top
+                    MinX, // left
+                    MaxX) ) { // right
+//fprintf(stderr, "Line is visible\n");
+            }
+            else {
+
+//fprintf(stderr, "Line is NOT visible\n");
+
+                // Free the allocated vector memory
+                if (vectorX)
+                    free(vectorX);
+                if (vectorY)
+                    free(vectorY);
+                if (vectorZ)
+                    free(vectorZ);
+
+                return; // Exit early
+            }
+        }
+
+        // If we've gotten to this point, part or all of the
+        // object is within our view so at least some drawing
+        // should occur.
+
+
+// WE7U
+// This next section should be replaced with calls to draw_vector_ll()
+// instead of converting to Xastir coordinates, then screen
+// coordinates and truncating the lines.  draw_vector_ll() uses
+// proper line-clipping so that the slope of the lines don't
+// change.
+//
+// Draw_OGR_Labels() would need to be changed also so that it
+// doesn't use screen coordinates or perhaps leave the screen
+// coordinate calc's in if it's too difficult or would slow things
+// down too much.
+//
+// Another option is to use maps.c:clip2d_screen() to eliminate
+// and/or clip lines based on screen coordinates.
+//
+// If we clip lines in the arrays then the Draw_OGR_Labels()
+// function will have less work to do as it'll only be working
+// against visible points.  An excellent speedup.
+//
+// Make sure we don't end up drawing a polyline/polygon along the
+// screen edges due to clipping a larger polygon.  Each vector needs
+// to be treated separately:  If one endpoint is the same for two
+// vectors in the array and we do clipping, we'll have problems.
+
+
+        XL = (unsigned long *)malloc(sizeof(unsigned long) * num_points);
+        YL = (unsigned long *)malloc(sizeof(unsigned long) * num_points);
+        CHECKMALLOC(XL);
+        CHECKMALLOC(YL);
+
+        // Convert arrays to the Xastir coordinate system
+        for (ii = 0; ii < num_points; ii++) {
+            convert_to_xastir_coordinates(&XL[ii],
+                &YL[ii],
+                vectorX[ii],
+                vectorY[ii]);
+        }
+
+        // Free the allocated vector memory
+        if (vectorX)
+            free(vectorX);
+        if (vectorY)
+            free(vectorY);
+        if (vectorZ)
+            free(vectorZ);
+
+        XI = (long *)malloc(sizeof(long) * num_points);
+        YI = (long *)malloc(sizeof(long) * num_points);
+        CHECKMALLOC(XI);
+        CHECKMALLOC(YI);
+
+        // Convert arrays to screen coordinates.  Careful here!
+        // The format conversions you'll need if you try to
+        // compress this into two lines will get you into
+        // trouble.
+        //
+        // We also clip to screen size and compute min/max
+        // values here.
+        for (ii = 0; ii < num_points; ii++) {
+            XI[ii] = XL[ii] - NW_corner_longitude;
+            XI[ii] = XI[ii] / scale_x;
+
+            YI[ii] = YL[ii] - NW_corner_latitude;
+            YI[ii] = YI[ii] / scale_y;
+
+// Here we truncate:  We should polygon clip instead, so that the
+// slopes of the line segments don't change.  Points beyond +/-
+// 32767 can cause problems in X11 when we draw.
+            XI[ii] = l16(XI[ii]);
+            YI[ii] = l16(YI[ii]);
+        }
+
+        // We don't need the Xastir coordinate system arrays
+        // anymore.  We've already converted to screen
+        // coordinates.
+        if (XL)
+            free(XL);
+        if (YL)
+            free(YL);
+
+        // Set up the XPoint array.
+        xpoints = (XPoint *)malloc(sizeof(XPoint) * num_points);
+        CHECKMALLOC(xpoints);
+
+        // Load up our xpoints array
+        for (ii = 0; ii < num_points; ii++) {
+            xpoints[ii].x = l16(XI[ii]);
+            xpoints[ii].y = l16(YI[ii]);
+        }
+
+        // Free the screen coordinate arrays.
+        if (XI)
+            free(XI);
+        if (YI)
+            free(YI);
+
+
+        // Actually draw the lines
+        (void)XDrawLines(XtDisplay(da),
+            pixmap,
+            gc,
+            xpoints,
+            l16(num_points),
+            CoordModeOrigin);
+
+        // Draw the corresponding labels
+        Draw_OGR_Labels(w,
+            pixmap,
+            featureH,
+            geometryH,
+            xpoints,
+            num_points,
+            label_color_guess);
+
+        if (xpoints)
+            free(xpoints);
+
+    }
+}
+
+
+
+
+
+// create_clip_mask()
+//
+// Create a rectangular X11 Region.  It should be the size of the
+// extents for the outer polygon.
+//
+Region create_clip_mask( int num,
+                         int minX,
+                         int minY,
+                         int maxX,
+                         int maxY) {
+
+    XRectangle rectangle;
+    Region region;
+
+
+//fprintf(stderr,"create_clip_mask: num=%i ", num);
+
+    rectangle.x      = (short) minX;
+    rectangle.y      = (short) minY;
+    rectangle.width  = (unsigned short)(maxX - minX + 1);
+    rectangle.height = (unsigned short)(maxY - minY + 1);
+
+    // Create an empty region
+    region = XCreateRegion();
+
+/*
+    fprintf(stderr,"Create: x:%d y:%d x:%d y:%d\n",
+        minX,
+        minY,
+        maxX,
+        maxY);
+
+    fprintf(stderr,"Create: x:%d y:%d w:%d h:%d\n",
+        rectangle.x,
+        rectangle.y,
+        rectangle.width,
+        rectangle.height);
+*/
+
+    // Create a region containing a filled rectangle
+    XUnionRectWithRegion(&rectangle,
+        region,
+        region);
+
+//fprintf(stderr,"Done\n");
+
+    return(region);
+}
+
+
+ 
+
+
+// create_hole_in_mask()
+//
+// Create a hole in an X11 Region, using a polygon as input.  X11
+// Region must have been created with "create_clip_mask()" before
+// this function is called.
+//
+Region create_hole_in_mask( Region mask,
+                            int num,
+                            long *X,
+                            long *Y) {
+
+    Region region2 = NULL;
+    Region region3 = NULL;
+    XPoint *xpoints = NULL;
+    int ii;
+
+
+//fprintf(stderr,"create_hole_in_mask: num=%i ", num);
+
+    if (num < 3) {  // Not enough for a polygon
+        fprintf(stderr,
+            "create_hole_in_mask:XPolygonRegion w/too few vertices: %d\n",
+            num);
+        return(mask);    // Net result = no change to Region
+    }
+
+    // Get memory to hold the points
+    xpoints = (XPoint *)malloc(sizeof(XPoint) * num);
+    CHECKMALLOC(xpoints);
+
+    // Load up our xpoints array
+    for (ii = 0; ii < num; ii++) {
+        xpoints[ii].x = (short)X[ii];
+        xpoints[ii].y = (short)Y[ii];
+    }
+
+    // Create empty regions
+    region2 = XCreateRegion();
+    region3 = XCreateRegion();
+
+    // Draw the "hole" polygon
+    region2 = XPolygonRegion(xpoints,
+        num,
+        WindingRule);
+
+    // Free the allocated memory
+    if (xpoints)
+        free(xpoints);
+
+    XSubtractRegion(mask, region2, region3);
+
+    // Get rid of the two regions we no longer need.
+    XDestroyRegion(mask);
+    XDestroyRegion(region2);
+
+//fprintf(stderr,"Done\n");
+
+    // Return our new region that has another hole in it.
+    return(region3);
+}
+
+
+
+
+
+// draw_polygon_with_mask()
+//
+// Draws a polygon onto a pixmap using an X11 Region to mask areas
+// that shouldn't be drawn over (holes).  X11 Region is created with
+// the "create_clip_mask()" function, holes in it are created with
+// the "create_hole_in_mask()" function.  The polygon used to create
+// the initial X11 Region was saved away during the creation.  Now
+// we just draw it to the pixmap using the X11 Region as a mask.
+//
+void draw_polygon_with_mask( Region mask,
+                             XPoint *xpoints,
+                             int num_points) {
+
+    GC gc_temp = NULL;
+    XGCValues gc_temp_values;
+
+
+//    fprintf(stderr,"draw_polygon_with_mask: ");
+
+    // There were "hole" polygons, so by now we've created a "holey"
+    // region.  Draw a filled polygon with gc_temp here and then get
+    // rid of gc_temp and the regions.
+
+    gc_temp = XCreateGC(XtDisplay(da),
+        XtWindow(da),
+        0,
+        &gc_temp_values);
+
+
+    // Set the clip-mask into the GC.  This GC is now ruined for
+    // other purposes, so destroy it when we're done drawing this
+    // one shape.
+    if (mask != NULL)
+        XSetRegion(XtDisplay(da), gc_temp, mask);
+
+    (void)XSetForeground(XtDisplay(da),
+        gc_temp,
+        colors[(int)label_color_guess]);
+
+    // Actually draw the filled polygon
+    (void)XFillPolygon(XtDisplay(da),
+        pixmap,
+        gc_temp,
+        xpoints,
+        num_points,
+        Nonconvex,
+        CoordModeOrigin);
+
+    if (mask != NULL)
+        XDestroyRegion(mask);
+
+    if (gc_temp != NULL)
+        XFreeGC(XtDisplay(da), gc_temp);
+
+//    fprintf(stderr,"Done!\n");
+}
+
+
+
+
+
+// Draw_OGR_Polygons().
+//
+// A function which can be recursively called.  Tracks the recursion
+// depth so that we can recover if we exceed the maximum.  If we
+// keep finding geometries below us, keep calling the same function.
+// Simple and efficient.
+// 
+// This can get complicated for Shapefiles:  Polygons are composed
+// of multiple rings.  If a ring goes in one direction, it's a fill
+// polygon, if the other direction, it's a hole polygon.
+//
+// Can test the operation using Shapefiles for Island County, WA,
+// Camano Island, where there's an Island in Puget Sound that has a
+// lake with an island in it (48.15569N/122.48953W)!
+//
+// At 48.43867N/122.61687W there's another lake with an island in
+// it, but this lake isn't on an island like the first example.
+//
+// A note from Frank Warmerdam (GDAL guy):
+//
+// "An OGRPolygon objects consists of one outer ring and zero or
+// more inner rings.  The inner rings are holes.  The C API kind of
+// hides this fact, but you should be able to assume that the first
+// ring is an outer ring, and any other rings are inner rings
+// (holes).  Note that in the simple features geometry model you
+// can't make any assumptions about the winding direction of holes
+// or outer rings.
+//
+// Some polygons when read from Shapefiles will be returned as
+// OGRMultiPolygon.  These are basically areas that have multiple
+// outer rings.  For instance, if you had one feature that was a
+// chain of islands.  In the past (and likely even now with some
+// format drivers) these were just returned as polygons with the
+// outer and inner rings all mixed up.  But the development code
+// includes fixes (for shapefiles at least) to fix this up and
+// convert into a multi polygon so you can properly establish what
+// are outer rings, and what are inner rings (holes)."
+//
+// In the case of !fast_extents, it might be faster to convert the
+// entire object to Xastir coordinates, then check whether it is
+// visible.  That would elimate two conversions in the case that the
+// object gets drawn.  For the fast_extents case, we're just
+// snagging the extents instead of the entire object, so we might
+// just leave it as-is.
+//
+void Draw_OGR_Polygons( Widget w,
+                        OGRFeatureH featureH,
+                        OGRGeometryH geometryH,
+                        int level,
+                        OGRCoordinateTransformationH transformH,
+                        int draw_filled,
+                        int fast_extents) {
+ 
+    int kk;
+    int object_num = 0;
+    Region mask = NULL;
+    XPoint *xpoints = NULL;
+    int num_outer_points = 0;
+
+
+//fprintf(stderr,"Draw_OGR_Polygons\n");
+
+    if (geometryH == NULL)
+        return; // Exit early
+
+    // Check for more objects below this one, recursing into any
+    // objects found.  "level" keeps us from recursing too far (we
+    // don't want infinite recursion here).  These objects may be
+    // rings or they may be other polygons in a collection.
+    // 
+    object_num = OGR_G_GetGeometryCount(geometryH);
+
+    // Iterate through the objects found.  If another geometry is
+    // detected, call this function again recursively.  That will
+    // cause all of the lower objects to get drawn.
+    //
+    for ( kk = 0; kk < object_num; kk++ ) {
+        OGRGeometryH child_geometryH;
+        int sub_object_num;
+
+
+        // This may be a ring, or another object with rings.
+        child_geometryH = OGR_G_GetGeometryRef(geometryH, kk);
+
+        sub_object_num = OGR_G_GetGeometryCount(child_geometryH);
+
+        if (sub_object_num) {
+            // We found geometries below this.  Recurse.
+            if (level < 5) {
+
+                // If we got here, we're dealing with a multipolygon
+                // file.  There are multiple sets of polygon
+                // objects, each may have inner (hole) and outer
+                // (fill) rings.  If (level > 0), it's a
+                // multipolygon layer.
+
+//fprintf(stderr, "DrawPolygons: Recursing level %d\n", level);
+
+                Draw_OGR_Polygons(w,
+                    featureH,
+                    child_geometryH,
+                    level+1,
+                    transformH,
+                    draw_filled,
+                    fast_extents);
+            }
+        }
+
+        else {  // Draw
+            int polygon_points;
+            OGREnvelope envelopeH;
+            int polygon_hole = 0;
+            int single_polygon = 0;
+
+
+            // if (kk==0) we're dealing with an outer (fill) ring.
+            // If (kk>0) we're dealing with an inner (hole) ring.
+            if (kk == 0 || object_num == 1) {
+                if (object_num == 1) {
+//fprintf(stderr,"Polygon->Fill\n");
+                    single_polygon++;
+                }
+                else {
+//fprintf(stderr,"Polygon->Fill w/holes\n");
+                }
+                
+            }
+            else if (object_num > 1) {
+//fprintf(stderr,"Polygon->Hole\n");
+                polygon_hole++;
+            }
+
+            if (fast_extents) {
+
+                // Get the extents for this Polygon
+                OGR_G_GetEnvelope(geometryH, &envelopeH);
+
+                // Convert them to WGS84/Geographic coordinate system
+                if (transformH) {
+                    // Convert to WGS84 coordinates.
+                    if (!OCTTransform(transformH, 2, &envelopeH.MinX, &envelopeH.MinY, NULL)) {
+                        fprintf(stderr,
+                            "Couldn't convert to WGS84\n");
+                    }
+                }
+
+                if (map_visible_lat_lon( envelopeH.MinY,    // bottom
+                        envelopeH.MaxY, // top
+                        envelopeH.MinX, // left
+                        envelopeH.MaxX) ) { // right
+                    //fprintf(stderr, "Fast Extents: Polygon is visible\n");
+                }
+                else {
+                    //fprintf(stderr, "Fast Extents: Polygon is NOT visible\n");
+                    return; // Exit early
+                }
+
+                // If we made it this far, the feature is within our
+                // view (if it has fast_extents).
+            }
+            else {
+                // Fast extents not available.  We'll need to
+                // compute our own extents below.
+            }
+
+            polygon_points = OGR_G_GetPointCount(child_geometryH);
+//fprintf(stderr, "Vertices: %d\n", polygon_points);
+
+            if (polygon_points > 3) { // Not a polygon if < 3 points
+                int mm;
+                double *vectorX;
+                double *vectorY;
+                double *vectorZ;
+
+
+                // Get some memory to hold the polygon vectors
+                vectorX = (double *)malloc(sizeof(double) * polygon_points);
+                vectorY = (double *)malloc(sizeof(double) * polygon_points);
+                vectorZ = (double *)malloc(sizeof(double) * polygon_points);
+                CHECKMALLOC(vectorX);
+                CHECKMALLOC(vectorY);
+                CHECKMALLOC(vectorZ);
+
+                // Get the points, fill in the vectors
+                for ( mm = 0; mm < polygon_points; mm++ ) {
+
+                    OGR_G_GetPoint(child_geometryH,
+                        mm,
+                        &vectorX[mm],
+                        &vectorY[mm],
+                        &vectorZ[mm]);
+                }
+
+ 
+                if (transformH) {
+                    // Convert entire polygon to WGS84 coordinates.
+                    if (!OCTTransform(transformH, polygon_points, vectorX, vectorY, vectorZ)) {
+//                        fprintf(stderr,
+//                            "Couldn't convert polygon to WGS84\n");
+//return;
+                    }
+                }
+
+ 
+                // For the non-fast_extents case, we need to compute
+                // the extents and check whether this object is
+                // within our view.
+                //
+                if (!fast_extents) {
+                    double MinX, MaxX, MinY, MaxY;
+
+                    MinX = vectorX[0];
+                    MaxX = vectorX[0];
+                    MinY = vectorY[0];
+                    MaxY = vectorY[0];
+
+                    for ( mm = 1; mm < polygon_points; mm++ ) {
+                        if (vectorX[mm] < MinX) MinX = vectorX[mm];
+                        if (vectorX[mm] > MaxX) MaxX = vectorX[mm];
+                        if (vectorY[mm] < MinY) MinY = vectorY[mm];
+                        if (vectorY[mm] > MaxY) MaxY = vectorY[mm];
+                    }
+
+                    // We have the extents now in geographic/WGS84
+                    // datum.  Check for visibility.
+                    //
+                    if (map_visible_lat_lon( MinY,    // bottom
+                            MaxY, // top
+                            MinX, // left
+                            MaxX) ) { // right
+//fprintf(stderr, "Polygon is visible\n");
+                    }
+                    else {
+
+//fprintf(stderr, "Polygon is NOT visible\n");
+
+                        // Free the allocated vector memory
+                        if (vectorX)
+                            free(vectorX);
+                        if (vectorY)
+                            free(vectorY);
+                        if (vectorZ)
+                            free(vectorZ);
+
+                        //return; // Exit early
+                        continue;   // Next ieration of the loop
+                    }
+                }
+
+
+                // If draw_filled != 0, draw the polygon using X11
+                // polygon calls instead of just drawing the border.
+                //
+                if (draw_filled) { // Draw a filled polygon
+                    unsigned long *XL = NULL;
+                    unsigned long *YL = NULL;
+                    long *XI = NULL;
+                    long *YI = NULL;
+                    int nn;
+                    int minX, maxX, minY, maxY;
+
+
+                    XL = (unsigned long *)malloc(sizeof(unsigned long) * polygon_points);
+                    YL = (unsigned long *)malloc(sizeof(unsigned long) * polygon_points);
+                    CHECKMALLOC(XL);
+                    CHECKMALLOC(YL);
+ 
+                    // Convert arrays to the Xastir coordinate
+                    // system
+                    for (nn = 0; nn < polygon_points; nn++) {
+                        convert_to_xastir_coordinates(&XL[nn],
+                            &YL[nn],
+                            vectorX[nn],
+                            vectorY[nn]);
+                    }
+
+
+                    XI = (long *)malloc(sizeof(long) * polygon_points);
+                    YI = (long *)malloc(sizeof(long) * polygon_points);
+                    CHECKMALLOC(XI);
+                    CHECKMALLOC(YI);
+ 
+// Note:  We're limiting screen size to 32767 in this routine.
+                    minX = -32768;
+                    maxX =  32767;
+                    minY = -32768;
+                    maxY =  32767;
+ 
+
+                    // Convert arrays to screen coordinates.
+                    // Careful here!  The format conversions you'll
+                    // need if you try to compress this into two
+                    // lines will get you into trouble.
+                    //
+                    // We also clip to screen size and compute
+                    // min/max values here.
+                    for (nn = 0; nn < polygon_points; nn++) {
+                        XI[nn] = XL[nn] - NW_corner_longitude;
+                        XI[nn] = XI[nn] / scale_x;
+
+                        YI[nn] = YL[nn] - NW_corner_latitude;
+                        YI[nn] = YI[nn] / scale_y;
+ 
+// Here we truncate:  We should polygon clip instead, so that the
+// slopes of the line segments don't change.  Points beyond +/-
+// 32767 can cause problems in X11 when we draw.  Here we are more
+// interested in keeping the rectangles small and fast.  Screen-size
+// or smaller basically.
+                        XI[nn] = l16(XI[nn]);
+                        YI[nn] = l16(YI[nn]);
+
+                        if (!polygon_hole) {
+
+                            // Find the min/max extents for the
+                            // arrays.  We use that to set the size
+                            // of our mask region.
+                            if (XI[nn] < minX) minX = XI[nn];
+                            if (XI[nn] > maxX) maxX = XI[nn];
+                            if (YI[nn] < minY) minY = YI[nn];
+                            if (YI[nn] > maxY) maxY = YI[nn];
+                        }
+                    }
+
+
+                    // We don't need the Xastir coordinate system
+                    // arrays anymore.  We've already converted to
+                    // screen coordinates.
+                    if (XL)
+                        free(XL);
+                    if (YL)
+                        free(YL);
+
+                    if (!polygon_hole) {    // Outer ring (fill)
+                        int pp;
+
+                        // Set up the XPoint array that we'll need
+                        // for our final draw (after the "holey"
+                        // region is set up if we have multiple
+                        // rings).
+                        xpoints = (XPoint *)malloc(sizeof(XPoint) * polygon_points);
+                        CHECKMALLOC(xpoints);
+
+                        // Load up our xpoints array
+                        for (pp = 0; pp < polygon_points; pp++) {
+                            xpoints[pp].x = (short)XI[pp];
+                            xpoints[pp].y = (short)YI[pp];
+                        }
+                        num_outer_points = polygon_points;
+                    }
+
+
+                    // If we have no inner polygons, skip the whole
+                    // X11 Region thing and just draw a filled
+                    // polygon to the pixmap for speed.  We do that
+                    // here via the "single_polygon" variable.
+                    //
+                    if (!polygon_hole) {   // Outer ring (fill)
+
+                        if (single_polygon) {
+                            mask = NULL;
+                        }
+                        else {
+                            // Pass the extents of the polygon to
+                            // create a mask rectangle out of them.
+                            mask = create_clip_mask(polygon_points,
+                                minX,
+                                minY,
+                                maxX,
+                                maxY);
+                        }
+                    }
+                    else {  // Inner ring (hole)
+
+                        // Pass the entire "hole" polygon set of
+                        // vertices into the hole region creation
+                        // function.  This knocks a hole in our mask
+                        // so that underlying map layers can show
+                        // through.
+
+                        // This segfaults for TIGER polygons without
+                        // the if(mask) part.
+                        //
+                        if (mask) { // create_clip_mask has been
+                                    // called already
+                            mask = create_hole_in_mask(mask,
+                                polygon_points,
+                                XI,
+                                YI);
+                        }
+                        else {
+                            fprintf(stderr,
+                                "Draw_OGR_Polygons: Attempt to make hole in empty polygon mask!\n");
+                        }
+                    }
+
+
+                    // Free the screen coordinate arrays.
+                    if (XI)
+                        free(XI);
+                    if (YI)
+                        free(YI);
+
+                    // Draw the original polygon to the pixmap
+                    // using the X11 Region as a mask.  Mask may be
+                    // null if we're doing a single outer polygon
+                    // with no "hole" polygons.
+                    if (kk == (object_num - 1)) {
+                        draw_polygon_with_mask(mask,
+                            xpoints,
+                            num_outer_points);
+
+
+                        // Draw the corresponding labels
+                        Draw_OGR_Labels(w,
+                            pixmap,
+                            featureH,
+                            geometryH,
+                            xpoints,
+                            num_outer_points,
+                            label_color_guess);
+
+                        free(xpoints);
+                    }
+                }   // end of draw_filled
+
+
+                else {  // We're drawing non-filled polygons.
+                        // Draw just the border.
+                    int skip_duplicates = 0;
+
+                    if (polygon_hole) {
+                        // Inner ring, draw a dashed line
+                        (void)XSetLineAttributes (XtDisplay(da), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+                    }
+                    else {
+                        // Outer ring, draw a solid line
+                        (void)XSetLineAttributes (XtDisplay(da), gc, 0, LineSolid, CapButt,JoinMiter);
+                    }
+
+                    for ( mm = 1; mm < polygon_points; mm++ ) {
+
+/*
+fprintf(stderr,"Vector %d: %7.5f %8.5f  %7.5f %8.5f\n",
+    mm,
+    vectorY[mm-1],
+    vectorX[mm-1],
+    vectorY[mm],
+    vectorX[mm]);
+*/
+
+
+                        draw_vector_ll(da,
+                            (float)vectorY[mm-1],
+                            (float)vectorX[mm-1],
+                            (float)vectorY[mm],
+                            (float)vectorX[mm],
+                            gc,
+                            pixmap,
+                            skip_duplicates);
+
+                        skip_duplicates = 1;
+                    }
+
+/*
+                    // Draw the corresponding labels
+                    Draw_OGR_Labels(w,
+                        pixmap,
+                        featureH,
+                        geometryH,
+                        xpoints,
+                        num_points,
+                        label_color_guess);
+*/
+
+                }
+
+
+// For weather polygons, we might want to draw the border color in a
+// different color so that we can see these borders easily, or skip
+// drawing the border itself for a few pixels, like UI-View does.
+
+                // Free the allocated vector memory
+                if (vectorX)
+                    free(vectorX);
+                if (vectorY)
+                    free(vectorY);
+                if (vectorZ)
+                    free(vectorZ);
+ 
+            }
+            else {
+                // Not enough points to draw a polygon
+            }
+        }
+    }
+}
+
+
+
+
+
+// Set up coordinate translation:  We need it for indexing and
+// drawing so we do it first and keep pointers to our transforms.
+//
+// Inputs:  datasourceH
+//          layerH
+//
+// Outputs: map_spatialH
+//          transformH
+//          reverse_transformH
+//          wgs84_spatialH
+//          no_spatial
+//          geographic
+//          projected
+//          local
+//          datum
+//          geogcs
+//
+void setup_coord_translation(OGRDataSourceH datasourceH,
+        OGRLayerH layerH,
+        OGRSpatialReferenceH *map_spatialH,
+        OGRCoordinateTransformationH *transformH,
+        OGRCoordinateTransformationH *reverse_transformH,
+        OGRSpatialReferenceH *wgs84_spatialH,
+        int *no_spatial,
+        int *geographic,
+        int *projected,
+        int *local,
+        const char *datum,
+        const char *geogcs) {
+
+
+    *map_spatialH = NULL;
+    *transformH = NULL;
+    *reverse_transformH = NULL;
+    *wgs84_spatialH = NULL;
+    datum = NULL;
+    geogcs = NULL;
+
+
+set_dangerous("map_gdal: OGR_DS_GetLayerCount");
+    if (OGR_DS_GetLayerCount(datasourceH) <= 0) {
+clear_dangerous();
+        fprintf(stderr,"No layers detected\n");
+        return; // No layers detected!
+    }
+clear_dangerous();
+
+
+    // Query the coordinate system for the dataset.
+set_dangerous("map_gdal: OGR_L_GetSpatialRef");
+    *map_spatialH = OGR_L_GetSpatialRef(layerH);
+clear_dangerous();
+
+
+    if (*map_spatialH) {
+        const char *temp;
+
+
+        // We found spatial data
+        no_spatial = 0;
+
+
+set_dangerous("map_gdal: OGRIsGeographic");
+        if (OSRIsGeographic(*map_spatialH)) {
+            geographic++;
+        }
+        else if (OSRIsProjected(*map_spatialH)) {
+            projected++;
+        }
+        else {
+            local++;
+        }
+clear_dangerous();
+
+
+        // PROJCS, GEOGCS, DATUM, SPHEROID, PROJECTION
+        //
+set_dangerous("map_gdal:OSRGetAttrValue");
+        if (projected) {
+            temp = OSRGetAttrValue(*map_spatialH, "PROJCS", 0);
+            temp = OSRGetAttrValue(*map_spatialH, "PROJECTION", 0);
+        }
+        temp = OSRGetAttrValue(*map_spatialH, "SPHEROID", 0);
+        datum = OSRGetAttrValue(*map_spatialH, "DATUM", 0);
+        geogcs = OSRGetAttrValue(*map_spatialH, "GEOGCS", 0);
+clear_dangerous();
+
+    }
+
+
+    else {
+
+        if (debug_level & 16)
+            fprintf(stderr,"  Couldn't get spatial reference\n");
+
+        // For this case, assume that it is WGS84/geographic, and
+        // attempt to index as-is.  If the numbers don't make sense,
+        // we can skip indexing this dataset.
+
+        // Perhaps some layers may have a spatial reference, and
+        // others might not?  Solved this problem by defined
+        // "no_spatial", which will be '1' if no spatial data was
+        // found in any of the layers.  In that case we just store
+        // the extents we find.
+    }
+
+
+//fprintf(stderr,"Datum: %s\n", datum);
+//fprintf(stderr,"GOGCS: %s\n", geogcs);
+
+ 
+    if (no_spatial) {   // No spatial info found
+
+        *transformH = NULL;  // No transforms needed
+        *reverse_transformH = NULL;
+
+        if (debug_level & 16) {
+            fprintf(stderr,
+                "  No spatial info found, NO CONVERSION DONE!, %s\n",
+                geogcs);
+        }
+    }
+    else if ( geographic  // Geographic and correct datum
+              && ( strcasecmp(geogcs,"WGS84") == 0
+                || strcasecmp(geogcs,"NAD83") == 0
+                || strcasecmp(datum,"North_American_Datum_1983") == 0
+                || strcasecmp(datum,"World_Geodetic_System_1984") == 0
+                || strcasecmp(datum,"D_North_American_1983") == 0 ) ) {
+
+// We also need to check "DATUM", as some datasets have nothing in
+// the "GEOGCS" variable.  Check for "North_American_Datum_1983" or
+// "???".
+
+        *transformH = NULL;  // No transforms needed
+        *reverse_transformH = NULL;
+
+        if (debug_level & 16) {
+            fprintf(stderr,
+                "  Geographic coordinate system, NO CONVERSION NEEDED!, %s\n",
+                geogcs);
+        }
+    }
+
+    else {  // We have coordinates but they're in the wrong datum or
+            // in a projected/local coordinate system.  Set up a
+            // transform to WGS84.
+
+        if (geographic) {
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "  Found geographic/wrong datum: %s.  Converting to wgs84 datum\n",
+                    geogcs);
+                fprintf(stderr, "  DATUM: %s\n", datum);
+            }
+        }
+
+        else if (projected) {
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "  Found projected coordinates: %s.  Converting to geographic/wgs84 datum\n",
+                    geogcs);
+            }
+        }
+
+        else if (local) {
+            // Convert to geographic/WGS84?  How?
+
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "  Found local coordinate system.  Returning\n");
+            }
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+        else {
+            // Abandon all hope, ye who enter here!  We don't
+            // have a geographic, projected, or local coordinate
+            // system.
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+ 
+        *wgs84_spatialH = OSRNewSpatialReference(NULL);
+
+
+        if (*wgs84_spatialH == NULL) {
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "Couldn't create empty wgs84_spatialH object\n");
+            }
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+
+        if (OSRSetWellKnownGeogCS(*wgs84_spatialH,"WGS84") == OGRERR_FAILURE) {
+ 
+            // Couldn't fill in WGS84 parameters.
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "Couldn't fill in wgs84 spatial reference parameters\n");
+            }
+
+            // NOTE: DO NOT destroy map_spatialH!  It is part of
+            // the datasource.  You'll get a segfault if you
+            // try, at the point where you destroy the
+            // datasource.
+
+            if (*wgs84_spatialH != NULL) {
+                OSRDestroySpatialReference(*wgs84_spatialH);
+            }
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+
+        if (*map_spatialH == NULL || *wgs84_spatialH == NULL) {
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "Couldn't transform because map_spatialH or wgs84_spatialH are NULL\n");
+            }
+
+            if (*wgs84_spatialH != NULL) {
+                OSRDestroySpatialReference(wgs84_spatialH);
+            }
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+
+        else {
+            // Set up transformation from original datum to wgs84
+            // datum.
+//fprintf(stderr,"Creating transform and reverse_transform\n");
+            *transformH = OCTNewCoordinateTransformation(
+                *map_spatialH, *wgs84_spatialH);
+
+            // Set up transformation from wgs84 datum to original
+            // datum.
+            *reverse_transformH = OCTNewCoordinateTransformation(
+                *wgs84_spatialH, *map_spatialH);
+
+
+            if (*transformH == NULL || *reverse_transformH == NULL) {
+                // Couldn't create transformation objects
+//                if (debug_level & 16) {
+                    fprintf(stderr,
+                        "Couldn't create transformation objects\n");
+//                }
+
+/*
+                if (*wgs84_spatialH != NULL) {
+                    OSRDestroySpatialReference(wgs84_spatialH);
+                }
+
+                // Close data source
+                if (datasourceH != NULL) {
+                    OGR_DS_Destroy( datasourceH );
+                }
+*/
+
+                return; // Exit early
+            }
+        }
+    }
+
+clear_dangerous();
+
+}   // End of setup_coord_translation()
+
+
+
+
+
+// Need this declaration for weather alerts currently
+#ifdef HAVE_LIBSHP
+extern void draw_shapefile_map (Widget w,
+                                char *dir,
+                                char *filenm,
+                                alert_entry *alert,
+                                u_char alert_color,
+                                int destination_pixmap,
+                                map_draw_flags *mdf);
+#endif /* HAVE_LIBSHP */
+
+
+// For AreaLandmarks and Landmarks data.  Allows us to look
+// up the POLYID integer given the LAND integer.
+typedef struct _landmarkinfo {
+    int LAND;        // From AreaLandmarks
+    int POLYID;      // From AreaLandmarks
+    char CENID[6];   // From AreaLandmarks
+}landmarkinfo;
+
+typedef struct _tlid_struct {
+    int TLID;  // Max value is 2^31 or 2,147,483,647
+    struct _tlid_struct *next;
+}tlid_struct;
+
+typedef struct _polyinfo {
+    int POLYID;      // From Polygon, polygon ID
+    char CENID[6];   // From Polygon, many others
+    double POLYLONG; // From PIP
+    double POLYLAT;  // From PIP
+    int WATER;       // From PIP, 1 or 2 = water
+    int LAND;        // From AreaLandmarks, Landmark ID
+    char CFCC[4];    // From Landmarks
+    char LANAME[31]; // From Landmarks, Landmark name
+    struct _tlid_struct *tlid_list; // From PolyChainLink
+}polyinfo;
+
+typedef struct _tlidinfo {
+    int TLID;      // Tiger/Line ID
+    char FEDIRP[3]; // Size from Tiger 2003 definitions
+    char FENAME[31];// Size from Tiger 2003 definitions
+    char FETYPE[5]; // Size from Tiger 2003 definitions
+    char FEDIRS[3]; // Size from Tiger 2003 definitions
+    OGRGeometryH geometryH;
+}tlidinfo;
+
+#define LAND_HASH_SIZE     5000
+#define POLYID_HASH_SIZE  64000
+#define TLID_HASH_SIZE   240000
+
+ 
+
+
+
+// Create hash from key.  LAND is unique within each county.
+// We perform the modulus function on it with the size of
+// our hash to derive the hash key.
+//
+unsigned int landmark_hash_from_key(void *key) {
+    landmarkinfo *temp = key;
+
+    return(temp->LAND % LAND_HASH_SIZE);
+}
+
+
+
+
+
+// Test equality of hash keys.  In this case LAND is the key
+// we care about.
+//
+int landmark_keys_equal(void *key1, void *key2) {
+    landmarkinfo *temp1 = key1;
+    landmarkinfo *temp2 = key2;
+
+    if (temp1->LAND == temp2->LAND)
+        return(1);  // LAND fields match
+    else
+        return(0);  // No match
+}
+
+
+
+
+
+// FUNCTION:
+// Create hash from key.  POLYID is unique within each
+// CENID.  We perform the modulus function on it with the
+// size of our hash to derive the hash key.
+//
+unsigned int polyid_hash_from_key(void *key) {
+    polyinfo *temp = key;
+
+    return(temp->POLYID % POLYID_HASH_SIZE);
+}
+
+
+
+
+
+// FUNCTION:
+// Test equality of hash keys.  In this case POLYID (and
+// CENID?) are the keys we care about.
+//
+int polyid_keys_equal(void *key1, void *key2) {
+    polyinfo *temp1 = key1;
+    polyinfo *temp2 = key2;
+
+    if (temp1->POLYID == temp2->POLYID)
+        return(1);  // POLYID fields match
+    else
+        return(0);  // No match
+}
+
+
+
+
+
+// FUNCTION:
+// Create hash from key.  TLID is unique across the U.S.  We
+// perform the modulus function on it with the size of our
+// hash to derive the hash key.
+//
+unsigned int tlid_hash_from_key(void *key) {
+    tlidinfo *temp = key;
+
+    return(temp->TLID % TLID_HASH_SIZE);
+}
+
+
+
+
+
+// FUNCTION:
+// Test equality of hash keys.  In this case TLID is the
+// absolute key that we care about.
+//
+int tlid_keys_equal(void *key1, void *key2) {
+    tlidinfo *temp1 = key1;
+    tlidinfo *temp2 = key2;
+
+    if (temp1->TLID == temp2->TLID)
+        return(1);  // TLID fields match
+    else
+        return(0);  // No match
+}
+
+
+
+
+
+// For TIGER, we must create polygons from the vector lines.  Use
+// this function in the C API to do that:
+//
+//     OGRGeometryH CPL_DLL OGRBuildPolygonFromEdges(
+//        OGRGeometryH hLinesAsCollection,
+//        int bBestEffort,
+//        int bAutoClose,
+//        double dfTolerance,
+//        OGRErr * peErr );
+//
+// We may need to create some as "hole" polygons and some as "fill"
+// polygons, then order the vectors properly to pass off to the
+// Draw_OGR_Polygon() function.
+//
+//
+// The GDAL docs say to use these flags to compile:
+// `gdal-config --libs` `gdal-config * --cflags`
+// but so far they return: "-L/usr/local/lib -lgdal" and
+// "-I/usr/local/include", which aren't much.  Leaving it hard-coded
+// in configure.ac for now instead of using "gdal-config".
+//
+// GRASS module that does OGR (for reference):  v.in.ogr
+//
+// This function started out as very nearly verbatim the example
+// C-API code off the OGR web pages.
+//
+// If destination_pixmap equals INDEX_CHECK_TIMESTAMPS or
+// INDEX_NO_TIMESTAMPS, then we are indexing the file (finding the
+// extents) instead of drawing it.
+//
+// Indexing/drawing works properly for either geographic or
+// projected coordinates, and does conversions to geographic/WGS84
+// datum before storing the extents in the map index.  It does not
+// work for local coordinate systems.
+//
+//
+// TODO:
+// *) map_visible_ll() needs to be re-checked.  Lines are not
+//    showing up sometimes when the end points are way outside the
+//    view.  Perhaps need line_visible() and line_visible_ll()
+//    functions?  If I don't want to compute the slope of a line and
+//    such, might just check for line ends being within boundaries
+//    or left/above, and within boundaries or right/below, to catch
+//    those lines that slant across the view.
+// *) Dbfawk support or similar?  Map preferences:  Colors, line
+//    widths, layering, filled, choose label field, label
+//    fonts/placement/color.
+// *) Allow user to select layers to draw/ignore.  Very important
+//    for those sorts of files that provide all layers (i.e. Tiger &
+//    SDTS).
+// *) Weather alert tinted polygons, draw to the correct pixmap,
+//    draw only those shapes called for, not the entire map.
+// *) Fast Extents:  We now pass a variable to the draw functions
+//    that tells whether we can do fast extents, but we still need
+//    to compute our own extents after we have the points for a
+//    shape in an array.  We could either check extents or just call
+//    the draw functions, which skip drawing if outside our view
+//    anyway (we currently do the latter).
+
+
+// We've changed over to the spatial filter scheme:  Set a spatial
+// filter based on our current view, draw only those objects that
+// OGR_L_GetNextFeature() passes back to us.  That saves a lot of
+// coordinate conversion code and speeds things up dramatically.
+
+
+// *) Figure out why SDTS hypsography (contour lines) on top of
+//    terraserver gives strange results when zooming/panning
+//    sometimes.  Restarting Xastir cleans up the image.  Perhaps
+//    colors or GC's are getting messed up?  Perhaps lines segments
+//    are too long when drawing?
+// *) Some sort of warning to the operator if large regions are
+//    being filled, and there's a base raster map?  Dbfawk likes to
+//    fill counties in with purple, wiping out rasters underneath.
+// *) Draw portions of a line/polygon correctly, instead of just
+//    dropping or concatenating lines.  This can cause missing line
+//    segments that cross the edge of our view, or incorrect slopes
+//    for lines that cross the edge.
+//    NOTE:  Have switched to chopping at +/- 32767 pixels, which
+//    seems to fix this nicely.  Chopping at much less causes
+//    problems, while X11 has problems at +/- 32767 or higher.
+// *) Speed things up in any way possible.
+//
+// 
+// Regarding coordinate systems, a note from Frank Warmerdam:  "In
+// theory different layers in a datasource can have different
+// coordinate systems, though this is uncommon.  It does happen
+// though."
+//
+// Question regarding how to specify drawing preferences, answered
+// by Frank:  "There are many standards.  Within the OGR API the
+// preferred approach to this is the OGR Feature Style
+// Specification:
+//
+// http://gdal.velocet.ca/~warmerda/projects/opengis/ogr_feature_style_008.html
+//
+// Basically this is intended to provide a mechanism for different
+// underlying formats to indicate their rendering information.  It
+// is at least partially implemented for the DGN and Mapinfo
+// drivers.  The only applications that I am aware of taking
+// advantage of it are OpenEV and MapServer."
+
+void draw_ogr_map( Widget w,
+                   char *dir,
+                   char *filenm,
+                   alert_entry *alert,
+                   u_char alert_color,
+                   int destination_pixmap,
+                   map_draw_flags *mdf) {
+
+    OGRDataSourceH datasourceH = NULL;
+    OGRSFDriverH driver = NULL;
+    OGRSpatialReferenceH map_spatialH = NULL;
+    OGRSpatialReferenceH wgs84_spatialH = NULL;
+    OGRCoordinateTransformationH transformH = NULL;
+    OGRCoordinateTransformationH reverse_transformH = NULL;
+    OGRGeometryH spatial_filter_geometryH = NULL;
+    int ii, numLayers;
+    char full_filename[300];
+    const char *ptr;
+    const char *driver_type;
+    int no_spatial = 1;
+    int geographic = 0;
+    int projected = 0;
+    int local = 0;
+    const char *datum = NULL;
+    const char *geogcs = NULL;
+    double ViewX[2], ViewY[2], ViewZ[2];
+    double ViewX2[2], ViewY2[2], ViewZ2[2];
+    long ViewLX[2], ViewLY[2];
+    float f_latitude0, f_latitude1, f_longitude0, f_longitude1;
+    char status_text[MAX_FILENAME];
+    char short_filenm[MAX_FILENAME];
+    int draw_filled;
+
+    draw_filled=mdf->draw_filled;
+ 
+    if (debug_level & 16)
+        fprintf(stderr,"Entered draw_ogr_map function\n");
+
+
+/******************************************************************/
+// We don't want to process weather alerts right now in this code.
+// We're not set up for it yet.  Call the original shapefile map
+// function instead.  We added an extern declaration above in order
+// that this function knows about the draw_shapefile_map() function
+// parameters.  Remove that declaration once we support weather
+// alerts in this code natively.
+//
+if (alert) {
+
+#ifdef HAVE_LIBSHP
+
+    // We have a weather alert, call the original function instead.
+    draw_shapefile_map(w,
+        dir,
+        filenm,
+        alert,
+        alert_color,
+        destination_pixmap,
+        mdf);
+
+#endif  // HAVE_LIBSHP
+
+    return;
+}
+/******************************************************************/
+
+
+    xastir_snprintf(full_filename,
+        sizeof(full_filename),
+        "%s/%s",
+        dir,
+        filenm);
+
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+
+//    if (debug_level & 16)
+        fprintf(stderr,"Opening datasource %s\n", full_filename);
+
+    //
+    // One computer segfaulted at OGROpen() if a .prj file was
+    // present with a shapefile.  Another system with newer Linux/
+    // libtiff/ libgeotiff works fine.  Getting rid of older header
+    // files/ libraries, then recompiling/installing libproj/
+    // libgeotiff/ libshape/ libgdal/ Xastir seemed to fix it.
+    //
+    // Open data source
+set_dangerous("map_gdal: OGROpen");
+    datasourceH = OGROpen(full_filename,
+        0 /* bUpdate */,
+        &driver);
+clear_dangerous();
+
+    if (datasourceH == NULL) {
+/*
+        fprintf(stderr,
+            "Unable to open %s\n",
+            full_filename);
+*/
+        return;
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr,"Opened datasource %s\n", full_filename);
+
+    driver_type = OGR_Dr_GetName(driver);
+
+    if (debug_level & 16)
+        fprintf(stderr,"%s: ", driver_type);
+
+    // Get name/path.  Less than useful since we should already know
+    // this.
+    ptr = OGR_DS_GetName(datasourceH);
+
+    if (debug_level & 16)
+        fprintf(stderr,"%s\n", ptr);
+
+
+    // Implement the indexing functions, so that we can use these
+    // map formats from within Xastir.  Without an index, it'll
+    // never appear in the map chooser.  Use the OGR "envelope"
+    // functions to get the extents for the each layer in turn.
+    // We'll find the min/max of the overall set of layers and use
+    // that for the extents for the entire dataset.
+    //
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+// We're indexing only.  Save the extents in the index.
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+
+        double file_MinX = 0;
+        double file_MaxX = 0;
+        double file_MinY = 0;
+        double file_MaxY = 0;
+        int first_extents = 1;
+
+
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(status_text,0);       // Indexing ...
+
+//fprintf(stderr,"Indexing %s\n", filenm);
+
+        // Use the OGR "envelope" function to get the extents for
+        // the entire file or dataset.  Remember that it could be in
+        // state-plane coordinate system or something else equally
+        // strange.  Convert it to WGS84 or NAD83 geographic
+        // coordinates before saving the index.
+
+        // Loop through all layers in the data source.  We can't get
+        // the extents for the entire data source without looping
+        // through the layers.
+        //
+        numLayers = OGR_DS_GetLayerCount(datasourceH);
+        for ( ii=0; ii<numLayers; ii++ ) {
+            OGRLayerH layerH;
+            OGREnvelope psExtent;  
+
+
+            layerH = OGR_DS_GetLayer( datasourceH, ii );
+
+            if (layerH == NULL) {
+
+                if (debug_level & 16) {
+                    fprintf(stderr,
+                        "Unable to open layer %d of %s\n",
+                        ii,
+                        full_filename);
+                }
+
+                if (wgs84_spatialH != NULL) {
+                    OSRDestroySpatialReference(wgs84_spatialH);
+                }
+
+//                if (transformH != NULL) {
+//                    OCTDestroyCoordinateTransformation(transformH);
+//                }
+
+//                if (reverse_transformH != NULL) {
+//                    OCTDestroyCoordinateTransformation(reverse_transformH);
+//                }
+
+                // Close data source
+                if (datasourceH != NULL) {
+                    OGR_DS_Destroy( datasourceH );
+                }
+
+                return; // Exit early
+            }
+
+
+            // Set up the coordinate translations we may need for
+            // both indexing and drawing operations.  It sets up the
+            // transform and the reverse transforms we need to
+            // convert between the spatial coordinate systems.
+            //
+            setup_coord_translation(datasourceH, // Input
+                layerH,                          // Input
+                &map_spatialH,                    // Output
+                &transformH,                      // Output
+                &reverse_transformH,              // Output
+                &wgs84_spatialH,                  // Output
+                &no_spatial,                     // Output
+                &geographic,                     // Output
+                &projected,                      // Output
+                &local,                          // Output
+                datum,                           // Output
+                geogcs);                         // Output
+
+
+            // Get the extents for this layer.  OGRERR_FAILURE means
+            // that the layer has no spatial info or that it would be
+            // an expensive operation to establish the extent.
+            // Here we set the force option to TRUE in order to read
+            // all of the extents even for files where that would be
+            // an expensive operation.  We're trying to index the
+            // file after all!  Whether or not the operation is
+            // expensive makes no difference at this point.
+            //
+            if (OGR_L_GetExtent(layerH, &psExtent, TRUE) != OGRERR_FAILURE) {
+
+//                fprintf(stderr,
+//                    "  MinX: %f, MaxX: %f, MinY: %f, MaxY: %f\n",
+//                    psExtent.MinX,
+//                    psExtent.MaxX,
+//                    psExtent.MinY,
+//                    psExtent.MaxY);
+
+                // If first value, store it.
+                if (first_extents) {
+                    file_MinX = psExtent.MinX;
+                    file_MaxX = psExtent.MaxX;
+                    file_MinY = psExtent.MinY;
+                    file_MaxY = psExtent.MaxY;
+
+                    first_extents = 0;
+                }
+                else {
+                    // Store the min/max values
+                    if (psExtent.MinX < file_MinX)
+                        file_MinX = psExtent.MinX;
+                    if (psExtent.MaxX > file_MaxX)
+                        file_MaxX = psExtent.MaxX;
+                    if (psExtent.MinY < file_MinY)
+                        file_MinY = psExtent.MinY;
+                    if (psExtent.MaxY > file_MaxY)
+                        file_MaxY = psExtent.MaxY;
+                }
+            }
+            // No need to free layerH handle, it belongs to the
+            // datasource.
+        }
+        // All done looping through the layers.
+
+
+        // We only know how to handle geographic or projected
+        // coordinate systems.  Test for these.
+        if ( !first_extents && (geographic || projected || no_spatial) ) {
+            // Need to also check datum!  Must be NAD83 or WGS84 and
+            // geographic for our purposes.
+/*
+            if ( no_spatial
+                || (geographic
+                    && ( strcasecmp(geogcs,"WGS84") == 0
+                        || strcasecmp(geogcs,"NAD83") == 0) ) ) {
+// Also check "datum" here
+
+                fprintf(stderr,
+                    "Geographic coordinate system, %s, adding to index\n",
+                    geogcs);
+
+                if (   file_MinY >=  -90.0 && file_MinY <=  90.0
+                    && file_MaxY >=  -90.0 && file_MaxY <=  90.0
+                    && file_MinX >= -180.0 && file_MinX <= 180.0
+                    && file_MaxX >= -180.0 && file_MaxX <= 180.0) {
+
+                    // Check for all-zero entries
+                    if (       file_MinY == 0.0
+                            && file_MaxY == 0.0
+                            && file_MinX == 0.0
+                            && file_MaxX == 0.0 ) {
+//                        if (debug_level & 16) {
+                            fprintf(stderr,
+                                "Geographic coordinates are all zero, skipping indexing\n");
+                            fprintf(stderr,"MinX:%f  MinY:%f  MaxX:%f MaxY:%f\n",
+                                file_MinX,
+                                file_MinY,
+                                file_MaxX,
+                                file_MaxY);
+//                        }
+                    }
+                    else {
+ 
+// Debug:  Don't add them to the index so that we can experiment
+// with datum translation and such.
+//#define WE7U
+#ifndef WE7U
+                        index_update_ll(filenm,    // Filename only
+                            file_MinY,  // Bottom
+                            file_MaxY,  // Top
+                            file_MinX,  // Left
+                            file_MaxX,  // Right
+                            1000);      // Default Map Layer
+#endif  // WE7U
+                    }
+                }
+                else {
+//                    if (debug_level & 16) {
+                        fprintf(stderr,
+                            "Geographic coordinates out of bounds, skipping indexing\n");
+                        fprintf(stderr,"MinX:%f  MinY:%f  MaxX:%f MaxY:%f\n",
+                            file_MinX,
+                            file_MinY,
+                            file_MaxX,
+                            file_MaxY);
+//                    }
+                }
+            }
+            else {  // We have coordinates but they're in the wrong
+                    // datum or in a projected coordinate system.
+                    // Convert to WGS84 coordinates.
+*/
+                double x[2];
+                double y[2];
+
+
+                x[0] = file_MinX;
+                x[1] = file_MaxX;
+                y[0] = file_MinY;
+                y[1] = file_MaxY;
+
+//                fprintf(stderr,"Before: %f,%f\t%f,%f\n",
+//                    x[0],y[0],
+//                    x[1],y[1]);
+
+                // We can get files that have a weird coordinate
+                // system in them that doesn't have a transform
+                // defined.  One such was "unamed".  Check whether
+                // we have a valid transform.  If not, just assume
+                // we're ok and index it as-is.
+                if (transformH == NULL) {
+                    if (debug_level & 16)
+                        fprintf(stderr, "No transform available!\n");
+                }
+                else {
+
+//                    fprintf(stderr,"Before: %f,%f\t%f,%f\n",
+//                        x[0],y[0],
+//                        x[1],y[1]);
+
+
+                    if (OCTTransform(transformH, 2, x, y, NULL)) {
+                            
+//                        fprintf(stderr," After: %f,%f\t%f,%f\n",
+//                            x[0],y[0],
+//                            x[1],y[1]);
+                    }
+                }
+
+                if (       y[0] >=  -90.0 && y[0] <=  90.0
+                        && y[1] >=  -90.0 && y[1] <=  90.0
+                        && x[0] >= -180.0 && x[0] <= 180.0
+                        && x[1] >= -180.0 && x[1] <= 180.0) {
+
+                    // Check for all-zero entries
+                    if (       file_MinY == 0.0
+                            && file_MaxY == 0.0
+                            && file_MinX == 0.0
+                            && file_MaxX == 0.0 ) {
+//                        if (debug_level & 16) {
+                            fprintf(stderr,
+                                "Coordinates are all zero, skipping indexing\n");
+                            fprintf(stderr,"MinX:%f  MinY:%f  MaxX:%f MaxY:%f\n",
+                                file_MinX,
+                                file_MinY,
+                                file_MaxX,
+                                file_MaxY);
+//                        }
+                    }
+                    else {
+ 
+// Debug:  Don't add them to the index so that we can experiment
+// with datum translation and such.
+#ifndef WE7U
+                        index_update_ll(filenm, // Filename only
+                            y[0],   // Bottom
+                            y[1],   // Top
+                            x[0],   // Left
+                            x[1],   // Right
+                            1000);  // Default Map Layer
+#endif  // WE7U
+                    }
+                }
+                else {
+//                    if (debug_level & 16) {
+                        fprintf(stderr,
+                            "Coordinates out of bounds, skipping indexing\n");
+                        fprintf(stderr,"MinX:%f  MinY:%f  MaxX:%f MaxY:%f\n",
+                            file_MinX,
+                            file_MinY,
+                            file_MaxX,
+                            file_MaxY);
+//                    }
+                }
+//            }
+        }
+
+        // Debug code:
+        // For now, set the index to be the entire world to get
+        // things up and running.
+//        index_update_ll(filenm,    // Filename only
+//             -90.0,  // Bottom
+//              90.0,  // Top
+//            -180.0,  // Left
+//             180.0,  // Right
+//              1000); // Default Map Layer
+
+        if (wgs84_spatialH != NULL) {
+            OSRDestroySpatialReference(wgs84_spatialH);
+        }
+
+        if (transformH != NULL) {
+            OCTDestroyCoordinateTransformation(transformH);
+        }
+
+        if (reverse_transformH != NULL) {
+            OCTDestroyCoordinateTransformation(reverse_transformH);
+        }
+
+        // Close data source
+        if (datasourceH != NULL) {
+            OGR_DS_Destroy( datasourceH );
+        }
+
+        return; // Done indexing the file
+    }
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+// The code below this point is for drawing, not indexing.
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+
+    xastir_snprintf(status_text,
+        sizeof(status_text),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(status_text,0);       // Loading ...
+
+//    fprintf(stderr,"Loading %s\n", filenm);
+
+
+ 
+    // Find out what type of file we're dealing with.  This reports
+    // one of:
+    //
+    // "AVCbin"
+    // "DGN"
+    // "FMEObjects Gateway"
+    // "GML"
+    // "Memory"
+    // "MapInfo File"
+    // "UK .NTF"
+    // "OCI"
+    // "ODBC"
+    // "OGDI"
+    // "PostgreSQL"
+    // "REC"
+    // "S57"
+    // "SDTS"
+    // "ESRI Shapefile"
+    // "TIGER"
+    // "VRT"
+    //
+
+
+    // If we're going to write, we need to test the capability using
+    // these functions:
+    // OGR_Dr_TestCapability(); // Does Driver have write capability?
+    // OGR_DS_TestCapability(); // Can we create new layers?
+
+
+// Optimization:  Get the envelope for each layer if it's not an
+// expensive operation.  Skip the layer if it's completely outside
+// our viewport.
+// Faster yet:  Set up a SpatialFilter, then GetNextFeature() should
+// only return features that are within our maximum bounding
+// rectangle (MBR).  setup_coord_translation() may have already set
+// up "wgs84_spatialH" for us as a SpatialReference.
+ 
+
+
+//(void)XSetFunction();
+(void)XSetFillStyle(XtDisplay(w), gc, FillSolid);
+
+
+
+    // Set up the geometry for the spatial filtering we'll do later
+    // in the layer loop.  The geometry should specify our current
+    // view, but in the spatial reference system of the map layer.
+    //
+    // Fill in the corner coordinates of our viewport, in lat/long
+    // coordinates.
+    //
+/*
+    ViewX[0] = -110.0;
+    ViewY[0] =   40.0;
+    ViewZ[0] =    0.0;
+    ViewX[1] = -090.0;
+    ViewY[1] =   35.0;
+    ViewZ[1] =    0.0;
+*/
+    //long  center_longitude;    // Longitude at center of map
+    //long  center_latitude;     // Latitude  at center of map
+
+    // Longitude, NW corner of map screen
+    ViewLX[0] = NW_corner_longitude;
+    // Latitude, NW corner of map screen
+    ViewLY[0] = NW_corner_latitude;
+    // Longitude, SE corner of map screen
+    ViewLX[1] = center_longitude + (center_longitude - NW_corner_longitude);
+    // Latitude, SE corner of map screen
+    ViewLY[1] = center_latitude + (center_latitude - NW_corner_latitude);
+
+    // Check for out-of bounds values
+    if (ViewLX[0] < 0) ViewLX[0] = 0;
+    if (ViewLY[0] < 0) ViewLY[0] = 0;
+    if (ViewLX[1] < 0) ViewLX[1] = 0;
+    if (ViewLY[1] < 0) ViewLY[1] = 0;
+
+    if (ViewLX[0] > 129600000) ViewLX[0] = 129600000;
+    if (ViewLY[0] >  64800000) ViewLY[0] =  64800000;
+    if (ViewLX[1] > 129600000) ViewLX[1] = 129600000;
+    if (ViewLY[1] >  64800000) ViewLY[1] =  64800000;
+
+    // Now convert the coordinates from Xastir coordinate system to
+    // Lat/long degrees in the form of floats.
+
+    convert_from_xastir_coordinates(&f_longitude0,
+        &f_latitude0,
+        ViewLX[0],
+        ViewLY[0]);
+    convert_from_xastir_coordinates(&f_longitude1,
+        &f_latitude1,
+        ViewLX[1],
+        ViewLY[1]);
+
+    // Convert to doubles
+    ViewX[0] = (double)f_longitude0;
+    ViewY[0] = (double)f_latitude0;
+    ViewX[1] = (double)f_longitude1;
+    ViewY[1] = (double)f_latitude1;
+    ViewZ[0] = 0.0;
+    ViewZ[1] = 0.0;
+
+
+    sdts_elevation_in_meters = 0;
+
+    // If it is an SDTS file, determine whether we may have
+    // elevation in feet or meters.  AHPT layer present = feet, AHPR
+    // layer present = meters.
+    if (strcasecmp(driver_type,"SDTS") == 0) {
+
+        if (OGR_DS_GetLayerByName(datasourceH, "AHPR")) {
+            fprintf(stderr,"Elevation is in meters\n");
+            sdts_elevation_in_meters = 1;
+        }
+
+        if (OGR_DS_GetLayerByName(datasourceH, "AHPT")) {
+            fprintf(stderr,"Elevation is in feet\n");
+        }
+    }
+
+
+    // If we put these flags down in the layer loop, we end up with
+    // all black lines being drawn.  Perhaps the layer that defines
+    // the types isn't the same layer that contains the vectors that
+    // get drawn?
+    //
+    hypsography_layer = 0;
+    hydrography_layer = 0;
+    water_layer = 0;
+    roads_trails_layer = 0;
+    railroad_layer = 0;
+    misc_transportation_layer = 0;
+
+
+
+    numLayers = OGR_DS_GetLayerCount(datasourceH);
+
+
+
+
+
+
+
+
+
+
+#ifdef TIGER_POLYGONS
+    // Special handling for TIGER files so that we can extract/draw
+    // polygons.
+    //
+    // Tiger Polygons:
+    // *) Read "Polygon".  Snag "POLYID" and "CENID" fields.
+//DONE!
+    // *) Read "PIP".  Match "POLYID" (and "CENID"?) field.  Snag
+    //    "POLYLONG", "POLYLAT", and "WATER" fields.  We'll use the
+    //    lat/long as the point to draw labels.  "WATER"=1:
+    //    Perennial.  "WATER"=2: Intermittent.
+//DONE!
+    // *) Read "AreaLandmarks".  Match on "POLYID" (and "CENID"?) if
+    //    possible.  Snag "LAND" field.
+//DONE!
+    // *) Read "Landmarks".  Match on "LAND" field.  Snag "CFCC" and 
+    //    "LANAME" fields.
+//DONE!
+    // *) Read "PolyChainLink".  Match "POLYID" to either "POLYIDL" or 
+    //    "POLYIDR" (and "CENID" to either "CENIDL" or "CENIDR"?).
+    //    Snag "TLID" fields.
+//DONE!
+    // *) Read the "CompleteChain" layer, caching the geometry of any 
+    //    lines that match "TLID" fields found above.  We might just
+    //    cache these with the polygon info while drawing the
+    //    vectors/points, then if a "polygon_flag" is set, proceed
+    //    to the last phases of drawing polygons.  This will allow
+    //    us to read in the vector information once instead of
+    //    twice.  Actually, reversing this would be better so that
+    //    we draw vectors on top of the polygons, so that roads and
+    //    railroads and such will get drawn on top of water, streams
+    //    will get drawn on top of city color-fill, etc.
+//DONE!
+    // *) Once we've processed the CompleteChain layer, turn those 
+    //    geometries into real polygons:
+    //      Create a wkbGeometryCollection object.
+//DONE!
+    //      BuildPolygonFromEdges()
+//DONE!
+    //      Draw the polygons.  Decide whether to draw based on the
+    //        WATER field and/or the CFCC field if present.
+//DONE!
+    // *) Draw non-polygon vectors.
+//DONE!
+    //
+    if (draw_filled && strcasecmp(driver_type,"TIGER") == 0) {
+        struct hashtable *polyid_hash;
+        struct hashtable *landmark_hash;
+        struct hashtable *tlid_hash;
+
+        OGRLayerH layerH;
+        OGRFeatureH featureH;
+        struct hashtable_itr *iterator = NULL;
+
+        // Create the empty hash table for polyid
+        polyid_hash = create_hashtable(POLYID_HASH_SIZE,
+            polyid_hash_from_key,
+            polyid_keys_equal);
+
+        // Create the empty hash table for "landmark"
+        landmark_hash = create_hashtable(LAND_HASH_SIZE,
+            landmark_hash_from_key,
+            landmark_keys_equal);
+
+        // Create the empty hash table for tlid
+        tlid_hash = create_hashtable(TLID_HASH_SIZE,
+            tlid_hash_from_key,
+            tlid_keys_equal);
+
+
+fprintf(stderr,"Starting polygon reassembly\n");
+fprintf(stderr,"                      Polygon Layer ");
+start_timer();
+
+
+        layerH = OGR_DS_GetLayerByName(datasourceH, "Polygon");
+        if (layerH) {
+            // Loop through all of the "Polygon" layer records,
+            // saving the POLYID/CENID fields.
+            polyinfo *temp;
+
+            while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+                int kk;
+
+                kk = OGR_F_GetFieldIndex( featureH, "POLYID");
+                if (kk != -1) {
+                    int polyid;
+                    int mm;
+
+                    polyid = OGR_F_GetFieldAsInteger( featureH, kk);
+
+                    // Allocate struct
+                    temp = (polyinfo *)malloc(sizeof(polyinfo));
+                    temp->POLYID = polyid;
+
+//fprintf(stderr,"POLYID:%i\n", polyid);
+
+                    // Fill in some defaults
+                    temp->WATER = 0;
+                    temp->LAND = -1;
+                    temp->CFCC[0] = '\0';
+                    temp->LANAME[0] = '\0';
+                    temp->tlid_list = NULL;
+
+                    mm = OGR_F_GetFieldIndex( featureH, "CENID");
+                    if (mm != -1) {
+                        const char *cenid;
+
+                        cenid = OGR_F_GetFieldAsString( featureH, mm);
+                        xastir_snprintf(temp->CENID,
+                            sizeof(temp->CENID),
+                            "%s",
+                            cenid);
+//fprintf(stderr,"CENID:%s\n", cenid);
+                    }
+                    else {
+                        temp->CENID[0] = '\0';
+                    }
+
+                    // Insert a new value into the hash
+// Remember to free() the hash storage later
+ 
+                    if (!hashtable_insert(polyid_hash,&temp->POLYID, temp)) {
+                        fprintf(stderr,"Couldn't insert into polyid_hash\n");
+                        free(temp);
+                    }
+//fprintf(stderr,"%i ",temp->POLYID);
+                }
+
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+            }   // End of while
+        }   // End of if (layerH)
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"                          PIP Layer ");
+
+
+        layerH = OGR_DS_GetLayerByName(datasourceH, "PIP");
+        if (layerH) {
+            // Loop through all of the "PIP" layer records,
+            // saving the POLYLONG/POLYLAT/WATER fields.
+
+            while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+                int kk;
+
+                kk = OGR_F_GetFieldIndex( featureH, "POLYID");
+                if (kk != -1) {
+                    int polyid;
+                    polyinfo *found;
+
+
+                    polyid = OGR_F_GetFieldAsInteger( featureH, kk);
+
+                    // Find an entry in the hash
+                    found = hashtable_search(polyid_hash, &polyid);
+                    if (found) {    // Found a match!
+                        int mm;
+
+//fprintf(stderr,"Found a match for POLYID in PIP layer!\n");
+
+                        mm = OGR_F_GetFieldIndex( featureH, "POLYLONG");
+                        if (mm != -1) {
+                                double polylong;
+
+//fprintf(stderr,"POLYLONG\t");
+                                polylong = OGR_F_GetFieldAsDouble( featureH, mm);
+                                found->POLYLONG = polylong;
+                        }
+
+                        mm = OGR_F_GetFieldIndex( featureH, "POLYLAT");
+                        if (mm != -1) {
+                                double polylat;
+ 
+//fprintf(stderr,"POLYLAT\t");
+                                polylat = OGR_F_GetFieldAsDouble( featureH, mm);
+                                found->POLYLAT = polylat;
+                        }
+
+                        mm = OGR_F_GetFieldIndex( featureH, "WATER");
+                        if (mm != -1) {
+                                int water;
+ 
+//fprintf(stderr,"WATER\n");
+                                water = OGR_F_GetFieldAsInteger( featureH, mm);
+                                found->WATER = water;
+                        }
+                    }
+                }
+
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+            }   // End of while
+        }   // End of if (layerH)
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"                AreaLandmarks Layer ");
+
+
+        layerH = OGR_DS_GetLayerByName(datasourceH, "AreaLandmarks");
+        if (layerH) {
+            // Loop through all of the "AreaLandmarks" layer records,
+            // saving the LAND fields in landmark_hash.
+
+            while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+                int kk;
+
+                kk = OGR_F_GetFieldIndex( featureH, "LAND");
+                if (kk != -1) {
+                    int land;
+
+                    land = OGR_F_GetFieldAsInteger( featureH, kk);
+
+                    kk = OGR_F_GetFieldIndex( featureH, "POLYID");
+                    if (kk != -1) {
+                        int polyid;
+                        landmarkinfo *temp;
+
+                        polyid = OGR_F_GetFieldAsInteger( featureH, kk);
+ 
+                        // Allocate struct
+                        temp = (landmarkinfo *)malloc(sizeof(landmarkinfo));
+                        temp->LAND = land;
+                        temp->POLYID = polyid;
+ 
+                        kk = OGR_F_GetFieldIndex( featureH, "CENID");
+                        if (kk != -1) {
+                            const char *cenid;
+
+                            cenid = OGR_F_GetFieldAsString( featureH, kk);
+                            xastir_snprintf(temp->CENID,
+                                sizeof(temp->CENID),
+                                "%s",
+                                cenid);
+                        }
+                        else {
+                            temp->CENID[0] = '\0';
+                        }
+
+                        // Insert a new value into the hash
+// Remember to free() the hash storage later
+                        if (!hashtable_insert(landmark_hash,&temp->LAND, temp)) {
+                            fprintf(stderr,"Couldn't insert into landmark_hash\n");
+                            free(temp);
+                        }
+                    }
+                }
+
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+            }   // End of while
+        }   // End of if (layerH)
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"                    Landmarks Layer ");
+
+
+        layerH = OGR_DS_GetLayerByName(datasourceH, "Landmarks");
+        if (layerH) {
+            // Loop through all of the "Landmarks" layer records,
+            // use the LAND value to search for the POLYID value in
+            // the landmark hash, then use the POLYID value to find
+            // the actual record in the polyid_hash and fill in the
+            // LANAME/CFCC fields there.
+            //
+            while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+                int kk;
+
+                kk = OGR_F_GetFieldIndex( featureH, "LAND");
+                if (kk != -1) {
+                    int land;
+                    landmarkinfo *found;
+
+                    land = OGR_F_GetFieldAsInteger( featureH, kk);
+
+                    // Find an entry in landmark_hash
+                    found = hashtable_search(landmark_hash, &land);
+                    if (found) {    // Found a match!
+                        polyinfo *found2;
+
+//fprintf(stderr,"Found a match for LAND (%i) in Landmarks layer!\n", land);
+
+                        // Find the corresponding entry in the polyid_hash
+                        found2 = hashtable_search(polyid_hash, &found->POLYID);
+                        if (found2) {   // We have our destination record
+                            int mm;
+
+//fprintf(stderr,"Found a match for POLYID (%i) in Landmarks layer!\n", found2->POLYID);
+
+                            mm = OGR_F_GetFieldIndex( featureH, "CFCC");
+                            if (mm != -1) {
+                                const char *cfcc;
+
+                                cfcc = OGR_F_GetFieldAsString( featureH, mm);
+//fprintf(stderr,"CFCC:%s\n", cfcc);
+                                xastir_snprintf(found2->CFCC,
+                                    sizeof(found2->CFCC),
+                                    "%s",
+                                    cfcc);
+                            }
+
+                            mm = OGR_F_GetFieldIndex( featureH, "LANAME");
+                            if (mm != -1) {
+                                const char *laname;
+
+                                laname = OGR_F_GetFieldAsString( featureH, mm);
+//fprintf(stderr,"LANAME:%s\n",laname);
+ 
+                                xastir_snprintf(found2->LANAME,
+                                    sizeof(found2->LANAME),
+                                    "%s",
+                                    laname);
+                            }
+                        }
+                    }
+                }
+
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+            }   // End of while
+
+            // Restart reads of this layer at the first feature.
+            OGR_L_ResetReading(layerH);
+        }
+
+
+
+// The below section is probably not correct yet.  I'll assume that
+// we need to watch how we do the right/left thing and construct our
+// chain appropriately, else we'll end up with weird polygons that
+// have all of the correct vertices but the wrong line segments
+// between them.
+// We also need to collect the geometry information for all of the
+// matches and link them together, so we can then use
+// OGRBuildPolygonFromEdges() to construct a real polygon that we
+// can draw.
+//
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"                PolyChainLink Layer ");
+
+ 
+        layerH = OGR_DS_GetLayerByName(datasourceH, "PolyChainLink");
+        if (layerH) {
+            // Match "POLYID" from above to either "POLYIDL" or
+            // "POLYIDR" fields.  Save the "TLID" fields on matches.
+            while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+                int kk, mm, nn;
+                int polyidl = -1;
+                int polyidr = -1;
+                int tlid = -1;
+                polyinfo *found1;
+                polyinfo *found2;
+
+
+                kk = OGR_F_GetFieldIndex( featureH, "POLYIDL" );
+                mm = OGR_F_GetFieldIndex( featureH, "POLYIDR" );
+                nn = OGR_F_GetFieldIndex( featureH, "TLID" );
+
+                if (kk != -1)
+                    polyidl = OGR_F_GetFieldAsInteger( featureH, kk);
+                if (mm != -1)
+                    polyidr = OGR_F_GetFieldAsInteger( featureH, mm);
+                if (nn != -1)
+                    tlid = OGR_F_GetFieldAsInteger( featureH, nn);
+
+
+                // Find an entry in the hash.  Check both polyidl
+                // and polyidr for matches this time.  If either
+                // match, add to the record.
+                //
+                found1 = hashtable_search(polyid_hash, &polyidl);
+                found2 = hashtable_search(polyid_hash, &polyidr);
+
+                if (found1 || found2) { // Found at least one match!
+                    tlid_struct *tlid_temp;
+
+//fprintf(stderr,"Found a match for POLYIDL or POLYIDR in PolyChainLink layer!\n");
+
+                    // Link it in at the END of the list to keep the
+                    // line order correct.  These are short lists on
+                    // average so we're not losing too much time by
+                    // traversing down the list each time.  We could
+                    // later make it a doubly-linked list in order
+                    // to speed things up.
+                    //
+                    if (found1) {
+                        // Allocate a new record and link it in at the
+                        // end of the list.  Fill it in with the value
+                        // of TLID.
+                        tlid_temp = (tlid_struct *)malloc(sizeof(tlid_struct));
+                        tlid_temp->TLID = tlid;
+                        tlid_temp->next = NULL;
+
+/*
+                        if (found1->tlid_list == NULL) {
+                            // List is NULL:  Add the new record
+                            found1->tlid_list = tlid_temp;
+                        }
+                        else {  // List has at least one record.
+                                // Traverse to the end of the list.
+                            tlid_struct *p;
+
+                            p = found1->tlid_list;  // Head of list
+                            while (p->next != NULL) {
+                                p = p->next;
+                            }
+                            // We should be sitting at the last record.
+                            // Add our new record to the end.
+                            p->next = tlid_temp;
+                        }
+*/
+
+// Try linking it at the beginning of the list instead, which will
+// change the drawing order of the vertices but should be much
+// faster.
+tlid_temp->next = found1->tlid_list;
+found1->tlid_list = tlid_temp;
+
+                    }
+                    if (found2) {
+                        // Allocate a new record and link it in at the
+                        // end of the list.  Fill it in with the value
+                        // of TLID.
+                        tlid_temp = (tlid_struct *)malloc(sizeof(tlid_struct));
+                        tlid_temp->TLID = tlid;
+                        tlid_temp->next = NULL;
+
+/*
+                        if (found2->tlid_list == NULL) {
+                            // List is NULL:  Add the new record
+                            found2->tlid_list = tlid_temp;
+                        }
+                        else {  // List has at least one record.
+                                // Traverse to the end of the list.
+                            tlid_struct *p;
+
+                            p = found2->tlid_list;  // Head of list
+                            while (p->next != NULL) {
+                                p = p->next;
+                            }
+                            // We should be sitting at the last record.
+                            // Add our new record to the end.
+                            p->next = tlid_temp;
+                        }
+*/
+
+// Try linking it at the beginning of the list instead, which will
+// change the drawing order of the vertices but should be much
+// faster.
+tlid_temp->next = found2->tlid_list;
+found2->tlid_list = tlid_temp;
+
+                    }
+                }
+
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+            }   // End of while
+        }
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"                CompleteChain Layer ");
+
+
+        // Run through the CompleteChain layer.  Snag TLID, FEDIRP,
+        // FENAME, FETYPE, FEDIRS, and geometry, store it in a new
+        // hash by TLID.
+        //
+        layerH = OGR_DS_GetLayerByName(datasourceH, "CompleteChain");
+        if (layerH) {
+            tlidinfo *temp;
+
+            // Create a new hash table with TLID as the hash key.
+            while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+                int kk;
+
+                kk = OGR_F_GetFieldIndex( featureH, "TLID");
+                if (kk != -1) {
+                    int ll,mm,nn,oo;
+                    int tlid;
+                    const char *fedirp;
+                    const char *fename;
+                    const char *fetype;
+                    const char *fedirs;
+                    OGRGeometryH geometryH;
+ 
+
+                    tlid = OGR_F_GetFieldAsInteger(featureH, kk);
+ 
+                    // Allocate struct
+                    temp = (tlidinfo *)malloc(sizeof(tlidinfo));
+                    temp->TLID = tlid;
+                    temp->FEDIRP[0] = '\0';
+                    temp->FENAME[0] = '\0';
+                    temp->FETYPE[0] = '\0';
+                    temp->FEDIRS[0] = '\0';
+                    temp->geometryH = NULL;
+
+//fprintf(stderr,"TLID:%i\n", tlid);
+
+                    ll = OGR_F_GetFieldIndex( featureH, "FEDIRP");
+                    mm = OGR_F_GetFieldIndex( featureH, "FENAME");
+                    nn = OGR_F_GetFieldIndex( featureH, "FETYPE");
+                    oo = OGR_F_GetFieldIndex( featureH, "FEDIRS");
+ 
+                    if (ll != -1) {
+                        fedirp = OGR_F_GetFieldAsString( featureH, ll);
+                        if (fedirp != NULL) {
+                            xastir_snprintf(temp->FEDIRP,
+                                sizeof(temp->FEDIRP),
+                                "%s",
+                                fedirp);
+                        }
+                    }
+                    if (mm != -1) {
+                        fename = OGR_F_GetFieldAsString( featureH, mm);
+                        if (fename != NULL) {
+                            xastir_snprintf(temp->FENAME,
+                                sizeof(temp->FENAME),
+                                "%s",
+                                fename);
+                        }
+                    }
+                    if (nn != -1) {
+                        fetype = OGR_F_GetFieldAsString( featureH, nn);
+                        if (fetype != NULL) {
+                            xastir_snprintf(temp->FETYPE,
+                                sizeof(temp->FETYPE),
+                                "%s",
+                                fetype);
+                        }
+                    }
+                    if (oo != -1) {
+                        fedirs = OGR_F_GetFieldAsString( featureH, oo);
+                        if (fedirs != NULL) {
+                            xastir_snprintf(temp->FEDIRS,
+                                sizeof(temp->FEDIRS),
+                                "%s",
+                                fedirs);
+                        }
+                    }
+
+
+                    // Get a handle to the geometry itself, make a
+                    // clone of it and tie it to the struct.
+                    geometryH = OGR_F_GetGeometryRef(featureH);
+                    if (geometryH) {
+                        temp->geometryH = OGR_G_Clone(geometryH);
+                    }
+
+
+                    // Insert a new value into the hash
+// Remember to free() the hash storage later
+                    if (!hashtable_insert(tlid_hash,&temp->TLID, temp)) {
+                        fprintf(stderr,"Couldn't insert into tlid_hash\n");
+                        free(temp);
+                    }
+                }
+
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+            }   // End of while
+
+            // Restart reads of this layer at the first feature.
+            OGR_L_ResetReading(layerH);
+
+        }   // End of CompleteChain layer section
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"Combine Hashes, Create/Draw Polygon ");
+
+
+        // We have two hashes with part of the info in each of them.
+        // We should be able to iterate through the polyid_hash,
+        // snag the TLID parameters out of each polygon, and then
+        // snag the geometry for each TLID out of the tlid_hash.
+        // Through this method we can draw each polygon one at a
+        // time by creating a polygon geometry out of each one.
+
+        // Iterate over the polyid_hash, drawing polygons as we go.
+        //
+        if (hashtable_count(polyid_hash) > 0) {
+//fprintf(stderr,"polyid_hash\n");
+            iterator = hashtable_iterator(polyid_hash);
+//fprintf(stderr,"got iterator\n");
+            do {
+                polyinfo *record;
+                tlid_struct *head;
+                OGRGeometryH collectionH;
+                OGRGeometryH newpolygonH;
+                OGRErr error;
+
+
+                record = hashtable_iterator_value(iterator);
+
+//fprintf(stderr,"got record\n");
+
+
+// Create an empty geometry collection that we can add other
+// geometries to.
+                collectionH = OGR_G_CreateGeometry(wkbGeometryCollection);
+
+                if (collectionH == NULL)
+                    fprintf(stderr,"collectionH is empty\n");
+
+
+                // Iterate through the tlid_list linked list.  Look
+                // up each TLID in the tlid_hash.
+                head = record->tlid_list;
+                while (head) {
+                    tlidinfo *found;
+                    OGRErr error;
+
+                    // Find this TLID in the tlid_hash
+                    found = hashtable_search(tlid_hash, &head->TLID);
+                    if (found) {    // Found a match!
+//fprintf(stderr,"T");
+                        // Snag the geometry associated with this
+                        // TLID.  Add it to the geometry collection
+                        // for this POLYID.
+                        error = OGR_G_AddGeometry(collectionH,
+                            found->geometryH);
+                        if (error != OGRERR_NONE)
+                            fprintf(stderr,
+                                "OGR_G_AddGeometry: Unsupported geometry type?\n");
+                    }
+                    else {
+//fprintf(stderr,"?");
+                    }
+ 
+                    // Skip to the next tlid entry
+                    head = head->next;
+                }
+
+
+// Create a polygon geometry out of the geometry collection.
+                newpolygonH = OGRBuildPolygonFromEdges(collectionH,
+                    1,        // bBestEffort
+                    1,        // bAutoClose
+                    0.0,   // dfTolerance
+                    &error);  // OGRerr
+                if (error == OGRERR_NONE) {
+//fprintf(stderr,"\t\t\tCreated polygon!\n");
+                }
+                else {
+                    fprintf(stderr,"Failed to create polygon!\n");
+                }
+
+
+                // Draw the polygons.  All of the information to do
+                // so is available now.
+/*
+                guess_vector_attributes(w,
+                    driver_type,
+                    full_filename,
+                    layerH,
+                    featureH,
+                    geometry_type);
+*/
+
+// For testing purposes only draw the water polygons.
+
+//if (record->WATER > 0 && record->CFCC[0] != 'H')
+//    fprintf(stderr,"WATER polygon but no \'H\' CFCC!  CFCC=%s\n", record->CFCC);
+
+                if (record->WATER > 0 || record->CFCC[0] == 'H') {
+
+                    if (strncasecmp(record->CFCC,"H81",3) == 0) { // glacier
+                        label_color_guess = 0x4d;   // white
+//fprintf(stderr,"CFCC:%s\t", record->CFCC);
+//fprintf(stderr,"%s\n", record->LANAME);
+                    }
+                    else {
+                        label_color_guess = 0x1a;   // Steel Blue
+                    }
+ 
+                    if (label_color_guess != -1) {
+                        Draw_OGR_Polygons(w,
+                            //featureH,
+                            NULL,
+                            newpolygonH,
+                            1,
+                            transformH,
+                            draw_filled,
+                            //fast_extents);
+                            1);
+                    }
+                }
+
+
+                // Free the polygon structure
+                OGR_G_DestroyGeometry(newpolygonH);
+
+                // Free the geometry collection structure
+                OGR_G_DestroyGeometry(collectionH);
+
+            // Free the current hash element, advance to the next
+            } while (hashtable_iterator_advance(iterator));
+#ifndef USING_LIBGC
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+        }
+
+
+stop_timer(); print_timer_results(); start_timer();
+fprintf(stderr,"               Free'ing hash memory ");
+
+
+        // Free the memory we've allocated for the hashes.
+
+
+        // Iterate over the polyid_hash, free'ing the tlid_struct's
+        // that we allocated.  Don't remove the hash entry or free
+        // the polyinfo struct inside the loop as that will break
+        // the iterator.
+        //
+//fprintf(stderr,"Hash elements: polyid:%6i   ", hashtable_count(polyid_hash));
+        if (hashtable_count(polyid_hash) > 0) {
+            iterator = hashtable_iterator(polyid_hash);
+            do {
+                polyinfo *record;
+                tlid_struct *head;
+                tlid_struct *p;
+
+                record = hashtable_iterator_value(iterator);
+
+                // Free the tlid_struct linked list
+                head = record->tlid_list;
+                while (head) {
+//fprintf(stderr,"TLID ");
+                    p = head;
+                    head = head->next;
+                    free(p);
+                }
+
+            // Free the current hash element, advance to the next
+            } while (hashtable_iterator_remove(iterator));
+#ifndef USING_LIBGC
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+        }
+        // polyid_hash should be empty at this point.
+
+
+        // Iterate over the tlid_hash, free'ing the geometry memory
+        // that we allocated.  Don't remove the hash entry or free
+        // the tlidinfo struct inside the loop as that will break
+        // the iterator.
+        //
+//fprintf(stderr,"tlid:%6i   ", hashtable_count(tlid_hash));
+        if (hashtable_count(tlid_hash) > 0) {
+            iterator = hashtable_iterator(tlid_hash);
+            do {
+                tlidinfo *record;
+
+                record = hashtable_iterator_value(iterator);
+
+                // Free the geometry structure
+                OGR_G_DestroyGeometry(record->geometryH);
+
+            // Free the current hash element, advance to the next
+            } while (hashtable_iterator_remove(iterator));
+
+#ifndef USING_LIBGC
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+        }
+        // tlid_hash should be empty at this point.
+
+
+        // Iterate over the landmark_hash, free'ing the memory
+        // that we allocated.  Don't remove the hash entry of free
+        // the landmarkinfo struct inside the loop as that will
+        // break the iterator.
+        //
+//fprintf(stderr,"landmark:%6i\n", hashtable_count(landmark_hash));
+        if (hashtable_count(landmark_hash) > 0) {
+            iterator = hashtable_iterator(landmark_hash);
+            do {
+            // Free the current hash element, advance to the next
+            } while (hashtable_iterator_remove(iterator));
+#ifndef USING_LIBGC
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+        }
+        // landmark_hash should be empty at this point.
+
+
+        // Destroy the hash tables.  If the second argument is a
+        // one, it indicates that the values should be free'd as
+        // well.
+        //
+        hashtable_destroy(polyid_hash, 1);
+        hashtable_destroy(tlid_hash, 1);
+        hashtable_destroy(landmark_hash, 1);
+
+
+stop_timer(); print_timer_results();
+//fprintf(stderr,"Done\n");
+
+
+    }   // End of special TIGER section
+
+#endif  // TIGER_POLYGONS
+
+
+
+
+
+
+
+
+
+
+    // Loop through all layers in the data source.
+    //
+    // Optimizations:
+    //   SDTS, load only those layers that make sense.
+    //   TIGER, same thing, based on the type of file.  We probably need
+    //     to do some serious changes to how we do TIGER layers anyway,
+    //     as we have to pull multiple things together in order to draw
+    //     polygons.
+    //
+    for ( ii=0; ii<numLayers; ii++ ) {
+        OGRLayerH layerH;
+        OGRFeatureH featureH;
+//        OGRFeatureDefnH layerDefn;
+        OGREnvelope psExtent;  
+        int extents_found = 0;
+        char geometry_type_name[50] = "";
+        int geometry_type = -1;
+        int fast_extents = 0;
+        int features_processed = 0;
+        const char *layer_name;
+        
+
+//fprintf(stderr,"Layer %d:\n", ii); 
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+
+            if (wgs84_spatialH != NULL) {
+                OSRDestroySpatialReference(wgs84_spatialH);
+            }
+
+//            if (transformH != NULL) {
+//                OCTDestroyCoordinateTransformation(transformH);
+//            }
+
+//            if (reverse_transformH != NULL) {
+//                OCTDestroyCoordinateTransformation(reverse_transformH);
+//            }
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+        layerH = OGR_DS_GetLayer( datasourceH, ii );
+
+        if (layerH == NULL) {
+            if (debug_level & 16) {
+                fprintf(stderr,
+                    "Unable to open layer %d of %s\n",
+                    ii,
+                   full_filename);
+            }
+
+            if (wgs84_spatialH != NULL) {
+                OSRDestroySpatialReference(wgs84_spatialH);
+            }
+
+//            if (transformH != NULL) {
+//                OCTDestroyCoordinateTransformation(transformH);
+//            }
+
+//            if (reverse_transformH != NULL) {
+//                OCTDestroyCoordinateTransformation(reverse_transformH);
+//            }
+
+            // Close data source
+            if (datasourceH != NULL) {
+                OGR_DS_Destroy( datasourceH );
+            }
+
+            return; // Exit early
+        }
+
+
+        // Determine what kind of layer we're dealing with and set
+        // some flags.
+        //
+        layer_name = OGR_FD_GetName( OGR_L_GetLayerDefn( layerH ) );
+
+        if (layer_name != NULL) {
+
+//fprintf(stderr,"Layer %i: %s\n", ii, layer_name);
+
+            if (strcasecmp(driver_type,"SDTS") == 0) {
+                //
+                // Layer  0: ARDF Roads/Trails Layer
+                // Layer  1: ARRF Railroad Layer
+                // Layer  2: AMTF Misc Transportation Layer
+                // Layer  3: ARDM
+                // Layer  4: ACOI
+                // Layer  5: AHDR
+                // Layer  6: NP01
+                // Layer  7: NP02
+                // Layer  8: NP03
+                // Layer  9: NP04
+                // Layer 10: NP05
+                // Layer 11: NP06
+                // Layer 12: NP07
+                // Layer 13: NP08
+                // Layer 14: NP09
+                // Layer 15: NP10
+                // Layer 16: NP11
+                // Layer 17: NP12
+                // Layer 18: NA01
+                // Layer 19: NA02
+                // Layer 20: NA03
+                // Layer 21: NA04
+                // Layer 22: NA05
+                // Layer 23: NA06
+                // Layer 24: NA07
+                // Layer 25: NA08
+                // Layer 26: NA09
+                // Layer 27: NA10
+                // Layer 28: NA11
+                // Layer 29: NA12
+                // Layer 30: NO01
+                // Layer 31: NO02
+                // Layer 32: NO03
+                // Layer 33: NO04
+                // Layer 34: NO05
+                // Layer 35: NO06
+                // Layer 36: NO07
+                // Layer 37: NO08
+                // Layer 38: NO09
+                // Layer 39: NO10
+                // Layer 40: NO11
+                // Layer 41: NO12
+                // Layer 42: LE01
+                // Layer 43: LE02
+                // Layer 44: LE03
+                // Layer 45: LE04
+                // Layer 46: LE05
+                // Layer 47: LE06
+                // Layer 48: LE07
+                // Layer 49: LE08
+                // Layer 50: LE09
+                // Layer 51: LE10
+                // Layer 52: LE11
+                // Layer 53: LE12
+                // Layer 54: PC01
+                // Layer 55: PC02
+                // Layer 56: PC03
+                // Layer 57: PC04
+                // Layer 58: PC05
+                // Layer 59: PC06
+                // Layer 60: PC07
+                // Layer 61: PC08
+                // Layer 62: PC09
+                // Layer 63: PC10
+                // Layer 64: PC11
+                // Layer 65: PC12
+                //
+                if (strncasecmp(layer_name,"AHPF",4) == 0) {
+                    hypsography_layer++;    // Topo contours
+                    fprintf(stderr,"Hypsography Layer (topo contours)\n");
+                }
+                else if (strncasecmp(layer_name,"AHYF",4) == 0) {
+                    hydrography_layer++;    // Underwater contours
+                    fprintf(stderr,"Hydrography Layer (underwater topo contours)\n");
+                }
+                else if (strncasecmp(layer_name,"ARDF",4) == 0) {
+                    roads_trails_layer++;
+                    fprintf(stderr,"Roads/Trails Layer\n");
+                }
+                else if (strncasecmp(layer_name,"ARRF",4) == 0) {
+                    railroad_layer++;
+                    fprintf(stderr,"Railroad Layer\n");
+                }
+                else if (strncasecmp(layer_name,"AMTF",4) == 0) {
+                    misc_transportation_layer++;
+                    fprintf(stderr,"Misc Transportation Layer\n");
+                }
+            }
+            else if (strcasecmp(driver_type,"TIGER") == 0) {
+                //
+                // Layer  0: CompleteChain
+                // Layer  1: AltName
+                // Layer  2: FeatureIds
+                // Layer  3: ZipCodes
+                // Layer  4: Landmarks
+                // Layer  5: AreaLandmarks
+                // Layer  6: Polygon
+                // Layer  7: PolygonCorrections
+                // Layer  8: EntityNames
+                // Layer  9: PolygonEconomic
+                // Layer 10: IDHistory
+                // Layer 11: PolyChainLink
+                // Layer 12: PIP
+                // Layer 13: TLIDRange
+                // Layer 14: ZeroCellID
+                // Layer 15: OverUnder
+                // Layer 16: ZipPlus4
+                //
+                if (strncasecmp(layer_name,"AltName",7) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"ZipCodes",8) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"Landmarks",9) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"PolygonCorrections",18) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"AreaLandmarks",13) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"PolygonEconomic",15) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"IDHistory",9) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"ZeroCellID",10) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"OverUnder",9) == 0) {
+                    continue;   // Skip this layer
+                }
+                else if (strncasecmp(layer_name,"ZipPlus4",8) == 0) {
+                    continue;   // Skip this layer
+                }
+            }
+        }
+
+
+//fprintf(stderr,"    Processing Layer %i\n", ii);
+
+
+
+        // Set up the coordinate translations we may need for both
+        // indexing and drawing operations.  It sets up the
+        // transform and the reverse transforms we need to convert
+        // between the spatial coordinate systems.
+        //
+        setup_coord_translation(datasourceH, // Input
+            layerH,                          // Input
+            &map_spatialH,                   // Output
+            &transformH,                     // Output
+            &reverse_transformH,             // Output
+            &wgs84_spatialH,                 // Output
+            &no_spatial,                     // Output
+            &geographic,                     // Output
+            &projected,                      // Output
+            &local,                          // Output
+            datum,                           // Output
+            geogcs);                         // Output
+
+
+        // Snag the original values (again if 2nd or later loop
+        // iteration).
+        ViewX2[0] = ViewX[0];
+        ViewX2[1] = ViewX[1];
+        ViewY2[0] = ViewY[0];
+        ViewY2[1] = ViewY[1];
+        if (reverse_transformH) {
+            // Convert our view coordinates from WGS84 to this map
+            // layer's coordinates.
+            if (!OCTTransform(reverse_transformH, 2, ViewX2, ViewY2, ViewZ2)) {
+                fprintf(stderr,
+                    "Couldn't convert points from WGS84 to map's spatial reference\n");
+                // Use the coordinates anyway (don't exit).  We may be
+                // lucky enough to have things work anyway.
+            }
+            // Get rid of our reverse transform.  We shan't need it
+            // again.
+            OCTDestroyCoordinateTransformation(reverse_transformH);
+            reverse_transformH = NULL;
+        }
+
+//fprintf(stderr,"%2.5f %2.5f   %2.5f %2.5f\n",
+//    ViewY2[0], ViewX2[0], ViewY2[1], ViewX2[1]);
+
+
+        // Add these converted points to the spatial_filter_geometry so
+        // that we can set our spatial filter in the layer loop below.
+        // Snag the spatial reference from the map dataset 'cuz they
+        // should match now.
+        //
+        spatial_filter_geometryH = OGR_G_CreateGeometry(2); // LineString Type
+
+        // Use the map spatial geometry so that we match the map
+        OGR_G_AssignSpatialReference(spatial_filter_geometryH, map_spatialH);
+
+        // Add the corners of the viewport
+        OGR_G_AddPoint(spatial_filter_geometryH, ViewX2[0], ViewY2[0], ViewZ2[0]);
+        OGR_G_AddPoint(spatial_filter_geometryH, ViewX2[0], ViewY2[1], ViewZ2[1]);
+        OGR_G_AddPoint(spatial_filter_geometryH, ViewX2[1], ViewY2[1], ViewZ2[0]);
+        OGR_G_AddPoint(spatial_filter_geometryH, ViewX2[1], ViewY2[0], ViewZ2[1]);
+
+        // Set spatial filter so that the GetNextFeature() call will
+        // only return features that are within our view.  Note that
+        // the geometry used here should be in the same spacial
+        // reference system as the layer itself, so we need to
+        // convert our coordinates into the map coordinates before
+        // setting the filter.  We do this coordinate conversion and
+        // create the geometry outside the layer loop to save some
+        // time, then just set the spatial filter with the same
+        // geometry for each iteration.
+        //
+        // Note that this spatial filter doesn't strictly filter at
+        // the borders specified, but it does filter out a lot of
+        // the features that are outside our borders.  This speeds
+        // up map drawing tremendously!
+        //
+        OGR_L_SetSpatialFilter( layerH, spatial_filter_geometryH);
+
+ 
+
+        // Test the capabilities of the layer to know the best way
+        // to access it:
+        //
+        //   OLCRandomRead: TRUE if the OGR_L_GetFeature() function works
+        //   for this layer.
+        //   NOTE: Tiger and Shapefile report this as TRUE.
+        //
+        //   OLCFastSpatialFilter: TRUE if this layer implements spatial
+        //   filtering efficiently.
+        //
+        //   OLCFastFeatureCount: TRUE if this layer can return a feature
+        //   count (via OGR_L_GetFeatureCount()) efficiently.  In some cases
+        //   this will return TRUE until a spatial filter is installed after
+        //   which it will return FALSE.
+        //   NOTE: Tiger and Shapefile report this as TRUE.
+        //
+        //   OLCFastGetExtent: TRUE if this layer can return its data extent
+        //   (via OGR_L_GetExtent()) efficiently ... ie. without scanning
+        //   all the features. In some cases this will return TRUE until a
+        //   spatial filter is installed after which it will return FALSE.
+        //   NOTE: Shapefile reports this as TRUE.
+        //
+        if (ii == 0) {   // First layer
+            if (debug_level & 16)
+                fprintf(stderr, "  ");
+            if (OGR_L_TestCapability(layerH, OLCRandomRead)) {
+                if (debug_level & 16)
+                    fprintf(stderr, "Random Read, ");
+            }
+            if (OGR_L_TestCapability(layerH, OLCFastSpatialFilter)) {
+                if (debug_level & 16)
+                    fprintf(stderr,
+                        "Fast Spatial Filter, ");
+            }
+            if (OGR_L_TestCapability(layerH, OLCFastFeatureCount)) {
+                if (debug_level & 16)
+                    fprintf(stderr,
+                        "Fast Feature Count, ");
+            }
+            if (OGR_L_TestCapability(layerH, OLCFastGetExtent)) {
+                if (debug_level & 16)
+                    fprintf(stderr,
+                        "Fast Get Extent, ");
+                // Save this away and decide whether to
+                // request/compute extents based on this.
+                fast_extents = 1;
+            }
+        }
+
+
+/*
+        if (map_spatialH) {
+            const char *temp;
+            int geographic = 0;
+            int projected = 0;
+
+
+            if (OSRIsGeographic(map_spatialH)) {
+                if (ii == 0) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"  Geographic Coord, ");
+                }
+                geographic++;
+            }
+            else if (OSRIsProjected(map_spatialH)) {
+                if (ii == 0) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"  Projected Coord, ");
+                }
+                projected++;
+            }
+            else {
+                if (ii == 0) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"  Local Coord, ");
+                }
+            }
+
+            // PROJCS, GEOGCS, DATUM, SPHEROID, PROJECTION
+            //
+            temp = OSRGetAttrValue(map_spatialH, "DATUM", 0);
+            if (ii == 0) {
+                if (debug_level & 16)
+                    fprintf(stderr,"DATUM: %s, ", temp);
+            }
+
+            if (projected) {
+                temp = OSRGetAttrValue(map_spatialH, "PROJCS", 0);
+                if (ii == 0) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"PROJCS: %s, ", temp);
+                }
+ 
+                temp = OSRGetAttrValue(map_spatialH, "PROJECTION", 0);
+                if (ii == 0) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"PROJECTION: %s, ", temp);
+                }
+            }
+
+            temp = OSRGetAttrValue(map_spatialH, "GEOGCS", 0);
+            if (ii == 0) {
+                if (debug_level & 16)
+                    fprintf(stderr,"GEOGCS: %s, ", temp);
+            }
+
+            temp = OSRGetAttrValue(map_spatialH, "SPHEROID", 0);
+            if (ii == 0) {
+                if (debug_level & 16)
+                    fprintf(stderr,"SPHEROID: %s, ", temp);
+            }
+
+        }
+        else {
+            if (ii == 0) {
+                if (debug_level & 16)
+                    fprintf(stderr,"  No Spatial Info, ");
+                // Assume geographic/WGS84 unless the coordinates go
+                // outside the range of lat/long, in which case,
+                // exit.
+            }
+        }
+*/
+
+
+
+        // Get the extents for this layer.  OGRERR_FAILURE means
+        // that the layer has no spatial info or that it would be
+        // an expensive operation to establish the extent.
+        //OGRErr OGR_L_GetExtent(OGRLayerH hLayer, OGREnvelope *psExtent, int bForce);
+        if (OGR_L_GetExtent(layerH, &psExtent, FALSE) != OGRERR_FAILURE) {
+            // We have extents.  Check whether any part of the layer
+            // is within our viewport.
+            if (ii == 0) {
+                if (debug_level & 16)
+                    fprintf(stderr, "Extents obtained.");
+            }
+            extents_found++;
+        }
+        if (ii == 0) {
+            if (debug_level & 16)
+                fprintf(stderr, "\n");
+        }
+
+
+/*
+        if (extents_found) {
+            fprintf(stderr,
+                "  MinX: %f, MaxX: %f, MinY: %f, MaxY: %f\n",
+                psExtent.MinX,
+                psExtent.MaxX,
+                psExtent.MinY,
+                psExtent.MaxY);
+        }
+*/
+
+
+// Dump info about this layer
+/*
+        layerDefn = OGR_L_GetLayerDefn( layerH );
+        if (layerDefn != NULL) {
+            int jj;
+            int numFields;
+ 
+            numFields = OGR_FD_GetFieldCount( layerDefn );
+
+            fprintf(stderr,"  Layer %d: '%s'\n", ii, OGR_FD_GetName(layerDefn));
+
+            for ( jj=0; jj<numFields; jj++ ) {
+                OGRFieldDefnH fieldDefn;
+
+                fieldDefn = OGR_FD_GetFieldDefn( layerDefn, jj );
+                fprintf(stderr,"    Field %d: %s (%s)\n", 
+                       jj, OGR_Fld_GetNameRef(fieldDefn), 
+                       OGR_GetFieldTypeName(OGR_Fld_GetType(fieldDefn)));
+            }
+            fprintf(stderr,"\n");
+        }
+
+
+        // Restart reads of this layer at the first feature.
+        //OGR_L_ResetReading(layerH);
+*/
+
+
+
+// Optimization:  Get the envelope for each feature, skip the
+// feature if it's completely outside our viewport.
+
+        // Loop through all of the features in the layer.
+        //
+//        if ( (featureH = OGR_L_GetNextFeature( layerH ) ) != NULL ) {
+//if (0) {
+        while ( (featureH = OGR_L_GetNextFeature( layerH )) != NULL ) {
+            OGRGeometryH geometryH;
+            int num = 0;
+//            char *buffer;
+
+
+features_processed++;
+ 
+            HandlePendingEvents(app_context);
+            if (interrupt_drawing_now) {
+                if (featureH != NULL)
+                    OGR_F_Destroy( featureH );
+
+                if (wgs84_spatialH != NULL) {
+                    OSRDestroySpatialReference(wgs84_spatialH);
+                }
+
+                if (transformH != NULL) {
+                    OCTDestroyCoordinateTransformation(transformH);
+                }
+
+//                if (reverse_transformH != NULL) {
+//                    OCTDestroyCoordinateTransformation(reverse_transformH);
+//                }
+
+                // Close data source
+                if (datasourceH != NULL) {
+                    OGR_DS_Destroy( datasourceH );
+                }
+
+                return; // Exit early
+            }
+
+            if (featureH == NULL) {
+                continue;
+            }
+
+
+// Debug code
+//OGR_F_DumpReadable( featureH, stderr );
+
+
+            // Get a handle to the geometry itself
+            geometryH = OGR_F_GetGeometryRef(featureH);
+            if (geometryH == NULL) {
+                OGR_F_Destroy( featureH );
+//                if (strlen(geometry_type_name) == 0) {
+                if (debug_level & 16)
+                    fprintf(stderr,"  Layer %02d:   - No geometry info -\n", ii);
+//                    geometry_type_name[0] = ' ';
+//                    geometry_type_name[1] = '\0';
+//                }
+// Break out of this loop.  We don't know how to draw anything but
+// geometry features yet.  Change this when we start drawing labels.
+                break;
+//                continue;
+            }
+
+
+
+            // More debug code.  Print the Well Known Text
+            // representation of the geometry.
+            //if (OGR_G_ExportToWkt(geometryH, &buffer) == 0) {
+            //    fprintf(stderr, "%s\n", buffer);
+            //}
+
+
+            // These are from the OGRwkbGeometryType enumerated set
+            // in ogr_core.h:
+            //
+            //          0 "Unknown"
+            //          1 "POINT"              (ogrpoint.cpp)
+            //          2 "LINESTRING"         (ogrlinestring.cpp)
+            //          3 "POLYGON"            (ogrpolygon.cpp)
+            //          4 "MULTIPOINT"         (ogrmultipoint.cpp)
+            //          5 "MULTILINESTRING"    (ogrmultilinestring.cpp)
+            //          6 "MULTIPOLYGON"       (ogrmultipolygon.cpp)
+            //          7 "GEOMETRYCOLLECTION" (ogrgeometrycollection.cpp)
+            //        100 "None"
+            //        101 "LINEARRING"         (ogrlinearring.cpp)
+            // 0x80000001 "Point25D"
+            // 0x80000002 "LineString25D"
+            // 0x80000003 "Polygon25D"
+            // 0x80000004 "MultiPoint25D"
+            // 0x80000005 "MultiLineString25D"
+            // 0x80000006 "MultiPolygon25D"
+            // 0x80000007 "GeometryCollection25D"
+            //
+            // The geometry type will be the same for any particular
+            // layer.  We take advantage of that here by querying
+            // once per layer and saving the results in variables.
+            //
+            if (strlen(geometry_type_name) == 0) {
+                xastir_snprintf(geometry_type_name,
+                    sizeof(geometry_type_name),
+                    "%s",
+                    OGR_G_GetGeometryName(geometryH));
+                geometry_type = OGR_G_GetGeometryType(geometryH);
+//                fprintf(stderr,"  Layer %02d: ", ii); 
+//                fprintf(stderr,"  Type: %d, %s\n",  
+//                    geometry_type,
+//                    geometry_type_name);
+            }
+
+// Debug code 
+//OGR_G_DumpReadable(geometryH, stderr, "Shape: ");
+
+
+
+// We could call OGR_G_GetEnvelope() here and calculate for
+// ourselves it if is in our viewport, or we could set a filter and
+// let the library pass us only those that fit.
+//
+// If point or line feature, draw in normal manner.  If polygon
+// feature, do the "rotation one way = fill, rotation the other way
+// = hole" thing?
+//
+// We need all of the coordinates in WGS84 lat/long.  Use the
+// conversion code that's in the indexing portion of this routine to
+// accomplish this.
+
+
+            switch (geometry_type) {
+
+                case 1:             // Point
+                case 4:             // MultiPoint
+                case 0x80000001:    // Point25D
+                case 0x80000004:    // MultiPoint25D
+
+                    // Do this one time for the file itself to get
+                    // some usable defaults.
+                    guess_vector_attributes(w,
+                        driver_type,
+                        full_filename,
+                        layerH,
+                        featureH,
+                        geometry_type);
+
+                    if (label_color_guess != -1) {
+                        Draw_OGR_Points(w,
+                            featureH,
+                            geometryH,
+                            1,
+                            transformH);
+                    }
+                    break;
+
+                case 2:             // LineString (polyline)
+                case 5:             // MultiLineString
+                case 0x80000002:    // LineString25D
+                case 0x80000005:    // MultiLineString25D
+
+                    // Do this one time for the file itself to get
+                    // some usable defaults.
+                    guess_vector_attributes(w,
+                        driver_type,
+                        full_filename,
+                        layerH,
+                        featureH,
+                        geometry_type);
+
+                    // Special handling for TIGER water polygons,
+                    // which are represented as polylines instead of
+                    // polygons.
+                    //
+// How do we get the TIGER water drawn as filled polygons???
+                    //
+                    if (label_color_guess != -1) {
+                        if (water_layer && strstr(driver_type,"TIGER")) {
+//fprintf(stderr,"TIGER water layer\n");
+
+                            Draw_OGR_Lines(w,
+                                featureH,
+                                geometryH,
+                                1,
+                                transformH,
+                                fast_extents);
+                        }
+                        else {  // Normal processing
+                            Draw_OGR_Lines(w,
+                                featureH,
+                                geometryH,
+                                1,
+                                transformH,
+                                fast_extents);
+                        }
+                    }
+                    break;
+
+                case 3:             // Polygon
+                case 6:             // MultiPolygon
+                case 0x80000003:    // Polygon25D
+                case 0x80000006:    // MultiPolygon25D
+
+                    // Do this one time for the file itself to get
+                    // some usable defaults.
+                    guess_vector_attributes(w,
+                        driver_type,
+                        full_filename,
+                        layerH,
+                        featureH,
+                        geometry_type);
+
+                    if (label_color_guess != -1) {
+                        Draw_OGR_Polygons(w,
+                            featureH,
+                            geometryH,
+                            1,
+                            transformH,
+                            draw_filled,
+                            fast_extents);
+                    }
+                    break;
+
+                case 7:             // GeometryCollection
+                case 0x80000007:    // GeometryCollection25D
+                default:            // Unknown/Unimplemented
+
+                    num = 0;
+                    if (debug_level & 16)
+                        fprintf(stderr,"  Unknown or unimplemented geometry\n");
+                    break;
+            }
+            if (featureH)
+                OGR_F_Destroy( featureH );
+        }   // End of feature loop
+        // No need to free layerH handle, it belongs to the datasource
+
+//fprintf(stderr,"Features Processed: %d\n\n", features_processed);
+    } // End of layer loop
+
+    if (transformH != NULL) {
+        OCTDestroyCoordinateTransformation(transformH);
+    }
+
+//    if (reverse_transformH != NULL) {
+//        OCTDestroyCoordinateTransformation(reverse_transformH);
+//    }
+
+    if (wgs84_spatialH != NULL) {
+        OSRDestroySpatialReference(wgs84_spatialH);
+    }
+
+    // Close data source
+    if (datasourceH != NULL) {
+        OGR_DS_Destroy( datasourceH );
+    }
+}
+
+
+
+#endif // HAVE_LIBGDAL
+
+
diff --git a/src/map_geo.c b/src/map_geo.c
new file mode 100644
index 0000000..c1dea05
--- /dev/null
+++ b/src/map_geo.c
@@ -0,0 +1,2550 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_geo.c,v 1.109 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+//#define FUZZYRASTER
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "map_cache.h"
+#include "alert.h"
+#include "fetch_remote.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+#include "map_OSM.h"
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+
+// Check for XPM and/or ImageMagick.  We use "NO_GRAPHICS"
+// to disable some routines below if the support for them
+// is not compiled in.
+#if !(defined(HAVE_LIBXPM) || defined(HAVE_LIBXPM_IN_XM) || defined(HAVE_MAGICK))
+  #define NO_GRAPHICS 1
+#endif  // !(HAVE_LIBXPM || HAVE_LIBXPM_IN_XM || HAVE_MAGICK)
+
+#if !(defined(HAVE_LIBXPM) || defined(HAVE_LIBXPM_IN_XM))
+  #define NO_XPM 1
+#endif  // !(HAVE_LIBXPM || HAVE_LIBXPM_IN_XM)
+
+
+#ifdef HAVE_MAGICK
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+#undef RETSIGTYPE
+// TVR: "stupid ImageMagick"
+// The problem is that magick/api.h includes Magick's config.h file, and that
+// pulls in all the same autoconf-generated defines that we use.
+// plays those games below, but I don't think in the end that they actually 
+// make usable macros with our own data in them.
+// Fortunately, we don't need them, so I'll just undef the ones that are
+// causing problems today.  See main.c for fixes that preserve our values.
+#undef PACKAGE
+#undef VERSION
+/* JMT - stupid ImageMagick */
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#ifdef HAVE_GRAPHICSMAGICK
+/*#include <GraphicsMagick/magick/api.h>*/
+/* Define MAGICK_IMPLEMENTATION to access private interfaces
+ * such as DestroyImagePixels(). This may not be a good thing,
+ * but DestroyImagePixels() has been in this code for a long
+ * time. Defining MAGIC_IMPLEMENTATION eliminates the warning that is
+ * now (9/28/2010) being seen on some distros (Ubuntu 10.04 and
+ * OpenSuSE-11.3)
+ */
+#define MAGICK_IMPLEMENTATION
+#include <magick/api.h>
+#else   // HAVE_GRAPHICSMAGICK
+#include <magick/api.h>
+#endif  // HAVE_GRAPHICSMAGICK
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#endif // HAVE_MAGICK
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+int check_interrupt( 
+#ifdef HAVE_MAGICK
+			Image *image, ImageInfo *image_info, ExceptionInfo *exception, 
+#else // HAVE_MAGICK
+			XImage *xi,
+#endif // HAVE_MAGICK
+			Widget *da, Pixmap *pixmap, 
+			GC *gc, unsigned long screen_width, unsigned long screen_height)
+{
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+#ifdef HAVE_MAGICK
+        if (image) 
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+ #else   // HAVE_MAGICK
+    if (xi)
+        XDestroyImage (xi);
+#endif // HAVE_MAGICK
+        // Update to screen
+        (void)XCopyArea(XtDisplay(*da),
+            *pixmap,
+            XtWindow(*da),
+            *gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+#ifdef HAVE_MAGICK
+       DestroyExceptionInfo(exception);
+#endif // HAVE_MAGICK
+         return(~0);
+    } else
+	return(0);
+}
+
+void draw_geo_image_map (Widget w, char *dir, char *filenm, 
+    alert_entry *alert, u_char alert_color, int destination_pixmap,
+    map_draw_flags *mdf);
+
+
+
+
+
+/*  typedef struct _transparent_color_record{
+        unsigned long trans_color;
+        struct _transparent_color_record *next;
+    } transparent_color_record;
+*/
+    // Pointer to head of transparent color linked list.
+    transparent_color_record *trans_color_head = NULL;
+
+
+
+
+
+    // Empty out the linked list containing transparent colors
+    void empty_trans_color_list(void) {
+        transparent_color_record *p;
+
+        while (trans_color_head != NULL) {
+            p = trans_color_head;
+            trans_color_head = p->next;
+            free(p);
+        }
+    }
+
+
+
+
+
+    // Add a new transparent color to the linked list
+    void new_trans_color(unsigned long trans_color) {
+        transparent_color_record *p;
+
+//fprintf(stderr,"New transparent color: %lx\n", trans_color);
+
+        p = (transparent_color_record *)malloc( sizeof(transparent_color_record) );
+
+        // Fill in value
+        p->trans_color = trans_color;
+
+        // Link it to transparent color list
+        p->next = trans_color_head;
+        trans_color_head = p;
+    }
+ 
+
+
+
+
+/********************(**********************************************
+* check_trans()
+*
+* See if this pixel's color should be transparent
+*
+* We only call this from blocks where ImageMagick is used, so we're
+* ok to use IM calls.
+******************************************(************************/
+
+int check_trans (XColor c, transparent_color_record *c_trans_color_head) {
+    transparent_color_record *p = c_trans_color_head;
+
+    //    fprintf (stderr, "pix = %li,%lx, chk = %li,%lx.\n",c.pixel,c.pixel,c_trans_color,c_trans_color);
+    // A linked list from the geo file of colors to zap.
+
+    //    if ( c.pixel == (unsigned long) 0x000000 ) {
+    //    return 1; // black background
+    //}
+    while (p) {
+        if ( c.pixel == p->trans_color ) {
+            return 1;
+        }
+        p = p->next;
+    }
+
+    return 0; // everything else is OK to draw
+}
+
+
+
+
+
+// Regarding MAP CACHING for toporama maps:  Here we are only
+// snagging a .geo file for toporama from findu.com:  We send the
+// parameters off to findu.com, it computes the .geo file, we
+// download it, then we call draw_geo_image_map() with it.  We would
+// have to cache the .geo files from findu, we'd have to modify them
+// to point to our local cached map file (maybe), and we'd of course
+// have to cache that map image as well.  The image filename on
+// findu changes each time we call with the same parameters, so we'd
+// have to give the image file our own name based on the parameters
+// and write that same name into the cached .geo file.  A bit of
+// work, but it _could_ be done.  Actually, we should be able to map
+// between the original URL we use to request the .GEO file and the
+// final image we received.  That way the name would stay the same
+// each time we made the request.  There may be other things we need
+// from the generated .GEO file though.
+//
+// For this particular case we need to snag a remote .geo file and
+// then start the process all over again.  The URL we'll need to use
+// looks something like this:
+//
+// http://mm.aprs.net/toporama.cgi?set=50|lat=44.59333|lon=-75.72933|width=800|height=600|zoom=1
+//
+// Where the lat/lon are the center of our view, and the
+// width/height depend on our window size.  The "set" parameter
+// decides whether we're fetching 50k or 250k maps.
+//
+void draw_toporama_map (Widget w, 
+        char *dir,
+        char *filenm, 
+        alert_entry *alert,
+        u_char alert_color,
+        int destination_pixmap,
+        map_draw_flags *mdf,
+        int toporama_flag) {    // 50 or 250
+
+#ifdef HAVE_MAGICK
+
+    char fileimg[MAX_FILENAME+1];   // Ascii name of image file, read from GEO file
+    char map_it[MAX_FILENAME];
+    char local_filename[MAX_FILENAME];
+    char file[MAX_FILENAME+1];      // Complete path/name of image file
+    char short_filenm[MAX_FILENAME+1];
+    FILE *f;                        // Filehandle of image file
+    double lat_center = 0;
+    double long_center = 0;
+    double left, right, top, bottom;
+    int my_screen_width, my_screen_height;
+    float my_zoom = 1.0;
+    char temp_file_path[MAX_VALUE];
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+
+    //fprintf(stderr, "Found TOPORAMA in a .geo file, %dk scale\n", toporama_flag);
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        // Force the extents to the edges of the earth for the index
+        // file.
+        index_update_xastir(filenm, // Filename only
+            64800000l,      // Bottom
+            0l,             // Top
+            0l,             // Left
+            129600000l,     // Right
+            0);             // Default Map Level
+
+        // Update statusline
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(map_it,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+
+
+    // Compute the parameters we'll need for the URL, fetch the .geo
+    // file at that address, then pass that .geo file off to
+    // draw_geo_image_map().  This will cause us to fetch the image
+    // file corresponding to the .geo file and display it.  We may
+    // also need to tweak the zoom parameter for our current zoom
+    // level so that things match up properly.
+
+
+    // Compute the center of our view in decimal lat/long.
+    left = (double)((NW_corner_longitude - 64800000l )/360000.0);   // Lat/long Coordinates
+    top = (double)(-((NW_corner_latitude - 32400000l )/360000.0));  // Lat/long Coordinates
+    right = (double)((SE_corner_longitude - 64800000l)/360000.0);//Lat/long Coordinates
+    bottom = (double)(-((SE_corner_latitude - 32400000l)/360000.0));//Lat/long Coordinates
+
+    long_center = (left + right)/2.0l;
+    lat_center  = (top + bottom)/2.0l;
+
+    // We now have the center in decimal lat/long.  We also have the
+    // screen width and height in pixels, which we can use in the
+    // URL as well (depending on the zoom parameter and how to make
+    // the finished display look nice).
+
+
+    // Compute the size of the image we want to snag.  It should be
+    // easy to get darn near anything to work, although the size and
+    // scale of the image will drastically affect how nicely the
+    // finished map display will look.
+
+
+    // Compute the zoom parameter for the URL.
+
+
+    // A test URL that works, just to get things going.  This URL
+    // requests 1:50k scale maps ("set=50").
+    //xastir_snprintf(fileimg, sizeof(fileimg),
+    //    "\"http://mm.aprs.net/toporama.cgi?set=50|lat=44.59333|lon=-75.72933|width=800|height=600|zoom=1\"");
+
+    // Compute our custom URL based on our map view and the
+    // requested map scale.
+    //
+    my_screen_width = (int)screen_width;
+    my_screen_height = (int)screen_height;
+ 
+    if (toporama_flag == 50) {  // 1:50k
+
+        my_zoom = 32.0 / scale_y;
+ 
+        if (scale_y <= 16)
+            my_zoom = 2.0;
+    }
+    else {  // toporama_flag == 250 (1:250k)
+
+        my_zoom = 128.0 / scale_y;
+ 
+        if (scale_y <= 64)
+            my_zoom = 2.0;
+    }
+
+    // Set a max zoom limit so we don't tax the server too much.
+    if (my_zoom < 0.02)
+        my_zoom = 0.02;
+             
+    xastir_snprintf(fileimg, sizeof(fileimg),
+        "http://mm.aprs.net/toporama.cgi?set=%d|lat=%f|lon=%f|width=%d|height=%d|zoom=%0.3f",
+//        "http://www2.findu.com/toporama.cgi?set=%d|lat=%f|lon=%f|width=%d|height=%d|zoom=%0.3f",
+        toporama_flag,  // Scale, 50 or 250
+        lat_center,
+        long_center,
+        my_screen_width,
+        my_screen_height,
+        my_zoom);
+
+//fprintf(stderr,"%s\n", fileimg);
+
+    // Create a local filename that we'll save to.
+    xastir_snprintf(local_filename,
+        sizeof(local_filename),
+        "%s/map.geo",
+        get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)));
+
+    // Erase any previously existing local file by the same
+    // name.  This avoids the problem of having an old map image
+    // here and the code trying to display it when the download
+    // fails.
+    unlink( local_filename );
+
+
+    // Call wget or libcurl to fetch the .geo file.  Best would be
+    // to create a generic "fetch" routine which would fetch a
+    // remote file, then go back and rework all of the various map
+    // routines to use it.
+
+    if (fetch_remote_file(fileimg, local_filename)) {
+        // Had trouble getting the file.  Abort.
+        return;
+    }
+
+    // Set permissions on the file so that any user can overwrite it.
+    chmod(local_filename, 0666);
+
+    // We now re-use the "file" variable.  It'll hold the
+    //name of the map file now instead of the .geo file.
+
+    // Tell ImageMagick where to find it
+    xastir_snprintf(file,sizeof(file),"%s",local_filename);
+
+
+
+// Check whether we got a reasonable ~/.xastir/tmp/map.geo file from
+// the fetch.  If so, pass it off to the routine which can draw it.
+
+    // We also need to write a valid IMAGESIZE line into the .geo
+    // file.  We know these parameters because they should match
+    // screen_width/screen_height.
+    //
+    xastir_snprintf(map_it,
+        sizeof(map_it),
+        "IMAGESIZE\t%d\t%d\n",
+        my_screen_width,
+        my_screen_height);
+
+// Another thing we might need is a TRANSPARENT line, for the grey
+// color we see crossing over the U.S. border and obscuring maps on
+// this side of the border.
+
+    f = fopen (local_filename, "a");
+    if (f != NULL) {
+        fprintf(f, "%s", map_it);
+        (void)fclose (f);
+    }
+    else {
+        fprintf(stderr,"Couldn't open file: %s to add IMAGESIZE tag\n", local_filename);
+        return;
+    }
+
+
+    // Call draw_geo_image_map() with our newly-fetched .geo file,
+    // passing it most of the parameters that we were originally
+    // passed in order to effect the map draw.
+    draw_geo_image_map (w,
+        get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),
+        "map.geo",
+        alert,
+        alert_color,
+        destination_pixmap,
+        mdf);
+
+#endif  // HAVE_MAGICK
+}
+ 
+
+
+
+
+/**********************************************************
+ * draw_geo_image_map()
+ *
+ * If we have found a ".geo" file, we read it here and plot
+ * the graphic image into the current viewport.
+ * We check first to see whether the map should be plotted
+ * and skip it if it's not in our viewport.  These images
+ * are expected to be aligned in the lat/lon directions
+ * (not rotated) and rectangular.
+ **********************************************************/
+
+void draw_geo_image_map (Widget w, 
+			 char *dir,
+			 char *filenm, 
+			 alert_entry *alert,
+			 u_char alert_color,
+			 int destination_pixmap,
+			 map_draw_flags *mdf) {
+#ifdef NO_GRAPHICS
+    fprintf(stderr,"XPM and/or ImageMagick support have not been compiled in.\n");
+#else   // NO_GRAPHICS
+    char file[MAX_FILENAME+1];      // Complete path/name of image file
+    char short_filenm[MAX_FILENAME+1];
+    FILE *f;                        // Filehandle of image file
+    char line[MAX_FILENAME];        // One line from GEO file
+    char fileimg[MAX_FILENAME+1];   // Ascii name of image file, read from GEO file
+    char tileCache[MAX_FILENAME+1]; // directory for the OSM tile cache, read from GEO file.
+    char OSMstyle[MAX_OSMSTYLE];
+    char OSMtileExt[MAX_OSMEXT];
+
+    // Start with an empty fileimg[] string so that we can
+    // tell if a URL has been specified in the file. Same for OSMstyle.
+    fileimg[0] = '\0';
+    OSMstyle[0] = '\0';
+    tileCache[0] = '\0';
+    OSMtileExt[0] = '\0';
+
+    int width,height;
+#ifndef NO_XPM
+    XpmAttributes atb;              // Map attributes after map's read into an XImage
+#endif  // HAVE_MAGICK
+
+    tiepoint tp[2];                 // Calibration points for map, read in from .geo file
+    int n_tp;                       // Temp counter for number of tiepoints read
+    float temp_long, temp_lat;
+    register long map_c_T, map_c_L; // map delta NW edge coordinates, DNN: these should be signed
+    register long tp_c_dx, tp_c_dy; // tiepoint coordinate differences
+// DK7IN--
+    int test;                       // temporary debugging
+
+    unsigned long c_x_min,  c_y_min;// top left coordinates of map inside screen
+    unsigned long c_y_max;          // bottom right coordinates of map inside screen
+    double c_x;                     // Xastir coordinates 1/100 sec, 0 = 180�W
+    double c_y;                     // Xastir coordinates 1/100 sec, 0 =  90�N
+    double c_y_a;                   // coordinates correction for Transverse Mercator
+
+    long map_y_0;                   // map pixel pointer prior to TM adjustment
+    register long map_x, map_y;     // map pixel pointers, DNN: this was a float, chg to long
+    long map_x_min, map_x_max;      // map boundaries for in screen part of map
+    long map_y_min, map_y_max;      //
+    long map_x_ctr;                 // half map width in pixel
+    long map_y_ctr;                 // half map height in pixel
+//    long x;
+    int map_seen, map_act, map_done;
+    double corrfact;
+
+    long map_c_yc;                  // map center, vert coordinate
+    long map_c_xc;                  // map center, hor  coordinate
+    double map_c_dx, map_c_dy;      // map coordinates increment (pixel width)
+    double c_dx;                    // adjusted map pixel width
+
+    long scr_x,  scr_y;             // screen pixel plot positions
+    long scr_xp, scr_yp;            // previous screen plot positions
+    int  scr_dx, scr_dy;            // increments in screen plot positions
+    long scr_x_mc;                  // map center in screen units
+
+    long scr_c_xr;
+
+    double dist;                    // distance from equator in nm
+    double ew_ofs;                  // distance from map center in nm
+
+    long scale_xa;                  // adjusted for topo maps
+    double scale_x_nm;              // nm per Xastir coordinate unit
+    long scale_x0;                  // at widest map area
+
+#ifdef HAVE_MAGICK
+    char local_filename[MAX_FILENAME];
+    ExceptionInfo exception;
+    Image *image;
+    ImageInfo *image_info;
+    PixelPacket *pixel_pack;
+    PixelPacket temp_pack;
+    IndexPacket *index_pack;
+    int l;
+    XColor my_colors[256];
+    time_t query_start_time, query_end_time;
+    char gamma[16];
+    struct {
+        float r_gamma;
+        float g_gamma;
+        float b_gamma;
+        int gamma_flag;
+        int contrast;
+        int negate;
+        int equalize;
+        int normalize;
+        char level[32];
+        char modulate[32];
+    } imagemagick_options = { 1.0, 1.0, 1.0, 0, 0, -1, 0, 0, "", "" };
+    double left, right, top, bottom, map_width, map_height;
+    //N0VH
+//    double lat_center  = 0;
+//    double long_center = 0;
+    // Terraserver variables
+    double top_n=0, left_e=0, bottom_n=0, right_e=0, map_top_n=0, map_left_e=0;
+    int z, url_n=0, url_e=0, t_zoom=16, t_scale=12800;
+    char zstr0[8];
+    char zstr1[8];
+#else   // HAVE_MAGICK
+    XImage *xi;                 // Temp XImage used for reading in current image
+#endif // HAVE_MAGICK
+
+    int terraserver_flag = 0;   // U.S. satellite images/topo/reflectivity/urban
+                                // areas via terraserver
+    int tigerserver_flag = 0;   // U.S. Street maps via census.gov
+    int OSMserver_flag = 0;     // OpenStreetMaps server, 1 = static maps, 2 = tiled
+    unsigned tmp_zl = 0;
+
+    int toporama_flag = 0;      // Canadian topo's from mm.aprs.net (originally from Toporama)
+    int WMSserver_flag = 0;     // WMS server
+    char map_it[MAX_FILENAME];
+    int geo_image_width = 0;    // Image width  from GEO file
+    int geo_image_height = 0;   // Image height from GEO file
+    char geo_datum[8+1];        // WGS-84 etc.
+    char geo_projection[256+1];   // TM, UTM, GK, LATLON etc.
+    int map_proj=0;
+    int map_refresh_interval_temp = 0;
+    int nocache = 0;            // Don't cache the file if non-zero
+#ifdef FUZZYRASTER
+    int rasterfuzz = 3;    // ratio to skip 
+#endif //FUZZYRASTER
+    unsigned long temp_trans_color;    // what color to zap
+    int trans_skip = 0;  // skip transparent pixel
+    int crop_x1=0, crop_x2=0, crop_y1=0, crop_y2=0; // pixel crop box
+    int do_crop = 0;     // do we crop pixels
+//#define TIMING_DEBUG
+#ifdef TIMING_DEBUG
+    time_mark(1);
+#endif  // TIMING_DEBUG
+
+#ifdef HAVE_MAGICK
+  #ifdef USE_MAP_CACHE 
+    int map_cache_return;
+    char *cache_file_id;
+  #endif  // USE_MAP_CACHE
+#endif  // HAVE_MAGICK
+
+    char temp_file_path[MAX_VALUE];
+    KeySym OSM_key = 0;
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+
+    // Read the .geo file to find out map filename and tiepoint info
+
+    // Empty the transparent color list before we start reading in a
+    // new .geo file.
+    empty_trans_color_list();
+
+    n_tp = 0;
+    geo_datum[0]      = '\0';
+    geo_projection[0] = '\0';
+    f = fopen (file, "r");
+    if (f != NULL) {
+        while (!feof (f)) {
+            (void)get_line (f, line, MAX_FILENAME);
+            if (strncasecmp (line, "FILENAME", 8) == 0) {
+                if (1 != sscanf (line + 9, "%s", fileimg)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+                if (fileimg[0] != '/' ) { // not absolute path
+                    // make it relative to the .geo file
+                    char temp[MAX_FILENAME];
+
+                    // grab .geo file name
+                    xastir_snprintf(temp,sizeof(temp),"%s",file);
+
+                    (void)get_map_dir(temp);           // leaves just the path and trailing /
+                    if (strlen(temp) < (MAX_FILENAME - 1 - strlen(fileimg)))
+                        strncat(temp,
+                            fileimg,
+                            sizeof(temp) - 1 - strlen(temp));
+                    xastir_snprintf(fileimg,sizeof(fileimg),"%s",temp);
+                }
+            }
+            if (strncasecmp (line, "URL", 3) == 0)
+                if (1 != sscanf (line + 4, "%s", fileimg)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+
+            if (n_tp < 2) {     // Only take the first two tiepoints
+                if (strncasecmp (line, "TIEPOINT", 8) == 0) {
+                    if (4 != sscanf (line + 9, "%d %d %f %f",
+                            &tp[n_tp].img_x,
+                            &tp[n_tp].img_y,
+                            &temp_long,
+                            &temp_lat)) {
+                        fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                    }
+                    // Convert tiepoints from lat/lon to Xastir coordinates
+                    tp[n_tp].x_long = 64800000l + (360000.0 * temp_long);
+                    tp[n_tp].y_lat  = 32400000l + (360000.0 * (-temp_lat));
+                    n_tp++;
+                }
+            }
+
+            if (strncasecmp (line, "IMAGESIZE", 9) == 0)
+                if (2 != sscanf (line + 10, "%d %d",&geo_image_width,&geo_image_height)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+
+            if (strncasecmp (line, "DATUM", 5) == 0)
+                if (1 != sscanf (line + 6, "%8s",geo_datum)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+
+            if (strncasecmp (line, "PROJECTION", 10) == 0)
+                // Ignores leading and trailing space (nice!)
+                if (1 != sscanf (line + 11, "%256s",geo_projection)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+
+            if (strncasecmp (line, "TERRASERVER-URBAN", 17) == 0)
+                terraserver_flag = 4;
+
+            if (strncasecmp (line, "TERRASERVER-REFLECTIVITY", 24) == 0)
+                terraserver_flag = 3;
+
+            if (strncasecmp (line, "TERRASERVER-TOPO", 16) == 0) {
+                // Set to max brightness as it looks weird when the
+                // intensity variable comes into play.
+#ifdef HAVE_MAGICK
+// This one causes problems now.  Not sure why.
+//                xastir_snprintf(imagemagick_options.modulate,32,"100 100 100");
+#endif  // HAVE_MAGICK
+                terraserver_flag = 2;
+            }
+
+            if (strncasecmp (line, "TERRASERVER-SATELLITE", 21) == 0)
+                terraserver_flag = 1;
+
+            if (strncasecmp (line, "TIGERMAP", 8) == 0)
+                tigerserver_flag = 1;
+
+            if (strncasecmp (line, "OSMSTATICMAP", 12) == 0)
+            {
+                OSMserver_flag = 1;
+                if (strlen(line) > 13) {
+                    if (1 != sscanf (line + 13, "%s", OSMstyle)) {
+                        fprintf(stderr,"draw_geo_image_map:sscanf parsing error for OSM style.\n"); 
+                    }
+                }
+            }
+
+            if (strncasecmp (line, "OSM_TILED_MAP", 13) == 0)
+            {
+                OSMserver_flag = 2;
+                if (strlen(line) > 14) {
+                    if (1 != sscanf (line + 14, "%s", OSMstyle)) {
+                        fprintf(stderr,"draw_geo_image_map:sscanf parsing error for OSM style.\n"); 
+                    }
+                }
+            }
+
+            if (OSMserver_flag > 0) {  // the following keywords are only valid for OSM maps
+                if (strncasecmp (line, "OSM_OPTIMIZE_KEY", 16) == 0){
+                    if ((destination_pixmap != INDEX_CHECK_TIMESTAMPS)
+                            && (destination_pixmap != INDEX_NO_TIMESTAMPS)) {
+                        if (strlen(line) > 17) {
+                            if (1 != sscanf (line + 17, "%lu", &OSM_key)) {
+                                fprintf(stderr,"draw_geo_image_map:sscanf parsing error for OSM_OPTIMIZE_KEY.\n");
+                            } else {
+                                set_OSM_optimize_key(OSM_key);
+                            }
+                        }
+                    }
+                }
+
+                if (strncasecmp (line, "OSM_REPORT_SCALE_KEY", 20) == 0){
+                    if ((destination_pixmap != INDEX_CHECK_TIMESTAMPS)
+                            && (destination_pixmap != INDEX_NO_TIMESTAMPS)) {
+                        if (strlen(line) > 21) {
+                            if (1 != sscanf (line + 21, "%lu", &OSM_key)) {
+                                fprintf(stderr,"draw_geo_image_map:sscanf parsing error for OSM_OPTIMIZE_KEY.\n");
+                            } else {
+                                set_OSM_report_scale_key(OSM_key);
+                            }
+                        }
+                    }
+                }
+
+                if (strncasecmp (line, "TILE_DIR", 8) == 0) {
+                    if (strlen(line) > 9) {
+                        if (1 != sscanf (line + 9, "%s", tileCache)) {
+                        fprintf(stderr,"draw_geo_image_map:sscanf parsing error for TILE_DIR\n");
+                        }
+                    }
+                }
+
+                if (strncasecmp (line, "TILE_EXT", 8) == 0) {
+                    if (strlen(line) > 9) {
+                        if (1 != sscanf (line + 9, "%s", OSMtileExt)) {
+                        fprintf(stderr,"draw_geo_image_map:sscanf parsing error for TILE_EXT\n");
+                        }
+                    }
+                }
+
+                if (strncasecmp(line, "ZOOM_LEVEL_MIN", 14) == 0) {
+                    if (strlen(line) > 15) {
+                        if (1 != sscanf(line + 15, "%u", &tmp_zl)) {
+                            fprintf(stderr, "draw_geo_image_map:sscanf parsing error for ZOOM_LEVEL_MIN\n");
+                        } else {
+                            if (!(osm_zoom_level(scale_x) >= tmp_zl)) {
+                                // skip this map because the zoom level
+                                // is not supported.
+                                if (debug_level & 512) {
+                                    fprintf(stderr, "Skipping OSM map. zl = %u < %u\n", osm_zoom_level(scale_x), tmp_zl);
+                                }
+                                return;
+                            }
+                        }
+                    }
+                }
+                if (strncasecmp(line, "ZOOM_LEVEL_MAX", 14) == 0) {
+                    if (strlen(line) > 15) {
+                        if (1 != sscanf(line + 15, "%u", &tmp_zl)) {
+                            fprintf(stderr, "draw_geo_image_map:sscanf parsing error for ZOOM_LEVEL_MAX\n");
+                        } else {
+                            if (!(tmp_zl >= osm_zoom_level(scale_x))) {
+                                // skip this map because the zoom level
+                                // is not supported.
+                                if (debug_level & 512) {
+                                    fprintf(stderr, "Skipping OSM map. zl = %u > %u\n", osm_zoom_level(scale_x), tmp_zl);
+                                }
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (strncasecmp (line, "WMSSERVER", 9) == 0)
+                WMSserver_flag = 1;
+
+            // Check for Canadian topo map request
+            if (strncasecmp (line, "TOPORAMA-50k", 12) == 0) {
+                toporama_flag = 50;
+            }
+            if (strncasecmp (line, "TOPORAMA-250k", 13) == 0) {
+                toporama_flag = 250;
+            }
+
+
+            // Check whether we're indexing or drawing the map.
+            // Exclude setting the map refresh interval from
+            // indexing.
+            if ( (destination_pixmap != INDEX_CHECK_TIMESTAMPS)
+                    && (destination_pixmap != INDEX_NO_TIMESTAMPS) ) {
+
+                if (strncasecmp (line, "REFRESH", 7) == 0) {
+                    if (1 != sscanf (line + 8, "%d", &map_refresh_interval_temp)) {
+                        fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                    }
+                    if ( map_refresh_interval_temp > 0 && 
+                         ( map_refresh_interval == 0 || 
+                           map_refresh_interval_temp < map_refresh_interval) ) {
+                        map_refresh_interval = (time_t) map_refresh_interval_temp;
+                        map_refresh_time = sec_now() + map_refresh_interval;
+
+                        if (debug_level & 512)
+                            fprintf(stderr, "Map Refresh set to %d.\n", (int) map_refresh_interval);
+                    }
+                    nocache = map_refresh_interval_temp;
+                }
+            }
+
+            if (strncasecmp(line, "TRANSPARENT", 11) == 0) { 
+                // need to make this read a list of colors to zap
+                // out.  Use 32-bit unsigned values, so we can
+                // handle 32-bit color displays.
+                if (1 != sscanf (line + 12, "%lx", &temp_trans_color)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+
+                {
+                    unsigned short r,g,b;
+                    // We'll assume the temp_trans_color has been
+                    // specified as a 24-bit quantity
+                    r = (temp_trans_color&0xff0000) >> 16;
+                    g = (temp_trans_color&0x00ff00)>>8;
+                    b = temp_trans_color&0x0000ff;
+                    // Now this is an incredible kludge, but seems to be right
+                    // Apparently, if QuantumDepth is 16 bits, r, g, and b
+                    // values are duplicated in the high and low byte, which
+                    // is just bizarre
+#ifdef HAVE_MAGICK
+                    if (QuantumDepth == 16) {
+                        r=r|(r<<8);
+                        g=g|(g<<8);
+                        b=b|(b<<8);
+                    }
+#endif  // HAVE_MAGICK
+                    //fprintf(stderr,"Original Transparent %lx\n",temp_trans_color);
+                    //fprintf(stderr,"Transparent r,g,b=%x,%x,%x\n",r,g,b);
+                    if (visual_type == NOT_TRUE_NOR_DIRECT) {
+                        XColor junk;
+
+#ifdef HAVE_MAGICK
+                        if (QuantumDepth == 16) {
+                            junk.red=r;
+                            junk.green=g;
+                            junk.blue=b;
+                        }
+                        else
+#endif  // HAVE_MAGICK
+                        {
+                            junk.red= r<<8;
+                            junk.green = g<<8;
+                            junk.blue = b<<8;
+                        }
+                        XAllocColor(XtDisplay(w),cmap,&junk);
+                        temp_trans_color = junk.pixel;
+                    } else {
+                        pack_pixel_bits(r,g,b,&temp_trans_color);
+                    }
+                    //fprintf(stderr,"Packed Transparent %lx\n",temp_trans_color);
+                }
+
+//fprintf(stderr,"New Transparent: %lx\n",temp_trans_color);
+
+                // Link color to transparent color list
+                new_trans_color(temp_trans_color);
+            }
+            if (strncasecmp(line, "CROP", 4) == 0) { 
+                if (4 != sscanf (line + 5, "%d %d %d %d", 
+                        &crop_x1,
+                        &crop_y1,
+                        &crop_x2,
+                        &crop_y2 )) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+                if (crop_x1 < 0 ) crop_x1 = 0;
+                if (crop_y1 < 0 ) crop_y1 = 0;
+                if (crop_x2 < 0 ) crop_x2 = 0;
+                if (crop_y2 < 0 ) crop_y2 = 0;
+                if (crop_x2 < crop_x1 ) // swap
+                    {do_crop = crop_x1; crop_x1=crop_x2; crop_x2=do_crop;}
+                if (crop_y2 < crop_y1 ) // swap
+                    {do_crop = crop_y1; crop_y1=crop_y2; crop_y2=do_crop;}
+                do_crop = 1;
+            }   
+#ifdef HAVE_MAGICK
+            if (strncasecmp(line, "GAMMA", 5) == 0)
+                imagemagick_options.gamma_flag = sscanf(line + 6, "%f,%f,%f",
+                                                        &imagemagick_options.r_gamma,
+                                                        &imagemagick_options.g_gamma,
+                                                        &imagemagick_options.b_gamma);
+            if (strncasecmp(line, "CONTRAST", 8) == 0) {
+                if (1 != sscanf(line + 9, "%d", &imagemagick_options.contrast)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+            }
+            if (strncasecmp(line, "NEGATE", 6) == 0) {
+                if (1 != sscanf(line + 7, "%d", &imagemagick_options.negate)) {
+                    fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+                }
+            }
+            if (strncasecmp(line, "EQUALIZE", 8) == 0)
+                imagemagick_options.equalize = 1;
+            if (strncasecmp(line, "NORMALIZE", 9) == 0)
+                imagemagick_options.normalize = 1;
+#if (MagickLibVersion >= 0x0539)
+            if (strncasecmp(line, "LEVEL", 5) == 0) {
+                xastir_snprintf(imagemagick_options.level,
+                    sizeof(imagemagick_options.level),
+                    "%s",
+                    line+6);
+            }
+#endif  // MagickLibVersion >= 0x0539
+            if (strncasecmp(line, "MODULATE", 8) == 0) {
+                xastir_snprintf(imagemagick_options.modulate,
+                    sizeof(imagemagick_options.modulate),
+                    "%s",
+                    line+9); 
+            }
+#endif  // HAVE_MAGICK
+        }
+        (void)fclose (f);
+    }
+    else {
+        fprintf(stderr,"Couldn't open file: %s\n", file);
+        return;
+    }
+
+
+    // Check whether Tigermap has been selected.  If so, run off to
+    // another routine to service this request.
+    //
+    if (tigerserver_flag) {
+
+#ifdef HAVE_MAGICK
+
+        // We need to send the "nocache" parameter to this function
+        // for those instances when the tigermap received is bad.
+        // Later the GUI can implement a method for refreshing the
+        // latest map and replacing the bad map in the cache.
+        //
+        draw_tiger_map(w, filenm, destination_pixmap, nocache);
+
+#endif  // HAVE_MAGICK
+
+        return;
+    }
+    //
+    // Check whether OpenStreetMap has been selected.  If so, run off to
+    // another routine to service this request.
+    //
+    if (OSMserver_flag == 1) {
+
+#ifdef HAVE_MAGICK
+
+        // We need to send the "nocache" parameter to this function
+        // for those instances when the received map is bad.
+        // Later the GUI can implement a method for refreshing the
+        // latest map and replacing the bad map in the cache.
+        //
+        // fileimg is the server URL, if specified.
+        draw_OSM_map(w, filenm, destination_pixmap, fileimg, OSMstyle, nocache);
+
+#endif  // HAVE_MAGICK
+
+        return;
+    } else if (OSMserver_flag == 2) {
+#ifdef HAVE_MAGICK
+
+        // fileimg is the server URL, if specified.
+        draw_OSM_tiles(w, filenm, destination_pixmap, fileimg, tileCache, OSMstyle, OSMtileExt);
+
+#endif  // HAVE_MAGICK
+
+        return;
+    }
+
+
+
+    // Check whether a WMS server has been selected.  If so, run off
+    // to another routine to service this request.
+    //
+    if (WMSserver_flag) {
+
+#ifdef HAVE_MAGICK
+        // Pass the URL in "fileimg"
+        draw_WMS_map(w,
+            filenm,
+            destination_pixmap,
+            fileimg,
+            trans_color_head,
+            nocache); // Don't use cached version if non-zero
+
+#endif  // HAVE_MAGICK
+
+        return;
+    }
+
+
+    if (toporama_flag) {
+
+#ifdef HAVE_MAGICK
+        // Pass all of the parameters to it.  We'll need to use them
+        // to call draw_geo_image_map() again shortly, after we
+        // fetch the remote .geo file.
+        //
+        draw_toporama_map(w,
+            dir,
+            filenm,
+            alert,
+            alert_color,
+            destination_pixmap,
+            mdf,
+            toporama_flag);
+#endif  // HAVE_MAGICK
+
+        return;
+    }
+
+
+
+// DK7IN: I'm experimenting with the adjustment of topo maps with
+// Transverse Mercator projection. Those maps have equal scaling
+// in distance while we use equal scaling in degrees.
+
+// For now I use the map center as central meridian (I think that
+// is ok for mapblast), that will change with UTM and Gauss-Krueger
+
+// I have introduced new entries in the geo file for that...
+// I first adjust the x scaling depending on the latitude
+// Then I move points in y direction depending on the offset from
+// the central meridian. I hope I get that right with those
+// approximations. I have the correct formulas, but that will
+// be very computing intensive and result in slow map loading...
+
+//    if (geo_datum[0] != '\0')
+//        fprintf(stderr,"Map Datum: %s\n",geo_datum);   // not used now...
+
+    if (geo_projection[0] == '\0')
+        // default
+        xastir_snprintf(geo_projection,
+            sizeof(geo_projection),
+            "LatLon");
+    //fprintf(stderr,"Map Projection: %s\n",geo_projection);
+    //    (void)to_upper(geo_projection);
+    if (strcasecmp(geo_projection,"TM") == 0)
+        map_proj = 1;           // Transverse Mercator
+    else
+        map_proj = 0;           // Lat/Lon, default
+
+#ifdef HAVE_MAGICK
+    if (terraserver_flag) {
+//http://terraservice.net/download.ashx?t=1&s=10&x=2742&y=26372&z=10&w=820&h=480
+        if (scale_y <= 4) {
+                t_zoom  = 10; // 1m/pixel
+                t_scale = 200;
+        }
+        else if (scale_y <= 8) {
+             t_zoom  = 11; // 2m/pixel
+             t_scale = 400;
+        }
+        else if (scale_y <= 16) {
+            t_zoom  = 12; // 4m/pixel
+            t_scale = 800;
+        }
+        else if (scale_y <= 32) {
+            t_zoom  = 13; // 8m/pixel
+            t_scale = 1600;
+        }
+        else if (scale_y <= 64) {
+            t_zoom  = 14; // 16m/pixel
+            t_scale = 3200;
+        }
+        else if (scale_y <= 128) {
+            t_zoom  = 15; // 32m/pixel
+            t_scale = 6400;
+        }
+        else {
+            t_zoom  = 16; // 64m/pixel
+            t_scale = 12800;
+        }
+
+        top  = -((NW_corner_latitude - 32400000l) / 360000.0);
+        left =  (NW_corner_longitude - 64800000l) / 360000.0;
+        ll_to_utm_ups(gDatum[D_NAD_83_CONUS].ellipsoid,
+            top,
+            left,
+            &top_n,
+            &left_e,
+            zstr0,
+            sizeof(zstr0) );
+        if (1 != sscanf(zstr0, "%d", &z)) {
+            fprintf(stderr,"draw_geo_image_map:sscanf parsing error\n");
+        }
+
+        bottom = -((SE_corner_latitude - 32400000l) / 360000.0);
+        right  =   (SE_corner_longitude - 64800000l) / 360000.0;
+
+        ll_to_utm_ups(gDatum[D_NAD_83_CONUS].ellipsoid,
+            bottom,
+            right,
+            &bottom_n,
+            &right_e,
+            zstr1,
+            sizeof(zstr1) );
+
+
+//
+// NOTE:
+// POSSIBLE FUTURE ENHANCEMENT:
+// If zstr0 != zstr1, we have a viewscreen that crosses a UTM zone
+// boundary.  Terraserver/Toposerver will only feed us a map for one
+// side of it or the other.  It'd be VERY nice if some day we could
+// check for this condition and do two map loads instead of the one.
+// We'd need to stop drawing right at the boundary for each map
+// also, so that they'd tile together nicely.
+//
+
+
+        map_top_n  = (int)((top_n  / t_scale) + 1) * t_scale;
+        map_left_e = (int)((left_e / t_scale) + 0) * t_scale;
+        utm_ups_to_ll(gDatum[D_NAD_83_CONUS].ellipsoid,
+            map_top_n,
+            map_left_e,
+            zstr0,
+            &top,
+            &left);
+
+
+// Below here things can get messed up.  We can end up with very
+// large and/or negative values for geo_image_width and/or
+// geo_image_height.  Usually happens around UTM zone boundaries.
+//
+// Terraserver uses UTM coordinates for specifying the maps instead
+// of lat/long.  Note that we're also not supposed to cross UTM
+// zones in our requests.
+//
+// t = 1 - 4, theme.  1=DOQ (aerial photo)
+//                    2=DRG (topo)
+//                    3=shaded relief
+//                    4=Color photos/Urban areas
+// s = 10 - 16, scale.  10=1 meter/pixel.  11=2 meters/pixel.
+// x = UTM easting, center of image
+// y = UTM northing, center of image
+// z = 1 - 60, UTM zone, center of image
+// w = 50 - 2000, width in pixels
+// h = 50 - 2000, height in pixels
+// logo = 0/1, USGS logo in image if 1
+//
+
+        // This number gets messed up if we cross zones.  UTM lines
+        // are slanted, so we _can_ cross zones vertically!
+        geo_image_height = abs(map_top_n - bottom_n) * 200 / t_scale;
+
+        // This number gets messed up if we cross zones
+        geo_image_width  = abs(right_e - map_left_e) * 200 / t_scale;
+
+ 
+//fprintf(stderr,"\ngeo_image_height:%d\tmap_top_n:%0.1f\tbottom_n:%0.1f\tt_scale:%d\n",
+//geo_image_height,
+//map_top_n,
+//bottom_n,
+//t_scale);
+// map_top_n is the one that goes whacko, throwing off the height.
+// Check whether this is because we're crossing a UTM zone.  We
+// _can_ cross zones vertically because the UTM lines are slanted.
+
+//fprintf(stderr,"geo_image_width:%d\tright_e:%0.1f\tmap_left_e:%0.1f\tt_scale:%d\n",
+//geo_image_width,
+//right_e,
+//map_left_e,
+//t_scale);
+// right_e is the one that goes whacko, throwing off the width.
+// Check whether this is because we're crossing a UTM zone.
+
+
+        if (geo_image_height < 50)
+            geo_image_height = 50;
+
+        if (geo_image_width < 50)
+            geo_image_width = 50;
+
+        if (geo_image_height > 2000)
+            geo_image_height = geo_image_width;
+ 
+        if (geo_image_width > 2000)
+            geo_image_width = geo_image_height;
+
+        if (geo_image_height > 2000)
+            geo_image_height = geo_image_width;
+         if (geo_image_width > 2000)
+            geo_image_width = geo_image_height;
+
+
+        map_width  = right - left;
+        map_height = top - bottom;
+
+        tp[0].img_x = 0;
+        tp[0].img_y = 0;
+        tp[0].x_long = 64800000l + (360000.0 * left);
+        tp[0].y_lat  = 32400000l + (360000.0 * (-top));
+
+        tp[1].img_x = geo_image_width  - 1;
+        tp[1].img_y = geo_image_height - 1;
+        tp[1].x_long = 64800000l + (360000.0 * right);
+        tp[1].y_lat  = 32400000l + (360000.0 * (-bottom));
+
+        url_n = (int)(top_n  / t_scale); // The request URL does not use the
+        url_e = (int)(left_e / t_scale); // N/E of the map corner
+
+
+        xastir_snprintf(fileimg, sizeof(fileimg),
+            "http://terraservice.net/download.ashx?t=%d\046s=%d\046x=%d\046y=%d\046z=%d\046w=%d\046h=%d",
+//            "http://terraserver-usa.net/download.ashx?t=%d\046s=%d\046x=%d\046y=%d\046z=%d\046w=%d\046h=%d",
+            terraserver_flag,   // 1, 2, 3, or 4
+            t_zoom,
+            url_e,  // easting, center of map
+            url_n,  // northing, center of map
+            z,
+            geo_image_width,
+            geo_image_height);
+//http://terraservice.net/download.ashx?t=1&s=11&x=1384&y=13274&z=10&w=1215&h=560
+//fprintf(stderr,"%s\n",fileimg);
+
+        if (debug_level & 16) {
+            fprintf(stderr,"URL: %s\n", fileimg);
+        }
+    }
+#endif // HAVE_MAGICK
+
+    //
+    // DK7IN: we should check what we got from the geo file
+    //   we use geo_image_width, but it might not be initialised...
+    //   and it's wrong if the '\n' is missing at the end...
+
+    /*
+    * Here are the corners of our viewport, using the Xastir
+    * coordinate system.  Notice that Y is upside down:
+    *
+    *   left edge of view = NW_corner_longitude
+    *  right edge of view = SE_corner_longitude
+    *    top edge of view =  NW_corner_latitude
+    * bottom edge of view =  SE_corner_latitude
+    *
+    * The corners of our map will soon be (after translating the
+    * tiepoints to the corners if they're not already there):
+    *
+    *   left edge of map = tp[0].x_long   in Xastir format
+    *  right edge of map = tp[1].x_long
+    *    top edge of map = tp[0].y_lat
+    * bottom edge of map = tp[1].y_lat
+    *
+    */
+    map_c_L = tp[0].x_long - NW_corner_longitude;     // map left coordinate
+    map_c_T = tp[0].y_lat  - NW_corner_latitude;      // map top  coordinate
+
+    tp_c_dx = (long)(tp[1].x_long - tp[0].x_long);//  Width between tiepoints
+    tp_c_dy = (long)(tp[1].y_lat  - tp[0].y_lat); // Height between tiepoints
+
+
+    // Check for tiepoints being in wrong relation to one another
+    if (tp_c_dx < 0) tp_c_dx = -tp_c_dx;       // New  width between tiepoints
+    if (tp_c_dy < 0) tp_c_dy = -tp_c_dy;       // New height between tiepoints
+
+
+    if (debug_level & 512) {
+        fprintf(stderr,"X tiepoint width: %ld\n", tp_c_dx);
+        fprintf(stderr,"Y tiepoint width: %ld\n", tp_c_dy);
+    }
+
+    // Calculate step size per pixel
+    map_c_dx = ((double) tp_c_dx / abs(tp[1].img_x - tp[0].img_x));
+    map_c_dy = ((double) tp_c_dy / abs(tp[1].img_y - tp[0].img_y));
+
+    // Scaled screen step size for use with XFillRectangle below
+    scr_dx = (int) (map_c_dx / scale_x) + 1;
+    scr_dy = (int) (map_c_dy / scale_y) + 1;
+
+    if (debug_level & 512) {
+        fprintf(stderr,"\nImage: %s\n", file);
+        fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height);
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+    }
+
+    // calculate top left map corner from tiepoints
+    if (tp[0].img_x != 0) {
+        tp[0].x_long -= (tp[0].img_x * map_c_dx);   // map left edge longitude
+        map_c_L = tp[0].x_long - NW_corner_longitude;     // delta ??
+        tp[0].img_x = 0;
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_0 x: %d\t%lu\n", tp[0].img_x, tp[0].x_long);
+    }
+    if (tp[0].img_y != 0) {
+        tp[0].y_lat -= (tp[0].img_y * map_c_dy);    // map top edge latitude
+        map_c_T = tp[0].y_lat - NW_corner_latitude;
+        tp[0].img_y = 0;
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_0 y: %d\t%lu\n", tp[0].img_y, tp[0].y_lat);
+    }
+
+    // By this point, geo_image_width & geo_image_height have to
+    // have been initialized to something.
+
+    if ( (geo_image_width == 0) || (geo_image_height == 0) ) {
+
+        if ( (strncasecmp ("http", fileimg, 4) == 0)
+             || (strncasecmp ("ftp", fileimg, 3) == 0)) {
+            // what to do for remote files... hmm... -cbell
+        } else {
+
+#ifdef HAVE_MAGICK
+            GetExceptionInfo(&exception);
+            image_info=CloneImageInfo((ImageInfo *) NULL);
+            xastir_snprintf(image_info->filename,
+                sizeof(image_info->filename),
+                "%s",
+                fileimg);
+            if (debug_level & 16) {
+                fprintf(stderr,"Copied %s into image info.\n", file);
+                fprintf(stderr,"image_info got: %s\n", image_info->filename);
+                fprintf(stderr,"Entered ImageMagick code.\n");
+                fprintf(stderr,"Attempting to open: %s\n", image_info->filename);
+            }
+            
+            // We do a test read first to see if the file exists, so we
+            // don't kill Xastir in the ReadImage routine.
+            f = fopen (image_info->filename, "r");
+            if (f == NULL) {
+fprintf(stderr,"1 ");
+                fprintf(stderr,"File %s could not be read\n",image_info->filename);
+
+#ifdef USE_MAP_CACHE
+            // clear from cache if bad    
+            if (map_cache_del(fileimg)) {
+	        if (debug_level & 512) {
+                    fprintf(stderr,"Couldn't delete map from cache\n");
+	        }
+            }
+#endif
+               if (image_info)
+                 DestroyImageInfo(image_info);
+               DestroyExceptionInfo(&exception);
+               return;
+            }
+            (void)fclose (f);
+            
+            image = PingImage(image_info, &exception);
+        
+            if (image == (Image *) NULL) {
+                MagickWarning(exception.severity, exception.reason, exception.description);
+                //fprintf(stderr,"MagickWarning\n");
+
+#ifdef USE_MAP_CACHE
+            // clear from cache if bad    
+            if (map_cache_del(fileimg)) {
+	        if (debug_level & 512) {
+                    fprintf(stderr,"Couldn't delete map from cache\n");
+	        }
+            }
+#endif
+
+               if (image_info)
+                 DestroyImageInfo(image_info);
+               DestroyExceptionInfo(&exception);
+                return;
+            }
+            
+            if (debug_level & 16)
+                fprintf(stderr,"Color depth is %i \n", (int)image->depth);
+            
+            geo_image_width = image->magick_columns;
+            geo_image_height = image->magick_rows;
+     
+            // close and clean up imagemagick
+        
+            if (image)
+                DestroyImage(image);
+            if (image_info)
+                DestroyImageInfo(image_info);
+            DestroyExceptionInfo(&exception);
+#endif // HAVE_MAGICK
+        }
+    }
+
+    //    fprintf(stderr, "Geo: %s: size %ux%u.\n",file, geo_image_width, geo_image_height);
+    // if that did not generate a valid size, bail out... 
+    if ( (geo_image_width == 0) || (geo_image_height == 0) ) {
+        fprintf(stderr,"*** Skipping '%s', IMAGESIZE tag missing or incorrect. ***\n",file);
+        fprintf(stderr,"Perhaps no XPM/ImageMagick/GraphicsMagick library support is installed?\n");
+        return;
+    }
+    // calculate bottom right map corner from tiepoints
+    // map size is geo_image_width / geo_image_height
+    if (tp[1].img_x != (geo_image_width - 1) ) {
+        tp[1].img_x = geo_image_width - 1;
+        tp[1].x_long = tp[0].x_long + (tp[1].img_x * map_c_dx); // right
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_1 x: %d\t%lu\n", tp[1].img_x, tp[1].x_long);
+    }
+    if (tp[1].img_y != (geo_image_height - 1) ) {
+        tp[1].img_y = geo_image_height - 1;
+        tp[1].y_lat = tp[0].y_lat + (tp[1].img_y * map_c_dy);   // bottom
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_1 y: %d\t%lu\n", tp[1].img_y, tp[1].y_lat);
+    }
+
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        if (terraserver_flag) {
+            // Force the extents to the edges of the earth for the
+            // index file.
+            index_update_xastir(filenm, // Filename only
+                64800000l,      // Bottom
+                0l,             // Top
+                0l,             // Left
+                129600000l,     // Right
+                0);             // Default Map Level
+        }
+        else {
+            index_update_xastir(filenm, // Filename only
+                tp[1].y_lat,    // Bottom
+                tp[0].y_lat,    // Top
+                tp[0].x_long,   // Left
+                tp[1].x_long,   // Right
+                0);             // Default Map Level
+        }
+
+        // Update statusline
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(map_it,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    // Check whether map is inside our current view
+    //                bottom        top    left        right
+    if (!map_visible (tp[1].y_lat, tp[0].y_lat, tp[0].x_long, tp[1].x_long)) {
+        if (debug_level & 16) {
+            fprintf(stderr,"Map not in current view, skipping: %s\n", file);
+            fprintf(stderr,"\nImage: %s\n", file);
+            fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height);
+            fprintf(stderr,"   Map:  lat0:%ld\t lon0:%ld\t lat1:%ld\t lon1:%ld\n",
+                tp[0].y_lat,
+                tp[0].x_long,
+                tp[1].y_lat,
+                tp[1].x_long);
+            fprintf(stderr,"Screen: NWlat:%ld\tNWlon:%ld\tSElat:%ld\tSElon:%ld\n",
+                NW_corner_latitude,
+                NW_corner_longitude,
+                SE_corner_latitude,
+                SE_corner_longitude);
+            fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+        }
+        return;            // Skip this map 
+#ifdef FUZZYRASTER 
+   } else if (((float)(map_c_dx/scale_x) > rasterfuzz) ||
+               ((float)(scale_x/map_c_dx) > rasterfuzz) ||
+               ((float)(map_c_dy/scale_y) > rasterfuzz) ||
+               ((float)(scale_y/map_c_dy) > rasterfuzz)) {
+      fprintf(stderr,"Skipping fuzzy map %s with sx=%f,sy=%f.\n", file,
+             (float)(map_c_dx/scale_x),(float)(map_c_dy/scale_y));
+      return;
+#endif //FUZZYRASTER
+    } else if (debug_level & 16) {
+        fprintf(stderr,"Loading imagemap: %s\n", file);
+        fprintf(stderr,"\nImage: %s\n", file);
+        fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height);
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+    }
+
+    // Update statusline
+    xastir_snprintf(map_it,
+        sizeof(map_it),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(map_it,0);       // Loading/Indexing ...
+
+#ifndef NO_XPM
+    atb.valuemask = 0;
+#endif  // NO_XPM
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+// Best here would be to add the process ID or user ID to the filename
+// (to keep the filename distinct for different users), and to check
+// the timestamp on the map file.  If it's older than xx minutes, go
+// get another one.  Make sure to delete the temp files when closing
+// Xastir.  It'd probably be good to check for old files and delete
+// them when starting Xastir as well.
+
+    // Check to see if we have to use "wget" to go get an internet map
+    if ( (strncasecmp ("http", fileimg, 4) == 0)
+            || (strncasecmp ("ftp", fileimg, 3) == 0)
+            || (terraserver_flag) ) {
+#ifdef HAVE_MAGICK
+        char *ext;
+
+        if (debug_level & 16)
+            fprintf(stderr,"ftp or http file: %s\n", fileimg);
+
+        if (terraserver_flag)
+            ext = "jpg";
+        else
+            ext = get_map_ext(fileimg); // Use extension to determine image type
+
+        if (debug_level & 512) {
+            query_start_time=time(&query_start_time);
+        }
+
+#ifdef USE_MAP_CACHE
+
+        if (nocache || map_cache_fetch_disable) {
+
+            // Delete old copy from the cache
+            if (map_cache_fetch_disable && fileimg[0] != '\0') {
+                if (map_cache_del(fileimg)) {
+                    if (debug_level & 512) {
+                        fprintf(stderr,"Couldn't delete old map from cache\n");
+                    }
+                }
+            }
+
+            // Simulate a cache miss
+            map_cache_return = 1;
+        }
+        else {
+            // Look for the file in the cache
+            map_cache_return = map_cache_get(fileimg,local_filename);
+        }
+
+        if (debug_level & 512) {
+            fprintf(stderr,"map_cache_return: %d\n", map_cache_return);
+        }
+
+        // If nocache is non-zero, we're supposed to refresh the map
+        // at intervals.  Don't use a cached version of the map in
+        // that case.
+        //
+        if (nocache || map_cache_return != 0 ) {
+
+            // Caching not requested or cached file not found.  We
+            // must snag the remote file via libcurl or wget.
+
+            if (nocache) {
+                xastir_snprintf(local_filename,
+                    sizeof(local_filename),
+                    "%s/map.%s",
+                    get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),ext);
+            }
+            else {
+                cache_file_id = map_cache_fileid();
+                xastir_snprintf(local_filename,
+                    sizeof(local_filename),
+                    "%s/map_%s.%s",
+                    get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)),
+                    cache_file_id,
+                    ext);
+                free(cache_file_id);
+            }
+
+#else   // USE_MAP_CACHE
+
+        xastir_snprintf(local_filename,
+            sizeof(local_filename),
+            "%s/map.%s",
+            get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),ext);
+
+#endif  // USE_MAP_CACHE
+
+
+        // Erase any previously existing local file by the same
+        // name.  This avoids the problem of having an old map image
+        // here and the code trying to display it when the download
+        // fails.
+        unlink( local_filename );
+
+        if (fetch_remote_file(fileimg, local_filename)) {
+            // Had trouble getting the file.  Abort.
+            return;
+        }
+    
+#ifdef USE_MAP_CACHE
+
+        // Cache the map only if map_refresh_interval_temp is zero
+        if (!map_refresh_interval_temp) {
+            map_cache_put(fileimg,local_filename);
+        }
+
+        } // end if is cached
+#endif // MAP_CACHE
+
+        if (debug_level & 512) {
+            fprintf (stderr, "Fetch or query took %d seconds\n", 
+                (int) (time(&query_end_time) - query_start_time)); 
+        }
+
+        // Set permissions on the file so that any user can overwrite it.
+        chmod(local_filename, 0666);
+
+        // We now re-use the "file" variable.  It'll hold the
+        //name of the map file now instead of the .geo file.
+        // Tell ImageMagick where to find it
+        xastir_snprintf(file, sizeof(file), "%s", local_filename);
+#endif  // HAVE_MAGICK
+
+    } else {
+        //fprintf(stderr,"Not ftp or http file\n");
+
+        // We now re-use the "file" variable.  It'll hold the
+        //name of the map file now instead of the .geo file.
+        xastir_snprintf(file, sizeof(file), "%s", fileimg);
+    }
+
+    //fprintf(stderr,"File = %s\n",file);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+// The status line is not updated yet, probably 'cuz we're too busy
+// getting the map in this thread and aren't redrawing?
+
+#ifdef HAVE_MAGICK
+    GetExceptionInfo(&exception);
+    image_info=CloneImageInfo((ImageInfo *) NULL);
+    xastir_snprintf(image_info->filename,
+        sizeof(image_info->filename),
+        "%s",
+        file);
+    if (debug_level & 16) {
+           fprintf(stderr,"Copied %s into image info.\n", file);
+           fprintf(stderr,"image_info got: %s\n", image_info->filename);
+           fprintf(stderr,"Entered ImageMagick code.\n");
+           fprintf(stderr,"Attempting to open: %s\n", image_info->filename);
+    }
+
+    // We do a test read first to see if the file exists, so we
+    // don't kill Xastir in the ReadImage routine.
+    f = fopen (image_info->filename, "r");
+    if (f == NULL) {
+fprintf(stderr,"2 ");
+        fprintf(stderr,"File %s could not be read\n",image_info->filename);
+        if (image_info)
+          DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+    (void)fclose (f);
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        if (image_info)
+          DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    image = ReadImage(image_info, &exception);
+
+    if (image == (Image *) NULL) {
+        MagickWarning(exception.severity, exception.reason, exception.description);
+        //fprintf(stderr,"MagickWarning\n");
+        if (image_info)
+          DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr,"Color depth is %i \n", (int)image->depth);
+
+    if (image->colorspace != RGBColorspace) {
+        fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    width = image->columns;
+    height = image->rows;
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    // gamma setup
+    if (imagemagick_options.gamma_flag == 0 ||
+        imagemagick_options.gamma_flag == 1) {
+        if (imagemagick_options.gamma_flag == 0) // if not set in file, set to 1.0
+            imagemagick_options.r_gamma = 1.0;
+
+        imagemagick_options.gamma_flag = 1; // set flag to do gamma
+
+        imagemagick_options.r_gamma += imagemagick_gamma_adjust;
+
+        if (imagemagick_options.r_gamma > 0.95 && imagemagick_options.r_gamma < 1.05)
+            imagemagick_options.gamma_flag = 0; // don't bother if near 1.0
+        else if (imagemagick_options.r_gamma < 0.1)
+            imagemagick_options.r_gamma = 0.1; // 0.0 is black and negative is really wacky
+
+        xastir_snprintf(gamma, sizeof(gamma), "%.1f", imagemagick_options.r_gamma);
+    }
+    else if (imagemagick_options.gamma_flag == 3) {
+        // No checking if you specify 3 channel gamma correction, so you can try negative
+        // numbers, etc. if you wish.
+        imagemagick_options.gamma_flag = 1; // set flag to do gamma
+        imagemagick_options.r_gamma += imagemagick_gamma_adjust;
+        imagemagick_options.g_gamma += imagemagick_gamma_adjust;
+        imagemagick_options.b_gamma += imagemagick_gamma_adjust;
+        xastir_snprintf(gamma, sizeof(gamma), "%.1f,%.1f,%.1f",
+                        imagemagick_options.r_gamma,
+                        imagemagick_options.g_gamma,
+                        imagemagick_options.b_gamma);
+    }
+    else
+        imagemagick_options.gamma_flag = 0;
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (imagemagick_options.gamma_flag) {
+        if (debug_level & 16)
+            fprintf(stderr,"gamma=%s\n", gamma);
+        GammaImage(image, gamma);
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (imagemagick_options.contrast != 0) {
+        if (debug_level & 16)
+            fprintf(stderr,"contrast=%d\n", imagemagick_options.contrast);
+        ContrastImage(image, imagemagick_options.contrast);
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (imagemagick_options.negate != -1) {
+        if (debug_level & 16)
+            fprintf(stderr,"negate=%d\n", imagemagick_options.negate);
+        NegateImage(image, imagemagick_options.negate);
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (imagemagick_options.equalize) {
+        if (debug_level & 16)
+            fprintf(stderr,"equalize");
+        EqualizeImage(image);
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (imagemagick_options.normalize) {
+        if (debug_level & 16)
+            fprintf(stderr,"normalize");
+        NormalizeImage(image);
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+#if (MagickLibVersion >= 0x0539)
+    if (imagemagick_options.level[0] != '\0') {
+        if (debug_level & 16)
+            fprintf(stderr,"level=%s\n", imagemagick_options.level);
+        LevelImage(image, imagemagick_options.level);
+    }
+#endif  // MagickLibVersion >= 0x0539
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (imagemagick_options.modulate[0] != '\0') {
+        if (debug_level & 16)
+            fprintf(stderr,"modulate=%s\n", imagemagick_options.modulate);
+        ModulateImage(image, imagemagick_options.modulate);
+    }
+/*
+    // Else check the menu option for raster intensity
+    else if (raster_map_intensity < 1.0) {
+        char tempstr[30];
+        int temp_i;
+
+        temp_i = (int)(raster_map_intensity * 100.0);
+
+        xastir_snprintf(tempstr,
+            sizeof(tempstr),
+            "%d, 100, 100",
+            temp_i);
+
+//fprintf(stderr,"Modulate: %s\n", tempstr);
+
+        ModulateImage(image, tempstr);
+    }
+*/
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    // crop image: if we just use CropImage(), then the tiepoints will be off
+    // make border pixels transparent.  
+    // cbell - this is a first attempt, it will be integrated into the
+    //         lower loops to speed them up... 
+    if ( do_crop) {
+        int x, y;
+        //        PixelPacket target;
+        register PixelPacket *q;
+      
+        //        target=GetOnePixel(image,0,0);
+        for (y=0; y < (long) image->rows; y++) {
+            q=GetImagePixels(image,0,y,image->columns,1);
+            if (q == (PixelPacket *) NULL)
+                fprintf(stderr, "GetImagePixels Failed....\n");
+            for (x=0; x < (int) image->columns; x++) {
+                if ( (x < crop_x1) || (x > crop_x2) || 
+                     (y < crop_y1) || (y > crop_y2)) {
+                    q->opacity=(Quantum) 1;
+                }
+                q++;
+            }
+            if (!SyncImagePixels(image))
+                fprintf(stderr, "SyncImagePixels Failed....\n");
+	}
+        DestroyImagePixels(image);
+    }
+
+    // If were are drawing to a low bpp display (typically < 8bpp)
+    // try to reduce the number of colors in an image.
+    // This may take some time, so it would be best to do ahead of
+    // time if it is a static image.
+#if (MagickLibVersion < 0x0540)
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) {
+#else   // MagickLib >= 540
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, &exception) > 128) {
+#endif  // MagickLib Version
+
+        if (image->storage_class == PseudoClass) {
+#if (MagickLibVersion < 0x0549)
+            CompressColormap(image); // Remove duplicate colors
+#else // MagickLib >= 0x0549
+            CompressImageColormap(image); // Remove duplicate colors
+#endif  // MagickLibVersion < 0x0549
+        }
+
+        // Quantize down to 128 will go here...
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows);
+    if (!pixel_pack) {
+        fprintf(stderr,"pixel_pack == NULL!!!");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+         return;
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    index_pack = GetIndexes(image);
+    if (image->storage_class == PseudoClass && !index_pack) {
+        fprintf(stderr,"PseudoClass && index_pack == NULL!!!");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+        DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+    if (debug_level & 16)
+#ifdef HAVE_GRAPHICSMAGICK
+        fprintf(stderr,"Colors = %d\n", (int)image->colors);
+#else   // HAVE_GRAPHICSMAGICK
+        fprintf(stderr,"Colors = %ld\n", image->colors);
+#endif  // HAVE_GRAPHICSMAGICK
+
+    // Set up our own version of the color map.
+    if (image->storage_class == PseudoClass && image->colors <= 256) {
+        for (l = 0; l < (int)image->colors; l++) {
+            int leave_unchanged = 0;
+
+            // Need to check how to do this for ANY image, as ImageMagick can read in all sorts
+            // of image files
+            temp_pack = image->colormap[l];
+            if (debug_level & 16)
+                fprintf(stderr,"Colormap color is %i  %i  %i \n",
+                       temp_pack.red, temp_pack.green, temp_pack.blue);
+
+            // Here's a tricky bit:  PixelPacket entries are defined as Quantum's.  Quantum
+            // is defined in /usr/include/magick/image.h as either an unsigned short or an
+            // unsigned char, depending on what "configure" decided when ImageMagick was installed.
+            // We can determine which by looking at MaxRGB or QuantumDepth.
+            //
+
+            if (QuantumDepth == 16) {   // Defined in /usr/include/magick/magick_config.h
+                if (debug_level & 16)
+                    fprintf(stderr,"Color quantum is [0..65535]\n");
+
+                my_colors[l].red   = temp_pack.red;
+                my_colors[l].green = temp_pack.green;
+                my_colors[l].blue  = temp_pack.blue;
+            }
+            else {  // QuantumDepth = 8
+                if (debug_level & 16)
+                    fprintf(stderr,"Color quantum is [0..255]\n");
+
+                my_colors[l].red   = temp_pack.red << 8;
+                my_colors[l].green = temp_pack.green << 8;
+                my_colors[l].blue  = temp_pack.blue << 8;
+            }
+
+            // Take care not to screw up the transparency value by
+            // the raster_map_intensity multiplication factor.
+            if ( trans_color_head ) {
+//fprintf(stderr,"Checking for transparency\n");
+
+                // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
+                if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                    XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                    XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+                }
+                else {
+                    pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                    &my_colors[l].pixel);
+                }
+
+                if (check_trans(my_colors[l],trans_color_head) ) {
+
+                    // Found a transparent color.  Leave it alone.
+                    leave_unchanged++;
+//fprintf(stderr,"Found transparency\n");
+// We never get here!
+                }
+            }
+
+            // Use the map_intensity value if it's not a transparent
+            // color we're dealing with.
+            if (!leave_unchanged) {
+                my_colors[l].red   = my_colors[l].red   * raster_map_intensity;
+                my_colors[l].green = my_colors[l].green * raster_map_intensity;
+                my_colors[l].blue  = my_colors[l].blue  * raster_map_intensity;
+            }
+ 
+
+            // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
+            if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+            }
+            else {
+                pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                &my_colors[l].pixel);
+            }
+
+            if (debug_level & 16)
+                fprintf(stderr,"Color allocated is %li  %i  %i  %i \n", my_colors[l].pixel,
+                       my_colors[l].red, my_colors[l].blue, my_colors[l].green);
+        }
+    }
+
+    if (check_interrupt(image, image_info, 
+	&exception, &da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+#ifdef TIMING_DEBUG
+    time_mark(0);
+#endif  // TIMING_DEBUG
+
+    if (debug_level & 16) {
+       fprintf(stderr,"Image size %d %d\n", width, height);
+#if (MagickLibVersion < 0x0540)
+       fprintf(stderr,"Unique colors = %d\n", GetNumberColors(image, NULL));
+#else   // MagickLibVersion < 0x0540
+       fprintf(stderr,"Unique colors = %ld\n", GetNumberColors(image, NULL, &exception));
+#endif  // MagickLibVersion < 0x0540
+       fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T,
+               map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+
+       #if (MagickLibVersion < 0x0540)
+           fprintf(stderr,"is Gray Image = %i\n", IsGrayImage(image));
+           fprintf(stderr,"is Monochrome Image = %i\n", IsMonochromeImage(image));
+           //fprintf(stderr,"is Opaque Image = %i\n", IsOpaqueImage(image));
+           //fprintf(stderr,"is PseudoClass = %i\n", image->storage_class == PseudoClass);
+       #else    // MagickLibVersion < 0x0540
+           fprintf(stderr,"is Gray Image = %i\n", IsGrayImage( image, &exception ));
+           fprintf(stderr,"is Monochrome Image = %i\n", IsMonochromeImage( image, &exception ));
+           //fprintf(stderr,"is Opaque Image = %i\n", IsOpaqueImage( image, &exception ));
+           //fprintf(stderr,"is PseudoClass = %i\n", image->storage_class == PseudoClass);
+       #endif   // MagickLibVersion < 0x0540
+
+       fprintf(stderr,"image matte is %i\n", image->matte);
+       fprintf(stderr,"Colorspace = %i\n", image->colorspace);
+       if (image->colorspace == UndefinedColorspace)
+            fprintf(stderr,"Class Type = Undefined\n");
+       else if (image->colorspace == RGBColorspace)
+            fprintf(stderr,"Class Type = RGBColorspace\n");
+       else if (image->colorspace == GRAYColorspace)
+            fprintf(stderr,"Class Type = GRAYColorspace\n");
+       else if (image->colorspace == sRGBColorspace)
+            fprintf(stderr,"Class Type = sRGBColorspace\n");
+    }
+
+#else   // HAVE_MAGICK
+
+    // We don't have ImageMagick libs compiled in, so use the
+    // XPM library instead.
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    // Check whether file has .xpm or .xpm.Z or .xpm.gz at the end.
+    // If not, don't use the XpmReadFileToImage call below.
+
+    if (       !strstr(filenm,"xpm")
+            && !strstr(filenm,"XPM")
+            && !strstr(filenm,"Xpm") ) {
+        fprintf(stderr,
+            "Error: File format not supported by XPM library: %s\n",
+            filenm);
+        return;
+    }
+
+    /*  XpmReadFileToImage is the call we wish to avoid if at all
+     *  possible.  On large images this can take quite a while.  We
+     *  check above to see whether the image is inside our viewport,
+     *  and if not we skip loading the image.
+     */
+    if (! XpmReadFileToImage (XtDisplay (w), file, &xi, NULL, &atb) == XpmSuccess) {
+        fprintf(stderr,"ERROR loading %s\n", file);
+        if (xi)
+            XDestroyImage (xi);
+        return;
+    }
+
+    if (debug_level & 16) {
+        fprintf(stderr,"Image size %d %d\n", (int)atb.width, (int)atb.height);
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n",
+            map_c_L,
+            map_c_T,
+            map_c_dx,
+            (int) (map_c_dx / scale_x),
+            map_c_dy,
+            (int) (map_c_dy / scale_y));
+    }
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        if (xi)
+            XDestroyImage (xi);
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    width  = atb.width;
+    height = atb.height;
+
+#endif  // HAVE_MAGICK
+
+    // draw the image from the file out to the map screen
+
+    // Get the border values for the X and Y for loops used
+    // for the XFillRectangle call later.
+
+    map_c_yc = (tp[0].y_lat + tp[1].y_lat) / 2;     // vert center of map as reference
+    map_y_ctr = (long)(height / 2 +0.499);
+    scale_x0 = get_x_scale(0,map_c_yc,scale_y);     // reference scaling at vert map center
+
+    map_c_xc  = (tp[0].x_long + tp[1].x_long) / 2;  // hor center of map as reference
+    map_x_ctr = (long)(width  / 2 +0.499);
+    scr_x_mc  = (map_c_xc - NW_corner_longitude) / scale_x; // screen coordinates of map center
+
+    // calculate map pixel range in y direction that falls into screen area
+    c_y_max = 0ul;
+    map_y_min = map_y_max = 0l;
+    for (map_y_0 = 0, c_y = tp[0].y_lat; map_y_0 < (long)height; map_y_0++, c_y += map_c_dy) {
+        scr_y = (c_y - NW_corner_latitude) / scale_y;   // current screen position
+        if (scr_y > 0) {
+            if (scr_y < screen_height) {
+                map_y_max = map_y_0;          // update last map pixel in y
+                c_y_max = (unsigned long)c_y;// bottom map inside screen coordinate
+            } else
+                break;                      // done, reached bottom screen border
+        } else {                            // pixel is above screen
+            map_y_min = map_y_0;              // update first map pixel in y
+        }
+    }
+//    fprintf(stderr,"map top: %ld bottom: %ld\n",tp[0].y_lat,tp[1].y_lat);
+    c_y_min = (unsigned long)(tp[0].y_lat + map_y_min * map_c_dy);   // top map inside screen coordinate
+
+//    // find the y coordinate nearest to the equator
+//    c_y = 90*60*60*100;         // Equator
+//    if ((c_y_min>c_y && c_y_max>c_y) || (c_y_min<c_y && c_y_max<c_y)) {
+//        if (abs(c_y_min-c_y) > abs(c_y_max-c_y))
+//            c_y = c_y_max;      // north
+//        else
+//            c_y = c_y_min;      // south
+//    }
+//    scale_x0 = get_x_scale(0,(long)c_y,scale_y); // calc widest map area in x
+
+//    if (map_proj != 1) {
+        // calculate map pixel range in x direction that falls into screen area
+        map_x_min = map_x_max = 0l;
+        for (map_x = 0, c_x = tp[0].x_long; map_x < (long)width; map_x++, c_x += map_c_dx) {
+            scr_x = (c_x - NW_corner_longitude)/ scale_x;  // current screen position
+            if (scr_x > 0) {
+                if (scr_x < screen_width)
+                    map_x_max = map_x;          // update last map pixel in x
+                else
+                    break;                      // done, reached right screen border
+            } else {                            // pixel is left from screen
+                map_x_min = map_x;              // update first map pixel in x
+            }
+        }
+        c_x_min = (unsigned long)(tp[0].x_long + map_x_min * map_c_dx);   // left map inside screen coordinate
+//    }
+//    for (scr_y = scr_y_min; scr_y <= scr_y_max;scr_y++) {       // screen lines
+//    }
+
+    test = 1;           // DK7IN: debuging
+    scr_yp = -1;
+    scr_c_xr = SE_corner_longitude;
+    c_dx = map_c_dx;                            // map pixel width
+    scale_xa = scale_x0;                        // the compiler likes it ;-)
+
+//    for (map_y_0 = 0, c_y = tp[0].y_lat; map_y_0 < (long)height; map_y_0++, c_y += map_c_dy) {
+//        scr_y = (c_y - NW_corner_latitude) / scale_y;   // current screen position
+
+    map_done = 0;
+    map_act  = 0;
+    map_seen = 0;
+    scr_y = screen_height - 1;
+
+#ifdef TIMING_DEBUG
+    time_mark(0);
+#endif  // TIMING_DEBUG
+
+
+    if (check_interrupt(
+#ifdef HAVE_MAGICK
+			image, image_info, &exception, 
+#else  // HAVE_MAGICK
+            		xi,
+#endif // HAVE_MAGICK
+			&da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+
+    // loop over map pixel rows
+    for (map_y_0 = map_y_min, c_y = (double)c_y_min;
+                (map_y_0 <= map_y_max) || (map_proj == 1 && !map_done && scr_y < screen_height);
+                map_y_0++, c_y += map_c_dy) {
+
+    if (check_interrupt(
+#ifdef HAVE_MAGICK
+			image, image_info, &exception, 
+#else  // HAVE_MAGICK
+            		xi,
+#endif // HAVE_MAGICK
+			&da, &pixmap, &gc, screen_width, screen_height))
+	return;
+
+        scr_y = (c_y - NW_corner_latitude) / scale_y;
+        if (scr_y != scr_yp) {                  // don't do a row twice
+            scr_yp = scr_y;                     // remember as previous y
+            if (map_proj == 1) {                // Transverse Mercator correction in x
+                scale_xa = get_x_scale(0,(long)c_y,scale_y); // recalc scale_x for current y
+                c_dx = map_c_dx * scale_xa / scale_x0;       // adjusted map pixel width
+
+                map_x_min = map_x_ctr - (map_c_xc - NW_corner_longitude) / c_dx;
+                if (map_x_min < 0)
+                    map_x_min = 0;
+                c_x_min = map_c_xc - (map_x_ctr - map_x_min) * c_dx;
+                map_x_max = map_x_ctr - (map_c_xc - scr_c_xr) / c_dx;
+                if (map_x_max > (long)width)
+                    map_x_max = width;
+                scr_dx = (int) (c_dx / scale_x) + 1;    // at least 1 pixel wide
+            }
+
+//            if (c_y == (double)c_y_min) {  // first call
+//                fprintf(stderr,"map: min %ld ctr %ld max %ld, c_dx %ld, c_x_min %ld, c_y_min %ld\n",map_x_min,map_x_ctr,map_x_max,(long)c_dx,c_x_min,c_y_min);
+//            }
+            scr_xp = -1;
+            // loop over map pixel columns
+            map_act = 0;
+            scale_x_nm = calc_dscale_x(0,(long)c_y) / 1852.0;  // nm per Xastir coordinate
+            for (map_x = map_x_min, c_x = (double)c_x_min; map_x <= map_x_max; map_x++, c_x += c_dx) {
+                scr_x = (c_x - NW_corner_longitude) / scale_x;
+                if (scr_x != scr_xp) {      // don't do a pixel twice
+                    scr_xp = scr_x;         // remember as previous x
+                    if (map_proj == 1) {    // Transverse Mercator correction in y
+// DK7IN--
+                        dist = (90*60 - (c_y / 6000.0));   // equator distance in nm
+                        // ?? 180W discontinuity!  not done yet
+                        ew_ofs = (c_x - (double)map_c_xc) * scale_x_nm;  // EW offset from center in nm
+                        //corrfact = (map_y_0 - map_y_ctr)/(2*map_y_ctr);  // 0..50%
+                        //corrfact = fabs(ew_ofs/dist)*3.0;
+                        //corrfact = 1.0-1.0*(0.5*map_y_0 / map_y_ctr);
+                        corrfact = 1.0;
+                        c_y_a = (fabs(dist) - sqrt((double)(dist*dist - ew_ofs*ew_ofs)))*6000.0; // in Xastir units
+                        if (dist < 0)           // S
+                            map_y = map_y_0 + (long)(corrfact*c_y_a / map_c_dy);  // coord per pixel
+                        else                    // N
+                            map_y = map_y_0 - (long)(corrfact*c_y_a / map_c_dy);
+//                        if (test < 10) {
+//                            fprintf(stderr,"dist: %ldkm, ew_ofs: %ldkm, dy: %ldkm\n",(long)(1.852*dist),(long)(1.852*ew_ofs),(long)(1.852*c_y_a/6000.0));
+//                            fprintf(stderr,"  corrfact: %f, mapy0: %ld, mapy: %ld\n",corrfact,map_y_0,map_y);
+//                            test++;
+//                        }
+                    } else {
+                        map_y = map_y_0;
+                    }
+
+                    if (map_y >= 0 && map_y <= tp[1].img_y) { // check map boundaries in y direction
+                        map_seen = 1;
+                        map_act = 1;    // detects blank screen rows (end of map)
+
+// DK7IN--
+
+//----- copy pixel from map to screen ---------------------
+//            if (c_y == (double)c_y_min && (scr_x < 5 || (c_x == (double)c_x_min))) {  // first call
+//                fprintf(stderr,"map: x %ld y %ld scr: x %ld y %ld dx %d, dy %d\n",map_x,map_y,scr_x,scr_y,scr_dx,scr_dy);
+//                fprintf(stderr,"color: %ld\n",XGetPixel (xi, map_x, map_y));
+//                // 65529
+//            }
+
+                        // now copy a pixel from the map image to the screen
+#ifdef HAVE_MAGICK
+                        l = map_x + map_y * image->columns;
+                        trans_skip = 1; // possibly transparent
+                        if (image->storage_class == PseudoClass) {
+                            if ( trans_color_head && 
+                                    check_trans(my_colors[index_pack[l]],trans_color_head) ) {
+                                trans_skip = 1; // skip it
+                            }
+                            else {
+                                XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel);
+                                trans_skip = 0; // draw it
+                            }
+                        } else {
+                            // It is not safe to assume that the red/green/blue
+                            // elements of pixel_pack of type Quantum are the
+                            // same as the red/green/blue of an XColor!
+                            if (QuantumDepth==16) {
+                                my_colors[0].red=pixel_pack[l].red;
+                                my_colors[0].green=pixel_pack[l].green;
+                                my_colors[0].blue=pixel_pack[l].blue;
+                            }
+                            else { // QuantumDepth=8
+                                // shift the bits of the 8-bit quantity so that
+                                // they become the high bigs of my_colors.*
+                                my_colors[0].red=pixel_pack[l].red<<8;
+                                my_colors[0].green=pixel_pack[l].green<<8;
+                                my_colors[0].blue=pixel_pack[l].blue<<8;
+                            }
+                            // NOW my_colors has the right r,g,b range for
+                            // pack_pixel_bits
+                            pack_pixel_bits(my_colors[0].red * raster_map_intensity,
+                                            my_colors[0].green * raster_map_intensity,
+                                            my_colors[0].blue * raster_map_intensity,
+                                            &my_colors[0].pixel);
+                            if ( trans_color_head && 
+                                    check_trans(my_colors[0],trans_color_head) ) {
+                                trans_skip = 1; // skip it
+                            }
+                            else {
+                                XSetForeground(XtDisplay(w), gc, my_colors[0].pixel);
+                                trans_skip = 0; // draw it
+                            }
+                        }
+#else   // HAVE_MAGICK
+                        (void)XSetForeground (XtDisplay (w), gc, XGetPixel (xi, map_x, map_y));
+#endif  // HAVE_MAGICK
+
+
+                        // Skip drawing if a transparent pixel
+#ifdef HAVE_MAGICK
+                        if ( pixel_pack[l].opacity == 0 && !trans_skip  ) // skip transparent
+#else   // HAVE_MAGICK
+                        if (!trans_skip)    // skip transparent
+#endif  // HAVE_MAGICK
+
+                            (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,scr_dx,scr_dy);
+                    } // check map boundaries in y direction
+                }
+            } // loop over map pixel columns
+            if (map_seen && !map_act)
+                map_done = 1;
+        }
+    } // loop over map pixel rows
+
+#ifdef HAVE_MAGICK
+    if (image)
+        DestroyImage(image);
+    if (image_info)
+        DestroyImageInfo(image_info);
+    DestroyExceptionInfo(&exception);
+ #else   // HAVE_MAGICK
+    if (xi)
+        XDestroyImage (xi);
+#endif // HAVE_MAGICK
+
+#ifdef TIMING_DEBUG
+    time_mark(0);
+#endif  // TIMING_DEBUG
+#endif  // NO_GRAPHICS
+}
diff --git a/src/map_gnis.c b/src/map_gnis.c
new file mode 100644
index 0000000..89097fb
--- /dev/null
+++ b/src/map_gnis.c
@@ -0,0 +1,1405 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_gnis.c,v 1.41 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+//NOTE:  This function has a problem if a non-gnis file is labeled
+//with a ".gnis" extension.  It causes a segfault in Xastir.  More
+//error checking needs to be done in order to prevent this.
+
+// draw_gnis_map()
+//
+// Allows drawing a background map of labels for the viewport.
+// Example format (old):
+// "WA","Abbey View Memorial Park","cemetery","Snohomish","53","061","474647N","1221650W","47.77972","-122.28056","","","","","420","","Edmonds East"
+//
+// Example format (new):
+// 376016|ID|12th Ave Drain|stream|Canyon|16|027|433107N|1163348W|43.51861|-116.56333||||||||Nampa
+//
+// These types of files are available from http://geonames.usgs.gov/
+// under "Download State Gazetteer Data - Available Via Anonymous FTP".
+// A typical filename would be: "WA_Features_20090401.zip".   Do not get the other
+// types of files which are columnar.  The files that we parse are
+// pipe-delimited.
+//
+void draw_gnis_map (Widget w,
+		    char *dir,
+		    char *filenm,
+		    alert_entry *alert,
+		    u_char alert_color,
+		    int destination_pixmap,
+		    map_draw_flags *mdf)
+{
+    char file[MAX_FILENAME];        // Complete path/name of GNIS file
+    char short_filenm[MAX_FILENAME];
+    FILE *f;                        // Filehandle of GNIS file
+    char line[MAX_FILENAME];        // One line of text from file
+    char *i, *j;
+    char state[50];
+    char name[200];
+    char type[100];
+    char county[100];
+    char latitude[15];
+    char longitude[15];
+    char population[15];
+    char lat_dd[3];
+    char lat_mm[3];
+    char lat_ss[3];
+    char lat_dir[2];
+    char long_dd[4];
+    char long_mm[3];
+    char long_ss[3];
+    char long_dir[2];
+    char lat_str[15];
+    char long_str[15];
+    int temp1;
+    long coord_lon, coord_lat;
+    long min_lat, min_lon, max_lat, max_lon;
+    int ok;
+    long x,y;
+    char symbol_table, symbol_id, symbol_over;
+    unsigned long bottom_extent = 0l;
+    unsigned long top_extent = 0l;
+    unsigned long left_extent = 0l;
+    unsigned long right_extent = 0l;
+    char status_text[MAX_FILENAME];
+    int count = 0;
+
+
+    //fprintf(stderr,"draw_gnis_map starting: %s/%s\n",dir,filenm);
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    // Screen view
+    min_lat = SE_corner_latitude;
+    max_lat = NW_corner_latitude;
+    min_lon = NW_corner_longitude;
+    max_lon = SE_corner_longitude;
+
+
+    // The map extents in the map index are checked in draw_map to
+    // see whether we should draw the map at all.
+
+
+    // Update the statusline for this map name
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA039"),
+            short_filenm);
+    }
+    else {
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA028"),
+            short_filenm);
+    }
+    statusline(status_text,0);       // Loading/Indexing ...
+
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+
+/*
+Latest pipe-delimited format from USGS (as of 08/12/2004):
+----------------------------------------------------------
+Feature ID Number (FID)
+State Alpha Code
+Feature Name
+Feature Type
+County Name
+State Number Code (FIPS Code)
+County Number Code (FIPS Code)
+Primary Latitude (DMS)
+Primary Longitude (DMS)
+Primary Latitude (decimal degrees)
+Primary Longitude (decimal degrees)
+Source Latitude (DMS)
+Source Longitude (DMS)
+Source Latitude (decimal degrees)
+Source Longitude (decimal degrees)
+Elevation
+Estimated Population
+Federal Status
+Cell Name
+*/
+
+
+    // Attempt to open the file
+    f = fopen (file, "r");
+    if (f != NULL) {
+        while (!feof (f)) {     // Loop through entire file
+            int lat_in_view = 0;
+
+            count++;
+            if ((count % 16) == 0) {
+
+                // Check whether map drawing should be interrupted.
+                // Check every 16 lines.
+                //
+                HandlePendingEvents(app_context);
+                if (interrupt_drawing_now) {
+                    (void)fclose (f);
+                    // Update to screen
+                    (void)XCopyArea(XtDisplay(da),
+                        pixmap,
+                        XtWindow(da),
+                        gc,
+                        0,
+                        0,
+                        (unsigned int)screen_width,
+                        (unsigned int)screen_height,
+                        0,
+                        0);
+                    return;
+                }
+            }
+
+            if ( get_line (f, line, MAX_FILENAME) ) {  // Snag one line of data
+
+                // It is common for these lines to have incredible
+                // numbers of spaces at the end, so trim them here.
+                (void)remove_trailing_spaces(line);
+
+                if (strlen(line) > 0) {
+
+                    // Default population, in case the field isn't
+                    // present in the file.
+                    xastir_snprintf(population,sizeof(population),"0");
+ 
+// Examples of old/new format:
+// 1462331|VA|Abingdon Elementary School|school|Arlington|51|013|385023N|0770546W|38.83972|-77.09611||||||||Alexandria
+// 1462331|VA|Abingdon Elementary School|School|Arlington|51|013|385023N|0770545W|38.8398349|-77.0958117|56|Alexandria
+// 2008 Format follows
+//FEATURE_ID|FEATURE_NAME|FEATURE_CLASS|STATE_ALPHA|STATE_NUMERIC|COUNTY_NAME|COUNTY_NUMERIC|PRIMARY_LAT_DMS|PRIM_LONG_DMS|PRIM_LAT_DEC|PRIM_LONG_DEC|SOURCE_LAT_DMS|SOURCE_LONG_DMS|SOURCE_LAT_DEC|SOURCE_LONG_DEC|ELEVATION|MAP_NAME|DATE_CREATED|DATE_EDITED
+//205110|Appalachian National Scenic Trail|Trail|PA|42|Perry|099|401920N|0770439W|40.3221113|-77.0775473|||||201|Wertzville|09/12/1979|05/19/2008
+
+                    //NOTE:  We handle running off the end of "line"
+                    //via the "continue" statement.  Skip the line
+                    //if we don't find enough parameters while
+                    //parsing.
+
+                    // Find end of Feature ID Number field
+                    j = index(line,'|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+//NOTE:  It'd be nice to take the part after the comma and put it before the rest
+// of the text someday, i.e. "Cassidy, Lake".
+
+                    // Find end of Feature Name field
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(name,sizeof(name),"%s",j);
+
+                    // Find end of Feature Type field
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+                    xastir_snprintf(type,sizeof(type),"%s",i);
+
+                    // Find end of State field
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(state,sizeof(state),"%s",j);
+
+                    // Find end of State Number Code field
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+
+                    // Find end of County Name field
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(county,sizeof(county),"%s",j);
+
+                    // Find end of County Number Code field
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+
+// Examples of old/new format:
+// 1462331|VA|Abingdon Elementary School|school|Arlington|51|013|385023N|0770546W|38.83972|-77.09611||||||||Alexandria
+// 1462331|VA|Abingdon Elementary School|School|Arlington|51|013|385023N|0770545W|38.8398349|-77.0958117|56|Alexandria
+
+                    // Find end of Primary Latitude field (DDMMSSN)
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(latitude,sizeof(latitude),"%s",j);
+                    if (!isdigit((int)latitude[0])) { // skip record if not
+                        continue;                // numeric! (e.g. "UNKNOWN")
+                    }
+
+//WE7U
+                    clean_string(latitude);
+                    
+                    // Find end of Primary Longitude field (DDDMMSSW)
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+                    xastir_snprintf(longitude,sizeof(longitude),"%s",i);
+                    if (!isdigit((int)longitude[0])) { // skip record if not
+                        continue;                 // numeric (e.g. UNKNOWN)
+                    }
+
+//WE7U
+                    clean_string(longitude);
+
+                    // Find end of Primary Latitude field (decimal
+                    // degrees)
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Primary Longitude field (decimal
+                    // degrees)
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    j[0] = '\0';
+
+// Examples of old/new format:
+// 1462331|VA|Abingdon Elementary School|school|Arlington|51|013|385023N|0770546W|38.83972|-77.09611||||||||Alexandria
+// 1462331|VA|Abingdon Elementary School|School|Arlington|51|013|385023N|0770545W|38.8398349|-77.0958117|56|Alexandria
+ 
+                    // Find end of Source Latitude field (DMS) (old
+                    // format) or elevation (new format)
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Source Longitude field (DMS) (old
+                    // format) or 
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    j[0] = '\0';
+
+                    // Find end of Source Latitude field (decimal
+                    // degrees)
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Source Longitude field (decimal
+                    // degrees)
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    j[0] = '\0';
+
+                    // Find end of Elevation field
+                    i = index(++j, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Estimated Population field
+                    j = index(++i, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    if ( j != NULL ) {
+                        j[0] = '\0';
+                        xastir_snprintf(population,sizeof(population),"%s",i);
+                    }
+
+FINISH:
+                    // There are two more fields (old format),
+                    // "Federal Status" and "Cell Name".  We ignore
+                    // those for now.
+ 
+		    if (strlen(latitude) < 7) 
+			continue;	// We really don't have any latitude here.
+                    lat_dd[0] = latitude[0];
+                    lat_dd[1] = latitude[1];
+                    lat_dd[2] = '\0';
+ 
+                    lat_mm[0] = latitude[2];
+                    lat_mm[1] = latitude[3];
+                    lat_mm[2] = '\0';
+
+                    lat_ss[0] = latitude[4];
+                    lat_ss[1] = latitude[5];
+                    lat_ss[2] = '\0';
+
+                    lat_dir[0] = latitude[6];
+                    lat_dir[1] = '\0';
+
+                    // Now must convert from DD MM SS format to DD MM.MM format so that we
+                    // can run it through our conversion routine to Xastir coordinates.
+                    if (1 != sscanf(lat_ss, "%d", &temp1)) {
+                        fprintf(stderr,"draw_gnis_map:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(lat_str, sizeof(lat_str), "%s%s.%02d%s", lat_dd,
+                            lat_mm, temp1, lat_dir);
+                    coord_lat = convert_lat_s2l(lat_str);
+
+                    // Quick test of latitude to see if it's within
+                    // our view.  If not and we're not doing
+                    // indexing, skip this line and go on to the
+                    // next.
+                    if (coord_lat <= min_lat && coord_lat >= max_lat) {
+                        // Latitude is ok
+                        lat_in_view++;
+                    }
+                    else {  // Latitude not in current view
+
+                        // Check whether we're indexing the map
+                        if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                                || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+                            // Process the line 'cuz we're indexing
+                        }
+                        else {  // Not indexing so skip to the next
+                                // line in the file
+                            continue;
+                        }
+                    }
+
+		    if (strlen(longitude) < 8) 
+			continue;	// We really don't have any longitude here.
+                    long_dd[0] = longitude[0];
+                    long_dd[1] = longitude[1];
+                    long_dd[2] = longitude[2];
+                    long_dd[3] = '\0';
+ 
+                    long_mm[0] = longitude[3];
+                    long_mm[1] = longitude[4];
+                    long_mm[2] = '\0';
+ 
+                    long_ss[0] = longitude[5];
+                    long_ss[1] = longitude[6];
+                    long_ss[2] = '\0';
+ 
+                    long_dir[0] = longitude[7];
+                    long_dir[1] = '\0';
+
+                    if (1 != sscanf(long_ss, "%d", &temp1)) {
+                        fprintf(stderr,"draw_gnis_map:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(long_str, sizeof(long_str), "%s%s.%02d%s", long_dd,
+                            long_mm, temp1, long_dir);
+                    coord_lon = convert_lon_s2l(long_str);
+
+
+                    // Check whether we're indexing the map
+                    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+                        // Save the min/max extents of the file.  We
+                        // should really initially set the extents
+                        // to the min/max for the Xastir coordinate
+                        // system, but in practice zeroes should
+                        // work just as well.
+                        //
+                        if ((coord_lat > (long)bottom_extent) || (bottom_extent == 0l))
+                            bottom_extent = coord_lat;
+                        if ((coord_lat < (long)top_extent) || (top_extent == 0l))
+                            top_extent = coord_lat;
+                        if ((coord_lon < (long)left_extent) || (left_extent == 0l))
+                            left_extent = coord_lon;
+                        if ((coord_lon > (long)right_extent) || (right_extent == 0l))
+                            right_extent = coord_lon;
+                    }
+                    // Now check whether this lat/lon is within our viewport.  If it
+                    // is, draw a text label at that location.
+                    else if (coord_lon >= min_lon && coord_lon <= max_lon
+                            && lat_in_view) {
+
+                        clean_string(state);
+                        clean_string(name);
+                        clean_string(type);
+                        clean_string(county);
+                        clean_string(population);
+
+                        if (debug_level & 16) {
+                            fprintf(stderr,"%s\t%s\t%s\t%s\t%s\t%s\t\t",
+                                    state, name, type, county, latitude, longitude);
+                            fprintf(stderr,"%s %s %s %s\t%s %s %s %s\t\t",
+                                    lat_dd, lat_mm, lat_ss, lat_dir, long_dd, long_mm, long_ss, long_dir);
+                            fprintf(stderr,"%s\t%s\n", lat_str, long_str);
+                        }
+
+                        // Convert to screen coordinates.  Careful
+                        // here!  The format conversions you'll need
+                        // if you try to compress this into two
+                        // lines will get you into trouble.
+                        x = coord_lon - NW_corner_longitude;
+                        y = coord_lat - NW_corner_latitude;
+                        x /= scale_x;
+                        y /= scale_y;
+
+                        ok = 1;
+
+                        /* set default symbol */
+                        symbol_table = '/';
+                        symbol_id = '.'; /* small x */
+                        symbol_over = ' ';
+
+                        if (strcasecmp(type,"airport") == 0) {
+                            symbol_id = '^';
+                            if (scale_y > 100)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"arch") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"area") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"arroyo") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bar") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"basin") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bay") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"beach") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bench") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bend") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bridge") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"building") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"canal") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cape") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cave") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cemetery") == 0) {
+                            symbol_table = '\\';
+                            symbol_id = '+';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"census") == 0) {
+                          /* if (scale_y > 50)*/  /* Census divisions */
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"channel") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"church") == 0) {
+                            symbol_table = '\\';
+                            symbol_id = '+';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"civil") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cliff") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"crater") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"crossing") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"dam") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"falls") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"flat") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"forest") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"gap") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"geyser") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"glacier") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"gut") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"harbor") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"hospital") == 0) {
+                            symbol_id = 'h';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"island") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"isthmus") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"lake") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"lava") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"levee") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"locale") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"military") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"mine") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"oilfield") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"other") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"park") == 0) {
+                            symbol_table = '\\';
+                            symbol_id = ';';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"pillar") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"plain") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"po") == 0) {
+                            symbol_id = ']';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"ppl") == 0) {
+                            symbol_id = '/';
+                            if (scale_y > 20000)    // Don't draw cities at zoom higher than 20,000
+                                ok = 0;
+                            else if (scale_y > 4000) {  // Don't draw cities of less than 20,000
+                                if (atoi(population) < 50000) {
+                                    ok = 0;
+                                }
+                            }
+                            else if (scale_y > 1500) {  // Don't draw cities of less than 10,000
+                                if (atoi(population) < 20000) {
+                                    ok = 0;
+                                }
+                            }
+                            else if (scale_y > 750) {  // Don't draw cities of less than 5,000
+                                if (atoi(population) < 10000) {
+                                    ok = 0;
+                                }
+                            }
+                            else if (scale_y > 200) {   // Don't draw cities 
+                                                        // of less than 1,000
+                                if (atoi(population) < 1000) {
+                                    ok = 0;
+                                    //fprintf(stderr,
+                                    // "Name: %s\tPopulation: %s\n",name,
+                                    // population);
+                                }
+                            }
+                        }
+                        else if (strcasecmp(type,"range") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"rapids") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"reserve") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"reservoir") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"ridge") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"school") == 0) {
+                            symbol_id = 'K';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"sea") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"slope") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"spring") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"stream") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"summit") == 0) {
+                            if (scale_y > 100)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"swamp") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"trail") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"tower") == 0) {
+                            symbol_id = 'r';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"tunnel") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"valley") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"well") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"woods") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"ruin") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else {
+                            fprintf(stderr,"Something unusual found, Type:%s\tState:%s\tCounty:%s\tName:%s\n",
+                                type,state,county,name);
+                        }
+
+                        if (ok == 1) {  // If ok to draw it
+                            symbol(w, 0, symbol_table, symbol_id, symbol_over, pixmap, 1, x-10, y-10, ' ');
+                            draw_nice_string(w, pixmap, 0, x+10, y+5, (char*)name, 0xf, 0x10, strlen(name));
+                        }
+
+                    }
+                    else {
+                        //fprintf(stderr,"Not in viewport.  Coordinates: %ld %ld\n",coord_lat,coord_lon);
+                        //fprintf(stderr,"Min/Max Lat: %ld %ld\n",min_lat,max_lat);
+                        //fprintf(stderr,"Min/Max Lon: %ld %ld\n",min_lon,max_lon);
+                    }
+                }
+            }
+        }   // End of while
+        (void)fclose (f);
+
+
+        // Check whether we're indexing the map
+        if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+            // We're indexing only.  Save the extents in the index.
+            index_update_xastir(filenm, // Filename only
+                bottom_extent,  // Bottom
+                top_extent,     // Top
+                left_extent,    // Left
+                right_extent,   // Right
+                99999);         // Default Map Level
+        }
+    }
+    else {
+        fprintf(stderr,"Couldn't open file: %s\n", file);
+        return;
+    }
+    if (debug_level & 16)
+        fprintf(stderr,"Exiting draw_gnis_map\n");
+}
+
+
+
+
+
+// Search for a placename among GNIS files
+//
+// We need to search a file in the map directory that has the filename
+// STATE.gis, where STATE is from the "state" variable passed to us.
+// Search for the placename/county/state/type that the user requested.
+// Once found, center the map on that location or bring up a response
+// dialog that asks whether one wants to go there, and that dialog
+// provides info about the place found, with a possible selection
+// out of a list of matches.
+// Might also need to place a label at that position on the map in
+// case that GNIS file isn't currently selected.
+//
+int gnis_locate_place( Widget w,
+        char *name_in,
+        char *state_in,
+        char *county_in,
+        char *quad_in,
+        char *type_in,
+        char *filename_in,
+        int follow_case,
+        int get_match,
+        char match_array_name[50][200],
+        long match_array_lat[50],
+        long match_array_long[50] ) {
+
+    char file[MAX_FILENAME];        // Complete path/name of GNIS file
+    FILE *f;                        // Filehandle of GNIS file
+    char line[MAX_FILENAME];        // One line of text from file
+    char *i, *j;
+    char state[50];
+    char state_in2[50];
+    char name[200];
+    char name_in2[50];
+    char type[100];
+    char type_in2[50];
+    char county[100];
+    char county_in2[50];
+    char quad[100];
+    char quad_in2[100];
+    char latitude[15];
+    char longitude[15];
+    char population[15];
+    char lat_dd[3];
+    char lat_mm[3];
+    char lat_ss[3];
+    char lat_dir[2];
+    char long_dd[4];
+    char long_mm[3];
+    char long_ss[3];
+    char long_dir[2];
+    char lat_str[15];
+    char long_str[15];
+    int temp1;
+    long coord_lon, coord_lat;
+    int ok;
+    struct stat file_status;
+    int my_count = 0;
+ 
+ 
+    xastir_snprintf(file,sizeof(file),"%s",filename_in);
+
+    if (debug_level & 16)
+        fprintf(stderr,"File: %s\n",file);
+
+
+    xastir_snprintf(name_in2,sizeof(name_in2),"%s",name_in);
+    xastir_snprintf(state_in2,sizeof(state_in2),"%s",state_in);
+    xastir_snprintf(county_in2,sizeof(county_in2),"%s",county_in);
+    xastir_snprintf(quad_in2,sizeof(quad_in2),"%s",quad_in);
+    xastir_snprintf(type_in2,sizeof(type_in2),"%s",type_in);
+
+
+    // Convert State/Province to upper-case always (they're
+    // always upper-case in the GNIS files from USGS.
+    to_upper(state_in2);
+
+
+    if (debug_level & 16)
+        fprintf(stderr,"Name:%s\tState:%s\tCounty:%s\tQuad:%s\tType:%s\n",
+        name_in,state_in2,county_in,quad_in,type_in);
+
+
+    // If "Match Case" togglebutton is not set, convert the
+    // rest of the keys to upper-case.
+    if (!follow_case) {
+        to_upper(name_in2);
+        to_upper(county_in2);
+        to_upper(quad_in2);
+        to_upper(type_in2);
+    }
+
+
+    // Check status of the file
+    if (stat(file, &file_status) < 0) {
+        // "Can't open file"
+        popup_message( langcode("POPEM00028"), filename_in );
+        return(0);
+    }
+    // Check for regular file
+    if (!S_ISREG(file_status.st_mode)) {
+        // "Can't open file"
+        popup_message( langcode("POPEM00028"), filename_in );
+        return(0);
+    }
+    // Attempt to open the file
+    f = fopen (file, "r");
+    if (f == NULL) {
+        // "Can't open file"
+        popup_message_always( langcode("POPEM00028"), filename_in );
+        return(0);
+    }
+ 
+    while (!feof (f)) {     // Loop through entire file
+        if ( get_line (f, line, MAX_FILENAME) ) {  // Snag one line of data
+            if (strlen(line) > 0) {
+
+
+//NOTE:  How do we handle running off the end of "line" while using "index"?
+// Short lines here can cause segfaults.
+
+                // Find end of Feature ID Number field
+                j = index(line,'|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip this line
+                }
+
+//NOTE:  It'd be nice to take the part after the comma and put it before the rest
+// of the text someday, i.e. "Cassidy, Lake".
+
+                // Find end of Feature Name field
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(name,sizeof(name),"%s",j);
+                clean_string(name);
+
+                // Find end of Feature Type field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+                xastir_snprintf(type,sizeof(type),"%s",i);
+                clean_string(type);
+
+                // Find end of State field
+                i = index(++j,'|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(state,sizeof(state),"%s",j);
+                clean_string(state);
+
+                // Find end of State Number Code field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of County Name field
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(county,sizeof(county),"%s",j);
+                clean_string(county);
+
+                // Find end of County Number Code field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Primary Latitude field (DDMMSSN)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(latitude,sizeof(latitude),"%s",j);
+                clean_string(latitude);
+
+                // Find end of Primary Longitude field (DDDMMSSW)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+                xastir_snprintf(longitude,sizeof(longitude),"%s",i);
+                clean_string(longitude);
+
+                // Find end of Primary Latitude field (decimal
+                // degrees)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Primary Longitude field (decimal
+                // degrees)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Source Latitude field (DMS)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Source Longitude (DMS)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Source Latitude field (decimal
+                // degrees)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Source Longitude field (decimal
+                // degrees)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Estimated Population field
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                xastir_snprintf(population,sizeof(population),"%s",j);
+                clean_string(population);
+
+                // Find end of Quad field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                xastir_snprintf(quad,sizeof(quad),"%s",i);
+                clean_string(quad);
+
+                // If "Match Case" togglebutton is not set, convert
+                // the data to upper-case before we do our compare.
+                if (!follow_case) {
+                    to_upper(name);
+                    to_upper(state);
+                    to_upper(county);
+                    to_upper(quad);
+                    to_upper(type);
+                }
+
+// Still need to code for the "Match Exact" togglebutton.
+
+
+                // Now compare the input variables with those we've
+                // parsed.  If a match, bring up a list of items which
+                // match.
+                //
+                ok = 1;
+                if (get_match) {    // Looking for exact match
+                    if (name_in2[0] != '\0')
+                        if (strcmp(name,name_in2) != 0)
+                            ok = 0;
+                    if (state_in2[0] != '\0')
+                        if (strcmp(state,state_in2) != 0)
+                            ok = 0;
+                    if (county_in2[0] != '\0')
+                        if (strcmp(county,county_in2) != 0)
+                            ok = 0;
+                    if (quad_in2[0] != '\0')
+                        if (strcmp(quad,quad_in2) != 0)
+                            ok = 0;
+                    if (type_in2[0] != '\0')
+                        if (strcmp(type,type_in2) != 0)
+                            ok = 0;
+                }
+                else {  // Look for substring in file, not exact match
+                    if (name_in2[0] != '\0')
+                        if (strstr(name,name_in2) == NULL)
+                            ok = 0;
+                    if (state_in2[0] != '\0')
+                        if (strstr(state,state_in2) == NULL)
+                            ok = 0;
+                    if (county_in2[0] != '\0')
+                        if (strstr(county,county_in2) == NULL)
+                            ok = 0;
+                    if (quad_in2[0] != '\0')
+                        if (strstr(quad,quad_in2) == NULL)
+                            ok = 0;
+                    if (type_in2[0] != '\0')
+                        if (strstr(type,type_in2) == NULL)
+                            ok = 0;
+                }
+
+
+                if (ok) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"Match: %s,%s,%s,%s\n",name,state,county,type);
+
+// This one pops up the names of whatever we found.
+// "Found It!"
+//popup_message_always( langcode("POPEM00029"), name );
+
+		    if (strlen(latitude) < 7) 
+			continue;	// We really don't have any latitude here.
+                    lat_dd[0] = latitude[0];
+                    lat_dd[1] = latitude[1];
+                    lat_dd[2] = '\0';
+ 
+                    lat_mm[0] = latitude[2];
+                    lat_mm[1] = latitude[3];
+                    lat_mm[2] = '\0';
+
+                    lat_ss[0] = latitude[4];
+                    lat_ss[1] = latitude[5];
+                    lat_ss[2] = '\0';
+
+                    lat_dir[0] = latitude[6];
+                    lat_dir[1] = '\0';
+
+		    if (strlen(longitude) < 8) 
+			continue;	// We really don't have any longitude here.
+                    long_dd[0] = longitude[0];
+                    long_dd[1] = longitude[1];
+                    long_dd[2] = longitude[2];
+                    long_dd[3] = '\0';
+ 
+                    long_mm[0] = longitude[3];
+                    long_mm[1] = longitude[4];
+                    long_mm[2] = '\0';
+ 
+                    long_ss[0] = longitude[5];
+                    long_ss[1] = longitude[6];
+                    long_ss[2] = '\0';
+ 
+                    long_dir[0] = longitude[7];
+                    long_dir[1] = '\0';
+
+                    // Now must convert from DD MM SS format to DD MM.MM format so that we
+                    // can run it through our conversion routine to Xastir coordinates.
+                    if (1 != sscanf(lat_ss, "%d", &temp1)) {
+                        fprintf(stderr,"locate_place:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(lat_str, sizeof(lat_str), "%s%s.%02d%s", lat_dd,
+                        lat_mm, temp1, lat_dir);
+                    coord_lat = convert_lat_s2l(lat_str);
+
+                    if (1 != sscanf(long_ss, "%d", &temp1)) {
+                        fprintf(stderr,"locate_place:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(long_str, sizeof(long_str), "%s%s.%02d%s", long_dd,
+                        long_mm, temp1, long_dir);
+                    coord_lon = convert_lon_s2l(long_str);
+
+
+//set_map_position(w, coord_lat, coord_lon);
+
+                    // Fill in the array values with what we just
+                    // found, increment the counter.
+                    xastir_snprintf(match_array_name[my_count],200,"%s",name);
+                    match_array_lat[my_count] = coord_lat;
+                    match_array_long[my_count] = coord_lon;
+                    my_count++;
+
+                    // Check for a max array.  Return if it is full.
+                    if (my_count > 50) {
+                        return(50);
+                    }
+                }
+            }
+        }
+    }
+
+    return(my_count);
+}
+
+
diff --git a/src/map_pdb.c b/src/map_pdb.c
new file mode 100644
index 0000000..ee156d4
--- /dev/null
+++ b/src/map_pdb.c
@@ -0,0 +1,585 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_pdb.c,v 1.24 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+#define DOS_HDR_LINES 8
+#define GRID_MORE 5000
+
+
+// Note:  There are long's in the pdb_hdr that are not being used.
+// If they were, the ntohl() function would need to be used in order
+// to make sure they were represented correctly on big-endian and
+// little-endian machines.  Same goes for short's, make sure ntohs()
+// is used in all cases.
+//
+// Also Note: It looks like all the values in the data structures are 
+// unsigned, we may have to explicitly define the long's as well.  -KD6ZWR
+//
+void draw_palm_image_map(Widget w, 
+			 char *dir,
+			 char *filenm,
+			 alert_entry *alert, 
+			 u_char alert_color,
+			 int destination_pixmap, 
+			 map_draw_flags *mdf) {
+
+// Do NOT change any of these structs.  They have to match the
+// structs  that the palm maps were made with.
+#pragma pack(1)
+    struct {
+        char name[32];
+        short file_attributes;
+        short version;  // 2: No placeholder bytes in file, 3: w/bytes
+        long creation_date;
+        long modification_date;
+        long backup_date;
+        long modification_number;
+        long app_info;
+        long sort_info;
+        char database_type[4];
+        char creator_type[4];
+        long unique_id_seed;
+        long next_record_list;
+        short number_of_records;
+    } pdb_hdr;
+
+    struct {
+        long record_data_offset;
+        char category;
+        char id[3];
+    } prl;
+
+    // Two placeholder bytes where were added in version 3.  We
+    // skip these below automatically using the fseek calls and the
+    // record offsets.
+    //struct {
+    //    short placeholder;
+    //} pdb_ph;
+
+    struct {
+        long left_bounds;
+        long right_bounds;
+        long top_bounds;
+        long bottom_bounds;
+        char menu_name[12];
+        short granularity;
+        char sort_order;
+        char fill[33];
+    } pmf_hdr;
+
+    struct {
+        char type;
+        char sub_type;
+        short minimum_zoom;
+    } record_hdr;
+
+    struct {
+        unsigned short next_vector;
+        unsigned short left_bounds;
+        unsigned short right_bounds;
+        unsigned short top_bounds;
+        unsigned short bottom_bounds;
+        unsigned short line_start_x;
+        unsigned short line_start_y;
+    } vector_hdr;
+
+    struct {
+        unsigned char next_x;
+        unsigned char next_y;
+    } vector_point;
+
+    struct {
+        unsigned short next_label;
+        unsigned short start_x;
+        unsigned short start_y;
+        char symbol_set;
+        char symbol_char;
+        char color;
+        char treatment;
+        short fill;
+        char text[20];
+    } label_record;     
+
+    FILE *fn;
+    char filename[MAX_FILENAME];
+    char short_filenm[MAX_FILENAME];
+    int records, record_count, count;
+    int scale;
+    long map_left, map_right, map_top, map_bottom, max_x, max_y;
+    long record_ptr;
+    long line_x, line_y;
+    int vector;
+    char status_text[MAX_FILENAME];
+    int draw_filled;
+
+    draw_filled = mdf->draw_filled;
+
+    xastir_snprintf(filename, sizeof(filename), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    if ((fn = fopen(filename, "r")) == NULL) {
+        fprintf(stderr,"Couldn't open file: %s\n", filename);
+        return;
+    }
+ 
+    if (debug_level & 512)
+        fprintf(stderr,"opened file: %s\n", filename);
+
+    fread(&pdb_hdr, sizeof(pdb_hdr), 1, fn);
+
+    if (strncmp(pdb_hdr.database_type, "map1", 4) != 0
+            || strncmp(pdb_hdr.creator_type, "pAPR", 4) != 0) {
+        fprintf(stderr,"Not Palm OS Map: %s\n", filename);
+        fclose(fn);
+        return;
+    }
+
+    records = ntohs(pdb_hdr.number_of_records);
+
+    fread(&prl, sizeof(prl), 1, fn);
+
+    if (debug_level & 512) {
+        fprintf(stderr,"Palm Map: %s, %d records, offset: %8x\n",
+            pdb_hdr.name,
+            records,
+            (unsigned int)ntohl(prl.record_data_offset));
+    }
+
+    // Save the current pointer into the file
+    record_ptr = (long)ftell(fn);
+    // record_ptr should now be point to the next record list in
+    // the sequence (if there is another one).
+
+    // Point to the map file header corresponding to the record
+    // list we just read in & snag it.
+    fseek(fn, ntohl(prl.record_data_offset), SEEK_SET);
+    fread(&pmf_hdr, sizeof(pmf_hdr), 1, fn);
+
+    scale = ntohs(pmf_hdr.granularity);
+    map_left = ntohl(pmf_hdr.left_bounds);
+    map_right = ntohl(pmf_hdr.right_bounds);
+    map_top = ntohl(pmf_hdr.top_bounds);
+    map_bottom = ntohl(pmf_hdr.bottom_bounds);
+
+    if (debug_level & 512) {
+        fprintf(stderr,"\tLeft %ld, Right %ld, Top %ld, Bottom %ld, %s, Scale %d, %d\n",
+            map_left,
+            map_right,
+            map_top,
+            map_bottom,
+            pmf_hdr.menu_name,
+            scale,
+            pmf_hdr.sort_order);
+    }
+
+    // DNN: multipy by 10; pocketAPRS corners in tenths of seconds,
+    // internal map in hundredths of seconds (was "scale" which was wrong,
+    // scale is not used for the map corners)
+    // Multipy now so we don't have to do it for every use below...
+    map_left *= 10;
+    map_right *= 10;
+    map_top *= 10;
+    map_bottom *= 10;
+
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        index_update_xastir(filenm,     // Filename only
+            map_bottom, // Bottom
+            map_top,    // Top
+            map_left,   // Left
+            map_right,  // Right
+            1000);      // Default Map Level
+
+        fclose(fn);
+
+        // Update the statusline for this map name.
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(status_text,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+
+
+    if (!map_onscreen(map_left, map_right, map_top, map_bottom, 1)) {
+        fclose(fn);
+        return;
+    }
+
+
+    // Update the statusline for this map name
+    xastir_snprintf(status_text,
+        sizeof(status_text),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(status_text,0);       // Loading/Indexing ...
+
+
+    max_x = (long)(screen_width + MAX_OUTBOUND);
+    max_y = (long)(screen_height + MAX_OUTBOUND);
+
+
+    /* read vectors */
+    for (record_count = 2; record_count <= records; record_count++) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            fclose(fn);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        // Point to the next record list header & snag it
+        fseek(fn, record_ptr, SEEK_SET);
+        fread(&prl, sizeof(prl), 1, fn);
+
+        if (debug_level & 512) {
+            fprintf(stderr,"\tRecord %d, offset: %8x\n",
+                record_count,
+                (unsigned int)ntohl(prl.record_data_offset));
+        }
+
+        // Save a pointer to the next record list header
+        record_ptr = (long)ftell(fn);
+
+        // Point to the next map file header & snag it
+        fseek(fn, ntohl(prl.record_data_offset), SEEK_SET);
+        fread(&record_hdr, sizeof(record_hdr), 1, fn);
+
+        if (debug_level & 512) {
+            fprintf(stderr,"\tType %d, Sub %d, Zoom %d\n",
+                record_hdr.type,
+                record_hdr.sub_type,
+                (unsigned short) ntohs(record_hdr.minimum_zoom));
+        }
+
+        if (record_hdr.type > 0 && record_hdr.type < 16) {
+
+            vector = True;
+
+            while (vector && fread(&vector_hdr, sizeof(vector_hdr), 1, fn)) {
+
+                count = (unsigned short) ntohs(vector_hdr.next_vector);
+
+                if (count && !(count&1)) {
+                    line_x = (long)ntohs(vector_hdr.line_start_x);
+                    line_y = (long)ntohs(vector_hdr.line_start_y);
+
+                    if (debug_level & 512) {
+                        fprintf(stderr,"\tvector %d, left %d, right %d, top %d, bottom %d, start x %ld, start y %ld\n",
+                            count,
+                            (unsigned short) ntohs(vector_hdr.left_bounds),
+                            (unsigned short) ntohs(vector_hdr.right_bounds),
+                            (unsigned short) ntohs(vector_hdr.top_bounds),
+                            (unsigned short) ntohs(vector_hdr.bottom_bounds),
+                            line_x,
+                            line_y);
+                    }
+
+                    // DNN: Only line_x and line_y are scaled,
+                    // not map_left and map_top
+                    map_plot (w,
+                        max_x,
+                        max_y,
+                        map_left + (line_x * scale),
+                        map_top + (line_y * scale),
+                        record_hdr.type,    // becomes the color choice
+                        0,
+                        destination_pixmap,
+                        draw_filled);
+
+                    for (count -= sizeof(vector_hdr); count > 0; count -= sizeof(vector_point)) {
+
+                        fread(&vector_point, sizeof(vector_point), 1, fn);
+
+                        if ((debug_level & 513) == 513) {
+                            fprintf(stderr,"\tnext x %d, next y %d\n",
+                                vector_point.next_x,
+                                vector_point.next_y);
+                        }
+
+                        line_x += vector_point.next_x - 127;
+                        line_y += vector_point.next_y - 127;
+
+                        // DNN: Only line_x and line_y are scaled,
+                        // not map_left and map_top
+                        map_plot (w,
+                            max_x,
+                            max_y,
+                            map_left + (line_x * scale),
+                            map_top + (line_y * scale),
+                            record_hdr.type,
+                            0,
+                            destination_pixmap,
+                            draw_filled);
+                    }
+
+                    // DNN: Only line_x and line_y are scaled,
+                    // not map_left and map_top
+                    map_plot (w,
+                        max_x,
+                        max_y,
+                        map_left + (line_x * scale),
+                        map_top + (line_y * scale),
+                        0,  // Color 0
+                        0,
+                        destination_pixmap,
+                        draw_filled);
+                }
+                else {
+                    vector = False;
+                }
+            }
+        }
+        else if ( (record_hdr.type == 0)    // We have a label
+                && map_labels) {  // and we wish to draw it
+            long label_x_cord;
+            long label_y_cord;
+            int  label_length;
+            int  label;
+            long  label_mag;
+            long x;
+            long y;
+            int  i;
+            int color;
+
+
+            label_mag = (long) ntohs(record_hdr.minimum_zoom);
+ 
+            // DNN: Multiplication by 4 looks reasonable on the map I
+            // checked, be my guest to come up with a better value...
+            // For the map I used the behaviour mimics the
+            // behaviour on pocketAPRS when the labels show up
+            label_mag *= 4;
+ 
+            label = True;
+
+            while (label && fread(&label_record, sizeof(label_record), 1, fn)) {
+
+                count = ntohs(label_record.next_label);
+
+                if (count && !(count&1)) {
+                    line_x = (long)ntohs(vector_hdr.line_start_x);
+                    line_y = (long)ntohs(vector_hdr.line_start_y);
+ 
+                    if (debug_level & 512) {
+                        fprintf(stderr,"\t%d, %d, %d, %d, %d, %d, 0x%x, %s\n",
+                            ntohs(label_record.next_label),
+                            ntohs(label_record.start_x),
+                            ntohs(label_record.start_y),
+                            label_record.symbol_set,
+                            label_record.symbol_char,
+                            label_record.color,
+                            label_record.treatment,
+                            label_record.text);
+                    }
+ 
+                    label_x_cord = map_left +
+                        (((long) ntohs(label_record.start_x)) * scale);
+                    label_y_cord = map_top +
+                        (((long) ntohs(label_record.start_y)) * scale);
+ 
+                    // DNN:  Skip empty labels
+                    if(label_record.text[0] != '\0') {
+                        label_record.text[19] = '\0';  // Make sure we have a terminator
+                        label_length = (int)strlen (label_record.text);
+ 
+                        for (i = (label_length - 1); i > 0; i--) {
+                            if (label_record.text[i] == ' ')
+                                label_record.text[i] = '\0';
+                            else
+                                break;
+                        }
+ 
+                        label_length = (int)strlen (label_record.text);
+               
+                        // DNN: todo: treatment:
+                        // bit 7: inverse
+                        // bit 6: draw beneath map line data
+                        // bit 5,4: 00 = left, 01 = center, 10 = right
+                        // bit 3,2,1,0: typeface 0 = normal, 1 = bold,
+                        //        2 = large, 3 = extra large
+                        //
+                        // For now KISS, just put it on the map.
+ 
+                        x = ((label_x_cord - NW_corner_longitude) / scale_x);
+ 
+                        /* examine bits 4 and 5 of treatment */
+                        if((label_record.treatment & 0x30) == 0x00) {
+                            /* left of coords */
+                            x = x - (label_length * 6);
+                        }
+                        else if((label_record.treatment & 0x30) == 0x10) {
+                            /* center */
+                            x = x - (label_length * 3);
+                        }
+                        else {
+                            /* right of coords */
+                            x = ((label_x_cord - NW_corner_longitude) / scale_x);
+                        }
+ 
+                        y = ((label_y_cord - NW_corner_latitude) / scale_y);
+ 
+                        // Color selection
+                        switch (label_record.color) {
+                            case 0:
+                                color = 0x08;   // black
+                                break;
+                            case 1:
+                                color = 0x07;   // darkgray
+                                break;
+                            case 2:
+                                color = 0x14;   // lightgray
+                                break;
+                            case 3:
+                                color = 0x0f;   // white
+                                break;
+                            default:
+                                color = 0x08;   // black
+                                break;
+                        }
+
+                        if (label_mag > (int)((scale_x) - 1) || label_mag == 0) {
+                            if (x > (0) && (x < (int)screen_width)) {
+                                if (y > (0) && (y < (int)screen_height)) {
+                                    draw_rotated_label_text (w,
+                                        -90.0,
+                                        x,
+                                        y,
+                                        label_length,
+                                        colors[color],
+                                        label_record.text,
+                                        FONT_DEFAULT);
+                                }
+                            }
+                        }
+                    }
+                    /* Label has a symbol */
+                    if(label_record.symbol_char != '\0') {
+                        // DNN: Not implemented (yet)
+                    }
+                }
+                else {
+                    label = False;
+                }
+            } // End of while
+        }   // End of else if
+    }   // end of for loop
+
+    fclose(fn);
+
+    if (debug_level & 512)
+        fprintf(stderr,"Closed file\n");
+}
diff --git a/src/map_pop.c b/src/map_pop.c
new file mode 100644
index 0000000..9224f3d
--- /dev/null
+++ b/src/map_pop.c
@@ -0,0 +1,1405 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id$
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+//NOTE:  This function has a problem if a non-pop file is labeled
+//with a ".pop" extension.  It causes a segfault in Xastir.  More
+//error checking needs to be done in order to prevent this.
+
+// draw_pop_map()
+//
+// Allows drawing a background map of labels for the viewport.
+// Example format (old):
+// "WA","Abbey View Memorial Park","cemetery","Snohomish","53","061","474647N","1221650W","47.77972","-122.28056","","","","","420","","Edmonds East"
+//
+// Example format (new):
+// 376016|ID|12th Ave Drain|stream|Canyon|16|027|433107N|1163348W|43.51861|-116.56333||||||||Nampa
+//
+// These types of files are available from ftp://aprs.tamu.edu/
+// A typical filename would be: "WA_deci.gz".   Do not get the other
+// types of files which are columnar.  The files that we parse are
+// pipe-delimited.
+// These files were originally from geonames.usgs.gov but the format changed
+// on that site from population to elevation and the display of populated sites
+// was severly broken by the new format. The population information should be
+// gathered from census.gov or other locations concerned with population mapping.
+//
+void draw_pop_map (Widget w,
+		    char *dir,
+		    char *filenm,
+		    alert_entry *alert,
+		    u_char alert_color,
+		    int destination_pixmap,
+		    map_draw_flags *mdf)
+{
+    char file[MAX_FILENAME];        // Complete path/name of pop file
+    char short_filenm[MAX_FILENAME];
+    FILE *f;                        // Filehandle of pop file
+    char line[MAX_FILENAME];        // One line of text from file
+    char *i, *j;
+    char state[50];
+    char name[200];
+    char type[100];
+    char county[100];
+    char latitude[15];
+    char longitude[15];
+    char population[15];
+    char lat_dd[3];
+    char lat_mm[3];
+    char lat_ss[3];
+    char lat_dir[2];
+    char long_dd[4];
+    char long_mm[3];
+    char long_ss[3];
+    char long_dir[2];
+    char lat_str[15];
+    char long_str[15];
+    int temp1;
+    long coord_lon, coord_lat;
+    long min_lat, min_lon, max_lat, max_lon;
+    int ok;
+    long x,y;
+    char symbol_table, symbol_id, symbol_over;
+    unsigned long bottom_extent = 0l;
+    unsigned long top_extent = 0l;
+    unsigned long left_extent = 0l;
+    unsigned long right_extent = 0l;
+    char status_text[MAX_FILENAME];
+    int count = 0;
+
+
+    //fprintf(stderr,"draw_pop_map starting: %s/%s\n",dir,filenm);
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    // Screen view
+    min_lat = SE_corner_latitude;
+    max_lat = NW_corner_latitude;
+    min_lon = NW_corner_longitude;
+    max_lon = SE_corner_longitude;
+
+
+    // The map extents in the map index are checked in draw_map to
+    // see whether we should draw the map at all.
+
+
+    // Update the statusline for this map name
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA039"),
+            short_filenm);
+    }
+    else {
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA028"),
+            short_filenm);
+    }
+    statusline(status_text,0);       // Loading/Indexing ...
+
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+
+/*
+Latest pipe-delimited format from USGS (as of 08/12/2004):
+----------------------------------------------------------
+Feature ID Number (FID)
+State Alpha Code
+Feature Name
+Feature Type
+County Name
+State Number Code (FIPS Code)
+County Number Code (FIPS Code)
+Primary Latitude (DMS)
+Primary Longitude (DMS)
+Primary Latitude (decimal degrees)
+Primary Longitude (decimal degrees)
+Source Latitude (DMS)
+Source Longitude (DMS)
+Source Latitude (decimal degrees)
+Source Longitude (decimal degrees)
+Elevation
+Estimated Population
+Federal Status
+Cell Name
+*/
+
+
+    // Attempt to open the file
+    f = fopen (file, "r");
+    if (f != NULL) {
+        while (!feof (f)) {     // Loop through entire file
+            int lat_in_view = 0;
+
+            count++;
+            if ((count % 16) == 0) {
+
+                // Check whether map drawing should be interrupted.
+                // Check every 16 lines.
+                //
+                HandlePendingEvents(app_context);
+                if (interrupt_drawing_now) {
+                    (void)fclose (f);
+                    // Update to screen
+                    (void)XCopyArea(XtDisplay(da),
+                        pixmap,
+                        XtWindow(da),
+                        gc,
+                        0,
+                        0,
+                        (unsigned int)screen_width,
+                        (unsigned int)screen_height,
+                        0,
+                        0);
+                    return;
+                }
+            }
+
+            if ( get_line (f, line, MAX_FILENAME) ) {  // Snag one line of data
+
+                // It is common for these lines to have incredible
+                // numbers of spaces at the end, so trim them here.
+                (void)remove_trailing_spaces(line);
+
+                if (strlen(line) > 0) {
+
+                    // Default population, in case the field isn't
+                    // present in the file.
+                    xastir_snprintf(population,sizeof(population),"0");
+ 
+// Examples of old/new format:
+// 1462331|VA|Abingdon Elementary School|school|Arlington|51|013|385023N|0770546W|38.83972|-77.09611||||||||Alexandria
+// 1462331|VA|Abingdon Elementary School|School|Arlington|51|013|385023N|0770545W|38.8398349|-77.0958117|56|Alexandria
+
+                    //NOTE:  We handle running off the end of "line"
+                    //via the "continue" statement.  Skip the line
+                    //if we don't find enough parameters while
+                    //parsing.
+
+                    // Find end of Feature ID Number field
+                    j = index(line,'|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    // Find end of State field
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(state,sizeof(state),"%s",j+1);
+
+//NOTE:  It'd be nice to take the part after the comma and put it before the rest
+// of the text someday, i.e. "Cassidy, Lake".
+
+                    // Find end of Feature Name field
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+                    xastir_snprintf(name,sizeof(name),"%s",i+1);
+
+                    // Find end of Feature Type field
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(type,sizeof(type),"%s",j+1);
+
+                    // Find end of County Name field
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+                    xastir_snprintf(county,sizeof(county),"%s",i+1);
+
+                    // Find end of State Number Code field
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of County Number Code field
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+
+// Examples of old/new format:
+// 1462331|VA|Abingdon Elementary School|school|Arlington|51|013|385023N|0770546W|38.83972|-77.09611||||||||Alexandria
+// 1462331|VA|Abingdon Elementary School|School|Arlington|51|013|385023N|0770545W|38.8398349|-77.0958117|56|Alexandria
+
+                    // Find end of Primary Latitude field (DDMMSSN)
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    i[0] = '\0';
+                    xastir_snprintf(latitude,sizeof(latitude),"%s",j+1);
+                    if (!isdigit((int)latitude[0])) { // skip record if not
+                        continue;                // numeric! (e.g. "UNKNOWN")
+                    }
+
+//WE7U
+                    clean_string(latitude);
+                    
+                    // Find end of Primary Longitude field (DDDMMSSW)
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        continue;   // Skip this line
+                    }
+
+                    j[0] = '\0';
+                    xastir_snprintf(longitude,sizeof(longitude),"%s",i+1);
+                    if (!isdigit((int)longitude[0])) { // skip record if not
+                        continue;                 // numeric (e.g. UNKNOWN)
+                    }
+
+//WE7U
+                    clean_string(longitude);
+
+                    // Find end of Primary Latitude field (decimal
+                    // degrees)
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Primary Longitude field (decimal
+                    // degrees)
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    j[0] = '\0';
+
+// Examples of old/new format:
+// 1462331|VA|Abingdon Elementary School|school|Arlington|51|013|385023N|0770546W|38.83972|-77.09611||||||||Alexandria
+// 1462331|VA|Abingdon Elementary School|School|Arlington|51|013|385023N|0770545W|38.8398349|-77.0958117|56|Alexandria
+ 
+                    // Find end of Source Latitude field (DMS) (old
+                    // format) or elevation (new format)
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Source Longitude field (DMS) (old
+                    // format) or 
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    j[0] = '\0';
+
+                    // Find end of Source Latitude field (decimal
+                    // degrees)
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Source Longitude field (decimal
+                    // degrees)
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    j[0] = '\0';
+
+                    // Find end of Elevation field
+                    i = index(j+1, '|');
+
+                    if (i == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    i[0] = '\0';
+
+                    // Find end of Estimated Population field
+                    j = index(i+1, '|');
+
+                    if (j == NULL) {    // Pipe not found
+                        goto FINISH;    // We have enough to process now
+                    }
+
+                    if ( j != NULL ) {
+                        j[0] = '\0';
+                        xastir_snprintf(population,sizeof(population),"%s",i+1);
+                    }
+
+FINISH:
+                    // There are two more fields (old format),
+                    // "Federal Status" and "Cell Name".  We ignore
+                    // those for now.
+ 
+		    if (strlen(latitude) < 7)
+			continue;	// We really don't have any latitude here!
+                    lat_dd[0] = latitude[0];
+                    lat_dd[1] = latitude[1];
+                    lat_dd[2] = '\0';
+ 
+                    lat_mm[0] = latitude[2];
+                    lat_mm[1] = latitude[3];
+                    lat_mm[2] = '\0';
+
+                    lat_ss[0] = latitude[4];
+                    lat_ss[1] = latitude[5];
+                    lat_ss[2] = '\0';
+
+                    lat_dir[0] = latitude[6];
+                    lat_dir[1] = '\0';
+
+                    // Now must convert from DD MM SS format to DD MM.MM format so that we
+                    // can run it through our conversion routine to Xastir coordinates.
+                    if (1 != sscanf(lat_ss, "%d", &temp1)) {
+                        fprintf(stderr,"draw_pop_map:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(lat_str, sizeof(lat_str), "%s%s.%02d%s", lat_dd,
+                            lat_mm, temp1, lat_dir);
+                    coord_lat = convert_lat_s2l(lat_str);
+
+                    // Quick test of latitude to see if it's within
+                    // our view.  If not and we're not doing
+                    // indexing, skip this line and go on to the
+                    // next.
+                    if (coord_lat <= min_lat && coord_lat >= max_lat) {
+                        // Latitude is ok
+                        lat_in_view++;
+                    }
+                    else {  // Latitude not in current view
+
+                        // Check whether we're indexing the map
+                        if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                                || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+                            // Process the line 'cuz we're indexing
+                        }
+                        else {  // Not indexing so skip to the next
+                                // line in the file
+                            continue;
+                        }
+                    }
+
+		    if (strlen(longitude) < 8)
+			continue;	// We really don't have any latitude here!
+                    long_dd[0] = longitude[0];
+                    long_dd[1] = longitude[1];
+                    long_dd[2] = longitude[2];
+                    long_dd[3] = '\0';
+ 
+                    long_mm[0] = longitude[3];
+                    long_mm[1] = longitude[4];
+                    long_mm[2] = '\0';
+ 
+                    long_ss[0] = longitude[5];
+                    long_ss[1] = longitude[6];
+                    long_ss[2] = '\0';
+ 
+                    long_dir[0] = longitude[7];
+                    long_dir[1] = '\0';
+
+                    if (1 != sscanf(long_ss, "%d", &temp1)) {
+                        fprintf(stderr,"draw_pop_map:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(long_str, sizeof(long_str), "%s%s.%02d%s", long_dd,
+                            long_mm, temp1, long_dir);
+                    coord_lon = convert_lon_s2l(long_str);
+
+
+                    // Check whether we're indexing the map
+                    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+                        // Save the min/max extents of the file.  We
+                        // should really initially set the extents
+                        // to the min/max for the Xastir coordinate
+                        // system, but in practice zeroes should
+                        // work just as well.
+                        //
+                        if ((coord_lat > (long)bottom_extent) || (bottom_extent == 0l))
+                            bottom_extent = coord_lat;
+                        if ((coord_lat < (long)top_extent) || (top_extent == 0l))
+                            top_extent = coord_lat;
+                        if ((coord_lon < (long)left_extent) || (left_extent == 0l))
+                            left_extent = coord_lon;
+                        if ((coord_lon > (long)right_extent) || (right_extent == 0l))
+                            right_extent = coord_lon;
+                    }
+                    // Now check whether this lat/lon is within our viewport.  If it
+                    // is, draw a text label at that location.
+                    else if (coord_lon >= min_lon && coord_lon <= max_lon
+                            && lat_in_view) {
+
+                        clean_string(state);
+                        clean_string(name);
+                        clean_string(type);
+                        clean_string(county);
+                        clean_string(population);
+
+                        if (debug_level & 16) {
+                            fprintf(stderr,"%s\t%s\t%s\t%s\t%s\t%s\t\t",
+                                    state, name, type, county, latitude, longitude);
+                            fprintf(stderr,"%s %s %s %s\t%s %s %s %s\t\t",
+                                    lat_dd, lat_mm, lat_ss, lat_dir, long_dd, long_mm, long_ss, long_dir);
+                            fprintf(stderr,"%s\t%s\n", lat_str, long_str);
+                        }
+
+                        // Convert to screen coordinates.  Careful
+                        // here!  The format conversions you'll need
+                        // if you try to compress this into two
+                        // lines will get you into trouble.
+                        x = coord_lon - NW_corner_longitude;
+                        y = coord_lat - NW_corner_latitude;
+                        x /= scale_x;
+                        y /= scale_y;
+
+                        ok = 1;
+
+                        /* set default symbol */
+                        symbol_table = '/';
+                        symbol_id = '.'; /* small x */
+                        symbol_over = ' ';
+
+                        if (strcasecmp(type,"airport") == 0) {
+                            symbol_id = '^';
+                            if (scale_y > 100)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"arch") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"area") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"arroyo") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bar") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"basin") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bay") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"beach") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bench") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bend") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"bridge") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"building") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"canal") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cape") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cave") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cemetery") == 0) {
+                            symbol_table = '\\';
+                            symbol_id = '+';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"census") == 0) {
+                          /* if (scale_y > 50)*/  /* Census divisions */
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"channel") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"church") == 0) {
+                            symbol_table = '\\';
+                            symbol_id = '+';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"civil") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"cliff") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"crater") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"crossing") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"dam") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"falls") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"flat") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"forest") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"gap") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"geyser") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"glacier") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"gut") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"harbor") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"hospital") == 0) {
+                            symbol_id = 'h';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"island") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"isthmus") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"lake") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"lava") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"levee") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"locale") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"military") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"mine") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"oilfield") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"other") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"park") == 0) {
+                            symbol_table = '\\';
+                            symbol_id = ';';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"pillar") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"plain") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"po") == 0) {
+                            symbol_id = ']';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"ppl") == 0) {
+                            symbol_id = '/';
+                            if (scale_y > 20000)    // Don't draw cities at zoom higher than 20,000
+                                ok = 0;
+                            else if (scale_y > 4000) {  // Don't draw cities of less than 20,000
+                                if (atoi(population) < 50000) {
+                                    ok = 0;
+                                }
+                            }
+                            else if (scale_y > 1500) {  // Don't draw cities of less than 10,000
+                                if (atoi(population) < 20000) {
+                                    ok = 0;
+                                }
+                            }
+                            else if (scale_y > 750) {  // Don't draw cities of less than 5,000
+                                if (atoi(population) < 10000) {
+                                    ok = 0;
+                                }
+                            }
+                            else if (scale_y > 200) {   // Don't draw cities 
+                                                        // of less than 1,000
+                                if (atoi(population) < 1000) {
+                                    ok = 0;
+                                    //fprintf(stderr,
+                                    // "Name: %s\tPopulation: %s\n",name,
+                                    // population);
+                                }
+                            }
+                        }
+                        else if (strcasecmp(type,"range") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"rapids") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"reserve") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"reservoir") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"ridge") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"school") == 0) {
+                            symbol_id = 'K';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"sea") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"slope") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"spring") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"stream") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"summit") == 0) {
+                            if (scale_y > 100)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"swamp") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"trail") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"tower") == 0) {
+                            symbol_id = 'r';
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"tunnel") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"valley") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"well") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"woods") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else if (strcasecmp(type,"ruin") == 0) {
+                            if (scale_y > 50)
+                                ok = 0;
+                        }
+                        else {
+                            fprintf(stderr,"Something unusual found, Type:%s\tState:%s\tCounty:%s\tName:%s\n",
+                                type,state,county,name);
+                        }
+
+                        if (ok == 1) {  // If ok to draw it
+                            symbol(w, 0, symbol_table, symbol_id, symbol_over, pixmap, 1, x-10, y-10, ' ');
+                            draw_nice_string(w, pixmap, 0, x+10, y+5, (char*)name, 0xf, 0x10, strlen(name));
+                        }
+
+                    }
+                    else {
+                        //fprintf(stderr,"Not in viewport.  Coordinates: %ld %ld\n",coord_lat,coord_lon);
+                        //fprintf(stderr,"Min/Max Lat: %ld %ld\n",min_lat,max_lat);
+                        //fprintf(stderr,"Min/Max Lon: %ld %ld\n",min_lon,max_lon);
+                    }
+                }
+            }
+        }   // End of while
+        (void)fclose (f);
+
+
+        // Check whether we're indexing the map
+        if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+            // We're indexing only.  Save the extents in the index.
+            index_update_xastir(filenm, // Filename only
+                bottom_extent,  // Bottom
+                top_extent,     // Top
+                left_extent,    // Left
+                right_extent,   // Right
+                99999);         // Default Map Level
+        }
+    }
+    else {
+        fprintf(stderr,"Couldn't open file: %s\n", file);
+        return;
+    }
+    if (debug_level & 16)
+        fprintf(stderr,"Exiting draw_pop_map\n");
+}
+
+
+
+
+
+// Search for a placename among pop files
+//
+// We need to search a file in the map directory that has the filename
+// STATE.gis, where STATE is from the "state" variable passed to us.
+// Search for the placename/county/state/type that the user requested.
+// Once found, center the map on that location or bring up a response
+// dialog that asks whether one wants to go there, and that dialog
+// provides info about the place found, with a possible selection
+// out of a list of matches.
+// Might also need to place a label at that position on the map in
+// case that pop file isn't currently selected.
+//
+int pop_locate_place( Widget w,
+        char *name_in,
+        char *state_in,
+        char *county_in,
+        char *quad_in,
+        char *type_in,
+        char *filename_in,
+        int follow_case,
+        int get_match,
+        char match_array_name[50][200],
+        long match_array_lat[50],
+        long match_array_long[50] ) {
+
+    char file[MAX_FILENAME];        // Complete path/name of pop file
+    FILE *f;                        // Filehandle of pop file
+    char line[MAX_FILENAME];        // One line of text from file
+    char *i, *j;
+    char state[50];
+    char state_in2[50];
+    char name[200];
+    char name_in2[50];
+    char type[100];
+    char type_in2[50];
+    char county[100];
+    char county_in2[50];
+    char quad[100];
+    char quad_in2[100];
+    char latitude[15];
+    char longitude[15];
+    char population[15];
+    char lat_dd[3];
+    char lat_mm[3];
+    char lat_ss[3];
+    char lat_dir[2];
+    char long_dd[4];
+    char long_mm[3];
+    char long_ss[3];
+    char long_dir[2];
+    char lat_str[15];
+    char long_str[15];
+    int temp1;
+    long coord_lon, coord_lat;
+    int ok;
+    struct stat file_status;
+    int my_count = 0;
+ 
+ 
+    xastir_snprintf(file,sizeof(file),"%s",filename_in);
+
+    if (debug_level & 16)
+        fprintf(stderr,"File: %s\n",file);
+
+
+    xastir_snprintf(name_in2,sizeof(name_in2),"%s",name_in);
+    xastir_snprintf(state_in2,sizeof(state_in2),"%s",state_in);
+    xastir_snprintf(county_in2,sizeof(county_in2),"%s",county_in);
+    xastir_snprintf(quad_in2,sizeof(quad_in2),"%s",quad_in);
+    xastir_snprintf(type_in2,sizeof(type_in2),"%s",type_in);
+
+
+    // Convert State/Province to upper-case always (they're
+    // always upper-case in the pop files from USGS.
+    to_upper(state_in2);
+
+
+    if (debug_level & 16)
+        fprintf(stderr,"Name:%s\tState:%s\tCounty:%s\tQuad:%s\tType:%s\n",
+        name_in,state_in2,county_in,quad_in,type_in);
+
+
+    // If "Match Case" togglebutton is not set, convert the
+    // rest of the keys to upper-case.
+    if (!follow_case) {
+        to_upper(name_in2);
+        to_upper(county_in2);
+        to_upper(quad_in2);
+        to_upper(type_in2);
+    }
+
+
+    // Check status of the file
+    if (stat(file, &file_status) < 0) {
+        // "Can't open file"
+        popup_message( langcode("POPEM00028"), filename_in );
+        return(0);
+    }
+    // Check for regular file
+    if (!S_ISREG(file_status.st_mode)) {
+        // "Can't open file"
+        popup_message( langcode("POPEM00028"), filename_in );
+        return(0);
+    }
+    // Attempt to open the file
+    f = fopen (file, "r");
+    if (f == NULL) {
+        // "Can't open file"
+        popup_message_always( langcode("POPEM00028"), filename_in );
+        return(0);
+    }
+ 
+    while (!feof (f)) {     // Loop through entire file
+        if ( get_line (f, line, MAX_FILENAME) ) {  // Snag one line of data
+            if (strlen(line) > 0) {
+
+
+//NOTE:  How do we handle running off the end of "line" while using "index"?
+// Short lines here can cause segfaults.
+
+                // Find end of Feature ID Number field
+                j = index(line,'|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip this line
+                }
+
+                // Find end of State field
+                i = index(++j,'|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(state,sizeof(state),"%s",j);
+                clean_string(state);
+
+//NOTE:  It'd be nice to take the part after the comma and put it before the rest
+// of the text someday, i.e. "Cassidy, Lake".
+
+                // Find end of Feature Name field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+                xastir_snprintf(name,sizeof(name),"%s",i);
+                clean_string(name);
+
+                // Find end of Feature Type field
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(type,sizeof(type),"%s",j);
+                clean_string(type);
+
+                // Find end of County Name field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+                xastir_snprintf(county,sizeof(county),"%s",i);
+                clean_string(county);
+
+                // Find end of State Number Code field
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of County Number Code field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Primary Latitude field (DDMMSSN)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+                xastir_snprintf(latitude,sizeof(latitude),"%s",j);
+                clean_string(latitude);
+
+                // Find end of Primary Longitude field (DDDMMSSW)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+                xastir_snprintf(longitude,sizeof(longitude),"%s",i);
+                clean_string(longitude);
+
+                // Find end of Primary Latitude field (decimal
+                // degrees)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Primary Longitude field (decimal
+                // degrees)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Source Latitude field (DMS)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Source Longitude (DMS)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Source Latitude field (decimal
+                // degrees)
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Source Longitude field (decimal
+                // degrees)
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+
+                // Find end of Elevation field
+                i = index(++j, '|');
+
+                if (i == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                i[0] = '\0';
+
+                // Find end of Estimated Population field
+                j = index(++i, '|');
+
+                if (j == NULL) {    // Pipe not found
+                    continue;   // Skip line
+                }
+
+                j[0] = '\0';
+                xastir_snprintf(population,sizeof(population),"%s",i);
+                clean_string(population);
+
+                // Snag Cell Name field (Quad name, last field)
+                xastir_snprintf(quad,sizeof(quad),"%s",j+1);
+                clean_string(quad);
+
+                // If "Match Case" togglebutton is not set, convert
+                // the data to upper-case before we do our compare.
+                if (!follow_case) {
+                    to_upper(name);
+                    to_upper(state);
+                    to_upper(county);
+                    to_upper(quad);
+                    to_upper(type);
+                }
+
+// Still need to code for the "Match Exact" togglebutton.
+
+
+                // Now compare the input variables with those we've
+                // parsed.  If a match, bring up a list of items which
+                // match.
+                //
+                ok = 1;
+                if (get_match) {    // Looking for exact match
+                    if (name_in2[0] != '\0')
+                        if (strcmp(name,name_in2) != 0)
+                            ok = 0;
+                    if (state_in2[0] != '\0')
+                        if (strcmp(state,state_in2) != 0)
+                            ok = 0;
+                    if (county_in2[0] != '\0')
+                        if (strcmp(county,county_in2) != 0)
+                            ok = 0;
+                    if (quad_in2[0] != '\0')
+                        if (strcmp(quad,quad_in2) != 0)
+                            ok = 0;
+                    if (type_in2[0] != '\0')
+                        if (strcmp(type,type_in2) != 0)
+                            ok = 0;
+                }
+                else {  // Look for substring in file, not exact match
+                    if (name_in2[0] != '\0')
+                        if (strstr(name,name_in2) == NULL)
+                            ok = 0;
+                    if (state_in2[0] != '\0')
+                        if (strstr(state,state_in2) == NULL)
+                            ok = 0;
+                    if (county_in2[0] != '\0')
+                        if (strstr(county,county_in2) == NULL)
+                            ok = 0;
+                    if (quad_in2[0] != '\0')
+                        if (strstr(quad,quad_in2) == NULL)
+                            ok = 0;
+                    if (type_in2[0] != '\0')
+                        if (strstr(type,type_in2) == NULL)
+                            ok = 0;
+                }
+
+
+                if (ok) {
+                    if (debug_level & 16)
+                        fprintf(stderr,"Match: %s,%s,%s,%s\n",name,state,county,type);
+
+// This one pops up the names of whatever we found.
+// "Found It!"
+//popup_message_always( langcode("POPEM00029"), name );
+
+		    if (strlen(latitude) < 7)
+			continue;	// We really don't have any latitude here!
+                    lat_dd[0] = latitude[0];
+                    lat_dd[1] = latitude[1];
+                    lat_dd[2] = '\0';
+ 
+                    lat_mm[0] = latitude[2];
+                    lat_mm[1] = latitude[3];
+                    lat_mm[2] = '\0';
+
+                    lat_ss[0] = latitude[4];
+                    lat_ss[1] = latitude[5];
+                    lat_ss[2] = '\0';
+
+                    lat_dir[0] = latitude[6];
+                    lat_dir[1] = '\0';
+
+		    if (strlen(longitude) < 8)
+			continue;	// We really don't have any longitude here!
+                    long_dd[0] = longitude[0];
+                    long_dd[1] = longitude[1];
+                    long_dd[2] = longitude[2];
+                    long_dd[3] = '\0';
+ 
+                    long_mm[0] = longitude[3];
+                    long_mm[1] = longitude[4];
+                    long_mm[2] = '\0';
+ 
+                    long_ss[0] = longitude[5];
+                    long_ss[1] = longitude[6];
+                    long_ss[2] = '\0';
+ 
+                    long_dir[0] = longitude[7];
+                    long_dir[1] = '\0';
+
+                    // Now must convert from DD MM SS format to DD MM.MM format so that we
+                    // can run it through our conversion routine to Xastir coordinates.
+                    if (1 != sscanf(lat_ss, "%d", &temp1)) {
+                        fprintf(stderr,"locate_place:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(lat_str, sizeof(lat_str), "%s%s.%02d%s", lat_dd,
+                        lat_mm, temp1, lat_dir);
+                    coord_lat = convert_lat_s2l(lat_str);
+
+                    if (1 != sscanf(long_ss, "%d", &temp1)) {
+                        fprintf(stderr,"locate_place:sscanf parsing error\n");
+                    }
+
+                    temp1 = (int)((temp1 / 60.0) * 100 + 0.5);  // Poor man's rounding
+                    xastir_snprintf(long_str, sizeof(long_str), "%s%s.%02d%s", long_dd,
+                        long_mm, temp1, long_dir);
+                    coord_lon = convert_lon_s2l(long_str);
+
+
+//set_map_position(w, coord_lat, coord_lon);
+
+                    // Fill in the array values with what we just
+                    // found, increment the counter.
+                    xastir_snprintf(match_array_name[my_count],200,"%s",name);
+                    match_array_lat[my_count] = coord_lat;
+                    match_array_long[my_count] = coord_lon;
+                    my_count++;
+
+                    // Check for a max array.  Return if it is full.
+                    if (my_count > 50) {
+                        return(50);
+                    }
+                }
+            }
+        }
+    }
+
+    return(my_count);
+}
+
+
diff --git a/src/map_shp.c b/src/map_shp.c
new file mode 100644
index 0000000..7a1e2c6
--- /dev/null
+++ b/src/map_shp.c
@@ -0,0 +1,4182 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_shp.c,v 1.144 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ *
+ * Please see separate copyright notice attached to the
+ * shape_ring_direction() function in this file.
+ *
+ * DBFAWK TODO:
+ *  - reload .dbfawk's when they've changed (or maps are reindexed)
+ *  - scale line widths based on zoom level (see city_flag, for example)
+ *  - allow multiple font sizes (font_size=small|medium|large|huge)
+ *  - allow multiple font faces?
+ *  - allow setting of map layer for individual shapes
+ *  - transparency
+ *  - allow setting fill_style (solid, stippled, etc.)
+ *  - do more config/ *.dbfawk files!
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+#define CHECKREALLOC(m)  if (!m) { fprintf(stderr, "***** Realloc Failed *****\n"); exit(0); }
+
+#ifdef HAVE_LIBSHP
+#ifdef HAVE_LIBPCRE
+#include "awk.h"
+#include "dbfawk.h"
+#endif /* HAVE_LIBPCRE */
+#ifdef HAVE_SHAPEFIL_H
+#include <shapefil.h>
+#else   // HAVE_SHAPEFIL_H
+#ifdef HAVE_LIBSHP_SHAPEFIL_H
+#include <libshp/shapefil.h>
+#else   // HAVE_LIBSHP_SHAPEFIL_H
+#error HAVE_LIBSHP defined but no corresponding include defined
+#endif // HAVE_LIBSHP_SHAPEFIL_H
+#endif // HAVE_SHAPEFIL_H
+
+extern int npoints;		/* tsk tsk tsk -- globals */
+
+#ifdef USE_RTREE
+#include <rtree/index.h>    
+#include "shp_hash.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+static int *RTree_hitarray=NULL;
+int RTree_hitarray_size=0;
+int RTree_hitarray_index=0;
+
+
+//This trivial routine is used by the RTreeSearch as a callback when it finds
+// a match.
+int RTreeSearchCallback(int id, void* arg) 
+{
+    if (!RTree_hitarray) {
+        RTree_hitarray = (int *)malloc(1000*sizeof(int));
+        RTree_hitarray_size=1000;
+    }
+    if (RTree_hitarray_size <= RTree_hitarray_index) {
+        int *ptr;
+        ptr = realloc(RTree_hitarray, (RTree_hitarray_size+1000)*sizeof(int));
+        CHECKREALLOC(ptr);  // fatal error if we can't get 'em :-(
+        RTree_hitarray=ptr;
+        RTree_hitarray_size += 1000;
+        //fprintf(stderr,"Hitarray now at %d\n",RTree_hitarray_size);
+    }
+
+        
+    RTree_hitarray[RTree_hitarray_index++]=id-1;
+    return 1;  // signal to keep searching for more matches
+}
+#endif // USE_RTREE
+
+
+
+
+
+/*******************************************************************
+ * create_shapefile_map()
+ *
+ * Do we have a need for storing date/ time/ speed/ course/
+ * altitude/ heard-direct for each point?  Altitude could be stored
+ * in the Z space.  If we store a station's trail as an SHPT_POINT
+ * file, then we can associate a bunch of info with each point:
+ * date/time, altitude, course, speed, status/comments, path, port,
+ * heard-direct, weather data, etc.  We could also dynamically
+ * change the number of fields based on what we have a need to
+ * store, using field-names to determine what's stored in each file.
+ *
+ * shapefile_name is the path/name of the map file we wish to create
+ * (without the extension).
+ *
+ * type = SHPT_POINT, SHPT_ARC, SHPT_POLYGON,
+ * SHPT_MULTIPOINT, etc.
+ *
+ * quantity equals the number of vertices we have.
+ *
+ * padfx/padfy/padfz are the vertices themselves, in double format.
+ *******************************************************************/
+void create_shapefile_map(char *dir, char *shapefile_name, int type,
+        int quantity, double *padfx, double *padfy, double *padfz,
+        int add_timestamp, char * shape_label) {
+
+    SHPHandle my_shp_handle;
+    SHPObject *my_object;
+    DBFHandle my_dbf_handle;
+    char timedatestring[101];
+    int index;
+    int max_objects = 1;
+    char credit_string[] = "Created by Xastir, http://www.xastir.org";
+    char temp_shapefile_name[MAX_FILENAME];
+    char temp_prj_name[MAX_FILENAME];
+
+    if (debug_level & 16) {
+        fprintf(stderr,"create_shapefile_map\n");
+        fprintf(stderr,"%s %s %d %d %d\n",
+            dir,
+            shapefile_name,
+            type,
+            quantity,
+            add_timestamp);
+    }
+
+    if (quantity == 0) {
+        // No reason to make a map if we don't have any points.
+        return;
+    }
+
+    // Get the time/datestamp
+    get_timestamp(timedatestring);
+
+    if (add_timestamp) {    // Prepend a timestamp to the filename
+        int ii;
+
+        xastir_snprintf(temp_shapefile_name,
+            sizeof(temp_shapefile_name),
+            "%s%s_%s",
+            dir,
+            timedatestring,
+            shapefile_name);
+
+        // Change spaces and colons to underlines
+        for (ii = 0; ii < (int)strlen(temp_shapefile_name); ii++) {
+            if (temp_shapefile_name[ii] == ' ' ||
+                temp_shapefile_name[ii] == ':') {
+                temp_shapefile_name[ii] = '_';
+            }
+
+        }
+    }
+    else {  // Use the filename directly, no timestamp
+        xastir_snprintf(temp_shapefile_name,
+            sizeof(temp_shapefile_name),
+            "%s%s",
+            dir,
+            shapefile_name);
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr, "Creating file %s\n", temp_shapefile_name);
+ 
+    // Create empty .shp/.shx/.dbf files
+    //
+    my_shp_handle = SHPCreate(temp_shapefile_name, type);
+    my_dbf_handle = DBFCreate(temp_shapefile_name);
+
+    // Check whether we were able to open these handles
+    if ((my_shp_handle == NULL) || (my_dbf_handle == NULL)) {
+        // Probably write-protected directory
+        fprintf(stderr, "Could not create shapefile %s\n",
+            temp_shapefile_name);
+        return;
+    }
+
+    // Write out a WKT in a .prj file to go with this shapefile.
+    xastir_snprintf(temp_prj_name,
+                    sizeof(temp_prj_name),
+                    "%s.prj",
+                    temp_shapefile_name);
+    xastirWriteWKT(temp_prj_name);
+
+    // Create the different fields we'll use to store the
+    // attributes:
+    //
+    // Add a credits field and set the length.  Field 0.
+    DBFAddField(my_dbf_handle, "Credits", FTString, strlen(credit_string) + 1, 0);
+    //
+    // Add a date/time field and set the length.  Field 1.
+    DBFAddField(my_dbf_handle, "DateTime", FTString, strlen(timedatestring) + 1, 0);
+
+    // Add a label field
+    DBFAddField(my_dbf_handle, "Label", FTString, strlen(shape_label) + 1, 0);
+
+    // Note that if were passed additional parameters that went
+    // along with the lat/long/altitude points, we could write those
+    // into the DBF file in the loop below.  We would have to change
+    // from a polygon to a point filetype though.
+
+    // Populate the files with objects and attributes.  Perform this
+    // loop once for each object.
+    //
+    for (index = 0; index < max_objects; index++) {
+
+        // Create a temporary object from the vertices
+        my_object = SHPCreateSimpleObject( type,
+            quantity,
+            padfx,
+            padfy,
+            padfz);
+
+        // Write out the vertices
+        SHPWriteObject( my_shp_handle,
+            -1,
+            my_object);
+
+        // Destroy the temporary object
+        SHPDestroyObject(my_object);
+
+// Note that with the current setup the below really only get
+// written into the file once.  Check it with dbfinfo/dbfdump.
+
+        // Write the credits attributes
+        DBFWriteStringAttribute( my_dbf_handle,
+            index,
+            0,
+            credit_string);
+
+        // Write the time/date string
+        DBFWriteStringAttribute( my_dbf_handle,
+            index,
+            1,
+            timedatestring);
+
+        // Write the label string
+        DBFWriteStringAttribute( my_dbf_handle,
+            index,
+            2,
+            shape_label);
+    }
+
+    // Close the .shp/.shx/.dbf files
+    SHPClose(my_shp_handle);
+    DBFClose(my_dbf_handle);
+}
+
+
+
+
+
+// Function which creates a Shapefile map from an APRS trail.
+//
+// Navigate through the linked list of TrackRow structs to pick out
+// the lat/long and write them into arrays of floats.  We then pass
+// those arrays to create_shapefile_map().
+//
+void create_map_from_trail(char *call_sign) {
+    DataRow *p_station;
+
+
+    // Find the station in our database.  Count the number of points
+    // for that station first, then allocate some arrays to hold
+    // that quantity of points.  Stuff the lat/long into the arrays
+    // and then call create_shapefile_map().
+    //
+    if (search_station_name(&p_station, call_sign, 1)) {
+        int count;
+        int ii;
+        TrackRow *ptr;
+        char temp[MAX_FILENAME];
+        char temp2[MAX_FILENAME];
+        double *x;
+        double *y;
+        double *z;
+        char temp_base_dir[MAX_VALUE];
+
+        count = 0;
+        ptr = p_station->oldest_trackpoint;
+        while (ptr != NULL) {
+            count++;
+            ptr = ptr->next;
+        }
+
+//fprintf(stderr, "Quantity of points: %d\n", count);
+
+        if (count == 0) {
+            // No reason to make a map if we don't have any points
+            // in the track list.
+           return;
+        }
+
+        // We know how many points are in the linked list.  Allocate
+        // arrays to hold the values.
+        x = (double *) malloc( count * sizeof(double) );
+        y = (double *) malloc( count * sizeof(double) );
+        z = (double *) malloc( count * sizeof(double) );
+        CHECKMALLOC(x);
+        CHECKMALLOC(y);
+        CHECKMALLOC(z);
+
+        // Fill in the values.  We need to convert from Xastir
+        // coordinate system to lat/long doubles as we go.
+        ptr = p_station->oldest_trackpoint;
+        ii = 0;
+        while ((ptr != NULL) && (ii < count) ) {
+
+            // Convert from Xastir coordinates to lat/long
+
+            // Convert to string
+            convert_lon_l2s(ptr->trail_long_pos, temp, sizeof(temp), CONVERT_DEC_DEG);
+            // Convert to double and stuff into array of doubles
+            if (1 != sscanf(temp, "%lf", &x[ii])) {
+                fprintf(stderr,"create_map_from_trail:sscanf parsing error\n");
+            }
+            // If longitude string contains "W", make the final
+            // result negative.
+            if (index(temp, 'W'))
+                x[ii] = x[ii] * -1.0;
+           
+            // Convert to string 
+            convert_lat_l2s(ptr->trail_lat_pos, temp, sizeof(temp), CONVERT_DEC_DEG);
+            // Convert to double and stuff into array of doubles
+            if (1 != sscanf(temp, "%lf", &y[ii])) {
+                fprintf(stderr,"create_map_from_trail:sscanf parsing error\n");
+            }
+            // If latitude string contains "S", make the final
+            // result negative.
+            if (index(temp, 'S'))
+                y[ii] = y[ii] * -1.0;
+
+            z[ii] = ptr->altitude;  // Altitude (meters), undefined=-99999
+
+            ptr = ptr->next;
+            ii++;
+        }
+
+        // Create a Shapefile from the APRS trail.  Write it into
+        // "~/.xastir/tracklogs" and add a date/timestamp to the end.
+        //
+        xastir_snprintf(temp, sizeof(temp),
+            "%s/",
+            get_user_base_dir("tracklogs", temp_base_dir, sizeof(temp_base_dir)));
+
+        // Create filename
+        xastir_snprintf(temp2, sizeof(temp2),
+            "%s%s",
+            call_sign,
+            "_APRS_Trail_Red");
+
+        create_shapefile_map(
+            temp,
+            temp2,
+            SHPT_ARC,
+            count,
+            x,
+            y,
+            z,
+            1, // Add a timestamp to the front of the filename
+            call_sign); 
+
+        // Free the storage that we malloc'ed
+        free(x);
+        free(y);
+        free(z);
+    }
+    else {  // Couldn't find the station of interest
+    }
+}
+
+
+
+
+
+// Code borrowed from Shapelib which determines whether a ring is CW
+// or CCW.  Thanks to Frank Warmerdam for permitting us to use this
+// under the GPL license!  Per e-mail of 04/29/2003 between Frank
+// and Curt, WE7U.  Frank gave permission for us to use _any_
+// portion of Shapelib inside the GPL'ed Xastir program.
+//
+// Test Ring for Clockwise/Counter-Clockwise (fill or hole ring)
+//
+// Return  1  for Clockwise (fill ring)
+// Return -1  for Counter-Clockwise (hole ring)
+// Return  0  for error/indeterminate (shouldn't get this!)
+//
+int shape_ring_direction ( SHPObject *psObject, int Ring ) {
+    int nVertStart;
+    int nVertCount;
+    int iVert;
+    float dfSum;
+    int result;
+
+ 
+    nVertStart = psObject->panPartStart[Ring];
+
+    if( Ring == psObject->nParts-1 )
+        nVertCount = psObject->nVertices - psObject->panPartStart[Ring];
+    else
+        nVertCount = psObject->panPartStart[Ring+1] 
+            - psObject->panPartStart[Ring];
+
+    dfSum = 0.0;
+    for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
+    {
+        dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1]
+               - psObject->padfY[iVert] * psObject->padfX[iVert+1];
+    }
+
+    dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
+           - psObject->padfY[iVert] * psObject->padfX[nVertStart];
+
+    if (dfSum < 0.0)
+        result = 1;
+    else if (dfSum > 0.0)
+        result = -1;
+    else 
+        result = 0;
+
+    return(result);
+}
+
+
+
+
+
+/**********************************************************
+ * draw_shapefile_map()
+ *
+ * This function handles both weather-alert shapefiles (from the
+ * NOAA site) and shapefiles used as maps (from a number of
+ * sources).
+ *
+ * If destination_pixmap equals INDEX_CHECK_TIMESTAMPS or
+ * INDEX_NO_TIMESTAMPS, then we are indexing the file (finding the
+ * extents) instead of drawing it.
+ *
+ * The current implementation can draw Polygon, PolyLine, and Point
+ * Shapefiles, but only from a few sources (NOAA, Mapshots.com, and
+ * ESRI/GeographyNetwork.com).  We don't handle some of the more
+ * esoteric formats.  We now handle the "hole" drawing in polygon
+ * shapefiles, where one direction around the ring means a fill, and
+ * the other direction means a hole in the polygon.
+ *
+ * Note that we must currently hard-code the file-recognition
+ * portion and the file-drawing portion, because every new source of
+ * Shapefiles has a different format, and the fields and field
+ * definitions can all change between them.
+ *
+ * If alert is NULL, draw every shape that fits the screen.  If
+ * non-NULL, draw only the shape that matches the zone number.
+ * 
+ * Here's what I get for the County_Warning_Area Shapefile:
+ *
+ *
+ * Info for shapefiles/county_warning_areas/w_24ja01.shp
+ * 4 Columns,  121 Records in file
+ *            WFO          string  (3,0)
+ *            CWA          string  (3,0)
+ *            LON           float  (18,5)
+ *            LAT           float  (18,5)
+ * Info for shapefiles/county_warning_areas/w_24ja01.shp
+ * Polygon(5), 121 Records in file
+ * File Bounds: (              0,              0)
+ *              (    179.7880249,    71.39809418)
+ *
+ * From the NOAA web pages:
+
+ Zone Alert Maps: (polygon) (such as z_16mr01.shp)
+ ----------------
+ field name type   width,dec description 
+ STATE      character 2     [ss] State abbrev (US Postal Standard) 
+ ZONE       character 3     [zzz] Zone number, from WSOM C-11 
+ CWA        character 3     County Warning Area, from WSOM C-47 
+ NAME       character 254   Zone name, from WSOM C-11 
+ STATE_ZONE character 5     [sszzz] state+("00"+zone.trim).right(3)) 
+ TIME_ZONE  character 2     [tt] Time Zone, 2 chars if split 
+ FE_AREA    character 2     [aa] Cardinal area of state (occasional) 
+ LON        numeric   10,5  Longitude of centroid [decimal degrees] 
+ LAT        numeric   9,5   Latitude of centroid [decimal degrees] 
+
+
+ NOTE:  APRS weather alerts have these sorts of codes in them:
+    AL_C001
+    AUTAUGACOUNTY
+    MS_C075
+    LAUDERDALE&NEWTONCOUNTIES
+    KY_C009
+    EDMONSON
+    MS_CLARKE
+    MS_C113
+    MN_Z076
+    PIKECOUNTY
+    ATTALACOUNTY
+    ST.LUCIECOUNTY
+    CW_AGLD
+
+ The strings in the shapefiles are mixed-case, and it appears that the NAME field would
+ have the county name, in case state_zone-number format was not used.  We can use the
+ STATE_ZONE filed for a match unless it is a non-standard form, in which case we'll need
+ to look through the NAME field, and perhaps chop off the "SS_" state portion first.
+
+
+ County Warning Areas: (polygon)
+ ---------------------
+ field name type   width,dec description 
+ WFO        character 3     WFO Identifier (name of CWA) 
+ CWA        character 3     CWA Identifier (same as WFO) 
+ LON        numeric   10,5  Longitude of centroid [decimal degrees]
+ LAT        numeric   9,5   Latitude of centroid [decimal degrees]
+
+ Coastal and Offshore Marine Areas: (polygon)
+ ----------------------------------
+ field name type   width,dec description 
+ ID         character 6     Marine Zone Identifier 
+ WFO        character 3     Assigned WFO (Office Identifier) 
+ NAME       character 250   Name of Marine Zone 
+ LON        numeric   10,5  Longitude of Centroid [decimal degrees] 
+ LAT        numeric   9,5   Latitude of Centroid [decimal degrees] 
+ WFO_AREA   character 200   "Official Area of Responsibility", from WSOM D51/D52 
+
+ Road Maps: (polyline)
+ ----------
+ field name type     width,dec  description
+ STFIPS     numeric     2,0     State FIPS Code
+ CTFIPS     numeric     3,0     County FIPS Code
+ MILES      numeric     6,2     length [mi]
+ KILOMETERS numeric     6,2     length [km]
+ TOLL       numeric     1,0 
+ SURFACE    numeric     1,0     Surface type
+ LANES      numeric     2,0     Number of lanes
+ FEAT_CLASS numeric     2,0  
+ CLASS      character   30
+ SIGN1      character   6       Primary Sign Route
+ SIGN2      character   6       Secondary Sign Route
+ SIGN3      character   6       Alternate Sign Route
+ DESCRIPT   character   35      Name of road (sparse)
+ SPEEDLIM   numeric     16,0
+ SECONDS    numeric     16,2
+
+Lakes (lk17de98.shp):
+---------------------
+field name  type     width,dec  description
+NAME        string      (40,0)
+FEATURE     string      (40,0)
+LON         float       (10,5)
+LAT         float       (9,5)
+
+
+USGS Quads Overlay (24kgrid.shp) from
+http://data.geocomm.com/quadindex/
+----------------------------------
+field name  type     width,dec  Example
+NAME        string     (30,0)   Lummi Bay OE W
+STATE       string      (2,0)   WA
+LAT         string      (6,0)   48.750
+LON         string      (8,0)   -122.750
+MRC         string      (8,0)   48122-G7
+
+
+// Need to figure out which type of alert it is, select the corresponding shapefile,
+// then store the shapefile AND the alert_tag in the alert hash .filename list?
+// and draw the map.  Add an item to alert hash to keep track?
+
+// The last parameter denotes loading into pixmap_alerts instead of pixmap or pixmap_final
+// Here's the old APRS-type map call:
+//map_search (w, alert_scan, alert, &alert_count,(int)(alert_status[i + 2] == DATA_VIA_TNC || alert_status[i + 2] == DATA_VIA_LOCAL), DRAW_TO_PIXMAP_ALERTS);
+
+// Check the zone name(s) to see which Shapefile(s) to use.
+
+            switch (zone[4]) {
+                case ('C'): // County File (c_16my01.shp)
+                    break;
+***             case ('A'): // County Warning File (w_24ja01.shp)
+                    break;
+                case ('Z'): // Zone File (z_16mr01.shp, z_16my01.shp, mz24ja01.shp, oz09de99.shp)
+                    break;
+                case ('F'): // Fire weather (fz_ddmmyy.shp)
+                    break;
+***             case ('A'): // Canadian Area (a_mmddyy.shp)
+                    break;
+                case ('R'): // Canadian Region (r_mmddyy.shp)
+                    break;
+            }
+
+
+ **********************************************************/
+
+#ifdef WITH_DBFAWK
+static dbfawk_sig_info *Dbf_sigs = NULL;
+static awk_symtab *Symtbl = NULL;
+/* default dbfawk rule when no better signature match is found */
+static awk_rule dbfawk_default_rules[] = {
+      { 0,
+        BEGIN,
+        NULL,
+        NULL,
+        0,
+        0,
+        "dbfinfo=\"\"; key=\"\"; lanes=1; color=8; fill_color=13; fill_stipple=0; name=\"\"; filled=0; fill_style=0; pattern=0; display_level=65536; label_level=0",
+        0,
+        0 },
+};
+#define dbfawk_default_nrules (sizeof(dbfawk_default_rules)/sizeof(dbfawk_default_rules[0]))
+static dbfawk_sig_info *dbfawk_default_sig = NULL;
+#endif  // WITH_DBFAWK
+
+void draw_shapefile_map (Widget w,
+                        char *dir,
+                        char *filenm,
+                        alert_entry * alert,
+                        u_char alert_color,
+                        int destination_pixmap,
+                        map_draw_flags *mdf) {
+
+    DBFHandle       hDBF;
+    SHPObject       *object;
+    static XPoint   points[MAX_MAP_POINTS];
+    char            file[MAX_FILENAME];  /* Complete path/name of image file */
+    char            short_filenm[MAX_FILENAME];
+    int             i, fieldcount, recordcount, structure, ring;
+#ifndef WITH_DBFAWK
+    char            ftype[15];
+    int             nWidth, nDecimals;
+#endif /*!WITH_DBFAWK*/
+    SHPHandle       hSHP;
+    int             nShapeType, nEntities;
+    double          adfBndsMin[4], adfBndsMax[4];
+    char            *sType;
+    unsigned long   my_lat, my_long;
+    long            x,y;
+    int             ok, index;
+    int             polygon_hole_flag;
+    int             *polygon_hole_storage;
+    GC              gc_temp = NULL;
+    XGCValues       gc_temp_values;
+    Region          region[3];
+    int             temp_region1;
+    int             temp_region2;
+    int             temp_region3;
+    int             gps_flag = 0;
+    char            gps_label[100];
+    int             gps_color = 0x0c;
+#ifndef WITH_DBFAWK
+    int             road_flag = 0;
+    int             lake_flag = 0;
+    int             river_flag = 0;
+    int             railroad_flag = 0;
+    int             school_flag = 0;
+    int             path_flag = 0;
+    int             city_flag = 0;
+#endif /*!WITH_DBFAWK*/
+    int             quad_overlay_flag = 0;
+#ifndef WITH_DBFAWK
+    int             mapshots_labels_flag = 0;
+#endif /*!WITH_DBFAWK*/
+    int             weather_alert_flag = 0;
+    char            *filename;  // filename itself w/o directory
+    char            search_param1[10];
+#ifndef WITH_DBFAWK
+    int             search_field1 = 0;
+    int             search_field2 = -1;
+#endif /* !WITH_DBFAWK */
+    char            search_param2[10];
+    int             found_shape = -1;
+#ifndef USE_RTREE
+    int             start_record;
+    int             end_record;
+#endif // !USE_RTREE
+    int             ok_to_draw = 0;
+    int             high_water_mark_i = 0;
+    int             high_water_mark_index = 0;
+    char            quad_label[100];
+    char            status_text[MAX_FILENAME];
+#ifdef WITH_DBFAWK
+    /* these have to be static since I recycle Symtbl between calls */
+    static char     dbfsig[1024],dbffields[1024],name[64],key[64],sym[4];
+    static int      color,lanes,filled,pattern,display_level,label_level;
+    static int      fill_style,fill_color;
+    static int      fill_stipple;
+    //static int layer;
+    dbfawk_sig_info *sig_info = NULL;
+    dbfawk_field_info *fld_info = NULL;
+
+
+    int draw_filled_orig;
+#endif  // WITH_DBFAWK
+    int draw_filled;
+    static int label_color = 8; /* set by dbfawk.  Otherwise it's black. */
+    static int font_size = FONT_DEFAULT; // set by dbfawk, else this default
+
+    typedef struct _label_string {
+        char   label[50];
+        int    found;
+        struct _label_string *next;
+    } label_string;
+
+    // Define hash table for label pointers
+    label_string *label_hash[256];
+    // And the index into it
+    uint8_t hash_index = 0;
+
+    label_string *ptr2 = NULL;
+
+#ifdef USE_RTREE
+    struct Rect viewportRect;
+    double rXmin, rYmin, rXmax,rYmax;
+    shpinfo *si;
+    int nhits;
+#endif // USE_RTREE
+
+    // pull this out of the map_draw_flags
+    draw_filled = mdf->draw_filled;
+
+    // Initialize the hash table label pointers
+    for (i = 0; i < 256; i++) {
+        label_hash[i] = NULL;
+    }
+
+
+#ifdef WITH_DBFAWK
+    // We're going to change draw_filled a bunch if we've got Auto turned
+    // on, but we have to check --- save this!
+    draw_filled_orig=draw_filled;
+
+    // Re-initialize these static variables every time through here.
+    // Otherwise, if a dbfawk file forgets to set one, we'd use what the
+    // last map used.  Sometimes that's ugly.
+    color=8;
+    lanes=1;
+    filled=0;
+    fill_style=0;
+    fill_color=13;
+    fill_stipple=0;
+    pattern=0;
+    display_level=8192;
+    label_level=0;
+    label_color=8;
+    font_size=FONT_DEFAULT;
+#endif  // WITH_DBFAWK
+
+#ifdef WITH_DBFAWK
+    if (Dbf_sigs == NULL)
+        Dbf_sigs = dbfawk_load_sigs(get_data_base_dir("config"),".dbfawk");
+
+    if (debug_level & 16)
+        fprintf(stderr,"DBFAWK signatures %sfound in %s.\n",
+                (Dbf_sigs)?" ":"NOT ",get_data_base_dir("config"));
+
+    if (dbfawk_default_sig == NULL) {
+        /* set up default dbfawk when no sig matches */
+        // This one is ok to leave allocated, as it gets malloc'ed
+        // once during each runtime and then gets left alone.  We
+        // don't need to free it.
+        dbfawk_default_sig = calloc(1,sizeof(dbfawk_sig_info));
+        CHECKMALLOC(dbfawk_default_sig);
+
+        // Calls awk_new_program which allocates memory.  Again, we
+        // don't need to free this one, as it gets allocated only
+        // once per runtime.
+        dbfawk_default_sig->prog = awk_load_program_array(dbfawk_default_rules,dbfawk_default_nrules);
+    }
+#endif  // WITH_DBFAWK
+
+    //fprintf(stderr,"*** Alert color: %d ***\n",alert_color);
+
+    // We don't draw the shapes if alert_color == -1
+    if (alert_color != 0xff)
+        ok_to_draw++;
+
+    search_param1[0] = '\0';
+    search_param2[0] = '\0';
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    //fprintf(stderr,"draw_shapefile_map:start:%s\n",file);
+
+    filename = filenm;
+    i = strlen(filenm);
+    while ( (filenm[i] != '/') && (i >= 0) )
+        filename = &filenm[i--];
+        //fprintf(stderr,"draw_shapefile_map:filename:%s\ttitle:%s\n",filename,alert->title);    
+
+    if (alert)
+        weather_alert_flag++;
+
+    // Check for ~/.xastir/tracklogs directory.  We set up the
+    // labels and colors differently for these types of files.
+//    if (strstr(filenm,".xastir/tracklogs")) { // We're in the ~/.xastir/tracklogs directory
+    if (strstr(filenm,"GPS")) { // We're in the maps/GPS directory
+        gps_flag++;
+    }
+
+    // Open the .dbf file for reading.  This has the textual
+    // data (attributes) associated with each shape.
+    hDBF = DBFOpen( file, "rb" );
+    if ( hDBF == NULL ) {
+        if (debug_level & 16)
+            fprintf(stderr,"draw_shapefile_map: DBFOpen(%s,\"rb\") failed.\n", file );
+
+        return;
+    }
+    if (debug_level & 16)
+        fprintf(stderr,"\n---------------------------------------------\nInfo for %s\n",filenm);
+
+#ifdef WITH_DBFAWK
+    *dbfsig = '\0';
+    fieldcount = dbfawk_sig(hDBF,dbfsig,sizeof(dbfsig));
+#else   // WITH_DBFAWK
+    fieldcount = DBFGetFieldCount(hDBF);
+#endif /* !WITH_DBFAWK */
+    if (fieldcount == 0) {
+        DBFClose( hDBF );   // Clean up open file descriptors
+        return;     // Should have at least one field
+        
+    }
+    recordcount = DBFGetRecordCount(hDBF);
+    if (recordcount == 0) {
+        DBFClose( hDBF );   // Clean up open file descriptors
+        return;     // Should have at least one record
+    }
+    if (debug_level & 16) {
+        fprintf(stderr,"%d Columns,  %d Records in file\n", fieldcount, recordcount);
+#ifdef WITH_DBFAWK
+        fprintf(stderr,"DBF signature: %s\n",dbfsig);
+#endif  // WITH_DBFAWK
+    }
+#ifdef WITH_DBFAWK
+    if (Dbf_sigs) {   /* see if we have a .dbfawk file that matches */
+        sig_info = dbfawk_find_sig(Dbf_sigs,dbfsig,file);
+        if (sig_info) gps_flag = 0; // trump gps_flag-- use dbfawk
+        if (!sig_info) {
+            fprintf(stderr,"No DBFAWK signature for %s!  Using default.\n",filenm);
+            sig_info = dbfawk_default_sig;
+        }
+        if (sig_info) {         /* we've got a .dbfawk, so set up symtbl */
+
+            if (!Symtbl) {
+                Symtbl = awk_new_symtab();
+                awk_declare_sym(Symtbl,"dbffields",STRING,dbffields,sizeof(dbffields));
+                awk_declare_sym(Symtbl,"color",INT,&color,sizeof(color));
+                awk_declare_sym(Symtbl,"lanes",INT,&lanes,sizeof(lanes));
+                //awk_declare_sym(Symtbl,"layer",INT,&layer,sizeof(layer));
+                awk_declare_sym(Symtbl,"name",STRING,name,sizeof(name));
+                awk_declare_sym(Symtbl,"key",STRING,key,sizeof(key));
+                awk_declare_sym(Symtbl,"symbol",STRING,sym,sizeof(sym));
+                awk_declare_sym(Symtbl,"filled",INT,&filled,sizeof(filled));
+                awk_declare_sym(Symtbl,"fill_style",INT,&fill_style,sizeof(fill_style));
+                awk_declare_sym(Symtbl,"fill_color",INT,&fill_color,sizeof(fill_color));
+                awk_declare_sym(Symtbl,"fill_stipple",INT,&fill_stipple,sizeof(fill_stipple));
+                awk_declare_sym(Symtbl,"pattern",INT,&pattern,sizeof(pattern));
+                awk_declare_sym(Symtbl,"display_level",INT,&display_level,sizeof(display_level));
+                awk_declare_sym(Symtbl,"label_level",INT,&label_level,sizeof(label_level));
+                awk_declare_sym(Symtbl,"label_color",INT,&label_color,sizeof(label_color));
+                awk_declare_sym(Symtbl,"font_size",INT,&font_size,sizeof(font_size));
+            }
+            if (awk_compile_program(Symtbl,sig_info->prog) < 0) {
+                fprintf(stderr,"Unable to compile .dbfawk program\n");
+
+                if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+                    dbfawk_free_sigs(sig_info);
+                }
+                return;
+            }
+            awk_exec_begin(sig_info->prog); /* execute a BEGIN rule if any */
+
+            /* find out which dbf fields we care to read */
+            fld_info = dbfawk_field_list(hDBF, dbffields);
+
+       } else {                /* should never be reached anymore! */
+            fprintf(stderr,"No DBFAWK signature for %s and no default!\n",filenm);
+            //exit(1);  // Debug
+            return;
+        }
+    }
+#endif /* WITH_DBFAWK */
+    /* 
+     * DBFAWK: all this WX junk following to set up the search fields and
+     * parameters is now done by the dbfawk file which sets the "key" 
+     * variable to the appropriate search key for each record which is 
+     * compared to the alert->title[].
+     */
+#ifndef WITH_DBFAWK
+    // If we're doing weather alerts and index is not filled in yet
+    if (weather_alert_flag && (alert->index == -1) ) {
+
+        // For weather alerts:
+        // Need to figure out from the initial characters of the filename which
+        // type of file we're using, then compute the fields we're looking for.
+        // After we know that, need to look in the DBF file for a match.  Once
+        // we find a match, we can open up the SHX/SHP files, go straight to
+        // the shape we want, and draw it.
+        switch (filenm[0]) {
+
+            case 'c':   // County File
+                // County, c_ files:  WI_C037
+                // STATE  CWA  COUNTYNAME
+                // AL     BMX  Morgan
+                // Need fields 0/1:
+                search_field1 = 0;  // STATE
+                search_field2 = 3;  // FIPS
+                xastir_snprintf(search_param1,sizeof(search_param1),"%c%c",
+                    alert->title[0],
+                    alert->title[1]);
+                xastir_snprintf(search_param2,sizeof(search_param2),"%c%c%c",
+                    alert->title[4],
+                    alert->title[5],
+                    alert->title[6]);
+                break;
+
+            case 'w':   // County Warning Area File
+                // County Warning Area, w_ files:  CW_ATAE
+                // WFO  CWA
+                // TAE  TAE
+                // Need field 0
+                search_field1 = 0;  // WFO
+                search_field2 = -1;
+                xastir_snprintf(search_param1,sizeof(search_param1),"%c%c%c",
+                    alert->title[4],
+                    alert->title[5],
+                    alert->title[6]);
+                break;
+
+            case 'o':   // Offshore Marine Area File
+                // Offshore Marine Zones, oz files:  AN_Z081
+                // ID      WFO  NAME
+                // ANZ081  MPC  Gulf of Maine
+                // Need field 0
+                search_field1 = 0;  // ID
+                search_field2 = -1;
+                xastir_snprintf(search_param1,sizeof(search_param1),"%c%c%c%c%c%c",
+                    alert->title[0],
+                    alert->title[1],
+                    alert->title[3],
+                    alert->title[4],
+                    alert->title[5],
+                    alert->title[6]);
+                break;
+
+            case 'm':   // Marine Area File
+                // Marine Zones, mz?????? files:  PK_Z120
+                // ID      WFO  NAME
+                // PKZ120  AJK  Area 1B. Southeast Alaska,
+                // Need field 0
+                search_field1 = 0;  // ID
+                search_field2 = -1;
+                xastir_snprintf(search_param1,sizeof(search_param1),"%c%c%c%c%c%c",
+                    alert->title[0],
+                    alert->title[1],
+                    alert->title[3],
+                    alert->title[4],
+                    alert->title[5],
+                    alert->title[6]);
+                break;
+
+            case 'z':   // Zone File
+            case 'f':   // Fire zone file, KS_F033
+            default:
+                // Weather alert zones, z_ files:  KS_Z033
+                // STATE_ZONE
+                // AK225
+                // Need field 4
+                search_field1 = 4;  // STATE_ZONE
+                search_field2 = -1;
+                xastir_snprintf(search_param1,sizeof(search_param1),"%c%c%c%c%c",
+                    alert->title[0],
+                    alert->title[1],
+                    alert->title[4],
+                    alert->title[5],
+                   alert->title[6]);
+                break;
+        }
+
+        //fprintf(stderr,"Search_param1: %s,\t",search_param1);
+        //fprintf(stderr,"Search_param2: %s\n",search_param2);
+    } /* weather_alert */
+
+    for (i=0; i < fieldcount; i++) {
+        char szTitle[12];
+
+        switch (DBFGetFieldInfo(hDBF, i, szTitle, &nWidth, &nDecimals)) {
+        case FTString:
+            xastir_snprintf(ftype,sizeof(ftype),"string");
+            break;
+
+        case FTInteger:
+            xastir_snprintf(ftype,sizeof(ftype),"integer");
+            break;
+
+        case FTDouble:
+            xastir_snprintf(ftype,sizeof(ftype),"float");
+            break;
+
+        case FTInvalid:
+            xastir_snprintf(ftype,sizeof(ftype),"invalid/unsupported");
+            break;
+
+        default:
+            xastir_snprintf(ftype,sizeof(ftype),"unknown");
+            break;
+        }
+
+        // Check for quad overlay type of map
+        if (strstr(filename,"24kgrid")) {  // USGS Quad overlay file
+            quad_overlay_flag++;
+        }
+
+        // Check the filename for mapshots.com filetypes to see what
+        // type of file we may be dealing with.
+        if (strncasecmp(filename,"tgr",3) == 0) {   // Found Mapshots or GeographyNetwork file
+
+            if (strstr(filename,"lpt")) {           // Point file
+                mapshots_labels_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found point file ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"plc")) {         // Designated Places:  Arlington
+                city_flag++;
+                mapshots_labels_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found (Designated Places) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"ctycu")) {    // County Boundaries: WA, Snohomish
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found county (mapshots county) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"lkA")) {      // Roads
+                road_flag++;
+                mapshots_labels_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found some roads (mapshots roads) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"lkB")) {      // Railroads
+                railroad_flag++;
+                mapshots_labels_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found some railroads (mapshots railroads) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"lkC")) {      // Paths/etc.  Pipelines?  Transmission lines?
+                path_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found some paths (mapshots paths/etc) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"lkH")) {      // Rivers/Streams/Lakes/Glaciers
+                river_flag++;
+                mapshots_labels_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found water (mapshots rivers/streams/lakes/glaciers) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (  strstr(filename,"elm")       // Elementary school district
+                    || strstr(filename,"mid")       // Middle school district
+                    || strstr(filename,"sec")       // Secondary school district
+                    || strstr(filename,"uni") ) {   // Unified school district
+                school_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found school district ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"urb")) {      // Urban areas: Seattle, WA
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found (mapshots urban areas) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+            else if (strstr(filename,"wat")) {      // Bodies of water, creeks/lakes/glaciers
+                lake_flag++;
+                mapshots_labels_flag++;
+                if (debug_level & 16) {
+                    fprintf(stderr,"*** Found some water (mapshots bodies of water, creeks/lakes/glaciers) ***\n");
+                    break;
+                }
+                else
+                    break;
+            }
+        }
+
+
+        // Attempt to guess which type of shapefile we're dealing
+        // with, and how we should draw it.
+        // If debug is on, we want to print out every field, otherwise
+        // break once we've made our guess on the type of shapefile.
+        if (debug_level & 16)
+            fprintf(stderr,"%15.15s\t%15s  (%d,%d)\n", szTitle, ftype, nWidth, nDecimals);
+
+        if (strncasecmp(szTitle, "SPEEDLIM", 8) == 0) {
+            // sewroads shapefile?
+            road_flag++;
+            if (debug_level & 16)
+                fprintf(stderr,"*** Found some roads (SPEEDLIM*) ***\n");
+            else
+                break;
+        }
+        else if (strncasecmp(szTitle, "US_RIVS_ID", 10) == 0) {
+            // which shapefile?
+            river_flag++;
+            if (debug_level & 16)
+                fprintf(stderr,"*** Found some rivers (US_RIVS_ID*) ***\n");
+            else
+                break;
+        }
+        else if (strcasecmp(szTitle, "FEATURE") == 0) {
+            char *attr_str;
+            int j;
+            for (j=0; j < recordcount; j++) {
+                if (fieldcount >= (i+1)) {
+                    attr_str = (char*)DBFReadStringAttribute(hDBF, j, i);
+                    if (strncasecmp(attr_str, "LAKE", 4) == 0) {
+                        // NOAA Lakes and Water Bodies (lk17de98) shapefile
+                        lake_flag++;
+                        if (debug_level & 16)
+                            fprintf(stderr,"*** Found some lakes (FEATURE == LAKE*) ***\n");
+                        break;
+                    }
+                    else if (strstr(attr_str, "Highway") != NULL ||
+                             strstr(attr_str, "highway") != NULL ||
+                             strstr(attr_str, "HIGHWAY") != NULL) {
+                         // NOAA Interstate Highways of the US (in011502) shapefile
+                         // NOAA Major Roads of the US (rd011802) shapefile
+                         road_flag++;
+                         if (debug_level & 16)
+                             fprintf(stderr,"*** Found some roads (FEATURE == *HIGHWAY*) ***\n");
+                         break;
+                     }
+                }
+            }
+            if (!(debug_level & 16) && (lake_flag || road_flag))
+                break;
+        }
+        else if (strcasecmp(szTitle, "LENGTH") == 0 ||
+                 strcasecmp(szTitle, "RR")     == 0 ||
+                 strcasecmp(szTitle, "HUC")    == 0 ||
+                 strcasecmp(szTitle, "TYPE")   == 0 ||
+                 strcasecmp(szTitle, "SEGL")   == 0 ||
+                 strcasecmp(szTitle, "PMILE")  == 0 ||
+                 strcasecmp(szTitle, "ARBSUM") == 0 ||
+                 strcasecmp(szTitle, "PNAME")  == 0 ||
+                 strcasecmp(szTitle, "OWNAME") == 0 ||
+                 strcasecmp(szTitle, "PNMCD")  == 0 ||
+                 strcasecmp(szTitle, "OWNMCD") == 0 ||
+                 strcasecmp(szTitle, "DSRR")   == 0 ||
+                 strcasecmp(szTitle, "DSHUC")  == 0 ||
+                 strcasecmp(szTitle, "USDIR")  == 0) {
+            // NOAA Rivers of the US (rv14fe02) shapefile
+            // NOAA Rivers of the US Subset (rt14fe02) shapefile
+            river_flag++;
+            if (river_flag >= 14) {
+                if (debug_level & 16)
+                    fprintf(stderr,"*** Found some rivers (NOAA Rivers of the US or Subset) ***\n");
+                else
+                    break;
+            }
+        }
+    } /* ... end for (i = 0; i < fieldcount; i++) */
+#endif /* !WITH_DBFAWK */
+
+    // Search for specific record if we're doing alerts
+    if (weather_alert_flag && (alert->index == -1) ) {
+        int done = 0;
+#ifndef WITH_DBFAWK
+        char *string1;
+        char *string2;
+#endif /* !DBFAWK */
+
+        // Step through all records
+        for( i = 0; i < recordcount && !done; i++ ) {
+#ifdef WITH_DBFAWK
+            int keylen;
+
+            if (sig_info) {
+                char modified_title[50];
+
+                dbfawk_parse_record(sig_info->prog,hDBF,fld_info,i);
+
+                keylen = strlen(key);
+                if (debug_level & 16) {
+                    static char old_key[4]; // Used to limit number of output lines in debug mode
+
+                    if (strncmp(old_key, key, 4)) {
+                      fprintf(stderr,"dbfawk alert parse: record %d key=%s\n",
+                              i,key);
+                      memcpy(old_key, key, sizeof(old_key));
+                    }
+                }
+
+                xastir_snprintf(modified_title, sizeof(modified_title), "%s", alert->title);
+
+                // Tweak for RED_FLAG alerts:  If RED_FLAG alert
+                // we've changed the 'Z' to an 'F' in our
+                // alert->title already.  Change the 'F' back to a
+                // 'Z' temporarily (modified_title) for our
+                // compares.
+                //
+                if (modified_title[3] == 'F' && strncmp(alert->filename, "fz", 2) == 0) {
+                    modified_title[3] = 'Z';
+                }
+
+                // If match using keylen number of chars, try the
+                // same match but using titlelen number of chars
+                if (strncmp(modified_title,key,keylen) == 0) {
+                    int titlelen;
+
+                    titlelen = strlen(modified_title);
+
+                    // Try the same match with titlelen number of
+                    // chars
+                    if (strncmp(modified_title,key,titlelen) == 0) {
+ 
+                        found_shape = i;
+                        done++;
+                        if (debug_level & 16) {
+                            fprintf(stderr,"dbfawk alert found it: %d \n",i);
+                            fprintf(stderr,"Title %s, key %s\n",modified_title,key);
+ 
+                        }
+                    }
+                    else {
+                        // Found a match using keylen number of
+                        // characters, but it's not a match using
+                        // titlelen number of characters.
+                        if (debug_level & 16) {
+                            fprintf(stderr,
+                                "dbfawk alert: match w/keylen, not w/titlelen: %s=%d %s=%d\n",
+                                key,
+                                keylen,
+                                modified_title,
+                                titlelen);
+                            fprintf(stderr,"Title %s, key %s\n",modified_title,key);
+                        }
+                    }
+                }
+            }
+#else /* !WITH_DBFAWK */
+            char *ptr;
+            switch (filenm[0]) {
+                case 'c':   // County File
+                    // Remember that there's only one place for
+                    // internal storage of the DBF string.  This is
+                    // why this code is organized with two "if"
+                    // statements.
+                    if (fieldcount >= (search_field1 + 1) ) {
+                        string1 = (char *)DBFReadStringAttribute(hDBF,i,search_field1);
+                        if (!strncasecmp(search_param1,string1,2)) {
+                            //fprintf(stderr,"Found state\n");
+                            if (fieldcount >= (search_field2 + 1) ) {
+                                string2 = (char *)DBFReadStringAttribute(hDBF,i,search_field2);
+                                ptr = string2;
+                                ptr += 2;   // Skip past first two characters of FIPS code
+                                if (!strncasecmp(search_param2,ptr,3)) {
+//fprintf(stderr,"Found it!  %s\tShape: %d\n",string1,i);
+                                    done++;
+                                    found_shape = i;
+                                }
+                            }
+                        }
+                    }
+                    break;
+                case 'w':   // County Warning Area File
+                    if (fieldcount >= (search_field1 + 1) ) {
+                        string1 = (char *)DBFReadStringAttribute(hDBF,i,search_field1);
+                        if ( !strncasecmp(search_param1,string1,strlen(string1))
+                                && (strlen(string1) != 0) ) {
+//fprintf(stderr,"Found it!  %s\tShape: %d\n",string1,i);
+                            done++;
+                            found_shape = i;
+                        }
+                    }
+                    break;
+                case 'o':   // Offshore Marine Area File
+                    if (fieldcount >= (search_field1 + 1) ) {
+                        string1 = (char *)DBFReadStringAttribute(hDBF,i,search_field1);
+                        if ( !strncasecmp(search_param1,string1,strlen(string1))
+                                && (strlen(string1) != 0) ) {
+//fprintf(stderr,"Found it!  %s\tShape: %d\n",string1,i);
+                            done++;
+                            found_shape = i;
+                        }
+                    }
+                    break;
+                case 'm':   // Marine Area File
+                    if (fieldcount >= (search_field1 + 1) ) {
+                        string1 = (char *)DBFReadStringAttribute(hDBF,i,search_field1);
+                        if ( !strncasecmp(search_param1,string1,strlen(string1))
+                                && (strlen(string1) != 0) ) {
+//fprintf(stderr,"Found it!  %s\tShape: %d\n",string1,i);
+                            done++;
+                            found_shape = i;
+                        }
+                    }
+                    break;
+                case 'z':   // Zone File
+                case 'f':   // Fire zone file
+                    if (fieldcount >= (search_field1 + 1) ) {
+                        string1 = (char *)DBFReadStringAttribute(hDBF,i,search_field1);
+                        if ( !strncasecmp(search_param1,string1,strlen(string1))
+                                && (strlen(string1) != 0) ) {
+//fprintf(stderr,"Found it!  %s\tShape: %d\n",string1,i);
+                            done++;
+                            found_shape = i;
+                        }
+                    }
+                default:
+                    break;
+            }
+#endif /* !WITH_DBFAWK */
+        }
+        alert->index = found_shape; // Fill it in 'cuz we just found it
+    } /* if (weather_alert_flag && alert_index == -1)... */
+    else if (weather_alert_flag) {
+        // We've been here before and we already know the index into the
+        // file to fetch this particular shape.
+        found_shape = alert->index;
+        if (debug_level & 16)
+            fprintf(stderr,"wx_alert: found_shape = %d\n",found_shape);
+    }
+
+    //fprintf(stderr,"Found shape: %d\n", found_shape);
+
+    if (debug_level & 16)
+        fprintf(stderr,"Calling SHPOpen()\n");
+
+    // Open the .shx/.shp files for reading.
+    // These are the index and the vertice files.
+    hSHP = SHPOpen( file, "rb" );
+    if( hSHP == NULL ) {
+        fprintf(stderr,"draw_shapefile_map: SHPOpen(%s,\"rb\") failed.\n", file );
+        DBFClose( hDBF );   // Clean up open file descriptors
+
+#ifdef WITH_DBFAWK
+        dbfawk_free_info(fld_info);
+        if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+            dbfawk_free_sigs(sig_info);
+        }
+#endif  // WITH_DBFAWK
+
+        return;
+    }
+
+
+    // Get the extents of the map file
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, adfBndsMin, adfBndsMax );
+
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(status_text,0);       // Indexing ...
+
+        // We're indexing only.  Save the extents in the index.
+        index_update_ll(filenm,    // Filename only
+            adfBndsMin[1],  // Bottom
+            adfBndsMax[1],  // Top
+            adfBndsMin[0],  // Left
+            adfBndsMax[0],  // Right
+            1000);          // Default Map Level
+
+        DBFClose( hDBF );   // Clean up open file descriptors
+        SHPClose( hSHP );
+
+#ifdef WITH_DBFAWK
+        dbfawk_free_info(fld_info);
+        if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+            dbfawk_free_sigs(sig_info);
+        }
+#endif  // WITH_DBFAWK
+
+        return; // Done indexing this file
+    }
+    else {
+        xastir_snprintf(status_text,
+            sizeof(status_text),
+            langcode ("BBARSTA028"),
+            short_filenm);
+        statusline(status_text,0);       // Loading ...
+    }
+
+#ifdef USE_RTREE
+    // We put this section AFTER the code that determines whether we're merely
+    // indexing, so we don't bother to generate rtrees unless we're really
+    // drawing the file.
+    si=NULL;
+
+    // Don't bother even looking at the hash if this shapefile is completely
+    // contained in the current viewport.  We'll have to read every shape
+    // in it anyway, and all we'd be doing is extra work searching the
+    // RTree
+    if (!map_inside_viewport_lat_lon(adfBndsMin[1],
+                                     adfBndsMax[1],
+                                     adfBndsMin[0],
+                                     adfBndsMax[0])) {
+        si = get_shp_from_hash(file);
+        if (!si) {
+            // we don't have what we need, so generate the index and make
+            // the hashtable entry
+            add_shp_to_hash(file,hSHP); // this will index all the shapes in 
+                                        // an RTree and save the root in a 
+                                        // shpinfo structure
+            si=get_shp_from_hash(file); // now get that structure
+            if (!si) {
+                fprintf(stderr,
+                        "Panic!  added %s, lost it already!\n",file);
+                exit(1);
+            }
+        }
+    }
+    // we need this for the rtree search
+    get_viewport_lat_lon(&rXmin, &rYmin, &rXmax, &rYmax);
+    viewportRect.boundary[0] = (RectReal) rXmin;
+    viewportRect.boundary[1] = (RectReal) rYmin;
+    viewportRect.boundary[2] = (RectReal) rXmax;
+    viewportRect.boundary[3] = (RectReal) rYmax;
+#endif // USE_RTREE
+
+    switch ( nShapeType ) {
+        case SHPT_POINT:
+            sType = "Point";
+            break;
+
+        case SHPT_POINTZ:
+            sType = "3D Point";
+            break;
+
+        case SHPT_ARC:
+            sType = "Polyline";
+            break;
+
+        case SHPT_ARCZ:
+            sType = "3D Polyline";
+            break;
+
+        case SHPT_POLYGON:
+            sType = "Polygon";
+            break;
+
+        case SHPT_POLYGONZ:
+            sType = "3D Polygon";
+            break;
+
+        case SHPT_MULTIPOINT:
+            fprintf(stderr,"Multi-Point Shapefile format not implemented: %s\n",file);
+            sType = "MultiPoint";
+            DBFClose( hDBF );   // Clean up open file descriptors
+            SHPClose( hSHP );
+
+#ifdef WITH_DBFAWK
+            dbfawk_free_info(fld_info);
+            if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+                dbfawk_free_sigs(sig_info);
+            }
+#endif  // WITH_DBFAWK
+
+            return; // Multipoint type.  Not implemented yet.
+            break;
+
+        default:
+            DBFClose( hDBF );   // Clean up open file descriptors
+            SHPClose( hSHP );
+
+#ifdef WITH_DBFAWK
+            dbfawk_free_info(fld_info);
+            if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+                dbfawk_free_sigs(sig_info);
+            }
+#endif  // WITH_DBFAWK
+
+            return; // Unknown type.  Don't know how to process it.
+            break;
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr,"%s(%d), %d Records in file\n",sType,nShapeType,nEntities);
+
+    if (debug_level & 16)
+        fprintf(stderr,"File Bounds: (%15.10g,%15.10g)\n\t(%15.10g,%15.10g)\n",
+            adfBndsMin[0], adfBndsMin[1], adfBndsMax[0], adfBndsMax[1] );
+
+    // Check the bounding box for this shapefile.  If none of the
+    // file is within our viewport, we can skip the entire file.
+
+    if (debug_level & 16)
+        fprintf(stderr,"Calling map_visible_lat_lon on the entire shapefile\n");
+
+    if (! map_visible_lat_lon(  adfBndsMin[1],  // Bottom
+                                adfBndsMax[1],  // Top
+                                adfBndsMin[0],  // Left
+                                adfBndsMax[0]) ) {  // Right
+        if (debug_level & 16)
+            fprintf(stderr,"No shapes within viewport.  Skipping file...\n");
+
+        DBFClose( hDBF );   // Clean up open file descriptors
+        SHPClose( hSHP );
+
+#ifdef WITH_DBFAWK
+        dbfawk_free_info(fld_info);
+        if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+            dbfawk_free_sigs(sig_info);
+        }
+#endif  // WITH_DBFAWK
+
+        return;     // The file contains no shapes in our viewport
+    }
+
+
+    // Set a default line width for all maps.  This will most likely
+    // be modified for particular maps in later code.
+    (void)XSetLineAttributes(XtDisplay(w), gc, 0, LineSolid, CapButt,JoinMiter);
+
+
+    // NOTE: Setting the color here and in the "else" may not stick if we do more
+    //       complex drawing further down like a SteelBlue lake with a black boundary,
+    //       or if we have labels turned on which resets our color to black.
+    if (weather_alert_flag) {   /* XXX */
+        char xbm_path[MAX_FILENAME];
+        unsigned int _w, _h;
+        int _xh, _yh;
+        int ret_val;
+        FILE *alert_fp = NULL;
+        char xbm_filename[MAX_FILENAME];
+        
+
+        // This GC is used for weather alerts (writing to the
+        // pixmap: pixmap_alerts) and _was_ used for beam_heading
+        // rays, but no longer is.
+        (void)XSetForeground (XtDisplay (w), gc_tint, colors[(int)alert_color]);
+
+        // N7TAP: No more tinting as that would change the color of the alert, losing that information.
+        (void)XSetFunction(XtDisplay(w), gc_tint, GXcopy);
+        /*
+        Options are:
+            GXclear         0                       (Don't use)
+            GXand           src AND dst             (Darker colors, black can result from overlap)
+            GXandReverse    src AND (NOT dst)       (Darker colors)
+            GXcopy          src                     (Don't use)
+            GXandInverted   (NOT src) AND dst       (Pretty colors)
+            GXnoop          dst                     (Don't use)
+            GXxor           src XOR dst             (Don't use, overlapping areas cancel each other out)
+            GXor            src OR dst              (More pastel colors, too bright?)
+            GXnor           (NOT src) AND (NOT dst) (Darker colors, very readable)
+            GXequiv         (NOT src) XOR dst       (Bright, very readable)
+            GXinvert        (NOT dst)               (Don't use)
+            GXorReverse     src OR (NOT dst)        (Bright, not as readable as others)
+            GXcopyInverted  (NOT src)               (Don't use)
+            GXorInverted    (NOT src) OR dst        (Bright, not very readable)
+            GXnand          (NOT src) OR (NOT dst)  (Bright, not very readable)
+            GXset           1                       (Don't use)
+        */
+
+    
+        // Note that we can define more alert files for other countries.  They just need to match
+        // the alert text that comes along in the NWS packet.
+        // Current alert files we have defined:
+        //      winter_storm.xbm *
+        //      snow.xbm
+        //      winter_weather.xbm *
+        //      flood.xbm
+        //      torndo.xbm *
+        //      red_flag.xbm
+        //      wind.xbm
+        //      alert.xbm (Used if no match to another filename)
+
+        // Alert texts we receive:
+        //      FLOOD
+        //      SNOW
+        //      TORNDO
+        //      WIND
+        //      WINTER_STORM
+        //      WINTER_WEATHER
+        //      RED_FLAG
+        //      SVRTSM (no file defined for this yet)
+        //      Many others.
+
+        // Attempt to open the alert filename:  <alert_tag>.xbm (lower-case alert text)
+        // to detect whether we have a matching filename for our alert text.
+        xastir_snprintf(xbm_filename, sizeof(xbm_filename), "%s", alert->alert_tag);
+
+        // Convert the filename to lower-case
+        to_lower(xbm_filename);
+
+        // Construct the complete path/filename
+        xastir_snprintf(xbm_path, sizeof(xbm_path), "%s/%s.xbm", SYMBOLS_DIR, xbm_filename);
+
+        // Try opening the file
+        alert_fp = fopen(xbm_path, "rb");
+        if (alert_fp == NULL) {
+            // Failed to find a matching file:  Instead use the "alert.xbm" file
+            xastir_snprintf(xbm_path, sizeof(xbm_path), "%s/%s", SYMBOLS_DIR, "alert.xbm");
+        } else {
+            // Success:  Close the file pointer
+            fclose(alert_fp);
+        }
+
+        /* XXX - need to add SVRTSM */
+
+
+        (void)XSetLineAttributes(XtDisplay(w), gc_tint, 0, LineSolid, CapButt,JoinMiter);
+        XFreePixmap(XtDisplay(w), pixmap_wx_stipple);
+        ret_val = XReadBitmapFile(XtDisplay(w),
+            DefaultRootWindow(XtDisplay(w)),
+            xbm_path,
+            &_w,
+            &_h,
+            &pixmap_wx_stipple,
+            &_xh,
+            &_yh);
+
+        if (ret_val != 0) {
+            fprintf(stderr,"XReadBitmapFile() failed: Bitmap not found? %s\n",xbm_path);
+
+            // We shouldn't exit on this one, as it's not so severe
+            // that we should kill Xastir.  I've seen this happen
+            // after very long runtimes though, so perhaps there's a
+            // problem somewhere in the X11 server and/or it's
+            // caching?
+            //
+            //exit(1);
+        }
+        else {
+            // We successfully loaded the bitmap, so set the stipple
+            // properly to use it.  Skip this part if we were
+            // unsuccessful at loading the bitmap.
+            (void)XSetStipple(XtDisplay(w), gc_tint, pixmap_wx_stipple);
+        }
+
+    } /* ...end if (weather_alert_flag) */
+    else { /* !weather_alert_flag */
+// Are these actually used anymore by the code?  Colors get set later
+// when we know more about what we're dealing with.
+#ifndef WITH_DBFAWK
+        if (lake_flag || river_flag)
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x1a]); // Steel Blue
+        else if (path_flag)
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]); // black
+        else if (railroad_flag)
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x01]); // purple
+        else if (city_flag || school_flag)
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0e]); // yellow
+        else
+            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]); // black
+#endif /* !WITH_DBFAWK */
+    }
+
+    // Now that we have the file open, we can read out the structures.
+    // We can handle Point, PolyLine and Polygon shapefiles at the moment.
+
+
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        DBFClose( hDBF );   // Clean up open file descriptors
+        SHPClose( hSHP );
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+
+#ifdef WITH_DBFAWK
+        dbfawk_free_info(fld_info);
+        if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+            dbfawk_free_sigs(sig_info);
+        }
+#endif  // WITH_DBFAWK
+
+        return;
+    }
+
+#ifdef USE_RTREE
+    // Now instead of looping over all the shapes, search for the ones that
+    // are in our viewport and only loop over those
+    //fprintf(stderr,"Deciding how to process this file...\n");
+    if (weather_alert_flag) {   // We're drawing _one_ weather alert shape
+        //fprintf(stderr," weather alert flag set...\n");
+        if (found_shape != -1) {    // Found the record
+            //fprintf(stderr,"  found_shape set...\n");
+            // just in case we haven't drawn any real maps yet...
+            if (!RTree_hitarray) {
+                //fprintf(stderr,"   mallocing hitarray...\n");
+                RTree_hitarray = (int *)malloc(sizeof(int)*1000);
+                RTree_hitarray_size=1000;
+            }
+            CHECKMALLOC(RTree_hitarray);
+            RTree_hitarray[0]=found_shape;
+            //fprintf(stderr," %s contains alert\n",file);
+            nhits=1;
+        }
+        else {  // Didn't find the record
+            //fprintf(stderr,"   found_shape is -1...\n");
+            nhits=0;
+        }
+    }
+    else {  // Draw an entire Shapefile map
+        //fprintf(stderr,"   weather_alert_flag not set...\n");
+        if (si) {
+            //fprintf(stderr,"   si is 0x%lx...\n",(unsigned long int) si);
+            RTree_hitarray_index=0;
+            // the callback will be executed every time the search finds a 
+            // shape whose bounding box overlaps the viewport.
+            nhits = Xastir_RTreeSearch(si->root, &viewportRect, 
+                                (void *)RTreeSearchCallback, 0);
+            //fprintf(stderr,"Found %d hits in %s\n",nhits,file);
+        } else {
+            //fprintf(stderr,"   si not set ...\n");
+            // we read the entire shapefile
+            nhits=nEntities;
+            // fprintf(stderr," %s entirely in view, with %d shapes\n",file,nhits);
+        }
+    }
+    //fprintf(stderr," Done with decision, nhits is %d\n",nhits);
+#else   // USE_RTREE
+    if (weather_alert_flag) {   // We're drawing _one_ weather alert shape
+        if (found_shape != -1) {    // Found the record
+            start_record = found_shape;
+            end_record = found_shape + 1;
+        }
+        else {  // Didn't find the record
+            start_record = 0;
+            end_record = 0;
+        }
+    }
+    else {  // Draw an entire Shapefile map
+        start_record = 0;
+        end_record = nEntities;
+    }
+#endif  // USE_RTREE
+
+#ifdef USE_RTREE
+    // only iterate over the hits found by RTreeSearch, not all of them
+    for (RTree_hitarray_index=0; RTree_hitarray_index<nhits; 
+         RTree_hitarray_index++) {
+#else   // USE_RTREE
+
+    // Here's where we actually iterate through the entire file, drawing
+    // each structure as we find it.
+    for (structure = start_record; structure < end_record; structure++) {
+#endif  // USE_RTREE
+        int skip_it = 0;
+        int skip_label = 0;
+
+
+        // Call HandlePendingEvents() every XX objects so that we
+        // can interrupt map drawing if necessary.  Keep this at a
+        // power of two for speed.  Bigger numbers speed up map
+        // drawing at the expense of being able to interrupt map
+        // drawing quickly.  HandlePendingEvents() drops to about
+        // 0.5% CPU at 64 (according to gprof).  That appears to be
+        // the break-even point where CPU is minimal.
+        //
+#ifdef USE_RTREE
+        if ( (RTree_hitarray_index % 64) == 0 ) {
+#else
+        if ( (structure % 64) == 0 ) {
+#endif
+        
+            HandlePendingEvents(app_context);
+            if (interrupt_drawing_now) {
+                DBFClose( hDBF );   // Clean up open file descriptors
+                SHPClose( hSHP );
+                // Update to screen
+                (void)XCopyArea(XtDisplay(da),
+                    pixmap,
+                    XtWindow(da),
+                    gc,
+                    0,
+                    0,
+                    (unsigned int)screen_width,
+                    (unsigned int)screen_height,
+                    0,
+                    0);
+#ifdef WITH_DBFAWK
+                dbfawk_free_info(fld_info);
+                if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+                    dbfawk_free_sigs(sig_info);
+                }
+#endif  // WITH_DBFAWK
+                return;
+            }
+        }
+
+
+#ifdef USE_RTREE
+        if (si) {
+            structure=RTree_hitarray[RTree_hitarray_index];
+        } else if ((weather_alert_flag && found_shape!=-1)) {
+            structure = RTree_hitarray[0];
+        } else {
+            structure = RTree_hitarray_index;
+        }
+#endif  // USE_RTREE
+
+        // Have had segfaults before at the SHPReadObject() call
+        // when the Shapefile was corrupted.
+        //fprintf(stderr,"Before SHPReadObject:%d\n",structure);
+
+        object = SHPReadObject( hSHP, structure );  // Note that each structure can have multiple rings
+
+        //fprintf(stderr,"After SHPReadObject\n");
+
+        if (object == NULL)
+            continue;   // Skip this iteration, go on to the next
+
+        // Fill in the boundary variables in the alert record.  We use
+        // this info in load_alert_maps() to determine which alerts are
+        // within our view, without having to open up the shapefiles to
+        // get this info (faster).
+        if (weather_alert_flag) {
+            alert->top_boundary    = object->dfYMax;
+            alert->left_boundary   = object->dfXMin;
+            alert->bottom_boundary = object->dfYMin;
+            alert->right_boundary  = object->dfXMax;
+        }
+
+        // Here we check the bounding box for this shape against our
+        // current viewport.  If we can't see it, don't draw it.
+
+//        if (debug_level & 16)
+//            fprintf(stderr,"Calling map_visible_lat_lon on a shape\n");
+
+        if ( map_visible_lat_lon( object->dfYMin,   // Bottom
+                                  object->dfYMax,   // Top
+                                  object->dfXMin,   // Left
+                                  object->dfXMax) ) {   // Right
+
+            const char *temp;
+#ifndef WITH_DBFAWK
+            char temp2[100];
+#endif /*!WITH_DBFAWK*/
+            int jj;
+            int x0 = 0; // Used for computing label rotation
+            int x1 = 0;
+            int y0 = 0;
+            int y1 = 0;
+
+
+            if (debug_level & 16) {
+                fprintf(stderr,"Shape %d is visible, drawing it.", structure);
+                fprintf(stderr,"  Parts in shape: %d\n", object->nParts );    // Number of parts in this structure
+            }
+
+            if (debug_level & 16) {
+                // Print the field contents
+                for (jj = 0; jj < fieldcount; jj++) {
+                    if (fieldcount >= (jj + 1) ) {
+                        temp = DBFReadStringAttribute( hDBF, structure, jj );
+                        if (temp != NULL) {
+                            fprintf(stderr,"%s, ", temp);
+                        }
+                    }
+                }
+                fprintf(stderr,"\n");
+                fprintf(stderr,"Done with field contents\n");
+            }
+#ifdef WITH_DBFAWK
+            if (sig_info) {
+                dbfawk_parse_record(sig_info->prog,hDBF,fld_info,structure);
+                if (debug_level & 16) {
+                    fprintf(stderr,"dbfawk parse of structure %d: ",structure);
+                    fprintf(stderr,"color=%d ",color);
+                    fprintf(stderr,"lanes=%d ",lanes);
+                    fprintf(stderr,"name=%s ",name);
+                    fprintf(stderr,"key=%s ",key);
+                    fprintf(stderr,"symbol=%s ",sym);
+                    fprintf(stderr,"filled=%d ",filled);
+                    fprintf(stderr,"fill_style=%d ",fill_style);
+                    fprintf(stderr,"fill_color=%d ",fill_color);
+                    fprintf(stderr,"fill_stipple=%d ",fill_stipple);
+                    fprintf(stderr,"pattern=%d ",pattern);
+                    fprintf(stderr,"display_level=%d ",display_level);
+                    fprintf(stderr,"label_level=%d ",label_level);
+                    fprintf(stderr,"label_color=%d\n",label_color);
+                    // fprintf(stderr,"layer=%d\n",layer);
+                }
+                /* set attributes */
+                (void)XSetForeground(XtDisplay(w), gc, colors[color]);
+
+
+                // Let the user decide whether to make the map
+                // filled or unfilled via the Map Properties dialog.
+                // This allows things like the NOAA counties map to
+                // be used as a base map (filled) or as a vector
+                // overlay map at the user's discretion.  The
+                // choices available are:
+                // 0: Global No-Fill.  Don't fill any polygons.
+                // 1: Global Fill.  Fill all polygons.
+                // 2: Auto.  dbfawk file, if present, takes over control.
+                //
+                if (debug_level & 16) {
+                    fprintf(stderr," draw_filled is %d\n",draw_filled_orig);
+                }
+                switch (draw_filled_orig) {
+
+                    case 0: // Global No-Fill (Vector)
+                        // Do nothing, user has chosen Global
+                        // No_Fill for this map.  The draw_filled
+                        // variable takes precedence.
+                        break;
+
+                    case 1: // Global Fill
+                        // Do nothing, user has chosen Global
+                        // Fill for this map.  The draw_filled
+                        // variable takes precedence.
+                        break;
+
+                    case 2: // Auto
+                    default:
+                        // User has chosen Auto Fill for this map,
+                        // so the Dbfawk file controls the fill
+                        // property.  If no dbfawk file, "filled"
+                        // will take on the default setting listed
+                        // in dbfawk_default_rules[] above.
+                        draw_filled = filled;
+                        break;
+                }
+
+
+                if (weather_alert_flag) { /* XXX will this fix WX alerts? */
+                    fill_style = FillStippled;
+                } 
+
+                skip_it = (map_color_levels && (scale_y > display_level));
+                skip_label = (map_color_levels && (scale_y > label_level));
+
+            }
+#else   /* WITH_DBFAWK */
+            if (draw_filled == 2) {
+                // "Auto" fill was chosen, but dbfawk support is not
+                // compiled in.  Default to vector mode (no polygon
+                // fills)
+                draw_filled = 0;
+            }
+#endif /* WITH_DBFAWK */
+
+            /* This case statement is a mess.  Lots of common code could be
+               used before the case but currently isn't */
+
+            switch ( nShapeType ) {
+
+
+                case SHPT_POINT:
+                case SHPT_POINTZ:
+                    // We hit this case once for each point shape in
+                    // the file, iff that shape is within our
+                    // viewport.
+
+
+                    if (debug_level & 16)
+                        fprintf(stderr,"Found Point Shapefile\n");
+
+                    // Read each point, place a label there, and an optional symbol
+                    //object->padfX
+                    //object->padfY
+                    //object->padfZ
+ 
+//                    if (    mapshots_labels_flag
+//                            && map_labels
+//                            && (fieldcount >= 3) ) {
+
+                    if (!skip_it) {    // Need a bracket so we can define
+                                // some local variables.
+                        const char *temp = NULL;
+                        int ok = 1;
+                        int temp_ok;
+
+#ifdef WITH_DBFAWK
+                        if (map_labels)
+                            temp = name;
+#else /* !WITH_DBFAWK */
+                        // If labels are enabled and we have enough
+                        // fields in the .dbf file, read the label.
+                        if (map_labels && fieldcount >= 1) {
+                            // Snag the label from the .dbf file
+                            temp = DBFReadStringAttribute( hDBF, structure, 0 );
+                        }
+#endif /* !WITH_DBFAWK */
+                        // Convert point to Xastir coordinates
+                        temp_ok = convert_to_xastir_coordinates(&my_long,
+                            &my_lat,
+                            (float)object->padfX[0],
+                            (float)object->padfY[0]);
+                        //fprintf(stderr,"%ld %ld\n", my_long, my_lat);
+
+                        if (!temp_ok) {
+                            fprintf(stderr,"draw_shapefile_map1: Problem converting from lat/lon\n");
+                            ok = 0;
+                            x = 0;
+                            y = 0;
+                        }
+                        else {
+                            // Convert to screen coordinates.  Careful
+                            // here!  The format conversions you'll need
+                            // if you try to compress this into two
+                            // lines will get you into trouble.
+                            x = my_long - NW_corner_longitude;
+                            y = my_lat - NW_corner_latitude;
+                            x = x / scale_x;
+                            y = y / scale_y;
+                        }
+
+                        if (ok == 1) {
+                            char symbol_table = '/';
+                            char symbol_id = '.'; /* small x */
+                            char symbol_over = ' ';
+
+                            // Fine-tuned the location here so that
+                            // the middle of the 'X' would be at the
+                            // proper pixel.
+#ifdef WITH_DBFAWK
+                            if (*sym)
+                                symbol(w,0,sym[0],sym[1],sym[2],pixmap,1,x-10,y-10,' ');
+                            else
+                                symbol(w, 0, symbol_table, symbol_id, symbol_over, pixmap, 1, x-10, y-10, ' ');
+#else // WITH_DBFAWK
+                            symbol(w, 0, symbol_table, symbol_id, symbol_over, pixmap, 1, x-10, y-10, ' ');
+#endif //WITH_DBFAWK
+
+                            // Fine-tuned this string so that it is
+                            // to the right of the 'X' and aligned
+                            // nicely.
+                            if (map_labels && !skip_label) {
+// Labeling of points done here
+                                draw_nice_string(w, pixmap, 0, x+10, y+5, (char*)temp, 0xf, 0x10, strlen(temp));
+                                //(void)draw_label_text ( w, x, y, strlen(temp), colors[label_color], (char *)temp);
+                                //(void)draw_rotated_label_text (w, 90, x+10, y, strlen(temp), colors[label_color], (char *)temp);
+                            }
+                        }
+                    }
+                    break;
+
+
+
+                case SHPT_ARC:
+                case SHPT_ARCZ:
+                    // We hit this case once for each polyline shape
+                    // in the file, iff at least part of that shape
+                    // is within our viewport.
+
+
+                    if (debug_level & 16)
+                        fprintf(stderr,"Found Polylines\n");
+
+// Draw the PolyLines themselves:
+
+                    // Default in case we forget to set the line
+                    // width later:
+                    (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineSolid, CapButt,JoinMiter);
+
+
+#ifdef WITH_DBFAWK
+                    if (!skip_it) {
+                        (void)XSetForeground(XtDisplay(w), gc, colors[color]);
+                        (void)XSetLineAttributes(XtDisplay (w), gc, 
+                                                 (lanes)?lanes:1,
+                                                 pattern,
+                                                 CapButt,JoinMiter);
+                    }
+#else /*!WITH_DBFAWK*/
+// Set up width and zoom level for roads
+                    if (road_flag) {
+                        int lanes = 0;
+                        int dashed_line = 0;
+
+                        if ( mapshots_labels_flag && (fieldcount >= 9) ) {
+                            const char *temp;
+
+                            temp = DBFReadStringAttribute( hDBF, structure, 8 );    // CFCC Field
+                            switch (temp[1]) {
+                                case '1':   // A1? = Primary road or interstate highway
+                                    if (map_color_levels && scale_y > 16384)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16384)
+                                        skip_label++;
+                                    lanes = 4;
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x04]); // brown
+                                    break;
+                                case '2':   // A2? = Primary road w/o limited access, US highways
+                                    if (map_color_levels && scale_y > 8192)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 8192)
+                                        skip_label++;
+                                    lanes = 3;
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]); // black
+                                    break;
+                                case '3':   // A3? = Secondary road & connecting road, state highways
+                                    // Skip the road if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_label++;
+                                    lanes = 2;
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]); // black
+                                    switch (temp[2]) {
+                                        case '1':
+                                        case '2':
+                                        case '3':
+                                        case '4':
+                                        case '5':
+                                        case '6':
+                                            break;
+                                        case '7':
+                                        case '8':
+                                        default:
+                                            if (map_color_levels && scale_y > 128)
+                                                skip_label++;
+                                            break;
+                                    }
+                                    break;
+                                case '4':   // A4? = Local, neighborhood & rural roads, city streets
+                                    // Skip the road if we're above this zoom level
+                                    if (map_color_levels && scale_y > 96)
+                                        skip_it++;
+                                    // Skip labels above this zoom level to keep things uncluttered
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x28]); // gray35
+                                    break;
+                                case '5':   // A5? = Vehicular trail passable only by 4WD vehicle
+                                    // Skip the road if we're above this zoom level
+                                    if (map_color_levels && scale_y > 64)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+                                    dashed_line++;
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x28]); // gray35
+                                    break;
+                                case '6':   // A6? = Cul-de-sac, traffic circles, access ramp,
+                                            // service drive, ferry crossing
+                                    if (map_color_levels && scale_y > 64)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+ 
+                                    switch (temp[2]) {
+                                        case '5':   // Ferry crossing
+                                            lanes = 2;
+                                            dashed_line++;
+                                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x08]); // black
+                                           break;
+                                        default:
+                                            lanes = 1;
+                                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x28]); // gray35
+                                            break;
+                                    }
+
+                                    break;
+                                case '7':   // A7? = Walkway or pedestrian trail, stairway,
+                                            // alley, driveway or service road
+                                    // Skip the road if we're above this zoom level
+                                    if (map_color_levels && scale_y > 64)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+                                    dashed_line++;
+
+                                    switch (temp[2]) {
+                                        case '1':   // Walkway or trail for pedestrians
+                                        case '2':   // Stairway or stepped road for pedestrians
+                                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0c]); // red
+                                            break;
+                                        default:
+                                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x28]); // gray35
+                                            break;
+                                    }
+
+                                    break;
+                                default:
+                                    lanes = 1;
+                                    if (map_color_levels && scale_y > 64)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x28]); // gray35
+                                    break;
+                            }
+                        }
+                        else {  // Must not be a mapshots or ESRI Tiger map
+                            if (fieldcount >= 7) {  // Need at least 7 fields if we're snagging #6, else segfault
+                                lanes = DBFReadIntegerAttribute( hDBF, structure, 6 );
+
+                                // In case we guess wrong on the
+                                // type of file and the lanes are
+                                // really out of bounds:
+                                if (lanes < 1 || lanes > 10) {
+                                    //fprintf(stderr,"lanes = %d\n",lanes);
+                                    lanes = 1;
+                                }
+                            }
+                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x28]); // gray35
+                        }
+                        if (lanes != (int)NULL) {
+                            if (dashed_line) {
+                                (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineOnOffDash, CapButt,JoinMiter);
+                            }
+                            else {
+                                (void)XSetLineAttributes (XtDisplay (w), gc, lanes, LineSolid, CapButt,JoinMiter);
+                            }
+                        }
+                        else {
+                            (void)XSetLineAttributes (XtDisplay (w), gc, 1, LineSolid, CapButt,JoinMiter);
+                        }
+                    }   // End of road flag portion
+
+// Set up width and zoom levels for water
+                    else if (river_flag || lake_flag) {
+                        int lanes = 0;
+                        int dashed_line = 0;
+                        int glacier_flag = 0;
+
+                        if ( mapshots_labels_flag && (fieldcount >= 9) ) {
+                            const char *temp;
+
+                            temp = DBFReadStringAttribute( hDBF, structure, 8 );    // CFCC Field
+                            switch (temp[1]) {
+                                case '0':   // H0? = Water feature/shoreline
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 4096)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 0;
+
+                                    switch (temp[2]) {
+                                        case '2':   // Intermittent
+                                            dashed_line++;
+                                            // Skip the vector if we're above this zoom level
+                                            if (map_color_levels && scale_y > 64)
+                                                skip_it++;
+                                            if (map_color_levels && scale_y > 16)
+                                                skip_label++;
+                                           break;
+                                        default:
+                                            break;
+                                    }
+
+                                   break;
+                                case '1':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 128)
+                                        skip_label++;
+                                    switch (temp[2]) {
+                                        case '0':
+                                            if (map_color_levels && scale_y > 16)
+                                                skip_label++;
+                                            lanes = 1;
+                                            break;
+                                        case '1':
+                                            if (map_color_levels && scale_y > 16)
+                                                skip_label++;
+                                            lanes = 1;
+                                            break;
+                                        case '2':
+                                            if (map_color_levels && scale_y > 16)
+                                                skip_label++;
+                                            lanes = 1;
+                                            dashed_line++;
+                                            break;
+                                        case '3':
+                                            if (map_color_levels && scale_y > 16)
+                                                skip_label++;
+                                            lanes = 1;
+                                            break;
+                                        default:
+                                            if (map_color_levels && scale_y > 16)
+                                                skip_label++;
+                                            lanes = 1;
+                                            break;
+                                    }
+                                    break;
+                                case '2':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+ 
+                                    switch (temp[2]) {
+                                        case '2':   // Intermittent
+                                            dashed_line++;
+                                           break;
+                                        default:
+                                            break;
+                                    }
+
+                                   break;
+                                case '3':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+ 
+                                    switch (temp[2]) {
+                                        case '2':   // Intermittent
+                                            dashed_line++;
+                                           break;
+                                        default:
+                                            break;
+                                    }
+
+                                   break;
+                                case '4':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+ 
+                                    switch (temp[2]) {
+                                        case '2':   // Intermittent
+                                            dashed_line++;
+                                           break;
+                                        default:
+                                            break;
+                                    }
+
+                                   break;
+                                case '5':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+                                    break;
+                                case '6':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+                                    break;
+                                case '7':   // Nonvisible stuff.  Don't draw these
+                                    skip_it++;
+                                    skip_label++;
+                                    break;
+                                case '8':
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+  
+                                    switch (temp[2]) {
+                                        case '1':   // Glacier
+                                            glacier_flag++;
+                                           break;
+                                        default:
+                                            break;
+                                    }
+
+                                   break;
+                                default:
+                                    // Skip the vector if we're above this zoom level
+                                    if (map_color_levels && scale_y > 256)
+                                        skip_it++;
+                                    if (map_color_levels && scale_y > 16)
+                                        skip_label++;
+                                    lanes = 1;
+                                    break;
+                            }
+                            if (dashed_line) {
+                                (void)XSetLineAttributes (XtDisplay (w), gc, lanes, LineOnOffDash, CapButt,JoinMiter);
+                            }
+                            else {
+                                (void)XSetLineAttributes (XtDisplay (w), gc, lanes, LineSolid, CapButt,JoinMiter);
+                            }
+                        }
+                        else {  // We don't know how wide to make it, not a mapshots or ESRI Tiger maps
+                            if (dashed_line) {
+                                (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineOnOffDash, CapButt,JoinMiter);
+                            }
+                            else {
+                                (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineSolid, CapButt,JoinMiter);
+                            }
+                        }
+                        if (glacier_flag)
+                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x0f]); // white
+                        else
+                            (void)XSetForeground(XtDisplay(w), gc, colors[(int)0x1a]); // Steel Blue
+                    }   // End of river_flag/lake_flag code
+
+                    else {  // Set default line width, use whatever color is already defined by this point.
+                        (void)XSetLineAttributes (XtDisplay (w), gc, 0, LineSolid, CapButt,JoinMiter);
+                    }
+#endif /* !WITH_DBFAWK */
+
+//WE7U
+// I'd like to be able to change the color of each GPS track for
+// each team in the field.  It'll help to differentiate the tracks
+// where they happen to cross.
+/* XXX - WITH_DBFAWK should handle this case too.  Need to add a color
+   attribute to the generated dbf file */
+                    if (gps_flag) {
+                        int jj;
+                        int done = 0;
+
+
+                        // Fill in the label we'll use later
+                        xastir_snprintf(gps_label,
+                            sizeof(gps_label), "%s",
+                            filename);
+
+                        // Knock off the "_Color.shp" portion of the
+                        // label.  Find the last underline character
+                        // and change it to an end-of-string.
+                        jj = strlen(gps_label);
+                        while ( !done && (jj > 0) ) {
+                            if (gps_label[jj] == '_') {
+                                gps_label[jj] = '\0';   // Terminate it here
+                                done++;
+                            }
+                            jj--;
+                        }
+
+
+                        // Check for a color in the filename: i.e.
+                        // "Team2_Track_Red.shp"
+                        if (strstr(filenm,"_Red.shp")) {
+                            gps_color = 0x0c; // Red
+                        }
+                        else if (strstr(filenm,"_Green.shp")) {
+//                            gps_color = 0x64; // ForestGreen
+                            gps_color = 0x23; // Area Green Hi
+                        }
+                        else if (strstr(filenm,"_Black.shp")) {
+                            gps_color = 0x08; // black
+                        }
+                        else if (strstr(filenm,"_White.shp")) {
+                            gps_color = 0x0f; // white
+                        }
+                        else if (strstr(filenm,"_Orange.shp")) {
+//                            gps_color = 0x06; // orange
+//                            gps_color = 0x19; // orange2
+//                            gps_color = 0x41; // DarkOrange3 (good medium orange)
+                            gps_color = 0x62; // orange3 (brighter)
+                        }
+                        else if (strstr(filenm,"_Blue.shp")) {
+                            gps_color = 0x03; // cyan
+                        }
+                        else if (strstr(filenm,"_Yellow.shp")) {
+                            gps_color = 0x0e; // yellow
+                        }
+                        else if (strstr(filenm,"_Purple.shp")) {
+                            gps_color = 0x0b; // mediumorchid
+                        }
+                        else {  // Default color
+                            gps_color = 0x0c; // Red
+                        }
+
+                        // Set the color for the arc's
+                        (void)XSetForeground(XtDisplay(w), gc, colors[gps_color]);
+ 
+                        // Make the track nice and wide: Easy to
+                        // see.
+//                        (void)XSetLineAttributes (XtDisplay (w), gc, 3, LineSolid, CapButt,JoinMiter);
+                        (void)XSetLineAttributes (XtDisplay (w), gc, 3, LineOnOffDash, CapButt,JoinMiter);
+//                        (void)XSetLineAttributes (XtDisplay (w), gc, 3, LineDoubleDash, CapButt,JoinMiter);
+
+                    }   // End of gps flag portion
+
+
+                    index = 0;  // Index into our own points array.
+                                // Tells how many points we've
+                                // collected so far.
+
+ 
+                    if (ok_to_draw && !skip_it) {
+
+                        // Read the vertices for each vector now
+
+                        for (ring = 0; ring < object->nVertices; ring++ ) {
+                            int temp_ok;
+
+                            ok = 1;
+
+                            //fprintf(stderr,"\t%d:%g %g\t", ring, object->padfX[ring], object->padfY[ring] );
+                            // Convert to Xastir coordinates
+                            temp_ok = convert_to_xastir_coordinates(&my_long,
+                                &my_lat,
+                                (float)object->padfX[ring],
+                                (float)object->padfY[ring]);
+                            //fprintf(stderr,"%ld %ld\n", my_long, my_lat);
+
+                            if (!temp_ok) {
+                                fprintf(stderr,"draw_shapefile_map2: Problem converting from lat/lon\n");
+                                ok = 0;
+                                x = 0;
+                                y = 0;
+                            }
+                            else {
+                                // Convert to screen coordinates.  Careful
+                                // here!  The format conversions you'll need
+                                // if you try to compress this into two
+                                // lines will get you into trouble.
+                                x = my_long - NW_corner_longitude;
+                                y = my_lat - NW_corner_latitude;
+                                x = x / scale_x;
+                                y = y / scale_y;
+
+
+                                // Save the endpoints of the first line
+                                // segment for later use in label rotation
+                                if (ring == 0) {
+                                    // Save the first set of screen coordinates
+                                    x0 = (int)x;
+                                    y0 = (int)y;
+                                }
+                                else if (ring == 1) {
+                                    // Save the second set of screen coordinates
+                                    x1 = (int)x;
+                                    y1 = (int)y;
+                                }
+                            }
+ 
+                            if (ok == 1) {
+                                // XDrawLines uses 16-bit unsigned
+                                // integers (shorts).  Make sure we
+                                // stay within the limits.
+                                points[index].x = l16(x);
+                                points[index].y = l16(y);
+                                //fprintf(stderr,"%d %d\t", points[index].x, points[index].y);
+                                index++;
+                            }
+                            if (index > high_water_mark_index)
+                                high_water_mark_index = index;
+
+                            if (index >= MAX_MAP_POINTS) {
+                                index = MAX_MAP_POINTS - 1;
+                                fprintf(stderr,"Trying to overrun the points array: SHPT_ARC, index=%d\n",index);
+                            }
+                        }   // End of "for" loop for polyline points
+                    }
+
+
+                    if (ok_to_draw && !skip_it) {
+                        (void)XDrawLines(XtDisplay(w),
+                            pixmap,
+                            gc,
+                            points,
+                            l16(index),
+                            CoordModeOrigin);
+                    }
+
+
+// Figure out and draw the labels for PolyLines.  Note that we later
+// determine whether we want to draw the label at all.  Move all
+// code possible below that decision point to keep everything fast.
+// Don't do unnecessary calculations if we're not going to draw the
+// label.
+
+#ifdef WITH_DBFAWK
+                    temp = (gps_flag)?gps_label:name;
+#else /* !WITH_DBFAWK */
+                    // We're done with drawing the arc's.  Draw the
+                    // labels in this next section.
+                    //
+                    temp = "";
+                    if (       !skip_label
+                            && !skip_it
+                            && map_labels
+                            && road_flag) {
+                            char a[2],b[2],c[2];
+
+                        if ( (mapshots_labels_flag) && (fieldcount >= 8) ) {
+                            char temp3[3];
+                            char temp4[31];
+                            char temp5[5];
+                            char temp6[3];
+
+                            temp = DBFReadStringAttribute( hDBF, structure, 4 );
+                            xastir_snprintf(temp3,sizeof(temp3),"%s",temp);
+                            temp = DBFReadStringAttribute( hDBF, structure, 5 );
+                            xastir_snprintf(temp4,sizeof(temp4),"%s",temp);
+                            temp = DBFReadStringAttribute( hDBF, structure, 6 );
+                            xastir_snprintf(temp5,sizeof(temp5),"%s",temp);
+                            temp = DBFReadStringAttribute( hDBF, structure, 7 );
+                            xastir_snprintf(temp6,sizeof(temp6),"%s",temp);
+
+                            // Take care to not insert spaces if
+                            // some of the strings are empty.
+                            if (strlen(temp3) != 0)
+                                xastir_snprintf(a,sizeof(a)," ");
+                            else
+                                a[0] = '\0';
+                            if (strlen(temp4) != 0)
+                                xastir_snprintf(b,sizeof(b)," ");
+                            else
+                                b[0] = '\0';
+                            if (strlen(temp5) != 0)
+                                xastir_snprintf(c,sizeof(c)," ");
+                            else
+                                c[0] = '\0';
+
+                            xastir_snprintf(temp2,sizeof(temp2),"%s%s%s%s%s%s%s",
+                                temp3,a,temp4,b,temp5,c,temp6);
+                            temp = temp2;
+                        }
+                        else if (fieldcount >=10) {  // Need at least 10 fields if we're snagging #9, else segfault
+                            // For roads, we need to use SIGN1 if it exists, else use DESCRIP if it exists.
+                            temp = DBFReadStringAttribute( hDBF, structure, 9 );    // SIGN1
+                        }
+                        if ( (temp == NULL) || (strlen(temp) == 0) ) {
+                            if (fieldcount >=13)    // Need at least 13 fields if we're snagging #12, else segfault
+                                temp = DBFReadStringAttribute( hDBF, structure, 12 );    // DESCRIP
+                            else
+                                temp = NULL;
+                        }
+                    }
+                    else if (!skip_label
+                            && map_labels
+                            && !skip_it
+                            && (lake_flag || river_flag) ) {
+
+                        if ( mapshots_labels_flag && river_flag && (fieldcount >= 8) ) {
+                            char temp3[3];
+                            char temp4[31];
+                            char temp5[5];
+                            char temp6[3];
+
+
+                            temp = DBFReadStringAttribute( hDBF, structure, 4 );
+                            xastir_snprintf(temp3,sizeof(temp3),"%s",temp);
+                            temp = DBFReadStringAttribute( hDBF, structure, 5 );
+                            xastir_snprintf(temp4,sizeof(temp4),"%s",temp);
+                            temp = DBFReadStringAttribute( hDBF, structure, 6 );
+                            xastir_snprintf(temp5,sizeof(temp5),"%s",temp);
+                            temp = DBFReadStringAttribute( hDBF, structure, 7 );
+                            xastir_snprintf(temp6,sizeof(temp6),"%s",temp);
+                            xastir_snprintf(temp2,sizeof(temp2),"%s %s %s %s",
+                                temp3,temp4,temp5,temp6);
+                            temp = temp2;
+                        }
+                        else if (mapshots_labels_flag && lake_flag && (fieldcount >= 4) ) {
+                            temp = DBFReadStringAttribute( hDBF, structure, 3 );
+                        }
+                        else if (fieldcount >=14) {  // Need at least 14 fields if we're snagging #13, else segfault
+                            temp = DBFReadStringAttribute( hDBF, structure, 13 );   // PNAME (rivers)
+                        }
+                        else
+                            temp = NULL;
+                    }
+
+
+                    // First we need to convert over to using the
+                    // temp2 variable, which is changeable.  Make
+                    // temp point to it.  temp may already be
+                    // pointing to the temp2 variable.
+
+                    if (temp != temp2) {
+                        // temp points to an unchangeable string
+
+                        if (temp != NULL) { // NOAA interstates file has a NULL at this point
+                            // Copy the string so we can change it
+                            xastir_snprintf(temp2,sizeof(temp2),"%s",temp);
+                            temp = temp2;                       // Point temp to it (for later use)
+                        }
+                        else {
+                            temp2[0] = '\0';
+                        }
+                    }
+                    else {  // We're already set to work on temp2!
+                    }
+
+
+                    if ( map_labels && gps_flag ) {
+                        // We're drawing GPS info.  Use gps_label,
+                        // overriding anything set before.
+                        xastir_snprintf(temp2,
+                            sizeof(temp2),
+                            "%s",
+                            gps_label);
+                    }
+
+
+                    // Change "United States Highway 2" into "US 2"
+                    // Look for substring at start of string
+                    if ( strstr(temp2,"United States Highway") == temp2 ) {
+                        int index;
+                        // Convert to "US"
+                        temp2[1] = 'S';  // Add an 'S'
+                        index = 2;
+                        while (temp2[index+19] != '\0') {
+                            temp2[index] = temp2[index+19];
+                            index++;
+                        }
+                        temp2[index] = '\0';
+                    }
+                    else {  // Change "State Highway 204" into "State 204"
+                        // Look for substring at start of string
+                        if ( strstr(temp2,"State Highway") == temp2 ) {
+                            int index;
+                            // Convert to "State"
+                            index = 5;
+                            while (temp2[index+8] != '\0') {
+                            temp2[index] = temp2[index+8];
+                            index++;
+                            }
+                            temp2[index] = '\0';
+                        }
+                        else {  // Change "State Route 2" into "State 2"
+                            // Look for substring at start of string
+                            if ( strstr(temp2,"State Route") == temp2 ) {
+                                int index;
+                                // Convert to "State"
+                                index = 5;
+                                while (temp2[index+6] != '\0') {
+                                temp2[index] = temp2[index+6];
+                                index++;
+                                }
+                                temp2[index] = '\0';
+                            }
+                        }
+                    }
+#endif /* !WITH_DBFAWK */
+                    if ( (temp != NULL)
+                            && (strlen(temp) != 0)
+                            && map_labels
+                            && !skip_it
+                            && !skip_label ) {
+                        int temp_ok;
+
+                        ok = 1;
+
+                        // Convert to Xastir coordinates
+                        temp_ok = convert_to_xastir_coordinates(&my_long,
+                            &my_lat,
+                            (float)object->padfX[0],
+                            (float)object->padfY[0]);
+                        //fprintf(stderr,"%ld %ld\n", my_long, my_lat);
+
+                        if (!temp_ok) {
+                            fprintf(stderr,"draw_shapefile_map3: Problem converting from lat/lon\n");
+                            ok = 0;
+                            x = 0;
+                            y = 0;
+                        }
+                        else {
+                            // Convert to screen coordinates.  Careful
+                            // here!  The format conversions you'll need
+                            // if you try to compress this into two
+                            // lines will get you into trouble.
+                            x = my_long - NW_corner_longitude;
+                            y = my_lat - NW_corner_latitude;
+                            x = l16(x / scale_x);
+                            y = l16(y / scale_y);
+                        }
+
+                        if (ok == 1 && ok_to_draw) {
+
+                            int new_label = 1;
+                            int mod_number;
+
+                            // Set up the mod_number, which is used
+                            // below to determine how many of each
+                            // identical label are skipped at each
+                            // zoom level.
+
+// The goal here is to have one complete label visible on the screen
+// for each road.  We end up skipping labels based on zoom level,
+// which, if the road doesn't have very many segments, may end up
+// drawing one label almost entirely off-screen.  :-(
+
+// If we could check the first line segment to see if the label
+// would be drawn off-screen, perhaps we could start drawing at
+// segment #2?  We'd have to check whether there is a segment #2.
+// Another possibility would be to shift the label on-screen.  Would
+// this work for twisty/turny roads though?  I suppose, 'cuz they'd
+// end up with more line segments and we could just draw at segment
+// #2 in that case instead of shifting.
+
+                            if      (scale_y == 1)
+                                mod_number = 1;
+                            else if (scale_y <= 2)
+                                mod_number = 1;
+                            else if (scale_y <= 4)
+                                mod_number = 2;
+                            else if (scale_y <= 8)
+                                mod_number = 4;
+                            else if (scale_y <= 16)
+                                mod_number = 8;
+                            else if (scale_y <= 32)
+                                mod_number = 16;
+                            else
+                                mod_number = (int)(scale_y);
+
+                            // Check whether we've written out this string
+                            // already:  Look for a match in our linked list
+
+// The problem with this method is that we might get strings
+// "written" at the extreme top or right edge of the display, which
+// means the strings wouldn't be visible, but Xastir thinks that it
+// wrote the string out visibly.  To partially counteract this I've
+// set it up to write only some of the identical strings.  This
+// still doesn't help in the cases where a street only comes in from
+// the top or right and doesn't have an intersection with another
+// street (and therefore another label) within the view.
+
+                            // Hash index is just the first
+                            // character.  Tried using lower 6 bits
+                            // of first two chars and lower 7 bits
+                            // of first two chars but the result was
+                            // slower than just using the first
+                            // character.
+                            hash_index = (uint8_t)(temp[0]);
+
+                            ptr2 = label_hash[hash_index];
+                            while (ptr2 != NULL) {   // Step through the list
+                                // Check 2nd character (fast!)
+                                if ( (uint8_t)(ptr2->label[1]) == (uint8_t)(temp[1]) ) {
+                                    if (strcasecmp(ptr2->label,temp) == 0) {    // Found a match
+                                        //fprintf(stderr,"Found a match!\t%s\n",temp);
+                                        new_label = 0;
+                                        ptr2->found = ptr2->found + 1;  // Increment the "found" quantity
+
+// We change this "mod" number based on zoom level, so that long
+// strings don't overwrite each other, and so that we don't get too
+// many or too few labels drawn.  This will cause us to skip
+// intersections (the tiger files appear to have a label at each
+// intersection).  Between rural and urban areas, this method might
+// not work well.  Urban areas have few intersections, so we'll get
+// fewer labels drawn.
+// A better method might be to check the screen location for each
+// one and only write the strings if they are far enough apart, and
+// only count a string as written if the start of it is onscreen and
+// the angle is correct for it to be written on the screen.
+
+                                        // Draw a number of labels
+                                        // appropriate for the zoom
+                                        // level.
+// Labeling: Skip label logic
+                                        if ( ((ptr2->found - 1) % mod_number) != 0) {
+                                            skip_label++;
+                                        }
+                                        ptr2 = NULL; // End the loop
+                                    }
+                                    else {
+                                        ptr2 = ptr2->next;
+                                    }
+                                }
+                                else {
+                                    ptr2 = ptr2->next;
+                                }
+                            }
+
+                            if (!skip_label) {  // Draw the string
+
+                                // Compute the label rotation angle
+                                float diff_X = (int)x1 - x0;
+                                float diff_Y = (int)y1 - y0;
+                                float angle = 0.0;  // Angle for the beginning of this polyline
+                        
+                                if (diff_X == 0.0) {  // Avoid divide by zero errors
+                                    diff_X = 0.0000001;
+                                }
+                                angle = atan( diff_X / diff_Y );    // Compute in radians
+                                // Convert to degrees
+                                angle = angle / (2.0 * M_PI );
+                                angle = angle * 360.0;
+
+                                // Change to fit our rotate label function's idea of angle
+                                angle = 360.0 - angle;
+
+                                //fprintf(stderr,"Y: %f\tX: %f\tAngle: %f ==> ",diff_Y,diff_X,angle);
+
+                                if ( angle > 90.0 ) {angle += 180.0;}
+                                if ( angle >= 360.0 ) {angle -= 360.0;}
+
+                                //fprintf(stderr,"%f\t%s\n",angle,temp);
+
+// Labeling of polylines done here
+
+//                              (void)draw_label_text ( w, x, y, strlen(temp), colors[label_color], (char *)temp);
+                                if (gps_flag) {
+                                    (void)draw_rotated_label_text (w,
+                                        //(int)angle,
+                                        -90,    // Horizontal, easiest to read
+                                        x,
+                                        y,
+                                        strlen(temp),
+                                        colors[gps_color],
+                                        (char *)temp,
+                                        font_size);
+                                }
+                                else {
+                                    (void)draw_rotated_label_text(w,
+                                        (int)angle,
+                                        x,
+                                        y,
+                                        strlen(temp),
+                                        colors[label_color],
+                                        (char *)temp,
+                                        font_size);
+                                }
+                            }
+
+                            if (new_label) {
+
+                                // Create a new record for this string
+                                // and add it to the head of the list.
+                                // Make sure to "free" this linked
+                                // list.
+                                //fprintf(stderr,"Creating a new record: %s\n",temp);
+                                ptr2 = (label_string *)malloc(sizeof(label_string));
+                                CHECKMALLOC(ptr2);
+
+                                xastir_snprintf(ptr2->label,sizeof(ptr2->label),"%s",temp);
+                                ptr2->found = 1;
+
+                                // We use first character of string
+                                // as our hash index.
+                                hash_index = temp[0];
+
+                                ptr2->next = label_hash[hash_index];
+                                label_hash[hash_index] = ptr2;
+                                //if (label_hash[hash_index]->next == NULL)
+                                //    fprintf(stderr,"only one record\n");
+                            }
+                        }
+                    }
+                    break;
+
+
+
+                case SHPT_POLYGON:
+                case SHPT_POLYGONZ:
+
+                    if (debug_level & 16)
+                        fprintf(stderr,"Found Polygons\n");
+
+#ifdef WITH_DBFAWK
+                    // User requested filled polygons with stippling.
+                    // Set the stipple now.  need to do here, because if
+                    // done earlier the labels get stippled, too.
+                    (void)XSetFillStyle(XtDisplay(w), gc, fill_style);
+
+                    if (draw_filled != 0 && fill_style == FillStippled) {
+ 
+                
+                        switch (fill_stipple) {
+                        case 0:
+                            (void)XSetStipple(XtDisplay(w), gc, 
+                                              pixmap_13pct_stipple);
+                            break;
+                        case 1:
+                            (void)XSetStipple(XtDisplay(w), gc, 
+                                              pixmap_25pct_stipple);
+                            break;
+                        default:
+                            (void)XSetStipple(XtDisplay(w), gc, 
+                                              pixmap_25pct_stipple);
+                            break;
+                        }
+                    }
+#endif  // WITH_DBFAWK
+
+                    // Each polygon can be made up of multiple
+                    // rings, and each ring has multiple points that
+                    // define it.  We hit this case once for each
+                    // polygon shape in the file, iff at least part
+                    // of that shape is within our viewport.
+
+// We now handle the "hole" drawing in polygon shapefiles, where
+// clockwise direction around the ring means a fill, and CCW means a
+// hole in the polygon.
+//
+// Possible implementations:
+//
+// 1) Snag an algorithm for a polygon "fill" function from
+// somewhere, but add a piece that will check for being inside a
+// "hole" polygon and just not draw while traversing it (change the
+// pen color to transparent over the holes?).
+// SUMMARY: How to do this?
+//
+// 2) Draw to another layer, then copy only the filled pixels to
+// their final destination pixmap.
+// SUMMARY: Draw polygons once, then a copy operation.
+//
+// 3) Separate area:  Draw polygon.  Copy from other map layer into
+// holes, then copy the result back.
+// SUMMARY:  How to determine outline?
+//
+// 4) Use clip-masks to prevent drawing over the hole areas:  Draw
+// to another 1-bit pixmap or region.  This area can be the size of
+// the max shape extents.  Filled = 1.  Holes = 0.  Use that pixmap
+// as a clip-mask to draw the polygons again onto the final pixmap.
+// SUMMARY: We end up drawing the shape twice!
+//
+// MODIFICATION:  Draw a filled rectangle onto the map pixmap using
+// the clip-mask to control where it actually gets drawn.
+// SUMMARY: Only end up drawing the shape once.
+//
+// 5) Inverted clip-mask:  Draw just the holes to a separate pixmap:
+// Create a pixmap filled with 1's (XFillRectangle & GXset).  Draw
+// the holes and use GXinvert to draw zero's to the mask where the
+// holes go.  Use this as a clip-mask to draw the filled areas of
+// the polygon to the map pixmap.
+// SUMMARY: Faster than methods 1-4?
+//
+// 6) Use Regions to do the same method as #5 but with more ease.
+// Create a polygon Region, then create a Region for each hole and
+// subtract the hole from the polygon Region.  Once we have a
+// complete polygon + holes, use that as the clip-mask for drawing
+// the real polygon.  Use XSetRegion() on the GC to set this up.  We
+// might have to do offsets as well so that the region maps properly
+// to our map pixmap when we draw the final polygon to it.
+// SUMMARY:  Should be faster than methods 1-5.
+//
+// 7) Do method 6 but instead of drawing a polygon region, draw a
+// rectangle region first, then knock holes in it.  Use that region
+// as the clip-mask for the XFillPolygon() later by calling
+// XSetRegion() on the GC.  We don't really need a polygon region
+// for a clip-mask.  A rectangle with holes in it will work just as
+// well and should be faster overall.  We might have to do offsets
+// as well so that the region maps properly to our map pixmap when
+// we draw the final polygon to it.
+// SUMMARY:  This might be the fastest method of the ones listed, if
+// drawing a rectangle region is faster than drawing a polygon
+// region.  We draw the polygon once here instead of twice, and each
+// hole only once.  The only added drawing time would be the
+// creation of the rectangle region, which should be fairly fast,
+// and the subtracting of the hole regions from it.
+//
+//
+// Shapefiles also allow identical points to be next to each other
+// in the vertice list.  We should look for that and get rid of
+// duplicate vertices.
+
+
+//if (object->nParts > 1)
+//fprintf(stderr,"Number of parts: %d\n", object->nParts);
+
+
+// Unfortunately, for Polygon shapes we must make one pass through
+// the entire set of rings to see if we have any "hole" rings (as
+// opposed to "fill" rings).  If we have any "hole" rings, we must
+// handle the drawing of the Shape quite differently.
+//
+// Read the vertices for each ring in the Shape.  Test whether we
+// have a hole ring.  If so, save the ring index away for the next
+// step when we actually draw the shape.
+
+                    polygon_hole_flag = 0;
+
+                    // Allocate storage for a flag for each ring in
+                    // this Shape.
+                    // !!Remember to free this storage later!!
+                    polygon_hole_storage = (int *)malloc(object->nParts*sizeof(int));
+                    CHECKMALLOC(polygon_hole_storage);
+
+// Run through the entire shape (all rings of it) once.  Create an
+// array of flags that specify whether each ring is a fill or a
+// hole.  If any holes found, set the global polygon_hole_flag as
+// well.
+
+                    for (ring = 0; ring < object->nParts; ring++ ) {
+
+                        // Testing for fill or hole ring.  This will
+                        // determine how we ultimately draw the
+                        // entire shape.
+                        //
+                        switch ( shape_ring_direction( object, ring) ) {
+                            case  0:    // Error in trying to compute whether fill or hole
+                                fprintf(stderr,"Error in computing fill/hole ring\n");
+                            case  1:    // It's a fill ring
+                                // Do nothing for these two cases
+                                // except clear the flag in our
+                                // storage
+                                polygon_hole_storage[ring] = 0;
+                                break;
+                            case -1:    // It's a hole ring
+                                // Add it to our list of hole rings
+                                // here and set a flag.  That way we
+                                // won't have to run through
+                                // SHPRingDir_2d again in the next
+                                // loop.
+                                polygon_hole_flag++;
+                                polygon_hole_storage[ring] = 1;
+//                                fprintf(stderr, "Ring %d/%d is a polygon hole\n",
+//                                    ring,
+//                                    object->nParts);
+                                break;
+                        }
+                    }
+// We're done with the initial run through the vertices of all
+// rings.  We now know which rings are fills and which are holes and
+// have recorded the data.
+
+// Speedup:  Only loop through the vertices once, by determining
+// hole/fill polygons as we go.
+
+
+//WE7U3
+                    // Speedup:  If not draw_filled, then don't go
+                    // through the math and region code.  Set the
+                    // flag to zero so that we won't do all the math
+                    // and the regions.
+                    if (!map_color_fill || !draw_filled)
+                        polygon_hole_flag = 0;
+
+                    if (polygon_hole_flag) {
+                        XRectangle rectangle;
+                        long width, height;
+                        double top_ll, left_ll, bottom_ll, right_ll;
+                        int temp_ok;
+
+
+//                        fprintf(stderr, "%s:Found %d hole rings in shape %d\n",
+//                            file,
+//                            polygon_hole_flag,
+//                            structure);
+
+//WE7U3
+////////////////////////////////////////////////////////////////////////
+
+// Now that we know which are fill/hole rings, worry about drawing
+// each ring of the Shape:
+//
+// 1) Create a filled rectangle region, probably the size of the
+// Shape extents, and at the same screen coordinates as the entire
+// shape would normally be drawn.
+//
+// 2) Create a region for each hole ring and subtract these new
+// regions one at a time from the rectangle region created above.
+//
+// 3) When the "swiss-cheese" rectangle region is complete, draw
+// only the filled polygons onto the map pixmap using the
+// swiss-cheese rectangle region as the clip-mask.  Use a temporary
+// GC for this operation, as I can't find a way to remove a
+// clip-mask from a GC.  We may have to use offsets to make this
+// work properly.
+
+
+                        // Create three regions and rotate between
+                        // them, due to the XSubtractRegion()
+                        // needing three parameters.  If we later
+                        // find that two of the parameters can be
+                        // repeated, we can simplify our code.
+                        // We'll rotate through them mod 3.
+
+                        temp_region1 = 0;
+
+                        // Create empty region
+                        region[temp_region1] = XCreateRegion();
+
+                        // Draw a rectangular clip-mask inside the
+                        // Region.  Use the same extents as the full
+                        // Shape.
+
+                        // Set up the real sizes from the Shape
+                        // extents.
+                        top_ll    = object->dfYMax;
+                        left_ll   = object->dfXMin;
+                        bottom_ll = object->dfYMin;
+                        right_ll  = object->dfXMax;
+
+                        // Convert point to Xastir coordinates:
+                        temp_ok = convert_to_xastir_coordinates(&my_long,
+                            &my_lat,
+                            left_ll,
+                            top_ll);
+                        //fprintf(stderr,"%ld %ld\n", my_long, my_lat);
+
+                        if (!temp_ok) {
+                            fprintf(stderr,"draw_shapefile_map4: Problem converting from lat/lon\n");
+                            ok = 0;
+                            x = 0;
+                            y = 0;
+                        }
+                        else {
+                            // Convert to screen coordinates.  Careful
+                            // here!  The format conversions you'll need
+                            // if you try to compress this into two
+                            // lines will get you into trouble.
+                            x = my_long - NW_corner_longitude;
+                            y = my_lat - NW_corner_latitude;
+                            x = x / scale_x;
+                            y = y / scale_y;
+
+
+                            // Here we check for really wacko points that will cause problems
+                            // with the X drawing routines, and fix them.
+                            if (x > 1700l) x = 1700l;
+                            if (x <    0l) x =    0l;
+                            if (y > 1700l) y = 1700l;
+                            if (y <    0l) y =    0l;
+                        }
+
+                        // Convert points to Xastir coordinates
+                        temp_ok = convert_to_xastir_coordinates(&my_long,
+                            &my_lat,
+                            right_ll,
+                            bottom_ll);
+                         //fprintf(stderr,"%ld %ld\n", my_long, my_lat);
+
+                        if (!temp_ok) {
+                            fprintf(stderr,"draw_shapefile_map5: Problem converting from lat/lon\n");
+                            ok = 0;
+                            width = 0;
+                            height = 0;
+                        }
+                        else {
+                            // Convert to screen coordinates.  Careful
+                            // here!  The format conversions you'll need
+                            // if you try to compress this into two
+                            // lines will get you into trouble.
+                            width = my_long - NW_corner_longitude;
+                            height = my_lat - NW_corner_latitude;
+                            width = width / scale_x;
+                            height = height / scale_y;
+
+                            // Here we check for really wacko points that will cause problems
+                            // with the X drawing routines, and fix them.
+                            if (width  > 1700l) width  = 1700l;
+                            if (width  <    1l) width  =    1l;
+                            if (height > 1700l) height = 1700l;
+                            if (height <    1l) height =    1l;
+                        }
+
+//TODO
+// We can run into trouble here because we only have 16-bit values
+// to work with.  If we're zoomed in and the Shape is large in
+// comparison to the screen, we'll easily exceed these numbers.
+// Perhaps we'll need to work with something other than screen
+// coordinates?  Perhaps truncating the values will be adequate.
+
+                        rectangle.x      = (short) x;
+                        rectangle.y      = (short) y;
+                        rectangle.width  = (unsigned short) width;
+                        rectangle.height = (unsigned short) height;
+
+//fprintf(stderr,"*** Rectangle: %d,%d %dx%d\n", rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+
+                        // Create the initial region containing a
+                        // filled rectangle.
+                        XUnionRectWithRegion(&rectangle,
+                            region[temp_region1],
+                            region[temp_region1]);
+ 
+                        // Create a region for each set of hole
+                        // vertices (CCW rotation of the vertices)
+                        // and subtract each from the rectangle
+                        // region.
+                        for (ring = 0; ring < object->nParts; ring++ ) {
+                            int endpoint;
+                            int on_screen;
+ 
+
+                            if (polygon_hole_storage[ring] == 1) {
+                                // It's a hole polygon.  Cut the
+                                // hole out of our rectangle region.
+                                int num_vertices = 0;
+                                int nVertStart;
+
+ 
+                                nVertStart = object->panPartStart[ring];
+
+                                if( ring == object->nParts-1 )
+                                    num_vertices = object->nVertices
+                                                 - object->panPartStart[ring];
+                                else
+                                    num_vertices = object->panPartStart[ring+1] 
+                                                 - object->panPartStart[ring];
+
+//TODO
+// Snag the vertices and put them into the "points" array,
+// converting to screen coordinates as we go, then subtracting the
+// starting point, so that the regions remain small?
+//
+// We could either subtract the starting point of each shape from
+// each point, or take the hit on region size and just use the full
+// screen size (or whatever part of it the shape required plus the
+// area from the starting point to 0,0).
+
+
+                                if ( (ring+1) < object->nParts)
+                                    endpoint = object->panPartStart[ring+1];
+                                    //else endpoint = object->nVertices;
+                                else
+                                    endpoint = object->panPartStart[0] + object->nVertices;
+                                //fprintf(stderr,"Endpoint %d\n", endpoint);
+                                //fprintf(stderr,"Vertices: %d\n", endpoint - object->panPartStart[ring]);
+
+                                i = 0;  // i = Number of points to draw for one ring
+                                on_screen = 0;
+
+                                // index = ptr into the shapefile's array of points
+                                for (index = object->panPartStart[ring]; index < endpoint; ) {
+                                    int temp_ok;
+       
+ 
+                                    // Get vertice and convert to Xastir coordinates
+                                    temp_ok = convert_to_xastir_coordinates(&my_long,
+                                        &my_lat,
+                                        (float)object->padfX[index],
+                                        (float)object->padfY[index]);
+
+                                    //fprintf(stderr,"%lu %lu\t", my_long, my_lat);
+
+                                    if (!temp_ok) {
+                                        fprintf(stderr,"draw_shapefile_map6: Problem converting from lat/lon\n");
+                                        ok = 0;
+                                        x = 0;
+                                        y = 0;
+                                    }
+                                    else {
+                                        // Convert to screen coordinates.  Careful
+                                        // here!  The format conversions you'll need
+                                        // if you try to compress this into two
+                                        // lines will get you into trouble.
+                                        x = my_long - NW_corner_longitude;
+                                        y = my_lat - NW_corner_latitude;
+                                        x = x / scale_x;
+                                        y = y / scale_y;
+
+        
+                                        //fprintf(stderr,"%ld %ld\t\t", x, y);
+
+                                        // Here we check for really
+                                        // wacko points that will
+                                        // cause problems with the X
+                                        // drawing routines, and fix
+                                        // them.  Increment
+                                        // on_screen if any of the
+                                        // points might be on
+                                        // screen.
+                                        if (x >  1700l)
+                                            x =  1700l;
+                                        else if (x < 0l)
+                                            x = 0l;
+                                        else on_screen++;
+
+                                        if (y >  1700l)
+                                            y =  1700l;
+                                        else if (y < 0l)
+                                            y = 0l;
+                                        else on_screen++;
+
+                                        points[i].x = l16(x);
+                                        points[i].y = l16(y);
+
+if (on_screen) {
+//    fprintf(stderr,"%d x:%d y:%d\n",
+//        i,
+//        points[i].x,
+//        points[i].y);
+}
+                                        i++;
+                                    }
+                                    index++;
+
+                                    if (index > high_water_mark_index)
+                                        high_water_mark_index = index;
+
+                                    if (index > endpoint) {
+                                        index = endpoint;
+                                        fprintf(stderr,"Trying to run past the end of shapefile array: index=%d\n",index);
+                                    }
+                                }   // End of converting vertices for a ring
+
+
+                                // Create and subtract the region
+                                // only if it might be on screen.
+                                if (on_screen) {
+                                    temp_region2 = (temp_region1 + 1) % 3;
+                                    temp_region3 = (temp_region1 + 2) % 3;
+
+                                    // Create empty regions.
+                                    region[temp_region2] = XCreateRegion();
+                                    region[temp_region3] = XCreateRegion();
+
+                                    // Draw the hole polygon
+                                    if (num_vertices >= 3) {
+                                        XDestroyRegion(region[temp_region2]); // Release the old
+                                        region[temp_region2] = XPolygonRegion(points,
+                                            num_vertices,
+                                            WindingRule);
+                                    }
+                                    else {
+                                        fprintf(stderr,
+                                            "draw_shapefile_map:XPolygonRegion with too few vertices:%d\n",
+                                            num_vertices);
+                                    }
+
+                                    // Subtract region2 from region1 and
+                                    // put the result into region3.
+//fprintf(stderr, "Subtracting region\n");
+                                    XSubtractRegion(region[temp_region1],
+                                        region[temp_region2],
+                                        region[temp_region3]);
+
+                                    // Get rid of the two regions we no
+                                    // longer need
+                                    XDestroyRegion(region[temp_region1]);
+                                    XDestroyRegion(region[temp_region2]);
+
+                                    // Indicate the final result region for
+                                    // the next iteration or the exit of the
+                                    // loop.
+                                    temp_region1 = temp_region3;
+                                }
+                            }
+                        }
+
+                        // region[temp_region1] now contains a
+                        // clip-mask of the original polygon with
+                        // holes cut out of it (swiss-cheese
+                        // rectangle).
+
+                        // Create temporary GC.  It looks like we
+                        // don't need this to create the regions,
+                        // but we'll need it when we draw the filled
+                        // polygons onto the map pixmap using the
+                        // final region as a clip-mask.
+
+// Offsets?
+// XOffsetRegion
+
+//                        gc_temp_values.function = GXcopy;
+                        gc_temp = XCreateGC(XtDisplay(w),
+                            XtWindow(w),
+                            0,
+                            &gc_temp_values);
+                        // now copy the fill style and stipple from gc.
+                        XCopyGC(XtDisplay(w),
+                                gc, 
+                                (GCFillStyle|GCStipple),
+                                gc_temp);
+
+                        // Set the clip-mask into the GC.  This GC
+                        // is now ruined for other purposes, so
+                        // destroy it when we're done drawing this
+                        // one shape.
+                        XSetRegion(XtDisplay(w), gc_temp, region[temp_region1]);
+                        XDestroyRegion(region[temp_region1]);
+                    }
+//WE7U3
+////////////////////////////////////////////////////////////////////////
+
+
+                    // Read the vertices for each ring in this Shape
+                    for (ring = 0; ring < object->nParts; ring++ ) {
+                        int endpoint;
+#ifndef WITH_DBFAWK
+                        int glacier_flag = 0;
+                        const char *temp;
+
+                        if (lake_flag || river_flag) {
+                            if ( mapshots_labels_flag && (fieldcount >= 3) ) {
+                                temp = DBFReadStringAttribute( hDBF, structure, 2 );    // CFCC Field
+                                switch (temp[1]) {
+                                    case '8':   // Special water feature
+                                        switch(temp[2]) {
+                                            case '1':
+                                                glacier_flag++;  // Found a glacier
+                                                break;
+                                            default:
+                                                break;
+                                        }
+                                        break;
+                                    default:
+                                        break;
+                                }
+                            }
+                        }
+#endif /* !WITH_DBFAWK */
+                        //fprintf(stderr,"Ring: %d\t\t", ring);
+
+                        if ( (ring+1) < object->nParts)
+                            endpoint = object->panPartStart[ring+1];
+                            //else endpoint = object->nVertices;
+                        else
+                            endpoint = object->panPartStart[0] + object->nVertices;
+
+                        //fprintf(stderr,"Endpoint %d\n", endpoint);
+                        //fprintf(stderr,"Vertices: %d\n", endpoint - object->panPartStart[ring]);
+
+                        i = 0;  // i = Number of points to draw for one ring
+                        // index = ptr into the shapefile's array of points
+                        for (index = object->panPartStart[ring]; index < endpoint; ) {
+                            int temp_ok;
+
+                            ok = 1;
+
+                            //fprintf(stderr,"\t%d:%g %g\t", index, object->padfX[index], object->padfY[index] );
+
+                            // Get vertice and convert to Xastir coordinates
+                            temp_ok = convert_to_xastir_coordinates(&my_long,
+                                &my_lat,
+                                (float)object->padfX[index],
+                                (float)object->padfY[index]);
+
+                            //fprintf(stderr,"%lu %lu\t", my_long, my_lat);
+
+                            if (!temp_ok) {
+                                fprintf(stderr,"draw_shapefile_map7: Problem converting from lat/lon\n");
+                                ok = 0;
+                                x = 0;
+                                y = 0;
+                                index++;
+                            }
+                            else {
+                                // Convert to screen coordinates.  Careful
+                                // here!  The format conversions you'll need
+                                // if you try to compress this into two
+                                // lines will get you into trouble.
+                                x = my_long - NW_corner_longitude;
+                                y = my_lat - NW_corner_latitude;
+                                x = x / scale_x;
+                                y = y / scale_y;
+
+
+                                //fprintf(stderr,"%ld %ld\t\t", x, y);
+
+                                // Here we check for really wacko points that will cause problems
+                                // with the X drawing routines, and fix them.
+                                points[i].x = l16(x);
+                                points[i].y = l16(y);
+                                i++;    // Number of points to draw
+
+                                if (i > high_water_mark_i)
+                                    high_water_mark_i = i;
+
+
+                                if (i >= MAX_MAP_POINTS) {
+                                    i = MAX_MAP_POINTS - 1;
+                                    fprintf(stderr,"Trying to run past the end of our internal points array: i=%d\n",i);
+                                }
+
+                                //fprintf(stderr,"%d %d\t", points[i].x, points[i].y);
+
+                                index++;
+
+                                if (index > high_water_mark_index)
+                                    high_water_mark_index = index;
+
+                                if (index > endpoint) {
+                                    index = endpoint;
+                                    fprintf(stderr,"Trying to run past the end of shapefile array: index=%d\n",index);
+                                }
+                            }
+                        }
+
+                        if ( (i >= 3)
+                                && (ok_to_draw && !skip_it)
+                                && ( !draw_filled || !map_color_fill || (draw_filled && polygon_hole_storage[ring] == 0) ) ) {
+                            // We have a polygon to draw!
+//WE7U3
+                            if ((!draw_filled || !map_color_fill) && polygon_hole_storage[ring] == 1) {
+                                // We have a hole drawn as unfilled.
+                                // Draw as a black dashed line.
+#ifdef WITH_DBFAWK
+                                (void)XSetForeground(XtDisplay(w), gc, colors[color]);
+#else   // WITH_DBFAWK
+                                (void)XSetForeground(XtDisplay(w), gc, colors[0x08]); // black for border
+#endif  // WITH_DBFAWK
+                                (void)XSetLineAttributes (XtDisplay (w),
+                                    gc,
+                                    0,
+                                    LineOnOffDash,
+                                    CapButt,
+                                    JoinMiter);
+                                (void)XDrawLines(XtDisplay(w),
+                                    pixmap,
+                                    gc,
+                                    points,
+                                    l16(i),
+                                    CoordModeOrigin);
+                                (void)XSetLineAttributes (XtDisplay (w),
+                                    gc,
+                                    0,
+                                    LineSolid,
+                                    CapButt,
+                                    JoinMiter);
+                            }
+                            else if (quad_overlay_flag) {
+                                (void)XDrawLines(XtDisplay(w),
+                                    pixmap,
+                                    gc,
+                                    points,
+                                    l16(i),
+                                    CoordModeOrigin);
+                            }
+                            /* old glacier, lake and river code was identical
+                               with the exception of what color to use! */
+#ifdef WITH_DBFAWK
+                            else if (!weather_alert_flag) {
+                                /* color is already set by dbfawk(?) */
+                                /* And so are lanes and pattern.  Let's
+                                   use what was specified. */
+                                (void)XSetLineAttributes(XtDisplay(w),
+                                                         gc,
+                                                         (lanes)?lanes:1,
+                                                         pattern,
+                                                         CapButt,
+                                                         JoinMiter);
+#else /* !WITH_DBFAWK */
+                            else if (glacier_flag||lake_flag||river_flag) {
+                                int color = (glacier_flag)?0x0f:
+                                    (lake_flag||river_flag)?0x1a:8;
+#endif /* !WITH_DBFAWK */
+                                (void)XSetForeground(XtDisplay(w), gc, colors[color]);
+                                if (map_color_fill && draw_filled) {
+                                    if (polygon_hole_flag) {
+#ifdef WITH_DBFAWK
+                                        (void)XSetForeground(XtDisplay(w), gc_temp, colors[fill_color]);
+#else   // WITH_DBFAWK
+                                        (void)XSetForeground(XtDisplay(w), gc_temp, colors[color]);
+#endif  // WITH_DBFAWK
+                                        if (i >= 3) {
+                                            (void)XFillPolygon(XtDisplay(w),
+                                                pixmap,
+                                                gc_temp,
+                                                points,
+                                                i,
+                                                Nonconvex,
+                                                CoordModeOrigin);
+                                        }
+                                        else {
+                                            fprintf(stderr,
+                                                "draw_shapefile_map:Too few points:%d, Skipping XFillPolygon()",
+                                                npoints);
+                                        }
+                                    }
+                                    else { /* no holes in this polygon */
+                                        if (i >= 3) {
+                                            /* draw the filled polygon */
+#ifdef WITH_DBFAWK
+                                            (void)XSetForeground(XtDisplay(w), gc, colors[fill_color]);
+#endif  // WITH_DBFAWK
+                                            (void)XFillPolygon(XtDisplay(w),
+                                                pixmap,
+                                                gc,
+                                                points,
+                                                i,
+                                                Nonconvex,
+                                                CoordModeOrigin);
+                                        }
+                                        else {
+                                            fprintf(stderr,
+                                                "draw_shapefile_map:Too few points:%d, Skipping XFillPolygon()",
+                                                npoints);
+                                        }
+                                    }
+                                }
+                                /* draw the polygon border */
+                                (void)XSetForeground(XtDisplay(w), gc, colors[color]);
+                                (void)XSetFillStyle(XtDisplay(w), gc, FillSolid);
+                                (void)XDrawLines(XtDisplay(w),
+                                    pixmap,
+                                    gc,
+                                    points,
+                                    l16(i),
+                                    CoordModeOrigin);
+                            }
+                            else if (weather_alert_flag) {
+                                (void)XSetFillStyle(XtDisplay(w), gc_tint, FillStippled);
+// We skip the hole/fill thing for these?
+
+                                if (i >= 3) {
+                                    (void)XFillPolygon(XtDisplay(w),
+                                        pixmap_alerts,
+                                        gc_tint,
+                                        points,
+                                        i,
+                                        Nonconvex,
+                                        CoordModeOrigin);
+                                }
+                                else {
+                                    fprintf(stderr,
+                                        "draw_shapefile_map:Too few points:%d, Skipping XFillPolygon()",
+                                        npoints);
+                                }
+
+                                (void)XSetFillStyle(XtDisplay(w), gc_tint, FillSolid);
+                                (void)XDrawLines(XtDisplay(w),
+                                    pixmap_alerts,
+                                    gc_tint,
+                                    points,
+                                    l16(i),
+                                    CoordModeOrigin);
+                            }
+                            else if (map_color_fill && draw_filled) {  // Land masses?
+                                if (polygon_hole_flag) {
+#ifndef WITH_DBFAWK
+                                    /* city_flag not needed WITH_DBFAWK */
+                                    if (city_flag)
+                                        (void)XSetForeground(XtDisplay(w), gc_temp, GetPixelByName(w,"RosyBrown"));  // RosyBrown, duh
+                                    else
+                                        (void)XSetForeground(XtDisplay(w), gc_temp, colors[0xff]); // grey
+#else   // WITH_DBFAWK
+                                    (void)XSetForeground(XtDisplay(w), gc_temp, colors[fill_color]);
+#endif /* WITH_DBFAWK */
+                                    if (i >= 3) {
+                                        (void)XFillPolygon(XtDisplay(w),
+                                            pixmap,
+                                            gc_temp,
+                                            points,
+                                            i,
+                                            Nonconvex,
+                                            CoordModeOrigin);
+                                    }
+                                    else {
+                                        fprintf(stderr,
+                                            "draw_shapefile_map:Too few points:%d, Skipping XFillPolygon()",
+                                            npoints);
+                                    }
+                                }
+                                else { /* no polygon hole */
+#ifndef WITH_DBFAWK
+                                    if (city_flag)
+                                        (void)XSetForeground(XtDisplay(w), gc, GetPixelByName(w,"RosyBrown"));  // RosyBrown, duh
+                                    else
+                                        (void)XSetForeground(XtDisplay(w), gc, colors[0xff]); // grey
+#else   // WITH_DBFAWK
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[fill_color]);
+#endif /* !WITH_DFBAWK */
+                                    if (i >= 3) {
+                                        (void)XFillPolygon(XtDisplay (w),
+                                            pixmap,
+                                            gc,
+                                            points,
+                                            i,
+                                            Nonconvex,
+                                            CoordModeOrigin);
+                                    }
+                                    else {
+                                        fprintf(stderr,
+                                            "draw_shapefile_map:Too few points:%d, Skipping XFillPolygon()",
+                                            npoints);
+                                    }
+                                }
+
+#ifdef WITH_DBFAWK
+                                (void)XSetForeground(XtDisplay(w), gc, colors[color]); // border color
+#endif  // WITH_DBFAWK
+
+                                // Draw a thicker border for city boundaries
+#ifndef WITH_DBFAWK
+                                if (city_flag) {
+                                    if (scale_y <= 64) {
+                                        (void)XSetLineAttributes(XtDisplay(w), gc, 2, LineSolid, CapButt,JoinMiter);
+                                    }
+                                    else if (scale_y <= 128) {
+                                        (void)XSetLineAttributes(XtDisplay(w), gc, 1, LineSolid, CapButt,JoinMiter);
+                                    }
+                                    else {
+                                        (void)XSetLineAttributes(XtDisplay(w), gc, 0, LineSolid, CapButt,JoinMiter);
+                                    }
+
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[0x14]); // lightgray for border
+                                }
+                                else {
+                                    (void)XSetForeground(XtDisplay(w), gc, colors[0x08]); // black for border
+                                }
+#else   // WITH_DBFAWK
+                                (void)XSetForeground(XtDisplay(w), gc, colors[color]); // border
+                                (void)XSetFillStyle(XtDisplay(w), gc, FillSolid);
+#endif /* WITH_DBFAWK */
+
+                                (void)XDrawLines(XtDisplay(w),
+                                    pixmap,
+                                    gc,
+                                    points,
+                                    l16(i),
+                                    CoordModeOrigin);
+                            }
+                            else {  // Use whatever color is defined by this point.
+                                (void)XSetLineAttributes(XtDisplay(w), gc, 0, LineSolid, CapButt,JoinMiter);
+                                (void)XSetFillStyle(XtDisplay(w), gc, FillSolid);
+                                (void)XDrawLines(XtDisplay(w),
+                                    pixmap,
+                                    gc,
+                                    points,
+                                    l16(i),
+                                    CoordModeOrigin);
+                            }
+                        }
+                    }
+                    // Free the storage that we allocated to hold
+                    // the "hole" flags for the shape.
+                    free(polygon_hole_storage);
+
+                    if (polygon_hole_flag) {
+                        //Free the temporary GC that we may have used to
+                        //draw polygons using the clip-mask:
+                        XFreeGC(XtDisplay(w), gc_temp);
+                    }
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Done with drawing shapes, now draw labels
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef WITH_DBFAWK
+                    temp = name;
+                    // Set fill style back to defaults, or labels will get
+                    // stippled along with polygons!
+                    XSetFillStyle(XtDisplay(w), gc, FillSolid);
+
+#else /* !WITH_DBFAWK */
+                    /* labels come from dbfawk, not here... */
+
+                    temp = "";
+                    if (lake_flag) {
+                        if (map_color_levels && scale_y > 128)
+                            skip_label++;
+                        if (mapshots_labels_flag && (fieldcount >= 4) )
+                            temp = DBFReadStringAttribute( hDBF, structure, 3 );
+                        else if (fieldcount >= 1)
+                            temp = DBFReadStringAttribute( hDBF, structure, 0 );    // NAME (lakes)
+                        else
+                            temp = NULL;
+                    }
+                    else if (city_flag) {
+                        if (map_color_levels && scale_y > 512)
+                            skip_label++;
+                        if (mapshots_labels_flag && (fieldcount >= 4) )
+                            temp = DBFReadStringAttribute( hDBF, structure, 3 );    // NAME (designated places)
+                        else
+                            temp = NULL;
+                    }
+#endif /* !WITH_DBFAWK */
+                    /* XXX - figure out how to set this from dbfawk: */
+                    if (quad_overlay_flag) {
+                        if (fieldcount >= 5) {
+                            // Use just the last two characters of
+                            // the quad index.  "44072-A3" converts
+                            // to "A3"
+                            temp = DBFReadStringAttribute( hDBF, structure, 4 );
+                            xastir_snprintf(quad_label,
+                                sizeof(quad_label),
+                                "%s ",
+                                &temp[strlen(temp) - 2]);
+
+                            // Append the name of the quad
+                            temp = DBFReadStringAttribute( hDBF, structure, 0 );
+                            strncat(quad_label,
+                                temp,
+                                sizeof(quad_label) - 1 - strlen(quad_label));
+                        }
+                        else {
+                            quad_label[0] = '\0';
+                        }
+                    }
+
+                    if ( (temp != NULL)
+                            && (strlen(temp) != 0)
+                            && map_labels
+                            && !skip_label ) {
+                        int temp_ok;
+
+                        if (debug_level & 16) {
+                            fprintf(stderr,"I think I should display labels\n");
+                        }
+                        ok = 1;
+
+                        // Convert to Xastir coordinates:
+                        // If quad overlay shapefile, need to
+                        // snag the label coordinates from the DBF
+                        // file instead.  Note that the coordinates
+                        // are for the bottom right corner of the
+                        // quad, so we need to shift it left by 7.5'
+                        // to make the label appear inside the quad
+                        // (attached to the bottom left corner in
+                        // this case).
+                        /* XXX - figure out how to do WITH_DBFAWK: */
+                        if (quad_overlay_flag) {
+                            const char *dbf_temp;
+                            float lat_f;
+                            float lon_f;
+
+                            if (fieldcount >= 4) {
+                                dbf_temp = DBFReadStringAttribute( hDBF, structure, 2 );
+                                if (1 != sscanf(dbf_temp, "%f", &lat_f)) {
+                                    fprintf(stderr,"draw_shapefile_map:sscanf parsing error\n");
+                                }
+                                dbf_temp = DBFReadStringAttribute( hDBF, structure, 3 );
+                                if (1 != sscanf(dbf_temp, "%f", &lon_f)) {
+                                    fprintf(stderr,"draw_shapefile_map:sscanf parsing error\n");
+                                }
+                                lon_f = lon_f - 0.125;
+                            }
+                            else {
+                                lat_f = 0.0;
+                                lon_f = 0.0;
+                            }
+
+                            //fprintf(stderr,"Lat: %f, Lon: %f\t, Quad: %s\n", lat_f, lon_f, quad_label);
+
+                            temp_ok = convert_to_xastir_coordinates(&my_long,
+                                &my_lat,
+                                (float)lon_f,
+                                (float)lat_f);
+                        }
+                        else {  // Not quad overlay, use vertices
+             // XXX - todo: center large polygon labels in the center (e.g. county boundary)
+                            /* center label in polygon bounding box */
+                            temp_ok = convert_to_xastir_coordinates(&my_long,
+                                &my_lat,
+                                ((float)(object->dfXMax + object->dfXMin))/2.0,
+                                ((float)(object->dfYMax + object->dfYMin))/2.0);
+#ifdef notdef
+                            temp_ok = convert_to_xastir_coordinates(&my_long,
+                                &my_lat,
+                                (float)object->padfX[0],
+                                (float)object->padfY[0]);
+#endif  // notdef
+                        }
+                        //fprintf(stderr,"%ld %ld\n", my_long, my_lat);
+
+                        if (!temp_ok) {
+                            fprintf(stderr,"draw_shapefile_map8: Problem converting from lat/lon\n");
+                            ok = 0;
+                            x = 0;
+                            y = 0;
+                        }
+                        else {
+                            // Convert to screen coordinates.  Careful
+                            // here!  The format conversions you'll need
+                            // if you try to compress this into two
+                            // lines will get you into trouble.
+                            x = my_long - NW_corner_longitude;
+                            y = my_lat - NW_corner_latitude;
+                            x = x / scale_x;
+                            y = y / scale_y;
+
+// Labeling of polygons done here
+ 
+                            if (ok == 1 && ok_to_draw) {
+                                if (quad_overlay_flag) {
+                                    draw_nice_string(w,
+                                        pixmap,
+                                        0,
+                                        x+2,
+                                        y-1,
+                                        (char*)quad_label,
+                                        0xf,
+                                        0x10,
+                                        strlen(quad_label));
+                                }
+                                else {
+#ifdef notdef
+                                    (void)draw_label_text ( w,
+                                        x,
+                                        y,
+                                        strlen(temp),
+                                        colors[label_color],
+                                        (char *)temp);
+#endif  // notdef
+                                    if (debug_level & 16) {
+                                        fprintf(stderr,
+                                       "  displaying label %s with color %x\n",
+                                                temp,label_color);
+                                    }
+                                    (void)draw_centered_label_text(w,
+                                        -90,
+                                        x,
+                                        y,
+                                        strlen(temp),
+                                        colors[label_color],
+                                        (char *)temp,
+                                        font_size);
+                                }
+                            }
+                        }
+                    }
+                    break;
+
+                case SHPT_MULTIPOINT:
+                case SHPT_MULTIPOINTZ:
+                        // Not implemented.
+                        fprintf(stderr,"Shapefile Multi-Point format files aren't supported!\n");
+                    break;
+
+                default:
+                        // Not implemented.
+                        fprintf(stderr,"Shapefile format not supported: Subformat unknown (default clause of switch)!\n");
+                    break;
+
+            }   // End of switch
+        }
+        SHPDestroyObject( object ); // Done with this structure
+    }
+
+
+    // Free our hash of label strings, if any.  Each hash entry may
+    // have a linked list attached below it.
+    for (i = 0; i < 256; i++) {
+        ptr2 = label_hash[i];
+        while (ptr2 != NULL) {
+            label_hash[i] = ptr2->next;
+            //fprintf(stderr,"free: %s\n",ptr2->label);
+            free(ptr2);
+            ptr2 = label_hash[i];
+        }
+    }
+
+#ifdef WITH_DBFAWK
+    dbfawk_free_info(fld_info);
+    if (sig_info != NULL && sig_info != dbfawk_default_sig  && (sig_info->sig == NULL)) {
+        dbfawk_free_sigs(sig_info);
+    }
+#endif  // WITH_DBFAWK
+
+    DBFClose( hDBF );
+    SHPClose( hSHP );
+
+//    XmUpdateDisplay (XtParent (da));
+
+    if (debug_level & 16) {
+        fprintf(stderr,"High-Mark Index:%d,\tHigh-Mark i:%d\n",
+            high_water_mark_index,
+            high_water_mark_i);
+    }
+
+    // Set fill style back to defaults
+    XSetFillStyle(XtDisplay(w), gc, FillSolid);
+}
+// End of draw_shapefile_map()
+
+
+
+
+
+#ifdef WITH_DBFAWK
+
+// This function will delete any pre-loaded dbfawk sigs and clear Dbf_sigs
+// This will trigger a  reload the first time a shapfile is redisplayed
+void clear_dbfawk_sigs(void) {
+    //    fprintf(stderr,"Clearing signatures.\n");
+    if (Dbf_sigs ) {
+        dbfawk_free_sigs(Dbf_sigs);
+        Dbf_sigs = NULL;
+    }
+}
+        
+#endif  // WITH_DBFAWK
+
+
+#endif  // HAVE_LIBSHP
+
+
diff --git a/src/map_tif.c b/src/map_tif.c
new file mode 100644
index 0000000..4fb4486
--- /dev/null
+++ b/src/map_tif.c
@@ -0,0 +1,2824 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_tif.c,v 1.47 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+#define DOS_HDR_LINES 8
+#define GRID_MORE 5000
+
+extern int npoints;		/* tsk tsk tsk -- globals */
+extern int mag;
+
+#ifdef HAVE_LIBGEOTIFF
+
+
+#include "xtiffio.h"
+//#include "geotiffio.h"
+
+#include "geo_normalize.h"
+
+
+// Needed for GTIFProj4FromLatLong() replacement below
+#ifdef HAVE_LIBGDAL
+#  include "proj_api.h"
+#endif  // HAVE_LIBGDAL
+
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+/**********************************************************
+ * get_alt_fgd_path()
+ *
+ * Used to search for .fgd in ../metadata subdir, as it is
+ * layed out on a USGS CDROM.
+ **********************************************************/
+void get_alt_fgd_path(char *fullpath, int fullpath_length) {
+    int len;
+    int i, j = 0;
+    char *dir = fullpath;
+    char fname[MAX_FILENAME];
+
+    // Split up into directory and filename
+    len = (int)strlen (fullpath);
+    for (i = len; i >= 0; i--) {
+        if (fullpath[i] == '/') {
+            dir = &fullpath[i];
+            break;
+        }
+    }
+    for (++i; i <= len; i++) {
+    fname[j++] = fullpath[i];   // Grab the filename
+    if (fullpath[i] == '\0')
+        break;
+    }
+
+    // We have the filename now.  dir now points to
+    // the '/' at the end of the path.
+
+    // Now do it again to knock off the "data" subdirectory
+    // from the end.
+    dir[0] = '\0';  // Terminate the current string, wiping out the '/' character
+    len = (int)strlen (fullpath);   // Length of the new shortened string
+    for (i = len; i >= 0; i--) {
+        if (fullpath[i] == '/') {
+            dir = &fullpath[i + 1]; // Dir now points to one past the '/' character
+            break;
+        }
+    }
+    for (++i; i <= len; i++) {
+    if (fullpath[i] == '\0')
+        break;
+    }   
+
+    // Add "metadata/" into the path
+    xastir_snprintf(dir, fullpath_length, "metadata/%s", fname);
+    //fprintf(stderr,"FGD Directory: %s\n", fullpath);
+}
+
+
+
+
+
+/**********************************************************
+ * get_alt_fgd_path2()
+ *
+ * Used to search for .fgd in Metadata subdir.  This function
+ * is no longer used.
+ **********************************************************/
+void get_alt_fgd_path2(char *fullpath, int fullpath_length) {
+    int len;
+    int i, j = 0;
+    char *dir = fullpath;
+    char fname[MAX_FILENAME];
+
+    // Split up into directory and filename
+    len = (int)strlen (fullpath);
+    for (i = len; i >= 0; i--) {
+        if (fullpath[i] == '/') {
+            dir = &fullpath[i + 1];
+            break;
+        }
+    }
+    for (++i; i <= len; i++) {
+    fname[j++] = fullpath[i];
+    if (fullpath[i] == '\0')
+        break;
+    }
+
+    // Add "Metadata/" into the path
+    xastir_snprintf(dir, fullpath_length, "Metadata/%s", fname);
+}
+
+
+
+
+
+/***********************************************************
+ * read_fgd_file()
+ *
+ * Read in the "*.fgd" file associated with the geoTIFF
+ * file.  Get the corner points from it and return.  If
+ * no fgd file exists for this map, return a 0.
+ ***********************************************************/
+int read_fgd_file ( char* tif_filename,
+                    float* f_west_bounding,
+                    float* f_east_bounding,
+                    float* f_north_bounding,
+                    float* f_south_bounding)
+{
+    char fgd_file[MAX_FILENAME];/* Complete path/name of .fgd file */
+    FILE *fgd;                  /* Filehandle of .fgd file */
+    char line[MAX_FILENAME];    /* One line from .fgd file */
+    int length;
+    char *ptr;                  /* Substring pointer */
+    int num_coordinates = 0;
+
+
+    /* Read the .fgd file to find corners of the map neat-line */
+    xastir_snprintf(fgd_file,
+        sizeof(fgd_file),
+        "%s",
+        tif_filename);
+    length = strlen(fgd_file);
+
+    /* Change the extension to ".fgd" */
+    fgd_file[length-3] = 'f';
+    fgd_file[length-2] = 'g';
+    fgd_file[length-1] = 'd';
+
+    if (debug_level & 512)
+        fprintf(stderr,"%s\n",fgd_file);
+
+    /*
+     * Search for the WEST/EAST/NORTH/SOUTH BOUNDING COORDINATES
+     * in the .fgd file.
+     */
+    fgd = fopen (fgd_file, "r");
+
+    // Try an alternate path (../metadata/ subdirectory) if the first path didn't work
+    // This allows working with USGS maps directly from CDROM
+    if (fgd == NULL) {
+        get_alt_fgd_path(fgd_file, sizeof(fgd_file) );
+
+        if (debug_level & 512)
+            fprintf(stderr,"%s\n",fgd_file);
+
+        fgd = fopen (fgd_file, "r");
+    }
+
+    if (fgd != NULL)
+    {
+        while ( ( !feof (fgd) ) && ( num_coordinates < 4 ) )
+        {
+            get_line (fgd, line, MAX_FILENAME);
+
+            if (*f_west_bounding == 0.0)
+            {
+                if ( ( (ptr = strstr(line, "WEST BOUNDING COORDINATE:") ) != NULL)
+                        || ( (ptr = strstr(line, "West_Bounding_Coordinate:") ) != NULL) )
+                {
+                    if (1 != sscanf (ptr + 25, " %f", f_west_bounding)) {
+                        fprintf(stderr,"read_fgd_file:sscanf parsing error\n");
+                    }
+                    if (debug_level & 512)
+                        fprintf(stderr,"West Bounding:  %f\n",*f_west_bounding);
+                    num_coordinates++;
+                }
+            }
+
+            else if (*f_east_bounding == 0.0)
+            {
+                if ( ( (ptr = strstr(line, "EAST BOUNDING COORDINATE:") ) != NULL)
+                        || ( (ptr = strstr(line, "East_Bounding_Coordinate:") ) != NULL) )
+                {
+                    if (1 != sscanf (ptr + 25, " %f", f_east_bounding)) {
+                        fprintf(stderr,"read_fgd_file:sscanf parsing error\n");
+                    }
+                    if (debug_level & 512)
+                        fprintf(stderr,"East Bounding:  %f\n",*f_east_bounding);
+                    num_coordinates++;
+                }
+            }
+
+            else if (*f_north_bounding == 0.0)
+            {
+                if ( ( (ptr = strstr(line, "NORTH BOUNDING COORDINATE:") ) != NULL)
+                        || ( (ptr = strstr(line, "North_Bounding_Coordinate:") ) != NULL) )
+                {
+                    if (1 != sscanf (ptr + 26, " %f", f_north_bounding)) {
+                        fprintf(stderr,"read_fgd_file:sscanf parsing error\n");
+                    }
+                    if (debug_level & 512)
+                        fprintf(stderr,"North Bounding: %f\n",*f_north_bounding);
+                    num_coordinates++;
+                }
+            }
+
+            else if (*f_south_bounding == 0.0)
+            {
+                if ( ( (ptr = strstr(line, "SOUTH BOUNDING COORDINATE:") ) != NULL)
+                        || ( (ptr = strstr(line, "South_Bounding_Coordinate:") ) != NULL) )
+                {
+                    if (1 != sscanf (ptr + 26, " %f", f_south_bounding)) {
+                        fprintf(stderr,"read_fgd_file:sscanf parsing error\n");
+                    }
+                    if (debug_level & 512)
+                        fprintf(stderr,"South Bounding: %f\n",*f_south_bounding);
+                    num_coordinates++;
+                }
+            }
+
+        }
+        fclose (fgd);
+    }
+    else
+    {
+        if (debug_level & 512)
+            fprintf(stderr,"Couldn't open '.fgd' file, assuming no map collar to chop %s\n",
+                    tif_filename);
+        return(0);
+    }
+
+
+    /*
+     * We should now have exactly four bounding coordinates.
+     * These specify the map neat-line corners.  We can use
+     * them to chop off the white collar from around the map.
+     */
+    if (num_coordinates != 4)
+    {
+        fprintf(stderr,"Couldn't find 4 bounding coordinates in '.fgd' file, map %s\n",
+                tif_filename);
+        return(0);
+    }
+
+
+    if (debug_level & 512) {
+        fprintf(stderr,"%f %f %f %f\n",
+        *f_south_bounding,
+        *f_north_bounding,
+        *f_west_bounding,
+        *f_east_bounding);
+    }
+
+    return(1);    /* Successful */
+}
+
+
+
+
+
+#ifndef HAVE_LIBGDAL
+#  define my_GTIFProj4FromLatLong GTIFProj4FromLatLong
+#else
+
+// If we have libgdal included then the GTIFProj4FromLatLong()
+// functions may not work.  In this case we use the function below
+// instead.
+
+
+// This next function was borrowed from the libgeotiff project.  We
+// have permission from Frank Warmerdam to use any code from
+// geotiff_proj4.c and relicense it under GPL, per private message
+// of 10/14/2005.  Frank wrote that module.
+//
+// When we used the original function from libgeotiff we'd lose topo
+// map capability if we linked in libgdal.  We avoid that problem by
+// having a local copy of the function here with a different name so
+// that libgdal can't try to override it.
+//
+//***********************************************************************
+//                        my_GTIFProj4FromLatLong()
+//
+//      Convert lat/long values to projected coordinate for a
+//      particular definition.
+//***********************************************************************
+
+int my_GTIFProj4FromLatLong( GTIFDefn * psDefn,
+                             int nPoints,
+                             double *padfX,
+                             double *padfY ) {
+
+    char    *pszProjection;
+    projPJ      psPJ;
+    int     i;
+
+// --------------------------------------------------------------------
+//  Get a projection definition.
+// --------------------------------------------------------------------
+    pszProjection = GTIFGetProj4Defn( psDefn );
+
+    if( pszProjection == NULL )
+        return FALSE;
+
+//fprintf(stderr,"pszProjection:%s\n", pszProjection);
+// Returned this:
+// pszProjection:+proj=utm +zone=10 +ellps=clrk66 +units=m 
+
+
+// --------------------------------------------------------------------
+//      Initialize the projection
+// --------------------------------------------------------------------
+
+    psPJ = pj_init_plus(pszProjection);
+
+    if( psPJ == NULL ) {
+        return FALSE;
+    }
+
+// --------------------------------------------------------------------
+//      Process each of the points.
+// --------------------------------------------------------------------
+
+    for( i = 0; i < nPoints; i++ ) {
+        projUV  sUV;
+
+        sUV.u = padfX[i] * DEG_TO_RAD;
+        sUV.v = padfY[i] * DEG_TO_RAD;
+
+        sUV = pj_fwd( sUV, psPJ );
+
+        padfX[i] = sUV.u;
+        padfY[i] = sUV.v;
+    }
+
+    pj_free( psPJ );
+
+    return TRUE;
+}
+#endif  // HAVE_LIBGDAL
+
+
+
+
+
+// Check the "GTIFProj4*" functions to see if we can use
+// datum.c instead for any of them.  These calls are all in
+// draw_geotiff_image_map().  It looks like they deal with
+// converting from pixels to coordinates and vice-versa, so we
+// probably still need them.  Perhaps we can borrow the code for
+// that and do it ourselves, to get rid of the extra library?
+
+/***********************************************************
+ * draw_geotiff_image_map()
+ *
+ * Here's where we handle geoTIFF files, such as USGS DRG
+ * topo maps.  The .fgd file gives us the lat/lon of the map
+ * neat-line corners for USGS maps.  We use this info to
+ * chop off the white map border.  If no .fgd file is present,
+ * we assume there is no map collar to be cropped and display
+ * every pixel.
+ * We also translate from the map datum to WGS84.  We use
+ * libgeotiff/libtiff/libproj for these operations.
+
+ * TODO:
+ * Provide support for datums other than NAD27/NAD83/WGS84.
+ * Libproj doesn't currently support many datums.
+ *
+ * Provide support for handling different map projections.
+ * Perhaps by reprojecting the map data and storing it on
+ * disk in another format.
+ *
+ * Select 'o', 'f', 'k', or 'c' maps based on zoom level.
+ * Might also put some hysteresis in this so that it keeps
+ * the current type of map through one extra zoom each way.
+ * 'c': Good from x256 to x064.
+ * 'f': Good from x128 to x032.  Not very readable at x128.
+ * 'k': Good from x??? to x???.
+ * 'o': Good from x064 to x004.  Not very readable at x64.
+ ***********************************************************/
+void draw_geotiff_image_map (Widget w, 
+			     char *dir, 
+			     char *filenm,
+			     alert_entry *alert,
+			     u_char alert_color,
+			     int destination_pixmap,
+			     map_draw_flags *mdf) {
+    char file[MAX_FILENAME];    /* Complete path/name of image file */
+    char short_filenm[MAX_FILENAME];
+    TIFF *tif = (TIFF *) 0;     /* Filehandle for tiff image file */
+    GTIF *gtif = (GTIF *) 0;    /* GeoKey-level descriptor */
+    /* enum { VERSION = 0, MAJOR, MINOR }; */
+    int versions[3];
+    uint32 width;               /* Width of the image */
+    uint32 height;              /* Height of the image */
+    uint16 bitsPerSample;       /* Should be 8 for USGS DRG's */
+    uint16 samplesPerPixel = 1; /* Should be 1 for USGS DRG's.  Some maps
+                                    don't have this tag so we default to 1 */
+    uint32 rowsPerStrip;        /* Should be 1 for USGS DRG's */
+    uint16 planarConfig;        /* Should be 1 for USGS DRG's */
+    uint16 photometric;         /* DRGs are RGB (2) */
+    int    bytesPerRow;            /* Bytes per scanline row of tiff file */
+    GTIFDefn defn;              /* Stores geotiff details */
+    u_char *imageMemory;        /* Fixed pointer to same memory area */
+    uint32 row;                 /* My row counter for the loop */
+    int num_colors;             /* Number of colors in the geotiff colormap */
+    uint16 *red_orig, *green_orig, *blue_orig; /* Used for storing geotiff colors */
+    XColor my_colors[256];      /* Used for translating colormaps */
+    unsigned long west_bounding = 0;
+    unsigned long east_bounding = 0;
+    unsigned long north_bounding = 0;
+    unsigned long south_bounding = 0;
+    float f_west_bounding = 0.0;
+    float f_east_bounding = 0.0;
+    float f_north_bounding = 0.0;
+    float f_south_bounding = 0.0;
+
+    unsigned long west_bounding_wgs84 = 0;
+    unsigned long east_bounding_wgs84 = 0;
+    unsigned long north_bounding_wgs84 = 0;
+    unsigned long south_bounding_wgs84 = 0;
+
+    float f_NW_x_bounding;
+    float f_NW_y_bounding;
+    float f_NE_x_bounding;
+    float f_NE_y_bounding;
+    float f_SW_x_bounding;
+    float f_SW_y_bounding;
+    float f_SE_x_bounding;
+    float f_SE_y_bounding;
+
+    unsigned long NW_x_bounding_wgs84 = 0;
+    unsigned long NW_y_bounding_wgs84 = 0;
+    double f_NW_x_bounding_wgs84 = 0.0;
+    double f_NW_y_bounding_wgs84 = 0.0;
+
+    unsigned long NE_x_bounding_wgs84 = 0;
+    unsigned long NE_y_bounding_wgs84 = 0;
+    double f_NE_x_bounding_wgs84 = 0.0;
+    double f_NE_y_bounding_wgs84 = 0.0;
+
+    unsigned long SW_x_bounding_wgs84 = 0;
+    unsigned long SW_y_bounding_wgs84 = 0;
+    double f_SW_x_bounding_wgs84 = 0.0;
+    double f_SW_y_bounding_wgs84 = 0.0;
+
+    unsigned long SE_x_bounding_wgs84 = 0;
+    unsigned long SE_y_bounding_wgs84 = 0;
+    double f_SE_x_bounding_wgs84 = 0.0;
+    double f_SE_y_bounding_wgs84 = 0.0;
+
+    int NW_x = 0;               /* Store pixel values for map neat-line */
+    int NW_y = 0;               /* ditto */
+    int NE_x = 0;               /* ditto */
+    int NE_y = 0;               /* ditto */
+    int SW_x = 0;               /* ditto */
+    int SW_y = 0;               /* ditto */
+    int SE_x = 0;               /* ditto */
+    int SE_y = 0;               /* ditto */
+    int left_crop;              /* Pixel cropping value */
+    int right_crop;             /* Pixel cropping value */
+    int top_crop;               /* Pixel cropping value */
+    int bottom_crop;            /* Pixel cropping value */
+    double xxx, yyy;            /* LFM: needs more accuracy here */
+    register long sxx, syy;              /* X Y screen plot positions          */
+    float steph;
+    register float stepw;
+    int stepwc, stephc;
+    char map_it[MAX_FILENAME];           /* Used to hold filename for status line */
+    int have_fgd;               /* Tells where we have an associated *.fgd file */
+    //short datum;
+    char *datum_name;           /* Points to text name of datum */
+    //double *GeoTie;
+    int crop_it = 0;            /* Flag which tells whether the image should be cropped */
+
+    register uint32 column;
+
+    float xastir_left_x_increment;
+    float left_x_increment;
+    float xastir_left_y_increment;
+    float left_y_increment;
+    float xastir_right_x_increment;
+    float right_x_increment;
+    float xastir_right_y_increment;
+    float right_y_increment;
+    float xastir_top_y_increment;
+    float top_y_increment;
+    float xastir_bottom_y_increment;
+    float bottom_y_increment;
+    float xastir_avg_y_increment;
+    float avg_y_increment;
+    int row_offset;
+    register unsigned long current_xastir_left;
+    unsigned long current_xastir_right;
+    register uint32 current_left;
+    uint32 current_right;
+    uint32 current_line_width;
+    register unsigned long xastir_current_y;
+    register uint32 column_offset;
+    register unsigned long xastir_current_x;
+    double *PixelScale;
+    int have_PixelScale;
+    uint16 qty;
+    int SkipRows;
+    unsigned long view_min_x, view_max_x;
+    unsigned long view_min_y, view_max_y;
+
+    register unsigned long xastir_total_y;
+    int NW_line_offset;
+    int NE_line_offset;
+    int NW_xastir_x_offset;
+    int NE_xastir_x_offset;
+    int NW_xastir_y_offset;
+    int NW_x_offset;
+    int NE_x_offset;
+    float xastir_avg_left_right_y_increment;
+    register float total_avg_y_increment;
+    unsigned long view_left_minus_pixel_width;
+    unsigned long view_top_minus_pixel_height;
+    int proj_is_latlong;
+    short PCS;
+    int usgs_drg;
+    char *imagedesc;
+
+    usgs_drg = mdf->usgs_drg;              // yes, no, or auto
+
+    if (debug_level & 16)
+        fprintf(stderr,"%s/%s\n", dir, filenm);
+
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    /* Check whether we have an associated *.fgd file.  This
+     * file contains the neat-line corner points for USGS DRG
+     * maps, which allows us to chop off the map collar.
+     */
+    have_fgd = read_fgd_file( file,
+                              &f_west_bounding,
+                              &f_east_bounding,
+                              &f_north_bounding,
+                              &f_south_bounding );
+
+    /*
+     * If we are able to read the fgd file then we have the lat/lon
+     * corner points in floating point variables.  If there isn't
+     * an fgd file then we must get the info from the geotiff
+     * tags themselves and we assume that there's no map collar to
+     * chop off.
+     */
+
+
+    /*
+     * What we NEED to do (implemented a bit later in this function
+     * in order to support geotiff files created with other map
+     * datums, is to open up the geotiff file and get the map datum
+     * used for the data.  Then convert the corner points to WGS84
+     * and check to see whether the image is inside our viewport.
+     * Some USGS geotiff maps have map data in NAD83 datum and the
+     * .fgd file incorrectly specifying NAD27 datum.  There are also
+     * some USGS geotiff maps created with WGS84 datum.
+     */
+
+
+    /* convert_to_xastir_coordinates( x,y,longitude,latitude ); */
+    if (have_fgd)   /* Could be a USGS file */
+    {
+        int temp_ok1, temp_ok2;
+
+        if (debug_level & 16) {
+            fprintf(stderr,"FGD:  W:%f  E:%f  N:%f  S:%f\n",
+                f_west_bounding,
+                f_east_bounding,
+                f_north_bounding,
+                f_south_bounding);
+        }
+
+        crop_it = 1;        /* The map collar needs to be cropped */
+
+        temp_ok1 = convert_to_xastir_coordinates(  &west_bounding,
+                                        &north_bounding,
+                                        f_west_bounding,
+                                        f_north_bounding );
+
+
+        temp_ok2 = convert_to_xastir_coordinates(  &east_bounding,
+                                        &south_bounding,
+                                        f_east_bounding,
+                                        f_south_bounding );
+
+        if (!temp_ok1 || !temp_ok2) {
+            fprintf(stderr,"draw_geotiff_image_map: problem converting from lat/lon\n");
+            return;
+        }
+
+
+        /*
+         * Check whether map is inside our current view.  It'd be
+         * good to do a datum conversion first, but we don't know
+         * what the datum is by this point in the code.  I'm just
+         * doing this check here for speed, so that I can eliminate
+         * maps that aren't even close to our viewport area, without
+         * having to open those map files.  All other maps that pass
+         * this test (at the next go-around later in the code) must
+         * have their corner points datum-shifted so that we can
+         * REALLY tell whether a map fits within the viewport.
+         *
+         * Perhaps add a bit to the corners (the max datum shift?)
+         * to do our quick check?  I decided to add about 10 seconds
+         * to the map edges, which equates to 1000 in the Xastir
+         * coordinate system.  That should be greater than any datum
+         * shift in North America for USGS topos.  I'm artificially
+         * inflating the size of the map just for this quick
+         * elimination check.
+         *
+         *   bottom          top             left           right
+         */
+
+        // Check whether we're indexing or drawing the map
+        if ( (destination_pixmap != INDEX_CHECK_TIMESTAMPS)
+            && (destination_pixmap != INDEX_NO_TIMESTAMPS) ) {
+
+            // We're drawing.
+            if (!map_visible( south_bounding + 1000,
+                              north_bounding - 1000,
+                              west_bounding - 1000,
+                              east_bounding + 1000 ) ) {
+                if (debug_level & 16) {
+                    fprintf(stderr,"Map not within current view.\n");
+                    fprintf(stderr,"Skipping map: %s\n", file);
+                }
+
+                // Map isn't inside our current view.  We're done.
+                // Free any memory used and return.
+                //
+                return;    // Skip this map
+            }
+            else {
+                if (debug_level & 16) {
+                    fprintf(stderr,"Map is viewable\n");
+                }
+            }
+        }
+    }   // End of if have_fgd
+
+
+    /*
+     * At this point the map MAY BE in our current view.
+     * We don't know for sure until we do a datum translation
+     * on the bounding coordinates and check again.  Note that
+     * if there's not an accompanying .fgd file, we don't have
+     * the bounding coordinates yet by this point.
+     */
+
+    if (debug_level & 16)
+        fprintf(stderr,"XTIFFOpen\n");
+
+    /* Open TIFF descriptor to read GeoTIFF tags */
+    tif = XTIFFOpen (file, "r");
+    if (!tif)
+        return;
+
+    if (debug_level & 16)
+        fprintf(stderr,"GTIFNew\n");
+
+    /* Open GTIF Key parser.  Keys will be read at this time */
+    gtif = GTIFNew (tif);
+    if (!gtif)
+    {
+        /* Close the TIFF file descriptor */
+        XTIFFClose (tif);
+        return;
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr,"GTIFDirectoryInfo\n");
+
+    /*
+     * Get the GeoTIFF directory info.  Need this for
+     * some of the operations further down in the code.
+     */
+    GTIFDirectoryInfo (gtif, versions, 0);
+
+    /*
+    if (versions[MAJOR] > 1)
+    {
+        fprintf(stderr,"This file is too new for me\n");
+        GTIFFree (gtif);
+        XTIFFClose (tif);
+        return;
+    }
+    */
+
+    if (debug_level & 16)
+        fprintf(stderr,"GTIFGetDefn\n");
+
+
+    /* I might want to attempt to avoid the GTIFGetDefn
+     * call, as it takes a bit of time per file.  It
+     * normalizes the info.  Try getting just the tags
+     * or keys that I need individually instead.  I
+     * need "defn" for the GTIFProj4ToLatLong calls though.
+     */
+    if (GTIFGetDefn (gtif, &defn)) {
+        if (debug_level & 16)
+            GTIFPrintDefn (&defn, stdout);
+    }
+    else {
+        fprintf(stderr,"GTIFGetDefn failed\n");
+    }
+
+    proj_is_latlong=FALSE;
+
+    if( !GTIFKeyGet(gtif,ProjectedCSTypeGeoKey, &PCS,0,1)) {
+        // fprintf(stderr,"Warning: no PCS in geotiff file %s, assuming map is in lat/lon!\n", filenm);
+        proj_is_latlong=TRUE;
+    }
+
+    /* Fetch a few TIFF fields for this image */
+    if ( !TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &width) ) {
+        width = 5493;
+        fprintf(stderr,"No width tag found in file, setting it to 5493\n");
+    }
+
+    if ( !TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &height) ) {
+        height = 6840;
+        fprintf(stderr,"No height tag found in file, setting it to 6840\n");
+    }
+
+    // If we're autodetecting usgs_drg, check the image description tag
+    // Note, the TIFFGetField doesn't allocate a string, it returns a pointer
+    // to an existing one.  Don't free it!
+    if (usgs_drg == 2) {
+        if ( TIFFGetField (tif, TIFFTAG_IMAGEDESCRIPTION, &imagedesc)) {
+            if (strncasecmp(imagedesc,"USGS GeoTIFF DRG",16) == 0) {
+                usgs_drg = 1;   // Yes
+            } 
+            else {
+                usgs_drg = 0;  // No
+            }
+        }
+        else {
+                usgs_drg = 0;  // No tag, assume not a usgs topo 
+        }
+            
+    }
+
+    /*
+     * If we don't have an associated .fgd file for this map,
+     * check for corner points in the ImageDescription
+     * tag (proposed new USGS DRG standard).  Boundary
+     * coordinates will be the outside corners of the image
+     * unless I can find some other proof.
+     * Currently I assume that the map has no
+     * map collar to chop off and set the neat-line corners
+     * to be the outside corners of the image.
+     *
+     * NOTE:  For the USGS files (with a map collar), the
+     * image must be cropped and rotated and is slightly
+     * narrower at one end (top for northern hemisphere, bottom
+     * for southern hemisphere).  For other files with no map
+     * collar, the image is rectangular but the lat/lon
+     * coordinates may be rotated.
+     */
+    if (!have_fgd)      // Not a USGS map or perhaps a newer spec
+    {
+        crop_it = 1;        /* crop this map image */
+
+        /*
+         * Snag and parse ImageDescription tag here.
+         */
+
+        /* Code goes here for getting ImageDescription tag... */
+
+
+        /* Figure out the bounding coordinates for this map */
+        if (debug_level & 16)
+            fprintf(stderr,"\nCorner Coordinates:\n");
+
+        /* Find lat/lon for NW corner of image */
+        xxx = 0.0;
+        yyy = 0.0;
+        if ( GTIFImageToPCS( gtif, &xxx, &yyy ) )   // Do all 4 of these in one call?
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"%-13s ", "Upper Left" );
+                fprintf(stderr,"(%11.3f,%11.3f)\n", xxx, yyy );
+            }
+        }
+
+        if ( proj_is_latlong || GTIFProj4ToLatLong( &defn, 1, &xxx, &yyy ) )   // Do all 4 of these in one call?
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"  (%s,", GTIFDecToDMS( xxx, "Long", 2 ) );
+                fprintf(stderr,"%s)\n", GTIFDecToDMS( yyy, "Lat", 2 ) );
+                fprintf(stderr,"%f  %f\n", xxx, yyy);
+            }
+        }
+        else {
+            if (!proj_is_latlong) {
+                fprintf(stderr,"Failed GTIFProj4ToLatLong() call\n");
+            }
+        }
+
+        f_NW_x_bounding = (float)xxx;
+        f_NW_y_bounding = (float)yyy;
+
+
+        /* Find lat/lon for NE corner of image */
+        xxx = width - 1;
+        yyy = 0.0;
+        if ( GTIFImageToPCS( gtif, &xxx, &yyy ) )
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"%-13s ", "Lower Right" );
+                fprintf(stderr,"(%11.3f,%11.3f)\n", xxx, yyy );
+            }
+        }
+
+        if (  proj_is_latlong || GTIFProj4ToLatLong( &defn, 1, &xxx, &yyy ) )
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"  (%s,", GTIFDecToDMS( xxx, "Long", 2 ) );
+                fprintf(stderr,"%s)\n", GTIFDecToDMS( yyy, "Lat", 2 ) );
+                fprintf(stderr,"%f  %f\n", xxx, yyy);
+            }
+        }
+        else {
+            if (!proj_is_latlong) {
+                fprintf(stderr,"Failed GTIFProj4ToLatLong() call\n");
+            }
+        }
+
+        f_NE_x_bounding = (float)xxx;
+        f_NE_y_bounding = (float)yyy;
+
+        /* Find lat/lon for SW corner of image */
+        xxx = 0.0;
+        yyy = height - 1;
+        if ( GTIFImageToPCS( gtif, &xxx, &yyy ) )
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"%-13s ", "Lower Right" );
+                fprintf(stderr,"(%11.3f,%11.3f)\n", xxx, yyy );
+            }
+        }
+
+        if (  proj_is_latlong || GTIFProj4ToLatLong( &defn, 1, &xxx, &yyy ) )
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"  (%s,", GTIFDecToDMS( xxx, "Long", 2 ) );
+                fprintf(stderr,"%s)\n", GTIFDecToDMS( yyy, "Lat", 2 ) );
+                fprintf(stderr,"%f  %f\n", xxx, yyy);
+            }
+        }
+        else {
+            if (!proj_is_latlong) {
+                fprintf(stderr,"Failed GTIFProj4ToLatLong() call\n");
+            }
+        }
+
+        f_SW_x_bounding = (float)xxx;
+        f_SW_y_bounding = (float)yyy;
+
+        /* Find lat/lon for SE corner of image */
+        xxx = width - 1;
+        yyy = height - 1;
+        if ( GTIFImageToPCS( gtif, &xxx, &yyy ) )
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"%-13s ", "Lower Right" );
+                fprintf(stderr,"(%11.3f,%11.3f)\n", xxx, yyy );
+            }
+        }
+
+        if (  proj_is_latlong || GTIFProj4ToLatLong( &defn, 1, &xxx, &yyy ) )
+        {
+            if (debug_level & 16) {
+                fprintf(stderr,"  (%s,", GTIFDecToDMS( xxx, "Long", 2 ) );
+                fprintf(stderr,"%s)\n", GTIFDecToDMS( yyy, "Lat", 2 ) );
+                fprintf(stderr,"%f  %f\n", xxx, yyy);
+            }
+        }
+        else {
+            if (!proj_is_latlong) {
+                fprintf(stderr,"Failed GTIFProj4ToLatLong() call\n");
+            }
+        }
+
+        f_SE_x_bounding = (float)xxx;
+        f_SE_y_bounding = (float)yyy;
+
+        if (f_NW_y_bounding > 0) {
+          yyy=((f_NW_y_bounding > f_NE_y_bounding) ? f_NE_y_bounding
+               : f_NW_y_bounding);
+          xxx=((f_SW_y_bounding < f_SE_y_bounding) ? f_SE_y_bounding
+               : f_SW_y_bounding);
+        } else {
+          yyy=((f_NW_y_bounding < f_NE_y_bounding) ? f_NE_y_bounding
+               : f_NW_y_bounding);
+          xxx=((f_SW_y_bounding > f_SE_y_bounding) ? f_SE_y_bounding
+               : f_SW_y_bounding);
+        }
+        f_north_bounding = (float)yyy;
+        f_south_bounding = (float)xxx;
+        if (f_NE_x_bounding > 0) {
+          xxx=((f_NE_x_bounding < f_SE_x_bounding) ? f_SE_x_bounding
+               : f_NE_x_bounding);
+          yyy=((f_NW_x_bounding > f_SW_x_bounding) ? f_SW_x_bounding
+               : f_NW_x_bounding);
+        } else {
+          xxx=((f_NE_x_bounding > f_SE_x_bounding) ? f_SE_x_bounding
+               : f_NE_x_bounding);
+          yyy=((f_NW_x_bounding < f_SW_x_bounding) ? f_SW_x_bounding
+               : f_NW_x_bounding);
+        }
+        f_west_bounding = (float)yyy;
+        f_east_bounding = (float)xxx;
+    }
+
+    f_NW_x_bounding = f_west_bounding;
+    f_NW_y_bounding = f_north_bounding;
+
+    f_SW_x_bounding = f_west_bounding;
+    f_SW_y_bounding = f_south_bounding;
+
+    f_NE_x_bounding = f_east_bounding;
+    f_NE_y_bounding = f_north_bounding;
+
+    f_SE_x_bounding = f_east_bounding;
+    f_SE_y_bounding = f_south_bounding;
+
+
+    // Fill in the wgs84 variables so we can do a datum
+    // conversion but keep our original values also.
+    f_NW_x_bounding_wgs84 = f_NW_x_bounding;
+    f_NW_y_bounding_wgs84 = f_NW_y_bounding;
+
+    f_SW_x_bounding_wgs84 = f_SW_x_bounding;
+    f_SW_y_bounding_wgs84 = f_SW_y_bounding;
+
+    f_NE_x_bounding_wgs84 = f_NE_x_bounding;
+    f_NE_y_bounding_wgs84 = f_NE_y_bounding;
+
+    f_SE_x_bounding_wgs84 = f_SE_x_bounding;
+    f_SE_y_bounding_wgs84 = f_SE_y_bounding;
+
+
+    /* Get the datum */
+    // GTIFKeyGet( gtif, GeogGeodeticDatumGeoKey, &datum, 0, 1 );
+    // if (debug_level & 16)
+    //     fprintf(stderr,"GeogGeodeticDatumGeoKey: %d\n", datum );
+
+
+    /* Get the tiepoints (in UTM coordinates always?)
+     * In our case they look like:
+     *
+     * 0.000000         Y
+     * 0.000000         X
+     * 0.000000         Z
+     * 572983.025771    Y in UTM (longitude for some maps?)
+     * 5331394.085064   X in UTM (latitude for some maps?)
+     * 0.000000         Z
+     *
+     */
+    /*
+    if (debug_level & 16) {
+        fprintf(stderr,"Tiepoints:\n");
+        if ( TIFFGetField( tif, TIFFTAG_GEOTIEPOINTS, &qty, &GeoTie ) ) {
+            for ( i = 0; i < qty; i++ ) {
+                fprintf(stderr,"%f\n", *(GeoTie + i) );
+            }
+        }
+    }
+    */
+
+
+    /* Get the geotiff horizontal datum name */
+    if ( defn.Datum != 32767 ) {
+        GTIFGetDatumInfo( defn.Datum, &datum_name, NULL );
+        if (debug_level & 16)
+            fprintf(stderr,"Datum: %d/%s\n", defn.Datum, datum_name );
+    }
+
+
+    /*
+     * Perform a datum shift on the bounding coordinates before we
+     * check whether the map is inside our viewport.  At the moment
+     * this is still hard-coded to NAD27 datum.  If the map is already
+     * in WGS84 or NAD83 datum, skip the datum conversion code.
+     */
+    if (   (defn.Datum != 6030)     /* DatumE_WGS84 */
+        && (defn.Datum != 6326)     /*  Datum_WGS84 */
+        && (defn.Datum != 6269) )   /* Datum_North_American_Datum_1983 */ {
+
+        if (debug_level & 16)
+            fprintf(stderr,"***** Attempting Datum Conversions\n");
+
+
+        // This code uses datum.h/datum.c to do the conversion
+        // instead of the proj.4 library as we had before.
+        // Here we assume that if it's not one of the three datums
+        // listed above, it's NAD27.
+
+        // Convert NW corner to WGS84
+        wgs84_datum_shift(TO_WGS_84,
+            &f_NW_y_bounding_wgs84,
+            &f_NW_x_bounding_wgs84,
+            D_NAD_27_CONUS);   // NAD27 CONUS
+
+        // Convert NE corner to WGS84
+        wgs84_datum_shift(TO_WGS_84,
+            &f_NE_y_bounding_wgs84,
+            &f_NE_x_bounding_wgs84,
+            D_NAD_27_CONUS);   // NAD27 CONUS
+
+        // Convert SW corner to WGS84
+        wgs84_datum_shift(TO_WGS_84,
+            &f_SW_y_bounding_wgs84,
+            &f_SW_x_bounding_wgs84,
+            D_NAD_27_CONUS);   // NAD27 CONUS
+
+        // Convert SE corner to WGS84
+        wgs84_datum_shift(TO_WGS_84,
+            &f_SE_y_bounding_wgs84,
+            &f_SE_x_bounding_wgs84,
+            D_NAD_27_CONUS);   // NAD27 CONUS (131)
+    }
+    else
+        if (debug_level & 16)
+            fprintf(stderr,"***** Skipping Datum Conversion\n");
+
+
+    /*
+     * Convert new datum-translated bounding coordinates to the
+     * Xastir coordinate system.
+     * convert_to_xastir_coordinates( x,y,longitude,latitude )
+     */
+    // NW corner
+    if (!convert_to_xastir_coordinates(  &NW_x_bounding_wgs84,
+                                        &NW_y_bounding_wgs84,
+                                        (float)f_NW_x_bounding_wgs84,
+                                        (float)f_NW_y_bounding_wgs84 ) ) {
+        fprintf(stderr,"draw_geotiff_image_map: Problem converting from lat/lon\n");
+        fprintf(stderr,"Did you follow the instructions for installing PROJ?\n");
+        return;
+    }
+
+    // NE corner
+    if (!convert_to_xastir_coordinates(  &NE_x_bounding_wgs84,
+                                        &NE_y_bounding_wgs84,
+                                        (float)f_NE_x_bounding_wgs84,
+                                        (float)f_NE_y_bounding_wgs84 ) ) {
+        fprintf(stderr,"draw_geotiff_image_map: Problem converting from lat/lon\n");
+        fprintf(stderr,"Did you follow the instructions for installing PROJ?\n");
+ 
+        return;
+    }
+
+    // SW corner
+    if (!convert_to_xastir_coordinates(  &SW_x_bounding_wgs84,
+                                        &SW_y_bounding_wgs84,
+                                        (float)f_SW_x_bounding_wgs84,
+                                        (float)f_SW_y_bounding_wgs84 ) ) {
+        fprintf(stderr,"draw_geotiff_image_map: Problem converting from lat/lon\n");
+        fprintf(stderr,"Did you follow the instructions for installing PROJ?\n");
+ 
+        return;
+    }
+
+    // SE corner
+    if (!convert_to_xastir_coordinates(  &SE_x_bounding_wgs84,
+                                        &SE_y_bounding_wgs84,
+                                        (float)f_SE_x_bounding_wgs84,
+                                        (float)f_SE_y_bounding_wgs84 ) ) {
+        fprintf(stderr,"draw_geotiff_image_map: Problem converting from lat/lon\n");
+        fprintf(stderr,"Did you follow the instructions for installing PROJ?\n");
+ 
+        return;
+    }
+
+
+    /*
+     * Check whether map is inside our current view.  These
+     * are the real datum-shifted bounding coordinates now,
+     * so this is the final decision as to whether the map
+     * should be loaded.
+     */
+
+    // Find the largest dimensions
+    if (NW_y_bounding_wgs84 <= NE_y_bounding_wgs84)
+        north_bounding_wgs84 = NW_y_bounding_wgs84;
+    else
+        north_bounding_wgs84 = NE_y_bounding_wgs84;
+
+    if (NW_x_bounding_wgs84 <= SW_x_bounding_wgs84)
+        west_bounding_wgs84 = NW_x_bounding_wgs84;
+    else
+        west_bounding_wgs84 = SW_x_bounding_wgs84;
+
+    if (SW_y_bounding_wgs84 >= SE_y_bounding_wgs84)
+        south_bounding_wgs84 = SW_y_bounding_wgs84;
+    else
+        south_bounding_wgs84 = SE_y_bounding_wgs84;
+
+    if (NE_x_bounding_wgs84 >= SE_x_bounding_wgs84)
+        east_bounding_wgs84 = NE_x_bounding_wgs84;
+    else
+        east_bounding_wgs84 = SE_x_bounding_wgs84;
+
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(map_it,0);       // Indexing ...
+
+        // We're indexing only.  Save the extents in the index.
+        index_update_xastir(filenm, // Filename only
+            south_bounding_wgs84,   // Bottom
+            north_bounding_wgs84,   // Top
+            west_bounding_wgs84,    // Left
+            east_bounding_wgs84,    // Right
+            0);                     // Default Map Level
+
+        //Free any memory used and return
+        /* We're finished with the geoTIFF key parser, so get rid of it */
+        GTIFFree (gtif);
+
+        /* Close the TIFF file descriptor */
+        XTIFFClose (tif);
+ 
+        return; // Done indexing this file
+    }
+    else {
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA028"),
+            short_filenm);
+        statusline(map_it,0);       // Loading ...
+    }
+
+
+
+
+    // bottom top left right
+    if (!map_visible( south_bounding_wgs84,
+                         north_bounding_wgs84,
+                         west_bounding_wgs84,
+                         east_bounding_wgs84 ) )
+    {
+        if (debug_level & 16) {
+            fprintf(stderr,"Map not within current view.\n");
+            fprintf(stderr,"Skipping map: %s\n", file);
+        }
+
+        /*
+         * Map isn't inside our current view.  We're done.
+         * Free any memory used and return
+         */
+
+        /* We're finished with the geoTIFF key parser, so get rid of it */
+        GTIFFree (gtif);
+
+        /* Close the TIFF file descriptor */
+        XTIFFClose (tif);
+
+        return;         /* Skip this map */
+    }
+
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        GTIFFree (gtif);
+        XTIFFClose (tif);
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+
+/*
+From running in debug mode:
+            Width: 5493
+           Height: 6840
+   Rows Per Strip: 1
+  Bits Per Sample: 8
+Samples Per Pixel: 1
+    Planar Config: 1
+*/
+
+
+    /* Fetch a few TIFF fields for this image */
+    if ( !TIFFGetField (tif, TIFFTAG_PHOTOMETRIC, &photometric) ) {
+        photometric = PHOTOMETRIC_RGB;
+        fprintf(stderr,"No photometric tag found in file, setting it to RGB\n");
+    }
+    if ( !TIFFGetField (tif, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip) ) {
+        rowsPerStrip = 1;
+        fprintf(stderr,"No rowsPerStrip tag found in file, setting it to 1\n");
+    }
+
+    if ( !TIFFGetField (tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample) ) {
+        bitsPerSample = 8;
+        fprintf(stderr,"No bitsPerSample tag found in file, setting it to 8\n");
+    }
+
+    if ( !TIFFGetField (tif, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel) ) {
+        samplesPerPixel = 1;
+        fprintf(stderr,"No samplesPerPixel tag found in file, setting it to 1\n");
+    }
+
+    if ( !TIFFGetField (tif, TIFFTAG_PLANARCONFIG, &planarConfig) ) {
+        planarConfig = 1;
+        fprintf(stderr,"No planarConfig tag found in file, setting it to 1\n");
+    }
+
+
+    if (debug_level & 16) {
+        fprintf(stderr,"            Width: %ld\n", (long int)width);
+        fprintf(stderr,"           Height: %ld\n", (long int)height);
+        fprintf(stderr,"      Photometric: %d\n", photometric);
+        fprintf(stderr,"   Rows Per Strip: %ld\n", (long int)rowsPerStrip);
+        fprintf(stderr,"  Bits Per Sample: %d\n", bitsPerSample);
+        fprintf(stderr,"Samples Per Pixel: %d\n", samplesPerPixel);
+        fprintf(stderr,"    Planar Config: %d\n", planarConfig);
+    }
+
+
+    /*
+     * Check for properly formatted geoTIFF file.  If it isn't
+     * in the standard format we're looking for, spit out an
+     * error message and return.
+     *
+     * Should we also check compression method here?
+     */
+    /* if ( (   rowsPerStrip != 1) */
+    if ( (samplesPerPixel != 1)
+        || (  bitsPerSample != 8)
+        || (   planarConfig != 1) )
+    {
+        fprintf(stderr,"*** geoTIFF file %s is not in the proper format:\n", file);
+        if (samplesPerPixel != 1)
+            fprintf(stderr,"***** Has %d samples per pixel instead of 1\n",
+                    samplesPerPixel);
+        if (bitsPerSample != 8)
+            fprintf(stderr,"***** Has %d bits per sample instead of 8\n",
+                    bitsPerSample);
+        if (planarConfig != 1)
+            fprintf(stderr,"***** Has planarConfig of %d instead of 1\n",
+                    planarConfig);
+        fprintf(stderr,"*** Please reformat it and try again.\n");
+        XTIFFClose(tif);
+        return;
+    }
+
+
+    if (debug_level & 16)
+        fprintf(stderr,"Loading geoTIFF map: %s\n", file);
+
+
+    /*
+     * Snag the original map colors out of the colormap embedded
+     * inside the tiff file.
+     */
+    if (photometric == PHOTOMETRIC_PALETTE) {
+        if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig))
+        {
+            TIFFError(TIFFFileName(tif), "Missing required \"Colormap\" tag");
+            GTIFFree (gtif);
+            XTIFFClose (tif);
+            return;
+        }
+    }
+
+    /* Here are the number of possible colors.  It turns out to
+     * be 256 for a USGS geotiff file, of which only the first
+     * 13 are used.  Other types of geotiff's may use more
+     * colors (and do).  A proposed revision to the USGS DRG spec
+     * allows using more colors.
+     */
+    num_colors = (1L << bitsPerSample);
+
+
+    /* Print out the colormap info */
+    //if (debug_level & 16) {
+    //    int l;
+    //
+    //    for (l = 0; l < num_colors; l++)
+    //    fprintf(stderr,"   %5u: %5u %5u %5u\n",
+    //    l,
+    //    red_orig[l],
+    //    green_orig[l],
+    //    blue_orig[l]);
+    //}
+    // Example output from a USGS 7.5' map:
+    //
+    //   0:     0     0     0   black
+    //   1: 65280 65280 65280   light grey
+    //   2:     0 38656 41984
+    //   3: 51968     0  5888
+    //   4: 33536 16896  9472   contour lines, brownish-red
+    //   5: 51456 59904 40192   green
+    //   6: 35072 13056 32768   purple?  freeways, some roads
+    //   7: 65280 59904     0
+    //   8: 42752 57856 57856   blue, bodies of water
+    //   9: 65280 47104 47104   red brick color, cities?
+    //  10: 55808 45824 54784   purple.  freeways, some roads
+    //  11: 53504 53504 53504   grey
+    //  12: 52992 41984 36352   contour lines, tan, more dots/less lines
+    //  13:     0     0     0   black, unused slot?
+    //  14:     0     0     0   black, unused slot?
+    //  15:     0     0     0   black, unused slot?
+    //  16:     0     0     0   black, unused slot?
+    // The rest are all 0's.
+    
+
+    if (crop_it)    // USGS geoTIFF map
+    {
+         /*
+         * Next:
+         * Convert the map neat-line corners to image x/y coordinates.
+         * This will give the map neat-line coordinates in pixels.
+         * Use this data to chop the image at these boundaries
+         * and to stretch the shorter lines to fit a rectangle.
+         *
+         * Note that at this stage we're using the bounding coordinates
+         * that are in the map original datum so that the translations
+         * to pixel coordinates will be correct.
+         *
+         * Note that we already have the datum-shifted values for all
+         * the corners in the *_wgs84 variables.  In short:  We use the
+         * non datum-shifted values to work with the tiff file, and the
+         * datum-shifted values to plot the points in Xastir.
+         */
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            GTIFFree (gtif);
+            XTIFFClose (tif);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        if (debug_level & 16)
+            fprintf(stderr,"\nNW neat-line corner = %f\t%f\n",
+                    f_NW_x_bounding,
+                    f_NW_y_bounding);
+
+        xxx = (double)f_NW_x_bounding;
+        yyy = (double)f_NW_y_bounding;
+
+        /* Convert lat/long to projected coordinates */
+        if (  proj_is_latlong || my_GTIFProj4FromLatLong( &defn, 1, &xxx, &yyy ) ) {     // Do all 4 in one call?
+
+            if (debug_level & 16)
+                fprintf(stderr,"%11.3f,%11.3f\n", xxx, yyy);
+
+            /* Convert from PCS coordinates to image pixel coordinates */
+            if ( GTIFPCSToImage( gtif, &xxx, &yyy ) ) { // Do all 4 in one call?
+
+                if (debug_level & 16)
+                    fprintf(stderr,"X/Y Pixels: %f, %f\n", xxx, yyy);
+
+                NW_x = (int)(xxx + 0.5);    /* Tricky way of rounding */
+                NW_y = (int)(yyy + 0.5);    /* Tricky way of rounding */
+
+                if (debug_level & 16)
+                    fprintf(stderr,"X/Y Pixels: %d, %d\n", NW_x, NW_y);
+
+                if (NW_x < 0 || NW_y < 0 || NW_x >= (int)width || NW_y >= (int)height) {
+
+                    fprintf(stderr,
+                        "\nWarning:  NW Neat-line corner calculated at x:%d, y:%d, %s\n",
+                        NW_x,
+                        NW_y,
+                        filenm);
+                    fprintf(stderr,
+                        "Limits are: 0,0 and %ld,%ld. Resetting corner position.\n",
+                        (long int)width,
+                        (long int)height);
+                    fprintf(stderr,
+                        "Map may appear in the wrong location or scale incorrectly.\n");
+
+                    if (NW_x < 0)
+                        NW_x = 0;
+
+                    if (NW_x >= (int)width)
+                        NW_x = width - 1;
+
+                    if (NW_y < 0)
+                        NW_y = 0;
+
+                    if (NW_y >= (int)height)
+                        NW_y = height -1;
+
+/*
+                    //Free any memory used and return
+                    // We're finished with the geoTIFF key parser, so get rid of it
+                    GTIFFree (gtif);
+
+                    // Close the TIFF file descriptor
+                    XTIFFClose (tif);
+ 
+                    return;
+*/
+                }
+            }
+        }
+        else {
+            fprintf(stderr,"Problem in translating\n");
+        }
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            GTIFFree (gtif);
+            XTIFFClose (tif);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+            return;
+        }
+
+        if (debug_level & 16)
+            fprintf(stderr,"NE neat-line corner = %f\t%f\n",
+                    f_NE_x_bounding,
+                    f_NE_y_bounding);
+
+        xxx = (double)f_NE_x_bounding;
+        yyy = (double)f_NE_y_bounding;
+
+        /* Convert lat/long to projected coordinates */
+        if (  proj_is_latlong || my_GTIFProj4FromLatLong( &defn, 1, &xxx, &yyy ) )
+        {
+            if (debug_level & 16)
+                fprintf(stderr,"%11.3f,%11.3f\n", xxx, yyy);
+
+            /* Convert from PCS coordinates to image pixel coordinates */
+            if ( GTIFPCSToImage( gtif, &xxx, &yyy ) )
+            {
+                if (debug_level & 16)
+                    fprintf(stderr,"X/Y Pixels: %f, %f\n", xxx, yyy);
+
+                NE_x = (int)(xxx + 0.5);    /* Tricky way of rounding */
+                NE_y = (int)(yyy + 0.5);    /* Tricky way of rounding */
+
+                if (debug_level & 16)
+                    fprintf(stderr,"X/Y Pixels: %d, %d\n", NE_x, NE_y);
+
+                if (NE_x < 0 || NE_y < 0 || NE_x >= (int)width || NE_y >= (int)height) {
+
+                    fprintf(stderr,
+                        "\nWarning:  NE Neat-line corner calculated at x:%d, y:%d, %s\n",
+                        NE_x,
+                        NE_y,
+                        filenm);
+                    fprintf(stderr,
+                        "Limits are: 0,0 and %ld,%ld. Resetting corner position.\n",
+                        (long int)width,
+                        (long int)height);
+                    fprintf(stderr,
+                        "Map may appear in the wrong location or scale incorrectly.\n");
+
+                    if (NE_x < 0)
+                        NE_x = 0;
+
+                    if (NE_x >= (int)width)
+                        NE_x = width - 1;
+
+                    if (NE_y < 0)
+                        NE_y = 0;
+
+                    if (NE_y >= (int)height)
+                        NE_y = height -1;
+
+/*
+                    //Free any memory used and return
+                    // We're finished with the geoTIFF key parser, so get rid of it
+                    GTIFFree (gtif);
+
+                    // Close the TIFF file descriptor
+                    XTIFFClose (tif);
+ 
+                    return;
+*/
+                }
+            }
+        }
+        else {
+            fprintf(stderr,"Problem in translating\n");
+        }
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            GTIFFree (gtif);
+            XTIFFClose (tif);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+            return;
+        }
+
+        if (debug_level & 16)
+            fprintf(stderr,"SW neat-line corner = %f\t%f\n",
+                    f_SW_x_bounding,
+                    f_SW_y_bounding);
+
+        xxx = (double)f_SW_x_bounding;
+        yyy = (double)f_SW_y_bounding;
+
+        /* Convert lat/long to projected coordinates */
+        if (  proj_is_latlong || my_GTIFProj4FromLatLong( &defn, 1, &xxx, &yyy ) )
+        {
+            if (debug_level & 16)
+                fprintf(stderr,"%11.3f,%11.3f\n", xxx, yyy);
+
+            /* Convert from PCS coordinates to image pixel coordinates */
+            if ( GTIFPCSToImage( gtif, &xxx, &yyy ) )
+            {
+                if (debug_level & 16)
+                    fprintf(stderr,"X/Y Pixels: %f, %f\n", xxx, yyy);
+
+                SW_x = (int)(xxx + 0.5);    /* Tricky way of rounding */
+                SW_y = (int)(yyy + 0.5);    /* Tricky way of rounding */
+
+                if (debug_level & 16)
+                    fprintf(stderr,"X/Y Pixels: %d, %d\n", SW_x, SW_y);
+
+                if (SW_x < 0 || SW_y < 0 || SW_x >= (int)width || SW_y >= (int)height) {
+
+                    fprintf(stderr,
+                        "\nWarning:  SW Neat-line corner calculated at x:%d, y:%d, %s\n",
+                        SW_x,
+                        SW_y,
+                        filenm);
+                    fprintf(stderr,
+                        "Limits are: 0,0 and %ld,%ld. Resetting corner position.\n",
+                        (long int)width,
+                        (long int)height);
+                    fprintf(stderr,
+                        "Map may appear in the wrong location or scale incorrectly.\n");
+
+                    if (SW_x < 0)
+                        SW_x = 0;
+
+                    if (SW_x >= (int)width)
+                        SW_x = width - 1;
+
+                    if (SW_y < 0)
+                        SW_y = 0;
+
+                    if (SW_y >= (int)height)
+                        SW_y = height -1;
+
+/*
+                    //Free any memory used and return
+                    // We're finished with the geoTIFF key parser, so get rid of it
+                    GTIFFree (gtif);
+
+                    // Close the TIFF file descriptor
+                    XTIFFClose (tif);
+ 
+                    return;
+*/
+                }
+            }
+        }
+        else {
+            fprintf(stderr,"Problem in translating\n");
+        }
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            GTIFFree (gtif);
+            XTIFFClose (tif);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+            return;
+        }
+
+        if (debug_level & 16)
+            fprintf(stderr,"SE neat-line corner = %f\t%f\n",
+                    f_SE_x_bounding,
+                    f_SE_y_bounding);
+
+        xxx = (double)f_SE_x_bounding;
+        yyy = (double)f_SE_y_bounding;
+
+        /* Convert lat/long to projected coordinates */
+        if (  proj_is_latlong || my_GTIFProj4FromLatLong( &defn, 1, &xxx, &yyy ) )
+        {
+            if (debug_level & 16)
+                fprintf(stderr,"%11.3f,%11.3f\n", xxx, yyy);
+
+        /* Convert from PCS coordinates to image pixel coordinates */
+        if ( GTIFPCSToImage( gtif, &xxx, &yyy ) )
+        {
+            if (debug_level & 16)
+                fprintf(stderr,"X/Y Pixels: %f, %f\n", xxx, yyy);
+
+            SE_x = (int)(xxx + 0.5);    /* Tricky way of rounding */
+            SE_y = (int)(yyy + 0.5);    /* Tricky way of rounding */
+
+            if (debug_level & 16)
+                fprintf(stderr,"X/Y Pixels: %d, %d\n", SE_x, SE_y);
+
+                if (SE_x < 0 || SE_y < 0 || SE_x >= (int)width || SE_y >= (int)height) {
+
+                    fprintf(stderr,
+                        "\nWarning:  SE Neat-line corner calculated at x:%d, y:%d, %s\n",
+                        SE_x,
+                        SE_y,
+                        filenm);
+                    fprintf(stderr,
+                        "Limits are: 0,0 and %ld,%ld. Resetting corner position.\n",
+                        (long int)width,
+                        (long int)height);
+                    fprintf(stderr,
+                        "Map may appear in the wrong location or scale incorrectly.\n");
+
+                    if (SE_x < 0)
+                        SE_x = 0;
+
+                    if (SE_x >= (int)width)
+                        SE_x = width - 1;
+
+                    if (SE_y < 0)
+                        SE_y = 0;
+
+                    if (SE_y >= (int)height)
+                        SE_y = height -1;
+
+/*
+                    //Free any memory used and return
+                    // We're finished with the geoTIFF key parser, so get rid of it
+                    GTIFFree (gtif);
+
+                    // Close the TIFF file descriptor
+                    XTIFFClose (tif);
+ 
+                    return;
+*/
+                }
+            }
+        }
+        else {
+            fprintf(stderr,"Problem in translating\n");
+        }
+    }
+    else    /*
+             * No map collar to crop off, so we already know
+             * where the corner points are.  This is for non-USGS
+             * maps.
+             */
+    {
+        NW_x = 0;
+        NW_y = 0;
+
+        NE_x = width - 1;
+        NE_y = 0;
+
+        SW_x = 0;
+        SW_y = height - 1;
+
+        SE_x = width - 1;
+        SE_y = height - 1;
+    }
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        GTIFFree (gtif);
+        XTIFFClose (tif);
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+        return;
+    }
+
+    // Here's where we crop off part of the black border for USGS maps.
+    if (crop_it)    // USGS maps only
+    {
+        int i = 3;
+
+        NW_x += i;
+        NW_y += i;
+        NE_x -= i;
+        NE_y += i;
+        SW_x += i;      
+        SW_y -= i;
+        SE_x -= i;
+        SE_y -= i;
+    }
+
+
+    // Now figure out the rough pixel crop values from what we know.
+    // Image rotation means a simple rectangular crop isn't sufficient.
+    if (NW_y < NE_y)
+        top_crop = NW_y;
+    else
+        top_crop = NE_y;
+
+
+    if (SW_y > SE_y)
+        bottom_crop = SW_y;
+    else
+        bottom_crop = SE_y;
+
+ 
+    if (NE_x > SE_x)
+        right_crop = NE_x;
+    else
+        right_crop = SE_x;
+
+ 
+    if (NW_x < SW_x)
+        left_crop = NW_x;
+    else
+        left_crop = SW_x;
+
+
+    if (!crop_it)       /* If we shouldn't crop the map collar... */
+    {
+      top_crop = 0;
+      bottom_crop = height - 1;
+      left_crop = 0;
+      right_crop = width - 1;
+    }
+
+    // The four crop variables are the maximum rectangle that we
+    // wish to keep, rotation notwithstanding (we may want to crop
+    // part of some lines due to rotation).  Crop all lines/pixels
+    // outside these ranges.
+
+//WE7U
+if (top_crop < 0 || top_crop >= (int)height)
+top_crop = 0;
+
+if (bottom_crop < 0 || bottom_crop >= (int)height)
+bottom_crop = height - 1;
+
+if (left_crop < 0 || left_crop >= (int)width)
+left_crop = 0;
+
+if (right_crop < 0 || right_crop >= (int)width)
+right_crop = width - 1;
+
+    if (debug_level & 16) {
+        fprintf(stderr,"Crop points (pixels):\n");
+        fprintf(stderr,"Top: %d\tBottom: %d\tLeft: %d\tRight: %d\n",
+        top_crop,
+        bottom_crop,
+        left_crop,
+        right_crop);
+    }
+
+
+    /*
+     * The color map is embedded in the geoTIFF file as TIFF tags.
+     * We get those tags out of the file and translate to our own
+     * colormap.
+     * Allocate colors for the map image.  We allow up to 256 colors
+     * and allow only 8-bits per pixel in the original map file.  We
+     * get our 24-bit RGB colors right out of the map file itself, so
+     * the colors should look right.
+     * We're picking existing colormap colors that are closest to
+     * the original map colors, so we shouldn't run out of colors
+     * for other applications.
+     *
+     * Brightness adjust for the colors?  Implemented in the
+     * "raster_map_intensity" variable below.
+     */
+
+    {
+        int l;
+
+        switch (photometric) {
+        case PHOTOMETRIC_PALETTE:
+            for (l = 0; l < num_colors; l++)
+            {
+                my_colors[l].red   =   (uint16)(red_orig[l] * raster_map_intensity);
+                my_colors[l].green = (uint16)(green_orig[l] * raster_map_intensity);
+                my_colors[l].blue  =  (uint16)(blue_orig[l] * raster_map_intensity);
+
+                if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                    XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                    XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+                }
+                else {
+                    pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                    &my_colors[l].pixel);
+                }
+            }
+            break;
+        case PHOTOMETRIC_MINISBLACK:
+            for (l = 0; l < num_colors; l++)
+            {
+                int v = (l * 255) / (num_colors-1);
+                my_colors[l].red = my_colors[l].green = my_colors[l].blue =
+                    (uint16)(v * raster_map_intensity) << 8;
+
+                if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                    XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                    XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+                }
+                else {
+                    pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                    &my_colors[l].pixel);
+                }
+            }
+            break;
+        case PHOTOMETRIC_MINISWHITE:
+            for (l = 0; l < num_colors; l++)
+            {
+                int v = (((num_colors-1)-l) * 255) / (num_colors-1);
+                my_colors[l].red = my_colors[l].green = my_colors[l].blue =
+                  (uint16)(v * raster_map_intensity) << 8;
+
+                if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                    XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                    XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+                }
+                else {
+                    pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                    &my_colors[l].pixel);
+                }
+            }
+            break;
+        }
+    }
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        GTIFFree (gtif);
+        XTIFFClose (tif);
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+        return;
+    }
+
+    // Each data value should be an 8-bit value, which is a
+    // pointer into a color
+    // table.  Later we perform a translation from the geoTIFF
+    // color table to our current color table (matching values
+    // as close as possible), at the point where we're writing
+    // the image to the pixmap.
+
+
+    /* We should be ready now to actually read in some
+     * pixels and deposit them on the screen.  We will
+     * allocate memory for the data area based on the
+     * sizes of fields and data in the geoTIFF file.
+     */
+
+    bytesPerRow = TIFFScanlineSize(tif);
+
+    if (debug_level & 16) {
+        fprintf(stderr,"\nInitial Bytes Per Row: %d\n", bytesPerRow);
+    }
+
+
+    // Here's a tiny malloc that'll hold only one scanline worth of pixels
+    imageMemory = (u_char *) malloc(bytesPerRow + 2);
+    CHECKMALLOC(imageMemory);
+
+
+    // TODO:  Figure out the middle boundary on each edge for
+    // lat/long and adjust the crop values to match the largest
+    // of either the middle or the corners for each edge.  This
+    // will help to handle edges that are curved.
+
+
+    /*
+     * There are some optimizations that can still be done:
+     *
+     * 1) Read in all scanlines but throw away unneeded pixels,
+     *    paying attention not to lose smaller details.  Compare
+     *    neighboring pixels?
+     *
+     * 3) Keep a map cache or a screenmap cache to reduce need
+     *    for reading map files so often.
+     */
+
+
+
+    // Here we wish to start at the top line that may have
+    // some pixels of interest and proceed to the bottom line
+    // of interest.  Process scanlines from top_crop to bottom_crop.
+    // Start at the left/right_crop pixels, compute the lat/long
+    // of each, using x/y increments so we can quickly scan across
+    // the line.
+    // Iterate across the line checking whether each pixel is
+    // within the viewport.  If so, plot it on the pixmap at
+    // the correct scale.
+
+    // Later I may wish to get the lat/lon of each pixel and plot
+    // it at the correct point, to handle the curvature of each
+    // line (this might be VERY slow).  Right now I treat them as
+    // straight lines.
+
+    // At this point we have these variables defined.  The
+    // first column contains map corners in Xastir coordinates,
+    // the second column contains map corners in pixels:
+    //
+    // NW corner:
+    // NW_x_bounding_wgs84  <-> NW_x
+    // NW_y_bounding_wgs84  <-> NW_y
+    //
+    // NE corner:
+    // NE_x_bounding_wgs84  <-> NE_x
+    // NE_y_bounding_wgs84  <-> NE_y
+    //
+    // SW corner:
+    // SW_x_bounding_wgs84  <-> SW_x
+    // SW_y_bounding_wgs84  <-> SW_y
+    //
+    // SE corner:
+    // SE_x_bounding_wgs84  <-> SE_x
+    // SE_y_bounding_wgs84  <-> SE_y
+
+    // I should be able to use these variables to figure out
+    // the xastir coordinates of each scanline pixel using
+    // linear interpolation along each edge.
+    //
+    // I don't want to use the crop values in general.  I'd
+    // rather crop properly along the neat line instead of a
+    // rectangular crop.
+    //
+    // Define lines along the left/right edges so that I can
+    // compute the Xastir coordinates of each pixel along these
+    // two lines.  These will be the start/finish of each of my
+    // scanlines, and I can use these values to compute the
+    // x/y_increment values for each line.  This way I can
+    // stretch short lines as I go along, and auto-crop the
+    // white border as well.
+
+    // Left_line goes from (top to bottom):
+    // NW_x,NW_y -> SW_x,SW_y
+    // and from:
+    // west_bounding_wgs84,north_bounding_wgs84 -> west_bounding_wgs84,south_bounding_wgs84
+    //
+    // Right_line goes from(top to bottom):
+    // NE_x,NE_y -> SE_x,SE-Y
+    // and from:
+    // east_bounding_wgs84,north_bounding_wgs84 -> east_bounding_wgs84,south_bounding_wgs84
+    //
+    // Simpler:  Along each line, Xastir coordinates change how much
+    // and in what direction as we move down one scanline?
+
+
+    // These increments are how much we change in Xastir coordinates and
+    // in pixel coordinates as we move down either the left or right
+    // neatline one pixel.
+    // Be prepared for 0 angle of rotation as well (x-increments = 0).
+
+
+    // Xastir Coordinate System:
+    //
+    //              0 (90 deg. or 90N)
+    //
+    // 0 (-180 deg. or 180W)      129,600,000 (180 deg. or 180E)
+    //
+    //          64,800,000 (-90 deg. or 90S)
+
+
+    // Watch out for division by zero here.
+
+
+    //
+    // Left Edge X Increment Per Scanline (Going from top to bottom).
+    // This increment will help me to keep track of the left edge of
+    // the image, both in Xastir coordinates and in pixel coordinates.
+    //
+    if (SW_y != NW_y)
+    {
+        // Xastir coordinates
+        xastir_left_x_increment = (float)
+            (1.0 * abs(SW_x_bounding_wgs84 - NW_x_bounding_wgs84)   // Need to add one pixel worth here yet
+            / abs(SW_y - NW_y));
+
+        // Pixel coordinates
+        left_x_increment = (float)(1.0 * abs(SW_x - NW_x)
+                            / abs(SW_y - NW_y));
+
+        if (SW_x_bounding_wgs84 < NW_x_bounding_wgs84)
+            xastir_left_x_increment = -xastir_left_x_increment;
+
+        if (SW_x < NW_x)
+            left_x_increment = -left_x_increment;
+
+//WE7U
+//if (abs(left_x_increment) > (width/10)) {
+//    left_x_increment = 0.0;
+//    xastir_left_x_increment = 0.0;
+//}
+
+        if (debug_level & 16)
+             fprintf(stderr,"xastir_left_x_increment: %f  %ld  %ld     %f  %d  %d  %d  %d\n",
+             xastir_left_x_increment,
+             SW_x_bounding_wgs84,
+             NW_x_bounding_wgs84,
+             left_x_increment,
+             SW_x,
+             NW_x,
+             bottom_crop,
+             top_crop);
+    }
+    else
+    {
+        // Xastir coordinates
+        xastir_left_x_increment = 0;
+
+        // Pixel coordinates
+        left_x_increment = 0;
+    }
+
+
+    //
+    // Left Edge Y Increment Per Scanline (Going from top to bottom)
+    // This increment will help me to keep track of the left edge of
+    // the image, both in Xastir coordinates and in pixel coordinates.
+    //
+    if (SW_y != NW_y)
+    {
+        // Xastir coordinates
+        xastir_left_y_increment = (float)
+            (1.0 * abs(SW_y_bounding_wgs84 - NW_y_bounding_wgs84)   // Need to add one pixel worth here yet
+            / abs(SW_y - NW_y));
+
+        // Pixel coordinates
+        left_y_increment = (float)1.0; // Aren't we going down one pixel each time?
+
+        if (SW_y_bounding_wgs84 < NW_y_bounding_wgs84)  // Ain't gonn'a happen
+            xastir_left_y_increment = -xastir_left_y_increment;
+
+//WE7U
+//if (abs(left_y_increment) > (width/10)) {
+//    xastir_left_y_increment = 0.0;
+//}
+
+        if (debug_level & 16)
+             fprintf(stderr,"xastir_left_y_increment: %f  %ld  %ld     %f  %d  %d  %d  %d\n",
+             xastir_left_y_increment,
+             SW_y_bounding_wgs84,
+             NW_y_bounding_wgs84,
+             left_y_increment,
+             SW_y,
+             NW_y,
+             bottom_crop,
+             top_crop);
+    }
+    else
+    {
+        // Xastir coordinates
+        xastir_left_y_increment = 0;
+
+        // Pixel coordinates
+        left_y_increment = 0;
+    }
+
+
+    //
+    // Right Edge X Increment Per Scanline (Going from top to bottom)
+    // This increment will help me to keep track of the right edge of
+    // the image, both in Xastir coordinates and image coordinates.
+    //
+    if (SE_y != NE_y)
+    {
+        // Xastir coordinates
+        xastir_right_x_increment = (float)
+            (1.0 * abs(SE_x_bounding_wgs84 - NE_x_bounding_wgs84)   // Need to add one pixel worth here yet
+            / abs(SE_y - NE_y));
+
+        // Pixel coordinates
+        right_x_increment = (float)(1.0 * abs(SE_x - NE_x)
+                            / abs(SE_y - NE_y));
+
+        if (SE_x_bounding_wgs84 < NE_x_bounding_wgs84)
+            xastir_right_x_increment = -xastir_right_x_increment;
+
+        if (SE_x < NE_x)
+            right_x_increment = -right_x_increment;
+
+//WE7U
+//if (abs(right_x_increment) > (width/10)) {
+//    right_x_increment = 0.0;
+//    xastir_right_x_increment = 0.0;
+//}
+
+        if (debug_level & 16)
+            fprintf(stderr,"xastir_right_x_increment: %f  %ld  %ld     %f  %d  %d  %d  %d\n",
+            xastir_right_x_increment,
+            SE_x_bounding_wgs84,
+            NE_x_bounding_wgs84,
+            right_x_increment,
+            SE_x,
+            NE_x,
+            bottom_crop,
+            top_crop);
+    }
+    else
+    {
+        // Xastir coordinates
+        xastir_right_x_increment = 0;
+
+        // Pixel coordinates
+        right_x_increment = 0;
+    }
+
+
+    //
+    // Right Edge Y Increment Per Scanline (Going from top to bottom)
+    // This increment will help me to keep track of the right edge of
+    // the image, both in Xastir coordinates and in image coordinates.
+    //
+    if (SE_y != NE_y)
+    {
+        // Xastir coordinates
+        xastir_right_y_increment = (float)
+            (1.0 * abs(SE_y_bounding_wgs84 - NE_y_bounding_wgs84)   // Need to add one pixel worth here yet
+            / abs(SE_y - NE_y));
+
+        // Pixel coordinates
+        right_y_increment = (float)1.0;    // Aren't we going down one pixel each time?
+
+        if (SE_y_bounding_wgs84 < NE_y_bounding_wgs84)  // Ain't gonn'a happen
+            xastir_right_y_increment = -xastir_right_y_increment;
+
+//WE7U
+//if (abs(right_y_increment) > (width/10)) {
+//    xastir_right_y_increment = 0.0;
+//}
+
+        if (debug_level & 16)
+            fprintf(stderr,"xastir_right_y_increment: %f  %ld  %ld     %f  %d  %d  %d  %d\n",
+            xastir_right_y_increment,
+            SE_y_bounding_wgs84,
+            NE_y_bounding_wgs84,
+            right_y_increment,
+            SE_y,
+            NE_y,
+            bottom_crop,
+            top_crop);
+    }
+    else
+    {
+        // Xastir coordinates
+        xastir_right_y_increment = 0;
+
+        // Pixel coordinates
+        right_y_increment = 0;
+    }
+
+
+    if (debug_level & 16) {
+        fprintf(stderr," Left x increments: %f %f\n", xastir_left_x_increment, left_x_increment);
+        fprintf(stderr," Left y increments: %f %f\n", xastir_left_y_increment, left_y_increment);
+        fprintf(stderr,"Right x increments: %f %f\n", xastir_right_x_increment, right_x_increment);
+        fprintf(stderr,"Right y increments: %f %f\n", xastir_right_y_increment, right_y_increment);
+    }
+
+
+    // Compute how much "y" changes per pixel as we traverse from left to right
+    // along a scanline along the top of the image.
+    //
+    // Top Edge Y Increment Per X-Pixel Width (Going from left to right).
+    // This increment will help me to get rid of image rotation.
+    //
+    if (NE_x != NW_x)
+    {
+        // Xastir coordinates
+        xastir_top_y_increment = (float)
+            (1.0 * abs(NE_y_bounding_wgs84 - NW_y_bounding_wgs84)   // Need to add one pixel worth here yet
+            / abs(NE_x - NW_x));    // And a "+ 1.0" here?
+
+        // Pixel coordinates
+        top_y_increment = (float)(1.0 * abs(NE_y - NW_y)
+                    / abs(NE_x - NW_x));
+
+        if (NE_y_bounding_wgs84 < NW_y_bounding_wgs84)
+            xastir_top_y_increment = -xastir_top_y_increment;
+
+        if (NE_y < NW_y)
+            top_y_increment = -top_y_increment;
+
+        if (debug_level & 16)
+            fprintf(stderr,"xastir_top_y_increment: %f  %ld  %ld     %f  %d  %d  %d  %d\n",
+            xastir_top_y_increment,
+            NE_y_bounding_wgs84,
+            NW_y_bounding_wgs84,
+            top_y_increment,
+            NE_y,
+            NW_y,
+            right_crop,
+            left_crop);
+    }
+    else
+    {
+        // Xastir coordinates
+        xastir_top_y_increment = 0;
+
+        // Pixel coordinates
+        top_y_increment = 0;
+    }
+
+
+    // Compute how much "y" changes per pixel as you traverse from left to right
+    // along a scanline along the bottom of the image.
+    //
+    // Bottom Edge Y Increment Per X-Pixel Width (Going from left to right).
+    // This increment will help me to get rid of image rotation.
+    //
+    if (SE_x != SW_x)
+    {
+        // Xastir coordinates
+        xastir_bottom_y_increment = (float)
+            (1.0 * abs(SE_y_bounding_wgs84 - SW_y_bounding_wgs84)   // Need to add one pixel worth here yet
+            / abs(SE_x - SW_x));    // And a "+ 1.0" here?
+
+        // Pixel coordinates
+        bottom_y_increment = (float)(1.0 * abs(SE_y - SW_y)
+                        / abs(SE_x - SW_x));
+
+        if (SE_y_bounding_wgs84 < SW_y_bounding_wgs84)  
+            xastir_bottom_y_increment = -xastir_bottom_y_increment;
+
+        if (SE_y < SW_y)
+            bottom_y_increment = -bottom_y_increment;
+
+        if (debug_level & 16)
+            fprintf(stderr,"xastir_bottom_y_increment: %f  %ld  %ld     %f  %d  %d  %d  %d\n",
+            xastir_bottom_y_increment,
+            SE_y_bounding_wgs84,
+            SW_y_bounding_wgs84,
+            bottom_y_increment,
+            SE_y,
+            SW_y,
+            right_crop,
+            left_crop);
+    }
+    else
+    {
+        // Xastir coordinates
+        xastir_bottom_y_increment = 0;
+
+        // Pixel coordinates
+        bottom_y_increment = 0;
+    }
+
+
+    // Find the average change in Y as we traverse from left to right one pixel
+    xastir_avg_y_increment = (float)(xastir_top_y_increment + xastir_bottom_y_increment) / 2.0;
+    avg_y_increment = (float)(top_y_increment + bottom_y_increment) / 2.0;
+
+
+    // Find edges of current viewport in Xastir coordinates
+    //
+    view_min_x = NW_corner_longitude;  // left edge of view
+    if (view_min_x > 129600000l)
+        view_min_x = 0;
+
+    view_max_x = SE_corner_longitude; // right edge of view 
+    if (view_max_x > 129600000l)
+        view_max_x = 129600000l;
+
+    view_min_y = NW_corner_latitude;   // top edge of view
+    if (view_min_y > 64800000l)
+        view_min_y = 0;
+
+    view_max_y = SE_corner_latitude;  // bottom edge of view
+    if (view_max_y > 64800000l)
+        view_max_y = 64800000l;
+
+
+    /* Get the pixel scale */
+    have_PixelScale = TIFFGetField( tif, TIFFTAG_GEOPIXELSCALE, &qty, &PixelScale );
+    if (debug_level & 16) {
+        if (have_PixelScale) {
+            fprintf(stderr,"PixelScale: %f %f %f\n",
+                *PixelScale,
+                *(PixelScale + 1),
+                *(PixelScale + 2) );
+        }
+        else {
+            fprintf(stderr,"No PixelScale tag found in file\n");
+        }
+    }
+
+
+    // Use PixelScale to determine lines to skip at each
+    // zoom level?
+    // O-size map:
+    // ModelPixelScaleTag (1,3):
+    //   2.4384           2.4384           0
+    //
+    // F-size map:
+    // ModelPixelScaleTag (1,3):
+    //   10.16            10.16            0                
+    //
+    // C-size map:
+    // ModelPixelScaleTag (1,3):
+    //   25.400001        25.400001        0                
+    //
+
+    if (debug_level & 16)
+        fprintf(stderr,"Size: x %ld, y %ld\n", scale_x,scale_y);
+
+
+    // I tried to be very aggressive with the scaling factor
+    // below (3.15) in order to skip the most possible rows
+    // to speed things up.  If you see diagonal lines across
+    // the maps, increase this number (up to a max of 4.0
+    // probably).  A higher number means less rows skipped,
+    // which improves the look but slows the map drawing down.
+    //
+    // This needs modification somewhat when the raster is already in 
+    // lat/long, and the PixelScale is already in degrees per pixel.
+    // The scale_y is the integer number of hundredths of seconds per pixel.
+    // The decision of how many rows to skip can simply be made by converting
+    // the PixelScale to the same units as scale_y, and skipping accordingly.
+
+    if (have_PixelScale) {
+        double coef;
+        if (!proj_is_latlong) {
+            coef = 3.15;
+        } 
+        else {
+            coef=100*60*60;  // xastir coords are in 1/100 of a second,
+                             // and lat/lon pixel scales will be in degrees
+        }
+        SkipRows = (int)( ( scale_y / ( *PixelScale * coef ) ) + 0.5 );
+        if (SkipRows < 1)
+            SkipRows = 1;
+        if (SkipRows > (int)(height / 10) )
+            SkipRows = height / 10;
+    }
+    else {
+        SkipRows = 1;
+    }
+    if (debug_level & 16)
+        fprintf(stderr,"SkipRows: %d\n", SkipRows);
+
+    // Use SkipRows to set increments for the loops below.
+
+
+    if ( top_crop <= 0 )
+        top_crop = 0;               // First row of image
+
+    if ( ( bottom_crop + 1) >= (int)height )
+        bottom_crop = height - 1;   // Last row of image
+
+    // Here I pre-compute some of the values I'll need in the
+    // loops below in order to save some time.
+    NW_line_offset = (int)(NW_y - top_crop);
+    NE_line_offset = (int)(NE_y - top_crop);
+
+    NW_xastir_x_offset =  (int)(xastir_left_x_increment * NW_line_offset);
+    NE_xastir_x_offset = (int)(xastir_right_x_increment * NE_line_offset);
+    NW_xastir_y_offset =  (int)(xastir_left_y_increment * NW_line_offset);
+
+    NW_x_offset =  (int)(1.0 * left_x_increment * NW_line_offset);
+    NE_x_offset = (int)(1.0 * right_x_increment * NE_line_offset);
+    xastir_avg_left_right_y_increment = (float)((xastir_right_y_increment + xastir_left_y_increment) / 2.0);
+    total_avg_y_increment = (float)(xastir_avg_left_right_y_increment * avg_y_increment);
+
+
+    // (Xastir bottom - Xastir top) / height
+    //steph = (double)( (left_y_increment + right_y_increment) / 2); 
+    // NOTE:  This one does not take into account current height
+    steph = (float)( (SW_y_bounding_wgs84 - NW_y_bounding_wgs84)
+                      / (1.0 * (SW_y - NW_y) ) );
+
+    // Compute scaled pixel size for XFillRectangle
+    stephc = (int)( ( (1.50 * steph / scale_x) + 1.0) + 1.5);
+
+    view_top_minus_pixel_height = (unsigned long)(view_min_y - steph);
+
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        if (imageMemory)
+            free(imageMemory);
+        GTIFFree (gtif);
+        XTIFFClose (tif);
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+        return;
+    }
+
+
+    // Set the bit-blitting function to XOR.  This is only used if
+    // DRG_XOR_colors is set to a non-zero value, but we set it here
+    // outside the pixel loop for speed reasons.
+    //
+    if (DRG_XOR_colors) {
+        (void)XSetLineAttributes (XtDisplay (w), gc_tint, 1, LineSolid, CapButt,JoinMiter);
+
+//        (void)XSetForeground (XtDisplay (w), gc_tint, colors[0x27]);  // yellow
+//        (void)XSetForeground (XtDisplay (w), gc_tint, colors[0x0f]); // White
+//        (void)XSetForeground (XtDisplay (w), gc_tint, colors[0x03]); // cyan
+//        (void)XSetForeground (XtDisplay (w), gc_tint, colors[0x06]); // orange
+ 
+        (void)XSetFunction (XtDisplay (da), gc_tint, GXxor);
+    }
+
+
+    // Iterate over the rows of interest only.  Using the rectangular
+    // top/bottom crop values for these is ok at this point.
+    //
+    // Put row multipliers above loops.  Try to get as many
+    // multiplications as possible outside the loops.  Adds and
+    // subtracts are ok.  Try to do as little floating point stuff
+    // as possible inside the loops.  I also declared a lot of
+    // the inner loop stuff as register variables.  Saved me about
+    // a second per map (not much, but I'll take what I can get!)
+    //
+    for ( row = top_crop; (int)row < bottom_crop + 1; row+= SkipRows )
+    {
+        int skip = 0;
+
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            if (imageMemory)
+                free(imageMemory);
+            GTIFFree (gtif);
+            XTIFFClose (tif);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),pixmap,XtWindow(da),gc,0,0,screen_width,screen_height,0,0);
+            return;
+        }
+
+        // Our offset from the top row of the map neatline
+        // (kind of... ignoring rotation anyway).
+        row_offset = row - top_crop;
+        //fprintf(stderr,"row_offset: %d\n", row_offset);
+
+
+        // Compute the line end-points in Xastir coordinates
+        // Initially was a problem here:  Offsetting from NW_x_bounding but
+        // starting at top_crop line.  Fixed by last term added to two
+        // equations below.
+
+        current_xastir_left = (unsigned long)
+              ( NW_x_bounding_wgs84
+            + ( 1.0 * xastir_left_x_increment * row_offset )
+            -   NW_xastir_x_offset );
+
+        current_xastir_right = (unsigned long)
+              ( NE_x_bounding_wgs84
+            + ( 1.0 * xastir_right_x_increment * row_offset )
+            -   NE_xastir_x_offset );
+
+
+        //if (debug_level & 16)
+        //  fprintf(stderr,"Left: %ld  Right:  %ld\n",
+        //      current_xastir_left,
+        //      current_xastir_right);
+
+
+        // In pixel coordinates:
+        current_left = (int)
+                          ( NW_x
+                        + ( 1.0 * left_x_increment * row_offset ) + 0.5
+                        -   NW_x_offset );
+
+        current_right = (int)
+                          ( NE_x
+                        + ( 1.0 * right_x_increment * row_offset ) + 0.5
+                        -   NE_x_offset );
+
+//WE7U:  This comparison is always false:  current_left is unsigned
+//therefore always positive!
+//if (current_left < 0)
+//    current_left = 0;
+
+if (current_right >= width)
+    current_right = width - 1;
+
+        current_line_width = current_right - current_left + 1;  // Pixels
+
+
+        // if (debug_level & 16)
+        //     fprintf(stderr,"Left: %ld  Right: %ld  Width: %ld\n",
+        //         current_left,
+        //         current_right, current_line_width);
+
+
+        // Compute original pixel size in Xastir coordinates.  Note
+        // that this can change for each scanline in a USGS geoTIFF.
+
+        // (Xastir right - Xastir left) / width-of-line
+        // Need the "1.0 *" or the math will be incorrect (won't be a float)
+        stepw = (float)( (current_xastir_right - current_xastir_left)
+                      / (1.0 * (current_right - current_left) ) );
+
+
+
+        // if (debug_level & 16)
+        //     fprintf(stderr,"\t\t\t\t\t\tPixel Width: %f\n",stepw);
+
+        // Compute scaled pixel size for XFillRectangle
+        stepwc = (int)( ( (1.0 * stepw / scale_x) + 1.0) + 0.5);
+
+
+        // In Xastir coordinates
+        xastir_current_y = (unsigned long)(NW_y_bounding_wgs84
+                  + (xastir_left_y_increment * row_offset) );
+
+        xastir_current_y = (unsigned long)(xastir_current_y - NW_xastir_y_offset);
+
+
+        view_left_minus_pixel_width = view_min_x - stepw;
+
+
+        // Check whether any part of the scanline will be within the
+        // view.  If so, read the scanline from the file and iterate
+        // across the pixels.  If not, skip this line altogether.
+
+        // Compute right edge of image
+        xastir_total_y = (unsigned long)
+                           ( xastir_current_y
+                         - ( total_avg_y_increment * (current_right - current_left) ) );
+
+        // Check left edge y-value then right edge y-value.
+        // If either are within view, process the line, else skip it.
+        if ( ( ( xastir_current_y <= view_max_y) && (xastir_total_y >= view_top_minus_pixel_height) )
+            || ( ( xastir_total_y <= view_max_y ) && ( xastir_total_y >= view_top_minus_pixel_height ) ) )
+        {
+            // Read one geoTIFF scanline
+            if (TIFFReadScanline(tif, imageMemory, row, 0) < 0)
+                break;  // No more lines to read or we couldn't read the file at all
+
+
+            // Iterate over the columns of interest, skipping the left/right
+            // cropped pixels, looking for pixels that fit within our viewport.
+            //
+            for ( column = current_left; column < (current_right + 1); column++ )
+            {
+                skip = 0;
+
+
+                column_offset = column - current_left;  // Pixels
+
+                //fprintf(stderr,"Column Offset: %ld\n", column_offset);  // Pixels
+                //fprintf(stderr,"Current Left: %ld\n", current_left);    // Pixels
+
+                xastir_current_x = (unsigned long)
+                                    current_xastir_left
+                                    + (stepw * column_offset);    // In Xastir coordinates
+
+                // Left line y value minus
+                // avg y-increment per scanline * avg y-increment per x-pixel * column_offset
+                xastir_total_y = (unsigned long)
+                                  ( xastir_current_y
+                                - ( total_avg_y_increment * column_offset ) );
+
+                //fprintf(stderr,"Xastir current: %ld %ld\n", xastir_current_x, xastir_current_y);
+
+
+                // Check whether pixel fits within boundary lines (USGS maps)
+                // This is how we get rid of the last bit of white border at
+                // the top and bottom of the image.
+                if (have_fgd)   // USGS map
+                {
+                    if (   (xastir_total_y > SW_y_bounding_wgs84)
+                        || (xastir_total_y < NW_y_bounding_wgs84) )
+                    skip++;
+
+
+                    // Here's a trick to make it look like the map pages join better.
+                    // If we're within a certain distance of a border, change any black
+                    // pixels to white (changes map border to less obtrusive color).
+                    if ( *(imageMemory + column) == 0x00 )  // If pixel is Black
+                    {
+                        if ( (xastir_total_y > (SW_y_bounding_wgs84 - 25) )
+                            || (xastir_total_y < (NW_y_bounding_wgs84 + 25) )
+                            || (xastir_current_x < (SW_x_bounding_wgs84 + 25) )
+                            || (xastir_current_x > (SE_x_bounding_wgs84 - 25) ) )
+                        {
+//WE7U: column is unsigned so "column >= 0" is always true
+//                            if ((int)column < bytesPerRow && column >= 0) {
+                            if ((int)column < bytesPerRow) {
+ 
+                                *(imageMemory + column) = 0x01; // Change to White
+                            }
+                            else {
+//WE7U
+//                                fprintf(stderr,"draw_geotiff_image_map: Bad fgd file for map?: %s\n", filenm);
+                            }
+                        }
+                    }
+                }
+
+
+                /* Look for left or right map boundaries inside view */    
+                if ( !skip
+                    && ( xastir_current_x <= view_max_x )
+                    && ( xastir_current_x >= view_left_minus_pixel_width )    
+                    && ( xastir_total_y <= view_max_y )
+                    && ( xastir_total_y >= view_top_minus_pixel_height ) )
+                {
+                    // Here are the corners of our viewport, using the Xastir
+                    // coordinate system.  Notice that Y is upside down:
+                    // 
+                    // left edge of view = NW_corner_longitude
+                    // right edge of view = SE_corner_longitude
+                    // top edge of view =  NW_corner_latitude
+                    // bottom edge of view =  SE_corner_latitude
+
+
+                    // Compute the screen position of the pixel and scale it
+                    sxx = (xastir_current_x - NW_corner_longitude) / scale_x;
+                    syy = (xastir_total_y   - NW_corner_latitude ) / scale_y;
+
+
+
+// If we wish some colors to be transparent, we could check for a
+// color match here and refuse to draw those that are on our list of
+// transparent colors.  Might be useful for drawing say contour
+// lines on top of satellite images.  Since the USGS topo's use the
+// same colormap for all of the topo's (I believe that is true) then
+// we could just compare on the index into the array instead of the
+// color contents in the array.
+//
+    // Example output from a USGS 7.5' map:
+    //
+    //   0:     0     0     0   black
+    //   1: 65280 65280 65280   light grey
+    //   2:     0 38656 41984
+    //   3: 51968     0  5888
+    //   4: 33536 16896  9472   contour lines, brownish-red
+    //   5: 51456 59904 40192   green
+    //   6: 35072 13056 32768   purple?  freeways, some roads
+    //   7: 65280 59904     0
+    //   8: 42752 57856 57856   blue, bodies of water
+    //   9: 65280 47104 47104   red brick color, cities?
+    //  10: 55808 45824 54784   purple.  freeways, some roads
+    //  11: 53504 53504 53504   grey
+    //  12: 52992 41984 36352   contour lines, tan, more dots/less lines
+    //  13:     0     0     0   black, unused slot?
+    //  14:     0     0     0   black, unused slot?
+    //  15:     0     0     0   black, unused slot?
+    //  16:     0     0     0   black, unused slot?
+    // The rest are all 0's.
+                    // either show all colors (usgs_drg==0) or show selected
+                    // colors (usgs_drg == 1) 
+                    if ( usgs_drg == 0 ||
+                         (usgs_drg ==1 && (*(imageMemory + column) >= 13
+                          || DRG_show_colors[*(imageMemory + column)] == 1))) {
+
+
+                        // If this is set, use gc_tint for drawing
+                        // with "GXxor" as the bit-blit operation.
+                        //
+                        if (DRG_XOR_colors) {
+
+                            // Draw the pixel using "gc_tint"
+                            // instead of "gc".
+
+                            XSetForeground (XtDisplay (w), gc_tint, my_colors[*(imageMemory + column)].pixel);
+ 
+                            XFillRectangle (XtDisplay (w), pixmap, gc_tint, sxx, syy, stepwc, stephc);
+                        }
+                        else {
+
+                            // Set the color for the pixel
+                            XSetForeground (XtDisplay (w), gc, my_colors[*(imageMemory + column)].pixel);
+
+                            // And draw the pixel
+                            XFillRectangle (XtDisplay (w), pixmap, gc, sxx, syy, stepwc, stephc);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /* Free up any malloc's that we did */
+    if (imageMemory)
+        free(imageMemory);
+
+
+    if (debug_level & 16)
+        fprintf(stderr,"%d rows read in\n", (int) row);
+
+    /* We're finished with the geoTIFF key parser, so get rid of it */
+    GTIFFree (gtif);
+
+    /* Close the TIFF file descriptor */
+    XTIFFClose (tif);
+
+    // Close the filehandles that are left open after the
+    // four GTIFImageToPCS calls.
+    //(void)CSVDeaccess(NULL);
+}
+#endif /* HAVE_LIBGEOTIFF */
+
+
diff --git a/src/map_tiger.c b/src/map_tiger.c
new file mode 100644
index 0000000..6cb917d
--- /dev/null
+++ b/src/map_tiger.c
@@ -0,0 +1,969 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: map_tiger.c,v 1.68 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "fetch_remote.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+#include "map_cache.h"
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+#ifdef HAVE_MAGICK
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+#undef RETSIGTYPE
+// TVR: "stupid ImageMagick"
+// The problem is that magick/api.h includes Magick's config.h file, and that
+// pulls in all the same autoconf-generated defines that we use.
+// plays those games below, but I don't think in the end that they actually 
+// make usable macros with our own data in them.
+// Fortunately, we don't need them, so I'll just undef the ones that are
+// causing problems today.  See main.c for fixes that preserve our values.
+#undef PACKAGE
+#undef VERSION
+/* JMT - stupid ImageMagick */
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#ifdef HAVE_GRAPHICSMAGICK
+/*#include <GraphicsMagick/magick/api.h>*/
+#include <magick/api.h>
+#else   // HAVE_GRAPHICSMAGICK
+#include <magick/api.h>
+#endif  // HAVE_GRAPHICSMAGICK 
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#endif // HAVE_MAGICK
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+extern int npoints;		/* tsk tsk tsk -- globals */
+extern int mag;
+
+
+
+
+
+void get_tiger_local_file(char * local_filename, char * fileimg){
+#ifdef HAVE_MAGICK
+
+//  char local_filename[MAX_FILENAME];
+
+//    char fileimg[MAX_FILENAME];     // Ascii name of image file, read from GEO file
+
+
+    time_t query_start_time, query_end_time; 
+
+#ifdef USE_MAP_CACHE 
+    int map_cache_return = 1; // Default = cache miss
+    char *cache_file_id;
+#endif  // USE_MAP_CACHE
+
+    char temp_file_path[MAX_VALUE];
+
+    if (debug_level & 512) {
+        query_start_time=time(&query_start_time); 
+    }
+
+
+#ifdef USE_MAP_CACHE 
+
+    if (!map_cache_fetch_disable) {
+
+        // Delete old copy from the cache
+        if (map_cache_fetch_disable && fileimg[0] != '\0') {
+            if (map_cache_del(fileimg)) {
+                if (debug_level & 512) {
+                    fprintf(stderr,"Couldn't delete old map from cache\n");
+                }
+            }
+        }
+
+set_dangerous("map_tiger: map_cache_get");
+	map_cache_return = map_cache_get(fileimg,local_filename); 
+clear_dangerous();
+    }
+
+    if (debug_level & 512) {
+            fprintf(stderr,"map_cache_return: <%d> bytes returned: %d\n",
+                map_cache_return,
+                (int) strlen(local_filename));
+    }
+   
+    if (map_cache_return != 0 ) {
+
+set_dangerous("map_tiger: map_cache_fileid");
+        cache_file_id = map_cache_fileid();
+        xastir_snprintf(local_filename,
+            MAX_FILENAME,           // hardcoded to avoid sizeof()
+            "%s/map_%s.%s",
+            get_user_base_dir("map_cache", temp_file_path, sizeof(temp_file_path)),
+            cache_file_id,
+            "gif");
+        free(cache_file_id);
+clear_dangerous();
+
+#else   // USE_MAP_CACHE
+
+    xastir_snprintf(local_filename,
+        MAX_FILENAME,               // hardcoded to avoid sizeof()
+        "%s/map.%s",
+         get_user_base_dir("tmp", temp_file_path, sizeof(temp_file_path)),
+        "gif");
+
+#endif  // USE_MAP_CACHE
+
+
+    // Erase any previously existing local file by the same name.
+    // This avoids the problem of having an old map image here and
+    // the code trying to display it when the download fails.
+
+    unlink( local_filename );
+
+    if (fetch_remote_file(fileimg, local_filename)) {
+        // Had trouble getting the file.  Abort.
+        return;
+    }
+
+    // For debugging the MagickError/MagickWarning segfaults.
+    //system("cat /dev/null >/var/tmp/xastir_hacker_map.gif");
+   
+ 
+#ifdef USE_MAP_CACHE
+
+set_dangerous("map_tiger: map_cache_put");
+	map_cache_put(fileimg,local_filename); 
+clear_dangerous();
+
+        } // end if is cached  DHBROWN
+
+#endif // MAP_CACHE
+
+
+    if (debug_level & 512) {
+        fprintf (stderr, "Fetch or query took %d seconds\n", 
+            (int) (time(&query_end_time) - query_start_time)); 
+    }
+
+    // Set permissions on the file so that any user can overwrite it.
+    chmod(local_filename, 0666);
+
+#endif  //HAVE_MAGICK
+
+} // end get_tiger_local_file
+
+
+
+
+
+/**********************************************************
+ * draw_tiger_map()
+ * N0VH
+ **********************************************************/
+#ifdef HAVE_MAGICK
+void draw_tiger_map (Widget w,
+        char *filenm,
+        int destination_pixmap,
+        int nocache) {  // For future implementation of a "refresh cached map" option
+    char file[MAX_FILENAME];        // Complete path/name of image file
+    char short_filenm[MAX_FILENAME];
+    FILE *f;                        // Filehandle of image file
+    char fileimg[MAX_FILENAME];     // Ascii name of image file, read from GEO file
+    char tigertmp[MAX_FILENAME*2];  // Used for putting together the tigermap query
+    int width, height;
+    tiepoint tp[2];                 // Calibration points for map, read in from .geo file
+    register long map_c_T, map_c_L; // map delta NW edge coordinates, DNN: these should be signed
+    register long tp_c_dx, tp_c_dy; // tiepoint coordinate differences
+    unsigned long c_x_min,  c_y_min;// top left coordinates of map inside screen
+    unsigned long c_y_max;          // bottom right coordinates of map inside screen
+    double c_x;                     // Xastir coordinates 1/100 sec, 0 = 180�W
+    double c_y;                     // Xastir coordinates 1/100 sec, 0 =  90�N
+
+    long map_y_0;                   // map pixel pointer prior to TM adjustment
+    register long map_x, map_y;     // map pixel pointers, DNN: this was a float, chg to long
+    long map_x_min, map_x_max;      // map boundaries for in screen part of map
+    long map_y_min, map_y_max;      //
+    long map_x_ctr;                 // half map width in pixel
+    long map_y_ctr;                 // half map height in pixel
+    int map_seen = 0;
+    int map_act;
+    int map_done;
+
+    long map_c_yc;                  // map center, vert coordinate
+    long map_c_xc;                  // map center, hor  coordinate
+    double map_c_dx, map_c_dy;      // map coordinates increment (pixel width)
+    double c_dx;                    // adjusted map pixel width
+
+    long scr_x,  scr_y;             // screen pixel plot positions
+    long scr_xp, scr_yp;            // previous screen plot positions
+    int  scr_dx, scr_dy;            // increments in screen plot positions
+    long scr_x_mc;                  // map center in screen units
+
+    long scr_c_xr;
+
+    long scale_xa;                  // adjusted for topo maps
+    double scale_x_nm;              // nm per Xastir coordinate unit
+    long scale_x0;                  // at widest map area
+
+    char local_filename[MAX_FILENAME];
+    
+    ExceptionInfo exception;
+    Image *image;
+    ImageInfo *image_info;
+    PixelPacket *pixel_pack;
+    PixelPacket temp_pack;
+    IndexPacket *index_pack;
+    int l;
+    XColor my_colors[256];
+    double left, right, top, bottom, map_width, map_height;
+    double lat_center  = 0;
+    double long_center = 0;
+
+    char map_it[MAX_FILENAME];
+    char tmpstr[100];
+    int geo_image_width;        // Image width  from GEO file
+    int geo_image_height;       // Image height from GEO file
+
+    // initialize this
+    local_filename[0]='\0';
+
+    // Create a shorter filename for display (one that fits the
+    // status line more closely).  Subtract the length of the
+    // "Indexing " and/or "Loading " strings as well.
+    if (strlen(filenm) > (41 - 9)) {
+        int avail = 41 - 11;
+        int new_len = strlen(filenm) - avail;
+
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "..%s",
+            &filenm[new_len]);
+    }
+    else {
+        xastir_snprintf(short_filenm,
+            sizeof(short_filenm),
+            "%s",
+            filenm);
+    }
+
+    xastir_snprintf(map_it,
+        sizeof(map_it),
+        langcode ("BBARSTA028"),
+        short_filenm);
+    statusline(map_it,0);       // Loading ...
+
+
+        
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing only.  Save the extents in the index.
+        // Force the extents to the edges of the earth for the
+        // index file.
+        index_update_xastir(filenm, // Filename only
+            64800000l,      // Bottom
+            0l,             // Top
+            0l,             // Left
+            129600000l,     // Right
+            0);             // Default Map Level
+
+        // Update statusline
+        xastir_snprintf(map_it,
+            sizeof(map_it),
+            langcode ("BBARSTA039"),
+            short_filenm);
+        statusline(map_it,0);       // Loading/Indexing ...
+
+        return; // Done indexing this file
+    }
+
+
+    // Tiepoint for upper left screen corner
+    //
+    tp[0].img_x = 0;                // Pixel Coordinates
+    tp[0].img_y = 0;                // Pixel Coordinates
+    tp[0].x_long = NW_corner_longitude;   // Xastir Coordinates
+    tp[0].y_lat  = NW_corner_latitude;    // Xastir Coordinates
+
+    // Tiepoint for lower right screen corner
+    //
+    tp[1].img_x =  screen_width - 1; // Pixel Coordinates
+    tp[1].img_y = screen_height - 1; // Pixel Coordinates 
+
+    tp[1].x_long = SE_corner_longitude; // Xastir Coordinates
+    tp[1].y_lat  =  SE_corner_latitude; // Xastir Coordinates
+
+    left = (double)((NW_corner_longitude - 64800000l )/360000.0);   // Lat/long Coordinates
+    top = (double)(-((NW_corner_latitude - 32400000l )/360000.0));  // Lat/long Coordinates
+    right = (double)((SE_corner_longitude - 64800000l)/360000.0);//Lat/long Coordinates
+    bottom = (double)(-((SE_corner_latitude - 32400000l)/360000.0));//Lat/long Coordinates
+
+    map_width = right - left;   // Lat/long Coordinates
+    map_height = top - bottom;  // Lat/long Coordinates
+
+    geo_image_width  = screen_width;
+    geo_image_height = screen_height;
+
+    long_center = (left + right)/2.0l;
+    lat_center  = (top + bottom)/2.0l;
+
+//  Example query to the census map server....
+/*        xastir_snprintf(fileimg, sizeof(fileimg), 
+        "\'http://tiger.census.gov/cgi-bin/mapper/map.gif?on=CITIES&on=GRID&on=counties&on=majroads&on=places&&on=interstate&on=states&on=ushwy&on=statehwy&lat=%f\046lon=%f\046wid=%f\046ht=%f\046iwd=%i\046iht=%i\'",\
+                   lat_center, long_center, map_width, map_height, tp[1].img_x + 1, tp[1].img_y + 1); */
+
+    xastir_snprintf(tigertmp, sizeof(tigertmp), "http://tiger.census.gov/cgi-bin/mapper/map.gif?");
+
+    if (tiger_show_grid)
+        strncat(tigertmp, "&on=GRID", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=GRID", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_counties)
+        strncat(tigertmp, "&on=counties", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=counties", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_cities)
+        strncat(tigertmp, "&on=CITIES", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=CITIES", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_places)
+        strncat(tigertmp, "&on=places", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=places", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_majroads)
+        strncat(tigertmp, "&on=majroads", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=majroads", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_streets)
+        strncat(tigertmp, "&on=streets", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    // Don't turn streets off since this will automagically show up as you zoom in.
+
+    if (tiger_show_railroad)
+        strncat(tigertmp, "&on=railroad", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=railroad", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_states)
+        strncat(tigertmp, "&on=states", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=states", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_interstate)
+        strncat(tigertmp, "&on=interstate", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=interstate", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_ushwy)
+        strncat(tigertmp, "&on=ushwy", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=ushwy", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_statehwy)
+        strncat(tigertmp, "&on=statehwy", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=statehwy", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_water)
+        strncat(tigertmp, "&on=water", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=water", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_lakes)
+        strncat(tigertmp, "&on=shorelin", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=shorelin", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    if (tiger_show_misc)
+        strncat(tigertmp, "&on=miscell", sizeof(tigertmp) - 1 - strlen(tigertmp));
+    else
+        strncat(tigertmp, "&off=miscell", sizeof(tigertmp) - 1 - strlen(tigertmp));
+
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "&lat=%f\046lon=%f\046", lat_center, long_center);    
+    strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp));
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "wid=%f\046ht=%f\046", map_width, map_height);
+    strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp));
+    xastir_snprintf(tmpstr, sizeof(tmpstr), "iwd=%i\046iht=%i", tp[1].img_x + 1, tp[1].img_y + 1);
+    strncat (tigertmp, tmpstr, sizeof(tigertmp) - 1 - strlen(tigertmp));
+    xastir_snprintf(fileimg, sizeof(fileimg), "%s", tigertmp);
+
+    if (debug_level & 512) {
+          fprintf(stderr,"left side is %f\n", left);
+          fprintf(stderr,"right side is %f\n", right);
+          fprintf(stderr,"top  is %f\n", top);
+          fprintf(stderr,"bottom is %f\n", bottom);
+          fprintf(stderr,"lat center is %f\n", lat_center);
+          fprintf(stderr,"long center is %f\n", long_center);
+          fprintf(stderr,"screen width is %li\n", screen_width);
+          fprintf(stderr,"screen height is %li\n", screen_height);
+          fprintf(stderr,"map width is %f\n", map_width);
+          fprintf(stderr,"map height is %f\n", map_height);
+          fprintf(stderr,"fileimg is %s\n", fileimg);
+          fprintf(stderr,"ftp or http file: %s\n", fileimg);
+    }
+
+
+// Hopefully this will eventually allow us to get maps in the background
+//    while (sometimeout !=0 && local_filename[0]==NULL){
+
+    if  (local_filename[0]=='\0' ){
+
+        if (debug_level & 512 ) { 
+            fprintf(stderr,"tiger_local_file=<%s>\n",local_filename);
+        }
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        get_tiger_local_file(local_filename,fileimg); 
+
+    }
+
+// whackadoodle
+
+
+    // Tell ImageMagick where to find it
+    xastir_snprintf(file,
+        sizeof(file),
+        "%s",
+        local_filename);
+
+    GetExceptionInfo(&exception);
+
+    image_info=CloneImageInfo((ImageInfo *) NULL);
+
+    xastir_snprintf(image_info->filename,
+        sizeof(image_info->filename),
+        "%s",
+        file);
+
+    if (debug_level & 512) {
+           fprintf(stderr,"Copied %s into image info.\n", file);
+           fprintf(stderr,"image_info got: %s\n", image_info->filename);
+           fprintf(stderr,"Entered ImageMagick code.\n");
+           fprintf(stderr,"Attempting to open: %s\n", image_info->filename);
+    }
+
+    // We do a test read first to see if the file exists, so we
+    // don't kill Xastir in the ReadImage routine.
+    f = fopen (image_info->filename, "r");
+    if (f == NULL) {
+        if (debug_level & 512)
+            fprintf(stderr,"File could not be read\n");
+
+#ifdef USE_MAP_CACHE
+
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete unreadable map from cache\n");
+            }
+        }
+#endif
+         
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+    (void)fclose (f);
+
+
+    image = ReadImage(image_info, &exception);
+
+    if (image == (Image *) NULL) {
+        MagickWarning(exception.severity, exception.reason, exception.description);
+        //fprintf(stderr,"MagickWarning\n");
+
+#ifdef USE_MAP_CACHE
+        // clear from cache if bad    
+        if (map_cache_del(fileimg)) {
+            if (debug_level & 512) {
+                fprintf(stderr,"Couldn't delete map from cache\n");
+            }
+        }
+#endif
+
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+
+
+    if (debug_level & 512)
+        fprintf(stderr,"Color depth is %i \n", (int)image->depth);
+
+    if (image->colorspace != RGBColorspace) {
+        fprintf(stderr,"TBD: I don't think we can deal with colorspace != RGB");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+
+    width = image->columns;
+    height = image->rows;
+
+    //  Code to mute the image so it's not as bright.
+/*    if (raster_map_intensity < 1.0) {
+        char tempstr[30];
+
+        if (debug_level & 512)
+            fprintf(stderr,"level=%s\n", tempstr);
+
+        xastir_snprintf(tempstr,
+            sizeof(tempstr),
+            "%d, 100, 100",
+            (int)(raster_map_intensity * 100.0));
+
+        ModulateImage(image, tempstr);
+    }
+*/
+
+
+    // If were are drawing to a low bpp display (typically < 8bpp)
+    // try to reduce the number of colors in an image.
+    // This may take some time, so it would be best to do ahead of
+    // time if it is a static image.
+#if (MagickLibVersion < 0x0540)
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL) > 128) {
+#else   // MagickLib >= 540
+    if (visual_type == NOT_TRUE_NOR_DIRECT && GetNumberColors(image, NULL, &exception) > 128) {
+#endif  // MagickLib Version
+
+        if (image->storage_class == PseudoClass) {
+#if (MagickLibVersion < 0x0549)
+            CompressColormap(image); // Remove duplicate colors
+#else // MagickLib >= 0x0549
+            CompressImageColormap(image); // Remove duplicate colors
+#endif  // MagickLibVersion < 0x0549
+        }
+
+        // Quantize down to 128 will go here...
+    }
+
+
+    pixel_pack = GetImagePixels(image, 0, 0, image->columns, image->rows);
+    if (!pixel_pack) {
+        fprintf(stderr,"pixel_pack == NULL!!!");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+
+
+    index_pack = GetIndexes(image);
+    if (image->storage_class == PseudoClass && !index_pack) {
+        fprintf(stderr,"PseudoClass && index_pack == NULL!!!");
+        if (image)
+            DestroyImage(image);
+        if (image_info)
+            DestroyImageInfo(image_info);
+	DestroyExceptionInfo(&exception);
+        return;
+    }
+
+
+    if (image->storage_class == PseudoClass && image->colors <= 256) {
+        for (l = 0; l < (int)image->colors; l++) {
+            // Need to check how to do this for ANY image, as ImageMagick can read in all sorts
+            // of image files
+            temp_pack = image->colormap[l];
+            if (debug_level & 512)
+                fprintf(stderr,"Colormap color is %i  %i  %i \n",
+                       temp_pack.red, temp_pack.green, temp_pack.blue);
+
+            // Here's a tricky bit:  PixelPacket entries are defined as Quantum's.  Quantum
+            // is defined in /usr/include/magick/image.h as either an unsigned short or an
+            // unsigned char, depending on what "configure" decided when ImageMagick was installed.
+            // We can determine which by looking at MaxRGB or QuantumDepth.
+            //
+            if (QuantumDepth == 16) {   // Defined in /usr/include/magick/image.h
+                if (debug_level & 512)
+                    fprintf(stderr,"Color quantum is [0..65535]\n");
+                my_colors[l].red   = temp_pack.red * raster_map_intensity;
+                my_colors[l].green = temp_pack.green * raster_map_intensity;
+                my_colors[l].blue  = temp_pack.blue * raster_map_intensity;
+            }
+            else {  // QuantumDepth = 8
+                if (debug_level & 512)
+                    fprintf(stderr,"Color quantum is [0..255]\n");
+                my_colors[l].red   = (temp_pack.red << 8) * raster_map_intensity;
+                my_colors[l].green = (temp_pack.green << 8) * raster_map_intensity;
+                my_colors[l].blue  = (temp_pack.blue << 8) * raster_map_intensity;
+            }
+
+            // Get the color allocated on < 8bpp displays. pixel color is written to my_colors.pixel
+            if (visual_type == NOT_TRUE_NOR_DIRECT) {
+//                XFreeColors(XtDisplay(w), cmap, &(my_colors[l].pixel),1,0);
+                XAllocColor(XtDisplay(w), cmap, &my_colors[l]);
+            }
+            else {
+                pack_pixel_bits(my_colors[l].red, my_colors[l].green, my_colors[l].blue,
+                                &my_colors[l].pixel);
+            }
+
+            if (debug_level & 512)
+                fprintf(stderr,"Color allocated is %li  %i  %i  %i \n", my_colors[l].pixel,
+                       my_colors[l].red, my_colors[l].blue, my_colors[l].green);
+        }
+    }
+
+
+
+    /*
+    * Here are the corners of our viewport, using the Xastir
+    * coordinate system.  Notice that Y is upside down:
+    *
+    *   left edge of view = NW_corner_longitude
+    *  right edge of view = SE_corner_longitude
+    *    top edge of view =  NW_corner_latitude
+    * bottom edge of view =  SE_corner_latitude
+    *
+    * The corners of our map will soon be (after translating the
+    * tiepoints to the corners if they're not already there):
+    *
+    *   left edge of map = tp[0].x_long   in Xastir format
+    *  right edge of map = tp[1].x_long
+    *    top edge of map = tp[0].y_lat
+    * bottom edge of map = tp[1].y_lat
+    *
+    */
+    map_c_L = tp[0].x_long - NW_corner_longitude;     // map left coordinate
+    map_c_T = tp[0].y_lat  - NW_corner_latitude;      // map top  coordinate
+
+    tp_c_dx = (long)(tp[1].x_long - tp[0].x_long);//  Width between tiepoints
+    tp_c_dy = (long)(tp[1].y_lat  - tp[0].y_lat); // Height between tiepoints
+
+
+    // Check for tiepoints being in wrong relation to one another
+    if (tp_c_dx < 0) 
+        tp_c_dx = -tp_c_dx;       // New  width between tiepoints
+    if (tp_c_dy < 0) 
+        tp_c_dy = -tp_c_dy;       // New height between tiepoints
+
+    // Calculate step size per pixel
+    map_c_dx = ((double) tp_c_dx / abs(tp[1].img_x - tp[0].img_x));
+    map_c_dy = ((double) tp_c_dy / abs(tp[1].img_y - tp[0].img_y));
+
+    // Scaled screen step size for use with XFillRectangle below
+    scr_dx = (int) (map_c_dx / scale_x) + 1;
+    scr_dy = (int) (map_c_dy / scale_y) + 1;
+
+    // calculate top left map corner from tiepoints
+    if (tp[0].img_x != 0) {
+        tp[0].x_long -= (tp[0].img_x * map_c_dx);   // map left edge longitude
+        map_c_L = tp[0].x_long - NW_corner_longitude;     // delta ??
+        tp[0].img_x = 0;
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_0 x: %d\t%lu\n", tp[0].img_x, tp[0].x_long);
+    }
+    if (tp[0].img_y != 0) {
+        tp[0].y_lat -= (tp[0].img_y * map_c_dy);    // map top edge latitude
+        map_c_T = tp[0].y_lat - NW_corner_latitude;
+        tp[0].img_y = 0;
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_0 y: %d\t%lu\n", tp[0].img_y, tp[0].y_lat);
+    }
+
+    // calculate bottom right map corner from tiepoints
+    // map size is geo_image_width / geo_image_height
+    if (tp[1].img_x != (geo_image_width - 1) ) {
+        tp[1].img_x = geo_image_width - 1;
+        tp[1].x_long = tp[0].x_long + (tp[1].img_x * map_c_dx); // right
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_1 x: %d\t%lu\n", tp[1].img_x, tp[1].x_long);
+    }
+    if (tp[1].img_y != (geo_image_height - 1) ) {
+        tp[1].img_y = geo_image_height - 1;
+        tp[1].y_lat = tp[0].y_lat + (tp[1].img_y * map_c_dy);   // bottom
+        if (debug_level & 512)
+            fprintf(stderr,"Translated tiepoint_1 y: %d\t%lu\n", tp[1].img_y, tp[1].y_lat);
+    }
+
+    if (debug_level & 512) {
+        fprintf(stderr,"X tiepoint width: %ld\n", tp_c_dx);
+        fprintf(stderr,"Y tiepoint width: %ld\n", tp_c_dy);
+        fprintf(stderr,"Loading imagemap: %s\n", file);
+        fprintf(stderr,"\nImage: %s\n", file);
+        fprintf(stderr,"Image size %d %d\n", geo_image_width, geo_image_height);
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n",
+            map_c_L, map_c_T, map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+        fprintf(stderr,"Image size %d %d\n", width, height);
+#if (MagickLibVersion < 0x0540)
+        fprintf(stderr,"Unique colors = %d\n", GetNumberColors(image, NULL));
+#else // MagickLib < 540
+        fprintf(stderr,"Unique colors = %ld\n", GetNumberColors(image, NULL, &exception));
+#endif // MagickLib < 540
+        fprintf(stderr,"XX: %ld YY:%ld Sx %f %d Sy %f %d\n", map_c_L, map_c_T,
+            map_c_dx,(int) (map_c_dx / scale_x), map_c_dy, (int) (map_c_dy / scale_y));
+        fprintf(stderr,"image matte is %i\n", image->matte);
+    } // debug_level & 512
+
+    // draw the image from the file out to the map screen
+
+    // Get the border values for the X and Y for loops used
+    // for the XFillRectangle call later.
+
+    map_c_yc = (tp[0].y_lat + tp[1].y_lat) / 2;     // vert center of map as reference
+    map_y_ctr = (long)(height / 2 +0.499);
+    scale_x0 = get_x_scale(0,map_c_yc,scale_y);     // reference scaling at vert map center
+
+    map_c_xc  = (tp[0].x_long + tp[1].x_long) / 2;  // hor center of map as reference
+    map_x_ctr = (long)(width  / 2 +0.499);
+    scr_x_mc  = (map_c_xc - NW_corner_longitude) / scale_x; // screen coordinates of map center
+
+    // calculate map pixel range in y direction that falls into screen area
+    c_y_max = 0ul;
+    map_y_min = map_y_max = 0l;
+    for (map_y_0 = 0, c_y = tp[0].y_lat; map_y_0 < (long)height; map_y_0++, c_y += map_c_dy) {
+        scr_y = (c_y - NW_corner_latitude) / scale_y;   // current screen position
+        if (scr_y > 0) {
+            if (scr_y < screen_height) {
+                map_y_max = map_y_0;          // update last map pixel in y
+                c_y_max = (unsigned long)c_y;// bottom map inside screen coordinate
+            } else
+                break;                      // done, reached bottom screen border
+        } else {                            // pixel is above screen
+            map_y_min = map_y_0;              // update first map pixel in y
+        }
+    }
+    c_y_min = (unsigned long)(tp[0].y_lat + map_y_min * map_c_dy);   // top map inside screen coordinate
+
+        map_x_min = map_x_max = 0l;
+        for (map_x = 0, c_x = tp[0].x_long; map_x < (long)width; map_x++, c_x += map_c_dx) {
+            scr_x = (c_x - NW_corner_longitude)/ scale_x;  // current screen position
+            if (scr_x > 0) {
+                if (scr_x < screen_width)
+                    map_x_max = map_x;          // update last map pixel in x
+                else
+                    break;                      // done, reached right screen border
+            } else {                            // pixel is left from screen
+                map_x_min = map_x;              // update first map pixel in x
+            }
+        }
+        c_x_min = (unsigned long)(tp[0].x_long + map_x_min * map_c_dx);   // left map inside screen coordinate
+
+    scr_yp = -1;
+    scr_c_xr = SE_corner_longitude;
+    c_dx = map_c_dx;                            // map pixel width
+    scale_xa = scale_x0;                        // the compiler likes it ;-)
+
+    map_done = 0;
+    map_act  = 0;
+    map_seen = 0;
+    scr_y = screen_height - 1;
+
+
+    // loop over map pixel rows
+    for (map_y_0 = map_y_min, c_y = (double)c_y_min; (map_y_0 <= map_y_max); map_y_0++, c_y += map_c_dy) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            if (image)
+               DestroyImage(image);
+            if (image_info)
+               DestroyImageInfo(image_info);
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            DestroyExceptionInfo(&exception);
+            return;
+        }
+
+        scr_y = (c_y - NW_corner_latitude) / scale_y;
+        if (scr_y != scr_yp) {                  // don't do a row twice
+            scr_yp = scr_y;                     // remember as previous y
+            scr_xp = -1;
+            // loop over map pixel columns
+            map_act = 0;
+            scale_x_nm = calc_dscale_x(0,(long)c_y) / 1852.0;  // nm per Xastir coordinate
+            for (map_x = map_x_min, c_x = (double)c_x_min; map_x <= map_x_max; map_x++, c_x += c_dx) {
+                scr_x = (c_x - NW_corner_longitude) / scale_x;
+                if (scr_x != scr_xp) {      // don't do a pixel twice
+                    scr_xp = scr_x;         // remember as previous x
+                    map_y = map_y_0;
+
+                    if (map_y >= 0 && map_y <= tp[1].img_y) { // check map boundaries in y direction
+                        map_seen = 1;
+                        map_act = 1;    // detects blank screen rows (end of map)
+
+                        // now copy a pixel from the map image to the screen
+                        l = map_x + map_y * image->columns;
+                        if (image->storage_class == PseudoClass) {
+                            XSetForeground(XtDisplay(w), gc, my_colors[index_pack[l]].pixel);
+                        }
+                        else {
+                            // It is not safe to assume that the red/green/blue
+                            // elements of pixel_pack of type Quantum are the
+                            // same as the red/green/blue of an XColor!
+                            if (QuantumDepth==16) {
+                                my_colors[0].red=pixel_pack[l].red;
+                                my_colors[0].green=pixel_pack[l].green;
+                                my_colors[0].blue=pixel_pack[l].blue;
+                            }
+                            else { // QuantumDepth=8
+                                // shift the bits of the 8-bit quantity so that
+                                // they become the high bigs of my_colors.*
+                                my_colors[0].red=pixel_pack[l].red<<8;
+                                my_colors[0].green=pixel_pack[l].green<<8;
+                                my_colors[0].blue=pixel_pack[l].blue<<8;
+                            }
+                            // NOW my_colors has the right r,g,b range for
+                            // pack_pixel_bits
+                            pack_pixel_bits(my_colors[0].red * raster_map_intensity,
+                                            my_colors[0].green * raster_map_intensity,
+                                            my_colors[0].blue * raster_map_intensity,
+                                            &my_colors[0].pixel);
+                            XSetForeground(XtDisplay(w), gc, my_colors[0].pixel);
+                        }
+                        (void)XFillRectangle (XtDisplay (w),pixmap,gc,scr_x,scr_y,scr_dx,scr_dy);
+                    } // check map boundaries in y direction
+                }
+            } // loop over map pixel columns
+            if (map_seen && !map_act)
+                map_done = 1;
+        }
+    } // loop over map pixel rows
+
+    if (image)
+       DestroyImage(image);
+    if (image_info)
+       DestroyImageInfo(image_info);
+    DestroyExceptionInfo(&exception);
+}
+#endif //HAVE_MAGICK
+///////////////////////////////////////////// End of Tigermap code ///////////////////////////////////////
diff --git a/src/maps.c b/src/maps.c
new file mode 100644
index 0000000..153e9e3
--- /dev/null
+++ b/src/maps.c
@@ -0,0 +1,9061 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: maps.c,v 1.534 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+//#define GDAL_SHAPEFILES
+//#define MAP_SCALE_CHECK
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#ifdef HAVE_MAGICK
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+#undef RETSIGTYPE
+// TVR: "stupid ImageMagick"
+// The problem is that magick/api.h includes Magick's config.h file, and that
+// pulls in all the same autoconf-generated defines that we use.
+// plays those games below, but I don't think in the end that they actually 
+// make usable macros with our own data in them.
+// Fortunately, we don't need them, so I'll just undef the ones that are
+// causing problems today.  See main.c for fixes that preserve our values.
+#undef PACKAGE
+#undef VERSION
+/* JMT - stupid ImageMagick */
+#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+#undef PACKAGE_NAME
+#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+#undef PACKAGE_STRING
+#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#ifdef HAVE_GRAPHICSMAGICK
+/*#include <GraphicsMagick/magick/api.h>*/
+#include <magick/api.h>
+#else   // HAVE_GRAPHICSMAGICK
+#include <magick/api.h>
+#endif  // HAVE_GRAPHICSMAGICK 
+#undef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+#undef XASTIR_PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+#undef XASTIR_PACKAGE_NAME
+#undef PACKAGE_STRING
+#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+#undef XASTIR_PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+#undef XASTIR_PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+#undef XASTIR_PACKAGE_VERSION
+#endif // HAVE_MAGICK
+
+#include <dirent.h>
+#include <netinet/in.h>
+#include <Xm/XmAll.h>
+
+#ifdef HAVE_X11_XPM_H
+#include <X11/xpm.h>
+#ifdef HAVE_LIBXPM // if we have both, prefer the extra library
+#undef HAVE_XM_XPMI_H
+#endif // HAVE_LIBXPM
+#endif // HAVE_X11_XPM_H
+
+#ifdef HAVE_XM_XPMI_H
+#include <Xm/XpmI.h>
+#endif // HAVE_XM_XPMI_H
+
+#include <X11/Xlib.h>
+
+#include <math.h>
+
+#include "xastir.h"
+#include "maps.h"
+#include "alert.h"
+#include "util.h"
+#include "main.h"
+#include "datum.h"
+#include "draw_symbols.h"
+#include "rotated.h"
+#include "color.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+#define GRID_MORE 5000
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+
+// Check for XPM and/or ImageMagick.  We use "NO_GRAPHICS"
+// to disable some routines below if the support for them
+// is not compiled in.
+#if !(defined(HAVE_LIBXPM) || defined(HAVE_LIBXPM_IN_XM) || defined(HAVE_MAGICK))
+  #define NO_GRAPHICS 1
+#endif  // !(HAVE_LIBXPM || HAVE_LIBXPM_IN_XM || HAVE_MAGICK)
+
+#if !(defined(HAVE_LIBXPM) || defined(HAVE_LIBXPM_IN_XM))
+  #define NO_XPM 1
+#endif  // !(HAVE_LIBXPM || HAVE_LIBXPM_IN_XM)
+
+
+void draw_rotated_label_text_to_target (Widget w, int rotation, int x, int y, int label_length, int color, char *label_text, int fontsize, Pixmap target_pixmap, int draw_outline, int outline_bg_color);
+int get_rotated_label_text_height_pixels(Widget w, char *label_text, int fontsize);
+
+// Constants defining the color of the labeled grid border.
+int outline_border_labels = TRUE;   // if true put an outline around the border labels
+int border_foreground_color = 0x20; // color of the map border, if shown 
+                                    // 0x08 is black.
+                                    // 0x20 is white.
+int outline_border_labels_color = 0x20;
+                                    // outline_border_labels_color = border_foreground_color; 
+                                    // color of outline to draw around border labels
+                                    // use color of border to help make text more legible.
+
+// Print options
+Widget print_properties_dialog = (Widget)NULL;
+static xastir_mutex print_properties_dialog_lock;
+Widget print_postscript_dialog = (Widget)NULL;
+static xastir_mutex print_postscript_dialog_lock;
+Widget printer_data;
+Widget previewer_data;
+ 
+Widget rotate_90 = (Widget)NULL;
+Widget auto_rotate = (Widget)NULL;
+//char  print_paper_size[20] = "Letter";  // Displayed in dialog, but not used yet.
+int   print_rotated = 0;
+int   print_auto_rotation = 0;
+//float print_scale = 1.0;                // Not used yet.
+int   print_auto_scale = 0;
+//int   print_blank_background_color = 0; // Not used yet.
+int   print_in_monochrome = 0;
+int   print_resolution = 150;           // 72 dpi is normal for Postscript.
+                                        // 100 or 150 dpi work well with HP printer
+int   print_invert = 0;                 // Reverses black/white
+
+char printer_program[MAX_FILENAME+1];
+char previewer_program[MAX_FILENAME+1];
+
+time_t last_snapshot = 0;               // Used to determine when to take next snapshot
+time_t last_kmlsnapshot = 0;               // Used to determine when to take next kml snapshot
+int doing_snapshot = 0;
+int snapshot_interval = 0;
+
+
+int mag;
+int npoints;    /* number of points in a line */
+
+
+float raster_map_intensity = 0.65;    // Raster map color intensity, set from Maps->Map Intensity
+float imagemagick_gamma_adjust = 0.0;  // Additional imagemagick map gamma correction, set from Maps->Adjust Gamma
+
+// Storage for the index file timestamp
+time_t map_index_timestamp;
+
+int grid_size = 0;
+
+// Rounding
+#ifndef HAVE_ROUNDF
+// Poor man's rounding, but rounds away from zero as roundf is supposed to.
+
+float roundf(float x) 
+{
+    int i;
+    i= (((x)>=0)?(((x)+.5)):(((x)-.5)));
+    return ((float)i);
+}
+
+#endif
+
+
+// UTM Grid stuff
+//
+//#define UTM_DEBUG
+//#define UTM_DEBUG_VERB
+//#define UTM_DEBUG_ALLOC
+//
+inline int  max_i(int  a, int  b) { return (a > b ? a : b); }
+#define UTM_GRID_EQUATOR 10000000
+// the maximum number of UTM zones that will appear on a screen that has a 
+// high enough resolution to display the within-zone utm grid
+#define UTM_GRID_MAX_ZONES      4
+// the maximum number of grid lines in each direction shown in each zone
+// on the screen at one time
+#define UTM_GRID_MAX_COLS_ROWS 64
+#define UTM_GRID_DEF_NALLOCED   8
+#define UTM_GRID_RC_EMPTY  0xffff
+
+// the hash stores the upper left and lower right boundaries of the 
+// display of a utm grid to determine whether it matches the current
+// screen boundaries or whether the grid needs to be recalculated
+// for the current screen.
+typedef struct {
+    long ul_x;
+    long ul_y;
+    long lr_x;
+    long lr_y;
+} hash_t;
+
+// The utm grid is drawn by connecting a grid of points marking the
+// intersection of the easting and northing lines.  col_or_row holds
+// this grid of points for the portion of a utm zone visible on the
+// screen.  Zone boundaries are not directly represented here.
+// In particular, the parallels separating lettered zone rows are
+// not directly represented here.
+typedef struct {
+    int firstpoint;
+    int npoints;
+    int nalloced;
+    XPoint *points;
+} col_or_row_t;
+
+// The portion of a utm zone visible on the screen has some number of
+// visible easting lines and northing lines forming a grid that covers
+// part or all of the screen.  Zone holds arrays of the coordinates
+// of the visible easting and northing intersections, and the next set
+// of intersections off screen.  The coarseness of this grid is
+// determined by the current scale and stored in utm_grid_spacing_m.
+typedef struct {
+    unsigned int ncols;
+    col_or_row_t col[UTM_GRID_MAX_COLS_ROWS];
+    unsigned int nrows;
+    col_or_row_t row[UTM_GRID_MAX_COLS_ROWS];
+    int          boundary_x;
+} zone_t;
+
+// A utm grid is represented by its hash (upper left and lower right coordinates)
+// which are used to check whether or not it fits the current screen or needs to 
+// be recalculated, and an array of the zones visible on the screen, each containing
+// arrays of the points marking the easting/northing intersections of a zone (with
+// one or more lettered zone rows).
+typedef struct {
+    hash_t       hash;
+    unsigned int nzones;
+    zone_t       zone[UTM_GRID_MAX_ZONES];
+} utm_grid_t;
+
+utm_grid_t utm_grid;
+
+unsigned int utm_grid_spacing_m;
+// ^ the above is extern'ed in maps.h for use by draw_ruler_text in
+// db.c
+
+
+
+
+
+// Clear out/set up the UTM/MGRS minor grid intersection arrays.
+//
+// do_alloc = 0:  Don't allocate memory
+//            1:  Allocate memory for the points
+//
+// Returns: 0 if ok
+//          1 if malloc problem
+//
+int utm_grid_clear(int do_alloc)
+{
+    int i, j;
+
+    utm_grid.hash.ul_x = 0;
+    utm_grid.hash.ul_y = 0;
+    utm_grid.hash.lr_x = 0;
+    utm_grid.hash.lr_y = 0;
+    utm_grid.nzones    = 0;
+
+    for (i=0; i < UTM_GRID_MAX_ZONES; i++) {
+
+        utm_grid.zone[i].ncols = utm_grid.zone[i].nrows = 0;
+        utm_grid.zone[i].boundary_x = 0;
+
+        for (j=0; j < UTM_GRID_MAX_COLS_ROWS; j++) {
+
+            //
+            // Clear out column arrays
+            //
+            utm_grid.zone[i].col[j].firstpoint = UTM_GRID_RC_EMPTY;
+            utm_grid.zone[i].col[j].npoints    = 0;
+
+            if (utm_grid.zone[i].col[j].nalloced)
+                free(utm_grid.zone[i].col[j].points);
+
+            utm_grid.zone[i].col[j].nalloced   = 0;
+            utm_grid.zone[i].col[j].points = NULL;
+
+            if (do_alloc) {
+
+                // Allocate enough space for 8 points
+                utm_grid.zone[i].col[j].points = calloc(UTM_GRID_DEF_NALLOCED, sizeof(XPoint));
+                if (!utm_grid.zone[i].col[j].points) {
+                    fprintf(stderr,"calloc(%d, %d) for z=%d col=%d FAILED!\n",
+                        UTM_GRID_DEF_NALLOCED,
+                        (int)sizeof(XPoint),
+                        i,
+                        j);
+//                    abort();  // Causes a segfault
+                    return(1);
+                }
+                utm_grid.zone[i].col[j].nalloced = UTM_GRID_DEF_NALLOCED;
+            }
+
+            //
+            // Clear out row arrays
+            //
+            utm_grid.zone[i].row[j].firstpoint = UTM_GRID_RC_EMPTY;
+            utm_grid.zone[i].row[j].npoints    = 0;
+            utm_grid.zone[i].row[j].nalloced   = 0;
+
+            if (utm_grid.zone[i].row[j].nalloced)
+                free(utm_grid.zone[i].row[j].points);
+
+            utm_grid.zone[i].row[j].nalloced   = 0;
+            utm_grid.zone[i].row[j].points = NULL;
+
+            if (do_alloc) {
+
+                // Allocate enough space for 8 points
+                utm_grid.zone[i].row[j].points = calloc(UTM_GRID_DEF_NALLOCED, sizeof(XPoint));
+                if (!utm_grid.zone[i].row[j].points) {
+                    fprintf(stderr,"calloc(%d, %d) for z=%d row=%d FAILED!\n",
+                        UTM_GRID_DEF_NALLOCED,
+                        (int)sizeof(XPoint),
+                        i,
+                        j);
+//                    abort();  // Causes a segfault
+                    return(1);
+                }
+                utm_grid.zone[i].row[j].nalloced = UTM_GRID_DEF_NALLOCED;
+            }
+        }
+    }
+    return(0);
+}
+
+
+
+
+
+void maps_init(void)
+{
+    fprintf(stderr,"\n\nBuilt-in map types:\n");
+    fprintf(stderr,"%10s   USGS GNIS Datapoints\n","gnis");
+    fprintf(stderr,"%10s   USGS GNIS Datapoints w/population\n","pop");
+    fprintf(stderr,"%10s   APRSdos Maps\n","map");
+    fprintf(stderr,"%10s   WinAPRS/MacAPRS/X-APRS Maps\n","map");
+    fprintf(stderr,"%10s   PocketAPRS Maps\n","pdb");
+
+    fprintf(stderr,"\nSupport for these additional map types has been compiled in: \n");
+ 
+#ifdef HAVE_MAGICK
+    fprintf(stderr,"%10s   Image Map (ImageMagick/GraphicsMagick library, many formats allowed)\n","geo");
+#endif  // HAVE_MAGICK
+
+#ifndef NO_GRAPHICS
+#ifdef HAVE_LIBCURL
+    fprintf(stderr,"%10s   URL (Internet maps via libcurl library)\n","geo");
+    fprintf(stderr,"%10s   URL (OpenStreetMaps via libcurl library\n","geo");
+    fprintf(stderr,"%10s        Copyright OpenStreetMap and contributors, CC-BY-SA)\n", "");
+
+#else
+#ifdef HAVE_WGET
+    fprintf(stderr,"%10s   URL (Internet maps via wget)\n","geo");
+    fprintf(stderr,"%10s   URL (OpenStreetMaps via wget\n","geo");
+    fprintf(stderr,"%10s        Copyright OpenStreetMap and contributors, CC-BY-SA)\n", "");
+#endif  // HAVE_WGET
+#endif  // HAVE_LIBCURL
+#endif  // NO_GRAPHICS
+
+
+//#define GDAL_SHAPEFILES
+#ifdef GDAL_SHAPEFILES
+  #ifdef HAVE_LIBGDAL
+    fprintf(stderr,"%10s   ESRI Shapefile Maps (GDAL/OGR library)\n","shp");
+  #endif    // HAVE_LIBGDAL
+#else   // GDAL_SHAPEFILES
+  #ifdef HAVE_LIBSHP
+    fprintf(stderr,"%10s   ESRI Shapefile Maps (Shapelib library)\n","shp");
+  #endif  // HAVE_LIBSHP
+#endif  // GDAL_SHAPEFILES
+
+
+#ifdef HAVE_LIBGEOTIFF
+    fprintf(stderr,"%10s   USGS DRG Geotiff Topographic Maps (libgeotiff/libproj)\n","tif");
+#endif  // HAVE_LIBGEOTIFF
+
+#ifndef NO_XPM
+    fprintf(stderr,"%10s   X Pixmap Maps (XPM library)\n","xpm");
+#endif  // NO_XPM
+
+    init_critical_section( &print_properties_dialog_lock );
+    init_critical_section( &print_postscript_dialog_lock );
+
+    // Clear the minor UTM/MGRS grid arrays.  Do _not_ allocate
+    // memory for the points.
+    (void)utm_grid_clear(0);
+}
+
+
+
+
+
+/*
+ *  Calculate NS distance scale at a given location
+ *  in meters per Xastir unit
+ */
+double calc_dscale_y(long x, long y) {
+
+    // approximation by looking at +/- 0.5 minutes offset
+    //    (void)(calc_distance(y-3000, x, y+3000, x)/6000.0);
+    // but this scale is fixed at 1852/6000
+    return((double)(1852.0/6000.0));
+}
+
+
+
+
+
+/*
+ *  Calculate EW distance scale at a given location
+ *  in meters per Xastir unit
+ */
+double calc_dscale_x(long x, long y) {
+
+    // approximation by looking at +/- 0.5 minutes offset
+    // we should find a better formula...
+    return(calc_distance(y, x-3000, y, x+3000)/6000.0);
+}
+
+
+
+
+
+/*
+ *  Calculate x map scaling for current location
+ *  With that we could have equal distance scaling or a better
+ *  view for pixel maps
+ */
+long get_x_scale(long x, long y, long ysc) {
+    long   xsc;
+    double sc_x;
+    double sc_y;
+    
+    sc_x = calc_dscale_x(x,y);          // meter per Xastir unit
+    sc_y = calc_dscale_y(x,y);
+    if (sc_x < 0.01 || ysc > 50000)
+        // keep it near the poles (>88 deg) or if big parts of world seen
+        xsc = ysc;
+    else
+        // adjust y scale, so that the distance is identical in both directions:
+        xsc = (long)(ysc * sc_y / sc_x +0.4999);
+    
+    //fprintf(stderr,"Scale: x %5.3fkm/deg, y %5.3fkm/deg, x %ld y %ld\n",sc_x*360,sc_y*360,xsc,ysc);
+    return(xsc);
+}
+
+
+
+
+
+/** MAP DRAWING ROUTINES **/
+
+
+
+// Function to perform 2D line-clipping Using the improved parametric
+// line-clipping algorithm by Liang, Barsky, and Slater published in
+// the paper: "Some Improvements to a Parametric Line Clipping
+// Algorithm", 1992.  Called by clip2d() function below.  This
+// function is set up for float values.  See the clipt_long() and
+// clipt_int() functions for use with other types of values.
+//
+// Returns False if the line is rejected, True otherwise.  May modify
+// t0 and t1.
+//
+int clipt(float p, float q, float *t0, float *t1) {
+    float r;
+    int accept = True;
+
+
+    if (p < 0) {  // Entering visible region, so compute t0
+
+        if (q < 0) {  // t0 will be non-negative, so continue
+
+            r = q / p;
+
+            if (r > *t1) {  // t0 will exceed t1, so reject
+                accept = False;
+            }
+            else if (r > *t0) {  // t0 is max of r's
+                *t0 = r;
+            }
+        }
+    }
+    else {
+
+        if (p > 0) {  // Exiting visible region, so compute t1
+
+            if (q < p) {  // t1 will be <= 1, so continue
+
+                r = q / p;
+
+                if (r < *t0) {  // t1 will be <= t0, so reject
+                    accept = False;
+                }
+                else if (r < *t1) {  // t1 is min of r's
+                    *t1 = r;
+                }
+            }
+        }
+        else {  // p == 0
+
+            if (q < 0) {  // Line parallel and outside, so reject
+                accept = False;
+            }
+        }
+    }
+    return(accept);
+}
+
+
+
+
+
+// Function to perform 2D line-clipping using the improved parametric
+// line-clipping algorithm by Liang, Barsky, and Slater published in
+// the paper: "Some Improvements to a Parametric Line Clipping
+// Algorithm", 1992.  Uses the clipt() function above.
+//
+// Returns False if the line is rejected, True otherwise.  x0, y0,
+// x1, y1 may get modified by this function.  These will be the new
+// clipped line ends that fit inside the window.
+//
+// Clip 2D line segment with endpoints (x0,y0) and (x1,y1).  The clip
+// window is x_left <= x <= x_right and y_bottom <= y <= y_top.
+//
+// This function is set up for float values.  See the clip2d_long()
+// and clip2d_screen() functions for use with other types of values.
+//
+int clip2d(float *x0, float *y0, float *x1, float *y1) {
+    float t0, t1;
+    float delta_x, delta_y;
+    int visible = False;
+    float x_left, y_top;        // NW corner of screen
+    float x_right, y_bottom;    // SE corner of screen
+
+
+    // Assign floating point values for screen corners
+    y_top = f_NW_corner_latitude;
+    y_bottom = f_SE_corner_latitude;
+    x_left = f_NW_corner_longitude;
+    x_right =  f_SE_corner_longitude;
+
+    if (       ((*x0 < x_left)   && (*x1 < x_left))
+            || ((*x0 > x_right)  && (*x1 > x_right))
+            || ((*y0 < y_bottom) && (*y1 < y_bottom))
+            || ((*y0 > y_top)    && (*y1 > y_top)) ) {
+
+        // Both endpoints are on outside and same side of visible
+        // region, so reject.
+        return(visible);
+    }
+
+    t0 = 0;
+    t1 = 1;
+    delta_x = *x1 - *x0;
+
+    if ( clipt(-delta_x, *x0 - x_left, &t0, &t1) ) {           // left
+
+        if ( clipt(delta_x, x_right - *x0, &t0, &t1) ) {       // right
+
+            delta_y = *y1 - *y0;
+
+            if ( clipt(-delta_y, *y0 - y_bottom, &t0, &t1) ) { // bottom
+
+                if ( clipt(delta_y, y_top - *y0, &t0, &t1) ) { // top
+                    // Compute coordinates
+
+                    if (t1 < 1) {   // Compute V1' (new x1,y1)
+                        *x1 = *x0 + t1 * delta_x;
+                        *y1 = *y0 + t1 * delta_y;
+                    }
+
+                    if (t0 > 0) {   // Compute V0' (new x0,y0)
+                        *x0 = *x0 + t0 * delta_x;
+                        *y0 = *y0 + t0 * delta_y;
+                    }
+                    visible = True;
+                }
+            }
+        }
+    }
+    return(visible);
+}
+
+
+
+
+
+// Function to perform 2D line-clipping Using the improved parametric
+// line-clipping algorithm by Liang, Barsky, and Slater published in
+// the paper: "Some Improvements to a Parametric Line Clipping
+// Algorithm", 1992.  Called by clip2d_long() function below.  This
+// function is set up for Xastir coordinate values (unsigned longs).
+// See the clipt() and clipt_int() functions for use with other
+// types of values.
+//
+// Returns False if the line is rejected, True otherwise.  May modify
+// t0 and t1.
+//
+int clipt_long(long p, long q, float *t0, float *t1) {
+    float r;
+    int accept = True;
+
+
+    if (p < 0) {  // Entering visible region, so compute t0
+
+        if (q < 0) {  // t0 will be non-negative, so continue
+
+            r = q / (p * 1.0);
+
+            if (r > *t1) {  // t0 will exceed t1, so reject
+                accept = False;
+            }
+            else if (r > *t0) {  // t0 is max of r's
+                *t0 = r;
+            }
+        }
+    }
+    else {
+
+        if (p > 0) {  // Exiting visible region, so compute t1
+
+            if (q < p) {  // t1 will be <= 1, so continue
+
+                r = q / (p * 1.0);
+
+                if (r < *t0) {  // t1 will be <= t0, so reject
+                    accept = False;
+                }
+                else if (r < *t1) {  // t1 is min of r's
+                    *t1 = r;
+                }
+            }
+        }
+        else {  // p == 0
+
+            if (q < 0) {  // Line parallel and outside, so reject
+                accept = False;
+            }
+        }
+    }
+    //fprintf(stderr,"clipt_long: %d\n",accept);
+    return(accept);
+}
+
+
+
+
+
+// Function to perform 2D line-clipping using the improved parametric
+// line-clipping algorithm by Liang, Barsky, and Slater published in
+// the paper: "Some Improvements to a Parametric Line Clipping
+// Algorithm", 1992.  Uses the clipt_long() function above.
+//
+// Returns False if the line is rejected, True otherwise.  x0, y0,
+// x1, y1 may get modified by this function.  These will be the new
+// clipped line ends that fit inside the window.
+//
+// Clip 2D line segment with endpoints (x0,y0) and (x1,y1).  The clip
+// window is x_left <= x <= x_right and y_bottom <= y <= y_top.
+//
+// This function uses the Xastir coordinate system.  We had to flip
+// y_bottom/y_top below due to the coordinate system being
+// upside-down.
+//
+// This function is set up for Xastir coordinate values (unsigned
+// longs).  See the clip2d() or clip2d_screen() functions for use
+// with other types of values.
+//
+int clip2d_long(unsigned long *x0, unsigned long *y0, unsigned long *x1, unsigned long *y1) {
+    float t0, t1;
+    long delta_x, delta_y;
+    int visible = False;
+    unsigned long x_left   = NW_corner_longitude;
+    unsigned long x_right = SE_corner_longitude;
+    // Reverse the following two as our Xastir coordinate system is
+    // upside down.  The algorithm requires this order.
+    unsigned long y_top = SE_corner_latitude;
+    unsigned long y_bottom = NW_corner_latitude;
+
+
+    if (       ( (*x0 < x_left  ) && (*x1 < x_left  ) )
+            || ( (*x0 > x_right ) && (*x1 > x_right ) )
+            || ( (*y0 < y_bottom) && (*y1 < y_bottom) )
+            || ( (*y0 > y_top   ) && (*y1 > y_top   ) ) ) {
+
+        // Both endpoints are on same side of visible region and
+        // outside of it, so reject.
+        //fprintf(stderr,"reject 1\n");
+        return(visible);
+    }
+
+    t0 = 0;
+    t1 = 1;
+    delta_x = *x1 - *x0;
+
+    if ( clipt_long(-delta_x, *x0 - x_left, &t0, &t1) ) {           // left
+
+        if ( clipt_long(delta_x, x_right - *x0, &t0, &t1) ) {       // right
+
+            delta_y = *y1 - *y0;
+
+            if ( clipt_long(-delta_y, *y0 - y_bottom, &t0, &t1) ) { // bottom
+
+                if ( clipt_long(delta_y, y_top - *y0, &t0, &t1) ) { // top
+                    // Compute coordinates
+
+                    if (t1 < 1) {   // Compute V1' (new x1,y1)
+                        *x1 = *x0 + t1 * delta_x;
+                        *y1 = *y0 + t1 * delta_y;
+                    }
+
+                    if (t0 > 0) {   // Compute V0' (new x0,y0)
+                        *x0 = *x0 + t0 * delta_x;
+                        *y0 = *y0 + t0 * delta_y;
+                    }
+                    visible = True;
+                }
+                else {
+                    //fprintf(stderr,"reject top\n");
+                }
+            }
+            else {
+                //fprintf(stderr,"reject bottom\n");
+            }
+        }
+        else {
+            //fprintf(stderr,"reject right\n");
+        }
+    }
+    else {
+        //fprintf(stderr,"reject left\n");
+    }
+    return(visible);
+}
+
+
+
+
+
+// Function to perform 2D line-clipping Using the improved parametric
+// line-clipping algorithm by Liang, Barsky, and Slater published in
+// the paper: "Some Improvements to a Parametric Line Clipping
+// Algorithm", 1992.  Called by clip2d_screen() function below.  This
+// function is set up for screen coordinate values (unsigned ints).
+// See the clipt() and clipt_long functions for use with other types
+// of values.
+//
+// Returns False if the line is rejected, True otherwise.  May modify
+// t0 and t1.
+//
+int clipt_int(int p, int q, float *t0, float *t1) {
+    float r;
+    int accept = True;
+
+
+    if (p < 0) {  // Entering visible region, so compute t0
+
+        if (q < 0) {  // t0 will be non-negative, so continue
+
+            r = q / (p * 1.0);
+
+            if (r > *t1) {  // t0 will exceed t1, so reject
+                accept = False;
+            }
+            else if (r > *t0) {  // t0 is max of r's
+                *t0 = r;
+            }
+        }
+    }
+    else {
+
+        if (p > 0) {  // Exiting visible region, so compute t1
+
+            if (q < p) {  // t1 will be <= 1, so continue
+
+                r = q / (p * 1.0);
+
+                if (r < *t0) {  // t1 will be <= t0, so reject
+                    accept = False;
+                }
+                else if (r < *t1) {  // t1 is min of r's
+                    *t1 = r;
+                }
+            }
+        }
+        else {  // p == 0
+
+            if (q < 0) {  // Line parallel and outside, so reject
+                accept = False;
+            }
+        }
+    }
+    //fprintf(stderr,"clipt_int: %d\n",accept);
+    return(accept);
+}
+
+
+
+
+
+// Function to perform 2D line-clipping using the improved parametric
+// line-clipping algorithm by Liang, Barsky, and Slater published in
+// the paper: "Some Improvements to a Parametric Line Clipping
+// Algorithm", 1992.  Uses the clipt_int() function above.
+//
+// Returns False if the line is rejected, True otherwise.  x0, y0,
+// x1, y1 may get modified by this function.  These will be the new
+// clipped line ends that fit inside the window.
+//
+// Clip 2D line segment with endpoints (x0,y0) and (x1,y1).  The clip
+// window is x_left <= x <= x_right and y_bottom <= y <= y_top.
+//
+// This function uses the screen coordinate system.  We had to flip
+// y_bottom/y_top below due to the coordinate system being
+// upside-down.
+//
+// This function is set up for screen coordinate values (unsigned
+// ints).  See the clip2d() and clip2d_long() functions for use
+// with other types of values.
+//
+int clip2d_screen(unsigned int *x0, unsigned int *y0, unsigned int *x1, unsigned int *y1) {
+    float t0, t1;
+    int delta_x, delta_y;
+    int visible = False;
+    unsigned int x_right  = screen_width;
+    unsigned int x_left   = 0;
+    // Reverse the following two as our screen coordinate system is
+    // upside down.  The algorithm requires this order.
+    unsigned int y_top    = screen_height;
+    unsigned int y_bottom = 0;
+
+
+    if (       ( (*x0 < x_left  ) && (*x1 < x_left  ) )
+            || ( (*x0 > x_right ) && (*x1 > x_right ) )
+            || ( (*y0 < y_bottom) && (*y1 < y_bottom) )
+            || ( (*y0 > y_top   ) && (*y1 > y_top   ) ) ) {
+
+        // Both endpoints are on same side of visible region and
+        // outside of it, so reject.
+        //fprintf(stderr,"reject 1\n");
+        return(visible);
+    }
+
+    t0 = 0;
+    t1 = 1;
+    delta_x = *x1 - *x0;
+
+    if ( clipt_int(-delta_x, *x0 - x_left, &t0, &t1) ) {           // left
+
+        if ( clipt_int(delta_x, x_right - *x0, &t0, &t1) ) {       // right
+
+            delta_y = *y1 - *y0;
+
+            if ( clipt_int(-delta_y, *y0 - y_bottom, &t0, &t1) ) { // bottom
+
+                if ( clipt_int(delta_y, y_top - *y0, &t0, &t1) ) { // top
+                    // Compute coordinates
+
+                    if (t1 < 1) {   // Compute V1' (new x1,y1)
+                        *x1 = *x0 + t1 * delta_x;
+                        *y1 = *y0 + t1 * delta_y;
+                    }
+
+                    if (t0 > 0) {   // Compute V0' (new x0,y0)
+                        *x0 = *x0 + t0 * delta_x;
+                        *y0 = *y0 + t0 * delta_y;
+                    }
+                    visible = True;
+                }
+                else {
+                    //fprintf(stderr,"reject top\n");
+                }
+            }
+            else {
+                //fprintf(stderr,"reject bottom\n");
+            }
+        }
+        else {
+            //fprintf(stderr,"reject right\n");
+        }
+    }
+    else {
+        //fprintf(stderr,"reject left\n");
+    }
+    return(visible);
+}
+
+
+
+
+
+// Draws a point onto a pixmap.  Assumes that the proper GC has
+// already been set up for drawing the correct color/width/linetype,
+// etc.  If the bounding box containing the point doesn't intersect
+// with the current view, the point isn't drawn.
+//
+// Input point is in the Xastir coordinate system.
+//
+void draw_point(Widget w,
+                 unsigned long x1,
+                 unsigned long y1,
+                 GC gc,
+                 Pixmap which_pixmap,
+                 int skip_duplicates) {
+
+    int x1i, y1i;
+    static int last_x1i;
+    static int last_y1i;
+
+
+    // Check whether the two bounding boxes intersect.  If not, skip
+    // the rest of this function.  Do we need to worry about
+    // special-case code here to handle vertical/horizontal lines
+    // (width or length of zero)?
+    //
+//
+// WE7U
+// Check to see if we can do this faster than map_visible() can.  A
+// point is a special case that should take only four compares
+// against the map window boundaries.
+//
+    if (!map_visible(y1, y1, x1, x1)) {
+        // Skip this vector
+        //fprintf(stderr,"Point not visible\n");
+        return;
+    }
+
+    // Convert to screen coordinates.  Careful here!
+    // The format conversions you'll need if you try to
+    // compress this into two lines will get you into
+    // trouble.
+    x1i = x1 - NW_corner_longitude;
+    x1i = x1i / scale_x;
+ 
+    y1i = y1 - NW_corner_latitude;
+    y1i = y1i / scale_y;
+
+    if (skip_duplicates) {
+        if (x1i == last_x1i && y1i == last_y1i) {
+            return;
+        }
+    }
+
+    // XDrawPoint uses 16-bit unsigned integers
+    // (shorts).  Make sure we stay within the limits.
+    (void)XDrawPoint(XtDisplay(w),
+        which_pixmap,
+        gc,
+        l16(x1i),
+        l16(y1i));
+
+    last_x1i = x1i;
+    last_y1i = y1i;
+}
+
+
+
+
+
+// Draws a vector onto a pixmap.  Assumes that the proper GC has
+// already been set up for drawing the correct color/width/linetype,
+// etc.
+//
+// Input points are in lat/long coordinates.
+//
+void draw_point_ll(Widget w,
+                    float y1,   // lat1
+                    float x1,   // long1
+                    GC gc,
+                    Pixmap which_pixmap,
+                 int skip_duplicates) {
+
+    unsigned long x1L, y1L;
+
+//
+// WE7U
+// We should probably do four floating point compares against the
+// map boundaries here in order to speed up rejection of points that
+// don't fit our window.  If we change to that, copy the conversion-
+// to-screen-coordinates and drawing stuff from draw_point() down to
+// this routine so that we don't go through the comparisons again
+// there.
+//
+    // Convert the point to the Xastir coordinate system.
+    convert_to_xastir_coordinates(&x1L,
+        &y1L,
+        x1,
+        y1);
+
+    // Call the draw routine above.
+    draw_point(w, x1L, y1L, gc, which_pixmap, skip_duplicates);
+}
+
+
+
+
+
+// Draws a vector onto a pixmap.  Assumes that the proper GC has
+// already been set up for drawing the correct color/width/linetype,
+// etc.  If the bounding box containing the vector doesn't intersect
+// with the current view, the line isn't drawn.
+//
+// Input points are in the Xastir coordinate system.
+//
+void draw_vector(Widget w,
+                 unsigned long x1,
+                 unsigned long y1,
+                 unsigned long x2,
+                 unsigned long y2,
+                 GC gc,
+                 Pixmap which_pixmap,
+                 int skip_duplicates) {
+
+    int x1i, x2i, y1i, y2i;
+    static int last_x1i, last_x2i, last_y1i, last_y2i;
+
+
+    //fprintf(stderr,"%ld,%ld  %ld,%ld\t",x1,y1,x2,y2);
+    if ( !clip2d_long(&x1, &y1, &x2, &y2) ) {
+        // Skip this vector
+        //fprintf(stderr,"Line not visible\n");
+        //fprintf(stderr,"%ld,%ld  %ld,%ld\n",x1,y1,x2,y2);
+        return;
+    }
+    //fprintf(stderr,"%ld,%ld  %ld,%ld\n",x1,y1,x2,y2);
+ 
+    // Convert to screen coordinates.  Careful here!
+    // The format conversions you'll need if you try to
+    // compress this into two lines will get you into
+    // trouble.
+    x1i = x1 - NW_corner_longitude;
+    x1i = x1i / scale_x;
+ 
+    y1i = y1 - NW_corner_latitude;
+    y1i = y1i / scale_y;
+
+    x2i = x2 - NW_corner_longitude;
+    x2i = x2i / scale_x;
+ 
+    y2i = y2 - NW_corner_latitude;
+    y2i = y2i / scale_y;
+
+    if (skip_duplicates) {
+        if (last_x1i == x1i
+                && last_x2i == x2i
+                && last_y1i == y1i
+                && last_y2i == y2i) {
+            return;
+        }
+    }
+
+    // XDrawLine uses 16-bit unsigned integers
+    // (shorts).  Make sure we stay within the limits.
+    // clip2d_long() should make sure of this anyway as it clips
+    // lines to fit the window.
+    //
+    (void)XDrawLine(XtDisplay(w),
+        which_pixmap,
+        gc,
+        l16(x1i),
+        l16(y1i),
+        l16(x2i),
+        l16(y2i));
+
+    last_x1i = x1i;
+    last_x2i = x2i;
+    last_y1i = y1i;
+    last_y2i = y2i;
+}
+
+
+
+
+
+// Draws a vector onto a pixmap.  Assumes that the proper GC has
+// already been set up for drawing the correct color/width/linetype,
+// etc.
+//
+// Input points are in lat/long coordinates.
+//
+void draw_vector_ll(Widget w,
+                    float y1,   // lat1
+                    float x1,   // long1
+                    float y2,   // lat2
+                    float x2,   // long2
+                    GC gc,
+                    Pixmap which_pixmap,
+                    int skip_duplicates) {
+
+    unsigned long x1L, x2L, y1L, y2L;
+    int x1i, x2i, y1i, y2i;
+    static int last_x1i, last_x2i, last_y1i, last_y2i;
+
+
+    //fprintf(stderr,"%lf,%lf  %lf,%lf\t",x1,y1,x2,y2);
+    if ( !clip2d(&x1, &y1, &x2, &y2) ) {
+        // Skip this vector
+//fprintf(stderr,"Line not visible: %lf,%lf  %lf,%lf\n",y1,x1,y2,x2);
+        return;
+    }
+//fprintf(stderr,"%lf,%lf  %lf,%lf\n",x1,y1,x2,y2);
+ 
+    // Convert the points to the Xastir coordinate system.
+    convert_to_xastir_coordinates(&x1L,
+        &y1L,
+        x1,
+        y1);
+
+    convert_to_xastir_coordinates(&x2L,
+        &y2L,
+        x2,
+        y2);
+
+//fprintf(stderr,"%ld,%ld  %ld,%ld\n",x1L,y1L,x2L,y2L);
+ 
+    // Convert to screen coordinates.  Careful here!
+    // The format conversions you'll need if you try to
+    // compress this into two lines will get you into
+    // trouble.
+    x1i = (int)(x1L - NW_corner_longitude);
+    x1i = x1i / scale_x;
+ 
+    y1i = (int)(y1L - NW_corner_latitude);
+    y1i = y1i / scale_y;
+
+    x2i = (int)(x2L - NW_corner_longitude);
+    x2i = x2i / scale_x;
+ 
+    y2i = (int)(y2L - NW_corner_latitude);
+    y2i = y2i / scale_y;
+
+    if (skip_duplicates) {
+        if (last_x1i == x1i
+                && last_x2i == x2i
+                && last_y1i == y1i
+                && last_y2i == y2i) {
+//            fprintf(stderr,"Duplicate line\n");
+            return;
+        }
+    }
+//fprintf(stderr,"NW_corner_latitude:%ld, NW_corner_longitude:%ld, scale_x:%ld, scale_y:%ld\n",
+//    NW_corner_latitude,
+//    NW_corner_longitude,
+//    scale_x,
+//    scale_y);
+
+//fprintf(stderr,"%d,%d  %d,%d\n\n",x1i,y1i,x2i,y2i);
+ 
+    // XDrawLine uses 16-bit unsigned integers
+    // (shorts).  Make sure we stay within the limits.
+    // clip2d() should make sure of this anyway as it clips lines to
+    // fit the window.
+    //
+    (void)XDrawLine(XtDisplay(w),
+        which_pixmap,
+        gc,
+        l16(x1i),
+        l16(y1i),
+        l16(x2i),
+        l16(y2i));
+
+    last_x1i = x1i;
+    last_x2i = x2i;
+    last_y1i = y1i;
+    last_y2i = y2i;
+}
+
+
+
+
+
+// Find length of a standard string of seven zeroes in the border font.
+// Supporting function for draw_grid() and the grid drawing functions.
+int get_standard_border_string_width_pixels(Widget w, int length) {
+    int string_width_pixels = 0; // Width of the unrotated seven_zeroes label string in pixels.
+    char seven_zeroes[8] = "0000000";
+    char five_zeroes[6]  = "00000";
+   
+    if (length==5) 
+         string_width_pixels = get_rotated_label_text_length_pixels(w, five_zeroes, FONT_BORDER);
+    
+    string_width_pixels = get_rotated_label_text_length_pixels(w, seven_zeroes, FONT_BORDER);
+    return string_width_pixels;
+}
+
+
+
+
+
+// Find height of a standard string in the border font
+// Supporting function for draw_grid() and the grid drawing functions.
+int get_standard_border_string_height_pixels(Widget w) {
+    int string_width_pixels = 0; // Width of the unrotated seven_zeroes label string in pixels.
+    char one_zero[2] = "0";
+   
+    string_width_pixels = get_rotated_label_text_height_pixels(w, one_zero, FONT_BORDER);
+    return string_width_pixels;
+}
+
+
+
+
+
+// Find out the width to use for the border to apply when uing a labeled grid.
+// Border width is determined from the height of the border font.
+// Supporting function for draw_grid() and the grid drawing functions.
+int get_border_width(Widget w) {
+    int border_width = 14;      // The width of the border to draw around the 
+                                // map to place labeled tick marks into
+                                // should be an even number.
+                                // The default here is overidden by size of the border font.
+    int string_height_pixels = 0; // Height of a string in the border font in pixels
+
+    string_height_pixels = get_standard_border_string_height_pixels(w);
+    // Rotated text functions used to draw the border text add some 
+    // blank space at the bottom of the text so make the border wide enough 
+    // to compensate for this.
+    border_width = string_height_pixels + (string_height_pixels/2) + 1; 
+    // check to see if string_height_pixels is even
+    if ((float)string_height_pixels/2.0!=floor((float)string_height_pixels/2.0)) { 
+        border_width++; 
+    }
+    // we are using draw nice string to write the metadata in the top border, so 
+    // make sure the border is wide enough for it, even if the grid labels are small.
+    if (border_width < 14) { border_width = 14; }
+    return border_width;
+}
+
+
+
+
+
+// ***********************************************************
+//
+// get_horizontal_datum()
+//
+// Provides the current map datum.  Current default is WGS84.
+// Parameters: datum, character array ponter for the string
+//             that will be filled with the current datum
+// sizeof_datum, the size of the datum character array.  
+//
+//***********************************************************
+void get_horizontal_datum(char *datum, int sizeof_datum) {
+    char metadata_datum[6] = "WGS84";  // datum to display in metadata on top border
+    xastir_snprintf(datum, sizeof_datum, "%s", metadata_datum);
+    if (sizeof_datum<6) 
+       fprintf(stderr,"Datum [%s] truncated to [%s]\n",metadata_datum,datum);
+}
+
+
+
+
+
+// Lat/Long coordinate system, draw lat/long lines.  Called by
+// draw_grid() below.  
+//
+void draw_complete_lat_lon_grid(Widget w) {
+
+    int coord;
+    char dash[2];
+    unsigned int x,x1,x2;
+    unsigned int y,y1,y2;
+    unsigned int stepsx;         // spacing of grid lines  
+    unsigned int stepsy;         // spacing of grid lines
+    int coordinate_format;      // Format to use for coordinates on border (e.g. decimal degrees).
+    char grid_label[25];        // String to draw labels on grid lines
+    int screen_width_xastir;  // screen width in xastir units (1/100 of a second)
+    int screen_height_xastir; // screen height in xastir units (1/100 of a second)
+    int border_width;          // the width of the labeled border in pixels.
+    int string_width_pixels = 0;// Width of a grid label string in pixels.
+    float screen_width_degrees;   // Width of the screen in degrees
+    int log_screen_width_degrees; // Log10 of the screen width in degrees, used to scale degrees
+    long xx2, yy2;
+    long xx, yy;
+    unsigned int last_label_end;  // cordinate of the end of the previous label
+    char metadata_datum[6];  // datum to display in metadata on top border
+    char grid_label1[25];       // String to draw latlong metadata 
+    char grid_label2[25];       // String to draw latlong metadata 
+    char top_label[180];        // String to draw metadata on top border
+ 
+    if (!long_lat_grid) // We don't wish to draw a map grid
+        return;
+ 
+    // convert between selected coordinate format constant and display format constants
+    if (coordinate_system == USE_DDDDDD) {
+       coordinate_format = CONVERT_DEC_DEG;
+    }
+    else if (coordinate_system == USE_DDMMSS) {
+       coordinate_format = CONVERT_DMS_NORMAL_FORMATED;
+    }
+    else {
+       coordinate_format = CONVERT_HP_NORMAL_FORMATED;
+    }
+    border_width = get_border_width(w);
+    // Find xastir coordinates of upper left and lower right corners.
+    xx = NW_corner_longitude  + (border_width * scale_x);
+    yy = NW_corner_latitude   + (border_width * scale_y);
+    xx2 = NW_corner_longitude  + ((screen_width - border_width) * scale_x);
+    yy2 = NW_corner_latitude   + ((screen_height - border_width) * scale_y);
+    screen_width_xastir = xx2 - xx;
+    screen_height_xastir = yy2 - yy;
+    // Determine some parameters used in drawing the border.
+    string_width_pixels = get_standard_border_string_width_pixels(w, 7);
+    // 1 xastir coordinate = 1/100 of a second  
+    // 100*60*60 xastir coordinates (=360000 xastir coordinates) = 1 degree
+    // 64800000 xastir coordinates = 180 degrees
+    // 360000   xastir coordinates = 1 degree
+    // scale_x * (screen_width/10) = one tenth of the screen width in xastir coordinates
+    // scale_x number of xastir coordinates per pixel
+    screen_width_degrees = (float)(screen_width_xastir / (float)360000);
+    log_screen_width_degrees = (int)log10(screen_width_degrees);
+ 
+
+    if (draw_labeled_grid_border==TRUE) { 
+        get_horizontal_datum(metadata_datum, sizeof(metadata_datum));
+ 
+        // Put metadata in top border.
+        // find location of upper left corner of map, convert to Lat/Long
+        convert_lon_l2s(xx, grid_label1, sizeof(grid_label1), coordinate_format);
+        convert_lat_l2s(yy, grid_label2, sizeof(grid_label2), coordinate_format);
+        xastir_snprintf(grid_label,
+            sizeof(grid_label),
+            "%s %s",
+            grid_label1,grid_label2);
+        // find location of lower right corner of map, convert to Lat/Long
+        convert_lon_l2s(xx2, grid_label1, sizeof(grid_label1), coordinate_format);
+        convert_lat_l2s(yy2, grid_label2, sizeof(grid_label2), coordinate_format);
+        //"XASTIR Map of %s (upper left) to %s %s (lower right).  Lat/Long grid, %s datum. ",
+        xastir_snprintf(top_label,
+            sizeof(top_label),
+            langcode("MDATA002"),
+            grid_label,grid_label1,grid_label2,metadata_datum);
+        draw_rotated_label_text_to_target (w, 270, 
+            border_width+2,
+            border_width-1,
+            sizeof(top_label),colors[0x10],top_label,FONT_BORDER,
+            pixmap_final,
+            outline_border_labels, colors[outline_border_labels_color]);
+    }
+
+    // A crude grid spacing can be obtained from scaling one tenth of the screen width.
+    // This works, but puts the grid lines at arbitrary increments of a degree. 
+    //stepsx = (scale_x*(screen_width/10));
+
+    // Setting the grid using the base 10 log of the screen width in degrees allows 
+    // both scaling the grid to the screen and spacing the grid lines at appropriately 
+    // rounded increments of a degree.  
+    //
+    // Set default grid to 0.1 degree.  This will be used when the screen width is about 1 degree.
+    stepsx = 36000;  // if (log_screen_width_degrees == 0)
+    // Work out an appropriate grid spacing for the screen size and coordinate system.
+    if (log_screen_width_degrees > 0) {
+        // grid spacing is rounded to 10 degree increment.
+        stepsx = ((int)(screen_width_degrees / (pow(10,log_screen_width_degrees)))*pow(10,log_screen_width_degrees)) * 36000;
+    }
+    if (log_screen_width_degrees < 0) {
+        // Grid spacing is rounded to less than one degree.
+        if (coordinate_system == USE_DDDDDD) {
+            // Round to tenths or hundrethds or thousanths of a degree.
+            stepsx = ((float)(int)(((float)screen_width_degrees / pow(10,log_screen_width_degrees)*10.0)))*pow(10,log_screen_width_degrees) * 3600;
+        }
+        else {
+            // For decimal minutes or minutes and seconds.
+            // Find screen width and log screen width in minutes.
+            screen_width_degrees = screen_width_degrees * 60.0;
+            log_screen_width_degrees = (int)log10(screen_width_degrees);
+            // round to minutes or tenths of minutes.
+            stepsx = ((float)(int)
+                      ((float)(screen_width_degrees) / pow(10,log_screen_width_degrees) * 10.0)
+                     )
+                     * pow(10,log_screen_width_degrees) * 3600;
+            if (log_screen_width_degrees==0) {
+                stepsx = 600; // 6000 = 1 minute
+            }
+        }
+    }
+    // Grid should now be close to reasonable spacing for screen size, but
+    // may need to be tuned. 
+    // Test for too tightly or too coarsely spaced grid.
+    if (stepsx<(unsigned int)(scale_x * string_width_pixels * 1.5)) {
+        stepsx = stepsx * 2.0;
+    }
+    if (stepsx<(unsigned int)(scale_x * string_width_pixels * 1.5)) {
+        stepsx = stepsx * 2.0;
+    }
+    if (stepsx>(unsigned int)((scale_x * screen_width)/3.5)) {
+        stepsx = stepsx / 2.0;
+    }
+    // Handle special case of very small screen - only draw a single grid line
+    if (screen_width < (string_width_pixels * 2)) {
+        stepsx = (scale_x*(screen_width/2));
+    }
+    // Make sure we don't pass an erronous stepsx of 0 on.
+    if (stepsx==0) 
+        stepsx=36000;
+   
+    // Use the same grid spacing for both latitude and longitude grids.
+    // We could use a scaling factor related to the screen height width ratio here.
+    stepsy = stepsx;
+
+    // protect against division by zero
+    if (scale_x==0) scale_x = 1;
+    if (scale_y==0) scale_y = 1;
+
+    // Now draw and label the grid.
+    // Draw vertical longitude lines
+    if (NW_corner_latitude >= 0)
+        y1 = 0;
+    else
+        y1 = -NW_corner_latitude/scale_y;
+
+    y2 = (180*60*60*100-NW_corner_latitude)/scale_y;
+
+    if (y2 > (unsigned int)screen_height)
+        y2 = screen_height-1;
+
+    coord = NW_corner_longitude+stepsx-(NW_corner_longitude%stepsx);
+    if (coord < 0)
+        coord = 0;
+
+    last_label_end = 0;
+    for (; coord < SE_corner_longitude && coord <= 360*60*60*100; coord += stepsx) {
+
+        x = (coord-NW_corner_longitude)/scale_x;
+
+        if ((coord%(648000*100)) == 0) {
+            (void)XSetLineAttributes (XtDisplay (w),
+                gc_tint,
+                1,
+                LineSolid,
+                CapButt,
+                JoinMiter);
+            (void)XDrawLine (XtDisplay (w),
+                pixmap_final,
+                gc_tint,
+                l16(x),
+                l16(y1),
+                l16(x),
+                l16(y2));
+            (void)XSetLineAttributes (XtDisplay (w),
+                gc_tint,
+                1,
+                LineOnOffDash,
+                CapButt,
+                JoinMiter);
+            continue;   // Go to next iteration of for loop
+        }
+        else if ((coord%(72000*100)) == 0) {
+            dash[0] = dash[1] = 8;
+            (void)XSetDashes (XtDisplay (w), gc_tint, 0, dash, 2);
+        } 
+         else if ((coord%(7200*100)) == 0) {
+            dash[0] = dash[1] = 4;
+            (void)XSetDashes (XtDisplay (w), gc_tint, 0, dash, 2);
+        }
+        else if ((coord%(300*100)) == 0) {
+            dash[0] = dash[1] = 2;
+            (void)XSetDashes (XtDisplay (w), gc_tint, 0, dash, 2);
+        }
+
+        (void)XDrawLine (XtDisplay (w),
+            pixmap_final,
+            gc_tint,
+            l16(x),
+            l16(y1),
+            l16(x),
+            l16(y2));
+
+        if (draw_labeled_grid_border==TRUE) { 
+            // Label the longitudes in lower border.
+            convert_lon_l2s(coord, grid_label, sizeof(grid_label), coordinate_format);
+            if (log_screen_width_degrees > 0 && strlen(grid_label) > 5) {
+                 // truncate the grid_label string
+                 if (coordinate_system==USE_DDMMMM) {
+                     // Add ' and move EW and null characters forward.
+                     grid_label[strlen(grid_label)-5] = '\'';
+                     grid_label[strlen(grid_label)-4] = grid_label[strlen(grid_label)-1];
+                     grid_label[strlen(grid_label)-3] = grid_label[strlen(grid_label)];
+                 } 
+                 else {
+                     // Move EW and null characters forward.
+                     grid_label[strlen(grid_label)-5] = grid_label[strlen(grid_label)-1];
+                     grid_label[strlen(grid_label)-4] = grid_label[strlen(grid_label)];
+                 }
+            }
+            string_width_pixels = get_rotated_label_text_length_pixels(w, grid_label, FONT_BORDER);
+            // test for overlap of label with previously printed label
+            if (x > last_label_end + 3 && x < (unsigned int)(screen_width - string_width_pixels)) {
+                draw_rotated_label_text_to_target (w, 270, 
+                    x,
+                    screen_height, 
+                    sizeof(grid_label),colors[0x09],grid_label,FONT_BORDER,
+                    pixmap_final,
+                    outline_border_labels, colors[outline_border_labels_color]);
+                last_label_end = x + string_width_pixels;
+            }
+        }
+    }
+
+    // Draw horizontal latitude lines.
+    last_label_end = 0;
+    if (NW_corner_longitude >= 0)
+        x1 = 0;
+    else
+        x1 = -NW_corner_longitude/scale_x;
+
+    x2 = (360*60*60*100-NW_corner_longitude)/scale_x;
+    if (x2 > (unsigned int)screen_width)
+        x2 = screen_width-1;
+
+    coord = NW_corner_latitude+stepsy-(NW_corner_latitude%stepsy);
+    if (coord < 0)
+        coord = 0;
+
+    for (; coord < SE_corner_latitude && coord <= 180*60*60*100; coord += stepsy) {
+
+        y = (coord-NW_corner_latitude)/scale_y;
+
+        if ((coord%(324000*100)) == 0) {
+            (void)XSetLineAttributes (XtDisplay (w),
+                gc_tint,
+                1,
+                LineSolid,
+                CapButt,
+                JoinMiter);
+            (void)XDrawLine (XtDisplay (w),
+                pixmap_final,
+                gc_tint,
+                l16(x1),
+                l16(y),
+                l16(x2),
+                l16(y));
+            (void)XSetLineAttributes (XtDisplay (w),
+                gc_tint,
+                1,
+                LineOnOffDash,
+                CapButt,
+                JoinMiter);
+            continue;   // Go to next iteration of for loop
+        }
+        else if ((coord%(36000*100)) == 0) {
+            dash[0] = dash[1] = 8;
+            (void)XSetDashes (XtDisplay (w), gc_tint, 4, dash, 2);
+        }
+        else if ((coord%(3600*100)) == 0) {
+            dash[0] = dash[1] = 4;
+            (void)XSetDashes (XtDisplay (w), gc_tint, 2, dash, 2);
+        }
+        else if ((coord%(150*100)) == 0) {
+            dash[0] = dash[1] = 2;
+        (void)XSetDashes (XtDisplay (w), gc_tint, 1, dash, 2);
+        }
+
+        (void)XDrawLine (XtDisplay (w),
+            pixmap_final,
+            gc_tint,
+            l16(x1),
+            l16(y),
+            l16(x2),
+            l16(y));
+
+        if (draw_labeled_grid_border==TRUE) { 
+            // label the latitudes on left and right borders
+            // (unlike UTM where easting before northing order is important)
+            convert_lat_l2s(coord, grid_label, sizeof(grid_label), coordinate_format);
+            if (log_screen_width_degrees > 0 && strlen(grid_label) > 5) {
+                 // truncate the grid_label string
+                 if (coordinate_system==USE_DDMMMM) {
+                     // Add ' and move EW and null characters forward.
+                     grid_label[strlen(grid_label)-5] = '\'';
+                     grid_label[strlen(grid_label)-4] = grid_label[strlen(grid_label)-1];
+                     grid_label[strlen(grid_label)-3] = grid_label[strlen(grid_label)];
+                 } 
+                 else {
+                     // Move EW and null characters forward.
+                     grid_label[strlen(grid_label)-5] = grid_label[strlen(grid_label)-1];
+                     grid_label[strlen(grid_label)-4] = grid_label[strlen(grid_label)];
+                 }
+            }
+            string_width_pixels = get_rotated_label_text_length_pixels(w, grid_label, FONT_BORDER);
+            // check to make sure we aren't overwriting the previous label text
+            if ((y > last_label_end+3) && (y > (unsigned int)string_width_pixels)) {
+                draw_rotated_label_text_to_target (w, 180, 
+                    screen_width, 
+                    y,
+                    sizeof(grid_label),colors[0x09],grid_label,FONT_BORDER,
+                    pixmap_final,
+                    outline_border_labels, colors[outline_border_labels_color]);
+                draw_rotated_label_text_to_target (w, 180, 
+                    border_width, 
+                    y,
+                    sizeof(grid_label),colors[0x09],grid_label,FONT_BORDER,
+                    pixmap_final,
+                    outline_border_labels, colors[outline_border_labels_color]);
+                last_label_end = y + string_width_pixels;
+            }
+        }
+    }
+} // End of draw_complete_lat_lon_grid()
+
+
+
+
+
+// Draw the major zones for UTM and MGRS.  Called by draw_grid()
+// below.
+//
+// These are based off 6-degree lat/long lines, with a few irregular
+// zones that have to be special-cased.  This part of the code
+// handles the irregular zones in SW Norway (31V/32V) and the
+// regions near Svalbard (31X/33X/35X/37X) just fine.
+
+// These are based off the central meridian running up the middle of
+// each zone (3 degrees from either side of the standard six-degree
+// zones).  Even the irregular zones key off the same medians.  UTM
+// grids are defined in terms of meters instead of lat/long, so they
+// don't line up with the left/right edges of the zones or with the
+// longitude lines.
+//
+// According to Peter Dana (Geographer's Craft web pages), even when
+// the major grid boundaries have been shifted, the meridian used
+// for drawing the subgrids is still based on six-degree boundaries
+// (as if the major grid hadn't been shifted at all).  That means we
+// are drawing the subgrids correctly as it stands now for the
+// irregular grids (31V/32V/31X/33X/35X/37X).  The irregular zones
+// have sizes of 3/9/12 degrees (width) instead of 6 degrees.
+//
+// UTM NOTES:  84 degrees North to 80 degrees South. 60 zones, each
+// covering six (6) degrees of longitude. Each zone extends three
+// degrees eastward and three degrees westward from its central
+// meridian.  Zones are numbered consecutively west to east from the
+// 180 degree meridian. From 84 degrees North and 80 degrees South
+// to the respective poles, the Universal Polar Stereographic (UPS)
+// is used.
+//
+// For MGRS and UTM-Special grid only:
+// UTM Zone 32 has been widened to 9� (at the expense of zone 31)
+// between latitudes 56� and 64� (band V) to accommodate southwest
+// Norway. Thus zone 32 extends westwards to 3�E in the North Sea.
+// Similarly, between 72� and 84� (band X), zones 33 and 35 have
+// been widened to 12� to accommodate Svalbard. To compensate for
+// these 12� wide zones, zones 31 and 37 are widened to 9� and zones
+// 32, 34, and 36 are eliminated. Thus the W and E boundaries of
+// zones are 31: 0 - 9 E, 33: 9 - 21 E, 35: 21 - 33 E and 37: 33 -
+// 42 E.
+//
+// UTM is depending on the ellipsoid and the datum used.  For our
+// purposes, we're always using WGS84 ellipsoid and datum, so it's a
+// non-issue.
+//
+// Horizontal bands corresponding to the NATO UTM/UPS lettering:
+// Zones go from A (south pole) to Z (north pole).  South of -80 are
+// zones A/B, north of +84 are zones Y/Z.  "I" and "O" are not used.
+// Zones from C to W are 8 degrees high.  Zone X is 12 degrees high.
+//
+// We need these NATO letters or a N/S designator in order to
+// specify which hemisphere the UTM coordinates are in.  Often, the
+// same coordinates can appear in either hemisphere.  Some computer
+// software uses +/- to designate northings instead of N/S or the
+// NATO lettered bands.
+//
+// UPS system is used at the poles instead of UTM.  UPS uses a false
+// northing and easting of 2,000,000 meters.
+//
+// An arbitrary false northing of 10,000,000 at the equator is used
+// for southern latitudes only.  Northern latitudes assume the
+// equator northing is at zero.  An arbitrary false easting of
+// 500,000 is along the meridian of each zone (3 degrees from each
+// side).  The lettered grid lines are necessary due to some
+// coordinates being valid in both the northern and the southern
+// hemisphere.
+//
+// Y/Z  84N to 90N (UPS System) false N/E = 2,000,000
+// X    72N to 84N (12 degrees latitude, equator=0)
+// W    64N to 72N ( 8 degrees latitude, equator=0)
+// V    56N to 64N ( 8 degrees latitude, equator=0)
+// U    48N to 56N ( 8 degrees latitude, equator=0)
+// T    40N to 48N ( 8 degrees latitude, equator=0)
+// S    32N to 40N ( 8 degrees latitude, equator=0)
+// R    24N to 32N ( 8 degrees latitude, equator=0)
+// Q    16N to 24N ( 8 degrees latitude, equator=0)
+// P     8N to 16N ( 8 degrees latitude, equator=0)
+// N     0N to  8N ( 8 degrees latitude, equator=0)
+// M     0S to  8S ( 8 degrees latitude, equator=10,000,000)
+// L     8S to 16S ( 8 degrees latitude, equator=10,000,000)
+// K    16S to 24S ( 8 degrees latitude, equator=10,000,000)
+// J    24S to 32S ( 8 degrees latitude, equator=10,000,000)
+// H    32S to 40S ( 8 degrees latitude, equator=10,000,000)
+// G    40S to 48S ( 8 degrees latitude, equator=10,000,000)
+// F    48S to 56S ( 8 degrees latitude, equator=10,000,000)
+// E    56S to 64S ( 8 degrees latitude, equator=10,000,000)
+// D    64S to 72S ( 8 degrees latitude, equator=10,000,000)
+// C    72S to 80S ( 8 degrees latitude, equator=10,000,000)
+// A/B  80S to 90S (UPS System) false N/E = 2,000,000
+//
+void draw_major_utm_mgrs_grid(Widget w) {
+    int ii;
+
+// need to move metadata to its own function and put it up after grids have been drawn.
+//*******
+    // variables for metadata in grid border
+    long xx2, yy2;  // coordinates of screen corners used for metadata
+    int border_width;           // Width of the border to draw labels into.
+    double easting, northing;   // Values used in border metadata.
+    int x, y;                   // Screen coordinates for border labels.
+    char zone_str[10];
+    char zone_str2[10];
+    char metadata_datum[6];
+    char grid_label[25];        // String to draw labels on grid lines
+    char grid_label1[25];       // String to draw latlong metadata 
+    char top_label[180];        // String to draw metadata on top border
+
+    // variables to support components of MGRS strings in the metadata
+    char mgrs_zone[4] = "   ";   // MGRS zone letter
+    char mgrs_eastingL[3] = "  "; 
+    char mgrs_northingL[3] = "  ";
+    unsigned int int_utmEasting;
+    unsigned int int_utmNorthing; 
+    char mgrs_space_string[4] = "   ";
+    int mgrs_single_digraph = FALSE; // mgrs_ul_digraph and mgrs_ur_digraph are the same.
+    char mgrs_ul_digraph[3] = "  ";  // MGRS digraph for upper left corner of screen
+    char mgrs_lr_digraph[3] = "  ";  // MGRS digraph for lower right corner of screen
+
+ 
+//fprintf(stderr,"draw_major_utm_mgrs_grid start\n");
+ 
+    if (!long_lat_grid) // We don't wish to draw a map grid
+        return;
+ 
+    // Vertical lines:
+
+    // Draw the vertical vectors (except for the irregular regions
+    // and the prime meridian).  The polar areas only have two zones
+    // each, so we don't want to draw through those areas.
+
+    for (ii = -180; ii < 0; ii += 6) {
+        draw_vector_ll(w, -80.0,  (float)ii, 84.0,  (float)ii, gc_tint, pixmap_final, 0);
+    }
+    for (ii = 42; ii <= 180; ii += 6) {
+        draw_vector_ll(w, -80.0,  (float)ii, 84.0,  (float)ii, gc_tint, pixmap_final, 0);
+    }
+
+    // Draw the short vertical vectors in the polar regions
+    draw_vector_ll(w, -90.0, -180.0, -80.0, -180.0, gc_tint, pixmap_final, 0);
+    draw_vector_ll(w, -90.0,  180.0, -80.0,  180.0, gc_tint, pixmap_final, 0);
+    draw_vector_ll(w,  84.0, -180.0,  90.0, -180.0, gc_tint, pixmap_final, 0);
+    draw_vector_ll(w,  84.0,  180.0,  90.0,  180.0, gc_tint, pixmap_final, 0);
+ 
+    if (coordinate_system == USE_UTM_SPECIAL
+            || coordinate_system == USE_MGRS) {
+        // For MGRS, we need to draw irregular zones in certain
+        // areas.
+
+        // Draw the partial vectors from 80S to the irregular region
+        draw_vector_ll(w, -80.0,    6.0,  56.0,    6.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w, -80.0,   12.0,  72.0,   12.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w, -80.0,   18.0,  72.0,   18.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w, -80.0,   24.0,  72.0,   24.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w, -80.0,   30.0,  72.0,   30.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w, -80.0,   36.0,  72.0,   36.0, gc_tint, pixmap_final, 0);
+
+        // Draw the short vertical vectors in the irregular region 
+        draw_vector_ll(w,  56.0,    3.0,  64.0,    3.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  64.0,    6.0,  72.0,    6.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  72.0,    9.0,  84.0,    9.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  72.0,   21.0,  84.0,   21.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  72.0,   33.0,  84.0,   33.0, gc_tint, pixmap_final, 0);
+
+        // Draw the short vertical vectors above the irregular region 
+        draw_vector_ll(w,  84.0,    6.0,  84.0,    6.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  84.0,   12.0,  84.0,   12.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  84.0,   18.0,  84.0,   18.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  84.0,   24.0,  84.0,   24.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  84.0,   30.0,  84.0,   30.0, gc_tint, pixmap_final, 0);
+        draw_vector_ll(w,  84.0,   36.0,  84.0,   36.0, gc_tint, pixmap_final, 0);
+    }
+    else {
+        // Draw normal zone boundaries used for civilian UTM
+        // grid.
+        for (ii = 6; ii < 42; ii += 6) {
+            draw_vector_ll(w, -80.0,  (float)ii, 84.0,  (float)ii, gc_tint, pixmap_final, 0);
+        }
+    }
+
+
+    // Horizontal lines:
+
+    // Draw the 8 degree spaced lines, except for the equator
+    for (ii = -80; ii < 0; ii += 8) {
+        draw_vector_ll(w, (float)ii, -180.0, (float)ii, 180.0, gc_tint, pixmap_final, 0);
+    }
+    // Draw the 8 degree spaced lines 
+    for (ii = 8; ii <= 72; ii += 8) {
+        draw_vector_ll(w, (float)ii, -180.0, (float)ii, 180.0, gc_tint, pixmap_final, 0);
+    }
+
+    // Draw the one 12 degree spaced line
+    draw_vector_ll(w, 84.0, -180.0, 84.0, 180.0, gc_tint, pixmap_final, 0);
+
+    // Draw the pole lines
+    draw_vector_ll(w, -90.0, -180.0, -90.0, 180.0, gc_tint, pixmap_final, 0);
+    draw_vector_ll(w,  90.0, -180.0,  90.0, 180.0, gc_tint, pixmap_final, 0);
+
+    // Set to solid line for the equator.  Make it extra wide as
+    // well.
+    (void)XSetLineAttributes (XtDisplay (w), gc_tint, 3, LineSolid, CapButt,JoinMiter);
+
+    // Draw the equator as a solid line
+    draw_vector_ll(w, 0.0, -180.0, 0.0, 180.0, gc_tint, pixmap_final, 0);
+
+    (void)XSetLineAttributes (XtDisplay (w), gc_tint, 2, LineSolid, CapButt,JoinMiter);
+
+    // Draw the prime meridian in the same manner
+    draw_vector_ll(w, -80.0, 0.0, 84.0, 0.0, gc_tint, pixmap_final, 0);
+
+    // add metadata and labels
+    if (draw_labeled_grid_border==TRUE && scale_x > 3000) { 
+        // Determine the width of the border
+        border_width = get_border_width(w);
+        // Find out what the map datum is.
+        get_horizontal_datum(metadata_datum, sizeof(metadata_datum));
+
+        // Put metadata in top border.
+        // find location of upper left corner of map, convert to UTM
+        xx2 = NW_corner_longitude  + (border_width * scale_x);
+        yy2 = NW_corner_latitude   + (border_width * scale_y);
+        convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), 
+            xx2, yy2);
+        if (coordinate_system == USE_MGRS) {
+            convert_xastir_to_MGRS_str_components(mgrs_zone, strlen(mgrs_zone), 
+                mgrs_eastingL,   sizeof(mgrs_eastingL), 
+                mgrs_northingL,  sizeof(mgrs_northingL), 
+                &int_utmEasting, &int_utmNorthing, 
+                xx2, yy2,
+                0, mgrs_space_string, strlen(mgrs_space_string));
+            xastir_snprintf(mgrs_ul_digraph, sizeof(mgrs_ul_digraph),
+                           "%c%c", mgrs_eastingL[0], mgrs_northingL[0]);
+            xastir_snprintf(grid_label,
+                sizeof(grid_label),
+                "%s %s %05.0f %05.0f",
+                mgrs_zone,mgrs_ul_digraph,(float)int_utmEasting,(float)int_utmNorthing);
+        } 
+        else {
+            xastir_snprintf(grid_label,
+                sizeof(grid_label),
+                "%s %07.0f %07.0f",
+                zone_str,easting,northing);
+        }
+        // find location of lower right corner of map, convert to UTM
+        xx2 = NW_corner_longitude  + ((screen_width - border_width) * scale_x);
+        yy2 = NW_corner_latitude   + ((screen_height - border_width) * scale_y);
+        convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), 
+            xx2, yy2);
+        if (coordinate_system == USE_MGRS) {
+            convert_xastir_to_MGRS_str_components(mgrs_zone, strlen(mgrs_zone), 
+                mgrs_eastingL,   sizeof(mgrs_eastingL), 
+                mgrs_northingL,  sizeof(mgrs_northingL), 
+                &int_utmEasting, &int_utmNorthing, 
+                xx2, yy2,
+                0, mgrs_space_string, strlen(mgrs_space_string));
+            xastir_snprintf(mgrs_lr_digraph, sizeof(mgrs_lr_digraph),
+                           "%c%c", mgrs_eastingL[0], mgrs_northingL[0]);
+            xastir_snprintf(grid_label1,
+                sizeof(grid_label1),
+                "%s %s %05.0f %05.0f",
+                mgrs_zone,mgrs_lr_digraph,(float)int_utmEasting,(float)int_utmNorthing);
+           if (strcmp(mgrs_lr_digraph,mgrs_ul_digraph)==0) {
+                 mgrs_single_digraph = TRUE; // mgrs_ul_digraph and mgrs_ur_digraph are the same.
+           } 
+           else {
+                 mgrs_single_digraph = FALSE; // mgrs_ul_digraph and mgrs_ur_digraph are the same.
+           }
+        } 
+        else {
+            xastir_snprintf(grid_label1,
+                sizeof(grid_label1),
+                "%s %07.0f %07.0f",
+                zone_str,easting,northing);
+        }
+        // Write metadata on upper border of map.
+        //"XASTIR Map of %s (upper left) to %s (lower right).  UTM zones, %s datum. ",
+        xastir_snprintf(top_label,
+            sizeof(top_label),
+            langcode("MDATA003"),
+            grid_label,grid_label1,metadata_datum);
+        draw_rotated_label_text_to_target (w, 270, 
+            border_width+2,
+            border_width-1,
+            sizeof(top_label),colors[0x10],top_label,FONT_BORDER,
+            pixmap_final,
+            outline_border_labels, colors[outline_border_labels_color]);
+        // Crudely identify zone boundaries by 
+        // iterating across bottom border.
+        xastir_snprintf(zone_str2,
+            sizeof(zone_str2),
+            "%s"," ");
+        for (x=1; x<(screen_width - border_width); x++) {
+            xx2 = NW_corner_longitude  + (x * scale_x);
+            yy2 = NW_corner_latitude   + ((screen_height - border_width) * scale_y);
+            convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), 
+               xx2, yy2);
+            zone_str[strlen(zone_str)-1] = '\0';
+            if (strcmp(zone_str,zone_str2) !=0) {
+                draw_rotated_label_text_to_target (w, 270, 
+                    x + 1,
+                    screen_height,
+                    sizeof(zone_str),colors[0x10],zone_str,FONT_BORDER,
+                    pixmap_final,
+                    outline_border_labels, colors[outline_border_labels_color]);
+            }
+            xastir_snprintf(zone_str2,
+                sizeof(zone_str2),
+                "%s",zone_str);
+        } 
+        // Crudely identify zone letters by iterating down left border
+        for (y=(border_width*2); y<(screen_height - border_width); y++) {
+            xx2 = NW_corner_longitude   + (border_width * scale_x);
+            yy2 = NW_corner_latitude   + (y * scale_y);
+            convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), 
+               xx2, yy2);
+            zone_str[0] = zone_str[strlen(zone_str)-1];
+            zone_str[1] = '\0';
+            if (strcmp(zone_str,zone_str2) !=0) {
+                draw_rotated_label_text_to_target (w, 270, 
+                    1,
+                    y,
+                    sizeof(zone_str),colors[0x10],zone_str,FONT_BORDER,
+                    pixmap_final,
+                   outline_border_labels, colors[outline_border_labels_color]);
+            }
+            xastir_snprintf(zone_str2,
+                sizeof(zone_str2),
+                "%s",zone_str);
+        } 
+    } // end if draw labeled border
+ 
+    // Set the line width and style in the GC to 1 pixel wide for
+    // drawing the smaller grid
+    (void)XSetLineAttributes (XtDisplay (w), gc_tint, 1, LineOnOffDash, CapButt,JoinMiter);
+
+//fprintf(stderr,"draw_major_utm_mgrs_grid end\n");
+ 
+} // End of draw_major_utm_mgrs_grid()
+
+
+
+
+
+// This is the function which actually draws a minor UTM grid.
+// Called by draw_minor_utm_mgrs_grid() function below.
+// draw_minor_utm_mgrs_grid() is the function which calculates the
+// grid points.
+//
+void actually_draw_utm_minor_grid(Widget w) {
+
+
+    int border_width;           // Width of the border to draw labels into.
+    int numberofzones = 0;      // number of elements in utm_grid.zone[] that are used
+    int Zone;
+    int ii;
+    int easting_color;          // Colors for the grid labels
+    int northing_color;
+    int zone_color;             // zone label color
+    int label_on_left;          // if true, draw northing labels on left
+    long xx, yy, xx2, yy2;
+    char zone_str[10];
+    char zone_str2[10];
+    double easting, northing;   
+    int short_width_pixels = 0; // Width of an unrotated string of five_zeroes in the border font in pixels.
+    int string_width_pixels = 0;// Width of an unrotated string of seven_zeroes in the border font in pixels.
+    char metadata_datum[6];
+    char grid_label[25];        // String to draw labels on grid lines
+    char grid_label1[25];       // String to draw latlong metadata 
+    char top_label[180];        // String to draw metadata on top border
+    int grid_spacing_pixels;    // Spacing of fine grid lines in pixels.
+    int bottom_point;           // utm_grid.zone[].col[].npoints can extend past the 
+                                // bottom of the screen, this is the lowest point in the
+                                // points array that is on the screen.
+    int  skip_alternate_label;  // Skip alternate easting and northing labels
+                                // if they would overlap on the
+                                // display.
+    int last_line_labeled;      // Marks lines that were labeled
+                                // when alternate lines are not
+                                // being labeled.
+ 
+    // variables to support components of MGRS strings
+    char mgrs_zone[4] = "   ";   // MGRS zone letter
+    char mgrs_eastingL[3] = "  "; 
+    char mgrs_northingL[3] = "  ";
+    unsigned int int_utmEasting;
+    unsigned int int_utmNorthing; 
+    char mgrs_space_string[4] = "   ";
+    int mgrs_single_digraph = FALSE; // mgrs_ul_digraph and mgrs_ur_digraph are the same.
+    char mgrs_ul_digraph[3] = "  ";  // MGRS digraph for upper left corner of screen
+    char mgrs_lr_digraph[3] = "  ";  // MGRS digraph for lower right corner of screen
+
+    if (!long_lat_grid) // We don't wish to draw a map grid
+        return;
+ 
+    // OLD: Draw grid in dashed white lines.
+    // NEW: Tint the lines as they go along, making them appear
+    // no matter what color is underneath.
+    (void)XSetForeground(XtDisplay(w), gc_tint, colors[0x27]);
+
+    // Note:  npoints can be negative here!  Make sure our code
+    // checks for that.  Initially npoints was an unsigned int.
+    // Changed it to an int so that we can get and check for
+    // negative values, bypassing segfaults.
+    //
+    numberofzones = 0;
+
+    // Determine the width of the border
+    border_width = get_border_width(w);
+    // Determine some parameters used in drawing the border.
+    string_width_pixels = get_standard_border_string_width_pixels(w, 7);
+    short_width_pixels = get_standard_border_string_width_pixels(w,5);
+
+    for (Zone=0; Zone < UTM_GRID_MAX_ZONES; Zone++) {
+
+        if (utm_grid.zone[Zone].ncols > 0) {
+            // find out how many zones are actually drawn on the map
+            numberofzones++;
+        }
+    }
+
+    for (Zone=0; Zone < UTM_GRID_MAX_ZONES; Zone++) {
+
+        for (ii=0; ii < (int)utm_grid.zone[Zone].ncols; ii++) {
+            if (utm_grid.zone[Zone].col[ii].npoints > 1) {
+
+                // We need to check for points that are more
+                // than +/- 16383.  If we have any, it can cause
+                // X11 to lock up for a while drawing lots of
+                // extra lines, due to bugs in X11.  We do that
+                // checking above with xx and yy.
+                //
+                (void)XDrawLines(XtDisplay(w),
+                    pixmap_final,
+                    gc_tint,
+                    utm_grid.zone[Zone].col[ii].points,
+                    l16(utm_grid.zone[Zone].col[ii].npoints),
+                    CoordModeOrigin);
+            }
+        }
+
+        for (ii=0; ii < (int)utm_grid.zone[Zone].nrows; ii++) {
+            if (utm_grid.zone[Zone].row[ii].npoints > 1) {
+
+                // We need to check for points that are more
+                // than +/- 16383.  If we have any, it can cause
+                // X11 to lock up for a while drawing lots of
+                // extra lines, due to bugs in X11.  We do that
+                // checking above with xx and yy.
+                //
+                (void)XDrawLines(XtDisplay(w),
+                    pixmap_final,
+                    gc_tint,
+                    utm_grid.zone[Zone].row[ii].points,
+                    l16(utm_grid.zone[Zone].row[ii].npoints),
+                    CoordModeOrigin);
+            }
+        }
+
+        // Check each of the 4 possible utm_grid.zone array elements 
+        // that might contain a grid, and label the grid if it exists.
+        if (utm_grid.zone[Zone].nrows>0 && utm_grid.zone[Zone].ncols>0) {
+            if (draw_labeled_grid_border==TRUE) { 
+                // Label the UTM grid on the border.
+                // Since the coordinate of the current mouse pointer position is 
+                // continually updated, labeling the grid is primarily for the 
+                // purpose of printing maps and saving screenshots.
+                //
+                // ******* Doesn't work properly near poles when 3 zones are on screen
+                // ******* (e.g. 13,14,15) - overlaps northings for 14 and 15.
+                // ******* Doesn't clearly distinguish one zone with 2 lettered rows
+                // ******* (e.g. 18T,18U) needs color distinction between northings
+                // ******* to indicate which northings are in which lettered row.
+                //
+                    
+                // Default labels for just one zone on screen are black text for
+                // zone at lower left corner, eastings on bottom, and northings
+                // at right.
+                // Idea is to normally start at the lower left corner
+                // users can then easily follow left to right to get easting, 
+                // and bottom to top to get northing.
+                // For two zones, second zone uses blue text for eastings and northings.
+                easting_color = 0x08;  // black text
+                northing_color = 0x08; // black text
+                zone_color = 0x08;     // black text 
+                                           // 0x09=blue (0x0e=yellow works well with outline, but not without).
+                label_on_left = FALSE;
+ 
+                // Find out what the map datum is.
+                get_horizontal_datum(metadata_datum, sizeof(metadata_datum));
+
+                if (numberofzones>1) {
+                    // check to see if the upper left and lower left corners are in the same zone
+                    // if not, label the upper left corner
+                    xx = (border_width * scale_x) + NW_corner_longitude;
+                    yy = ((screen_height - border_width) * scale_y) + NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx, yy);
+                    yy = (border_width * scale_y) + NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str2, sizeof(zone_str2), xx, yy);
+                    if (strcmp(zone_str,zone_str2)!=0) {
+                        xastir_snprintf(grid_label,
+                            sizeof(grid_label),
+                            "%s",
+                            zone_str2);
+                        //draw_nice_string(w,pixmap_final,0,
+                        //    border_width+2,
+                        //    (2*border_width)+2,
+                        //    grid_label,
+                        //    0x10,zone_color,(int)strlen(grid_label));
+                        draw_rotated_label_text_to_target (w, 270, 
+                            border_width+2,
+                            (2*border_width)+2,
+                            sizeof(grid_label),colors[zone_color],grid_label,FONT_BORDER,
+                            pixmap_final,
+                            1, colors[0x0f]);
+                    }
+                    if (strcmp(zone_str,zone_str2)!=0) {
+                        xastir_snprintf(grid_label,
+                            sizeof(grid_label),
+                            "%s",
+                            zone_str);
+                        draw_rotated_label_text_to_target (w, 270, 
+                            border_width+2,
+                            screen_height - (2*border_width) - 2,
+                            sizeof(grid_label),colors[zone_color],grid_label,FONT_BORDER,
+                            pixmap_final,
+                            1, colors[0x0f]);
+                    }
+                    zone_color = 0x09;
+                    // likewise for upper and lower right corners
+                    xx = ((screen_width - border_width) * scale_x) + NW_corner_longitude;
+                    yy = ((screen_height - border_width) * scale_y) + NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx, yy);
+                    yy = (border_width * scale_y) + NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str2, sizeof(zone_str2), xx, yy);
+                    if (strcmp(zone_str,zone_str2)!=0) {
+                        xastir_snprintf(grid_label,
+                            sizeof(grid_label),
+                            "%s",
+                            zone_str2);
+                        //draw_nice_string(w,pixmap_final,0,
+                        //    screen_width - (border_width * 3) ,
+                        //    (2*border_width)+2,
+                        //    grid_label,
+                        //    0x10,zone_color,(int)strlen(grid_label));
+                        draw_rotated_label_text_to_target (w, 270, 
+                            screen_width - (border_width * 3) ,
+                            (2*border_width)+2,
+                            sizeof(grid_label),colors[zone_color],grid_label,FONT_BORDER,
+                            pixmap_final,
+                            1, colors[0x0f]);
+                    }
+                    if (strcmp(zone_str,zone_str2)!=0) {
+                        xastir_snprintf(grid_label,
+                            sizeof(grid_label),
+                            "%s",
+                            zone_str);
+                        draw_rotated_label_text_to_target (w, 270, 
+                            screen_width - (border_width * 3) ,
+                            screen_height - (2*border_width) - 2,
+                            sizeof(grid_label),colors[zone_color],grid_label,FONT_BORDER,
+                            pixmap_final,
+                            1, colors[0x0f]);
+                    }
+                        
+                    // are we currently the same zone as the upper left corner
+                    // if so, we need to place the northing labels on the left side
+                    xx = (utm_grid.zone[Zone].col[0].points[0].x * scale_x) + NW_corner_longitude;
+                    yy = (utm_grid.zone[Zone].col[0].points[0].y * scale_y) + NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx, yy);
+                    convert_xastir_to_UTM(&easting, &northing, zone_str2, sizeof(zone_str2), NW_corner_longitude, NW_corner_latitude);
+                    if (strcmp(zone_str,zone_str2)==0) {
+                        northing_color = 0x08;  // 0x08 = black, same as lower left easting
+                        label_on_left = TRUE;
+                    }
+
+                }    
+                // check to see if there is a horizontal boundary 
+                // compare xone of upper left and lower left corners
+                convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), NW_corner_longitude, NW_corner_latitude);
+
+                // Overwrite defaults as appropriate and 
+                // label zones differently if more than one appears on the screen.
+
+                if (Zone > 0) {
+                    // write the zone label on the bottom border
+                    zone_color = 0x09;     // blue
+                    easting_color = 0x09;  // blue
+                    northing_color = 0x09; // blue
+                    xx2 = utm_grid.zone[Zone].col[0].points[0].x;
+                    xx = (xx2 * scale_x) + NW_corner_longitude;
+                    yy2 = utm_grid.zone[Zone].col[0].points[utm_grid.zone[Zone].col[0].npoints-1].y;
+                    yy = (yy2 * scale_y) +  NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx,yy);
+                    xastir_snprintf(grid_label,
+                        sizeof(grid_label),
+                        "%s",
+                        zone_str);
+                    draw_rotated_label_text_to_target (w, 270, 
+                        xx2,
+                        screen_height, 
+                        sizeof(grid_label),colors[easting_color],grid_label,FONT_BORDER,
+                        pixmap_final,
+                        outline_border_labels, colors[outline_border_labels_color]);
+                    //draw_nice_string(w,pixmap_final,0,
+                    //    xx2,
+                    //    screen_height - 2,
+                    //    grid_label,
+                    //    0x10,zone_color,(int)strlen(grid_label));
+                }
+
+                if (Zone==0) {
+                    // write the zone of the lower left corner of the map
+                    xx = (border_width * scale_x) + NW_corner_longitude;
+                    yy = ((screen_height - border_width) * scale_y) +  NW_corner_latitude;
+                    convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx, yy);
+                    xastir_snprintf(grid_label,
+                        sizeof(grid_label),
+                        "%s",
+                        zone_str);
+                    draw_rotated_label_text_to_target (w, 270, 
+                        1,
+                        screen_height, 
+                        sizeof(grid_label),colors[easting_color],grid_label,FONT_BORDER,
+                        pixmap_final,
+                        outline_border_labels, colors[outline_border_labels_color]);
+                    //draw_nice_string(w,pixmap_final,0,
+                    //    1,
+                    //    screen_height - 2,
+                    //    grid_label,
+                    //    0x10,0x20,(int)strlen(grid_label));
+                }
+                // Put metadata in top border.
+                // find location of upper left corner of map, convert to UTM
+                xx2 = NW_corner_longitude  + (border_width * scale_x);
+                yy2 = NW_corner_latitude   + (border_width * scale_y);
+                convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), 
+                    xx2, yy2);
+                if (coordinate_system == USE_MGRS) {
+                    convert_xastir_to_MGRS_str_components(mgrs_zone, strlen(mgrs_zone), 
+                        mgrs_eastingL,   sizeof(mgrs_eastingL), 
+                        mgrs_northingL,  sizeof(mgrs_northingL), 
+                        &int_utmEasting, &int_utmNorthing, 
+                        xx2, yy2,
+                        0, mgrs_space_string, strlen(mgrs_space_string));
+                    xastir_snprintf(mgrs_ul_digraph, sizeof(mgrs_ul_digraph),
+                                   "%c%c", mgrs_eastingL[0], mgrs_northingL[0]);
+                    xastir_snprintf(grid_label,
+                        sizeof(grid_label),
+                        "%s %s %05.0f %05.0f",
+                        mgrs_zone,mgrs_ul_digraph,(float)int_utmEasting,(float)int_utmNorthing);
+                } 
+                else {
+                    xastir_snprintf(grid_label,
+                        sizeof(grid_label),
+                        "%s %07.0f %07.0f",
+                        zone_str,easting,northing);
+                }
+                // find location of lower right corner of map, convert to UTM
+                xx2 = NW_corner_longitude  + ((screen_width - border_width) * scale_x);
+                yy2 = NW_corner_latitude   + ((screen_height - border_width) * scale_y);
+                convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), 
+                    xx2, yy2);
+                if (coordinate_system == USE_MGRS) {
+                    convert_xastir_to_MGRS_str_components(mgrs_zone, strlen(mgrs_zone), 
+                        mgrs_eastingL,   sizeof(mgrs_eastingL), 
+                        mgrs_northingL,  sizeof(mgrs_northingL), 
+                        &int_utmEasting, &int_utmNorthing, 
+                        xx2, yy2,
+                        0, mgrs_space_string, strlen(mgrs_space_string));
+                    xastir_snprintf(mgrs_lr_digraph, sizeof(mgrs_lr_digraph),
+                                   "%c%c", mgrs_eastingL[0], mgrs_northingL[0]);
+                    xastir_snprintf(grid_label1,
+                        sizeof(grid_label1),
+                        "%s %s %05.0f %05.0f",
+                        mgrs_zone,mgrs_lr_digraph,(float)int_utmEasting,(float)int_utmNorthing);
+                   if (strcmp(mgrs_lr_digraph,mgrs_ul_digraph)==0) {
+                         mgrs_single_digraph = TRUE; // mgrs_ul_digraph and mgrs_ur_digraph are the same.
+                   } 
+                   else {
+                         mgrs_single_digraph = FALSE; // mgrs_ul_digraph and mgrs_ur_digraph are the same.
+                   }
+                } 
+                else {
+                    xastir_snprintf(grid_label1,
+                        sizeof(grid_label1),
+                        "%s %07.0f %07.0f",
+                        zone_str,easting,northing);
+                }
+                //"XASTIR Map of %s (upper left) to %s (lower right).  UTM %d m grid, %s datum. ",
+                xastir_snprintf(top_label,
+                    sizeof(top_label),
+                    langcode("MDATA001"),
+                    grid_label,grid_label1,utm_grid_spacing_m,metadata_datum);
+                //draw_nice_string(w,pixmap_final,0,
+                //    border_width+2,
+                //    border_width-2,
+                //    top_label,
+                //    0x10,0x20,(int)strlen(top_label));
+                draw_rotated_label_text_to_target (w, 270, 
+                    border_width+2,
+                    border_width-1,
+                    sizeof(top_label),colors[0x10],top_label,FONT_BORDER,
+                    pixmap_final,
+                    outline_border_labels, colors[outline_border_labels_color]);
+
+                // deterimne whether the easting and northing strings will fit
+                // in a grid box, or whether easting strings in adjacent boxes
+                // will overlap (so that alternate strings can be skipped).  
+                if (utm_grid.zone[Zone].ncols > 1) {
+                    // find out the number of pixels beteen two grid lines
+                    grid_spacing_pixels = 
+                               utm_grid.zone[Zone].col[1].points[0].x  -
+                               utm_grid.zone[Zone].col[0].points[0].x;
+
+                    if (grid_spacing_pixels == 0)
+                        grid_spacing_pixels = -1; // Skip
+
+                }
+                else {
+                    // only one column in this zone, skip alternate doesn't matter
+                    grid_spacing_pixels = -1;
+                }
+   
+                // Is truncated easting or northing larger than grid spacing?
+                // If so, skip alternate labels
+                // short_width_pixels+2 seems to work well.
+                if (short_width_pixels+2>grid_spacing_pixels) {
+                    skip_alternate_label = TRUE;
+                }
+                else {
+                    skip_alternate_label = FALSE;
+                }
+    
+                // Label the grid lines on the border.
+                // Put easting along the bottom for easier correct ordering of easting and northing
+                // by people who are reading the map.
+                last_line_labeled = FALSE;
+                for (ii=1; ii < (int)utm_grid.zone[Zone].ncols; ii++) {
+                    // label meridianal grid lines with easting
+
+                    if (utm_grid.zone[Zone].col[ii].npoints > 1) {
+
+                        // adjust up in case npoints goes far below the screen
+                        if (grid_spacing_pixels == 0)
+                            continue;   // Go to next iteration of for loop
+
+                        bottom_point = (int)(screen_height/grid_spacing_pixels);
+
+                        if (bottom_point >= utm_grid.zone[Zone].col[ii].npoints) 
+                            bottom_point = utm_grid.zone[Zone].col[ii].npoints - 1;
+                        if (skip_alternate_label==TRUE && last_line_labeled==TRUE) {
+                            last_line_labeled = FALSE; 
+                        }
+                        else {
+                             xx = (utm_grid.zone[Zone].col[ii].points[bottom_point].x * scale_x) + NW_corner_longitude;
+                             yy = (utm_grid.zone[Zone].col[ii].points[bottom_point].y * scale_y) + NW_corner_latitude;
+                             convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx, yy);
+                             // To display full precision to one meter, use:
+                             //xastir_snprintf(grid_label,
+                             //    sizeof(grid_label),
+                             //    "%06.0f0",
+                             //    (float)((utm_grid_spacing_m/10) * roundf(easting/(utm_grid_spacing_m))));
+                             // 
+                             // Divide easting by utm_grid_spacing to make sure the line is labeled 
+                             // correctly, and not a few meters off, and truncate to at least 100 m.
+                             xastir_snprintf(grid_label,
+                                 sizeof(grid_label),
+                                 "%05.0f",
+                                 (float)((utm_grid_spacing_m/100) * roundf(easting/(utm_grid_spacing_m))));
+                             // truncate the label to an appropriate level of precision for the grid
+                             if (utm_grid_spacing_m ==1000) 
+                                 grid_label[4] = ' ';
+                             if (utm_grid_spacing_m ==10000) {
+                                 grid_label[3] = ' ';
+                                 grid_label[4] = ' ';
+                             }
+                             if (utm_grid_spacing_m ==100000) {
+                                 grid_label[2] = ' ';
+                                 grid_label[3] = ' ';
+                                 grid_label[4] = ' ';
+                             }
+                             if (coordinate_system == USE_MGRS) {
+                                 convert_xastir_to_MGRS_str_components(mgrs_zone, strlen(mgrs_zone), 
+                                     mgrs_eastingL,   sizeof(mgrs_eastingL), 
+                                     mgrs_northingL,  sizeof(mgrs_northingL), 
+                                     &int_utmEasting, &int_utmNorthing, 
+                                     xx, yy,
+                                     0, mgrs_space_string, strlen(mgrs_space_string));
+                                 grid_label[0] = mgrs_eastingL[0];
+                                 grid_label[1] = mgrs_northingL[0];
+                                 if (mgrs_single_digraph==FALSE) 
+                                     grid_label[1] = '_';
+                             }
+                             // draw each number at the bottom of the screen just to the right of the 
+                             // relevant grid line at its location at the bottom of the screen
+                             //draw_nice_string(w,pixmap_final,0,
+                             //    utm_grid.zone[Zone].col[i].points[bottom_point].x+1,
+                             //    screen_height-2,
+                             //    grid_label,
+                             //    0x10,easting_color,(int)strlen(grid_label));
+                          
+                             // Don't overwrite the zone label, half the seven zeros string should give it room.
+                             // Don't draw the label if it will go off the left edge fo the screen.
+                             if ((utm_grid.zone[Zone].col[ii].points[bottom_point].x+1 > (string_width_pixels/2)) 
+                                && (utm_grid.zone[Zone].col[ii].points[bottom_point].x+1 < (screen_width - string_width_pixels)) 
+                                ) {
+                                 // ok to draw the label
+                                 last_line_labeled = TRUE;
+                                 draw_rotated_label_text_to_target (w, 270, 
+                                     utm_grid.zone[Zone].col[ii].points[bottom_point].x+1,
+                                     screen_height, 
+                                     sizeof(grid_label),colors[easting_color],grid_label,FONT_BORDER,
+                                     pixmap_final,
+                                     outline_border_labels, colors[outline_border_labels_color]);
+                             }
+                         }
+                    }
+                }
+                last_line_labeled = FALSE;
+                // put northing along the right border, again for easier correct ordering of easting and northing.
+                for (ii=0; ii < (int)utm_grid.zone[Zone].nrows; ii++) {
+                    // label latitudinal grid lines with northing
+                    if (utm_grid.zone[Zone].row[ii].npoints > 1) {
+                         if (skip_alternate_label==TRUE && last_line_labeled==TRUE) {
+                             last_line_labeled = FALSE; 
+                         } 
+                         else {
+                             if (label_on_left==TRUE) { 
+                                 xx = (utm_grid.zone[Zone].row[ii].points[0].x * scale_x) + NW_corner_longitude;
+                             } 
+                             else {
+                                 xx = (utm_grid.zone[Zone].row[ii].points[utm_grid.zone[Zone].row[ii].npoints-1].x * scale_x) + NW_corner_longitude;
+                             }
+                             yy = (utm_grid.zone[Zone].row[ii].points[utm_grid.zone[Zone].row[ii].npoints-1].y * scale_y) +  NW_corner_latitude;
+                             convert_xastir_to_UTM(&easting, &northing, zone_str, sizeof(zone_str), xx, yy);
+                             // To display to full 1 meter precision use:
+                             //xastir_snprintf(grid_label,
+                             //    sizeof(grid_label),
+                             //    "%06.0f0",
+                             //    (float)((utm_grid_spacing_m/10) * roundf(northing/(utm_grid_spacing_m))));
+                             //
+                             // Divide northing by utm grid spacing to make sure the line is labeled correctly
+                             // and displays zeroes in its least significant digits, and truncate to 100 m
+                             xastir_snprintf(grid_label,
+                                 sizeof(grid_label),
+                                 "%05.0f",
+                                 (float)((utm_grid_spacing_m/100) * roundf(northing/(utm_grid_spacing_m))));
+                             if (utm_grid_spacing_m ==1000) 
+                                 grid_label[4] = ' ';
+                             if (utm_grid_spacing_m ==10000) {
+                                 grid_label[3] = ' ';
+                                 grid_label[4] = ' ';
+                             }
+                             if (utm_grid_spacing_m ==100000) {
+                                 grid_label[2] = ' ';
+                                 grid_label[3] = ' ';
+                                 grid_label[4] = ' ';
+                             }
+                             if (coordinate_system == USE_MGRS) {
+                                 convert_xastir_to_MGRS_str_components(mgrs_zone, strlen(mgrs_zone), 
+                                     mgrs_eastingL,   3, 
+                                     mgrs_northingL,  3, 
+                                     &int_utmEasting, &int_utmNorthing, 
+                                     xx, yy,
+                                     0, mgrs_space_string, strlen(mgrs_space_string));
+                                 grid_label[0] = mgrs_eastingL[0];
+                                 if (mgrs_single_digraph==FALSE) 
+                                     grid_label[0] = '_';
+                                 grid_label[1] = mgrs_northingL[0];
+                             }
+                             // Draw northing labels.
+                             // Draw each number just above the relevant grid line along the right side
+                             // of the screen.  Don't write in the bottom border or off the top of the screen.
+                             if (label_on_left==TRUE) { 
+                                     // label northings on left border 
+                                     // don't overwrite the zone designator in  the lower left border
+                                     if ((utm_grid.zone[Zone].row[ii].points[0].y < (screen_height - border_width)) 
+                                         &&
+                                         (utm_grid.zone[Zone].row[ii].points[0].y > (string_width_pixels)) 
+                                        ) {
+                                         last_line_labeled = TRUE;
+                                         draw_rotated_label_text_to_target (w, 180, 
+                                             border_width, 
+                                             utm_grid.zone[Zone].row[ii].points[0].y,
+                                             sizeof(grid_label),colors[northing_color],grid_label,FONT_BORDER,
+                                             pixmap_final,
+                                             outline_border_labels, colors[outline_border_labels_color]);
+                                     }
+                             } 
+                             else {
+                                 if (((utm_grid.zone[Zone].row[ii].points[utm_grid.zone[Zone].row[ii].npoints-1].y-1) 
+                                     < (screen_height - border_width))
+                                     &&
+                                     ((utm_grid.zone[Zone].row[ii].points[utm_grid.zone[Zone].row[ii].npoints-1].y-1) 
+                                     > (string_width_pixels))
+                                    ) {
+                                     // label northings on right border
+                                     last_line_labeled = TRUE;
+                                     draw_rotated_label_text_to_target (w, 180, 
+                                         screen_width, 
+                                         utm_grid.zone[Zone].row[ii].points[utm_grid.zone[Zone].row[ii].npoints-1].y-1,
+                                         sizeof(grid_label),colors[northing_color],grid_label,FONT_BORDER,
+                                         pixmap_final,
+                                         outline_border_labels, colors[outline_border_labels_color]);
+                                 }
+                             }
+                         }
+                    }
+                } // for i=0 to nrows
+            } // if draw labeled grid border
+        } // if utm_grid.zone[Zone] is non-empty
+    } // for each zone in utm_grid.zone 
+} // End of actually_draw_utm_minor_grid() function
+ 
+
+
+
+
+// Calculate the minor UTM grids.  Called by draw_grid() below.
+// This function calculates and caches a within-zone UTM grid 
+// for the current map view if one does not allready exist, it 
+// then calls actually_draw_utm_minor_grid() function above to do 
+// the drawing once the grid has been calculated.  Zone boundaries
+// are drawn separately by draw_major_utm_mgrs_grid().
+//
+// This routine appears to draw most of the UTM/UPS grid ok, with
+// the exceptions of:
+//
+// 1) Sometimes fails to draw vertical lines nearest zone
+//    boundaries.
+// 2) Lines connect across zone boundaries in an incorrect manner,
+//    jumping up one grid interval across the boundary.
+// 3) Segfaults near the special zone intersections as you zoom in.
+//
+// The code currently creates a col and row array per zone visible,
+// with XPoints malloced that contain the grid intersections in
+// screen coordinates.  If the screen is zoomed or panned they are
+// recalculated.
+//
+// Perhaps we could do the same but with lat/long coordinates in the
+// future so that we'd only have to recalculate when a new Zone came
+// into view.  We'd use the lat/long vector drawing programs above
+// then, with a possible slowdown due to more calculations if we're
+// not moving around.
+//
+// Returns: 0 if successful or nothing to draw
+//          1 if malloc error
+//          2 if iterations error
+//          3 if out of zones
+//          4 if realloc failure
+//
+int draw_minor_utm_mgrs_grid(Widget w) {
+
+    long xx, yy, xx1, yy1;
+    double e[4], n[4];
+    char place_str[10], zone_str[10];
+    int done = 0;
+    int z1, z2, Zone, col, col_point, row, row_point, row_point_start;
+    int iterations = 0;
+    int finished_with_current_zone = 0;
+    int ii, jj;
+    float slope;
+    int coordinate_system_backup = coordinate_system;
+
+ 
+    col = 0;
+    row = 0;
+    col_point = 0;
+    row_point = 0;
+    row_point_start = 0;
+    Zone = 0;
+
+    // Set up for drawing zone grid(s)
+    if (scale_x < 15)
+        utm_grid_spacing_m =    100;
+    else if (scale_x < 150)
+        utm_grid_spacing_m =   1000;
+    else if (scale_x < 1500)
+        utm_grid_spacing_m =  10000;
+    else if (scale_x < 3000)
+        utm_grid_spacing_m = 100000;
+    else {
+        utm_grid_spacing_m = 0;
+        // All done!  Don't draw the minor grids.  Major grids
+        // have already been drawn by this point.
+        return(0);
+    }
+
+    // Check hash to see if utm_grid is already set up
+    if (utm_grid.hash.ul_x == NW_corner_longitude &&
+        utm_grid.hash.ul_y == NW_corner_latitude &&
+        utm_grid.hash.lr_x == SE_corner_longitude &&
+        utm_grid.hash.lr_y == SE_corner_latitude) {
+
+        // XPoint arrays are already set up.  Go draw the grid.
+        actually_draw_utm_minor_grid(w);
+
+        return(0);
+    }
+
+
+// If we get to this point, we need to re-create the minor UTM/MGRS
+// grids as they haven't been set up yet or they don't match the
+// current view.
+
+
+    // Clear the minor UTM/MGRS grid arrays.  Alloc space for
+    // the points in the grid structure.
+    if (utm_grid_clear(1)) {
+        // If we got here, we had a problem with malloc's
+        return(1);
+    }
+
+    // Find top left point of current view
+    xx = NW_corner_longitude;
+    yy = NW_corner_latitude;
+
+    // Note that the minor grid depends on the STANDARD six degree
+    // UTM zones, not the UTM-Special/MGRS zones.  Force our
+    // calculations to use the standard zones.
+    coordinate_system = USE_UTM;
+    convert_xastir_to_UTM(&e[0], &n[0], place_str, sizeof(place_str), xx, yy);
+    coordinate_system = coordinate_system_backup;
+
+    n[0] += UTM_GRID_EQUATOR; // To work in southern hemisphere
+
+
+// Select starting point, NW corner of NW zone
+
+    // Move the coordinates to the nearest subgrid intersection,
+    // based on our current grid spacing.  The grid intersection
+    // we calculate here is northwest of our view's northwest
+    // corner.
+    e[0] /= utm_grid_spacing_m;
+    e[0]  = (double)((int)e[0] * utm_grid_spacing_m);
+    n[0] /= utm_grid_spacing_m;
+    n[0]  = (double)((int)n[0] * utm_grid_spacing_m);
+    n[0] += utm_grid_spacing_m;
+
+
+//WE7U
+// It appears that the horizontal grid lines get messed up in cases
+// where the top horizontal line isn't in view on it's left end.
+// That's a major clue!  Read the comment below (again with a "WE7U"
+// tag).  The problem occurs at the point where we copy the last
+// point from the previous grid over to the first point of a new
+// grid.  That can cause us to be off by one, as for the grid on the
+// left, the top horizontal line _is_ in view on the left.  We end
+// up connecting the wrong horizontal lines together because of this
+// mismatch, but again, only if the top horizontal line on the left
+// grid is above the current view.
+//
+// It also appears that the vertical lines that are missing in some
+// cases are on the right of the zone boundary.  This is probably
+// because the top of that line doesn't go to the top of the view.
+// On views where it does, the line is drawn.  I assume this is
+// because we're drawing from NW corner to the right, and then down,
+// which would cause that line to be skipped if it's not present on
+// the first line?
+
+
+    e[1] = e[0];
+    n[1] = n[0];
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+    // Start filling in the row/column arrays of grid intersections
+    while (!done) {
+        XPoint *temp_point;
+
+
+        // Here's our escape in case we get stuck in this loop.
+        // We can go through this loop multiple times for each
+        // zone though, depending on our grid spacing.  64 rows * 64
+        // colums * 8 points each = 32768, which gives us our upper
+        // limit.
+        if (iterations++ > 32768) {
+            fprintf(stderr,
+                "draw_minor_utm_mgrs_grid() looped too many times, escaping.\n");
+            utm_grid_clear(1);
+            return(2);
+        }
+
+
+        if (finished_with_current_zone) {
+            // Set up to compute the next zone
+
+            xx = NW_corner_longitude + ((utm_grid.zone[Zone].boundary_x + 1) * scale_x);
+
+            yy = NW_corner_latitude;
+
+            // Note that the minor grid depends on the STANDARD six
+            // degree UTM zones, not the UTM-Special/MGRS zones.
+            // Force our calculations to use the standard zones.
+            coordinate_system = USE_UTM;
+            convert_xastir_to_UTM(&e[0], &n[0], place_str, sizeof(place_str), xx, yy);
+            coordinate_system = coordinate_system_backup;
+
+            n[0] += UTM_GRID_EQUATOR; // To work in southern hemisphere
+
+// Fix the coordinates to the nearest subgrid intersection based on
+// our current grid spacing.  Bump both the easting and northing up
+// by one subgrid.
+            e[0] /= utm_grid_spacing_m;
+            e[0]  = (double)((int)e[0] * utm_grid_spacing_m);
+            e[0] += utm_grid_spacing_m;
+            n[0] /= utm_grid_spacing_m;
+            n[0]  = (double)((int)n[0] * utm_grid_spacing_m);
+            n[0] += utm_grid_spacing_m;
+
+            e[1] = e[0];
+            n[1] = n[0];
+
+#ifdef UTM_DEBUG
+            fprintf(stderr,"\nFinished Zone=%d\n", Zone);
+#endif
+
+            // We're all done with the current zone.  Increment
+            // to the next zone and set up to calculate its
+            // points.
+            Zone++;
+
+#ifdef UTM_DEBUG
+            fprintf(stderr,"\nstarting Zone=%d, row_point_start=1\n", Zone);
+#endif
+
+            row_point = row_point_start = 1;
+            col = row = col_point = 0;
+            finished_with_current_zone = 0;
+
+            if (Zone >= UTM_GRID_MAX_ZONES) {
+                fprintf(stderr,"Error: Zone=%d: out of zones!\n", Zone);
+                Zone = 0;
+                done = 1;
+                utm_grid_clear(1);
+                return(3);
+            }
+        }   // End of if(finished_with_current_zone)
+
+        // Note that the minor grid depends on the STANDARD six
+        // degree UTM zones, not the UTM-Special/MGRS zones.  Force
+        // our calculations to use the standard zones.
+        coordinate_system = USE_UTM;
+        convert_UTM_to_xastir(e[1], n[1]-UTM_GRID_EQUATOR, place_str, &xx, &yy);
+        coordinate_system = coordinate_system_backup;
+ 
+        xx1 = xx; // Save
+        yy1 = yy; // Save
+
+        // Note that the minor grid depends on the STANDARD six
+        // degree UTM zones, not the UTM-Special/MGRS zones.  Force
+        // our calculations to use the standard zones.
+        coordinate_system = USE_UTM;
+        convert_xastir_to_UTM(&e[2], &n[2], zone_str, sizeof(zone_str), xx, yy);
+        coordinate_system = coordinate_system_backup;
+ 
+        n[2] += UTM_GRID_EQUATOR;
+        xx = (xx - NW_corner_longitude) / scale_x;
+        yy = (yy - NW_corner_latitude)  / scale_y;
+
+        // Not all columns (and maybe rows) will start at point
+        // 0
+        if (utm_grid.zone[Zone].col[col].firstpoint == UTM_GRID_RC_EMPTY) {
+            utm_grid.zone[Zone].col[col].firstpoint = l16(col_point);
+#ifdef UTM_DEBUG
+            fprintf(stderr,"col[%d] started at point %d\n", col, col_point);
+#endif
+        }
+        if (utm_grid.zone[Zone].row[row].firstpoint == UTM_GRID_RC_EMPTY) {
+            utm_grid.zone[Zone].row[row].firstpoint = l16(row_point);
+#ifdef UTM_DEBUG
+            fprintf(stderr,"row[%d] started at point %d\n", row, row_point);
+#endif
+        }
+
+        // Check to see if we need to alloc more space for
+        // column points
+        ii = utm_grid.zone[Zone].col[col].npoints +
+            utm_grid.zone[Zone].col[col].firstpoint + 1;
+        if (ii > utm_grid.zone[Zone].col[col].nalloced) {
+#ifdef UTM_DEBUG_ALLOC
+            fprintf(stderr,"i=%d n=%d realloc(utm_grid.zone[%d].col[%d].points, ",
+                   ii, utm_grid.zone[Zone].col[col].nalloced, Zone, col);
+#endif
+            ii = ((ii / UTM_GRID_DEF_NALLOCED) + 1) * UTM_GRID_DEF_NALLOCED;
+#ifdef UTM_DEBUG_ALLOC
+            fprintf(stderr,"%d)\n", ii);
+#endif
+
+            temp_point = realloc(utm_grid.zone[Zone].col[col].points,
+                ii * sizeof(XPoint));
+
+            if (temp_point) {
+                utm_grid.zone[Zone].col[col].points = temp_point;
+                utm_grid.zone[Zone].col[col].nalloced = ii;
+            }
+            else {
+                puts("realloc FAILED!");
+                (void)utm_grid_clear(1); // Clear arrays and allocate memory for points
+                return(4);
+            }
+        }
+
+        // Check to see if we need to alloc more space for row
+        // points
+        ii = utm_grid.zone[Zone].row[row].npoints +
+            utm_grid.zone[Zone].row[row].firstpoint + 1;
+        if (ii > utm_grid.zone[Zone].row[row].nalloced) {
+#ifdef UTM_DEBUG_ALLOC
+            fprintf(stderr,"i=%d n=%d realloc(utm_grid.zone[%d].row[%d].points, ",
+                   ii, utm_grid.zone[Zone].row[row].nalloced, Zone, row);
+#endif
+            ii = ((ii / UTM_GRID_DEF_NALLOCED) + 1) * UTM_GRID_DEF_NALLOCED;
+#ifdef UTM_DEBUG_ALLOC
+            fprintf(stderr,"%d)\n", ii);
+#endif
+
+            temp_point = realloc(utm_grid.zone[Zone].row[row].points,
+                ii * sizeof(XPoint));
+
+            if (temp_point) {
+                utm_grid.zone[Zone].row[row].points = temp_point;
+                utm_grid.zone[Zone].row[row].nalloced = ii;
+            }
+            else {
+                puts("realloc FAILED!");
+                (void)utm_grid_clear(1); // Clear arrays and allocate memory for points
+                return(4);
+            }
+        }
+
+        // Here we check to see whether we are inserting points
+        // that are greater than about +/- 32767.  If so,
+        // truncate at that.  This prevents XDrawLines() from
+        // going nuts and drawing hundreds of extra lines.
+        //
+        xx = l16(xx);
+        yy = l16(yy);
+
+        utm_grid.zone[Zone].col[col].points[col_point].x = l16(xx);
+        utm_grid.zone[Zone].col[col].points[col_point].y = l16(yy);
+        utm_grid.zone[Zone].col[col].npoints++;
+        utm_grid.zone[Zone].row[row].points[row_point].x = l16(xx);
+        utm_grid.zone[Zone].row[row].points[row_point].y = l16(yy);
+        utm_grid.zone[Zone].row[row].npoints++;
+
+#ifdef UTM_DEBUG
+        fprintf(stderr,"utm_grid.zone[%d].col[%d].points[%d] = [ %ld,%ld ] npoints=%d\n",
+               Zone, col, col_point, xx, yy, utm_grid.zone[Zone].col[col].npoints);
+        fprintf(stderr,"utm_grid.zone[%d].row[%d].points[%d] = [ %ld,%ld ]\n",
+               Zone, row, row_point, xx, yy);
+#endif
+
+        col++;
+        row_point++;
+        if (col >= UTM_GRID_MAX_COLS_ROWS)
+            finished_with_current_zone++;
+
+        z1 = atoi(place_str);
+        z2 = atoi(zone_str);
+        if (z1 != z2 || xx > screen_width) { // We hit a boundary
+
+#ifdef UTM_DEBUG_VERB
+            if (z1 != z2)
+                fprintf(stderr,"Zone boundary! \"%s\" -> \"%s\"\n", place_str, zone_str);
+            else
+                puts("Screen boundary!");
+#endif
+
+//#warning
+//#warning I suspect that I should not use just col for the following.
+//#warning
+            if (col-2 >= 0)
+                slope = (float)(yy - utm_grid.zone[Zone].col[col-2].points[col_point].y) /
+                    (float)(xx - utm_grid.zone[Zone].col[col-2].points[col_point].x + 0.001);
+            else
+                slope = 0.0;
+
+            if (xx > screen_width)
+                xx1 = screen_width;
+            else {
+
+                // 360,000 Xastir units equals one degree.  This
+                // code appears to be adjusting xx1 to a major
+                // zone edge.
+                xx1 = (xx1 / (6 * 360000)) * 6 * 360000;
+                xx1 = (xx1 - NW_corner_longitude) / scale_x;
+            }
+
+            utm_grid.zone[Zone].boundary_x = xx1;
+            yy1 = yy - (xx - xx1) * slope;
+
+#ifdef UTM_DEBUG
+            fprintf(stderr,"_tm_grid.zone[%d].col[%d].points[%d] =  [ %ld,%ld ]\n",
+                   Zone, col-1, col_point, xx1, yy1);
+            fprintf(stderr,"_tm_grid.zone[%d].row[%d].points[%d] =  [ %ld,%ld ]\n",
+                   Zone, row, row_point-1, xx1, yy1);
+#endif
+
+            if (col-1 >= 0 && row_point-1 >= 0) {
+                utm_grid.zone[Zone].col[col-1].points[col_point].x = l16(xx1);
+                utm_grid.zone[Zone].col[col-1].points[col_point].y = l16(yy1);
+                utm_grid.zone[Zone].row[row].points[row_point-1].x = l16(xx1);
+                utm_grid.zone[Zone].row[row].points[row_point-1].y = l16(yy1);
+                if (z1 != z2 && Zone+1 < UTM_GRID_MAX_ZONES) {
+                    // copy over last points to start off new
+                    // zone
+#ifdef UTM_DEBUG
+                    fprintf(stderr,"ztm_grid.zone[%d].row[%d].points[%d] =  [ %ld,%ld ]\n",
+                           Zone+1, row, 0, xx1, yy1);
+#endif
+
+//WE7U
+// This is where we can end up linking up/down one grid width
+// between zones!!!  Without it though, we end up have a blank
+// section to the right of the zone boundary.  Perhaps we could do
+// this here, but when we get the next points calculated, we could
+// check to see if we're off by about one grid width in the vertical
+// direction.  If so, shift the initial point by that amount?
+//
+// Another possibility might be to draw bottom-to-top if in northern
+// hemisphere, and top-to-bottom if in southern hemisphere.  That
+// way we'd have the max amount of lines present when we start, and
+// some might peter out as we draw along N/S.  Looking at the
+// southern hemisphere right now though, that method doesn't appear
+// to work.  We get the same problems there even though we're
+// drawing top to bottom.
+//
+                    utm_grid.zone[Zone+1].row[row].points[0].x = l16(xx1);
+                    utm_grid.zone[Zone+1].row[row].points[0].y = l16(yy1);
+                    utm_grid.zone[Zone+1].row[row].firstpoint =  0;
+                    utm_grid.zone[Zone+1].row[row].npoints    =  1;
+                }
+            }
+
+
+            // Check last built row to see if it is all off
+            // screen
+            finished_with_current_zone++; // Assume we're done with this zone
+            for (ii=0; ii < utm_grid.zone[Zone].row[row].npoints; ii++) {
+                if (utm_grid.zone[Zone].row[row].points[ii].y <= screen_height)
+                    finished_with_current_zone = 0; // Some points were within the zone, keep computing
+            }
+
+
+            e[1]  = e[0];               // carriage return
+            n[1] -= utm_grid_spacing_m; // line feed
+// Yea, your comments are real funny Olivier...  Gets the point
+// across though!
+
+
+            row++;
+            if (row >= UTM_GRID_MAX_COLS_ROWS)
+                finished_with_current_zone++;
+
+            utm_grid.zone[Zone].ncols = max_i(col, utm_grid.zone[Zone].ncols);
+            utm_grid.zone[Zone].nrows = max_i(row, utm_grid.zone[Zone].nrows);
+            col = 0;
+            row_point = row_point_start;
+            col_point++;
+
+            if (n[1] < 0) {
+                fprintf(stderr,"n[1] < 0\n");
+                finished_with_current_zone++;
+            }
+
+            if (finished_with_current_zone && xx > screen_width)
+                done = 1;
+
+            // Go to next iteration of while loop (skip next statement)
+            continue;
+        }
+
+        e[1] += utm_grid_spacing_m;
+
+    }   // End of while (done) loop
+ 
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+
+
+//fprintf(stderr, "After while loop\n");
+
+    // utm_grid.zone[] now contains an array of points marking fine grid 
+    // line intersections for parts of 1 to 4 zones that appear on 
+    // the screen.  Each utm_grid.zone[] is a vertical stripe, and may include
+    // more than one zone letter, e.g. zone[0] might include 15U and 15T,
+    // while zone[1] might include 16U and 16T.    
+
+//#define UTM_DEBUG_VERB
+
+    for (Zone=0; Zone < UTM_GRID_MAX_ZONES; Zone++) {
+
+#ifdef UTM_DEBUG_VERB
+        fprintf(stderr,"\nutm_grid.zone[%d].ncols=%d\nutm_grid.zone[%d].nrows=%d\n",
+               Zone, utm_grid.zone[Zone].ncols, Zone, utm_grid.zone[Zone].nrows);
+#endif
+
+        // Cleanup columns
+        for (ii=0; ii < (int)utm_grid.zone[Zone].ncols; ii++) {
+            int np = utm_grid.zone[Zone].col[ii].npoints;
+            int fp = utm_grid.zone[Zone].col[ii].firstpoint;
+            int nbp = 0;
+
+#ifdef UTM_DEBUG_VERB
+            fprintf(stderr,"utm_grid.zone[%d].col[%d].npoints=%d .firstpoint=%d\n",
+                   Zone, ii, np, fp);
+            if (np < 2)
+                puts(" Not enough points!");
+            else
+                puts("");
+
+            for (jj=fp; jj < fp+np; jj++) {
+                fprintf(stderr,"         col[%d].points[%d] = [ %d, %d ]", ii, jj,
+                       utm_grid.zone[Zone].col[ii].points[jj].x,
+                       utm_grid.zone[Zone].col[ii].points[jj].y);
+                if (utm_grid.zone[Zone].col[ii].points[jj].x ==
+                    utm_grid.zone[Zone].boundary_x)
+                    puts(" Boundary");
+                else
+                    puts("");
+            }
+#endif
+            for (jj=fp; jj < fp+np; jj++) {
+                if (utm_grid.zone[Zone].col[ii].points[jj].x ==
+                    utm_grid.zone[Zone].boundary_x)
+                    nbp++;
+                else if (nbp > 0) { // We had a boundary point, but not anymore
+                    fp = utm_grid.zone[Zone].col[ii].firstpoint = l16(jj - 1);
+//fprintf(stderr,"np:%d, jj:%d\n",np,jj);
+                    // This can result in negative numbers!
+                    np = utm_grid.zone[Zone].col[ii].npoints = np - jj + 1;
+//fprintf(stderr,"new np:%d\n",np);
+                    if (np < 0) {
+                        np = 0; // Prevents segfaults in
+                                // XDrawLines() and memmove()
+                                // below.
+                    }
+                    break;  // Exit from for loop
+                }
+                if (nbp == np) { // All points are boundary points
+                    fp = utm_grid.zone[Zone].col[ii].firstpoint = 0;
+                    np = utm_grid.zone[Zone].col[ii].npoints    = 0;
+                }
+            }
+
+// What's the below code doing?  Can get a segfault without this in
+// the XDrawLines() functions below (fixed by making npoints an int
+// instead of an unsigned int).  Sometimes we get a segfault right
+// here due to the memmove() function.  In one such case, np was -2.
+// Latest code keeps some lines from getting drawn, but at least we
+// don't get a segfault.
+//
+            if (fp > 0) {
+                if (np > 0) {
+                    memmove(&utm_grid.zone[Zone].col[ii].points[0],
+                        &utm_grid.zone[Zone].col[ii].points[fp], np * sizeof(XPoint));
+                    fp = utm_grid.zone[Zone].col[ii].firstpoint = 0;
+                }
+                else {
+//fprintf(stderr,"draw_minor_utm_mgrs_grid: ii:%d, np:%d, size:%d\n",ii,np,sizeof(XPoint));
+//fprintf(stderr,"Problem1: in draw_minor_utm_mgrs_grid() memmove, np was %d.  Skipping memmove.\n",np);
+                }
+            }
+
+#ifdef UTM_DEBUG_VERB
+            fprintf(stderr,"_tm_grid.zone[%d].col[%d].npoints=%d.firstpoint=%d\n",
+                   Zone, ii, np, fp);
+            for (jj=fp; jj < fp+np; jj++) {
+                fprintf(stderr,"         col[%d].points[%d] = [ %d, %d ]", ii, jj,
+                       utm_grid.zone[Zone].col[ii].points[jj].x,
+                       utm_grid.zone[Zone].col[ii].points[jj].y);
+                if (utm_grid.zone[Zone].col[ii].points[jj].x ==
+                    utm_grid.zone[Zone].boundary_x)
+                    puts(" Boundary");
+                else
+                    puts("");
+            }
+            puts("");
+#endif
+        }
+
+        // Cleanup rows
+        for (ii=0; ii < (int)utm_grid.zone[Zone].nrows; ii++) {
+            int np = utm_grid.zone[Zone].row[ii].npoints;
+            int fp = utm_grid.zone[Zone].row[ii].firstpoint;
+#ifdef UTM_DEBUG_VERB
+            fprintf(stderr,"utm_grid.zone[%d].row[%d].npoints=%d.firstpoint=%d\n",
+                   Zone, ii, np, fp);
+            if (np < 2)
+                puts(" Not enough points!");
+            else
+                puts("");
+#endif
+// What's this doing?  This appears to be important, as things get
+// really messed up if it's commented out.
+            if (fp > 0) {   
+                if (np > 0) {
+                    memmove(&utm_grid.zone[Zone].row[ii].points[0],
+                        &utm_grid.zone[Zone].row[ii].points[fp], np * sizeof(XPoint));
+                    fp = utm_grid.zone[Zone].row[ii].firstpoint = 0;
+                }
+                else {
+//fprintf(stderr,"draw_minor_utm_mgrs_grid: ii:%d, np:%d, size:%d\n",ii,np,sizeof(XPoint));
+//fprintf(stderr,"Problem2: in draw_minor_utm_mgrs_grid() memmove, np was %d.  Skipping memmove.\n",np);
+                }
+ 
+            }
+#ifdef UTM_DEBUG_VERB
+            for (jj=fp; jj < fp+np; jj++) {
+                fprintf(stderr,"         row[%d].points[%d] = [ %d, %d ]\n", ii, jj,
+                       utm_grid.zone[Zone].row[ii].points[jj].x,
+                       utm_grid.zone[Zone].row[ii].points[jj].y);
+            }
+#endif
+        }
+    }
+
+    // Rows and columns ready to go so setup hash
+    utm_grid.hash.ul_x = NW_corner_longitude;
+    utm_grid.hash.ul_y = NW_corner_latitude;
+    utm_grid.hash.lr_x = SE_corner_longitude;
+    utm_grid.hash.lr_y = SE_corner_latitude;
+
+    // XPoint arrays are set up.  Go draw the grid.
+    actually_draw_utm_minor_grid(w);
+
+    return(0);
+
+}   // End of draw_minor_utm_mgrs_grid() function
+
+
+
+
+
+//*****************************************************************
+// draw_grid()
+//
+// Draws a lat/lon or UTM/UPS grid on top of the view.
+//
+//*****************************************************************
+void draw_grid(Widget w) {
+    int half;                   // Center of the white lines used to draw the borders
+    int border_width = 14;      // The width of the border to draw around the 
+                                // map to place labeled tick marks into
+                                // should be an even number.
+                                // The default here is overidden by the border fontsize.
+
+
+    if (!long_lat_grid) // We don't wish to draw a map grid
+        return;
+ 
+    if (draw_labeled_grid_border==TRUE) { 
+        // Determine how wide the border should be.
+        border_width = get_border_width(w);
+        half = border_width/2; 
+        // draw a white border around the map.
+        (void)XSetLineAttributes(XtDisplay(w),
+            gc,
+            border_width,
+            LineSolid,
+            CapRound,
+            JoinRound);
+        (void)XSetForeground(XtDisplay(w),
+            gc,
+            colors[border_foreground_color]);         // white
+        (void)XDrawLine(XtDisplay(w),
+            pixmap_final,
+            gc,
+            0,
+            l16(half),
+            l16(screen_width),
+            l16(half));
+        (void)XDrawLine(XtDisplay(w),
+            pixmap_final,
+            gc,
+            l16(half),
+            0,
+            l16(half),
+            l16(screen_height));
+        (void)XDrawLine(XtDisplay(w),
+            pixmap_final,
+            gc,
+            0,
+            l16(screen_height-half),
+            l16(screen_width),
+            l16(screen_height-half));
+        (void)XDrawLine(XtDisplay(w),
+            pixmap_final,
+            gc,
+            l16(screen_width-half),
+            0,
+            l16(screen_width-half),
+            l16(screen_height));
+    }
+
+    // Set the line width in the GC to 2 pixels wide for the larger
+    // UTM grid and the complete Lat/Long grid.
+    (void)XSetLineAttributes (XtDisplay (w), gc_tint, 2, LineOnOffDash, CapButt,JoinMiter);
+    (void)XSetForeground (XtDisplay (w), gc_tint, colors[0x27]);
+    (void)XSetFunction (XtDisplay (da), gc_tint, GXxor);
+
+    if (coordinate_system == USE_UTM
+            || coordinate_system == USE_UTM_SPECIAL
+            || coordinate_system == USE_MGRS) {
+
+        int ret_code;
+
+//draw_vector_ll(w, -5.0, -5.0,  5.0,  5.0, gc_tint, pixmap_final, 0);
+//draw_vector_ll(w,  5.0,  5.0, -5.0, -5.0, gc_tint, pixmap_final, 0);
+ 
+        // Draw major UTM/MGRS zones
+        draw_major_utm_mgrs_grid(w);
+ 
+        // Draw minor UTM/MGRS zones
+        ret_code = draw_minor_utm_mgrs_grid(w);
+        if (ret_code) {
+            fprintf(stderr,
+                "Encountered problem %d while calculating minor utm grid!\n",
+                ret_code);
+        }
+
+    }   // End of UTM grid section
+    else { // Lat/Long coordinate system, draw lat/long lines
+        draw_complete_lat_lon_grid(w);
+    }   // End of Lat/Long section
+}  // End of draw_grid()
+
+
+
+
+
+/**********************************************************
+ * get_map_ext()
+ *
+ * Returns the extension for the filename.  We use this to
+ * determine which sort of map file it is.
+ **********************************************************/
+char *get_map_ext (char *filename) {
+    int len;
+    int i;
+    char *ext;
+
+    ext = NULL;
+    len = (int)strlen (filename);
+    for (i = len; i >= 0; i--) {
+        if (filename[i] == '.') {
+            ext = filename + (i + 1);
+            break;
+        }
+    }
+    return (ext);
+}
+
+
+
+
+
+/**********************************************************
+ * get_map_dir()
+ *
+ * Used to snag just the pathname from a complete filename.
+ * Modifies input parameter "fullpath".
+ **********************************************************/
+char *get_map_dir (char *fullpath) {
+    int len;
+    int i;
+
+    len = (int)strlen (fullpath);
+    for (i = len; i >= 0; i--) {
+        if (fullpath[i] == '/') {
+            fullpath[i + 1] = '\0';
+            break;
+        }
+    }
+    return (fullpath);
+}
+
+
+
+
+
+/***********************************************************
+ * map_visible()
+ *
+ * Tests whether a particular path/filename is within our
+ * current view.  We use this to decide whether to plot or
+ * skip a particular image file (major speed-up!).
+ * Input coordinates are in the Xastir coordinate system.
+ *
+ * Had to fix a bug here where the viewport glanced over the
+ * edge of the earth, causing strange results like this.
+ * Notice the View Edges Top value is out of range:
+ *
+ *
+ *                Bottom         Top          Left       Right
+ * View Edges:  31,017,956  4,290,923,492  35,971,339  90,104,075
+ *  Map Edges:  12,818,482     12,655,818  64,079,859  64,357,110
+ *
+ * Left map boundary inside view
+ * Right map boundary inside view
+ * map_inside_view: 1  view_inside_map: 0  parallel_edges: 0
+ * Map not within current view.
+ * Skipping map: /usr/local/share/xastir/maps/tif/uk/425_0525_bng.tif
+ *
+ *
+ * I had to check for out-of-bounds numbers for the viewport and
+ * set them to min or max values so that this function always
+ * works properly.  Here are the bounds of the earth (Xastir
+ * Coordinate System):
+ *
+ *              0 (90 deg. or 90N)
+ *
+ * 0 (-180 deg. or 180W)      129,600,000 (180 deg. or 180E)
+ *
+ *          64,800,000 (-90 deg. or 90S)
+ *
+ ***********************************************************/
+int map_visible (unsigned long map_max_y,   // bottom_map_boundary
+                 unsigned long map_min_y,   // top_map_boundary
+                 unsigned long map_min_x,   // left_map_boundary
+                 unsigned long map_max_x) { // right_map_boundary) {
+
+    //fprintf(stderr,"map_visible\n");
+
+    // From computation geometry equations, intersection of two line
+    // segments, they use the bounding box for two lines.  This is
+    // the same as what we want to do:
+    //
+    // http://www.cs.kent.edu/~dragan/AdvAlg/CompGeom-2x1.pdfa
+    // http://www.gamedev.net/reference/articles/article735.asp
+    //
+    // The quick rejection algorithm:
+    //
+    if (NW_corner_latitude > (long)map_max_y) {
+        if (debug_level & 16) {
+            fprintf(stderr,
+                "map_visible, rejecting: NW_corner_latitude:%ld > map_max_y:%ld\n",
+                NW_corner_latitude,
+                map_max_y);
+            fprintf(stderr,
+                "\tmap or object is above viewport\n");
+        }
+        return(0);
+    }
+
+    if ((long)map_min_y > SE_corner_latitude) {
+        if (debug_level & 16) {
+            fprintf(stderr,
+                "map_visible, rejecting: map_min_y:%ld > SE_corner_latitude:%ld\n",
+                map_min_y,
+                SE_corner_latitude);
+            fprintf(stderr,
+                "\tmap or object is below viewport\n");
+        }
+        return(0);
+    }
+
+    if (NW_corner_longitude > (long)map_max_x) {
+        if (debug_level & 16) {
+            fprintf(stderr,
+                "map_visible, rejecting: NW_corner_longitude:%ld > map_max_x:%ld\n",
+                NW_corner_longitude,
+                map_max_x);
+            fprintf(stderr,
+                "\tmap or object is left of viewport\n");
+        }
+        return(0);
+    }
+
+    if ((long)map_min_x > SE_corner_longitude) {
+        if (debug_level & 16) {
+            fprintf(stderr,
+                "map_visible, rejecting: map_min_x:%ld > SE_corner_longitude:%ld\n",
+                map_min_x,
+                SE_corner_longitude);
+            fprintf(stderr,
+                "\tmap or object is right of viewport\n");
+        }
+        return(0);
+    }
+
+    return (1); // At least part of the map is on-screen
+}
+
+
+
+/////////////////////////////////////////////////////////////////////
+// get_viewport_lat_lon(double *xmin, double *ymin, double* xmax, double *ymax)
+// Simply returns the floating point corners of the map display.
+/////////////////////////////////////////////////////////////////////
+void get_viewport_lat_lon(double *xmin, 
+                          double *ymin, 
+                          double* xmax, 
+                          double *ymax) {
+
+    *xmin=(double)f_NW_corner_longitude;
+    *ymin=(double)f_SE_corner_latitude;
+    *xmax=(double)f_SE_corner_longitude;
+    *ymax=(double)f_NW_corner_latitude;
+}
+
+/////////////////////////////////////////////////////////////////////
+// map_inside_viewport_lat_lon()
+//  Returns 1 if the given set of xmin,xmax, ymin,ymax defines a 
+//  rectangle entirely contained in the current viewport (as opposed to
+//  merely partially overlapping it.  Returns zero otherwise.
+/////////////////////////////////////////////////////////////////////
+int map_inside_viewport_lat_lon(double map_min_y,
+                                double map_max_y,
+                                double map_min_x,
+                                double map_max_x) {
+    int retval=0;
+    if (map_min_x >= f_NW_corner_longitude &&
+        map_min_y >= f_SE_corner_latitude &&
+        map_max_x <= f_SE_corner_longitude &&
+        map_max_y <= f_NW_corner_latitude) {
+        retval=1;
+    }
+
+    return (retval);
+}
+        
+                         
+/////////////////////////////////////////////////////////////////////
+// map_visible_lat_lon()
+//
+// We have the center of the view in floating point format:
+//
+//   float f_center_longitude; // Floating point map center longitude
+//   float f_center_latitude;  // Floating point map center latitude
+//
+// So we just need to compute the top/bottom/left/right using those
+// values and the scale_x/scale_y values before doing the compare.
+//
+// y scaling in 1/100 sec per pixel
+// x scaling in 1/100 sec per pixel, calculated from scale_y
+//
+// 
+//              0 (90 deg. or 90N)
+//
+// 0 (-180 deg. or 180W)      129,600,000 (180 deg. or 180E)
+//
+//          64,800,000 (-90 deg. or 90S)
+//
+// *******************                  ******************* max_y
+// *NW               * +                *                 * +
+// *                 *                  *                 *
+// *                 *                  *                 *
+// *      View       * latitude (y)     *       Map       *
+// *                 *                  *                 *
+// *                 *                  *                 *
+// *               SE* -                *                 * -
+// *******************                  ******************* min_y
+// -  longitude(x)   +                  - min_x     max_x +
+
+/////////////////////////////////////////////////////////////////////
+int map_visible_lat_lon (double map_min_y,    // f_bottom_map_boundary
+                         double map_max_y,    // f_top_map_boundary
+                         double map_min_x,    // f_left_map_boundary
+                         double map_max_x) {  // f_right_map_boundary
+
+//fprintf(stderr,"map_visible_lat_lon\n");
+
+    // From computation geometry equations, intersection of two line
+    // segments, they use the bounding box for two lines.  This is
+    // the same as what we want to do:
+    //
+    // http://www.cs.kent.edu/~dragan/AdvAlg/CompGeom-2x1.pdfa
+    // http://www.gamedev.net/reference/articles/article735.asp
+    //
+    // The quick rejection algorithm:
+    //
+    if (map_max_y < f_SE_corner_latitude ) return(0); // map below view
+    if (map_max_x < f_NW_corner_longitude) return(0); // map left of view
+    if (map_min_y > f_NW_corner_latitude ) return(0); // view below map
+    if (map_min_x > f_SE_corner_longitude) return(0); // view left of  map
+
+    return (1); // Draw this map onto the screen
+}
+
+
+
+
+
+/**********************************************************
+ * draw_label_text()
+ *
+ * Does what it says.  Used to draw strings onto the
+ * display.
+ **********************************************************/
+void draw_label_text (Widget w, int x, int y, int label_length, int color, char *label_text) {
+
+    // This draws a gray background rectangle upon which we draw the text.
+    // Probably not needed.  It ends up obscuring details underneath.
+    //(void)XSetForeground (XtDisplay (w), gc, colors[0x0ff]);
+    //(void)XFillRectangle (XtDisplay (w), pixmap, gc, x - 1, (y - 10),(label_length * 6) + 2, 11);
+
+    (void)XSetForeground (XtDisplay (w), gc, color);
+    (void)XDrawString (XtDisplay (w), pixmap, gc, x, y, label_text, label_length);
+}
+
+
+
+
+
+// Must make sure that fonts are not loaded again and again, as this
+// takes a big chunk of memory each time.  Can you say "memory
+// leak"?
+
+XFontStruct *rotated_label_font[FONT_MAX]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+char rotated_label_fontname[FONT_MAX][MAX_LABEL_FONTNAME];
+static char
+current_rotated_label_fontname[FONT_MAX][sizeof(rotated_label_fontname)] = {"","","","","","","","",""};
+
+/**********************************************************
+ * draw_rotated_label_text_common()
+ * call through wrappers:
+ * draw_rotated_label_text_to_pixmap()
+ * draw_rotated_label_text()
+ * draw_centered_label_text()
+ *
+ * Does what it says.  Used to draw strings onto the
+ * display.
+ *
+ * Use "xfontsel" or other tools to figure out what fonts
+ * to use here.
+ * 
+ * Paramenters:
+ * target_pixmap specifies the pixmap the text is to be drawn to.
+ * draw_outline specifies whether a 1 pixel outline around the
+ *    text, TRUE to draw outline.
+ * outline_bg_color is the color of the outline.
+ * color is the color of the text inside the outline, or the 
+ *    color of the text itself if no outline is added.
+ **********************************************************/
+/* common code used by the two entries --- a result of retrofitting a new
+   feature (centered) */
+static void draw_rotated_label_text_common (Widget w, float my_rotation, int x, int y, int label_length, int color, char *label_text, int align, int fontsize, Pixmap target_pixmap, int draw_outline, int outline_bg_color) {
+//    XPoint *corner;
+//    int i;
+    int x_outline;
+    int y_outline;
+
+
+    // Do some sanity checking
+    if (fontsize < 0 || fontsize >= FONT_MAX) {
+        fprintf(stderr,"Font size is out of range: %d\n", fontsize);
+        return;
+    }
+
+    /* see if fontname has changed */
+    if (rotated_label_font[fontsize] && 
+        strcmp(rotated_label_fontname[fontsize],current_rotated_label_fontname[fontsize]) != 0) {
+        XFreeFont(XtDisplay(w),rotated_label_font[fontsize]);
+        rotated_label_font[fontsize] = NULL;
+        xastir_snprintf(current_rotated_label_fontname[fontsize],
+            sizeof(rotated_label_fontname),
+            "%s",
+            rotated_label_fontname[fontsize]);
+    }
+    /* load font */
+    if(!rotated_label_font[fontsize]) {
+        rotated_label_font[fontsize]=(XFontStruct *)XLoadQueryFont(XtDisplay (w),
+                                                rotated_label_fontname[fontsize]);
+        if (rotated_label_font[fontsize] == NULL) {    // Couldn't get the font!!!
+            fprintf(stderr,"draw_rotated_label_text: Couldn't get font %s\n",
+                rotated_label_fontname[fontsize]);
+            return;
+        }
+    }
+
+    if (draw_outline) {
+        // make outline style
+        (void)XSetForeground(XtDisplay(w),gc,outline_bg_color);
+        // Draw the string repeatedly with 1 pixel offsets in the
+        // background color to make an outline. 
+    
+        for (x_outline=-1;x_outline<2;x_outline++) {
+            for (y_outline=-1;y_outline<2;y_outline++) {
+                // draws one extra copy at x,y
+                (void)XRotDrawAlignedString(XtDisplay (w),
+                                rotated_label_font[fontsize],
+                                my_rotation,
+                                target_pixmap,
+                                gc,
+                                x+x_outline,
+                                y+y_outline,
+                                label_text,
+                                align);
+            }
+       }
+    }
+
+
+    // Code to determine the bounding box corner points for the rotated text
+//    corner = XRotTextExtents(w,rotated_label_font,my_rotation,x,y,label_text,BLEFT);
+//    for (i=0;i<5;i++) {
+//        fprintf(stderr,"%d,%d\t",corner[i].x,corner[i].y);
+//    }
+//    fprintf(stderr,"\n");
+
+    (void)XSetForeground (XtDisplay (w), gc, color);
+
+    //fprintf(stderr,"%0.1f\t%s\n",my_rotation,label_text);
+
+    (void)XRotDrawAlignedString(XtDisplay (w),
+                                rotated_label_font[fontsize],
+                                my_rotation,
+                                target_pixmap,
+                                gc,
+                                x,
+                                y,
+                                label_text,
+                                align);
+}
+
+
+
+
+
+// Find the pixel length of an unrotated string in the rotated_label_font.
+// Parameters:
+//    w - the XtDisplay.
+//    label_text - the string of which the length is to be found.
+//    fontsize - the fontsize in the rotated_label_font in which the string
+//    is to be rendered.
+// Returns: the length in pixels of the string, -1 on an error.
+int get_rotated_label_text_length_pixels(Widget w, char *label_text, int fontsize) {
+    int dir, asc, desc;   // parameters returned by XTextExtents, but not used here.
+    XCharStruct overall;  // description of the space occupied by the string.
+    int return_value;     // value to return
+    int got_font;         // flag indicating that a font is available
+
+    return_value = -1;
+    got_font = TRUE;
+
+    /* load font */
+    if(!rotated_label_font[fontsize]) {
+        rotated_label_font[fontsize]=(XFontStruct *)XLoadQueryFont(XtDisplay (w),
+                                                rotated_label_fontname[fontsize]);
+        if (rotated_label_font[fontsize] == NULL) {    // Couldn't get the font!!!
+            fprintf(stderr,"get_rotated_label_text_length_pixels: Couldn't get font %s\n",
+                rotated_label_fontname[fontsize]);
+            got_font = FALSE;
+        }
+    }
+   
+    if (got_font) {
+        // find out the width in pixels of the unrotated label_text string.
+        XTextExtents(rotated_label_font[fontsize], label_text, strlen(label_text), &dir, &asc, &desc,
+             &overall);
+        return_value = overall.width;
+    }
+
+    return return_value;
+}
+
+
+
+
+
+// Find the pixel height of an unrotated string in the rotated_label_font.
+// Parameters:
+//    w - the XtDisplay.
+//    label_text - the string of which the length is to be found.
+//    fontsize - the fontsize in the rotated_label_font in which the string
+//    is to be rendered.
+// Returns: the height in pixels of the string, -1 on an error.
+int get_rotated_label_text_height_pixels(Widget w, char *label_text, int fontsize) {
+    int dir, asc, desc;   // parameters returned by XTextExtents, but not used here.
+    XCharStruct overall;  // description of the space occupied by the string.
+    int return_value;     // value to return
+    int got_font;         // flag indicating that a font is available
+
+    return_value = -1;
+    got_font = TRUE;
+
+    /* load font */
+    if(!rotated_label_font[fontsize]) {
+        rotated_label_font[fontsize]=(XFontStruct *)XLoadQueryFont(XtDisplay (w),
+                                                rotated_label_fontname[fontsize]);
+        if (rotated_label_font[fontsize] == NULL) {    // Couldn't get the font!!!
+            fprintf(stderr,"get_rotated_label_text_height_pixels: Couldn't get font %s\n",
+                rotated_label_fontname[fontsize]);
+            got_font = FALSE;
+        }
+    }
+   
+    if (got_font) {
+        // find out the width in pixels of the unrotated label_text string.
+        XTextExtents(rotated_label_font[fontsize], label_text, strlen(label_text), &dir, &asc, &desc,
+             &overall);
+        return_value = overall.ascent + overall.descent;
+    }
+
+    return return_value;
+}
+
+
+
+
+
+// Draw a rotated label onto the specified pixmap.
+// Wrapper for draw_rotated_label_text-common().
+void draw_rotated_label_text_to_target (Widget w, int rotation, int x, int y, int label_length, int color, char *label_text, int fontsize, Pixmap target_pixmap, int draw_outline, int outline_bg_color) {
+    float my_rotation = (float)((-rotation)-90);
+
+    if ( ( (my_rotation < -90.0) && (my_rotation > -270.0) )
+         || ( (my_rotation >  90.0) && (my_rotation <  270.0) ) ) {
+        my_rotation = my_rotation + 180.0;
+        (void)draw_rotated_label_text_common(w,
+            my_rotation,
+            x,
+            y,
+            label_length,                                    
+            color,
+            label_text,
+            BRIGHT,
+            fontsize,
+            target_pixmap,
+            draw_outline,
+            outline_bg_color);
+    }
+    else {
+        (void)draw_rotated_label_text_common(w,
+            my_rotation,
+            x,
+            y,
+            label_length,                                    
+            color,
+            label_text,
+            BLEFT,
+            fontsize,
+            target_pixmap,
+            draw_outline,
+            outline_bg_color);
+    }
+}
+
+
+
+
+
+void draw_rotated_label_text (Widget w, int rotation, int x, int y, int label_length, int color, char *label_text, int fontsize) {
+    float my_rotation = (float)((-rotation)-90);
+
+    if ( ( (my_rotation < -90.0) && (my_rotation > -270.0) )
+         || ( (my_rotation >  90.0) && (my_rotation <  270.0) ) ) {
+        my_rotation = my_rotation + 180.0;
+        (void)draw_rotated_label_text_common(w,
+            my_rotation,
+            x,
+            y,
+            label_length,                                    
+            color,
+            label_text,
+            BRIGHT,
+            fontsize,
+            pixmap, 0, 0);
+    }
+    else {
+        (void)draw_rotated_label_text_common(w,
+            my_rotation,
+            x,
+            y,
+            label_length,                                    
+            color,
+            label_text,
+            BLEFT,
+            fontsize,
+            pixmap, 0, 0);
+    }
+}
+
+void draw_centered_label_text (Widget w, int rotation, int x, int y, int label_length, int color, char *label_text, int fontsize) {
+    float my_rotation = (float)((-rotation)-90);
+
+        (void)draw_rotated_label_text_common(w,
+            my_rotation,
+            x,
+            y,
+            label_length,                                    
+            color,
+            label_text,
+            BCENTRE,
+            fontsize,
+            pixmap, 0, 0);
+}
+
+
+
+
+
+static void Print_postscript_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    char *temp_ptr;
+
+
+    XtPopdown(shell);
+
+begin_critical_section(&print_postscript_dialog_lock, "maps.c:Print_postscript_destroy_shell" );
+
+    if (print_postscript_dialog) {
+        // Snag the path to the printer program from the print dialog
+        temp_ptr = XmTextFieldGetString(printer_data);
+        xastir_snprintf(printer_program,
+            sizeof(printer_program),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+        (void)remove_trailing_spaces(printer_program);
+
+        // Check for empty variable
+        if (printer_program[0] == '\0') {
+
+#ifdef LPR_PATH
+            // Path to LPR if defined
+            xastir_snprintf(printer_program,
+                sizeof(printer_program),
+                "%s",
+                LPR_PATH);
+#else // LPR_PATH
+            // Empty path
+            xastir_snprintf(printer_program,
+                sizeof(printer_program),
+                "");
+#endif // LPR_PATH
+        }
+
+//fprintf(stderr,"%s\n", printer_program);
+
+        // Snag the path to the previewer program from the print dialog
+        temp_ptr = XmTextFieldGetString(previewer_data);
+        xastir_snprintf(previewer_program,
+            sizeof(previewer_program),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+        (void)remove_trailing_spaces(previewer_program);
+
+        // Check for empty variable
+        if (previewer_program[0] == '\0') {
+
+#ifdef GV_PATH
+            // Path to GV if defined
+            xastir_snprintf(previewer_program,
+                sizeof(previewer_program),
+                "%s",
+                GV_PATH);
+#else // GV_PATH
+            // Empty string
+            previewer_program[0] = '\0';
+#endif // GV_PATH
+        }
+//fprintf(stderr,"%s\n", previewer_program);
+    }
+ 
+    XtDestroyWidget(shell);
+    print_postscript_dialog = (Widget)NULL;
+
+end_critical_section(&print_postscript_dialog_lock, "maps.c:Print_postscript_destroy_shell" );
+
+}
+
+
+
+
+
+static void Print_properties_destroy_shell(/*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+
+    if (!shell)
+        return;
+
+    XtPopdown(shell);
+
+begin_critical_section(&print_properties_dialog_lock, "maps.c:Print_properties_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    print_properties_dialog = (Widget)NULL;
+
+end_critical_section(&print_properties_dialog_lock, "maps.c:Print_properties_destroy_shell" );
+
+}
+
+
+
+
+
+// Print_window:  Prints the drawing area to a Postscript file and
+// then sends it to the printer program (usually "lpr).
+//
+static void Print_window( Widget widget, XtPointer clientData, XtPointer callData ) {
+
+#ifdef NO_XPM
+//    fprintf(stderr,"XPM or ImageMagick support not compiled into Xastir!\n");
+    popup_message_always(langcode("POPEM00035"),
+        "XPM or ImageMagick support not compiled into Xastir! Cannot Print!");
+#else   // NO_XPM
+
+    char xpm_filename[MAX_FILENAME];
+    char ps_filename[MAX_FILENAME];
+    char command[MAX_FILENAME*2];
+    char temp[MAX_FILENAME];
+    int xpmretval;
+    char temp_base_dir[MAX_VALUE];
+
+    get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir));
+
+    xastir_snprintf(xpm_filename,
+        sizeof(xpm_filename),
+        "%s/print.xpm",
+        temp_base_dir);
+
+    xastir_snprintf(ps_filename,
+        sizeof(ps_filename),
+        "%s/print.ps",
+        temp_base_dir);
+
+    busy_cursor(appshell);  // Show a busy cursor while we're doing all of this
+
+    // Get rid of the Print dialog
+    Print_postscript_destroy_shell(widget, print_postscript_dialog, NULL );
+
+    if ( debug_level & 512 )
+        fprintf(stderr,"Creating %s\n", xpm_filename );
+
+    xastir_snprintf(temp, sizeof(temp), "%s", langcode("PRINT0012") );
+    statusline(temp,1);       // Dumping image to file...
+
+    chdir(temp_base_dir);
+    xpmretval=XpmWriteFileFromPixmap(XtDisplay(appshell),// Display *display
+            "print.xpm",                                 // char *filename
+            pixmap_final,                                // Pixmap pixmap
+            (Pixmap)NULL,                                // Pixmap shapemask
+            NULL );
+
+    if (xpmretval != XpmSuccess) {
+        fprintf(stderr,"ERROR writing %s: %s\n", xpm_filename,
+            XpmGetErrorString(xpmretval));
+        popup_message_always(langcode("POPEM00035"),
+            "Error writing xpm image file! Cannot Print!");
+        return; 
+    }
+    else {          // We now have the xpm file created on disk
+
+        chmod( xpm_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"Convert %s ==> %s\n", xpm_filename, ps_filename );
+
+
+        // Convert it to a postscript file for printing.  This depends
+        // on the ImageMagick command "convert".
+        //
+
+        if (debug_level & 512)
+            fprintf(stderr,"Width: %ld\tHeight: %ld\n", screen_width, screen_height);
+
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode("PRINT0013") );
+        statusline(temp,1);       // Converting to Postscript...
+
+
+#ifdef HAVE_CONVERT
+        xastir_snprintf(command,
+            sizeof(command),
+            "%s -filter Point %s %s",
+            CONVERT_PATH,
+            xpm_filename,
+            ps_filename );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"%s\n", command );
+
+        if ( system( command ) != 0 ) {
+//            fprintf(stderr,"\n\nPrint: Couldn't convert from XPM to PS!\n\n\n");
+            popup_message_always(langcode("POPEM00035"),
+                "Couldn't convert from XPM to PS!");
+            return;
+        }
+#endif  // HAVE_CONVERT
+
+        chmod( ps_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+
+        // Delete temporary xpm file
+        if ( !(debug_level & 512) )
+            unlink( xpm_filename );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"Printing postscript file %s\n", ps_filename);
+
+// Note: This needs to be changed to "lp" for Solaris.
+// Also need to have a field to configure the printer name.  One
+// fill-in field could do both.
+//
+// Since we could be running SUID root, we don't want to be
+// calling "system" anyway.  Several problems with it.
+
+        xastir_snprintf(command,
+            sizeof(command),
+            "%s %s",
+            printer_program,
+            ps_filename );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"%s\n", command);
+
+        if (printer_program[0] == '\0') {
+//            fprintf(stderr,"\n\nPrint: No print program defined!\n\n\n");
+            popup_message_always(langcode("POPEM00035"),
+                "No print program defined!");
+            return;
+        }
+
+        if ( system( command ) != 0 ) {
+//            fprintf(stderr,"\n\nPrint: Couldn't send to the printer!\n\n\n");
+            popup_message_always(langcode("POPEM00035"),
+                "Couldn't send to the printer!");
+            return;
+        }
+
+/*
+        if ( !(debug_level & 512) )
+            unlink( ps_filename );
+*/
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"  Done printing.\n");
+    }
+
+    xastir_snprintf(temp, sizeof(temp), "%s", langcode("PRINT0014") );
+    statusline(temp,1);       // Finished creating print file.
+
+    //popup_message( langcode("PRINT0015"), langcode("PRINT0014") );
+
+#endif // NO_XPM
+
+}
+
+
+
+
+
+// Print_preview:  Prints the drawing area to a Postscript file.  If
+// previewer_program has "gv" in it, then use the various options
+// selected by the user.  If not, skip those options.
+//
+static void Print_preview( Widget widget, XtPointer clientData, XtPointer callData ) {
+
+#ifdef NO_XPM
+//    fprintf(stderr,"XPM or ImageMagick support not compiled into Xastir!\n");
+    popup_message_always(langcode("POPEM00035"),
+        "XPM or ImageMagick support not compiled into Xastir! Cannot Print!");
+#else   // NO_GRAPHICS
+
+    char xpm_filename[MAX_FILENAME];
+    char ps_filename[MAX_FILENAME];
+    char mono[50] = "";
+    char invert[50] = "";
+    char rotate[50] = "";
+    char scale[50] = "";
+    char density[50] = "";
+    char command[MAX_FILENAME*2];
+    char temp[MAX_FILENAME];
+    char format[100] = " ";
+    int xpmretval;
+    char temp_base_dir[MAX_VALUE];
+
+    get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir));
+
+
+    xastir_snprintf(xpm_filename,
+        sizeof(xpm_filename),
+        "%s/print.xpm",
+        temp_base_dir);
+
+    xastir_snprintf(ps_filename,
+        sizeof(ps_filename),
+        "%s/print.ps",
+        temp_base_dir);
+
+    busy_cursor(appshell);  // Show a busy cursor while we're doing all of this
+
+    // Get rid of the Print Properties dialog if it exists
+    Print_properties_destroy_shell(widget, print_properties_dialog, NULL );
+
+    if ( debug_level & 512 )
+        fprintf(stderr,"Creating %s\n", xpm_filename );
+
+    xastir_snprintf(temp, sizeof(temp), "%s", langcode("PRINT0012") );
+    statusline(temp,1);       // Dumping image to file...
+
+    chdir(temp_base_dir);
+    xpmretval=XpmWriteFileFromPixmap(XtDisplay(appshell),// Display *display
+            "print.xpm",                                 // char *filename
+            pixmap_final,                                // Pixmap pixmap
+            (Pixmap)NULL,                                // Pixmap shapemask
+            NULL );
+
+    if (xpmretval != XpmSuccess) {
+        fprintf(stderr,"ERROR writing %s: %s\n", xpm_filename,
+            XpmGetErrorString(xpmretval));
+        popup_message_always(langcode("POPEM00035"),
+            "Error writing XPM file!");
+        return; 
+    }
+    else {          // We now have the xpm file created on disk
+
+        chmod( xpm_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"Convert %s ==> %s\n", xpm_filename, ps_filename );
+
+
+        // If we're not using "gv", skip most of the code below and
+        // go straight to the previewer program portion of the code.
+        //
+        if ( strstr(previewer_program,"gv") ) {
+
+            // Convert it to a postscript file for printing.  This
+            // depends on the ImageMagick command "convert".
+            //
+            // Other options to try in the future:
+            // -label
+            //
+         if ( print_auto_scale ) {
+//                sprintf(scale, "-geometry 612x792 -page 612x792 ");   // "Letter" size at 72 dpi
+//                sprintf(scale, "-sample 612x792 -page 612x792 ");     // "Letter" size at 72 dpi
+                xastir_snprintf(scale, sizeof(scale), "-page 1275x1650+0+0 "); // "Letter" size at 150 dpi
+            }
+            else
+                scale[0] = '\0';    // Empty string
+
+
+            if ( print_in_monochrome )
+                xastir_snprintf(mono, sizeof(mono), "-monochrome +dither " );    // Monochrome
+            else
+                xastir_snprintf(mono, sizeof(mono), "+dither ");                // Color
+
+
+            if ( print_invert )
+                xastir_snprintf(invert, sizeof(invert), "-negate " );              // Reverse Colors
+            else
+                invert[0] = '\0';   // Empty string
+
+
+            if (debug_level & 512)
+                fprintf(stderr,"Width: %ld\tHeight: %ld\n", screen_width, screen_height);
+
+
+            if ( print_rotated ) {
+                xastir_snprintf(rotate, sizeof(rotate), "-rotate -90 " );
+
+#ifdef HAVE_OLD_GV
+                xastir_snprintf(format, sizeof(format), "-landscape " );
+#else   // HAVE_OLD_GV
+                xastir_snprintf(format, sizeof(format), "--orientation=landscape " );
+#endif  // HAVE_OLD_GV
+
+            }
+            else if ( print_auto_rotation ) {
+                // Check whether the width or the height of the
+                // pixmap is greater.  If width is greater than
+                // height, rotate the image by 270 degrees.
+                if (screen_width > screen_height) {
+                    xastir_snprintf(rotate, sizeof(rotate), "-rotate -90 " );
+
+#ifdef HAVE_OLD_GV
+                    xastir_snprintf(format, sizeof(format), "-landscape " );
+#else   // HAVE_OLD_GV
+                    xastir_snprintf(format, sizeof(format), "--orientation=landscape " );
+#endif  // HAVE_OLD_GV
+
+                    if (debug_level & 512)
+                        fprintf(stderr,"Rotating\n");
+                }
+                else {
+                    rotate[0] = '\0';   // Empty string
+                    if (debug_level & 512)
+                        fprintf(stderr,"Not Rotating\n");
+                }
+            }
+            else {
+                rotate[0] = '\0';   // Empty string
+                if (debug_level & 512)
+                    fprintf(stderr,"Not Rotating\n");
+            }
+
+
+            // Higher print densities require more memory and time
+            // to process
+            xastir_snprintf(density, sizeof(density), "-density %dx%d", print_resolution,
+                    print_resolution );
+
+            xastir_snprintf(temp, sizeof(temp), "%s", langcode("PRINT0013") );
+            statusline(temp,1);       // Converting to Postscript...
+
+
+            // Filters:
+            // Point (ok at higher dpi's)
+            // Box  (not too bad)
+            // Triangle (no)
+            // Hermite (no)
+            // Hanning (no)
+            // Hamming (no)
+            // Blackman (better but still not good)
+            // Gaussian (no)
+            // Quadratic (no)
+            // Cubic (no)
+            // Catrom (not too bad)
+            // Mitchell (no)
+            // Lanczos (no)
+            // Bessel (no)
+            // Sinc (not too bad)
+
+        }
+
+#ifdef HAVE_CONVERT
+        xastir_snprintf(command,
+            sizeof(command),
+            "%s -filter Point %s%s%s%s%s %s %s",
+            CONVERT_PATH,
+            mono,
+            invert,
+            rotate,
+            scale,
+            density,
+            xpm_filename,
+            ps_filename );
+        if ( debug_level & 512 )
+            fprintf(stderr,"%s\n", command );
+
+        if ( system( command ) != 0 ) {
+//            fprintf(stderr,"\n\nPrint: Couldn't convert from XPM to PS!\n\n\n");
+            popup_message_always(langcode("POPEM00035"),
+                "Couldn't convert from XPM to PS!");
+            return;
+        }
+#endif  // HAVE_CONVERT
+
+        chmod( ps_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+
+        // Delete temporary xpm file
+        if ( !(debug_level & 512) )
+            unlink( xpm_filename );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"Printing postscript file %s\n", ps_filename);
+
+// Since we could be running SUID root, we don't want to be
+// calling "system" anyway.  Several problems with it.
+
+        // Bring up the postscript viewer
+        xastir_snprintf(command,
+            sizeof(command),
+            "%s %s %s &",
+            previewer_program,
+            format,
+            ps_filename );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"%s\n", command);
+
+        if (previewer_program[0] == '\0') {
+//            fprintf(stderr,"\n\nPrint: No print previewer defined!\n\n\n");
+            popup_message_always(langcode("POPEM00035"),
+                "No print previewer defined!");
+            return;
+        }
+
+        if ( system( command ) != 0 ) {
+//            fprintf(stderr,"\n\nPrint: Couldn't bring up the postscript viewer!\n\n\n");
+            popup_message_always(langcode("POPEM00035"),
+                "Couldn't bring up the viewer!");
+            return;
+        }
+
+/*
+        if ( !(debug_level & 512) )
+            unlink( ps_filename );
+*/
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"  Done printing.\n");
+    }
+
+    xastir_snprintf(temp, sizeof(temp), "%s", langcode("PRINT0014") );
+    statusline(temp,1);       // Finished creating print file.
+
+    //popup_message( langcode("PRINT0015"), langcode("PRINT0014") );
+
+#endif // NO_XPM
+
+}
+
+
+
+
+
+/*
+ *  Auto_rotate
+ *
+ */
+static void  Auto_rotate( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        print_auto_rotation = atoi(which);
+        print_rotated = 0;
+        XmToggleButtonSetState(rotate_90, FALSE, FALSE);
+    }
+    else {
+        print_auto_rotation = 0;
+    }
+}
+
+
+
+
+
+/*
+ *  Rotate_90
+ *
+ */
+static void  Rotate_90( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        print_rotated = atoi(which);
+        print_auto_rotation = 0;
+        XmToggleButtonSetState(auto_rotate, FALSE, FALSE);
+    }
+    else {
+        print_rotated = 0;
+    }
+}
+
+
+
+
+
+/*
+ *  Auto_scale
+ *
+ */
+static void  Auto_scale( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        print_auto_scale = atoi(which);
+    }
+    else {
+        print_auto_scale = 0;
+    }
+}
+
+
+
+
+
+/*
+ *  Monochrome
+ *
+ */
+void  Monochrome( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        print_in_monochrome = atoi(which);
+    }
+    else {
+        print_in_monochrome = 0;
+    }
+}
+
+
+
+
+
+/*
+ *  Invert
+ *
+ */
+static void  Invert( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        print_invert = atoi(which);
+    }
+    else {
+        print_invert = 0;
+    }
+}
+
+
+
+
+
+// Print_properties:  Prints the drawing area to a PostScript file.
+// Provides various togglebuttons for configuring the "gv" previewer
+// only.
+//
+// Perhaps later:
+// 1) Select an area on the screen to print
+// 2) -label
+//
+void Print_properties( Widget w, XtPointer clientData, XtPointer callData ) {
+    static Widget pane, form, button_ok, button_cancel,
+            sep, auto_scale,
+//            paper_size, paper_size_data, scale, scale_data, blank_background,
+//            res_label1, res_label2, res_x, res_y,
+            monochrome, invert;
+    Atom delw;
+
+    // Get rid of the Print dialog
+    Print_postscript_destroy_shell(w, print_postscript_dialog, NULL );
+
+
+    // If we're not using "gv", skip the entire dialog below and go
+    // straight to the actual previewer function.
+    //
+    if ( !strstr(previewer_program,"gv") ) {
+        Print_preview(w, NULL, NULL);
+        return;
+    }
+
+
+    if (!print_properties_dialog) {
+
+
+begin_critical_section(&print_properties_dialog_lock, "maps.c:Print_properties" );
+
+
+        print_properties_dialog = XtVaCreatePopupShell(langcode("PRINT0001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+
+        pane = XtVaCreateWidget("Print_properties pane",xmPanedWindowWidgetClass, print_properties_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+
+        form =  XtVaCreateWidget("Print_properties form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 2,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+
+/*
+        paper_size = XtVaCreateManagedWidget(langcode("PRINT0002"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(paper_size,FALSE);
+
+ 
+        paper_size_data = XtVaCreateManagedWidget("Print_properties paper_size_data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 15,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, paper_size,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 10,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(paper_size_data,FALSE);
+*/
+
+
+        auto_rotate  = XtVaCreateManagedWidget(langcode("PRINT0003"),xmToggleButtonWidgetClass,form,
+//                                      XmNtopAttachment, XmATTACH_WIDGET,
+//                                      XmNtopWidget, paper_size_data,
+//                                      XmNtopOffset, 5,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtAddCallback(auto_rotate,XmNvalueChangedCallback,Auto_rotate,"1");
+
+
+        rotate_90  = XtVaCreateManagedWidget(langcode("PRINT0004"),xmToggleButtonWidgetClass,form,
+//                                      XmNtopAttachment, XmATTACH_WIDGET,
+//                                      XmNtopWidget, paper_size_data,
+//                                      XmNtopOffset, 5,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, auto_rotate,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_FORM,
+                                      XmNrightOffset, 10,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtAddCallback(rotate_90,XmNvalueChangedCallback,Rotate_90,"1");
+
+
+        auto_scale = XtVaCreateManagedWidget(langcode("PRINT0005"),xmToggleButtonWidgetClass,form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, auto_rotate,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtAddCallback(auto_scale,XmNvalueChangedCallback,Auto_scale,"1");
+
+
+/*
+        scale = XtVaCreateManagedWidget(langcode("PRINT0006"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, auto_rotate,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, auto_scale,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(scale,FALSE);
+
+
+        scale_data = XtVaCreateManagedWidget("Print_properties scale_data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 15,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, auto_rotate,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, scale,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 10,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(scale_data,FALSE);
+*/
+
+
+/*
+        blank_background = XtVaCreateManagedWidget(langcode("PRINT0007"),xmToggleButtonWidgetClass,form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, scale_data,
+                                      XmNtopWidget, auto_rotate,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(blank_background,FALSE);
+*/
+
+
+        monochrome = XtVaCreateManagedWidget(langcode("PRINT0008"),xmToggleButtonWidgetClass,form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+//                                      XmNtopWidget, blank_background,
+                                      XmNtopWidget, auto_scale,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtAddCallback(monochrome,XmNvalueChangedCallback,Monochrome,"1");
+
+
+        invert = XtVaCreateManagedWidget(langcode("PRINT0016"),xmToggleButtonWidgetClass,form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, monochrome,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset ,10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtAddCallback(invert,XmNvalueChangedCallback,Invert,"1");
+
+
+/*
+        res_label1 = XtVaCreateManagedWidget(langcode("PRINT0009"),xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, invert,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(res_label1,FALSE);
+
+
+        res_x = XtVaCreateManagedWidget("Print_properties resx_data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 15,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, invert,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, res_label1,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_NONE,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(res_x,FALSE);
+
+
+        res_label2 = XtVaCreateManagedWidget("X",xmLabelWidgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, invert,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, res_x,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(res_label2,FALSE);
+
+
+        res_y = XtVaCreateManagedWidget("Print_properties res_y_data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 15,
+                                      XmNwidth, ((15*7)+2),
+                                      XmNmaxLength, 15,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, invert,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, res_label2,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 10,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+XtSetSensitive(res_y,FALSE);
+*/
+
+
+        sep = XtVaCreateManagedWidget("Print_properties sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+//                                      XmNtopWidget, res_y,
+                                      XmNtopWidget, invert,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+//        button_ok = XtVaCreateManagedWidget(langcode("PRINT0011"),xmPushButtonGadgetClass, form,
+        button_ok = XtVaCreateManagedWidget(langcode("PRINT0010"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 0,
+                                      XmNleftOffset, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 1,
+                                      XmNrightOffset, 2,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 1,
+                                      XmNleftOffset, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 2,
+                                      XmNrightOffset, 5,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        XtAddCallback(button_ok, XmNactivateCallback, Print_preview, NULL );
+        XtAddCallback(button_cancel, XmNactivateCallback, Print_properties_destroy_shell, print_properties_dialog);
+
+
+        XmToggleButtonSetState(rotate_90,FALSE,FALSE);
+        XmToggleButtonSetState(auto_rotate,TRUE,FALSE);
+
+
+        if (print_auto_rotation)
+            XmToggleButtonSetState(auto_rotate, TRUE, TRUE);
+        else
+            XmToggleButtonSetState(auto_rotate, FALSE, TRUE);
+
+
+        if (print_rotated)
+            XmToggleButtonSetState(rotate_90, TRUE, TRUE);
+        else
+            XmToggleButtonSetState(rotate_90, FALSE, TRUE);
+
+
+        if (print_in_monochrome)
+            XmToggleButtonSetState(monochrome, TRUE, FALSE);
+        else
+            XmToggleButtonSetState(monochrome, FALSE, FALSE);
+
+
+        if (print_invert)
+            XmToggleButtonSetState(invert, TRUE, FALSE);
+        else
+            XmToggleButtonSetState(invert, FALSE, FALSE);
+
+
+        if (print_auto_scale)
+            XmToggleButtonSetState(auto_scale, TRUE, TRUE);
+        else
+            XmToggleButtonSetState(auto_scale, FALSE, TRUE);
+ 
+
+//        XmTextFieldSetString(paper_size_data,print_paper_size);
+
+
+end_critical_section(&print_properties_dialog_lock, "maps.c:Print_properties" );
+
+
+        pos_dialog(print_properties_dialog);
+
+
+        delw = XmInternAtom(XtDisplay(print_properties_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(print_properties_dialog, delw, Print_properties_destroy_shell, (XtPointer)print_properties_dialog);
+
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+
+        XtPopup(print_properties_dialog,XtGrabNone);
+        fix_dialog_size(print_properties_dialog);
+
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(print_properties_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+
+    }
+    else {
+        (void)XRaiseWindow(XtDisplay(print_properties_dialog), XtWindow(print_properties_dialog));
+    }
+}
+
+
+
+
+
+// General print dialog.  From here we can either print Postscript
+// files to the device selected in this dialog, or head off to a
+// print preview program that might allow us a variety of print
+// options.  From here we should be able to set the print device
+// and the print preview program & path.
+//
+void Print_Postscript( Widget w, XtPointer clientData, XtPointer callData ) {
+    static Widget pane, form, button_print, button_cancel,
+            sep, button_preview;
+    Atom delw;
+
+    if (!print_postscript_dialog) {
+
+
+begin_critical_section(&print_postscript_dialog_lock, "maps.c:Print_Postscript" );
+
+
+        print_postscript_dialog = XtVaCreatePopupShell(langcode("PULDNFI015"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+
+        pane = XtVaCreateWidget("Print_postscript pane",xmPanedWindowWidgetClass, print_postscript_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+
+        form =  XtVaCreateWidget("Print_postscript form",xmFormWidgetClass, pane,
+                            XmNfractionBase, 3,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+
+        // "Direct to:"
+        button_print = XtVaCreateManagedWidget(langcode("PRINT1001"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        printer_data = XtVaCreateManagedWidget("Print_Postscript printer_data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 40,
+                                      XmNwidth, ((40*7)+2),
+                                      XmNmaxLength, MAX_FILENAME,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_FORM,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, button_print,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        // "Via Previewer:"
+        button_preview = XtVaCreateManagedWidget(langcode("PRINT1002"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, button_print,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+ 
+        previewer_data = XtVaCreateManagedWidget("Print_Postscript previewer_data", xmTextFieldWidgetClass, form,
+                                      XmNeditable,   TRUE,
+                                      XmNcursorPositionVisible, TRUE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 40,
+                                      XmNwidth, ((40*7)+2),
+                                      XmNmaxLength, MAX_FILENAME,
+                                      XmNbackground, colors[0x0f],
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, button_print,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, button_preview,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        sep = XtVaCreateManagedWidget("Print_postscript sep", xmSeparatorGadgetClass,form,
+                                      XmNorientation, XmHORIZONTAL,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, button_preview,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, sep,
+                                      XmNtopOffset, 5,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_FORM,
+                                      XmNrightOffset, 5,
+                                      XmNbackground, colors[0xff],
+                                      XmNnavigationType, XmTAB_GROUP,
+                                      XmNtraversalOn, TRUE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        XtAddCallback(button_preview, XmNactivateCallback, Print_properties, NULL );
+        XtAddCallback(button_print, XmNactivateCallback, Print_window, NULL );
+        XtAddCallback(button_cancel, XmNactivateCallback, Print_postscript_destroy_shell, print_postscript_dialog);
+
+        // Fill in the text fields from persistent variables out of the config file.
+        XmTextFieldSetString(printer_data, printer_program);
+        XmTextFieldSetString(previewer_data, previewer_program);
+
+end_critical_section(&print_postscript_dialog_lock, "maps.c:Print_Postscript" );
+
+
+        pos_dialog(print_postscript_dialog);
+
+
+        delw = XmInternAtom(XtDisplay(print_postscript_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(print_postscript_dialog, delw, Print_postscript_destroy_shell, (XtPointer)print_postscript_dialog);
+
+
+        XtManageChild(form);
+        XtManageChild(pane);
+
+
+        XtPopup(print_postscript_dialog,XtGrabNone);
+        fix_dialog_size(print_postscript_dialog);
+
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(print_postscript_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+
+    }
+    else {
+        (void)XRaiseWindow(XtDisplay(print_postscript_dialog), XtWindow(print_postscript_dialog));
+    }
+}
+ 
+
+
+
+
+// Create png image (for use in web browsers??).  Requires that "convert"
+// from the ImageMagick package be installed on the system.  At the
+// point this thread is started, the XPM file has already been
+// created.  We now create a .geo file to go with the .png file.
+//
+#ifndef NO_XPM
+static void* snapshot_thread(void *arg) {
+    char xpm_filename[MAX_FILENAME];
+    char png_filename[MAX_FILENAME];
+    char geo_filename[MAX_FILENAME];
+    char kml_filename[MAX_FILENAME];   // filename for kml file that describes the png file in keyhole markup language
+    char timestring[101];  // string representation of the time heard or the current time
+    FILE *f;
+    FILE *fk;  // file handle for kml file
+    time_t expire_time;  
+#ifdef HAVE_CONVERT
+    char command[MAX_FILENAME*2];
+#endif  // HAVE_CONVERT
+    char temp_base_dir[MAX_VALUE];
+
+    get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir));
+
+
+    // The pthread_detach() call means we don't care about the
+    // return code and won't use pthread_join() later.  Makes
+    // threading more efficient.
+    (void)pthread_detach(pthread_self());
+
+    xastir_snprintf(xpm_filename,
+        sizeof(xpm_filename),
+        "%s/snapshot.xpm",
+        temp_base_dir);
+
+    xastir_snprintf(png_filename,
+        sizeof(png_filename),
+        "%s/snapshot.png",
+        temp_base_dir);
+
+    // Same for the .geo filename
+    xastir_snprintf(geo_filename,
+        sizeof(geo_filename),
+        "%s/snapshot.geo",
+        temp_base_dir);
+
+    // Same for the .kml filename
+    xastir_snprintf(kml_filename,
+        sizeof(kml_filename),
+        "%s/snapshot.kml",
+        temp_base_dir);
+
+
+    // Create a .geo file to match the new png image
+    // Likewise for a matching .kml file
+    f = fopen(geo_filename,"w");    // Overwrite whatever file
+                                        // is there.
+    fk = fopen(kml_filename,"w"); 
+
+    if (f == NULL || fk == NULL) {
+        if (f==NULL) 
+           fprintf(stderr,"Couldn't open %s\n",geo_filename);
+        if (fk==NULL) 
+           fprintf(stderr,"Couldn't open %s\n",kml_filename);
+    }
+    else {
+        float lat1, long1, lat2, long2;
+
+
+        long1 = f_NW_corner_longitude;
+        lat1 = f_NW_corner_latitude;
+        long2 = f_SE_corner_longitude;
+        lat2 = f_SE_corner_latitude;
+
+        // FILENAME   world1.xpm
+        // #          x          y        lon         lat
+        // TIEPOINT   0          0        -180        90
+        // TIEPOINT   639        319      180         -90
+        // IMAGESIZE  640        320
+        // REFRESH    250
+
+        fprintf(f,"FILENAME     snapshot.png\n");
+        fprintf(f,"#            x       y        lon           lat\n");
+        fprintf(f,"TIEPOINT     0       0       %8.5f     %8.5f\n",
+            long1, lat1);
+        fprintf(f,"TIEPOINT     %-4d    %-4d    %8.5f     %8.5f\n",
+            (int)screen_width-1, (int)screen_height-1, long2, lat2);
+ 
+        fprintf(f,"IMAGESIZE    %-4d    %-4d\n",
+            (int)screen_width, (int)screen_height);
+        fprintf(f,"REFRESH      250\n");
+        fclose(f);
+
+        // Write a matching kml file that describes the location of the snapshot on
+        // the Earth's surface.
+        // Another kml file pointing to the location of this file with a networklinkcontrol element
+        // and an update element loaded into a kml application should be able to reload this file
+        // at regular intervals.
+        // See kml documentation of:
+        // <kml><NetworkLinkControl><linkName/><refreshMode/>
+        //
+        // <?xml version="1.0" encoding="UTF-8"?>
+        // <kml xmlns="http://earth.google.com/kml/2.1">
+        // <Document>
+        //   <NetworkLink>
+        //      <Link>
+        //        <href>http://www.example.com/cgi-bin/screenshot.kml</href>
+        //        <refreshMode>onExpire</refreshMode>
+        //      </Link>
+        //  </NetworkLink>
+        // </Document>
+        // </kml>
+        // 
+        // TODO: Calculate a suitable range and tilt for viewing the snapshot draped on the 
+        // underlying terrain.
+
+        fprintf(fk,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        fprintf(fk,"<kml xmlns=\"http://earth.google.com/kml/2.2\">\n");
+        // Add an expire time matching the time when the next snapshot should
+        // be produced, so that a network link with an onExpire refresh mode
+        // will check for the next snapshot. 
+        expire_time = sec_now() + (time_t)(snapshot_interval * 60); 
+        if (get_w3cdtf_datetime(expire_time, timestring, False, False)) {  
+              if (strlen(timestring) > 0) {
+                  fprintf(fk,"  <NetworkLinkControl>\n");
+                  fprintf(fk,"     <expires>%s</expires>\n",timestring);
+                  fprintf(fk,"  </NetworkLinkControl>\n");
+              }
+        }
+        fprintf(fk,"  <Document>\n");
+        fprintf(fk,"    <name>XASTIR Snapshot from %s</name>\n",my_callsign);
+        fprintf(fk,"    <open>1</open>\n");
+        fprintf(fk,"    <GroundOverlay>\n");
+        fprintf(fk,"      <name>Xastir snapshot</name>\n");
+        fprintf(fk,"      <visibility>1</visibility>\n");
+        // timestamp the overlay with the current time
+        if (get_w3cdtf_datetime(sec_now(), timestring, True, True)) {  
+              if (strlen(timestring) > 0) {
+                  fprintf(fk,"      <TimeStamp><when>%s</when></TimeStamp>\n",timestring);
+                  fprintf(fk,"      <description>Overlay shows screen visible for %s in Xastir at %s.</description>\n",my_callsign,timestring);
+              }
+        } else { 
+           fprintf(fk,"      <description>Overlay shows screen visible for %s in Xastir.</description>\n",my_callsign);
+        }
+        fprintf(fk,"      <LookAt>\n");
+        fprintf(fk,"        <longitude>%8.5f</longitude>\n",f_center_longitude);
+        fprintf(fk,"        <latitude>%8.5f</latitude>\n",f_center_latitude);
+        fprintf(fk,"        <altitude>0</altitude>\n");
+        fprintf(fk,"        <range>30350.36838438907</range>\n");  // range in meters from viewer to lookat point
+        fprintf(fk,"        <tilt>0</tilt>\n");  // 0 is looking straight down
+        fprintf(fk,"        <altitudeMode>clampToGround</altitudeMode>\n");  
+        fprintf(fk,"        <heading>0</heading>\n");  // 0 is north at top, 90 east at top
+        fprintf(fk,"      </LookAt>\n");
+        fprintf(fk,"      <Icon>\n");
+        fprintf(fk,"        <href>snapshot.png</href>\n");
+        fprintf(fk,"      </Icon>\n");
+        fprintf(fk,"      <LatLonBox>\n");
+        fprintf(fk,"        <north>%8.5f</north>\n",lat1);
+        fprintf(fk,"        <south>%8.5f</south>\n",lat2);
+        fprintf(fk,"        <east>%8.5f</east>\n",long2);
+        fprintf(fk,"        <west>%8.5f</west>\n",long1);
+        fprintf(fk,"        <rotation>0</rotation>\n");
+        fprintf(fk,"      </LatLonBox>\n");
+        fprintf(fk,"    </GroundOverlay>\n");
+        fprintf(fk,"  </Document>\n");
+        fprintf(fk,"</kml>\n");
+
+        fclose(fk);
+
+        chmod( geo_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+        chmod( kml_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+    }
+
+
+    if ( debug_level & 512 )
+        fprintf(stderr,"Convert %s ==> %s\n", xpm_filename, png_filename );
+
+
+#ifdef HAVE_CONVERT
+    // Convert it to a png file.  This depends upon having the
+    // ImageMagick command "convert" installed.
+    xastir_snprintf(command,
+        sizeof(command),
+        "%s -quality 100 -colors 256 %s %s",
+        CONVERT_PATH,
+        xpm_filename,
+        png_filename );
+
+    if ( system( command ) != 0 ) {
+        // We _may_ have had an error.  Check errno to make
+        // sure.
+        if (errno) {
+            fprintf(stderr, "%s\n", strerror(errno));
+            fprintf(stderr,
+                "Failed to convert snapshot: %s -> %s\n",
+                xpm_filename,
+                png_filename);
+        }
+        else {
+            fprintf(stderr,
+                "System call return error: convert: %s -> %s\n",
+                xpm_filename,
+                png_filename);
+        }
+    }
+    else {
+        chmod( png_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+
+//        // Delete temporary xpm file
+//        unlink( xpm_filename );
+
+        if ( debug_level & 512 )
+            fprintf(stderr,"  Done creating png.\n");
+    }
+
+#endif  // HAVE_CONVERT
+
+    // Signify that we're all done and that another snapshot can
+    // occur.
+    doing_snapshot = 0;
+
+    return(NULL);
+}
+#endif  // NO_XPM
+
+
+
+
+
+// Starts a separate thread that creates a png image from the
+// current displayed image.
+//
+void Snapshot(void) {
+#ifndef NO_XPM
+    pthread_t snapshot_thread_id;
+    char xpm_filename[MAX_FILENAME];
+    int xpmretval;
+#endif  // NO_XPM
+    char temp_base_dir[MAX_VALUE];
+
+    get_user_base_dir("tmp", temp_base_dir, sizeof(temp_base_dir));
+
+
+    // Check whether we're already doing a snapshot
+    if (doing_snapshot)
+        return;
+
+    // Time to take another snapshot?
+    // New snapshot interval based on slider in Configure Timing
+    // dialog (in minutes)
+    if (sec_now() < (last_snapshot + (snapshot_interval * 60)) )
+        return;
+
+    last_snapshot = sec_now(); // Set up timer for next time
+
+
+#ifndef NO_XPM
+
+    if (debug_level & 512)
+	    fprintf(stderr,"Taking Snapshot\n");
+
+    doing_snapshot++;
+
+    // Set up the XPM filename that we'll use
+    xastir_snprintf(xpm_filename,
+        sizeof(xpm_filename),
+        "%s/snapshot.xpm",
+        temp_base_dir);
+
+
+    if ( debug_level & 512 )
+        fprintf(stderr,"Creating %s\n", xpm_filename );
+
+    // Create an XPM file from pixmap_final.
+    chdir(temp_base_dir);
+    xpmretval=XpmWriteFileFromPixmap(XtDisplay(appshell),   // Display *display
+            "snapshot.xpm",                             // char *filename
+            pixmap_final,                               // Pixmap pixmap
+            (Pixmap)NULL,                               // Pixmap shapemask
+            NULL );
+
+    if (xpmretval != XpmSuccess) {
+        fprintf(stderr,"ERROR writing %s: %s\n", xpm_filename,
+            XpmGetErrorString(xpmretval));
+        return;
+    }
+
+    chmod( xpm_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+
+
+//----- Start New Thread -----
+
+    //
+    // Here we start a new thread.  We'll communicate with the main
+    // thread via global variables.  Use mutex locks if there might
+    // be a conflict as to when/how we're updating those variables.
+    //
+
+    if (pthread_create(&snapshot_thread_id, NULL, snapshot_thread, NULL)) {
+        fprintf(stderr,"Error creating snapshot thread\n");
+    }
+    else {
+        // We're off and running with the new thread!
+    }
+#endif  // NO_XPM
+}
+
+
+
+
+
+// Function to remove double-quote characters and spaces that occur
+// outside of the double-quote characters.
+void clean_string(char *input) {
+    char *i;
+    char *j;
+
+
+    //fprintf(stderr,"|%s|\t",input);
+
+    // Remove any double quote characters
+    i = index(input,'"');   // Find first quote character, if any
+
+    if (i != NULL) {
+        j = index(i+1,'"'); // Find second quote character, if any
+
+        if (j != NULL) {    // Found two quote characters
+            j[0] = '\0';    // Terminate the string at the 2nd quote
+            // Can't use strcpy here because it can't work with
+            // overlapping strings.  strcpy is a dangerous function
+            // anyway and shouldn't be used.
+            memmove(input, i+1, j-i);
+        }
+        else {  // We only found one quote character.  What to do?
+//            fprintf(stderr,"clean_string: Only one quote found!\n");
+        }
+    }
+    //fprintf(stderr,"|%s|\n",input);
+
+    // Remove leading/trailing spaces?
+}
+
+
+
+
+
+
+
+// Test map visibility (on screen)
+//
+// Input parameters are in Xastir coordinate system (fastest for us)
+// check_percentage:
+//      0 = don't check
+//      1 = check map size versus viewport scale.  Return 0 if map
+//      is too large/small (percentage-wise) to be displayed.
+//
+// Returns: MAP_NOT_VIS if map is _not_ visible
+//          MAP_IS_VIS if map _is_ visible
+//
+// Xastir Coordinate System:
+//
+//              0 (90 deg. or 90N)
+//
+// 0 (-180 deg. or 180W)      129,600,000 (180 deg. or 180E)
+//
+//          64,800,000 (-90 deg. or 90S)
+//
+// Note that we already have map_visible() and map_visible_lat_lon()
+// routines.
+//
+enum map_onscreen_enum map_onscreen(long left,
+                                    long right, 
+                                    long top, 
+                                    long bottom,
+                                    int check_percentage) {
+
+    enum map_onscreen_enum in_window = MAP_NOT_VIS;
+
+
+    if (map_visible((unsigned long)bottom,
+            (unsigned long)top,
+            (unsigned long)left,
+            (unsigned long)right)) {
+        in_window = MAP_IS_VIS;
+        //fprintf(stderr,"map_onscreen:Map is visible\n");
+    }
+
+
+#ifdef MAP_SCALE_CHECK
+    // Check whether map is too large/small for our current scale?
+    // Check whether the map extents are < XX% of viewscreen size
+    // (both directions), or viewscreen is > XX% of map extents
+    // (either direction).  This will knock out maps that are too
+    // large/small to be displayed at this zoom level.
+//WE7U
+    if (in_window && check_percentage) {
+        long map_x, map_y, view_x, view_y;
+        float percentage = 0.04;
+
+
+        map_x  = right - left;
+        if (map_x < 0)
+            map_x = 0;
+
+        map_y  = bottom - top;
+        if (map_y < 0)
+            map_y = 0;
+
+        view_x = max_NW_corner_longitude - NW_corner_longitude;
+        if (view_x < 0)
+            view_x = 0;
+
+        view_y = max_NW_corner_latitude - NW_corner_latitude;
+        if (view_y < 0)
+            view_y = 0;
+
+//fprintf(stderr,"\n map_x: %d\n", map_x);
+//fprintf(stderr," map_y: %d\n", map_y);
+//fprintf(stderr,"view_x: %d\n", view_x);
+//fprintf(stderr,"view_y: %d\n", view_y);
+
+        if ((map_x < (view_x * percentage )) && (map_y < (view_x * percentage))) {
+            in_window = 0;  // Send back "not-visible" flag
+fprintf(stderr,"map too small for view: %d%%\n",(int)(percentage * 100));
+        }
+
+//        if ((view_x < (map_x * percentage)) && (view_y < (map_x * percentage))) {
+//            in_window = 0;  // Send back "not-visible" flag
+//fprintf(stderr,"view too small for map: %d%%\n",(int)(percentage * 100));
+//        }
+
+    }
+#endif  // MAP_SCALE_CHECK
+ 
+    //fprintf(stderr,"map_onscreen returning %d\n", in_window);
+    return (in_window);
+}
+
+
+
+
+
+// Function which checks whether a map is onscreen, but does so by
+// finding the map boundaries from the map index.  The only input
+// parameter is the complete path/filename.
+//
+// Returns: MAP_NOT_VIS if map is _not_ visible
+//          MAP_IS_VIS if map _is_ visible
+//          MAP_NOT_INDEXED if the map is not in the index
+//
+enum map_onscreen_enum map_onscreen_index(char *filename) {
+    unsigned long top, bottom, left, right;
+    enum map_onscreen_enum onscreen = MAP_NOT_INDEXED;
+    int max_zoom, min_zoom;
+    int map_layer, draw_filled, usgs_drg, auto_maps; // Unused in this function
+
+
+    if (index_retrieve(filename, &bottom, &top, &left, &right,
+                       &max_zoom, &min_zoom, &map_layer, 
+                       &draw_filled, &usgs_drg, &auto_maps) ) {
+
+        //fprintf(stderr, "Map found in index: %s\n", filename);
+
+        // Map was in the index, check for visibility and scale
+        // Check whether the map extents are < XX% of viewscreen
+        // size (both directions), or viewscreen is > XX% of map
+        // extents (either direction).  This will knock out maps
+        // that are too large/small to be displayed at this zoom
+        // level.
+        if (map_onscreen(left, right, top, bottom, 1)) {
+
+            //fprintf(stderr, "Map found in index and onscreen: %s\n", filename);
+
+            if (((max_zoom == 0) || 
+                 ((max_zoom != 0) && (scale_y <= max_zoom))) && 
+                ((min_zoom == 0) || 
+                 ((min_zoom != 0) && (scale_y >= min_zoom)))) {
+
+                onscreen = MAP_IS_VIS;
+                //fprintf(stderr,"Map in the zoom zone: %s\n",filename);
+            }
+            else {
+                onscreen = MAP_NOT_VIS;
+                //fprintf(stderr,"Map not in the zoom zone: %s\n",filename);
+            }
+
+// Check whether the map extents are < XX% of viewscreen size (both
+// directions), or viewscreen is > XX% of map extents (either
+// direction).  This will knock out maps that are too large/small to
+// be displayed at this zoom level.
+
+
+        }
+        else {  // Map is not visible
+            onscreen = MAP_NOT_VIS;
+            //fprintf(stderr,"Map found in index but not onscreen: %s\n",filename);
+        }
+    }
+    else {  // Map is not in the index
+        onscreen = MAP_NOT_INDEXED;
+        //fprintf(stderr,"Map not found in index: %s\n",filename);
+    }
+    return(onscreen);
+}
+ 
+
+
+
+
+/**********************************************************
+ * draw_map()
+ *
+ * Function which tries to figure out what type of map or
+ * image file we're dealing with, and takes care of getting
+ * it onto the screen.  Calls other functions to deal with
+ * .geo/.tif/.shp maps.
+ *
+ * If destination_pixmap == DRAW_NOT, then we'll not draw
+ * the map anywhere, but we'll determine the map extents
+ * and write them to the map index file.
+ **********************************************************/
+/* table of map drivers, selected by filename extension */
+extern void draw_dos_map(Widget w,
+                         char *dir,
+                         char *filenm,
+                         alert_entry *alert,
+                         u_char alert_color,
+                         int destination_pixmap,
+                         map_draw_flags *draw_flags);
+
+extern void draw_palm_image_map(Widget w,
+                         char *dir,
+                         char *filenm,
+                         alert_entry *alert,
+                         u_char alert_color,
+                         int destination_pixmap,
+                         map_draw_flags *draw_flags);
+
+#ifdef HAVE_LIBSHP
+extern void draw_shapefile_map (Widget w, 
+                                char *dir, 
+                                char *filenm, 
+                                alert_entry *alert,
+                                u_char alert_color, 
+                                int destination_pixmap,
+                                map_draw_flags *draw_flags);
+#ifdef WITH_DBFAWK
+extern void clear_dbfawk_sigs(void);
+#endif /* WITH_DBFAWK */
+#endif /* HAVE_LIBSHP */
+#ifdef HAVE_LIBGEOTIFF
+extern void draw_geotiff_image_map(Widget w,
+                                   char *dir,
+                                   char *filenm,
+                                   alert_entry *alert,
+                                   u_char alert_color,
+                                   int destination_pixmap,
+                                   map_draw_flags *draw_flags);
+#endif /* HAVE_LIBGEOTIFF */
+extern void draw_geo_image_map(Widget w,
+                               char *dir,
+                               char *filenm,
+                               alert_entry *alert,
+                               u_char alert_color,
+                               int destination_pixmap,
+                               map_draw_flags *draw_flags);
+
+extern void draw_gnis_map(Widget w,
+                          char *dir,
+                          char *filenm,
+                          alert_entry *alert,
+                          u_char alert_color,
+                          int destination_pixmap,
+                          map_draw_flags *draw_flags);
+
+extern void draw_pop_map(Widget w,
+                          char *dir,
+                          char *filenm,
+                          alert_entry *alert,
+                          u_char alert_color,
+                          int destination_pixmap,
+                          map_draw_flags *draw_flags);
+
+#ifdef HAVE_LIBGDAL
+extern void draw_gdal_map(Widget w,
+                   char *dir,
+                   char *filenm,
+                   alert_entry *alert,
+                   u_char alert_color,
+                   int destination_pixmap,
+                   map_draw_flags *draw_flags);
+
+extern void draw_ogr_map(Widget w,
+                   char *dir,
+                   char *filenm,
+                   alert_entry *alert,
+                   u_char alert_color,
+                   int destination_pixmap,
+                   map_draw_flags *draw_flags);
+#endif /* HAVE_LIBGDAL */
+
+struct {
+    char *ext;
+    enum {none=0, map, pdb, tif, geo, gnis, shp, tiger, mapinfo, dgn, sdts, s57, pop} type;
+    void (*func)(Widget w,
+               char *dir,
+               char *filenm,
+               alert_entry *alert,
+               u_char alert_color,
+               int destination_pixmap,
+               map_draw_flags *draw_flags);
+} map_driver[] = {
+  {"map",map,draw_dos_map},
+  {"pdb",pdb,draw_palm_image_map},
+
+#ifdef HAVE_LIBGEOTIFF
+  {"tif",tif,draw_geotiff_image_map},
+#endif /* HAVE_LIBGEOTIFF */
+
+  {"geo",geo,draw_geo_image_map},
+  {"gnis",gnis,draw_gnis_map},
+  {"pop",pop,draw_pop_map},
+
+#ifdef HAVE_LIBSHP
+#ifndef GDAL_SHAPEFILES
+  {"shp",shp,draw_shapefile_map},
+#endif  // GDAL_SHAPEFILES
+#endif /* HAVE_LIBSHP */
+
+#ifdef HAVE_LIBGDAL
+
+#ifdef GDAL_SHAPEFILES
+  {"shp",shp,draw_ogr_map},
+#endif  // GDAL_SHAPEFILES
+
+  {"rt1",tiger,draw_ogr_map},
+//  {"rt2",tiger,draw_ogr_map},
+//  {"rt4",tiger,draw_ogr_map},
+//  {"rt5",tiger,draw_ogr_map},
+//  {"rt6",tiger,draw_ogr_map},
+//  {"rt7",tiger,draw_ogr_map},
+//  {"rt8",tiger,draw_ogr_map},
+//  {"rta",tiger,draw_ogr_map},
+//  {"rtc",tiger,draw_ogr_map},
+//  {"rth",tiger,draw_ogr_map},
+//  {"rti",tiger,draw_ogr_map},
+//  {"rtp",tiger,draw_ogr_map},
+//  {"rtr",tiger,draw_ogr_map},
+//  {"rts",tiger,draw_ogr_map},
+//  {"rtt",tiger,draw_ogr_map},
+//  {"rtz",tiger,draw_ogr_map},
+  {"tab",mapinfo,draw_ogr_map}, // MapInfo
+  {"mid",mapinfo,draw_ogr_map}, // MapInfo
+  {"mif",mapinfo,draw_ogr_map}, // MapInfo
+  {"dgn",dgn,draw_ogr_map},     // DGN
+  {"ddf",sdts,draw_ogr_map},    // SDTS
+  {"s57",s57,draw_ogr_map},     // S57
+#endif  // HAVE_LIBGDAL
+
+  {NULL,none,NULL}
+}, *map_driver_ptr;
+
+
+
+
+
+void draw_map (Widget w, char *dir, char *filenm, alert_entry *alert,
+                u_char alert_color, int destination_pixmap,
+                map_draw_flags *draw_flags) {
+  enum map_onscreen_enum onscreen;
+  char *ext;
+  char file[MAX_FILENAME];
+
+    if ((ext = get_map_ext(filenm)) == NULL)
+      return;
+
+    if (debug_level & 16)
+        fprintf(stderr,"draw_map: Searching for map driver\n");
+
+    for (map_driver_ptr = map_driver; map_driver_ptr->ext; map_driver_ptr++) {
+        if (strcasecmp(ext,map_driver_ptr->ext) == 0) {
+            if (debug_level & 16)
+                fprintf(stderr,
+                    "draw_map: Found map driver: %s: %d\n",
+                    ext,
+                    map_driver_ptr->type);
+            break;			/* found our map_driver */
+        }
+    }
+    if (map_driver_ptr->type == none) {    /* fall thru: unknown map driver */
+        // Check whether we're indexing or drawing the map
+        if ( (destination_pixmap != INDEX_CHECK_TIMESTAMPS)
+	            && (destination_pixmap != INDEX_NO_TIMESTAMPS) ) {
+	        // We're drawing, not indexing.  Output a warning
+	        // message.
+	        fprintf(stderr,"*** draw_map: Unknown map type: %s ***\n", filenm);
+        }
+        else {  // We're indexing
+            if (debug_level & 16)
+                fprintf(stderr,"draw_map: No map driver found\n");
+        }
+        return;
+    }
+
+    onscreen = map_onscreen_index(filenm); // Check map index
+
+    // Check whether we're indexing or drawing the map
+    if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+            || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+
+        // We're indexing maps
+        if (onscreen != MAP_NOT_INDEXED) // We already have an index entry for this map.
+            // This is where we pick up a big speed increase:
+            // Refusing to index a map that's already indexed.
+            return; // Skip it.
+    }
+    else {  // We're drawing maps
+        // See if map is visible.  If not, skip it.
+        if (onscreen == MAP_NOT_VIS) {  // Map is not visible, skip it.
+            //fprintf(stderr,"map not visible\n");
+	    if (alert) alert->flags[on_screen] = 'N';
+            return;
+        }
+    }
+
+
+    xastir_snprintf(file, sizeof(file), "%s/%s", dir, filenm);
+
+    // Used for debugging.  If we get a segfault on a map, this is
+    // often the only way of finding out which map file we can't
+    // handle.
+    if (debug_level & 16)
+        fprintf(stderr,"draw_map: %s\n",file);
+
+    /* XXX - aren't alerts just shp maps?  Why was there special case code? */
+    
+    if (map_driver_ptr->func) {
+        map_driver_ptr->func(w,
+                             dir,
+                             filenm,
+                             alert,
+                             alert_color,
+                             destination_pixmap,
+                             draw_flags);
+    }
+        
+    XmUpdateDisplay (XtParent (da));
+}  // End of draw_map()
+
+
+
+
+
+static void index_update_directory(char *directory);
+static void index_update_accessed(char *filename);
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+// map_search()
+//
+// Function which recurses through map directories, finding map
+// files.  It's called from load_auto_maps and load_alert_maps.  If
+// a map file is found, it is drawn.  We can also call this function
+// in indexing mode rather than draw mode, specified by the
+// destination_pixmap parameter.
+//
+// If alert == NULL, we looking for a regular map file to draw.
+// If alert != NULL, we have a weather alert to draw.
+//
+// For alert maps, we need to do things a bit differently, as there
+// should be only a few maps that contain all of the alert maps, and we
+// can compute which map some of them might be in.  We need to fill in
+// the alert structure with the filename that alert is found in.
+// For alerts we're not drawing the maps, we're just computing the
+// full filename for the alert and filling that struct field in.
+//
+// The "warn" parameter specifies whether to warn the operator about
+// the alert on the console as well.  If it was received locally or
+// via local RF, then the answer is yes.  The severe weather may be
+// nearby.
+//
+// We have the timestamp of the map_index.sys file stored away in
+// the global:  time_t map_index_timestamp;
+// Use that timestamp to compare the map file or GEO file timestamps
+// to.  Re-index the map if map_index_timestamp is older.
+//
+/////////////////////////////////////////////////////////////////////
+static void map_search (Widget w, char *dir, alert_entry * alert, int *alert_count,int warn, int destination_pixmap) {
+    struct dirent *dl = NULL;
+    DIR *dm;
+    char fullpath[MAX_FILENAME];
+    struct stat nfile;
+//    const time_t *ftime;
+//    char this_time[40];
+    char *ptr;
+    char *map_dir;
+    int map_dir_length;
+    map_draw_flags mdf;
+
+    // We'll use the weather alert directory if it's an alert
+    map_dir = alert ? ALERT_MAP_DIR : SELECTED_MAP_DIR;
+
+    map_dir_length = (int)strlen (map_dir);
+
+    if (alert) {    // We're doing weather alerts
+        // First check whether the alert->filename variable is filled
+        // in.  If so, we've already found the file and can just display
+        // that shape in the file
+        if (alert->filename[0] == '\0') {   // No filename in struct, so will have
+                                            // to search for the shape in the files.
+            switch (alert->title[3]) {
+                case 'F':   // 'F' in 4th char means fire alert
+                    // Use fire alert file fz_??????
+                    //fprintf(stderr,"%c:Fire Alert file\n",alert->title[3]);
+                    xastir_snprintf(alert->filename,
+                        sizeof(alert->filename),
+                        "fz");
+                    break;
+ 
+                case 'C':   // 'C' in 4th char means county
+                    // Use County file c_??????
+                    //fprintf(stderr,"%c:County file\n",alert->title[3]);
+                    xastir_snprintf(alert->filename,
+                        sizeof(alert->filename),
+                        "c_");
+                    break;
+                case 'A':   // 'A' in 4th char means county warning area
+                    // Use County warning area w_?????
+                    //fprintf(stderr,"%c:County warning area file\n",alert->title[3]);
+                    xastir_snprintf(alert->filename,
+                        sizeof(alert->filename),
+                        "w_");
+                    break;
+                case 'Z':
+                    // Zone, coastal or offshore marine zone file z_????? or mz?????? or oz??????
+                    // oz: ANZ081-086,088,PZZ081-085
+                    // mz: AM,AN,GM,LC,LE,LH,LM,LO,LS,PH,PK,PM,PS,PZ,SL
+                    // z_: All others
+                    if (strncasecmp(alert->title,"AM",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"AN",2) == 0) {
+                        // Need to check for Z081-Z086, Z088, if so use
+                        // oz??????, else use mz??????
+                        if (       (strncasecmp(&alert->title[3],"Z081",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z082",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z083",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z084",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z085",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z086",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z088",4) == 0) ) {
+                            //fprintf(stderr,"%c:Offshore marine zone file\n",alert->title[3]);
+                            xastir_snprintf(alert->filename,
+                                sizeof(alert->filename),
+                                "oz");
+                        }
+                        else {
+                            //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                            xastir_snprintf(alert->filename,
+                                sizeof(alert->filename),
+                                "mz");
+                        }
+                    }
+                    else if (strncasecmp(alert->title,"GM",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"LC",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"LE",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"LH",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"LM",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"LO",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"LS",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"PH",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"PK",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"PM",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"PS",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else if (strncasecmp(alert->title,"PZ",2) == 0) {
+// Need to check for PZZ081-085, if so use oz??????, else use mz??????
+                        if (       (strncasecmp(&alert->title[3],"Z081",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z082",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z083",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z084",4) == 0)
+                                || (strncasecmp(&alert->title[3],"Z085",4) == 0) ) {
+                            //fprintf(stderr,"%c:Offshore marine zone file\n",alert->title[3]);
+                            xastir_snprintf(alert->filename,
+                                sizeof(alert->filename),
+                                "oz");
+                        }
+                        else {
+                            //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                            xastir_snprintf(alert->filename,
+                                sizeof(alert->filename),
+                                "mz");
+                        }
+                    }
+                    else if (strncasecmp(alert->title,"SL",2) == 0) {
+                        //fprintf(stderr,"%c:Coastal marine zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "mz");
+                    }
+                    else {
+                        // Must be regular zone file instead of coastal
+                        // marine zone or offshore marine zone.
+                        //fprintf(stderr,"%c:Zone file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "z_");
+                    }
+                    break;
+               
+                default:
+// VK2XJG
+// This section could most likely be moved so that it's not called as part of the default, but in order
+// to get the shapefiles for BOM working this was the best spot at the time...
+                    // Australian BOM alerts use the following shapefiles:
+                    // PW = Public Warning = gfe_public_weather
+                    // MW = Coastal Waters = gfe_coastal_waters
+                    // CW = Coastal Waters Warnings = gfe_coastal_waters_warnings
+                    // FW = Fire Weather = gfe_fire_weather
+                    // ME = Metro Effects = gfe_metro_areas
+                    // Note - Need to cater for both 2 and 3 character state designators
+                    // Shapefile filenames are static - there is no datestamp in the filename.
+                    if ((strncasecmp(&alert->title[4],"MW",2) == 0) || (strncasecmp(&alert->title[3],"MW",2) == 0)) {
+                        //fprintf(stderr,"%c:BOM Coastal Waters file\n",alert->title[4]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "gfe_coastal_waters.shp");
+                    }
+                    else if ((strncasecmp(&alert->title[4],"CW",2) == 0) || (strncasecmp(&alert->title[3],"CW",2) == 0)) {
+                        //fprintf(stderr,"%c:BOM Coastal waters warning file\n",alert->title[3]);
+                        xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "gfe_coastal_waters_warnings.shp");
+                    }
+                    else if ((strncasecmp(&alert->title[4],"PW",2) == 0) || (strncasecmp(&alert->title[3],"PW",2) == 0)) {
+                        //fprintf(stderr,"%c:BOM Public Weather file\n",alert->title[3]);
+                         xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "gfe_public_weather.shp");
+                    }
+                    else if ((strncasecmp(&alert->title[4],"FW",2) == 0) || (strncasecmp(&alert->title[3],"FW",2) == 0)) {
+                        //fprintf(stderr,"%c:BOM Fire Weather file\n",alert->title[3]);
+                         xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "gfe_fire_weather.shp");
+                    }
+                    else if ((strncasecmp(&alert->title[4],"ME",2) == 0) || (strncasecmp(&alert->title[3],"ME",2) == 0)) {
+                        //fprintf(stderr,"%c:BOM Metro Areas file\n",alert->title[3]);
+                         xastir_snprintf(alert->filename,
+                            sizeof(alert->filename),
+                            "gfe_metro_areas.shp");
+                    }
+
+
+                    
+                    // Unknown type
+//fprintf(stderr,"%c:Can't match weather warning to a Shapefile:%s\n",alert->title[3],alert->title);
+                    break;
+            }
+//            fprintf(stderr,"%s\t%s\t%s\n",alert->activity,alert->alert_status,alert->title);
+            //fprintf(stderr,"File: %s\n",alert->filename);
+        }
+
+// NOTE:  Need to skip this part if we have a full filename.
+
+        if (alert->filename[0]) {   // We have at least a partial filename
+            int done = 0;
+
+            if (strlen(alert->filename) > 3)
+                done++; // We already have a filename
+
+            if (!done) {    // We don't have a filename yet
+
+                // Look through the warning directory to find a match for
+                // the first few characters that we already figured out.
+                // This is designed so that we don't need to know the exact
+                // filename, but only the lead three characters in order to
+                // figure out which shapefile to use.
+                dm = opendir (dir);
+                if (!dm) {  // Couldn't open directory
+                    xastir_snprintf(fullpath, sizeof(fullpath), "aprsmap %s", dir);
+                    // If local alert, warn the operator via the
+                    // console as well.
+                    if (warn)
+                        perror (fullpath);
+                }
+                else {    // We could open the directory just fine
+                    while ( (dl = readdir(dm)) && !done ) {
+                        int i;
+
+                        // Check the file/directory name for control
+                        // characters
+                        for (i = 0; i < (int)strlen(dl->d_name); i++) {
+                            // Dump out a warning if control
+                            // characters other than LF or CR are
+                            // found.
+                            if ( (dl->d_name[i] != '\n')
+                                    && (dl->d_name[i] != '\r')
+                                    && (dl->d_name[i] < 0x20) ) {
+
+                                fprintf(stderr,"\nmap_search: Found control char 0x%02x in alert file/alert directory name.  Line was:\n",
+                                    dl->d_name[i]);
+                                fprintf(stderr,"%s\n",dl->d_name);
+                            }
+/*
+// This part might not work 'cuz we'd be changing a memory area that
+// we might have only read access to.  Check this.
+                            if (dl->d_name[i] < 0x20) {
+                                // Terminate string at any control character
+                                dl->d_name[i] = '\0';
+                            }
+*/
+                        }
+
+                        xastir_snprintf(fullpath, sizeof(fullpath), "%s%s", dir, dl->d_name);
+                        /*fprintf(stderr,"FULL PATH %s\n",fullpath); */
+                        if (stat (fullpath, &nfile) == 0) {
+//                            ftime = (time_t *)&nfile.st_ctime;
+                            switch (nfile.st_mode & S_IFMT) {
+                                case (S_IFDIR):     // It's a directory, skip it
+                                    break;
+
+                                case (S_IFREG):     // It's a file, check it
+                                    /*fprintf(stderr,"FILE %s\n",dl->d_name); */
+                                    // Here we look for a match for the
+                                    // first 2 characters of the filename.
+                                    // 
+                                    if (strncasecmp(alert->filename,dl->d_name,2) == 0) {
+                                        // We have a match for the
+                                        // first few characters.
+                                        // Check that last three are
+                                        // "shp"
+
+                                        //fprintf(stderr,"%s\n",fullpath);
+
+                                        if ( (dl->d_name[strlen(dl->d_name)-3] == 's'
+                                                || dl->d_name[strlen(dl->d_name)-3] == 'S')
+                                            && (dl->d_name[strlen(dl->d_name)-2] == 'h'
+                                                || dl->d_name[strlen(dl->d_name)-2] == 'H')
+                                            && (dl->d_name[strlen(dl->d_name)-1] == 'p'
+                                                || dl->d_name[strlen(dl->d_name)-1] == 'P') ) {
+                                            // We have an exact match.
+                                            // Save the filename in the alert
+                                            xastir_snprintf(alert->filename,
+                                                sizeof(alert->filename),
+                                                "%s",
+                                                dl->d_name);
+                                            done++;
+                                            //fprintf(stderr,"%s\n",dl->d_name);
+                                        }
+                                    }
+                                    break;
+
+                                default:    // Not dir or file, skip it
+                                    break;
+                            }
+                        }
+                    }
+                }
+                (void)closedir (dm);
+            }
+
+            if (done) {    // We found a filename match for the alert
+                // Go draw the weather alert (kind'a)
+//WE7U
+                mdf.draw_filled=1;
+                mdf.usgs_drg=0;
+
+                if (debug_level & 16)
+                    fprintf(stderr,"map_search: calling draw_map for an alert\n");
+
+                draw_map (w,
+                    dir,                // Alert directory
+                    alert->filename,    // Shapefile filename
+                    alert,
+                    -1,                 // Signifies "DON'T DRAW THE SHAPE"
+                    destination_pixmap,
+                    &mdf );
+
+                if (debug_level & 16)
+                    fprintf(stderr,"map_search: returned from draw_map\n");
+
+            }
+            else {      // No filename found that matches the first two
+                        // characters that we already computed.
+
+                //
+                // Need code here
+                //
+
+            }
+        }
+        else {  // Still no filename for the weather alert.
+                // Output an error message?
+            //
+            // Need code here
+            //
+
+        }
+    }
+
+
+// MAPS, not alerts
+
+    else {  // We're doing regular maps, not weather alerts
+        time_t map_timestamp;
+
+
+        dm = opendir (dir);
+        if (!dm) {  // Couldn't open directory
+            xastir_snprintf(fullpath, sizeof(fullpath), "aprsmap %s", dir);
+            if (warn)
+                perror (fullpath);
+        }
+        else {
+            int count = 0;
+            while ((dl = readdir (dm))) {
+                int i;
+
+                // Check the file/directory name for control
+                // characters
+                for (i = 0; i < (int)strlen(dl->d_name); i++) {
+                    // Dump out a warning if control characters
+                    // other than LF or CR are found.
+                    if ( (dl->d_name[i] != '\n')
+                            && (dl->d_name[i] != '\r')
+                            && (dl->d_name[i] < 0x20) ) {
+
+                        fprintf(stderr,"\nmap_search: Found control char 0x%02x in map file/map directory name.  Line was:\n",
+                            dl->d_name[i]);
+                        fprintf(stderr,"%s\n",dl->d_name);
+                    }
+/*
+// This part might not work 'cuz we'd be changing a memory area that
+// we might have only read access to.  Check this.
+                    if (dl->d_name[i] < 0x20) {
+                        // Terminate string at any control character
+                        dl->d_name[i] = '\0';
+                    }
+*/
+                }
+
+                xastir_snprintf(fullpath, sizeof(fullpath), "%s/%s", dir, dl->d_name);
+                //fprintf(stderr,"FULL PATH %s\n",fullpath);
+                if (stat (fullpath, &nfile) == 0) {
+//                    ftime = (time_t *)&nfile.st_ctime;
+                    switch (nfile.st_mode & S_IFMT) {
+                        case (S_IFDIR):     // It's a directory, recurse
+                            //fprintf(stderr,"file %c letter %c\n",dl->d_name[0],letter);
+                            if ((strcmp (dl->d_name, ".") != 0) && (strcmp (dl->d_name, "..") != 0)) {
+
+                                //fprintf(stderr,"FULL PATH %s\n",fullpath);
+
+                                // If we're indexing, throw the
+                                // directory into the map index as
+                                // well.
+                                if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                                        || (destination_pixmap == INDEX_NO_TIMESTAMPS) ) {
+                                    char temp_dir[MAX_FILENAME];
+
+                                    // Drop off the base part of the
+                                    // path for the indexing,
+                                    // usually
+                                    // "/usr/local/share/xastir/maps".
+                                    // Add a '/' to the end.
+                                    xastir_snprintf(temp_dir,
+                                        sizeof(temp_dir),
+                                        "%s/",
+                                        &fullpath[map_dir_length+1]);
+
+                                    // Add the directory to the
+                                    // in-memory map index.
+                                    index_update_directory(temp_dir);
+                                }
+
+//                                xastir_snprintf(this_time,
+//                                    sizeof(this_time),
+//                                    "%s",
+//                                    ctime(ftime));
+                                map_search(w, fullpath, alert, alert_count, warn, destination_pixmap);
+                            }
+                            break;
+
+                        case (S_IFREG):     // It's a file, draw the map
+                            /*fprintf(stderr,"FILE %s\n",dl->d_name); */
+
+                            // Get the last-modified timestamp for the map file
+                            //map_timestamp = (time_t)nfile.st_mtime;
+                            map_timestamp =
+                                (time_t)( (nfile.st_mtime>nfile.st_ctime) ? nfile.st_mtime : nfile.st_ctime );
+
+
+                            // Check whether we're doing indexing or
+                            // map drawing.  If indexing, we only
+                            // want to index if the map timestamp is
+                            // newer than the index timestamp.
+                            if (destination_pixmap == INDEX_CHECK_TIMESTAMPS
+                                    || destination_pixmap == INDEX_NO_TIMESTAMPS) {
+                                // We're doing indexing, not map drawing
+                                char temp_dir[MAX_FILENAME];
+
+                                // Drop off the base part of the
+                                // path for the indexing, usually
+                                // "/usr/local/share/xastir/maps".
+                                xastir_snprintf(temp_dir,
+                                    sizeof(temp_dir),
+                                    "%s",
+                                    &fullpath[map_dir_length+1]);
+
+                                // Update the "accessed"
+                                // variable in the record
+                                index_update_accessed(temp_dir);
+
+// Note:  This is not as efficient as it should be, as we're looking
+// through the in-memory map index here just to update the
+// "accessed" variable, then in some cases looking through it again
+// in the next section for updated maps, or if we're ignoring
+// timestamps while indexing.  Looking through a linear linked list
+// too many times overall.
+
+                                if ( (destination_pixmap == INDEX_CHECK_TIMESTAMPS)
+                                        && (map_timestamp < map_index_timestamp) ) {
+                                    // Map is older than index _and_
+                                    // we're supposed to check
+                                    // timestamps.
+                                    count++;
+                                    break;  // Skip indexing this file
+                                }
+                                else {  // Map is newer or we're ignoring timestamps.
+                                    // We'll index the map
+                                    if (debug_level & 16) {
+                                        fprintf(stderr,"Indexing map: %s\n",fullpath);
+                                    }
+                                }
+                            }
+
+                            // Check whether the file is in a subdirectory
+                            if (strncmp (fullpath, map_dir, (size_t)map_dir_length) != 0) {
+
+                                if (debug_level & 16) {
+                                    fprintf(stderr,"Calling draw_map\n");
+                                }
+                                mdf.draw_filled=1;
+                                mdf.usgs_drg=0;
+
+                                draw_map (w,
+                                    dir,
+                                    dl->d_name,
+                                    alert ? &alert[*alert_count] : NULL,
+                                    '\0',
+                                    destination_pixmap,
+                                    &mdf );
+
+                                if (debug_level & 16) {
+                                    fprintf(stderr,"Returned from draw_map\n");
+                                }
+                                if (alert_count && *alert_count)
+                                    (*alert_count)--;
+                            }
+                            else {
+                                // File is in the main map directory
+                                // Find the '/' character
+                                for (ptr = &fullpath[map_dir_length]; *ptr == '/'; ptr++) ;
+                                mdf.draw_filled=1;
+                                mdf.usgs_drg=0;
+
+                                if (debug_level & 16)
+                                    fprintf(stderr,"Calling draw_map\n");
+
+                                draw_map (w,
+                                    map_dir,
+                                    ptr,
+                                    alert ? &alert[*alert_count] : NULL,
+                                    '\0',
+                                    destination_pixmap,
+                                    &mdf );
+
+                                if (alert_count && *alert_count)
+                                    (*alert_count)--;
+                            }
+                            count++;
+                            break;
+
+                        default:
+                            break;
+                    }
+                }
+            }
+            if (debug_level & 16)
+                fprintf(stderr,"Number of maps queried: %d\n", count);
+
+            (void)closedir (dm);
+        }
+    }
+}
+
+
+
+
+
+// List pointer for the map index linked list.
+map_index_record *map_index_head = NULL;
+
+// Might wish to have another variable in the index which is used to
+// record that a file has been indexed recently.  This could be used
+// to prune old entries out of the index if a full indexing didn't
+// touch a file entry.  Could also delete an entry from the index
+// if/when a file can't be opened?
+
+
+
+
+
+// Function to dissect and free all of the records in a map index
+// linked list, leaving it totally empty.
+//
+static void free_map_index(map_index_record *index_list_head) {
+    map_index_record *current;
+    map_index_record *temp;
+
+
+    current = index_list_head;
+
+    while (current != NULL) {
+        temp = current;
+        if (current->XmStringPtr != NULL) {
+            XmStringFree(current->XmStringPtr);
+        }
+        current = current->next;
+        free(temp);
+    }
+
+    index_list_head = NULL;
+}
+
+
+
+
+
+// Function to copy just the properties fields from the backup map
+// index to the primary index.  Must match each record before
+// copying.  Once it's done, it frees the backup map index.
+//
+static void map_index_copy_properties(map_index_record *primary_index_head,
+        map_index_record *backup_index_head) {
+    map_index_record *primary;
+    map_index_record *backup;
+
+
+    backup = backup_index_head;
+
+    // Walk the backup list, comparing the filename field with the
+    // primary list.  When a match is found, copy just the
+    // Properties fields (map_layer/draw_filled/auto_maps/selected)
+    // across to the primary record.
+    //
+    while (backup != NULL) {
+        int done = 0;
+
+        primary = primary_index_head;
+
+        while (!done && primary != NULL) {
+
+            if (strcmp(primary->filename, backup->filename) == 0) { // If match
+
+                if (debug_level & 16) {
+                    fprintf(stderr,"Match: %s\t%s\n",
+                        primary->filename,
+                        backup->filename);
+                }
+
+                // Copy the Properties across
+                primary->max_zoom    = backup->max_zoom;
+                primary->min_zoom    = backup->min_zoom;
+                primary->map_layer   = backup->map_layer;
+                primary->draw_filled = backup->draw_filled;
+                primary->usgs_drg    = backup->usgs_drg;
+                primary->auto_maps   = backup->auto_maps;
+                primary->selected    = backup->selected;
+
+                // Done copying this backup record.  Go on to the
+                // next.  Skip the rest of the primary list for this
+                // iteration.
+                done++;
+            }
+            else {  // No match, walk the primary list looking for one.
+                primary = primary->next;
+            }
+        }
+
+        // Walk the backup list
+        backup = backup->next;
+    }
+
+    // We're done copying.  Free the backup list.
+    free_map_index(backup_index_head);
+}
+
+
+
+
+
+// Function used to add map directories to the in-memory map index.
+// Causes an update of the index list in memory.  Input Records are
+// inserted in alphanumerical order.  We mark directories in the
+// index with a '/' on the end of the name, and zero entries for
+// top/bottom/left/right.
+// The input directory to this routine MUST have a '/' character on
+// the end of it.  This is how we differentiate directories from
+// files in the list.
+static void index_update_directory(char *directory) {
+
+    map_index_record *current = map_index_head;
+    map_index_record *previous = map_index_head;
+    map_index_record *temp_record = NULL;
+    int done = 0;
+    int i;
+
+
+    //fprintf(stderr,"index_update_directory: %s\n", directory );
+
+    // Check for initial bad input
+    if ( (directory == NULL)
+            || (directory[0] == '\0')
+            || (directory[strlen(directory) - 1] != '/')
+            || ( (directory[1] == '/') && (strlen(directory) == 1)) ) {
+        fprintf(stderr,"index_update_directory: Bad input: %s\n",directory);
+        return;
+    }
+    // Make sure there aren't any weird characters in the directory
+    // that might cause problems later.  Look for control characters
+    // and convert them to string-end characters.
+    for ( i = 0; i < (int)strlen(directory); i++ ) {
+        // Change any control characters to '\0' chars
+        if (directory[i] < 0x20) {
+
+            fprintf(stderr,"\nindex_update_directory: Found control char 0x%02x in map file/map directory name:\n%s\n",
+                directory[i],
+                directory);
+
+            directory[i] = '\0';    // Terminate it here
+        }
+    }
+    // Check if the string is _now_ bogus
+    if ( (directory[0] == '\0')
+            || (directory[strlen(directory) - 1] != '/')
+            || ( (directory[1] == '/') && (strlen(directory) == 1))) {
+        fprintf(stderr,"index_update_directory: Bad input: %s\n",directory);
+        return;
+    }
+
+    //if (map_index_head == NULL)
+    //    fprintf(stderr,"Empty list\n");
+
+    // Search for a matching directory name in the linked list
+    while ((current != NULL) && !done) {
+        int test;
+
+        //fprintf(stderr,"Comparing %s to\n          %s\n",
+        //    current->filename, directory);
+
+        test = strcmp(current->filename, directory);
+        if (test == 0) {
+            // Found a match!
+            //fprintf(stderr,"Found: Updating entry for %s\n",directory);
+            temp_record = current;
+            done++; // Exit loop, "current" points to found record
+        }
+        else if (test > 0) {    // Found a string past us in the
+                                // alphabet.  Insert ahead of this
+                                // last record.
+
+            //fprintf(stderr,"\n%s\n%s\n",current->filename,directory);
+
+            //fprintf(stderr,"Not Found: Inserting an index record for %s\n",directory);
+            temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+            CHECKMALLOC(temp_record);
+
+            if (current == map_index_head) {  // Start of list!
+                // Insert new record at head of list
+                temp_record->next = map_index_head;
+                map_index_head = temp_record;
+                //fprintf(stderr,"Inserting at head of list\n");
+            }
+            else {  // Insert between "previous" and "current"
+                // Insert new record before "current"
+                previous->next = temp_record;
+                temp_record->next = current;
+                //fprintf(stderr,"Inserting before current\n");
+            }
+
+            //fprintf(stderr,"Adding:%d:%s\n",strlen(directory),directory);
+ 
+            // Fill in some default values for the new record.
+            temp_record->selected = 0;
+            temp_record->auto_maps = 0;
+            temp_record->XmStringPtr = NULL;
+
+            //current = current->next;
+            done++;
+        }
+        else {  // Haven't gotten to the correct insertion point yet
+            previous = current; // Save ptr to last record
+            current = current->next;
+        }
+    }
+
+    if (!done) {    // Matching record not found, add a record to
+                    // the end of the list.  "previous" points to
+                    // the last record in the list or NULL (empty
+                    // list).
+        //fprintf(stderr,"Not Found: Adding an index record for %s\n",directory);
+        temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+        CHECKMALLOC(temp_record);
+
+        temp_record->next = NULL;
+
+        if (previous == NULL) { // Empty list
+            map_index_head = temp_record;
+            //fprintf(stderr,"First record in new list\n");
+        }
+        else {  // Else at end of list
+            previous->next = temp_record;
+            //fprintf(stderr,"Adding to end of list: %s\n",directory);
+        }
+
+        //fprintf(stderr,"Adding:%d:%s\n",strlen(directory),directory);
+ 
+        // Fill in some default values for the new record.
+        temp_record->selected = 0;
+        temp_record->auto_maps = 0;
+        temp_record->XmStringPtr = NULL;
+    }
+
+    // Update the values.  By this point we have a struct to fill
+    // in, whether it's a new or old struct doesn't matter.  Convert
+    // the values from lat/long to Xastir coordinate system.
+    xastir_snprintf(temp_record->filename,MAX_FILENAME,"%s",directory);
+
+    temp_record->bottom = 0;
+    temp_record->top = 0;
+    temp_record->left = 0;
+    temp_record->right = 0;
+    temp_record->accessed = 1;
+    temp_record->max_zoom = 0;
+    temp_record->min_zoom = 0;
+    temp_record->map_layer = 0;
+    temp_record->draw_filled = 0;
+    temp_record->usgs_drg = 2;
+}
+
+
+
+
+
+// Function called by the various draw_* functions when in indexing
+// mode.  Causes an update of the index list in memory.  Input
+// parameters are in the Xastir coordinate system due to speed
+// considerations.  Records are inserted in alphanumerical order.
+void index_update_xastir(char *filename,
+                  unsigned long bottom,
+                  unsigned long top,
+                  unsigned long left,
+                  unsigned long right,
+                  int default_map_layer) {
+
+    map_index_record *current = map_index_head;
+    map_index_record *previous = map_index_head;
+    map_index_record *temp_record = NULL;
+    int done = 0;
+    int i;
+
+
+    // Check for initial bad input
+    if ( (filename == NULL)
+            || (filename[0] == '\0')
+            || (filename[strlen(filename) - 1] == '/') ) {
+        fprintf(stderr,"index_update_xastir: Bad input: %s\n",filename);
+        return;
+    }
+    // Make sure there aren't any weird characters in the filename
+    // that might cause problems later.  Look for control characters
+    // and convert them to string-end characters.
+    for ( i = 0; i < (int)strlen(filename); i++ ) {
+        // Change any control characters to '\0' chars
+        if (filename[i] < 0x20) {
+
+            fprintf(stderr,"\nindex_update_xastir: Found control char 0x%02x in map file/map directory name:\n%s\n",
+                filename[i],
+                filename);
+
+            filename[i] = '\0';    // Terminate it here
+        }
+    }
+    // Check if the string is _now_ bogus
+    if (filename[0] == '\0') {
+        fprintf(stderr,"index_update_xastir: Bad input: %s\n",filename);
+        return;
+    }
+
+    //fprintf(stderr,"index_update_xastir: (%lu,%lu)\t(%lu,%lu)\t%s\n",
+    //    bottom, top, left, right, filename );
+
+    //if (map_index_head == NULL)
+    //    fprintf(stderr,"Empty list\n");
+
+    // Skip dbf and shx map extensions.  Really should make this
+    // case-independent...
+    if (       strstr(filename,"shx")
+            || strstr(filename,"dbf")
+            || strstr(filename,"SHX")
+            || strstr(filename,"DBF") ) {
+        return;
+    }
+
+    // Search for a matching filename in the linked list
+    while ((current != NULL) && !done) {
+        int test;
+
+        //fprintf(stderr,"Comparing %s to\n          %s\n",current->filename,filename);
+
+        test = strcmp(current->filename,filename);
+        if (test == 0) {
+            // Found a match!
+            //fprintf(stderr,"Found: Updating entry for %s\n",filename);
+            temp_record = current;
+            done++; // Exit the while loop
+        }
+        else if (test > 0) {    // Found a string past us in the
+                                // alphabet.  Insert ahead of this
+                                // last record.
+
+            //fprintf(stderr,"\n%s\n%s\n",current->filename,filename);
+
+            //fprintf(stderr,"Not Found: Inserting an index record for %s\n",filename);
+            temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+            CHECKMALLOC(temp_record);
+
+            if (current == map_index_head) {  // Start of list!
+                // Insert new record at head of list
+                temp_record->next = map_index_head;
+                map_index_head = temp_record;
+                //fprintf(stderr,"Inserting at head of list\n");
+            }
+            else {
+                // Insert new record before "current"
+                previous->next = temp_record;
+                temp_record->next = current;
+                //fprintf(stderr,"Inserting before current\n");
+            }
+
+            //fprintf(stderr,"Adding:%d:%s\n",strlen(filename),filename);
+
+            // Fill in some default values for the new record
+//WE7U
+// Here's where we might look at the file extension and assign
+// default map_layer fields based on that.
+            temp_record->max_zoom = 0;
+            temp_record->min_zoom = 0;
+            temp_record->map_layer = default_map_layer;
+            temp_record->selected = 0;
+            temp_record->XmStringPtr = NULL;
+ 
+            if (       strstr(filename,".geo")
+                    || strstr(filename,".GEO")
+                    || strstr(filename,".Geo")) {
+                temp_record->auto_maps = 0;
+            }
+            else {
+                temp_record->auto_maps = 1;
+            }
+
+            if (       strstr(filename,".shp")
+                    || strstr(filename,".SHP")
+                    || strstr(filename,".Shp") ) {
+                temp_record->draw_filled = 2; // Auto
+            }
+            else {
+                temp_record->draw_filled = 0; // No-Fill
+            }
+
+            if (       strstr(filename,".tif")
+                    || strstr(filename,".TIF")
+                    || strstr(filename,".Tif") ) {
+                temp_record->usgs_drg = 2; // Auto
+            }
+            else {
+                temp_record->usgs_drg = 0; // No
+            }
+ 
+            //current = current->next;
+            done++;
+        }
+        else {  // Haven't gotten to the correct insertion point yet
+            previous = current; // Save ptr to last record
+            current = current->next;
+        }
+    }
+
+    if (!done) {  // Matching record not found, add a
+        // record to the end of the list
+        //fprintf(stderr,"Not Found: Adding an index record for %s\n",filename);
+        temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+        CHECKMALLOC(temp_record);
+
+        temp_record->next = NULL;
+
+        if (previous == NULL) { // Empty list
+            map_index_head = temp_record;
+            //fprintf(stderr,"First record in new list\n");
+        }
+        else {  // Else at end of list
+            previous->next = temp_record;
+            //fprintf(stderr,"Adding to end of list: %s\n",filename);
+        }
+
+        //fprintf(stderr,"Adding:%d:%s\n",strlen(filename),filename);
+
+        // Fill in some default values for the new record
+//WE7U
+// Here's where we might look at the file extension and assign
+// default map_layer fields based on that.
+        temp_record->max_zoom = 0;
+        temp_record->min_zoom = 0;
+        temp_record->map_layer = default_map_layer;
+        temp_record->selected = 0;
+        temp_record->XmStringPtr = NULL;
+
+        if (       strstr(filename,".geo")
+                || strstr(filename,".GEO")
+                || strstr(filename,".Geo")) {
+            temp_record->auto_maps = 0;
+        }
+        else {
+            temp_record->auto_maps = 1;
+        }
+
+        if (       strstr(filename,".shp")
+                || strstr(filename,".SHP")
+                || strstr(filename,".Shp") ) {
+            temp_record->draw_filled = 2; // Auto
+        }
+        else {
+            temp_record->draw_filled = 0; // No-Fill
+        }
+
+        if (       strstr(filename,".tif")
+                || strstr(filename,".TIF")
+                || strstr(filename,".Tif") ) {
+            temp_record->usgs_drg = 2; // Auto
+        }
+        else {
+            temp_record->usgs_drg = 0; // No
+        }
+
+    }
+
+    // Update the values.  By this point we have a struct to fill
+    // in, whether it's a new or old struct doesn't matter.  Convert
+    // the values from lat/long to Xastir coordinate system.
+    xastir_snprintf(temp_record->filename,MAX_FILENAME,"%s",filename);
+
+    temp_record->bottom = bottom;
+    temp_record->top = top;
+    temp_record->left = left;
+    temp_record->right = right;
+    temp_record->accessed = 1;
+}
+
+
+
+
+
+// Function called by the various draw_* functions when in indexing
+// mode.  Causes an update of the index list in memory.  Input
+// parameters are in lat/long, which are converted to Xastir
+// coordinates for storage due to speed considerations.  Records are
+// inserted in alphanumerical order.
+void index_update_ll(char *filename,
+                  double bottom,
+                  double top,
+                  double left,
+                  double right,
+                  int default_map_layer) {
+
+    map_index_record *current = map_index_head;
+    map_index_record *previous = map_index_head;
+    map_index_record *temp_record = NULL;
+    int done = 0;
+    unsigned long temp_left, temp_right, temp_top, temp_bottom;
+    int ok;
+    int i;
+
+
+    // Check for initial bad input
+    if ( (filename == NULL)
+            || (filename[0] == '\0')
+            || (filename[strlen(filename) - 1] == '/') ) {
+        fprintf(stderr,"index_update_ll: Bad input: %s\n",filename);
+        return;
+    }
+    // Make sure there aren't any weird characters in the filename
+    // that might cause problems later.  Look for control characters
+    // and convert them to string-end characters.
+    for ( i = 0; i < (int)strlen(filename); i++ ) {
+        // Change any control characters to '\0' chars
+        if (filename[i] < 0x20) {
+
+            fprintf(stderr,"\nindex_update_ll: Found control char 0x%02x in map file/map directory name:\n%s\n",
+                filename[i],
+                filename);
+
+            filename[i] = '\0';    // Terminate it here
+        }
+    }
+    // Check if the string is _now_ bogus
+    if (filename[0] == '\0') {
+        fprintf(stderr,"index_update_ll: Bad input: %s\n",filename);
+        return;
+    }
+
+    //fprintf(stderr,"index_update_ll: (%15.10g,%15.10g)\t(%15.10g,%15.10g)\t%s\n",
+    //    bottom, top, left, right, filename );
+
+    //if (map_index_head == NULL)
+    //    fprintf(stderr,"Empty list\n");
+
+    // Skip dbf and shx map extensions.  Really should make this
+    // case-independent...
+    if (       strstr(filename,"shx")
+            || strstr(filename,"dbf")
+            || strstr(filename,"SHX")
+            || strstr(filename,"DBF") ) {
+        return;
+    }
+
+    // Search for a matching filename in the linked list
+    while ((current != NULL) && !done) {
+        int test;
+
+        //fprintf(stderr,"Comparing %s to\n          %s\n",current->filename,filename);
+
+        test = strcmp(current->filename,filename);
+
+        if (test == 0) {
+            // Found a match!
+            //fprintf(stderr,"Found: Updating entry for %s\n",filename);
+            temp_record = current;
+            done++; // Exit the while loop
+        }
+
+        else if (test > 0) {
+            // Found a string past us in the alphabet.  Insert ahead
+            // of this last record.
+
+            //fprintf(stderr,"\n%s\n%s\n",current->filename,filename);
+
+            //fprintf(stderr,"Not Found: Inserting an index record for %s\n",filename);
+            temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+            CHECKMALLOC(temp_record);
+
+            if (current == map_index_head) {  // Start of list!
+                // Insert new record at head of list
+                temp_record->next = map_index_head;
+                map_index_head = temp_record;
+                //fprintf(stderr,"Inserting at head of list\n");
+            }
+            else {
+                // Insert new record before "current"
+                previous->next = temp_record;
+                temp_record->next = current;
+                //fprintf(stderr,"Inserting before current\n");
+            }
+
+            //fprintf(stderr,"Adding:%d:%s\n",strlen(filename),filename);
+
+            // Fill in some default values for the new record
+//WE7U
+// Here's where we might look at the file extension and assign
+// default map_layer fields based on that.
+            temp_record->max_zoom = 0;
+            temp_record->min_zoom = 0;
+            temp_record->map_layer = default_map_layer;
+            temp_record->selected = 0;
+            temp_record->XmStringPtr = NULL;
+
+            if (       strstr(filename,".geo")
+                    || strstr(filename,".GEO")
+                    || strstr(filename,".Geo")) {
+                temp_record->auto_maps = 0;
+            }
+            else {
+                temp_record->auto_maps = 1;
+            }
+ 
+            if (       strstr(filename,".shp")
+                    || strstr(filename,".SHP")
+                    || strstr(filename,".Shp") ) {
+                temp_record->draw_filled = 2; // Auto
+            }
+            else {
+                temp_record->draw_filled = 0; // No-Fill
+            }
+
+            if (       strstr(filename,".tif")
+                    || strstr(filename,".TIF")
+                    || strstr(filename,".Tif") ) {
+                temp_record->usgs_drg = 2; // Auto
+            }
+            else {
+                temp_record->usgs_drg = 0; // No
+            }
+ 
+            //current = current->next;
+            done++;
+        }
+        else {  // Haven't gotten to the correct insertion point yet
+            previous = current; // Save ptr to last record
+            current = current->next;
+        }
+    }
+
+    if (!done) {    // Matching record not found, didn't find alpha
+                    // chars after our string either, add record to
+                    // the end of the list.
+
+        //fprintf(stderr,"Not Found: Adding an index record for %s\n",filename);
+        temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+        CHECKMALLOC(temp_record);
+
+        temp_record->next = NULL;
+
+        if (previous == NULL) { // Empty list
+            map_index_head = temp_record;
+            //fprintf(stderr,"First record in new list\n");
+        }
+        else {  // Else at end of list
+            previous->next = temp_record;
+            //fprintf(stderr,"Adding to end of list: %s\n",filename);
+        }
+
+        //fprintf(stderr,"Adding:%d:%s\n",strlen(filename),filename);
+
+        // Fill in some default values for the new record
+//WE7U
+// Here's where we might look at the file extension and assign
+// default map_layer fields based on that.
+        temp_record->max_zoom = 0;
+        temp_record->min_zoom = 0;
+        temp_record->map_layer = default_map_layer;
+        temp_record->selected = 0;
+        temp_record->XmStringPtr = NULL;
+
+        if (       strstr(filename,".geo")
+                || strstr(filename,".GEO")
+                || strstr(filename,".Geo")) {
+            temp_record->auto_maps = 0;
+        }
+        else {
+            temp_record->auto_maps = 1;
+        }
+
+        if (       strstr(filename,".shp")
+                || strstr(filename,".SHP")
+                || strstr(filename,".Shp") ) {
+            temp_record->draw_filled = 2; // Auto
+        }
+        else {
+            temp_record->draw_filled = 0; // No-Fill
+        }
+
+        if (       strstr(filename,".tif")
+                || strstr(filename,".TIF")
+                || strstr(filename,".Tif") ) {
+            temp_record->usgs_drg = 2; // Auto
+        }
+        else {
+            temp_record->usgs_drg = 0; // No
+        }
+
+    }
+
+    // Update the values.  By this point we have a struct to fill
+    // in, whether it's a new or old struct doesn't matter.  Convert
+    // the values from lat/long to Xastir coordinate system.
+
+    // In this case the struct uses MAX_FILENAME for the length of
+    // the field, so the below statement is ok.
+    xastir_snprintf(temp_record->filename,MAX_FILENAME,"%s",filename);
+
+    ok = convert_to_xastir_coordinates( &temp_left,
+        &temp_top,
+        (float)left,
+        (float)top);
+    if (!ok)
+        fprintf(stderr,"%s\n\n",filename);
+
+    ok = convert_to_xastir_coordinates( &temp_right,
+        &temp_bottom,
+        (float)right,
+        (float)bottom);
+    if (!ok)
+        fprintf(stderr,"%s\n\n",filename);
+ 
+    temp_record->bottom = temp_bottom;
+    temp_record->top = temp_top;
+    temp_record->left = temp_left;
+    temp_record->right = temp_right;
+    temp_record->accessed = 1;
+}
+
+
+
+
+
+// Function which will update the "accessed" variable on either a
+// directory or a filename in the map index.
+static void index_update_accessed(char *filename) {
+    map_index_record *current = map_index_head;
+    int done = 0;
+    int i;
+
+
+    // Check for initial bad input
+    if ( (filename == NULL) || (filename[0] == '\0') ) {
+        fprintf(stderr,"index_update_accessed: Bad input: %s\n",filename);
+        return;
+    }
+
+    // Make sure there aren't any weird characters in the filename
+    // that might cause problems later.  Look for control characters
+    // and convert them to string-end characters.
+    for ( i = 0; i < (int)strlen(filename); i++ ) {
+        // Change any control characters to '\0' chars
+        if (filename[i] < 0x20) {
+
+            fprintf(stderr,"\nindex_update_accessed: Found control char 0x%02x in map file/map directory name:\n%s\n",
+                filename[i],
+                filename);
+
+            filename[i] = '\0';    // Terminate it here
+        }
+    }
+    // Check if the string is _now_ bogus
+    if (filename[0] == '\0') {
+        fprintf(stderr,"index_update_accessed: Bad input: %s\n",filename);
+        return;
+    }
+
+    // Skip dbf and shx map extensions.  Really should make this
+    // case-independent...
+    if (       strstr(filename,"shx")
+            || strstr(filename,"dbf")
+            || strstr(filename,"SHX")
+            || strstr(filename,"DBF") ) {
+        return;
+    }
+
+    // Search for a matching filename in the linked list
+    while ((current != NULL) && !done) {
+        int test;
+
+//fprintf(stderr,"Comparing %s to\n          %s\n",current->filename,filename);
+
+        test = strcmp(current->filename,filename);
+
+        if (test == 0) {
+            // Found a match!
+//fprintf(stderr,"Found: Updating entry for %s\n\n",filename);
+            current->accessed = 1;
+            done++; // Exit the while loop
+        }
+
+        else {  // Haven't gotten to the correct insertion point yet
+            current = current->next;
+        }
+    }
+}
+
+
+
+
+
+// Function called by map_onscreen_index()
+//
+// This function returns:
+//      0 if the map isn't in the index
+//      1 if the map is listed in the index
+//      Four parameters listing the extents of the map
+//
+// The updated parameters are in the Xastir coordinate system for
+// speed reasons.
+//
+// Note that the index retrieval could be made much faster by
+// storing the data in a hash instead of a linked list.  This is
+// just an initial implementation to see what speedups are possible.
+// Hashing might be next.  --we7u
+//
+// Note that since we've alphanumerically ordered the list, we can
+// stop when we hit something after this filename in the alphabet.
+// It speeds things up quite a bit.
+//
+// In order to speed this up slightly for the general case, we'll
+// assume that we'll be fetching indexes in alphabetical order, as
+// that's how we store them everywhere.  We'll save the last map
+// index pointer away and start searching there each time.  That
+// should make all but the _first_ lookup much faster.
+//
+map_index_record *last_index_lookup = NULL;
+
+int index_retrieve(char *filename,
+                   unsigned long *bottom,
+                   unsigned long *top,
+                   unsigned long *left,
+                   unsigned long *right,
+                   int *max_zoom,
+                   int *min_zoom,
+                   int *map_layer,
+                   int *draw_filled,
+                   int *usgs_drg,
+                   int *auto_maps) {
+
+    map_index_record *current;
+    int status = 0;
+
+
+    if ( (filename == NULL)
+            || (strlen(filename) >= MAX_FILENAME) ) {
+        return(status);
+    }
+
+    // Attempt to start where we left off last time
+    if (last_index_lookup != NULL) {
+        current = last_index_lookup;
+    }
+    else {
+        current = map_index_head;
+//fprintf(stderr,"Start at beginning:%s\t", filename);
+    }
+
+    // Check to see if we're past the correct area.  If so, start at
+    // the beginning of the index instead.
+    //
+    if (current
+            && ((current->filename[0] > filename[0])
+                || (strcmp(current->filename, filename) > 0))) {
+        //
+        // We're past the correct point.  Start at the beginning of
+        // the list unless we're already there.
+        //
+        if (current != map_index_head) {
+            current = map_index_head;
+        }
+//fprintf(stderr,"Start at beginning:%s\t", filename);
+    }
+
+    //
+    // Search for a matching filename in the linked list.
+    //
+
+    // Check the first char only.  Loop until they match or go past.
+    // This is our high-speed method to get to the correct search
+    // area.
+    //
+    while (current && (current->filename[0] < filename[0])) {
+        // Save the pointer away for next time.  There's a reason we
+        // save it before we increment the counter:  For "z" weather
+        // alerts, it's nice to have it scan just the very last of
+        // the list before it fails, instead of scanning the entire
+        // list each time and then failing.  Need to find out why
+        // weather alerts always fail, and therefore why this
+        // routine gets called every time for them.
+        //
+        last_index_lookup = current;
+        current = current->next;
+//fprintf(stderr,"1");
+    }
+
+    // Stay in this loop while the first char matches.  This is our
+    // active search area.
+    //
+    while (current && (current->filename[0] == filename[0])) {
+        int result;
+
+        // Check the entire string
+        result = strcmp(current->filename, filename);
+
+        if (result == 0) {
+            // Found a match!
+            status = 1;
+            *bottom = current->bottom;
+            *top = current->top;
+            *left = current->left;
+            *right = current->right;
+            *max_zoom = current->max_zoom;
+            *min_zoom = current->min_zoom;
+            *map_layer = current->map_layer;
+            *draw_filled = current->draw_filled;
+            *usgs_drg = current->usgs_drg;
+            *auto_maps = current->auto_maps;
+//fprintf(stderr," Found it\n");
+            return(status);
+        }
+        else if (result > 0) {
+            // We're past it in the index.  We didn't find it in the
+            // index.
+//fprintf(stderr," Did not find1\n");
+            return(status);
+        }
+        else {  // Not found yet, look at the next
+            // Save the pointer away for next time.  There's a
+            // reason we save it before we increment the counter:
+            // For "z" weather alerts, it's nice to have it scan
+            // just the very last of the list before it fails,
+            // instead of scanning the entire list each time and
+            // then failing.  Need to find out why weather alerts
+            // always fail, and therefore why this routine gets
+            // called every time for them.
+            //
+            last_index_lookup = current;
+            current = current->next;
+//fprintf(stderr,"2");
+        }
+    }
+
+    // We're past the correct search area and didn't find it.
+//fprintf(stderr," Did not find2\n");
+ 
+    return(status);
+}
+
+
+
+
+
+// Saves the linked list pointed to by map_index_head to a file.
+// Keeps the same order as the memory linked list.  Delete records
+// in the in-memory linked list for which the "accessed" variable is
+// 0 or filename is empty.
+//
+void index_save_to_file(void) {
+    FILE *f;
+    map_index_record *current;
+    map_index_record *last;
+    char out_string[MAX_FILENAME*2];
+    char map_index_path[MAX_VALUE];
+
+    get_user_base_dir(MAP_INDEX_DATA, map_index_path, sizeof(map_index_path));
+
+
+//fprintf(stderr,"Saving map index to file\n");
+
+    f = fopen( map_index_path, "w" );
+
+    if (f == NULL) {
+        fprintf(stderr,"Couldn't create/update map index file: %s\n",
+            map_index_path );
+        return;
+    }
+
+    current = map_index_head;
+    last = current;
+
+    while (current != NULL) {
+        int i;
+
+        // Make sure there aren't any weird characters in the
+        // filename that might cause problems later.  Look for
+        // control characters and convert them to string-end
+        // characters.
+        for ( i = 0; i < (int)strlen(current->filename); i++ ) {
+            // Change any control characters to '\0' chars
+            if (current->filename[i] < 0x20) {
+
+                fprintf(stderr,"\nindex_save_to_file: Found control char 0x%02x in map name:\n%s\n",
+                    current->filename[i],
+                    current->filename);
+
+                current->filename[i] = '\0';    // Terminate it here
+            }
+        }
+ 
+        // Save to file if filename non-blank and record has the
+        // accessed field set.
+        if ( (current->filename[0] != '\0')
+                && (current->accessed != 0) ) {
+
+            // Write each object out to the file as one
+            // comma-delimited line
+            xastir_snprintf(out_string,
+                sizeof(out_string),
+                "%010lu,%010lu,%010lu,%010lu,%05d,%01d,%01d,%01d,%05d,%05d,%s\n",
+                current->bottom,
+                current->top,
+                current->left,
+                current->right,
+                current->map_layer,
+                current->draw_filled,
+                current->usgs_drg,
+                current->auto_maps,
+                current->max_zoom,
+                current->min_zoom,
+                current->filename);
+
+            if (fprintf(f,"%s",out_string) < (int)strlen(out_string)) {
+                // Failed to write
+                fprintf(stderr,"Couldn't write objects to map index file: %s\n",
+                    map_index_path );
+                current = NULL; // All done
+            }
+            // Set up pointers for next loop iteration
+            last = current;
+
+            if (current != NULL)
+                current = current->next;
+        }
+
+
+        else {
+            last = current;
+            current = current->next;
+        }
+/*
+//WE7U
+        else {  // Delete this record from our list!  It's a record
+                // for a map file that doesn't exist in the
+                // filesystem anymore.
+            if (last == current) {   // We're at the head of the list
+                map_index_head = current->next;
+
+// Remember to free the XmStringPtr if we use this bit of code
+// again.
+
+                free(current);
+
+                // Set up pointers for next loop iteration
+                current = map_index_head;
+                last = current;
+            }
+            else {  // Not the first record in the list
+                map_index_record *gone;
+
+                gone = current; // Save ptr to record we wish to delete 
+                last->next = current->next; // Unlink from list
+
+// Remember to free the XmStringPtr if we use this bit of code
+// again.
+
+                free(gone);
+
+                // Set up pointers for next loop iteration
+                // "last" is still ok
+                current = last->next;
+            }
+        }
+*/
+    }
+    (void)fclose(f);
+}
+
+
+
+
+
+// This function is currently not used.
+//
+// Function used to add map directories/files to the in-memory map
+// index.  Causes an update of the index list in memory.  Input
+// records are inserted in alphanumerical order.  This function is
+// called from the index_restore_from_file() function below.  When
+// this function is called the new record has all of the needed
+// information in it.
+//
+/*
+static void index_insert_sorted(map_index_record *new_record) {
+
+    map_index_record *current = map_index_head;
+    map_index_record *previous = map_index_head;
+    int done = 0;
+    int i;
+
+
+    //fprintf(stderr,"index_insert_sorted: %s\n", new_record->filename );
+
+    // Check for bad input.
+    if (new_record == NULL) {
+        fprintf(stderr,"index_insert_sorted: Bad input.\n");
+        return;
+    }
+    // Make sure there aren't any weird characters in the filename
+    // that might cause problems later.  Look for any control
+    // characters and convert them to string-end characters.
+    for ( i = 0; i < (int)strlen(new_record->filename); i++ ) {
+        if (new_record->filename[i] < 0x20) {
+
+            fprintf(stderr,"\nindex_insert_sorted: Found control char 0x%02x in map name:\n%s\n",
+                new_record->filename[i],
+                new_record->filename);
+
+            new_record->filename[i] = '\0';    // Terminate it here
+        }
+    }
+    // Check if the string is _now_ bogus
+    if (new_record->filename[0] == '\0') {
+        fprintf(stderr,"index_insert_sorted: Bad input.\n");
+        return;
+    }
+
+    //if (map_index_head == NULL)
+    //    fprintf(stderr,"Empty list\n");
+
+    // Search for a matching filename in the linked list
+    while ((current != NULL) && !done) {
+        int test;
+
+        //fprintf(stderr,"Comparing %s to\n          %s\n",
+        //    current->filename, new_record->filename);
+
+        test = strcmp(current->filename, new_record->filename);
+
+        if (test == 0) {    // Found a match!
+            int selected;
+
+//fprintf(stderr,"Found a match: Updating entry for %s\n",new_record->filename);
+
+            // Save this away temporarily.
+            selected = current->selected;
+
+            // Copy the fields across and then free new_record.  We
+            // overwrite the contents of the existing record.
+            xastir_snprintf(current->filename,
+                MAX_FILENAME,
+                "%s",
+                new_record->filename);
+            current->bottom = new_record->bottom;
+            current->top = new_record->top;
+            current->left = new_record->left;
+            current->right = new_record->right;
+            current->accessed = 1;
+            current->max_zoom = new_record->max_zoom;
+            current->min_zoom = new_record->min_zoom;
+            current->map_layer = new_record->map_layer;
+            current->draw_filled = new_record->draw_filled;
+            current->usgs_drg = new_record->usgs_drg;
+            current->selected = selected;   // Restore it
+            current->auto_maps = new_record->auto_maps;
+
+// Remember to free the XmStringPtr if we use this bit of code
+// again.
+
+            free(new_record);   // Don't need it anymore
+
+            done++; // Exit loop, "current" points to found record
+        }
+        else if (test > 0) {    // Found a string past us in the
+                                // alphabet.  Insert ahead of this
+                                // last record.
+
+//fprintf(stderr,"Not Found, inserting: %s\n", new_record->filename);
+//fprintf(stderr,"       Before record: %s\n", current->filename);
+
+            if (current == map_index_head) {  // Start of list!
+                // Insert new record at head of list
+                new_record->next = map_index_head;
+                map_index_head = new_record;
+                //fprintf(stderr,"Inserting at head of list\n");
+            }
+            else {  // Insert between "previous" and "current"
+                // Insert new record before "current"
+                previous->next = new_record;
+                new_record->next = current;
+                //fprintf(stderr,"Inserting before current\n");
+            }
+
+            //fprintf(stderr,"Adding:%d:%s\n",strlen(filename),filename);
+ 
+            // Fill in some default values for the new record that
+            // don't exist in the map_index.sys file.
+            new_record->selected = 0;
+
+            if (       strstr(new_record->filename,".geo")
+                    || strstr(new_record->filename,".GEO")
+                    || strstr(new_record->filename,".Geo") ) {
+                new_record->auto_maps = 0;
+            }
+            else {
+                new_record->auto_maps = 1;
+            }
+
+            //current = current->next;
+            done++;
+        }
+        else {  // Haven't gotten to the correct insertion point yet
+            previous = current; // Save ptr to last record
+            current = current->next;
+        }
+    }
+
+    if (!done) {    // Matching record not found, add the record to
+        // the end of the list.  "previous" points to the last
+        // record in the list or NULL (empty list).
+
+//fprintf(stderr,"Not Found: Adding to end: %s\n",new_record->filename);
+
+        new_record->next = NULL;
+
+        if (previous == NULL) { // Empty list
+            map_index_head = new_record;
+            //fprintf(stderr,"First record in new list\n");
+        }
+        else {  // Else at end of list
+            previous->next = new_record;
+            //fprintf(stderr,"Adding to end of list: %s\n",new_record->filename);
+        }
+
+        //fprintf(stderr,"Adding:%d:%s\n",strlen(new_record->filename),new_record->filename);
+ 
+        // Fill in some default values for the new record.
+        new_record->selected = 0;
+
+        if (       strstr(new_record->filename,".geo")
+                || strstr(new_record->filename,".GEO")
+                || strstr(new_record->filename,".Geo") ) {
+            new_record->auto_maps = 0;
+        }
+        else {
+            new_record->auto_maps = 1;
+        }
+    }
+}
+*/
+
+
+
+
+
+// sort map index
+// simple bubble sort, since we should be sorted already
+//
+static void index_sort(void) {
+    map_index_record *current, *previous, *next;
+    int changed = 1;
+    int loops = 0; // for debug stats
+
+    previous = map_index_head;
+    next = NULL;
+    //  fprintf(stderr, "index_sort: start.\n");
+    // check if we have any records at all, and at least two
+    if ( (previous != NULL) && (previous->next != NULL) ) {
+        current = previous->next;
+        while ( changed == 1) {
+            changed = 0;
+            if (current->next != NULL) {next = current->next;}
+            if ( strcmp( previous->filename, current->filename) >= 0 ) {
+                // out of order - swap them
+                current->next = previous;
+                previous->next = next;
+                map_index_head = current;
+                current = previous;
+                previous = map_index_head;
+                changed = 1;
+            }
+            
+            while ( next != NULL ) {
+                if ( strcmp( current->filename, next->filename) >= 0 ) {
+                    // out of order - swap them
+                    current->next = next->next;
+                    previous->next = next;
+                    next->next = current;
+                    // get ready for the next iteration
+                    previous = next;  // current already moved ahead from the swap
+                    next = current->next;
+                    changed = 1;
+                }
+                else {
+                    previous = current;
+                    current = next;
+                    next = current->next;
+                }
+            }
+            previous = map_index_head;
+            current = previous->next;
+            next = current->next;
+            loops++;
+        }
+    }
+    // debug stats
+    // fprintf(stderr, "index_sort: ran %d loops.\n", loops);
+}
+
+
+
+
+
+// Snags the file and creates the linked list pointed to by the
+// map_index_head pointer.  The memory linked list keeps the same
+// order as the entries in the file.
+//
+// NOTE:  If we're converting from the old format to the new, we
+// need to call index_save_to_file() in order to write out the new
+// format once we're done.
+//
+void index_restore_from_file(void) {
+    FILE *f;
+    map_index_record *temp_record;
+    map_index_record *last_record;
+    char in_string[MAX_FILENAME*2];
+    int doing_migration = 0;
+    char map_index_path[MAX_VALUE];
+
+    get_user_base_dir(MAP_INDEX_DATA, map_index_path, sizeof(map_index_path));
+
+
+//fprintf(stderr,"\nRestoring map index from file\n");
+
+    if (map_index_head != NULL) {
+        fprintf(stderr,"Warning: index_restore_from_file(): map_index_head was non-null!\n");
+    }
+
+    map_index_head = NULL;  // Starting with empty list
+    last_record = NULL;
+
+    f = fopen( map_index_path, "r" );
+    if (f == NULL)  // No map_index file yet
+        return;
+
+    while (!feof (f)) { // Loop through entire map_index file
+
+        // Read one line from the file
+        if ( get_line (f, in_string, MAX_FILENAME*2) ) {
+
+            if (strlen(in_string) >= 15) {   // We have some data.
+                                            // Try to process the
+                                            // line.
+                char scanf_format[50];
+                char old_scanf_format[50];
+                char older_scanf_format[50];
+                int processed;
+                int i, jj;
+
+//fprintf(stderr,"%s\n",in_string);
+
+                // Tweaked the string below so that it will track
+                // along with MAX_FILENAME-1.  We're constructing
+                // the string "%lu,%lu,%lu,%lu,%d,%d,%2000c", where
+                // the 2000 example number is from MAX_FILENAME.
+                xastir_snprintf(scanf_format,
+                    sizeof(scanf_format),
+                    "%s%d%s",
+                    "%lu,%lu,%lu,%lu,%d,%d,%d,%d,%d,%d,%",
+                    MAX_FILENAME,
+                    "c");
+                //fprintf(stderr,"%s\n",scanf_format);
+
+                // index predates addition of usgs_drg flag (26 Jul 2005)
+                xastir_snprintf(old_scanf_format,
+                    sizeof(old_scanf_format),
+                    "%s%d%s",
+                    "%lu,%lu,%lu,%lu,%d,%d,%d,%d,%d,%",
+                    MAX_FILENAME,
+                    "c");
+
+                // index predates addition of min/max zoom (29 Oct 2003)
+                xastir_snprintf(older_scanf_format,
+                    sizeof(older_scanf_format),
+                    "%s%d%s",
+                    "%lu,%lu,%lu,%lu,%d,%d,%d,%",
+                    MAX_FILENAME,
+                    "c");
+ 
+                // Malloc an index record.  We'll add it to the list
+                // only if the data looks reasonable.
+                temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+                CHECKMALLOC(temp_record);
+
+                memset(temp_record->filename, 0, sizeof(temp_record->filename));
+                temp_record->next = NULL;
+                temp_record->bottom = 64800001l;// Too high
+                temp_record->top = 64800001l;   // Too high
+                temp_record->left = 129600001l; // Too high
+                temp_record->right = 129600001l;// Too high
+                temp_record->map_layer = -1;    // Too low
+                temp_record->draw_filled = -1;  // Too low
+                temp_record->usgs_drg = -1;     // Too low
+                temp_record->auto_maps = -1;    // Too low
+                temp_record->max_zoom = -1;     // Too low
+                temp_record->min_zoom = -1;     // Too low
+                temp_record->filename[0] = '\0';// Empty
+
+                processed = sscanf(in_string,
+                    scanf_format,
+                    &temp_record->bottom,
+                    &temp_record->top,
+                    &temp_record->left,
+                    &temp_record->right,
+                    &temp_record->map_layer,
+                    &temp_record->draw_filled,
+                    &temp_record->usgs_drg,
+                    &temp_record->auto_maps,
+                    &temp_record->max_zoom,
+                    &temp_record->min_zoom,
+                    temp_record->filename);
+
+                if (processed < 11) {
+                    // We're upgrading from an old format index file
+                    // that doesn't have usgs_drg.  Try the
+                    // old_scanf_format string instead.
+
+                    doing_migration = 1;
+
+                    processed = sscanf(in_string,
+                        old_scanf_format,
+                        &temp_record->bottom,
+                        &temp_record->top,
+                        &temp_record->left,
+                        &temp_record->right,
+                        &temp_record->map_layer,
+                        &temp_record->draw_filled,
+                        &temp_record->auto_maps,
+                        &temp_record->max_zoom,
+                        &temp_record->min_zoom,
+                        temp_record->filename);
+                    if (processed < 10) {
+                        // It's really old, doesn't have min/max zoom either
+                        temp_record->max_zoom = -1;     // Too low
+                        temp_record->min_zoom = -1;     // Too low
+
+                        processed = sscanf(in_string,
+                                           older_scanf_format,
+                                           &temp_record->bottom,
+                                           &temp_record->top,
+                                           &temp_record->left,
+                                           &temp_record->right,
+                                           &temp_record->map_layer,
+                                           &temp_record->draw_filled,
+                                           &temp_record->auto_maps,
+                                           temp_record->filename);
+                    }
+                    // either way, it doesn't have usgs_drg, so add one
+                    // defaulting to Auto if it's a tif file, no if not
+                    if (       strstr(temp_record->filename,".tif")
+                               || strstr(temp_record->filename,".TIF")
+                               || strstr(temp_record->filename,".Tif") ) {
+                        temp_record->usgs_drg = 2; // Auto
+                    }
+                    else {
+                        temp_record->usgs_drg = 0; // No
+                    }
+                }
+
+                temp_record->XmStringPtr = NULL;
+
+                // Do some reasonableness checking on the parameters
+                // we just parsed.
+//WE7U: First comparison here is always false
+//                if ( (temp_record->bottom < 0l)
+//                        || (temp_record->bottom > 64800000l) ) {
+                if (temp_record->bottom > 64800000l) {
+ 
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: bottom extent incorrect %lu in map name:\n%s\n",
+                            temp_record->bottom,
+                            temp_record->filename);
+                }
+
+ 
+//WE7U: First comparison here is always false
+//               if ( (temp_record->top < 0l)
+//                        || (temp_record->top > 64800000l) ) {
+               if (temp_record->top > 64800000l) {
+ 
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: top extent incorrect %lu in map name:\n%s\n",
+                            temp_record->top,
+                            temp_record->filename);
+                }
+
+//WE7U: First comparison here is always false
+//                if ( (temp_record->left < 0l)
+//                        || (temp_record->left > 129600000l) ) {
+                if (temp_record->left > 129600000l) {
+ 
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: left extent incorrect %lu in map name:\n%s\n",
+                            temp_record->left,
+                            temp_record->filename);
+                }
+
+//WE7U: First comparison here is always false
+//                if ( (temp_record->right < 0l)
+//                        || (temp_record->right > 129600000l) ) {
+                if (temp_record->right > 129600000l) {
+ 
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: right extent incorrect %lu in map name:\n%s\n",
+                            temp_record->right,
+                            temp_record->filename);
+                }
+
+                if ( (temp_record->max_zoom < 0)
+                        || (temp_record->max_zoom > 99999) ) {
+//                    processed = 0;  // Reject this record
+//                    fprintf(stderr,"\nindex_restore_from_file: max_zoom field incorrect %d in map name:\n%s\n",
+//                            temp_record->max_zoom,
+//                            temp_record->filename);
+                    // Assign a reasonable value
+                    temp_record->max_zoom = 0;
+                    //fprintf(stderr,"Assigning max_zoom of 0\n");
+                }
+
+                if ( (temp_record->min_zoom < 0)
+                        || (temp_record->min_zoom > 99999) ) {
+//                    processed = 0;  // Reject this record
+//                    fprintf(stderr,"\nindex_restore_from_file: min_zoom field incorrect %d in map name:\n%s\n",
+//                            temp_record->min_zoom,
+//                            temp_record->filename);
+                    // Assign a reasonable value
+                    temp_record->min_zoom = 0;
+                    //fprintf(stderr,"Assigning min_zoom of 0\n");
+                }
+
+                if ( (temp_record->map_layer < -99999)
+                        || (temp_record->map_layer > 99999) ) {
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: map_layer field incorrect %d in map name:\n%s\n",
+                            temp_record->map_layer,
+                            temp_record->filename);
+                }
+
+                if ( (temp_record->draw_filled < 0)
+                        || (temp_record->draw_filled > 2) ) {
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: draw_filled field incorrect %d in map name:\n%s\n",
+                            temp_record->draw_filled,
+                            temp_record->filename);
+                }
+
+                if ( (temp_record->usgs_drg < 0)
+                        || (temp_record->usgs_drg > 2) ) {
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: usgs_drg field incorrect %d in map name:\n%s\n",
+                            temp_record->usgs_drg,
+                            temp_record->filename);
+                }
+
+                if ( (temp_record->auto_maps < 0)
+                        || (temp_record->auto_maps > 1) ) {
+                    processed = 0;  // Reject this record
+                    fprintf(stderr,"\nindex_restore_from_file: auto_maps field incorrect %d in map name:\n%s\n",
+                            temp_record->auto_maps,
+                            temp_record->filename);
+                }
+
+                // Check whether the filename is empty
+                if (strlen(temp_record->filename) == 0) {
+                    processed = 0;  // Reject this record
+                }
+
+                // Check for control characters in the filename.
+                // Reject any that have them.
+                jj = (int)strlen(temp_record->filename);
+                for (i = 0; i < jj; i++)
+                {
+                    if (temp_record->filename[i] < 0x20) {
+
+                        processed = 0;  // Reject this record
+                        fprintf(stderr,"\nindex_restore_from_file: Found control char 0x%02x in map name:\n%s\n",
+                            temp_record->filename[i],
+                            temp_record->filename);
+                    }
+                }
+
+
+                // Mark the record as accessed at this point.
+                // At the stage where we're writing this list off to
+                // disk, if the record hasn't been accessed by the
+                // re-indexing, it doesn't get written.  This has
+                // the effect of flushes deleted files from the
+                // index quickly.
+                temp_record->accessed = 1;
+
+                // Default is not-selected.  Later we read in the
+                // selected_maps.sys file and tweak some of these
+                // fields.
+                temp_record->selected = 0;
+
+                temp_record->filename[MAX_FILENAME-1] = '\0';
+
+                // If correct number of parameters for either old or
+                // new format
+                if (processed == 11 || processed == 10 || processed == 8) {
+
+                    //fprintf(stderr,"Restored: %s\n",temp_record->filename);
+ 
+                    // Insert the new record into the in-memory map
+                    // list in sorted order.
+                    // --slow for large lists
+                    // index_insert_sorted(temp_record);
+                    // -- so we just add it to the end of the list
+                    // and sort it at the end tp make sure nobody 
+                    // messed us up by editting the file by hand
+                    if ( last_record == NULL ) { // first record
+                        map_index_head = temp_record;
+                    }
+                    else {
+                        last_record->next = temp_record;
+                    }
+                    last_record = temp_record;
+
+
+                    // Remember that we may just have attached the
+                    // record to our in-memory map list, or we may
+                    // have free'ed it in the above function call.
+                    // Set the pointer to NULL to make sure we don't
+                    // try to do anything else with the memory.
+                    temp_record = NULL;
+                }
+                else {  // sscanf didn't parse the proper number of
+                        // items.  Delete the record.
+
+// Remember to free the XmString pointer if necessary.
+
+                    free(temp_record);
+//                    fprintf(stderr,"index_restore_from_file:sscanf parsing error\n");
+                }
+            }
+        }
+    }
+    (void)fclose(f);
+    // now that we have read the whole file, make sure it is sorted
+    index_sort();  // probably should check for dup records
+
+    if (doing_migration) {
+        // Save in new file format if we just did a migration from
+        // old format to new.
+        fprintf(stderr,"Migrating from old map_index.sys format to new format.\n");
+        index_save_to_file();
+    }
+}
+
+
+
+
+
+// map_indexer()
+//
+// Recurses through the map directories finding map extents
+// and recording them in the map index.  Once the indexing is
+// complete, write the current index out to a file.
+//
+// It'd be nice to call index_restore_from_file() from main.c:main()
+// so that an earlier copy of the index is restored before the map
+// display is created.
+//
+// If we set the "accessed" variable in the in-memory index to 0 for
+// each record and then run the indexer, the save-to-file function
+// will delete those with a value of 0 when writing to disk.  Those
+// maps no longer exist in the filesystem and should be deleted.  We
+// could either wipe them from the in-memory database at that time
+// as well, or wipe the whole list and re-read it from disk to get
+// the current list.
+//
+// If parameter is 0, we'll do the smart timestamp-checking
+// indexing.
+// If 1, we'll erase the in-memory index and do full indexing.
+//
+void map_indexer(int parameter) {
+    struct stat nfile;
+    int check_times = 1;
+    FILE *f;
+    map_index_record *current;
+    map_index_record *backup_list_head = NULL;
+    char map_index_path[MAX_VALUE];
+
+    get_user_base_dir(MAP_INDEX_DATA, map_index_path, sizeof(map_index_path));
+
+
+    if (debug_level & 16)
+        fprintf(stderr,"map_indexer() start\n");
+
+    fprintf(stderr,"Indexing maps...\n");
+
+#ifdef HAVE_LIBSHP
+#ifdef WITH_DBFAWK
+    // get rid of stored dbfawk signatures and force reload.
+    clear_dbfawk_sigs();
+#endif
+#endif
+
+    // Find the timestamp on the index file first.  Save it away so
+    // that the timestamp for each map file can be compared to it.
+    if (stat ( map_index_path, &nfile) != 0) {
+
+        // File doesn't exist yet.  Create it.
+        f = fopen( map_index_path, "w" );
+        if (f != NULL)
+            (void)fclose(f);
+        else
+            fprintf(stderr,"Couldn't create map index file: %s\n",
+                map_index_path );
+        
+        check_times = 0; // Don't check the timestamps.  Do them all. 
+    }
+    else {  // File exists
+        map_index_timestamp = (time_t)nfile.st_mtime;
+        check_times = 1;
+    }
+
+
+    if (parameter == 1) {   // Full indexing instead of timestamp-check indexing
+
+        // Move the in-memory index to a backup pointer
+        backup_list_head = map_index_head;
+        map_index_head = NULL;
+
+//        // Set the timestamp to 0 so that everything gets indexed
+//        map_index_timestamp = (time_t)0l;
+
+        check_times = 0;
+    }
+
+
+    // Set the "accessed" field to zero for every record in the
+    // index.  Note that the list could be empty at this point.
+    current = map_index_head;
+    while (current != NULL) {
+        current->accessed = 0;
+        current = current->next;
+    }
+
+
+    if (check_times) {
+        if (debug_level & 16)
+            fprintf(stderr,"map_indexer: Calling map_search\n");
+
+        map_search (NULL, AUTO_MAP_DIR, NULL, NULL, (int)FALSE, INDEX_CHECK_TIMESTAMPS);
+
+        if (debug_level & 16)
+            fprintf(stderr,"map_indexer: Returned from map_search\n");
+    }
+    else {
+        if (debug_level & 16)
+            fprintf(stderr,"map_indexer: Calling map_search\n");
+
+        map_search (NULL, AUTO_MAP_DIR, NULL, NULL, (int)FALSE, INDEX_NO_TIMESTAMPS);
+
+        if (debug_level & 16)
+            fprintf(stderr,"map_indexer: Returned from map_search\n");
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr,"map_indexer() middle\n");
+
+
+    if (parameter == 1) {   // Full indexing instead of timestamp-check indexing
+        // Copy the Properties from the backup list to the new list,
+        // then free the backup list.
+        map_index_copy_properties(map_index_head, backup_list_head);
+    }
+
+ 
+    // Save the updated index to the file
+    index_save_to_file();
+
+    fprintf(stderr,"Finished indexing maps\n");
+
+    if (debug_level & 16)
+        fprintf(stderr,"map_indexer() end\n");
+}
+
+
+
+
+
+/* moved these here and made them static so it will function on FREEBSD */
+#define MAX_ALERT 7000
+// If we comment this out, we link, but get a segfault at runtime.
+// Take out the "static" and we get a segfault when we zoom out too
+// far with the lakes or counties shapefile loaded.  No idea why
+// yet.  --we7u
+//static alert_entry alert[MAX_ALERT];
+static int alert_count;
+
+
+
+
+
+/*******************************************************************
+ * fill_in_new_alert_entries()
+ *
+ * Fills in the index and filename portions of any alert entries
+ * that are missing them.  This function should be called at the
+ * point where we've just received a new weather alert.
+ *
+
+//WE7U
+// Later we should change this so that it doesn't scan the entire
+// message list, but is passed the important info directly from the
+// decode routines in db.c, and the message should NOT be added to
+// the message list.
+//WE7U
+
+ *
+ * This function is designed to use ESRI Shapefile map files.  The
+ * base directory where the Shapefiles are located is passed to us
+ * in the "dir" variable.
+ *
+ * map_search() fills in the filename field of the alert struct.
+ * draw_shapefile_map() fills in the index field.
+ *******************************************************************/
+void fill_in_new_alert_entries() {
+//    int ii;
+    char alert_scan[MAX_FILENAME], *dir_ptr;
+    struct hashtable_itr *iterator = NULL;
+    alert_entry *temp;
+    char dir[MAX_FILENAME];
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"fill_in_new_alert_entries start\n");
+
+    xastir_snprintf(dir,
+        sizeof(dir),
+        "%s",
+        ALERT_MAP_DIR);
+
+    alert_count = MAX_ALERT - 1;
+
+    // Set up our path to the wx alert maps
+    memset(alert_scan, 0, sizeof (alert_scan));    // Zero our alert_scan string
+    xastir_snprintf(alert_scan, // Fetch the base directory
+        sizeof(alert_scan),
+        "%s",
+        dir);
+    strncat(alert_scan, // Complete alert directory is now set up in the string
+        "/",
+        sizeof(alert_scan) - 1 - strlen(alert_scan));
+    dir_ptr = &alert_scan[strlen (alert_scan)]; // Point to end of path
+
+    // Iterate through the weather alerts.  It looks like we wish to
+    // just fill in the alert struct and to determine whether the
+    // alert is within our viewport here.  We don't wish to draw the
+    // alerts at this stage, that happens in the load_alert_maps()
+    // function below.
+
+    iterator = create_wx_alert_iterator();
+    temp = get_next_wx_alert(iterator);
+    while (iterator != NULL && temp) {
+
+        if (!temp->filename[0]) { // Filename is
+            // empty, we need to fill it in.
+
+//            fprintf(stderr,"fill_in_new_alert_entries() Title: %s\n",temp->title);
+
+            // The last parameter denotes loading into
+            // pixmap_alerts instead of pixmap or pixmap_final.
+            // Note that just calling map_search does not get
+            // the alert areas drawn on the screen.  The
+            // draw_map() function called by map_search just
+            // fills in the filename field in the struct and
+            // exits.
+            //
+            // The "warn" parameter (next to last) specifies whether
+            // to dump warnings out to the console as well.  If the
+            // warning was received on local RF or locally, warn the
+            // operator (the weather must be near).
+            map_search (da,
+                alert_scan,
+                temp,
+                &alert_count,
+                (int)temp->flags[source],
+                DRAW_TO_PIXMAP_ALERTS);
+
+//            fprintf(stderr,"fill_in_new_alert_entries() Title1:%s\n",temp->title);
+        }
+        temp = get_next_wx_alert(iterator);
+    }
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 4\n");
+    if (iterator) free(iterator);
+#endif  // USING_LIBGC
+
+    if (debug_level & 2)
+        fprintf(stderr,"fill_in_new_alert_entries end\n");
+}
+
+
+
+
+/*******************************************************************
+ * load_alert_maps()
+ *
+ * Used to load weather alert maps, based on NWS weather alerts that
+ * are received.  Called from create_image() and refresh_image().
+ * This function is designed to use ESRI Shapefile map files.  The
+ * base directory where the Shapefiles are located is passed to us
+ * in the "dir" variable.
+ *
+ * map_search() fills in the filename field of the alert struct.
+ * draw_shapefile_map() fills in the index field.
+ *******************************************************************/
+void load_alert_maps (Widget w, char *dir) {
+//    int ii;
+    int level;
+    unsigned char fill_color[] = {  (unsigned char)0x69,    // gray86
+                                    (unsigned char)0x4a,    // red2
+                                    (unsigned char)0x63,    // yellow2
+                                    (unsigned char)0x66,    // cyan2
+                                    (unsigned char)0x61,    // RoyalBlue
+                                    (unsigned char)0x64,    // ForestGreen
+                                    (unsigned char)0x62 };  // orange3
+
+    struct hashtable_itr *iterator = NULL;
+    alert_entry *temp;
+    map_draw_flags mdf;
+
+
+//fprintf(stderr,"load_alert_maps\n");
+
+// TODO:
+// Figure out how to pass a quantity of zones off to the map drawing
+// routines, then we can draw them all with one pass through each
+// map file.  Alphanumerically sort the zones to make it easier for
+// the map drawing functions?  Note that the indexing routines fill
+// in both the filename and the shapefile index for each record.
+//
+// Alternative:  Call map_draw for each filename listed and have the
+// draw_shapefile function iterate through the array looking for all
+// filename matches, pulling non-negative indexes out of each index
+// field for matches and drawing them.  That should be fast and
+// require no sorting of the array.  Downside:  The alerts won't be
+// layered based on alert level unless we modify the above:  Drawing
+// each file once for each alert-level in the proper layering order.
+// Perhaps we could keep a list of which filenames have been called,
+// and only call each one once per load_alert_maps() call.
+
+
+// Just for a test
+//draw_shapefile_map (w, dir, filenm, alert, alert_color, destination_pixmap);
+//draw_shapefile_map (w, dir, "c_16my01.shp", NULL, '\0', DRAW_TO_PIXMAP_ALERTS);
+
+
+// Are we drawing them in reverse order so that the important 
+// alerts end up drawn on top of the less important alerts?
+// Actually, since the alert hash isn't ordered, perhaps we need to
+// order them by priority, then by map file, so that we can draw the
+// shapes from each map file in the correct order.  This might cause
+// each map file to be drawn up to three times (once for each
+// priority level), but that's better than calling each map for each
+// zone as is done now.
+
+    iterator = create_wx_alert_iterator();
+    temp = get_next_wx_alert(iterator);
+    while (iterator != NULL && temp) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 5\n");
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+            return;
+        }
+
+        if (disable_all_maps) {
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 6\n");
+            if (iterator) free(iterator);
+#endif  // USING_LIBGC
+            return;
+        }
+
+        //  Check whether the alert slot is filled/empty
+        if (temp->title[0] == '\0') { // Empty slot
+            temp = get_next_wx_alert(iterator);
+            continue;
+        }
+
+        if ( (level = alert_active(temp, ALERT_ALL) ) ) {
+            if (level >= (int)sizeof (fill_color))
+                level = 0;
+
+            // The last parameter denotes drawing into pixmap_alert
+            // instead of pixmap or pixmap_final.
+
+		if (debug_level & 16) {
+	            fprintf(stderr,"load_alert_maps() Drawing %s\n",temp->filename);
+	            fprintf(stderr,"load_alert_maps() Title4:%s\n",temp->title);
+		}
+
+            // Attempt to draw alert
+            if ( temp->index != -1 ) {          // Shape found in shapefile
+
+                // Check whether we've ever tried to draw this alert
+                // before.  If not, attempt it and get the boundary
+                // limits filled in.
+                //
+                if (       temp->bottom_boundary == 0.0
+                        && temp->top_boundary == 0.0
+                        && temp->left_boundary == 0.0
+                        && temp->right_boundary == 0.0) {
+
+                    if (temp->alert_level != 'C') {
+                        draw_map (w, dir, temp->filename, temp,
+                            fill_color[level], DRAW_TO_PIXMAP_ALERTS, &mdf);  // draw filled
+                    }
+                }
+
+                if (map_visible_lat_lon(temp->bottom_boundary, // Shape visible
+                        temp->top_boundary,
+                        temp->left_boundary,
+                        temp->right_boundary) ) {
+
+                    if (temp->alert_level != 'C') {     // Alert not cancelled
+                        mdf.draw_filled=1;
+                        mdf.usgs_drg=0;
+  
+                        if (debug_level & 16)
+                          fprintf(stderr,"load_alert_maps: Calling draw_map\n");
+  
+                        draw_map (w, dir, temp->filename, temp,
+                                  fill_color[level], DRAW_TO_PIXMAP_ALERTS, &mdf);  // draw filled
+                    }
+                    if (temp) temp->flags[on_screen] = 'Y';
+                }
+                else {
+                    // Not in our viewport, don't draw it!
+                    if (debug_level & 16) fprintf(stderr,"load_alert_maps() Alert not visible\n");
+//fprintf(stderr,"B:%f  T:%f  L:%f  R:%f\n", temp->bottom_boundary, temp->top_boundary, temp->left_boundary, temp->right_boundary);
+                    if (temp) temp->flags[on_screen] = 'N';
+                }
+            }
+            else {
+                // Can't find this shape in the shapefile.
+                if (debug_level & 16) {
+                    fprintf(stderr,
+                        "load_alert_maps() Shape %s, strlen=%d, not found in %s\n",
+                        temp->title,
+                        (int)strlen(temp->title),
+                        temp->filename );
+                }
+            }
+        }
+        temp = get_next_wx_alert(iterator);
+    }
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 7\n");
+    if (iterator) free(iterator);
+#endif  // USING_LIBGC
+
+	if (debug_level & 16) fprintf(stderr,"load_alert_maps() Done drawing all active alerts\n");
+
+    if (alert_display_request()) {
+        alert_redraw_on_update = redraw_on_new_data = 2;
+    }
+}
+
+
+
+
+
+// Here's the head of our sorted-by-layer maps list
+static map_index_record *map_sorted_list_head = NULL;
+
+
+static void empty_map_sorted_list(void) {
+    map_index_record *current = map_sorted_list_head;
+
+    while (map_sorted_list_head != NULL) {
+        current = map_sorted_list_head;
+        map_sorted_list_head = current->next;
+        if (current->XmStringPtr != NULL) {
+            XmStringFree(current->XmStringPtr);
+        }
+        free(current);
+    }
+}
+
+
+
+
+
+// Insert a map into the list at the end of the maps with the same
+// layer number.  We'll need to look up the parameters for it from
+// the master map_index list and then attach a new record to our new
+// sorted list in the proper place.
+//
+// This function should be called when we're first starting up
+// Xastir and anytime that selected_maps.sys is changed.
+//
+static void insert_map_sorted(char *filename){
+    map_index_record *current;
+    map_index_record *last;
+    map_index_record *temp_record;
+    unsigned long bottom;
+    unsigned long top;
+    unsigned long left;
+    unsigned long right;
+    int max_zoom;
+    int min_zoom;
+    int map_layer;
+    int draw_filled;
+    int usgs_drg;
+    int auto_maps;
+    int done;
+
+
+    if (index_retrieve(filename,
+            &bottom,
+            &top,
+            &left,
+            &right,
+            &max_zoom,
+            &min_zoom,
+            &map_layer,
+            &draw_filled,
+            &usgs_drg,
+            &auto_maps)) {    // Found a match
+
+        // Allocate a new record
+        temp_record = (map_index_record *)malloc(sizeof(map_index_record));
+        CHECKMALLOC(temp_record);
+
+        // Fill in the values
+        xastir_snprintf(temp_record->filename,MAX_FILENAME,"%s",filename);
+        temp_record->bottom = bottom;
+        temp_record->top = top;
+        temp_record->left = left;
+        temp_record->right = right;
+        temp_record->max_zoom = max_zoom;
+        temp_record->min_zoom = min_zoom;
+        temp_record->map_layer = map_layer;
+        temp_record->draw_filled = draw_filled;
+        temp_record->usgs_drg = usgs_drg;
+        temp_record->auto_maps = auto_maps;
+        temp_record->selected = 1;  // Always, we already know this!
+        temp_record->accessed = 0;
+        temp_record->next = NULL;
+        temp_record->XmStringPtr = NULL;
+
+        // Now find the proper place for it and insert it in
+        // layer-order into the list.
+        current = map_sorted_list_head;
+        last = map_sorted_list_head;
+        done = 0;
+
+        // Possible cases:
+        // Empty list
+        // insert at beginning of list
+        // insert at end of list
+        // insert between other entries
+
+        if (map_sorted_list_head == NULL) {
+            // Empty list.  Insert record.
+            map_sorted_list_head = temp_record;
+            done++;
+        }
+        else if (map_layer < current->map_layer) {
+            // Insert at beginning of list
+            temp_record->next = current;
+            map_sorted_list_head = temp_record;
+            done++;
+        }
+        else {  // Need to insert between records or at end of list
+            while (!done && (current != NULL) ) {
+                if (map_layer >= current->map_layer) {  // Not to our layer yet
+                    last = current;
+                    current = current->next;    // May point to NULL now
+                }
+                else if (map_layer < current->map_layer) {
+                    temp_record->next = current;
+                    last->next = temp_record;
+                    done++;
+                }
+            }
+        }
+        // Handle running off the end of the list
+        if (!done && (current == NULL) ) {
+            last->next = temp_record;
+        }
+    }
+    else {
+        // We failed to find it in the map index
+    }
+}
+
+
+
+
+
+/**********************************************************
+ * load_auto_maps()
+ *
+ * NEW:  Uses the in-memory map_index to scan through the
+ * maps.
+ *
+ * OLD: Recurses through the map directories looking for
+ * maps to load.
+ **********************************************************/
+void load_auto_maps (Widget w, char *dir) {
+    map_index_record *current = map_index_head;
+    map_draw_flags mdf;
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        return;
+    }
+
+    // Skip the sorting of the maps if we don't need to do it
+    if (re_sort_maps) {
+
+        //fprintf(stderr,"*** Sorting the selected maps by layer...\n");
+
+        // Empty the sorted list first.  We'll create a new one.
+        empty_map_sorted_list();
+
+        // Run through the entire map_index linked list
+        while (current != NULL) {
+            if (auto_maps_skip_raster
+                    && (   strstr(current->filename,".geo")
+                        || strstr(current->filename,".GEO")
+                        || strstr(current->filename,".Geo")
+                        || strstr(current->filename,".tif")
+                        || strstr(current->filename,".TIF")
+                        || strstr(current->filename,".Tif"))) {
+                // Skip this map
+            }
+            else {  // Draw this map
+
+                //fprintf(stderr,"Loading: %s/%s\n",SELECTED_MAP_DIR,current->filename);
+
+                //WE7U
+                insert_map_sorted(current->filename);
+ 
+/*
+                draw_map (w,
+                    SELECTED_MAP_DIR,
+                    current->filename,
+                    NULL,
+                    '\0',
+                    DRAW_TO_PIXMAP);
+*/
+            }
+            current = current->next;
+        }
+
+        // All done sorting until something is changed in the Map
+        // Chooser.
+        re_sort_maps = 0;
+
+        //fprintf(stderr,"*** DONE sorting the selected maps.\n");
+    }
+
+    // We have the maps in sorted order.  Run through the list and
+    // draw them.  Only include those that have the auto_maps field
+    // set to 1.
+    current = map_sorted_list_head;
+    while  (current != NULL) {
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    if (disable_all_maps) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+        // Debug
+//        fprintf(stderr,"Drawing level:%05d, file:%s\n",
+//            current->map_layer,
+//            current->filename);
+
+        // Draw the maps in sorted-by-layer order
+        if (current->auto_maps) {
+
+            mdf.draw_filled = current->draw_filled;
+            mdf.usgs_drg = current->usgs_drg;
+
+            if (debug_level & 16)
+                fprintf(stderr,"load_auto_maps: Calling draw_map\n");
+
+            draw_map (w,
+                SELECTED_MAP_DIR,
+                current->filename,
+                NULL,
+                '\0',
+                DRAW_TO_PIXMAP,
+                &mdf);
+        }
+
+        current = current->next;
+    }
+}
+
+
+
+
+
+/*******************************************************************
+ * load_maps()
+ *
+ * Loads maps, draws grid, updates the display.
+ *
+ * We now create a linked list of maps in layer-order and use this
+ * list to draw the maps.  This preserves the correct ordering in
+ * all cases.  The layer to draw each map is specified in the
+ * map_index.sys file (fifth parameter).  Eventually code will be
+ * added to the Map Chooser in order to change the layer each map is
+ * drawn at.
+ *******************************************************************/
+void load_maps (Widget w) {
+    FILE *f;
+    char mapname[MAX_FILENAME];
+    int i;
+    char selected_dir[MAX_FILENAME];
+    map_index_record *current;
+    map_draw_flags mdf;
+    char selected_map_path[MAX_VALUE];
+
+    get_user_base_dir(SELECTED_MAP_DATA, selected_map_path, sizeof(selected_map_path));
+
+//    int dummy;
+
+
+    if (debug_level & 16)
+        fprintf(stderr,"Load maps start\n");
+
+    HandlePendingEvents(app_context);
+    if (interrupt_drawing_now) {
+        // Update to screen
+        (void)XCopyArea(XtDisplay(da),
+            pixmap,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+        return;
+    }
+
+    // Skip the sorting of the maps if we don't need to do it
+    if (re_sort_maps) {
+
+        //fprintf(stderr,"*** Sorting the selected maps by layer...\n");
+
+        // Empty the sorted list first.  We'll create a new one.
+        empty_map_sorted_list();
+ 
+        // Make sure the string is empty before we start
+        selected_dir[0] = '\0';
+
+        // Create empty file if it doesn't exist
+        (void)filecreate( selected_map_path );
+
+        f = fopen ( selected_map_path, "r" );
+        if (f != NULL) {
+            if (debug_level & 16)
+                fprintf(stderr,"Load maps Open map file\n");
+
+            while (!feof (f)) {
+
+                // Grab one line from the file
+                if ( fgets( mapname, MAX_FILENAME-1, f ) != NULL ) {
+
+                    // Forced termination (just in case)
+                    mapname[MAX_FILENAME-1] = '\0';
+
+                    // Get rid of the newline at the end
+                    for (i = strlen(mapname); i > 0; i--) {
+                        if (mapname[i] == '\n')
+                            mapname[i] = '\0'; 
+                    }
+
+                    if (debug_level & 16)
+                        fprintf(stderr,"Found mapname: %s\n", mapname);
+
+                    // Test for comment
+                    if (mapname[0] != '#') {
+
+
+                        // Check whether it's a directory that was
+                        // selected.  If so, save it in a special
+                        // variable and use that to match all the files
+                        // inside the directory.  Note that with the way
+                        // we have things ordered in the list, the
+                        // directories appear before their member files.
+                        if (mapname[strlen(mapname)-1] == '/') {
+                            int len;
+
+                            // Found a directory.  Save the name.
+                            xastir_snprintf(selected_dir,
+                                sizeof(selected_dir),
+                                "%s",
+                                mapname);
+
+                            len = strlen(mapname);
+
+//fprintf(stderr,"Selected %s directory\n",selected_dir);
+
+                            // Here we need to run through the map_index
+                            // list to find all maps that match the
+                            // currently selected directory.  Attempt to
+                            // load all of those maps as well.
+
+//fprintf(stderr,"Load all maps under this directory: %s\n",selected_dir);
+
+                            // Point to the start of the map_index list
+                            current = map_index_head;
+
+                            while (current != NULL) {
+
+                                if (strncmp(current->filename,selected_dir,len) == 0) {
+
+                                    if (current->filename[strlen(current->filename)-1] != '/') {
+
+//fprintf(stderr,"Loading: %s\n",current->filename);
+
+                                        //WE7U
+                                        insert_map_sorted(current->filename);
+
+/*
+                                        draw_map (w,
+                                            SELECTED_MAP_DIR,
+                                            current->filename,
+                                            NULL,
+                                            '\0',
+                                            DRAW_TO_PIXMAP);
+*/
+
+                                    }
+                                }
+                                current = current->next;
+                            }
+                        }
+                        // Else must be a regular map file
+                        else { 
+//fprintf(stderr,"%s\n",mapname);
+//start_timer();
+
+                            //WE7U
+                            insert_map_sorted(mapname);
+
+/*
+                            draw_map (w,
+                                SELECTED_MAP_DIR,
+                                mapname,
+                                NULL,
+                                '\0',
+                                DRAW_TO_PIXMAP);
+*/
+
+//stop_timer();
+//print_timer_results();
+
+                            if (debug_level & 16)
+                                fprintf(stderr,"Load maps -%s\n", mapname);
+
+                            XmUpdateDisplay (da);
+                        }
+                    }
+                }
+                else {  // We've hit EOF
+                    break;
+                }
+
+            }
+            (void)fclose (f);
+            statusline(" ",1);      // delete status line
+        }
+        else
+            fprintf(stderr,"Couldn't open file: %s\n", selected_map_path );
+
+        // All done sorting until something is changed in the Map
+        // Chooser.
+        re_sort_maps = 0;
+
+        //fprintf(stderr,"*** DONE sorting the selected maps.\n");
+    }
+
+
+    // We have the maps in sorted order.  Run through the list and
+    // draw them.
+    current = map_sorted_list_head;
+    while  (current != NULL) {
+
+        HandlePendingEvents(app_context);
+        if (interrupt_drawing_now) {
+            statusline(" ",1);      // delete status line
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+
+        if (disable_all_maps) {
+            // Update to screen
+            (void)XCopyArea(XtDisplay(da),
+                pixmap,
+                XtWindow(da),
+                gc,
+                0,
+                0,
+                (unsigned int)screen_width,
+                (unsigned int)screen_height,
+                0,
+                0);
+            return;
+        }
+ 
+        // Debug
+//        fprintf(stderr,"Drawing level:%05d, file:%s\n",
+//            current->map_layer,
+//            current->filename);
+
+        // Draw the maps in sorted-by-layer order
+        mdf.draw_filled = current->draw_filled;
+        mdf.usgs_drg = current->usgs_drg;
+
+        if (debug_level & 16)
+            fprintf(stderr,"load_maps: Calling draw_map\n");
+
+// Map profiling, set up for 800x600 window at "Map Profile Test
+// Site" bookmark.
+//
+// Loading "rd011802.shp" 500 times takes
+// 302->256->264->269->115->116 seconds.
+//
+// 100 times on PP200 takes 192->183 seconds.
+//
+//start_timer();
+//fprintf(stderr,"Calling draw_map() 500 times...\n");
+//for (dummy = 0; dummy < 500; dummy++) {
+        draw_map (w,
+            SELECTED_MAP_DIR,
+            current->filename,
+            NULL,
+            '\0',
+            DRAW_TO_PIXMAP,
+            &mdf);
+//}
+//stop_timer(); print_timer_results();
+
+        current = current->next;
+    }
+
+    if (debug_level & 16)
+        fprintf(stderr,"Load maps stop\n");
+}
+
+
diff --git a/src/maps.h b/src/maps.h
new file mode 100644
index 0000000..d3c2582
--- /dev/null
+++ b/src/maps.h
@@ -0,0 +1,230 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: maps.h,v 1.75 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef __XASTIR_MAPS_H
+#define __XASTIR_MAPS_H
+
+#include <X11/Intrinsic.h>
+#include <Xm/Xm.h>
+
+#define MAX_OUTBOUND 900
+#define MAX_MAP_POINTS 100000
+#define MAX_FILENAME 2000
+
+#define DRAW_TO_PIXMAP          0
+#define DRAW_TO_PIXMAP_FINAL    1
+#define DRAW_TO_PIXMAP_ALERTS   2
+#define INDEX_CHECK_TIMESTAMPS  9998
+#define INDEX_NO_TIMESTAMPS     9999
+
+
+/* memory structs */
+
+typedef struct {
+  unsigned char vector_start_color;
+  unsigned char object_behavior;
+  unsigned long longitude;
+  unsigned long latitude;
+} map_vectors;
+
+typedef struct {
+  unsigned long longitude;
+  unsigned long latitude;
+  unsigned int mag;
+  char label_text[33];
+  unsigned char text_color_quad;
+} text_label;
+
+typedef struct {
+  unsigned long longitude;
+  unsigned long latitude;
+  unsigned int mag;
+  unsigned char symbol;
+  unsigned char aprs_symbol;
+  unsigned char text_color;
+  char label_text[30];
+} symbol_label;
+
+typedef struct _map_index_record{
+    char filename[MAX_FILENAME];
+    XmString XmStringPtr;
+    unsigned long bottom;
+    unsigned long top;
+    unsigned long left;
+    unsigned long right;
+    int accessed;
+    int max_zoom;       // Specify maximum zoom at which this layer is drawn.
+    int min_zoom;       // Specify minimum zoom at which this layer is drawn.
+    int map_layer;      // Specify which layer to draw the map on.
+    int draw_filled;    // Specify whether to fill polygons when drawing.
+                        // 0 = Global No-Fill (Vector)
+                        // 1 = Global Fill
+                        // 2 = Auto (dbfawk controls it if present)
+    int usgs_drg;       // Specify whether the map has USGS DRG colormap
+                        // and should have color configuration applied
+                        // 0 = No
+                        // 1 = Yes
+                        // 2 = Auto (detect from TIFFTAG_IMAGEDESCRIPTION)
+    int selected;       // Specifies if map is currently selected
+    int temp_select;    // Temporary selection used in map properties dialog
+    int auto_maps;      // Specifies if map included in automaps function
+    struct _map_index_record *next;
+} map_index_record;
+extern map_index_record *map_index_head;
+
+typedef struct {
+    int img_x;
+    int img_y;
+    unsigned long x_long;
+    unsigned long y_lat;
+} tiepoint;
+
+void draw_point(Widget w,
+                 unsigned long x1,
+                 unsigned long y1,
+                 GC gc,
+                 Pixmap which_pixmap,
+                 int skip_duplicates);
+
+void draw_point_ll(Widget w,
+                 float y1,
+                 float x1,
+                 GC gc,
+                 Pixmap which_pixmap,
+                 int skip_duplicates);
+
+void draw_vector(Widget w,
+                 unsigned long x1,
+                 unsigned long y1,
+                 unsigned long x2,
+                 unsigned long y2,
+                 GC gc,
+                 Pixmap which_pixmap,
+                 int skip_duplicates);
+
+void draw_vector_ll(Widget w,
+                 float y1,
+                 float x1,
+                 float y2,
+                 float x2,
+                 GC gc,
+                 Pixmap which_pixmap,
+                 int skip_duplicates);
+
+char *get_map_ext (char *filename);
+char *get_map_dir (char *fullpath);
+void load_auto_maps(Widget w, char *dir);
+void load_maps(Widget w);
+void fill_in_new_alert_entries(void);
+void load_alert_maps(Widget w, char *dir);
+void  index_update_xastir(char *filename, unsigned long bottom, unsigned long top, unsigned long left, unsigned long right, int default_map_layer);
+void  index_update_ll(char *filename, double bottom, double top, double left, double right, int default_map_layer);
+extern void get_horizontal_datum(char *datum, int sizeof_datum);
+void draw_grid (Widget w);
+void Snapshot(void);
+extern int index_retrieve(char *filename, unsigned long *bottom,
+    unsigned long *top, unsigned long *left, unsigned long *right,
+    int *max_zoom, int *min_zoom, int *map_layer, int *draw_filled, 
+    int *usgs_drg, int *automaps);
+extern void index_restore_from_file(void);
+extern void index_save_to_file(void);
+extern void map_indexer(int parameter);
+extern void get_viewport_lat_lon(double *xmin, 
+                                 double *ymin, 
+                                 double *xmax,
+                                 double *ymax);
+extern int map_visible (unsigned long bottom_map_boundary,
+                        unsigned long top_map_boundary,
+                        unsigned long left_map_boundary,
+                        unsigned long right_map_boundary);
+extern int map_visible_lat_lon (double f_bottom_map_boundary,
+                                double f_top_map_boundary,
+                                double f_left_map_boundary,
+                                double f_right_map_boundary);
+extern int map_inside_viewport_lat_lon(double map_min_y,
+                                       double map_max_y,
+                                       double map_min_x,
+                                       double map_max_x);
+extern void draw_label_text (Widget w, int x, int y, int label_length, int color, char *label_text);
+extern void draw_rotated_label_text (Widget w, int rotation, int x, int y, int label_length, int color, char *label_text, int fontsize);
+extern int get_rotated_label_text_length_pixels(Widget w, char *label_text, int fontsize);
+extern void draw_centered_label_text (Widget w, int rotation, int x, int y, int label_length, int color, char *label_text, int fontsize);
+extern void  Monochrome( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData);
+extern void Snapshot(void);
+extern void clean_string(char *input);
+extern int print_rotated;
+extern int print_auto_rotation;
+extern int print_auto_scale;
+extern int print_in_monochrome;
+extern int print_invert;
+extern char printer_program[MAX_FILENAME+1];
+extern char previewer_program[MAX_FILENAME+1];
+
+extern int  gnis_locate_place(Widget w, char *name, char *state,
+char *county, char *quad, char* type, char *filename, int
+follow_case, int get_match, char match_array_name[50][200], long
+match_array_lat[50], long match_array_long[50]);
+
+extern int  pop_locate_place(Widget w, char *name, char *state,
+char *county, char *quad, char* type, char *filename, int
+follow_case, int get_match, char match_array_name[50][200], long
+match_array_lat[50], long match_array_long[50]);
+
+
+extern void maps_init(void);
+enum map_onscreen_enum {MAP_NOT_VIS=0,MAP_IS_VIS,MAP_NOT_INDEXED};
+extern enum map_onscreen_enum map_onscreen(long left, long right, long top, long bottom, int checkpercentage);
+extern enum map_onscreen_enum map_onscreen_index(char *filename);
+extern time_t last_snapshot;
+extern time_t last_kmlsnapshot;
+extern int snapshot_interval;
+
+extern int grid_size;
+
+#if !defined(NO_GRAPHICS)
+  #if defined(HAVE_MAGICK)
+    extern float imagemagick_gamma_adjust;
+  #endif    // HAVE_MAGICK
+#endif  // NO_GRAPHICS
+
+extern float raster_map_intensity;
+ 
+extern void Print_Postscript(Widget widget, XtPointer clientData, XtPointer callData);
+
+extern void map_plot (Widget w, long max_x, long max_y, long x_long_cord, long y_lat_cord, unsigned char color, long object_behavior, int destination_pixmap, int draw_filled); 
+
+extern void map_gdal_init(void);
+
+// A struct to pass down in to map driver functions so they can have 
+// driver-specific flags.  Most drivers won't care about any (or even all)
+// of the flags, but this way we can just pass a single pointer rather than
+// adding new arguments to the generic interface each time we want new flags
+typedef struct {
+    int draw_filled;
+    int usgs_drg;
+} map_draw_flags;
+
+#endif /* __XASTIR_MAPS_H */
+
+
diff --git a/src/messages.c b/src/messages.c
new file mode 100644
index 0000000..b134964
--- /dev/null
+++ b/src/messages.c
@@ -0,0 +1,1480 @@
+/*
+ * $Id: messages.c,v 1.80 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <Xm/XmAll.h>
+#include <X11/Xatom.h>
+#include <X11/Shell.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#else
+#  include <strings.h>
+#endif
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include "xastir.h"
+#include "main.h"
+#include "messages.h"
+#include "util.h"
+#include "interface.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+char group_data_file[400];
+char *group_data_list = NULL;   // Need this NULL for Solaris!
+int  group_data_count = 0;
+int  group_data_max = 0;
+
+char message_counter[5+1];
+
+int auto_reply;
+char auto_reply_message[100];
+
+Message_Window mw[MAX_MESSAGE_WINDOWS+1];   // Send Message widgets
+
+Message_transmit message_pool[MAX_OUTGOING_MESSAGES+1]; // Transmit message queue
+
+
+
+
+
+void clear_message_windows(void) {
+    int i;
+
+begin_critical_section(&send_message_dialog_lock, "messages.c:clear_message_windows" );
+
+    for (i = 0;  i < MAX_MESSAGE_WINDOWS; i++) {
+
+        if (mw[i].send_message_dialog)
+            XtDestroyWidget(mw[i].send_message_dialog);
+
+        mw[i].send_message_dialog = (Widget)NULL;
+        mw[i].to_call_sign[0] = '\0';
+        mw[i].send_message_call_data = (Widget)NULL;
+        mw[i].D700_mode = (Widget)NULL;
+        mw[i].D7_mode = (Widget)NULL;
+        mw[i].HamHUD_mode = (Widget)NULL;
+        mw[i].message_data_line1 = (Widget)NULL;
+        mw[i].message_data_line2 = (Widget)NULL;
+        mw[i].message_data_line3 = (Widget)NULL;
+        mw[i].message_data_line4 = (Widget)NULL;
+        mw[i].send_message_text = (Widget)NULL;
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages.c:clear_message_windows" );
+
+}
+
+
+
+
+
+static int group_comp(const void *a, const void *b) {
+    if (!*(char *)a)
+        return ((int)(*(char *)b != '\0'));
+    return strcasecmp(a, b);
+}
+
+
+
+
+
+void group_build_list(char *filename) {
+    char *ptr;
+    FILE *f;
+    struct stat group_stat;
+    int i;
+
+    if (group_data_count == group_data_max) {
+        ptr = realloc(group_data_list, (size_t)(group_data_max+10)*10);
+
+        if (ptr) {
+            group_data_list = ptr;
+            group_data_max += 10;
+
+//fprintf(stderr,                "group_data_max: %d\n", group_data_max);
+
+        }
+        else {
+            fprintf(stderr,
+                "Unable to allocate more memory for group_data_list (1)\n");
+        }
+    }
+
+
+// Make sure we always listen for ourself, XASTIR, & our Version groups
+    xastir_snprintf(&group_data_list[0],10,"%s",my_callsign);
+    xastir_snprintf(&group_data_list[10],10,"XASTIR");
+    xastir_snprintf(&group_data_list[20],10,"%s",XASTIR_TOCALL);
+    group_data_count = 3;
+// If we are in special group look for messages.
+    if (altnet) {
+        xastir_snprintf(&group_data_list[group_data_count*10],10,"%s",altnet_call);
+        group_data_count++;
+    }
+//
+
+    if (! stat(filename, &group_stat) )
+        f = fopen(filename, "r");   // File exists
+    else
+        f = fopen(filename, "w+");  // No file.  Create it and open it.
+
+    if (f == NULL) {
+        fprintf(stderr,"Couldn't open file for reading -or- appending: %s\n", filename);
+        return;
+    }
+
+    while (!feof(f)) {
+        if (group_data_count == group_data_max) {
+            ptr = realloc(group_data_list, (size_t)(group_data_max+10)*10);
+            if (ptr) {
+                group_data_list = ptr;
+                group_data_max += 10;
+
+//fprintf(stderr,                "group_data_max(2): %d\n", group_data_max);
+
+            }
+            else {
+                fprintf(stderr,
+                    "Unable to allocate more memory for group_data_list (2)\n");
+            }
+        }
+        if (group_data_count < group_data_max) {
+            group_data_list[group_data_count*10] = '\0';
+            (void)fgets(&group_data_list[group_data_count*10], 10, f);
+            if ((ptr = strchr(&group_data_list[group_data_count*10], '\n')))
+                *ptr = '\0';
+            else
+                while ((i = fgetc(f)) != EOF && i != '\n'); // clean-up after long group name
+
+	// check for DOS EOL markup!
+            if ((ptr = strchr(&group_data_list[group_data_count*10], '\r')))
+                *ptr = '\0';
+            if (group_data_list[group_data_count*10])
+                group_data_count++;
+        }
+    }
+    (void)fclose(f);
+    qsort(group_data_list, (size_t)group_data_count, 10, group_comp);
+
+    if (debug_level & 2) {
+        for (i = 0; i < group_data_count; i++)
+            fprintf(stderr,"Group %2d: %s\n", i, &group_data_list[i*10]);
+    }
+}
+
+
+
+
+
+int group_active(char *from) {
+    static struct stat current_group_stat;
+    struct stat group_stat;
+    static char altgroup[10];
+    char group_data_path[MAX_VALUE];
+
+    get_user_base_dir(group_data_file, group_data_path, 
+                      sizeof(group_data_path));
+
+    (void)remove_trailing_spaces(from);
+
+    // If we cycle to/from special group or file changes, rebuild group list.
+    if ((!stat( group_data_path, &group_stat )
+            && (current_group_stat.st_size != group_stat.st_size
+                || current_group_stat.st_mtime != group_stat.st_mtime
+                || current_group_stat.st_ctime != group_stat.st_ctime))) {
+
+// altgroup equates to "address of altgroup" which always evaluates
+// as true.  Commenting it out of the conditional.  --we7u.
+//                || (altgroup && strcasecmp(altgroup, VERSIONFRM))) {
+
+        group_build_list( group_data_path );
+        current_group_stat = group_stat;
+        xastir_snprintf(altgroup,sizeof(altgroup),"%s",VERSIONFRM);
+    }
+    if (group_data_list != NULL)    // Causes segfault on Solaris 2.5 without this!
+        return (int)(bsearch(from, group_data_list, (size_t)group_data_count, (size_t)10, group_comp) != NULL);
+    else
+        return(0);
+}
+
+
+
+
+
+int look_for_open_group_data(char *to) {
+    int i,found;
+    char temp1[MAX_CALLSIGN+1];
+    char *temp_ptr;
+
+
+begin_critical_section(&send_message_dialog_lock, "messages.c:look_for_open_group_data" );
+
+    found = FALSE;
+     for(i = 0; i < MAX_MESSAGE_WINDOWS; i++) {
+        /* find station  */
+        if(mw[i].send_message_dialog != NULL) {
+
+            temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data);
+            xastir_snprintf(temp1,
+                sizeof(temp1),
+                "%s",
+                temp_ptr);
+            XtFree(temp_ptr);
+
+            (void)to_upper(temp1);
+            /*fprintf(stderr,"Looking at call <%s> for <%s>\n",temp1,to);*/
+            if(strcmp(temp1,to)==0) {
+                found=(int)TRUE;
+                break;
+            }
+        }
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages.c:look_for_open_group_data" );
+
+    return(found);
+}
+
+
+
+
+
+// What we wish to do here:  Check for an active Send Message dialog
+// that contains the callsign of interest.  If one doesn't exist,
+// create one and pop it up.  We don't want to do this for duplicate
+// message lines or duplicate acks for any particular QSO.  To do so
+// would cause the Send Message dialog to pop up on every such
+// received message, which is VERY annoying (that was the default in
+// Xastir for years, and nobody liked it!).
+//
+int check_popup_window(char *from_call_sign, int group) {
+    int i,found,j,ret;
+    char temp1[MAX_CALLSIGN+1];
+    char *temp_ptr;
+
+
+//fprintf(stderr,"\tcheck_popup_window()\n");
+
+    ret = -1;
+    found = -1;
+
+begin_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window" );
+
+    // Check for an already-created dialog for talking to this
+    // particular call_sign.
+    //
+    for (i = 0; i < MAX_MESSAGE_WINDOWS; i++) {
+
+        if (mw[i].send_message_dialog != NULL) { // If dialog created
+
+            temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data);
+            xastir_snprintf(temp1,
+                sizeof(temp1),
+                "%s",
+                temp_ptr);
+            XtFree(temp_ptr);
+
+            /*fprintf(stderr,"Looking at call <%s> for <%s>\n",temp1,from_call_sign);*/
+            if (strcasecmp(temp1, from_call_sign) == 0) {
+                // Found a call_sign match in a Send Message dialog!
+
+//fprintf(stderr,"\tFound a Send_message dialog match\n");
+
+                found = i;
+                break;
+            }
+        }
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window" );
+
+    // If found == -1 at this point, we haven't found a Send Message
+    // dialog that contains the call_sign of interest.
+    //
+    if (found == -1 && (group == 2 || group_active(from_call_sign))) {
+        /* no window found Open one! */
+
+//fprintf(stderr,"\tNo Send Message dialog found, creating one\n");
+
+begin_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window2" );
+
+        i= -1;
+        for (j=0; j<MAX_MESSAGE_WINDOWS; j++) {
+            if (!mw[j].send_message_dialog) {
+                i=j;
+                break;
+            }
+        }
+
+end_critical_section(&send_message_dialog_lock, "messages.c:check_popup_window2" );
+
+        if (i!= -1) {
+
+            if (group == 1) {
+                temp1[0] = '*';
+                temp1[1] = '\0';
+            }
+            else {
+                temp1[0] = '\0';
+            }
+
+            strncat(temp1,
+                from_call_sign,
+                sizeof(temp1) - 1 - strlen(temp1));
+
+            if (!disable_all_popups) {
+                Send_message(appshell, temp1, NULL);
+            }
+
+            update_messages(1);
+
+            ret=i;
+        }
+        else {
+            fprintf(stderr,"No open windows!\n");
+        }
+    }
+    else {
+        /* window open! */
+        // Pop it up
+        ret=found;
+    }
+
+    if (found != -1) {  // Already have a window
+        XtPopup(mw[i].send_message_dialog,XtGrabNone);
+    }
+
+    return(ret);
+}
+
+
+
+
+
+void clear_outgoing_message(int i) {
+    message_pool[i].active=MESSAGE_CLEAR;
+    message_pool[i].to_call_sign[0] = '\0';
+    message_pool[i].from_call_sign[0] = '\0';
+    message_pool[i].message_line[0] = '\0';
+    message_pool[i].seq[0] = '\0';
+    message_pool[i].active_time=0;;
+    message_pool[i].next_time=0l;
+    message_pool[i].tries=0;
+}
+
+
+
+
+
+// Clear all pending transmit messages that are from us and to the
+// callsign listed.  Perhaps it'd be better to time it out instead
+// so that it still shows up in the message window?  Here we just
+// erase it.
+//
+void clear_outgoing_messages_to(char *callsign) {
+    int ii;
+
+
+//    fprintf(stderr,"Callsign: %s\n", callsign);
+
+    // Run through the entire outgoing message queue
+    for (ii = 0; ii < MAX_OUTGOING_MESSAGES; ii++) {
+
+        // If it matches the callsign we're talking to
+        if (strcasecmp(message_pool[ii].to_call_sign,callsign) == 0) {
+
+            // Record a fake ack and add "*CANCELLED*" to the
+            // message.  This will be displayed in the Send Message
+            // dialog.
+            msg_record_ack(message_pool[ii].to_call_sign,
+                message_pool[ii].from_call_sign,
+                message_pool[ii].seq,
+                0,  // Not a timeout
+                1); // Record a cancel
+ 
+            // Clear it out.
+            message_pool[ii].active=MESSAGE_CLEAR;
+            message_pool[ii].to_call_sign[0] = '\0';
+            message_pool[ii].from_call_sign[0] = '\0';
+            message_pool[ii].message_line[0] = '\0';
+            message_pool[ii].seq[0] = '\0';
+            message_pool[ii].active_time=0;;
+            message_pool[ii].next_time=0l;
+            message_pool[ii].tries=0;
+        }
+    }
+}
+
+
+
+
+
+// Change path on all pending transmit messages that are from us and
+// to the callsign listed.
+//
+void change_path_outgoing_messages_to(char *callsign, char *new_path) {
+    int ii;
+    char my_callsign[20];
+
+
+//fprintf(stderr,
+//    "Changing all outgoing msgs to %s to new path: %s\n",
+//    callsign,
+//    new_path);
+
+    xastir_snprintf(my_callsign,
+        sizeof(my_callsign),
+        "%s",
+        callsign);
+
+    remove_trailing_spaces(my_callsign);
+
+    // Run through the entire outgoing message queue
+    for (ii = 0; ii < MAX_OUTGOING_MESSAGES; ii++) {
+
+        if (message_pool[ii].active == MESSAGE_ACTIVE) {
+ 
+//fprintf(stderr,"\t'%s'\n\t'%s'\n",
+//    message_pool[ii].to_call_sign,
+//    my_callsign);
+
+            // If it matches the callsign we're talking to
+            if (strcasecmp(message_pool[ii].to_call_sign,my_callsign) == 0) {
+
+//fprintf(stderr,"\tFound an outgoing queued msg to change path on.\n");
+
+                xastir_snprintf(message_pool[ii].path,
+                    sizeof(message_pool[ii].path),
+                    "%s",
+                    new_path);
+            }
+        }
+    }
+}
+
+
+
+
+
+time_t last_check_and_transmit = (time_t)0l;
+
+
+// Kick the interval timer back to 7 and tries back to 1 for
+// messages in this QSO.  Used to get a QSO going again when the
+// interval timer has gotten large, but the message is important to
+// get through quickly.
+//
+void kick_outgoing_timer(char *callsign) {
+    int ii;
+
+
+//    fprintf(stderr,"Callsign: %s\n", callsign);
+
+    // Run through the entire outgoing message queue
+    for (ii = 0; ii < MAX_OUTGOING_MESSAGES; ii++) {
+
+        // If it matches the callsign we're talking to
+        if (strcasecmp(message_pool[ii].to_call_sign,callsign) == 0) {
+            message_pool[ii].next_time = (time_t)7l;
+            message_pool[ii].tries = 0;
+            message_pool[ii].active_time = (time_t)0l;
+        }
+    }
+
+    // Cause the transmit routine to get called again
+    last_check_and_transmit = (time_t)0l;
+}
+
+
+
+
+
+void reset_outgoing_messages(void) {
+    int i;
+
+    for(i=0;i<MAX_OUTGOING_MESSAGES;i++)
+        clear_outgoing_message(i);
+}
+
+
+
+
+
+void clear_outgoing_messages(void) {
+    int i;
+
+    for (i=0;i<MAX_OUTGOING_MESSAGES;i++)
+        clear_outgoing_message(i);
+
+begin_critical_section(&send_message_dialog_lock, "messages.c:clear_outgoing_messages" );
+
+    /* clear message send buttons */
+    for (i=0;i<MAX_MESSAGE_WINDOWS;i++) {
+        /* find station  */
+//        if (mw[i].send_message_dialog!=NULL) /* clear submit */
+//            XtSetSensitive(mw[i].button_ok,TRUE);
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages.c:clear_outgoing_messages" );
+
+}
+
+
+
+
+
+// Bumps message sequence ID up to the next value.
+//
+// Roll over message_counter if we hit the max.  Now with Reply/Ack
+// protocol the max is only two characters worth.  We changed to
+// sending the sequence number in Base-?? format in order to get
+// more range from the 2-character variable.
+//
+int bump_message_counter(char *message_counter) {
+
+    int bump_warning = 0;
+    message_counter[2] = '\0';  // Terminate at 2 chars
+
+    // Increment the least significant digit
+    message_counter[1]++;
+
+    // Span the gaps between the correct ranges
+    if (message_counter[1] == ':')
+        message_counter[1] = 'A';
+
+    if (message_counter[1] == '[')
+        message_counter[1] = 'a';
+
+    if (message_counter[1] == '{') {
+        message_counter[1] = '0';
+        message_counter[0]++;   // Roll over to next char
+    }
+
+    // Span the gaps between the correct ranges
+    if (message_counter[0] == ':')
+        message_counter[0] = 'A';
+
+    if (message_counter[0] == '[')
+        message_counter[0] = 'a';
+
+    if (message_counter[0] == '{') {
+        message_counter[0] = '0';
+        bump_warning = 1;
+    }
+    return bump_warning;
+}
+
+
+
+
+
+// Adds a message to the outgoing message queue.  Doesn't actually
+// cause a transmit.  "check_and_transmit_messages()" is the
+// function which actually gets things moving.
+//
+// We also stuff the message into the main message queue so that the
+// queued messages will appear in the Send Message box.
+//
+void output_message(char *from, char *to, char *message, char *path) {
+    int ok,i,j;
+    char message_out[MAX_MESSAGE_OUTPUT_LENGTH+1+5+1]; // +'{' +msg_id +terminator
+    int last_space, message_ptr, space_loc;
+    int wait_on_first_ack;
+    int error;
+    long record;
+
+
+//fprintf(stderr,"output_message:%s\n", message);
+
+    message_ptr=0;
+    last_space=0;
+    ok=0;
+    error=0;
+
+    if (debug_level & 2)
+        fprintf(stderr,"Output Message from <%s>  to <%s>\n",from,to);
+
+    // Repeat until we process the entire message.  We'll process it
+    // a chunk at a time, size of chunk to correspond to max APRS
+    // message line length.
+    //
+    while (!error && (message_ptr < (int)strlen(message))) {
+        ok=0;
+        space_loc=0;
+
+        // Break a long message into smaller chunks that can be
+        // processed into APRS messages.  Break at a space character
+        // if possible.
+        //
+        for (j=0; j<MAX_MESSAGE_OUTPUT_LENGTH; j++) {
+
+            if(message[j+message_ptr] != '\0') {
+
+                if(message[j+message_ptr]==' ') {
+                    last_space=j+message_ptr+1;
+                    space_loc=j;
+                }
+
+                if (j!=MAX_MESSAGE_OUTPUT_LENGTH) {
+                    message_out[j]=message[j+message_ptr];
+                    message_out[j+1] = '\0';
+                }
+                else {
+
+                    if(space_loc!=0)
+                        message_out[space_loc] = '\0';
+                    else
+                        last_space=j+message_ptr;
+                }
+            }
+            else {
+                j=MAX_MESSAGE_OUTPUT_LENGTH+1;
+                last_space=strlen(message)+1;
+            }
+        }
+
+//fprintf(stderr,"message_out: %s\n", message_out);
+
+        if (debug_level & 2)
+            fprintf(stderr,"MESSAGE <%s> %d %d\n",message_out,message_ptr,last_space);
+
+        if (j >= MAX_MESSAGE_OUTPUT_LENGTH) {
+            message_ptr = MAX_MESSAGE_OUTPUT_LENGTH;
+        }
+        else {
+            message_ptr=last_space;
+        }
+
+        /* check for others in the queue */
+        wait_on_first_ack=0;
+        for (i=0; i<MAX_OUTGOING_MESSAGES; i++) {
+            if (message_pool[i].active == MESSAGE_ACTIVE
+                    && strcmp(to, message_pool[i].to_call_sign) == 0
+                    && strcmp(from, "***") != 0) {
+                wait_on_first_ack=1;
+                i=MAX_OUTGOING_MESSAGES+1;  // Done with loop
+            }
+        }
+
+        for (i=0; i<MAX_OUTGOING_MESSAGES && !ok ;i++) {
+            /* Check for clear position*/
+            if (message_pool[i].active==MESSAGE_CLEAR) {
+                /* found a spot */
+                ok=1;
+
+                // Increment the message sequence ID variable
+                if (bump_message_counter(message_counter)) 
+		   fprintf(stderr, "!WARNING!: Wrap around Message Counter");
+
+
+// Note that Xastir's messaging can lock up if we do a rollover and
+// have unacked messages on each side of the rollover.  This is due
+// to the logic in db.c that looks for the lowest numbered unacked
+// message.  We get stuck on both sides of the fence at once.  To
+// avoid this condition we could reduce the compare number (8100) to
+// a smaller value, and only roll over when there are no unacked
+// messages?  Another way to do it would be to write a "0" to the
+// config file if we're more than 1000 when we quit Xastir?  That
+// would probably be easier.  It's still possible to get to 8100
+// messages during one runtime though.  Unlikely, but possible.
+
+                message_pool[i].active = MESSAGE_ACTIVE;
+                message_pool[i].wait_on_first_ack = wait_on_first_ack;
+                xastir_snprintf(message_pool[i].to_call_sign,
+                    sizeof(message_pool[i].to_call_sign),
+                    "%s",
+                    to);
+                xastir_snprintf(message_pool[i].from_call_sign,
+                    sizeof(message_pool[i].from_call_sign),
+                    "%s",
+                    from);
+                xastir_snprintf(message_pool[i].message_line,
+                    sizeof(message_pool[i].message_line),
+                    "%s",
+                    message_out);
+
+                if (path != NULL)
+                    xastir_snprintf(message_pool[i].path,
+                        sizeof(message_pool[i].path),
+                        "%s",
+                        path);
+                else
+                    message_pool[i].path[0] = '\0';
+
+//                // We compute the base-90 sequence number here
+//                // This allows it to range from "!!" to "zz"
+//                xastir_snprintf(message_pool[i].seq,
+//                    sizeof(message_pool[i].seq),
+//                    "%c%c",
+//                    (char)(((message_counter / 90) % 90) + 33),
+//                    (char)((message_counter % 90) + 33));
+
+                xastir_snprintf(message_pool[i].seq,
+                    sizeof(message_pool[i].seq),
+                    "%c%c",
+                    message_counter[0],
+                    message_counter[1]);
+
+                message_pool[i].active_time=0;
+                message_pool[i].next_time = (time_t)7l;
+
+                if (strcmp(from,"***")!= 0)
+                    message_pool[i].tries = 0;
+                else
+                    message_pool[i].tries = MAX_TRIES-1;
+
+                // Cause the message to get added to the main
+                // message queue as well, with the proper sequence
+                // number, so queued messages will appear in the
+                // Send Message box as unacked messages.
+                //
+
+// We must get rid of the lock we already have for a moment, as
+// update_messages(), which is called by msg_data_add(), also snags
+// this lock.
+end_critical_section(&send_message_dialog_lock, "db.c:update_messages" );
+
+                (void)msg_data_add(to,
+                    from,
+                    message_out,
+                    message_pool[i].seq,
+                    MESSAGE_MESSAGE,
+                    'L',    // From the Local system
+                    &record);
+/*
+                fprintf(stderr,"msg_data_add %s %s %s %s\n",
+                    to,
+                    from,
+                    message_out,
+                    message_pool[i].seq);
+*/
+
+// Regain the lock we had before
+begin_critical_section(&send_message_dialog_lock, "db.c:update_messages" );
+
+            }
+        }
+        if(!ok) {
+            fprintf(stderr,"Output message queue is full!\n");
+            error=1;
+        }
+    }
+}
+
+
+
+
+
+// Here we're doing some routing of the transmitted packets.  We
+// want to keep Xastir from transmitting on ports that aren't
+// actively being used in the QSO, but also cover the case where
+// ports can go up/down during the QSO.
+//
+// Note that igates might get into the act quite a bit for RF<->RF
+// QSO's if we're sending to the internet too, but that's a bug in
+// the igate software, and not something that Xastir should try to
+// correct itself.
+//
+void transmit_message_data(char *to, char *message, char *path) {
+    DataRow *p_station;
+
+    if (debug_level & 2)
+        fprintf(stderr,"Transmitting data to %s : %s\n",to,message);
+
+    p_station = NULL;
+
+
+    if (strcmp(to, my_callsign) == 0) { // My station message
+
+        // Send out all active ports
+
+        if (debug_level & 2)
+            fprintf(stderr,"My call VIA any way\n");
+
+        output_my_data(message,-1,0,0,0,path);
+
+        // All done 
+        return;
+    }
+
+
+    if (!search_station_name(&p_station,to,1)) {
+
+        // No data record found for this station.  Send to all
+        // active ports.
+
+        if (debug_level & 2)
+            fprintf(stderr,"VIA any way\n");
+
+        output_my_data(message,-1,0,0,0,path);
+
+        // All done
+        return;
+    }
+
+
+    if (debug_level & 2)
+        fprintf(stderr,"found station %s\n",p_station->call_sign);
+
+
+    // It's not being sent to my callsign but to somebody else
+    // "out there".  Because the truth is...
+
+
+    if ( ((p_station->flag & ST_VIATNC) != 0)
+            && (heard_via_tnc_in_past_hour(to)) ) {
+
+        int port_num;
+
+
+        // Station was heard via a TNC port within the previous
+        // hour.  Send to TNC port it was heard on.
+        // 
+        output_my_data(message,p_station->heard_via_tnc_port,0,0,0,path);
+
+        // Send to all internet ports.  Iterate through the port
+        // definitions looking for internet ports, send the message
+        // out once to each.
+        //
+        for (port_num = 0; port_num < MAX_IFACE_DEVICES; port_num++) {
+
+            // If it's an internet port, send the message.
+            if (port_data[port_num].device_type == DEVICE_NET_STREAM) {
+                output_my_data(message,port_num,0,0,0,path);
+            }
+        }
+
+        // All done
+        return;
+    }
+
+    else if (p_station->data_via==DATA_VIA_NET) {
+        int port_num;
+        int active_internet_ports_found = 0;
+
+
+        // Station was heard over an internet interface.  Check
+        // whether we have any internet interfaces available with TX
+        // enabled.  If so, send out those ports.  Else drop through
+        // and hit the TRANSMIT-ALL clause at the end of this
+        // function.
+
+        // Iterate through the port definitions looking for internet
+        // ports with transmit enabled.  Send the message out once
+        // to each.
+        //
+        for (port_num = 0; port_num < MAX_IFACE_DEVICES; port_num++) {
+
+            // If it's an internet port and transmit is enabled,
+            // send the message and set the flag.
+            if ( (port_data[port_num].device_type == DEVICE_NET_STREAM)
+                    && (port_data[port_num].active == DEVICE_IN_USE)
+                    && (port_data[port_num].status == DEVICE_UP)
+                    && (devices[port_num].transmit_data == 1) ) {
+
+                // Found a tx-enabled internet port that was up and
+                // running.  Send the message out this port.
+                output_my_data(message,port_num,0,0,0,path);
+
+                active_internet_ports_found++;
+            }
+        }
+
+        if (active_internet_ports_found) {
+            // We found at least one tx-enabled internet interface
+            // that was up and running.
+
+            // All done.
+            return;
+        }
+        else {  // No active tx-enabled internet ports were found.
+                // Drop through to the TRANSMIT-ALL clause below.
+        } 
+    }
+
+
+    // We've NOT heard this station on a TNC port within the
+    // last hour and have no active tx-enabled internet ports to
+    // send to.  Send to ALL active ports.
+
+    if (debug_level & 2)
+        fprintf(stderr,"VIA any way\n");
+
+    output_my_data(message,-1,0,0,0,path);
+}
+
+
+
+
+
+// The below variables and functions implement the capability to
+// schedule ACK's some number of seconds out from the current time.
+// We use it to schedule duplicate ACK's at 30/60/120 seconds out,
+// but only if we see duplicate message lines from remote stations.
+//
+// Create a struct to hold the delayed ack's.
+typedef struct _delayed_ack_record {
+    char to_call_sign[MAX_CALLSIGN+1];
+    char message_line[MAX_MESSAGE_OUTPUT_LENGTH+1+5+1];
+    char path[200];
+    time_t active_time;
+    struct _delayed_ack_record *next;
+} delayed_ack_record, *delayed_ack_record_p;
+
+// And a pointer to a list of them.
+    delayed_ack_record_p delayed_ack_list_head = NULL;
+
+
+void transmit_message_data_delayed(char *to, char *message,
+                                   char *path, time_t when) {
+    delayed_ack_record_p ptr = delayed_ack_list_head;
+
+
+    // We need to run down the current list looking for any records
+    // that are identical and within 30 seconds time-wise of this
+    // one.  If so, don't allocate a new record.  This keeps the
+    // dupes down on transmit so that at the most we transmit one
+    // ack per 30 seconds per QSO, except of course for real-time
+    // ack's which don't go through this function.
+
+    // Run through the queue and check each record
+    while (ptr != NULL) {
+
+        if ( strcmp(ptr->to_call_sign,to) == 0
+                && strcmp(ptr->message_line,message) == 0 ) {
+
+            //
+            // We have matches on call_sign and message.  Check the
+            // time next.
+            //
+            if (abs(when - ptr->active_time) < 30) {
+                //
+                // We're within 30 seconds of an identical ack.
+                // Drop this new one (don't add it).
+                //
+
+//fprintf(stderr,"Dropping delayed ack: Too close timewise to another: %s, %s\n",
+//    to, message);
+
+                return; // Don't allocate new record on queue
+            }
+        }
+        ptr = ptr->next;
+    }
+
+    // If we made it to here, there aren't any queued ACK's that are
+    // close enough in time to drop this new one.  Add it to the
+    // queue.
+
+//fprintf(stderr, "Queuing ACK for delayed transmit: %s, %s\n",
+//    to, message);
+
+    // Allocate a record to hold it
+    ptr = (delayed_ack_record_p)malloc(sizeof(delayed_ack_record));
+
+    // Fill in the record
+    xastir_snprintf(ptr->to_call_sign,
+        sizeof(ptr->to_call_sign),
+        "%s",
+        to);
+
+    xastir_snprintf(ptr->message_line,
+        sizeof(ptr->message_line),
+        "%s",
+        message);
+
+    if (path == NULL) {
+        ptr->path[0] = '\0';
+    }
+    else {
+        xastir_snprintf(ptr->path,
+            sizeof(ptr->path),
+            "%s",
+            path);
+    }
+
+    ptr->active_time = when;
+
+    // Add the record to the head of the list
+    ptr->next = delayed_ack_list_head;
+    delayed_ack_list_head = ptr;
+}
+
+
+
+
+
+time_t delayed_transmit_last_check = (time_t)0;
+
+
+void check_delayed_transmit_queue(int curr_sec) {
+    delayed_ack_record_p ptr = delayed_ack_list_head;
+    int active_records = 0;
+
+
+    // Skip this function if we did it during this second already.
+    if (delayed_transmit_last_check == curr_sec) {
+        return;
+    }
+    delayed_transmit_last_check = curr_sec;
+
+//fprintf(stderr, "Checking delayed TX queue for something to transmit.\n");
+//fprintf(stderr, ".");
+
+    // Run down the linked list checking every record.
+    while (ptr != NULL) {
+        if (ptr->active_time != 0) {   // Active record
+            char new_path[MAX_LINE_SIZE+1];
+
+
+//fprintf(stderr, "Found active record\n");
+
+            active_records++;
+
+
+            // Check for a custom path having been set in the Send
+            // Message dialog.  If so, use this for our outgoing
+            // path instead and reset all of the queued message
+            // paths to this station to this new path.
+            //
+            get_send_message_path(ptr->to_call_sign,
+                new_path,
+                sizeof(new_path));
+
+            if (new_path[0] != '\0'
+                    && strcmp(new_path, ptr->path) != 0) {
+
+                // We have a custom path set which is different than
+                // the path saved with the outgoing message.  Change
+                // the path to match the new path.
+                //
+//fprintf(stderr,
+//    "Changing queued ack's to new path: %s\n",
+//    new_path);
+
+                xastir_snprintf(ptr->path,
+                    sizeof(ptr->path),
+                    "%s",
+                    new_path);
+            }
+
+
+            if (ptr->active_time <= sec_now()) {
+                // Transmit it
+//fprintf(stderr,"Found something delayed to transmit!  %ld\n",sec_now());
+
+                if (ptr->path[0] == '\0') {
+                    transmit_message_data(ptr->to_call_sign,
+                        ptr->message_line,
+                        NULL);
+                }
+                else {
+                    transmit_message_data(ptr->to_call_sign,
+                        ptr->message_line,
+                        ptr->path);
+                }
+                
+                ptr->active_time = (time_t)0;
+            }
+        }
+        ptr = ptr->next;
+    } 
+
+    // Check if entire list contains inactive records.  If so,
+    // delete the list.
+    //
+    if (!active_records && (delayed_ack_list_head != NULL)) {
+        // No active records, but the list isn't empty.  Reclaim the
+        // records in the list.
+        while (delayed_ack_list_head != NULL) {
+            ptr = delayed_ack_list_head->next;
+            free(delayed_ack_list_head);
+//fprintf(stderr,"Free'ing delayed_ack record\n");
+            delayed_ack_list_head = ptr;
+        }
+    }
+}
+
+
+
+
+
+void check_and_transmit_messages(time_t time) {
+    int i;
+    char temp[200];
+    char to_call[40];
+
+
+    // Skip this function if we did it during this second already.
+    if (last_check_and_transmit == time) {
+        return;
+    }
+    last_check_and_transmit = time;
+
+    for (i=0; i<MAX_OUTGOING_MESSAGES;i++) {
+        if (message_pool[i].active==MESSAGE_ACTIVE) {
+            if (message_pool[i].wait_on_first_ack!=1) { // Tx only if 0
+                if (message_pool[i].active_time < time) {
+                    char *last_ack_ptr;
+                    char last_ack[5+1];
+
+
+                    if (message_pool[i].tries < MAX_TRIES) {
+                        char new_path[MAX_LINE_SIZE+1];
+
+ 
+                        /* sending message let the tnc and net transmits check to see if we should */
+                        if (debug_level & 2)
+                            fprintf(stderr,
+                                "Time %ld Active time %ld next time %ld\n",
+                                (long)time,
+                                (long)message_pool[i].active_time,
+                                (long)message_pool[i].next_time);
+
+                        if (debug_level & 2)
+                            fprintf(stderr,"Send message#%d to <%s> from <%s>:%s-%s\n",
+                                message_pool[i].tries,
+                                message_pool[i].to_call_sign,
+                                message_pool[i].from_call_sign,
+                                message_pool[i].message_line,
+                                message_pool[i].seq);
+
+                        pad_callsign(to_call,message_pool[i].to_call_sign);
+
+                        // Add Leading ":" as per APRS Spec.
+                        // Add trailing '}' to signify that we're
+                        // Reply/Ack protocol capable.
+                        last_ack_ptr = get_most_recent_ack(to_call);
+                        if (last_ack_ptr != NULL)
+                            xastir_snprintf(last_ack,
+                                sizeof(last_ack),
+                                "%s",
+                                last_ack_ptr);
+                        else
+                            last_ack[0] = '\0';
+                        
+                        xastir_snprintf(temp, sizeof(temp), ":%s:%s{%s}%s",
+                                to_call,
+                                message_pool[i].message_line,
+                                message_pool[i].seq,
+                                last_ack);
+
+                        if (debug_level & 2)
+                            fprintf(stderr,"MESSAGE OUT>%s<\n",temp);
+
+
+                        // Check for a custom path having been set
+                        // in the Send Message dialog.  If so, use
+                        // this for our outgoing path instead and
+                        // reset all of the queued message paths to
+                        // this station to this new path.
+                        //
+                        get_send_message_path(to_call,
+                            new_path,
+                            sizeof(new_path));
+
+//fprintf(stderr,"get_send_message_path(%s) returned: %s\n",to_call,new_path);
+ 
+                        if (new_path[0] != '\0'
+                                && strcmp(new_path,message_pool[i].path) != 0) {
+
+                            // We have a custom path set which is
+                            // different than the path saved with
+                            // the outgoing message.
+                            //
+                            // Change all messages to that callsign
+                            // to match the new path.
+                            //
+                            change_path_outgoing_messages_to(to_call,new_path);
+                        }
+
+
+                        // Transmit the message
+                        transmit_message_data(message_pool[i].to_call_sign,
+                            temp,
+                            message_pool[i].path);
+
+
+                        message_pool[i].active_time = time + message_pool[i].next_time;
+
+                        //fprintf(stderr,"%d\n",(int)message_pool[i].next_time);
+                    }
+
+/*
+fprintf(stderr,
+    "Msg Interval = %3ld seconds or %4.1f minutes\n",
+    message_pool[i].next_time,
+    message_pool[i].next_time / 60.0);
+*/
+
+                    // Record the interval we're using.  Put it with
+                    // the message in the general message pool, so
+                    // that the Send Message dialog can display it.
+                    // It will only display it if the message is
+                    // actively being transmitted.  If it has been
+                    // cancelled, timed out, or hasn't made it to
+                    // the transmit position yet, it won't be shown.
+                    //
+                    msg_record_interval_tries(message_pool[i].to_call_sign,
+                        message_pool[i].from_call_sign,
+                        message_pool[i].seq,
+                        message_pool[i].next_time,  // Interval
+                        message_pool[i].tries);     // Tries
+
+                    // Start at 7 seconds for the interval.  We set
+                    // it to 7 seconds in output_message() above.
+                    // Double the interval each retry until we hit
+                    // 10 minutes.  Keep transmitting at 10 minute
+                    // intervals until we hit MAX_TRIES.
+
+                    // Double the interval between messages
+                    message_pool[i].next_time = message_pool[i].next_time * 2;
+
+                    // Limit the max interval to 10 minutes
+                    if (message_pool[i].next_time > (time_t)600l)
+                        message_pool[i].next_time = (time_t)600l;
+
+                    message_pool[i].tries++;
+
+                    // Expire it if we hit the limit
+                    if (message_pool[i].tries > MAX_TRIES) {
+                        char temp[150];
+                        char temp_to[20];
+
+                        xastir_snprintf(temp,sizeof(temp),"To: %s, Msg: %s",
+                            message_pool[i].to_call_sign,
+                            message_pool[i].message_line);
+                        //popup_message(langcode("POPEM00004"),langcode("POPEM00017"));
+                        popup_message( "Retries Exceeded!", temp );
+
+                        // Fake the system out: We're pretending
+                        // that we got an ACK back from it so that
+                        // we can either release the next message to
+                        // go out, or at least make the send button
+                        // sensitive again.
+                        // We need to copy the to_call_sign into
+                        // another variable because the
+                        // clear_acked_message() function clears out
+                        // the message then needs this parameter to
+                        // do another compare (to enable the Send Msg
+                        // button again).
+                        xastir_snprintf(temp_to,
+                            sizeof(temp_to),
+                            "%s",
+                            message_pool[i].to_call_sign);
+
+                        // Record a fake ack and add "*TIMEOUT*" to
+                        // the message.  This will be displayed in
+                        // the Send Message dialog.
+                        msg_record_ack(temp_to,
+                            message_pool[i].from_call_sign,
+                            message_pool[i].seq,
+                            1,  // "1" specifies a timeout
+                            0); // Not a cancel
+
+                        clear_acked_message(temp_to,
+                            message_pool[i].from_call_sign,
+                            message_pool[i].seq);
+
+//                        if (mw[i].send_message_dialog!=NULL) /* clear submit */
+//                            XtSetSensitive(mw[i].button_ok,TRUE);
+                    }
+                }
+            } else {
+                if (debug_level & 2)
+                    fprintf(stderr,"Message #%s is waiting to have a previous one cleared\n",message_pool[i].seq);
+            }
+        }
+    }
+}
+
+
+
+
+
+// Function which marks a message as ack'ed in the transmit queue
+// and releases the next message to allow it to be transmitted.
+// Handles REPLY-ACK format or normal ACK format just fine.
+//
+void clear_acked_message(char *from, char *to, char *seq) {
+    int i,ii;
+    int found;
+    char lowest[3];
+    char temp1[MAX_CALLSIGN+1];
+    char *temp_ptr;
+    char msg_id[5+1];
+
+
+    // Copy seq into local variable
+    xastir_snprintf(msg_id,
+        sizeof(msg_id),
+        "%s",
+        seq);
+
+    // Check for REPLY-ACK protocol.  If found, terminate at the end
+    // of the first ack.
+    temp_ptr = strchr(msg_id, '}');
+    if (temp_ptr)
+        *temp_ptr = '\0';
+
+    (void)remove_trailing_spaces(msg_id);  // This is IMPORTANT here!!!
+
+    //lowest=100000;
+    // Highest Base-90 2-char string
+    xastir_snprintf(lowest,sizeof(lowest),"zz");
+    found= -1;
+    for (i=0; i<MAX_OUTGOING_MESSAGES;i++) {
+        if (message_pool[i].active==MESSAGE_ACTIVE) {
+
+            if (debug_level & 1)
+                fprintf(stderr,
+                    "TO <%s> <%s> from <%s> <%s> seq <%s> <%s>\n",
+                    to,
+                    message_pool[i].to_call_sign,
+                    from,
+                    message_pool[i].from_call_sign,
+                    msg_id,
+                    message_pool[i].seq);
+
+            if (strcmp(message_pool[i].to_call_sign,from)==0) {
+                if (debug_level & 1)
+                    fprintf(stderr,"Matched message to_call_sign\n");
+                if (strcmp(message_pool[i].from_call_sign,to)==0) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"Matched message from_call_sign\n");
+                    if (strcmp(message_pool[i].seq,msg_id)==0) {
+                        if (debug_level & 2)
+                            fprintf(stderr,"Found and cleared\n");
+
+                        clear_outgoing_message(i);
+                        // now find and release next message, look for the lowest sequence?
+// What about when the sequence rolls over?
+                        for (i=0; i<MAX_OUTGOING_MESSAGES;i++) {
+                            if (message_pool[i].active==MESSAGE_ACTIVE) {
+                                if (strcmp(message_pool[i].to_call_sign,from)==0) {
+// Need to change this to a string compare instead of an integer
+// compare.  We are using base-90 encoding now.
+                                    //if (atoi(message_pool[i].seq)<lowest) {
+                                    if (strncmp(message_pool[i].seq,lowest,2) < 0) {
+                                        //lowest=atoi(message_pool[i].seq);
+                                        xastir_snprintf(lowest,
+                                            sizeof(lowest),
+                                            "%s",
+                                            message_pool[i].seq);
+                                        found=i;
+                                    }
+                                }
+                            }
+                        }
+                        // Release the next message in the queue for transmission
+                        if (found!= -1) {
+                            message_pool[found].wait_on_first_ack=0;
+                        }
+                        else {
+                            /* if no more clear the send button */
+
+begin_critical_section(&send_message_dialog_lock, "messages.c:clear_acked_message" );
+
+                            for (ii=0;ii<MAX_MESSAGE_WINDOWS;ii++) {
+                                /* find station  */
+                                if (mw[ii].send_message_dialog!=NULL) {
+
+                                    temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data);
+                                    xastir_snprintf(temp1,
+                                        sizeof(temp1),
+                                        "%s",
+                                        temp_ptr);
+                                    XtFree(temp_ptr);
+
+                                    (void)to_upper(temp1);
+                                    //fprintf(stderr,"%s\t%s\n",temp1,from);
+//                                    if (strcmp(temp1,from)==0) {
+                                        /*clear submit*/
+//                                        XtSetSensitive(mw[ii].button_ok,TRUE);
+//                                    }
+                                }
+                            }
+
+end_critical_section(&send_message_dialog_lock, "messages.c:clear_acked_message" );
+
+                        }
+                    }
+                    else {
+                        if (debug_level & 1)
+                            fprintf(stderr,"Sequences didn't match: %s %s\n",message_pool[i].seq,msg_id);
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+// This routine is not currently used.
+//
+void send_queued(char *to) {
+    int i;
+
+    for (i=0; i<MAX_OUTGOING_MESSAGES ;i++) {
+        /* Check for messages to call */
+        if (message_pool[i].active==MESSAGE_ACTIVE)
+            if (strcmp(to,message_pool[i].to_call_sign)==0)
+                message_pool[i].active_time=0;
+
+    }
+}
+
diff --git a/src/messages.h b/src/messages.h
new file mode 100644
index 0000000..a372dfd
--- /dev/null
+++ b/src/messages.h
@@ -0,0 +1,123 @@
+/*
+ * $Id: messages.h,v 1.31 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_MESSAGES_H
+#define XASTIR_MESSAGES_H
+
+/*
+ * Message structures
+ *
+ */
+
+/* define MESSAGE STATUS */
+#define MESSAGE_ACTIVE  'A'
+#define MESSAGE_CLEAR 'C'
+
+#define MAX_OUTGOING_MESSAGES 100
+#define MAX_MESSAGE_OUTPUT_LENGTH 67
+#define MAX_MESSAGE_ORDER 10
+
+// Max tries to get a message through
+#define MAX_TRIES 18
+
+typedef struct {
+    char active;
+    char to_call_sign[MAX_CALLSIGN+1];
+    char from_call_sign[MAX_CALLSIGN+1];
+    char message_line[MAX_MESSAGE_OUTPUT_LENGTH+1];
+    char path[200];
+    char seq[MAX_MESSAGE_ORDER+1];
+    time_t active_time;
+    time_t next_time;
+    int tries;
+    int wait_on_first_ack;
+} Message_transmit;
+
+#define MAX_MESSAGE_WINDOWS 25
+
+typedef struct {
+    char win[10];
+    char to_call_sign[MAX_CALLSIGN+1];
+    int message_group;
+    Widget send_message_dialog;
+    Widget send_message_call_data;
+    Widget D700_mode;
+    Widget D7_mode;
+    Widget HamHUD_mode;
+    Widget message_data_line1;
+    Widget message_data_line2;
+    Widget message_data_line3;
+    Widget message_data_line4;
+    Widget send_message_text;
+    Widget send_message_path;
+    Widget send_message_reverse_path;
+    Widget send_message_change_path;
+    Widget pane, form, button_ok, button_cancel;
+    Widget button_clear_old_msgs, button_submit_call;
+    Widget button_clear_pending_msgs;
+    Widget button_kick_timer;
+    Widget call, message, path, reverse_path_label;
+} Message_Window;
+
+
+extern Message_transmit message_pool[MAX_OUTGOING_MESSAGES+1];
+
+extern Widget auto_msg_on, auto_msg_off;
+
+extern int auto_reply;
+extern char auto_reply_message[100];
+extern char group_data_file[400];
+
+extern void clear_acked_message(char *from, char *to, char *seq);
+extern void transmit_message_data(char *to, char *message, char *path);
+extern void transmit_message_data_delayed(char *to, char *message, char *path, time_t when);
+extern void check_delayed_transmit_queue(int curr_sec);
+
+
+//extern void output_message(char *from, char *to, char *message);
+extern int check_popup_window(char *from_call_sign, int group);
+extern int look_for_open_group_data(char *to);
+extern int group_active(char *from);
+extern void send_queued(char *to);
+extern void clear_outgoing_messages_to(char *callsign);
+extern void change_path_outgoing_messages_to(char *callsign, char *new_path);
+
+/* from messages_gui.c */
+extern xastir_mutex send_message_dialog_lock;
+extern void messages_gui_init(void);
+extern void get_send_message_path(char *callsign, char *path, int path_size);
+extern void Send_message(Widget w, XtPointer clientData, XtPointer callData);
+extern void Show_pending_messages(Widget w, XtPointer clientData, XtPointer callData);
+extern void Clear_messages(Widget w, XtPointer clientData, XtPointer callData);
+void kick_outgoing_timer(char *callsign);
+extern void Send_message_call(Widget w, XtPointer clientData, XtPointer callData);
+
+// view_message_gui.c
+extern int vm_range;
+extern int view_message_limit;
+extern int Read_messages_packet_data_type;
+extern int Read_messages_mine_only;
+
+#endif  /*  XASTIR_MESSAGES_H */
+
diff --git a/src/messages_gui.c b/src/messages_gui.c
new file mode 100644
index 0000000..96154de
--- /dev/null
+++ b/src/messages_gui.c
@@ -0,0 +1,2673 @@
+/*
+ * $Id: messages_gui.c,v 1.87 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdlib.h>
+#include <stdio.h>                      // printf
+#include <stdint.h>
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "lang.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+#if defined(__LSB__) || defined(LESSTIF_VERSION)
+  #define NO_DYNAMIC_WIDGETS 1
+#endif
+
+
+#define MAX_PATH 200
+
+
+Widget auto_msg_on, auto_msg_off;
+Widget auto_msg_dialog = (Widget)NULL;
+Widget auto_msg_set_data = (Widget)NULL;
+
+static xastir_mutex auto_msg_dialog_lock;
+xastir_mutex send_message_dialog_lock;
+
+void select_station_type(int ii);
+
+
+
+
+
+void messages_gui_init(void)
+{
+    init_critical_section( &auto_msg_dialog_lock );
+    init_critical_section( &send_message_dialog_lock );
+}
+
+
+
+
+
+/**** Send Message ******/
+
+
+
+// This function chops off the first callsign, then returns a string
+// containing the same string in reversed callsign order.  Note that
+// if RELAY was used by the sending station and that RELAY did _not_
+// do callsign substitution, that part of the path will be chopped
+// heading back.  If the sending station really needed that relay
+// station in order to receive the reply, he/she should have put in
+// a callsign instead of RELAY.  We can't in good conscience use
+// RELAY on the end of the return path.
+//
+// We also chop off anything after comma "q" two letters, and a
+// comma.  This is the injection-ID called the Q-construct, which
+// lets us know how a signal was injected into the NET and by whom.
+//
+void reverse_path(char *input_string) {
+    char reverse_path[200];
+    int indexes[20];
+    int i, j, len;
+    char temp[MAX_CALLSIGN+1];
+
+
+    // Check for NULL pointer
+    if (input_string == NULL)
+        return;
+
+    // Check for zero-length string
+    len = strlen(input_string);
+    if (len == 0)
+        return;
+
+    // Initialize
+    reverse_path[0] = '\0';
+    for (i = 0; i < 20; i++)
+        indexes[i] = -1;
+
+    // Add a comma onto the end (makes later code easier)
+    input_string[len++] = ',';
+    input_string[len] = '\0';   // Terminate it
+
+    // Find each comma 
+    j = 0; 
+    for (i = 0; i < (int)strlen(input_string); i++) {
+        if (input_string[i] == ',') {
+            indexes[j++] = i;
+            //fprintf(stderr,"%d\n",i);     // Debug code
+        }
+    }
+
+    // Get rid of asterisks and commas in the original string:
+    for (i = 0; i < len; i++) {
+        if (input_string[i] == '*' || input_string[i] == ',') {
+            input_string[i] = '\0';
+        }
+    }
+
+    // Go left to right looking for a 3-letter callsign starting
+    // with 'q'.  If found readjust 'j' to skip that callsign and
+    // everything after it.
+    //
+    for ( i = 0; i < j; i++) {
+        char *c = &input_string[indexes[i] + 1];
+
+//fprintf(stderr,"'%s'\t", c );
+
+        if (c[0] == 'q') {
+            if ( strlen(c) == 3 ) { // "qAR"
+
+//fprintf(stderr,"Found:%s\n", c);
+
+                j = i;
+            }
+        }
+    }
+
+    // Convert used "WIDEn-N"/"TRACEn-N" paths back to their
+    // original glory.  Convert "TRACE" to "WIDE" as well.  We could
+    // also choose to change "WIDEn-N" to a slimmer version based on
+    // how many digi's were used, for instance "WIDE7-6" could
+    // change to "WIDE1-1" or "WIDE7-1", and "WIDE5-2" could change
+    // to "WIDE3-3" or "WIDE5-3".
+//    for ()
+
+    // j now tells us how many were found.  Now go in the reverse
+    // order and concatenate the substrings together.  Get rid of
+    // "RELAY" and "TCPIP" calls as we're doing it.
+    input_string[0] = '\0'; // Clear out the old string first
+    for ( i = j - 1; i >= 0; i-- ) {
+        if ( (input_string[indexes[i]+1] != '\0')
+                && (strncasecmp(&input_string[indexes[i]+1],"RELAY",5) != 0)
+                && (strncasecmp(&input_string[indexes[i]+1],"TCPIP",5) != 0) ) {
+
+            // Snag each callsign into temp:
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%s",
+                &input_string[indexes[i]+1]);
+
+            // Massage temp until it resembles something we want to
+            // use.
+            //  "WIDEn" -> "WIDEn-N,"
+            // "TRACEn" -> "WIDEn-N,"
+            //  "TRACE" -> "WIDE,"
+            if (strncasecmp(temp,"WIDE",4) == 0) {
+                if ( (temp[4] != ',') && is_num_chr(temp[4]) ) {
+//fprintf(stderr,"Found a WIDEn-N\n");
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "WIDE%c-%c",
+                        temp[4],
+                        temp[4]);
+                }
+                else {
+//fprintf(stderr,"Found a WIDE\n");
+                    // Leave temp alone, it's just a WIDE
+                }
+            }
+            else if (strncasecmp(temp,"TRACE",5) == 0) {
+                if ( (temp[5] != ',') && is_num_chr(temp[5]) ) {
+//fprintf(stderr,"Found a TRACEn-N\n");
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "WIDE%c-%c",
+                        temp[5],
+                        temp[5]);
+                }
+                else {
+//fprintf(stderr,"Found a TRACE\n");
+                    // Convert it from TRACE to WIDE
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "WIDE");
+                }
+            }
+
+            // Add temp to the end of our path:
+            strncat(reverse_path,temp,sizeof(temp));
+ 
+            strncat(reverse_path,",",1);
+        }
+    }
+
+    // Remove the ending comma
+    reverse_path[strlen(reverse_path) - 1] = '\0';
+
+    // Save the new path back into the string we were given.
+    strncat(input_string, reverse_path, len);
+}
+
+
+
+
+
+void get_path_data(char *callsign, char *path, int max_length) {
+    DataRow *p_station;
+
+
+    if (search_station_name(&p_station,callsign,1)) {  // Found callsign
+        char new_path[200];
+
+        if (p_station->node_path_ptr) {
+            xastir_snprintf(new_path,sizeof(new_path), "%s", p_station->node_path_ptr);
+            
+            if(debug_level & 2)
+                fprintf(stderr,"\nPath from %s: %s\n",
+                        callsign,
+                        new_path);
+            
+            // We need to chop off the first call, remove asterisks
+            // and injection ID's, and reverse the order of the
+            // callsigns.  We need to do the same thing in the
+            // callback for button_submit_call, so that we get a new
+            // path whenever the callsign is changed.  Create a new
+            // TextFieldWidget to hold the path info, which gets
+            // filled in here (and the callback) but can be changed by
+            // the user.  Must find a nice way to use this path from
+            // output_my_data() as well.
+            
+            reverse_path(new_path);
+            
+            if (debug_level & 2)
+                fprintf(stderr,"  Path to %s: %s\n",
+                        callsign,
+                        new_path);
+            
+            xastir_snprintf(path,
+                            max_length,
+                            "%s",
+                            new_path);
+        } else {
+            if (debug_level & 2) 
+                fprintf(stderr," Path from %s is (null)\n",callsign);
+            path[0]='\0';
+        }
+    }
+    else {  // Couldn't find callsign.  It's
+            // not in our station database.
+        if(debug_level & 2)
+            fprintf(stderr,"Path from %s: No Path Known\n",callsign);
+        
+        path[0] = '\0';
+    }
+
+}
+
+
+
+
+
+static Widget change_path_dialog = NULL;
+static Widget current_path = NULL;
+ 
+
+
+
+
+void Send_message_change_path_destroy_shell(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if (change_path_dialog) {
+        XtPopdown(change_path_dialog);
+
+        XtDestroyWidget(change_path_dialog);
+    }
+    change_path_dialog = (Widget)NULL;
+}
+
+
+
+
+
+// Apply button
+// Fetch the text from the "current_path" widget and place it into
+// the mw[ii].send_message_path widget.
+//
+void Send_message_change_path_apply(Widget widget, XtPointer clientData, XtPointer callData) {
+    char path[MAX_PATH+1];
+    char *temp_ptr;
+
+ 
+    if (current_path != NULL && clientData != NULL) {
+
+        temp_ptr = XmTextFieldGetString(current_path);
+        xastir_snprintf(path,
+            sizeof(path),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(path);
+        (void)to_upper(path);
+
+
+// Check here for "DIRECT PATH" or "DEFAULT PATH".  If one of them,
+// do some special processing if need be so that lower layers will
+// interpret it correctly.
+
+        XmTextFieldSetString(clientData, path);
+
+        Send_message_change_path_destroy_shell(NULL, NULL, NULL);
+    }
+}
+
+
+
+
+
+// "Direct Path" button
+//
+// Put "DIRECT PATH" in the widgets.  We pass "DIRECT PATH" all the
+// way to the transmit routines, then change it to an empty path
+// when the transmit actually goes out.
+//
+void Send_message_change_path_direct(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if (current_path == NULL || clientData == NULL) {
+        Send_message_change_path_destroy_shell(NULL, NULL, NULL);
+    }
+
+    // Change current_path widget
+    XmTextFieldSetString(current_path, "DIRECT PATH");
+
+    Send_message_change_path_apply(NULL, clientData, NULL);
+}
+ 
+
+
+
+
+// "Default Path(s)" button
+//
+// Blank out the path so the default paths get used.  We pass
+// "DEFAULT PATH" all the way to the transmit routines, then change
+// it there to be a blank.
+//
+void Send_message_change_path_default(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    if (current_path == NULL || clientData == NULL) {
+        Send_message_change_path_destroy_shell(NULL, NULL, NULL);
+    }
+
+    // Change current_path widget
+    XmTextFieldSetString(current_path, "DEFAULT PATH");
+
+    Send_message_change_path_apply(NULL, clientData, NULL);
+}
+ 
+
+
+
+
+// TODO:  Change the "Path:" box so that clicking or double-clicking
+// on it will bring up a "Change Path" dialog.  Could also use a
+// "Change" or "Change Path" button if easier.  This new dialog
+// should have the current path (editable), the reverse path (not
+// editable), and these buttons:
+//
+//      "DIRECT path"
+//      "DEFAULT path(s)"
+//      "Apply"
+//      "Cancel"
+//
+// Of course the underlying code will have to tweaked to be able to
+// pass an EMPTY path all the way down through the layers.  We can't
+// currently do that.  We'll have to define a specific string for
+// that.  Insert the text "--DEFAULT--", "--BLANK--", or the actual
+// path in the editable box and in the "Path:" box on the Send
+// Message dialog so that the user knows which one is in effect.
+//
+// Remember to close the Change Path dialog if we close the Send
+// Message dialog which corresponds to it.
+//
+// Adding this new CHANGE PATH dialog will allow us to get rid of
+// three bugs on the active bug-list:  #1499820, #1326975, and
+// #1326973.
+//
+void Send_message_change_path( Widget widget, XtPointer clientData, XtPointer callData) {
+    int ii;
+    Atom delw;
+    Widget pane, form, current_path_label, reverse_path_label,
+        reverse_path, button_default, button_direct, button_apply,
+        button_cancel;
+    Widget button_wide11, button_wide21, button_wide22, button_nogate;
+    char *temp_ptr;
+    char temp1[MAX_LINE_SIZE+1];
+    char path[MAX_PATH+1];
+ 
+
+//begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message_change_path" );
+
+    if (clientData == NULL) {
+        return;
+    }
+
+    if (change_path_dialog) {
+        // Destroy the old one before creating a new one
+        Send_message_change_path_destroy_shell(NULL, NULL, NULL);
+    }
+
+    // Fetch Send Message dialog number from clientData, store in
+    // "ii".
+    //
+    ii = atoi(clientData);
+
+    // "Change Path"
+    change_path_dialog = XtVaCreatePopupShell(langcode("WPUPMSB019"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNtitleString,"Change Path",
+                XmNfontList, fontlist1,
+                NULL);
+
+    pane = XtVaCreateWidget("Send_message_change_path pane",
+                xmPanedWindowWidgetClass, 
+                change_path_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+    form =  XtVaCreateWidget("Send_message_change_path form",
+                xmFormWidgetClass,
+                pane,
+                XmNfractionBase, 4,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+    // "Path:"
+    current_path_label = XtVaCreateManagedWidget(langcode("WPUPMSB010"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    current_path = XtVaCreateManagedWidget("Send_message_change_path path", 
+                xmTextFieldWidgetClass, 
+                form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 26,
+                XmNwidth, ((26*7)+2),
+                XmNmaxLength, 199,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, current_path_label,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+    // "Reverse Path:"
+    reverse_path_label = XtVaCreateManagedWidget(langcode("WPUPMSB022"),
+                xmLabelWidgetClass,
+                form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, current_path,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    reverse_path = XtVaCreateManagedWidget("Send_message_change_path reverse path", 
+                xmTextFieldWidgetClass, 
+                form,
+                XmNeditable,   FALSE,
+                XmNcursorPositionVisible, FALSE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 26,
+                XmNwidth, ((26*7)+2),
+                XmNmaxLength, 199,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, reverse_path_label,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    button_wide11 = XtVaCreateManagedWidget("WIDE1-1",
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, current_path_label,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    button_wide21 = XtVaCreateManagedWidget("WIDE2-1",
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, current_path_label,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    button_wide22 = XtVaCreateManagedWidget("WIDE2-2",
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, current_path_label,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+     button_nogate = XtVaCreateManagedWidget("NOGATE",
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, current_path_label,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+XtSetSensitive(button_wide11, FALSE);
+XtSetSensitive(button_wide21, FALSE);
+XtSetSensitive(button_wide22, FALSE);
+XtSetSensitive(button_nogate, FALSE);
+ 
+    // "Use Default Path(s)"
+    button_default = XtVaCreateManagedWidget(langcode("WPUPMSB020"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, button_wide11,
+                XmNtopOffset, 0,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    // "Direct (No path)"
+    button_direct = XtVaCreateManagedWidget(langcode("WPUPMSB021"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, button_wide11,
+                XmNtopOffset, 0,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    // "Apply"
+    button_apply = XtVaCreateManagedWidget(langcode("UNIOP00032"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, button_wide11,
+                XmNtopOffset, 0,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    // "Close"
+    button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, button_wide11,
+                XmNtopOffset, 0,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+    XtAddCallback(button_default, XmNactivateCallback, Send_message_change_path_default, (XtPointer)mw[ii].send_message_path);
+    XtAddCallback(button_direct, XmNactivateCallback, Send_message_change_path_direct, (XtPointer)mw[ii].send_message_path);
+    XtAddCallback(button_apply, XmNactivateCallback, Send_message_change_path_apply, (XtPointer)mw[ii].send_message_path);
+    XtAddCallback(button_cancel, XmNactivateCallback, Send_message_change_path_destroy_shell,(XtPointer)mw[ii].win);
+
+    // Fill in the fields 
+    if(mw[ii].send_message_dialog != NULL) {
+        char call_sign[MAX_CALLSIGN+1];
+
+        temp_ptr = XmTextFieldGetString(mw[ii].send_message_path);
+        xastir_snprintf(temp1,
+            sizeof(temp1),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+        (void)to_upper(temp1);
+        XmTextFieldSetString(current_path, temp1);
+ 
+        // Go get the reverse path.  Start with the callsign.
+        temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data);
+        xastir_snprintf(call_sign,
+            sizeof(call_sign),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_dash_zero(call_sign);
+
+        // Try lowercase
+        get_path_data(call_sign, path, MAX_PATH);
+        if (strlen(path) == 0) {
+            // Try uppercase
+            (void)to_upper(call_sign);
+            get_path_data(call_sign, path, MAX_PATH);
+        }
+        XmTextFieldSetString(reverse_path, path);
+    }
+ 
+    pos_dialog(change_path_dialog);
+
+    delw = XmInternAtom(XtDisplay(change_path_dialog),"WM_DELETE_WINDOW", FALSE);
+//    XmAddWMProtocolCallback(change_path_dialog, delw, Send_message_destroy_shell, (XtPointer)mw[ii].win);
+
+    XtManageChild(form);
+    XtManageChild(pane);
+
+    XtPopup(change_path_dialog,XtGrabNone);
+
+    // Move focus to the Cancel button.  This appears to highlight the
+    // button fine, but we're not able to hit the <Enter> key to
+    // have that default function happen.  Note:  We _can_ hit the
+    // <SPACE> key, and that activates the option.
+//    XmUpdateDisplay(change_path_dialog);
+    XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+//end_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message_change_path" );
+
+}
+
+
+
+
+
+// Find a custom path set in a Send Message dialog, using the remote
+// callsign as the key.  If no custom path, sets path to '\0'.
+//
+void get_send_message_path(char *callsign, char *path, int path_size) {
+    int ii;
+    int found = -1;
+    char *temp_ptr;
+    char temp1[MAX_LINE_SIZE+1];
+    char my_callsign[20];
+    
+
+    xastir_snprintf(my_callsign,sizeof(my_callsign),"%s",callsign); 
+    remove_trailing_spaces(my_callsign);
+
+//fprintf(stderr,"Looking for %s\n", my_callsign);
+    for(ii = 0; ii < MAX_MESSAGE_WINDOWS; ii++) {
+
+        // find matching callsign
+        if(mw[ii].send_message_dialog != NULL) {
+
+            temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data);
+            xastir_snprintf(temp1,
+                sizeof(temp1),
+                "%s",
+                temp_ptr);
+            XtFree(temp_ptr);
+
+            (void)remove_trailing_dash_zero(temp1);
+            (void)to_upper(temp1);
+
+            if(strcmp(temp1,my_callsign)==0) {
+                found = ii;
+                break;
+            }
+        }
+    }
+
+    if (found == -1) {
+//fprintf(stderr,"Didn't find dialog\n");
+        path[0] = '\0';
+        return;
+    }
+
+    // We have the correct Send Message dialog.  Snag the path.
+    //
+    temp_ptr = XmTextFieldGetString(mw[ii].send_message_path);
+    xastir_snprintf(temp1,
+        sizeof(temp1),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)to_upper(temp1);
+    (void)remove_leading_spaces(temp1);
+    (void)remove_trailing_spaces(temp1);
+
+    // Path empty?
+    if (temp1[0] == '\0') {
+//fprintf(stderr,"Didn't find custom path\n");
+        path[0] = '\0';
+        return;
+    }
+
+    // We have a real path!  Stuff it into the path variable.
+    xastir_snprintf(path,
+        path_size,
+        "%s",
+        temp1);
+//fprintf(stderr,"Found custom path: %s\n", path);
+}
+
+
+
+
+
+void Send_message_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int ii;
+//    char *temp_ptr;
+//    char temp1[MAX_LINE_SIZE+1];
+
+//fprintf(stderr,"3Send_message_destroy_shell() start\n");
+ 
+    ii=atoi((char *)clientData);
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message_destroy_shell" );
+
+    if (mw[ii].send_message_dialog) {
+
+/*
+        // Check whether the send_message_call_data field has a
+        // custom path entered.
+        temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data);
+        xastir_snprintf(temp1,
+                sizeof(temp1),
+                "%s",
+                temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_leading_spaces(temp1);
+        (void)remove_trailing_spaces(temp1);
+        (void)remove_trailing_dash_zero(temp1);
+
+        if(temp1[0] != '\0') {
+            // Yep, we have a custom path.  Warn the user that
+            // they're going to lose this path by destroying the
+            // dialog.
+            popup_message_always(langcode("POPEM00036"),
+                langcode("POPEM00040"));
+        }
+*/
+ 
+        XtPopdown(mw[ii].send_message_dialog);
+        XtDestroyWidget(mw[ii].send_message_dialog);
+    }
+
+
+    mw[ii].send_message_dialog = (Widget)NULL;
+    mw[ii].to_call_sign[0] = '\0';
+    mw[ii].send_message_call_data = (Widget)NULL;
+    mw[ii].D700_mode = (Widget)NULL;
+    mw[ii].D7_mode = (Widget)NULL;
+    mw[ii].HamHUD_mode = (Widget)NULL;
+    mw[ii].message_data_line1 = (Widget)NULL;
+    mw[ii].message_data_line2 = (Widget)NULL;
+    mw[ii].message_data_line3 = (Widget)NULL;
+    mw[ii].message_data_line4 = (Widget)NULL;
+    mw[ii].send_message_text = (Widget)NULL;
+
+    Send_message_change_path_destroy_shell(NULL, NULL, NULL);
+ 
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message_destroy_shell" );
+
+//fprintf(stderr,"3Send_message_destroy_shell() finished\n");
+ 
+}
+
+
+
+
+
+void Check_new_call_messages( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int pos;
+    intptr_t i;
+
+    i=(intptr_t)clientData;
+ 
+    /* clear window*/
+    pos=0;
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Check_new_call_messages" );
+
+    if (mw[i].send_message_dialog) {
+        // If we have a dialog already, clear out the message area
+        // from 0 to the last text position.
+
+        // Known to have memory leaks with some versions of Motif:
+        //XmTextSetString(mw[i].send_message_text,"");
+
+        XmTextReplace(mw[i].send_message_text, (XmTextPosition) 0,
+                XmTextGetLastPosition(mw[i].send_message_text), "");
+
+        // Set the cursor position to 0
+        XtVaSetValues(mw[i].send_message_text,XmNcursorPosition,pos,NULL);
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Check_new_call_messages" );
+
+    update_messages(1); // Force an immediate update
+
+    if (mw[i].send_message_dialog) {
+        // Re-arrange the outgoing message boxes based on the type of device we're talking to.
+        select_station_type(i);
+    }
+}
+
+
+
+
+
+void Clear_messages( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    clear_outgoing_messages();
+}
+
+
+
+
+
+void Send_message_now( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char temp1[MAX_CALLSIGN+1];
+    char temp2[68];
+    char temp_line1[68] = "";
+
+#ifndef NO_DYNAMIC_WIDGETS
+    char temp_line2[23] = "";
+    char temp_line3[23] = "";
+    char temp_line4[10] = "";
+#endif	// NO_DYNAMIC_WIDGETS
+
+    char path[200];
+    int ii, jj;
+    char *temp_ptr;
+    int substitution_made = 0;
+    int d700;
+    int d7;
+    int hamhud;
+    char temp_file_path[MAX_VALUE];
+
+    ii=atoi((char *)clientData);
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message_now" );
+
+    if (mw[ii].send_message_dialog) {
+
+        d700 = XmToggleButtonGetState(mw[ii].D700_mode);
+        d7 = XmToggleButtonGetState(mw[ii].D7_mode);
+        hamhud = XmToggleButtonGetState(mw[ii].HamHUD_mode);
+
+        temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data);
+        xastir_snprintf(temp1,
+            sizeof(temp1),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(temp1);
+        (void)to_upper(temp1);
+        (void)remove_trailing_dash_zero(temp1);
+
+        // Fetch message_data_line1 in all cases
+        temp_ptr = XmTextFieldGetString(mw[ii].message_data_line1);
+        xastir_snprintf(temp_line1,
+            sizeof(temp_line1),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+#ifndef NO_DYNAMIC_WIDGETS
+
+        // If D700/D7 mode, fetch message_data_line2
+        if (d700 || d7) {
+            temp_ptr = XmTextFieldGetString(mw[ii].message_data_line2);
+            xastir_snprintf(temp_line2,
+                sizeof(temp_line2),
+                "%s",
+                temp_ptr);
+            XtFree(temp_ptr);
+        }
+
+        // If D700/D7 mode, fetch message_data_line3
+        if (d700 || d7) {
+            temp_ptr = XmTextFieldGetString(mw[ii].message_data_line3);
+            xastir_snprintf(temp_line3,
+                sizeof(temp_line3),
+                "%s",
+                temp_ptr);
+            XtFree(temp_ptr);
+        }
+
+        // If D7 mode, fetch message_data_line4
+        if (d7) {
+            temp_ptr = XmTextFieldGetString(mw[ii].message_data_line4);
+            xastir_snprintf(temp_line4,
+                sizeof(temp_line4),
+                "%s",
+                temp_ptr);
+            XtFree(temp_ptr);
+        }
+
+        // Construct the entire message now
+        if (hamhud) { // Combine two lines together
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%-20s%-47s",
+                temp_line1,
+                temp_line2);
+        }
+        else if (d700) { // Combine three lines together
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%-22s%-22s%-20s",
+                temp_line1,
+                temp_line2,
+                temp_line3);
+        }
+        else if (d7) {  // Combine four lines together
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%-12s%-12s%-12s%-9s",
+                temp_line1,
+                temp_line2,
+                temp_line3,
+                temp_line4);
+        }
+        else
+
+#endif  // NO_DYNAMIC_WIDGETS 
+
+        {  // Use line1 only
+            xastir_snprintf(temp2,
+                sizeof(temp2),
+                "%s",
+                temp_line1);
+        }
+
+        // We have the message text now.  Check it for illegal
+        // characters, remove them and substitute '.' if found.
+        // Illegal characters are '|', '{', and '~' for messaging.
+        for (jj = 0; jj < (int)strlen(temp2); jj++) {
+            if (       temp2[jj] == '|'
+                    || temp2[jj] == '{'
+                    || temp2[jj] == '~' ) {
+                temp2[jj] = '.';    // Replace with a dot
+                substitution_made++;
+            }
+        }
+        if (substitution_made) {
+            popup_message_always(langcode("POPEM00022"),
+                langcode("POPEM00039"));
+        }
+
+        (void)remove_trailing_spaces(temp2);
+
+        temp_ptr = XmTextFieldGetString(mw[ii].send_message_path);
+        xastir_snprintf(path,
+            sizeof(path),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(path);
+        (void)to_upper(path);
+
+        if(debug_level & 2)
+            fprintf(stderr,
+                "Send message to <%s> from <%s> :%s\n",
+                temp1,
+                mw[ii].to_call_sign,
+                temp2);
+
+        if ( (strlen(temp1) != 0)                       // Callsign field is not blank
+                && (strlen(temp2) != 0)                 // Message field is not blank
+                && (strcmp(temp1,my_callsign) ) ) {     // And not my own callsign
+            /* if you're sending a message you must be at the keyboard */
+            auto_reply=0;
+            XmToggleButtonSetState(auto_msg_toggle,FALSE,FALSE);
+            statusline(langcode("BBARSTA011"),0);       // Auto Reply Messages OFF
+            output_message(mw[ii].to_call_sign,temp1,temp2,path);
+
+//fprintf(stderr,"         1111111111222222222233333333334444444444555555555566666666\n");
+//fprintf(stderr,"1234567890123456789012345678901234567890123456789012345678901234567\n");
+//fprintf(stderr,"%s\n",temp2);
+
+            XmTextFieldSetString(mw[ii].message_data_line1,"");
+
+            if (mw[ii].message_data_line2) // If exists, blank it
+                XmTextFieldSetString(mw[ii].message_data_line2,"");
+
+            if (mw[ii].message_data_line3) // If exists, blank it
+                XmTextFieldSetString(mw[ii].message_data_line3,"");
+
+            if (mw[ii].message_data_line4) // If exists, blank it
+                XmTextFieldSetString(mw[ii].message_data_line4,"");
+
+//            if (mw[ii].message_group!=1)
+//                XtSetSensitive(mw[ii].button_ok,FALSE);
+
+            // Do message logging if that feature is enabled.
+            if (log_message_data) {
+                char temp_msg[MAX_MESSAGE_LENGTH+1];
+
+                xastir_snprintf(temp_msg,
+                    sizeof(temp_msg),
+                    "%s>%s,%s:%s",
+                    mw[ii].to_call_sign,    // To
+                    temp1,                  // From
+                    path,                   // Path
+                    temp2);                 // Message
+                log_data( get_user_base_dir(LOGFILE_MESSAGE, temp_file_path, 
+                                            sizeof(temp_file_path)), 
+                          temp_msg );
+            }
+        }
+        else {
+            if ( strcmp(temp1,my_callsign) == 0 ) { // It's my own callsign
+                popup_message_always(langcode("POPEM00022"),
+                    langcode("POPEM00054"));   // We're trying to talk to ourselves!
+            }
+            else if ( strlen(temp1) == 0 ) { // Callsign field is blank
+                popup_message_always(langcode("POPEM00022"),
+                    langcode("POPEM00052"));   // Callsign is EMPTY!
+            }
+            else if ( strlen(temp2) == 0 ) { // Message field is blank
+                popup_message_always(langcode("POPEM00022"),
+                    langcode("POPEM00053"));   // Message is EMPTY!
+            }
+        }
+    }
+
+    // Move focus to the first message box to make typing the next
+    // message easier.
+    XmProcessTraversal(mw[ii].message_data_line1, XmTRAVERSE_CURRENT);
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message_now" );
+
+}
+
+
+
+
+
+void Clear_message_from( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char temp1[MAX_CALLSIGN+1];
+    int i;
+    char *temp_ptr;
+/* int pos;*/
+
+
+    i=atoi((char *)clientData);
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_from" );
+
+    if (mw[i].send_message_dialog) {
+
+        temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data);
+        xastir_snprintf(temp1,
+            sizeof(temp1),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(temp1);  
+        (void)to_upper(temp1);
+        (void)remove_trailing_dash_zero(temp1);
+
+        /*fprintf(stderr,"Clear message from <%s> to <%s>\n",temp1,my_callsign);*/
+        mdelete_messages_from(temp1);
+        new_message_data=1;
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_from" );
+
+}
+
+
+
+
+
+void Clear_message_to( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char temp1[MAX_CALLSIGN+1];
+    int i;
+    char *temp_ptr;
+
+
+    i=atoi((char *)clientData);
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_to" );
+
+    if (mw[i].send_message_dialog) {
+
+        temp_ptr = XmTextFieldGetString(mw[i].send_message_call_data);
+        xastir_snprintf(temp1,
+            sizeof(temp1),
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        (void)remove_trailing_spaces(temp1);  
+        (void)to_upper(temp1);
+        (void)remove_trailing_dash_zero(temp1);
+
+        /*fprintf(stderr,"Clear message to <%s>\n",temp1);*/
+        mdelete_messages_to(temp1);
+        new_message_data=1;
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_to" );
+
+}
+
+
+
+
+
+void Clear_message_to_from( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    int i, pos;
+
+    Clear_message_to(w, clientData, callData);
+    Clear_message_from(w, clientData, callData);
+
+    i=atoi((char *)clientData);
+    /* clear window*/
+    pos=0;
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_to_from" );
+
+    if (mw[i].send_message_dialog) {
+
+        // Known to have memory leaks with some versions of Motif:
+        //XmTextSetString(mw[i].send_message_text,"");
+
+        // Clear out the message window
+        XmTextReplace(mw[i].send_message_text, (XmTextPosition) 0,
+                XmTextGetLastPosition(mw[i].send_message_text), "");
+
+        // Set the cursor position to 0
+        XtVaSetValues(mw[i].send_message_text,XmNcursorPosition,pos,NULL);
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_to_from" );
+
+        update_messages(1);     // Force an update to clear the window
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_to_from" );
+
+    }
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Clear_message_to_from" );
+
+}
+
+
+
+
+
+void Kick_timer( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char *temp_ptr;
+    char temp1[MAX_CALLSIGN+1];
+
+
+    temp_ptr = XmTextFieldGetString(mw[atoi(clientData)].send_message_call_data);
+    xastir_snprintf(temp1,
+        sizeof(temp1),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(temp1);
+    (void)to_upper(temp1);
+    (void)remove_trailing_dash_zero(temp1);
+
+    kick_outgoing_timer(temp1);
+}
+
+
+
+
+
+void Clear_messages_to( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char *temp_ptr;
+    char temp1[MAX_CALLSIGN+1];
+
+
+    temp_ptr = XmTextFieldGetString(mw[atoi(clientData)].send_message_call_data);
+        xastir_snprintf(temp1,
+            sizeof(temp1),
+            "%s",
+            temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(temp1);
+    (void)to_upper(temp1);
+    (void)remove_trailing_dash_zero(temp1);
+
+    clear_outgoing_messages_to(temp1);
+    update_messages(1); // Force an update to the window
+}
+
+
+
+
+
+void Send_message_call( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char call[20];
+
+    if(clientData != NULL) {
+        xastir_snprintf(call,
+            sizeof(call),
+            "%s",
+            (char *)clientData);
+        Send_message(appshell, call, NULL);
+    }           
+}
+
+
+
+
+
+// These are used for callbacks below so that we have a unique
+// identifier for the XtRemoveCallback() function to work with.  The
+// last two parameters of an XtAddCallback() or XtRemoveCallback()
+// must be unique.
+//
+void Send_message_now_1( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Send_message_now( w, clientData, callData);
+}
+void Send_message_now_2( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Send_message_now( w, clientData, callData);
+}
+void Send_message_now_3( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Send_message_now( w, clientData, callData);
+}
+void Send_message_now_4( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Send_message_now( w, clientData, callData);
+}
+
+
+
+
+
+void build_send_message_input_boxes(int i, int hamhud, int d700, int d7) {
+
+//fprintf(stderr, "\n  build:   i:%d  hamhud:%d  d700:%d  d7:%d\n", i, hamhud, d700, d7);
+
+
+// Skip most of these sections and go to the default section if
+// using LSB.  We have problems with Lesstif segfaulting on us
+// otherwise.
+
+#ifndef NO_DYNAMIC_WIDGETS
+
+    // HamHUD mode (Here we're assuming the 4x20 LCD in the HamHUD-II)
+    if (hamhud) {
+        // Draw a textfield widget of size 20
+        mw[i].message_data_line1 = XtVaCreateManagedWidget("Send_message smmd", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 22,
+            XmNwidth, ((22*7)),
+            XmNmaxLength, 20,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message,
+            XmNleftOffset, 5,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+// HamHUD will display all 67 chars, but only stores the first 20,
+// therefore if you want the recipient to be able to look at it
+// later, only send them 20 chars per message.
+/*
+        // Draw another textfield widget of size 47
+        mw[i].message_data_line2 = XtVaCreateManagedWidget("Send_message line2", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 43,
+            XmNwidth, ((43*7)),
+            XmNmaxLength, 47,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message_data_line1,
+            XmNleftOffset, 2,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+*/
+    }
+
+    // D700A mode
+    else if (d700) {
+
+        // Draw a textfield widget of size 22
+        mw[i].message_data_line1 = XtVaCreateManagedWidget("Send_message smmd", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 22,
+            XmNwidth, ((22*7)),
+            XmNmaxLength, 22,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message,
+            XmNleftOffset, 5,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // Draw another textfield widget of size 22
+        mw[i].message_data_line2 = XtVaCreateManagedWidget("Send_message line2", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 22,
+            XmNwidth, ((22*7)),
+            XmNmaxLength, 22,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message_data_line1,
+            XmNleftOffset, 2,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // Draw another textfield widget of size 20
+        mw[i].message_data_line3 = XtVaCreateManagedWidget("Send_message line3", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 21,
+            XmNwidth, ((21*7)),
+            XmNmaxLength, 20,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message_data_line2,
+            XmNleftOffset, 2,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+    }
+
+    // D7A/D7E Mode
+    else if (d7) {
+
+        // Draw a textfield widget of size 12
+        mw[i].message_data_line1 = XtVaCreateManagedWidget("Send_message smmd", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 12,
+            XmNwidth, ((12*7)+4),
+            XmNmaxLength, 12,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message,
+            XmNleftOffset, 5,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // Draw a textfield widget of size 12
+        mw[i].message_data_line2 = XtVaCreateManagedWidget("Send_message line2", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 12,
+            XmNwidth, ((12*7)+4),
+            XmNmaxLength, 12,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message_data_line1,
+            XmNleftOffset, 2,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+// Separate the next two from the previous two for a bit, to help
+// indicate that the first two are one screen on a TH-D7, the next
+// two are another screen.
+
+        // Draw a textfield widget of size 12
+        mw[i].message_data_line3 = XtVaCreateManagedWidget("Send_message line3", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 12,
+            XmNwidth, ((12*7)+4),
+            XmNmaxLength, 12,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message_data_line2,
+            XmNleftOffset, 15,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        // Draw a textfield widget of size 9
+        mw[i].message_data_line4 = XtVaCreateManagedWidget("Send_message line4", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 9,
+            XmNwidth, ((10*7)+0),
+            XmNmaxLength, 9,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message_data_line3,
+            XmNleftOffset, 2,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+   }
+
+    // Standard APRS Mode
+   else // Standard APRS message box size (67)
+
+#endif  // NO_DYNAMIC_WIDGETS
+
+    {
+
+       mw[i].message_data_line1 = XtVaCreateManagedWidget("Send_message smmd", 
+            xmTextFieldWidgetClass, 
+            mw[i].form,
+            XmNeditable,   TRUE,
+            XmNcursorPositionVisible, TRUE,
+            XmNsensitive, TRUE,
+            XmNshadowThickness,    1,
+            XmNcolumns, 67,
+            XmNwidth, ((65*7)+2),
+            XmNmaxLength, 67,
+            XmNbackground, colors[0x0f],
+            XmNtopAttachment, XmATTACH_NONE,
+            XmNbottomAttachment, XmATTACH_WIDGET,
+            XmNbottomWidget, mw[i].button_clear_old_msgs,
+            XmNbottomOffset, 5,
+            XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, mw[i].message,
+            XmNleftOffset, 5,
+            XmNrightAttachment,XmATTACH_NONE,
+            XmNnavigationType, XmTAB_GROUP,
+            XmNtraversalOn, TRUE,
+            XmNfontList, fontlist1,
+            NULL);
+    }
+
+
+//fprintf(stderr,"Starting to add callbacks\n");
+
+
+    if (mw[i].message_data_line1) // If exists, add another callback
+        XtAddCallback(mw[i].message_data_line1, XmNactivateCallback, Send_message_now_1, (XtPointer)mw[i].win);
+
+    if (mw[i].message_data_line2) // If exists, add another callback
+        XtAddCallback(mw[i].message_data_line2, XmNactivateCallback, Send_message_now_2, (XtPointer)mw[i].win);
+
+    if (mw[i].message_data_line3) // If exists, add another callback
+        XtAddCallback(mw[i].message_data_line3, XmNactivateCallback, Send_message_now_3, (XtPointer)mw[i].win);
+
+    if (mw[i].message_data_line4) // If exists, add another callback
+        XtAddCallback(mw[i].message_data_line4, XmNactivateCallback, Send_message_now_4, (XtPointer)mw[i].win);
+
+//fprintf(stderr,"Exiting build_send_message_input_boxes()\n");
+
+}
+
+
+
+
+
+void rebuild_send_message_input_boxes(int ii, int hamhud, int d700, int d7) {
+
+//fprintf(stderr, "\nrebuild:  ii:%d  hamhud:%d  d700:%d  d7:%d\n", ii, hamhud, d700, d7);
+
+
+// Lesstif appears to have a problem with removing/adding widgets to
+// a dialog that's already been created and will segfault in this
+// case.  In order to make LSB-Xastir more reliable we disable the
+// dynamically-created widget code here and stick with the default
+// setup (one long TextField widget for input).
+//
+// Perhaps we need to do a Lesstif detect and do the same thing
+// anytime Lesstif is used as well?
+
+#ifndef NO_DYNAMIC_WIDGETS
+
+    // Remove the current message widgets
+    if (mw[ii].message_data_line4) {
+        XtDestroyWidget(mw[ii].message_data_line4);
+    }
+
+    if (mw[ii].message_data_line3) {
+        XtDestroyWidget(mw[ii].message_data_line3);
+    }
+
+    if (mw[ii].message_data_line2) {
+        XtDestroyWidget(mw[ii].message_data_line2);
+    }
+
+    if (mw[ii].message_data_line1) {
+        XtDestroyWidget(mw[ii].message_data_line1);
+    }
+
+
+    mw[ii].message_data_line1 = (Widget)NULL;
+    mw[ii].message_data_line2 = (Widget)NULL;
+    mw[ii].message_data_line3 = (Widget)NULL;
+    mw[ii].message_data_line4 = (Widget)NULL;
+
+
+    // Build the new boxes
+    build_send_message_input_boxes(ii, hamhud, d700, d7);
+
+#endif  // NO_DYNAMIC_WIDGETS
+
+}
+
+
+
+
+
+void HamHUD_Msg( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    intptr_t ii =(intptr_t)clientData;
+    int hamhud;
+
+    hamhud = XmToggleButtonGetState(mw[ii].HamHUD_mode);
+
+    if (hamhud) {
+        XmToggleButtonSetState(mw[ii].D700_mode,FALSE,FALSE);
+        XmToggleButtonSetState(mw[ii].D7_mode,FALSE,FALSE);
+    }
+    rebuild_send_message_input_boxes(ii, hamhud, 0, 0);
+}
+
+
+
+
+
+void D700_Msg( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    intptr_t ii = (intptr_t)clientData;
+    int d700;
+
+    d700 = XmToggleButtonGetState(mw[ii].D700_mode);
+
+    if (d700) {
+        XmToggleButtonSetState(mw[ii].HamHUD_mode,FALSE,FALSE);
+        XmToggleButtonSetState(mw[ii].D7_mode,FALSE,FALSE);
+    }
+    rebuild_send_message_input_boxes(ii, 0, d700, 0);
+}
+
+
+
+
+
+void D7_Msg( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    intptr_t ii = (intptr_t)clientData;
+    int d7;
+
+    d7 = XmToggleButtonGetState(mw[ii].D7_mode);
+
+    if (d7) {
+        XmToggleButtonSetState(mw[ii].HamHUD_mode,FALSE,FALSE);
+        XmToggleButtonSetState(mw[ii].D700_mode,FALSE,FALSE);
+    }
+    rebuild_send_message_input_boxes(ii, 0, 0, d7);
+}
+
+
+
+
+
+// Select HamHUD/D7/D700/Normal APRS messaging based on info
+// available in the station record.  Change the Send Message dialog
+// to match.
+//
+// Only call this when the Send Message dialog is first constructed
+// or when we hit the New/Refresh Call button.  We don't want to
+// have the user fighting against this function every sent or
+// received packet if this function happens to guess wrong.
+//
+void select_station_type(int ii) {
+    DataRow *p_station;
+    char call_sign[MAX_CALLSIGN+1];
+    char *temp_ptr;
+
+
+    if (mw[ii].send_message_call_data == NULL) {
+        fprintf(stderr,"messages_gui.c:select_station_type():mw[ii].send_message_call_data is NULL\n");
+        return;
+    }
+
+    temp_ptr = XmTextFieldGetString(mw[ii].send_message_call_data);
+    xastir_snprintf(call_sign,
+        sizeof(call_sign),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(call_sign);
+    (void)to_upper(call_sign);
+
+    // We have the callsign.  See if we have the station name in our
+    // database.
+    if (call_sign[0] != '\0'
+            && search_station_name(&p_station, call_sign, 1) ) { // Exact match
+
+        int hamhud = 0;
+        int d700 = 0;
+        int d7 = 0;
+//        int tx_only = 0;
+
+
+//fprintf(stderr,"Found callsign: %s\n", call_sign);
+
+        // check if station appears to be a transmit only station such as the TinyTrak and OpenTrak trackers.
+// ********* wrong test ********** 
+//if (p_station->aprs_symbol != NULL) { 
+//   if (p_station->aprs_symbol.aprs_type != NULL) { 
+//      fprintf(stderr,"Has Type: %s\n", p_station->aprs_symbol.aprs_type);
+//        if is_tx_only(p_station) {  
+//            tx_only++;
+//        }
+//   }
+//}
+
+        // Check first two comment records, if they exist
+        if (p_station->comment_data != NULL) {
+
+            // Check first comment record
+            if (strstr(p_station->comment_data->text_ptr,"TM-D700")) {
+                d700++;
+            }
+            else if (strstr(p_station->comment_data->text_ptr,"TH-D7")) {
+                d7++;
+            }
+            else if (p_station->comment_data->next) {
+                // Check second comment record
+                if (strstr(p_station->comment_data->next->text_ptr,"TM-D700")) {
+                    d700++;
+                }
+                else if (strstr(p_station->comment_data->next->text_ptr,"TH-D7")) {
+                    d7++;
+                }
+            }
+        }
+
+        // If not D700 or D7, check for HamHUD in the TOCALL.
+        // APHH2/APRHH2.  We'll skip the version number so-as to
+        // catch future versions as well.
+        //
+        if (!d700 && !d7) {
+            if (p_station->node_path_ptr) {
+                if (strncmp(p_station->node_path_ptr,"APRHH",5) == 0
+                        || strncmp(p_station->node_path_ptr,"APHH",4) == 0) {
+                    hamhud++;
+                }
+            }
+        }
+
+
+        if (hamhud) {
+//            fprintf(stderr,"HamHUD found\n");
+            XmToggleButtonSetState(mw[ii].HamHUD_mode,TRUE,FALSE);
+            XmToggleButtonSetState(mw[ii].D700_mode,FALSE,FALSE);
+            XmToggleButtonSetState(mw[ii].D7_mode,FALSE,FALSE);
+            rebuild_send_message_input_boxes(ii, hamhud, 0, 0);
+        }
+        else if (d700) { 
+//            fprintf(stderr,"D700 found\n");
+            XmToggleButtonSetState(mw[ii].HamHUD_mode,FALSE,FALSE);
+            XmToggleButtonSetState(mw[ii].D700_mode,TRUE,FALSE);
+            XmToggleButtonSetState(mw[ii].D7_mode,FALSE,FALSE);
+            rebuild_send_message_input_boxes(ii, 0, d700, 0);
+        }
+        else if (d7) {
+//            fprintf(stderr,"D7 found\n");
+            XmToggleButtonSetState(mw[ii].HamHUD_mode,FALSE,FALSE);
+            XmToggleButtonSetState(mw[ii].D700_mode,FALSE,FALSE);
+            XmToggleButtonSetState(mw[ii].D7_mode,TRUE,FALSE);
+            rebuild_send_message_input_boxes(ii, 0, 0, d7);
+        }
+        else {
+//            fprintf(stderr,"Standard APRS found\n");
+            XmToggleButtonSetState(mw[ii].HamHUD_mode,FALSE,FALSE);
+            XmToggleButtonSetState(mw[ii].D700_mode,FALSE,FALSE);
+            XmToggleButtonSetState(mw[ii].D7_mode,FALSE,FALSE);
+            rebuild_send_message_input_boxes(ii, 0, 0, d7);
+        }
+    }
+}
+
+
+
+
+
+// The main Send Message dialog.  db.c:update_messages() is the
+// function which fills in the message history information.
+//
+// The underlying code has been tweaked so that we can pass an EMPTY
+// path all the way down through the layers.  We defined special
+// strings for that and for setting default paths, and display these
+// to the user in this and the Change Path dialogs:
+//
+//  "DEFAULT PATH"
+//  "DIRECT PATH"
+//
+// A note from Jim Fuller, N7VR:
+//
+//   "I just set a test setup to my TH-D7GA.  First Display shows
+//   two lines 12 characters each, with the a third line of 12
+//   character and fourth line of 9 characters on the second display
+//   by pressing ok.  This means 45 characters for max message.
+//
+//   On my D-700, main first display is like the TH-D7GA.  But when
+//   I go to the message display it displays three lines.  The first
+//   two are 22 characters and the last is 20 characters.  This
+//   means 64 characters total.
+//
+//   I would only send a 24 character message to field troops, based
+//   on first read capability."
+//
+//
+void Send_message( /*@unused@*/ Widget w, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Arg args[50];
+    char temp[60];
+    unsigned int n;
+    int j;
+    intptr_t i;
+    char group[MAX_CALLSIGN+1];
+    int groupon;
+    int box_len;
+    Atom delw;
+
+
+//fprintf(stderr,"\n1Send_message\n");
+
+    groupon=0;
+    box_len=105;
+    i=0;
+
+begin_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message" );
+
+    for(j=0; j<MAX_MESSAGE_WINDOWS; j++) {
+        if(!mw[j].send_message_dialog) {
+            i=j;
+            break;
+        }
+    }
+
+    if(!mw[i].send_message_dialog) {
+
+        if (clientData != NULL) {
+            substr(group,(char *)clientData, MAX_CALLSIGN);
+            if (group[0] == '*') {
+                xastir_snprintf(mw[i].to_call_sign,
+                    sizeof(mw[i].to_call_sign),
+                    "***");
+                mw[i].to_call_sign[3] = '\0';   // Terminate it
+                memmove(group, &group[1], strlen(group));
+                groupon=1;
+                box_len=100;
+            } else {
+                xastir_snprintf(mw[i].to_call_sign,
+                    sizeof(mw[i].to_call_sign),
+                    "%s",
+                    my_callsign);
+                mw[i].to_call_sign[MAX_CALLSIGN] = '\0';    // Terminate it
+            }
+        } else {
+            xastir_snprintf(mw[i].to_call_sign,
+                sizeof(mw[i].to_call_sign),
+                "%s",
+                my_callsign);
+            mw[i].to_call_sign[MAX_CALLSIGN] = '\0';    // Terminate it
+        }
+
+        xastir_snprintf(temp, sizeof(temp), langcode(groupon==0 ? "WPUPMSB001": "WPUPMSB002"),
+                (i+1));
+
+        mw[i].message_group = groupon;
+        mw[i].send_message_dialog = XtVaCreatePopupShell(temp,
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNtitleString,"Send Message",
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].pane = XtVaCreateWidget("Send_message pane",
+                xmPanedWindowWidgetClass, 
+                mw[i].send_message_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].form =  XtVaCreateWidget("Send_message form",
+                xmFormWidgetClass,
+                mw[i].pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Row 1 (bottom)
+        mw[i].button_clear_old_msgs = XtVaCreateManagedWidget(langcode("WPUPMSB007"),
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].button_clear_pending_msgs = XtVaCreateManagedWidget(langcode("WPUPMSB011"),
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].button_kick_timer = XtVaCreateManagedWidget(langcode("WPUPMSB012"),
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].button_ok = XtVaCreateManagedWidget(langcode("WPUPMSB009"),
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 4,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Row 2 (1 up from bottom row)
+
+        // If D700 or D7 mode is enabled we break up the message
+        // box into 3 or 4 boxes with the lengths appropriate for
+        // those devices, else we use a single box which is 67 chars
+        // long, the maximum for an APRS message.
+        //
+        // Size of Kenwood screens:
+        // TH-D7A/E: Arranged as 12,12,12,9 (45 chars) 
+        // TM-D700A: Arranged as 22,22,20   (64 chars)
+        //
+        // Size of HamHUD screen:
+        // 20 char fits on one screen, any more gets scrolled.
+        //
+
+// First have radio buttons to change how we'll draw the message
+// input widgets:
+
+        mw[i].D7_mode =XtVaCreateManagedWidget("D7",
+                xmToggleButtonGadgetClass,
+                mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].button_clear_old_msgs,
+                XmNbottomOffset, 0,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+#ifndef NO_DYNAMIC_WIDGETS
+        XtAddCallback(mw[i].D7_mode,XmNvalueChangedCallback,D7_Msg,(XtPointer)i);
+#else   // NO_DYNAMIC_WIDGETS
+        XtSetSensitive(mw[i].D7_mode, FALSE);
+#endif  // NO_DYNAMIC_WIDGETS
+
+        mw[i].D700_mode =XtVaCreateManagedWidget("D700",
+                xmToggleButtonGadgetClass,
+                mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].D7_mode,
+                XmNbottomOffset, 0,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+            NULL);
+
+#ifndef NO_DYNAMIC_WIDGETS
+        XtAddCallback(mw[i].D700_mode,XmNvalueChangedCallback,D700_Msg,(XtPointer)i);
+#else   // NO_DYNAMIC_WIDGETS
+        XtSetSensitive(mw[i].D700_mode, FALSE);
+#endif  // NO_DYNAMIC_WIDGETS
+
+        mw[i].HamHUD_mode =XtVaCreateManagedWidget("HamHUD",
+                xmToggleButtonGadgetClass,
+                mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].D700_mode,
+                XmNbottomOffset, 0,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+            NULL);
+
+#ifndef NO_DYNAMIC_WIDGETS
+        XtAddCallback(mw[i].HamHUD_mode,XmNvalueChangedCallback,HamHUD_Msg,(XtPointer)i);
+#else   // NO_DYNAMIC_WIDGETS
+        XtSetSensitive(mw[i].HamHUD_mode, FALSE);
+#endif  // NO_DYNAMIC_WIDGETS
+
+        mw[i].message = XtVaCreateManagedWidget(langcode("WPUPMSB008"),
+                xmLabelWidgetClass, 
+                mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].button_clear_old_msgs,
+                XmNbottomOffset, 10,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, mw[i].HamHUD_mode,
+                XmNleftOffset, 3,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+// Default:  No D700 or D7 mode selected.  Standard APRS mode.
+// Go build the proper input box for standard APRS mode, 67
+// chars long.
+//
+        build_send_message_input_boxes(i, 0, 0, 0);
+
+
+// Row 3 (2 up from bottom row)
+        mw[i].call = XtVaCreateManagedWidget(langcode(groupon == 0  ? "WPUPMSB003": "WPUPMSB004"),
+                xmLabelWidgetClass, mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].message,
+                XmNbottomOffset, 15,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, mw[i].HamHUD_mode,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].send_message_call_data = XtVaCreateManagedWidget("Send_message smcd", 
+                xmTextFieldWidgetClass, 
+                mw[i].form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 10,
+                XmNwidth, ((10*7)+2),
+                XmNmaxLength, 10,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].message,
+                XmNbottomOffset, 10,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, mw[i].call,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        xastir_snprintf(temp, sizeof(temp), "%s", langcode(groupon == 0 ? "WPUPMSB005": "WPUPMSB006"));
+
+        mw[i].button_submit_call = XtVaCreateManagedWidget(temp,
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, mw[i].send_message_call_data,
+                XmNleftOffset, 10,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].message,
+                XmNbottomOffset, 12,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].path = XtVaCreateManagedWidget(langcode("WPUPMSB010"),
+                xmLabelWidgetClass, mw[i].form,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].message,
+                XmNbottomOffset, 15,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, mw[i].button_submit_call,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].send_message_change_path = XtVaCreateManagedWidget(langcode("WPUPMSB019"),
+                xmPushButtonGadgetClass, 
+                mw[i].form,
+                XmNleftAttachment, XmATTACH_NONE,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].message,
+                XmNbottomOffset, 12,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        mw[i].send_message_path = XtVaCreateManagedWidget("Send_message path", 
+                xmTextFieldWidgetClass, 
+                mw[i].form,
+                XmNeditable,   FALSE,
+                XmNcursorPositionVisible, FALSE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 26,
+                XmNwidth, ((26*7)+2),
+                XmNmaxLength, 199,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_NONE,
+                XmNbottomAttachment, XmATTACH_WIDGET,
+                XmNbottomWidget, mw[i].message,
+                XmNbottomOffset, 10,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, mw[i].path,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_WIDGET,
+                XmNrightWidget, mw[i].send_message_change_path,
+                XmNrightOffset, 10,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Row 4 (3 up from bottom row).  Message area.
+        n=0;
+        XtSetArg(args[n], XmNrows, 10); n++;
+        XtSetArg(args[n], XmNmaxHeight, 170); n++;
+        XtSetArg(args[n], XmNcolumns, box_len); n++;
+        XtSetArg(args[n], XmNeditable, FALSE); n++;
+        XtSetArg(args[n], XmNtraversalOn, FALSE); n++;
+        XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
+        XtSetArg(args[n], XmNwordWrap, TRUE); n++;
+        XtSetArg(args[n], XmNshadowThickness, 3); n++;
+        XtSetArg(args[n], XmNscrollHorizontal, FALSE); n++;
+        XtSetArg(args[n], XmNcursorPositionVisible, FALSE); n++;
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNtopOffset, 5); n++;
+        XtSetArg(args[n], XmNbottomAttachment,XmATTACH_WIDGET); n++;
+        XtSetArg(args[n], XmNbottomWidget,mw[i].call); n++;
+        XtSetArg(args[n], XmNbottomOffset, 10); n++;
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNleftOffset, 5); n++;
+        XtSetArg(args[n], XmNrightAttachment,XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNrightOffset,5); n++;
+        XtSetArg(args[n], XmNautoShowCursorPosition, FALSE); n++;
+        XtSetArg(args[n], XmNforeground, MY_FG_COLOR); n++;
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+
+// This one causes segfaults, why?  Answer: args[] was set to 20
+// (too small)
+//        XtSetArg(args[n], XmNbackground, MY_BG_COLOR); n++;
+ 
+        mw[i].send_message_text = XmCreateScrolledText(mw[i].form,
+                "Send_message smt",
+                args,
+                n);
+
+        xastir_snprintf(mw[i].win, sizeof(mw[i].win), "%ld", i);
+
+        XtAddCallback(mw[i].send_message_change_path, XmNactivateCallback, Send_message_change_path, (XtPointer)mw[i].win);
+ 
+        XtAddCallback(mw[i].button_ok, XmNactivateCallback, Send_message_now, (XtPointer)mw[i].win);
+
+        XtAddCallback(mw[i].button_cancel, XmNactivateCallback, Send_message_destroy_shell, (XtPointer)mw[i].win);
+ 
+// Note group messages isn't implemented fully yet.  When it is, the following might have
+// to change again:
+//        XtAddCallback(mw[i].button_clear_old_msgs, XmNactivateCallback, groupon == 0 ? Clear_message_from: Clear_message_to,
+//                (XtPointer)mw[i].win);
+        XtAddCallback(mw[i].button_clear_old_msgs, XmNactivateCallback, Clear_message_to_from, (XtPointer)mw[i].win);
+
+        XtAddCallback(mw[i].button_clear_pending_msgs, XmNactivateCallback, Clear_messages_to, (XtPointer)mw[i].win);
+
+        XtAddCallback(mw[i].button_kick_timer, XmNactivateCallback, Kick_timer, (XtPointer)mw[i].win);
+
+        XtAddCallback(mw[i].button_submit_call, XmNactivateCallback, Check_new_call_messages, (XtPointer)i);
+
+        if (clientData != NULL) {
+            XmTextFieldSetString(mw[i].send_message_call_data, group);
+        }
+
+        // Set "DEFAULT PATH" into the path field
+        XmTextFieldSetString(mw[i].send_message_path,"DEFAULT PATH");
+
+        pos_dialog(mw[i].send_message_dialog);
+
+        delw = XmInternAtom(XtDisplay(mw[i].send_message_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(mw[i].send_message_dialog, delw, Send_message_destroy_shell, (XtPointer)mw[i].win);
+
+        XtManageChild(mw[i].form);
+        XtManageChild(mw[i].send_message_text);
+        XtVaSetValues(mw[i].send_message_text, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(mw[i].pane);
+
+        XtPopup(mw[i].send_message_dialog,XtGrabNone);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(mw[i].send_message_dialog);
+        XmProcessTraversal(mw[i].button_cancel, XmTRAVERSE_CURRENT);
+
+    }
+
+//fprintf(stderr,"2calling select_station_type()\n");
+
+    // Re-arrange the outgoing message boxes based on the type of
+    // device we're talking to.
+    select_station_type(i);
+ 
+//fprintf(stderr,"2returned from select_station_type()\n");
+//fprintf(stderr,"1end of Send_message()\n");
+
+end_critical_section(&send_message_dialog_lock, "messages_gui.c:Send_message" );
+
+}
+
+
+
+
+
+// Bring up a Send Message dialog for each QSO that has pending
+// outbound messages.
+//
+void Show_pending_messages( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    intptr_t ii;
+    int msgs_found = 0;
+
+
+    // Look through the outgoing message queue.  Find all callsigns
+    // that we're currently trying to send messages to.
+    //
+    for (ii = 0; ii < MAX_OUTGOING_MESSAGES; ii++) {
+
+        // If it matches the callsign we're talking to
+        if (message_pool[ii].active==MESSAGE_ACTIVE) {
+
+            msgs_found++;
+
+            // Bring up a Send Message box for each callsign found.
+            Send_message_call(NULL, message_pool[ii].to_call_sign, NULL);
+
+            // Fill in the old data in case it doesn't auto-fill
+            Check_new_call_messages(NULL, (XtPointer)ii, NULL);
+        }
+    }
+
+    if (msgs_found == 0) {
+        fprintf(stderr, "No Pending Messages.\n");
+    }
+}
+
+
+
+
+
+/************************* Auto msg **************************************/
+/*************************************************************************/
+void Auto_msg_option( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer calldata) {
+    int item_no = XTPOINTER_TO_INT(clientData);
+
+    if (item_no)
+        auto_reply = 1;
+    else
+        auto_reply = 0;
+}
+
+
+
+
+
+void Auto_msg_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) { 
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&auto_msg_dialog_lock, "messages_gui.c:Auto_msg_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    auto_msg_dialog = (Widget)NULL;
+
+end_critical_section(&auto_msg_dialog_lock, "messages_gui.c:Auto_msg_destroy_shell" );
+
+}
+
+
+
+
+
+void Auto_msg_set_now(Widget w, XtPointer clientData, XtPointer callData) {
+    char temp[110];
+    char *temp_ptr;
+
+
+    temp_ptr = XmTextFieldGetString(auto_msg_set_data);
+    substr(temp, temp_ptr, 99);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(temp);
+    xastir_snprintf(auto_reply_message,
+        sizeof(auto_reply_message),
+        "%s",
+        temp);
+    Auto_msg_destroy_shell(w, clientData, callData);
+}
+
+
+
+
+
+void Auto_msg_set( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, button_ok, button_cancel, reply;
+    Atom delw;
+
+begin_critical_section(&auto_msg_dialog_lock, "messages_gui.c:Auto_msg_set" );
+
+    if(!auto_msg_dialog) {
+
+        auto_msg_dialog = XtVaCreatePopupShell(langcode("WPUPARM001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Auto_msg_set pane",
+                xmPanedWindowWidgetClass, 
+                auto_msg_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Auto_msg_set my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        reply = XtVaCreateManagedWidget(langcode("WPUPARM002"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        auto_msg_set_data = XtVaCreateManagedWidget("Auto_msg_set auto_msg_set_data", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 40,
+                XmNwidth, ((40*7)+2),
+                XmNmaxLength, 100,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, reply,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("UNIOP00001"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, auto_msg_set_data,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, auto_msg_set_data,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 3,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 4,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Auto_msg_set_now, auto_msg_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Auto_msg_destroy_shell, auto_msg_dialog);
+
+        pos_dialog(auto_msg_dialog);
+
+        delw = XmInternAtom(XtDisplay(auto_msg_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(auto_msg_dialog, delw, Auto_msg_destroy_shell, (XtPointer)auto_msg_dialog);
+        XmTextFieldSetString(auto_msg_set_data,auto_reply_message);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        XtPopup(auto_msg_dialog,XtGrabNone);
+        fix_dialog_size(auto_msg_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(auto_msg_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(auto_msg_dialog), XtWindow(auto_msg_dialog));
+
+end_critical_section(&auto_msg_dialog_lock, "messages_gui.c:Auto_msg_set" );
+
+}
+
+
diff --git a/src/objects.c b/src/objects.c
new file mode 100644
index 0000000..f7c1d38
--- /dev/null
+++ b/src/objects.c
@@ -0,0 +1,11106 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: objects.c,v 1.67 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+//#include <stdio.h>
+//#include <stdlib.h>
+#include <stdint.h>
+//#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+//#include <sys/stat.h>
+//#include <sys/file.h>
+//#include <unistd.h>
+//#include <dirent.h>
+//#include <signal.h>
+//#include <termios.h>
+//#include <pwd.h>
+//#include <locale.h>
+
+// Needed for Solaris
+//#ifdef HAVE_STRINGS_H
+//#include <strings.h>
+//#endif  // HAVE_STRINGS_H
+
+//#include <sys/wait.h>
+//#include <errno.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+//#ifdef HAVE_MAGICK
+//#include <sys/types.h>
+//#undef RETSIGTYPE
+///* JMT - stupid ImageMagick */
+//#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+//#undef PACKAGE_BUGREPORT
+//#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+//#undef PACKAGE_NAME
+//#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+//#undef PACKAGE_STRING
+//#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+//#undef PACKAGE_TARNAME
+//#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+//#undef PACKAGE_VERSION
+//#ifdef HAVE_GRAPHICSMAGICK
+//#include <GraphicsMagick/magick/api.h>
+//#else   // HAVE_GRAPHICSMAGICK
+//#include <magick/api.h>
+//#endif  // HAVE_GRAPHICSMAGICK 
+//#undef PACKAGE_BUGREPORT
+//#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+//#undef XASTIR_PACKAGE_BUGREPORT
+//#undef PACKAGE_NAME
+//#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+//#undef XASTIR_PACKAGE_NAME
+//#undef PACKAGE_STRING
+//#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+//#undef XASTIR_PACKAGE_STRING
+//#undef PACKAGE_TARNAME
+//#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+//#undef XASTIR_PACKAGE_TARNAME
+//#undef PACKAGE_VERSION
+//#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+//#undef XASTIR_PACKAGE_VERSION
+//#endif // HAVE_MAGICK
+
+//#ifdef  HAVE_LIBINTL_H
+//#include <libintl.h>
+//#define _(x)        gettext(x)
+//#else   // HAVE_LIBINTL_H
+//#define _(x)        (x)
+//#endif  // HAVE_LIBINTL_H
+
+//#ifdef HAVE_NETAX25_AXLIB_H
+//#include <netax25/axlib.h>
+//#endif    // HAVE_NETAX25_AXLIB_H
+
+//#ifdef HAVE_LIBCURL
+//#include <curl/curl.h>
+//#endif
+
+//#ifdef HAVE_LIBGDAL
+//// WE7U - stupid ImageMagick
+//#define XASTIR_PACKAGE_BUGREPORT PACKAGE_BUGREPORT
+//#undef PACKAGE_BUGREPORT
+//#define XASTIR_PACKAGE_NAME PACKAGE_NAME
+//#undef PACKAGE_NAME
+//#define XASTIR_PACKAGE_STRING PACKAGE_STRING
+//#undef PACKAGE_STRING
+//#define XASTIR_PACKAGE_TARNAME PACKAGE_TARNAME
+//#undef PACKAGE_TARNAME
+//#define XASTIR_PACKAGE_VERSION PACKAGE_VERSION
+//#undef PACKAGE_VERSION
+//#include <ogr_api.h>
+//#undef PACKAGE_BUGREPORT
+//#define PACKAGE_BUGREPORT XASTIR_PACKAGE_BUGREPORT
+//#undef XASTIR_PACKAGE_BUGREPORT
+//#undef PACKAGE_NAME
+//#define PACKAGE_NAME XASTIR_PACKAGE_NAME
+//#undef XASTIR_PACKAGE_NAME
+//#undef PACKAGE_STRING
+//#define PACKAGE_STRING XASTIR_PACKAGE_STRING
+//#undef XASTIR_PACKAGE_STRING
+//#undef PACKAGE_TARNAME
+//#define PACKAGE_TARNAME XASTIR_PACKAGE_TARNAME
+//#undef XASTIR_PACKAGE_TARNAME
+//#undef PACKAGE_VERSION
+//#define PACKAGE_VERSION XASTIR_PACKAGE_VERSION
+//#undef XASTIR_PACKAGE_VERSION
+//#include <gdal.h>
+//#endif
+
+#include "xastir.h"
+#include "draw_symbols.h"
+#include "main.h"
+#include "xa_config.h"
+#include "maps.h"
+//#include "alert.h"
+#include "interface.h"
+//#include "wx.h"
+//#include "popup.h"
+//#include "track_gui.h"
+//#include "list_gui.h"
+//#include "util.h"
+//#include "color.h"
+//#include "gps.h"
+//#include "bulletin_gui.h"
+//#include "rotated.h"
+//#include "datum.h"
+//#include "igate.h"
+#include "objects.h"
+
+//#include "database.h"
+// in lieu of the above, just declare one function:
+void move_station_time(DataRow *p_curr, DataRow *p_time);
+
+//#ifdef HAVE_LIBSHP
+//  #include "shp_hash.h"
+//#endif  // HAVE_LIBSHP
+
+//#include "x_spider.h"
+//#include "map_cache.h"
+
+
+#include <Xm/XmAll.h>
+#include <X11/cursorfont.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+// lesstif (at least as of version 0.94 in 2008), doesn't
+// have full implementation of combo boxes.
+#ifndef USE_COMBO_BOX
+#if (XmVERSION >= 2 && !defined(LESSTIF_VERSION))
+#  define USE_COMBO_BOX 1
+#endif
+#endif  // USE_COMBO_BOX
+
+
+// ---------------------------- object -------------------------------
+Widget object_dialog = (Widget)NULL;
+Widget df_object_dialog = (Widget)NULL;
+Widget object_name_data,
+       object_lat_data_deg, object_lat_data_min, object_lat_data_ns,
+       object_lon_data_deg, object_lon_data_min, object_lon_data_ew,
+       object_group_data, object_symbol_data, object_icon,
+       object_comment_data, ob_frame, ob_group, ob_symbol,
+       ob_option_frame,
+       signpost_frame, area_frame, area_toggle, signpost_toggle,
+       df_bearing_toggle, map_view_toggle, probabilities_toggle,
+       ob_bearing_data, frameomni, framebeam,
+       ob_speed, ob_speed_data, ob_course, ob_course_data,
+       ob_comment,
+       ob_altitude, ob_altitude_data, signpost_data,
+       probability_data_min, probability_data_max,
+       open_filled_toggle, ob_lat_offset_data, ob_lon_offset_data,
+       ob_corridor, ob_corridor_data, ob_corridor_miles,
+       omni_antenna_toggle, beam_antenna_toggle;
+Pixmap Ob_icon0, Ob_icon;
+void Set_Del_Object(Widget w, XtPointer clientData, XtPointer calldata);
+// Array to hold predefined objects to display on Create/Move popup menu.
+predefinedObject predefinedObjects[MAX_NUMBER_OF_PREDEFINED_OBJECTS];
+void Populate_predefined_objects(predefinedObject *predefinedObjects);
+int number_of_predefined_objects;  
+char predefined_object_definition_filename[256] = "predefined_SAR.sys";
+int predefined_menu_from_file = 0;
+
+int Area_object_enabled = 0;
+int Map_View_object_enabled = 0;
+int Area_type = 0;
+char Area_color[3] = "/0";
+int Area_bright = 0;
+int Area_filled = 0;
+int Signpost_object_enabled = 0;
+int Probability_circles_enabled = 0;
+int DF_object_enabled = 0;
+int Omni_antenna_enabled = 0;
+int Beam_antenna_enabled = 0;
+char object_shgd[5] = "0000\0";
+char object_NRQ[4] = "960\0";
+XtPointer global_parameter1 = (XtPointer)NULL;
+XtPointer global_parameter2 = (XtPointer)NULL;
+
+int polygon_last_x = -1;        // Draw CAD Objects functions
+int polygon_last_y = -1;        // Draw CAD Objects functions
+
+int doing_move_operation = 0;
+
+Widget draw_CAD_objects_dialog = (Widget)NULL;
+Widget cad_dialog = (Widget)NULL;
+Widget cad_label_data, 
+       cad_comment_data, 
+       cad_probability_data, 
+       cad_line_style_data;
+       // Values entered in the cad_dialog
+int draw_CAD_objects_flag = 0;
+void Draw_All_CAD_Objects(Widget w);
+void Save_CAD_Objects_to_file(void);
+Widget cad_erase_dialog;
+Widget list_of_existing_CAD_objects = (Widget)NULL;
+Widget cad_list_dialog = (Widget)NULL;
+Widget list_of_existing_CAD_objects_edit = (Widget)NULL;
+void Format_area_for_output(double *area_km2, char *area_description, int sizeof_area_description);
+void Update_CAD_objects_list_dialog(void);
+void CAD_object_set_raw_probability(CADRow *object_ptr, float probability, int as_percent);
+int CAD_draw_objects = TRUE;
+int CAD_show_label = TRUE;
+int CAD_show_raw_probability = TRUE;
+int CAD_show_comment = TRUE;
+int CAD_show_area = TRUE; 
+void Draw_CAD_Objects_erase_dialog_close(Widget w, XtPointer clientData, XtPointer callData);
+void Draw_CAD_Objects_list_dialog_close(Widget w, XtPointer clientData, XtPointer callData);
+#ifndef USE_COMBO_BOX
+int clsd_value;  // replacement value for cad line type combo box
+#endif // !USE_COMBO_BOX
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Init values for Objects dialog
+char last_object[9+1];
+char last_obj_grp;
+char last_obj_sym;
+char last_obj_overlay;
+char last_obj_comment[34+1];
+
+
+
+/////////////////////////////////////////////////////////////////////////
+
+
+
+/*
+ *  Check for a valid object name
+ */
+int valid_object(char *name) {
+    int len, i;
+
+    // max 9 printable ASCII characters, case sensitive   [APRS
+    // Reference]
+    len = (int)strlen(name);
+    if (len > 9 || len == 0)
+        return(0);                      // wrong size
+
+    for (i=0;i<len;i++)
+        if (!isprint((int)name[i]))
+            return(0);                  // not printable
+
+    return(1);
+}
+
+
+
+
+
+/*
+ *  Check for a valid item name (3-9 chars, any printable ASCII
+ *  except '!' or '_')
+ */
+int valid_item(char *name) {
+    int len, i;
+
+    // min 3, max 9 printable ASCII characters, case sensitive
+    // [APRS Reference]
+    len = (int)strlen(name);
+    if (len > 9 || len < 3)
+        return(0);                      // Wrong size
+
+    for (i=0;i<len;i++) {
+        if (!isprint((int)name[i])) {
+            return(0);                  // Not printable
+        }
+        if ( (name[i] == '!') || (name[i] == '_') ) {
+            return(0);                  // Contains '!' or '_'
+        }
+    }
+
+    return(1);
+}
+
+
+
+
+
+/*
+ *  Clear out object/item history log file
+ */
+void Object_History_Clear( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char *file;
+    FILE *f;
+    char temp_file_path[MAX_VALUE];
+
+    file = get_user_base_dir("config/object.log", temp_file_path, sizeof(temp_file_path));
+
+    f=fopen(file,"w");
+    if (f!=NULL) {
+        (void)fclose(f);
+
+        if (debug_level & 1)
+            fprintf(stderr,"Clearing Object/Item history file...\n");
+    }
+    else {
+        fprintf(stderr,"Couldn't open file for writing: %s\n", file);
+    }
+}
+
+
+
+
+
+/*
+ *  Re-read object/item history log file
+ */
+void Object_History_Refresh( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+
+    // Reload saved objects and items from previous runs.
+    reload_object_item();
+}
+
+
+
+
+
+// We have a lot of code duplication between Setup_object_data,
+// Setup_item_data, and Create_object_item_tx_string.
+//
+// Make sure to look at the "transmit_compressed_objects_items"
+// variable
+// to decide whether to send a compressed packet.
+/*
+ *  Create the transmit string for Objects/Items.
+ *  Input is a DataRow struct, output is both an integer that says
+ *  whether it completed successfully, and a char* that has the
+ *  output tx string in it.
+ *
+ *  Returns 0 if there's a problem.
+ */
+int Create_object_item_tx_string(DataRow *p_station, char *line, int line_length) {
+    int i, done;
+    char lat_str[MAX_LAT];
+    char lon_str[MAX_LONG];
+    char comment[43+1];                 // max 43 characters of comment
+    char comment2[43+1];
+    char time[7+1];
+    struct tm *day_time;
+    time_t sec;
+    char complete_area_color[3];
+    int complete_area_type;
+    int lat_offset, lon_offset;
+    char complete_corridor[6];
+    char altitude[10];
+    char speed_course[8];
+    int speed;
+    int course;
+    int temp;
+    long temp2;
+    char signpost[6];
+    int bearing;
+    char tempstr[50];
+    char object_group;
+    char object_symbol;
+    int killed = 0;
+
+
+    (void)remove_trailing_spaces(p_station->call_sign);
+    //(void)to_upper(p_station->call_sign);     Not per spec.  Don't
+    //use this.
+
+    if ((p_station->flag & ST_OBJECT) != 0) {   // We have an object
+        if (!valid_object(p_station->call_sign)) {
+            line[0] = '\0';
+            return(0);
+        }
+    }
+    else if ((p_station->flag & ST_ITEM) != 0) {    // We have an item
+        xastir_snprintf(tempstr,
+            sizeof(tempstr),
+            "%s",
+            p_station->call_sign);
+        if (strlen(tempstr) == 1)  // Add two spaces (to make 3 minimum chars)
+            xastir_snprintf(p_station->call_sign, sizeof(p_station->call_sign), "%s  ",tempstr);
+        else if (strlen(tempstr) == 2) // Add one space (to make 3 minimum chars)
+            xastir_snprintf(p_station->call_sign, sizeof(p_station->call_sign), "%s ",tempstr);
+
+        if (!valid_item(p_station->call_sign)) {
+            line[0] = '\0';
+            return(0);
+        }
+    }
+    else {  // Not an item or an object, what are we doing here!
+        line[0] = '\0';
+        return(0);
+    }
+
+    // Lat/lon are in Xastir coordinates, so we need to convert
+    // them to APRS string format here.
+    convert_lat_l2s(p_station->coord_lat, lat_str, sizeof(lat_str), CONVERT_LP_NOSP);
+    convert_lon_l2s(p_station->coord_lon, lon_str, sizeof(lon_str), CONVERT_LP_NOSP);
+
+    // Check for an overlay character.  Replace the group character
+    // (table char) with the overlay if present.
+    if (p_station->aprs_symbol.special_overlay != '\0') {
+        // Overlay character found
+        object_group = p_station->aprs_symbol.special_overlay;
+        if ( (object_group >= '0' && object_group <= '9')
+                || (object_group >= 'A' && object_group <= 'Z') ) {
+            // Valid overlay character, use what we have
+        }
+        else {
+            // Bad overlay character, throw it away
+            object_group = '\\';
+        }
+    }
+    else {    // No overlay character
+        object_group = p_station->aprs_symbol.aprs_type;
+    }
+
+    object_symbol = p_station->aprs_symbol.aprs_symbol;
+
+    // In this case we grab only the first comment field (if it
+    // exists) for the object/item
+    if ( (p_station->comment_data != NULL)
+            && (p_station->comment_data->text_ptr != NULL) ){
+        xastir_snprintf(comment,
+            sizeof(comment),
+            "%s",
+            p_station->comment_data->text_ptr);
+    }
+    else {
+        comment[0] = '\0';  // Empty string
+    }
+
+    if ( (p_station->probability_min[0] != '\0')
+            || (p_station->probability_max[0] != '\0') ) {
+
+        if (p_station->probability_max[0] == '\0') {
+            // Only have probability_min
+            xastir_snprintf(comment2,
+                sizeof(comment2),"Pmin%s,%s",
+                p_station->probability_min,
+                comment);
+        }
+        else if (p_station->probability_min[0] == '\0') {
+            // Only have probability_max
+            xastir_snprintf(comment2,
+                sizeof(comment2),"Pmax%s,%s",
+                p_station->probability_max,
+                comment);
+        }
+        else {  // Have both
+            xastir_snprintf(comment2,
+                sizeof(comment2),"Pmin%s,Pmax%s,%s",
+                p_station->probability_min,
+                p_station->probability_max,
+                comment);
+        }
+        xastir_snprintf(comment,sizeof(comment), "%s", comment2);
+    }
+
+
+    // Put RNG or PHG at the beginning of the comment
+    xastir_snprintf(comment2,
+        sizeof(comment2),
+        "%s%s",
+        p_station->power_gain,
+        comment);
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        comment2);
+
+
+    (void)remove_trailing_spaces(comment);
+
+
+    // This is for objects only, not items.  Uses current time but
+    // should use the transmitted time from the DataRow struct.
+    // Which time field in the struct would that be?  Have to find
+    // out
+    // from the extract_?? code.
+    if ((p_station->flag & ST_OBJECT) != 0) {
+        sec = sec_now();
+        day_time = gmtime(&sec);
+        xastir_snprintf(time,
+            sizeof(time),
+            "%02d%02d%02dz",
+            day_time->tm_mday,
+            day_time->tm_hour,
+            day_time->tm_min);
+    }
+
+
+// Handle Generic Options
+
+
+    // Speed/Course Fields
+    xastir_snprintf(speed_course, sizeof(speed_course), ".../"); // Start with invalid-data string
+    course = 0;
+    if (strlen(p_station->course) != 0) {    // Course was entered
+        // Need to check for 1 to three digits only, and 001-360
+        // degrees)
+        temp = atoi(p_station->course);
+        if ( (temp >= 1) && (temp <= 360) ) {
+            xastir_snprintf(speed_course, sizeof(speed_course), "%03d/",temp);
+            course = temp;
+        }
+        else if (temp == 0) {   // Spec says 001 to 360 degrees...
+            xastir_snprintf(speed_course, sizeof(speed_course), "360/");
+        }
+    }
+    speed = 0;
+    if (strlen(p_station->speed) != 0) { // Speed was entered (we only handle knots currently)
+        // Need to check for 1 to three digits, no alpha characters
+        temp = atoi(p_station->speed);
+        if ( (temp >= 0) && (temp <= 999) ) {
+            long x_long, y_lat;
+
+            xastir_snprintf(tempstr, sizeof(tempstr), "%03d",temp);
+            strncat(speed_course,
+                tempstr,
+                sizeof(speed_course) - 1 - strlen(speed_course));
+            speed = temp;
+
+            // Speed is non-zero.  Compute the current dead-reckoned
+            // position and use that instead.
+            compute_current_DR_position(p_station,
+                &x_long,
+                &y_lat);
+
+            // Lat/lon are in Xastir coordinates, so we need to
+            // convert them to APRS string format here.
+            //
+            convert_lat_l2s(y_lat,
+                lat_str,
+                sizeof(lat_str),
+                CONVERT_LP_NOSP);
+
+            convert_lon_l2s(x_long,
+                lon_str,
+                sizeof(lon_str),
+                CONVERT_LP_NOSP);
+
+//fprintf(stderr,"\t%s  %s\n", lat_str, lon_str);
+
+        }
+        else {
+            strncat(speed_course,
+                "...",
+                sizeof(speed_course) - 1 - strlen(speed_course));
+        }
+    }
+    else {  // No speed entered, blank it out
+        strncat(speed_course,
+            "...",
+            sizeof(speed_course) - 1 - strlen(speed_course));
+    }
+    if ( (speed_course[0] == '.') && (speed_course[4] == '.') ) {
+        speed_course[0] = '\0'; // No speed or course entered, so blank it
+    }
+    if (p_station->aprs_symbol.area_object.type != AREA_NONE) {  // It's an area object
+        speed_course[0] = '\0'; // Course/Speed not allowed if Area Object
+    }
+
+    // Altitude Field
+    altitude[0] = '\0'; // Start with empty string
+    if (strlen(p_station->altitude) != 0) {   // Altitude was entered (we only handle feet currently)
+        // Need to check for all digits, and 1 to 6 digits
+        if (isdigit((int)p_station->altitude[0])) {
+            // Must convert from meters to feet before transmitting
+            temp2 = (int)( (atof(p_station->altitude) / 0.3048) + 0.5);
+            if ( (temp2 >= 0) && (temp2 <= 99999l) ) {
+                xastir_snprintf(altitude, sizeof(altitude), "/A=%06ld",temp2);
+            }
+        }
+    }
+
+
+// Handle Specific Options
+
+
+    // Area Objects
+    if (p_station->aprs_symbol.area_object.type != AREA_NONE) { // It's an area object
+
+        // Note that transmitted color consists of two characters,
+        // from "/0" to "15"
+        xastir_snprintf(complete_area_color, sizeof(complete_area_color), "%02d", p_station->aprs_symbol.area_object.color);
+        if (complete_area_color[0] == '0')
+            complete_area_color[0] = '/';
+
+        complete_area_type = p_station->aprs_symbol.area_object.type;
+
+        lat_offset = p_station->aprs_symbol.area_object.sqrt_lat_off;
+        lon_offset = p_station->aprs_symbol.area_object.sqrt_lon_off;
+
+        // Corridor
+        complete_corridor[0] = '\0';
+        if ( (complete_area_type == 1) || (complete_area_type == 6)) {
+            if (p_station->aprs_symbol.area_object.corridor_width > 0) {
+                xastir_snprintf(complete_corridor, sizeof(complete_corridor), "{%d}",
+                        p_station->aprs_symbol.area_object.corridor_width);
+            }
+        }
+
+        if ((p_station->flag & ST_OBJECT) != 0) {   // It's an object
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%1d%02d%2s%02d%s%s%s",
+                    p_station->call_sign,
+                    time,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    complete_area_type,
+                    lat_offset,
+                    complete_area_color,
+                    lon_offset,
+                    speed_course,
+                    complete_corridor,
+                    altitude);
+
+            }
+            else {  // Non-compressed posit object
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%1d%02d%2s%02d%s%s%s",
+                    p_station->call_sign,
+                    time,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    complete_area_type,
+                    lat_offset,
+                    complete_area_color,
+                    lon_offset,
+                    speed_course,
+                    complete_corridor,
+                    altitude);
+            }
+        }
+        else  {     // It's an item
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ")%s!%s%1d%02d%2s%02d%s%s%s",
+                    p_station->call_sign,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    complete_area_type,
+                    lat_offset,
+                    complete_area_color,
+                    lon_offset,
+                    speed_course,
+                    complete_corridor,
+                    altitude);
+            }
+            else {  // Non-compressed item
+
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%c%1d%02d%2s%02d%s%s%s",
+                    p_station->call_sign,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    complete_area_type,
+                    lat_offset,
+                    complete_area_color,
+                    lon_offset,
+                    speed_course,
+                    complete_corridor,
+                    altitude);
+            }
+        }
+    }
+
+    else if ( (p_station->aprs_symbol.aprs_type == '\\') // We have a signpost object
+            && (p_station->aprs_symbol.aprs_symbol == 'm' ) ) {
+        if (strlen(p_station->signpost) > 0) {
+            xastir_snprintf(signpost, sizeof(signpost), "{%s}", p_station->signpost);
+        }
+        else {  // No signpost data entered, blank it out
+            signpost[0] = '\0';
+        }
+        if ((p_station->flag & ST_OBJECT) != 0) {   // It's an object
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%s%s",
+                    p_station->call_sign,
+                    time,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    altitude,
+                    signpost);
+            }
+            else {  // Non-compressed posit object
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%s%s%s",
+                    p_station->call_sign,
+                    time,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    speed_course,
+                    altitude,
+                    signpost);
+            }
+        }
+        else {  // It's an item
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ")%s!%s%s%s",
+                    p_station->call_sign,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    altitude,
+                    signpost);
+            }
+            else {  // Non-compressed item
+
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%c%s%s%s",
+                    p_station->call_sign,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    speed_course,
+                    altitude,
+                    signpost);
+            }
+        }
+    }
+
+    else if (p_station->signal_gain[0] != '\0') { // Must be an Omni-DF object/item
+
+        if ((p_station->flag & ST_OBJECT) != 0) {   // It's an object
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%s/%s%s",
+                    p_station->call_sign,
+                    time,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    p_station->signal_gain,
+                    speed_course,
+                    altitude);
+            }
+            else {  // Non-compressed posit object
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%s/%s%s",
+                    p_station->call_sign,
+                    time,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    p_station->signal_gain,
+                    speed_course,
+                    altitude);
+            }
+        }
+        else {  // It's an item
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ")%s!%s%s/%s%s",
+                    p_station->call_sign,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    p_station->signal_gain,
+                    speed_course,
+                    altitude);
+            }
+            else {  // Non-compressed item
+
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%c%s/%s%s",
+                    p_station->call_sign,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    p_station->signal_gain,
+                    speed_course,
+                    altitude);
+            }
+        }
+    }
+    else if (p_station->NRQ[0] != 0) {  // It's a Beam Heading DFS object/item
+
+        if (strlen(speed_course) != 7)
+                xastir_snprintf(speed_course,
+                    sizeof(speed_course),
+                    "000/000");
+
+        bearing = atoi(p_station->bearing);
+        if ( (bearing < 1) || (bearing > 360) )
+                bearing = 360;
+
+        if ((p_station->flag & ST_OBJECT) != 0) {   // It's an object
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s/%03i/%s%s",
+                    p_station->call_sign,
+                    time,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    bearing,
+                    p_station->NRQ,
+                    altitude);
+            }
+            else {  // Non-compressed posit object
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%s/%03i/%s%s",
+                    p_station->call_sign,
+                    time,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    speed_course,
+                    bearing,
+                    p_station->NRQ,
+                    altitude);
+            }
+        }
+        else {  // It's an item
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ")%s!%s/%03i/%s%s",
+                    p_station->call_sign,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    bearing,
+                    p_station->NRQ,
+                    altitude);
+            }
+            else {  // Non-compressed item
+
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%c%s/%03i/%s%s",
+                    p_station->call_sign,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    speed_course,
+                    bearing,
+                    p_station->NRQ,
+                    altitude);
+            }
+        }
+    }
+
+    else {  // Else it's a normal object/item
+
+        if ((p_station->flag & ST_OBJECT) != 0) {   // It's an object
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%s",
+                    p_station->call_sign,
+                    time,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    altitude);
+            }
+            else {  // Non-compressed posit object
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%s%s",
+                    p_station->call_sign,
+                    time,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    speed_course,
+                    altitude);
+            }
+        }
+        else {  // It's an item
+
+            if (transmit_compressed_objects_items) {
+                char temp_group = object_group;
+                long x_long, y_lat;
+
+                // If we have a numeric overlay, we need to convert
+                // it to 'a-j' for compressed objects.
+                if (temp_group >= '0' && temp_group <= '9') {
+                    temp_group = temp_group + 'a';
+                }
+
+                if (speed == 0) {
+                    x_long = p_station->coord_lon;
+                    y_lat  = p_station->coord_lat;
+                }
+                else {
+                    // Speed is non-zero.  Compute the current
+                    // dead-reckoned position and use that instead.
+                    compute_current_DR_position(p_station,
+                        &x_long,
+                        &y_lat);
+                }
+
+                // We need higher precision lat/lon strings than
+                // those created above.
+                convert_lat_l2s(y_lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+                convert_lon_l2s(x_long, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+
+                xastir_snprintf(line, line_length, ")%s!%s%s",
+                    p_station->call_sign,
+                    compress_posit(lat_str,
+                        temp_group,
+                        lon_str,
+                        object_symbol,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank
+                    altitude);
+            }
+            else {  // Non-compressed item
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%c%s%s",
+                    p_station->call_sign,
+                    lat_str,
+                    object_group,
+                    lon_str,
+                    object_symbol,
+                    speed_course,
+                    altitude);
+            }
+        }
+    }
+
+    // If it's a "killed" object, change '*' to an '_'
+    if ((p_station->flag & ST_OBJECT) != 0) {               // It's an object
+        if ((p_station->flag & ST_ACTIVE) != ST_ACTIVE) {   // It's been killed
+            line[10] = '_';
+            killed++;
+        }
+    }
+    // If it's a "killed" item, change '!' to an '_'
+    else {                                                  // It's an item
+        if ((p_station->flag & ST_ACTIVE) != ST_ACTIVE) {   // It's been killed
+            killed++;
+            done = 0;
+            i = 0;
+            while ( (!done) && (i < 11) ) {
+                if (line[i] == '!') {
+                    line[i] = '_';          // mark as deleted object
+                    done++;                 // Exit from loop
+                }
+                i++;
+            }
+        }
+    }
+
+    // Check whether we need to stop transmitting particular killed
+    // object/items now.
+    if (killed) {
+        // Check whether we should decrement the object_retransmit
+        // counter so that we will eventually stop sending this
+        // object/item.
+        if (p_station->object_retransmit == 0) {
+            // We shouldn't be transmitting this killed object/item
+            // anymore.  We're already done transmitting it.
+
+//fprintf(stderr, "Done transmitting this object: %s,  %d\n",
+//p_station->call_sign,
+//p_station->object_retransmit);
+
+            return(0);
+        }
+
+        // Check whether the timeout has been set yet on this killed
+        // object/item.  If not, change it from -1 (continuous
+        // transmit of non-killed objects) to
+        // MAX_KILLED_OBJECT_RETRANSMIT.
+        if (p_station->object_retransmit <= -1) {
+
+//fprintf(stderr, "Killed object %s, setting retries, %d -> %d\n",
+//p_station->call_sign,
+//p_station->object_retransmit,
+//MAX_KILLED_OBJECT_RETRANSMIT - 1);
+
+                if ((MAX_KILLED_OBJECT_RETRANSMIT - 1) < 0) {
+                    p_station->object_retransmit = 0;
+                    return(0);  // No retransmits desired
+                }
+                else {
+                    p_station->object_retransmit = MAX_KILLED_OBJECT_RETRANSMIT - 1;
+                }
+        }
+        else {
+            // Decrement the timeout if it is a positive number.
+            if (p_station->object_retransmit > 0) {
+
+//fprintf(stderr, "Killed object %s, decrementing retries, %d ->
+//%d\n",
+//p_station->call_sign,
+//p_station->object_retransmit,
+//p_station->object_retransmit - 1);
+
+                p_station->object_retransmit--;
+            }
+        }
+    }
+
+    // We need to tack the comment on the end, but need to make
+    // sure we don't go over the maximum length for an object/item.
+    if (strlen(comment) != 0) {
+        temp = 0;
+        if ((p_station->flag & ST_OBJECT) != 0) {
+            while ( (strlen(line) < 80) && (temp < (int)strlen(comment)) ) {
+                //fprintf(stderr,"temp: %d->%d\t%c\n", temp,
+                //strlen(line), comment[temp]);
+                line[strlen(line) + 1] = '\0';
+                line[strlen(line)] = comment[temp++];
+            }
+        }
+        else {  // It's an item
+            while ( (strlen(line) < (64 + strlen(p_station->call_sign))) && (temp < (int)strlen(comment)) ) {
+                //fprintf(stderr,"temp: %d->%d\t%c\n", temp,
+                //strlen(line), comment[temp]);
+                line[strlen(line) + 1] = '\0';
+                line[strlen(line)] = comment[temp++];
+            }
+        }
+    }
+
+    //fprintf(stderr,"line: %s\n",line);
+
+// NOTE:  Compressed mode will be shorter still.  Account
+// for that when compressed mode is implemented for objects/items.
+
+    return(1);
+}
+
+
+
+
+
+// check_and_transmit_objects_items
+//
+// This function checks the last_transmit_time for each
+// locally-owned object/item.  If it has been at least the
+// transmit_time_increment since the last transmit, the increment is
+// doubled and the object/item transmitted.
+//
+// Killed objects/items are transmitted for
+// MAX_KILLED_OBJECT_RETRANSMIT times and then transmitting of those
+// objects ceases.
+//
+// This would be a good place to implement auto-expiration of
+// objects that's been discussed on the mailing lists.
+//
+// This function depends on the local loopback that is in
+// interface.c.  If we don't hear & decode our own packets, we won't
+// have our own objects/items in our list.
+//
+// We need to check DataRow objects for ST_OBJECT or ST_ITEM types
+// that were transmitted by our callsign & SSID.  We might also need
+// to modify the remove_time() and check_station_remove functions in
+// order not to delete our own objects/items too quickly.
+//
+// insert_time/remove_time/next_station_time/prev_station_time
+//
+// It would be nice if the create/modify object dialog and this
+// routine went
+// through the same functions to create the transmitted packets:
+//      objects.c:Setup_object_data
+//      objects.c:Setup_item_data
+// Unfortunately those routines snag their data directly from the
+// dialog.
+// In order to make them use the same code we'd have to separate out
+// the
+// fetch-from-dialog code from the create-transmit-packet code.
+//
+// This is what aprsDOS does, from Bob's APRS.TXT file:  "a
+// fundamental precept is that old data is less important than new
+// data."  "Each new packet is transmitted immediately, then 20
+// seconds later.  After every transmission, the period is doubled.
+// After 20 minutes only six packets have been transmitted.  From
+// then on the rate remains at 10 minutes times the number of
+// digipeater hops you are using."
+// Actually, talking to Bob, he's used a period of 15 seconds as his
+// base unit.  We now do the same using the OBJECT_CHECK_RATE define
+// to set the initial timing.
+
+//
+// Added these to database.h:DataRow struct:
+// time_t last_transmit_time;          // Time we last transmitted
+// an object/item.  Used to
+//                                     // implement decaying
+//                                     transmit time algorithm
+// short transmit_time_increment;      // Seconds to add to transmit
+// next time around.  Used
+//                                     // to implement decaying
+//                                     transmit time algorithm
+//
+// The earlier code here transmitted objects/items at a specified
+// rate.  This can cause large transmissions every OBJECT_rate
+// seconds, as all objects/items are transmitted at once.  With the
+// new code, the objects/items may be spaced a bit from each other
+// time-wise, plus they are transmitted less and less often with
+// each transmission until they hit the max interval specified by
+// the "Object/Item TX Interval" slider.  When they hit that max
+// interval, they are transmitted at the constant interval until
+// killed.  When they are killed, they are transmitted for
+// MAX_KILLED_OBJECT_RETRANSMIT iterations using the decaying
+// algorithm, then transmissions cease.
+//
+void check_and_transmit_objects_items(time_t time) {
+    DataRow *p_station;     // pointer to station data
+    char line[256];
+    int first = 1;  // Used to output debug message only once
+    int increment;
+
+
+    // Time to re-transmit objects/items?
+    // Check every OBJECT_CHECK_RATE seconds - 20%.  No faster else
+    // we'll be running through the station list too often and
+    // wasting cycles.
+    if (time < (last_object_check + (int)(4.0 * OBJECT_CHECK_RATE/5.0 + 1.0) ) )
+      return;
+
+//fprintf(stderr,"check_and_transmit_objects_items\n");
+
+    // Set up timer for next go-around
+    last_object_check = time;
+
+    if (debug_level & 1)
+      fprintf(stderr,"Checking whether to retransmit any objects/items\n");
+
+// We could speed things up quite a bit here by either keeping a
+// separate list of our own objects/items, or going through the list
+// of stations by time instead of by name (If by time, only check
+// backwards from the current time by the max transmit interval plus
+// some increment.  Watch out for the user changing the slider).
+
+    for (p_station = n_first; p_station != NULL; p_station = p_station->n_next) {
+
+        //fprintf(stderr,"%s\t%s\n",p_station->call_sign,p_station->origin);
+
+        // If station is owned by me (Exact match includes SSID)
+//        if (is_my_call(p_station->origin,1)) {
+        // and it's an object or item
+        if ((p_station->flag & (ST_OBJECT|ST_ITEM)) && is_my_object_item(p_station)) {
+
+            long x_long_save, y_lat_save;
+
+            // If dead-reckoning, we need to send out a new
+            // position for this object instead of just
+            // overwriting the old position, which will cause
+            // the track to skip.  Here we save the old position
+            // away so we can save it back to the record later.
+            //
+            x_long_save = p_station->coord_lon;
+            y_lat_save = p_station->coord_lat;
+
+            if (debug_level & 1) {
+                fprintf(stderr,
+                        "Found a locally-owned object or item: %s\n",
+                        p_station->call_sign);
+            }
+
+            // Call the DR function to compute a new lat/long
+            // and change the object's lat/long to match so that
+            // we move the object along each time we transmit
+            // it.
+            //
+// WE7U
+// Here we should log the new position to file if it's not done
+// automatically.
+            //
+            if (p_station->speed[0] != '\0') {
+                long x_long, y_lat;
+
+                compute_current_DR_position(p_station, &x_long, &y_lat);
+
+                // Put the new position into the record
+                // temporarily so that we can 
+                p_station->coord_lon = x_long;
+                p_station->coord_lat = y_lat;
+            }
+
+            // Keep the timestamp current on my own
+            // objects/items so they don't expire.
+            p_station->sec_heard = sec_now();
+            move_station_time(p_station,NULL);
+
+// Implementing sped-up transmission of new objects, regular
+// transmission of old objects (decaying algorithm).  We'll do this
+// by keeping a last_transmit_time variable and a
+// transmit_time_increment with each DataRow struct.  If the
+// last_transmit_time is older than the transmit_time_increment, we
+// transmit the object and double the increment variable, until we
+// hit the OBJECT_rate limit for the increment.  This will make
+// newer objects/items transmit more often, and will also space out
+// the transmissions of old objects so they're not transmitted all
+// at once in a group.  Each time a new object/item is created that
+// is owned by us, it needs to have it's timer set to 20 (seconds).
+// If an object/item is touched, it needs to again be set to 20
+// seconds.
+///////////////////////////////////
+
+// Run through the station list.
+
+// Transmit any objects/items that have equalled or gone past
+// (last_transmit_time + transmit_time_increment).  Update the
+// last_transmit_time to current time.
+//
+// Double the transmit_time_increment.  If it has gone beyond
+// OBJECT_rate, set it to OBJECT_rate instead.
+//
+///////////////////////////////////
+
+
+            // Check for the case where the timing slider has
+            // been reduced and the expire time is too long.
+            // Reset it to the current max expire time so that
+            // it'll get transmitted more quickly.
+            if (p_station->transmit_time_increment > OBJECT_rate)
+              p_station->transmit_time_increment = OBJECT_rate;
+
+
+            increment = p_station->transmit_time_increment;
+
+            if ( ( p_station->last_transmit_time + increment) <= time ) {
+                // We should transmit this object/item as it has
+                // hit its transmit interval.
+
+                float randomize;
+                int one_fifth_increment;
+                int new_increment;
+
+
+                if (first && !object_tx_disable) {    // "Transmitting objects/items"
+                    statusline(langcode("BBARSTA042"),1);
+                    first = 0;
+                }
+
+                // Set up the new doubling increment
+                increment = increment * 2;
+                if (increment > OBJECT_rate) {
+                    increment = OBJECT_rate;
+                }
+
+                // Randomize the distribution a bit, so that all
+                // objects are not transmitted at the same time.
+                // Allow the random number to vary over 20%
+                // (one-fifth) of the newly computed increment.
+                one_fifth_increment = (int)((increment / 5) + 0.5);
+//fprintf(stderr,"one_fifth_increment: %d\n", one_fifth_increment);
+
+                // Scale the random number from 0.0 to 1.0.
+                // Must convert at least one of the numbers to a
+                // float else randomize will be zero every time.
+                randomize = rand() / (float)RAND_MAX;
+//fprintf(stderr,"randomize: %f\n", randomize);
+
+                // Scale it to the range we want (0% to 20% of
+                // the interval)
+                randomize = randomize * one_fifth_increment;
+//fprintf(stderr,"scaled randomize: %f\n", randomize);
+
+                // Subtract it from the increment, use
+                // poor-man's rounding to turn the random number
+                // into an int (so we get the full range).
+                new_increment = increment - (int)(randomize + 0.5);
+                p_station->transmit_time_increment = (short)new_increment;
+
+//fprintf(stderr,"check_and_transmit_objects_items():Setting
+//tx_increment to %d:%s\n",
+//    new_increment,
+//    p_station->call_sign);
+
+                // Set the last transmit time into the object.
+                // Keep this based off the time the object was
+                // last created/modified/deleted, so that we
+                // don't end up with a bunch of them transmitted
+                // together.
+                p_station->last_transmit_time = p_station->last_transmit_time + new_increment;
+
+                // Here we need to re-assemble and re-transmit
+                // the object or item
+                // Check whether it is a "live" or "killed"
+                // object and vary the
+                // number of retransmits accordingly.  Actually
+                // we should be able
+                // to keep retransmitting "killed" objects until
+                // they expire out of
+                // our station queue with no problems.  If
+                // someone wants to ressurect
+                // the object we'll get new info into our struct
+                // and this function will
+                // ignore that object from then on, unless we
+                // again snatch control of
+                // the object.
+
+                // if signpost, area object, df object, or
+                // generic object
+                // check p_station->APRS_Symbol->aprs_type:
+                //   APRS_OBJECT
+                //   APRS_ITEM
+                //   APRS_DF (looks like I didn't use this one
+                //   when I implemented DF objects)
+
+                //   Whether area, df, signpost.
+                // Check ->signpost for signpost data.  Check
+                // ->df_color also.
+
+                // call_sign, sec_heard, coord_lon, coord_lat,
+                // packet_time, origin,
+                // aprs_symbol, pos_time, altitude, speed,
+                // course, bearing, NRQ,
+                // power_gain, signal_gain, signpost,
+                // station_time, station_time_type,
+                // comments, df_color
+                if (Create_object_item_tx_string(p_station, line, sizeof(line)) ) {
+
+                    // Restore the original lat/long before we
+                    // transmit the (possibly) new position.
+                    //
+                    p_station->coord_lon = x_long_save;
+                    p_station->coord_lat = y_lat_save;
+
+//fprintf(stderr,"Transmitting: %s\n",line);
+                    // Attempt to transmit the object/item again
+                    if (object_tx_disable || transmit_disable) {    // Send to loopback only
+                        output_my_data(line,-1,0,1,0,NULL); // Local loopback only, not igating
+                    }
+                    else { // Send to all active tx-enabled interfaces
+                        output_my_data(line,-1,0,0,0,NULL); // Transmit/loopback object data, not igating
+                    }
+                }
+                else {
+//fprintf(stderr,"Create_object_item_tx_string returned a 0\n");
+                    // Don't transmit it.
+                }
+            }
+            else {  // Not time to transmit it yet
+//fprintf(stderr,"Not time to TX yet:
+//%s\t%s\t",p_station->call_sign,p_station->origin);
+//fprintf(stderr, "%ld secs to go\n", p_station->last_transmit_time
+//+ increment - time );
+            }
+        }
+    }
+//fprintf(stderr,"Exiting check_and_transmit_objects_items\n");
+}
+
+
+
+//////////////////// Draw CAD Objects Functions ////////////////////
+
+
+
+//#define CAD_DEBUG
+
+// Allocate a new vertice along the polygon.  If the vertice is very
+// close to the first vertice, ask the operator if they wish to
+// close the polygon.  If closing, ask for a raw probability?
+//
+// As each vertice is allocated, write it out to file?  We'd then
+// need to edit the file and comment vertices out if we're deleting
+// vertices in memory.  We could also write out an entire object
+// when we select "Close Polygon".
+//
+void CAD_vertice_allocate(long latitude, long longitude) {
+
+#ifdef CAD_DEBUG
+    fprintf(stderr,"Allocating a new vertice\n");
+#endif
+
+    // Check whether a line segment will cross another?
+
+    // We use the CAD_list_head variable, as it will be pointing to
+    // the top of the list, where the current object we're working
+    // on will be placed.  Check whether that pointer is NULL
+    // though, just in case.
+    if (CAD_list_head) {   // We have at least one object defined
+        VerticeRow *p_new;
+
+        // Allocate area to hold the vertice
+        p_new = (VerticeRow *)malloc(sizeof(VerticeRow));
+
+        if (!p_new) {
+            fprintf(stderr,"Couldn't allocate memory in CAD_vertice_allocate()\n");
+            return;
+        }
+ 
+        p_new->latitude = latitude;
+        p_new->longitude = longitude;
+ 
+        // Link it in at the top of the vertice chain.
+        p_new->next = CAD_list_head->start;
+        CAD_list_head->start = p_new;
+    }
+    
+    // Call redraw_symbols outside this function, as 
+    // verticies may be allocated both when loading lots of them from a file
+    // and when the user is drawing objects in the user interface
+    // Reload symbols/tracks/CAD objects
+    //redraw_symbols(da);
+}
+
+
+
+
+
+// Allocate a struct for a new object and add one vertice to it.
+// When do we name it and place the label?  Assign probability to
+// it?  We should keep a pointer to the current polygon we're
+// working on, so that we can modify it easily as we draw.
+// Actually, it'll be pointed to by CAD_list_head, so we already
+// have it!
+//
+// As each object is allocated, write it out to file?
+//
+// Compute a default label of date/time?
+//
+void CAD_object_allocate(long latitude, long longitude) {
+    CADRow *p_new;
+
+#ifdef CAD_DEBUG
+    fprintf(stderr,"Allocating a new CAD object\n");
+#endif
+
+    // Allocate memory and link it to the top of the singly-linked
+    // list of CADRow objects.
+    p_new = (CADRow *)malloc(sizeof(CADRow));
+
+    if (!p_new) {
+        fprintf(stderr,"Couldn't allocate memory in CAD_object_allocate()\n");
+        return;
+    }
+
+    // Fill in default values
+    p_new->creation_time = sec_now();
+    p_new->start = NULL;
+    p_new->line_color = colors[0x27];
+    p_new->line_type = 2;  // LineOnOffDash;
+    p_new->line_width = 4;
+    p_new->computed_area = 0;
+    CAD_object_set_raw_probability(p_new,0.0,FALSE);
+    p_new->label_latitude = 0l;
+    p_new->label_longitude = 0l;
+    p_new->label[0] = '\0';
+    p_new->comment[0] = '\0';
+
+    // Allocate area to hold the first vertice
+
+#ifdef CAD_DEBUG
+    fprintf(stderr,"Allocating a new vertice\n");
+#endif
+
+    p_new->start = (VerticeRow *)malloc(sizeof(VerticeRow));
+    if (!p_new->start) {
+        fprintf(stderr,"Couldn't allocate memory in CAD_object_allocate(2)\n");
+        free(p_new);
+        return;
+    }
+
+    p_new->start->next = NULL;
+    p_new->start->latitude = latitude;
+    p_new->start->longitude = longitude;
+ 
+    // Hook it into the linked list of objects
+    p_new->next = CAD_list_head;
+    CAD_list_head = p_new;
+
+/*
+//
+// Note:  It was too confusing to have these two dialogs close and
+// get redrawn when we click on the first vertice.  The net result
+// is that we may have two dialogs move on top of the drawing area
+// to the spot we're trying to draw.  Commented out this section due
+// to that.  We'll get the two dialogs updated when we click on
+// either the DONE or CANCEL button on the Close Polygon dialog.
+//
+    // Here we update the erase cad objects dialog if it is up on
+    // the screen.  We get rid of it and re-establish it, which will
+    // usually make the dialog move, but this is better than having
+    // it be out-of-date.
+    //
+    if (cad_erase_dialog != NULL) {
+        Draw_CAD_Objects_erase_dialog_close(da, NULL, NULL);
+        Draw_CAD_Objects_erase_dialog(da, NULL, NULL);
+    }
+
+    // Here we update the edit cad objects dialog by getting rid of
+    // it and then re-establishing it if it is active when we start.
+    // This will usually make the dialog move, but it's better than
+    // having it be out-of-date.
+    //
+    if (cad_list_dialog!=NULL) {
+        // Update the Edit CAD Objects list
+        Draw_CAD_Objects_list_dialog_close(da, NULL, NULL);
+        Draw_CAD_Objects_list_dialog(da, NULL, NULL);
+    }
+*/
+}
+
+
+
+
+
+// Delete all vertices associated with a CAD object and free the
+// memory.  We really should pass a pointer to the object here
+// instead of a vertice, and set the start pointer to NULL when
+// done.
+//
+void CAD_vertice_delete_all(VerticeRow *v) {
+    VerticeRow *tmp;
+
+    // Call CAD_vertice_delete() for each vertice, then unlink this
+    // CAD object from the linked list and free its memory.
+
+    // Iterate through each vertice, deleting as we go
+    while (v != NULL) {
+        tmp = v;
+        v = v->next;
+        free(tmp);
+
+#ifdef CAD_DEBUG
+        fprintf(stderr,"Free'ing a vertice\n");
+#endif
+
+    }
+}
+
+
+
+
+
+// Delete _all_ CAD objects and all associated vertices.  Loop
+// through the entire list of CAD objects, calling
+// CAD_vertice_delete_all() and then free'ing the CAD object.  When
+// done, set the start pointer to NULL.
+//
+// We also need to wipe the persistent CAD object file.
+//
+void CAD_object_delete_all(void) {
+    CADRow *p = CAD_list_head;
+    CADRow *tmp;
+ 
+    while (p != NULL) {
+        VerticeRow *v = p->start;
+
+        // Remove all of the vertices
+        if (v != NULL) {
+
+            // Delete/free the vertices
+            CAD_vertice_delete_all(v);
+        }
+
+        // Remove the object and free its memory
+        tmp = p;
+        p = p->next;
+        free(tmp);
+
+#ifdef CAD_DEBUG
+        fprintf(stderr,"Free'ing an object\n");
+#endif
+
+    }
+
+    // Zero the CAD linked list head
+    CAD_list_head = NULL;
+}
+
+
+
+
+
+// Remove a vertice, thereby joining two segments into one?
+//
+// Recompute the raw probability if need be, or make it an invalid
+// value so that we know we need to recompute it.
+//
+//void CAD_vertice_delete(CADrow *object) {
+//    VerticeRow *v = object->start;
+
+    // Unlink the vertice from the linked list and free its memory.
+    // Allow removing a vertice in the middle or end of a chain.  If
+    // removing the vertice turns the polygon into an open polygon,
+    // alert the user of that fact and ask if they wish to close it.
+//}
+
+
+
+
+
+/* Test to see if a CAD object of the name (label) provided exists.
+   Parameter: label, the label text to be checked.
+   Returns 0 if no CAD object with a name matching the 
+   provided name is found.
+   Returns 1 if a CAD object with a name matching the 
+   provided name is found.  */
+int exists_CAD_object_by_label(char *label) {
+    CADRow *object_pointer = CAD_list_head;
+    int result = 0;  // function return value
+    int done = 0;    // flag to stop loop when a match is found
+    while (object_pointer != NULL && done==0) {
+        if (strcmp(object_pointer->label,label)==0) {
+            // a matching name was found
+            result = 1;
+            done = 1;
+        }
+        object_pointer = object_pointer->next;
+    } 
+    return result;
+}
+
+
+
+
+
+/* Counts to see how many CAD objects of the name (label) provided exist.
+   Parameter: label, the label text to be checked.
+   Returns 0 if no CAD object with a name matching the 
+   provided name is found.
+   Returns count of the number of CAD objects with a matching label if
+   one or more is found.  */
+int count_CAD_object_with_matching_label(char *label) {
+    CADRow *object_pointer = CAD_list_head;
+    int result = 0;
+    while (object_pointer != NULL) {
+        // iterate through all CAD objects
+        if (strcmp(object_pointer->label,label)==0) {
+            // a matching name was found
+            result++;
+            object_pointer = object_pointer->next;
+        }
+    } 
+    return result;
+}
+
+
+
+
+
+/* Delete one CAD object and all of its vertices. */
+void CAD_object_delete(CADRow *object) {
+    CADRow *all_objects_ptr = CAD_list_head;
+    CADRow *previous_object_ptr = CAD_list_head;
+    VerticeRow *v = object->start;
+    int done = 0;
+
+#ifdef CAD_DEBUG
+    fprintf(stderr,"Deleting CAD object %s\n",object->label);
+#endif
+    // check to see if the object we were given was the first object
+    if (object==all_objects_ptr) {
+#ifdef CAD_DEBUG
+        fprintf(stderr,"Deleting first CAD object %s\n",object->label);
+#endif
+        CAD_vertice_delete_all(v); // Frees the memory also
+
+        // Unlink the object from the chain and free the memory.
+        CAD_list_head = object->next;  // Unlink
+        free(object);   // Free the object memory
+    } 
+    else {
+#ifdef CAD_DEBUG
+        fprintf(stderr,"Deleting other than first CAD object %s\n",object->label);
+#endif
+        // walk through the list and delete the object when found
+        while (all_objects_ptr != NULL && done==0) {
+            if (object==all_objects_ptr) {
+                v = object->start;
+                CAD_vertice_delete_all(v);
+                previous_object_ptr->next = object->next;
+                free(object);
+                done = 1;
+            }
+            else {
+                all_objects_ptr = all_objects_ptr->next;
+            }
+        }
+    }
+}
+
+
+
+
+
+// Split an existing CAD object into two objects.  Can we trigger
+// this by drawing a line across a closed polygon?
+void CAD_object_split_existing(void) {
+}
+
+// Join two existing polygons into one larger polygon.
+void CAD_object_join_two(void) {
+}
+
+// Move an entire CAD object, with all it's vertices, somewhere
+// else.  Move the label along with it as well.
+void CAD_object_move(void) {
+}
+
+
+
+
+
+// Determine if a CAD object is a closed polygon.
+//
+// Takes a pointer to a CAD object as an argument.
+// Returns 1 if the object is closed.
+// Returns 0 if the object is not closed.
+//
+int is_CAD_object_open(CADRow *cad_object) {
+   VerticeRow *vertex_pointer;
+   int vertex_count = 0;
+   int result = 1;
+   int atleast_one_different = 0;
+   long start_lat, start_long;
+   long stop_lat, stop_long;
+
+   vertex_pointer = cad_object->start;
+   if (vertex_pointer!=NULL) {
+        // greater than zero points, get first point.
+        start_lat = vertex_pointer->latitude;
+        start_long = vertex_pointer->longitude;
+        stop_lat = vertex_pointer->latitude;
+        stop_long = vertex_pointer->longitude;
+        vertex_pointer = vertex_pointer->next;
+        while (vertex_pointer != NULL) {
+            //greater than one point, get current point.
+            stop_lat = vertex_pointer->latitude;
+            stop_long = vertex_pointer->longitude;
+            if (stop_lat!=start_lat || stop_long!=start_long) 
+                atleast_one_different = 1;
+            vertex_pointer = vertex_pointer->next;
+            vertex_count++;
+        }
+        if (vertex_count>2 && start_lat==stop_lat && start_long==stop_long && atleast_one_different > 0) {
+            // more than two points, and they aren't in the same place  
+            result = 0;
+        }
+   }
+   return result;
+}
+
+
+
+
+
+// Compute the area enclosed by a CAD object.  Check that it is a
+// closed, non-intersecting polygon first.
+//
+double CAD_object_compute_area(CADRow *CAD_list_head) {
+    VerticeRow *tmp;
+    double area;
+    char temp_course[20];
+    // Walk the linked list again, computing the area of the
+    // polygon.  Greene's Theorem is how we can compute the area of
+    // a polygon using the vertices.  We could also compute whether
+    // we're going clockwise or counter-clockwise around the polygon
+    // using Greene's Theorem.  In fact I think we do that for
+    // Shapefile hole polygons.  Remember that here we're walking
+    // around the vertices backwards due to the ordering of the
+    // list.  Shouldn't matter for our purposes though.
+    //
+    area = 0.0;
+    tmp = CAD_list_head->start;
+    if (is_CAD_object_open(CAD_list_head)==0) { 
+        // Only compute the area if CAD object is a closed polygon,
+        // that is, not an open polygon.
+        while (tmp->next != NULL) {
+            double dx0, dy0, dx1, dy1;
+                                                                                                                            
+            // Because lat/long units can vary drastically w.r.t. real
+            // units, we need to multiply the terms by the real units in
+            // order to get real area.
+                                                                                                                            
+            // Compute real distances from a fixed point.  Convert to
+            // the current measurement units.  We'll use the starting
+            // vertice as our fixed point.
+            //
+            dx0 = calc_distance_course(
+                    CAD_list_head->start->latitude,
+                    CAD_list_head->start->longitude,
+                    CAD_list_head->start->latitude,
+                    tmp->longitude,
+                    temp_course,
+                    sizeof(temp_course));
+                                                                                                                            
+            if (tmp->longitude < CAD_list_head->start->longitude)
+                dx0 = -dx0;
+                                                                                                                            
+            dy0 = calc_distance_course(
+                    CAD_list_head->start->latitude,
+                    CAD_list_head->start->longitude,
+                    tmp->latitude,
+                    CAD_list_head->start->longitude,
+                    temp_course,
+                    sizeof(temp_course));
+                                                                                                                            
+            if (tmp->latitude < CAD_list_head->start->latitude)
+                dx0 = -dx0;
+                                                                                                                            
+            dx1 = calc_distance_course(
+                    CAD_list_head->start->latitude,
+                    CAD_list_head->start->longitude,
+                    CAD_list_head->start->latitude,
+                    tmp->next->longitude,
+                    temp_course,
+                    sizeof(temp_course));
+                                                                                                                            
+            if (tmp->next->longitude < CAD_list_head->start->longitude)
+                dx0 = -dx0;
+                                                                                                                            
+            dy1 = calc_distance_course(
+                    CAD_list_head->start->latitude,
+                    CAD_list_head->start->longitude,
+                    tmp->next->latitude,
+                    CAD_list_head->start->longitude,
+                    temp_course,
+                    sizeof(temp_course));
+                                                                                                                            
+            // Add the minus signs back in, if any
+            if (tmp->longitude < CAD_list_head->start->longitude)
+                dx0 = -dx0;
+            if (tmp->latitude < CAD_list_head->start->latitude)
+                dy0 = -dy0;
+            if (tmp->next->longitude < CAD_list_head->start->longitude)
+                dx1 = -dx1;
+            if (tmp->next->latitude < CAD_list_head->start->latitude)
+                dy1 = -dy1;
+                                                                                                                            
+            // Greene's Theorem:  Summation of the following, then
+            // divide by two:
+            //
+            // A = X Y    - X   Y
+            //  i   i i+1    i+1 i
+            //
+            area += (dx0 * dy1) - (dx1 * dy0);
+                                                                                                                            
+            tmp = tmp->next;
+        }
+        area = 0.5 * area;
+    } 
+                                                                                                                      
+    if (area < 0.0)
+        area = -area;
+                                                                                                                        
+    return area;
+                                                                                                                        
+
+}
+
+
+
+
+
+// Allocate a label for an object, and place it according to the
+// user's requests.  Keep track of where from the origin to place
+// the label, font to use, color, etc.
+void CAD_object_allocate_label(void) {
+}
+
+
+
+
+
+// Set the probability for an object.  We should probably allocate
+// the raw probability to small "buckets" within the closed polygon.
+// This will allow us to split/join polygons later without messing
+// up the probablity assigned to each area originally.  Check that
+// it is a closed polygon first.
+// if as_percent==TRUE, then probability is treated as a percent
+// (expected to be a value between 0 and 100).
+// otherwise, then probability is treated as a probability 
+// (expected to be a value between 0 and 1).
+//
+void CAD_object_set_raw_probability(CADRow *object_ptr, float probability, int as_percent) {
+   // initial implementation just assigns a single raw probability to the whole polygon.
+   // internal storage is as a probability between 0 and 1
+   // users will usually want to manipulate this as a percent (between 0 and 100)
+   // thus the get and set functions are aware of both internal storage and
+   // the user's request and return an appropriately scaled value.  
+   if (as_percent==TRUE) {
+       // convert from a percent to a probability between 0 and 1
+       object_ptr->raw_probability = (probability/100.00);
+   } 
+   else {
+       // treat as in internal storage form
+       object_ptr->raw_probability = probability;
+   }
+}
+
+
+
+
+
+// Get the raw probability for an object.  Sum up the raw
+// probability "buckets" contained within the closed polygon.  Check
+// that it _is_ a closed polygon first.
+//
+float CAD_object_get_raw_probability(CADRow *object_ptr, int as_percent) {
+   float result = 0.0;
+   // not checking yet for closure
+   if (object_ptr != NULL) {
+      // initial implementation returns just the single raw probability
+      result = object_ptr->raw_probability;
+      if (as_percent > 0) {
+          // raw probability is a probability between 0 an 1, 
+          // this may be desired as a percent.
+          result = result * 100;
+      }
+   }
+#ifdef CAD_DEBUG
+   fprintf(stderr,"Getting Probability: %01.5f\n",result);
+#endif
+   return result;
+}
+
+
+
+
+
+void CAD_object_set_line_width(void) {
+}
+
+
+
+
+
+void CAD_object_set_color(void) {
+}
+
+
+
+
+
+void CAD_object_set_linetype(void) {
+}
+
+
+
+
+
+// Used to break a line segment into two.  Can then move the vertice
+// if needed.  Recompute the raw probability if need be, or make it
+// an invalid value so that we know we need to recompute it.
+void CAD_vertice_insert_new(void) {
+    // Check whether a line segment will cross another?
+}
+
+
+
+
+
+// Move an existing vertice.  Recompute the raw probability if need
+// be, or make it an invalid value so that we know we need to
+// recompute it.
+void CAD_vertice_move(void) {
+    // Check whether a line segment will cross another?
+}
+
+
+
+
+
+// Set the location for drawing the label of an area to the center
+// of the area.  Takes a pointer to a CAD object as a parameter.
+// Sets the label_latitude and label_longitude attributes of the CAD
+// object to the center of the region described by the vertices of
+// the object.
+//
+void CAD_object_set_label_at_centroid(CADRow *CAD_object) {
+    // *** current implementation approximates the center as the 
+    // average of the largest and smallest of each of latitude
+    // and longitude rather than correctly computing the centroid,
+    // that is, it places the label at the centroid of a bounding
+    // box for the area.  ***
+    // We can't use a simple x=sum(x)/n, y=sum(y)/n as the 
+    // points on the outline shouldn't be weighted equally.
+    // Ideal would be to place the label at the central point within
+    // the area itslef, apparently this is a hard prbolem.
+    // alternative would be to use the centroid, which like the 
+    // average of maximum and minimum values may lie outside of
+    // the area. 
+    VerticeRow *vertex_pointer;
+    long min_lat, min_long;
+    long max_lat, max_long;
+    // Walk the linked list and compute the centroid of the bounding box.
+    vertex_pointer = CAD_object->start;
+    min_lat = 0.0;
+    min_long = 0.0;
+                                                                                                                        
+    // Set the latitude and longitude of the label to the
+    // centroid of the bounding box.
+    // Start by setting lat and long of label to first point.
+    CAD_object->label_latitude = vertex_pointer->latitude;
+    CAD_object->label_longitude = vertex_pointer->longitude;
+    if (vertex_pointer != NULL) {
+        // Iterate through the vertices and calculate the center x and y position
+        // based on an average of the largest and smallest latitudes and longitudes.
+        min_lat = vertex_pointer->latitude;
+        min_long = vertex_pointer->longitude;
+        max_lat = vertex_pointer->latitude;
+        max_long = vertex_pointer->longitude;
+        while (vertex_pointer != NULL) {
+            if (vertex_pointer->next != NULL) {
+                if (vertex_pointer->longitude < min_long )
+                    min_long = vertex_pointer->longitude;
+                if (vertex_pointer->latitude < min_lat )
+                    min_lat = vertex_pointer->latitude;
+                if (vertex_pointer->longitude > max_long )
+                    max_long = vertex_pointer->longitude;
+                if (vertex_pointer->latitude > max_lat )
+                    max_lat = vertex_pointer->latitude;
+            }
+            vertex_pointer = vertex_pointer->next;
+        }
+        CAD_object->label_latitude = (max_lat + min_lat)/2.0;
+        CAD_object->label_longitude = (max_long + min_long)/2.0;
+    }
+}
+
+
+
+
+
+// This is the callback for the CAD objects parameters dialog.  It
+// takes the values entered in the dialog and stores them in the
+// most recently created object.
+//
+void Set_CAD_object_parameters (Widget widget,
+                     XtPointer clientData,
+                     XtPointer calldata) {
+
+    float probability = 0.0;
+    CADRow *target_object = NULL;
+    int cb_selected;
+    // need to find out object to edit from clientData rather than
+    // using the first object in list as the one to edit.
+    //target_object = CAD_list_head;
+    target_object = (CADRow *)clientData;
+
+    // set label, comment, and probability for area
+    xastir_snprintf(target_object->label,
+                sizeof(target_object->label),
+                "%s", XmTextGetString(cad_label_data)
+                );
+    xastir_snprintf(target_object->comment,
+                sizeof(target_object->comment),
+                "%s", XmTextGetString(cad_comment_data)
+                );
+    // Is more error checking needed?  atof appears to correctly handle
+    // empty input, reasonable probability values, and text (0.00).  
+    // User side probabilities are expressed as percent.
+    probability = atof(XmTextGetString(cad_probability_data));
+    CAD_object_set_raw_probability(target_object, probability, TRUE);
+
+    // Use the selected line type, default is dashed
+    cb_selected = FALSE;
+
+#ifdef USE_COMBO_BOX
+    XtVaGetValues(cad_line_style_data, 
+        XmNselectedPosition,
+        &cb_selected,
+        NULL);
+#else
+    cb_selected = clsd_value;
+#endif // USE_COMBO_BOX        
+
+    if (cb_selected) {
+        target_object->line_type = cb_selected;
+    } 
+    else {
+        target_object->line_type = 2; // LineOnOffDash
+    }
+
+    if (cad_list_dialog) {
+        Update_CAD_objects_list_dialog();
+    }
+                                                                                                                        
+    // close object_parameters dialog
+    XtPopdown(cad_dialog);
+    XtDestroyWidget(cad_dialog);
+    cad_dialog = (Widget)NULL;
+
+    Save_CAD_Objects_to_file();
+    // Reload symbols/tracks/CAD objects so that object name will show on map.
+    redraw_symbols(da);
+
+    // Here we update the erase cad objects dialog if it is up on
+    // the screen.  We get rid of it and re-establish it, which will
+    // usually make the dialog move, but this is better than having
+    // it be out-of-date.
+    //
+    if (cad_erase_dialog != NULL) {
+        Draw_CAD_Objects_erase_dialog_close(widget,clientData,calldata);
+        Draw_CAD_Objects_erase_dialog(widget,clientData,calldata);
+    }
+
+    // Here we update the edit cad objects dialog by getting rid of
+    // it and then re-establishing it if it is active when we start.
+    // This will usually make the dialog move, but it's better than
+    // having it be out-of-date.
+    //
+    if (cad_list_dialog!=NULL) {
+        // Update the Edit CAD Objects list
+        Draw_CAD_Objects_list_dialog_close(widget, clientData, calldata);
+        Draw_CAD_Objects_list_dialog(widget, clientData, calldata);
+    }
+}
+
+
+
+
+
+// Update the list of existing CAD objects on the cad list dialog to
+// reflect the current list of objects.
+//
+void Update_CAD_objects_list_dialog() {
+    CADRow *object_ptr = CAD_list_head;
+    int counter = 1;
+    XmString cb_item;
+
+    if (list_of_existing_CAD_objects_edit!=NULL && cad_list_dialog) {
+         XmListDeleteAllItems(list_of_existing_CAD_objects_edit);
+
+         // iterate through list of objects to populate scrolled list
+         while (object_ptr != NULL) {
+
+            //  If no label, use the string "<Empty Label>" instead
+            if (object_ptr->label == NULL || object_ptr->label[0] == '\0')
+                cb_item = XmStringCreateLtoR("<Empty Label>", XmFONTLIST_DEFAULT_TAG);
+            else
+                cb_item = XmStringCreateLtoR(object_ptr->label, XmFONTLIST_DEFAULT_TAG);
+
+             XmListAddItem(list_of_existing_CAD_objects_edit,
+                           cb_item,
+                           counter);  
+             counter++;
+             XmStringFree(cb_item);
+             object_ptr = object_ptr->next;
+         }
+    }
+}
+
+
+
+
+
+void close_object_params_dialog(Widget widget, XtPointer clientData, XtPointer calldata) {
+    XtPopdown(cad_dialog);
+    XtDestroyWidget(cad_dialog);
+    cad_dialog = (Widget)NULL;
+
+    // Here we update the erase cad objects dialog if it is up on
+    // the screen.  We get rid of it and re-establish it, which will
+    // usually make the dialog move, but this is better than having
+    // it be out-of-date.
+    //
+    if (cad_erase_dialog != NULL) {
+        Draw_CAD_Objects_erase_dialog_close(widget,clientData,calldata);
+        Draw_CAD_Objects_erase_dialog(widget,clientData,calldata);
+    }
+
+    // Here we update the edit cad objects dialog by getting rid of
+    // it and then re-establishing it if it is active when we start.
+    // This will usually make the dialog move, but it's better than
+    // having it be out-of-date.
+    //
+    if (cad_list_dialog!=NULL) {
+        // Update the Edit CAD Objects list
+        Draw_CAD_Objects_list_dialog_close(widget, clientData, calldata);
+        Draw_CAD_Objects_list_dialog(widget, clientData, calldata);
+    }
+}
+
+
+#ifndef USE_COMBO_BOX
+void clsd_menuCallback(Widget widget, XtPointer ptr, XtPointer callData) {
+    //XmPushButtonCallbackStruct *data = (XmPushButtonCallbackStruct *)callData;    
+    XtPointer userData;
+
+    XtVaGetValues(widget, XmNuserData, &userData, NULL);
+
+    //clsd_menu is zero based, cad_line_style_data constants are one based. 
+    clsd_value = (int)userData + 1;
+    if (debug_level & 1)
+        fprintf(stderr,"Selected value on cad line type pulldown: %d\n",clsd_value);
+}
+#endif  // !USE_COMBO_BOX
+
+
+
+// Create a dialog to obtain information about a newly created CAD
+// object from the user.  Values of probability, name, and comment
+// are initially blank.  Takes as a parameter a string describing
+// the area of the object.  There is a single button with a callback
+// to Set_CAD_object_parameters, which stores values from the dialog
+// in the object's struct.  Should be generalized to allow editing
+// of a pre-existing CAD object (except for the name).  Parameter
+// should be a pointer to the object.
+//
+void Set_CAD_object_parameters_dialog(char *area_description, CADRow *CAD_object) {
+    Widget cad_pane, cad_form,
+           cad_label,
+           cad_comment,
+           cad_probability,
+           cad_line_style,
+           button_done,
+           button_cancel;
+    char   probability_string[5];
+    int i;  // loop counters
+    //XmString cb_item;  // used to create picklist of line styles
+    XmString cb_items[3]; 
+#ifndef USE_COMBO_BOX
+    Widget clsd_menuPane;  
+    Widget clsd_button;
+    Widget clsd_buttons[3];
+    Widget clsd_menu;
+    char buf[18];   
+    int x;
+    Arg args[12]; // available for XtSetArguments
+#endif // !USE_COMBO_BOX
+    Widget clsd_widget;
+
+                                                                                                                        
+    if (cad_dialog) {
+        (void)XRaiseWindow(XtDisplay(cad_dialog), XtWindow(cad_dialog));
+    } 
+    else {
+
+        // Area Object"
+        cad_dialog = XtVaCreatePopupShell(langcode("CADPUD001"),
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,          XmDESTROY,
+                XmNdefaultPosition,         FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+                                                                                                                        
+        cad_pane = XtVaCreateWidget("Set_Del_Object pane",
+                xmPanedWindowWidgetClass,
+                cad_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+                                                                                                                        
+        cad_form =  XtVaCreateWidget("Set_Del_Object ob_form",
+                xmFormWidgetClass,
+                cad_pane,
+                XmNfractionBase,            2,
+                XmNautoUnmanage,            FALSE,
+                XmNshadowThickness,         1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+        // Area of polygon, already scaled and internationalized.
+        cad_label = XtVaCreateManagedWidget(area_description,
+                xmLabelWidgetClass,
+                cad_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // "Area Label:"
+        cad_label = XtVaCreateManagedWidget(langcode("CADPUD002"),
+                xmLabelWidgetClass,
+                cad_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               50,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // label text field
+        cad_label_data = XtVaCreateManagedWidget("Set_Del_Object name_data",
+                xmTextFieldWidgetClass,
+                cad_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 20,
+                XmNmaxLength,               CAD_LABEL_MAX_SIZE - 1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               50,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              cad_label,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "Comment"
+        cad_comment = XtVaCreateManagedWidget(langcode("CADPUD003"),
+                xmLabelWidgetClass,
+                cad_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               90,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // comment text field
+        cad_comment_data = XtVaCreateManagedWidget("Set_Del_Object name_data",
+                xmTextFieldWidgetClass,
+                cad_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 40,
+                XmNmaxLength,               CAD_COMMENT_MAX_SIZE - 1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               90,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              cad_comment,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "Probability (as %)"
+        cad_probability = XtVaCreateManagedWidget(langcode("CADPUD004"),
+                xmLabelWidgetClass,
+                cad_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               130,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // probability field
+        cad_probability_data = XtVaCreateManagedWidget("Set_Del_Object name_data",
+                xmTextFieldWidgetClass,
+                cad_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 5,
+                XmNmaxLength,               5,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               130,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              cad_probability,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                 NULL);
+        // Boundary Line Type
+        cad_line_style = XtVaCreateManagedWidget("Line Type:",
+                xmLabelWidgetClass,
+                cad_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               cad_probability_data,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // lesstif as of 0.95 in 2008 doesn't fully support combo boxes
+        // 
+        // Need to replace combo boxes with a pull down menu when lesstif is used.
+        // See xpdf's  XPDFViewer.cc/XPDFViewer.h for an example.
+        //cb_items = (XmString *) XtMalloc ( sizeof (XmString) * 4 );
+        // Solid
+        cb_items[0] = XmStringCreateLtoR( langcode("CADPUD012"), XmFONTLIST_DEFAULT_TAG);
+        // Dashed
+        cb_items[1] = XmStringCreateLtoR( langcode("CADPUD013"), XmFONTLIST_DEFAULT_TAG);
+        // Double Dash
+        cb_items[2] = XmStringCreateLtoR( langcode("CADPUD014"), XmFONTLIST_DEFAULT_TAG);
+
+        clsd_widget = cad_line_style_data;
+
+#ifdef USE_COMBO_BOX
+        // Combo box to pick line style
+        cad_line_style_data = XtVaCreateManagedWidget("select line style",
+                xmComboBoxWidgetClass,
+                cad_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               cad_probability_data,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              cad_line_style,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNnavigationType,          XmTAB_GROUP,
+                XmNcomboBoxType,            XmDROP_DOWN_LIST,
+                XmNpositionMode,            XmONE_BASED, 
+                XmNvisibleItemCount,        3,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmComboBoxAddItem(cad_line_style_data,cb_items[0],1,1);  
+        XmComboBoxAddItem(cad_line_style_data,cb_items[1],2,1);  
+        XmComboBoxAddItem(cad_line_style_data,cb_items[2],3,1);  
+
+        clsd_widget = cad_line_style_data;
+#else
+        // menu replacement for combo box when using lesstif
+        x = 0;
+        XtSetArg(args[x], XmNmarginWidth, 0); ++x;
+        XtSetArg(args[x], XmNmarginHeight, 0); ++x;
+        XtSetArg(args[x], XmNfontList, fontlist1); ++x;
+        clsd_menuPane = XmCreatePulldownMenu(cad_form,"sddd_menuPane", args, x);
+        //sddd_menu is zero based, constants for database types are one based.
+        //sddd_value is set to match constants in callback.
+        for (i=0;i<3;i++) { 
+            x = 0;
+            XtSetArg(args[x], XmNlabelString, cb_items[i]); x++;
+            XtSetArg(args[x], XmNuserData, (XtPointer)i); x++;
+            XtSetArg(args[x], XmNfontList, fontlist1); ++x;
+            sprintf(buf,"button%d",i);
+            clsd_button = XmCreatePushButton(clsd_menuPane, buf, args, x);
+            XtManageChild(clsd_button);
+            XtAddCallback(clsd_button, XmNactivateCallback, clsd_menuCallback, Set_CAD_object_parameters_dialog);
+            clsd_buttons[i] = clsd_button;
+        }
+        x = 0;
+        XtSetArg(args[x], XmNleftAttachment, XmATTACH_WIDGET); ++x;
+        XtSetArg(args[x], XmNleftWidget, cad_line_style); ++x;
+        XtSetArg(args[x], XmNtopAttachment, XmATTACH_WIDGET); ++x;
+        XtSetArg(args[x], XmNtopWidget, cad_probability_data); ++x;
+        XtSetArg(args[x], XmNmarginWidth, 0); ++x;
+        XtSetArg(args[x], XmNmarginHeight, 0); ++x;
+        XtSetArg(args[x], XmNtopOffset, 5); ++x;
+        XtSetArg(args[x], XmNleftOffset, 10); ++x;
+        XtSetArg(args[x], XmNsubMenuId, clsd_menuPane); ++x;
+        XtSetArg(args[x], XmNfontList, fontlist1); ++x;
+        clsd_menu = XmCreateOptionMenu(cad_form, "sddd_Menu", args, x);
+        XtManageChild(clsd_menu);
+        clsd_value = 2;   // set a default value (line on off dash)
+        clsd_widget = clsd_menu;
+#endif  // USE_COMBO_BOX
+        // free up space from combo box strings 
+        for (i=0;i<3;i++) {
+           XmStringFree(cb_items[i]);
+        }
+
+
+       // "OK"
+        button_done = XtVaCreateManagedWidget(langcode("CADPUD005"),
+                xmPushButtonGadgetClass,
+                cad_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         clsd_widget,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_POSITION,
+                XmNleftPosition,      0,
+                XmNrightAttachment,   XmATTACH_POSITION,
+                XmNrightPosition,     1,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Cancel"
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass,
+                cad_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         clsd_widget,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_POSITION,
+                XmNleftPosition,      1,
+                XmNrightAttachment,   XmATTACH_POSITION,
+                XmNrightPosition,     2,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        // callback depends on whether this is a new or old object
+        //XtAddCallback(button_done, XmNactivateCallback, Set_CAD_object_parameters, Set_CAD_object_parameters_dialog);
+
+        if (CAD_object!=NULL) {
+            XtAddCallback(button_done, XmNactivateCallback, Set_CAD_object_parameters, (XtPointer *)CAD_object);
+        } 
+        else {
+            // called to get information for a newly created cad object
+            // pass pointer to the head of the list, which contains
+            // the most recently created cad object.
+            XtAddCallback(button_done, XmNactivateCallback, Set_CAD_object_parameters, CAD_list_head);
+        } 
+
+        XtAddCallback(button_cancel, XmNactivateCallback, close_object_params_dialog, NULL);
+
+        pos_dialog(cad_dialog);
+        XmInternAtom(XtDisplay(cad_dialog),"WM_DELETE_WINDOW", FALSE);
+
+        XtManageChild(cad_form);
+        XtManageChild(cad_pane);
+                                                                                                                        
+        XtPopup(cad_dialog,XtGrabNone);
+    } // end if ! caddialog
+
+    if (CAD_object!=NULL) {
+        XmString tempSelection;
+
+        // given an existing object, fill form with its information
+        XmTextFieldSetString(cad_label_data,CAD_object->label);
+        XmTextFieldSetString(cad_comment_data,CAD_object->comment);
+        xastir_snprintf(probability_string,
+            sizeof(probability_string),
+            "%01.2f",
+            CAD_object_get_raw_probability(CAD_object,1));
+        XmTextFieldSetString(cad_probability_data,probability_string);
+
+        switch(CAD_object->line_type) {
+
+            case 1: // Solid
+#ifndef USE_COMBO_BOX
+                i = 0;
+#endif // !USE_COMBO_BOX
+                tempSelection = XmStringCreateLtoR( langcode("CADPUD012"),
+                    XmFONTLIST_DEFAULT_TAG);
+                break;
+
+            case 2: // Dashed
+#ifndef USE_COMBO_BOX
+                i = 1;
+#endif // !USE_COMBO_BOX
+                tempSelection = XmStringCreateLtoR( langcode("CADPUD013"),
+                    XmFONTLIST_DEFAULT_TAG);
+                break;
+
+            case 3: // Double Dash
+#ifndef USE_COMBO_BOX
+                i = 2;
+#endif // !USE_COMBO_BOX
+                tempSelection = XmStringCreateLtoR( langcode("CADPUD014"),
+                    XmFONTLIST_DEFAULT_TAG);
+                break;
+
+            default:
+#ifndef USE_COMBO_BOX
+                i = 1;
+#endif // !USE_COMBO_BOX
+                tempSelection = XmStringCreateLtoR( langcode("CADPUD013"),
+                    XmFONTLIST_DEFAULT_TAG);
+                break;
+        }        
+#ifdef USE_COMBO_BOX
+        XmComboBoxSelectItem(cad_line_style_data, tempSelection);
+#else
+        clsd_value = i+1;
+        //clsd_menu is zero based, line types are one based.
+        //clsd_value matches line types (1-3).
+        XtVaSetValues(clsd_menu, XmNmenuHistory, clsd_buttons[i], NULL);
+#endif // USE_COMBO_BOX
+       XmStringFree(tempSelection);
+    } 
+}
+
+
+
+
+
+static Cursor cs_CAD = (Cursor)NULL;
+
+void free_cs_CAD(void)
+{
+	XFreeCursor(XtDisplay(da), cs_CAD);
+	cs_CAD = (Cursor)NULL;
+}
+
+// This is the callback for the Draw togglebutton
+//
+void Draw_CAD_Objects_mode( /*@unused@*/ Widget widget,
+        XtPointer clientData,
+        XtPointer callData) {
+
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+
+    if(state->set) {
+        draw_CAD_objects_flag = 1;
+
+        // Create the "pencil" cursor so we know what mode we're in.
+        //
+        if(!cs_CAD) {
+            cs_CAD=XCreateFontCursor(XtDisplay(da),XC_pencil);
+            atexit(free_cs_CAD);
+        }
+    
+        // enable the close polygon button on an open CAD menu
+        if (CAD_close_polygon_menu_item) { 
+            XtSetSensitive(CAD_close_polygon_menu_item,TRUE);
+        } 
+
+        (void)XDefineCursor(XtDisplay(da),XtWindow(da),cs_CAD);
+        (void)XFlush(XtDisplay(da));
+
+        draw_CAD_objects_flag = 1;
+        polygon_last_x = -1;    // Invalid position
+        polygon_last_y = -1;    // Invalid position
+    }
+    else {
+        draw_CAD_objects_flag = 0;
+        polygon_last_x = -1;    // Invalid position
+        polygon_last_y = -1;    // Invalid position
+
+        Save_CAD_Objects_to_file();
+ 
+        // Remove the special "pencil" cursor.
+        (void)XUndefineCursor(XtDisplay(da),XtWindow(da));
+        (void)XFlush(XtDisplay(da));
+
+        // disable the close polygon button on an open CAD menu.
+        if (CAD_close_polygon_menu_item) { 
+            XtSetSensitive(CAD_close_polygon_menu_item,FALSE);
+        } 
+    }
+}
+
+
+
+
+
+// Called when we complete a new CAD object.  Save the object to
+// disk so that we can recover in the case of a crash or power
+// failure.  Save any old file to a backup file.  Perhaps write them
+// to numbered backup files so that we keep several on-hand?
+//
+void Save_CAD_Objects_to_file(void) {
+    FILE *f;
+    char *file;
+    CADRow *object_ptr = CAD_list_head;
+    char temp_file_path[MAX_VALUE];
+
+    fprintf(stderr,"Saving CAD objects to file\n");
+
+    // Save in ~/.xastir/config/CAD_object.log
+    file = get_user_base_dir("config/CAD_object.log", temp_file_path, sizeof(temp_file_path));
+    f = fopen(file,"w+");
+
+    if (f == NULL) {
+        fprintf(stderr,
+            "Couldn't open config/CAD_object.log file for writing!\n");
+        return;
+    }
+
+    while (object_ptr != NULL) {
+        VerticeRow *vertice = object_ptr->start;
+
+        // Write out the main object info:
+        fprintf(f,"\nCAD_Object\n");
+        fprintf(f,"creation_time:   %lu\n",(unsigned long)object_ptr->creation_time);
+        fprintf(f,"line_color:      %d\n",object_ptr->line_color);
+        fprintf(f,"line_type:       %d\n",object_ptr->line_type);
+        fprintf(f,"line_width:      %d\n",object_ptr->line_width);
+        fprintf(f,"computed_area:   %f\n",object_ptr->computed_area);
+        fprintf(f,"raw_probability: %f\n",CAD_object_get_raw_probability(object_ptr,TRUE));
+        fprintf(f,"label_latitude:  %lu\n",object_ptr->label_latitude);
+        fprintf(f,"label_longitude: %lu\n",object_ptr->label_longitude);
+        fprintf(f,"label: %s\n",object_ptr->label);
+        if (strlen(object_ptr->comment)>1) { 
+            fprintf(f,"comment: %s\n",object_ptr->comment);
+        } 
+        else {
+            fprintf(f,"comment: NULL\n");
+        }
+
+        // Iterate through the vertices:
+        while (vertice != NULL) {
+
+            fprintf(f,"Vertice: %lu %lu\n",
+                vertice->latitude,
+                vertice->longitude);
+
+            vertice = vertice->next;
+        }
+        object_ptr = object_ptr->next;
+    }
+    (void)fclose(f);
+}
+
+
+
+
+
+// Called by main() when we start Xastir.  Restores CAD objects
+// created in earlier Xastir sessions.
+//
+void Restore_CAD_Objects_from_file(void) {
+    FILE *f;
+    char *file;
+    char line[MAX_FILENAME];
+    char temp_file_path[MAX_VALUE];
+#ifdef CAD_DEBUG
+    fprintf(stderr,"Restoring CAD objects from file\n");
+#endif
+
+    // Restore from ~/.xastir/config/CAD_object.log
+    file = get_user_base_dir("config/CAD_object.log", temp_file_path, sizeof(temp_file_path));
+    f = fopen(file,"r");
+
+    if (f == NULL) {
+#ifdef CAD_DEBUG
+        fprintf(stderr,
+            "Couldn't open config/CAD_object.log file for reading!\n");
+#endif
+        return;
+    }
+
+    while (!feof (f)) {
+        (void)get_line(f, line, MAX_FILENAME);
+        if (strncasecmp(line,"CAD_Object",10) == 0) {
+            // Found a new CAD Object declaration!
+
+            //fprintf(stderr,"Found CAD_Object\n");
+
+            // Malloc a new object, add it to the linked list, start
+            // filling in the fields.
+            //
+            // This gives us a default object with one vertice.  We
+            // can replace all of the fields in it as we parse them.
+            CAD_object_allocate(0l, 0l);
+
+            // Remove the one vertice from the newly allocated
+            // object so that we don't end up with one too many
+            // vertices when all done.
+            CAD_vertice_delete_all(CAD_list_head->start);
+            CAD_list_head->start = NULL;
+            
+        }
+        else if (strncasecmp(line,"creation_time:",14) == 0) {
+            //fprintf(stderr,"Found creation_time:\n");
+            unsigned long temp_time;
+            if (1 != sscanf(line+15, "%lu",&temp_time)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [creation_time]\n");
+            }
+            CAD_list_head->creation_time=(time_t)temp_time;
+        }
+        else if (strncasecmp(line,"line_color:",11) == 0) {
+            //fprintf(stderr,"Found line_color:\n");
+            if (1 != sscanf(line+12,"%d",
+                    &CAD_list_head->line_color)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [line_color]\n");
+            }
+        }
+        else if (strncasecmp(line,"line_type:",10) == 0) {
+            //fprintf(stderr,"Found line_type:\n");
+            if (1 != sscanf(line+11,"%d",
+                    &CAD_list_head->line_type)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [line_type]\n");
+            }
+        }
+        else if (strncasecmp(line,"line_width:",11) == 0) {
+            //fprintf(stderr,"Found line_width:\n");
+            if (1 != sscanf(line+12,"%d",
+                    &CAD_list_head->line_width)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [line_width]\n");
+            }
+        }
+        else if (strncasecmp(line,"computed_area:",14) == 0) {
+            //fprintf(stderr,"Found computed_area:\n");
+            if (1 != sscanf(line+15,"%f",
+                    &CAD_list_head->computed_area)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [computed_area]\n");
+            }
+        }
+        else if (strncasecmp(line,"raw_probability:",16) == 0) {
+            //fprintf(stderr,"Found raw_probability:\n");
+            if (1 != sscanf(line+17,"%f",
+                    &CAD_list_head->raw_probability)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [raw_probability]\n");
+            } 
+            else {
+                // External storage is as percent, need to make sure that this
+                // fits the expected internal storage format.
+                // Thus take given value and store using method that knows 
+                // how to handle percents
+                CAD_object_set_raw_probability(CAD_list_head,CAD_list_head->raw_probability,TRUE);
+            }
+        }
+        else if (strncasecmp(line,"label_latitude:",15) == 0) {
+            //fprintf(stderr,"Found label_latitude:\n");
+            if (1 != sscanf(line+16,"%lu",
+                    (unsigned long *)&CAD_list_head->label_latitude)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [label_latitude]\n");
+            }
+        }
+        else if (strncasecmp(line,"label_longitude:",16) == 0) {
+            //fprintf(stderr,"Found label_longitude:\n");
+            if (1 != sscanf(line+17,"%lu",
+                    (unsigned long *)&CAD_list_head->label_longitude)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [label_longitude]\n");
+            }
+        }
+        else if (strncasecmp(line,"label:",6) == 0) {
+            //fprintf(stderr,"Found label:\n");
+            xastir_snprintf(CAD_list_head->label,
+                sizeof(CAD_list_head->label),
+                "%s",
+                line+7);
+        }
+        else if (strncasecmp(line,"comment:",8) == 0) {
+            //fprintf(stderr,"Found comment:\n");
+            xastir_snprintf(CAD_list_head->comment,
+                sizeof(CAD_list_head->comment),
+                "%s",
+                line+9);
+ 
+            if (strcmp(CAD_list_head->comment,"NULL")==0) {
+                xastir_snprintf(CAD_list_head->comment,
+                    sizeof(CAD_list_head->comment),
+                    "%c",
+                    '\0'
+                    );
+            }
+        }
+        else if (strncasecmp(line,"Vertice:",8) == 0) {
+            long latitude, longitude;
+
+            //fprintf(stderr,"Found Vertice:\n");
+            if (2 != sscanf(line+9,"%lu %lu",
+                    (unsigned long *)&latitude,
+                    (unsigned long *)&longitude)) {
+                fprintf(stderr,"Restore_CAD_Objects_from_file:sscanf parsing error [vertex]\n");
+            }
+            CAD_vertice_allocate(latitude,longitude);
+        }
+        else {
+            // Else not recognized, do nothing with it!
+            //fprintf(stderr,"Found unrecognized line\n");
+        }
+    }
+    (void)fclose(f);
+    // Reload symbols/tracks/CAD objects to draw the loaded objects
+    redraw_symbols(da);
+}
+
+
+
+
+
+// popdown and destroy the cad_erase_dialog.
+//
+void Draw_CAD_Objects_erase_dialog_close ( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+
+    if (cad_erase_dialog!=NULL) {
+        // close cad_erase_dialog
+        XtPopdown(cad_erase_dialog);
+        XtDestroyWidget(cad_erase_dialog);
+        cad_erase_dialog = (Widget)NULL;
+    }
+
+}
+
+
+
+
+
+// Call back for delete selected button on
+// Draw_CAD_Objects_erase_dialog.  Iterates through the list of
+// selected CAD objects and deletes them.
+//
+void Draw_CAD_Objects_erase_selected ( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+    int itemCount;       // number of items in list of CAD objects.
+    XmString *listItems; // names of CAD objects on list 
+    char *cadName;       // the text name of a CAD object
+    Position x;          // position on list
+    char *selectedName;  // the text name of a selected CAD object
+    CADRow *object_ptr = CAD_list_head;  // pointer to the linked list of CAD objects
+    int done = 0;        // has a cad object with a name matching the current selection been found
+
+    // For more than a few objects this loop/save/redraw will need to move
+    // off to a separate thread.
+
+    XtVaGetValues(list_of_existing_CAD_objects,
+               XmNitemCount,&itemCount,
+               XmNitems,&listItems,
+               NULL);
+    // iterate through list and delete each first object with a name matching 
+    // those that are selected on the list.
+    //
+    // *** Note: If names are not unique the results may not be what the user expects.
+    // The first match to a selection will be deleted, not necessarily the selection.
+    //
+    for (x=1; x<=itemCount;x++) {
+
+        if (done)
+            break;
+
+        if (XmListPosSelected(list_of_existing_CAD_objects,x)) {
+            int no_label = 0;
+
+            XmStringGetLtoR(listItems[(x-1)],XmFONTLIST_DEFAULT_TAG,&selectedName);
+
+            // Check for our own definition of no label for the CAD
+            // objects, which is "<Empty Label>"
+            if (strcmp(selectedName,"<Empty Label>") == 0)
+                no_label++;
+
+            object_ptr = CAD_list_head;
+            done = 0;
+
+            while (object_ptr != NULL && done == 0) {
+
+                cadName = object_ptr->label;
+
+                if (strcmp(cadName,selectedName)==0
+                        || ( (cadName == NULL || cadName[0] == '\0') && no_label) ) {
+                    // delete CAD object matching the selected name
+                    CAD_object_delete(object_ptr);
+                    done = 1;
+                } 
+                else {
+                   object_ptr = object_ptr->next;
+                }
+            }
+        }
+    }
+
+    Draw_CAD_Objects_erase_dialog_close(w,clientData,callData);
+
+    // Save the altered list to file.
+    Save_CAD_Objects_to_file();
+    // Reload symbols/tracks/CAD objects
+    redraw_symbols(da);
+
+    // Here we update the edit cad objects dialog by getting rid of it and
+    // then re-establishing it if it is active when we start.  This will
+    // usually make the dialog move, but it's better than having it be
+    // out-of-date.
+    //
+    if (cad_list_dialog!=NULL) {
+        // Update the Edit CAD Objects list
+        Draw_CAD_Objects_list_dialog_close(w, clientData, callData);
+        Draw_CAD_Objects_list_dialog(w, clientData, callData);
+    }
+}
+
+
+
+
+
+// Callback for delete CAD objects menu option.  Dialog to allow
+// users to delete all CAD objects or select individual CAD objects
+// to delete.
+//
+void Draw_CAD_Objects_erase_dialog( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+
+    Widget cad_erase_pane, cad_erase_form, cad_erase_label,
+           button_delete_all, button_delete_selected, button_cancel;
+    Arg al[100];       /* Arg List */
+    unsigned int ac;   /* Arg Count */
+    CADRow *object_ptr = CAD_list_head;
+    int counter = 1;
+    XmString cb_item;
+
+    if (cad_erase_dialog) {
+        (void)XRaiseWindow(XtDisplay(cad_erase_dialog), XtWindow(cad_erase_dialog));
+    } else {
+
+        // Delete CAD Objects
+        cad_erase_dialog = XtVaCreatePopupShell("Delete CAD Objects",
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,          XmDESTROY,
+                XmNdefaultPosition,         FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+                                                                                                                        
+        cad_erase_pane = XtVaCreateWidget("CAD erase Object pane",
+                xmPanedWindowWidgetClass,
+                cad_erase_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+                                                                                                                        
+        cad_erase_form =  XtVaCreateWidget("Cad erase Object form",
+                xmFormWidgetClass,
+                cad_erase_pane,
+                XmNfractionBase,            3,
+                XmNautoUnmanage,            FALSE,
+                XmNshadowThickness,         1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // heading: Delete CAD Objects 
+        cad_erase_label = XtVaCreateManagedWidget(langcode("CADPUD009"),
+                xmLabelWidgetClass,
+                cad_erase_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // *** need to handle the special case of no CAD objects ? ***
+
+        // scrolled pick list to allow selection of current objects
+        /*set args for list */
+        ac=0;
+        XtSetArg(al[ac], XmNvisibleItemCount, 11); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmEXTENDED_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+        XtSetArg(al[ac], XmNtopWidget, cad_erase_label); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        //XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, colors[0x0f]); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        list_of_existing_CAD_objects = XmCreateScrolledList(cad_erase_form,
+                "CAD objects for deletion scrolled list",
+                al,
+                ac);
+        // make sure list is empty
+        XmListDeleteAllItems(list_of_existing_CAD_objects);
+
+        // iterate through list of objects to populate scrolled list
+        while (object_ptr != NULL) {
+
+            //  If no label, use the string "<Empty Label>" instead
+            if (object_ptr->label == NULL || object_ptr->label[0] == '\0')
+                cb_item = XmStringCreateLtoR("<Empty Label>", XmFONTLIST_DEFAULT_TAG);
+            else
+                cb_item = XmStringCreateLtoR(object_ptr->label, XmFONTLIST_DEFAULT_TAG);
+
+
+            XmListAddItem(list_of_existing_CAD_objects,
+                          cb_item,
+                          counter);  
+            counter++;
+            XmStringFree(cb_item);
+            object_ptr = object_ptr->next;
+        }
+
+        // "Delete All"
+        button_delete_all = XtVaCreateManagedWidget(langcode("CADPUD010"),
+                xmPushButtonGadgetClass,
+                cad_erase_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         list_of_existing_CAD_objects,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_FORM,
+                XmNleftOffset,        5,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_delete_all, XmNactivateCallback, Draw_CAD_Objects_erase, Draw_CAD_Objects_erase_dialog);
+
+        // "Delete Selected"
+        button_delete_selected = XtVaCreateManagedWidget(langcode("CADPUD011"),
+                xmPushButtonGadgetClass,
+                cad_erase_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         list_of_existing_CAD_objects,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_WIDGET,
+                XmNleftWidget,        button_delete_all,
+                XmNleftOffset,        10,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_delete_selected, XmNactivateCallback, Draw_CAD_Objects_erase_selected, Draw_CAD_Objects_erase_dialog);
+
+        // "Cancel"
+        button_cancel = XtVaCreateManagedWidget(langcode("CADPUD008"),
+                xmPushButtonGadgetClass,
+                cad_erase_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         list_of_existing_CAD_objects,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_WIDGET,
+                XmNleftWidget,        button_delete_selected,
+                XmNleftOffset,        10,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_cancel, XmNactivateCallback, Draw_CAD_Objects_erase_dialog_close, Draw_CAD_Objects_erase_dialog);                        
+        pos_dialog(cad_erase_dialog);
+        XmInternAtom(XtDisplay(cad_erase_dialog),"WM_DELETE_WINDOW", FALSE);
+
+        XtManageChild(cad_erase_form);
+        XtManageChild(list_of_existing_CAD_objects);
+        XtManageChild(cad_erase_pane);
+                                                                                                                        
+        XtPopup(cad_erase_dialog,XtGrabNone);
+    }
+}
+
+
+
+
+
+// popdown and destroy the cad_list_dialog
+//
+void Draw_CAD_Objects_list_dialog_close ( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+
+    if (cad_list_dialog!=NULL) {
+        // close cad_list_dialog
+        XtPopdown(cad_list_dialog);
+        XtDestroyWidget(cad_list_dialog);
+        cad_list_dialog = (Widget)NULL;
+    }
+
+}
+
+
+
+
+
+// Show details for selected CAD object.  Callback for the show/edit
+// details button on the Draw_CAD_Objects_list dialog.
+//
+void Show_selected_CAD_object_details ( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+
+    static int sizeof_area_description = 200;
+    int itemCount;       // number of items in list of CAD objects.
+    XmString *listItems; // names of CAD objects on list 
+    char *cadName;       // the text name of a CAD object
+    Position x;          // position on list
+    char *selectedName;  // the text name of a selected CAD object
+    CADRow *object_ptr = CAD_list_head;  // pointer to the linked list of CAD objects
+    int done = 0;        // has a cad object with a name matching the current selection been found
+    double area;
+    char area_description[sizeof_area_description];
+    xastir_snprintf(area_description, sizeof_area_description, "Area");
+
+    if (cad_list_dialog!=NULL) {
+        // get the selected object
+        XtVaGetValues(list_of_existing_CAD_objects_edit,
+                   XmNitemCount,&itemCount,
+                   XmNitems,&listItems,
+                   NULL);
+        // iterate through list and find each object with a name
+        // matching one selected on the list.
+        //
+        // *** Note: If names are not unique the results may not be what the user expects.
+        // The first match to a selection will be used, not necessarily the selection.
+        //
+        for (x=1; x<=itemCount;x++) {
+            if (XmListPosSelected(list_of_existing_CAD_objects_edit,x)) {
+                int no_label = 0;
+
+                XmStringGetLtoR(listItems[(x-1)],XmFONTLIST_DEFAULT_TAG,&selectedName);
+
+                // Check for our own definition of no label for the CAD
+                // objects, which is "<Empty Label>"
+                if (strcmp(selectedName,"<Empty Label>") == 0)
+                    no_label++;
+    
+                object_ptr = CAD_list_head;
+                done = 0;
+
+                while (object_ptr != NULL && done == 0) {
+
+                    cadName = object_ptr->label;
+
+                    if (strcmp(cadName,selectedName)==0
+                            || ( (cadName == NULL || cadName[0] == '\0') && no_label) ) {
+
+                        // get the area for the CAD object matching the selected name
+                        // and format it as a localized string.
+                        area = object_ptr->computed_area;
+                        Format_area_for_output(&area, area_description,sizeof_area_description);
+                        // open the CAD object details dialog for the matching CAD object
+                        Set_CAD_object_parameters_dialog(area_description,object_ptr);
+                        done = 1;
+                    } else {
+                       object_ptr = object_ptr->next;
+                    }
+                }
+            }
+        }
+
+        // leave the list dialog open
+    }
+}
+
+
+
+
+
+// Callback for edit CAD objects menu option.  Dialog to allow users
+// to select individual CAD objects in order to edit their metadata.
+//
+void Draw_CAD_Objects_list_dialog( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+
+    Widget cad_list_pane, cad_list_form, cad_list_label,
+           button_list_selected, button_close;
+    Arg al[100];       /* Arg List */
+    unsigned int ac;   /* Arg Count */
+    CADRow *object_ptr = CAD_list_head;
+    int counter = 1;
+    XmString cb_item;
+
+    if (cad_list_dialog) {
+        (void)XRaiseWindow(XtDisplay(cad_list_dialog), XtWindow(cad_list_dialog));
+    } 
+    else {
+
+        // List CAD Objects
+        cad_list_dialog = XtVaCreatePopupShell("List CAD Objects",
+                xmDialogShellWidgetClass,
+                appshell,
+                XmNdeleteResponse,          XmDESTROY,
+                XmNdefaultPosition,         FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+                                                                                                                        
+        cad_list_pane = XtVaCreateWidget("CAD list Object pane",
+                xmPanedWindowWidgetClass,
+                cad_list_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+                                                                                                                        
+        cad_list_form =  XtVaCreateWidget("Cad list Object form",
+                xmFormWidgetClass,
+                cad_list_pane,
+                XmNfractionBase,            3,
+                XmNautoUnmanage,            FALSE,
+                XmNshadowThickness,         1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // heading: CAD Objects 
+        cad_list_label = XtVaCreateManagedWidget(langcode("CADPUD006"), 
+                xmLabelWidgetClass,
+                cad_list_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // *** need to handle the special case of no CAD objects ? ***
+
+        // scrolled pick list to allow selection of current objects
+        /*set args for list */
+        ac=0;
+        XtSetArg(al[ac], XmNvisibleItemCount, 11); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+        XtSetArg(al[ac], XmNtopWidget, cad_list_label); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        //XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, colors[0x0f]); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        list_of_existing_CAD_objects_edit = XmCreateScrolledList(cad_list_form,
+                "CAD objects for deletion scrolled list",
+                al,
+                ac);
+        // make sure list is empty
+        XmListDeleteAllItems(list_of_existing_CAD_objects_edit);
+
+        // iterate through list of objects to populate scrolled list
+        while (object_ptr != NULL) {
+
+            //  If no label, use the string "<Empty Label>" instead
+            if (object_ptr->label == NULL || object_ptr->label[0] == '\0')
+                cb_item = XmStringCreateLtoR("<Empty Label>", XmFONTLIST_DEFAULT_TAG);
+            else
+                cb_item = XmStringCreateLtoR(object_ptr->label, XmFONTLIST_DEFAULT_TAG);
+
+            XmListAddItem(list_of_existing_CAD_objects_edit,
+                          cb_item,
+                          counter);  
+            counter++;
+            XmStringFree(cb_item);
+            object_ptr = object_ptr->next;
+        }
+
+       // "Show/edit details"
+        button_list_selected = XtVaCreateManagedWidget(langcode("CADPUD007"),
+                xmPushButtonGadgetClass,
+                cad_list_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         list_of_existing_CAD_objects_edit,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_FORM,
+                XmNleftOffset,        10,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_list_selected, XmNactivateCallback, Show_selected_CAD_object_details, Draw_CAD_Objects_list_dialog);
+
+        // "Close"
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass,
+                cad_list_form,
+                XmNtopAttachment,     XmATTACH_WIDGET,
+                XmNtopWidget,         list_of_existing_CAD_objects_edit,
+                XmNtopOffset,         5,
+                XmNbottomAttachment,  XmATTACH_FORM,
+                XmNbottomOffset,      5,
+                XmNleftAttachment,    XmATTACH_WIDGET,
+                XmNleftWidget,        button_list_selected,
+                XmNleftOffset,        10,
+                XmNnavigationType,    XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(button_close, XmNactivateCallback, Draw_CAD_Objects_list_dialog_close, Draw_CAD_Objects_erase_dialog);                        
+        pos_dialog(cad_list_dialog);
+        XmInternAtom(XtDisplay(cad_list_dialog),"WM_DELETE_WINDOW", FALSE);
+
+        XtManageChild(cad_list_form);
+        XtManageChild(list_of_existing_CAD_objects_edit);
+        XtManageChild(cad_list_pane);
+                                                                                                                        
+        XtPopup(cad_list_dialog,XtGrabNone);
+    }
+}
+
+
+
+
+
+// Free the object and vertice lists then do a screen update.
+// callback from delete all button on cad_erase_dialog.
+//
+void Draw_CAD_Objects_erase( /*@unused@*/ Widget w,
+        /*@unused@*/ XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+    
+    // if we were called from the cad_erase_dialog, make sure it is closed properly
+    if (cad_erase_dialog) 
+        Draw_CAD_Objects_erase_dialog_close(w,clientData,callData);
+
+    CAD_object_delete_all();
+    polygon_last_x = -1;    // Invalid position
+    polygon_last_y = -1;    // Invalid position
+
+    // Save the empty list out to file
+    Save_CAD_Objects_to_file();
+
+    // Reload symbols/tracks/CAD objects
+    redraw_symbols(da);
+}
+
+
+
+
+
+// Formats an area in square kilometers as a string in english or
+// metric units, converting to feet or meters if the area is less
+// than 0.1 square kilometers and adding localized text.
+// Parameters: area: an area in square kilometers.
+// area_description: area reformatted as a localized text string.
+// sizeof_area_description: array length of area_description.
+//
+void Format_area_for_output(double *area_km2, char *area_description, int sizeof_area_description) {
+    double area;
+    // Format it for output and dump it out.  We're using square
+    // terms, so apply the conversion factor twice to convert from
+    // nautical square miles to the units of interest.
+    area = *area_km2 * cvt_kn2len * cvt_kn2len;
+
+    // We could be measuring a very small or a very large object.
+    // In the case of very small, convert it to square feet or
+    // square meters.
+    if (area < 0.1) {
+
+        // Small area.  Convert to square feet or square meters
+
+        if (english_units) { // Square feet
+            area = area * 5280 * 5280;
+            xastir_snprintf(area_description,
+                sizeof_area_description,
+                "A:%0.2f %s %s",
+                area,
+                langcode("POPUPMA052"),     // sq
+                langcode("POPUPMA053") );   // ft
+            //popup_message_always(langcode("POPUPMA020"),area_description);
+        }
+        else {  // Square meters
+            area = area * 1000 * 1000;  // Square meters
+            xastir_snprintf(area_description,
+                sizeof_area_description,
+                "A:%0.2f %s %s",
+                area,
+                langcode("POPUPMA052"),     // sq
+                langcode("POPUPMA054") );   // meters
+            //popup_message_always(langcode("POPUPMA020"),area_description);
+        }
+    }
+    else {  // Not small
+        xastir_snprintf(area_description,
+            sizeof_area_description,
+            "A:%0.2f %s %s",
+            area,
+            langcode("POPUPMA052"), // sq
+            un_dst);
+        //popup_message_always(langcode("POPUPMA020"),area_description);
+    }
+}
+
+
+
+
+
+// Add an ending vertice that is the same as the starting vertice.
+// Best not to use the screen coordinates we captured first, as the
+// user may have zoomed or panned since then.  Better to copy the
+// first vertice that we recorded in our linked list.
+//
+// Compute the area of the closed polygon.  Write it out to STDERR,
+// the computed_area field in the Object, and to a dialog that pops
+// up on the screen.
+//
+void Draw_CAD_Objects_close_polygon( /*@unused@*/ Widget widget,
+        XtPointer clientData,
+        /*@unused@*/ XtPointer callData) {
+    static int sizeof_area_description = 200;
+    VerticeRow *tmp;
+    double area;
+    int n;
+    //char temp_course[20];
+    char area_description[sizeof_area_description];
+    xastir_snprintf(area_description, sizeof_area_description, "Area");
+ 
+    // Check whether we're currently working on a polygon.  If not,
+    // get out of here.
+    if (polygon_last_x == -1 || polygon_last_y == -1) {
+
+        // Tell the code that we're starting a new polygon by wiping
+        // out the first position.
+        polygon_last_x = -1;    // Invalid position
+        polygon_last_y = -1;    // Invalid position 
+
+        return;
+    }
+
+    // Find the last vertice in the linked list.  That will be the
+    // first vertice we recorded for the object.
+
+    // Check for at least three vertices.  We don't need to check
+    // that the first/last point are equal:  We force it below by
+    // copying the first vertice to the last.
+    //
+    n = 0;
+    if (CAD_list_head != NULL) {
+ 
+        // Walk the linked list.  Stop at the last record.
+        tmp = CAD_list_head->start;
+        if (tmp != NULL) {
+            n++;
+            while (tmp->next != NULL) {
+                tmp = tmp->next;
+                n++;
+            }
+            if (n > 2) {
+                // We have more than a point or a line, therefore
+                // can copy the first point to the last, closing the
+                // polygon.
+                CAD_vertice_allocate(tmp->latitude, tmp->longitude);
+            }
+        }
+    }
+    // Reload symbols/tracks/CAD objects and redraw the polygon
+    redraw_symbols(da);
+
+#ifdef CAD_DEBUG
+    fprintf(stderr,"Points in closed polygon: n = %d\n",n);
+#endif
+
+    if (n < 3) {
+        // Not enough points to compute an area.
+
+        // Tell the code that we're starting a new polygon by wiping
+        // out the first position.
+        polygon_last_x = -1;    // Invalid position
+        polygon_last_y = -1;    // Invalid position 
+
+        return;
+    }
+    area =  CAD_object_compute_area(CAD_list_head);
+
+    // Save it in the object.  Convert nautical square miles to
+    // square kilometers.
+    area = area * 1.852 * 1.852; //km2
+    CAD_list_head->computed_area = area;
+
+    Format_area_for_output(&area, area_description, sizeof_area_description);
+
+#ifdef CAD_DEBUG
+    // Also write the area to stderr
+    fprintf(stderr,"New CAD object %s\n",area_description);
+#endif
+
+    // Tell the code that we're starting a new polygon by wiping out
+    // the first position.
+    polygon_last_x = -1;    // Invalid position
+    polygon_last_y = -1;    // Invalid position
+
+    CAD_object_set_label_at_centroid(CAD_list_head);
+    // CAD object vertices are ready, needs associated data
+    // obtain label, comment, and probability for this polygon
+    // from user through a dialog.
+    Set_CAD_object_parameters_dialog(area_description,NULL);
+}
+
+
+
+
+
+// Function called by UpdateTime when doing screen refresh.  Draws
+// all CAD objects onto the screen again.
+//
+void Draw_All_CAD_Objects(Widget w) {
+    CADRow *object_ptr = CAD_list_head;
+    long x_long, y_lat;
+    long x_offset, y_offset;
+    float probability;
+    char probability_string[8];
+    VerticeRow *vertice;
+    double area;
+    int actual_line_type = LineOnOffDash;
+    static int sizeof_area_description = 50; // define here as local static to limit size of display on map 
+                                              // independent of size as shown on form
+    char area_description[sizeof_area_description];
+    char dash[2];
+
+    // Start at CAD_list_head, iterate through entire linked list,
+    // drawing as we go.  Respect the line
+    // width/line_color/line_type variables for each object.
+
+//fprintf(stderr,"Drawing CAD objects\n");
+    if (CAD_draw_objects==TRUE) {
+        while (object_ptr != NULL) {
+            probability = CAD_object_get_raw_probability(object_ptr,1);
+            xastir_snprintf(probability_string,
+                sizeof(probability_string),
+                "%01.1f%%",
+                probability);
+    
+            // find point at which to draw label and other descriptive text
+            x_long = object_ptr->label_longitude;
+            y_lat = object_ptr->label_latitude;
+    #ifdef CAD_DEBUG
+            fprintf(stderr,"Drawing object %s\n", (object_ptr->label) ? object_ptr->label : "NULL" );
+    #endif
+            //fprintf(stderr,"Lat: %d\n", y_lat);
+            //fprintf(stderr,"Long: %d\n", x_long);
+//            if ((x_long+10>=0) && (x_long-10<=129600000l)) {      // 360 deg
+    
+//                if ((y_lat+10>=0) && (y_lat-10<=64800000l)) {     // 180 deg
+    
+                    if ((x_long>NW_corner_longitude) && (x_long<SE_corner_longitude)) {
+    
+                        if ((y_lat>NW_corner_latitude) && (y_lat<SE_corner_latitude)) {
+    
+                            // ok to draw label and assocated data, point is on screen
+                            x_offset=((x_long-NW_corner_longitude)/scale_x)-(10);
+                            y_offset=((y_lat -NW_corner_latitude) /scale_y)-(10);
+                            // ****** ?? use -10 or point ??
+                            x_offset=((x_long-NW_corner_longitude)/scale_x);
+                            y_offset=((y_lat -NW_corner_latitude) /scale_y);
+    
+                            if ((object_ptr->label!=NULL) & ((int)strlen(object_ptr->label)>0) & (CAD_show_label==TRUE)) {
+                                // Draw Label   
+                                // 0x08 is background color
+                                // 0x40 is foreground color (yellow)
+                                draw_nice_string(w,pixmap_final,letter_style,x_offset,y_offset,object_ptr->label,0x08,0x40,strlen(object_ptr->label));
+                                                                                                                        
+                                x_offset=x_offset+12;
+                                y_offset=y_offset+15;
+                            }
+    
+                            if (CAD_show_raw_probability==TRUE) {
+                                // draw probability
+                                draw_nice_string(w,pixmap_final,letter_style,x_offset,y_offset,probability_string,0x08,0x40,strlen(probability_string));
+                                y_offset=y_offset+15;
+                            }
+    
+                            if ((CAD_show_comment==TRUE) & (object_ptr->comment!=NULL) & ((int)strlen(object_ptr->comment)>0)) {
+                                // draw comment
+                                draw_nice_string(w,pixmap_final,letter_style,x_offset,y_offset,object_ptr->comment,0x08,0x40,strlen(object_ptr->comment));
+                                y_offset=y_offset+15;
+                            }
+    
+    
+                            if (CAD_show_area==TRUE) {
+                                area = object_ptr->computed_area;
+                                Format_area_for_output(&area, area_description, sizeof_area_description);
+                                draw_nice_string(w,pixmap_final,letter_style,x_offset,y_offset,area_description,0x08,0x40,strlen(area_description));
+                                y_offset=y_offset+15;
+                            }
+    
+                        }
+                    }
+//                }
+//            }
+    
+            // Iterate through the vertices and draw the lines
+            vertice = object_ptr->start;
+ 
+            switch (object_ptr->line_type) {
+
+                case 1:
+                    actual_line_type = LineSolid;
+                    break;
+
+                case 2:
+                    actual_line_type = LineOnOffDash;
+                    dash[0] = dash[1]  = 8;
+                    break;
+
+                case 3:
+                    actual_line_type = LineDoubleDash;
+                    dash[0] = dash[1]  = 16;
+                    break;
+
+                default:
+                    actual_line_type = LineOnOffDash;
+                    dash[0] = dash[1]  = 8;
+                    break;
+            } 
+
+            // Set up line color/width/type here
+            (void)XSetLineAttributes (XtDisplay (da),
+                gc_tint,
+                object_ptr->line_width,
+                actual_line_type,
+                CapButt,
+                JoinMiter);
+
+            if (object_ptr->line_type  != 1) { 
+                (void)XSetDashes (XtDisplay (da),
+                    gc_tint,
+                    0,       // dash offset
+                    dash,    // dash list[]
+                    2);      // elements in dash lista
+            }
+ 
+            (void)XSetForeground (XtDisplay (da),
+                gc_tint,
+                object_ptr->line_color);
+    
+            (void)XSetFunction (XtDisplay (da),
+                gc_tint,
+                GXxor);
+    
+            while (vertice != NULL) {
+                if (vertice->next != NULL) {
+                    // Use the draw_vector function from maps.c
+                    draw_vector(w,
+                        vertice->longitude,
+                        vertice->latitude,
+                        vertice->next->longitude,
+                        vertice->next->latitude, 
+                        gc_tint,
+                        pixmap_final,
+                        0);
+                }
+                vertice = vertice->next;
+            }
+            object_ptr = object_ptr->next;
+        }
+    }
+}
+
+
+
+/////////////////////////////////////////   Object Dialog   //////////////////////////////////////////
+
+
+
+/*
+ *  Destroy Object Dialog Popup Window
+ */
+void Object_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+    (void)XFreePixmap(XtDisplay(appshell),Ob_icon0);
+    (void)XFreePixmap(XtDisplay(appshell),Ob_icon);
+    XtDestroyWidget(shell);
+    object_dialog = (Widget)NULL;
+
+    // Take down the symbol selection dialog as well (if it's up)
+    if (select_symbol_dialog) {
+        Select_symbol_destroy_shell( widget, select_symbol_dialog, callData);
+    }
+
+    // NULL out the dialog field in the global struct used for
+    // Coordinate Calculator.  Prevents segfaults if the calculator is
+    // still up and trying to write to us.
+    coordinate_calc_array.calling_dialog = NULL;
+}
+
+
+
+
+
+// Snag the latest DR'ed position for an object/item and create the
+// types of strings that we need for Setup_object_data() and
+// Setup_item_data() for APRS and Base-91 compressed formats.
+//
+void fetch_current_DR_strings(DataRow *p_station, char *lat_str,
+        char *lon_str, char *ext_lat_str, char *ext_lon_str) {
+
+    long x_long, y_lat;
+
+
+    // Fetch the latest position for a DR'ed object.  Returns the
+    // values in two longs, x_long and y_lat.
+    compute_current_DR_position(p_station, &x_long, &y_lat);
+
+    // Normal precision for APRS format
+    convert_lat_l2s(y_lat,
+        lat_str,
+        MAX_LAT,
+        CONVERT_LP_NOSP);
+
+    convert_lon_l2s(x_long,
+        lon_str,
+        MAX_LONG,
+        CONVERT_LP_NOSP);
+
+    // Extended precision for Base-91 compressed format
+    convert_lat_l2s(y_lat,
+        ext_lat_str,
+        MAX_LAT,
+        CONVERT_HP_NOSP);
+
+    convert_lon_l2s(x_long,
+        ext_lon_str,
+        MAX_LONG,
+        CONVERT_HP_NOSP);
+}
+
+
+
+
+
+// Convert this eventually to populate a DataRow struct, then call
+// data.c:Create_object_item_tx_string().  Right now we have a lot
+// of code duplication between Setup_object_data, Setup_item_data,
+// and Create_object_item_tx_string.
+//
+// Make sure to look at the "transmit_compressed_objects_items" variable
+// to decide whether to send a compressed packet.
+/*
+ *  Setup APRS Information Field for Objects
+ */
+int Setup_object_data(char *line, int line_length, DataRow *p_station) {
+    char lat_str[MAX_LAT];
+    char lon_str[MAX_LONG];
+    char ext_lat_str[20];   // Extended precision for base91 compression
+    char ext_lon_str[20];   // Extended precision for base91 compression
+    char comment[43+1];                 // max 43 characters of comment
+    char time[7+1];
+    struct tm *day_time;
+    time_t sec;
+    char complete_area_color[3];
+    int complete_area_type;
+    int lat_offset, lon_offset;
+    char complete_corridor[6];
+    char altitude[10];
+    char speed_course[8];
+    int speed;
+    int course;
+    int temp;
+    long temp2;
+    float temp3;
+    char signpost[6];
+    char prob_min[20+1];
+    char prob_max[20+1];
+    int bearing;
+    char *temp_ptr;
+    char *temp_ptr2;
+    int DR = 0; // Dead-reckoning flag
+    int comment_field_used = 0;   // Amount of comment field used up
+
+
+    //fprintf(stderr,"Setup_object_data\n");
+
+    // If speed for the original object was non-zero, then we need
+    // to snag the updated DR'ed position for the object.  Snag the
+    // current DR position and build the strings we need // for
+    // position transmit.
+    //
+    if (p_station != NULL) { 
+
+        speed = atoi(p_station->speed);
+
+        if (speed > 0 && !doing_move_operation) {
+
+            fetch_current_DR_strings(p_station,
+                lat_str,
+                lon_str,
+                ext_lat_str,
+                ext_lon_str);
+            DR++;   // Set the dead-reckoning flag
+        }
+
+        // Keep the time current for our own objects.
+        p_station->sec_heard = sec_now();
+        move_station_time(p_station,NULL);
+    }
+
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(line,
+        line_length,
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(line);
+    //(void)to_upper(line);      Not per spec.  Don't use this.
+    if (!valid_object(line))
+        return(0);
+
+    // Copy object name into "last_object"
+    xastir_snprintf(last_object,
+        sizeof(last_object),
+        "%s",
+        line);
+
+
+    if (!DR) {  // We're not doing dead-reckoning, so proceed
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_ns);
+        if((char)toupper((int)temp_ptr[0]) == 'S')
+            line[0] = 'S';
+        else
+            line[0] = 'N';
+        XtFree(temp_ptr);
+
+        // Check latitude for out-of-bounds
+        temp_ptr = XmTextFieldGetString(object_lat_data_deg);
+        temp = atoi(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp > 90) || (temp < 0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_min);
+        temp3 = atof(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp3 >= 60.0) || (temp3 < 0.0) )
+            return(0);
+        if ( (temp == 90) && (temp3 != 0.0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lat_data_min);
+        xastir_snprintf(lat_str, sizeof(lat_str), "%02d%05.2f%c",
+            atoi(temp_ptr),
+// An attempt was made to round here, adding 0.001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//            atof(temp_ptr2) + 0.001,
+            atof(temp_ptr2),
+            line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lat_data_min);
+        xastir_snprintf(ext_lat_str, sizeof(ext_lat_str), "%02d%05.3f%c",
+            atoi(temp_ptr),
+// An attempt was made to round here, adding 0.0001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//            atof(temp_ptr2) + 0.0001,
+            atof(temp_ptr2),
+            line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_ew);
+        xastir_snprintf(line,
+            line_length,
+            "%s",
+            temp_ptr);
+        XtFree(temp_ptr);
+
+        if((char)toupper((int)line[0]) == 'E')
+            line[0] = 'E';
+        else
+            line[0] = 'W';
+
+        // Check longitude for out-of-bounds
+        temp_ptr = XmTextFieldGetString(object_lon_data_deg);
+        temp = atoi(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp > 180) || (temp < 0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_min);
+        temp3 = atof(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp3 >= 60.0) || (temp3 < 0.0) )
+            return(0);
+
+        if ( (temp == 180) && (temp3 != 0.0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lon_data_min);
+        xastir_snprintf(lon_str, sizeof(lon_str), "%03d%05.2f%c",
+            atoi(temp_ptr),
+// An attempt was made to round here, adding 0.001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//            atof(temp_ptr2) + 0.001,
+            atof(temp_ptr2),
+            line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lon_data_min);
+        xastir_snprintf(ext_lon_str, sizeof(ext_lon_str), "%03d%05.3f%c",
+            atoi(temp_ptr),
+// An attempt was made to round here, adding 0.0001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//            atof(temp_ptr2) + 0.0001,
+            atof(temp_ptr2),
+            line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+    }
+
+
+    temp_ptr = XmTextFieldGetString(object_group_data);
+    xastir_snprintf(line,
+        line_length,
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    last_obj_grp = line[0];
+    if(isalpha((int)last_obj_grp))
+        last_obj_grp = toupper((int)line[0]);          // todo: toupper in dialog
+
+    // Check for overlay character
+    if (last_obj_grp != '/' && last_obj_grp != '\\') {
+        // Found an overlay character.  Check that it's within the
+        // proper range
+        if ( (last_obj_grp >= '0' && last_obj_grp <= '9')
+                || (last_obj_grp >= 'A' && last_obj_grp <= 'Z') ) {
+            last_obj_overlay = last_obj_grp;
+            last_obj_grp = '\\';
+        }
+        else {
+            last_obj_overlay = '\0';
+        }
+    }
+    else {
+        last_obj_overlay = '\0';
+    }
+
+    temp_ptr = XmTextFieldGetString(object_symbol_data);
+    xastir_snprintf(line,
+        line_length,
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    last_obj_sym = line[0];
+
+    temp_ptr = XmTextFieldGetString(object_comment_data);
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(comment);
+    //fprintf(stderr,"Comment Field was: %s\n",comment);
+
+    sec = sec_now();
+    day_time = gmtime(&sec);
+    xastir_snprintf(time, sizeof(time), "%02d%02d%02dz", day_time->tm_mday, day_time->tm_hour,
+            day_time->tm_min);
+
+    // Handle Generic Options
+
+    // Speed/Course Fields
+    temp_ptr = XmTextFieldGetString(ob_course_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    xastir_snprintf(speed_course, sizeof(speed_course), "%s", ".../");
+    course = 0;
+    if (strlen(line) != 0) {    // Course was entered
+        // Need to check for 1 to three digits only, and 001-360 degrees)
+        temp = atoi(line);
+        if ( (temp >= 1) && (temp <= 360) ) {
+            xastir_snprintf(speed_course, sizeof(speed_course), "%03d/", temp);
+            course = temp;
+        } else if (temp == 0) {   // Spec says 001 to 360 degrees...
+            xastir_snprintf(speed_course, sizeof(speed_course), "%s", "360/");
+        }
+    }
+    temp_ptr = XmTextFieldGetString(ob_speed_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    speed = 0;
+    if (strlen(line) != 0) { // Speed was entered (we only handle knots currently)
+        // Need to check for 1 to three digits, no alpha characters
+        temp = atoi(line);
+        if ( (temp >= 0) && (temp <= 999) ) {
+            xastir_snprintf(line, line_length, "%03d", temp);
+            strncat(speed_course,
+                line,
+                sizeof(speed_course) - 1 - strlen(speed_course));
+            speed = temp;
+        }
+        else {
+            strncat(speed_course,
+                "...",
+                sizeof(speed_course) - 1 - strlen(speed_course));
+        }
+    }
+    else {  // No speed entered, blank it out
+        strncat(speed_course,
+            "...",
+            sizeof(speed_course) - 1 - strlen(speed_course));
+    }
+    if ( (speed_course[0] == '.') && (speed_course[4] == '.') ) {
+        speed_course[0] = '\0'; // No speed or course entered, so blank it
+    }
+    if (Area_object_enabled) {
+        speed_course[0] = '\0'; // Course/Speed not allowed if Area Object
+    }
+
+    // Altitude Field
+    temp_ptr = XmTextFieldGetString(ob_altitude_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    //fprintf(stderr,"Altitude entered: %s\n", line);
+    altitude[0] = '\0'; // Start with empty string
+    if (strlen(line) != 0) {   // Altitude was entered (we only handle feet currently)
+        // Need to check for all digits, and 1 to 6 digits
+        if (isdigit((int)line[0])) {
+            temp2 = atoi(line);
+            if ( (temp2 >= 0) && (temp2 <= 999999) ) {
+                xastir_snprintf(altitude, sizeof(altitude), "/A=%06ld", temp2);
+                //fprintf(stderr,"Altitude string: %s\n",altitude);
+            }
+        }
+    }
+
+    // Handle Specific Options
+
+    // Area Objects
+    if (Area_object_enabled) {
+        //fprintf(stderr,"Area_bright: %d\n", Area_bright);
+        //fprintf(stderr,"Area_filled: %d\n", Area_filled);
+       if (Area_bright) {  // Bright color
+            xastir_snprintf(complete_area_color, sizeof(complete_area_color), "%2s", Area_color);
+        } else {              // Dim color
+            xastir_snprintf(complete_area_color, sizeof(complete_area_color), "%02d",
+                    atoi(&Area_color[1]) + 8);
+
+            if ( (Area_color[1] == '0') || (Area_color[1] == '1') ) {
+                complete_area_color[0] = '/';
+            }
+        }
+        if ( (Area_filled) && (Area_type != 1) && (Area_type != 6) ) {
+            complete_area_type = Area_type + 5;
+        } else {  // Can't fill in a line
+            complete_area_type = Area_type;
+        }
+        temp_ptr = XmTextFieldGetString(ob_lat_offset_data);
+        xastir_snprintf(line, line_length, "%s", temp_ptr);
+        XtFree(temp_ptr);
+
+        lat_offset = (int)sqrt(atof(line));
+        if (lat_offset > 99)
+            lat_offset = 99;
+        //fprintf(stderr,"Line: %s\tlat_offset: %d\n", line, lat_offset);
+
+        temp_ptr = XmTextFieldGetString(ob_lon_offset_data);
+        xastir_snprintf(line, line_length, "%s", temp_ptr);
+        XtFree(temp_ptr);
+
+        lon_offset = (int)sqrt(atof(line));
+        if (lon_offset > 99)
+            lon_offset = 99;
+        //fprintf(stderr,"Line: %s\tlon_offset: %d\n", line, lon_offset);
+
+        //fprintf(stderr,"Corridor Field: %s\n", XmTextFieldGetString(ob_corridor_data) );
+        // Corridor
+        complete_corridor[0] = '\0';
+        if ( (Area_type == 1) || (Area_type == 6) ) {
+
+            temp_ptr = XmTextFieldGetString(ob_corridor_data);
+            xastir_snprintf(line, line_length, "%s", temp_ptr);
+            XtFree(temp_ptr);
+
+            if (strlen(line) != 0) {    // We have a line and some corridor data
+                // Need to check for 1 to three digits only
+                temp = atoi(line);
+                if ( (temp > 0) && (temp <= 999) ) {
+                    xastir_snprintf(complete_corridor, sizeof(complete_corridor), "{%d}", temp);
+                    //fprintf(stderr,"%s\n",complete_corridor);
+                }
+            }
+        }
+
+        //fprintf(stderr,"Complete_corridor: %s\n", complete_corridor);
+
+        if (transmit_compressed_objects_items) {
+            char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+            // Need to handle the conversion of numeric overlay
+            // chars to "a-j" here.
+            if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                temp_overlay = last_obj_overlay + 'a';
+            }
+ 
+            xastir_snprintf(line, line_length, ";%-9s*%s%s%1d%02d%2s%02d%s%s%s",
+                last_object,
+                time,
+                compress_posit(ext_lat_str,
+                    (temp_overlay) ? temp_overlay : last_obj_grp,
+                    ext_lon_str,
+                    last_obj_sym,
+                    course,
+                    speed,  // In knots
+                    ""),    // PHG, must be blank in this case
+                complete_area_type, // In comment field
+                lat_offset,         // In comment field
+                complete_area_color,// In comment field
+                lon_offset,         // In comment field
+                speed_course,       // In comment field
+                complete_corridor,  // In comment field
+                altitude);          // In comment field
+
+            comment_field_used = strlen(line) - 31;
+
+        }
+        else {
+ 
+            xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%1d%02d%2s%02d%s%s%s",
+                last_object,
+                time,
+                lat_str,
+                last_obj_grp,
+                lon_str,
+                last_obj_sym,
+                complete_area_type, // In comment field
+                lat_offset,         // In comment field
+                complete_area_color,// In comment field
+                lon_offset,         // In comment field
+                speed_course,       // In comment field
+                complete_corridor,  // In comment field
+                altitude);          // In comment field
+
+            comment_field_used = strlen(line) - 37;
+        }
+
+        //fprintf(stderr,"String is: %s\n", line);
+
+    } else if (Signpost_object_enabled) {
+        temp_ptr = XmTextFieldGetString(signpost_data);
+        xastir_snprintf(line, line_length, "%s", temp_ptr);
+        XtFree(temp_ptr);
+
+        //fprintf(stderr,"Signpost entered: %s\n", line);
+        if (strlen(line) != 0) {   // Signpost data was entered
+            // Need to check for between one and three characters
+            temp = strlen(line);
+            if ( (temp >= 0) && (temp <= 3) ) {
+                xastir_snprintf(signpost, sizeof(signpost), "{%s}", line);
+            } else {
+                signpost[0] = '\0';
+            }
+        } else {  // No signpost data entered, blank it out
+            signpost[0] = '\0';
+        }
+
+
+        if (transmit_compressed_objects_items) {
+            char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+            // Need to handle the conversion of numeric overlay
+            // chars to "a-j" here.
+            if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                temp_overlay = last_obj_overlay + 'a';
+            }
+ 
+            xastir_snprintf(line, line_length, ";%-9s*%s%s%s%s",
+                last_object,
+                time,
+                compress_posit(ext_lat_str,
+                    (temp_overlay) ? temp_overlay : last_obj_grp,
+                    ext_lon_str,
+                    last_obj_sym,
+                    course,
+                    speed,  // In knots
+                    ""),    // PHG, must be blank in this case
+                altitude,
+                signpost);
+
+            comment_field_used = strlen(line) - 31;
+
+        }
+        else {
+ 
+            xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%s%s%s",
+                last_object,
+                time,
+                lat_str,
+                last_obj_grp,
+                lon_str,
+                last_obj_sym,
+                speed_course,
+                altitude,
+                signpost);
+
+            comment_field_used = strlen(line) - 37;
+        }
+
+    } else if (DF_object_enabled) {   // A DF'ing object of some type
+        if (Omni_antenna_enabled) {
+
+            if (transmit_compressed_objects_items) {
+                char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+                // Need to handle the conversion of numeric overlay
+                // chars to "a-j" here.
+                if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                    temp_overlay = last_obj_overlay + 'a';
+                }
+ 
+                xastir_snprintf(line, line_length, ";%-9s*%s%sDFS%s/%s%s",
+                    last_object,
+                    time,
+                    compress_posit(ext_lat_str,
+                        (temp_overlay) ? temp_overlay : last_obj_grp,
+                        ext_lon_str,
+                        last_obj_sym,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank in this case
+                    object_shgd,
+                    speed_course,
+                    altitude);
+
+                comment_field_used = strlen(line) - 31;
+
+            }
+            else {
+ 
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%cDFS%s/%s%s",
+                    last_object,
+                    time,
+                    lat_str,
+                    last_obj_grp,
+                    lon_str,
+                    last_obj_sym,
+                    object_shgd,
+                    speed_course,
+                    altitude);
+
+                comment_field_used = strlen(line) - 37;
+            }
+
+        } else {  // Beam Heading DFS object
+            if (strlen(speed_course) != 7)
+                xastir_snprintf(speed_course,
+                    sizeof(speed_course),
+                    "000/000");
+
+            temp_ptr = XmTextFieldGetString(ob_bearing_data);
+            bearing = atoi(temp_ptr);
+            XtFree(temp_ptr);
+
+            if ( (bearing < 1) || (bearing > 360) )
+                bearing = 360;
+
+            if (transmit_compressed_objects_items) {
+                char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+                // Need to handle the conversion of numeric overlay
+                // chars to "a-j" here.
+                if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                    temp_overlay = last_obj_overlay + 'a';
+                }
+ 
+                xastir_snprintf(line, line_length, ";%-9s*%s%s/%03i/%s%s",
+                    last_object,
+                    time,
+                    compress_posit(ext_lat_str,
+                        (temp_overlay) ? temp_overlay : last_obj_grp,
+                        ext_lon_str,
+                        last_obj_sym,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank in this case
+                    bearing,
+                    object_NRQ,
+                    altitude);
+
+                comment_field_used = strlen(line) - 31;
+
+            }
+            else {
+ 
+ 
+                xastir_snprintf(line, line_length, ";%-9s*%s%s%c%s%c%s/%03i/%s%s",
+                    last_object,
+                    time,
+                    lat_str,
+                    last_obj_grp,
+                    lon_str,
+                    last_obj_sym,
+                    speed_course,
+                    bearing,
+                    object_NRQ,
+                    altitude);
+
+                comment_field_used = strlen(line) - 37;
+            }
+
+        }
+    } else {  // Else it's a normal object
+
+        prob_min[0] = '\0';
+        prob_max[0] = '\0';
+
+        if (Probability_circles_enabled) {
+
+            temp_ptr = XmTextFieldGetString(probability_data_min);
+            xastir_snprintf(line, line_length, "%s", temp_ptr);
+            XtFree(temp_ptr);
+
+            //fprintf(stderr,"Probability min circle entered: %s\n", line);
+            if (strlen(line) != 0) {   // Probability circle data was entered
+                xastir_snprintf(prob_min, sizeof(prob_min), "Pmin%s,", line);
+            }
+
+            temp_ptr = XmTextFieldGetString(probability_data_max);
+            xastir_snprintf(line, line_length, "%s", temp_ptr);
+            XtFree(temp_ptr);
+
+            //fprintf(stderr,"Probability max circle entered: %s\n", line);
+            if (strlen(line) != 0) {   // Probability circle data was entered
+                xastir_snprintf(prob_max, sizeof(prob_max), "Pmax%s,", line);
+            }
+        }
+
+        if (transmit_compressed_objects_items) {
+            char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+            // Need to handle the conversion of numeric overlay
+            // chars to "a-j" here.
+            if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                temp_overlay = last_obj_overlay + 'a';
+            }
+ 
+            xastir_snprintf(line,
+                line_length,
+                ";%-9s*%s%s%s%s%s",
+                last_object,
+                time,
+                compress_posit(ext_lat_str,
+                    (temp_overlay) ? temp_overlay : last_obj_grp,
+                    ext_lon_str,
+                    last_obj_sym,
+                    course,
+                    speed,  // In knots
+                    ""),    // PHG, must be blank in this case
+                altitude,
+                prob_min,
+                prob_max);
+
+            comment_field_used = strlen(line) - 31;
+
+        }
+        else {
+            xastir_snprintf(line,
+                line_length,
+                ";%-9s*%s%s%c%s%c%s%s%s%s",
+                last_object,
+                time,
+                lat_str,
+                last_obj_overlay ? last_obj_overlay : last_obj_grp,
+                lon_str,
+                last_obj_sym,
+                speed_course,
+                altitude,
+                prob_min,
+                prob_max);
+
+            comment_field_used = strlen(line) - 37;
+
+        }
+    }
+
+
+    // We need to tack the comment on the end, but need to make
+    // sure we don't go over the maximum length for an object.  The
+    // maximum comment field is 43 chars.  "comment_field_used"
+    // tells us how many chars of that field we've used up already
+    // with other parameters before adding the comment chars to the
+    // end.
+    //
+    //fprintf(stderr,"Comment: %s\n",comment);
+    if (strlen(comment) != 0) {
+
+        if (comment[0] == '}') {
+            // May be a multipoint polygon string at the start of
+            // the comment field.  Add a space before this special
+            // character as multipoints have to start with " }" to
+            // be valid.
+            line[strlen(line) + 1] = '\0';
+            line[strlen(line)] = ' ';
+
+            comment_field_used++;
+        }
+
+        temp = 0;
+//        while ( (strlen(line) < 80) && (temp < (int)strlen(comment)) ) {
+        while ((comment_field_used < 43) && (temp < (int)strlen(comment)) ) {
+            //fprintf(stderr,"temp: %d->%d\t%c\n", temp, strlen(line), comment[temp]);
+            line[strlen(line) + 1] = '\0';
+            line[strlen(line)] = comment[temp++];
+            comment_field_used++;
+        }
+    }
+    //fprintf(stderr,"line: %s\n",line);
+
+// NOTE:  Compressed mode will be shorter still.  Account
+// for that when compressed mode is implemented for objects.
+
+    return(1);
+}
+
+
+
+
+
+// Convert this eventually to populate a DataRow struct, then call
+// data.c:Create_object_item_tx_string().  Right now we have a lot
+// of code duplication between Setup_object_data, Setup_item_data,
+// and Create_object_item_tx_string.
+//
+// Make sure to look at the "transmit_compressed_objects_items" variable
+// to decide whether to send a compressed packet.
+/*
+ *  Setup APRS Information Field for Items
+ */
+int Setup_item_data(char *line, int line_length, DataRow *p_station) {
+    char lat_str[MAX_LAT];
+    char lon_str[MAX_LONG];
+    char ext_lat_str[20];   // Extended precision for base91 compression
+    char ext_lon_str[20];   // Extended precision for base91 compression
+    char comment[43+1];                 // max 43 characters of comment
+    char complete_area_color[3];
+    int complete_area_type;
+    int lat_offset, lon_offset;
+    char complete_corridor[6];
+    char altitude[10];
+    char speed_course[8];
+    int speed;
+    int course;
+    int temp;
+    long temp2;
+    float temp3;
+    char tempstr[MAX_CALLSIGN+1];
+    char signpost[6];
+    char prob_min[20+1];
+    char prob_max[20+1];
+    int bearing;
+    char *temp_ptr;
+    char *temp_ptr2;
+    int DR = 0; // Dead-reckoning flag
+    int comment_field_used = 0;   // Amount of comment field used up
+
+
+    // If speed for the original object was non-zero, then we need
+    // to snag the updated DR'ed position for the object.  Snag the
+    // current DR position and build the strings we need // for
+    // position transmit.
+    //
+    if (p_station != NULL) {
+
+        speed = atoi(p_station->speed);
+    
+        if (speed > 0 && !doing_move_operation) {
+
+            fetch_current_DR_strings(p_station,
+                lat_str,
+                lon_str,
+                ext_lat_str,
+                ext_lon_str);
+            DR++;   // Set the dead-reckoning flag
+        }
+
+        // Keep the time current for our own items.
+        p_station->sec_heard = sec_now();
+        move_station_time(p_station,NULL);
+    }
+
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(line);
+    //(void)to_upper(line);     Not per spec.  Don't use this.
+
+    xastir_snprintf(tempstr,
+        sizeof(tempstr),
+        "%s",
+        line);
+
+    if (strlen(line) == 1)  // Add two spaces (to make 3 minimum chars)
+        xastir_snprintf(line, line_length, "%s  ", tempstr);
+
+    else if (strlen(line) == 2) // Add one space (to make 3 minimum chars)
+        xastir_snprintf(line, line_length, "%s ", tempstr);
+
+    if (!valid_item(line))
+        return(0);
+
+    xastir_snprintf(last_object,
+        sizeof(last_object),
+        "%s",
+        line);
+
+
+    if (!DR) {  // We're not doing dead-reckoning, so proceed
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_ns);
+        if((char)toupper((int)temp_ptr[0]) == 'S')
+            line[0] = 'S';
+        else
+            line[0] = 'N';
+        XtFree(temp_ptr);
+
+        // Check latitude for out-of-bounds
+        temp_ptr = XmTextFieldGetString(object_lat_data_deg);
+        temp = atoi(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp > 90) || (temp < 0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_min);
+        temp3 = atof(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp3 >= 60.0) || (temp3 < 0.0) )
+            return(0);
+
+        if ( (temp == 90) && (temp3 != 0.0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lat_data_min);
+        xastir_snprintf(lat_str, sizeof(lat_str), "%02d%05.2f%c",
+                atoi(temp_ptr),
+// An attempt was made to round here, adding 0.001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//                atof(temp_ptr2) + 0.001,
+                atof(temp_ptr2),
+                line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+
+        temp_ptr = XmTextFieldGetString(object_lat_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lat_data_min);
+        xastir_snprintf(ext_lat_str, sizeof(ext_lat_str), "%02d%05.3f%c",
+                atoi(temp_ptr),
+// An attempt was made to round here, adding 0.0001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//                atof(temp_ptr2) + 0.0001,
+                atof(temp_ptr2),
+                line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_ew);
+        if((char)toupper((int)temp_ptr[0]) == 'E')
+            line[0] = 'E';
+        else
+            line[0] = 'W';
+        XtFree(temp_ptr);
+
+        // Check longitude for out-of-bounds
+        temp_ptr = XmTextFieldGetString(object_lon_data_deg);
+        temp = atoi(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp > 180) || (temp < 0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_min);
+        temp3 = atof(temp_ptr);
+        XtFree(temp_ptr);
+
+        if ( (temp3 >= 60.0) || (temp3 < 0.0) )
+            return(0);
+
+        if ( (temp == 180) && (temp3 != 0.0) )
+            return(0);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lon_data_min);
+        xastir_snprintf(lon_str, sizeof(lon_str), "%03d%05.2f%c",
+                atoi(temp_ptr),
+// An attempt was made to round here, adding 0.001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//                atof(temp_ptr2) + 0.001,
+                atof(temp_ptr2),
+                line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+
+        temp_ptr = XmTextFieldGetString(object_lon_data_deg);
+        temp_ptr2 = XmTextFieldGetString(object_lon_data_min);
+        xastir_snprintf(ext_lon_str, sizeof(ext_lon_str), "%03d%05.3f%c",
+                atoi(temp_ptr),
+// An attempt was made to round here, adding 0.0001 to the minutes
+// value.  Problems arise if it goes above 59 minutes as the degrees
+// value would need to bump up also.  This then gets into problems
+// at 90.0 degrees.  The correct method would be to convert it to
+// decimal at a higher precision and then convert it back to DD
+// MM.MM format.
+//                atof(temp_ptr2) + 0.0001,
+                atof(temp_ptr2),
+                line[0]);
+        XtFree(temp_ptr);
+        XtFree(temp_ptr2);
+    }
+
+
+    temp_ptr = XmTextFieldGetString(object_group_data);
+    last_obj_grp = temp_ptr[0];
+    if(isalpha((int)last_obj_grp))
+        last_obj_grp = toupper((int)temp_ptr[0]);          // todo: toupper in dialog
+    XtFree(temp_ptr);
+
+    // Check for overlay character
+    if (last_obj_grp != '/' && last_obj_grp != '\\') {
+        // Found an overlay character.  Check that it's within the
+        // proper range
+        if ( (last_obj_grp >= '0' && last_obj_grp <= '9')
+                || (last_obj_grp >= 'A' && last_obj_grp <= 'Z') ) {
+            last_obj_overlay = last_obj_grp;
+            last_obj_grp = '\\';
+        }
+        else {
+            last_obj_overlay = '\0';
+        }
+    }
+    else {
+        last_obj_overlay = '\0';
+    }
+
+    temp_ptr = XmTextFieldGetString(object_symbol_data);
+    last_obj_sym = temp_ptr[0];
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(object_comment_data);
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(comment);
+
+    // Handle Generic Options
+
+    // Speed/Course Fields
+    temp_ptr = XmTextFieldGetString(ob_course_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    sprintf(speed_course,".../");   // Start with invalid-data string
+    course = 0;
+    if (strlen(line) != 0) {    // Course was entered
+        // Need to check for 1 to three digits only, and 001-360 degrees)
+        temp = atoi(line);
+        if ( (temp >= 1) && (temp <= 360) ) {
+            xastir_snprintf(speed_course, sizeof(speed_course), "%03d/", temp);
+            course = temp;
+        } else if (temp == 0) {   // Spec says 001 to 360 degrees...
+            sprintf(speed_course, "360/");
+        }
+    }
+    temp_ptr = XmTextFieldGetString(ob_speed_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    speed = 0;
+    if (strlen(line) != 0) { // Speed was entered (we only handle knots currently)
+        // Need to check for 1 to three digits, no alpha characters
+        temp = atoi(line);
+        if ( (temp >= 0) && (temp <= 999) ) {
+            xastir_snprintf(line, line_length, "%03d", temp);
+            strncat(speed_course,
+                line,
+                sizeof(speed_course) - 1 - strlen(speed_course));
+            speed = temp;
+        } else {
+            strncat(speed_course,
+                "...",
+                sizeof(speed_course) - 1 - strlen(speed_course));
+        }
+    } else {  // No speed entered, blank it out
+        strncat(speed_course,
+            "...",
+            sizeof(speed_course) - 1 - strlen(speed_course));
+    }
+    if ( (speed_course[0] == '.') && (speed_course[4] == '.') ) {
+        speed_course[0] = '\0'; // No speed or course entered, so blank it
+    }
+
+    if (Area_object_enabled) {
+        speed_course[0] = '\0'; // Course/Speed not allowed if Area Object
+    }
+
+    // Altitude Field
+    temp_ptr = XmTextFieldGetString(ob_altitude_data);
+    xastir_snprintf(line, line_length, "%s", temp_ptr);
+    XtFree(temp_ptr);
+
+    //fprintf(stderr,"Altitude entered: %s\n", line);
+    altitude[0] = '\0'; // Start with empty string
+    if (strlen(line) != 0) {   // Altitude was entered (we only handle feet currently)
+        // Need to check for all digits, and 1 to 6 digits
+        if (isdigit((int)line[0])) {
+            temp2 = atoi(line);
+            if ((temp2 >= 0) && (temp2 <= 999999)) {
+                xastir_snprintf(altitude, sizeof(altitude), "/A=%06ld",temp2);
+            }
+        }
+    }
+
+    // Handle Specific Options
+
+    // Area Items
+    if (Area_object_enabled) {
+        if (Area_bright) {  // Bright color
+            xastir_snprintf(complete_area_color, sizeof(complete_area_color), "%2s",
+                    Area_color);
+        } else {              // Dim color
+            xastir_snprintf(complete_area_color, sizeof(complete_area_color), "%02d",
+                    atoi(&Area_color[1]) + 8);
+            if ((Area_color[1] == '0') || (Area_color[1] == '1')) {
+                complete_area_color[0] = '/';
+            }
+        }
+        if ( (Area_filled) && (Area_type != 1) && (Area_type != 6) ) {
+            complete_area_type = Area_type + 5;
+        } else {  // Can't fill in a line
+            complete_area_type = Area_type;
+        }
+        temp_ptr = XmTextFieldGetString(ob_lat_offset_data);
+        xastir_snprintf(line, line_length, "%s", temp_ptr);
+        XtFree(temp_ptr);
+
+        lat_offset = (int)sqrt(atof(line));
+        if (lat_offset > 99)
+            lat_offset = 99;
+        //fprintf(stderr,"Line: %s\tlat_offset: %d\n", line, lat_offset);
+        temp_ptr = XmTextFieldGetString(ob_lon_offset_data);
+        xastir_snprintf(line, line_length, "%s", temp_ptr);
+        XtFree(temp_ptr);
+
+        lon_offset = (int)sqrt(atof(line));
+        if (lon_offset > 99)
+            lon_offset = 99;
+        //fprintf(stderr,"Line: %s\tlon_offset: %d\n", line, lon_offset);
+
+        // Corridor
+        complete_corridor[0] = '\0';
+        if ( (Area_type == 1) || (Area_type == 6) ) {
+
+            temp_ptr = XmTextFieldGetString(ob_corridor_data);
+            xastir_snprintf(line, line_length, "%s", temp_ptr);
+            XtFree(temp_ptr);
+
+            if (strlen(line) != 0) {    // We have a line and some corridor data
+                // Need to check for 1 to three digits only
+                temp = atoi(line);
+                if ( (temp > 0) && (temp <= 999) ) {
+                    xastir_snprintf(complete_corridor, sizeof(complete_corridor), "{%d}", temp);
+                    //fprintf(stderr,"%s\n",complete_corridor);
+                }
+            }
+        }
+
+        if (transmit_compressed_objects_items) {
+            char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+            // Need to handle the conversion of numeric overlay
+            // chars to "a-j" here.
+            if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                temp_overlay = last_obj_overlay + 'a';
+            }
+ 
+            xastir_snprintf(line, line_length, ")%s!%s%1d%02d%2s%02d%s%s%s",
+                last_object,
+                compress_posit(ext_lat_str,
+                    (temp_overlay) ? temp_overlay : last_obj_grp,
+                    ext_lon_str,
+                    last_obj_sym,
+                    course,
+                    speed,  // In knots
+                    ""),    // PHG, must be blank in this case
+                complete_area_type,
+                lat_offset,
+                complete_area_color,
+                lon_offset,
+                speed_course,
+                complete_corridor,
+                altitude);
+
+            comment_field_used = strlen(line) - 15 - strlen(last_object);
+
+        }
+        else {
+ 
+            xastir_snprintf(line, line_length, ")%s!%s%c%s%c%1d%02d%2s%02d%s%s%s",
+                last_object,
+                lat_str,
+                last_obj_grp,
+                lon_str,
+                last_obj_sym,
+                complete_area_type,
+                lat_offset,
+                complete_area_color,
+                lon_offset,
+                speed_course,
+                complete_corridor,
+                altitude);
+
+            comment_field_used = strlen(line) - 21 - strlen(last_object);
+        }
+
+    } else if (Signpost_object_enabled) {
+        temp_ptr = XmTextFieldGetString(signpost_data);
+        xastir_snprintf(line, line_length, "%s", temp_ptr);
+        XtFree(temp_ptr);
+
+        //fprintf(stderr,"Signpost entered: %s\n", line);
+        if (strlen(line) != 0) {   // Signpost data was entered
+            // Need to check for between one and three characters
+            temp = strlen(line);
+            if ( (temp >= 0) && (temp <= 3) ) {
+                xastir_snprintf(signpost, sizeof(signpost), "{%s}", line);
+            } else {
+                signpost[0] = '\0';
+            }
+        } else {  // No signpost data entered, blank it out
+            signpost[0] = '\0';
+        }
+
+        if (transmit_compressed_objects_items) {
+            char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+            // Need to handle the conversion of numeric overlay
+            // chars to "a-j" here.
+            if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                temp_overlay = last_obj_overlay + 'a';
+            }
+ 
+            xastir_snprintf(line, line_length, ")%s!%s%s%s",
+                last_object,
+                compress_posit(ext_lat_str,
+                    (temp_overlay) ? temp_overlay : last_obj_grp,
+                    ext_lon_str,
+                    last_obj_sym,
+                    course,
+                    speed,  // In knots
+                    ""),    // PHG, must be blank in this case
+                altitude,
+                signpost);
+
+            comment_field_used = strlen(line) - 15 - strlen(last_object);
+
+        }
+        else {
+ 
+            xastir_snprintf(line, line_length, ")%s!%s%c%s%c%s%s%s",
+                last_object,
+                lat_str,
+                last_obj_grp,
+                lon_str,
+                last_obj_sym,
+                speed_course,
+                altitude,
+                signpost);
+
+            comment_field_used = strlen(line) - 21 - strlen(last_object);
+        }
+
+    } else if (DF_object_enabled) {   // A DF'ing item of some type
+        if (Omni_antenna_enabled) {
+
+            if (transmit_compressed_objects_items) {
+                char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+                // Need to handle the conversion of numeric overlay
+                // chars to "a-j" here.
+                if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                    temp_overlay = last_obj_overlay + 'a';
+                }
+ 
+                xastir_snprintf(line, line_length, ")%s!%sDFS%s/%s%s",
+                    last_object,
+                    compress_posit(ext_lat_str,
+                        (temp_overlay) ? temp_overlay : last_obj_grp,
+                        ext_lon_str,
+                        last_obj_sym,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank in this case
+                    object_shgd,
+                    speed_course,
+                    altitude);
+
+                comment_field_used = strlen(line) - 15 - strlen(last_object);
+
+            }
+            else {
+ 
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%cDFS%s/%s%s",
+                    last_object,
+                    lat_str,
+                    last_obj_grp,
+                    lon_str,
+                    last_obj_sym,
+                    object_shgd,
+                    speed_course,
+                    altitude);
+
+                comment_field_used = strlen(line) - 21 - strlen(last_object);
+
+            }
+
+        } else {  // Beam Heading DFS item
+            if (strlen(speed_course) != 7)
+                xastir_snprintf(speed_course,
+                    sizeof(speed_course),
+                    "000/000");
+
+            temp_ptr = XmTextFieldGetString(ob_bearing_data);
+            bearing = atoi(temp_ptr);
+            XtFree(temp_ptr);
+
+            if ( (bearing < 1) || (bearing > 360) )
+                bearing = 360;
+
+            if (transmit_compressed_objects_items) {
+                char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+                // Need to handle the conversion of numeric overlay
+                // chars to "a-j" here.
+                if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                    temp_overlay = last_obj_overlay + 'a';
+                }
+ 
+                xastir_snprintf(line, line_length, ")%s!%s/%03i/%s%s",
+                    last_object,
+                    compress_posit(ext_lat_str,
+                        (temp_overlay) ? temp_overlay : last_obj_grp,
+                        ext_lon_str,
+                        last_obj_sym,
+                        course,
+                        speed,  // In knots
+                        ""),    // PHG, must be blank in this case
+                    bearing,
+                    object_NRQ,
+                    altitude);
+
+                comment_field_used = strlen(line) - 15 - strlen(last_object);
+
+            }
+            else {
+ 
+                xastir_snprintf(line, line_length, ")%s!%s%c%s%c%s/%03i/%s%s",
+                    last_object,
+                    lat_str,
+                    last_obj_grp,
+                    lon_str,
+                    last_obj_sym,
+                    speed_course,
+                    bearing,
+                    object_NRQ,
+                    altitude);
+
+                comment_field_used = strlen(line) - 21 - strlen(last_object);
+            }
+
+        }
+    } else {  // Else it's a normal item
+
+        prob_min[0] = '\0';
+        prob_max[0] = '\0';
+ 
+        if (Probability_circles_enabled) {
+
+            temp_ptr = XmTextFieldGetString(probability_data_min);
+            xastir_snprintf(line, line_length, "%s", temp_ptr);
+            XtFree(temp_ptr);
+
+            //fprintf(stderr,"Probability min circle entered: %s\n",
+            //line);
+            if (strlen(line) != 0) {   // Probability circle data was entered
+                xastir_snprintf(prob_min, sizeof(prob_min), "Pmin%s,", line);
+            }
+
+            temp_ptr = XmTextFieldGetString(probability_data_max);
+            xastir_snprintf(line, line_length, "%s", temp_ptr);
+            XtFree(temp_ptr);
+
+            //fprintf(stderr,"Probability max circle entered: %s\n",
+            //line);
+            if (strlen(line) != 0) {   // Probability circle data was entered
+                xastir_snprintf(prob_max, sizeof(prob_max), "Pmax%s,", line);
+            }
+        }
+
+
+        if (transmit_compressed_objects_items) {
+            char temp_overlay = last_obj_overlay;
+
+
+// Need to compute "csT" at some point and add it to the object.
+// Until we do that we'll have no course/speed/altitude.  Looks like
+// we can have course/speed or altitude, but not both.  Must have to
+// add the "/A=000123" stuff to the end if we want both.
+//
+// If we have course and/or speed, use course/speed csT bytes.  If
+// no course/speed but we have altitude, use altitude csT bytes.  We
+// can cheat right now and just always use course/speed, adding
+// altitude with the altitude extension.  Not as efficient, but it
+// gets the job done.
+//
+// Later we should change compress_posit() to accept an altitude
+// parameter, and have it decide which csT set of bytes to add, and
+// whether to add altitude as an uncompressed extension if
+// necessary.
+
+
+            // Need to handle the conversion of numeric overlay
+            // chars to "a-j" here.
+            if (last_obj_overlay >= '0' && last_obj_overlay <= '9') {
+                temp_overlay = last_obj_overlay + 'a';
+            }
+ 
+            xastir_snprintf(line,
+                line_length,
+                ")%s!%s%s%s%s",
+                last_object,
+                compress_posit(ext_lat_str,
+                    (temp_overlay) ? temp_overlay : last_obj_grp,
+                    ext_lon_str,
+                    last_obj_sym,
+                    course,
+                    speed,  // In knots
+                    ""),    // PHG, must be blank in this case
+                    altitude,
+                    prob_min,
+                    prob_max);
+
+            comment_field_used = strlen(line) - 15 - strlen(last_object);
+
+        }
+        else {
+            xastir_snprintf(line,
+                line_length,
+                ")%s!%s%c%s%c%s%s%s%s",
+                last_object,
+                lat_str,
+                last_obj_overlay ? last_obj_overlay : last_obj_grp,
+                lon_str,
+                last_obj_sym,
+                speed_course,
+                altitude,
+                prob_min,
+                prob_max);
+
+            comment_field_used = strlen(line) - 21 - strlen(last_object);
+
+        }
+    }
+
+
+    // We need to tack the comment on the end, but need to make
+    // sure we don't go over the maximum length for an item.
+    //fprintf(stderr,"Comment: %s\n",comment);
+    if (strlen(comment) != 0) {
+
+        if (comment[0] == '}') {
+            // May be a multipoint polygon string at the start of
+            // the comment field.  Add a space before this special
+            // character as multipoints have to start with " }" to
+            // be valid.
+            line[strlen(line) + 1] = '\0';
+            line[strlen(line)] = ' ';
+            comment_field_used++;
+        }
+
+        temp = 0;
+//        while ( (strlen(line) < (64 + strlen(last_object))) && (temp < (int)strlen(comment)) ) {
+        while ( (comment_field_used < 43) && (temp < (int)strlen(comment)) ) {
+            //fprintf(stderr,"temp: %d->%d\t%c\n", temp, strlen(line), comment[temp]);
+            line[strlen(line) + 1] = '\0';
+            line[strlen(line)] = comment[temp++];
+            comment_field_used++;
+        }
+    }
+    //fprintf(stderr,"line: %s\n",line);
+
+// NOTE:  Compressed mode will be shorter still.  Account
+// for that when compressed mode is implemented for items.
+
+    return(1);
+}
+
+
+
+
+
+
+/*
+ *  Set an Object
+ */
+void Object_change_data_set(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char line[43+1+40];                 // ???
+    DataRow *p_station = global_parameter1;
+
+    //fprintf(stderr,"Object_change_data_set\n");
+
+    // p_station will be NULL if the object is new.
+    if (Setup_object_data(line, sizeof(line), p_station)) {
+
+        // Update this object in our save file
+        log_object_item(line,0,last_object);
+
+        // Set up the timer properly for the decaying algorithm
+        if (p_station != NULL) {
+            p_station->transmit_time_increment = OBJECT_CHECK_RATE;
+            p_station->last_transmit_time = sec_now();
+
+            // Keep the time current for our own objects.
+            p_station->sec_heard = sec_now();
+            move_station_time(p_station,NULL);
+ 
+//            p_station->last_modified_time = sec_now(); // For dead-reckoning
+//fprintf(stderr,"Object_change_data_set(): Setting transmit increment to %d\n", OBJECT_CHECK_RATE);
+        }
+
+        if (object_tx_disable || transmit_disable)
+            output_my_data(line,-1,0,1,0,NULL);    // Local loopback only, not igating
+        else
+            output_my_data(line,-1,0,0,0,NULL);    // Transmit/loopback object data, not igating
+
+        sched_yield();                  // Wait for transmitted data to get processed
+        Object_destroy_shell(widget,clientData,NULL);
+        // Getting a segfault here on a Move operation, so just
+        // comment it out.  A redraw will occur shortly anyway.
+        //redraw_symbols(da);
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    } else {
+        // error message
+        popup_message_always(langcode("POPEM00022"),langcode("POPEM00027"));
+    }
+}
+
+
+
+
+
+/*
+ *  Set an Item
+ */
+void Item_change_data_set(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char line[43+1+40];                 // ???
+    DataRow *p_station = global_parameter1;
+
+   
+    if (Setup_item_data(line,sizeof(line), p_station)) {
+
+        // Update this item in our save file
+        log_object_item(line,0,last_object);
+ 
+        // Set up the timer properly for the decaying algorithm
+        if (p_station != NULL) {
+            p_station->transmit_time_increment = OBJECT_CHECK_RATE;
+            p_station->last_transmit_time = sec_now();
+
+            // Keep the time current for our own items.
+            p_station->sec_heard = sec_now();
+            move_station_time(p_station,NULL);
+ 
+//            p_station->last_modified_time = sec_now(); // For dead-reckoning
+//fprintf(stderr,"Item_change_data_set(): Setting transmit increment to %d\n", OBJECT_CHECK_RATE);
+        }
+ 
+        if (object_tx_disable || transmit_disable)
+            output_my_data(line,-1,0,1,0,NULL);    // Local loopback only, not igating
+        else
+            output_my_data(line,-1,0,0,0,NULL);    // Transmit/loopback item data, not igating
+
+        sched_yield();                  // Wait for transmitted data to get processed
+        Object_destroy_shell(widget,clientData,NULL);
+        // Getting a segfault here on a Move operation, so just
+        // comment it out.  A redraw will occur shortly anyway.
+        //redraw_symbols(da);
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    } else {
+        // error message
+        popup_message_always(langcode("POPEM00022"),langcode("POPEM00027"));
+    }
+}
+
+
+
+
+
+// Check the name of a new Object.  If it already exists in our
+// database, warn the user.  Confirmation dialog to continue?
+//
+void Object_confirm_data_set(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp_ptr;
+    char line[MAX_CALLSIGN+1];
+    DataRow *p_station;
+ 
+
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(line,
+        sizeof(line),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_leading_spaces(line);
+    (void)remove_trailing_spaces(line);
+
+    //fprintf(stderr,"Object name:%s\n", line);
+
+    // We have the name now.  Check it against our database of
+    // stations/objects/items.  Do an exact match.
+    //
+    if (search_station_name(&p_station,line,1)
+            && (p_station->flag & ST_ACTIVE)) {
+        // Found a live object with that name.  Don't allow Object
+        // creation.  Bring up a warning message instead.
+        popup_message_always(langcode("POPEM00035"), langcode("POPEM00038"));
+    }
+    else {
+
+        // Not found.  Allow the Object to be created.
+        Object_change_data_set(widget, clientData, callData);
+    }
+}
+
+
+
+
+
+// Check the name of a new Item.  If it already exists in our
+// database, warn the user.  Confirmation dialog to continue?
+//
+void Item_confirm_data_set(Widget widget, XtPointer clientData, XtPointer callData) {
+    char *temp_ptr;
+    char line[MAX_CALLSIGN+1];
+    DataRow *p_station;
+ 
+
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(line,
+        sizeof(line),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_leading_spaces(line);
+    (void)remove_trailing_spaces(line);
+
+    //fprintf(stderr,"Item name:%s\n", line);
+
+    // We have the name now.  Check it against our database of
+    // stations/objects/items.  Do an exact match.
+    //
+    if (search_station_name(&p_station,line,1)
+            && (p_station->flag & ST_ACTIVE)) {
+        // Found a live object with that name.  Don't allow Object
+        // creation.  Bring up a warning message instead.
+        popup_message_always(langcode("POPEM00035"), langcode("POPEM00038"));
+    }
+    else {
+
+        // Not found.  Allow the Item to be created.
+        Item_change_data_set(widget, clientData, callData);
+    }
+}
+
+
+
+
+
+/*
+ *  Delete an Object
+ */
+void Object_change_data_del(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char line[43+1+40];                 // ???
+    DataRow *p_station = global_parameter1;
+
+    
+    if (Setup_object_data(line, sizeof(line), p_station)) {
+
+        line[10] = '_';                         // mark as deleted object
+
+        // Update this object in our save file, then comment all
+        // instances out in the file.
+        log_object_item(line,1,last_object);
+
+        // Set up the timer properly for the decaying algorithm
+        if (p_station != NULL) {
+            p_station->transmit_time_increment = OBJECT_CHECK_RATE;
+            p_station->last_transmit_time = sec_now();
+//            p_station->last_modified_time = sec_now(); // For dead-reckoning
+//fprintf(stderr,"Object_change_data_del(): Setting transmit increment to %d\n", OBJECT_CHECK_RATE);
+        }
+
+        if (object_tx_disable || transmit_disable)
+            output_my_data(line,-1,0,1,0,NULL);    // Local loopback only, not igating
+        else
+            output_my_data(line,-1,0,0,0,NULL);    // Transmit object data, not igating
+
+        Object_destroy_shell(widget,clientData,NULL);
+    }
+}
+
+
+
+
+
+/*
+ *  Delete an Item
+ */
+void Item_change_data_del(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char line[43+1+40];                 // ???
+    int i, done;
+    DataRow *p_station = global_parameter1;
+
+    
+    if (Setup_item_data(line,sizeof(line), p_station)) {
+
+        done = 0;
+        i = 0;
+        while ( (!done) && (i < 11) ) {
+            if (line[i] == '!') {
+                line[i] = '_';          // mark as deleted object
+                done++;                 // Exit from loop
+            }
+            i++;
+        }
+
+        // Update this item in our save file, then comment all
+        // instances out in the file.
+        log_object_item(line,1,last_object);
+
+        // Set up the timer properly for the decaying algorithm
+        if (p_station != NULL) {
+            p_station->transmit_time_increment = OBJECT_CHECK_RATE;
+            p_station->last_transmit_time = sec_now();
+//            p_station->last_modified_time = sec_now(); // For dead-reckoning
+//fprintf(stderr,"Item_change_data_del(): Setting transmit increment to %d\n", OBJECT_CHECK_RATE);
+        }
+
+        if (object_tx_disable || transmit_disable)
+            output_my_data(line,-1,0,1,0,NULL);    // Local loopback only, not igating
+        else
+            output_my_data(line,-1,0,0,0,NULL);    // Transmit item data, not igating
+
+        Object_destroy_shell(widget,clientData,NULL);
+    }
+}
+
+
+
+
+
+/*
+ *  Select a symbol graphically
+ */
+void Ob_change_symbol(/*@unused@*/ Widget widget, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    //fprintf(stderr,"Trying to change a symbol\n");
+    symbol_change_requested_from = 2;   // Tell Select_symbol who to return the data to
+    Select_symbol(widget, clientData, callData);
+}
+
+
+
+
+
+/*
+ *  Update symbol picture for changed symbol or table
+ */
+void updateObjectPictureCallback(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    char table, overlay;
+    char symb, group;
+    char *temp_ptr;
+
+
+    XtVaSetValues(object_icon, XmNlabelPixmap, Ob_icon0, NULL);         // clear old icon
+    XtManageChild(object_icon);
+
+    temp_ptr = XmTextFieldGetString(object_group_data);
+    group = temp_ptr[0];
+    XtFree(temp_ptr);
+
+    temp_ptr = XmTextFieldGetString(object_symbol_data);
+    symb  = temp_ptr[0];
+    XtFree(temp_ptr);
+
+    if (group == '/' || group == '\\') {
+        // No overlay character
+        table   = group;
+        overlay = ' ';
+    } else {
+        // Found overlay character.  Check that it's a valid
+        // overlay.
+        if ( (group >= '0' && group <= '9')
+                || (group >= 'A' && group <= 'Z') ) {
+            // Valid overlay character
+            table   = '\\';
+            overlay = group;
+        }
+        else {
+            // Bad overlay character
+            table = '\\';
+            overlay = ' ';
+        }
+    }
+    symbol(object_icon,0,table,symb,overlay,Ob_icon,0,0,0,' ');         // create icon
+
+    XtVaSetValues(object_icon,XmNlabelPixmap,Ob_icon,NULL);             // draw new icon
+    XtManageChild(object_icon);
+}
+
+
+
+
+
+// Handler for "Signpost" toggle button
+void Signpost_object_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    char temp_data[40];
+    char comment[43+1];     // max 43 characters of comment
+    char signpost_name[10];
+    char *temp_ptr;
+
+
+    // Save name and comment fields temporarily
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(signpost_name,
+        sizeof(signpost_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(signpost_name);
+
+    temp_ptr = XmTextFieldGetString(object_comment_data); 
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(comment);
+
+ 
+    if(state->set) {
+        Signpost_object_enabled = 1;
+        Area_object_enabled = 0;
+        DF_object_enabled = 0;
+        Map_View_object_enabled = 0;
+        Probability_circles_enabled = 0;
+
+        //fprintf(stderr,"Signpost Objects are ENABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+        XmToggleButtonSetState(area_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(df_bearing_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(map_view_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(probabilities_toggle, FALSE, FALSE);
+
+        temp_data[0] = '\\';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = 'm';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,FALSE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+   }
+    else {
+        Signpost_object_enabled = 0;
+
+        //fprintf(stderr,"Signpost Objects are DISABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,TRUE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+    }
+
+    // Restore name and comment fields
+    XmTextFieldSetString(object_name_data,signpost_name);
+    XmTextFieldSetString(object_comment_data,comment);
+}
+
+
+
+
+
+// Handler for "Probability Circles" toggle button
+void Probability_circle_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    char temp_data[40];
+    char comment[43+1];     // max 43 characters of comment
+    char signpost_name[10];
+    char *temp_ptr;
+
+
+    // Save name and comment fields temporarily
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(signpost_name,
+        sizeof(signpost_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(signpost_name);
+
+    temp_ptr = XmTextFieldGetString(object_comment_data); 
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(comment);
+
+ 
+    if(state->set) {
+        Signpost_object_enabled = 0;
+        Area_object_enabled = 0;
+        DF_object_enabled = 0;
+        Map_View_object_enabled = 0;
+        Probability_circles_enabled = 1;
+
+        //fprintf(stderr,"Probability Circles are ENABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+        XmToggleButtonSetState(area_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(df_bearing_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(map_view_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(signpost_toggle, FALSE, FALSE);
+
+        // Set to hiker symbol by default, but can be changed by
+        // user to something else.
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '[';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+    }
+    else {
+        Probability_circles_enabled = 0;
+
+        //fprintf(stderr,"Signpost Objects are DISABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,TRUE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+    }
+
+    // Restore name and comment fields
+    XmTextFieldSetString(object_name_data,signpost_name);
+    XmTextFieldSetString(object_comment_data,comment);
+}
+
+
+
+
+
+// Handler for "Enable Area Type" toggle button
+void  Area_object_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    char temp_data[40];
+    char comment[43+1];     // max 43 characters of comment
+    char signpost_name[10];
+    char *temp_ptr;
+
+
+    // Save name and comment fields temporarily
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(signpost_name,
+        sizeof(signpost_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(signpost_name);
+
+    temp_ptr = XmTextFieldGetString(object_comment_data); 
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(comment);
+
+ 
+    if(state->set) {
+        Area_object_enabled = 1;
+        Signpost_object_enabled = 0;
+        DF_object_enabled = 0;
+        Map_View_object_enabled = 0;
+        Probability_circles_enabled = 0;
+
+        //fprintf(stderr,"Area Objects are ENABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        XmToggleButtonSetState(signpost_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(df_bearing_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(map_view_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(probabilities_toggle, FALSE, FALSE);
+
+        XtSetSensitive(ob_speed,FALSE);
+        XtSetSensitive(ob_speed_data,FALSE);
+        XtSetSensitive(ob_course,FALSE);
+        XtSetSensitive(ob_course_data,FALSE);
+
+        temp_data[0] = '\\';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = 'l';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,FALSE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+   }
+    else {
+        Area_object_enabled = 0;
+
+        //fprintf(stderr,"Area Objects are DISABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        XtSetSensitive(ob_speed,TRUE);
+        XtSetSensitive(ob_speed_data,TRUE);
+        XtSetSensitive(ob_course,TRUE);
+        XtSetSensitive(ob_course_data,TRUE);
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,TRUE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+    }
+
+    // Restore name and comment fields
+    XmTextFieldSetString(object_name_data,signpost_name);
+    XmTextFieldSetString(object_comment_data,comment);
+}
+
+
+
+
+
+// Handler for "DF Bearing Object" toggle button
+void  DF_bearing_object_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    char temp_data[40];
+    char comment[43+1];     // max 43 characters of comment
+    char signpost_name[10];
+    char *temp_ptr;
+
+
+    // Save name and comment fields temporarily
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(signpost_name,
+        sizeof(signpost_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(signpost_name);
+
+    temp_ptr = XmTextFieldGetString(object_comment_data); 
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(comment);
+
+ 
+    if(state->set) {
+        Area_object_enabled = 0;
+        Signpost_object_enabled = 0;
+        DF_object_enabled = 1;
+        Map_View_object_enabled = 0;
+        Probability_circles_enabled = 0;
+
+        //fprintf(stderr,"DF Objects are ENABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        XmToggleButtonSetState(signpost_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(area_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(map_view_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(probabilities_toggle, FALSE, FALSE);
+
+        XtSetSensitive(ob_speed,TRUE);
+        XtSetSensitive(ob_speed_data,TRUE);
+        XtSetSensitive(ob_course,TRUE);
+        XtSetSensitive(ob_course_data,TRUE);
+        XtSetSensitive(frameomni,FALSE);
+        XtSetSensitive(framebeam,FALSE);
+        Omni_antenna_enabled = 0;
+        Beam_antenna_enabled = 0;
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '\\';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,FALSE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+   }
+    else {
+        DF_object_enabled = 0;
+
+        //fprintf(stderr,"DF Objects are DISABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,TRUE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+    }
+
+    // Restore name and comment fields
+    XmTextFieldSetString(object_name_data,signpost_name);
+    XmTextFieldSetString(object_comment_data,comment);
+}
+
+
+
+
+
+// Handler for "Map View Object" toggle button
+void  Map_View_object_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+    char temp_data[40];
+    char comment[43+1];     // max 43 characters of comment
+    char signpost_name[10];
+    char *temp_ptr;
+
+
+    // Save name and comment fields temporarily
+    temp_ptr = XmTextFieldGetString(object_name_data);
+    xastir_snprintf(signpost_name,
+        sizeof(signpost_name),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(signpost_name);
+
+    temp_ptr = XmTextFieldGetString(object_comment_data); 
+    xastir_snprintf(comment,
+        sizeof(comment),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+    (void)remove_trailing_spaces(comment);
+
+ 
+    if(state->set) {
+        // Make a bunch of the fields insensitive that we don't use
+        // here.
+
+        Area_object_enabled = 0;
+        Signpost_object_enabled = 0;
+        DF_object_enabled = 0;
+        Map_View_object_enabled = 1;
+        Probability_circles_enabled = 0;
+
+        //fprintf(stderr,"Map View Objects are ENABLED\n");
+
+
+// Make a bunch of the fields insensitive that we don't use here?
+
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+        XmToggleButtonSetState(signpost_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(area_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(df_bearing_toggle, FALSE, FALSE);
+        XmToggleButtonSetState(probabilities_toggle, FALSE, FALSE);
+ 
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = 'E'; // Eyeball symbol
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,FALSE);
+        XtSetSensitive(ob_option_frame,FALSE);
+
+       // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+   }
+    else {
+        Map_View_object_enabled = 0;
+
+        //fprintf(stderr,"Map View Objects are DISABLED\n");
+
+        // Call Set_Del_Object again, causing it to redraw with the new options.
+        //Set_Del_Object( widget, clientData, callData );
+        Set_Del_Object( widget, global_parameter1, global_parameter2 );
+
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_group_data,temp_data);
+
+        temp_data[0] = '/';
+        temp_data[1] = '\0';
+        XmTextFieldSetString(object_symbol_data,temp_data);
+
+        XtSetSensitive(ob_frame,TRUE);
+        XtSetSensitive(ob_option_frame,TRUE);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+    }
+
+    // Restore name and comment fields
+    XmTextFieldSetString(object_name_data,signpost_name);
+
+    // Don't want to restore the comment if it is a Map View object,
+    // as Set_Del_Object() changes that field in that case.
+    if (!Map_View_object_enabled) {
+        XmTextFieldSetString(object_comment_data,comment);
+    }
+}
+
+
+
+
+
+/* Area object type radio buttons */
+void Area_type_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        Area_type = atoi(which);    // Set to shape desired
+        if ( (Area_type == 1) || (Area_type == 6) ) {   // If either line type
+            //fprintf(stderr,"Line type: %d\n", Area_type);
+            XtSetSensitive(ob_corridor,TRUE);
+            XtSetSensitive(ob_corridor_data,TRUE);
+            XtSetSensitive(ob_corridor_miles,TRUE);
+            XtSetSensitive(open_filled_toggle,FALSE);
+        }
+        else {  // Not line type
+            //fprintf(stderr,"Not line type: %d\n", Area_type);
+            XtSetSensitive(ob_corridor,FALSE);
+            XtSetSensitive(ob_corridor_data,FALSE);
+            XtSetSensitive(ob_corridor_miles,FALSE);
+            XtSetSensitive(open_filled_toggle,TRUE);
+        }
+    }
+    else {
+        Area_type = 0;  // Open circle
+        //fprintf(stderr,"Type zero\n");
+    }
+    //fprintf(stderr,"Area type: %d\n", Area_type);
+}
+
+
+
+
+
+/* Area object color radio buttons */
+void Area_color_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        Area_color[0] = which[0];   // Set to color desired.
+        Area_color[1] = which[1];
+        Area_color[2] = '\0';
+    }
+    else {
+        Area_color[0] = '/';
+        Area_color[1] = '0';    // Black
+        Area_color[2] = '\0';
+    }
+    //fprintf(stderr,"Area color: %s\n", Area_color);
+}
+
+
+
+
+
+/* Area bright color enable button */
+void Area_bright_dim_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        Area_bright = atoi(which);
+        //fprintf(stderr,"Bright colors are ENABLED: %d\n", Area_bright);
+    }
+    else {
+        Area_bright = 0;
+        //fprintf(stderr,"Bright colors are DISABLED: %d\n", Area_bright);
+    }
+}
+
+
+
+
+
+/* Area filled enable button */
+void Area_open_filled_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        Area_filled = atoi(which);
+        //fprintf(stderr,"Filled shapes ENABLED: %d\n", Area_filled);
+    }
+    else {
+        Area_filled = 0;
+        //fprintf(stderr,"Filled shapes DISABLED: %d\n", Area_filled);
+    }
+}
+
+
+
+
+
+// Handler for "Omni Antenna" toggle button
+void  Omni_antenna_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+ 
+    if(state->set) {
+        //fprintf(stderr,"Omni Antenna ENABLED\n");
+        XmToggleButtonSetState(beam_antenna_toggle, FALSE, FALSE);
+        XtSetSensitive(frameomni,TRUE);
+        XtSetSensitive(framebeam,FALSE);
+        Omni_antenna_enabled = 1;
+        Beam_antenna_enabled = 0;
+   }
+    else {
+        //fprintf(stderr,"Omni Antenna DISABLED\n");
+        XtSetSensitive(frameomni,FALSE);
+        Omni_antenna_enabled = 0;
+    }
+}
+
+
+
+
+
+// Handler for "Beam Antenna" toggle button
+void  Beam_antenna_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+ 
+    if(state->set) {
+        //fprintf(stderr,"Beam Antenna ENABLED\n");
+        XmToggleButtonSetState(omni_antenna_toggle, FALSE, FALSE);
+        XtSetSensitive(frameomni,FALSE);
+        XtSetSensitive(framebeam,TRUE);
+        Omni_antenna_enabled = 0;
+        Beam_antenna_enabled = 1;
+   }
+    else {
+        //fprintf(stderr,"Beam Antenna DISABLED\n");
+        XtSetSensitive(framebeam,FALSE);
+        Beam_antenna_enabled = 0;
+    }
+}
+
+
+
+
+
+/* Object signal radio buttons */
+void Ob_signal_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        object_shgd[0] = which[0];  // Set to signal quality heard
+    }
+    else {
+        object_shgd[0] = '0';       // 0 (Signal not heard)
+    }
+    object_shgd[4] = '\0';
+
+    //fprintf(stderr,"SHGD: %s\n",object_shgd);
+}
+
+
+
+
+
+/* Object height radio buttons */
+void Ob_height_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        object_shgd[1] = which[0];  // Set to height desired
+    }
+    else {
+        object_shgd[1] = '0';       // 0 (10ft HAAT)
+    }
+    object_shgd[4] = '\0';
+
+    //fprintf(stderr,"SHGD: %s\n",object_shgd);
+}
+
+
+
+
+
+/* Object gain radio buttons */
+void Ob_gain_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        object_shgd[2] = which[0];  // Set to antenna gain desired
+    }
+    else {
+        object_shgd[2] = '0';       // 0dB gain
+    }
+    object_shgd[4] = '\0';
+
+    //fprintf(stderr,"SHGD: %s\n",object_shgd);
+}
+
+
+
+
+
+/* Object directivity radio buttons */
+void Ob_directivity_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        object_shgd[3] = which[0];  // Set to antenna pattern desired
+    }
+    else {
+        object_shgd[3] = '0';       // Omni-directional pattern
+    }
+    object_shgd[4] = '\0';
+
+    //fprintf(stderr,"SHGD: %s\n",object_shgd);
+}
+
+
+
+
+
+/* Object beamwidth radio buttons */
+void Ob_width_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        object_NRQ[2] = which[0];  // Set to antenna beamwidth desired
+    }
+    else {
+        object_NRQ[2] = '0';       // Beamwidth = "Useless"
+    }
+    object_NRQ[3] = '\0';
+
+    //fprintf(stderr,"NRQ: %s\n", object_NRQ);
+}
+
+
+
+
+
+/* populate predefined object (SAR) struct */
+void Populate_predefined_objects(predefinedObject *predefinedObjects) {
+    // The number of objects you are defining below must be 
+    // exactly equal to number_of_predefined_objects
+    // and less than MAX_NUMBER_OF_PREDEFINED_OBJECTS.
+    // using counter j for this seems inelegant **
+
+    // A set of predefined SAR objects are hardcoded and used by default
+    // other sets of predefined objects (SAR in km, public service event, 
+    // and user defined objects) can be loaded from a file.
+    // 
+    // Detailed instructions for the format of the files can be found in
+    // the two example files provided: predefined_SAR.sys and 
+    // predefined_EVENT.sys
+    char predefined_object_definition_file[263];
+    int read_file_ok = 0;
+    int line_max_length = 255;
+    int object_read_ok = 0;
+    char line[line_max_length];
+    char *value;
+    char *variable;
+    FILE *fp_file;
+    int j = 0;
+    char error_correct_location[256];
+    char predef_obj_path[MAX_VALUE];
+    char temp_file_path[MAX_VALUE];
+
+
+    xastir_snprintf(line,sizeof(line),"%s","\0");
+    xastir_snprintf(predefined_object_definition_file,sizeof(predefined_object_definition_file),"config/%s",predefined_object_definition_filename);
+
+    get_user_base_dir(predefined_object_definition_file, predef_obj_path, 
+                      sizeof(predef_obj_path));
+
+    number_of_predefined_objects = 0;
+
+    if (predefined_menu_from_file == 1 ) {
+        // Check to see if a file containing predefined object definitions 
+        // exists, if it does, open it and try to read the definitions
+        // if this fails, use the hardcoded SAR default instead.
+//        fprintf(stderr,"Checking for predefined objects menu file\n");
+#ifdef OBJECT_DEF_FILE_USER_BASE
+        if (filethere(predef_obj_path)) {
+            fp_file = fopen(predef_obj_path,"r");
+#else   // OBJECT_DEF_FILE_USER_BASE
+        if (filethere(get_data_base_dir(predefined_object_definition_file))) {
+            fp_file = fopen(get_data_base_dir(predefined_object_definition_file),"r");
+#endif  // OBJECT_DEF_FILE_USER_BASE
+    
+            xastir_snprintf(error_correct_location,
+                sizeof(error_correct_location),
+                "Loading from %s/%s \n",
+#ifdef OBJECT_DEF_FILE_USER_BASE
+                get_user_base_dir("config", temp_file_path, sizeof(temp_file_path)),
+#else   // OBJECT_DEF_FILE_USER_BASE
+                get_data_base_dir("config"),
+#endif  // OBJECT_DEF_FILE_USER_BASE
+                predefined_object_definition_file);
+            fprintf(stderr, "%s", error_correct_location);
+            while (!feof(fp_file)) {
+                // read lines to end of file
+                (void)get_line(fp_file, line, line_max_length);
+                // ignore blank lines and lines starting with #
+                if ((strncmp("#",line,1)!=0) && (strlen(line) > 2)) {
+                    // if line starts "NAME" begin an object
+                    // next five lines should be PAGE, SYMBOL, DATA, MENU, HIDDENCHILD 
+                    // NAME, PAGE, SYMBOL, MENU, and HIDDENCHILD are required.
+                    // HIDDENCHILD must come last (it is being used to identify the
+                    // end of one object).
+                    // split line into variable/value pairs on tab
+                    // See predefined_SAR.sys and predefined_event.sys for more details.
+                    variable = strtok((char *)&line,"\t");
+                    if (strcmp("NAME",variable)==0) {
+                        value = strtok(NULL,"\t\r\n");
+                        if (value != NULL) {
+                            xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call), "%s", value);
+                            // by default, set data to an empty string, allowing DATA to be ommitted
+                            xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+                            object_read_ok ++;
+                        }
+                    }
+                    if (strcmp("PAGE",variable)==0) {
+                        value = strtok(NULL,"\t\r\n");
+                        if (value != NULL) {
+                            xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page), "%s", value);
+                            object_read_ok ++;
+                        }
+                    }
+                    if (strcmp("SYMBOL",variable)==0) {
+                        value = strtok(NULL,"\t\r\n");
+                        if (value != NULL) {
+                            xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol), "%s", value);
+                            object_read_ok ++;
+                        }
+                    }
+                    if (strcmp("DATA",variable)==0) {
+                        value = strtok(NULL,"\t\r\n");
+                        if (value == NULL || strcmp(value,"NULL")==0) {
+                             xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+                        } else {
+                             xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data), "%s", value);
+                        }
+                    }
+                    if (strcmp("MENU",variable)==0) {
+                        value = strtok(NULL,"\t\r\n");
+                        if (value != NULL) {
+                             xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call), "%s", value);
+                            object_read_ok ++;
+                        }
+                    }
+                    if (strcmp("HIDDENCHILD",variable)==0) {
+                        value = strtok(NULL,"\t\r\n");
+                        if (strcmp(value,"YES")==0) {
+                            predefinedObjects[j].show_on_menu = 0;
+                            predefinedObjects[j].index_of_child = j - 1;
+                            predefinedObjects[j].index = j;
+                        } else {
+                            predefinedObjects[j].show_on_menu = 1;
+                            predefinedObjects[j].index_of_child = -1;
+                            predefinedObjects[j].index = j;
+                        }
+                        if (object_read_ok == 4) { 
+                           // All elements for an object were read correctly.
+                           // Begin filling next element in array.
+                           j++; 
+                           // Read of at least one object was successful, 
+                           // don't display default hardcoded menu items.
+                           read_file_ok = 1;
+                           // Reset value counter for next object.
+                           object_read_ok = 0;
+                        } else {
+                           // Something was missing or HIDDENCHILD was out of order.
+                           // Don't increment array (overwrite a partly filled entry).
+                           fprintf(stderr,"Error in reading predefined object menu file:\nAn object is not correctly defined.\n");
+                        }
+                    }
+                }
+            } // end while !feof()
+            fclose(fp_file);
+            if (read_file_ok==0) {
+                fprintf(stderr,"Error in reading predefined objects menu file:\nNo valid objects found.\n");
+            }
+        }
+        else {
+ 
+            fprintf(stderr,"Error: Predefined objects menu file not found.\n");
+
+            xastir_snprintf(error_correct_location,
+                sizeof(error_correct_location),
+                "File should be in %s\n",
+#ifdef OBJECT_DEF_FILE_USER_BASE
+                get_user_base_dir("config", temp_file_path, sizeof(temp_file_path)));
+#else   // OBJECT_DEF_FILE_USER_BASE
+                get_data_base_dir("config"));
+#endif  // OBJECT_DEF_FILE_USER_BASE
+            fprintf(stderr, "%s", error_correct_location);
+        }
+    }
+
+    if (read_file_ok==0) {
+        // file read failed or was not requested, display default SAR menu
+
+        // command post
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"ICP");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"/");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"c");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"ICP: Command Post");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+        // Staging area
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"Staging");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"S");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"0");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"Staging");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+        // Initial Planning Point
+        // set up to draw as two objects with different probability circles
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"IPP_");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"/");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"/");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data)," Pmin0.75,Pmax1.0");
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"[not shown]");
+        // show on menu = 0 will hide this entry on menu
+        predefinedObjects[j].show_on_menu = 0;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"IPP");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"/");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"/");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data)," Pmin0.25,Pmax0.5");
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"IPP: InitialPlanningPoint");
+        predefinedObjects[j].show_on_menu = 1;
+        // index of child j - 1 will add additional callback to IPP_
+        predefinedObjects[j].index_of_child = j - 1;
+        predefinedObjects[j].index = j;
+        j++;
+        
+        // Point last seen
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"PLS");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"/");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"/");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"PLS: Point Last Seen");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+    
+        // Last known point
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"LKP");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"/");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),".");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"LKP: Last Known Point");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+        // Base
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"Base");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"B");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"0");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"Base");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+        // Helibase (helicopter support base)
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"Helibase");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"H");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"0");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"Helibase");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+        
+        // Helispot  (helicopter landing spot)
+        // Heli- will be created as Heli-1, Heli-2, Heli-3, etc.  
+        // terminal - on a call is a magic character. see Create_SAR+Object.
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"Heli-");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"/");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"/");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"Heli-n: Helispot");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+        // Camp
+        xastir_snprintf(predefinedObjects[j].call,sizeof(predefinedObjects[j].call),"Camp");
+        xastir_snprintf(predefinedObjects[j].page,sizeof(predefinedObjects[j].page),"C");
+        xastir_snprintf(predefinedObjects[j].symbol,sizeof(predefinedObjects[j].symbol),"0");
+        xastir_snprintf(predefinedObjects[j].data,sizeof(predefinedObjects[j].data),"%c",'\0');
+        xastir_snprintf(predefinedObjects[j].menu_call,sizeof(predefinedObjects[j].menu_call),"Camp");
+        predefinedObjects[j].show_on_menu = 1;
+        predefinedObjects[j].index_of_child = -1;
+        predefinedObjects[j].index = j;
+        j++;
+    
+    }
+
+    // Could read additional entries from a file here.
+    // The total number of entries should be left fairly small 
+    // to prevent the menu from becoming too large and unweildy.
+
+    number_of_predefined_objects = j;
+    if (number_of_predefined_objects>MAX_NUMBER_OF_PREDEFINED_OBJECTS) {
+        // need beter handling of this - we will allready have run
+        // past the end of the array if we have reached here.
+        number_of_predefined_objects=MAX_NUMBER_OF_PREDEFINED_OBJECTS;
+    }
+}
+
+
+
+
+
+/* Create a predefined SAR/Public Event object
+   Create an object of the specified type at the current mouse position 
+   without a dialog.  
+   Current undesirable behavior: If an object of the same name exists, 
+   takes control of that object and moves it to the current mouse position.  
+
+   clientData is pointer to an integer representing the index of a 
+   predefined object in the predefinedObjects array
+   */
+void Create_SAR_Object(/*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, XtPointer calldata) {
+    Dimension width, height;
+    char call[MAX_CALLSIGN+1];
+    long x_lat,x_lon;
+    char origin[MAX_CALLSIGN+1];  // mycall
+    char data[MAX_LINE_SIZE];
+    char page[2];
+    // reserve space for probability circle as well as symbol /Pmin0.25,Pmax0.5,
+    char symbol_plus[PREDEFINED_OBJECT_DATA_LENGTH];
+    char symbol[2];
+    char c_lon[10]; 
+    char c_lat[10];
+    char time[7];
+    intptr_t i;
+    DataRow *p_station;
+    int done = 0;
+    int iterations_left = 1000; // Max iterations of while loop below
+    int extra_num = 1;
+    char orig_call[MAX_CALLSIGN+1];
+
+ 
+    // set some defaults in case of a non-matched value
+    xastir_snprintf(page,sizeof(page),"/");
+    xastir_snprintf(symbol,sizeof(symbol),"/");
+    xastir_snprintf(call, sizeof(call), "Marker");
+
+    //for (i=0;i<number_of_predefined_objects;i++) {
+    //   if (strcmp((char *)clientData,predefinedObjects[i].call)==0) {   
+    i = (intptr_t)clientData;
+    if (i > -1) {
+        if (i <= number_of_predefined_objects) {
+            xastir_snprintf(page,sizeof(page), "%s", predefinedObjects[i].page);
+            xastir_snprintf(symbol,sizeof(symbol), "%s", predefinedObjects[i].symbol);
+            xastir_snprintf(call, sizeof(call), "%s", predefinedObjects[i].call);
+            xastir_snprintf(symbol_plus, sizeof(symbol_plus), "%s%s",symbol,predefinedObjects[i].data);
+        }
+    }
+
+    // Get mouse position.
+    XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+    x_lon = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+    x_lat = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+    if(debug_level & 1)
+        fprintf(stderr, "Creating symbol %s %s at: %lu %lu with calldata: [%li]\n",
+             page,
+             symbol,
+             x_lat,
+             x_lon,
+             (intptr_t)clientData);
+
+    // CONVERT_LP_NOSP      = DDMM.MMN
+    convert_lat_l2s(x_lat, (char *)c_lat, sizeof(c_lat), CONVERT_LP_NOSP);
+    convert_lon_l2s(x_lon, (char *)c_lon, sizeof(c_lon), CONVERT_LP_NOSP);
+
+
+    // Save "call" away in "orig_call" so that we can use it again
+    // and again as we try to come up with a unique name for the
+    // object.
+    //
+    xastir_snprintf(orig_call,
+        sizeof(orig_call),
+        "%s",
+        call);
+
+    // '-' is a magic character.
+    //
+    // If the last character in call is a "-", the symbol is expected
+    // to be a numeric series starting with call-1, so change call to 
+    // call-1.  This lets us describe Heli- and create Heli-1, Heli-2
+    // and similar series.  Storing call to orig_call before appending 
+    // the number should allow the sequence to increment normally.
+    if ((int)'-'==(int)*(call+(strlen(call)-1))) {
+        // make sure that we don't write past the end of call
+        if (strlen(call)<MAX_CALLSIGN) {
+            strncat(call,"1",1);
+        }
+    }
+    // Check object names against our station database until we find
+    // a unique name or a killed object name we can use.
+    //
+    while (!done && iterations_left) {
+ 
+        // Create object as owned by own station, or take control of
+        // object if it has another owner.  Taking control of a
+        // received object is probably not a desirable behavior.
+
+        if (!search_station_name(&p_station,call,1)) {
+            //
+            // No match found with the original name, so the name
+            // for our object is ok to use.  Get out of the while
+            // loop and create the object.
+            //
+            done++;
+            continue;   // Next loop iteration (Exit the while loop)
+        }
+ 
+
+        // If we get to here, a station with this name exists.  We
+        // have a pointer to it with p_station.
+        //
+        // If object or item and killed, use the old name to create
+        // a new object.
+        //
+        // If not killed or not object/item, pick a new name by
+        // adding digits onto the end of the old name until we don't
+        // have a name collision or we find an old object or item by
+        // that name that has been killed.
+
+
+        // Check whether object or item.  If so, check whether killed.
+        if ((p_station->flag & (ST_OBJECT | ST_ITEM)) != 0) { // It's an object or item
+
+            // Check whether object/item has been killed already
+            if ((p_station->flag & ST_ACTIVE) != ST_ACTIVE) {
+                //
+                // The object or item has been killed.  Ok to use
+                // this object name.  Get out of the while loop and
+                // create the object.
+                //
+                done++;
+                continue;   // Next loop iteration (Exit the while loop)
+            }
+        }
+
+
+// If we get to this point we have an object name that matches
+// another in our database.  We must come up with a new name.  We
+// add digits to the end of the original name until we get one that
+// works for us.
+
+
+
+/*
+        // If my_callsign (Exact match includes SSID)
+//        if (is_my_call(p_station->origin,1)) {
+        if (is_my_object_item(p_station)) {
+
+            // The previous object with the same name is owned by
+            // me.
+            //   a) MOVE the EXISTING object (default), perhaps with the option
+            //      to clear the track.  Clearing the track would only take
+            //      effect on our local map screen, not on everyone else's.
+            //   b) RENAME the NEW object, perhaps tacking a number
+            //   onto the end until we get to an unused name.
+            //   c) CANCEL request
+
+
+fprintf(stderr, "Object with same name exists, owned by me\n");
+
+// Pop up a new dialog with the various options on it.  Save our
+// state here so that we can create the object in the callbacks for
+// the next dialog.
+//
+// Code goes here...
+
+
+        else {
+            // The previous object with the same name is NOT owned
+            // by me.
+            //   a) ADOPT the existing object and MOVE it (a very
+            //      poor idea).
+            //      Same track-clearing as option 1a.
+            //   b) RENAME the NEW object (default), perhaps tacking
+            //   a number onto the end until we get to an unused
+            //   name.
+            //   c) CANCEL request
+
+
+fprintf(stderr, "Object with same name exists, owned by %s\n", p_station->origin);
+
+// Pop up a new dialog with the various options on it.  Save our
+// state here so that we can create the object in the callbacks for
+// the next dialog.
+//
+// Code goes here...
+
+
+        }
+*/
+
+
+        extra_num++;
+
+        // Append extra_num to the object name (starts at "2"), try
+        // again to see if it is unique.
+        //
+        xastir_snprintf(call,
+            sizeof(call),
+            "%s%d",
+            orig_call,
+            extra_num);
+// ****** Bug ********
+// need to check length of call - if it has gone over 9 characters only 
+// the first 9 will be treated as unique, thus FirstAid11 will become FirstAid1 
+// and become new position for existing FirstAid1.
+// MAX_CALLSIGN is the constraining global.
+// In that case, need to fail gracefully and throw an error message.
+        iterations_left--;
+
+    }   // End of while loop
+
+
+    if (iterations_left == 0) {
+// Pop up a message stating that we couldn't find an empty name in
+// 1000 iterations.  Call popup_message_always()
+ 
+fprintf(stderr, "No more iterations left\n");
+
+    }
+
+
+    xastir_snprintf(origin,
+        sizeof(origin),
+        "%s", my_callsign);
+    xastir_snprintf(time, sizeof(time), "%02d%02d%02d", 
+        get_hours(), 
+        get_minutes(), 
+        get_seconds() );
+    // Prepare APRS data string using latitude and longitude from mouse click location
+    // and page, symbol, and any additional data from the prepared object.
+    xastir_snprintf(data,
+        sizeof(data),
+        ";%-9s*%sh%s%s%s%s",
+        call,
+        time,
+        c_lat,
+        page,
+        c_lon,
+        symbol_plus);
+
+//fprintf(stderr,"Packet:%s\n", data);
+
+    log_object_item(data,0,last_object);
+
+// *********** New objects not being displayed on map untill restart
+
+
+    if (object_tx_disable || transmit_disable)
+        output_my_data(data,-1,0,1,0,NULL); // Local loopback only, not igating
+    else
+        output_my_data(data,-1,0,0,0,NULL); // Transmit/loopback object data, not igating
+}
+
+
+
+
+
+// Fill in fields from an existing object/item or create the proper
+// transmit string for a new object/item from these fields.
+/*
+ *  Setup Object/Item Dialog
+ *  clientData = pointer to object struct, if it's a modify or a move operation,
+ *  else it's NULL.
+ *  If calldata = 2, then we're doing a move object operation.  We want in that
+ *  case to fill in the new values for lat/long and make them take effect.
+ *  If calldata = 1, then we've dropped through Station_info/Station_data
+ *  on the way to Modify->Object.
+ *  Need to put the tests for the different types of objects
+ *  at the top of this function, then the dialog will build properly for
+ *  the type of object initially.
+ */
+void Set_Del_Object( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, XtPointer calldata) {
+    Dimension width, height;
+    long lat,lon;
+    char lat_str[MAX_LAT];
+    char lon_str[MAX_LONG];
+    static Widget ob_pane, ob_form,
+                ob_name,ob_latlon_frame,ob_latlon_form,ob_latlon_ts,
+                ob_lat, ob_lat_deg, ob_lat_min, ob_lat_ns,
+                ob_lon, ob_lon_deg, ob_lon_min, ob_lon_ew,
+                ob_form1, ob_ts,
+                signpost_form,signpost_ts,
+                signpost_label,
+                probability_frame,probability_form,probability_ts,
+                probability_label_min, probability_label_max,
+                ob_option_ts,ob_option_form,
+                area_ts, area_form,
+                bright_dim_toggle,
+                shape_box,toption1,toption2,toption3,toption4,toption5,
+                color_box,coption1,coption2,coption3,coption4,coption5,coption6,coption7,coption8,
+                omnilabel,formomni,
+                signal_box,soption0,soption1,soption2,soption3,soption4,soption5,soption6,soption7,soption8,soption9,
+                height_box,hoption0,hoption1,hoption2,hoption3,hoption4,hoption5,hoption6,hoption7,hoption8,hoption9,
+                gain_box,goption0,goption1,goption2,goption3,goption4,goption5,goption6,goption7,goption8,goption9,
+                directivity_box,doption0,doption1,doption2,doption3,doption4,doption5,doption6,doption7,doption8,
+                beamlabel,formbeam,
+                width_box,woption0,woption1,woption2,woption3,woption4,woption5,woption6,woption7,woption8,woption9,
+                ob_bearing,
+                ob_lat_offset,ob_lon_offset,
+                ob_sep, ob_button_set,ob_button_del,ob_button_cancel,it_button_set,
+                ob_button_symbol,
+                compute_button;
+    char temp_data[40];
+    Atom delw;
+    DataRow *p_station = (DataRow *)clientData;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac;     /* Arg Count */
+    long x,y;
+
+
+/*
+    if (p_station != NULL)
+        fprintf(stderr,"Have a pointer to an object.  ");
+    else
+        fprintf(stderr,"No pointer, new object?       ");
+    if (calldata != NULL) {
+        if (strcmp(calldata,"2") == 0)
+            fprintf(stderr,"Set_Del_Object: calldata: 2.  Move object.\n");
+        else if (strcmp(calldata,"1") == 0)
+            fprintf(stderr,"Set_Del_Object: calldata: 1.  Modify object.\n");
+        else if (strcmp(calldata,"0") == 0)
+            fprintf(stderr,"Set_Del_Object: calldata: 0.  New object.\n");
+        else
+            fprintf(stderr,"Set_Del_Object: calldata: invalid.  New object.\n");
+    }
+*/
+
+    // Save the data so that other routines can access it.  Some of the
+    // callbacks can only handle one parameter, and we need two.
+    if (p_station != NULL)
+        global_parameter1 = clientData;
+    else
+        global_parameter1 = NULL;
+    global_parameter2 = calldata;
+    
+
+
+    // This function can be invoked from the mouse menus or by being called
+    // directly by other routines.  We look at the p_station pointer to decide
+    // how we were called.
+    //
+    if (p_station != NULL) {  // We were called from the Modify_object()
+                              // or Move() functions
+        //fprintf(stderr,"Got a pointer!\n");
+        lon = p_station->coord_lon;     // Fill in values from the original object
+        lat = p_station->coord_lat;
+    }
+    else {
+        // We were called from the "Create New Object" mouse menu or
+        // by the "Move" option get default position for object, the
+        // position we have clicked at.  For the special case of a
+        // Map View object, we instead want the screen center for
+        // this new object.
+        //
+        if (Map_View_object_enabled) {
+            // Get center of screen
+            lon = center_longitude;
+            lat = center_latitude;
+        }
+        else {
+            // Get mouse position
+            XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+            lon = center_longitude - ((width *scale_x)/2) + (menu_x*scale_x);
+            lat = center_latitude  - ((height*scale_y)/2) + (menu_y*scale_y);
+        }
+    }
+
+
+    // If the object dialog is up, we need to kill it and draw a new
+    // one so that we have the correct values filled in.
+    if (object_dialog)
+        Object_destroy_shell( w, object_dialog, NULL);
+
+
+    // Check for the three "Special" types of objects we deal with and set
+    // the global variables for them here.  This will result in the correct
+    // type of dialog being drawn for each type of object.
+// Question:  What about for Modify->Object where we're trying to change
+// the type of the object?
+
+    if (p_station != NULL) {
+/*
+        if (calldata != NULL) {
+            if (strcmp(calldata,"2") == 0)
+                fprintf(stderr,"Set_Del_Object: calldata: 2.  Move object.\n");
+            else if (strcmp(calldata,"1") == 0)
+                fprintf(stderr,"Set_Del_Object: calldata: 1.  Modify object.\n");
+            else if (strcmp(calldata,"0") == 0)
+                fprintf(stderr,"Set_Del_Object: calldata: 0.  New object.\n");
+            else
+                fprintf(stderr,"Set_Del_Object: calldata: invalid.  New object.\n");
+        }
+*/
+
+        // Check to see whether we should even be here at all!
+        if ( !(p_station->flag & ST_OBJECT)
+                && !(p_station->flag & ST_ITEM)) {  // Not an object or item
+            //fprintf(stderr,"flag: %i\n", (int)p_station->flag);
+            popup_message_always(langcode("POPEM00022"),
+                langcode("POPEM00043") ); // "Not an Object/Item!"
+            return;
+        }
+
+        // Set to known defaults first
+        Area_object_enabled = 0;
+        Signpost_object_enabled = 0;
+        DF_object_enabled = 0;
+        Map_View_object_enabled = 0;
+        Probability_circles_enabled = 0;
+ 
+        if (p_station->aprs_symbol.area_object.type != AREA_NONE) { // Found an area object
+            Area_object_enabled = 1;
+        }
+        else if ( (p_station->aprs_symbol.aprs_symbol == 'm') // Found a signpost object
+                && (p_station->aprs_symbol.aprs_type == '\\') ) {
+            Signpost_object_enabled = 1;
+        }
+        else if ( (p_station->aprs_symbol.aprs_symbol == '\\') // Found a DF object
+                && (p_station->aprs_symbol.aprs_type == '/')
+                && ((strlen(p_station->signal_gain) == 7) // That has data associated with it
+                    || (strlen(p_station->bearing) == 3)
+                    || (strlen(p_station->NRQ) == 3) ) ) {
+            DF_object_enabled = 1;
+        }
+        else if ( (p_station->aprs_symbol.aprs_symbol == 'E') // Found a Map View object
+                && (p_station->aprs_symbol.aprs_type == '/')
+                && (strstr(p_station->power_gain,"RNG") != 0) ) { // Has a range value
+
+            //fprintf(stderr,"Found a range\n");
+            Map_View_object_enabled = 1;
+        }
+
+        else if (p_station->probability_min[0] != '\0'      // Found some data
+                || p_station->probability_max[0] != '\0') { // Found some data
+            Probability_circles_enabled = 1;
+        }
+    }
+
+    //fprintf(stderr,"Area:Signpost:DF  %i:%i:%i\n",Area_object_enabled,Signpost_object_enabled,DF_object_enabled);
+
+// Ok.  The stage is now set to draw the proper type of dialog for the
+// type of object we're interested in currently.
+
+
+    if(object_dialog)           // it is already open
+        (void)XRaiseWindow(XtDisplay(object_dialog), XtWindow(object_dialog));
+    else {                      // create new popup window
+        object_dialog = XtVaCreatePopupShell(langcode("POPUPOB001"),
+                xmDialogShellWidgetClass,   appshell,
+                XmNdeleteResponse,          XmDESTROY,
+                XmNdefaultPosition,         FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_pane = XtVaCreateWidget("Set_Del_Object pane",
+                xmPanedWindowWidgetClass, 
+                object_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_form =  XtVaCreateWidget("Set_Del_Object ob_form",
+                xmFormWidgetClass, 
+                ob_pane,
+                XmNfractionBase,            3,
+                XmNautoUnmanage,            FALSE,
+                XmNshadowThickness,         1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Name"
+        ob_name = XtVaCreateManagedWidget(langcode("POPUPOB002"),
+                xmLabelWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // object name
+        object_name_data = XtVaCreateManagedWidget("Set_Del_Object name_data", 
+                xmTextFieldWidgetClass, 
+                ob_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 9,
+                XmNmaxLength,               9,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_name,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+
+
+//----- Frame for table / symbol
+        ob_frame = XtVaCreateManagedWidget("Set_Del_Object ob_frame", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               object_name_data,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // "Station Symbol"
+        ob_ts  = XtVaCreateManagedWidget(langcode("WPUPCFS009"),
+                xmLabelWidgetClass,
+                ob_frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_form1 =  XtVaCreateWidget("Set_Del_Object form1",
+                xmFormWidgetClass, 
+                ob_frame,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Group/overlay"
+        ob_group = XtVaCreateManagedWidget(langcode("WPUPCFS010"),
+                xmLabelWidgetClass, 
+                ob_form1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // table
+        object_group_data = XtVaCreateManagedWidget("Set_Del_Object group", 
+                xmTextFieldWidgetClass, 
+                ob_form1,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_group,
+                XmNleftOffset,              5,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Symbol"
+        ob_symbol = XtVaCreateManagedWidget(langcode("WPUPCFS011"),
+                xmLabelWidgetClass, 
+                ob_form1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_group_data,
+                XmNleftOffset,              20,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // symbol
+        object_symbol_data = XtVaCreateManagedWidget("Set_Del_Object symbol", 
+                xmTextFieldWidgetClass, 
+                ob_form1,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_symbol,
+                XmNleftOffset,              5,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // icon
+        Ob_icon0 = XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                DefaultDepthOfScreen(XtScreen(appshell)));
+        Ob_icon  = XCreatePixmap(XtDisplay(appshell),
+                RootWindowOfScreen(XtScreen(appshell)),
+                20,
+                20,
+                DefaultDepthOfScreen(XtScreen(appshell)));
+        object_icon = XtVaCreateManagedWidget("Set_Del_Object icon", 
+                xmLabelWidgetClass, 
+                ob_form1,
+                XmNlabelType,               XmPIXMAP,
+                XmNlabelPixmap,             Ob_icon,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_symbol_data,
+                XmNleftOffset,              15,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_button_symbol = XtVaCreateManagedWidget(langcode("WPUPCFS028"),
+                xmPushButtonGadgetClass, 
+                ob_form1,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               2,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_icon,
+                XmNleftOffset,              5,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             5,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ob_button_symbol, XmNactivateCallback, Ob_change_symbol, object_dialog);
+ 
+//----- Frame for Lat/Long
+        ob_latlon_frame = XtVaCreateManagedWidget("Set_Del_Object ob_latlon_frame", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_frame,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // "Location"
+        ob_latlon_ts  = XtVaCreateManagedWidget(langcode("POPUPOB028"),
+                xmLabelWidgetClass,
+                ob_latlon_frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_latlon_form =  XtVaCreateWidget("Set_Del_Object ob_latlon_form",
+                xmFormWidgetClass, 
+                ob_latlon_frame,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "LAT"
+        ob_lat = XtVaCreateManagedWidget(langcode("WPUPCFS003"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              15,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // lat deg
+        object_lat_data_deg = XtVaCreateManagedWidget("Set_Del_Object lat_deg", 
+                xmTextFieldWidgetClass, 
+                ob_latlon_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               2,
+                XmNtopOffset,               5,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lat,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "deg"
+        ob_lat_deg = XtVaCreateManagedWidget(langcode("WPUPCFS004"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_lat_data_deg,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // lat min
+        object_lat_data_min = XtVaCreateManagedWidget("Set_Del_Object lat_min", 
+                xmTextFieldWidgetClass, 
+                ob_latlon_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 6,
+                XmNmaxLength,               6,
+                XmNtopOffset,               5,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lat_deg,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "min"
+        ob_lat_min = XtVaCreateManagedWidget(langcode("WPUPCFS005"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_lat_data_min,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // N/S
+        object_lat_data_ns = XtVaCreateManagedWidget("Set_Del_Object lat_ns", 
+                xmTextFieldWidgetClass, 
+                ob_latlon_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               5,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lat_min,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "(N/S)"
+        ob_lat_ns = XtVaCreateManagedWidget(langcode("WPUPCFS006"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_lat_data_ns,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "LONG"
+        ob_lon = XtVaCreateManagedWidget(langcode("WPUPCFS007"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // long
+        object_lon_data_deg = XtVaCreateManagedWidget("Set_Del_Object long_deg", 
+                xmTextFieldWidgetClass, 
+                ob_latlon_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               3,
+                XmNtopOffset,               14,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lon,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "deg"
+        ob_lon_deg = XtVaCreateManagedWidget(langcode("WPUPCFS004"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_lon_data_deg,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // min
+        object_lon_data_min = XtVaCreateManagedWidget("Set_Del_Object long_min", 
+                xmTextFieldWidgetClass, 
+                ob_latlon_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 6,
+                XmNmaxLength,               6,
+                XmNtopOffset,               14,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lon_deg,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "min"
+        ob_lon_min = XtVaCreateManagedWidget(langcode("WPUPCFS005"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_lon_data_min,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // E/W
+        object_lon_data_ew = XtVaCreateManagedWidget("Set_Del_Object long_ew", 
+                xmTextFieldWidgetClass, 
+                ob_latlon_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   FALSE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 1,
+                XmNmaxLength,               1,
+                XmNtopOffset,               14,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lon_min,
+                XmNleftOffset,              10,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+        // "(E/W)"
+        ob_lon_ew = XtVaCreateManagedWidget(langcode("WPUPCFS008"),
+                xmLabelWidgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              object_lon_data_ew,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        compute_button = XtVaCreateManagedWidget(langcode("COORD002"),
+                xmPushButtonGadgetClass, 
+                ob_latlon_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_lat,
+                XmNtopOffset,               20,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lon_ew,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // Fill in the pointers to our input textfields so that the coordinate
+        // calculator can fiddle with them.
+        coordinate_calc_array.calling_dialog = object_dialog;
+        coordinate_calc_array.input_lat_deg = object_lat_data_deg;
+        coordinate_calc_array.input_lat_min = object_lat_data_min;
+        coordinate_calc_array.input_lat_dir = object_lat_data_ns;
+        coordinate_calc_array.input_lon_deg = object_lon_data_deg;
+        coordinate_calc_array.input_lon_min = object_lon_data_min;
+        coordinate_calc_array.input_lon_dir = object_lon_data_ew;
+//        XtAddCallback(compute_button, XmNactivateCallback, Coordinate_calc, ob_latlon_form);
+//        XtAddCallback(compute_button, XmNactivateCallback, Coordinate_calc, "Set_Del_Object");
+        XtAddCallback(compute_button, XmNactivateCallback, Coordinate_calc, langcode("POPUPOB001"));
+
+//----- Frame for generic options
+        ob_option_frame = XtVaCreateManagedWidget("Set_Del_Object ob_option_frame", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_frame,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // "Generic Options"
+        ob_option_ts  = XtVaCreateManagedWidget(langcode("POPUPOB027"),
+                xmLabelWidgetClass,
+                ob_option_frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_option_form =  XtVaCreateWidget("Set_Del_Object ob_option_form",
+                xmFormWidgetClass, 
+                ob_option_frame,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Speed"
+        ob_speed = XtVaCreateManagedWidget(langcode("POPUPOB036"),
+                xmLabelWidgetClass, 
+                ob_option_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              5,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_speed_data = XtVaCreateManagedWidget("Set_Del_Object ob_speed_data", 
+                xmTextFieldWidgetClass, 
+                ob_option_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               3,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_speed,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Course"
+        ob_course = XtVaCreateManagedWidget(langcode("POPUPOB037"),
+                xmLabelWidgetClass, 
+                ob_option_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_speed_data,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_course_data = XtVaCreateManagedWidget("Set_Del_Object ob_course_data", 
+                xmTextFieldWidgetClass, 
+                ob_option_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               3,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_course,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Altitude"
+        ob_altitude = XtVaCreateManagedWidget(langcode("POPUPOB035"),
+                xmLabelWidgetClass, 
+                ob_option_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_course_data,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_altitude_data = XtVaCreateManagedWidget("Set_Del_Object ob_altitude_data", 
+                xmTextFieldWidgetClass, 
+                ob_option_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 6,
+                XmNmaxLength,               6,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_altitude,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+//----- Comment Field
+        // "Comment:"
+        ob_comment = XtVaCreateManagedWidget(langcode("WPUPCFS017"),
+                xmLabelWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_option_frame,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        object_comment_data = XtVaCreateManagedWidget("Set_Del_Object comment", 
+                xmTextFieldWidgetClass, 
+                ob_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 43,     // max 43 without Data Extension
+                XmNmaxLength,               43,
+                XmNtopOffset,               6,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_comment,
+                XmNleftOffset,              5,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_option_frame,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        // "Probability Circles"
+        probabilities_toggle = XtVaCreateManagedWidget(langcode("POPUPOB047"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_latlon_frame,
+                XmNtopOffset,               2,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_option_frame,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(probabilities_toggle,XmNvalueChangedCallback,Probability_circle_toggle,(XtPointer)p_station);
+
+ 
+        // "Signpost Enable"
+        signpost_toggle = XtVaCreateManagedWidget(langcode("POPUPOB029"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               probabilities_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_option_frame,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(signpost_toggle,XmNvalueChangedCallback,Signpost_object_toggle,(XtPointer)p_station);
+
+
+        // "Area Enable"
+        area_toggle = XtVaCreateManagedWidget(langcode("POPUPOB008"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               signpost_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_option_frame,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(area_toggle,XmNvalueChangedCallback,Area_object_toggle,(XtPointer)p_station);
+
+
+
+        // "Area Enable"
+        df_bearing_toggle = XtVaCreateManagedWidget(langcode("POPUPOB038"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               area_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_option_frame,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(df_bearing_toggle,XmNvalueChangedCallback,DF_bearing_object_toggle,(XtPointer)p_station);
+
+
+
+        // "Map View Object"
+        map_view_toggle = XtVaCreateManagedWidget(langcode("POPUPOB048"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               df_bearing_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_option_frame,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(map_view_toggle,XmNvalueChangedCallback,Map_View_object_toggle,(XtPointer)p_station);
+
+
+
+//----- Frame for Probability Circles info
+if (Probability_circles_enabled) {
+
+        //fprintf(stderr,"Drawing probability circle data\n");
+
+        probability_frame = XtVaCreateManagedWidget("Set_Del_Object probability_frame", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               map_view_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Probability Circles"
+        probability_ts  = XtVaCreateManagedWidget(langcode("POPUPOB047"),
+                xmLabelWidgetClass,
+                probability_frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        probability_form =  XtVaCreateWidget("Set_Del_Object probability_form",
+                xmFormWidgetClass, 
+                probability_frame,
+                XmNfractionBase,            5,
+                XmNautoUnmanage,            FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Min (mi):"
+        probability_label_min = XtVaCreateManagedWidget(langcode("POPUPOB049"),
+                xmLabelWidgetClass, 
+                probability_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        probability_data_min = XtVaCreateManagedWidget("Set_Del_Object probability_data_min", 
+                xmTextFieldWidgetClass, 
+                probability_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 10,
+                XmNmaxLength,               10,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              probability_label_min,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Max (mi):"
+        probability_label_max = XtVaCreateManagedWidget(langcode("POPUPOB050"),
+                xmLabelWidgetClass, 
+                probability_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               probability_label_min,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        probability_data_max = XtVaCreateManagedWidget("Set_Del_Object probability_data_max", 
+                xmTextFieldWidgetClass, 
+                probability_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 10,
+                XmNmaxLength,               10,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              probability_label_max,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               probability_label_min,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+
+        ob_sep = XtVaCreateManagedWidget("Set_Del_Object ob_sep", 
+                xmSeparatorGadgetClass,
+                ob_form,
+                XmNorientation,             XmHORIZONTAL,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               probability_frame,
+                XmNtopOffset,               14,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+}
+
+
+
+//----- Frame for signpost info
+else if (Signpost_object_enabled) {
+
+        //fprintf(stderr,"Drawing signpost data\n");
+
+        signpost_frame = XtVaCreateManagedWidget("Set_Del_Object signpost_frame", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               map_view_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // "Signpost"
+        signpost_ts  = XtVaCreateManagedWidget(langcode("POPUPOB031"),
+                xmLabelWidgetClass,
+                signpost_frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        signpost_form =  XtVaCreateWidget("Set_Del_Object signpost_form",
+                xmFormWidgetClass, 
+                signpost_frame,
+                XmNfractionBase,            5,
+                XmNautoUnmanage,            FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Signpost Data"
+        signpost_label = XtVaCreateManagedWidget(langcode("POPUPOB030"),
+                xmLabelWidgetClass, 
+                signpost_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        signpost_data = XtVaCreateManagedWidget("Set_Del_Object signpost_data", 
+                xmTextFieldWidgetClass, 
+                signpost_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               3,
+                XmNtopOffset,               3,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              signpost_label,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_sep = XtVaCreateManagedWidget("Set_Del_Object ob_sep", 
+                xmSeparatorGadgetClass,
+                ob_form,
+                XmNorientation,             XmHORIZONTAL,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               signpost_frame,
+                XmNtopOffset,               14,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+}
+
+
+
+//----- Frame for area info
+else if (Area_object_enabled) {
+
+        //fprintf(stderr,"Drawing Area data\n");
+
+        area_frame = XtVaCreateManagedWidget("Set_Del_Object area_frame", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               map_view_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // "Area Options"
+        area_ts  = XtVaCreateManagedWidget(langcode("POPUPOB007"),
+                xmLabelWidgetClass,
+                area_frame,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        area_form =  XtVaCreateWidget("Set_Del_Object area_form",
+                xmFormWidgetClass, 
+                area_frame,
+                XmNfractionBase,            5,
+                XmNautoUnmanage,            FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        // "Bright Color Enable"
+        bright_dim_toggle = XtVaCreateManagedWidget(langcode("POPUPOB009"),
+                xmToggleButtonGadgetClass,
+                area_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNset,                     FALSE,   // Select default to be OFF
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(bright_dim_toggle,XmNvalueChangedCallback,Area_bright_dim_toggle,"1");
+        Area_bright = 0;    // Set to default each time dialog is created
+
+        // "Color-Fill Enable"
+        open_filled_toggle = XtVaCreateManagedWidget(langcode("POPUPOB010"),
+                xmToggleButtonGadgetClass,
+                area_form,
+                XmNtopAttachment,           XmATTACH_FORM,
+                XmNtopOffset,               8,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              bright_dim_toggle,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNset,                     FALSE,   // Select default to be OFF
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(open_filled_toggle,XmNvalueChangedCallback,Area_open_filled_toggle,"1");
+        Area_filled = 0;    // Set to default each time dialog is created
+
+
+// Shape of object
+        ac = 0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+
+        shape_box = XmCreateRadioBox(area_form,
+                "Set_Del_Object Shape Options box",
+                al,
+                ac);
+
+        XtVaSetValues(shape_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,  bright_dim_toggle,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,1,
+                NULL);
+
+
+        // "Circle"
+        toption1 = XtVaCreateManagedWidget(langcode("POPUPOB011"),
+                xmToggleButtonGadgetClass,
+                shape_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(toption1,XmNvalueChangedCallback,Area_type_toggle,"0");
+
+        // "Line-Right '/'"
+        toption2 = XtVaCreateManagedWidget(langcode("POPUPOB013"),
+                xmToggleButtonGadgetClass,
+                shape_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(toption2,XmNvalueChangedCallback,Area_type_toggle,"1");
+
+        // "Line-Left '\'
+        toption3 = XtVaCreateManagedWidget(langcode("POPUPOB012"),
+                xmToggleButtonGadgetClass,
+                shape_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(toption3,XmNvalueChangedCallback,Area_type_toggle,"6");
+
+        // "Triangle"
+        toption4 = XtVaCreateManagedWidget(langcode("POPUPOB014"),
+                xmToggleButtonGadgetClass,
+                shape_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(toption4,XmNvalueChangedCallback,Area_type_toggle,"3");
+
+        // "Rectangle"
+        toption5 = XtVaCreateManagedWidget(langcode("POPUPOB015"),
+                xmToggleButtonGadgetClass,
+                shape_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(toption5,XmNvalueChangedCallback,Area_type_toggle,"4");
+
+
+// Color of object
+        color_box = XmCreateRadioBox(area_form,
+                "Set_Del_Object Color Options box",
+                al,
+                ac);
+
+        XtVaSetValues(color_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, shape_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                NULL);
+
+
+        XtVaSetValues(color_box,
+                XmNnumColumns,4,
+                NULL);
+
+        // "Black"
+        coption1 = XtVaCreateManagedWidget(langcode("POPUPOB016"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption1,XmNvalueChangedCallback,Area_color_toggle,"/0");
+
+        // "Blue"
+        coption2 = XtVaCreateManagedWidget(langcode("POPUPOB017"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption2,XmNvalueChangedCallback,Area_color_toggle,"/1");
+
+        // "Green"
+        coption3 = XtVaCreateManagedWidget(langcode("POPUPOB018"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption3,XmNvalueChangedCallback,Area_color_toggle,"/2");
+
+        // "Cyan"
+        coption4 = XtVaCreateManagedWidget(langcode("POPUPOB019"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption4,XmNvalueChangedCallback,Area_color_toggle,"/3");
+
+        // "Red"
+        coption5 = XtVaCreateManagedWidget(langcode("POPUPOB020"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption5,XmNvalueChangedCallback,Area_color_toggle,"/4");
+
+        // "Violet"
+        coption6 = XtVaCreateManagedWidget(langcode("POPUPOB021"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption6,XmNvalueChangedCallback,Area_color_toggle,"/5");
+
+        // "Yellow"
+        coption7 = XtVaCreateManagedWidget(langcode("POPUPOB022"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption7,XmNvalueChangedCallback,Area_color_toggle,"/6");
+
+        // "Grey"
+        coption8 = XtVaCreateManagedWidget(langcode("POPUPOB023"),
+                xmToggleButtonGadgetClass,
+                color_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(coption8,XmNvalueChangedCallback,Area_color_toggle,"/7");
+
+// Latitude offset
+        // "Offset Up"
+        ob_lat_offset = XtVaCreateManagedWidget(langcode("POPUPOB024"),
+                xmLabelWidgetClass, 
+                area_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_lat_offset_data = XtVaCreateManagedWidget("Set_Del_Object lat offset", 
+                xmTextFieldWidgetClass, 
+                area_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 4,
+                XmNmaxLength,               4,
+                XmNtopOffset,               5,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lat_offset,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+// Longitude offset
+        // "Offset Left (except for '/')"
+        ob_lon_offset = XtVaCreateManagedWidget(langcode("POPUPOB025"),
+                xmLabelWidgetClass, 
+                area_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lat_offset_data,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_lon_offset_data = XtVaCreateManagedWidget("Set_Del_Object long offset", 
+                xmTextFieldWidgetClass, 
+                area_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 4,
+                XmNmaxLength,               4,
+                XmNtopOffset,               5,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lon_offset,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Corridor (Lines only)"
+        ob_corridor = XtVaCreateManagedWidget(langcode("POPUPOB026"),
+                xmLabelWidgetClass, 
+                area_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_lon_offset_data,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        ob_corridor_data = XtVaCreateManagedWidget("Set_Del_Object lat offset", 
+                xmTextFieldWidgetClass, 
+                area_form,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 3,
+                XmNmaxLength,               3,
+                XmNtopOffset,               5,
+                XmNbackground,              colors[0x0f],
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_corridor,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        // "Miles"
+        ob_corridor_miles = XtVaCreateManagedWidget(langcode("UNIOP00004"),
+                xmLabelWidgetClass, 
+                area_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               color_box,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            10,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_corridor_data,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtSetSensitive(ob_corridor,FALSE);
+        XtSetSensitive(ob_corridor_data,FALSE);
+        XtSetSensitive(ob_corridor_miles,FALSE);
+
+
+        ob_sep = XtVaCreateManagedWidget("Set_Del_Object ob_sep", 
+                xmSeparatorGadgetClass,
+                ob_form,
+                XmNorientation,             XmHORIZONTAL,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               area_frame,
+                XmNtopOffset,               14,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+}
+
+
+
+//----- Frame for DF-omni info
+else if (DF_object_enabled) {
+
+        //fprintf(stderr,"Drawing DF data\n");
+
+        // "Omni Antenna"
+        omni_antenna_toggle = XtVaCreateManagedWidget(langcode("POPUPOB041"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               signpost_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              area_toggle,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(omni_antenna_toggle,XmNvalueChangedCallback,Omni_antenna_toggle,(XtPointer)p_station);
+
+
+        // "Beam Antenna"
+        beam_antenna_toggle = XtVaCreateManagedWidget(langcode("POPUPOB042"),
+                xmToggleButtonGadgetClass,
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               omni_antenna_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNbottomOffset,            0,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              area_toggle,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(beam_antenna_toggle,XmNvalueChangedCallback,Beam_antenna_toggle,(XtPointer)p_station);
+
+
+        frameomni = XtVaCreateManagedWidget("Set_Del_Object frameomni", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               map_view_toggle,
+                XmNtopOffset,               0,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        omnilabel  = XtVaCreateManagedWidget(langcode("POPUPOB039"),
+                xmLabelWidgetClass,
+                frameomni,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        formomni =  XtVaCreateWidget("Set_Del_Object formomni",
+                xmFormWidgetClass,
+                frameomni,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        // Power
+        ac = 0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+
+        signal_box = XmCreateRadioBox(formomni,
+                "Set_Del_Object Power Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(signal_box,
+                XmNpacking,               XmPACK_TIGHT,
+                XmNorientation,           XmHORIZONTAL,
+                XmNtopAttachment,         XmATTACH_FORM,
+                XmNtopOffset,             5,
+                XmNbottomAttachment,      XmATTACH_NONE,
+                XmNleftAttachment,        XmATTACH_FORM,
+                XmNleftOffset,            5,
+                XmNrightAttachment,       XmATTACH_FORM,
+                XmNrightOffset,           5,
+                XmNnumColumns,            11,
+                NULL);
+
+        // No signal detected what-so-ever
+        soption0 = XtVaCreateManagedWidget("0",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption0,XmNvalueChangedCallback,Ob_signal_toggle,"0");
+
+        // Detectible signal (Maybe)
+        soption1 = XtVaCreateManagedWidget("1",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption1,XmNvalueChangedCallback,Ob_signal_toggle,"1");
+
+        // Detectible signal (certain but not copyable)
+        soption2 = XtVaCreateManagedWidget("2",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption2,XmNvalueChangedCallback,Ob_signal_toggle,"2");
+
+        // Weak signal marginally readable
+        soption3 = XtVaCreateManagedWidget("3",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption3,XmNvalueChangedCallback,Ob_signal_toggle,"3");
+
+        // Noisy but copyable
+        soption4 = XtVaCreateManagedWidget("4",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption4,XmNvalueChangedCallback,Ob_signal_toggle,"4");
+
+        // Some noise but easy to copy
+        soption5 = XtVaCreateManagedWidget("5",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption5,XmNvalueChangedCallback,Ob_signal_toggle,"5");
+
+        // Good signal with detectible noise
+        soption6 = XtVaCreateManagedWidget("6",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption6,XmNvalueChangedCallback,Ob_signal_toggle,"6");
+
+        // Near full-quieting signal
+        soption7 = XtVaCreateManagedWidget("7",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption7,XmNvalueChangedCallback,Ob_signal_toggle,"7");
+
+        // Dead full-quieting signal, no noise detectible
+        soption8 = XtVaCreateManagedWidget("8",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption8,XmNvalueChangedCallback,Ob_signal_toggle,"8");
+
+        // Extremely strong signal "pins the meter"
+        soption9 = XtVaCreateManagedWidget("9",
+                xmToggleButtonGadgetClass,
+                signal_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(soption9,XmNvalueChangedCallback,Ob_signal_toggle,"9");
+
+
+        // Height
+        height_box = XmCreateRadioBox(formomni,
+                "Set_Del_Object Height Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(height_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,signal_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,10,
+                NULL);
+
+
+        // 10 Feet
+        hoption0 = XtVaCreateManagedWidget(
+                (english_units) ? "10ft" : "3m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption0,XmNvalueChangedCallback,Ob_height_toggle,"0");
+
+        // 20 Feet
+        hoption1 = XtVaCreateManagedWidget(
+                (english_units) ? "20ft" : "6m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption1,XmNvalueChangedCallback,Ob_height_toggle,"1");
+
+        // 40 Feet
+        hoption2 = XtVaCreateManagedWidget(
+                (english_units) ? "40ft" : "12m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption2,XmNvalueChangedCallback,Ob_height_toggle,"2");
+
+        // 80 Feet
+        hoption3 = XtVaCreateManagedWidget(
+                (english_units) ? "80ft" : "24m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption3,XmNvalueChangedCallback,Ob_height_toggle,"3");
+
+        // 160 Feet
+        hoption4 = XtVaCreateManagedWidget(
+                (english_units) ? "160ft" : "49m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption4,XmNvalueChangedCallback,Ob_height_toggle,"4");
+
+        // 320 Feet
+        hoption5 = XtVaCreateManagedWidget(
+                (english_units) ? "320ft" : "98m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption5,XmNvalueChangedCallback,Ob_height_toggle,"5");
+
+        // 640 Feet
+        hoption6 = XtVaCreateManagedWidget(
+                (english_units) ? "640ft" : "195m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption6,XmNvalueChangedCallback,Ob_height_toggle,"6");
+
+        // 1280 Feet
+        hoption7 = XtVaCreateManagedWidget(
+                (english_units) ? "1280ft" : "390m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption7,XmNvalueChangedCallback,Ob_height_toggle,"7");
+
+        // 2560 Feet
+        hoption8 = XtVaCreateManagedWidget(
+                (english_units) ? "2560ft" : "780m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption8,XmNvalueChangedCallback,Ob_height_toggle,"8");
+
+        // 5120 Feet
+        hoption9 = XtVaCreateManagedWidget(
+                (english_units) ? "5120ft" : "1561m",
+                xmToggleButtonGadgetClass,
+                height_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(hoption9,XmNvalueChangedCallback,Ob_height_toggle,"9");
+
+
+        // Gain
+        gain_box = XmCreateRadioBox(formomni,
+                "Set_Del_Object Gain Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(gain_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,height_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,10,
+                NULL);
+
+
+        // 0 dB
+        goption0 = XtVaCreateManagedWidget("0dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption0,XmNvalueChangedCallback,Ob_gain_toggle,"0");
+
+        // 1 dB
+        goption1 = XtVaCreateManagedWidget("1dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption1,XmNvalueChangedCallback,Ob_gain_toggle,"1");
+
+        // 2 dB
+        goption2 = XtVaCreateManagedWidget("2dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption2,XmNvalueChangedCallback,Ob_gain_toggle,"2");
+
+        // 3 dB
+        goption3 = XtVaCreateManagedWidget("3dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption3,XmNvalueChangedCallback,Ob_gain_toggle,"3");
+
+        // 4 dB
+        goption4 = XtVaCreateManagedWidget("4dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption4,XmNvalueChangedCallback,Ob_gain_toggle,"4");
+
+        // 5 dB
+        goption5 = XtVaCreateManagedWidget("5dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption5,XmNvalueChangedCallback,Ob_gain_toggle,"5");
+
+        // 6 dB
+        goption6 = XtVaCreateManagedWidget("6dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption6,XmNvalueChangedCallback,Ob_gain_toggle,"6");
+
+        // 7 dB
+        goption7 = XtVaCreateManagedWidget("7dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption7,XmNvalueChangedCallback,Ob_gain_toggle,"7");
+
+        // 8 dB
+        goption8 = XtVaCreateManagedWidget("8dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption8,XmNvalueChangedCallback,Ob_gain_toggle,"8");
+
+        // 9 dB
+        goption9 = XtVaCreateManagedWidget("9dB",
+                xmToggleButtonGadgetClass,
+                gain_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(goption9,XmNvalueChangedCallback,Ob_gain_toggle,"9");
+
+
+        // Gain
+        directivity_box = XmCreateRadioBox(formomni,
+                "Set_Del_Object Directivity Radio Box",
+                al,
+                ac);
+
+        XtVaSetValues(directivity_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,gain_box,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 5,
+                XmNrightAttachment,XmATTACH_FORM,
+                XmNrightOffset, 5,
+                XmNnumColumns,10,
+                NULL);
+
+
+        // Omni-directional
+        doption0 = XtVaCreateManagedWidget(langcode("WPUPCFS016"),
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption0,XmNvalueChangedCallback,Ob_directivity_toggle,"0");
+
+        // 45 NE
+        doption1 = XtVaCreateManagedWidget("45�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption1,XmNvalueChangedCallback,Ob_directivity_toggle,"1");
+
+        // 90 E
+        doption2 = XtVaCreateManagedWidget("90�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption2,XmNvalueChangedCallback,Ob_directivity_toggle,"2");
+
+        // 135 SE
+        doption3 = XtVaCreateManagedWidget("135�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption3,XmNvalueChangedCallback,Ob_directivity_toggle,"3");
+
+        // 180 S
+        doption4 = XtVaCreateManagedWidget("180�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption4,XmNvalueChangedCallback,Ob_directivity_toggle,"4");
+
+        // 225 SW
+        doption5 = XtVaCreateManagedWidget("225�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption5,XmNvalueChangedCallback,Ob_directivity_toggle,"5");
+
+        // 270 W
+        doption6 = XtVaCreateManagedWidget("270�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption6,XmNvalueChangedCallback,Ob_directivity_toggle,"6");
+
+        // 315 NW
+        doption7 = XtVaCreateManagedWidget("315�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption7,XmNvalueChangedCallback,Ob_directivity_toggle,"7");
+
+        // 360 N
+        doption8 = XtVaCreateManagedWidget("360�",
+                xmToggleButtonGadgetClass,
+                directivity_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(doption8,XmNvalueChangedCallback,Ob_directivity_toggle,"8");
+
+
+//----- Frame for DF-beam info
+        framebeam = XtVaCreateManagedWidget("Set_Del_Object framebeam", 
+                xmFrameWidgetClass, 
+                ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               frameomni,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_FORM,
+                XmNrightOffset,             10,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        beamlabel  = XtVaCreateManagedWidget(langcode("POPUPOB040"),
+                xmLabelWidgetClass,
+                framebeam,
+                XmNchildType,               XmFRAME_TITLE_CHILD,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        formbeam =  XtVaCreateWidget("Set_Del_Object formbeam",
+                xmFormWidgetClass,
+                framebeam,
+                XmNfractionBase,            5,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+
+        // Beam width
+        ac = 0;
+        XtSetArg(al[ac], XmNforeground, MY_FG_COLOR); ac++;
+        XtSetArg(al[ac], XmNbackground, MY_BG_COLOR); ac++;
+
+        width_box = XmCreateRadioBox(formbeam,
+                "Set_Del_Object Width Box",
+                al,
+                ac);
+
+        XtVaSetValues(width_box,
+                XmNpacking,               XmPACK_TIGHT,
+                XmNorientation,           XmHORIZONTAL,
+                XmNtopAttachment,         XmATTACH_FORM,
+                XmNtopOffset,             5,
+                XmNbottomAttachment,      XmATTACH_NONE,
+                XmNleftAttachment,        XmATTACH_FORM,
+                XmNleftOffset,            5,
+                XmNrightAttachment,       XmATTACH_FORM,
+                XmNrightOffset,           5,
+                XmNnumColumns,            11,
+                NULL);
+
+        // Useless
+        woption0 = XtVaCreateManagedWidget(langcode("POPUPOB043"),
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption0,XmNvalueChangedCallback,Ob_width_toggle,"0");
+
+        // < 240 Degrees
+        woption1 = XtVaCreateManagedWidget("<240�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption1,XmNvalueChangedCallback,Ob_width_toggle,"1");
+
+        // < 120 Degrees
+        woption2 = XtVaCreateManagedWidget("<120�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption2,XmNvalueChangedCallback,Ob_width_toggle,"2");
+
+        // < 64 Degrees
+        woption3 = XtVaCreateManagedWidget("<64�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption3,XmNvalueChangedCallback,Ob_width_toggle,"3");
+
+        // < 32 Degrees
+        woption4 = XtVaCreateManagedWidget("<32�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption4,XmNvalueChangedCallback,Ob_width_toggle,"4");
+
+        // < 16 Degrees
+        woption5 = XtVaCreateManagedWidget("<16�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption5,XmNvalueChangedCallback,Ob_width_toggle,"5");
+
+        // < 8 Degrees
+        woption6 = XtVaCreateManagedWidget("<8�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption6,XmNvalueChangedCallback,Ob_width_toggle,"6");
+
+        // < 4 Degrees
+        woption7 = XtVaCreateManagedWidget("<4�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption7,XmNvalueChangedCallback,Ob_width_toggle,"7");
+
+        // < 2 Degrees
+        woption8 = XtVaCreateManagedWidget("<2�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption8,XmNvalueChangedCallback,Ob_width_toggle,"8");
+
+        // < 1 Degrees
+        woption9 = XtVaCreateManagedWidget("<1�",
+                xmToggleButtonGadgetClass,
+                width_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(woption9,XmNvalueChangedCallback,Ob_width_toggle,"9");
+
+
+        // "Bearing"
+        ob_bearing = XtVaCreateManagedWidget(langcode("POPUPOB046"),
+                xmLabelWidgetClass, 
+                formbeam,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               width_box,
+                XmNtopOffset,               10,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNleftOffset,              10,
+                XmNrightAttachment,         XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        // Bearing data
+        ob_bearing_data = XtVaCreateManagedWidget("Set_Del_Object ob_bearing_data", 
+                xmTextFieldWidgetClass, 
+                formbeam,
+                XmNeditable,                TRUE,
+                XmNcursorPositionVisible,   TRUE,
+                XmNsensitive,               TRUE,
+                XmNshadowThickness,         1,
+                XmNcolumns,                 9,
+                XmNmaxLength,               9,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               width_box,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_WIDGET,
+                XmNleftWidget,              ob_bearing,
+                XmNrightAttachment,         XmATTACH_NONE,
+                XmNbackground,              colors[0x0f],
+                XmNfontList, fontlist1,
+                NULL);
+
+
+        XtSetSensitive(frameomni,FALSE);
+        XtSetSensitive(framebeam,FALSE);
+        Omni_antenna_enabled = 0;
+        Beam_antenna_enabled = 0;
+
+
+        ob_sep = XtVaCreateManagedWidget("Set_Del_Object ob_sep", 
+                xmSeparatorGadgetClass,
+                ob_form,
+                XmNorientation,             XmHORIZONTAL,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               framebeam,
+                XmNtopOffset,               14,
+                XmNbottomAttachment,        XmATTACH_NONE,
+                XmNleftAttachment,          XmATTACH_FORM,
+                XmNrightAttachment,         XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+}
+// End of DF-specific widgets
+
+
+
+//----- No Special options selected.  We need a widget here for the next widget to attach to.
+        if (!DF_object_enabled
+                && !Area_object_enabled
+                && !Signpost_object_enabled
+                && !Probability_circles_enabled) {
+
+            //fprintf(stderr,"No special object types\n");
+
+            ob_sep = XtVaCreateManagedWidget("Set_Del_Object ob_sep", 
+                    xmSeparatorGadgetClass,
+                    ob_form,
+                    XmNorientation,             XmHORIZONTAL,
+                    XmNtopAttachment,           XmATTACH_WIDGET,
+                    XmNtopWidget,               map_view_toggle,
+                    XmNtopOffset,               0,
+                    XmNbottomAttachment,        XmATTACH_NONE,
+                    XmNleftAttachment,          XmATTACH_FORM,
+                    XmNrightAttachment,         XmATTACH_FORM,
+                    MY_FOREGROUND_COLOR,
+                    MY_BACKGROUND_COLOR,
+                    XmNfontList, fontlist1,
+                    NULL);
+        }
+
+
+
+//----- Buttons
+        if (p_station != NULL) {  // We were called from the Modify_object() or Move function
+
+            // Change the buttons/callbacks based on whether we're dealing with an item or an object
+            if ((p_station->flag & ST_ITEM) != 0) {     // Modifying an Item
+                // Here we need Modify Item/Delete Item/Cancel buttons
+                ob_button_set = XtVaCreateManagedWidget(langcode("POPUPOB034"),
+                        xmPushButtonGadgetClass, 
+                        ob_form,
+                        XmNtopAttachment,           XmATTACH_WIDGET,
+                        XmNtopWidget,               ob_sep,
+                        XmNtopOffset,               5,
+                        XmNbottomAttachment,        XmATTACH_FORM,
+                        XmNbottomOffset,            5,
+                        XmNleftAttachment,          XmATTACH_POSITION,
+                        XmNleftPosition,            0,
+                        XmNrightAttachment,         XmATTACH_POSITION,
+                        XmNrightPosition,           1,
+                        XmNnavigationType,          XmTAB_GROUP,
+                        MY_FOREGROUND_COLOR,
+                        MY_BACKGROUND_COLOR,
+                        XmNfontList, fontlist1,
+                        NULL);
+                XtAddCallback(ob_button_set, XmNactivateCallback, Item_change_data_set, object_dialog);
+
+                // Check whether we own this item
+                if (strcasecmp(p_station->origin,my_callsign)==0) {
+
+                    // We own this item, set up the "Delete"
+                    // button.
+                    ob_button_del = XtVaCreateManagedWidget(langcode("POPUPOB033"),
+                        xmPushButtonGadgetClass, 
+                        ob_form,
+                        XmNtopAttachment,           XmATTACH_WIDGET,
+                        XmNtopWidget,               ob_sep,
+                        XmNtopOffset,               5,
+                        XmNbottomAttachment,        XmATTACH_FORM,
+                        XmNbottomOffset,            5,
+                        XmNleftAttachment,          XmATTACH_POSITION,
+                        XmNleftPosition,            1,
+                        XmNrightAttachment,         XmATTACH_POSITION,
+                        XmNrightPosition,           2,
+                        XmNnavigationType,          XmTAB_GROUP,
+                        MY_FOREGROUND_COLOR,
+                        MY_BACKGROUND_COLOR,
+                        XmNfontList, fontlist1,
+                        NULL);
+                    XtAddCallback(ob_button_del, XmNactivateCallback, Item_change_data_del, object_dialog);
+                }
+                else {
+
+                    // Somebody else owns this item, set up the
+                    // "Adopt" button.
+                    ob_button_del = XtVaCreateManagedWidget(langcode("POPUPOB045"),
+                        xmPushButtonGadgetClass, 
+                        ob_form,
+                        XmNtopAttachment,           XmATTACH_WIDGET,
+                        XmNtopWidget,               ob_sep,
+                        XmNtopOffset,               5,
+                        XmNbottomAttachment,        XmATTACH_FORM,
+                        XmNbottomOffset,            5,
+                        XmNleftAttachment,          XmATTACH_POSITION,
+                        XmNleftPosition,            1,
+                        XmNrightAttachment,         XmATTACH_POSITION,
+                        XmNrightPosition,           2,
+                        XmNnavigationType,          XmTAB_GROUP,
+                        MY_FOREGROUND_COLOR,
+                        MY_BACKGROUND_COLOR,
+                        XmNfontList, fontlist1,
+                        NULL);
+                    XtAddCallback(ob_button_del, XmNactivateCallback, Item_change_data_set, object_dialog);
+                }
+            }
+            else {  // Modifying an Object
+                // Here we need Modify Object/Delete Object/Cancel buttons
+                ob_button_set = XtVaCreateManagedWidget(langcode("POPUPOB005"),
+                        xmPushButtonGadgetClass, 
+                        ob_form,
+                        XmNtopAttachment,           XmATTACH_WIDGET,
+                        XmNtopWidget,               ob_sep,
+                        XmNtopOffset,               5,
+                        XmNbottomAttachment,        XmATTACH_FORM,
+                        XmNbottomOffset,            5,
+                        XmNleftAttachment,          XmATTACH_POSITION,
+                        XmNleftPosition,            0,
+                        XmNrightAttachment,         XmATTACH_POSITION,
+                        XmNrightPosition,           1,
+                        XmNnavigationType,          XmTAB_GROUP,
+                        MY_FOREGROUND_COLOR,
+                        MY_BACKGROUND_COLOR,
+                        XmNfontList, fontlist1,
+                        NULL);
+                XtAddCallback(ob_button_set, XmNactivateCallback, Object_change_data_set, object_dialog);
+ 
+                // Check whether we own this Object
+                if (strcasecmp(p_station->origin,my_callsign)==0) {
+
+                    // We own this object, set up the "Delete"
+                    // button.
+                    ob_button_del = XtVaCreateManagedWidget(langcode("POPUPOB004"),
+                        xmPushButtonGadgetClass, 
+                        ob_form,
+                        XmNtopAttachment,           XmATTACH_WIDGET,
+                        XmNtopWidget,               ob_sep,
+                        XmNtopOffset,               5,
+                        XmNbottomAttachment,        XmATTACH_FORM,
+                        XmNbottomOffset,            5,
+                        XmNleftAttachment,          XmATTACH_POSITION,
+                        XmNleftPosition,            1,
+                        XmNrightAttachment,         XmATTACH_POSITION,
+                        XmNrightPosition,           2,
+                        XmNnavigationType,          XmTAB_GROUP,
+                        MY_FOREGROUND_COLOR,
+                        MY_BACKGROUND_COLOR,
+                        XmNfontList, fontlist1,
+                        NULL);
+               XtAddCallback(ob_button_del, XmNactivateCallback, Object_change_data_del, object_dialog);
+                }
+                else {
+
+                    // Somebody else owns this object, set up the
+                    // "Adopt" button.
+                    ob_button_del = XtVaCreateManagedWidget(langcode("POPUPOB044"),
+                        xmPushButtonGadgetClass, 
+                        ob_form,
+                        XmNtopAttachment,           XmATTACH_WIDGET,
+                        XmNtopWidget,               ob_sep,
+                        XmNtopOffset,               5,
+                        XmNbottomAttachment,        XmATTACH_FORM,
+                        XmNbottomOffset,            5,
+                        XmNleftAttachment,          XmATTACH_POSITION,
+                        XmNleftPosition,            1,
+                        XmNrightAttachment,         XmATTACH_POSITION,
+                        XmNrightPosition,           2,
+                        XmNnavigationType,          XmTAB_GROUP,
+                        MY_FOREGROUND_COLOR,
+                        MY_BACKGROUND_COLOR,
+                        XmNfontList, fontlist1,
+                        NULL);
+                    XtAddCallback(ob_button_del, XmNactivateCallback, Object_change_data_set, object_dialog);
+                }
+            }
+        }
+        else {  // We were called from Create->Object mouse menu
+            ob_button_set = XtVaCreateManagedWidget(langcode("POPUPOB003"),xmPushButtonGadgetClass, ob_form,
+                    XmNtopAttachment,           XmATTACH_WIDGET,
+                    XmNtopWidget,               ob_sep,
+                    XmNtopOffset,               5,
+                    XmNbottomAttachment,        XmATTACH_FORM,
+                    XmNbottomOffset,            5,
+                    XmNleftAttachment,          XmATTACH_POSITION,
+                    XmNleftPosition,            0,
+                    XmNrightAttachment,         XmATTACH_POSITION,
+                    XmNrightPosition,           1,
+                    XmNnavigationType,          XmTAB_GROUP,
+                    MY_FOREGROUND_COLOR,
+                    MY_BACKGROUND_COLOR,
+                    XmNfontList, fontlist1,
+                    NULL);
+
+            it_button_set = XtVaCreateManagedWidget(langcode("POPUPOB006"),xmPushButtonGadgetClass, ob_form,
+                    XmNtopAttachment,           XmATTACH_WIDGET,
+                    XmNtopWidget,               ob_sep,
+                    XmNtopOffset,               5,
+                    XmNbottomAttachment,        XmATTACH_FORM,
+                    XmNbottomOffset,            5,
+                    XmNleftAttachment,          XmATTACH_POSITION,
+                    XmNleftPosition,            1,
+                    XmNrightAttachment,         XmATTACH_POSITION,
+                    XmNrightPosition,           2,
+                    XmNnavigationType,          XmTAB_GROUP,
+                    MY_FOREGROUND_COLOR,
+                    MY_BACKGROUND_COLOR,
+                    XmNfontList, fontlist1,
+                    NULL);
+
+
+            // Changed to different callback routines here which
+            // check the new object/item name against our internal
+            // database then call
+            // Object_change_data_set/Item_change_data_set if all
+            // ok.  If a conflict (object/item already exists), do a
+            // popup_message() instead or bring up a confirmation
+            // dialog before creating the object/item.
+            //
+            //XtAddCallback(ob_button_set,
+            //    XmNactivateCallback,
+            //    Object_change_data_set,
+            //    object_dialog);
+            //XtAddCallback(it_button_set,
+            //    XmNactivateCallback,
+            //    Item_change_data_set,
+            //    object_dialog);
+            XtAddCallback(ob_button_set,
+                XmNactivateCallback,
+                Object_confirm_data_set,
+                object_dialog);
+            XtAddCallback(it_button_set,
+                XmNactivateCallback,
+                Item_confirm_data_set,
+                object_dialog);
+        }
+        
+        ob_button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, ob_form,
+                XmNtopAttachment,           XmATTACH_WIDGET,
+                XmNtopWidget,               ob_sep,
+                XmNtopOffset,               5,
+                XmNbottomAttachment,        XmATTACH_FORM,
+                XmNbottomOffset,            5,
+                XmNleftAttachment,          XmATTACH_POSITION,
+                XmNleftPosition,            2,
+                XmNrightAttachment,         XmATTACH_POSITION,
+                XmNrightPosition,           3,
+                XmNnavigationType,          XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XtAddCallback(ob_button_cancel, XmNactivateCallback, Object_destroy_shell,   object_dialog);
+
+
+        // Set ToggleButtons for the current state.  Don't notify the callback
+        // functions associated with them or we'll be in an infinite loop.
+        if (Area_object_enabled)
+            XmToggleButtonSetState(area_toggle, TRUE, FALSE);
+        if (Signpost_object_enabled)
+            XmToggleButtonSetState(signpost_toggle, TRUE, FALSE);
+        if (DF_object_enabled)
+            XmToggleButtonSetState(df_bearing_toggle, TRUE, FALSE);
+        if (Map_View_object_enabled)
+            XmToggleButtonSetState(map_view_toggle, TRUE, FALSE);
+        if (Probability_circles_enabled)
+            XmToggleButtonSetState(probabilities_toggle, TRUE, FALSE);
+
+
+// Fill in current data if object already exists
+        if (p_station != NULL) {  // We were called from the Modify_object() or Move functions
+
+            // Don't allow changing types if the object is already created.
+            // Already tried allowing it, and it causes other problems.
+            XtSetSensitive(area_toggle, FALSE);
+            XtSetSensitive(signpost_toggle, FALSE);
+            XtSetSensitive(df_bearing_toggle, FALSE);
+            XtSetSensitive(map_view_toggle, FALSE);
+            XtSetSensitive(probabilities_toggle, FALSE);
+
+            XmTextFieldSetString(object_name_data,p_station->call_sign);
+            // Need to make the above field non-editable 'cuz we're trying to modify
+            // _parameters_ of the object and the name has to stay the same in order
+            // to do this.  Change the name and we'll be creating a new object instead
+            // of modifying an old one.
+            XtSetSensitive(object_name_data, FALSE);
+            // Would be nice to change the colors too
+
+            // Check for overlay character
+            if (p_station->aprs_symbol.special_overlay) {
+                // Found an overlay character
+                temp_data[0] = p_station->aprs_symbol.special_overlay;
+            }
+            else {  // No overlay character
+                temp_data[0] = p_station->aprs_symbol.aprs_type;
+            }
+            temp_data[1] = '\0';
+            XmTextFieldSetString(object_group_data,temp_data);
+
+            temp_data[0] = p_station->aprs_symbol.aprs_symbol;
+            temp_data[1] = '\0';
+            XmTextFieldSetString(object_symbol_data,temp_data);
+
+            // We only check the first possible comment string in
+            // the record
+            //if (strlen(p_station->comments) > 0)
+            if (Map_View_object_enabled) {
+
+                if ( (p_station->comment_data != NULL)
+                        && (p_station->comment_data->text_ptr != NULL) ) {
+                    char temp[100];
+
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "%s%s",
+                        p_station->power_gain,
+                        p_station->comment_data->text_ptr);
+                    XmTextFieldSetString(object_comment_data,temp);
+                }
+                else {
+                    XmTextFieldSetString(object_comment_data,p_station->power_gain);
+                }
+            }
+
+            else if ( (p_station->comment_data != NULL)
+                    && (p_station->comment_data->text_ptr != NULL) ) {
+                XmTextFieldSetString(object_comment_data,p_station->comment_data->text_ptr);
+            }
+
+            else {
+                XmTextFieldSetString(object_comment_data,"");
+            }
+
+
+//            if ( (p_station->aprs_symbol.area_object.type != AREA_NONE) // Found an area object
+//                    && Area_object_enabled ) {
+if (Area_object_enabled) {
+
+                XtSetSensitive(ob_frame,FALSE);
+                XtSetSensitive(area_frame,TRUE);
+
+                switch (p_station->aprs_symbol.area_object.type) {
+                    case (1):   // Line '/'
+                        XmToggleButtonSetState(toption2, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, FALSE, TRUE);
+                        if (p_station->aprs_symbol.area_object.corridor_width > 0)
+                            xastir_snprintf(temp_data, sizeof(temp_data), "%d",
+                                    p_station->aprs_symbol.area_object.corridor_width );
+                        else
+                            temp_data[0] = '\0';    // Empty string
+
+                        XmTextFieldSetString( ob_corridor_data, temp_data );
+                        break;
+                    case (6):   // Line '\'
+                        XmToggleButtonGadgetSetState(toption3, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, FALSE, TRUE);
+                        if (p_station->aprs_symbol.area_object.corridor_width > 0)
+                            xastir_snprintf(temp_data, sizeof(temp_data), "%d",
+                                    p_station->aprs_symbol.area_object.corridor_width );
+                        else
+                            temp_data[0] = '\0';    // Empty string
+
+                        XmTextFieldSetString( ob_corridor_data, temp_data );
+                        break;
+                    case (3):   // Open Triangle
+                        XmToggleButtonGadgetSetState(toption4, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, FALSE, TRUE);
+                        break;
+                    case (4):   // Open Rectangle
+                        XmToggleButtonGadgetSetState(toption5, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, FALSE, TRUE);
+                        break;
+                    case (5):   // Filled Circle
+                        XmToggleButtonGadgetSetState(toption1, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, TRUE, TRUE);
+                        break;
+                    case (8):   // Filled Triangle
+                        XmToggleButtonGadgetSetState(toption4, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, TRUE, TRUE);
+                        break;
+                    case (9):   // Filled Rectangle
+                        XmToggleButtonGadgetSetState(toption5, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, TRUE, TRUE);
+                        break;
+                    case (0):   // Open Circle
+                    default:
+                        XmToggleButtonGadgetSetState(toption1, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(open_filled_toggle, FALSE, TRUE);
+                        break;
+                }
+
+                switch (p_station->aprs_symbol.area_object.color) {
+                    case (1):   // Blue Bright
+                        XmToggleButtonGadgetSetState(coption2, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (2):   // Green Bright
+                        XmToggleButtonGadgetSetState(coption3, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (3):   // Cyan Bright
+                        XmToggleButtonGadgetSetState(coption4, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (4):   // Red Bright
+                        XmToggleButtonGadgetSetState(coption5, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (5):   // Violet Bright
+                        XmToggleButtonGadgetSetState(coption6, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (6):   // Yellow Bright
+                        XmToggleButtonGadgetSetState(coption7, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (7):   // Gray Bright
+                        XmToggleButtonGadgetSetState(coption8, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                    case (8):   // Black Dim
+                        XmToggleButtonGadgetSetState(coption1, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (9):   // Blue Dim
+                        XmToggleButtonGadgetSetState(coption2, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (10):  // Green Dim
+                        XmToggleButtonGadgetSetState(coption3, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (11):  // Cyan Dim
+                        XmToggleButtonGadgetSetState(coption4, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (12):  // Red Dim
+                        XmToggleButtonGadgetSetState(coption5, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (13):  // Violet Dim
+                        XmToggleButtonGadgetSetState(coption6, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (14):  // Yellow Dim
+                        XmToggleButtonGadgetSetState(coption7, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (15):  // Gray Dim
+                        XmToggleButtonGadgetSetState(coption8, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);
+                        break;
+                    case (0):   // Black Bright
+                    default:
+                        XmToggleButtonGadgetSetState(coption1, TRUE, TRUE);
+                        XmToggleButtonGadgetSetState(bright_dim_toggle, TRUE, TRUE);
+                        break;
+                }
+
+                xastir_snprintf(temp_data, sizeof(temp_data), "%d",
+                        p_station->aprs_symbol.area_object.sqrt_lat_off
+                        * p_station->aprs_symbol.area_object.sqrt_lat_off );
+
+                XmTextFieldSetString( ob_lat_offset_data, temp_data );
+
+                xastir_snprintf(temp_data, sizeof(temp_data), "%d",
+                        p_station->aprs_symbol.area_object.sqrt_lon_off
+                        * p_station->aprs_symbol.area_object.sqrt_lon_off );
+
+                XmTextFieldSetString( ob_lon_offset_data, temp_data );
+
+            }   // Done with filling in Area Objects
+
+            else {  // Signpost/Probability/Normal Object
+
+                // Handle Generic Options (common to Signpost/Normal Objects)
+                if (strlen(p_station->speed) != 0) {
+                    xastir_snprintf(temp_data, sizeof(temp_data), "%d",
+                            (int)(atof(p_station->speed) + 0.5) );
+
+                    XmTextFieldSetString( ob_speed_data, temp_data );
+                } else
+                    XmTextFieldSetString( ob_speed_data, "" );
+
+                if (strlen(p_station->course) != 0)
+                    XmTextFieldSetString( ob_course_data, p_station->course);
+                else
+                    XmTextFieldSetString( ob_course_data, "" );
+
+//                if ( (p_station->aprs_symbol.aprs_symbol == 'm')   // Found a signpost object
+//                        && (p_station->aprs_symbol.aprs_type == '\\')
+//                        && Signpost_object_enabled) {
+                if (Signpost_object_enabled) {
+                    XtSetSensitive(ob_frame,FALSE);
+                    XtSetSensitive(signpost_frame,TRUE);
+                    XmTextFieldSetString( signpost_data, p_station->signpost);
+                }   // Done with filling in Signpost Objects
+
+
+                if (Probability_circles_enabled) {
+                    // Fetch the min/max fields from the object data and
+                    // write that data into the input fields.
+                    XmTextFieldSetString( probability_data_min, p_station->probability_min );
+                    XmTextFieldSetString( probability_data_max, p_station->probability_max );
+                }
+
+
+//                else if ( (p_station->aprs_symbol.aprs_type == '/') // Found a DF object
+//                        && (p_station->aprs_symbol.aprs_symbol == '\\' )) {
+                if (DF_object_enabled) {
+                    XtSetSensitive(ob_frame,FALSE);
+                    //fprintf(stderr,"Found a DF object\n");
+
+                    // Decide if it was an omni-DF object or a beam heading object
+                    if (p_station->NRQ[0] == '\0') {    // Must be an omni-DF object
+                        //fprintf(stderr,"omni-DF\n");
+                        //fprintf(stderr,"Signal_gain: %s\n", p_station->signal_gain);
+
+                        XmToggleButtonSetState(omni_antenna_toggle, TRUE, TRUE);
+
+                        // Set the received signal quality toggle
+                        switch (p_station->signal_gain[3]) {
+                            case ('1'):   // 1
+                                XmToggleButtonGadgetSetState(soption1, TRUE, TRUE);
+                                break;
+                            case ('2'):   // 2
+                                XmToggleButtonGadgetSetState(soption2, TRUE, TRUE);
+                                break;
+                            case ('3'):   // 3
+                                XmToggleButtonGadgetSetState(soption3, TRUE, TRUE);
+                                break;
+                            case ('4'):   // 4
+                                XmToggleButtonGadgetSetState(soption4, TRUE, TRUE);
+                                break;
+                            case ('5'):   // 5
+                                XmToggleButtonGadgetSetState(soption5, TRUE, TRUE);
+                                break;
+                            case ('6'):   // 6
+                                XmToggleButtonGadgetSetState(soption6, TRUE, TRUE);
+                                break;
+                            case ('7'):   // 7
+                                XmToggleButtonGadgetSetState(soption7, TRUE, TRUE);
+                                break;
+                            case ('8'):   // 8
+                                XmToggleButtonGadgetSetState(soption8, TRUE, TRUE);
+                                break;
+                            case ('9'):   // 9
+                                XmToggleButtonGadgetSetState(soption9, TRUE, TRUE);
+                                break;
+                            case ('0'):   // 0
+                            default:
+                                XmToggleButtonGadgetSetState(soption0, TRUE, TRUE);
+                                break;
+                        }
+
+                        // Set the HAAT toggle
+                        switch (p_station->signal_gain[4]) {
+                            case ('1'):   // 20ft
+                                XmToggleButtonGadgetSetState(hoption1, TRUE, TRUE);
+                                break;
+                            case ('2'):   // 40ft
+                                XmToggleButtonGadgetSetState(hoption2, TRUE, TRUE);
+                                break;
+                            case ('3'):   // 80ft
+                                XmToggleButtonGadgetSetState(hoption3, TRUE, TRUE);
+                                break;
+                            case ('4'):   // 160ft
+                                XmToggleButtonGadgetSetState(hoption4, TRUE, TRUE);
+                                break;
+                            case ('5'):   // 320ft
+                                XmToggleButtonGadgetSetState(hoption5, TRUE, TRUE);
+                                break;
+                            case ('6'):   // 640ft
+                                XmToggleButtonGadgetSetState(hoption6, TRUE, TRUE);
+                                break;
+                            case ('7'):   // 1280ft
+                                XmToggleButtonGadgetSetState(hoption7, TRUE, TRUE);
+                                break;
+                            case ('8'):   // 2560ft
+                                XmToggleButtonGadgetSetState(hoption8, TRUE, TRUE);
+                                break;
+                            case ('9'):   // 5120ft
+                                XmToggleButtonGadgetSetState(hoption9, TRUE, TRUE);
+                                break;
+                            case ('0'):   // 10ft
+                            default:
+                                XmToggleButtonGadgetSetState(hoption0, TRUE, TRUE);
+                                break;
+                        }
+
+                        // Set the antenna gain toggle
+                        switch (p_station->signal_gain[5]) {
+                            case ('1'):   // 1dB
+                                XmToggleButtonGadgetSetState(goption1, TRUE, TRUE);
+                                break;
+                            case ('2'):   // 2dB
+                                XmToggleButtonGadgetSetState(goption2, TRUE, TRUE);
+                                break;
+                            case ('3'):   // 3dB
+                                XmToggleButtonGadgetSetState(goption3, TRUE, TRUE);
+                                break;
+                            case ('4'):   // 4dB
+                                XmToggleButtonGadgetSetState(goption4, TRUE, TRUE);
+                                break;
+                            case ('5'):   // 5dB
+                                XmToggleButtonGadgetSetState(goption5, TRUE, TRUE);
+                                break;
+                            case ('6'):   // 6dB
+                                XmToggleButtonGadgetSetState(goption6, TRUE, TRUE);
+                                break;
+                            case ('7'):   // 7dB
+                                XmToggleButtonGadgetSetState(goption7, TRUE, TRUE);
+                                break;
+                            case ('8'):   // 8dB
+                                XmToggleButtonGadgetSetState(goption8, TRUE, TRUE);
+                                break;
+                            case ('9'):   // 9dB
+                                XmToggleButtonGadgetSetState(goption9, TRUE, TRUE);
+                                break;
+                            case ('0'):   // 0dB
+                            default:
+                                XmToggleButtonGadgetSetState(goption0, TRUE, TRUE);
+                                break;
+                        }
+
+                        // Set the antenna directivity toggle
+                        switch (p_station->signal_gain[6]) {
+                            case ('1'):   // 45
+                                XmToggleButtonGadgetSetState(doption1, TRUE, TRUE);
+                                break;
+                            case ('2'):   // 90
+                                XmToggleButtonGadgetSetState(doption2, TRUE, TRUE);
+                                break;
+                            case ('3'):   // 135
+                                XmToggleButtonGadgetSetState(doption3, TRUE, TRUE);
+                                break;
+                            case ('4'):   // 180
+                                XmToggleButtonGadgetSetState(doption4, TRUE, TRUE);
+                                break;
+                            case ('5'):   // 225
+                                XmToggleButtonGadgetSetState(doption5, TRUE, TRUE);
+                                break;
+                            case ('6'):   // 270
+                                XmToggleButtonGadgetSetState(doption6, TRUE, TRUE);
+                                break;
+                            case ('7'):   // 315
+                                XmToggleButtonGadgetSetState(doption7, TRUE, TRUE);
+                                break;
+                            case ('8'):   // 360
+                                XmToggleButtonGadgetSetState(doption8, TRUE, TRUE);
+                                break;
+                            case ('0'):   // Omni
+                            default:
+                                XmToggleButtonGadgetSetState(doption0, TRUE, TRUE);
+                                break;
+                        }
+                    }
+                    else {  // Must be a beam-heading object
+                        //fprintf(stderr,"beam-heading\n");
+
+                        XmToggleButtonSetState(beam_antenna_toggle, TRUE, TRUE);
+
+                        XmTextFieldSetString(ob_bearing_data, p_station->bearing);
+
+                        switch (p_station->NRQ[2]) {
+                            case ('1'):   // 240�
+                                XmToggleButtonGadgetSetState(woption1, TRUE, TRUE);
+                                break;
+                            case ('2'):   // 120�
+                                XmToggleButtonGadgetSetState(woption2, TRUE, TRUE);
+                                break;
+                            case ('3'):   // 64�
+                                XmToggleButtonGadgetSetState(woption3, TRUE, TRUE);
+                                break;
+                            case ('4'):   // 32�
+                                XmToggleButtonGadgetSetState(woption4, TRUE, TRUE);
+                                break;
+                            case ('5'):   // 16�
+                                XmToggleButtonGadgetSetState(woption5, TRUE, TRUE);
+                                break;
+                            case ('6'):   // 8�
+                                XmToggleButtonGadgetSetState(woption6, TRUE, TRUE);
+                                break;
+                            case ('7'):   // 4�
+                                XmToggleButtonGadgetSetState(woption7, TRUE, TRUE);
+                                break;
+                            case ('8'):   // 2�
+                                XmToggleButtonGadgetSetState(woption8, TRUE, TRUE);
+                                break;
+                            case ('9'):   // 1�
+                                XmToggleButtonGadgetSetState(woption9, TRUE, TRUE);
+                                break;
+                            case ('0'):   // Useless
+                            default:
+                                XmToggleButtonGadgetSetState(woption0, TRUE, TRUE);
+                                break;
+                        }
+                    }
+                } else {  // Found a normal object
+                    // Nothing needed in this block currently
+                } // Done with filling in Normal objects
+
+            } // Done with filling in Signpost, DF, or Normal Objects
+
+            // Handle Generic Options (common to all)
+            // Convert altitude from meters to feet
+            if (strlen(p_station->altitude) != 0) {
+                xastir_snprintf(temp_data, sizeof(temp_data), "%d",
+                        (int)((atof(p_station->altitude) / 0.3048) + 0.5) );
+
+                XmTextFieldSetString( ob_altitude_data, temp_data );
+            } else
+                XmTextFieldSetString( ob_altitude_data, "" );
+        }
+
+// Else we're creating a new object from scratch:  p_station == NULL
+        else {
+            if (Area_object_enabled) {
+                XmToggleButtonGadgetSetState(coption1, TRUE, TRUE);             // Black
+                XmToggleButtonGadgetSetState(bright_dim_toggle, FALSE, TRUE);   // Dim
+                XmToggleButtonGadgetSetState(toption1, TRUE, TRUE);             // Circle
+            }
+
+            XmTextFieldSetString(object_name_data,"");
+
+
+            // Set the symbol type based on the global variables
+            if (Area_object_enabled) {
+                temp_data[0] = '\\';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_group_data,temp_data);
+
+                temp_data[0] = 'l';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_symbol_data,temp_data);
+
+                XtSetSensitive(ob_frame,FALSE);
+
+
+            } else if (Signpost_object_enabled) {
+                temp_data[0] = '\\';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_group_data,temp_data);
+
+                temp_data[0] = 'm';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_symbol_data,temp_data);
+
+                XmTextFieldSetString( signpost_data, "" );
+
+                XtSetSensitive(ob_frame,FALSE);
+
+
+            } else if (Probability_circles_enabled) {
+                temp_data[0] = '/';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_group_data,temp_data);
+
+                temp_data[0] = '[';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_symbol_data,temp_data);
+
+                XmTextFieldSetString( probability_data_min, "" );
+                XmTextFieldSetString( probability_data_max, "" );
+
+
+            } else if (DF_object_enabled) {
+                temp_data[0] = '/';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_group_data,temp_data);
+
+                temp_data[0] = '\\';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_symbol_data,temp_data);
+
+                // Defaults Omni-DF
+                XmToggleButtonGadgetSetState(soption0, TRUE, TRUE); // Nothing heard
+                XmToggleButtonGadgetSetState(hoption1, TRUE, TRUE); // 20 feet HAAT
+                XmToggleButtonGadgetSetState(goption3, TRUE, TRUE); // 3dB gain antenna
+                XmToggleButtonGadgetSetState(doption0, TRUE, TRUE); // No directivity
+
+                // Defaults Beam-DF
+                XmToggleButtonGadgetSetState(woption5, TRUE, TRUE); // 16 degree beamwidth
+
+                XtSetSensitive(ob_frame,FALSE);
+
+
+            } else if (Map_View_object_enabled){
+                temp_data[0] = '/';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_group_data,temp_data);
+
+                temp_data[0] = 'E';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_symbol_data,temp_data);
+
+                XtSetSensitive(ob_frame,FALSE);
+                XtSetSensitive(ob_option_frame,FALSE);
+
+
+            } else {  // Normal object/item
+                temp_data[0] = '/';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_group_data,temp_data);
+
+                temp_data[0] = '/';
+                temp_data[1] = '\0';
+                XmTextFieldSetString(object_symbol_data,temp_data);
+            }
+
+            // Compute the range for the Map View object and store
+            // it in the comment field.
+            if (Map_View_object_enabled) {
+                double top_range, left_range, max_range;
+                char range[10];
+                Dimension width, height;
+
+
+                // Get the display parameters
+                XtVaGetValues(da,XmNwidth, &width,XmNheight, &height, NULL);
+
+                // Find distance from center to top of screen.
+                // top_range = distance from center_longitude,
+                // center_latitude to center_longitude,
+                // center_latitude-((height*scale_y)/2).
+                top_range = calc_distance(center_latitude,
+                    center_longitude,
+                    NW_corner_latitude,
+                    center_longitude);
+//fprintf(stderr," top_range:%1.0f meters\n", top_range);
+                // Find distance from center to left of screen.
+                // left_range = distance from center_longitude,
+                // center_latitude to
+                // center_longitude-((width*scale_x)/2),
+                // center_latitude.
+                left_range = calc_distance(center_latitude,
+                    center_longitude,
+                    center_latitude,
+                    NW_corner_longitude);
+//fprintf(stderr,"left_range:%1.0f meters\n", left_range);
+
+                // Compute greater of the two.  This is our range in
+                // meters.
+                if (top_range > left_range)
+                    max_range = top_range;
+                else
+                    max_range = left_range;
+
+                // Convert from meters to miles
+                max_range = max_range / 1000.0;  // kilometers
+                max_range = max_range * 0.62137; // miles
+
+                // Restrict it to four digits.
+                if (max_range > 9999.0)
+                    max_range = 9999.0;
+
+//fprintf(stderr,"Range:%04d miles\n", (int)(max_range + 0.5));
+
+                xastir_snprintf(range,
+                    sizeof(range),
+                    "RNG%04d",
+                    (int)(max_range + 0.5)); // Poor man's rounding
+ 
+                XmTextFieldSetString(object_comment_data, range);
+            }
+            else {
+                XmTextFieldSetString(object_comment_data,"");
+            }
+        }
+
+
+
+        if (strcmp(calldata,"2") != 0) {  // Normal Modify->Object or Create->Object behavior
+            // Fill in original lat/lon values
+            convert_lat_l2s(lat, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+            substr(temp_data,lat_str,2);
+            XmTextFieldSetString(object_lat_data_deg,temp_data);
+            substr(temp_data,lat_str+2,6);
+            XmTextFieldSetString(object_lat_data_min,temp_data);
+            substr(temp_data,lat_str+8,1);
+            XmTextFieldSetString(object_lat_data_ns,temp_data);
+
+            convert_lon_l2s(lon, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+            substr(temp_data,lon_str,3);
+            XmTextFieldSetString(object_lon_data_deg,temp_data);
+            substr(temp_data,lon_str+3,6);
+            XmTextFieldSetString(object_lon_data_min,temp_data);
+            substr(temp_data,lon_str+9,1);
+            XmTextFieldSetString(object_lon_data_ew,temp_data);
+        }
+
+        else  { // We're in the middle of moving an object, calldata was "2"
+            // Fill in new lat/long values
+            //fprintf(stderr,"Here we will fill in the new lat/long values\n");
+            x = (center_longitude - ((screen_width  * scale_x)/2) + (input_x * scale_x));
+            y = (center_latitude  - ((screen_height * scale_y)/2) + (input_y * scale_y));
+            if (x < 0)
+                x = 0l;                 // 180�W
+
+            if (x > 129600000l)
+                x = 129600000l;         // 180�E
+
+            if (y < 0)
+                y = 0l;                 //  90�N
+
+            if (y > 64800000l)
+                y = 64800000l;          //  90�S
+
+            convert_lat_l2s(y, lat_str, sizeof(lat_str), CONVERT_HP_NOSP);
+            substr(temp_data,lat_str,2);
+            XmTextFieldSetString(object_lat_data_deg,temp_data);
+            substr(temp_data,lat_str+2,6);
+            XmTextFieldSetString(object_lat_data_min,temp_data);
+            substr(temp_data,lat_str+8,1);
+            XmTextFieldSetString(object_lat_data_ns,temp_data);
+
+            convert_lon_l2s(x, lon_str, sizeof(lon_str), CONVERT_HP_NOSP);
+            substr(temp_data,lon_str,3);
+            XmTextFieldSetString(object_lon_data_deg,temp_data);
+            substr(temp_data,lon_str+3,6);
+            XmTextFieldSetString(object_lon_data_min,temp_data);
+            substr(temp_data,lon_str+9,1);
+            XmTextFieldSetString(object_lon_data_ew,temp_data);
+        }
+
+        XtAddCallback(object_group_data, XmNvalueChangedCallback, updateObjectPictureCallback, object_dialog);
+        XtAddCallback(object_symbol_data, XmNvalueChangedCallback, updateObjectPictureCallback, object_dialog);
+
+        // update symbol picture
+        (void)updateObjectPictureCallback((Widget)NULL,(XtPointer)NULL,(XtPointer)NULL);
+
+        pos_dialog(object_dialog);
+
+        delw = XmInternAtom(XtDisplay(object_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(object_dialog, delw, Object_destroy_shell, (XtPointer)object_dialog);
+
+        if (Signpost_object_enabled) {
+            XtManageChild(signpost_form);
+        } else if (Probability_circles_enabled) {
+            XtManageChild(probability_form);
+        } else if (Area_object_enabled) {
+            XtManageChild(shape_box);
+            XtManageChild(color_box);
+            XtManageChild(area_form);
+        } else if (DF_object_enabled) {
+            XtManageChild(signal_box);
+            XtManageChild(height_box);
+            XtManageChild(gain_box);
+            XtManageChild(directivity_box);
+            XtManageChild(width_box);
+            XtManageChild(formomni);
+            XtManageChild(formbeam);
+        }
+
+        XtManageChild(ob_latlon_form);
+        XtManageChild(ob_option_form);
+        XtManageChild(ob_form1);
+        XtManageChild(ob_form);
+        XtManageChild(ob_pane);
+
+        XtPopup(object_dialog,XtGrabNone);
+        fix_dialog_size(object_dialog);         // don't allow a resize
+
+        // Move focus to the Cancel button.  This appears to highlight t
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(object_dialog);
+        XmProcessTraversal(ob_button_cancel, XmTRAVERSE_CURRENT);
+    }
+
+    // This will cause the move to happen quickly without any button presses.
+    if (calldata != NULL) { // If we're doing a "move" operation
+        if (strcmp(calldata,"2") == 0) {
+            if ((p_station->flag & ST_ITEM) != 0) {     // Moving an Item
+//fprintf(stderr,"Calling Item_change_data_set()\n");
+                Item_change_data_set(w,object_dialog,object_dialog);    // Move it now!
+//fprintf(stderr,"Done with call\n");
+            }
+            else {                                      // Moving an Object
+//fprintf(stderr,"Calling Object_change_data_set()\n");
+                Object_change_data_set(w,object_dialog,object_dialog);  // Move it now!
+//fprintf(stderr,"Done with call\n");
+            }
+        }
+    }
+
+}   // End of Set_Del_Object
+
+
+
+
+
+/*
+ *  Change data for current object
+ *  If calldata = 2, we're doing a move object operation.  Pass the
+ *  value on through to Set_Del_Object.
+ */
+void Modify_object( Widget w, XtPointer clientData, XtPointer calldata) {
+    DataRow *p_station = clientData;
+
+    //if (calldata != NULL)
+    //    fprintf(stderr,"Modify_object:  calldata:  %s\n", (char *)calldata);
+    
+    //fprintf(stderr,"Object Name: %s\n", p_station->call_sign);
+
+    // Only move the object if it is our callsign, else force the
+    // user to adopt the object first, then move it.
+    //
+    // Not exact match (this one is useful for testing)
+////    if (!is_my_call(p_station->origin,0)) {
+//    if (!is_my_object_item(p_station)) {
+    //
+    // Exact match includes SSID (this one is for production code)
+//    if (!is_my_call(p_station->origin,1)) {
+    if (!is_my_object_item(p_station)) {
+
+        // It's not from my callsign
+        if (strncmp(calldata,"2",1) == 0) {
+
+            // We're doing a Move Object operation
+            //fprintf(stderr,"Modify_object:  Object not owned by
+            //me!\n");
+            popup_message_always(langcode("POPEM00035"),
+                langcode("POPEM00042"));
+            return;
+        }
+    }
+
+    Set_Del_Object( w, p_station, calldata );
+}
+
+
+
+
+
+//
+// Disown function called by object/item decode routines.
+// If an object/item is received that matches something in our
+// object.log file, we immediately cease to transmit that object and
+// we mark each line containing that object in our log file with a
+// hash mark ('#').  This comments out that object so that the next
+// time we reboot, we won't start transmitting it again.
+
+// Note that the length of "line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+void disown_object_item(char *call_sign, char *new_owner) {
+    char *ptr;
+    char file[200];
+    char file_temp[200];
+    FILE *f;
+    FILE *f_temp;
+    char line[300];
+    char name[15];
+    int ret;
+
+
+//fprintf(stderr,"disown_object_item, object: %s, new_owner: %s\n",
+//    call_sign,
+//    new_owner);
+
+
+    // If it's my call in the new_owner field, then I must have just
+    // deleted the object and am transmitting a killed object for
+    // it.  If it's not my call, someone else has assumed control of
+    // the object.
+    //
+    // Comment out any references to the object in the log file so
+    // that we don't start retransmitting it on a restart.
+
+    if (is_my_call(new_owner,1)) { // Exact match includes SSID
+        //fprintf(stderr,"Commenting out %s in object.log\n",
+        //call_sign);
+    }
+    else {
+        fprintf(stderr,"Disowning '%s': '%s' is taking over control of it.\n",
+            call_sign, new_owner);
+    }
+
+    get_user_base_dir("config/object.log", file, sizeof(file));
+
+    get_user_base_dir("config/object-temp.log", file_temp, sizeof(file_temp));
+
+    //fprintf(stderr,"%s\t%s\n",file,file_temp);
+
+    // Our own internal function from util.c
+    ret = copy_file(file, file_temp);
+    if (ret) {
+        fprintf(stderr,"\n\nCouldn't create temp file %s!\n\n\n",
+            file_temp);
+        return;
+    }
+
+    // Open the temp file and write to the original file, with hash
+    // marks in front of the appropriate lines.
+    f_temp=fopen(file_temp,"r");
+    f=fopen(file,"w");
+
+    if (f == NULL) {
+        fprintf(stderr,"Couldn't open %s\n",file);
+        return;
+    }
+    if (f_temp == NULL) {
+        fprintf(stderr,"Couldn't open %s\n",file_temp);
+        return;
+    }
+
+    // Read lines from the temp file and write them to the standard
+    // file, modifying them as necessary.
+    while (fgets(line, 300, f_temp) != NULL) {
+
+        // Need to check that the length matches for both!  Best way
+        // is to parse the object/item name out of the string and
+        // then do a normal string compare between the two.
+
+        if (line[0] == ';') {       // Object
+            substr(name,&line[1],9);
+            name[9] = '\0';
+            remove_trailing_spaces(name);
+        }
+
+        else if (line[0] == ')') {  // Item
+            int i;
+
+            // 3-9 char name
+            for (i = 1; i <= 9; i++) {
+                if (line[i] == '!' || line[i] == '_') {
+                    name[i-1] = '\0';
+                    break;
+                }
+                name[i-1] = line[i];
+            }
+            name[9] = '\0';  // In case we never saw '!' || '_'
+
+            // Don't remove trailing spaces for Items, else we won't
+            // get a match.
+        }
+
+        else if (line[1] == ';') {  // Commented out Object
+            substr(name,&line[2],10);
+            name[9] = '\0';
+            remove_trailing_spaces(name);
+
+        }
+
+        else if (line[1] == ')') {  // Commented out Item
+            int i;
+
+            // 3-9 char name
+            for (i = 2; i <= 10; i++) {
+                if (line[i] == '!' || line[i] == '_') {
+                    name[i-1] = '\0';
+                    break;
+                }
+                name[i-1] = line[i];
+            }
+            name[9] = '\0';  // In case we never saw '!' || '_'
+
+            // Don't remove trailing spaces for Items, else we won't
+            // get a match.
+        }
+
+
+        //fprintf(stderr,"'%s'\t'%s'\n", name, call_sign);
+
+        if (valid_object(name)) {
+
+            if ( strcmp(name,call_sign) == 0 ) {
+                // Match.  Comment it out in the file unless it's
+                // already commented out.
+                if (line[0] != '#') {
+                    fprintf(f,"#%s",line);
+                    //fprintf(stderr,"#%s",line);
+                }
+                else {
+                    fprintf(f,"%s",line);
+                    //fprintf(stderr,"%s",line);
+                }
+            }
+            else {
+                // No match.  Copy the line verbatim unless it's
+                // just a
+                // blank line.
+                if (line[0] != '\n') {
+                    fprintf(f,"%s",line);
+                    //fprintf(stderr,"%s",line);
+                }
+            }
+        }
+    }
+    fclose(f);
+    fclose(f_temp);
+}
+
+
+
+
+
+//
+// Logging function called by object/item create/modify routines.
+// We log each object/item as one line in a file.
+//
+// We need to check for objects of the same name in the file,
+// deleting lines that have the same name, and adding new records to
+// the end.  Actually  BAD IDEA!  We want to keep the history of the
+// object so that we can trace its movements later.
+//
+// Note that the length of "line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+// Change this function so that deleted objects/items get disowned
+// instead (commented out in the file so that they're not
+// transmitted again after a restart).  See disown_object_item().
+//
+void log_object_item(char *line, int disable_object, char *object_name) {
+    char file[MAX_VALUE];
+    FILE *f;
+
+    get_user_base_dir("config/object.log", file, sizeof(file));
+
+    f=fopen(file,"a");
+    if (f!=NULL) {
+        fprintf(f,"%s\n",line);
+        (void)fclose(f);
+
+        if (debug_level & 1)
+            fprintf(stderr,"Saving object/item to file: %s",line);
+
+        // Comment out all instances of the object/item in the log
+        // file.  This will make sure that the object is not
+        // retransmitted again when Xastir is restarted.
+        if (disable_object) {
+            disown_object_item(object_name, my_callsign);
+       }
+
+    }
+    else {
+        fprintf(stderr,"Couldn't open file for appending: %s\n", file);
+    }
+}
+
+
+
+
+
+//
+// Function to load saved objects and items back into Xastir.  This
+// is called on startup.  This implements persistent objects/items
+// across Xastir restarts.
+//
+// Note that the length of "line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+// This appears to skip the loading of killed objects/items.  We may
+// instead want to begin transmitting them again until they time
+// out, then mark them with a '#' in the log file at that point.
+//
+void reload_object_item(void) {
+    char file[MAX_VALUE];
+    FILE *f;
+    char line[300+1];
+    char line2[300+1];
+    int save_state;
+
+
+    get_user_base_dir("config/object.log", file, sizeof(file));
+
+    f=fopen(file,"r");
+    if (f!=NULL) {
+
+        // Turn off duplicate point checking (need this in order to
+        // work with SAR objects).  Save state so that we don't mess
+        // it up.
+        save_state = skip_dupe_checking;
+        skip_dupe_checking++;
+
+        while (fgets(line, 300, f) != NULL) {
+
+            if (debug_level & 1)
+                fprintf(stderr,"Loading object/item from file: %s",line);
+
+            if (line[0] != '#') {   // Skip comment lines
+                xastir_snprintf(line2,
+                    sizeof(line2),
+                    "%s>%s:%s",
+                    my_callsign,
+                    VERSIONFRM,
+                    line);
+
+                // Decode this packet.  This will put it into our
+                // station database and cause it to be transmitted
+                // at
+                // regular intervals.  Port is set to -1 here.
+                decode_ax25_line( line2, DATA_VIA_LOCAL, -1, 1);
+
+// Right about here we could do a lookup for the object/item
+// matching the name and change the timing on it.  This could serve
+// to spread the transmit timing out a bit so that all objects/items
+// are not transmitted together.  Another easier option would be to
+// change the routine which chooses when to transmit, having it
+// randomize the numbers a bit each time.  I chose the second
+// option.
+
+            }
+        }
+        (void)fclose(f);
+
+        // Restore the skip_dupe_checking state
+        skip_dupe_checking = save_state;
+
+        // Update the screen
+        redraw_symbols(da);
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_final,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            screen_width,
+            screen_height,
+            0,
+            0);
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"Couldn't open file for reading: %s\n", file);
+    }
+
+    // Start transmitting these objects in about 30 seconds.
+    // Prevent transmission of objects until sometime after we're
+    // done with our initial load.
+    last_object_check = sec_now() + 30;
+}
+
+
diff --git a/src/objects.h b/src/objects.h
new file mode 100644
index 0000000..118dfe4
--- /dev/null
+++ b/src/objects.h
@@ -0,0 +1,160 @@
+/*
+ * $Id: objects.h,v 1.14 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_OBJECTS_H
+#define XASTIR_OBJECTS_H
+
+#include <X11/Intrinsic.h>
+#include <stdint.h>
+
+
+// For mutex debugging with Linux threads only
+#ifdef __linux__
+  #define MUTEX_DEBUG 1
+#endif  // __linux__
+
+
+#ifdef __LCLINT__
+#define PACKAGE "xastir"
+#define VERSION "lclint"
+#define VERSIONTXT "xastir lclint debug version"
+#else   // __LCLINT__
+#define VERSIONTXT PACKAGE " " VERSION
+#endif  // __LCLINT__
+
+
+extern Widget object_dialog;
+extern Widget object_group_data;
+extern Widget object_symbol_data;
+extern void updateObjectPictureCallback(Widget w,XtPointer clientData,XtPointer callData);
+
+extern void Draw_All_CAD_Objects(Widget w);
+extern void Draw_CAD_Objects_erase_dialog(Widget w, XtPointer clientData, XtPointer callData);
+extern void Draw_CAD_Objects_list_dialog(Widget w, XtPointer clientData, XtPointer callData);
+extern int draw_CAD_objects_flag;
+extern int polygon_last_x;
+extern int polygon_last_y;
+extern int doing_move_operation;
+extern char last_object[9+1];
+extern char last_obj_grp;
+extern char last_obj_sym;
+extern int CAD_draw_objects;
+extern int CAD_show_label;
+extern int CAD_show_raw_probability;
+extern int CAD_show_comment;
+extern int CAD_show_area; 
+
+
+/* JMT - works in FreeBSD */
+#define DISABLE_SETUID_PRIVILEGE do { \
+seteuid(getuid()); \
+setegid(getgid()); \
+if (debug_level & 4) { fprintf(stderr, "Changing euid to %d and egid to %d\n", (int)getuid(), (int)getgid()); } \
+} while(0)
+#define ENABLE_SETUID_PRIVILEGE do { \
+seteuid(euid); \
+setegid(egid); \
+if (debug_level & 4) { fprintf(stderr, "Changing euid to %d and egid to %d\n", (int)euid, (int)egid); } \
+} while(0)
+
+
+
+// --------------------------------------------------------------------
+//
+// Function protypes and globals to support predefined SAR/Public service
+// objects.
+//
+//
+// MAX_NUMBER_OF_PREDEFINED_OBJECTS is the maximum number of predefined 
+// objects that can appear on the Create/Move Here popup menu.
+#define MAX_NUMBER_OF_PREDEFINED_OBJECTS  11
+//
+// PREDEFINED_OBJECT_DATA_LENGTH is the maximum length of a string 
+// that can follow the symbol specifier in a predefined object (such 
+// as a probability circle definition) plus one (for the terminator).
+#define PREDEFINED_OBJECT_DATA_LENGTH 44 
+//
+// number_of_predefined_objects holds the actual number of predefined
+// objects available to display on the Create/Move popup menu.
+int number_of_predefined_objects;  
+// File name of ~/.xastir/config file containing definitions for 
+// a predefined object menu.
+extern char predefined_object_definition_filename[256];
+// Flag to indicate whether or not to load the predefined objects menu
+// from the file specified by predefined_object_definition_filename or 
+// to use the hardcoded SAR object set.  0=use hardcoded SAR
+// 1=use predefined_object_definition_filename
+extern int predefined_menu_from_file;
+
+//extern void Set_Del_Object(Widget w, XtPointer clientData, XtPointer calldata);
+extern void Create_SAR_Object(Widget w, XtPointer clientData, XtPointer calldata);
+
+typedef struct {
+    char call[MAX_CALLSIGN+1];  // Callsign = object name.
+    char page[2];               // APRS symbol code page.
+    char symbol[2];             // APRS symbol specifier.
+    char data[PREDEFINED_OBJECT_DATA_LENGTH]; 
+                                // Data following the symbol.
+    char menu_call[26];         // Name to display on menu.
+    intptr_t index;             // Index of this object 
+                                // in the predefinedObjects array.
+    int show_on_menu;           // !=1 to hide on menu.
+    int index_of_child;         // > -1 to create two objects
+                                // in the same place at the 
+                                // same time, value is the 
+                                // index of the second object
+                                // in the predefinedObjects array.
+} predefinedObject;
+
+
+// predefinedObjects is an array of predefined object definitions,
+// once filled using Populate_predefined_objects it can be traversed
+// to build a list of predefined objects for menus, picklists, or
+// other user interface controls.
+//
+extern predefinedObject predefinedObjects[MAX_NUMBER_OF_PREDEFINED_OBJECTS];
+extern void Populate_predefined_objects(predefinedObject *predefinedObjects);
+
+// --------------------------------------------------------------------
+
+extern int valid_object(char *name);
+extern int valid_item(char *name);
+extern void Object_History_Refresh( Widget w, XtPointer clientData, XtPointer callData);
+extern void Object_History_Clear( Widget w, XtPointer clientData, XtPointer callData);
+extern void  Move_Object( Widget widget, XtPointer clientData, XtPointer callData);
+extern void Draw_CAD_Objects_mode( Widget widget, XtPointer clientData, XtPointer callData);
+extern void Draw_CAD_Objects_close_polygon(Widget w, XtPointer clientData, XtPointer calldata);
+extern void Draw_CAD_Objects_erase(Widget w, XtPointer clientData, XtPointer calldata);
+extern void CAD_vertice_allocate(long latitude, long longitude);
+extern void CAD_object_allocate(long latitude, long longitude);
+extern void Modify_object( Widget w, XtPointer clientData, XtPointer calldata);
+extern void Restore_CAD_Objects_from_file(void);
+extern void disown_object_item(char *call_sign, char *new_owner);
+extern void log_object_item(char *line, int disable_object, char *object_name);
+extern void reload_object_item(void);
+extern void check_and_transmit_objects_items(time_t time);
+
+#endif /* XASTIR_OBJECTS_H */
+
+
diff --git a/src/popup.h b/src/popup.h
new file mode 100644
index 0000000..0a4c344
--- /dev/null
+++ b/src/popup.h
@@ -0,0 +1,47 @@
+/*
+ * $Id: popup.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_POPUP_H
+#define XASTIR_POPUP_H
+
+#define MAX_POPUPS 30
+#define MAX_POPUPS_TIME 600 /* Max time popups will display 600=10min*/
+
+typedef struct
+{
+  char name[10];
+  Widget popup_message_dialog;
+  Widget popup_message_data;
+  Widget pane, form, button_close;
+  time_t sec_opened;
+
+} Popup_Window;
+
+/* from popup_gui.c */
+extern void popup_gui_init(void);
+extern void clear_popup_message_windows(void);
+extern void popup_time_out_check(int curr_sec);
+
+#endif /* XASTIR_POPUP_H */
+
diff --git a/src/popup_gui.c b/src/popup_gui.c
new file mode 100644
index 0000000..9f0215a
--- /dev/null
+++ b/src/popup_gui.c
@@ -0,0 +1,382 @@
+/*
+ * $Id: popup_gui.c,v 1.35 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "popup.h"
+#include "main.h"
+#include "lang.h"
+#include "rotated.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+static Popup_Window pw[MAX_POPUPS];
+static Popup_Window pwb;
+
+static xastir_mutex popup_message_dialog_lock;
+
+
+
+
+
+void popup_gui_init(void)
+{
+    init_critical_section( &popup_message_dialog_lock );
+}
+
+
+
+
+
+/**** Popup Message ******/
+
+void clear_popup_message_windows(void) {
+    int i;
+
+begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:clear_popup_message_windows" );
+
+    for (i=0;i<MAX_POPUPS;i++) {
+        pw[i].popup_message_dialog=(Widget)NULL;
+        pw[i].popup_message_data=(Widget)NULL;
+    }
+
+end_critical_section(&popup_message_dialog_lock, "popup_gui.c:clear_popup_message_windows" );
+
+    pwb.popup_message_dialog=(Widget)NULL;
+    pwb.popup_message_data=(Widget)NULL;
+}
+
+
+
+
+
+static void popup_message_destroy_shell(/*@unused@*/ Widget w,
+                                XtPointer clientData,
+                                /*@unused@*/ XtPointer callData) {
+    int i;
+
+    i=atoi((char *)clientData);
+    XtPopdown(pw[i].popup_message_dialog);
+
+begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message_destroy_shell" );
+
+    XtDestroyWidget(pw[i].popup_message_dialog);
+    pw[i].popup_message_dialog = (Widget)NULL;
+    pw[i].popup_message_data = (Widget)NULL;
+
+end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message_destroy_shell" );
+
+}
+
+
+
+
+
+time_t popup_time_out_check_last = (time_t)0l;
+
+void popup_time_out_check(int curr_sec) {
+    int i;
+
+    // Check only every two minutes or so
+    if (popup_time_out_check_last + 120 < curr_sec) {
+        popup_time_out_check_last = curr_sec;
+
+        for (i=0;i<MAX_POPUPS;i++) {
+            if (pw[i].popup_message_dialog!=NULL) {
+                if ((sec_now()-pw[i].sec_opened)>MAX_POPUPS_TIME) {
+                    XtPopdown(pw[i].popup_message_dialog);
+
+begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_time_out_check" );
+
+                    XtDestroyWidget(pw[i].popup_message_dialog);
+                    pw[i].popup_message_dialog = (Widget)NULL;
+                    pw[i].popup_message_data = (Widget)NULL;
+
+end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_time_out_check" );
+
+                }
+
+            }
+        }
+    }
+}
+
+
+
+
+
+void popup_message_always(char *banner, char *message) {
+    XmString msg_str;
+    int j,i;
+    Atom delw;
+
+
+    if (disable_all_popups)
+        return;
+
+    if (banner == NULL || message == NULL)
+        return;
+
+    i=0;
+    for (j=0; j<MAX_POPUPS; j++) {
+        if (!pw[j].popup_message_dialog) {
+            i=j;
+            j=MAX_POPUPS+1;
+        }
+    }
+
+    if(!pw[i].popup_message_dialog) {
+        if (banner!=NULL && message!=NULL) {
+
+begin_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message" );
+
+            pw[i].popup_message_dialog = XtVaCreatePopupShell(banner,
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNtitleString,banner,
+// An half-hearted attempt at fixing the problem where a popup
+// comes up extremely small.  Setting a minimum size for the popup.
+XmNminWidth, 220,
+XmNminHeight, 80,
+                XmNfontList, fontlist1,
+                NULL);
+
+            pw[i].pane = XtVaCreateWidget("popup_message pane",xmPanedWindowWidgetClass, pw[i].popup_message_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL);
+
+            pw[i].form =  XtVaCreateWidget("popup_message form",xmFormWidgetClass, pw[i].pane,
+                            XmNfractionBase, 5,
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1,
+                            NULL);
+
+            pw[i].popup_message_data = XtVaCreateManagedWidget("popup_message message",xmLabelWidgetClass, pw[i].form,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_FORM,
+                                      XmNrightOffset, 10,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+            pw[i].button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, pw[i].form,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, pw[i].popup_message_data,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset, 5,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 3,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+            sprintf(pw[i].name,"%d",i);
+
+            msg_str=XmStringCreateLtoR(message,XmFONTLIST_DEFAULT_TAG);
+            XtVaSetValues(pw[i].popup_message_data,XmNlabelString,msg_str,NULL);
+            XmStringFree(msg_str);
+
+            XtAddCallback(pw[i].button_close, XmNactivateCallback, popup_message_destroy_shell,(XtPointer)pw[i].name);
+
+            delw = XmInternAtom(XtDisplay(pw[i].popup_message_dialog),"WM_DELETE_WINDOW", FALSE);
+
+            XmAddWMProtocolCallback(pw[i].popup_message_dialog, delw, popup_message_destroy_shell, (XtPointer)pw[i].name);
+
+            pos_dialog(pw[i].popup_message_dialog);
+
+            XtManageChild(pw[i].form);
+            XtManageChild(pw[i].pane);
+
+end_critical_section(&popup_message_dialog_lock, "popup_gui.c:popup_message" );
+
+            XtPopup(pw[i].popup_message_dialog,XtGrabNone);
+
+// An half-hearted attempt at fixing the problem where a popup
+// comes up extremely small.  Commenting out the below so we can
+// change the size if necessary to read the message.
+//            fix_dialog_size(pw[i].popup_message_dialog);
+
+            pw[i].sec_opened=sec_now();
+        }
+    }
+}
+
+
+
+
+
+#ifndef HAVE_ERROR_POPUPS
+//
+// We'll write to STDERR instead since the user doesn't want to see
+// any error popups.  Add a timestamp to the front so we know when
+// the errors happened.
+//
+void popup_message(char *banner, char *message) {
+    char timestring[110];
+
+
+    if (disable_all_popups)
+        return;
+
+    if (banner == NULL || message == NULL)
+        return;
+
+    get_timestamp(timestring);
+    fprintf(stderr, "%s:\n\t%s  %s\n\n", timestring, banner, message);
+}
+#else   // HAVE_ERROR_POPUPS
+//
+// The user wishes to see popup error messages.  Call the routine
+// above which does so.
+//
+void popup_message(char *banner, char *message) {
+    popup_message_always(banner, message);
+}
+#endif  // HAVE_ERROR_POPUPS
+
+
+
+
+
+
+// Must make sure that fonts are not loaded again and again, as this
+// takes a big chunk of memory each time.  Can you say "memory
+// leak"?
+//
+static XFontStruct *id_font=NULL;
+
+
+
+
+ 
+// Routine which pops up a large message for a few seconds in the
+// middle of the screen, then removes it.
+//
+void popup_ID_message(char *banner, char *message) {
+    float my_rotation = 0.0;
+    int x = (int)(screen_width/10);
+    int y = (int)(screen_height/2);
+
+    if (ATV_screen_ID) {
+
+        // Fill the pixmap with grey so that the black ID text will
+        // be seen.
+        (void)XSetForeground(XtDisplay(da),gc,MY_BG_COLOR); // Not a mistake!
+        (void)XSetBackground(XtDisplay(da),gc,MY_BG_COLOR);
+        (void)XFillRectangle(XtDisplay(appshell),
+            pixmap_alerts,
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height);
+
+        /* load font */
+        if(!id_font) {
+            id_font=(XFontStruct *)XLoadQueryFont (XtDisplay(da), rotated_label_fontname[FONT_ATV_ID]);
+ 
+            if (id_font == NULL) {    // Couldn't get the font!!!
+                fprintf(stderr,"popup_ID_message: Couldn't get ATV ID font %s\n",
+                    rotated_label_fontname[FONT_ATV_ID]);
+                pending_ID_message = 0;
+                return;
+            }
+        }
+ 
+        (void)XSetForeground (XtDisplay(da), gc, colors[0x08]);
+
+        //fprintf(stderr,"%0.1f\t%s\n",my_rotation,label_text);
+
+        if (       ( (my_rotation < -90.0) && (my_rotation > -270.0) )
+                || ( (my_rotation >  90.0) && (my_rotation <  270.0) ) ) {
+            my_rotation = my_rotation + 180.0;
+            (void)XRotDrawAlignedString(XtDisplay(da),
+                id_font,
+                my_rotation,
+                pixmap_alerts,
+                gc,
+                x,
+                y,
+                message,
+                BRIGHT);
+        }
+        else {
+            (void)XRotDrawAlignedString(XtDisplay(da),
+                id_font,
+                my_rotation,
+                pixmap_alerts,
+                gc,
+                x,
+                y,
+                message,
+                BLEFT);
+        }
+
+        // Schedule a screen update in roughly 3 seconds
+        remove_ID_message_time = sec_now() + 3;
+        pending_ID_message = 1;
+
+        // Write it to the screen.  Symbols/tracks will disappear during
+        // this short interval time.
+        (void)XCopyArea(XtDisplay(da),
+            pixmap_alerts,
+            XtWindow(da),
+            gc,
+            0,
+            0,
+            (unsigned int)screen_width,
+            (unsigned int)screen_height,
+            0,
+            0);
+    }
+    else {  // ATV Screen ID is not enabled
+        pending_ID_message = 0;
+    }
+}
+
+
diff --git a/src/rac_data.c b/src/rac_data.c
new file mode 100644
index 0000000..cde28ad
--- /dev/null
+++ b/src/rac_data.c
@@ -0,0 +1,386 @@
+/*
+* $Id: rac_data.c,v 1.23 2012/09/23 16:19:22 tvrusso Exp $
+*
+* XASTIR, Amateur Station Tracking and Information Reporting
+* Copyright (C) 1999,2000  Frank Giannandrea
+* Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+//====================================================================
+//    Canadian Callsign Lookup
+//    Richard Hagemeyer, VE3UNW
+//    GNU COPYLEFT applies
+//    1999-11-08
+//
+//    For use with XASTIR by Frank Giannandrea
+//********************************************************************
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "rac_data.h"
+#include "xa_config.h"
+#include "main.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+/* ====================================================================    */
+/*    my version of chomp from perl, removes spaces and dashes    */
+/*                                    */
+/* ******************************************************************** */
+int chomp(char *input, unsigned int i) {
+    unsigned int    x;
+
+    for (x=i; input[x] == ' ' || input[x] == '-'; x--)
+        input[x] = '\0';
+
+    return ( (int)(i-x) );
+}
+
+
+
+
+
+/* ====================================================================    */
+/*    build a new (or newer if I check the file date) index file    */
+/*    check for current ic index file                    */
+/*      FG: added a date check in case the RAC file has been updated.   */
+/*      AMACALL.LST must have a time stamp newer than the index file    */
+/*      time stamp. Use the touch command on the AMACALL.LST file to    */
+/*      make the time current if necessary.                             */
+/* ******************************************************************** */
+int build_rac_index(void) {
+    FILE *fdb;
+    FILE *fndx;
+    unsigned long call_offset = 0;
+    unsigned long x = 0;
+    char racdata[RAC_DATA_LEN+8];
+    char amacall_path[MAX_VALUE];
+
+    get_user_base_dir("data/AMACALL.ndx", amacall_path, sizeof(amacall_path));
+
+    /* ====================================================================    */
+    /*    If the index file is there, exit                */
+    /*                                    */
+    if (filethere(amacall_path)) {
+        /* if file is there make sure the index date is newer */
+      if(file_time(amacall_path)<=file_time(amacall_path)) {
+            return(1);
+        } else {
+
+            // RAC index old, rebuilding
+            statusline(langcode("STIFCC0103"), 1);
+
+            fprintf(stderr,"RAC index is old.  Rebuilding index.\n");
+//            XmTextFieldSetString(text,"RAC Index old rebuilding");
+//            XtManageChild(text);
+//            XmUpdateDisplay(XtParent(text));
+        }
+    }
+    /* ====================================================================    */
+    /*    Open the database and index file                */
+    /*                                    */
+    fdb=fopen(get_data_base_dir("fcc/AMACALL.LST"),"rb");
+    if (fdb==NULL) {
+        fprintf(stderr,"Build:Could not open RAC data base: %s\n", get_data_base_dir("fcc/AMACALL.LST") );
+        return(0);
+    }
+
+    fndx=fopen(amacall_path,"w");
+    if (fndx==NULL) {
+        fprintf(stderr,"Build:Could not open/create RAC data base index: %s\n", amacall_path );
+        (void)fclose(fdb);
+        return(0);
+    }
+    /* ====================================================================    */
+    /*    Skip past the header to the first callsign (VA2AA)        */
+    /*                                    */
+    memset(racdata, 0, sizeof(racdata));
+    while (!feof(fdb) && strncmp(racdata,"VA",2)) {
+        call_offset = (unsigned long)ftell(fdb);
+        if (fgets(racdata, (int)sizeof(racdata), fdb)==NULL) {
+            fprintf(stderr,"Build:header:Unable to read data base\n");
+            (void)fclose(fdb);
+            (void)fclose(fndx);
+            fprintf(stderr,"rc=0\n");
+            return (0);
+        }
+    }
+
+    /* ====================================================================    */
+    /*    write out the current callsign and RBA of the db file         */
+    /*    skip 100 records and do it again until no more            */
+    /*                                    */
+    while (!feof(fdb)) {
+        fprintf(fndx,"%6.6s%li\n",racdata,(long)call_offset);
+        call_offset = (unsigned long)ftell(fdb);
+        for (x=0;x<=100 && !feof(fdb);x++)
+            if (fgets(racdata, (int)sizeof(racdata), fdb)==NULL)
+                break;
+    }
+    (void)fclose(fdb);
+    (void)fclose(fndx);
+
+//    XmTextFieldSetString(text,"");
+//    XtManageChild(text);
+
+    return(1);
+}
+
+
+
+
+
+/* ====================================================================    */
+/*    Check for ic data base file                    */
+/*    Check/build the index                        */
+/*                                    */
+/* ******************************************************************** */
+int check_rac_data(void) {
+    int rac_data_available = 0;
+    if( filethere( get_data_base_dir("fcc/AMACALL.LST") ) ) {
+        if (build_rac_index())
+            rac_data_available=1;
+        else {
+            fprintf(stderr,"Check:Could not build ic data base index\n");
+            rac_data_available=0;
+        }
+    }
+    return(rac_data_available);
+}
+
+
+
+
+
+/* ====================================================================    */
+/*    The real work.  Pass the callsign, get the info            */
+/*                                    */
+/* ******************************************************************** */
+int search_rac_data(char *callsign, rac_record *data) {
+    FILE *fdb;
+    FILE *fndx;
+    char *rc;
+    long call_offset = 0l;
+    char char_offset[16];
+    char index[32];
+    int found = 0;
+    rac_record racdata;
+    /*char        filler[8];*/
+    char amacall_path[MAX_VALUE];
+
+    get_user_base_dir("data/AMACALL.ndx", amacall_path, sizeof(amacall_path));
+
+
+    xastir_snprintf(index, sizeof(index)," ");
+    xastir_snprintf(racdata.callsign, sizeof(racdata.callsign)," ");
+
+    /* ====================================================================    */
+    /*    Search thru the index, get the RBA                */
+    /*                                    */
+
+    fndx = fopen(amacall_path, "r");
+    if(fndx != NULL) {
+        rc = fgets(index, (int)sizeof(index), fndx);
+        xastir_snprintf(char_offset, sizeof(char_offset), "%s", &index[6]);
+        while (!feof(fndx) && strncmp(callsign, index, 6) > 0) {
+            xastir_snprintf(char_offset, sizeof(char_offset), "%s", &index[6]);
+            rc = fgets(index, (int)sizeof(index), fndx);
+        }
+    } else {
+        fprintf(stderr,
+            "Search:Could not open RAC data base index: %s\n",
+            amacall_path );
+
+        return (0);
+    }
+    call_offset = atol(char_offset);
+ 
+    (void)fclose(fndx);
+
+    /* ====================================================================    */
+    /*    Now we have our pointer into the main database (text) file.    */
+    /*    Start from there and linear search the data.            */
+    /*    This will take an avg of 1/2 of the # skipped making the index    */
+    /*                                    */
+
+    fdb = fopen(get_data_base_dir("fcc/AMACALL.LST"), "r");
+    if (fdb != NULL) {
+        (void)fseek(fdb, call_offset, SEEK_SET);
+        if (callsign[5] == '-')
+            (void)chomp(callsign,5);
+
+        while (!feof(fdb) && strncmp((char *)&racdata, callsign, 6) < 0)
+
+//WE7U
+// Problem here:  We're sticking 8 bytes too many into racdata!
+            rc = fgets((char *)&racdata, sizeof(racdata), fdb);
+
+    } else
+        fprintf(stderr,"Search:Could not open RAC data base: %s\n", get_data_base_dir("fcc/AMACALL.LST") );
+
+    /*  || (callsign[5] == '-' && strncmp((char *)&racdata,callsign,5) < 0)) */
+    (void)chomp(racdata.callsign, 6);
+
+    if (!strncmp((char *)racdata.callsign, callsign, 6)) {
+        found = 1;
+
+// Some of these cause problems on 64-bit processors, so commented
+// them out for now.
+//        (void)chomp(racdata.first_name, 35);
+//        (void)chomp(racdata.last_name, 35);
+//        (void)chomp(racdata.address, 70);
+//        (void)chomp(racdata.city, 35);
+//        (void)chomp(racdata.province, 2);
+//        (void)chomp(racdata.postal_code, 10);
+//        (void)chomp(racdata.qual_a, 1);
+//        (void)chomp(racdata.qual_b, 1);
+//        (void)chomp(racdata.qual_c, 1);
+//        (void)chomp(racdata.qual_d, 1);
+//        (void)chomp(racdata.club_name, 141);
+//        (void)chomp(racdata.club_address, 70);
+//        (void)chomp(racdata.club_city, 35);
+//        (void)chomp(racdata.club_province, 2);
+//        (void)chomp(racdata.club_postal_code, 9);
+
+        xastir_snprintf(data->callsign,
+            sizeof(data->callsign),
+            "%s",
+            racdata.callsign);
+
+        xastir_snprintf(data->first_name,
+            sizeof(data->first_name),
+            "%s",
+            racdata.first_name);
+ 
+        xastir_snprintf(data->last_name,
+            sizeof(data->last_name),
+            "%s",
+            racdata.last_name);
+ 
+        xastir_snprintf(data->address,
+            sizeof(data->address),
+            "%s",
+            racdata.address);
+ 
+        xastir_snprintf(data->city,
+            sizeof(data->city),
+            "%s",
+            racdata.city);
+ 
+        xastir_snprintf(data->province,
+            sizeof(data->province),
+            "%s",
+            racdata.province);
+ 
+        xastir_snprintf(data->postal_code,
+            sizeof(data->postal_code),
+            "%s",
+            racdata.postal_code);
+ 
+        xastir_snprintf(data->qual_a,
+            sizeof(data->qual_a),
+            "%s",
+            racdata.qual_a);
+ 
+        xastir_snprintf(data->qual_b,
+            sizeof(data->qual_b),
+            "%s",
+            racdata.qual_b);
+ 
+        xastir_snprintf(data->qual_c,
+            sizeof(data->qual_c),
+            "%s",
+            racdata.qual_c);
+ 
+        xastir_snprintf(data->qual_d,
+            sizeof(data->qual_d),
+            "%s",
+            racdata.qual_d);
+ 
+        xastir_snprintf(data->club_name,
+            sizeof(data->club_name),
+            "%s",
+            racdata.club_name);
+ 
+        xastir_snprintf(data->club_address,
+            sizeof(data->club_address),
+            "%s",
+            racdata.club_address);
+ 
+        xastir_snprintf(data->club_city,
+            sizeof(data->club_city),
+            "%s",
+            racdata.club_city);
+ 
+        xastir_snprintf(data->club_province,
+            sizeof(data->club_province),
+            "%s",
+            racdata.club_province);
+ 
+        xastir_snprintf(data->club_postal_code,
+            sizeof(data->club_postal_code),
+            "%s",
+            racdata.club_postal_code);
+ 
+    }
+    (void)fclose(fdb);
+
+    if (!found) {
+
+        // "Callsign Search", "Callsign Not Found!"
+        popup_message_always(langcode("STIFCC0101"),
+            langcode("STIFCC0102") );
+    }
+ 
+    return(found);
+}
+
+
diff --git a/src/rac_data.h b/src/rac_data.h
new file mode 100644
index 0000000..1cdcbe7
--- /dev/null
+++ b/src/rac_data.h
@@ -0,0 +1,63 @@
+/*
+ * $Id: rac_data.h,v 1.11 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/*
+ * Industry Canada/RAC  Database structure
+ * 472 bytes -- filler is club info
+ * qual fields represent basic, 5wpm, 12wpm, advanced
+ */
+
+#ifndef __XASTIR_RAC_DATA_H
+#define __XASTIR_RAC_DATA_H
+
+#define RAC_DATA_LEN 472
+
+typedef struct {
+    char callsign[7];
+    char first_name[36];
+    char last_name[36];
+    char address[71];
+    char city[36];
+    char province[3];
+    char postal_code[11];
+    char qual_a[2];
+    char qual_b[2];
+    char qual_c[2];
+    char qual_d[2];
+    char club_name[142];
+    char club_address[71];
+    char club_city[36];
+    char club_province[3];
+    char club_postal_code[10];
+    char crlf[2];
+    char filler[8]; // To prevent overruns
+} rac_record;
+
+extern int search_rac_data(char *callsign, rac_record *data);
+extern int search_rac_data_appl(char *callsign, rac_record *data);
+extern int check_rac_data(void);
+
+
+#endif /* __XASTIR_RAC_DATA_H */
+
diff --git a/src/rotated.c b/src/rotated.c
new file mode 100644
index 0000000..03df773
--- /dev/null
+++ b/src/rotated.c
@@ -0,0 +1,1618 @@
+
+// $Id: rotated.c,v 1.24 2012/08/25 16:38:29 tvrusso Exp $
+//
+// Portions Copyright (C) 2000-2012  The Xastir Group
+//
+// Note that this version has been changed since xvertext 5.0 in order
+// to get rid of compiler warnings and such.  The original 5.0 notice
+// is below.  --we7u
+
+
+/* ********************************************************************** */
+
+/* xvertext 5.0, Copyright (c) 1993 Alan Richardson (mppa3 at uk.ac.sussex.syma)
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both the
+ * copyright notice and this permission notice appear in supporting
+ * documentation.  All work developed as a consequence of the use of
+ * this program should duly acknowledge such use. No representations are
+ * made about the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ */
+
+/* ********************************************************************** */
+
+
+/* BETTER: xvertext now does rotation at any angle!!
+ *
+ * BEWARE: function arguments have CHANGED since version 2.0!!
+ */
+
+/* ********************************************************************** */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "rotated.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/* Make sure cache size is set */
+
+#ifndef CACHE_SIZE_LIMIT
+#define CACHE_SIZE_LIMIT 0
+#endif /*CACHE_SIZE_LIMIT */
+    
+/* Make sure a cache method is specified */
+
+#ifndef CACHE_XIMAGES
+#ifndef CACHE_BITMAPS
+#define CACHE_BITMAPS
+#endif /*CACHE_BITMAPS*/
+#endif /*CACHE_XIMAGES*/
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/* Debugging macros */
+
+#ifdef DEBUG
+static int debug=1;
+#else   // DEBUG
+static int debug=0;
+#endif /*DEBUG*/
+
+#define DEBUG_PRINT1(a) if (debug) fprintf(stderr, a)
+#define DEBUG_PRINT2(a, b) if (debug) fprintf(stderr, a, b)
+#define DEBUG_PRINT3(a, b, c) if (debug) fprintf(stderr, a, b, c)
+#define DEBUG_PRINT4(a, b, c, d) if (debug) fprintf(stderr, a, b, c, d)
+#define DEBUG_PRINT5(a, b, c, d, e) if (debug) fprintf(stderr, a, b, c, d, e)
+
+
+/* ---------------------------------------------------------------------- */
+
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif  // M_PI
+
+// constants used to check for approximate equality with 90, 180, and 270 degrees
+// (int)((M_PI/2)*1000) 
+#define INT_M_PI_2_1000   1570  
+// (int)(M_PI*1000) 
+#define INT_M_PI_1000     3141
+// (int)((3*M_PI/2)*1000)
+#define INT_3_M_PI_2_1000 4712
+
+/* ---------------------------------------------------------------------- */
+
+
+/* A structure holding everything needed for a rotated string */
+
+typedef struct rotated_text_item_template {
+    Pixmap bitmap;
+    XImage *ximage;
+    
+    char *text;
+    char *font_name;
+    Font fid;
+    float angle;
+    int align;
+    float magnify;
+    
+    int cols_in;
+    int rows_in;
+    int cols_out;
+    int rows_out;
+    
+    int nl;
+    int max_width;
+    float *corners_x;
+    float *corners_y;
+    
+    long int size;
+    int cached;
+
+    struct rotated_text_item_template *next;
+} RotatedTextItem;
+
+RotatedTextItem *first_text_item=NULL;
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/* A structure holding current magnification and bounding box padding */
+
+static struct style_template {
+    float magnify;
+    int bbx_pad;
+} style={
+    1.,
+    0
+    };
+
+
+/* ---------------------------------------------------------------------- */
+
+
+static char *my_strdup(char *);
+
+static char *my_strtok(char *, char *);
+
+static XImage *MakeXImage(Display *, int, int);
+
+static int XRotPaintAlignedString(Display *,XFontStruct *,float, Drawable, GC, int, int, char*, int, int);
+
+static int XRotDrawHorizontalString(Display *, XFontStruct *, Drawable, GC, int, int, char*, int, int);
+
+static RotatedTextItem *XRotRetrieveFromCache(Display *, XFontStruct *, float, char *, int);
+
+static RotatedTextItem *XRotCreateTextItem(Display *, XFontStruct *, float, char *, int);
+
+static void XRotAddToLinkedList(Display *, RotatedTextItem *);
+
+static void XRotFreeTextItem(Display *, RotatedTextItem *);
+
+static XImage *XRotMagnifyImage(Display *, XImage *);
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Routine to mimic `strdup()' (some machines don't have it)              */
+/**************************************************************************/
+//
+// This function allocates some memory without freeing it.
+//
+static char *my_strdup(char *str) {
+    char *s;
+    
+    if(str==NULL)
+        return NULL;
+    
+    s=(char *)malloc((unsigned)(strlen(str)+1));
+
+    if(s!=NULL) {
+        xastir_snprintf(s,
+            strlen(str)+1,
+            "%s",
+            str);
+    }
+    else {
+        fprintf(stderr,"Couldn't allocate memory in my_strdup()\n");
+    }
+    
+    return s;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Routine to replace `strtok' : this one returns a zero length string if */
+/* it encounters two consecutive delimiters                               */
+/**************************************************************************/
+
+static char *my_strtok(char *str1, char *str2) {
+    char *ret;
+    int i, j, stop;
+    static int start, len;
+    static char *stext;
+    
+    if(str2==NULL)
+        return NULL;
+    
+    /* initialise if str1 not NULL */
+    if(str1!=NULL) {
+        start=0;
+        stext=str1;
+        len=strlen(str1);
+    }
+    
+    /* run out of tokens ? */
+    if(start>=len)
+        return NULL;
+    
+    /* loop through characters */
+    for(i=start; i<len; i++) {
+        /* loop through delimiters */
+        stop=0;
+        for(j=0; j < (int)strlen(str2); j++)
+            if(stext[i]==str2[j])
+                stop=1;
+        
+        if(stop)
+            break;
+    }
+    
+    stext[i]='\0';
+    
+    ret=stext+start;
+    
+    start=i+1;
+    
+    return ret;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Return version/copyright information                                   */
+/**************************************************************************/
+
+float XRotVersion(char *str, int n) {
+    if(str!=NULL)
+        xastir_snprintf(str, n, "%s", XV_COPYRIGHT);
+    return XV_VERSION;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Set the font magnification factor for all subsequent operations        */
+/**************************************************************************/
+
+void XRotSetMagnification(float m) {
+    if(m>0.)
+        style.magnify=m;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Set the padding used when calculating bounding boxes                   */
+/**************************************************************************/
+
+void XRotSetBoundingBoxPad(int p) {
+    if(p>=0)
+        style.bbx_pad=p;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  Create an XImage structure and allocate memory for it                 */
+/**************************************************************************/
+//
+// Function does not free the memory.
+//
+static XImage *MakeXImage(Display *dpy, int w, int h) {
+    XImage *I;
+    char *data;
+    
+    /* reserve memory for image */
+    data=(char *)calloc((unsigned)(((w-1)/8+1)*h), 1);
+    if(data==NULL) {
+        fprintf(stderr,"Couldn't allocate memory in MakeXImage()\n");
+        return NULL;
+    }
+    
+    /* create the XImage */
+    I=XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)), 1, XYBitmap,
+                   0, data, w, h, 8, 0);
+    if(I==NULL)
+        return NULL;
+    
+    I->byte_order=I->bitmap_bit_order=MSBFirst;
+    return I;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  A front end to XRotPaintAlignedString:                                */
+/*      -no alignment, no background                                      */
+/**************************************************************************/
+
+int XRotDrawString( Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *str) {
+    return (XRotPaintAlignedString(dpy, font, angle, drawable, gc,
+                                   x, y, str, NONE, 0));
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  A front end to XRotPaintAlignedString:                                */
+/*      -no alignment, paints background                                  */
+/**************************************************************************/
+
+int XRotDrawImageString( Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *str) {
+    return(XRotPaintAlignedString(dpy, font, angle, drawable, gc,
+                                  x, y, str, NONE, 1));
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  A front end to XRotPaintAlignedString:                                */
+/*      -does alignment, no background                                    */
+/**************************************************************************/
+
+int XRotDrawAlignedString( Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *text, int align) {
+    return(XRotPaintAlignedString(dpy, font, angle, drawable, gc,
+                                  x, y, text, align, 0));
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  A front end to XRotPaintAlignedString:                                */
+/*      -does alignment, paints background                                */
+/**************************************************************************/
+
+int XRotDrawAlignedImageString( Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *text, int align) {
+    return(XRotPaintAlignedString(dpy, font, angle, drawable, gc,
+                                  x, y, text, align, 1));
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  Aligns and paints a rotated string                                    */
+/**************************************************************************/
+//
+// This function allocates some memory but appears to free it
+// properly.
+//
+static int XRotPaintAlignedString( Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *text, int align, int bg) {
+    int i;
+    GC my_gc;
+    int xp, yp;
+    float hot_x, hot_y;
+    float hot_xp, hot_yp;
+    float sin_angle, cos_angle;
+    RotatedTextItem *item;
+    Pixmap bitmap_to_paint;
+    
+    /* return early for NULL/empty strings */
+    if(text==NULL)
+        return 0;
+    
+    if(strlen(text)==0)
+        return 0;
+
+    /* manipulate angle to 0<=angle<360 degrees */
+    while(angle<0)
+        angle+=360;
+    
+    while(angle>=360)
+        angle-=360;
+    
+    angle*=M_PI/180;
+    
+    /* horizontal text made easy */
+    if(angle==0. && style.magnify==1.) 
+        return(XRotDrawHorizontalString(dpy, font, drawable, gc, x, y,
+                                        text, align, bg));
+    
+    /* get a rotated bitmap */
+    item=XRotRetrieveFromCache(dpy, font, angle, text, align);
+    if(item==NULL)
+        return(0);
+    
+    /* this gc has similar properties to the user's gc */
+    my_gc=XCreateGC(dpy, drawable, 0, 0);
+    XCopyGC(dpy, gc, GCForeground|GCBackground|GCFunction|GCPlaneMask,
+            my_gc);
+
+    /* alignment : which point (hot_x, hot_y) relative to bitmap centre
+       coincides with user's specified point? */
+    
+    /* y position */
+    if(align==TLEFT || align==TCENTRE || align==TRIGHT)
+        hot_y=(float)item->rows_in/2*style.magnify;
+    else if(align==MLEFT || align==MCENTRE || align==MRIGHT)
+        hot_y=0;
+    else if(align==BLEFT || align==BCENTRE || align==BRIGHT)
+        hot_y=-(float)item->rows_in/2*style.magnify;
+    else
+        hot_y=-((float)item->rows_in/2-(float)font->descent)*style.magnify;
+    
+    /* x position */
+    if(align==TLEFT || align==MLEFT || align==BLEFT || align==NONE)
+        hot_x=-(float)item->max_width/2*style.magnify;
+    else if(align==TCENTRE || align==MCENTRE || align==BCENTRE)
+        hot_x=0;
+    else
+        hot_x=(float)item->max_width/2*style.magnify;
+    
+    /* pre-calculate sin and cos */
+    sin_angle=sin(angle);
+    cos_angle=cos(angle);
+    
+    /* rotate hot_x and hot_y around bitmap centre */
+    hot_xp= hot_x*cos_angle - hot_y*sin_angle;
+    hot_yp= hot_x*sin_angle + hot_y*cos_angle;
+    
+    /* text background will be drawn using XFillPolygon */
+    if(bg) {
+        GC depth_one_gc;
+        XPoint *xpoints;
+        Pixmap empty_stipple;
+        
+        /* reserve space for XPoints, free'd later */
+        xpoints=(XPoint *)malloc((unsigned)(4*item->nl*sizeof(XPoint)));
+        if(!xpoints) {
+            fprintf(stderr,"Couldn't allocate memory in XRotPaintAlignedString()\n");
+            return 1;
+        }
+        
+        /* rotate corner positions */
+        for(i=0; i<4*item->nl; i++) {
+            xpoints[i].x=(float)x + ( (item->corners_x[i]-hot_x)*cos_angle + 
+                                      (item->corners_y[i]+hot_y)*sin_angle);
+            xpoints[i].y=(float)y + (-(item->corners_x[i]-hot_x)*sin_angle + 
+                                      (item->corners_y[i]+hot_y)*cos_angle);
+        }
+        
+        /* we want to swap foreground and background colors here;
+           XGetGCValues() is only available in R4+ */
+        
+        empty_stipple=XCreatePixmap(dpy, drawable, 1, 1, 1);
+        
+        depth_one_gc=XCreateGC(dpy, empty_stipple, 0, 0);
+        XSetForeground(dpy, depth_one_gc, 0);
+        XFillRectangle(dpy, empty_stipple, depth_one_gc, 0, 0, 2, 2);
+
+        XSetStipple(dpy, my_gc, empty_stipple);
+        XSetFillStyle(dpy, my_gc, FillOpaqueStippled);
+
+        if (item->nl >= 1) {
+            XFillPolygon(dpy, drawable, my_gc, xpoints, 4*item->nl, Nonconvex,
+                     CoordModeOrigin);
+        }
+        else {
+            fprintf(stderr,
+                "XRotPaintAlignedString: Points too few:%d, skipping XFillPolygon",
+                item->nl);
+        }
+        
+        /* free our resources */
+        free((char *)xpoints);
+        XFreeGC(dpy, depth_one_gc);
+        XFreePixmap(dpy, empty_stipple);
+    }
+    
+    /* where should top left corner of bitmap go ? */
+    xp=(float)x-((float)item->cols_out/2 +hot_xp);
+    yp=(float)y-((float)item->rows_out/2 -hot_yp);
+    
+    /* by default we draw the rotated bitmap, solid */
+    bitmap_to_paint=item->bitmap;
+
+    /* handle user stippling */
+#ifndef X11R3
+    {
+        GC depth_one_gc;
+        XGCValues values;
+        Pixmap new_bitmap, inverse;
+        
+        /* try and get some GC properties */
+        if(XGetGCValues(dpy, gc, 
+                        GCStipple|GCFillStyle|GCForeground|GCBackground|
+                        GCTileStipXOrigin|GCTileStipYOrigin,
+                        &values)) {
+
+            /* only do this if stippling requested */
+            if((values.fill_style==FillStippled ||
+                values.fill_style==FillOpaqueStippled) && !bg) {
+
+                /* opaque stipple: draw rotated text in background colour */
+                if(values.fill_style==FillOpaqueStippled) {
+                    XSetForeground(dpy, my_gc, values.background);
+                    XSetFillStyle(dpy, my_gc, FillStippled);
+                    XSetStipple(dpy, my_gc, item->bitmap);
+                    XSetTSOrigin(dpy, my_gc, xp, yp);
+                    XFillRectangle(dpy, drawable, my_gc, xp, yp,
+                                   item->cols_out, item->rows_out);
+                    XSetForeground(dpy, my_gc, values.foreground);
+                }
+
+                /* this will merge the rotated text and the user's stipple */
+                new_bitmap=XCreatePixmap(dpy, drawable,
+                                         item->cols_out, item->rows_out, 1);
+
+                /* create a GC */
+                depth_one_gc=XCreateGC(dpy, new_bitmap, 0, 0);
+                XSetForeground(dpy, depth_one_gc, 1);
+                XSetBackground(dpy, depth_one_gc, 0);
+
+                /* set the relative stipple origin */
+                XSetTSOrigin(dpy, depth_one_gc, 
+                             values.ts_x_origin-xp, values.ts_y_origin-yp);
+
+                /* fill the whole bitmap with the user's stipple */
+                XSetStipple(dpy, depth_one_gc, values.stipple);
+                XSetFillStyle(dpy, depth_one_gc, FillOpaqueStippled);
+                XFillRectangle(dpy, new_bitmap, depth_one_gc,
+                               0, 0, item->cols_out, item->rows_out);
+
+                /* set stipple origin back to normal */
+                XSetTSOrigin(dpy, depth_one_gc, 0, 0);
+
+                /* this will contain an inverse copy of the rotated text */
+                inverse=XCreatePixmap(dpy, drawable,
+                                      item->cols_out, item->rows_out, 1);
+
+                /* invert text */
+                XSetFillStyle(dpy, depth_one_gc, FillSolid);
+                XSetFunction(dpy, depth_one_gc, GXcopyInverted);
+                XCopyArea(dpy, item->bitmap, inverse, depth_one_gc,
+                          0, 0, item->cols_out, item->rows_out, 0, 0);
+
+                /* now delete user's stipple everywhere EXCEPT on text */
+                XSetForeground(dpy, depth_one_gc, 0);
+                XSetBackground(dpy, depth_one_gc, 1);
+                XSetStipple(dpy, depth_one_gc, inverse);
+                XSetFillStyle(dpy, depth_one_gc, FillStippled);
+                XSetFunction(dpy, depth_one_gc, GXcopy);
+                XFillRectangle(dpy, new_bitmap, depth_one_gc,
+                               0, 0, item->cols_out, item->rows_out);
+
+                /* free resources */
+                XFreePixmap(dpy, inverse);
+                XFreeGC(dpy, depth_one_gc);
+
+                /* this is the new bitmap */
+                bitmap_to_paint=new_bitmap;
+            }
+        }
+    }
+#endif /*X11R3*/
+
+    /* paint text using stipple technique */
+    XSetFillStyle(dpy, my_gc, FillStippled);
+    XSetStipple(dpy, my_gc, bitmap_to_paint);
+    XSetTSOrigin(dpy, my_gc, xp, yp);
+    XFillRectangle(dpy, drawable, my_gc, xp, yp, 
+                   item->cols_out, item->rows_out);
+    
+    /* free our resources */
+    XFreeGC(dpy, my_gc);
+
+    /* stippled bitmap no longer needed */
+    if(bitmap_to_paint!=item->bitmap)
+        XFreePixmap(dpy, bitmap_to_paint);
+
+#ifdef CACHE_XIMAGES
+    XFreePixmap(dpy, item->bitmap);
+#endif /*CACHE_XIMAGES*/
+
+    /* if item isn't cached, destroy it completely */
+    if(!item->cached) 
+        XRotFreeTextItem(dpy,item);
+
+    /* we got to the end OK! */
+    return 0;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  Draw a horizontal string in a quick fashion                           */
+/**************************************************************************/
+//
+// This function allocates some memory but appears to free it
+// properly.
+//
+static int XRotDrawHorizontalString( Display *dpy, XFontStruct *font, Drawable drawable, GC gc, int x, int y, char *text, int align, int bg) {
+    GC my_gc;
+    int nl=1, i;
+    int height;
+    int xp, yp;
+    char *str1, *str2, *str3;
+    char *str2_a="\0", *str2_b="\n\0";
+    int dir, asc, desc;
+    XCharStruct overall;
+
+    DEBUG_PRINT1("**\nHorizontal text.\n");
+
+    /* this gc has similar properties to the user's gc (including stipple) */
+    my_gc=XCreateGC(dpy, drawable, 0, 0);
+    XCopyGC(dpy, gc,
+            GCForeground|GCBackground|GCFunction|GCStipple|GCFillStyle|
+            GCTileStipXOrigin|GCTileStipYOrigin|GCPlaneMask, my_gc);
+    XSetFont(dpy, my_gc, font->fid);
+        
+    /* count number of sections in string */
+    if(align!=NONE)
+        for(i=0; i < (int)(strlen(text)-1); i++)
+            if(text[i]=='\n')
+                nl++;
+    
+    /* ignore newline characters if not doing alignment */
+    if(align==NONE)
+        str2=str2_a;
+    else
+        str2=str2_b;
+    
+    /* overall font height */
+    height=font->ascent+font->descent;
+    
+    /* y position */
+    if(align==TLEFT || align==TCENTRE || align==TRIGHT)
+        yp=y+font->ascent;
+    else if(align==MLEFT || align==MCENTRE || align==MRIGHT)
+        yp=y-nl*height/2+font->ascent;
+    else if(align==BLEFT || align==BCENTRE || align==BRIGHT)
+        yp=y-nl*height+font->ascent;
+    else
+        yp=y;
+   
+// Allocates some memory 
+    str1=my_strdup(text);
+    if(str1==NULL)
+        return 1;
+    
+    str3=my_strtok(str1, str2);
+    
+    /* loop through each section in the string */
+    do {
+        XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc,
+                     &overall);
+
+        /* where to draw section in x ? */
+        if(align==TLEFT || align==MLEFT || align==BLEFT || align==NONE)
+            xp=x;
+        else if(align==TCENTRE || align==MCENTRE || align==BCENTRE)
+            xp=x-overall.rbearing/2;
+        else
+            xp=x-overall.rbearing;
+        
+        /* draw string onto bitmap */
+        if(!bg)
+            XDrawString(dpy, drawable, my_gc, xp, yp, str3, strlen(str3));
+        else
+            XDrawImageString(dpy, drawable, my_gc, xp, yp, str3, strlen(str3));
+        
+        /* move to next line */
+        yp+=height;
+        
+        str3=my_strtok((char *)NULL, str2);
+    }
+    while(str3!=NULL);
+    
+    free(str1);
+    XFreeGC(dpy, my_gc);
+
+    return 0;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*   Query cache for a match with this font/text/angle/alignment          */
+/*       request, otherwise arrange for its creation                      */
+/**************************************************************************/
+
+static RotatedTextItem *XRotRetrieveFromCache( Display *dpy, XFontStruct *font, float angle, char *text, int align) {
+    Font fid;
+    char *font_name=NULL;
+    unsigned long name_value;
+    RotatedTextItem *item=NULL;
+    RotatedTextItem *i1=first_text_item;
+    
+    /* get font name, if it exists */
+    if(XGetFontProperty(font, XA_FONT, &name_value)) {
+        DEBUG_PRINT1("got font name OK\n");
+        font_name=XGetAtomName(dpy, name_value);
+        fid=0;
+    }
+#ifdef CACHE_FID
+    /* otherwise rely (unreliably?) on font ID */
+    else {
+        DEBUG_PRINT1("can't get fontname, caching FID\n");
+        font_name=NULL;
+        fid=font->fid;
+    }
+#else   // CACHE_FID
+    /* not allowed to cache font ID's */
+    else {
+        DEBUG_PRINT1("can't get fontname, can't cache\n");
+        font_name=NULL;
+        fid=0;
+    }
+#endif /*CACHE_FID*/
+    
+    /* look for a match in cache */
+
+    /* matching formula:
+       identical text;
+       identical fontname (if defined, font ID's if not);
+       angles close enough (<0.00001 here, could be smaller);
+       HORIZONTAL alignment matches, OR it's a one line string;
+       magnifications the same */
+
+    while(i1 && !item) {
+        /* match everything EXCEPT fontname/ID */
+        if(strcmp(text, i1->text)==0 &&
+           fabs(angle-i1->angle)<0.00001 &&
+           style.magnify==i1->magnify &&
+           (i1->nl==1 ||
+            ((align==0)?9:(align-1))%3==
+              ((i1->align==0)?9:(i1->align-1))%3)) {
+
+            /* now match fontname/ID */
+            if(font_name!=NULL && i1->font_name!=NULL) {
+                if(strcmp(font_name, i1->font_name)==0) {
+                    item=i1;
+                    DEBUG_PRINT1("Matched against font names\n");
+                }
+                else
+                    i1=i1->next;
+            }
+#ifdef CACHE_FID
+            else if(font_name==NULL && i1->font_name==NULL) {
+                if(fid==i1->fid) {
+                    item=i1;
+                    DEBUG_PRINT1("Matched against FID's\n");
+                }
+                else
+                    i1=i1->next;
+            }
+#endif /*CACHE_FID*/
+            else
+                i1=i1->next;
+        }
+        else
+            i1=i1->next;
+    }
+    
+    if(item)
+        DEBUG_PRINT1("**\nFound target in cache.\n");
+    if(!item)
+        DEBUG_PRINT1("**\nNo match in cache.\n");
+
+    /* no match */
+    if(!item) {
+        /* create new item */
+        item=XRotCreateTextItem(dpy, font, angle, text, align);
+        if(!item)
+            return NULL;
+
+        /* record what it shows */
+// Allocates some memory
+        item->text=my_strdup(text);
+
+        /* fontname or ID */
+        if(font_name!=NULL) {
+// Allocates some memory
+            item->font_name=my_strdup(font_name);
+            item->fid=0;
+        }
+        else {
+            item->font_name=NULL;
+            item->fid=fid;
+        }
+
+        item->angle=angle;
+        item->align=align;
+        item->magnify=style.magnify;
+
+        /* cache it */
+        XRotAddToLinkedList(dpy, item);
+    }
+
+    if(font_name)
+        XFree(font_name);
+
+    /* if XImage is cached, need to recreate the bitmap */
+
+#ifdef CACHE_XIMAGES
+    {
+        GC depth_one_gc;
+
+        /* create bitmap to hold rotated text */
+        item->bitmap=XCreatePixmap(dpy, DefaultRootWindow(dpy),
+                                   item->cols_out, item->rows_out, 1);
+        
+        /* depth one gc */
+        depth_one_gc=XCreateGC(dpy, item->bitmap, NULL, 0);
+        XSetBackground(dpy, depth_one_gc, 0);
+        XSetForeground(dpy, depth_one_gc, 1);
+
+        /* make the text bitmap from XImage */
+        XPutImage(dpy, item->bitmap, depth_one_gc, item->ximage, 0, 0, 0, 0,
+                  item->cols_out, item->rows_out);
+
+        XFreeGC(dpy, depth_one_gc);
+    }
+#endif /*CACHE_XIMAGES*/
+    
+    return item;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  Create a rotated text item                                            */
+/**************************************************************************/
+//
+// This function allocates some memory but appears to free it
+// properly.
+//
+static RotatedTextItem *XRotCreateTextItem( Display *dpy, XFontStruct *font, float angle, char *text, int align) {
+    RotatedTextItem *item=NULL;
+    Pixmap canvas;
+    GC font_gc;
+    XImage *I_in;
+    register int i, j;
+    char *str1, *str2, *str3;
+    char *str2_a="\0", *str2_b="\n\0";
+    int height;
+    int byte_w_in, byte_w_out;
+    int xp, yp;
+    float sin_angle, cos_angle;
+    int it, jt;
+    float di, dj;
+    int ic=0;
+    float xl, xr, xinc;
+    int byte_out;
+    int dir, asc, desc;
+    XCharStruct overall;
+    int old_cols_in=0, old_rows_in=0;
+    int cols_in2, rows_in2;
+    int intAngle1000;       // stores first few digits of angle, 
+                            // used to avoid problems with rounding error in 
+                            // recognition of 90 degree angles 
+    
+    /* allocate memory */
+    item=(RotatedTextItem *)malloc((unsigned)sizeof(RotatedTextItem));
+    if(!item) {
+        fprintf(stderr,"Couldn't allocate memory in RotatedTextItem()\n");
+        return NULL;
+    }
+        
+    /* count number of sections in string */
+    item->nl=1;
+    if(align!=NONE)
+        for(i=0; i < (int)(strlen(text)-1); i++)
+            if(text[i]=='\n')
+                item->nl++;
+    
+    /* ignore newline characters if not doing alignment */
+    if(align==NONE)
+        str2=str2_a;
+    else
+        str2=str2_b;
+    
+    /* find width of longest section */
+// Allocates some memory
+    str1=my_strdup(text);
+    if(str1==NULL)
+        return NULL;
+    
+    str3=my_strtok(str1, str2);
+
+    XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc,
+                 &overall);
+    
+    item->max_width=overall.rbearing;
+    
+    /* loop through each section */
+    do {
+        str3=my_strtok((char *)NULL, str2);
+
+        if(str3!=NULL) {
+            XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc,
+                         &overall);
+
+            if(overall.rbearing>item->max_width)
+                item->max_width=overall.rbearing;
+        }
+    }
+    while(str3!=NULL);
+    
+    free(str1);
+    
+    /* overall font height */
+    height=font->ascent+font->descent;
+    
+    /* dimensions horizontal text will have */
+    item->cols_in=item->max_width;
+    item->rows_in=item->nl*height;
+    
+    /* bitmap for drawing on */
+    canvas=XCreatePixmap(dpy, DefaultRootWindow(dpy),
+                         item->cols_in, item->rows_in, 1);
+    
+    /* create a GC for the bitmap */
+    font_gc=XCreateGC(dpy, canvas, 0, 0);
+    XSetBackground(dpy, font_gc, 0);
+    XSetFont(dpy, font_gc, font->fid);
+    
+    /* make sure the bitmap is blank */
+    XSetForeground(dpy, font_gc, 0);
+    XFillRectangle(dpy, canvas, font_gc, 0, 0, 
+                   item->cols_in+1, item->rows_in+1);
+    XSetForeground(dpy, font_gc, 1);
+    
+    /* pre-calculate sin and cos */
+    sin_angle=sin(angle);
+    cos_angle=cos(angle);
+    
+    /* text background will be drawn using XFillPolygon */
+    item->corners_x=
+        (float *)malloc((unsigned)(4*item->nl*sizeof(float)));
+    if(!item->corners_x) {
+        fprintf(stderr,"Couldn't allocate memory in RotatedTextItem()\n");
+        return NULL;
+    }
+    
+    item->corners_y=
+        (float *)malloc((unsigned)(4*item->nl*sizeof(float)));
+    if(!item->corners_y) {
+        fprintf(stderr,"Couldn't allocate memory in RotatedTextItem()\n");
+        return NULL;
+    }
+    
+    /* draw text horizontally */
+    
+    /* start at top of bitmap */
+    yp=font->ascent;
+    
+// Allocates some memory
+    str1=my_strdup(text);
+    if(str1==NULL)
+        return NULL;
+    
+    str3=my_strtok(str1, str2);
+    
+    /* loop through each section in the string */
+    do {
+        XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc,
+                &overall);
+
+        /* where to draw section in x ? */
+        if(align==TLEFT || align==MLEFT || align==BLEFT || align==NONE)
+            xp=0;
+        else if(align==TCENTRE || align==MCENTRE || align==BCENTRE)
+            xp=(item->max_width-overall.rbearing)/2;
+        else
+            xp=item->max_width-overall.rbearing;
+
+        /* draw string onto bitmap */
+        XDrawString(dpy, canvas, font_gc, xp, yp, str3, strlen(str3));
+        
+        /* keep a note of corner positions of this string */
+        item->corners_x[ic]=((float)xp-(float)item->cols_in/2)*style.magnify;
+        item->corners_y[ic]=((float)(yp-font->ascent)-(float)item->rows_in/2)
+            *style.magnify;
+        item->corners_x[ic+1]=item->corners_x[ic];
+        item->corners_y[ic+1]=item->corners_y[ic]+(float)height*style.magnify;
+        item->corners_x[item->nl*4-1-ic]=item->corners_x[ic]+
+            (float)overall.rbearing*style.magnify;
+        item->corners_y[item->nl*4-1-ic]=item->corners_y[ic];
+        item->corners_x[item->nl*4-2-ic]=
+            item->corners_x[item->nl*4-1-ic];
+        item->corners_y[item->nl*4-2-ic]=item->corners_y[ic+1];
+        
+        ic+=2;
+        
+        /* move to next line */
+        yp+=height;
+        
+        str3=my_strtok((char *)NULL, str2);
+    }
+    while(str3!=NULL);
+    
+    free(str1);
+    
+    /* create image to hold horizontal text */
+    I_in=MakeXImage(dpy, item->cols_in, item->rows_in);
+    if(I_in==NULL)
+        return NULL;
+    
+    /* extract horizontal text */
+    XGetSubImage(dpy, canvas, 0, 0, item->cols_in, item->rows_in,
+                 1, XYPixmap, I_in, 0, 0);
+    I_in->format=XYBitmap;
+    
+    /* magnify horizontal text */
+    if(style.magnify!=1.) {
+        I_in=XRotMagnifyImage(dpy, I_in);
+
+        old_cols_in=item->cols_in;
+        old_rows_in=item->rows_in;
+        item->cols_in=(float)item->cols_in*style.magnify;
+        item->rows_in=(float)item->rows_in*style.magnify;
+    }
+
+    /* how big will rotated text be ? */
+    item->cols_out=fabs((float)item->rows_in*sin_angle) +
+        fabs((float)item->cols_in*cos_angle) +0.99999 +2;
+
+    item->rows_out=fabs((float)item->rows_in*cos_angle) +
+        fabs((float)item->cols_in*sin_angle) +0.99999 +2;
+
+    if(item->cols_out%2==0)
+        item->cols_out++;
+    
+    if(item->rows_out%2==0)
+        item->rows_out++;
+    
+    /* create image to hold rotated text */
+    item->ximage=MakeXImage(dpy, item->cols_out, item->rows_out);
+    if(item->ximage==NULL)
+        return NULL;
+    
+    byte_w_in=(item->cols_in-1)/8+1;
+    byte_w_out=(item->cols_out-1)/8+1;
+    
+    /* we try to make this bit as fast as possible - which is why it looks
+       a bit over-the-top */
+    
+    /* vertical distance from centre */
+    dj=0.5-(float)item->rows_out/2;
+
+    /* where abouts does text actually lie in rotated image? */
+    intAngle1000 =  (int)(angle*1000);
+    if (   intAngle1000==0 
+        || intAngle1000==INT_M_PI_2_1000 
+        || intAngle1000==INT_M_PI_1000 
+        || intAngle1000==INT_3_M_PI_2_1000 ) {
+        // 0, 90, 180, 270 degrees are special cases
+        // floating point errors may prevent recognition of them unless
+        // we round off, that is a value that started as 180 may not be
+        // recognized as == M_PI/2.  Rounding to .001 radian seems a
+        // reasonable choice for the purpose of orienting text strings.  
+        xl=0;
+        xr=(float)item->cols_out;
+        xinc=0;
+    }
+    else if(angle<M_PI) {
+        xl=(float)item->cols_out/2+
+            (dj-(float)item->rows_in/(2*cos_angle))/
+                tan(angle)-2;
+        xr=(float)item->cols_out/2+
+            (dj+(float)item->rows_in/(2*cos_angle))/
+                tan(angle)+2;
+        xinc=1./tan(angle);
+    }
+    else {
+        xl=(float)item->cols_out/2+
+            (dj+(float)item->rows_in/(2*cos_angle))/
+                tan(angle)-2;
+        xr=(float)item->cols_out/2+
+            (dj-(float)item->rows_in/(2*cos_angle))/
+                tan(angle)+2;
+        
+        xinc=1./tan(angle);
+    }
+
+
+    // Set up some constants for loops below
+    cols_in2 = item->cols_in / 2;
+    rows_in2 = item->rows_in / 2;
+
+    // Handle special cases of 90 degree rotation
+    if ( intAngle1000 == INT_M_PI_2_1000 ) {
+        // angle is 180 degrees, text is rotated 90 degrees from horizontal and runs up x axis
+        for(j=0; j<item->rows_out; j++) {
+            di=(float)((xl<0)?0:(int)xl)+0.5-(float)item->cols_out/2;
+            byte_out=(item->rows_out-j-1)*byte_w_out;
+            for(i=((xl<0)?0:(int)xl); 
+                    i<((xr>=item->cols_out)?item->cols_out:(int)xr); i++) {
+                jt=(float)rows_in2 + di;
+                it=(float)cols_in2 + dj;
+                if(it>=0 && it<item->cols_in && jt>=0 && jt<item->rows_in)
+                    if((I_in->data[jt*byte_w_in+it/8] & 128>>(it%8))>0)
+                        item->ximage->data[byte_out+i/8]|=128>>i%8;
+                
+                di+=1;
+            }
+            dj+=1;
+            xl+=xinc;
+            xr+=xinc;
+        }
+        // handling for special cases of 90 and 270 not written yet.
+        // need elseif clauses here.
+    } else {
+        // not a 90 degree rotation, use sin/cos transform
+        /* loop through all relevent bits in rotated image */
+        for(j=0; j<item->rows_out; j++) {
+            float dj_sin, dj_cos;
+            float temp_it, temp_jt;
+    
+            
+            /* no point re-calculating these every pass */
+            di=(float)((xl<0)?0:(int)xl)+0.5-(float)item->cols_out/2;
+            byte_out=(item->rows_out-j-1)*byte_w_out;
+    
+            // New code:  Calculate these outside the inner loop for
+            // major speed gains.
+            dj_sin = dj * sin_angle;
+            dj_cos = dj * cos_angle;
+            temp_it = (float)cols_in2 + dj_sin;
+            temp_jt = (float)rows_in2 - dj_cos;
+    
+            /* loop through meaningful columns */
+            for(i=((xl<0)?0:(int)xl); 
+                    i<((xr>=item->cols_out)?item->cols_out:(int)xr); i++) {
+                
+                // rotate coordinates
+    
+                // Original code (very slow)
+                //it=(float)item->cols_in/2 + ( di*cos_angle + dj*sin_angle);
+                //jt=(float)item->rows_in/2 - (-di*sin_angle + dj*cos_angle);
+    
+                // New code (much faster)
+                //it=(float)cols_in2 + ( di*cos_angle + dj_sin);
+                //jt=(float)rows_in2 - (-di*sin_angle + dj_cos);
+                it=(float)temp_it + di*cos_angle;
+                jt=(float)temp_jt + di*sin_angle;
+                
+                /* set pixel if required */
+                if(it>=0 && it<item->cols_in && jt>=0 && jt<item->rows_in)
+                    if((I_in->data[jt*byte_w_in+it/8] & 128>>(it%8))>0)
+                        item->ximage->data[byte_out+i/8]|=128>>i%8;
+                
+                di+=1;
+            }
+            dj+=1;
+            xl+=xinc;
+            xr+=xinc;
+        }
+    }
+    XDestroyImage(I_in);
+    
+    if(style.magnify!=1.) {
+        item->cols_in=old_cols_in;
+        item->rows_in=old_rows_in;
+    }
+
+
+#ifdef CACHE_BITMAPS
+
+    /* create a bitmap to hold rotated text */
+    item->bitmap=XCreatePixmap(dpy, DefaultRootWindow(dpy),
+                               item->cols_out, item->rows_out, 1);
+    
+    /* make the text bitmap from XImage */
+    XPutImage(dpy, item->bitmap, font_gc, item->ximage, 0, 0, 0, 0,
+              item->cols_out, item->rows_out);
+
+    XDestroyImage(item->ximage);
+
+#endif /*CACHE_BITMAPS*/
+
+    XFreeGC(dpy, font_gc);
+    XFreePixmap(dpy, canvas);
+
+    return item;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  Adds a text item to the end of the cache, removing as many items      */
+/*      from the front as required to keep cache size below limit         */
+/**************************************************************************/
+
+static void XRotAddToLinkedList( Display *dpy, RotatedTextItem *item) {
+    
+    static long int current_size=0;
+    static RotatedTextItem *last=NULL;
+    RotatedTextItem *i1=first_text_item, *i2=NULL;
+
+#ifdef CACHE_BITMAPS
+
+    /* I don't know how much memory a pixmap takes in the server -
+           probably this + a bit more we can't account for */
+
+    item->size=((item->cols_out-1)/8+1)*item->rows_out;
+
+#else   // CACHE_BITMAPS
+
+    /* this is pretty much the size of a RotatedTextItem */
+
+    item->size=((item->cols_out-1)/8+1)*item->rows_out +
+        sizeof(XImage) + strlen(item->text) + 
+            item->nl*8*sizeof(float) + sizeof(RotatedTextItem);
+
+    if(item->font_name!=NULL)
+        item->size+=strlen(item->font_name);
+    else
+        item->size+=sizeof(Font);
+
+#endif /*CACHE_BITMAPS */
+
+#ifdef DEBUG
+    /* count number of items in cache, for debugging */
+    {
+        int i=0;
+
+        while(i1) {
+            i++;
+            i1=i1->next;
+        }
+        DEBUG_PRINT2("Cache has %d items.\n", i);
+        i1=first_text_item;
+    }
+#endif  // DEBUG
+
+    DEBUG_PRINT4("current cache size=%ld, new item=%ld, limit=%ld\n",
+                 current_size, item->size, (long)(CACHE_SIZE_LIMIT*1024));
+
+    /* if this item is bigger than whole cache, forget it */
+    if(item->size>CACHE_SIZE_LIMIT*1024) {
+        DEBUG_PRINT1("Too big to cache\n\n");
+        item->cached=0;
+        return;
+    }
+
+    /* remove elements from cache as needed */
+    while(i1 && current_size+item->size>CACHE_SIZE_LIMIT*1024) {
+
+        DEBUG_PRINT2("Removed %d bytes\n", (int)i1->size);
+
+        if(i1->font_name!=NULL)
+            DEBUG_PRINT5("  (`%s'\n   %s\n   angle=%f align=%d)\n",
+                         i1->text, i1->font_name, i1->angle, i1->align);
+
+#ifdef CACHE_FID
+        if(i1->font_name==NULL)
+            DEBUG_PRINT5("  (`%s'\n  FID=%ld\n   angle=%f align=%d)\n",
+                         i1->text, i1->fid, i1->angle, i1->align);
+#endif /*CACHE_FID*/
+
+        current_size-=i1->size;
+
+        i2=i1->next;
+
+        /* free resources used by the unlucky item */
+        XRotFreeTextItem(dpy, i1);
+
+        /* remove it from linked list */
+        first_text_item=i2;
+        i1=i2;
+    }
+
+    /* add new item to end of linked list */
+    if(first_text_item==NULL) {
+        item->next=NULL;
+        first_text_item=item;
+        last=item;
+    }
+    else {
+        item->next=NULL;
+        last->next=item;
+        last=item;
+    }
+
+    /* new cache size */
+    current_size+=item->size;
+
+    item->cached=1;
+
+    DEBUG_PRINT1("Added item to cache.\n");
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/*  Free the resources used by a text item                                */
+/**************************************************************************/
+
+static void XRotFreeTextItem( Display *dpy, RotatedTextItem *item) {
+    free(item->text);
+
+    if(item->font_name!=NULL)
+        free(item->font_name);
+
+    free((char *)item->corners_x);
+    free((char *)item->corners_y);
+
+#ifdef CACHE_BITMAPS
+    XFreePixmap(dpy, item->bitmap);
+#else   // CACHE_BITMAPS
+    XDestroyImage(item->ximage);
+#endif /* CACHE_BITMAPS */
+
+    free((char *)item);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Magnify an XImage using bilinear interpolation                         */
+/**************************************************************************/
+
+static XImage *XRotMagnifyImage( Display *dpy, XImage *ximage) {
+    int i, j;
+    float x, y;
+    float u,t;
+    XImage *I_out;
+    int cols_in, rows_in;
+    int cols_out, rows_out;
+    register int i2, j2;
+    float z1, z2, z3, z4;
+    int byte_width_in, byte_width_out;
+    float mag_inv;
+
+    /* size of input image */
+    cols_in=ximage->width;
+    rows_in=ximage->height;
+
+    /* size of final image */
+    cols_out=(float)cols_in*style.magnify;
+    rows_out=(float)rows_in*style.magnify;
+
+    /* this will hold final image */
+    I_out=MakeXImage(dpy, cols_out, rows_out);
+    if(I_out==NULL)
+        return NULL;
+
+    /* width in bytes of input, output images */
+    byte_width_in=(cols_in-1)/8+1;
+    byte_width_out=(cols_out-1)/8+1;
+
+    /* for speed */
+    mag_inv=1./style.magnify;
+
+    y=0.;
+
+    /* loop over magnified image */
+    for(j2=0; j2<rows_out; j2++) {
+        x=0;
+        j=y;
+
+        for(i2=0; i2<cols_out; i2++) {
+            i=x;
+
+            /* bilinear interpolation - where are we on bitmap ? */
+            /* right edge */
+            if(i==cols_in-1 && j!=rows_in-1) {
+                t=0;
+                u=y-(float)j;
+
+                z1=(ximage->data[j*byte_width_in+i/8] & 128>>(i%8))>0;
+                z2=z1;
+                z3=(ximage->data[(j+1)*byte_width_in+i/8] & 128>>(i%8))>0;
+                z4=z3;
+            }
+            /* top edge */
+            else if(i!=cols_in-1 && j==rows_in-1) {
+                t=x-(float)i;
+                u=0;
+
+                z1=(ximage->data[j*byte_width_in+i/8] & 128>>(i%8))>0;
+                z2=(ximage->data[j*byte_width_in+(i+1)/8] & 128>>((i+1)%8))>0;
+                z3=z2;
+                z4=z1;
+            }
+            /* top right corner */
+            else if(i==cols_in-1 && j==rows_in-1) {
+                u=0;
+                t=0;
+
+                z1=(ximage->data[j*byte_width_in+i/8] & 128>>(i%8))>0;
+                z2=z1;
+                z3=z1;
+                z4=z1;
+            }
+            /* somewhere `safe' */
+            else {
+                t=x-(float)i;
+                u=y-(float)j;
+
+                z1=(ximage->data[j*byte_width_in+i/8] & 128>>(i%8))>0;
+                z2=(ximage->data[j*byte_width_in+(i+1)/8] & 128>>((i+1)%8))>0;
+                z3=(ximage->data[(j+1)*byte_width_in+(i+1)/8] &
+                    128>>((i+1)%8))>0;
+                z4=(ximage->data[(j+1)*byte_width_in+i/8] & 128>>(i%8))>0;
+            }
+
+            /* if interpolated value is greater than 0.5, set bit */
+            if(((1-t)*(1-u)*z1 + t*(1-u)*z2 + t*u*z3 + (1-t)*u*z4)>0.5)
+                I_out->data[j2*byte_width_out+i2/8]|=128>>i2%8;
+
+            x+=mag_inv;
+        }
+        y+=mag_inv;
+    }
+    
+    /* destroy original */
+    XDestroyImage(ximage);
+
+    /* return big image */
+    return I_out;
+}
+
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/**************************************************************************/
+/* Calculate the bounding box some text will have when painted            */
+/**************************************************************************/
+//
+// This function allocates some memory, frees all but xp_out which
+// is returned.
+//
+XPoint *XRotTextExtents( Display *dpy, XFontStruct *font, float angle, int x, int y, char *text, int align) {
+    register int i;
+    char *str1, *str2, *str3;
+    char *str2_a="\0", *str2_b="\n\0";
+    int height;
+    float sin_angle, cos_angle;
+    int nl, max_width;
+    int cols_in, rows_in;
+    float hot_x, hot_y;
+    XPoint *xp_in, *xp_out;
+    int dir, asc, desc;
+    XCharStruct overall;
+   
+    /* manipulate angle to 0<=angle<360 degrees */
+    while(angle<0)
+        angle+=360;
+    
+    while(angle>360)
+        angle-=360;
+
+    angle*=M_PI/180;
+
+    /* count number of sections in string */
+    nl=1;
+    if(align!=NONE) {
+            for (i=0; i < (int)(strlen(text)-1); i++) {
+                if(text[i]=='\n') {
+                        nl++;
+            }
+        }
+    }
+    
+    /* ignore newline characters if not doing alignment */
+    if(align==NONE)
+            str2=str2_a;
+    else
+            str2=str2_b;
+
+    /* find width of longest section */
+// Allocates some memory, free'd below
+    str1=my_strdup(text);
+    if(str1==NULL)
+            return NULL;
+
+    str3=my_strtok(str1, str2);
+
+    XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, &overall);
+
+    max_width=overall.rbearing;
+    
+    /* loop through each section */
+    do {
+            str3=my_strtok((char *)NULL, str2);
+
+            if(str3!=NULL) {
+                XTextExtents(font, str3, strlen(str3), &dir, &asc, &desc, &overall);
+
+            if(overall.rbearing>max_width)
+                    max_width=overall.rbearing;
+            }
+    }
+    while(str3!=NULL);
+ 
+    free(str1);
+    
+    /* overall font height */
+    height=font->ascent+font->descent;
+    
+    /* dimensions horizontal text will have */
+    cols_in=max_width;
+    rows_in=nl*height;
+    
+    /* pre-calculate sin and cos */
+    sin_angle=sin(angle);
+    cos_angle=cos(angle);
+    
+    /* y position */
+    if(align==TLEFT || align==TCENTRE || align==TRIGHT)
+        hot_y=(float)rows_in/2*style.magnify;
+    else if(align==MLEFT || align==MCENTRE || align==MRIGHT)
+            hot_y=0;
+    else if(align==BLEFT || align==BCENTRE || align==BRIGHT)
+            hot_y=-(float)rows_in/2*style.magnify;
+    else
+            hot_y=-((float)rows_in/2-(float)font->descent)*style.magnify;
+    
+    /* x position */
+    if(align==TLEFT || align==MLEFT || align==BLEFT || align==NONE)
+            hot_x=-(float)max_width/2*style.magnify;
+    else if(align==TCENTRE || align==MCENTRE || align==BCENTRE)
+            hot_x=0;
+    else
+        hot_x=(float)max_width/2*style.magnify;
+   
+    /* reserve space for XPoints */
+    xp_in=(XPoint *)malloc((unsigned)(5*sizeof(XPoint)));
+    if(!xp_in) {
+        fprintf(stderr,"Couldn't allocate memory in XRotTextExtents()\n");
+        return NULL;
+    }
+
+    xp_out=(XPoint *)malloc((unsigned)(5*sizeof(XPoint)));
+    if(!xp_out) {
+        fprintf(stderr,"Couldn't allocate memory in XRotTextExtents()\n");
+        return NULL;
+    }
+
+    /* bounding box when horizontal, relative to bitmap centre */
+    xp_in[0].x=-(float)cols_in*style.magnify/2-style.bbx_pad;
+    xp_in[0].y= (float)rows_in*style.magnify/2+style.bbx_pad;
+    xp_in[1].x= (float)cols_in*style.magnify/2+style.bbx_pad;
+    xp_in[1].y= (float)rows_in*style.magnify/2+style.bbx_pad;
+    xp_in[2].x= (float)cols_in*style.magnify/2+style.bbx_pad;
+    xp_in[2].y=-(float)rows_in*style.magnify/2-style.bbx_pad;
+    xp_in[3].x=-(float)cols_in*style.magnify/2-style.bbx_pad;
+    xp_in[3].y=-(float)rows_in*style.magnify/2-style.bbx_pad;
+    xp_in[4].x=xp_in[0].x;
+    xp_in[4].y=xp_in[0].y;
+        
+    /* rotate and translate bounding box */
+    for(i=0; i<5; i++) {
+            xp_out[i].x=(float)x + ( ((float)xp_in[i].x-hot_x)*cos_angle +
+                                 ((float)xp_in[i].y+hot_y)*sin_angle);
+            xp_out[i].y=(float)y + (-((float)xp_in[i].x-hot_x)*sin_angle +
+                                 ((float)xp_in[i].y+hot_y)*cos_angle);
+    }
+
+    free((char *)xp_in);
+
+    return xp_out;
+}
+
+
diff --git a/src/rotated.h b/src/rotated.h
new file mode 100644
index 0000000..8501cde
--- /dev/null
+++ b/src/rotated.h
@@ -0,0 +1,89 @@
+
+// $Id: rotated.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+//
+// Portions Copyright (C) 2000-2012  The Xastir Group
+//
+
+/* ************************************************************************ */
+
+
+/* Header file for the `xvertext 5.0' routines.
+
+   Copyright (c) 1993 Alan Richardson (mppa3 at uk.ac.sussex.syma) */
+
+
+/* ************************************************************************ */
+
+#ifndef _XVERTEXT_INCLUDED_ 
+#define _XVERTEXT_INCLUDED_
+
+
+#define XV_VERSION      5.0
+#define XV_COPYRIGHT \
+      "xvertext routines Copyright (c) 1993 Alan Richardson"
+
+
+/* ---------------------------------------------------------------------- */
+
+
+/* text alignment */
+
+#define NONE             0
+#define TLEFT            1
+#define TCENTRE          2
+#define TRIGHT           3
+#define MLEFT            4
+#define MCENTRE          5
+#define MRIGHT           6
+#define BLEFT            7
+#define BCENTRE          8
+#define BRIGHT           9
+
+
+/* ---------------------------------------------------------------------- */
+
+/* this shoulf be C++ compliant, thanks to 
+     vlp at latina.inesc.pt (Vasco Lopes Paulo) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+
+extern "C" {
+float   XRotVersion(char*, int);
+void    XRotSetMagnification(float);
+void    XRotSetBoundingBoxPad(int);
+int     XRotDrawString(Display*, XFontStruct*, float,
+                       Drawable, GC, int, int, char*);
+int     XRotDrawImageString(Display*, XFontStruct*, float,
+                            Drawable, GC, int, int, char*);
+int     XRotDrawAlignedString(Display*, XFontStruct*, float,
+                              Drawable, GC, int, int, char*, int);
+int     XRotDrawAlignedImageString(Display*, XFontStruct*, float,
+                                   Drawable, GC, int, int, char*, int);
+XPoint *XRotTextExtents(Display*, XFontStruct*, float,
+                        int, int, char*, int);
+}
+
+#else   // _cplusplus || c_plusplus
+
+extern float   XRotVersion(char *, int);
+extern void    XRotSetMagnification(float);
+extern void    XRotSetBoundingBoxPad(int);
+extern int     XRotDrawString(Display *, XFontStruct*, float,
+                            Drawable, GC, int, int, char*);
+extern int     XRotDrawImageString(Display*, XFontStruct*, float,
+                            Drawable, GC, int, int, char*);
+extern int     XRotDrawAlignedString(Display*, XFontStruct*, float,
+                              Drawable, GC, int, int, char*, int);
+extern int     XRotDrawAlignedImageString(Display*, XFontStruct*, float,
+                                   Drawable, GC, int, int, char*, int);
+extern XPoint *XRotTextExtents(Display*, XFontStruct*, float,
+                        int, int, char*, int);
+
+#endif /* __cplusplus */
+
+/* ---------------------------------------------------------------------- */
+
+
+#endif /* _XVERTEXT_INCLUDED_ */
+
+
diff --git a/src/rpl_malloc.c b/src/rpl_malloc.c
new file mode 100644
index 0000000..a64c09a
--- /dev/null
+++ b/src/rpl_malloc.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: rpl_malloc.c,v 1.7 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+/*
+//
+// We DON'T want config.h to redefine malloc in this file else we'll
+// get an infinite loop.
+//
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+*/
+
+#include <stdlib.h>
+
+#include "rpl_malloc.h"
+
+//
+// Work around bug on some systems where malloc (0) fails.
+// written by Jim Meyering
+//
+// configure.ac calls out AC_FUNC_MALLOC which checks the malloc()
+// function.  If malloc() is determined to do the wrong thing when
+// passed a 0 value, the Autoconf macro will do this:
+//      #define malloc rpl_malloc
+// We then need to have an rpl_malloc function defined.  Here it is:
+//
+// Allocate an N-byte block of memory from the heap.
+// If N is zero, allocate a 1-byte block.
+// 
+void *rpl_malloc (size_t size) {
+    if (size == 0)
+        size++;
+    return malloc (size);
+}
+
+
diff --git a/src/rpl_malloc.h b/src/rpl_malloc.h
new file mode 100644
index 0000000..df7f4a6
--- /dev/null
+++ b/src/rpl_malloc.h
@@ -0,0 +1,37 @@
+/*
+ * $Id: rpl_malloc.h,v 1.6 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_RPL_MALLOC_H
+#define __XASTIR_RPL_MALLOC_H
+
+
+
+
+extern void *rpl_malloc (size_t size);
+
+
+#endif // __XASTIR_RPL_MALLOC_H
+
+
diff --git a/src/rtree/Makefile.am b/src/rtree/Makefile.am
new file mode 100644
index 0000000..b9062a9
--- /dev/null
+++ b/src/rtree/Makefile.am
@@ -0,0 +1,13 @@
+
+# $Id: Makefile.am,v 1.8 2012/11/01 18:57:19 we7u Exp $
+# Copyright (C) 2004-2012  The Xastir Group
+
+noinst_LIBRARIES=librtree.a
+librtree_a_SOURCES=index.c \
+                 index.h \
+                 rect.c \
+                 node.c \
+                 card.c \
+                 card.h \
+                 split_l.c \
+                 split_l.h 
diff --git a/src/rtree/Makefile.in b/src/rtree/Makefile.in
new file mode 100644
index 0000000..1922d71
--- /dev/null
+++ b/src/rtree/Makefile.in
@@ -0,0 +1,476 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.8 2012/11/01 18:57:19 we7u Exp $
+# Copyright (C) 2004-2012  The Xastir Group
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/rtree
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+librtree_a_AR = $(AR) $(ARFLAGS)
+librtree_a_LIBADD =
+am_librtree_a_OBJECTS = index.$(OBJEXT) rect.$(OBJEXT) node.$(OBJEXT) \
+	card.$(OBJEXT) split_l.$(OBJEXT)
+librtree_a_OBJECTS = $(am_librtree_a_OBJECTS)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(librtree_a_SOURCES)
+DIST_SOURCES = $(librtree_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+noinst_LIBRARIES = librtree.a
+librtree_a_SOURCES = index.c \
+                 index.h \
+                 rect.c \
+                 node.c \
+                 card.c \
+                 card.h \
+                 split_l.c \
+                 split_l.h 
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rtree/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/rtree/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+librtree.a: $(librtree_a_OBJECTS) $(librtree_a_DEPENDENCIES) 
+	-rm -f librtree.a
+	$(librtree_a_AR) librtree.a $(librtree_a_OBJECTS) $(librtree_a_LIBADD)
+	$(RANLIB) librtree.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/card.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/index.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/node.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rect.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/split_l.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/rtree/card.c b/src/rtree/card.c
new file mode 100644
index 0000000..2e7c655
--- /dev/null
+++ b/src/rtree/card.c
@@ -0,0 +1,52 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: card.c,v 1.10 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+#include "index.h"
+#include "card.h"
+
+int Xastir_NODECARD = MAXCARD;
+int Xastir_LEAFCARD = MAXCARD;
+
+static int set_max(int *which, int new_max)
+{
+	if(2 > new_max || new_max > MAXCARD)
+		return 0;
+	*which = new_max;
+	return 1;
+}
+
+int Xastir_RTreeSetNodeMax(int new_max) { return set_max(&Xastir_NODECARD, new_max); }
+int Xastir_RTreeSetLeafMax(int new_max) { return set_max(&Xastir_LEAFCARD, new_max); }
+int Xastir_RTreeGetNodeMax(void) { return Xastir_NODECARD; }
+int Xastir_RTreeGetLeafMax(void) { return Xastir_LEAFCARD; }
diff --git a/src/rtree/card.h b/src/rtree/card.h
new file mode 100644
index 0000000..ad84659
--- /dev/null
+++ b/src/rtree/card.h
@@ -0,0 +1,49 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: card.h,v 1.9 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+#ifndef __CARD__
+#define __CARD__
+
+extern int Xastir_NODECARD;
+extern int Xastir_LEAFCARD;
+
+/* balance criteria for node splitting */
+/* NOTE: can be changed if needed. */
+#define MinNodeFill (Xastir_NODECARD / 2)
+#define MinLeafFill (Xastir_LEAFCARD / 2)
+
+#define MAXKIDS(n) ((n)->level > 0 ? Xastir_NODECARD : Xastir_LEAFCARD)
+#define MINFILL(n) ((n)->level > 0 ? MinNodeFill : MinLeafFill)
+
+#endif
diff --git a/src/rtree/index.c b/src/rtree/index.c
new file mode 100644
index 0000000..31f1475
--- /dev/null
+++ b/src/rtree/index.c
@@ -0,0 +1,367 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: index.c,v 1.12 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "assert.h"
+#include "index.h"
+#include "card.h"
+
+
+// Make a new index, empty.  Consists of a single node.
+//
+struct Node * Xastir_RTreeNewIndex(void)
+{
+	struct Node *x;
+	x = Xastir_RTreeNewNode();
+	x->level = 0; /* leaf */
+	return x;
+}
+
+
+
+// Search in an index tree or subtree for all data retangles that
+// overlap the argument rectangle.
+// Return the number of qualifying data rects.
+//
+int Xastir_RTreeSearch(struct Node *N, struct Rect *R, SearchHitCallback shcb, void* cbarg)
+{
+	register struct Node *n = N;
+	register struct Rect *r = R; // NOTE: Suspected bug was R sent in as Node* and cast to Rect* here. Fix not yet tested.
+	register int hitCount = 0;
+	register int i;
+
+	assert(n);
+	assert(n->level >= 0);
+	assert(r);
+
+	if (n->level > 0) /* this is an internal node in the tree */
+	{
+		for (i=0; i<Xastir_NODECARD; i++)
+			if (n->branch[i].child &&
+			    Xastir_RTreeOverlap(r,&n->branch[i].rect))
+			{
+				hitCount += Xastir_RTreeSearch(n->branch[i].child, R, shcb, cbarg);
+			}
+	}
+	else /* this is a leaf node */
+	{
+		for (i=0; i<Xastir_LEAFCARD; i++)
+			if (n->branch[i].child &&
+			    Xastir_RTreeOverlap(r,&n->branch[i].rect))
+			{
+				hitCount++;
+				if(shcb) // call the user-provided callback
+					if( ! shcb(n->branch[i].child, cbarg))
+						return hitCount; // callback wants to terminate search early
+			}
+	}
+	return hitCount;
+}
+
+
+
+// Inserts a new data rectangle into the index structure.
+// Recursively descends tree, propagates splits back up.
+// Returns 0 if node was not split.  Old node updated.
+// If node was split, returns 1 and sets the pointer pointed to by
+// new_node to point to the new node.  Old node updated to become one of two.
+// The level argument specifies the number of steps up from the leaf
+// level to insert; e.g. a data rectangle goes in at level = 0.
+//
+static int Xastir_RTreeInsertRect2(struct Rect *r,
+		void *tid, struct Node *n, struct Node **new_node, int level)
+{
+/*
+	register struct Rect *r = R;
+	register int tid = Tid;
+	register struct Node *n = N, **new_node = New_node;
+	register int level = Level;
+*/
+
+	register int i;
+	struct Branch b;
+	struct Node *n2;
+
+	assert(r && n && new_node);
+	assert(level >= 0 && level <= n->level);
+
+	// Still above level for insertion, go down tree recursively
+	//
+	if (n->level > level)
+	{
+		i = Xastir_RTreePickBranch(r, n);
+		if (!Xastir_RTreeInsertRect2(r, tid, n->branch[i].child, &n2, level))
+		{
+			// child was not split
+			//
+			n->branch[i].rect =
+				Xastir_RTreeCombineRect(r,&(n->branch[i].rect));
+			return 0;
+		}
+		else    // child was split
+		{
+			n->branch[i].rect = Xastir_RTreeNodeCover(n->branch[i].child);
+			b.child = n2;
+			b.rect = Xastir_RTreeNodeCover(n2);
+			return Xastir_RTreeAddBranch(&b, n, new_node);
+		}
+	}
+
+	// Have reached level for insertion. Add rect, split if necessary
+	//
+	else if (n->level == level)
+	{
+		b.rect = *r;
+		b.child = (struct Node *) tid;
+		/* child field of leaves contains tid of data record */
+		return Xastir_RTreeAddBranch(&b, n, new_node);
+	}
+	else
+	{
+		/* Not supposed to happen */
+		assert (FALSE);
+		return 0;
+	}
+}
+
+
+
+// Insert a data rectangle into an index structure.
+// Xastir_RTreeInsertRect provides for splitting the root;
+// returns 1 if root was split, 0 if it was not.
+// The level argument specifies the number of steps up from the leaf
+// level to insert; e.g. a data rectangle goes in at level = 0.
+// Xastir_RTreeInsertRect2 does the recursion.
+//
+int Xastir_RTreeInsertRect(struct Rect *R, void *Tid, struct Node **Root, int Level)
+{
+	register struct Rect *r = R;
+	register void *tid = Tid;
+	register struct Node **root = Root;
+	register int level = Level;
+	register int i;
+	register struct Node *newroot;
+	struct Node *newnode;
+	struct Branch b;
+	int result;
+
+	assert(r && root);
+	assert(level >= 0 && level <= (*root)->level);
+	for (i=0; i<NUMDIMS; i++)
+		assert(r->boundary[i] <= r->boundary[NUMDIMS+i]);
+
+	if (Xastir_RTreeInsertRect2(r, tid, *root, &newnode, level))  /* root split */
+	{
+		newroot = Xastir_RTreeNewNode();  /* grow a new root, & tree taller */
+		newroot->level = (*root)->level + 1;
+		b.rect = Xastir_RTreeNodeCover(*root);
+		b.child = *root;
+		Xastir_RTreeAddBranch(&b, newroot, NULL);
+		b.rect = Xastir_RTreeNodeCover(newnode);
+		b.child = newnode;
+		Xastir_RTreeAddBranch(&b, newroot, NULL);
+		*root = newroot;
+		result = 1;
+	}
+	else
+		result = 0;
+
+	return result;
+}
+
+
+
+
+// Allocate space for a node in the list used in DeletRect to
+// store Nodes that are too empty.
+//
+static struct ListNode * Xastir_RTreeNewListNode(void)
+{
+	return (struct ListNode *) malloc(sizeof(struct ListNode));
+	//return new ListNode;
+}
+
+
+static void Xastir_RTreeFreeListNode(struct ListNode *p)
+{
+	free(p);
+	//delete(p);
+}
+
+
+
+// Add a node to the reinsertion list.  All its branches will later
+// be reinserted into the index structure.
+//
+static void Xastir_RTreeReInsert(struct Node *n, struct ListNode **ee)
+{
+	register struct ListNode *l;
+
+	l = Xastir_RTreeNewListNode();
+	l->node = n;
+	l->next = *ee;
+	*ee = l;
+}
+
+
+// Delete a rectangle from non-root part of an index structure.
+// Called by Xastir_RTreeDeleteRect.  Descends tree recursively,
+// merges branches on the way back up.
+// Returns 1 if record not found, 0 if success.
+//
+static int
+Xastir_RTreeDeleteRect2(struct Rect *R, void *Tid, struct Node *N, struct ListNode **Ee)
+{
+	register struct Rect *r = R;
+	register void *tid = Tid;
+	register struct Node *n = N;
+	register struct ListNode **ee = Ee;
+	register int i;
+
+	assert(r && n && ee);
+	assert(tid >= (void *)0);
+	assert(n->level >= 0);
+
+	if (n->level > 0)  // not a leaf node
+	{
+	    for (i = 0; i < Xastir_NODECARD; i++)
+	    {
+		if (n->branch[i].child && Xastir_RTreeOverlap(r, &(n->branch[i].rect)))
+		{
+			if (!Xastir_RTreeDeleteRect2(r, tid, n->branch[i].child, ee))
+			{
+				if (n->branch[i].child->count >= MinNodeFill)
+					n->branch[i].rect = Xastir_RTreeNodeCover(
+						n->branch[i].child);
+				else
+				{
+					// not enough entries in child,
+					// eliminate child node
+					//
+					Xastir_RTreeReInsert(n->branch[i].child, ee);
+					Xastir_RTreeDisconnectBranch(n, i);
+				}
+				return 0;
+			}
+		}
+	    }
+	    return 1;
+	}
+	else  // a leaf node
+	{
+		for (i = 0; i < Xastir_LEAFCARD; i++)
+		{
+			if (n->branch[i].child &&
+			    n->branch[i].child == (struct Node *) tid)
+			{
+				Xastir_RTreeDisconnectBranch(n, i);
+				return 0;
+			}
+		}
+		return 1;
+	}
+}
+
+
+
+// Delete a data rectangle from an index structure.
+// Pass in a pointer to a Rect, the tid of the record, ptr to ptr to root node.
+// Returns 1 if record not found, 0 if success.
+// Xastir_RTreeDeleteRect provides for eliminating the root.
+//
+int Xastir_RTreeDeleteRect(struct Rect *R, void *Tid, struct Node**Nn)
+{
+	register struct Rect *r = R;
+	register void *tid = Tid;
+	register struct Node **nn = Nn;
+	register int i;
+	register struct Node *tmp_nptr=NULL; // Original superliminal.com
+                                             // source did not initialize.
+                                             // Code analysis says shouldn't
+                                             // matter, but let's initialize
+                                             // to shut up GCC
+	struct ListNode *reInsertList = NULL;
+	register struct ListNode *e;
+
+	assert(r && nn);
+	assert(*nn);
+	assert(tid >= (void *)0);
+
+	if (!Xastir_RTreeDeleteRect2(r, tid, *nn, &reInsertList))
+	{
+		/* found and deleted a data item */
+
+		/* reinsert any branches from eliminated nodes */
+		while (reInsertList)
+		{
+			tmp_nptr = reInsertList->node;
+			for (i = 0; i < MAXKIDS(tmp_nptr); i++)
+			{
+				if (tmp_nptr->branch[i].child)
+				{
+					Xastir_RTreeInsertRect(
+						&(tmp_nptr->branch[i].rect),
+						tmp_nptr->branch[i].child,
+						nn,
+						tmp_nptr->level);
+				}
+			}
+			e = reInsertList;
+			reInsertList = reInsertList->next;
+			Xastir_RTreeFreeNode(e->node);
+			Xastir_RTreeFreeListNode(e);
+		}
+		
+		/* check for redundant root (not leaf, 1 child) and eliminate
+		*/
+		if ((*nn)->count == 1 && (*nn)->level > 0)
+		{
+			for (i = 0; i < Xastir_NODECARD; i++)
+			{
+				tmp_nptr = (*nn)->branch[i].child;
+				if(tmp_nptr)
+					break;
+			}
+			assert(tmp_nptr);
+			Xastir_RTreeFreeNode(*nn);
+			*nn = tmp_nptr;
+		}
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
diff --git a/src/rtree/index.h b/src/rtree/index.h
new file mode 100644
index 0000000..7ab212b
--- /dev/null
+++ b/src/rtree/index.h
@@ -0,0 +1,130 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: index.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+#ifndef _INDEX_
+#define _INDEX_
+
+/* PGSIZE is normally the natural page size of the machine */
+#define PGSIZE	512
+#define NUMDIMS	2	/* number of dimensions */
+#define NDEBUG
+
+// This is what GRASS does
+//typedef double RectReal;
+// but this is the original, and saves lots of RAM --- these indices are
+// huge for big shapefiles!
+typedef float RectReal;
+
+
+/*-----------------------------------------------------------------------------
+| Global definitions.
+-----------------------------------------------------------------------------*/
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define NUMSIDES 2*NUMDIMS
+
+struct Rect
+{
+	RectReal boundary[NUMSIDES]; /* xmin,ymin,...,xmax,ymax,... */
+};
+
+struct Node;
+
+struct Branch
+{
+	struct Rect rect;
+	struct Node *child;
+};
+
+/* max branching factor of a node */
+#define MAXCARD (int)((PGSIZE-(2*sizeof(int))) / sizeof(struct Branch))
+
+struct Node
+{
+	int count;
+	int level; /* 0 is leaf, others positive */
+	struct Branch branch[MAXCARD];
+};
+
+struct ListNode
+{
+	struct ListNode *next;
+	struct Node *node;
+};
+
+/*
+ * If passed to a tree search, this callback function will be called
+ * with the ID of each data rect that overlaps the search rect
+ * plus whatever user specific pointer was passed to the search.
+ * It can terminate the search early by returning 0 in which case
+ * the search will return the number of hits found up to that point.
+ */
+typedef int (*SearchHitCallback)(void *id, void* arg);
+
+
+extern int Xastir_RTreeSearch(struct Node*, struct Rect*, SearchHitCallback, void*);
+extern int Xastir_RTreeInsertRect(struct Rect*, void *, struct Node**, int depth);
+extern int Xastir_RTreeDeleteRect(struct Rect*, void *, struct Node**);
+extern struct Node * Xastir_RTreeNewIndex(void);
+extern struct Node * Xastir_RTreeNewNode(void);
+extern void Xastir_RTreeInitNode(struct Node*);
+extern void Xastir_RTreeFreeNode(struct Node *);
+extern void Xastir_RTreePrintNode(struct Node *, int);
+extern void Xastir_RTreeDestroyNode(struct Node*);
+extern void Xastir_RTreeTabIn(int);
+extern struct Rect Xastir_RTreeNodeCover(struct Node *);
+extern void Xastir_RTreeInitRect(struct Rect*);
+extern struct Rect Xastir_RTreeNullRect(void);
+extern RectReal Xastir_RTreeRectArea(struct Rect*);
+extern RectReal Xastir_RTreeRectSphericalVolume(struct Rect *R);
+extern RectReal Xastir_RTreeRectVolume(struct Rect *R);
+extern struct Rect Xastir_RTreeCombineRect(struct Rect*, struct Rect*);
+extern int Xastir_RTreeOverlap(struct Rect*, struct Rect*);
+extern void Xastir_RTreePrintRect(struct Rect*, int);
+extern int Xastir_RTreeAddBranch(struct Branch *, struct Node *, struct Node **);
+extern int Xastir_RTreePickBranch(struct Rect *, struct Node *);
+extern void Xastir_RTreeDisconnectBranch(struct Node *, int);
+extern void Xastir_RTreeSplitNode(struct Node*, struct Branch*, struct Node**);
+
+extern int Xastir_RTreeSetNodeMax(int);
+extern int Xastir_RTreeSetLeafMax(int);
+extern int Xastir_RTreeGetNodeMax(void);
+extern int Xastir_RTreeGetLeafMax(void);
+
+#endif /* _INDEX_ */
diff --git a/src/rtree/node.c b/src/rtree/node.c
new file mode 100644
index 0000000..eb4c2b7
--- /dev/null
+++ b/src/rtree/node.c
@@ -0,0 +1,285 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: node.c,v 1.13 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "assert.h"
+#include "index.h"
+#include "card.h"
+//static int nnodes_alloced=0;
+//static long int bytes_malloced=0;
+
+// Initialize one branch cell in a node.
+//
+static void Xastir_RTreeInitBranch(struct Branch *b)
+{
+	Xastir_RTreeInitRect(&(b->rect));
+	b->child = NULL;
+}
+
+
+
+// Initialize a Node structure.
+//
+void Xastir_RTreeInitNode(struct Node *N)
+{
+	register struct Node *n = N;
+	register int i;
+	n->count = 0;
+	n->level = -1;
+	for (i = 0; i < MAXCARD; i++)
+		Xastir_RTreeInitBranch(&(n->branch[i]));
+}
+
+
+
+// Make a new node and initialize to have all branch cells empty.
+//
+struct Node * Xastir_RTreeNewNode(void)
+{
+	register struct Node *n;
+
+	//n = new Node;
+	n = (struct Node*)malloc(sizeof(struct Node));
+	assert(n);
+        //        nnodes_alloced++;
+        //        bytes_malloced+= sizeof(struct Node);
+        //        fprintf(stderr,"   Currently %d nodes (%ld bytes) in all rtrees\n",nnodes_alloced, bytes_malloced);
+	Xastir_RTreeInitNode(n);
+	return n;
+}
+
+
+void Xastir_RTreeFreeNode(struct Node *p)
+{
+	assert(p);
+	//delete p;
+        //        nnodes_alloced--;
+        //        bytes_malloced-= sizeof(struct Node);
+	free(p);
+}
+
+
+
+static void Xastir_RTreePrintBranch(struct Branch *b, int depth)
+{
+	Xastir_RTreePrintRect(&(b->rect), depth);
+	Xastir_RTreePrintNode(b->child, depth);
+}
+
+
+extern void Xastir_RTreeTabIn(int depth)
+{
+	int i;
+	for(i=0; i<depth; i++)
+		putchar('\t');
+}
+
+
+// Print out the data in a node.
+//
+void Xastir_RTreePrintNode(struct Node *n, int depth)
+{
+	int i;
+	assert(n);
+
+	Xastir_RTreeTabIn(depth);
+	printf("node");
+	if (n->level == 0)
+		printf(" LEAF");
+	else if (n->level > 0)
+		printf(" NONLEAF");
+	else
+		printf(" TYPE=?");
+        // Original superliminal.com implementation had no cast before 
+        // n, gcc gripes about "int format, pointer arg"
+        printf("  level=%d  count=%d  address=%lx\n", n->level, n->count, (unsigned long) n);
+
+	for (i=0; i<n->count; i++)
+	{
+		if(n->level == 0) {
+                    //			Xastir_RTreeTabIn(depth);
+                    //			printf("\t%d: data = %d\n", i, n->branch[i].child);
+		}
+		else {
+			Xastir_RTreeTabIn(depth);
+			printf("branch %d\n", i);
+			Xastir_RTreePrintBranch(&n->branch[i], depth+1);
+		}
+	}
+}
+
+
+
+// Find the smallest rectangle that includes all rectangles in
+// branches of a node.
+//
+struct Rect Xastir_RTreeNodeCover(struct Node *N)
+{
+	register struct Node *n = N;
+	register int i, first_time=1;
+	struct Rect r;
+	assert(n);
+
+	Xastir_RTreeInitRect(&r);
+	for (i = 0; i < MAXKIDS(n); i++)
+		if (n->branch[i].child)
+		{
+			if (first_time)
+			{
+				r = n->branch[i].rect;
+				first_time = 0;
+			}
+			else
+				r = Xastir_RTreeCombineRect(&r, &(n->branch[i].rect));
+		}
+	return r;
+}
+
+
+
+// Pick a branch.  Pick the one that will need the smallest increase
+// in area to accomodate the new rectangle.  This will result in the
+// least total area for the covering rectangles in the current node.
+// In case of a tie, pick the one which was smaller before, to get
+// the best resolution when searching.
+//
+int Xastir_RTreePickBranch(struct Rect *R, struct Node *N)
+{
+	register struct Rect *r = R;
+	register struct Node *n = N;
+	register struct Rect *rr;
+	register int i, first_time=1;
+        // Although it is impossible for bestArea and best to be used
+        // unininitialized the way the code is structured, gcc complains 
+        // about possible uninitialized usage.  Let's keep it happy.
+        // Original superliminal.com had no initializers here.
+	RectReal increase, bestIncr=(RectReal)-1, area, bestArea=0.0;
+	int best=0;
+	struct Rect tmp_rect;
+	assert(r && n);
+
+	for (i=0; i<MAXKIDS(n); i++)
+	{
+		if (n->branch[i].child)
+		{
+			rr = &n->branch[i].rect;
+			area = Xastir_RTreeRectSphericalVolume(rr);
+			tmp_rect = Xastir_RTreeCombineRect(r, rr);
+			increase = Xastir_RTreeRectSphericalVolume(&tmp_rect) - area;
+			if (increase < bestIncr || first_time)
+			{
+				best = i;
+				bestArea = area;
+				bestIncr = increase;
+				first_time = 0;
+			}
+			else if (increase == bestIncr && area < bestArea)
+			{
+				best = i;
+				bestArea = area;
+				bestIncr = increase;
+			}
+		}
+	}
+	return best;
+}
+
+
+
+// Add a branch to a node.  Split the node if necessary.
+// Returns 0 if node not split.  Old node updated.
+// Returns 1 if node split, sets *new_node to address of new node.
+// Old node updated, becomes one of two.
+//
+int Xastir_RTreeAddBranch(struct Branch *B, struct Node *N, struct Node **New_node)
+{
+	register struct Branch *b = B;
+	register struct Node *n = N;
+	register struct Node **new_node = New_node;
+	register int i;
+
+	assert(b);
+	assert(n);
+
+	if (n->count < MAXKIDS(n))  /* split won't be necessary */
+	{
+		for (i = 0; i < MAXKIDS(n); i++)  /* find empty branch */
+		{
+			if (n->branch[i].child == NULL)
+			{
+				n->branch[i] = *b;
+				n->count++;
+				break;
+			}
+		}
+		return 0;
+	}
+	else
+	{
+		assert(new_node);
+		Xastir_RTreeSplitNode(n, b, new_node);
+		return 1;
+	}
+}
+
+
+
+// Disconnect a dependent node.
+//
+void Xastir_RTreeDisconnectBranch(struct Node *n, int i)
+{
+	assert(n && i>=0 && i<MAXKIDS(n));
+	assert(n->branch[i].child);
+
+	Xastir_RTreeInitBranch(&(n->branch[i]));
+	n->count--;
+}
+
+// Destroy (free) node recursively. 
+void Xastir_RTreeDestroyNode (struct Node *n)
+{
+    int i;
+    //    fprintf(stderr,"  Freeing node %lx\n",(unsigned long int) n);
+    if (n->level > 0) {  //it is not leaf -> destroy childs 
+        for ( i = 0; i < Xastir_NODECARD; i++) {
+            if ( n->branch[i].child ) {
+                Xastir_RTreeDestroyNode ( n->branch[i].child );
+            }
+        }
+    }
+    
+    //
+    Xastir_RTreeFreeNode( n );
+}
diff --git a/src/rtree/rect.c b/src/rtree/rect.c
new file mode 100644
index 0000000..d7dc263
--- /dev/null
+++ b/src/rtree/rect.c
@@ -0,0 +1,393 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: rect.c,v 1.11 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "assert.h"
+#include "index.h"
+
+#include <float.h>
+#include <math.h>
+
+#define BIG_NUM (FLT_MAX/4.0)
+
+
+#define Undefined(x) ((x)->boundary[0] > (x)->boundary[NUMDIMS])
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+
+/*-----------------------------------------------------------------------------
+| Initialize a rectangle to have all 0 coordinates.
+-----------------------------------------------------------------------------*/
+void Xastir_RTreeInitRect(struct Rect *R)
+{
+	register struct Rect *r = R;
+	register int i;
+	for (i=0; i<NUMSIDES; i++)
+		r->boundary[i] = (RectReal)0;
+}
+
+
+/*-----------------------------------------------------------------------------
+| Return a rect whose first low side is higher than its opposite side -
+| interpreted as an undefined rect.
+-----------------------------------------------------------------------------*/
+struct Rect Xastir_RTreeNullRect(void)
+{
+	struct Rect r;
+	register int i;
+
+	r.boundary[0] = (RectReal)1;
+	r.boundary[NUMDIMS] = (RectReal)-1;
+	for (i=1; i<NUMDIMS; i++)
+		r.boundary[i] = r.boundary[i+NUMDIMS] = (RectReal)0;
+	return r;
+}
+
+
+#if 0
+
+/*-----------------------------------------------------------------------------
+| Fills in random coordinates in a rectangle.
+| The low side is guaranteed to be less than the high side.
+-----------------------------------------------------------------------------*/
+void Xastir_RTreeRandomRect(struct Rect *R)
+{
+	register struct Rect *r = R;
+	register int i;
+	register RectReal width;
+	for (i = 0; i < NUMDIMS; i++)
+	{
+		/* width from 1 to 1000 / 4, more small ones
+		*/
+		width = drand48() * (1000 / 4) + 1;
+
+		/* sprinkle a given size evenly but so they stay in [0,100]
+		*/
+		r->boundary[i] = drand48() * (1000-width); /* low side */
+		r->boundary[i + NUMDIMS] = r->boundary[i] + width; // high side
+	}
+}
+
+
+/*-----------------------------------------------------------------------------
+| Fill in the boundaries for a random search rectangle.
+| Pass in a pointer to a rect that contains all the data,
+| and a pointer to the rect to be filled in.
+| Generated rect is centered randomly anywhere in the data area,
+| and has size from 0 to the size of the data area in each dimension,
+| i.e. search rect can stick out beyond data area.
+-----------------------------------------------------------------------------*/
+void Xastir_RTreeSearchRect(struct Rect *Search, struct Rect *Data)
+{
+	register struct Rect *search = Search, *data = Data;
+	register int i, j;
+	register RectReal size, center;
+
+	assert(search);
+	assert(data);
+
+	for (i=0; i<NUMDIMS; i++)
+	{
+		j = i + NUMDIMS;  // index for high side boundary
+		if (data->boundary[i] > -BIG_NUM &&
+		    data->boundary[j] < BIG_NUM)
+		{
+			size = (drand48() * (data->boundary[j] -
+					 data->boundary[i] + 1)) / 2;
+			center = data->boundary[i] + drand48() *
+				(data->boundary[j] - data->boundary[i] + 1);
+			search->boundary[i] = center - size/2;
+			search->boundary[j] = center + size/2;
+		}
+		else  // some open boundary, search entire dimension
+		{
+			search->boundary[i] = -BIG_NUM;
+			search->boundary[j] = BIG_NUM;
+		}
+	}
+}
+
+#endif
+
+/*-----------------------------------------------------------------------------
+| Print out the data for a rectangle.
+-----------------------------------------------------------------------------*/
+void Xastir_RTreePrintRect(struct Rect *R, int depth)
+{
+	register struct Rect *r = R;
+	register int i;
+	assert(r);
+
+	Xastir_RTreeTabIn(depth);
+	printf("rect:\n");
+	for (i = 0; i < NUMDIMS; i++) {
+		Xastir_RTreeTabIn(depth+1);
+		printf("%f\t%f\n", r->boundary[i], r->boundary[i + NUMDIMS]);
+	}
+}
+
+/*-----------------------------------------------------------------------------
+| Calculate the n-dimensional volume of a rectangle
+-----------------------------------------------------------------------------*/
+RectReal Xastir_RTreeRectVolume(struct Rect *R)
+{
+	register struct Rect *r = R;
+	register int i;
+	register RectReal volume = (RectReal)1;
+
+	assert(r);
+	if (Undefined(r))
+		return (RectReal)0;
+
+	for(i=0; i<NUMDIMS; i++)
+		volume *= r->boundary[i+NUMDIMS] - r->boundary[i];
+	assert(volume >= 0.0);
+	return volume;
+}
+
+
+/*-----------------------------------------------------------------------------
+| Define the NUMDIMS-dimensional volume the unit sphere in that dimension into
+| the symbol "Xastir_UnitSphereVolume"
+| Note that if the gamma function is available in the math library and if the
+| compiler supports static initialization using functions, this is
+| easily computed for any dimension. If not, the value can be precomputed and
+| taken from a table. The following code can do it either way.
+-----------------------------------------------------------------------------*/
+
+#ifdef gamma
+
+/* computes the volume of an N-dimensional sphere. */
+/* derived from formule in "Regular Polytopes" by H.S.M Coxeter */
+static double sphere_volume(double dimension)
+{
+	static const double log_pi = log(3.1415926535);
+	double log_gamma, log_volume;
+	log_gamma = gamma(dimension/2.0 + 1);
+	log_volume = dimension/2.0 * log_pi - log_gamma;
+	return exp(log_volume);
+}
+static const double Xastir_UnitSphereVolume = sphere_volume(NUMDIMS);
+
+#else
+
+/* Precomputed volumes of the unit spheres for the first few dimensions */
+const double Xastir_UnitSphereVolumes[] = {
+	0.000000,  /* dimension   0 */
+	2.000000,  /* dimension   1 */
+	3.141593,  /* dimension   2 */
+	4.188790,  /* dimension   3 */
+	4.934802,  /* dimension   4 */
+	5.263789,  /* dimension   5 */
+	5.167713,  /* dimension   6 */
+	4.724766,  /* dimension   7 */
+	4.058712,  /* dimension   8 */
+	3.298509,  /* dimension   9 */
+	2.550164,  /* dimension  10 */
+	1.884104,  /* dimension  11 */
+	1.335263,  /* dimension  12 */
+	0.910629,  /* dimension  13 */
+	0.599265,  /* dimension  14 */
+	0.381443,  /* dimension  15 */
+	0.235331,  /* dimension  16 */
+	0.140981,  /* dimension  17 */
+	0.082146,  /* dimension  18 */
+	0.046622,  /* dimension  19 */
+	0.025807,  /* dimension  20 */
+};
+#if NUMDIMS > 20
+#	error "not enough precomputed sphere volumes"
+#endif
+#define Xastir_UnitSphereVolume Xastir_UnitSphereVolumes[NUMDIMS]
+
+#endif
+
+
+/*-----------------------------------------------------------------------------
+| Calculate the n-dimensional volume of the bounding sphere of a rectangle
+-----------------------------------------------------------------------------*/
+
+#if 0
+/*
+ * A fast approximation to the volume of the bounding sphere for the
+ * given Rect. By Paul B.
+ */
+RectReal Xastir_RTreeRectSphericalVolume(struct Rect *R)
+{
+	register struct Rect *r = R;
+	register int i;
+	RectReal maxsize=(RectReal)0, c_size;
+
+	assert(r);
+	if (Undefined(r))
+		return (RectReal)0;
+	for (i=0; i<NUMDIMS; i++) {
+		c_size = r->boundary[i+NUMDIMS] - r->boundary[i];
+		if (c_size > maxsize)
+			maxsize = c_size;
+	}
+	return (RectReal)(pow(maxsize/2, NUMDIMS) * Xastir_UnitSphereVolume);
+}
+#endif
+
+/*
+ * The exact volume of the bounding sphere for the given Rect.
+ */
+RectReal Xastir_RTreeRectSphericalVolume(struct Rect *R)
+{
+	register struct Rect *r = R;
+	register int i;
+	register double sum_of_squares=0, radius;
+
+	assert(r);
+	if (Undefined(r))
+		return (RectReal)0;
+	for (i=0; i<NUMDIMS; i++) {
+		double half_extent =
+			(r->boundary[i+NUMDIMS] - r->boundary[i]) / 2;
+		sum_of_squares += half_extent * half_extent;
+	}
+	radius = sqrt(sum_of_squares);
+	return (RectReal)(pow(radius, NUMDIMS) * Xastir_UnitSphereVolume);
+}
+
+
+/*-----------------------------------------------------------------------------
+| Calculate the n-dimensional surface area of a rectangle
+-----------------------------------------------------------------------------*/
+RectReal Xastir_RTreeRectSurfaceArea(struct Rect *R)
+{
+	register struct Rect *r = R;
+	register int i, j;
+	register RectReal sum = (RectReal)0;
+
+	assert(r);
+	if (Undefined(r))
+		return (RectReal)0;
+
+	for (i=0; i<NUMDIMS; i++) {
+		RectReal face_area = (RectReal)1;
+		for (j=0; j<NUMDIMS; j++)
+			/* exclude i extent from product in this dimension */
+			if(i != j) {
+				RectReal j_extent =
+					r->boundary[j+NUMDIMS] - r->boundary[j];
+				face_area *= j_extent;
+			}
+		sum += face_area;
+	}
+	return 2 * sum;
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Combine two rectangles, make one that includes both.
+-----------------------------------------------------------------------------*/
+struct Rect Xastir_RTreeCombineRect(struct Rect *R, struct Rect *Rr)
+{
+	register struct Rect *r = R, *rr = Rr;
+	register int i, j;
+	struct Rect new_rect;
+	assert(r && rr);
+
+	if (Undefined(r))
+		return *rr;
+
+	if (Undefined(rr))
+		return *r;
+
+	for (i = 0; i < NUMDIMS; i++)
+	{
+		new_rect.boundary[i] = MIN(r->boundary[i], rr->boundary[i]);
+		j = i + NUMDIMS;
+		new_rect.boundary[j] = MAX(r->boundary[j], rr->boundary[j]);
+	}
+	return new_rect;
+}
+
+
+/*-----------------------------------------------------------------------------
+| Decide whether two rectangles overlap.
+-----------------------------------------------------------------------------*/
+int Xastir_RTreeOverlap(struct Rect *R, struct Rect *S)
+{
+	register struct Rect *r = R, *s = S;
+	register int i, j;
+	assert(r && s);
+
+	for (i=0; i<NUMDIMS; i++)
+	{
+		j = i + NUMDIMS;  /* index for high sides */
+		if (r->boundary[i] > s->boundary[j] ||
+		    s->boundary[i] > r->boundary[j])
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+
+/*-----------------------------------------------------------------------------
+| Decide whether rectangle r is contained in rectangle s.
+-----------------------------------------------------------------------------*/
+int Xastir_RTreeContained(struct Rect *R, struct Rect *S)
+{
+	register struct Rect *r = R, *s = S;
+	register int i, j, result;
+	assert(r && s);
+
+ 	// undefined rect is contained in any other
+	//
+	if (Undefined(r))
+		return TRUE;
+
+	// no rect (except an undefined one) is contained in an undef rect
+	//
+	if (Undefined(s))
+		return FALSE;
+
+	result = TRUE;
+	for (i = 0; i < NUMDIMS; i++)
+	{
+		j = i + NUMDIMS;  /* index for high sides */
+		result = result
+			&& r->boundary[i] >= s->boundary[i]
+			&& r->boundary[j] <= s->boundary[j];
+	}
+	return result;
+}
diff --git a/src/rtree/split_l.c b/src/rtree/split_l.c
new file mode 100644
index 0000000..8246faf
--- /dev/null
+++ b/src/rtree/split_l.c
@@ -0,0 +1,408 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: split_l.c,v 1.12 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+#include <stdio.h>
+#include "assert.h"
+#include "index.h"
+#include "card.h"
+#include "split_l.h"
+
+
+/*-----------------------------------------------------------------------------
+| Load branch buffer with branches from full node plus the extra branch.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreeGetBranches(struct Node *N, struct Branch *B)
+{
+	register struct Node *n = N;
+	register struct Branch *b = B;
+	register int i;
+
+	assert(n);
+	assert(b);
+
+	/* load the branch buffer */
+	for (i=0; i<MAXKIDS(n); i++)
+	{
+		assert(n->branch[i].child);  /* every entry should be full */
+		Xastir_BranchBuf[i] = n->branch[i];
+	}
+	Xastir_BranchBuf[MAXKIDS(n)] = *b;
+	Xastir_BranchCount = MAXKIDS(n) + 1;
+
+	/* calculate rect containing all in the set */
+	Xastir_CoverSplit = Xastir_BranchBuf[0].rect;
+	for (i=1; i<MAXKIDS(n)+1; i++)
+	{
+		Xastir_CoverSplit = Xastir_RTreeCombineRect(&Xastir_CoverSplit, &Xastir_BranchBuf[i].rect);
+	}
+
+	Xastir_RTreeInitNode(n);
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Initialize a PartitionVars structure.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreeInitPVars(struct PartitionVars *P, int maxrects, int minfill)
+{
+	register struct PartitionVars *p = P;
+	register int i;
+	assert(p);
+
+	p->count[0] = p->count[1] = 0;
+	p->total = maxrects;
+	p->minfill = minfill;
+	for (i=0; i<maxrects; i++)
+	{
+		p->taken[i] = FALSE;
+		p->partition[i] = -1;
+	}
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Put a branch in one of the groups.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreeClassify(int i, int group, struct PartitionVars *p)
+{
+	assert(p);
+	assert(!p->taken[i]);
+
+	p->partition[i] = group;
+	p->taken[i] = TRUE;
+
+	if (p->count[group] == 0)
+		p->cover[group] = Xastir_BranchBuf[i].rect;
+	else
+		p->cover[group] = Xastir_RTreeCombineRect(&Xastir_BranchBuf[i].rect,
+					&p->cover[group]);
+	p->area[group] = Xastir_RTreeRectSphericalVolume(&p->cover[group]);
+	p->count[group]++;
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Pick two rects from set to be the first elements of the two groups.
+| Pick the two that are separated most along any dimension, or overlap least.
+| Distance for separation or overlap is measured modulo the width of the
+| space covered by the entire set along that dimension.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreePickSeeds(struct PartitionVars *P)
+{
+	register struct PartitionVars *p = P;
+	register int i, dim, high;
+	register struct Rect *r, *rlow, *rhigh;
+        // Original superliminal.com implementation had no initializers here.
+        // They are not strictly necessary, as the variables are initialized
+        // in the first iteration of the first for loop, but GCC complains
+        // anyway.  Initializers added to keep it happy.
+	register float w, separation, bestSep=0.0;
+	RectReal width[NUMDIMS];
+	int leastUpper[NUMDIMS], greatestLower[NUMDIMS];
+	int seed0=0, seed1=0;
+	assert(p);
+	
+	for (dim=0; dim<NUMDIMS; dim++)
+	{
+		high = dim + NUMDIMS;
+
+		/* find the rectangles farthest out in each direction
+		 * along this dimens */
+		greatestLower[dim] = leastUpper[dim] = 0;
+		for (i=1; i<Xastir_NODECARD+1; i++)
+		{
+			r = &Xastir_BranchBuf[i].rect;
+			if (r->boundary[dim] >
+			    Xastir_BranchBuf[greatestLower[dim]].rect.boundary[dim])
+			{
+				greatestLower[dim] = i;
+			}
+			if (r->boundary[high] <
+			    Xastir_BranchBuf[leastUpper[dim]].rect.boundary[high])
+			{
+				leastUpper[dim] = i;
+			}
+		}
+
+		/* find width of the whole collection along this dimension */
+		width[dim] = Xastir_CoverSplit.boundary[high] -
+			     Xastir_CoverSplit.boundary[dim];
+	}
+
+	/* pick the best separation dimension and the two seed rects */
+	for (dim=0; dim<NUMDIMS; dim++)
+	{
+		high = dim + NUMDIMS;
+
+		/* divisor for normalizing by width */
+		assert(width[dim] >= 0);
+		if (width[dim] == 0)
+			w = (RectReal)1;
+		else
+			w = width[dim];
+
+		rlow = &Xastir_BranchBuf[leastUpper[dim]].rect;
+		rhigh = &Xastir_BranchBuf[greatestLower[dim]].rect;
+		if (dim == 0)
+		{
+			seed0 = leastUpper[0];
+			seed1 = greatestLower[0];
+			separation = bestSep =
+				(rhigh->boundary[0] -
+				 rlow->boundary[NUMDIMS]) / w;
+		}
+		else
+		{
+			separation =
+				(rhigh->boundary[dim] -
+				rlow->boundary[dim+NUMDIMS]) / w;
+			if (separation > bestSep)
+			{
+				seed0 = leastUpper[dim];
+				seed1 = greatestLower[dim];
+				bestSep = separation;
+			}
+		}
+	}
+
+	if (seed0 != seed1)
+	{
+		Xastir_RTreeClassify(seed0, 0, p);
+		Xastir_RTreeClassify(seed1, 1, p);
+	}
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Put each rect that is not already in a group into a group.
+| Process one rect at a time, using the following hierarchy of criteria.
+| In case of a tie, go to the next test.
+| 1) If one group already has the max number of elements that will allow
+| the minimum fill for the other group, put r in the other.
+| 2) Put r in the group whose cover will expand less.  This automatically
+| takes care of the case where one group cover contains r.
+| 3) Put r in the group whose cover will be smaller.  This takes care of the
+| case where r is contained in both covers.
+| 4) Put r in the group with fewer elements.
+| 5) Put in group 1 (arbitrary).
+|
+| Also update the covers for both groups.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreePigeonhole(struct PartitionVars *P)
+{
+	register struct PartitionVars *p = P;
+	struct Rect newCover[2];
+	register int i, group;
+	RectReal newArea[2], increase[2];
+
+	for (i=0; i<Xastir_NODECARD+1; i++)
+	{
+		if (!p->taken[i])
+		{
+			/* if one group too full, put rect in the other */
+			if (p->count[0] >= p->total - p->minfill)
+			{
+				Xastir_RTreeClassify(i, 1, p);
+				continue;
+			}
+			else if (p->count[1] >= p->total - p->minfill)
+			{
+				Xastir_RTreeClassify(i, 0, p);
+				continue;
+			}
+
+			/* find areas of the two groups' old and new covers */
+			for (group=0; group<2; group++)
+			{
+				if (p->count[group]>0)
+					newCover[group] = Xastir_RTreeCombineRect(
+						&Xastir_BranchBuf[i].rect,
+						&p->cover[group]);
+				else
+					newCover[group] = Xastir_BranchBuf[i].rect;
+				newArea[group] = Xastir_RTreeRectSphericalVolume(
+							&newCover[group]);
+				increase[group] = newArea[group]-p->area[group];
+			}
+
+			/* put rect in group whose cover will expand less */
+			if (increase[0] < increase[1])
+				Xastir_RTreeClassify(i, 0, p);
+			else if (increase[1] < increase[0])
+				Xastir_RTreeClassify(i, 1, p);
+
+			/* put rect in group that will have a smaller cover */
+			else if (p->area[0] < p->area[1])
+				Xastir_RTreeClassify(i, 0, p);
+			else if (p->area[1] < p->area[0])
+				Xastir_RTreeClassify(i, 1, p);
+
+			/* put rect in group with fewer elements */
+			else if (p->count[0] < p->count[1])
+				Xastir_RTreeClassify(i, 0, p);
+			else
+				Xastir_RTreeClassify(i, 1, p);
+		}
+	}
+	assert(p->count[0] + p->count[1] == Xastir_NODECARD + 1);
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Method 0 for finding a partition:
+| First find two seeds, one for each group, well separated.
+| Then put other rects in whichever group will be smallest after addition.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreeMethodZero(struct PartitionVars *p, int minfill)
+{
+	Xastir_RTreeInitPVars(p, Xastir_BranchCount, minfill);
+	Xastir_RTreePickSeeds(p);
+	Xastir_RTreePigeonhole(p);
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+| Copy branches from the buffer into two nodes according to the partition.
+-----------------------------------------------------------------------------*/
+static void Xastir_RTreeLoadNodes(struct Node *N, struct Node *Q,
+			struct PartitionVars *P)
+{
+	register struct Node *n = N, *q = Q;
+	register struct PartitionVars *p = P;
+	register int i;
+	assert(n);
+	assert(q);
+	assert(p);
+
+	for (i=0; i<Xastir_NODECARD+1; i++)
+	{
+		if (p->partition[i] == 0)
+			Xastir_RTreeAddBranch(&Xastir_BranchBuf[i], n, NULL);
+		else if (p->partition[i] == 1)
+			Xastir_RTreeAddBranch(&Xastir_BranchBuf[i], q, NULL);
+		else
+			assert(FALSE);
+	}
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Split a node.
+| Divides the nodes branches and the extra one between two nodes.
+| Old node is one of the new ones, and one really new one is created.
+-----------------------------------------------------------------------------*/
+void Xastir_RTreeSplitNode(struct Node *n, struct Branch *b, struct Node **nn)
+{
+	register struct PartitionVars *p;
+	register int level;
+	RectReal area;
+
+	assert(n);
+	assert(b);
+
+	/* load all the branches into a buffer, initialize old node */
+	level = n->level;
+	Xastir_RTreeGetBranches(n, b);
+
+	/* find partition */
+	p = &Xastir_Partitions[0];
+
+	/* Note: can't use MINFILL(n) below since n was cleared by GetBranches() */
+	Xastir_RTreeMethodZero(p, level>0 ? MinNodeFill : MinLeafFill);
+
+	/* record how good the split was for statistics */
+	area = p->area[0] + p->area[1];
+
+	/* put branches from buffer in 2 nodes according to chosen partition */
+	*nn = Xastir_RTreeNewNode();
+	(*nn)->level = n->level = level;
+	Xastir_RTreeLoadNodes(n, *nn, p);
+	assert(n->count + (*nn)->count == Xastir_NODECARD+1);
+}
+
+
+
+/*-----------------------------------------------------------------------------
+| Print out data for a partition from PartitionVars struct.
+-----------------------------------------------------------------------------*/
+
+// This is not used at the moment, and because it's declared static gcc
+// warns us it's not used.  Commented out to shut gcc up
+#if 0
+static void Xastir_RTreePrintPVars(struct PartitionVars *p)
+{
+	int i;
+	assert(p);
+
+	printf("\npartition:\n");
+	for (i=0; i<Xastir_NODECARD+1; i++)
+	{
+		printf("%3d\t", i);
+	}
+	printf("\n");
+	for (i=0; i<Xastir_NODECARD+1; i++)
+	{
+		if (p->taken[i])
+			printf("  t\t");
+		else
+			printf("\t");
+	}
+	printf("\n");
+	for (i=0; i<Xastir_NODECARD+1; i++)
+	{
+		printf("%3d\t", p->partition[i]);
+	}
+	printf("\n");
+
+	printf("count[0] = %d  area = %f\n", p->count[0], p->area[0]);
+	printf("count[1] = %d  area = %f\n", p->count[1], p->area[1]);
+	printf("total area = %f  effectiveness = %3.2f\n",
+		p->area[0] + p->area[1],
+		Xastir_RTreeRectSphericalVolume(&Xastir_CoverSplit)/(p->area[0]+p->area[1]));
+
+	printf("cover[0]:\n");
+	Xastir_RTreePrintRect(&p->cover[0], 0);
+
+	printf("cover[1]:\n");
+	Xastir_RTreePrintRect(&p->cover[1], 0);
+}
+#endif // shut up GCC
diff --git a/src/rtree/split_l.h b/src/rtree/split_l.h
new file mode 100644
index 0000000..b3c7a75
--- /dev/null
+++ b/src/rtree/split_l.h
@@ -0,0 +1,54 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: split_l.h,v 1.11 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+/****************************************************************************
+ * MODULE:       R-Tree library 
+ *              
+ * AUTHOR(S):    Antonin Guttman - original code
+ *               Melinda Green (melinda at superliminal.com) - major clean-up
+ *                               and implementation of bounding spheres
+ *               
+ * PURPOSE:      Multidimensional index
+ *
+ */
+
+/*-----------------------------------------------------------------------------
+| Definitions and global variables used in linear split code.
+-----------------------------------------------------------------------------*/
+
+#define METHODS 1
+
+struct Branch Xastir_BranchBuf[MAXCARD+1];
+int Xastir_BranchCount;
+struct Rect Xastir_CoverSplit;
+
+/* variables for finding a partition */
+struct PartitionVars
+{
+	int partition[MAXCARD+1];
+	int total, minfill;
+	int taken[MAXCARD+1];
+	int count[2];
+	struct Rect cover[2];
+	RectReal area[2];
+} Xastir_Partitions[METHODS];
diff --git a/src/shapelib/ChangeLog b/src/shapelib/ChangeLog
new file mode 100644
index 0000000..0675b70
--- /dev/null
+++ b/src/shapelib/ChangeLog
@@ -0,0 +1,204 @@
+2003-04-07  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* Issue 1.2.10 Release.
+
+2003-03-10  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: modified DBFWriteAttribute call so that it returns FALSE
+	if it has to truncate the input value.
+
+2003-01-28  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shptree.c: avoid build warnings.
+
+2002-05-07  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Added DBFWriteAttributeDirectly() from the AVCE00
+	distribution to simplify AVC integration in GDAL.
+
+	* shptree.c: added use of qsort() in place of bubble sort as 
+	submitted by Bernhard Herzog.
+
+2002-04-10  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: Added SHPRewindObject() to correct ring winding.
+
+	* shprewind.c: New utility program.
+
+2002-03-12  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shapelib.def: added DBFWriteNULLAttribute.
+
+2002-01-17  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* contrib/ShapeFileII.pas: Contributed Delphi Pascal interface
+	to Shapelib. 
+
+2002-01-15  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shapelib.h: Added support for SHAPELIB_DLLEXPORT macro, and write
+	up material attempting to explain the use of SHPAPI_CALL macros.
+
+	* dbfopen.c: Compute nHeaderLength in DBFCloneEmpty() instead of
+	copying it from the source file so we don't have quirks when copying
+	from files with extra bytes of spacers in the header that don't 
+	themselves get copied properly.
+
+2001-12-07  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: Fix fclose() of SHX file if SHX file fails to open. 
+	Should be closing SHP file.  Reported by Ben Discoe.
+
+2001-11-28  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: two fixes for compiler warnings as suggested by
+	Richard Hash.
+
+2001-11-01  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c/shapefil.h: Move record buffer into SHPInfo so that 
+	different threads can safely access separate files.  Other threading
+	issues may remain.
+
+2001-08-28  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* Issue Shapelib 1.2.9
+
+	* shputils.c: DBFAddField() call should check for -1 return value
+	for failure.
+
+2001-07-03  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: cleanup better if SHX missing, provided by 
+	Riccardo Cohen.
+
+2001-06-21  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: Fixed NULL support with patches from Jim Matthews. 
+
+	* shpopen.c: Be more careful of establishing initial file bounds in
+	face of possible NULL shapes.
+
+2001-06-01  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* dbfopen.c: ensure binary mode open.
+
+2001-05-31  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: Add support for writing null shapes.
+
+	* dbfopen.c: added DBFGetFieldIndex(), contributed by Jim Matthews.
+
+	* dbfopen.c/shapefil.h/dbf_api.h: added support for NULL fields
+	in .dbf files. 
+
+2001-05-28  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shpopen.c: add some checking on the record count to ensure it
+	is reasonable.
+
+2001-05-23  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* shapefile.h, shpopen.c, dbfopen.c, shptree.c: added the SHPAPI_CALL
+	macro to allow compilation with _stdcall conventions. 
+
+2001-02-06  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* Fixed a few memory leaks when SHPOpen() fails. 
+
+2000-12-05  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* Fix from Craig Bruce (Cubewerx) for DBFReadAttribute() for
+	the white space trimming code to avoid reading outside allocated
+	memory.
+
+2000-11-02  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Checked in upgraded shputils.c from Bill Miller.
+
+2000-10-05  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Fixed DBFWriteAttribute() to ensure we can't overwrite the
+	end of the szSField buffer even if the width is set large.
+	Bug report by Kirk Benell <kirk at rsinc.com>.
+
+2000-09-25  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Added DBFGetNativeFieldType() (contributed by Daniel) to dbfopen.c.
+
+2000-07-18  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* added better enforcement of -1 for append in SHPWriteObject().
+
+2000-07-07  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Added stdlib.h and string.h where needed, and removed lots of 
+	unused variables, mainly from example mainlines at the suggestion
+	of Bill Hughes. 
+
+2000-05-24  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Added logic to shpadd to grow vertex lists at the suggestion of 
+	Santiago Nullo <sn at softhome.net>.
+	
+2000-05-23  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Added checks in dbfopen.c on return result of fseek() and fread().
+
+	* Avoid crashing in DBReadIntegerAttribute() or DBFReadDoubleAttribte()
+	if the field or record are out of range.
+
+2000-03-28  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Release as 1.2.8.
+
+	* Incorporated a -version-info fix and added mkinstalldirs from Jan.
+
+2000-03-17  Frank Warmerdam  <warmerda at cs46980-c>
+
+	* Added shared library hack to Makefile.
+
+	* Fixed up test scripts to look in ./ for executables.
+
+Wed Feb 16 11:20:29 2000  Frank Warmerdam  <warmerda at gdal.velocet.ca>
+
+	* Release 1.2.7.
+
+	* Modified SHPReadObject() so that will return NULL (type 0) shapes
+	in a sort of sensible way.
+
+Wed Dec 15 08:49:53 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
+
+	* Fixed record size written at beginning of records in .shp
+	file.  It was 4 bytes to long (thanks to Mikko Syrja of 3D-system Oy)
+	
+	* Use atof() instead of sscanf() in dbfopen.c, and add stdlib.h.
+
+Mon Dec 13 12:29:01 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
+
+	* Added support for uppercase .DBF extention c/o 
+          Dennis Christopher <dennis at avenza.com>
+
+Fri Nov  5 09:12:31 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
+
+	* Updated license headers to include the option of use of the code
+	  under the LGPL.
+	  
+1999-09-15 <warmerda at CS46980-B>
+
+	* Added shapelib.dll target to makefile.vc.
+
+Mon May 10 23:19:42 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
+
+	* Added candrsn's improvements to extension handling in dbfopen.c
+
+	* Added ``raw tuple'' api to dbfopen.c, still not in dbf_api.html.
+	  From candrsn.
+	
+
+Tue May  4 11:04:31 1999  Frank Warmerdam  <warmerda at gdal.velocet.ca>
+
+	* Prepare 1.2.5 release.
+
+	* Added support for 'F' fields.
+
diff --git a/src/shapelib/LICENSE.LGPL b/src/shapelib/LICENSE.LGPL
new file mode 100644
index 0000000..0b643ac
--- /dev/null
+++ b/src/shapelib/LICENSE.LGPL
@@ -0,0 +1,483 @@
+
+		  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/shapelib/Makefile.am b/src/shapelib/Makefile.am
new file mode 100644
index 0000000..2d41535
--- /dev/null
+++ b/src/shapelib/Makefile.am
@@ -0,0 +1,42 @@
+
+# $Id: Makefile.am,v 1.16 2012/11/01 18:57:19 we7u Exp $
+# Copyright (C) 2004-2012  The Xastir Group
+
+noinst_LIBRARIES=libshape.a
+
+noinst_PROGRAMS=dbfadd \
+        dbfcreate \
+        dbfdump \
+        shpadd \
+        shpcreate \
+        shpdump \
+        shprewind \
+        shptest \
+        shptreedump \
+        shputils
+
+libshape_a_SOURCES=shpopen.c \
+		shptree.c \
+		dbfopen.c \
+		shapefil.h
+
+dbfadd_LDADD=libshape.a
+dbfcreate_LDADD=libshape.a
+dbfdump_LDADD=libshape.a
+shpadd_LDADD=libshape.a
+shpcreate_LDADD=libshape.a
+shpdump_LDADD=libshape.a
+shprewind_LDADD=libshape.a
+shptest_LDADD=libshape.a
+shptreedump_LDADD=libshape.a
+shputils_LDADD=libshape.a
+
+EXTRA_DIST=ChangeLog LICENSE.LGPL README README.tree dbf_api.html \
+	dbfadd.c dbfcreate.c dbfdump.c libtool makefile.vc makeshape.sh \
+        mkinstalldirs shapelib.def shapelib.html shp_api.html \
+	shpadd.c shpcreate.c shpdump.c shprewind.c shptest.c shptreedump.c \
+	shputils.c stream1.out stream1.sh stream2.out stream2.sh stream3.out
+DIST_SUBDIRS=contrib
+SUBDIRS=contrib
+
+
diff --git a/src/shapelib/Makefile.in b/src/shapelib/Makefile.in
new file mode 100644
index 0000000..55189f1
--- /dev/null
+++ b/src/shapelib/Makefile.in
@@ -0,0 +1,724 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.16 2012/11/01 18:57:19 we7u Exp $
+# Copyright (C) 2004-2012  The Xastir Group
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = dbfadd$(EXEEXT) dbfcreate$(EXEEXT) dbfdump$(EXEEXT) \
+	shpadd$(EXEEXT) shpcreate$(EXEEXT) shpdump$(EXEEXT) \
+	shprewind$(EXEEXT) shptest$(EXEEXT) shptreedump$(EXEEXT) \
+	shputils$(EXEEXT)
+subdir = src/shapelib
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	ChangeLog mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libshape_a_AR = $(AR) $(ARFLAGS)
+libshape_a_LIBADD =
+am_libshape_a_OBJECTS = shpopen.$(OBJEXT) shptree.$(OBJEXT) \
+	dbfopen.$(OBJEXT)
+libshape_a_OBJECTS = $(am_libshape_a_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+dbfadd_SOURCES = dbfadd.c
+dbfadd_OBJECTS = dbfadd.$(OBJEXT)
+dbfadd_DEPENDENCIES = libshape.a
+dbfcreate_SOURCES = dbfcreate.c
+dbfcreate_OBJECTS = dbfcreate.$(OBJEXT)
+dbfcreate_DEPENDENCIES = libshape.a
+dbfdump_SOURCES = dbfdump.c
+dbfdump_OBJECTS = dbfdump.$(OBJEXT)
+dbfdump_DEPENDENCIES = libshape.a
+shpadd_SOURCES = shpadd.c
+shpadd_OBJECTS = shpadd.$(OBJEXT)
+shpadd_DEPENDENCIES = libshape.a
+shpcreate_SOURCES = shpcreate.c
+shpcreate_OBJECTS = shpcreate.$(OBJEXT)
+shpcreate_DEPENDENCIES = libshape.a
+shpdump_SOURCES = shpdump.c
+shpdump_OBJECTS = shpdump.$(OBJEXT)
+shpdump_DEPENDENCIES = libshape.a
+shprewind_SOURCES = shprewind.c
+shprewind_OBJECTS = shprewind.$(OBJEXT)
+shprewind_DEPENDENCIES = libshape.a
+shptest_SOURCES = shptest.c
+shptest_OBJECTS = shptest.$(OBJEXT)
+shptest_DEPENDENCIES = libshape.a
+shptreedump_SOURCES = shptreedump.c
+shptreedump_OBJECTS = shptreedump.$(OBJEXT)
+shptreedump_DEPENDENCIES = libshape.a
+shputils_SOURCES = shputils.c
+shputils_OBJECTS = shputils.$(OBJEXT)
+shputils_DEPENDENCIES = libshape.a
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libshape_a_SOURCES) dbfadd.c dbfcreate.c dbfdump.c \
+	shpadd.c shpcreate.c shpdump.c shprewind.c shptest.c \
+	shptreedump.c shputils.c
+DIST_SOURCES = $(libshape_a_SOURCES) dbfadd.c dbfcreate.c dbfdump.c \
+	shpadd.c shpcreate.c shpdump.c shprewind.c shptest.c \
+	shptreedump.c shputils.c
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+noinst_LIBRARIES = libshape.a
+libshape_a_SOURCES = shpopen.c \
+		shptree.c \
+		dbfopen.c \
+		shapefil.h
+
+dbfadd_LDADD = libshape.a
+dbfcreate_LDADD = libshape.a
+dbfdump_LDADD = libshape.a
+shpadd_LDADD = libshape.a
+shpcreate_LDADD = libshape.a
+shpdump_LDADD = libshape.a
+shprewind_LDADD = libshape.a
+shptest_LDADD = libshape.a
+shptreedump_LDADD = libshape.a
+shputils_LDADD = libshape.a
+EXTRA_DIST = ChangeLog LICENSE.LGPL README README.tree dbf_api.html \
+	dbfadd.c dbfcreate.c dbfdump.c libtool makefile.vc makeshape.sh \
+        mkinstalldirs shapelib.def shapelib.html shp_api.html \
+	shpadd.c shpcreate.c shpdump.c shprewind.c shptest.c shptreedump.c \
+	shputils.c stream1.out stream1.sh stream2.out stream2.sh stream3.out
+
+DIST_SUBDIRS = contrib
+SUBDIRS = contrib
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/shapelib/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/shapelib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libshape.a: $(libshape_a_OBJECTS) $(libshape_a_DEPENDENCIES) 
+	-rm -f libshape.a
+	$(libshape_a_AR) libshape.a $(libshape_a_OBJECTS) $(libshape_a_LIBADD)
+	$(RANLIB) libshape.a
+
+clean-noinstPROGRAMS:
+	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+dbfadd$(EXEEXT): $(dbfadd_OBJECTS) $(dbfadd_DEPENDENCIES) 
+	@rm -f dbfadd$(EXEEXT)
+	$(LINK) $(dbfadd_OBJECTS) $(dbfadd_LDADD) $(LIBS)
+dbfcreate$(EXEEXT): $(dbfcreate_OBJECTS) $(dbfcreate_DEPENDENCIES) 
+	@rm -f dbfcreate$(EXEEXT)
+	$(LINK) $(dbfcreate_OBJECTS) $(dbfcreate_LDADD) $(LIBS)
+dbfdump$(EXEEXT): $(dbfdump_OBJECTS) $(dbfdump_DEPENDENCIES) 
+	@rm -f dbfdump$(EXEEXT)
+	$(LINK) $(dbfdump_OBJECTS) $(dbfdump_LDADD) $(LIBS)
+shpadd$(EXEEXT): $(shpadd_OBJECTS) $(shpadd_DEPENDENCIES) 
+	@rm -f shpadd$(EXEEXT)
+	$(LINK) $(shpadd_OBJECTS) $(shpadd_LDADD) $(LIBS)
+shpcreate$(EXEEXT): $(shpcreate_OBJECTS) $(shpcreate_DEPENDENCIES) 
+	@rm -f shpcreate$(EXEEXT)
+	$(LINK) $(shpcreate_OBJECTS) $(shpcreate_LDADD) $(LIBS)
+shpdump$(EXEEXT): $(shpdump_OBJECTS) $(shpdump_DEPENDENCIES) 
+	@rm -f shpdump$(EXEEXT)
+	$(LINK) $(shpdump_OBJECTS) $(shpdump_LDADD) $(LIBS)
+shprewind$(EXEEXT): $(shprewind_OBJECTS) $(shprewind_DEPENDENCIES) 
+	@rm -f shprewind$(EXEEXT)
+	$(LINK) $(shprewind_OBJECTS) $(shprewind_LDADD) $(LIBS)
+shptest$(EXEEXT): $(shptest_OBJECTS) $(shptest_DEPENDENCIES) 
+	@rm -f shptest$(EXEEXT)
+	$(LINK) $(shptest_OBJECTS) $(shptest_LDADD) $(LIBS)
+shptreedump$(EXEEXT): $(shptreedump_OBJECTS) $(shptreedump_DEPENDENCIES) 
+	@rm -f shptreedump$(EXEEXT)
+	$(LINK) $(shptreedump_OBJECTS) $(shptreedump_LDADD) $(LIBS)
+shputils$(EXEEXT): $(shputils_OBJECTS) $(shputils_DEPENDENCIES) 
+	@rm -f shputils$(EXEEXT)
+	$(LINK) $(shputils_OBJECTS) $(shputils_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfadd.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfcreate.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfdump.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfopen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpadd.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpcreate.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpdump.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpopen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shprewind.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shptest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shptree.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shptreedump.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shputils.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@fail= failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \
+	ctags-recursive distclean distclean-compile distclean-generic \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+	ps ps-am tags tags-recursive uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/shapelib/README b/src/shapelib/README
new file mode 100755
index 0000000..ad5faa3
--- /dev/null
+++ b/src/shapelib/README
@@ -0,0 +1,35 @@
+
+Please read shapelib.html.
+
+Building on Unix
+----------------
+
+1) Edit Makefile, and set CFLAGS, and CC macros as required for the
+   target system.  Often the defaults will work fine.
+
+2) "type make" 
+
+The result should be:
+
+Core shapelib support.  
+  shpopen.o
+  dbfopen.o
+
+Utility/demonstration programs:
+  shpcreate, shpdump, shpadd, dbfcreate, dbfdump, dbfadd
+
+To test type:
+  make test
+
+
+Building on Windows
+-------------------
+
+If you have run the VC++ VCVARS32.BAT, you should be able to type the 
+following in a command window to build the code and executables:
+
+C:>  nmake /f makefile.vc 
+
+Otherwise create your own VC++ project.  There aren't many files to deal with
+here!
+
diff --git a/src/shapelib/README.tree b/src/shapelib/README.tree
new file mode 100644
index 0000000..434c648
--- /dev/null
+++ b/src/shapelib/README.tree
@@ -0,0 +1,172 @@
+Venkat,
+
+I have completed the planned Shapefile quadtree mechanism.  The additions
+to the traditional Shapelib are found in shptree.c (functions supporting
+quad tree searching and query).  There are also some new prototypes for
+the tree stuff in shapefil.h ... including some prototypes for functions
+you don't require and hence that I haven't implemented at this time. 
+
+I have also prepared a demonstration program using the API.  That is
+the ``shpdumptree'' program, with the source code in shpdumptree.c.  The
+shpdumptree program has two functions.  One is to dump an ASCII rendering
+of the internal quadtree, and the other is example use of a quad tree
+searching function. 
+
+Dumping the Tree
+----------------
+
+The tree dumping is done as shown below.  The "-maxdepth" commandline
+switch can be used to control the maximum depth, otherwise it internally
+computes a ``reasonable depth'' to use based on the number of structures
+in the shapefile.
+
+warmerda at gdal[207]% shptreedump -maxdepth 6 eg_data/polygon.shp
+( SHPTreeNode
+  Min = (471127.19,4751545.00)
+  Max = (489292.31,4765610.50)
+  Shapes(0): 
+  ( SHPTreeNode
+    Min = (471127.19,4751545.00)
+    Max = (481118.01,4765610.50)
+    Shapes(0): 
+    ( SHPTreeNode
+      Min = (471127.19,4751545.00)
+      Max = (481118.01,4759281.03)
+      Shapes(0): 
+      ( SHPTreeNode
+        Min = (471127.19,4751545.00)
+        Max = (476622.14,4759281.03)
+        Shapes(0): 
+        ( SHPTreeNode
+          Min = (471127.19,4751545.00)
+          Max = (476622.14,4755799.81)
+          Shapes(0): 
+          ( SHPTreeNode
+            Min = (471127.19,4751545.00)
+            Max = (474149.41,4755799.81)
+            Shapes(6): 395 397 402 404 405 422 
+          )
+          ( SHPTreeNode
+            Min = (473599.92,4751545.00)
+            Max = (476622.14,4755799.81)
+            Shapes(10): 392 394 403 413 414 417 426 433 434 447 
+          )
+        )
+...
+
+A structure like the following represents one node in the tree.  In
+this case it cover the region of 473599.92 < X < 476622.14,and 
+4751545.0 < Y < 4755799.81.  There are ten shapes within this region
+who's shapeids are 392, 394 ... 447.  This node has no children nodes.
+
+          ( SHPTreeNode
+            Min = (473599.92,4751545.00)
+            Max = (476622.14,4755799.81)
+            Shapes(10): 392 394 403 413 414 417 426 433 434 447 
+          )
+
+The heirarchy of indentation is intended to show the parent, child 
+relationship between nodes, with the tree being deeper the further to the
+right you go. 
+
+The `-v' flag to the program can be used to expand the report to include
+the full information about shapes, not just their shapeid.  This can result
+in a report looking more like this:
+
+          ...
+          ( SHPTreeNode
+            Min = (478095.78,4751545.00)
+            Max = (481118.01,4755799.81)
+            Shapes(3):
+            ( Shape
+              ShapeId = 448
+              Min = (479988.09,4753300.00)
+              Max = (480705.59,4754236.50)
+              Vertex[0] = (480136.59,4754174.50)
+              Vertex[1] = (480229.97,4754182.00)
+              Vertex[2] = (480370.09,4754200.50)
+              Vertex[3] = (480695.12,4754236.50)
+              Vertex[4] = (480687.97,4754129.50)
+              Vertex[5] = (480650.47,4754075.50)
+              Vertex[6] = (480520.62,4753948.00)
+              Vertex[7] = (480490.00,4753900.00)
+              Vertex[8] = (480499.78,4753840.50)
+              Vertex[9] = (480500.97,4753820.50)
+              Vertex[10] = (480534.75,4753660.50)
+              Vertex[11] = (480560.00,4753565.00)
+              Vertex[12] = (480574.91,4753550.50)
+          ...
+
+While it is possible to part the output of the shptreedump program, and
+insert it into your database, my intention was that the shptreedump program
+would serve as an example of how to pre-order traversal of the quad tree,
+and collect the information you will need to insert into your database. 
+I would then expect you to write a new program based on shptreedump that
+calls a C API for your database to insert objects instead of printing them
+out.  Alternatively there may be an ASCII format for loading tables that
+you could modify the program to output. 
+
+Searching
+---------
+
+The other thing that you can do with the shptreedump program is to 
+perform a search on the quadtree.  For instance the following shows
+searching on a small region.
+
+% shptreedump -search 471127 4751545 476622 4759281 eg_data/polygon.shp
+Shape 17: not in area of interest, but fetched.
+Shape 31: not in area of interest, but fetched.
+Shape 52: not in area of interest, but fetched.
+Shape 76: not in area of interest, but fetched.
+Shape 82: not in area of interest, but fetched.
+Shape 104: not in area of interest, but fetched.
+Shape 124: not in area of interest, but fetched.
+Shape 134: not in area of interest, but fetched.
+Shape 139: not in area of interest, but fetched.
+Shape 154: not in area of interest, but fetched.
+Shape 175: not in area of interest, but fetched.
+Shape 177: not in area of interest, but fetched.
+Shape 185: not in area of interest, but fetched.
+Shape 192: not in area of interest, but fetched.
+Shape 196: appears to be in area of interest.
+....
+
+
+I have included this capability (and the SHPTreeFindLikelyShapes() function)
+so that you can see a working example of how to search this quad tree. 
+Note that searching is a multi-stage affair.  
+
+First a pass is made over the quadtree, collecting the shapeids of all
+shapes contained in a quadtree node for which the bounding rectangle overlaps
+the search rectangle.  This is all accomplished by SHPTreeFindLikelyShapes()
+in shptree.c. 
+
+The second phase is to fetch the actual shapes, and verify if their bounding
+box falls within the area of interest.  This is necessary because the shape 
+will tend to have a significantly smaller bounding rectangle than the tree 
+node in which it is found.  This can result ``false positives'' on the first
+phase search, as indicated by teh ``not in area of interest, but fetched''
+messages above.  This stage is done in the SHPTreeNodeSearchAndDump()
+function in shptreedump.c. 
+
+A possible third phase is to verify that the actualy line segments in the
+shape actually cross the area of interest.  I don't both with this as it
+is complicated, and assuming that the drawing engine takes care of clipping
+it is quite a bit easier to let it fall through. 
+
+Building
+--------
+
+I have added a makefile.vc to the shapelib distribution.  After you have
+unpacked the shapefile you should have a shapelib subdirectory.  If you
+cd to that directory, and enter ``nmake -f makefile.vc'' in a DOS window
+you should be able to build everything with VC++ (assuming it is properly
+installed and in your path). 
+
+You can also create a project in VC just including the files 
+shpopen.c, shptree.c and shptreedump.c, building as a Win32 console
+application. 
+
+For your convenience I am including prebuild .obj files, and .exe files
+in the distribution. 
+
diff --git a/src/shapelib/contrib/Makefile.am b/src/shapelib/contrib/Makefile.am
new file mode 100644
index 0000000..efc9635
--- /dev/null
+++ b/src/shapelib/contrib/Makefile.am
@@ -0,0 +1,51 @@
+
+# $Id: Makefile.am,v 1.13 2012/11/01 18:57:19 we7u Exp $
+# C2pyright (C) 2004-2012  The Xastir Group
+
+EXTRA_DIST=Makefile_orig ShapeFileII.pas dbfcat.c dbfinfo.c makefile.vc \
+	my_nan.h shpcat.c shpcentrd.c shpdata.c shpdxf.c shpfix.c \
+	shpgeo.c shpgeo.h shpinfo.c shpproj.c shpwkb.c
+
+noinst_LIBRARIES=libshape.a
+
+noinst_PROGRAMS=dbfcat \
+        dbfinfo \
+        shpcat \
+        shpdxf \
+        shpfix \
+        shpinfo @CONTSHP@
+
+EXTRA_PROGRAMS = shpcentrd shpproj shpdata shpwkb
+libshape_a_SOURCES=../shpopen.c \
+        ../shptree.c \
+        ../dbfopen.c \
+        ../shapefil.h
+
+shpcentrd_SOURCES=shpcentrd.c \
+        shpgeo.c \
+        shpgeo.h
+
+shpdata_SOURCES=shpdata.c \
+        shpgeo.c \
+        shpgeo.h
+
+shpproj_SOURCES=shpproj.c \
+        shpgeo.c \
+        shpgeo.h
+
+shpwkb_SOURCES=shpwkb.c \
+        shpgeo.c \
+        shpgeo.h
+
+dbfcat_LDADD=libshape.a
+dbfinfo_LDADD=libshape.a
+shpcat_LDADD=libshape.a
+shpcentrd_LDADD=libshape.a
+shpdata_LDADD=libshape.a
+shpdxf_LDADD=libshape.a
+shpfix_LDADD=libshape.a
+shpinfo_LDADD=libshape.a
+shpproj_LDADD=libshape.a
+shpwkb_LDADD=libshape.a
+
+
diff --git a/src/shapelib/contrib/Makefile.in b/src/shapelib/contrib/Makefile.in
new file mode 100644
index 0000000..668ee0a
--- /dev/null
+++ b/src/shapelib/contrib/Makefile.in
@@ -0,0 +1,627 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.13 2012/11/01 18:57:19 we7u Exp $
+# C2pyright (C) 2004-2012  The Xastir Group
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = dbfcat$(EXEEXT) dbfinfo$(EXEEXT) shpcat$(EXEEXT) \
+	shpdxf$(EXEEXT) shpfix$(EXEEXT) shpinfo$(EXEEXT) @CONTSHP@
+EXTRA_PROGRAMS = shpcentrd$(EXEEXT) shpproj$(EXEEXT) shpdata$(EXEEXT) \
+	shpwkb$(EXEEXT)
+subdir = src/shapelib/contrib
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libshape_a_AR = $(AR) $(ARFLAGS)
+libshape_a_LIBADD =
+am_libshape_a_OBJECTS = shpopen.$(OBJEXT) shptree.$(OBJEXT) \
+	dbfopen.$(OBJEXT)
+libshape_a_OBJECTS = $(am_libshape_a_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+dbfcat_SOURCES = dbfcat.c
+dbfcat_OBJECTS = dbfcat.$(OBJEXT)
+dbfcat_DEPENDENCIES = libshape.a
+dbfinfo_SOURCES = dbfinfo.c
+dbfinfo_OBJECTS = dbfinfo.$(OBJEXT)
+dbfinfo_DEPENDENCIES = libshape.a
+shpcat_SOURCES = shpcat.c
+shpcat_OBJECTS = shpcat.$(OBJEXT)
+shpcat_DEPENDENCIES = libshape.a
+am_shpcentrd_OBJECTS = shpcentrd.$(OBJEXT) shpgeo.$(OBJEXT)
+shpcentrd_OBJECTS = $(am_shpcentrd_OBJECTS)
+shpcentrd_DEPENDENCIES = libshape.a
+am_shpdata_OBJECTS = shpdata.$(OBJEXT) shpgeo.$(OBJEXT)
+shpdata_OBJECTS = $(am_shpdata_OBJECTS)
+shpdata_DEPENDENCIES = libshape.a
+shpdxf_SOURCES = shpdxf.c
+shpdxf_OBJECTS = shpdxf.$(OBJEXT)
+shpdxf_DEPENDENCIES = libshape.a
+shpfix_SOURCES = shpfix.c
+shpfix_OBJECTS = shpfix.$(OBJEXT)
+shpfix_DEPENDENCIES = libshape.a
+shpinfo_SOURCES = shpinfo.c
+shpinfo_OBJECTS = shpinfo.$(OBJEXT)
+shpinfo_DEPENDENCIES = libshape.a
+am_shpproj_OBJECTS = shpproj.$(OBJEXT) shpgeo.$(OBJEXT)
+shpproj_OBJECTS = $(am_shpproj_OBJECTS)
+shpproj_DEPENDENCIES = libshape.a
+am_shpwkb_OBJECTS = shpwkb.$(OBJEXT) shpgeo.$(OBJEXT)
+shpwkb_OBJECTS = $(am_shpwkb_OBJECTS)
+shpwkb_DEPENDENCIES = libshape.a
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libshape_a_SOURCES) dbfcat.c dbfinfo.c shpcat.c \
+	$(shpcentrd_SOURCES) $(shpdata_SOURCES) shpdxf.c shpfix.c \
+	shpinfo.c $(shpproj_SOURCES) $(shpwkb_SOURCES)
+DIST_SOURCES = $(libshape_a_SOURCES) dbfcat.c dbfinfo.c shpcat.c \
+	$(shpcentrd_SOURCES) $(shpdata_SOURCES) shpdxf.c shpfix.c \
+	shpinfo.c $(shpproj_SOURCES) $(shpwkb_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+EXTRA_DIST = Makefile_orig ShapeFileII.pas dbfcat.c dbfinfo.c makefile.vc \
+	my_nan.h shpcat.c shpcentrd.c shpdata.c shpdxf.c shpfix.c \
+	shpgeo.c shpgeo.h shpinfo.c shpproj.c shpwkb.c
+
+noinst_LIBRARIES = libshape.a
+libshape_a_SOURCES = ../shpopen.c \
+        ../shptree.c \
+        ../dbfopen.c \
+        ../shapefil.h
+
+shpcentrd_SOURCES = shpcentrd.c \
+        shpgeo.c \
+        shpgeo.h
+
+shpdata_SOURCES = shpdata.c \
+        shpgeo.c \
+        shpgeo.h
+
+shpproj_SOURCES = shpproj.c \
+        shpgeo.c \
+        shpgeo.h
+
+shpwkb_SOURCES = shpwkb.c \
+        shpgeo.c \
+        shpgeo.h
+
+dbfcat_LDADD = libshape.a
+dbfinfo_LDADD = libshape.a
+shpcat_LDADD = libshape.a
+shpcentrd_LDADD = libshape.a
+shpdata_LDADD = libshape.a
+shpdxf_LDADD = libshape.a
+shpfix_LDADD = libshape.a
+shpinfo_LDADD = libshape.a
+shpproj_LDADD = libshape.a
+shpwkb_LDADD = libshape.a
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/shapelib/contrib/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/shapelib/contrib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libshape.a: $(libshape_a_OBJECTS) $(libshape_a_DEPENDENCIES) 
+	-rm -f libshape.a
+	$(libshape_a_AR) libshape.a $(libshape_a_OBJECTS) $(libshape_a_LIBADD)
+	$(RANLIB) libshape.a
+
+clean-noinstPROGRAMS:
+	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+dbfcat$(EXEEXT): $(dbfcat_OBJECTS) $(dbfcat_DEPENDENCIES) 
+	@rm -f dbfcat$(EXEEXT)
+	$(LINK) $(dbfcat_OBJECTS) $(dbfcat_LDADD) $(LIBS)
+dbfinfo$(EXEEXT): $(dbfinfo_OBJECTS) $(dbfinfo_DEPENDENCIES) 
+	@rm -f dbfinfo$(EXEEXT)
+	$(LINK) $(dbfinfo_OBJECTS) $(dbfinfo_LDADD) $(LIBS)
+shpcat$(EXEEXT): $(shpcat_OBJECTS) $(shpcat_DEPENDENCIES) 
+	@rm -f shpcat$(EXEEXT)
+	$(LINK) $(shpcat_OBJECTS) $(shpcat_LDADD) $(LIBS)
+shpcentrd$(EXEEXT): $(shpcentrd_OBJECTS) $(shpcentrd_DEPENDENCIES) 
+	@rm -f shpcentrd$(EXEEXT)
+	$(LINK) $(shpcentrd_OBJECTS) $(shpcentrd_LDADD) $(LIBS)
+shpdata$(EXEEXT): $(shpdata_OBJECTS) $(shpdata_DEPENDENCIES) 
+	@rm -f shpdata$(EXEEXT)
+	$(LINK) $(shpdata_OBJECTS) $(shpdata_LDADD) $(LIBS)
+shpdxf$(EXEEXT): $(shpdxf_OBJECTS) $(shpdxf_DEPENDENCIES) 
+	@rm -f shpdxf$(EXEEXT)
+	$(LINK) $(shpdxf_OBJECTS) $(shpdxf_LDADD) $(LIBS)
+shpfix$(EXEEXT): $(shpfix_OBJECTS) $(shpfix_DEPENDENCIES) 
+	@rm -f shpfix$(EXEEXT)
+	$(LINK) $(shpfix_OBJECTS) $(shpfix_LDADD) $(LIBS)
+shpinfo$(EXEEXT): $(shpinfo_OBJECTS) $(shpinfo_DEPENDENCIES) 
+	@rm -f shpinfo$(EXEEXT)
+	$(LINK) $(shpinfo_OBJECTS) $(shpinfo_LDADD) $(LIBS)
+shpproj$(EXEEXT): $(shpproj_OBJECTS) $(shpproj_DEPENDENCIES) 
+	@rm -f shpproj$(EXEEXT)
+	$(LINK) $(shpproj_OBJECTS) $(shpproj_LDADD) $(LIBS)
+shpwkb$(EXEEXT): $(shpwkb_OBJECTS) $(shpwkb_DEPENDENCIES) 
+	@rm -f shpwkb$(EXEEXT)
+	$(LINK) $(shpwkb_OBJECTS) $(shpwkb_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfcat.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfinfo.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dbfopen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpcat.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpcentrd.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpdata.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpdxf.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpfix.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpgeo.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpinfo.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpopen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpproj.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shptree.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shpwkb.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+shpopen.o: ../shpopen.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shpopen.o -MD -MP -MF $(DEPDIR)/shpopen.Tpo -c -o shpopen.o `test -f '../shpopen.c' || echo '$(srcdir)/'`../shpopen.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/shpopen.Tpo $(DEPDIR)/shpopen.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../shpopen.c' object='shpopen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shpopen.o `test -f '../shpopen.c' || echo '$(srcdir)/'`../shpopen.c
+
+shpopen.obj: ../shpopen.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shpopen.obj -MD -MP -MF $(DEPDIR)/shpopen.Tpo -c -o shpopen.obj `if test -f '../shpopen.c'; then $(CYGPATH_W) '../shpopen.c'; else $(CYGPATH_W) '$(srcdir)/../shpopen.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/shpopen.Tpo $(DEPDIR)/shpopen.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../shpopen.c' object='shpopen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shpopen.obj `if test -f '../shpopen.c'; then $(CYGPATH_W) '../shpopen.c'; else $(CYGPATH_W) '$(srcdir)/../shpopen.c'; fi`
+
+shptree.o: ../shptree.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shptree.o -MD -MP -MF $(DEPDIR)/shptree.Tpo -c -o shptree.o `test -f '../shptree.c' || echo '$(srcdir)/'`../shptree.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/shptree.Tpo $(DEPDIR)/shptree.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../shptree.c' object='shptree.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shptree.o `test -f '../shptree.c' || echo '$(srcdir)/'`../shptree.c
+
+shptree.obj: ../shptree.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shptree.obj -MD -MP -MF $(DEPDIR)/shptree.Tpo -c -o shptree.obj `if test -f '../shptree.c'; then $(CYGPATH_W) '../shptree.c'; else $(CYGPATH_W) '$(srcdir)/../shptree.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/shptree.Tpo $(DEPDIR)/shptree.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../shptree.c' object='shptree.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shptree.obj `if test -f '../shptree.c'; then $(CYGPATH_W) '../shptree.c'; else $(CYGPATH_W) '$(srcdir)/../shptree.c'; fi`
+
+dbfopen.o: ../dbfopen.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dbfopen.o -MD -MP -MF $(DEPDIR)/dbfopen.Tpo -c -o dbfopen.o `test -f '../dbfopen.c' || echo '$(srcdir)/'`../dbfopen.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/dbfopen.Tpo $(DEPDIR)/dbfopen.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../dbfopen.c' object='dbfopen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dbfopen.o `test -f '../dbfopen.c' || echo '$(srcdir)/'`../dbfopen.c
+
+dbfopen.obj: ../dbfopen.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dbfopen.obj -MD -MP -MF $(DEPDIR)/dbfopen.Tpo -c -o dbfopen.obj `if test -f '../dbfopen.c'; then $(CYGPATH_W) '../dbfopen.c'; else $(CYGPATH_W) '$(srcdir)/../dbfopen.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/dbfopen.Tpo $(DEPDIR)/dbfopen.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../dbfopen.c' object='dbfopen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dbfopen.obj `if test -f '../dbfopen.c'; then $(CYGPATH_W) '../dbfopen.c'; else $(CYGPATH_W) '$(srcdir)/../dbfopen.c'; fi`
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES clean-noinstPROGRAMS ctags distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/shapelib/contrib/Makefile_orig b/src/shapelib/contrib/Makefile_orig
new file mode 100644
index 0000000..ab0ab13
--- /dev/null
+++ b/src/shapelib/contrib/Makefile_orig
@@ -0,0 +1,59 @@
+
+#LINKOPT	=	/usr/local/lib/libdbmalloc.a
+#CFLAGS	=	-g
+
+# Endian: define either _LITTLE_ENDIAN or _BIG_ENDIAN
+ENDIAN	=	-D_LITTLE_ENDIAN
+
+CFLAGS	=	-g -I.. -DPROJ4 $(ENDIAN) -DDEBUG -DDEBUG2 
+
+SHPOBJ	=	../shpopen.o ../dbfopen.o 
+
+SHPGOBJ =	../shpopen.o ../dbfopen.o shpgeo.o
+
+GEOOBJ	=	./shpgeo.o -lm -lproj
+
+default:	all
+
+all:	shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfinfo dbfcat shpinfo shpfix shpcat
+
+clean:  
+	rm -f shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfcat dbfinfo shpinfo shpfix shpcat *.o
+
+shpgeo.o:	shpgeo.c shpgeo.h
+	$(CC) $(CFLAGS) -c shpgeo.c
+
+shpdxf:		shpdxf.c $(SHPOBJ)
+	$(CC) $(CFLAGS) shpdxf.c ${SHPOBJ} $(LINKOPT) -o shpdxf
+
+shpcentrd:	shpcentrd.c $(SHPGOBJ)
+	$(CC) $(CFLAGS) shpcentrd.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpcentrd
+
+shpdata:	shpdata.c $(SHPGOBJ)
+	$(CC) $(CFLAGS) shpdata.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpdata
+
+shpinfo:	shpinfo.c $(SHPOBJ)
+	$(CC) $(CFLAGS) shpinfo.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpinfo
+
+shpfix:		shpfix.c $(SHPOBJ)
+	$(CC) $(CFLAGS) shpfix.c ${SHPOBJ} $(LINKOPT) -o shpfix
+
+shpcat:		shpcat.c $(SHPOBJ)
+	$(CC) $(CFLAGS) shpcat.c ${SHPOBJ} $(LINKOPT) -o shpcat
+
+shpwkb:		shpwkb.c $(SHPGOBJ)
+	$(CC) $(CFLAGS) shpwkb.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpwkb
+
+shpproj: 	shpproj.c $(SHPGOBJ)
+	$(CC) $(CFLAGS) shpproj.c  $(SHPOBJ) $(GEOOBJ) -lm -lproj $(LINKOPT) -o shpproj
+
+dbfinfo: 	dbfinfo.c $(SHPOBJ)
+	$(CC) $(CFLAGS) dbfinfo.c $(SHPOBJ) $(LINKOPT) -o dbfinfo
+
+dbfcat:		dbfcat.c $(SHPOBJ)
+	$(CC) $(CFLAGS) dbfcat.c $(SHPOBJ) $(LINKOPT) -o dbfcat
+
+check:	testproj
+
+testproj: 
+	tests/shpproj.sh
diff --git a/src/shapelib/contrib/ShapeFileII.pas b/src/shapelib/contrib/ShapeFileII.pas
new file mode 100644
index 0000000..d386adf
--- /dev/null
+++ b/src/shapelib/contrib/ShapeFileII.pas
@@ -0,0 +1,254 @@
+{
+/******************************************************************************
+ * $Id: ShapeFileII.pas,v 1.1 2006/11/10 21:48:10 tvrusso Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Delphi Pascal interface to Shapelib.
+ * Author:   Kevin Meyer (Kevin at CyberTracker.co.za)
+ *
+ ******************************************************************************
+ * Copyright (c) 2002, Keven Meyer (Kevin at CyberTracker.co.za)
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: ShapeFileII.pas,v $
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.2  2002/01/21 14:09:26  warmerda
+ * Fixed name.
+ *
+ * Revision 1.1  2002/01/17 14:30:37  warmerda
+ * New
+ *
+ */
+}
+unit ShapeFileII;
+
+interface
+//uses	{ uses clause }
+//    ;
+{ Set compiler to pack on byte boundaries only }
+{$ALIGN OFF}
+{$OVERFLOWCHECKS OFF}
+{$J-}
+const
+    SHPT_NULL	 = 0;
+    SHPT_POINT	 = 1;
+    SHPT_ARC	 = 3;
+    SHPT_POLYGON	 = 5;
+    SHPT_MULTIPOINT	 = 8;
+    SHPT_POINTZ	 = 11;
+    SHPT_ARCZ	 = 13;
+    SHPT_POLYGONZ	 = 15;
+    SHPT_MULTIPOINTZ  = 18;
+    SHPT_POINTM	 = 21;
+    SHPT_ARCM	 = 23;
+    SHPT_POLYGONM	 = 25;
+    SHPT_MULTIPOINTM  = 28;
+    SHPT_MULTIPATCH  = 31;
+    XBASE_FLDHDR_SZ = 32;
+    szAccessBRW = 'rb+';
+
+// *********************** SHP support ************************
+
+type
+SHPObject = record
+    nSHPType,
+    nShapeId,
+    nParts : LongWord;
+    panPartStart,
+    panPartType : array of LongWord;
+    nVertices : LongWord;
+    padfX, padfY, padfZ, padfM : array of double;
+    dfXMin, dfYMin, dfZMin, dfMMin : double;
+    dfXMax, dfYMax, dfZMax, dfMMax : double;
+end;
+SHPObjectHandle = ^SHPObject;
+
+SHPBoundsArr = double;
+
+SHPInfo = record
+    fpSHP,
+    fpSHX : FILE;
+
+    nShapeType,
+    nFileSize,
+    nRecords,
+    nMaxRecords : LongWord;
+    panRecOffset,
+    panRecSize : array of LongWord;
+    adBoundsMin, adBoundsMax : SHPBoundsArr;
+    bUpdated : LongWord;
+end;
+SHPHandle = ^SHPInfo;
+
+// *********************** DBF support ************************
+
+DBFInfo = record
+    fp : FILE;
+    nRecords,
+    nRecordLength,
+    nHeaderLength,
+    nFields : LongWord;
+
+    panFieldOffset,
+    panFieldSize,
+    panFieldDecimals : array of LongWord;
+
+    pachFieldType : LongWord;
+    pszHeader : PChar;
+    nCurrentRecord,
+    bCurrentRecordModified : LongWord;
+    pszCurrentRecord : PChar;
+
+    bNoHeader,
+    bUpdated : LongWord;
+end;
+DBFHandle = ^DBFInfo;
+
+DBFFieldType = (DBFTString,  DBFTInteger, DBFTDouble,  DBFTInvalid) ;
+
+// *********************** SHP func declarations ************************
+
+{$ALIGN ON}
+
+function SHPOpen(pszShapeFile, pszAccess : PChar) : SHPHandle;cdecl;
+procedure SHPGetInfo(hSHP : SHPHandle; var pnEntities, pnShapeType : LongWord; var padfMinBoud, padfMaxBound : SHPBoundsArr);cdecl;
+procedure SHPClose(hSHP : SHPHandle);cdecl;
+function SHPReadObject(hSHP : SHPHandle; iShape : LongWord): SHPObjectHandle;cdecl;
+function SHPCreate(pszShapeFile : PChar; nShapeType : LongWord):SHPHandle;cdecl;
+function SHPWriteObject(hSHP : SHPHandle; iShape : LongWord; psObject : SHPObjectHandle): LongWord;cdecl;
+function SHPCreateSimpleObject(nSHPType, nVertices : LongWord; var padfX, padfY, padfZ : double):SHPObjectHandle;cdecl;
+procedure SHPDestroy(psObject : SHPObjectHandle);cdecl;
+
+procedure SHPComputeExtents(psObject : SHPObjectHandle);cdecl;
+function SHPCreateObject(nSHPType, iShape, nParts : LongWord; var panPartStart, panPartType : LongWord; nVertices : LongWord; var padfX, padfY, padfZ, padfM : SHPBoundsArr): SHPObjectHandle;cdecl;
+
+function SHPTypeStr(pnShapeType : LongWord): string;
+
+// *********************** DBF func declarations ************************
+
+function DBFOpen(pszDBFFile, pszAccess : PChar): DBFHandle;cdecl;
+function DBFCreate(pszDBFFile : PChar): DBFHandle ;cdecl;
+function DBFGetFieldCount(hDBF : DBFHandle) : LongWord ;cdecl;
+function DBFGetRecordCount(hDBF : DBFHandle) : LongWord;cdecl;
+function DBFGetFieldIndex(hDBF: DBFHandle; pszFieldName : PChar): LongWord;cdecl;
+function DBFGetFieldInfo(hDBF : DBFHandle; iField : LongWord; pszFieldName : PChar;
+                              var pnWidth, pnDecimals : LongWord): DBFFieldType;cdecl;
+function DBFAddField(hDBF : DBFHandle; pszFieldName : PChar;
+                 eType : DBFFieldType; nWidth, nDecimals  : LongWord): LongWord;cdecl;
+
+function DBFReadIntegerAttribute(hDBF : DBFHandle;iShape,  iField  : LongWord ): LongWord;cdecl;
+function DBFReadDoubleAttribute(hDBF : DBFHandle; iShape,  iField  : LongWord ):double;cdecl;
+function DBFReadStringAttribute(hDBF : DBFHandle; iShape,  iField  : LongWord ) : pchar;cdecl;
+function DBFIsAttributeNULL(hDBF : DBFHandle; iShape,  iField  : LongWord ): LongWord;cdecl;
+function DBFWriteIntegerAttribute(hDBF : DBFHandle;iShape, iField, nFieldValue : LongWord): LongWord;cdecl;
+function DBFWriteDoubleAttribute(hDBF : DBFHandle;iShape, iField   : LongWord;
+                             dFieldValue : double): LongWord ;cdecl;
+function DBFWriteStringAttribute(hDBF : DBFHandle;iShape, iField   : LongWord;
+                             pszFieldValue : PChar): LongWord ;cdecl;
+function DBFWriteNULLAttribute(hDBF : DBFHandle; iShape,  iField  : LongWord ) : LongWord;cdecl;
+procedure DBFClose(hDBF : DBFHandle);cdecl;
+function DBFGetNativeFieldType(hDBF : DBFHandle;  iField : LongWord) : Char;cdecl;
+
+// *********************** SHP implementation ************************
+implementation
+// *****************************************************************************
+function SHPCreateSimpleObject(nSHPType, nVertices : LongWord; var padfX, padfY, padfZ : double):SHPObjectHandle;external 'shapelib.dll' name 'SHPCreateSimpleObject';
+function SHPOpen(pszShapeFile, pszAccess : PChar) : SHPHandle; external 'shapelib.dll' name 'SHPOpen';
+procedure SHPGetInfo(hSHP : SHPHandle; var pnEntities, pnShapeType : LongWord; var padfMinBoud, padfMaxBound : SHPBoundsArr);external 'shapelib.dll' name 'SHPGetInfo';
+procedure SHPClose(hSHP : SHPHandle);external 'shapelib.dll' name 'SHPClose';
+function SHPReadObject(hSHP : SHPHandle; iShape : LongWord) : SHPObjectHandle;external 'shapelib.dll' name 'SHPReadObject';
+function SHPCreate(pszShapeFile : PChar; nShapeType : LongWord):SHPHandle;external 'shapelib.dll' name 'SHPCreate';
+function SHPWriteObject(hSHP : SHPHandle; iShape : LongWord; psObject : SHPObjectHandle): LongWord;cdecl;external 'shapelib.dll' name 'SHPWriteObject';
+procedure SHPDestroy(psObject : SHPObjectHandle);external 'shapelib.dll' name 'SHPDestroyObject';
+procedure SHPComputeExtents(psObject : SHPObjectHandle);external 'shapelib.dll' name 'SHPComputeExtents';
+function SHPCreateObject(nSHPType, iShape, nParts : LongWord; var panPartStart, panPartType : LongWord; nVertices : LongWord; var padfX, padfY, padfZ, padfM : SHPBoundsArr): SHPObjectHandle;external 'shapelib.dll' name 'SHPCreateObject';
+// *****************************************************************************
+function SHPTypeStr(pnShapeType : LongWord): string;
+begin
+  case pnShapeType of
+    SHPT_NULL           : result := 'NULL';
+    SHPT_POINT          : result := 'POINT';
+    SHPT_ARC            : result := 'ARC';
+    SHPT_POLYGON        : result := 'POLYGON';
+    SHPT_MULTIPOINT     : result := 'MULTIPOINT';
+    SHPT_POINTZ         : result := 'POINTZ';
+    SHPT_ARCZ           : result := 'ARCZ';
+    SHPT_POLYGONZ       : result := 'POLYGONZ';
+    SHPT_MULTIPOINTZ    : result := 'MULTIPOINTZ';
+    SHPT_POINTM         : result := 'POINTM';
+    SHPT_ARCM           : result := 'ARCM';
+    SHPT_POLYGONM       : result := 'POLYGONM';
+    SHPT_MULTIPOINTM    : result := 'MULTIPOINTM';
+    SHPT_MULTIPATCH     : result := 'MULTIPATCH';
+    else
+      result := '--unknown--';
+  end;
+end;
+// *****************************************************************************
+// *****************************************************************************
+function DBFOpen(pszDBFFile, pszAccess : PChar): DBFHandle;external 'shapelib.dll';
+function DBFCreate(pszDBFFile : PChar): DBFHandle ;external 'shapelib.dll';
+function DBFGetFieldCount(hDBF : DBFHandle) : LongWord ;external 'shapelib.dll';
+function DBFGetRecordCount(hDBF : DBFHandle) : LongWord;external 'shapelib.dll';
+function DBFGetFieldIndex(hDBF: DBFHandle; pszFieldName : PChar): LongWord;external 'shapelib.dll';
+function DBFGetFieldInfo(hDBF : DBFHandle; iField : LongWord; pszFieldName : PChar; var pnWidth, pnDecimals : LongWord): DBFFieldType;external 'shapelib.dll';
+function DBFAddField(hDBF : DBFHandle; pszFieldName : PChar; eType : DBFFieldType; nWidth, nDecimals  : LongWord): LongWord;external 'shapelib.dll';
+function DBFReadIntegerAttribute(hDBF : DBFHandle;iShape,  iField  : LongWord ): LongWord;external 'shapelib.dll';
+function DBFReadDoubleAttribute(hDBF : DBFHandle; iShape,  iField  : LongWord ):double;external 'shapelib.dll';
+function DBFReadStringAttribute(hDBF : DBFHandle; iShape,  iField  : LongWord ) : pchar;external 'shapelib.dll';
+function DBFIsAttributeNULL(hDBF : DBFHandle; iShape,  iField  : LongWord ): LongWord;external 'shapelib.dll';
+function DBFWriteIntegerAttribute(hDBF : DBFHandle;iShape, iField, nFieldValue : LongWord): LongWord;external 'shapelib.dll';
+function DBFWriteDoubleAttribute(hDBF : DBFHandle;iShape, iField   : LongWord; dFieldValue : double): LongWord ;external 'shapelib.dll';
+function DBFWriteStringAttribute(hDBF : DBFHandle;iShape, iField   : LongWord; pszFieldValue : PChar): LongWord ;external 'shapelib.dll';
+function DBFWriteNULLAttribute(hDBF : DBFHandle; iShape,  iField  : LongWord ) : LongWord;external 'shapelib.dll';
+procedure DBFClose(hDBF : DBFHandle);external 'shapelib.dll';
+function DBFGetNativeFieldType(hDBF : DBFHandle;  iField : LongWord) : Char;external 'shapelib.dll';
+// *****************************************************************************
+
+end.
diff --git a/src/shapelib/contrib/dbfcat.c b/src/shapelib/contrib/dbfcat.c
new file mode 100644
index 0000000..48806a2
--- /dev/null
+++ b/src/shapelib/contrib/dbfcat.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1995 Frank Warmerdam
+ *
+ * This code is in the public domain.
+ *
+ * $Log: dbfcat.c,v $
+ * Revision 1.4  2010/07/11 20:30:00  we7u
+ * More minor tweaks to get rid of compiler warnings.  Of particular note are
+ * some TODO entries added to a couple of files for two enumerated values that
+ * weren't being handled in "switch" statements.  There still isn't any code
+ * for those case statements, but the compiler warnings are gone.
+ *
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:45:27  we7u
+ * Adding includes necessary for warning-free compiles.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.1  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ * Revision 1.3  1995/10/21  03:15:01  warmerda
+ * Changed to use binary file access.
+ *
+ * Revision 1.2  1995/08/04  03:16:22  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] = 
+//  "$Id: dbfcat.c,v 1.4 2010/07/11 20:30:00 we7u Exp $";
+
+#include "shapefil.h"
+#include <stdlib.h>
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    DBFHandle	hDBF;
+//    int		*panWidth;
+    int     i, iRecord;
+//    char	szFormat[32], szField[1024];
+    char	cTitle[32], nTitle[32];
+    int		nWidth, nDecimals;
+    int		cnWidth, cnDecimals;
+    DBFHandle	cDBF;
+    DBFFieldType	hType,cType;
+    int		ci, ciRecord;
+    char	tfile[160];
+    int		hflds, cflds;
+//    int     j;
+    int 	verbose				= 0;
+    int		force 				= 0;
+    int		mismatch			= 0;
+    int		matches				= 0;
+    char	fld_m[256];
+    int		shift = 0;
+    char	type_names[4][15] = {"integer", "string", "double", "double"};
+
+    if( argc < 3 )
+    {
+	printf( "dbfcat [-v] [-f] from_DBFfile to_DBFfile\n" );
+	exit( 1 );
+    }
+
+
+    if ( strcmp ("-v", argv[1] ) == 0 ) { shift = 1; verbose = 1; }
+    if ( strcmp ("-f", argv[1 + shift] ) == 0 ) { shift ++; force = 1; }
+    if ( strcmp ("-v", argv[1 + shift] ) == 0 ) { shift ++; verbose = 1; }
+    strcpy (tfile, argv[1 + shift]);
+    strcat (tfile, ".dbf"); 
+    hDBF = DBFOpen( tfile, "rb" );
+    if( hDBF == NULL )
+    {
+	printf( "DBFOpen(%s.dbf,\"r\") failed for From_DBF.\n", tfile );
+	exit( 2 );
+    }
+
+    strcpy (tfile, argv[2 + shift]);
+    strcat (tfile, ".dbf"); 
+
+    cDBF = DBFOpen( tfile, "rb+" );
+    if( cDBF == NULL )
+    {
+	printf( "DBFOpen(%s.dbf,\"rb+\") failed for To_DBF.\n", tfile );
+	exit( 2 );
+    }
+    
+    
+    if( DBFGetFieldCount(hDBF) == 0 )
+    {
+	printf( "There are no fields in this table!\n" );
+	exit( 3 );
+    }
+
+    hflds = DBFGetFieldCount(hDBF);
+    cflds = DBFGetFieldCount(cDBF);
+
+    matches = 0;
+    for( i = 0; i < hflds; i++ )
+    {
+	char		szTitle[18];
+	char		cname[18];
+	int		j;
+	hType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
+	fld_m[i] = -1;
+        for ( j = 0; j < cflds; j ++ )
+          { 
+            cType = DBFGetFieldInfo( cDBF, j, cname, &cnWidth, &cnDecimals );
+            if ( strcmp (cname, szTitle) == 0 ) 
+	     { 
+        	if ( hType != cType ) 
+            	{ printf ("Incompatible fields %s(%s) != %s(%s),\n",
+             	   type_names[hType],nTitle,type_names[cType],cTitle);
+			mismatch = 1;
+              		}
+	        fld_m[i] = j;
+		if ( verbose ) 
+         	  { printf("%s  %s(%d,%d) <- %s  %s(%d,%d)\n", cname, type_names[cType],
+         	  		cnWidth, cnDecimals,
+         	       szTitle, type_names[hType], nWidth, nDecimals); }
+	        j = cflds;
+	        matches = 1;
+	      }
+	  }
+    }
+
+    if ( (matches == 0 ) && !force ) {
+      printf ("ERROR: No field names match for tables, cannot proceed\n   use -f to force processing using blank records\n");
+      exit(-1); }
+    if ( mismatch && !force ) {
+      printf ("ERROR: field type mismatch cannot proceed\n    use -f to force processing using attempted conversions\n");
+      exit(-1); }
+
+    for( iRecord = 0; iRecord < DBFGetRecordCount(hDBF); iRecord++ )
+    {
+      ciRecord = DBFGetRecordCount( cDBF );
+      for ( i = 0; i < hflds;i ++ )
+	{	
+//	double	cf;
+	ci = fld_m[i];
+	if ( ci != -1 )
+	{
+	cType = DBFGetFieldInfo( cDBF, ci, cTitle, &cnWidth, &cnDecimals );
+	hType = DBFGetFieldInfo( hDBF, i, nTitle, &nWidth, &nDecimals );
+
+	    switch( cType )
+	    {
+	      case FTString:
+	        DBFWriteStringAttribute(cDBF, ciRecord, ci,
+     			(char *) DBFReadStringAttribute( hDBF, iRecord, i ) );
+		break;
+
+	      case FTInteger:
+	    	DBFWriteIntegerAttribute(cDBF, ciRecord, ci, 
+			(int) DBFReadIntegerAttribute( hDBF, iRecord, i ) );
+		break;
+
+	      case FTDouble:
+/*	        cf = DBFReadDoubleAttribute( hDBF, iRecord, i );
+	        printf ("%s <-  %s (%f)\n", cTitle, nTitle, cf);
+*/
+	    	DBFWriteDoubleAttribute(cDBF, ciRecord, ci, 
+			(double) DBFReadDoubleAttribute( hDBF, iRecord, i ) );
+		break;
+
+          case FTLogical:
+// TODO:  Add code here
+        break;
+
+          case FTInvalid:
+// TODO:  Add code here
+        break;
+
+	    }
+	  }
+	}   /* fields names match */
+    }
+
+    if ( verbose ) { printf (" %d records appended \n\n", iRecord); }
+    DBFClose( hDBF );
+    DBFClose( cDBF );
+
+    return( 0 );
+}
diff --git a/src/shapelib/contrib/dbfinfo.c b/src/shapelib/contrib/dbfinfo.c
new file mode 100644
index 0000000..45cfe47
--- /dev/null
+++ b/src/shapelib/contrib/dbfinfo.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1999 Carl Anderson
+ *
+ * This code is in the public domain.
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ *
+ * requires shapelib 1.2
+ *   gcc dbfinfo dbfopen.o dbfinfo
+ * 
+ *
+ * $Log: dbfinfo.c,v $
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:45:27  we7u
+ * Adding includes necessary for warning-free compiles.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ * 
+ */
+
+
+#include "shapefil.h"
+#include <stdlib.h>
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    DBFHandle	hDBF;
+    int		*panWidth, i;
+//    int     iRecord;
+//    char	szFormat[32], szField[1024];
+    char	ftype[15];
+//    char cTitle[32], nTitle[32];
+    int		nWidth, nDecimals;
+//    int		cnWidth, cnDecimals;
+//    DBFHandle	cDBF;
+//    DBFFieldType	hType,cType;
+//    int		ci, ciRecord;
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 2 )
+    {
+	printf( "dbfinfo xbase_file\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the file.                                                  */
+/* -------------------------------------------------------------------- */
+    hDBF = DBFOpen( argv[1], "rb" );
+    if( hDBF == NULL )
+    {
+	printf( "DBFOpen(%s,\"r\") failed.\n", argv[1] );
+	exit( 2 );
+    }
+
+    printf ("Info for %s\n",argv[1]);
+
+/* -------------------------------------------------------------------- */
+/*	If there is no data in this file let the user know.		*/
+/* -------------------------------------------------------------------- */
+    i = DBFGetFieldCount(hDBF);
+    printf ("%d Columns,  %d Records in file\n",i,DBFGetRecordCount(hDBF));
+    
+/* -------------------------------------------------------------------- */
+/*	Compute offsets to use when printing each of the field 		*/
+/*	values. We make each field as wide as the field title+1, or 	*/
+/*	the field value + 1. 						*/
+/* -------------------------------------------------------------------- */
+    panWidth = (int *) malloc( DBFGetFieldCount( hDBF ) * sizeof(int) );
+
+    for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
+    {
+	char		szTitle[12];
+//	DBFFieldType	eType;
+
+	switch ( DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals )) {
+	      case FTString:
+	        strcpy (ftype, "string");;
+		break;
+
+	      case FTInteger:
+	    	strcpy (ftype, "integer");
+		break;
+
+	      case FTDouble:
+	    	strcpy (ftype, "float");
+		break;
+		
+	      case FTInvalid:
+	    	strcpy (ftype, "invalid/unsupported");
+		break;
+		
+	      default:
+	      	strcpy (ftype, "unknown");
+	      	break;			
+	    }
+        printf ("%15.15s\t%15s  (%d,%d)\n",szTitle, ftype, nWidth, nDecimals);
+
+    }
+
+    DBFClose( hDBF );
+
+    return( 0 );
+}
diff --git a/src/shapelib/contrib/makefile.vc b/src/shapelib/contrib/makefile.vc
new file mode 100644
index 0000000..ff3ce16
--- /dev/null
+++ b/src/shapelib/contrib/makefile.vc
@@ -0,0 +1,29 @@
+PROJ_DIR = 	D:\warmerda\proj
+
+CFLAGS	=	/I.. /I$(PROJ_DIR)\src /D_LITTLE_ENDIAN -DPROJ4 
+
+LINKARGS =	shpgeo.obj ..\shpopen.obj ..\dbfopen.obj \
+		D:\warmerda\proj\src\proj_i.lib
+
+default:	all
+
+all:	shpcat.exe shpcentrd.exe shpdxf.exe shpinfo.exe shpproj.exe
+
+shpcat.exe:	shpcat.obj shpgeo.obj 
+	$(CC) $(CFLAGS) shpcat.obj  $(LINKARGS) 
+
+shpcentrd.exe:	shpcentrd.obj shpgeo.obj 
+	$(CC) $(CFLAGS) shpcentrd.obj  $(LINKARGS) 
+
+shpproj.exe:	shpproj.obj shpgeo.obj 
+	$(CC) $(CFLAGS) shpproj.obj  $(LINKARGS) 
+
+shpdxf.exe:	shpdxf.obj shpgeo.obj 
+	$(CC) $(CFLAGS) shpdxf.obj  $(LINKARGS) 
+
+shpinfo.exe:	shpinfo.obj shpgeo.obj 
+	$(CC) $(CFLAGS) shpinfo.obj  $(LINKARGS) 
+
+clean:
+	del *.obj *.exe
+
diff --git a/src/shapelib/contrib/my_nan.h b/src/shapelib/contrib/my_nan.h
new file mode 100644
index 0000000..640dc3c
--- /dev/null
+++ b/src/shapelib/contrib/my_nan.h
@@ -0,0 +1,56 @@
+/* `NAN' constant for IEEE 754 machines.
+   Copyright (C) 1992, 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef	_GNU_NAN_H
+
+#define	_GNU_NAN_H	1
+
+#include <endian.h>
+
+/* hacked to define NAN on Solaris 2.7 if it wasn't defined  */
+
+/* IEEE Not A Number.  */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#  warning "*** Big Endian ***"
+#else 
+#  if __BYTE_ORDER == __SMALL_ENDIAN
+#    warning "*** Small Endian ***"
+#  else
+#    warning "*** Endian-ness unknown ***"
+#  endif
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#  define	__nan_bytes		{ 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }
+#else
+#  define	__nan_bytes		{ 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }
+#endif
+
+#ifdef	__GNUC__
+#  define	NAN \
+  (__extension__ ((union { unsigned char __c[8];			      \
+			   double __d; })				      \
+		  { __nan_bytes }).__d)
+#else	/* Not GCC.  */
+   static const char __nan[8] = __nan_bytes;
+#  define	NAN	(*(const double *) __nan)
+#endif
+
+#endif	/* gnu_nan.h */
diff --git a/src/shapelib/contrib/shpcat.c b/src/shapelib/contrib/shpcat.c
new file mode 100644
index 0000000..16568bd
--- /dev/null
+++ b/src/shapelib/contrib/shpcat.c
@@ -0,0 +1,99 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ *	shpcat
+ *
+ *  gcc shpcat.c ../shpopen.o -o shpcat
+ *
+ *  Utility program to concatenate two shapefiles
+ *  Must be used in concert with dbfcat
+ *
+ */
+
+#include "shapefil.h"
+#include <stdlib.h>
+
+int dbfcat_main( int argc, char ** argv );
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP, cSHP;
+    int		nShapeType, i, nEntities, nShpInFile;
+    SHPObject	*shape;
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 3 )
+    {
+	printf( "shpcat from_shpfile to_shpfile\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "rb" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+    
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL );
+    fprintf(stderr,"Opened From File %s, with %d shapes\n",argv[1],nEntities);
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    cSHP = SHPOpen( argv[2], "rb+" );
+
+    if( cSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[2] );
+	exit( 1 );
+    }
+    
+    SHPGetInfo( cSHP, &nShpInFile, NULL, NULL, NULL );
+    fprintf(stderr,"Opened to file %s with %d shapes, ready to add %d\n",
+            argv[2],nShpInFile,nEntities);
+
+/* -------------------------------------------------------------------- */
+/*	Skim over the list of shapes, printing all the vertices.	*/
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nEntities; i++ )
+    {
+        shape = SHPReadObject( hSHP, i );
+        SHPWriteObject( cSHP, -1, shape );
+        SHPDestroyObject ( shape );
+
+    }
+
+    SHPClose( hSHP );
+    SHPClose( cSHP );
+
+    exit( 0 );
+}
diff --git a/src/shapelib/contrib/shpcentrd.c b/src/shapelib/contrib/shpcentrd.c
new file mode 100644
index 0000000..9af9895
--- /dev/null
+++ b/src/shapelib/contrib/shpcentrd.c
@@ -0,0 +1,190 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * this code is based in part on the earlier work of Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * shpcentrd.c  - compute XY centroid for complex shapes 
+ *			and create a new SHPT_PT file of then
+ * 			specifically undo compound objects but not complex ones
+ *
+ *
+ * $Log: shpcentrd.c,v $
+ * Revision 1.4  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:45:27  we7u
+ * Adding includes necessary for warning-free compiles.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ *
+ * 
+ */
+
+
+/* the centroid is defined as
+ *
+ *      Cx = sum (x dArea ) / Total Area
+ *  and
+ *      Cy = sum (y dArea ) / Total Area
+ */           
+
+#include "shapefil.h"
+#include "shpgeo.h"
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	old_SHP, new_SHP;
+    DBFHandle   old_DBF, new_DBF;
+    int		nShapeType, nEntities, i;
+//    int     nVertices, nParts, *panParts, iPart;
+//    double	*padVertices, adBounds[4];
+//    const char 	*pszPlus;
+//    DBFFieldType  idfld_type;
+//    int		idfld, nflds;
+//    char	kv[257] = "";
+//    char	idfldName[120] = "";
+//    char	fldName[120] = "";
+//    char	shpFileName[120] = "";
+//    char	dbfFileName[120] = "";
+//    double	apeture[4];
+    char	*DBFRow = NULL;
+//    int		Cpan[2] = { 0,0 };
+    int		byRing = 1;
+    PT		Centrd;
+    SHPObject	*psCShape, *cent_pt;
+
+
+    if( argc < 3 )
+    {
+	printf( "shpcentrd shp_file new_shp_file\n" );
+	exit( 1 );
+    }
+    
+    old_SHP = SHPOpen (argv[1], "rb" );
+    old_DBF = DBFOpen (argv[1], "rb");
+    if( old_SHP == NULL || old_DBF == NULL )
+    {
+	printf( "Unable to open old files:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL );
+    new_SHP = SHPCreate ( argv[2], SHPT_POINT ); 
+    
+    new_DBF = DBFCloneEmpty (old_DBF, argv[2]);
+    if( new_SHP == NULL || new_DBF == NULL )
+    {
+	printf( "Unable to create new files:%s\n", argv[2] );
+	exit( 1 );
+    }
+
+    DBFRow = (char *) malloc ( (old_DBF->nRecordLength) + 15 );
+
+
+#ifdef 	DEBUG
+    printf ("ShpCentrd using shpgeo \n");
+#endif
+
+    for( i = 0; i < nEntities; i++ )
+    {
+//	int		res ;
+ 
+	psCShape = SHPReadObject( old_SHP, i );
+
+        if ( byRing == 1 ) {
+          int 	ring;
+          for ( ring = 0; ring < psCShape->nParts; ring ++ ) {
+	    SHPObject 	*psO;
+	    psO = SHPClone ( psCShape, ring,  ring + 1 );
+
+            Centrd = SHPCentrd_2d ( psO ); 
+
+            cent_pt = SHPCreateSimpleObject ( SHPT_POINT, 1, 
+        	(double*) &(Centrd.x), (double*) &(Centrd.y), NULL ); 
+
+            SHPWriteObject ( new_SHP, -1, cent_pt ); 
+                        
+            memcpy ( DBFRow, DBFReadTuple ( old_DBF, i ),
+		 old_DBF->nRecordLength );
+            DBFWriteTuple ( new_DBF, new_DBF->nRecords, DBFRow );            
+
+            SHPDestroyObject ( cent_pt );
+
+	    SHPDestroyObject ( psO );
+           }
+
+          }
+        else {
+        
+          Centrd = SHPCentrd_2d ( psCShape ); 
+
+          cent_pt = SHPCreateSimpleObject ( SHPT_POINT, 1, 
+        	(double*) &(Centrd.x), (double*) &(Centrd.y), NULL ); 
+
+          SHPWriteObject ( new_SHP, -1, cent_pt ); 
+                        
+          memcpy ( DBFRow, DBFReadTuple ( old_DBF, i ),
+		 old_DBF->nRecordLength );
+          DBFWriteTuple ( new_DBF, new_DBF->nRecords, DBFRow );            
+
+          SHPDestroyObject ( cent_pt );
+         }
+    }
+
+    SHPClose( old_SHP );
+    SHPClose( new_SHP );
+    DBFClose( old_DBF );
+    DBFClose( new_DBF );
+    printf ("\n");
+    return(0);
+}
+
diff --git a/src/shapelib/contrib/shpdata.c b/src/shapelib/contrib/shpdata.c
new file mode 100644
index 0000000..f1b6dba
--- /dev/null
+++ b/src/shapelib/contrib/shpdata.c
@@ -0,0 +1,164 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * this code is based in part on the earlier work of Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * shpdata.c  - utility program for testing elements of the libraries
+ *
+ *
+ * $Log: shpdata.c,v $
+ * Revision 1.3  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.2  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ *
+ * 
+ */
+      
+
+#include "shapefil.h"
+#include "shpgeo.h"
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	old_SHP;
+//    SHPHandle   new_SHP;
+    DBFHandle   old_DBF;
+//    DBFHandle   new_DBF;
+    int		nShapeType, nEntities, i;
+//    int		nVertices, nParts, *panParts, iPart;
+//    double	*padVertices, adBounds[4];
+//    const char 	*pszPlus;
+//    DBFFieldType  idfld_type;
+//    int		idfld, nflds;
+//    char	kv[257] = "";
+//    char	idfldName[120] = "";
+//    char	fldName[120] = "";
+//    char	shpFileName[120] = "";
+//    char	dbfFileName[120] = "";
+//    char	*DBFRow = NULL;
+//    int		Cpan[2] = { 0,0 };
+    int		byRing = 1;
+    PT		oCentrd, ringCentrd;
+    SHPObject	*psCShape;
+//    SHPObject   *cent_pt;
+    double	oArea = 0.0, oLen = 0.0;
+
+    if( argc < 2 )
+    {
+	printf( "shpdata shp_file \n" );
+	exit( 1 );
+    }
+    
+    old_SHP = SHPOpen (argv[1], "rb" );
+    old_DBF = DBFOpen (argv[1], "rb");
+    if( old_SHP == NULL || old_DBF == NULL )
+    {
+	printf( "Unable to open old files:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL );
+    for( i = 0; i < nEntities; i++ )
+    {
+//	int		res ;
+
+	psCShape = SHPReadObject( old_SHP, i );
+
+        if ( byRing == 1 ) {
+          int 	   ring, prevStart, ringDir;
+	  double   ringArea;
+
+          prevStart = psCShape->nVertices;
+          for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
+	    SHPObject 	*psO;
+	    int		numVtx, rStart;
+//        int     j;
+            
+            rStart = psCShape->panPartStart[ring];
+            if ( ring == (psCShape->nParts -1) )
+              { numVtx = psCShape->nVertices - rStart; }
+             else
+              { numVtx = psCShape->panPartStart[ring+1] - rStart; }
+              
+            printf ("(shpdata) Ring(%d) (%d for %d) \n", ring, rStart, numVtx);              
+	    psO = SHPClone ( psCShape, ring,  ring + 1 );
+
+            ringDir = SHPRingDir_2d ( psO, 0 );
+            ringArea = RingArea_2d (psO->nVertices,(double*) psO->padfX,
+            	 (double*) psO->padfY);
+            RingCentroid_2d ( psO->nVertices, (double*) psO->padfX, 
+     		(double*) psO->padfY, &ringCentrd, &ringArea);  
+
+            	 
+            printf ("(shpdata)  Ring %d, %f Area %d dir \n", 
+           	ring, ringArea, ringDir );
+
+	    SHPDestroyObject ( psO );
+            printf ("(shpdata) End Ring \n");
+           }  /* (ring) [0,nParts  */
+
+          }  /* by ring   */
+
+	   oArea = SHPArea_2d ( psCShape );
+	   oLen = SHPLength_2d ( psCShape ); 
+	   oCentrd = SHPCentrd_2d ( psCShape );
+           printf ("(shpdata) Part (%d) %f Area  %f length, C (%f,%f)\n",
+           	 i, oArea, oLen, oCentrd.x, oCentrd.y );
+    }
+
+    SHPClose( old_SHP );
+
+    DBFClose( old_DBF );
+
+    printf ("\n");
+    return(0);
+}
diff --git a/src/shapelib/contrib/shpdxf.c b/src/shapelib/contrib/shpdxf.c
new file mode 100644
index 0000000..975aa4c
--- /dev/null
+++ b/src/shapelib/contrib/shpdxf.c
@@ -0,0 +1,328 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * shp2dxf.c
+ *
+ * derived from a ESRI Avenue Script
+ * and DXF specification from AutoCad 3 (yes 1984)
+ *
+ * modifications Carl Andrson 11/96
+ * modifications Carl Andrson 3/97
+ *
+ * converted to C code 12/98
+ *
+ * requires shapelib 1.2
+ *   gcc shpdxf.c shpopen.o dbfopen.o -o shpdxf 
+ *
+ */
+
+#include "shapefil.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define FLOAT_PREC "%16.5f\r\n"
+
+void dxf_hdr (double x1, double y1, double x2, double y2, FILE *df)
+{
+/* Create HEADER section */
+
+  fprintf( df, "  0\r\n");
+  fprintf( df, "SECTION\r\n");
+  fprintf( df, "  2\r\n" );
+  fprintf( df, "HEADER\r\n" );
+  fprintf( df, "  9\r\n" );
+  fprintf( df, "$EXTMAX\r\n" );
+  fprintf( df, " 10\r\n" );
+  fprintf( df, FLOAT_PREC, x2 );
+  fprintf( df, " 20\r\n" );
+  fprintf( df, FLOAT_PREC, y2 );
+  fprintf( df, "  9\r\n" );
+  fprintf( df, "$EXTMIN\r\n" );
+  fprintf( df, " 10\r\n" );
+  fprintf( df, FLOAT_PREC, x1 );
+  fprintf( df, " 20\r\n" );
+  fprintf( df, FLOAT_PREC, y1 );
+  fprintf( df, "  9\r\n" );
+  fprintf( df, "$LUPREC\r\n" );
+  fprintf( df, " 70\r\n" );
+  fprintf( df, "    14\r\n" );
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "ENDSEC\r\n" );
+
+/*  ' Create TABLES section */
+
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "SECTION\r\n" );
+  fprintf( df, "  2\r\n" );
+  fprintf( df, "TABLES\r\n" );
+/*  ' Table 1 - set up line type */
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "TABLE\r\n" );
+  fprintf( df, "  2\r\n" );
+  fprintf( df, "LTYPE\r\n" );
+  fprintf( df, " 70\r\n" );
+  fprintf( df, "2\r\n" );
+/*  ' Entry 1 of Table 1 */
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "LTYPE\r\n" );
+  fprintf( df, "  2\r\n" );
+  fprintf( df, "CONTINUOUS\r\n" );
+  fprintf( df, " 70\r\n" );
+  fprintf( df, "64\r\n" );
+  fprintf( df, "  3\r\n" );
+  fprintf( df, "Solid line\r\n" );
+  fprintf( df, " 72\r\n" );
+  fprintf( df, "65\r\n" );
+  fprintf( df, " 73\r\n" );
+  fprintf( df, "0\r\n" );
+  fprintf( df, " 40\r\n" );
+  fprintf( df, "0.0\r\n" );
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "ENDTAB\r\n" );
+ /* End of TABLES section */
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "ENDSEC\r\n" );
+
+  /* Create BLOCKS section  */
+  
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "SECTION\r\n" );
+  fprintf( df, "  2\r\n" );
+  fprintf( df, "BLOCKS\r\n" );
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "ENDSEC\r\n" );
+  fprintf( df, "  0\r\n" );
+  fprintf( df, "SECTION\r\n" );
+  fprintf( df, "  2\r\n" );
+  fprintf( df, "ENTITIES\r\n" );
+  
+}
+
+
+void dxf_ent_preamble (int dxf_type, char *id, FILE *df)
+{
+
+  fprintf( df, "  0\r\n" );
+
+  switch (dxf_type) {
+    case  SHPT_POLYGON:
+    case  SHPT_ARC:	  fprintf (df, "POLYLINE\r\n");
+          break;
+    default:  fprintf(df, "POINT\r\n");
+  }	   
+
+  fprintf( df, "  8\r\n");
+  fprintf( df, "%s\r\n", id );
+  switch ( dxf_type ) {
+    case SHPT_ARC:
+                    fprintf( df, "  6\r\n" );
+                    fprintf( df, "CONTINUOUS\r\n" );
+                    fprintf( df, " 66\r\n" );
+                    fprintf( df, "1\r\n" );
+                 break;
+    case SHPT_POLYGON:
+                    fprintf( df, "  6\r\n" );
+                    fprintf( df, "CONTINUOUS\r\n" );
+                    fprintf( df, " 66\r\n" );
+                    fprintf( df, "1\r\n" );
+                    fprintf( df, " 70\r\n");
+		    fprintf (df, "1\r\n");
+    default:     break;
+  } 
+
+}
+
+void dxf_ent (char *id, double x, double y, double z, int dxf_type, FILE *df)
+{
+  if ((dxf_type == SHPT_ARC) || ( dxf_type == SHPT_POLYGON))  {
+    fprintf( df, "  0\r\n");
+    fprintf( df, "VERTEX\r\n");
+    fprintf( df, "  8\r\n");
+    fprintf( df, "%s\r\n", id);
+  }  
+  fprintf( df, " 10\r\n" );
+  fprintf( df, FLOAT_PREC, x );
+  fprintf( df, " 20\r\n" );
+  fprintf( df, FLOAT_PREC, y );
+  fprintf( df, " 30\r\n" );
+  if ( z != 0 ) 
+    fprintf( df, FLOAT_PREC, z );
+  else
+    fprintf( df, "0.0\r\n" );	       
+}
+
+
+void dxf_ent_postamble (int dxf_type, FILE *df)
+{
+  if ((dxf_type == SHPT_ARC) || ( dxf_type == SHPT_POLYGON)) 
+    fprintf( df, "  0\r\nSEQEND\r\n  8\r\n0\r\n");
+}
+
+
+int
+main (int argc, char **argv)
+
+{
+    char shpFileName[80] = "", dbfFileName[80] = "";
+    char dxfFileName[80] = "";
+    char idfldName[15];
+    char zfldName[6] = "ELEV";
+    char fldName[15];
+    char id[255];
+    double elev;
+    int   *panParts, nParts, nVertices;
+//    int   parts;
+    FILE	*dxf;
+    SHPHandle shp;
+    DBFHandle dbf;
+    DBFFieldType  idfld_type = FTInvalid;
+    double adfBoundsMin[4], adfBoundsMax[4];
+    int	vrtx, shp_type, shp_numrec, zfld, idfld, nflds, recNum, part;
+    int MaxElem = 0;
+ 
+    if ( argc < 2 )  {
+        printf ("usage: shpdxf shapefile {idfield}\r\n");
+        exit (-1);
+    }
+   
+    strcpy (shpFileName,argv[1]);
+    strncpy (dbfFileName, shpFileName, strlen(shpFileName)-3);
+    strcat (dbfFileName,"dbf"); 
+  
+    strncpy (dxfFileName, shpFileName,strlen(shpFileName)-3);
+    strcat( dxfFileName, "dxf");
+  
+    shp = SHPOpen (shpFileName, "rb");
+    dbf = DBFOpen (dbfFileName, "rb");
+    dxf = fopen( dxfFileName, "w");
+
+    printf("Starting conversion %s(%s) -> %s\r\n",
+           shpFileName,dbfFileName,dxfFileName);
+  
+    SHPGetInfo (shp, &shp_numrec, &shp_type, adfBoundsMin, adfBoundsMax );
+    printf ("file has %d objects\r\n", shp_numrec);
+    dxf_hdr(adfBoundsMin[0], adfBoundsMin[1], adfBoundsMax[0], adfBoundsMax[1],
+            dxf);
+      
+/* Before proceeding, allow the user to specify the ID field to use or default to the record number.... */
+
+    if ( argc > 3 )  MaxElem = atoi(argv[3]);
+  
+    nflds = DBFGetFieldCount(dbf);
+    if ( argc > 2 ) {
+        strcpy (idfldName, argv[2]);
+        for ( idfld=0; idfld < nflds; idfld++ ) {
+            idfld_type = DBFGetFieldInfo( dbf, idfld, fldName, NULL, NULL);
+            if (!strcmp (idfldName, fldName ))
+                break;
+        }
+        if ( idfld >= nflds ) {
+            printf ("Id field %s not found, using default\r\n",idfldName); 
+            idfld = -1;  
+        } else
+            printf ("proceeding with field %s for LayerNames\r\n",fldName);
+    }
+    else
+        idfld = -1;  
+    
+    for ( zfld=0; zfld < nflds; zfld++ ) {
+        DBFGetFieldInfo( dbf, zfld, fldName, NULL, NULL);
+        if (!strcmp (zfldName, fldName  ))
+            break;
+    }
+    if ( zfld >= nflds ) 
+        zfld = -1;
+//  printf ("proceeding with id = %d, elevation = %d\r\n",idfld, zfld);
+  
+/* Proceed to process data..... */
+  
+    for ( recNum = 0; (recNum < shp_numrec) && (recNum < MaxElem); recNum++)  {
+
+        SHPObject	*shape;
+
+        if ( idfld >= 0 )
+            switch (idfld_type) {
+              case FTString:  sprintf (id, "lvl_%s",DBFReadStringAttribute ( dbf, recNum, idfld ));
+                break;
+              default:    sprintf(id, "%-20.0lf", DBFReadDoubleAttribute (dbf, recNum, idfld));
+            }
+        else
+            sprintf (id,"lvl_%-20d",(recNum +1 )); 
+
+    
+        if ( zfld >= 0 ) 
+            elev = 0;
+        else  
+            elev = DBFReadDoubleAttribute ( dbf, recNum, zfld );
+  
+#ifdef DEBUG
+        printf("\r\nworking on obj %d", recNum);
+#endif
+
+        shape = SHPReadObject( shp, recNum );
+   
+        nVertices = shape->nVertices;
+        nParts = shape->nParts;
+        panParts = shape->panPartStart;
+        part = 0;
+        for (vrtx=0; vrtx < nVertices; vrtx ++ ) { 
+#ifdef DEBUG
+        printf("\rworking on part %d, vertex %d", part,vrtx);     
+#endif 
+            if ( panParts[part] == vrtx ) {
+#ifdef DEBUG
+       printf ("object preamble\r\n");
+#endif
+                dxf_ent_preamble (shp_type, id, dxf);
+            }
+     
+            dxf_ent (id, shape->padfX[vrtx], shape->padfY[vrtx],
+                     elev, shp_type, dxf);
+ 
+            if ((panParts[part] == (vrtx + 1))|| (vrtx == (nVertices -1)) ) {
+                dxf_ent_postamble (shp_type, dxf);
+                part ++;
+            }
+        }
+        SHPDestroyObject( shape );
+    }
+
+/* close out DXF file */
+    fprintf( dxf, "0\r\n" );
+    fprintf( dxf, "ENDSEC\r\n" );
+    fprintf( dxf, "0\r\n" );
+    fprintf( dxf, "EOF\r\n" );
+
+
+    SHPClose (shp);
+    DBFClose (dbf);
+    fclose (dxf);
+    return(0);
+}
+
+
+
+
+
+
diff --git a/src/shapelib/contrib/shpfix.c b/src/shapelib/contrib/shpfix.c
new file mode 100644
index 0000000..a24ab6e
--- /dev/null
+++ b/src/shapelib/contrib/shpfix.c
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * shpfix
+ *
+ *
+ *  gcc -c shpfix.c shpopen.c -o shpfix
+ *
+ *  Utility program to fix nulls and inconsistencies in Shapefiles
+ *  as happens from time to time
+ *
+ *  Simply load and rewrite each record, parameter fixrex allow user to null 
+ *  a particularly nasty record if needed
+ *
+ */
+
+#include "shapefil.h"
+#include <stdlib.h>
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP, cSHP;
+    int		nShapeType, cShapeType, nEntities, i;
+    double	adBounds[4];
+    SHPObject	*shape;
+    int		fix_rec;	
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc <= 3 )
+    {
+	printf( "shpfix shpfile new_file <Record# to Blank>\n" );
+	exit( 1 );
+    }
+
+   fix_rec = atoi (argv[3]);
+   fix_rec --;
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "rb+" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL );
+
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    cSHP = SHPCreate( argv[2], nShapeType );
+
+    if( cSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[2] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( cSHP, NULL, &cShapeType, &(adBounds[0]), &(adBounds[2]) );
+
+
+/* -------------------------------------------------------------------- */
+/*	Skim over the list of shapes, printing all the vertices.	*/
+/* -------------------------------------------------------------------- */
+
+    for( i = 0; i < nEntities; i++ )
+    {
+
+        shape = SHPReadObject( hSHP, i );
+        if ( i == fix_rec ) 
+          {  shape->nParts = 0;
+             shape->nVertices = 0;
+          }
+        SHPWriteObject( cSHP, -1, shape );          
+        SHPDestroyObject ( shape );
+
+    }
+    
+
+    SHPClose ( hSHP );
+    SHPClose ( cSHP );
+    return(0);
+}
+
diff --git a/src/shapelib/contrib/shpgeo.c b/src/shapelib/contrib/shpgeo.c
new file mode 100644
index 0000000..2b7162e
--- /dev/null
+++ b/src/shapelib/contrib/shpgeo.c
@@ -0,0 +1,1642 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * requires shapelib 1.2
+ *   gcc shpproj shpopen.o dbfopen.o -lm -lproj -o shpproj
+ * 
+ * this may require linking with the PROJ4 projection library available from
+ *
+ * http://www.remotesensing.org/proj
+ *
+ * use -DPROJ4 to compile in Projection support
+ *
+ * $Log: shpgeo.c,v $
+ * Revision 1.5  2010/07/13 06:12:22  we7u
+ * Attempting to fix the "endian-ness" tests.
+ *
+ * Revision 1.4  2010/07/11 20:30:00  we7u
+ * More minor tweaks to get rid of compiler warnings.  Of particular note are
+ * some TODO entries added to a couple of files for two enumerated values that
+ * weren't being handled in "switch" statements.  There still isn't any code
+ * for those case statements, but the compiler warnings are gone.
+ *
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:45:27  we7u
+ * Adding includes necessary for warning-free compiles.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.8  2002/01/15 14:36:56  warmerda
+ * upgrade to use proj_api.h
+ *
+ * Revision 1.7  2002/01/11 15:22:04  warmerda
+ * fix many warnings.  Lots of this code is cruft.
+ *
+ * Revision 1.6  2001/08/30 13:42:31  warmerda
+ * avoid use of auto initialization of PT for VC++
+ *
+ * Revision 1.5  2000/04/26 13:24:06  warmerda
+ * made projUV handling safer
+ *
+ * Revision 1.4  2000/04/26 13:17:15  warmerda
+ * check if projUV or UV
+ *
+ * Revision 1.3  2000/03/17 14:15:16  warmerda
+ * Don't try to use system nan.h ... doesn't always exist.
+ *
+ * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ */
+
+#include "shapefil.h"
+#include <string.h>
+#include <math.h>
+
+#ifndef NAN
+#include "my_nan.h"
+#endif
+
+#include "shpgeo.h"
+
+
+ /* I'm using some shorthand throughout this file
+ *      R+ is a Clockwise Ring and is the positive portion of an object
+ *      R- is a CounterClockwise Ring and is a hole in a R+
+ *      A complex object is one having at least one R-
+ *      A compound object is one having more than one R+
+ *	A simple object has one and only one element (R+ or R-)
+ *
+ *	The closed ring constraint is for polygons and assumed here
+ *	Arcs or LineStrings I am calling Rings (generically open or closed)
+ *	Point types are vertices or lists of vertices but not Rings
+ *
+ *   SHPT_POLYGON, SHPT_POLYGONZ, SHPT_POLYGONM and SHPT_MULTIPATCH
+ *   can have SHPObjects that are compound as well as complex
+ *  
+ *   SHP_POINT and its Z and M derivatives are strictly simple
+ *   MULTI_POINT, SHPT_ARC and their derivatives may be simple or compound
+ *
+ */
+
+
+/* **************************************************************************
+ * asFileName
+ *
+ * utility function, toss part of filename after last dot
+ *
+ * **************************************************************************/ 
+char * asFileName ( const char *fil, char *ext ) {
+  char	pszBasename[120];
+  static char	pszFullname[120];
+  int	i;
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+//    pszFullname = (char*) malloc(( strlen(fil)+5 ));
+//    pszBasename = (char *) malloc(strlen(fil)+5);
+    strcpy( pszBasename, fil );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+/* -------------------------------------------------------------------- */
+/*	Note that files pulled from										*/
+/*	a PC to Unix with upper case filenames won't work!				*/
+/* -------------------------------------------------------------------- */
+//    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.%s", pszBasename, ext );
+
+    return ( pszFullname );
+}
+
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+/* copied directly from shpopen.c -- maybe expose this in shapefil.h	*/  
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+
+/* **************************************************************************
+ * SHPPRoject
+ *
+ * Project points using projection handles, for use with PROJ4.3
+ *
+ * act as a wrapper to protect against library changes in PROJ
+ * 
+ * **************************************************************************/ 
+int SHPProject ( SHPObject *psCShape, projPJ inproj, projPJ outproj ) {
+#ifdef	PROJ4
+   int	j;
+   projUV   p;    /* struct { double u, double v } */
+
+   /* for each vertex project it and stuff the projeted point back into 	*/
+   /*	same SHPObject.  Proj assumes data is in radians so convert it.		*/
+   /*   Proj will convert Geographic -> <proj> and <proj> -> Geographic		*/
+   /*	so <proj1> -> <proj2> requires bouncing though geographic			*/
+   
+   for ( j=0; j < psCShape->nVertices; j++ ) {
+     p.u = psCShape->padfX[j];
+     p.v = psCShape->padfY[j];
+
+     if ( inproj )
+       p = pj_inv ( p, inproj );
+     else
+      { p.u *= DEG_TO_RAD;
+        p.v *= DEG_TO_RAD;
+      }
+
+     if ( outproj ) 
+       p = pj_fwd ( p, outproj );
+     else
+     { p.u *= RAD_TO_DEG;
+       p.v *= RAD_TO_DEG;
+     } 
+
+     psCShape->padfX[j] = p.u;
+     psCShape->padfY[j] = p.v;
+   }
+   
+   /* Recompute new Extents of projected Object								*/
+   SHPComputeExtents ( psCShape );
+#endif  
+
+   return ( 1 );
+}
+
+
+/* **************************************************************************
+ * SHPSetProjection
+ *
+ * establish a projection handle for use with PROJ4.3
+ *
+ * act as a wrapper to protect against library changes in PROJ
+ *
+ * **************************************************************************/
+projPJ SHPSetProjection ( int param_cnt, char **params ) {
+#ifdef PROJ4
+  projPJ	*p = NULL;
+
+  if ( param_cnt > 0 && params[0] )
+  { p = pj_init ( param_cnt, params ); }
+
+  return ( p );
+#else
+  return ( NULL );
+#endif
+}
+
+
+/* **************************************************************************
+ * SHPFreeProjection
+ *
+ * release a projection handle for use with PROJ4.3
+ *
+ * act as a wrapper to protect against library changes in PROJ
+ * 
+ * **************************************************************************/
+int SHPFreeProjection ( projPJ p) {
+#ifdef PROJ4
+  if ( p )
+    pj_free ( p );
+#endif
+  return ( 1 );
+}
+
+
+/* **************************************************************************
+ * SHPOGisType
+ *
+ * Convert Both ways from and to OGIS Geometry Types
+ *
+ * **************************************************************************/
+int SHPOGisType ( int GeomType, int toOGis) {
+
+    if ( toOGis == 0 )  /* connect OGis -> SHP types  					*/
+	switch (GeomType) {
+            case (OGIST_POINT):		return ( SHPT_POINT );      break;
+            case (OGIST_LINESTRING):	return ( SHPT_ARC );        break;
+            case (OGIST_POLYGON):		return ( SHPT_POLYGON );    break;
+            case (OGIST_MULTIPOINT):	return ( SHPT_MULTIPOINT ); break;
+            case (OGIST_MULTILINE):	return ( SHPT_ARC );	    break;
+            case (OGIST_MULTIPOLYGON):	return ( SHPT_POLYGON );    break;
+        }
+    else  /* ok so its SHP->OGis types 									*/
+        switch (GeomType) {
+	    case (SHPT_POINT):		return ( OGIST_POINT );	    break;
+	    case (SHPT_POINTM):		return ( OGIST_POINT );	    break;
+	    case (SHPT_POINTZ):		return ( OGIST_POINT );	    break;
+	    case (SHPT_ARC):		return ( OGIST_LINESTRING );break;
+	    case (SHPT_ARCZ):		return ( OGIST_LINESTRING );break;
+	    case (SHPT_ARCM):		return ( OGIST_LINESTRING );break;
+	    case (SHPT_POLYGON):	return ( OGIST_MULTIPOLYGON );break;
+	    case (SHPT_POLYGONZ):	return ( OGIST_MULTIPOLYGON );break;
+	    case (SHPT_POLYGONM):	return ( OGIST_MULTIPOLYGON );break;
+	    case (SHPT_MULTIPOINT):	return ( OGIST_MULTIPOINT );break;
+	    case (SHPT_MULTIPOINTZ):	return ( OGIST_MULTIPOINT );break;
+	    case (SHPT_MULTIPOINTM):	return ( OGIST_MULTIPOINT );break;
+	    case (SHPT_MULTIPATCH):	return ( OGIST_GEOMCOLL );  break;
+        } 	  	  	  
+
+    return 0;
+}
+
+
+/* **************************************************************************
+ * SHPReadSHPStream
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int SHPReadSHPStream ( SHPObject *psCShape, char *stream_obj) {
+
+//int	obj_storage;
+int	my_order, need_swap =0, GeoType =0 ;
+int	use_Z = 0;
+int	use_M = 0;
+
+  need_swap = stream_obj[0];
+  my_order = 1;
+  my_order = ((char*) (&my_order))[0];
+  need_swap = need_swap & my_order;
+
+  if ( need_swap )
+     swapW (stream_obj, (void*) &GeoType, sizeof (GeoType) );
+   else
+     memcpy (stream_obj, &GeoType, sizeof (GeoType) );
+
+           
+  if ( need_swap ) {
+  
+  } else {
+    memcpy (stream_obj, &(psCShape->nSHPType),  sizeof (psCShape->nSHPType) );
+    memcpy (stream_obj, &(psCShape->nShapeId),  sizeof (psCShape->nShapeId) );
+    memcpy (stream_obj, &(psCShape->nVertices), sizeof (psCShape->nVertices) );
+    memcpy (stream_obj, &(psCShape->nParts), 	 sizeof (psCShape->nParts) );
+    memcpy (stream_obj, &(psCShape->dfXMin), 	 sizeof (psCShape->dfXMin) );
+    memcpy (stream_obj, &(psCShape->dfYMin), 	 sizeof (psCShape->dfYMin) );
+    memcpy (stream_obj, &(psCShape->dfXMax), 	 sizeof (psCShape->dfXMax) );
+    memcpy (stream_obj, &(psCShape->dfYMax), 	 sizeof (psCShape->dfYMax) );
+    if ( use_Z ) {
+      memcpy (stream_obj, &(psCShape->dfZMin), 	 sizeof (psCShape->dfZMin) );
+      memcpy (stream_obj, &(psCShape->dfZMax), 	 sizeof (psCShape->dfZMax) );
+    }
+   
+    memcpy (stream_obj, psCShape->panPartStart, psCShape->nParts * sizeof (int) );
+    memcpy (stream_obj, psCShape->panPartType,  psCShape->nParts * sizeof (int) );
+    
+/* get X and Y coordinate arrarys */    
+    memcpy (stream_obj, psCShape->padfX, psCShape->nVertices * 2 * sizeof (double) );
+
+/* get Z coordinate array if used */
+    if ( use_Z ) 
+      memcpy (stream_obj, psCShape->padfZ, psCShape->nVertices * 2 * sizeof (double) );
+/* get Measure coordinate array if used */
+    if ( use_M ) 
+      memcpy (stream_obj, psCShape->padfM, psCShape->nVertices * 2 * sizeof (double) );
+   }    /* end put data without swap */
+   
+   return (0);
+}
+
+
+/* **************************************************************************
+ * SHPWriteSHPStream
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int SHPWriteSHPStream ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
+
+int	obj_storage = 0;
+int	need_swap = 0;
+//int my_order, GeoType;
+int	use_Z = 0;
+int	use_M = 0;
+
+  need_swap = 1;
+  need_swap = ((char*) (&need_swap))[0];
+  
+  if ( !realloc (stream_obj, obj_storage ) ) {
+    return(1);
+  }
+  
+  if ( need_swap ) {
+  
+  } else {
+    memcpy (stream_obj, psCShape, 4 * sizeof (int) );
+    memcpy (stream_obj, psCShape, 4 * sizeof (double) );
+    if ( use_Z ) 
+      memcpy (stream_obj, psCShape, 2 * sizeof (double) );
+    if ( use_M ) 
+      memcpy (stream_obj, psCShape, 2 * sizeof (double) );
+          
+    memcpy (stream_obj, psCShape, psCShape->nParts * 2 * sizeof (int) );
+    memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) );
+    if ( use_Z ) 
+      memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) );
+    if ( use_M ) 
+      memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) );
+   }
+   
+  return (0);
+}
+
+
+/* **************************************************************************
+ * WKBStreamWrite
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int WKBStreamWrite ( WKBStreamObj* wso, void* this, int tcount, int tsize ) {
+
+   if ( wso->NeedSwap )
+     SwapG ( &(wso->wStream[wso->StreamPos]), this, tcount, tsize );
+   else
+     memcpy ( &(wso->wStream[wso->StreamPos]), this, tsize * tcount );
+     
+   wso->StreamPos += tsize;
+
+   return 0;
+}
+
+
+
+/* **************************************************************************
+ * WKBStreamRead
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int WKBStreamRead ( WKBStreamObj* wso, void* this, int tcount, int tsize ) {
+
+   if ( wso->NeedSwap )
+     SwapG ( this, &(wso->wStream[wso->StreamPos]), tcount, tsize );
+   else
+     memcpy ( this, &(wso->wStream[wso->StreamPos]), tsize * tcount );
+     
+   wso->StreamPos += tsize;
+
+   return 0;
+}
+
+
+
+/* **************************************************************************
+ * SHPReadOGisWKB
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+SHPObject* SHPReadOGisWKB ( WKBStreamObj *stream_obj) {
+  SHPObject	*psCShape;
+  char		WKB_order;
+//  int		need_swap = 0;
+  int       my_order, GeoType = 0;
+//  int		use_Z = 0, use_M = 0;
+  int		nSHPType, thisDim;
+
+  WKBStreamRead ( stream_obj, &WKB_order, 1, sizeof(char));
+  my_order = 1;
+  my_order = ((char*) (&my_order))[0];
+  stream_obj->NeedSwap = !(WKB_order & my_order);
+
+  /* convert OGis Types to SHP types  */
+  nSHPType = SHPOGisType ( GeoType, 0 );
+
+  WKBStreamRead ( stream_obj, &GeoType, 1, sizeof(int));
+     
+  thisDim = SHPDimension ( nSHPType );
+  
+  if ( thisDim && SHPD_AREA ) 
+    { psCShape = SHPReadOGisPolygon ( stream_obj ); } 
+   else {
+    if ( thisDim && SHPD_LINE )
+      { psCShape = SHPReadOGisLine ( stream_obj ); }
+    else {
+      if ( thisDim && SHPD_POINT )
+        { psCShape = SHPReadOGisPoint ( stream_obj ); }
+      }
+    }
+   
+
+   return (0);
+}
+
+
+
+/* **************************************************************************
+ * SHPWriteOGisWKB
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int SHPWriteOGisWKB ( WKBStreamObj* stream_obj, SHPObject *psCShape ) {
+
+//  int		need_swap = 0;
+  int       my_order, GeoType, thisDim;
+//  int		use_Z = 0, use_M = 0;  
+  char		LSB = 1;
+  /* indicate that this WKB is in LSB Order	*/
+
+  /* OGis WKB can handle either byte order,  but if I get to choose I'd
+   * rather have it predicatable system-to-system							*/
+
+  if ( stream_obj ) {
+    if ( stream_obj->wStream )
+      free ( stream_obj->wStream );
+   } else 
+    { stream_obj = calloc ( 3, sizeof (int ) ); }
+
+  /* object size needs to be 9 bytes for the wrapper, and for each polygon	*/
+  /* another 9 bytes all plus twice the total number of vertices 		*/
+  /* times the sizeof (double) and just pad with 10 more chars for fun 		*/
+  stream_obj->wStream = calloc (1, (9 * (psCShape->nParts + 1)) +
+  	( sizeof(double) * 2 * psCShape->nVertices ) + 10 );
+  
+ #ifdef DEBUG2
+   printf (" I just allocated %d bytes to wkbObj \n", 
+  	sizeof (int) + sizeof (int) + sizeof(int) +
+        ( sizeof(int) * psCShape->nParts + 1 ) +
+  	( sizeof(double) * 2 * psCShape->nVertices ) + 10 );
+ #endif 
+ 
+  my_order = 1;
+  my_order = ((char*) (&my_order))[0];
+  /* Need to swap if this system is not  LSB (Intel Order)					*/
+  stream_obj->NeedSwap = ( my_order != LSB );
+
+  stream_obj->StreamPos = 0;
+
+  
+  #ifdef DEBUG2
+    printf ("this system is (%d) LSB recorded as needSwap %d\n",my_order, stream_obj->NeedSwap);
+  #endif
+
+  WKBStreamWrite ( stream_obj, & LSB, 1, sizeof(char) );
+  
+  #ifdef DEBUG2
+    printf ("this system in (%d) LSB \n");
+  #endif
+
+  
+  /* convert SHP Types to OGis types  */
+  GeoType = SHPOGisType ( psCShape->nSHPType, 1 );
+  WKBStreamWrite ( stream_obj, &GeoType, 1, sizeof(int) );
+     
+  thisDim = SHPDimension ( psCShape->nSHPType );
+  
+  if ( thisDim && SHPD_AREA ) 
+    { SHPWriteOGisPolygon ( stream_obj, psCShape ); } 
+   else {
+    if ( thisDim && SHPD_LINE )
+      { SHPWriteOGisLine ( stream_obj, psCShape ); }
+    else {
+      if ( thisDim && SHPD_POINT )
+        { SHPWriteOGisPoint ( stream_obj, psCShape ); }
+      }
+    }
+
+#ifdef DEBUG2
+  printf("(SHPWriteOGisWKB) outta here when stream pos is %d \n", stream_obj->StreamPos);
+#endif   
+  return (0);
+}
+
+
+/* **************************************************************************
+ * SHPWriteOGisPolygon
+ *
+ * for this pass code to more generic OGis MultiPolygon Type
+ * later add support for OGis Polygon Type
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int SHPWriteOGisPolygon ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
+   SHPObject		**ppsC;
+   SHPObject		*psC;
+   int			rPart, ring, rVertices, cpart, cParts, nextring, j;
+//   int          i;
+   char			Flag = 1;
+   int			GeoType = OGIST_POLYGON;
+   
+   /* cant have more than nParts complex objects in this object */
+   ppsC = calloc ( psCShape->nParts, sizeof(int) );
+
+   
+   nextring = 0;
+   cParts=0;
+   while ( nextring >= 0 ) {
+     ppsC[cParts] = SHPUnCompound ( psCShape, &nextring ); 
+     cParts++;
+    }
+   
+#ifdef DEBUG2
+     printf ("(SHPWriteOGisPolygon) Uncompounded into %d parts \n", cParts);
+#endif
+      
+   WKBStreamWrite ( stream_obj, &cParts, 1, sizeof(int) );
+
+   for ( cpart = 0; cpart < cParts; cpart++) {
+
+     WKBStreamWrite ( stream_obj, & Flag, 1, sizeof(char) );
+     WKBStreamWrite ( stream_obj, & GeoType, 1, sizeof(int) );
+  
+     psC = (SHPObject*) ppsC[cpart];
+     WKBStreamWrite ( stream_obj, &(psC->nParts), 1, sizeof(int) );    
+     
+     for ( ring = 0; (ring < (psC->nParts)) && (psC->nParts > 0); ring ++) {
+       if ( ring < (psC->nParts-2) )
+         { rVertices = psC->panPartStart[ring+1] - psC->panPartStart[ring]; }
+       else
+         { rVertices = psC->nVertices - psC->panPartStart[ring]; }
+#ifdef DEBUG2
+     printf ("(SHPWriteOGisPolygon) scanning part %d, ring %d %d vtxs \n", 
+     		cpart, ring, rVertices);
+#endif             
+       rPart = psC->panPartStart[ring];
+       WKBStreamWrite ( stream_obj, &rVertices, 1, sizeof(int) );       
+       for ( j=rPart; j < (rPart + rVertices); j++ ) {
+         WKBStreamWrite ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
+         WKBStreamWrite ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );
+        } /* for each vertex */
+      }  /* for each ring */
+    }  /* for each complex part */
+
+#ifdef DEBUG2
+     printf ("(SHPWriteOGisPolygon) outta here \n");
+#endif   
+  return (1);
+}
+
+
+/* **************************************************************************
+ * SHPWriteOGisLine
+ *
+ * for this pass code to more generic OGis MultiXXXXXXX Type
+ * later add support for OGis LineString Type
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int SHPWriteOGisLine ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
+
+  return ( SHPWriteOGisPolygon( stream_obj, psCShape ));
+}
+
+
+/* **************************************************************************
+ * SHPWriteOGisPoint
+ *
+ * for this pass code to more generic OGis MultiPoint Type
+ * later add support for OGis Point Type
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int SHPWriteOGisPoint ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
+   int			j;
+   
+   WKBStreamWrite ( stream_obj, &(psCShape->nVertices), 1, sizeof(int) );
+
+   for ( j=0; j < psCShape->nVertices; j++ ) {
+     WKBStreamWrite ( stream_obj, &(psCShape->padfX[j]), 1, sizeof(double) );
+     WKBStreamWrite ( stream_obj, &(psCShape->padfY[j]), 1, sizeof(double) );
+    } /* for each vertex */
+
+  return (1);
+}
+
+
+
+/* **************************************************************************
+ * SHPReadOGisPolygon
+ *
+ * for this pass code to more generic OGis MultiPolygon Type
+ * later add support for OGis Polygon Type
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+SHPObject* SHPReadOGisPolygon ( WKBStreamObj *stream_obj ) {
+//   SHPObject		**ppsC;
+   SHPObject		*psC;
+   int			rPart, ring, rVertices, cpart, cParts, j;
+//   int          i, nextring;
+   int			totParts, totVertices, pRings, nParts;
+   
+   psC = SHPCreateObject ( SHPT_POLYGON, -1, 0, NULL, NULL, 0,
+        	NULL, NULL, NULL, NULL ); 
+   /* initialize a blank SHPObject 											*/        	
+
+   WKBStreamRead ( stream_obj, &cParts, 1, sizeof(char) );
+
+   totParts = cParts;
+   totVertices = 0;
+   
+   SfRealloc ( psC->panPartStart, cParts * sizeof(int));
+   SfRealloc ( psC->panPartType, cParts * sizeof(int));
+
+   for ( cpart = 0; cpart < cParts; cpart++) {
+     WKBStreamRead ( stream_obj, &nParts, 1, sizeof(int) );
+     pRings = nParts;     
+     /* pRings is the number of rings prior to the Ring loop below			*/
+     
+     if ( nParts > 1 ) {
+       totParts += nParts - 1;
+       SfRealloc ( psC->panPartStart, totParts * sizeof(int));
+       SfRealloc ( psC->panPartType, totParts * sizeof(int));
+      }
+
+     rPart = 0;
+     for ( ring = 0; ring < (nParts - 1); ring ++) {
+       WKBStreamRead ( stream_obj, &rVertices, 1, sizeof(int) );
+       totVertices += rVertices;
+               
+       psC->panPartStart[ring+pRings] = rPart;
+       if ( ring == 0 )
+         { psC->panPartType[ring + pRings] = SHPP_OUTERRING; }
+        else
+         { psC->panPartType[ring + pRings] = SHPP_INNERRING; }
+
+       SfRealloc ( psC->padfX, totVertices * sizeof (double));
+       SfRealloc ( psC->padfY, totVertices * sizeof (double));
+              
+       for ( j=rPart; j < (rPart + rVertices); j++ ) {
+         WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
+         WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );        
+        } /* for each vertex */
+       rPart += rVertices;
+
+      }  /* for each ring */
+      
+    }  /* for each complex part */
+    
+    return ( psC );
+    
+}
+
+
+/* **************************************************************************
+ * SHPReadOGisLine
+ *
+ * for this pass code to more generic OGis MultiLineString Type
+ * later add support for OGis LineString Type
+ * 
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+SHPObject* SHPReadOGisLine ( WKBStreamObj *stream_obj ) {
+//   SHPObject		**ppsC;
+   SHPObject		*psC;
+   int			rPart, ring, rVertices, cpart, cParts, j;
+//   int          i, nextring;
+   int			totParts, totVertices, pRings, nParts;
+   
+   psC = SHPCreateObject ( SHPT_ARC, -1, 0, NULL, NULL, 0,
+        	NULL, NULL, NULL, NULL ); 
+   /* initialize a blank SHPObject 											*/        	
+
+   WKBStreamRead ( stream_obj, &cParts, 1, sizeof(int) );
+
+   totParts = cParts;
+   totVertices = 0;
+   
+   SfRealloc ( psC->panPartStart, cParts * sizeof(int));
+   SfRealloc ( psC->panPartType, cParts * sizeof(int));
+
+   for ( cpart = 0; cpart < cParts; cpart++) {
+     WKBStreamRead ( stream_obj, &nParts, 1, sizeof(int) );
+     pRings = totParts;     
+     /* pRings is the number of rings prior to the Ring loop below			*/
+     
+     if ( nParts > 1 ) {
+       totParts += nParts - 1;
+       SfRealloc ( psC->panPartStart, totParts * sizeof(int));
+       SfRealloc ( psC->panPartType, totParts * sizeof(int));
+      }
+
+     rPart = 0;
+     for ( ring = 0; ring < (nParts - 1); ring ++) {
+       WKBStreamRead ( stream_obj, &rVertices, 1, sizeof(int) );
+       totVertices += rVertices;
+               
+       psC->panPartStart[ring+pRings] = rPart;
+       if ( ring == 0 )
+         { psC->panPartType[ring + pRings] = SHPP_OUTERRING; }
+        else
+         { psC->panPartType[ring + pRings] = SHPP_INNERRING; }
+
+       SfRealloc ( psC->padfX, totVertices * sizeof (double));
+       SfRealloc ( psC->padfY, totVertices * sizeof (double));
+              
+       for ( j=rPart; j < (rPart + rVertices); j++ ) {
+         WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
+         WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );        
+        } /* for each vertex */
+       rPart += rVertices;
+
+      }  /* for each ring */
+      
+    }  /* for each complex part */
+    
+    return ( psC );
+}
+
+
+/* **************************************************************************
+ * SHPReadOGisPoint
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+SHPObject* SHPReadOGisPoint ( WKBStreamObj *stream_obj ) {
+   SHPObject		*psC;
+   int			nVertices, j;
+   
+   psC = SHPCreateObject ( SHPT_MULTIPOINT, -1, 0, NULL, NULL, 0,
+        	NULL, NULL, NULL, NULL ); 
+   /* initialize a blank SHPObject 											*/        	
+
+   WKBStreamRead ( stream_obj, &nVertices, 1, sizeof(int) );
+
+   SfRealloc ( psC->padfX, nVertices * sizeof (double));
+   SfRealloc ( psC->padfY, nVertices * sizeof (double));
+              
+   for ( j=0; j < nVertices; j++ ) {
+     WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
+     WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );        
+    } /* for each vertex */
+    
+    return ( psC );
+}
+
+
+
+
+/* **************************************************************************
+ * RingReadOGisWKB  
+ *
+ * this accepts OGisLineStrings which are basic building blocks
+ *
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int RingReadOgisWKB ( SHPObject *psCShape, char *stream_obj) {
+    return 0;
+}
+
+
+/* **************************************************************************
+ * RingWriteOGisWKB
+ *
+ * this emits OGisLineStrings which are basic building blocks
+ * 
+ * Encapsulate entire SHPObject for use with Postgresql
+ *
+ * **************************************************************************/
+int RingWriteOgisWKB ( SHPObject *psCShape, char *stream_obj) {
+
+    return 0;
+}
+
+
+/* **************************************************************************
+ * SHPDimension
+ *
+ * Return the Dimensionality of the SHPObject 
+ * a handy utility function
+ * 
+ * **************************************************************************/
+int SHPDimension ( int SHPType ) {
+    int 	dimension;
+    
+    dimension = 0;
+      
+    switch ( SHPType ) {
+    	case  SHPT_POINT       :	dimension = SHPD_POINT ;
+    	case  SHPT_ARC         :	dimension = SHPD_LINE;
+    	case  SHPT_POLYGON     :	dimension = SHPD_AREA;    	
+    	case  SHPT_MULTIPOINT  :	dimension = SHPD_POINT;    	
+    	case  SHPT_POINTZ      :	dimension = SHPD_POINT | SHPD_Z;    	
+    	case  SHPT_ARCZ        :	dimension = SHPD_LINE | SHPD_Z;
+    	case  SHPT_POLYGONZ    :	dimension = SHPD_AREA | SHPD_Z;
+    	case  SHPT_MULTIPOINTZ :	dimension = SHPD_POINT | SHPD_Z;    	
+    	case  SHPT_POINTM      :	dimension = SHPD_POINT | SHPD_MEASURE;    	
+    	case  SHPT_ARCM        :	dimension = SHPD_LINE | SHPD_MEASURE;
+    	case  SHPT_POLYGONM    :	dimension = SHPD_AREA | SHPD_MEASURE;
+    	case  SHPT_MULTIPOINTM :	dimension = SHPD_POINT | SHPD_MEASURE;   	 	
+    	case  SHPT_MULTIPATCH  :	dimension = SHPD_AREA;  
+    }
+
+   return ( dimension );
+}
+
+
+/* **************************************************************************
+ * SHPPointinPoly_2d
+ *
+ * Return a Point inside an R+ of a potentially 
+ * complex/compound SHPObject suitable for labelling
+ * return only one point even if if is a compound object
+ *
+ * reject non area SHP Types
+ * 
+ * **************************************************************************/
+PT	SHPPointinPoly_2d ( SHPObject *psCShape ) {
+   PT	*sPT, rPT;
+   
+   if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )
+   {
+       rPT.x = NAN;
+       rPT.y = NAN;
+       return rPT;
+   }
+
+   sPT = SHPPointsinPoly_2d ( psCShape );
+   
+   if ( sPT ) {
+     rPT.x = sPT[0].x;
+     rPT.y = sPT[0].y; 
+    } else {
+     rPT.x = NAN;
+     rPT.y = NAN;
+    }
+   return ( rPT );
+}
+
+
+/* **************************************************************************
+ * SHPPointsinPoly_2d
+ *
+ * Return a Point inside each R+ of a potentially 
+ * complex/compound SHPObject suitable for labelling
+ * return one point for each R+ even if it is a compound object
+ *
+ * reject non area SHP Types
+ * 
+ * **************************************************************************/
+PT*	SHPPointsinPoly_2d ( SHPObject *psCShape ) {
+   PT		*PIP = NULL;
+   int		cRing;
+   SHPObject	*psO, *psInt, *CLine;
+   double	*CLx, *CLy;
+   int		*CLstt, *CLst, nPIP =0, ring, rMpart =0, ring_vtx, ring_nVertices;
+   double	rLen =0.0, rLenMax =0.0;
+
+   if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )  
+      return ( NULL );
+
+   while ( (psO = SHPUnCompound(psCShape, &cRing)) != 0 ) {
+     CLx = calloc ( 4, sizeof(double));
+     CLy = calloc ( 4, sizeof(double));
+     CLst = calloc ( 2, sizeof(int));
+     CLstt = calloc ( 2, sizeof(int));
+     
+     /* a horizontal & vertical compound line though the middle of the 		*/
+     /* extents 															*/
+     CLx [0] = psO->dfXMin;
+     CLy [0] = (psO->dfYMin + psO->dfYMax ) * 0.5;
+     CLx [1] = psO->dfXMax;   
+     CLy [1] = (psO->dfYMin + psO->dfYMax ) * 0.5;
+   
+     CLx [2] = (psO->dfXMin + psO->dfXMax ) * 0.5;
+     CLy [2] = psO->dfYMin;   
+     CLx [3] = (psO->dfXMin + psO->dfXMax ) * 0.5;
+     CLy [3] = psO->dfYMax;
+     
+     CLst[0] = 0;   CLst[1] = 2; 
+     CLstt[0] = SHPP_RING; CLstt[1] = SHPP_RING;      
+     
+     CLine = SHPCreateObject ( SHPT_POINT, -1, 2, CLst, CLstt, 4,
+        	CLx, CLy, NULL, NULL ); 
+
+     /* with the H & V centrline compound object, intersect it with the OBJ	*/
+     psInt = SHPIntersect_2d ( CLine, psO );
+     /* return SHP type is lowest common dimensionality of the input types 	*/
+
+
+     /* find the longest linestring returned by the intersection			*/
+     ring_vtx = psInt->nVertices ;
+     for ( ring = (psInt->nParts - 1); ring >= 0; ring-- ) {
+       ring_nVertices = ring_vtx - psInt->panPartStart[ring];
+
+       rLen += RingLength_2d ( ring_nVertices, 
+     	(double*) &(psInt->padfX [psInt->panPartStart[ring]]), 
+     	(double*) &(psInt->padfY [psInt->panPartStart[ring]]) );
+ 
+       if ( rLen > rLenMax )  
+         { rLenMax = rLen;
+           rMpart = psInt->panPartStart[ring];
+         }
+       ring_vtx = psInt->panPartStart[ring];
+      } 
+
+     /* add the centerpoint of the longest ARC of the intersection to the	*/
+     /*	PIP list															*/
+     nPIP ++;
+     SfRealloc ( PIP, sizeof(double) * 2 * nPIP);
+     PIP[nPIP].x = (psInt ->padfX [rMpart] + psInt ->padfX [rMpart]) * 0.5;
+     PIP[nPIP].y = (psInt ->padfY [rMpart] + psInt ->padfY [rMpart]) * 0.5;
+     
+     SHPDestroyObject ( psO );
+     SHPDestroyObject ( CLine );
+     
+     /* does SHPCreateobject use preallocated memory or does it copy the 	*/
+     /* contents.  To be safe conditionally release CLx, CLy, CLst, CLstt	*/
+     if ( CLx )   free ( CLx );
+     if ( CLy )   free ( CLy );
+     if ( CLst )  free ( CLst );
+     if ( CLstt ) free ( CLstt );
+    }
+    
+  return ( PIP );
+}
+
+
+/* **************************************************************************
+ * SHPCentrd_2d
+ *
+ * Return the single mathematical / geometric centroid of a potentially 
+ * complex/compound SHPObject
+ *
+ * reject non area SHP Types
+ * 
+ * **************************************************************************/
+PT SHPCentrd_2d ( SHPObject *psCShape ) {
+    int		ring, ringPrev, ring_nVertices, rStart;
+    double	Area, ringArea;
+    PT		ringCentrd, C;
+    
+  
+   if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )
+   {
+       C.x = NAN;
+       C.y = NAN;
+       return C;
+   }
+
+#ifdef DEBUG
+	printf ("for Object with %d vtx, %d parts [ %d, %d] \n",
+		psCShape->nVertices, psCShape->nParts,
+		psCShape->panPartStart[0],psCShape->panPartStart[1]);
+#endif
+   
+   Area = 0;
+   C.x = 0.0;
+   C.y = 0.0;
+   
+   /* for each ring in compound / complex object calc the ring cntrd		*/
+   
+   ringPrev = psCShape->nVertices;
+   for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
+     rStart = psCShape->panPartStart[ring];
+     ring_nVertices = ringPrev - rStart;
+
+     RingCentroid_2d ( ring_nVertices, (double*) &(psCShape->padfX [rStart]), 
+     	(double*) &(psCShape->padfY [rStart]), &ringCentrd, &ringArea);  
+
+#ifdef DEBUG
+	printf ("(SHPCentrd_2d)  Ring %d, vtxs %d, area: %f, ring centrd %f, %f \n",
+		ring, ring_nVertices, ringArea, ringCentrd.x, ringCentrd.y);
+#endif
+
+     /* use Superposition of these rings to build a composite Centroid		*/
+     /* sum the ring centrds * ringAreas,  at the end divide by total area	*/
+     C.x +=  ringCentrd.x * ringArea;
+     C.y +=  ringCentrd.y * ringArea; 
+     Area += ringArea; 
+     ringPrev = rStart;
+    }    
+
+     /* hold on the division by AREA until were at the end					*/
+     C.x = C.x / Area;
+     C.y = C.y / Area;
+#ifdef DEBUG
+	printf ("SHPCentrd_2d) Overall Area: %f, Centrd %f, %f \n",
+		Area, C.x, C.y);
+#endif   
+   return ( C );
+}
+
+
+/* **************************************************************************
+ * RingCentroid_2d
+ *
+ * Return the mathematical / geometric centroid of a single closed ring
+ *
+ * **************************************************************************/
+int RingCentroid_2d ( int nVertices, double *a, double *b, PT *C, double *Area ) {
+  int		iv;
+//  int       jv;
+//  int		sign_x, sign_y;
+  double	dx_Area, Cx_accum, Cy_accum, ppx, ppy;
+//  double    dy_Area;
+  double 	x_base, y_base, x, y;
+
+/* the centroid of a closed Ring is defined as
+ *
+ *      Cx = sum (cx * dArea ) / Total Area
+ *  and
+ *      Cy = sum (cy * dArea ) / Total Area
+ */      
+   
+  x_base = a[0];
+  y_base = b[0];
+  
+  Cy_accum = 0.0;
+  Cx_accum = 0.0;
+
+  ppx = a[1] - x_base;
+  ppy = b[1] - y_base;
+  *Area = 0;
+
+/* Skip the closing vector */
+  for ( iv = 2; iv <= nVertices - 2; iv++ ) {
+    x = a[iv] - x_base;
+    y = b[iv] - y_base;
+
+    /* calc the area and centroid of triangle built out of an arbitrary 	*/
+    /* base_point on the ring and each successive pair on the ring			*/
+    
+    /* Area of a triangle is the cross product of its defining vectors		*/
+    /* Centroid of a triangle is the average of its vertices				*/
+
+    dx_Area =  ((x * ppy) - (y * ppx)) * 0.5;
+    *Area += dx_Area;
+    
+    Cx_accum += ( ppx + x ) * dx_Area;       
+    Cy_accum += ( ppy + y ) * dx_Area;
+#ifdef DEBUG2
+    printf("(ringcentrd_2d)  Pp( %f, %f), P(%f, %f)\n", ppx, ppy, x, y);
+    printf("(ringcentrd_2d)    dA: %f, sA: %f, Cx: %f, Cy: %f \n", 
+		dx_Area, *Area, Cx_accum, Cy_accum);
+#endif    
+    ppx = x;
+    ppy = y;
+  }
+
+#ifdef DEBUG2
+  printf("(ringcentrd_2d)  Cx: %f, Cy: %f \n", 
+  	( Cx_accum / ( *Area * 3) ), ( Cy_accum / (*Area * 3) ));
+#endif
+
+  /* adjust back to world coords 											*/
+  C->x = ( Cx_accum / ( *Area * 3)) + x_base;
+  C->y = ( Cy_accum / ( *Area * 3)) + y_base;
+      
+  return ( 1 );
+}
+
+
+
+
+/* **************************************************************************
+ * SHPRingDir_2d
+ *
+ * Test Polygon for CW / CCW  ( R+ / R- )
+ *
+ * return 1  for R+
+ * return -1 for R-
+ * return 0  for error
+ * **************************************************************************/
+int SHPRingDir_2d ( SHPObject *psCShape, int Ring ) {
+   int      ti = 0;
+   int		i, last_vtx;
+   double	tX;
+   double 	*a, *b;
+   double	dx0, dx1, dy0, dy1, v3;
+//   double   v1, v2;
+   
+   tX = 0.0;
+   a = psCShape->padfX;
+   b = psCShape->padfY;
+   
+   if ( Ring >= psCShape->nParts ) return ( 0 );
+   
+   if ( Ring >= psCShape->nParts -1 )
+     { last_vtx = psCShape->nVertices; }
+    else
+     { last_vtx = psCShape->panPartStart[Ring + 1]; }
+      
+   /* All vertices at the corners of the extrema (rightmost lowest, leftmost lowest, 	*/
+   /* topmost rightest, ...) must be less than pi wide.  If they werent they couldnt be	*/
+   /* extrema.																			*/   
+   /* of course the following will fail if the Extents are even a little wrong 			*/      
+   
+   for ( i = psCShape->panPartStart[Ring]; i < last_vtx; i++ ) {
+     if ( b[i] == psCShape->dfYMax && a[i] > tX ) 
+      { ti = i; }
+   }
+
+#ifdef DEBUG2
+   printf ("(shpgeo:SHPRingDir) highest Rightmost Pt is vtx %d (%f, %f)\n", ti, a[ti], b[ti]);
+#endif   
+   
+   /* cross product */
+   /* the sign of the cross product of two vectors indicates the right or left half-plane	*/
+   /* which we can use to indicate Ring Dir													*/ 
+   if ( (ti > psCShape->panPartStart[Ring]) && (ti < last_vtx) ) 
+    { dx0 = a[ti-1] - a[ti];
+      dx1 = a[ti+1] - a[ti];
+      dy0 = b[ti-1] - b[ti];
+      dy1 = b[ti+1] - b[ti];
+   }
+   else
+   /* if the tested vertex is at the origin then continue from 0 */ 
+   {  dx1 = a[1] - a[0];
+      dx0 = a[last_vtx] - a[0];
+      dy1 = b[1] - b[0];
+      dy0 = b[last_vtx] - b[0];
+   }
+   
+//   v1 = ( (dy0 * 0) - (0 * dy1) );
+//   v2 = ( (0 * dx1) - (dx0 * 0) );
+/* these above are always zero so why do the math */
+   v3 = ( (dx0 * dy1) - (dx1 * dy0) );
+
+#ifdef DEBUG2   
+   printf ("(shpgeo:SHPRingDir)  cross product for vtx %d was %f \n", ti, v3); 
+#endif
+
+   if ( v3 > 0 )
+    { return (1); }
+   else
+    { return (-1); }
+}
+
+
+
+/* **************************************************************************
+ * SHPArea_2d
+ *
+ * Calculate the XY Area of Polygon ( can be compound / complex )
+ *
+ * **************************************************************************/
+double SHPArea_2d ( SHPObject *psCShape ) {
+    double 	cArea;
+    int		ring, ring_vtx, ring_nVertices;
+//    int     ringDir;
+  
+   cArea = 0;
+   if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )  
+       return ( -1 );
+ 
+ 
+   /* Walk each ring adding its signed Area,  R- will return a negative 	*/
+   /* area, so we don't have to test for them								*/
+
+   /* I just start at the last ring and work down to the first				*/
+   ring_vtx = psCShape->nVertices ;
+   for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
+     ring_nVertices = ring_vtx - psCShape->panPartStart[ring];
+
+#ifdef DEBUG2
+     printf("(shpgeo:SHPArea_2d) part %d, vtx %d \n", ring,  ring_nVertices);
+#endif    
+     cArea += RingArea_2d ( ring_nVertices, 
+     	(double*) &(psCShape->padfX [psCShape->panPartStart[ring]]), 
+     	(double*) &(psCShape->padfY [psCShape->panPartStart[ring]]) );
+
+     ring_vtx = psCShape->panPartStart[ring];
+    } 
+
+#ifdef DEBUG2
+    printf ("(shpgeo:SHPArea_2d) Area = %f \n", cArea);
+#endif
+
+    /* Area is signed, negative Areas are R-									*/    
+    return ( cArea );
+    
+}
+
+
+/* **************************************************************************
+ * SHPLength_2d
+ *
+ * Calculate the Planar ( XY ) Length of Polygon ( can be compound / complex )
+ *    or Polyline ( can be compound ).  Length on Polygon is its Perimeter
+ *
+ * **************************************************************************/
+double SHPLength_2d ( SHPObject *psCShape ) {
+    double 	Length;
+    int		i, j;
+    double 	dx, dy;
+    
+   if ( !(SHPDimension (psCShape->nSHPType) & (SHPD_AREA || SHPD_LINE)) )  
+       return ( (double) -1 );    
+    
+    Length = 0;
+    j = 1;
+    for ( i = 1; i < psCShape->nVertices; i++ ) {  
+      if ( psCShape->panPartStart[j] == i ) 
+       { j ++; }
+    /* skip the moves with "pen up" from ring to ring */       
+      else
+       { 
+        dx = psCShape->padfX[i] - psCShape->padfX[i-1];
+        dy = psCShape->padfY[i] - psCShape->padfY[i-1];
+        Length += sqrt ( ( dx * dx ) + ( dy * dy ) );
+       }
+     /* simplify this equation */
+     }
+     
+   return ( Length );
+}
+
+
+/* **************************************************************************
+ * RingLength_2d
+ *
+ * Calculate the Planar ( XY ) Length of Polygon ( can be compound / complex )
+ *    or Polyline ( can be compound ).  Length of Polygon is its Perimeter
+ *
+ * **************************************************************************/
+double RingLength_2d ( int nVertices, double *a, double *b ) {
+    double 	Length;
+    int		i, j;
+    double 	dx, dy;
+    
+    Length = 0;
+    j = 1;
+    for ( i = 1; i < nVertices; i++ ) {  
+      dx = a[i] - b[i-1];
+      dy = b[i] - b[i-1];
+      Length += sqrt ( ( dx * dx ) + ( dy * dy ) );
+     /* simplify this equation */
+     }
+     
+   return ( Length );
+}
+
+
+/* **************************************************************************
+ * RingArea_2d
+ *
+ * Calculate the Planar Area of a single closed ring 
+ *
+ * **************************************************************************/
+double RingArea_2d ( int nVertices, double *a, double *b ) {
+  int		iv;
+//  int       jv;
+  double	ppx, ppy;
+  static 	double	Area;
+  double	dx_Area;
+  double 	x_base, y_base, x, y;
+  
+  x_base = a[0];
+  y_base = b[0];
+  
+  ppx = a[1] - x_base;
+  ppy = b[1] - y_base;
+  Area = 0.0;
+#ifdef DEBUG2  
+  printf("(shpgeo:RingArea) %d vertices \n", nVertices);
+#endif  
+  for ( iv = 2; iv <= ( nVertices - 1 ); iv++ ) {
+    x = a[iv] - x_base;
+    y = b[iv] - y_base;
+
+    /* Area of a triangle is the cross product of its defining vectors		*/
+    
+    dx_Area = ((x * ppy) - (y * ppx)) * 0.5;
+
+    Area += dx_Area;
+#ifdef DEBUG2
+    printf ("(shpgeo:RingArea)  dxArea %f  sArea %f for pt(%f, %f)\n", 
+    		dx_Area, Area, x, y);
+#endif
+    		
+    ppx = x;
+    ppy = y;
+  }
+
+#ifdef DEBUG2
+  printf ("(shpgeo:RingArea)  total RingArea %f \n", Area);
+#endif  
+  return ( Area );
+
+}
+
+
+
+/* **************************************************************************
+ * SHPUnCompound
+ *
+ * ESRI calls this function explode
+ * Return a non compound ( possibly complex ) object
+ *
+ * ring_number is R+ number corresponding to object
+ *
+ *
+ * ignore complexity in Z dimension for now
+ *
+ * **************************************************************************/
+SHPObject* SHPUnCompound  ( SHPObject *psCShape, int * ringNumber ) {
+   int 		ringDir, ring, lRing;
+   
+   if ( (*ringNumber >= psCShape->nParts) || *ringNumber == -1 ) {
+ 	*ringNumber = -1;	
+	return (NULL);
+      }
+
+   
+   if ( *ringNumber == (psCShape->nParts - 1) )  {
+        *ringNumber =  -1;
+        return ( SHPClone(psCShape, (psCShape->nParts - 1), -1) );
+      }
+
+   lRing = *ringNumber;
+   ringDir = -1;
+   for ( ring = (lRing + 1); (ring < psCShape->nParts) && ( ringDir < 0 ); ring ++)
+     ringDir = SHPRingDir_2d ( psCShape, ring);
+   
+   if ( ring ==  psCShape->nParts )
+     *ringNumber = -1; 
+   else
+     *ringNumber = ring;
+/*    I am strictly assuming that all R- parts of a complex object 
+ *	   directly follow their R+, so when we hit a new R+ its a
+ *	   new part of a compound object
+ *         a SHPClean may be needed to enforce this as it is not part
+ *	   of ESRI's definition of a SHPfile
+ */
+
+#ifdef DEBUG2    
+    printf ("(SHPUnCompound) asked for ring %d, lastring is %d \n", lRing, ring);
+#endif
+    return ( SHPClone(psCShape, lRing, ring ) );
+
+}
+
+
+/* **************************************************************************
+ * SHPIntersect_2d
+ *
+ * 
+ * prototype only for now
+ *
+ * return object with lowest common dimensionality of objects
+ * 
+ * **************************************************************************/ 
+SHPObject* SHPIntersect_2d ( SHPObject* a, SHPObject* b ) {
+  SHPObject	*C;
+  
+  if ( (SHPDimension(a->nSHPType) && SHPD_POINT) || ( SHPDimension(b->nSHPType) && SHPD_POINT ) )
+    return ( NULL );
+  /* there is no intersect function like this for points  */
+    
+  C = SHPClone ( a, 0 , -1 );
+
+  return ( C);
+
+}
+
+
+
+/* **************************************************************************
+ * SHPClean
+ *
+ * Test and fix normalization problems in shapes
+ * Different tests need to be implemented for different SHPTypes
+ * 	SHPT_POLYGON	check ring directions CW / CCW   ( R+ / R- )
+ *				put all R- after the R+ they are members of
+ *				i.e. each complex object is completed before the
+ *     				next object is started
+ *				check for closed rings
+ *				ring must not intersect itself, even on edge
+ *
+ *  no other types implemented yet
+ * 
+ * not sure why but return object in place
+ * use for object casting and object verification						 
+ * **************************************************************************/ 
+int SHPClean ( SHPObject *psCShape ) {
+
+
+    return (0);
+}
+
+
+/* **************************************************************************
+ * SHPClone
+ *
+ * Clone a SHPObject, replicating all data
+ * 
+ * **************************************************************************/ 
+SHPObject* SHPClone ( SHPObject *psCShape, int lowPart, int highPart ) {
+    SHPObject	*psObject;
+    int		newParts, newVertices;
+#ifdef DEBUG
+    int     	i;
+#endif
+
+    if ( highPart >= psCShape->nParts || highPart == -1 )
+	highPart = psCShape->nParts ;
+
+#ifdef DEBUG
+    printf (" cloning SHP (%d parts) from ring %d upto ring %d \n",
+	 psCShape->nParts, lowPart, highPart);
+#endif
+
+    newParts = highPart - lowPart;
+    if ( newParts == 0 ) { return ( NULL ); }
+    
+    psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
+    psObject->nSHPType = psCShape->nSHPType;
+    psObject->nShapeId = psCShape->nShapeId;
+    
+    psObject->nParts = newParts;
+    if ( psCShape->padfX ) {
+        psObject->panPartStart = (int*) calloc (newParts, sizeof (int)); 
+        memcpy ( psObject->panPartStart, psCShape->panPartStart, 
+      		newParts * sizeof (int) );
+     }
+    if ( psCShape->padfX ) {
+      psObject->panPartType = (int*) calloc (newParts, sizeof (int)); 
+      memcpy ( psObject->panPartType, 
+  		(int *) &(psCShape->panPartType[lowPart]), 
+      		newParts * sizeof (int) );
+     }
+
+    if ( highPart != psCShape->nParts ) {
+      newVertices = psCShape->panPartStart[highPart] -
+	 psCShape->panPartStart[lowPart]; 
+     }
+    else 
+     { newVertices = psCShape->nVertices - psCShape->panPartStart[lowPart]; }
+
+
+#ifdef DEBUG
+    if ( highPart = psCShape->nParts ) 
+      i = psCShape->nVertices;
+     else
+      i = psCShape->panPartStart[highPart];
+    printf (" from part %d (%d) to %d (%d) is %d vertices \n",
+	 lowPart, psCShape->panPartStart[lowPart], highPart,
+	 i, newVertices);
+#endif
+    psObject->nVertices = newVertices;
+    if ( psCShape->padfX ) {
+      psObject->padfX = (double*) calloc (newVertices, sizeof (double)); 
+      memcpy ( psObject->padfX,
+	 (double *) &(psCShape->padfX[psCShape->panPartStart[lowPart]]),
+      		newVertices * sizeof (double) );
+     } 
+    if ( psCShape->padfY ) {
+      psObject->padfY = (double*) calloc (newVertices, sizeof (double)); 
+      memcpy ( psObject->padfY, 
+	 (double *) &(psCShape->padfY[psCShape->panPartStart[lowPart]]),
+      		newVertices * sizeof (double) );
+     }
+    if ( psCShape->padfZ ) {
+      psObject->padfZ = (double*) calloc (newVertices, sizeof (double)); 
+      memcpy ( psObject->padfZ, 
+	 (double *) &(psCShape->padfZ[psCShape->panPartStart[lowPart]]),
+      		newVertices * sizeof (double) );
+     }
+    if ( psCShape->padfM ) {
+      psObject->padfM = (double*) calloc (newVertices, sizeof (double)); 
+      memcpy ( psObject->padfM,
+	(double *) &(psCShape->padfM[psCShape->panPartStart[lowPart]]),
+      		newVertices * sizeof (double) );
+     }
+
+    psObject->dfXMin = psCShape->dfXMin;
+    psObject->dfYMin = psCShape->dfYMin;
+    psObject->dfZMin = psCShape->dfZMin;
+    psObject->dfMMin = psCShape->dfMMin;
+
+    psObject->dfXMax = psCShape->dfXMax;
+    psObject->dfYMax = psCShape->dfYMax;
+    psObject->dfZMax = psCShape->dfZMax;
+    psObject->dfMMax = psCShape->dfMMax;
+
+    SHPComputeExtents ( psObject );
+    return ( psObject );
+}
+
+
+
+/************************************************************************/
+/*  SwapG 							                              	*/
+/*                                                                      */
+/*      Swap a 2, 4 or 8 byte word.                                     */
+/************************************************************************/
+void SwapG( void *so, void *in, int this_cnt, int this_size ) {
+    int		i, j;
+//    unsigned char	temp;
+
+/* return to a new pointer otherwise it would invalidate existing data	*/
+/* as prevent further use of it											*/
+
+    for( j=0; j < this_cnt; j++ )
+     {
+      for( i=0; i < this_size/2; i++ )
+      {
+	((unsigned char *) so)[i] = ((unsigned char *) in)[this_size-i-1];
+	((unsigned char *) so)[this_size-i-1] = ((unsigned char *) in)[i];
+      }
+    }
+}
+
+
+/* **************************************************************************
+ * SwapW
+ *
+ * change byte order on an array of 16 bit words
+ * need to change this over to shapelib, Frank Warmerdam's functions
+ *
+ * **************************************************************************/ 
+void swapW (void *so, unsigned char *in, long bytes) {
+  int i, j;
+  unsigned char map[4] = {3,2,1,0};
+  unsigned char *out;
+
+  out = so;
+  for (i=0; i <= (bytes/4); i++)
+   for (j=0; j < 4; j++)
+      out[(i*4)+map[j]] = in[(i*4)+j]; 
+}
+
+
+/* **************************************************************************
+ * SwapD
+ *
+ * change byte order on an array of (double) 32 bit words
+ * need to change this over to shapelib, Frank Warmerdam's functons
+ *
+ * **************************************************************************/ 
+void swapD (void *so, unsigned char *in, long bytes) {
+  int i, j;
+  unsigned char map[8] = {7,6,5,4,3,2,1,0};
+  unsigned char *out;
+
+  out = so;
+  for (i=0; i <= (bytes/8); i++)
+   for (j=0; j < 8; j++)
+      out[(i*8)+map[j]] = in[(i*8)+j]; 
+}
+
diff --git a/src/shapelib/contrib/shpgeo.h b/src/shapelib/contrib/shpgeo.h
new file mode 100644
index 0000000..92078ad
--- /dev/null
+++ b/src/shapelib/contrib/shpgeo.h
@@ -0,0 +1,177 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ * shpgeo.h
+ * 
+ * support for geometric and other additions to shapelib
+ *
+ *
+ * $Log: shpgeo.h,v $
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.3  2002/01/15 14:36:56  warmerda
+ * upgrade to use proj_api.h
+ *
+ * Revision 1.2  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ * 
+ */
+ 
+ 
+
+ /* I'm using some shorthand throughout this file
+ *      R+ is a Clockwise Ring and is the positive portion of an object
+ *      R- is a CounterClockwise Ring and is a hole in a R+
+ *      A complex object is one having at least one R-
+ *      A compound object is one having more than one R+
+ *	A simple object has one and only one element (R+ or R-)
+ *
+ *	The closed ring constraint is for polygons and assumed here
+ *	Arcs or LineStrings I am calling Rings (generically open or closed)
+ *	Point types are vertices or lists of vertices but not Rings
+ *
+ *   SHPT_POLYGON, SHPT_POLYGONZ, SHPT_POLYGONM and SHPT_MULTIPATCH
+ *   can have SHPObjects that are compound as well as complex
+ *  
+ *   SHP_POINT and its Z and M derivatives are strictly simple
+ *   MULTI_POINT, SHPT_ARC and their derivatives may be simple or compound
+ *
+ */
+
+
+#ifndef SHPGEO_H
+
+#define SHPGEO_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "proj_api.h"
+
+
+#define		SHPD_POINT	 		1
+#define		SHPD_LINE	 		2
+#define		SHPD_AREA			4
+#define 	SHPD_Z		 		8
+#define		SHPD_MEASURE		16
+
+
+/* move these into a ogis header file ogis.h */
+#define		OGIST_UNKNOWN			0
+#define		OGIST_POINT				1
+#define		OGIST_LINESTRING		2
+#define		OGIST_POLYGON			3
+#define		OGIST_MULTIPOINT		4
+#define		OGIST_MULTILINE			5
+#define		OGIST_MULTIPOLYGON		6
+#define		OGIST_GEOMCOLL			7
+
+typedef struct { int	StreamPos;
+		 int	NeedSwap;
+		 char	*wStream;	
+		} WKBStreamObj;
+		
+typedef struct { double x; double y; } PT;
+
+
+typedef struct { int		cParts;
+		 SHPObject	*SHPObj;
+	  	} SHPObjectList;
+
+
+#define   	LSB_ORDER  (int) 1
+
+
+extern char * asFileName ( const char *fil, char *ext );
+extern int 	SHPProject ( SHPObject *psCShape, 
+                             projPJ inproj, projPJ outproj );
+extern projPJ 	SHPSetProjection ( int param_cnt, char **params );
+extern int 	SHPFreeProjection ( projPJ p);
+
+extern int 	SHPDimension ( int SHPType );
+
+extern double 	SHPArea_2d ( SHPObject *psCShape );
+extern int 	SHPRingDir_2d ( SHPObject *psCShape, int Ring );
+extern double 	SHPLength_2d ( SHPObject *psCShape );
+extern PT 	SHPCentrd_2d ( SHPObject *psCShape );
+extern PT	SHPPointinPoly_2d ( SHPObject *psCShape );
+extern PT*	SHPPointsinPoly_2d ( SHPObject *psCShape );
+
+extern int 	RingCentroid_2d ( int nVertices, double *a, double *b, PT *C, 
+	double *Area );
+extern double 	RingLength_2d ( int nVertices, double *a, double *b );
+extern int	RingDir_2d ( int nVertices, double *a, double *b );
+extern double 	RingArea_2d ( int nVertices, double *a, double *b );
+
+extern SHPObject* 	SHPClone ( SHPObject *psCShape, int lowPart, int highPart );
+extern SHPObject* 	SHPUnCompound  ( SHPObject *psCShape, int * ringNumber );
+extern SHPObject* 	SHPIntersect_2d ( SHPObject* a, SHPObject* b );
+
+extern int 	SHPWriteOGisWKB ( WKBStreamObj *stream_obj, SHPObject *psCShape );
+extern SHPObject*	SHPReadOGisWKB ( WKBStreamObj *stream_obj );
+
+int SHPWriteOGisPolygon ( WKBStreamObj *stream_obj, SHPObject *psCShape );
+int SHPWriteOGisLine ( WKBStreamObj *stream_obj, SHPObject *psCShape );
+int SHPWriteOGisPoint ( WKBStreamObj *stream_obj, SHPObject *psCShape );
+
+SHPObject* SHPReadOGisPolygon ( WKBStreamObj *stream_obj );
+SHPObject* SHPReadOGisLine ( WKBStreamObj *stream_obj );
+SHPObject* SHPReadOGisPoint ( WKBStreamObj *stream_obj );
+
+extern int 	SHPClean ( SHPObject *psCShape );
+extern int 	SHPOGisType ( int GeomType, int toOGis);
+
+void 	swapD (void *so, unsigned char *in, long bytes);
+void 	swapW (void *so, unsigned char *in, long bytes);
+void 	SwapG( void *so, void *in, int this_cnt, int this_size );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif   /* ndef SHPGEO_H	*/
diff --git a/src/shapelib/contrib/shpinfo.c b/src/shapelib/contrib/shpinfo.c
new file mode 100644
index 0000000..2885deb
--- /dev/null
+++ b/src/shapelib/contrib/shpinfo.c
@@ -0,0 +1,147 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * requires shapelib 1.2
+ *   gcc shpinfoj shpopen.o -o shpinfo
+ * 
+ *
+ * $Log: shpinfo.c,v $
+ * Revision 1.4  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:45:27  we7u
+ * Adding includes necessary for warning-free compiles.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.3  2002/04/15 21:33:03  warmerda
+ * Avoid dereference arrays.
+ *
+ * Revision 1.2  2002/04/15 18:40:31  warmerda
+ * Fixed size of adfBnds{Min,Max} as per bug from David Fowler.
+ *
+ * Revision 1.1  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ *
+ */
+
+#include "shapefil.h"
+#include <stdlib.h>
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP;
+//    SHPHandle   cSHP;
+    int		nShapeType, nEntities;
+//    int     nVertices, nParts, *panParts, i, iPart;
+    double	adfBndsMin[4], adfBndsMax[4];
+//    double  *padVertices;
+//    const char 	*pszPlus;
+//    int		cShapeType, cEntities, cVertices, cParts, *cpanParts, ci, cPart;
+//    double	*cpadVertices, cadBounds[4];
+//    const char 	*cpszPlus;
+    char	sType [15]= "";
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 2 )
+    {
+	printf( "shpinfo shp_file\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "rb" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, adfBndsMin, adfBndsMax );
+    
+    switch ( nShapeType ) {
+       case SHPT_POINT:
+		strcpy(sType,"Point");
+		break;
+
+       case SHPT_ARC:
+		strcpy(sType,"Polyline");
+		break;
+
+       case SHPT_POLYGON:
+		strcpy(sType,"Polygon");
+		break;
+
+       case SHPT_MULTIPOINT:
+		strcpy(sType,"MultiPoint");
+		break;
+        }
+
+/* -------------------------------------------------------------------- */
+   printf ("Info for %s\n",argv[1]);
+   printf ("%s(%d), %d Records in file\n",sType,nShapeType,nEntities);
+
+/* -------------------------------------------------------------------- */
+/*      Print out the file bounds.                                      */
+/* -------------------------------------------------------------------- */
+    printf( "File Bounds: (%15.10lg,%15.10lg)\n\t(%15.10lg,%15.10lg)\n",
+	    adfBndsMin[0], adfBndsMin[1], adfBndsMax[0], adfBndsMax[1] );
+
+
+
+    SHPClose( hSHP );
+    return(0);
+}
+
diff --git a/src/shapelib/contrib/shpproj.c b/src/shapelib/contrib/shpproj.c
new file mode 100644
index 0000000..229b073
--- /dev/null
+++ b/src/shapelib/contrib/shpproj.c
@@ -0,0 +1,297 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * This code is based in part on the earlier work of Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *******************************************************************************
+ *
+ * requires shapelib 1.2
+ *   gcc shpproj ../shpopen.o ../dbfopen.o shpgeo.o -lm -lproj -o shpproj
+ * 
+ * this requires linking with the PROJ4.3 projection library available from
+ *
+ * ftp://kai.er.usgs.gov/ftp/PROJ.4
+ *
+ *
+ * SHPGeo must be compiled with -DPROJ4 support
+ *
+ * $Log: shpproj.c,v $
+ * Revision 1.5  2010/07/11 20:30:00  we7u
+ * More minor tweaks to get rid of compiler warnings.  Of particular note are
+ * some TODO entries added to a couple of files for two enumerated values that
+ * weren't being handled in "switch" statements.  There still isn't any code
+ * for those case statements, but the compiler warnings are gone.
+ *
+ * Revision 1.4  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:45:27  we7u
+ * Adding includes necessary for warning-free compiles.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.9  2002/01/15 14:37:08  warmerda
+ * upgrade to use proj_api.h
+ *
+ * Revision 1.8  2002/01/11 15:47:26  warmerda
+ * several fixes
+ *
+ * Revision 1.7  2002/01/11 15:23:28  warmerda
+ * use text mode reading and writing .prj files
+ *
+ * Revision 1.6  1999/05/26 02:56:31  candrsn
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
+ *
+ * Revision 1.2  1999/05/13 19:30:52  warmerda
+ * Removed libgen.h, added url for PROJ.4, and corrected unsafe return of
+ * local variable in asFileName().
+ *
+ */
+
+
+#include "shapefil.h"
+#include "shpgeo.h"
+#include <stdarg.h>
+#include <string.h>
+
+int main( int argc, char ** argv )
+{
+    SHPHandle	old_SHP, new_SHP;
+    DBFHandle   old_DBF, new_DBF;
+    int		nShapeType, nEntities, i;
+    unsigned int j;
+//    int     nVertices, nParts *panParts, iPart;
+//    double	*padVertices, adBounds[4];
+//    const char 	*pszPlus;
+//    DBFFieldType  idfld_type;
+    SHPObject	*psCShape;
+    FILE	*ifp = NULL;
+//    int		idfld, nflds;
+//    char	kv[257] = "";
+//    char	idfldName[120] = "";
+//    char	fldName[120] = "";
+//    char	shpFileName[120] = "";
+//    char	dbfFileName[120] = "";
+    char	prjFileName[120] = "";
+    char	parg[80];
+//    double	apeture[4];
+    int		inarg, outarg;
+    char	*DBFRow = NULL;
+
+/* for testing only 
+    char	*in_args[] = { "init=nad83:1002", "units=us-ft" };
+    char	*out_args[] = { "proj=utm", "zone=16", "units=m" };
+*/
+
+    char	*in_args[16];
+    char	*out_args[16];
+    int		in_argc = 0 , out_argc = 0, outf_arg;
+    char	*arglst;
+    projPJ	orig_prj, new_prj;
+//    va_list	myargs, moargs;
+
+    if( argc < 4)
+    {
+	printf( "shpproj shp_file new_shp ( -i=in_proj_file | -i=\"in_params\" | -i=geographic ) ( -o=out_info_file | -o=\"out_params\" | -o=geographic ) \n" );
+	exit( 1 );
+    }
+
+    old_SHP = SHPOpen( argv[1], "rb" );
+    old_DBF = DBFOpen( argv[1], "rb" );
+    if( old_SHP == NULL || old_DBF == NULL )
+    {
+	printf( "Unable to open old files:%s\n", argv[1] );
+	exit( 1 );
+    }
+    
+   outf_arg = 2;
+   inarg = 0;
+   outarg = 0;
+   for ( i = 3; i < argc; i++ ) {
+     if ( !strncmp ("-i=", argv[i], 3 ))  inarg = i;
+     if ( !strncmp ("-o=", argv[i], 3 ))  outarg = i;
+    }
+
+
+/* if shapefile has a prj component then use that 
+   else try for a file then read args as list */
+
+    if( inarg == 0 )
+    {
+        strcpy( prjFileName, argv[1] );
+        ifp = fopen( asFileName ( prjFileName, "prj" ),"rt");
+    }
+    else
+    {
+        ifp = fopen( asFileName ( argv[inarg] + 3, "prj" ),"rt");
+    }
+
+    i = 0;
+    if ( ifp ) {
+        if( inarg == 0 )
+            printf ("using default file proj params from <- %s\n",
+                    asFileName ( prjFileName, "prj"  ) );
+        else
+            printf ("using file proj params from <- %s\n",
+                    asFileName ( argv[inarg] + 3, "prj" ) );
+
+       while( fscanf( ifp, "%s", parg) != EOF ) {
+         in_args[i] = malloc ( strlen(parg)+1 );
+         strcpy ( in_args[i], parg);
+         i++;
+       }
+
+       in_argc = i;
+       fclose (ifp);
+      }
+     else {
+      if ( inarg > 0 ) {
+       arglst = argv[inarg] + 3;
+       j = 0;
+       i = 0;
+       while ( j < strlen (arglst) ) {    
+         in_argc += sscanf ( arglst + j, "%s", parg);
+        
+         in_args[i] = malloc( strlen (parg)+1); 
+         strcpy (in_args[i], parg);
+         i++;
+         j += strlen (parg) +1;
+         if ( arglst[j] + 1 == 0 ) j = strlen (argv[inarg]);  
+       }
+      }
+     }  
+
+    i = 0;
+    if ( outarg > 0 ) ifp = fopen( asFileName ( argv[outarg] + 3, "prj" ),"rt");   
+    if ( ifp ) {
+       while( fscanf( ifp, "%s", parg) != EOF ) {
+         out_args[i] = malloc ( strlen(parg));
+         strcpy ( out_args[i], parg);
+         i++;
+       }
+       out_argc = i;
+       fclose (ifp);
+     }
+     else {
+      if ( outarg > 0 ) {
+       arglst = argv[outarg] + 3;
+       j = 0;
+       i = 0;
+       while ( j < strlen (arglst) ) {    
+         out_argc += sscanf ( arglst + j, "%s", parg);
+         
+         out_args[i] = malloc( strlen (parg)+1); 
+         strcpy (out_args[i], parg);
+         i++;
+         j += strlen (parg) +1;
+         if ( arglst[j] + 1 == 0 ) j = strlen (argv[outarg]);  
+       }
+      }
+    }       
+    
+    if ( !strcmp( argv[inarg], "-i=geographic" )) in_argc = 0;
+    if ( !strcmp( argv[outarg], "-o=geographic" )) out_argc = 0;
+    
+    orig_prj = SHPSetProjection ( in_argc, in_args );
+    new_prj = SHPSetProjection ( out_argc, out_args );
+
+    if ( !(( (!in_argc) || orig_prj) && ( (!out_argc) || new_prj) )) { 
+      fprintf (stderr, "unable to process projection, exiting...\n");
+      exit(1);
+    }   
+
+
+    SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL);
+    new_SHP = SHPCreate ( argv[outf_arg], nShapeType ); 
+    
+    new_DBF = DBFCloneEmpty (old_DBF, argv[outf_arg]);
+    if( new_SHP == NULL || new_DBF == NULL )
+    {
+	printf( "Unable to create new files:%s\n", argv[outf_arg] );
+	exit( 1 );
+    }
+
+    DBFRow = (char *) malloc ( (old_DBF->nRecordLength) + 15 );
+     
+    for( i = 0; i < nEntities; i++ )
+    {
+//	int		j;
+
+	psCShape = SHPReadObject ( old_SHP, i );
+
+	SHPProject (psCShape, orig_prj, new_prj );
+
+	SHPWriteObject ( new_SHP, -1, psCShape );   
+	SHPDestroyObject ( psCShape );
+
+        memcpy ( DBFRow, DBFReadTuple ( old_DBF, i ), old_DBF->nRecordLength );
+        DBFWriteTuple ( new_DBF, new_DBF->nRecords, DBFRow );
+
+    }
+
+    SHPFreeProjection ( orig_prj );
+    SHPFreeProjection ( new_prj );
+
+    /* store projection params into prj file */
+    ifp = fopen( asFileName ( argv[outf_arg], "prj" ),"wt");   
+    if ( ifp ) {
+
+       if ( out_argc == 0 ) 
+        { fprintf( ifp, "proj=geographic\n" ); }
+       else
+        { for ( i = 0; i < out_argc; i++ )
+           fprintf( ifp, "%s\n", out_args[i]);
+        }
+       fclose (ifp);
+    }
+    
+    SHPClose( old_SHP );
+    SHPClose( new_SHP );
+    DBFClose( old_DBF );
+    DBFClose( new_DBF );
+    printf ("\n");
+    return(0);
+}
+
+
diff --git a/src/shapelib/contrib/shpwkb.c b/src/shapelib/contrib/shpwkb.c
new file mode 100644
index 0000000..977a562
--- /dev/null
+++ b/src/shapelib/contrib/shpwkb.c
@@ -0,0 +1,160 @@
+/******************************************************************************
+ * Copyright (c) 1999, Carl Anderson
+ *
+ * this code is based in part on the earlier work of Frank Warmerdam
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * shpwkb.c  - test WKB binary Input / Output
+ *
+ *
+ * $Log: shpwkb.c,v $
+ * Revision 1.3  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.2  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.1  1999/05/26 02:29:36  candrsn
+ * OGis Well Known Binary test program (output only)
+ *
+ *
+ * 
+ */
+
+#include "shapefil.h"
+#include "shpgeo.h"
+
+int main( int argc, char ** argv )
+{
+    SHPHandle	old_SHP;
+//    SHPHandle   new_SHP;
+    DBFHandle   old_DBF;
+//    DBFHandle   new_DBF;
+    int		nShapeType, nEntities, i;
+//    int     nVertices, nParts, *panParts, iPart;
+//    double	*padVertices, adBounds[4];
+//    const char 	*pszPlus;
+//    DBFFieldType  idfld_type;
+//    int		idfld, nflds;
+//    char	kv[257] = "";
+//    char	idfldName[120] = "";
+//    char	fldName[120] = "";
+//    char	shpFileName[120] = "";
+//    char	dbfFileName[120] = "";
+//    char	*DBFRow = NULL;
+//    int		Cpan[2] = { 0,0 };
+    int		byRing = 0;
+//    PT		oCentrd, ringCentrd;
+    SHPObject	*psCShape;
+//    SHPObject   *cent_pt;
+//    double	oArea = 0.0, oLen = 0.0;
+    WKBStreamObj *wkbObj = NULL;
+    FILE	*wkb_file = NULL;
+
+    if( argc < 3 )
+    {
+	printf( "shpwkb shp_file wkb_file\n" );
+	exit( 1 );
+    }
+    
+    old_SHP = SHPOpen (argv[1], "rb" );
+    old_DBF = DBFOpen (argv[1], "rb");
+    if( old_SHP == NULL || old_DBF == NULL )
+    {
+	printf( "Unable to open old files:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    wkb_file = fopen ( argv[2], "wb");
+    wkbObj = calloc ( 3, sizeof (int) );
+    
+    SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL );
+    for( i = 0; i < nEntities; i++ )
+    {
+	int		res ;
+
+	psCShape = SHPReadObject( old_SHP, i );
+
+        if ( byRing == 1 ) {
+          int 	   ring, prevStart;
+//          int      ringDir;
+//          double   ringArea;
+
+          prevStart = psCShape->nVertices;
+          for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
+	    SHPObject 	*psO;
+	    int		numVtx, rStart;
+//        int     j;
+            
+            rStart = psCShape->panPartStart[ring];
+            if ( ring == (psCShape->nParts -1) )
+              { numVtx = psCShape->nVertices - rStart; }
+             else
+              { numVtx = psCShape->panPartStart[ring+1] - rStart; }
+              
+            printf ("(shpdata) Ring(%d) (%d for %d) \n", ring, rStart, numVtx);              
+	    psO = SHPClone ( psCShape, ring,  ring + 1 );
+
+	    SHPDestroyObject ( psO );
+            printf ("(shpdata) End Ring \n");
+           }  /* (ring) [0,nParts  */
+
+          }  /* by ring   */
+	   
+	   printf ("gonna build a wkb \n");
+	   res = SHPWriteOGisWKB ( wkbObj, psCShape );
+	   printf ("gonna write a wkb that is %d bytes long \n", wkbObj->StreamPos );	   
+	   fwrite ( (void*) wkbObj->wStream, 1, wkbObj->StreamPos, wkb_file );
+    }
+
+
+    free ( wkbObj );
+    SHPClose( old_SHP );
+    DBFClose( old_DBF );
+    if ( wkb_file )  fclose ( wkb_file );
+
+    printf ("\n");
+    return(0);
+}
+
diff --git a/src/shapelib/dbf_api.html b/src/shapelib/dbf_api.html
new file mode 100644
index 0000000..b0fa373
--- /dev/null
+++ b/src/shapelib/dbf_api.html
@@ -0,0 +1,408 @@
+<html>
+<head>
+<title>Attribute (.DBF) API</title>
+</head>
+<body>
+<h1>Attribute (.DBF) API</h1>
+
+The Attribute (DBF) API uses DBFHandle to represent a handle for access
+to one .dbf file.  The contents of the DBFHandle are visible (see shapefil.h)
+but should be ignored by the application.  It is intended that all information
+be accessed by API functions.  Note that there should be exactly one record
+in the .dbf file for each shape in the .shp/.shx files.  This constraint
+must be maintained by the application.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFOpen()</h2>
+
+<pre>
+DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess );
+
+  pszDBFFile:		The name of the xBase (.dbf) file to access.
+
+  pszAccess:		The fopen() style access string.  At this time only
+			"rb" (read-only binary) and "rb+" (read/write binary) 
+		        should be used.
+</pre>
+
+  The DBFOpen() function should be used to establish access to an existing
+  xBase format table file.  The returned DBFHandle is passed to other 
+  access functions, and DBFClose() should be invoked to recover resources, and 
+  flush changes to disk when complete.  The DBFCreate() function should
+  called to create new xBase files.  As a convenience, DBFOpen() can be
+  called with the name of a .shp or .shx file, and it will figure out the
+  name of the related .dbf file.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFCreate()</h2>
+
+<pre>
+DBFHandle DBFCreate( const char * pszDBFFile );
+
+  pszDBFFile:		The name of the xBase (.dbf) file to create.
+</pre>
+  
+  The DBFCreate() function creates a new xBase format file with the given 
+  name, and returns an access handle that can be used with other DBF functions.
+  The newly created file will have no fields, and no records.  Fields should
+  be added with DBFAddField() before any records add written.
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFGetFieldCount()</h2>
+
+<pre>
+int DBFGetFieldCount( DBFHandle hDBF );
+
+  hDBF:		The access handle for the file to be queried, as returned
+                by DBFOpen(), or DBFCreate().
+</pre>
+
+  The DBFGetFieldCount() function returns the number of fields currently
+  defined for the indicated xBase file.
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFGetRecordCount()</h2>
+
+<pre>
+int DBFGetRecordCount( DBFHandle hDBF );
+
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+</pre>
+
+  The DBFGetRecordCount() function returns the number of records that
+  exist on the xBase file currently.  Note that with shape files one xBase
+  record exists for each shape in the .shp/.shx files.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFGetFieldIndex()</h2>
+
+<pre>
+int DBFGetFieldIndex( DBFHandle hDBF, const char *pszFieldName );
+
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+
+  pszFieldName: Name of the field to search for.
+</pre>
+
+  Returns the index of the field matching this name, or -1 on failure.  The
+  comparison is case insensitive.  However, lengths must match exactly.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFGetFieldInfo()</h2>
+
+<pre>
+DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
+                              int * pnWidth, int * pnDecimals );
+
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iField:	The field to be queried.  This should be a number between 
+                0 and n-1, where n is the number fields on the file, as
+                returned by DBFGetFieldCount().
+
+  pszFieldName:	If this pointer is not NULL the name of the requested field
+		will be written to this location.  The pszFieldName buffer 
+                should be at least 12 character is size in order to hold
+		the longest possible field name of 11 characters plus a 
+                terminating zero character.
+
+  pnWidth:	If this pointer is not NULL, the width of the requested field
+		will be returned in the int pointed to by pnWidth.  This is
+                the width in characters.  
+
+  pnDecimals:	If this pointer is not NULL, the number of decimal places
+                precision defined for the field will be returned.  This is
+                zero for integer fields, or non-numeric fields.
+</pre>
+
+  The DBFGetFieldInfo() returns the type of the requested field, which is
+  one of the DBFFieldType enumerated values.  As well, the field name, and
+  field width information can optionally be returned.  The field type returned
+  does not correspond one to one with the xBase field types.  For instance
+  the xBase field type for Date will just be returned as being FTInteger.  <p>
+
+<pre>
+    typedef enum {
+      FTString,			/* fixed length string field 		*/
+      FTInteger,		/* numeric field with no decimals 	*/
+      FTDouble,			/* numeric field with decimals 		*/
+      FTLogical,		/* logical field.                       */
+      FTInvalid                 /* not a recognised field type 		*/
+    } DBFFieldType;
+</pre>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFAddField()</h2>
+
+<pre>
+int DBFAddField( DBFHandle hDBF, const char * pszFieldName, 
+                 DBFFieldType eType, int nWidth, int nDecimals );
+
+  hDBF:		The access handle for the file to be updated, as returned by
+		DBFOpen(), or DBFCreate().
+
+  pszFieldName:	The name of the new field.  At most 11 character will be used.
+                In order to use the xBase file in some packages it may be
+                necessary to avoid some special characters in the field names
+                such as spaces, or arithmetic operators.
+
+  eType:	One of FTString, FTInteger or FTDouble in order to establish
+                the type of the new field.  Note that some valid xBase field
+                types cannot be created such as date fields.
+
+  nWidth:	The width of the field to be created.  For FTString fields this
+                establishes the maximum length of string that can be stored.
+                For FTInteger this establishes the number of digits of the
+                largest number that can
+                be represented.  For FTDouble fields this in combination
+                with the nDecimals value establish the size, and precision
+                of the created field.
+
+  nDecimals:    The number of decimal places to reserve for FTDouble fields.
+                For all other field types this should be zero.  For instance
+                with nWidth=7, and nDecimals=3 numbers would be formatted
+                similarly to `123.456'.
+</pre>
+
+  The DBFAddField() function is used to add new fields to an existing xBase
+  file opened with DBFOpen(), or created with DBFCreate().  Note that fields
+  can only be added to xBase files with no records, though this is limitation
+  of this API, not of the file format.<p>
+
+  The DBFAddField() return value is the field number of the new field, or
+  -1 if the addition of the field failed.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFReadIntegerAttribute()</h2>
+
+<pre>
+int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
+  
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) from which the field value
+                should be read.
+
+  iField:	The field within the selected record that should be read.
+</pre>
+
+  The DBFReadIntegerAttribute() will read the value of one field and return
+  it as an integer.  This can be used even with FTString fields, though the
+  returned value will be zero if not interpretable as a number.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFReadDoubleAttribute()</h2>
+
+<pre>
+double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
+  
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) from which the field value
+                should be read.
+
+  iField:	The field within the selected record that should be read.
+</pre>
+
+  The DBFReadDoubleAttribute() will read the value of one field and return
+  it as a double.  This can be used even with FTString fields, though the
+  returned value will be zero if not interpretable as a number.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFReadStringAttribute()</h2>
+
+<pre>
+const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
+  
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) from which the field value
+                should be read.
+
+  iField:	The field within the selected record that should be read.
+</pre>
+
+  The DBFReadStringAttribute() will read the value of one field and return
+  it as a string.  This function may be used on any field type (including 
+  FTInteger and FTDouble) and will return the string representation stored
+  in the .dbf file.  The returned pointer is to an internal buffer
+  which is only valid untill the next DBF function call.  It's contents may
+  be copied with normal string functions such as strcpy(), or strdup().  If
+  the TRIM_DBF_WHITESPACE macro is defined in shapefil.h (it is by default)
+  then all leading and trailing space (ASCII 32) characters will be stripped
+  before the string is returned.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFIsAttributeNULL()</h2>
+
+<pre>
+int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
+  
+  hDBF:		The access handle for the file to be queried, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) from which the field value
+                should be read.
+
+  iField:	The field within the selected record that should be read.
+</pre>
+
+  This function will return TRUE if the indicated field is NULL valued
+  otherwise FALSE.  Note that NULL fields are represented in the .dbf file
+  as having all spaces in the field.  Reading NULL fields will result in
+  a value of 0.0 or an empty string with the other DBFRead*Attribute() 
+  functions.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFWriteIntegerAttribute</h2>
+
+<pre>
+int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
+                              int nFieldValue );
+
+  hDBF:		The access handle for the file to be written, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) to which the field value
+                should be written.
+
+  iField:	The field within the selected record that should be written.
+
+  nFieldValue:	The integer value that should be written.
+</pre>
+
+The DBFWriteIntegerAttribute() function is used to write a value to a numeric
+field (FTInteger, or FTDouble).  If the write succeeds the value TRUE will
+be returned, otherwise FALSE will be returned.  If the value is too large to 
+fit in the field, it will be truncated and FALSE returned.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFWriteDoubleAttribute()</h2>
+
+<pre>
+int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
+                             double dFieldValue );
+
+  hDBF:		The access handle for the file to be written, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) to which the field value
+                should be written.
+
+  iField:	The field within the selected record that should be written.
+
+  dFieldValue:	The floating point value that should be written.
+</pre>
+
+The DBFWriteDoubleAttribute() function is used to write a value to a numeric
+field (FTInteger, or FTDouble).  If the write succeeds the value TRUE will
+be returned, otherwise FALSE will be returned.  If the value is too large to 
+fit in the field, it will be truncated and FALSE returned.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFWriteStringAttribute()</h2>
+
+<pre>
+int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
+                             const char * pszFieldValue );
+
+  hDBF:		The access handle for the file to be written, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) to which the field value
+                should be written.
+
+  iField:	The field within the selected record that should be written.
+
+  pszFieldValue: The string to be written to the field.
+</pre>
+
+The DBFWriteStringAttribute() function is used to write a value to a string
+field (FString).  If the write succeeds the value TRUE willbe returned, 
+otherwise FALSE will be returned.  If the value is too large to 
+fit in the field, it will be truncated and FALSE returned.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFWriteNULLAttribute()</h2>
+
+<pre>
+int DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
+
+  hDBF:		The access handle for the file to be written, as returned by
+		DBFOpen(), or DBFCreate().
+
+  iShape:	The record number (shape number) to which the field value
+                should be written.
+
+  iField:	The field within the selected record that should be written.
+</pre>
+
+The DBFWriteNULLAttribute() function is used to clear the indicated field
+to a NULL value.  In the .dbf file this is represented by setting the entire
+field to spaces.  If the write succeeds the value TRUE willbe returned, 
+otherwise FALSE will be returned.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFClose()</h2>
+
+<pre>
+void DBFClose( DBFHandle hDBF );
+
+  hDBF:		The access handle for the file to be closed.
+</pre>
+
+  The DBFClose() function will close the indicated xBase file (opened with
+  DBFOpen(), or DBFCreate()), flushing out all information to the file on
+  disk, and recovering any resources associated with having the file open.
+  The file handle (hDBF) should not be used again with the DBF API after
+  calling DBFClose().<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>DBFGetNativeFieldType()</h2>
+
+<pre>
+char DBFGetNativeFieldType( DBFHandle hDBF, int iField );
+
+  hDBF:		The access handle for the file.
+  iField:       The field index to query.
+  
+</pre>
+
+  This function returns the DBF type code of the indicated field. It will
+  be one of:<p>
+
+<ul>
+<li> 'C' (String)
+<li> 'D' (Date)
+<li> 'F' (Float)
+<li> 'N' (Numeric, with or without decimal)
+<li> 'L' (Logical)
+<li> 'M' (Memo: 10 digits .DBT block ptr)
+<li> ' ' (field out of range)
+</ul>
+
+</body>
+</html>
diff --git a/src/shapelib/dbfadd.c b/src/shapelib/dbfadd.c
new file mode 100644
index 0000000..2dd2b01
--- /dev/null
+++ b/src/shapelib/dbfadd.c
@@ -0,0 +1,151 @@
+/******************************************************************************
+ * $Id: dbfadd.c,v 1.3 2009/06/04 04:25:19 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Sample application for adding a record to an existing .dbf file.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: dbfadd.c,v $
+ * Revision 1.3  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.2  2009/06/03 22:24:19  we7u
+ * Adding includes for string.h to get rid of compiler warnings.
+ *
+ * Revision 1.1  2006/11/10 21:48:09  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.7  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.6  2001/05/31 18:15:40  warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.5  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.4  1998/12/03 16:36:06  warmerda
+ * Added stdlib.h and math.h to get atof() prototype.
+ *
+ * Revision 1.3  1995/10/21 03:13:23  warmerda
+ * Use binary mode..
+ *
+ * Revision 1.2  1995/08/04  03:15:59  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] =
+//    "$Id: dbfadd.c,v 1.3 2009/06/04 04:25:19 we7u Exp $";
+
+#include "shapefil.h"
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    DBFHandle	hDBF;
+    int		i, iRecord;
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc < 3 )
+    {
+	printf( "dbfadd xbase_file field_values\n" );
+
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Create the database.						*/
+/* -------------------------------------------------------------------- */
+    hDBF = DBFOpen( argv[1], "r+b" );
+    if( hDBF == NULL )
+    {
+	printf( "DBFOpen(%s,\"rb+\") failed.\n", argv[1] );
+	exit( 2 );
+    }
+    
+/* -------------------------------------------------------------------- */
+/*	Do we have the correct number of arguments?			*/
+/* -------------------------------------------------------------------- */
+    if( DBFGetFieldCount( hDBF ) != argc - 2 )
+    {
+	printf( "Got %d fields, but require %d\n",
+	        argc - 2, DBFGetFieldCount( hDBF ) );
+	exit( 3 );
+    }
+
+    iRecord = DBFGetRecordCount( hDBF );
+
+/* -------------------------------------------------------------------- */
+/*	Loop assigning the new field values.				*/
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
+    {
+        if( strcmp( argv[i+2], "" ) == 0 )
+            DBFWriteNULLAttribute(hDBF, iRecord, i );
+	else if( DBFGetFieldInfo( hDBF, i, NULL, NULL, NULL ) == FTString )
+	    DBFWriteStringAttribute(hDBF, iRecord, i, argv[i+2] );
+	else
+	    DBFWriteDoubleAttribute(hDBF, iRecord, i, atof(argv[i+2]) );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Close and cleanup.                                              */
+/* -------------------------------------------------------------------- */
+    DBFClose( hDBF );
+
+    return( 0 );
+}
diff --git a/src/shapelib/dbfcreate.c b/src/shapelib/dbfcreate.c
new file mode 100644
index 0000000..4cb21d0
--- /dev/null
+++ b/src/shapelib/dbfcreate.c
@@ -0,0 +1,150 @@
+/******************************************************************************
+ * $Id: dbfcreate.c,v 1.2 2009/06/04 04:25:19 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Sample application for creating a new .dbf file.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: dbfcreate.c,v $
+ * Revision 1.2  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.1  2006/11/10 21:48:09  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.6  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.5  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.4  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.3  1999/04/01 18:47:44  warmerda
+ * Fixed DBFAddField() call convention.
+ *
+ * Revision 1.2  1995/08/04 03:17:11  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] =
+//    "$Id: dbfcreate.c,v 1.2 2009/06/04 04:25:19 we7u Exp $";
+
+#include <stdlib.h>
+#include <string.h>
+#include "shapefil.h"
+
+int main( int argc, char ** argv )
+
+{
+    DBFHandle	hDBF;
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc < 2 )
+    {
+	printf( "dbfcreate xbase_file [[-s field_name width],[-n field_name width decimals]]...\n" );
+
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Create the database.						*/
+/* -------------------------------------------------------------------- */
+    hDBF = DBFCreate( argv[1] );
+    if( hDBF == NULL )
+    {
+	printf( "DBFCreate(%s) failed.\n", argv[1] );
+	exit( 2 );
+    }
+    
+/* -------------------------------------------------------------------- */
+/*	Loop over the field definitions adding new fields.	       	*/
+/* -------------------------------------------------------------------- */
+    for( i = 2; i < argc; i++ )
+    {
+	if( strcmp(argv[i],"-s") == 0 && i < argc-2 )
+	{
+	    if( DBFAddField( hDBF, argv[i+1], FTString, atoi(argv[i+2]), 0 )
+                == -1 )
+	    {
+		printf( "DBFAddField(%s,FTString,%d,0) failed.\n",
+		        argv[i+1], atoi(argv[i+2]) );
+		exit( 4 );
+	    }
+	    i = i + 2;
+	}
+	else if( strcmp(argv[i],"-n") == 0 && i < argc-3 )
+	{
+	    if( DBFAddField( hDBF, argv[i+1], FTDouble, atoi(argv[i+2]), 
+			      atoi(argv[i+3]) ) == -1 )
+	    {
+		printf( "DBFAddField(%s,FTDouble,%d,%d) failed.\n",
+		        argv[i+1], atoi(argv[i+2]), atoi(argv[i+3]) );
+		exit( 4 );
+	    }
+	    i = i + 3;
+	}
+	else
+	{
+	    printf( "Argument incomplete, or unrecognised:%s\n", argv[i] );
+	    exit( 3 );
+	}
+    }
+
+    DBFClose( hDBF );
+
+    return( 0 );
+}
diff --git a/src/shapelib/dbfdump.c b/src/shapelib/dbfdump.c
new file mode 100644
index 0000000..eba2fef
--- /dev/null
+++ b/src/shapelib/dbfdump.c
@@ -0,0 +1,305 @@
+/******************************************************************************
+ * $Id: dbfdump.c,v 1.3 2010/07/11 20:30:00 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Sample application for dumping .dbf files to the terminal.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: dbfdump.c,v $
+ * Revision 1.3  2010/07/11 20:30:00  we7u
+ * More minor tweaks to get rid of compiler warnings.  Of particular note are
+ * some TODO entries added to a couple of files for two enumerated values that
+ * weren't being handled in "switch" statements.  There still isn't any code
+ * for those case statements, but the compiler warnings are gone.
+ *
+ * Revision 1.2  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.1  2006/11/10 21:48:09  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.9  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.8  2001/05/31 18:15:40  warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.7  2000/09/20 13:13:55  warmerda
+ * added break after default:
+ *
+ * Revision 1.6  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.5  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.4  1998/12/31 15:30:13  warmerda
+ * Added -m, -r, and -h commandline options.
+ *
+ * Revision 1.3  1995/10/21 03:15:01  warmerda
+ * Changed to use binary file access.
+ *
+ * Revision 1.2  1995/08/04  03:16:22  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] = 
+//  "$Id: dbfdump.c,v 1.3 2010/07/11 20:30:00 we7u Exp $";
+
+#include <stdlib.h>
+#include <string.h>
+#include "shapefil.h"
+
+int main( int argc, char ** argv )
+
+{
+    DBFHandle	hDBF;
+    int		*panWidth, i, iRecord;
+    char	szFormat[32], *pszFilename = NULL;
+    int		nWidth, nDecimals;
+    int		bHeader = 0;
+    int		bRaw = 0;
+    int		bMultiLine = 0;
+    char	szTitle[12];
+
+/* -------------------------------------------------------------------- */
+/*      Handle arguments.                                               */
+/* -------------------------------------------------------------------- */
+    for( i = 1; i < argc; i++ )
+    {
+        if( strcmp(argv[i],"-h") == 0 )
+            bHeader = 1;
+        else if( strcmp(argv[i],"-r") == 0 )
+            bRaw = 1;
+        else if( strcmp(argv[i],"-m") == 0 )
+            bMultiLine = 1;
+        else
+            pszFilename = argv[i];
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( pszFilename == NULL )
+    {
+	printf( "dbfdump [-h] [-r] [-m] xbase_file\n" );
+        printf( "        -h: Write header info (field descriptions)\n" );
+        printf( "        -r: Write raw field info, numeric values not reformatted\n" );
+        printf( "        -m: Multiline, one line per field.\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the file.                                                  */
+/* -------------------------------------------------------------------- */
+    hDBF = DBFOpen( pszFilename, "rb" );
+    if( hDBF == NULL )
+    {
+	printf( "DBFOpen(%s,\"r\") failed.\n", argv[1] );
+	exit( 2 );
+    }
+    
+/* -------------------------------------------------------------------- */
+/*	If there is no data in this file let the user know.		*/
+/* -------------------------------------------------------------------- */
+    if( DBFGetFieldCount(hDBF) == 0 )
+    {
+	printf( "There are no fields in this table!\n" );
+	exit( 3 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Dump header definitions.					*/
+/* -------------------------------------------------------------------- */
+    if( bHeader )
+    {
+        for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
+        {
+            DBFFieldType	eType;
+            const char	 	*pszTypeName;
+
+            eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
+            if( eType == FTString )
+                pszTypeName = "String";
+            else if( eType == FTInteger )
+                pszTypeName = "Integer";
+            else if( eType == FTDouble )
+                pszTypeName = "Double";
+            else if( eType == FTInvalid )
+                pszTypeName = "Invalid";
+            else
+                pszTypeName = "Unknown";
+
+            printf( "Field %d: Type=%s, Title=`%s', Width=%d, Decimals=%d\n",
+                    i, pszTypeName, szTitle, nWidth, nDecimals );
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Compute offsets to use when printing each of the field 		*/
+/*	values. We make each field as wide as the field title+1, or 	*/
+/*	the field value + 1. 						*/
+/* -------------------------------------------------------------------- */
+    panWidth = (int *) malloc( DBFGetFieldCount( hDBF ) * sizeof(int) );
+
+    for( i = 0; i < DBFGetFieldCount(hDBF) && !bMultiLine; i++ )
+    {
+	DBFFieldType	eType;
+
+	eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
+	if( (int)strlen(szTitle) > nWidth )
+	    panWidth[i] = strlen(szTitle);
+	else
+	    panWidth[i] = nWidth;
+
+	if( eType == FTString )
+	    sprintf( szFormat, "%%-%ds ", panWidth[i] );
+	else
+	    sprintf( szFormat, "%%%ds ", panWidth[i] );
+	printf( szFormat, szTitle );
+    }
+    printf( "\n" );
+
+/* -------------------------------------------------------------------- */
+/*	Read all the records 						*/
+/* -------------------------------------------------------------------- */
+    for( iRecord = 0; iRecord < DBFGetRecordCount(hDBF); iRecord++ )
+    {
+        if( bMultiLine )
+            printf( "Record: %d\n", iRecord );
+        
+	for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
+	{
+            DBFFieldType	eType;
+            
+            eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals );
+
+            if( bMultiLine )
+            {
+                printf( "%s: ", szTitle );
+            }
+            
+/* -------------------------------------------------------------------- */
+/*      Print the record according to the type and formatting           */
+/*      information implicit in the DBF field description.              */
+/* -------------------------------------------------------------------- */
+            if( !bRaw )
+            {
+                if( DBFIsAttributeNULL( hDBF, iRecord, i ) )
+                {
+                    if( eType == FTString )
+                        sprintf( szFormat, "%%-%ds", nWidth );
+                    else
+                        sprintf( szFormat, "%%%ds", nWidth );
+
+                    printf( szFormat, "(NULL)" );
+                }
+                else
+                {
+                    switch( eType )
+                    {
+                      case FTString:
+                        sprintf( szFormat, "%%-%ds", nWidth );
+                        printf( szFormat, 
+                                DBFReadStringAttribute( hDBF, iRecord, i ) );
+                        break;
+                        
+                      case FTInteger:
+                        sprintf( szFormat, "%%%dd", nWidth );
+                        printf( szFormat, 
+                                DBFReadIntegerAttribute( hDBF, iRecord, i ) );
+                        break;
+                        
+                      case FTDouble:
+                        sprintf( szFormat, "%%%d.%dlf", nWidth, nDecimals );
+                        printf( szFormat, 
+                                DBFReadDoubleAttribute( hDBF, iRecord, i ) );
+                        break;
+                        
+                      default:
+                        break;
+                    }
+                }
+            }
+
+/* -------------------------------------------------------------------- */
+/*      Just dump in raw form (as formatted in the file).               */
+/* -------------------------------------------------------------------- */
+            else
+            {
+                sprintf( szFormat, "%%-%ds", nWidth );
+                printf( szFormat, 
+                        DBFReadStringAttribute( hDBF, iRecord, i ) );
+            }
+
+/* -------------------------------------------------------------------- */
+/*      Write out any extra spaces required to pad out the field        */
+/*      width.                                                          */
+/* -------------------------------------------------------------------- */
+	    if( !bMultiLine )
+	    {
+		sprintf( szFormat, "%%%ds", panWidth[i] - nWidth + 1 );
+		printf( szFormat, "" );
+	    }
+
+            if( bMultiLine )
+                printf( "\n" );
+
+	    fflush( stdout );
+	}
+	printf( "\n" );
+    }
+
+    DBFClose( hDBF );
+
+    return( 0 );
+}
diff --git a/src/shapelib/dbfopen.c b/src/shapelib/dbfopen.c
new file mode 100644
index 0000000..4de1e30
--- /dev/null
+++ b/src/shapelib/dbfopen.c
@@ -0,0 +1,1526 @@
+/******************************************************************************
+ * $Id: dbfopen.c,v 1.3 2006/11/14 21:30:18 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: dbfopen.c,v $
+ * Revision 1.3  2006/11/14 21:30:18  we7u
+ * The last revision also commented out an unused variable that I forgot to
+ * mention in the cvs log.
+ *
+ * Revision 1.2  2006/11/14 21:28:02  we7u
+ * Casting a couple of variables to int's to get rid of compiler warnings.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.48  2003/03/10 14:51:27  warmerda
+ * DBFWrite* calls now return FALSE if they have to truncate
+ *
+ * Revision 1.47  2002/11/20 03:32:22  warmerda
+ * Ensure field name in DBFGetFieldIndex() is properly terminated.
+ *
+ * Revision 1.46  2002/10/09 13:10:21  warmerda
+ * Added check that width is positive.
+ *
+ * Revision 1.45  2002/09/29 00:00:08  warmerda
+ * added FTLogical and logical attribute read/write calls
+ *
+ * Revision 1.44  2002/05/07 13:46:11  warmerda
+ * Added DBFWriteAttributeDirectly().
+ *
+ * Revision 1.43  2002/02/13 19:39:21  warmerda
+ * Fix casting issues in DBFCloneEmpty().
+ *
+ * Revision 1.42  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.41  2002/01/15 14:31:49  warmerda
+ * compute rather than copying nHeaderLength in DBFCloneEmpty()
+ *
+ * Revision 1.40  2002/01/09 04:32:35  warmerda
+ * fixed to read correct amount of header
+ *
+ * Revision 1.39  2001/12/11 22:41:03  warmerda
+ * improve io related error checking when reading header
+ *
+ * Revision 1.38  2001/11/28 16:07:31  warmerda
+ * Cleanup to avoid compiler warnings as suggested by Richard Hash.
+ *
+ * Revision 1.37  2001/07/04 05:18:09  warmerda
+ * do last fix properly
+ *
+ * Revision 1.36  2001/07/04 05:16:09  warmerda
+ * fixed fieldname comparison in DBFGetFieldIndex
+ *
+ * Revision 1.35  2001/06/22 02:10:06  warmerda
+ * fixed NULL shape support with help from Jim Matthews
+ *
+ * Revision 1.33  2001/05/31 19:20:13  warmerda
+ * added DBFGetFieldIndex()
+ *
+ * Revision 1.32  2001/05/31 18:15:40  warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.31  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.30  2000/12/05 14:43:38  warmerda
+ * DBReadAttribute() white space trimming bug fix
+ *
+ * Revision 1.29  2000/10/05 14:36:44  warmerda
+ * fix bug with writing very wide numeric fields
+ *
+ * Revision 1.28  2000/09/25 14:18:07  warmerda
+ * Added some casts of strlen() return result to fix warnings on some
+ * systems, as submitted by Daniel.
+ *
+ * Revision 1.27  2000/09/25 14:15:51  warmerda
+ * added DBFGetNativeFieldType()
+ *
+ * Revision 1.26  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.25  2000/05/29 18:19:13  warmerda
+ * avoid use of uchar, and adding casting fix
+ *
+ * Revision 1.24  2000/05/23 13:38:27  warmerda
+ * Added error checks on return results of fread() and fseek().
+ *
+ * Revision 1.23  2000/05/23 13:25:49  warmerda
+ * Avoid crashing if field or record are out of range in dbfread*attribute().
+ *
+ * Revision 1.22  1999/12/15 13:47:24  warmerda
+ * Added stdlib.h to ensure that atof() is prototyped.
+ *
+ * Revision 1.21  1999/12/13 17:25:46  warmerda
+ * Added support for upper case .DBF extention.
+ *
+ * Revision 1.20  1999/11/30 16:32:11  warmerda
+ * Use atof() instead of sscanf().
+ *
+ * Revision 1.19  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.18  1999/07/27 00:53:28  warmerda
+ * ensure that whole old field value clear on write of string
+ *
+ * Revision 1.1  1999/07/05 18:58:07  warmerda
+ * New
+ *
+ * Revision 1.17  1999/06/11 19:14:12  warmerda
+ * Fixed some memory leaks.
+ *
+ * Revision 1.16  1999/06/11 19:04:11  warmerda
+ * Remoted some unused variables.
+ *
+ * Revision 1.15  1999/05/11 03:19:28  warmerda
+ * added new Tuple api, and improved extension handling - add from candrsn
+ *
+ * Revision 1.14  1999/05/04 15:01:48  warmerda
+ * Added 'F' support.
+ *
+ * Revision 1.13  1999/03/23 17:38:59  warmerda
+ * DBFAddField() now actually does return the new field number, or -1 if
+ * it fails.
+ *
+ * Revision 1.12  1999/03/06 02:54:46  warmerda
+ * Added logic to convert shapefile name to dbf filename in DBFOpen()
+ * for convenience.
+ *
+ * Revision 1.11  1998/12/31 15:30:34  warmerda
+ * Improved the interchangability of numeric and string attributes.  Add
+ * white space trimming option for attributes.
+ *
+ * Revision 1.10  1998/12/03 16:36:44  warmerda
+ * Use r+b instead of rb+ for binary access.
+ *
+ * Revision 1.9  1998/12/03 15:34:23  warmerda
+ * Updated copyright message.
+ *
+ * Revision 1.8  1997/12/04 15:40:15  warmerda
+ * Added newline character after field definitions.
+ *
+ * Revision 1.7  1997/03/06 14:02:10  warmerda
+ * Ensure bUpdated is initialized.
+ *
+ * Revision 1.6  1996/02/12 04:54:41  warmerda
+ * Ensure that DBFWriteAttribute() returns TRUE if it succeeds.
+ *
+ * Revision 1.5  1995/10/21  03:15:12  warmerda
+ * Changed to use binary file access, and ensure that the
+ * field name field is zero filled, and limited to 10 chars.
+ *
+ * Revision 1.4  1995/08/24  18:10:42  warmerda
+ * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such
+ * as on the Sun.
+ *
+ * Revision 1.3  1995/08/04  03:15:16  warmerda
+ * Fixed up header.
+ *
+ * Revision 1.2  1995/08/04  03:14:43  warmerda
+ * Added header.
+ */
+
+//static char rcsid[] = 
+//  "$Id: dbfopen.c,v 1.3 2006/11/14 21:30:18 we7u Exp $";
+
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifndef FALSE
+#  define FALSE		0
+#  define TRUE		1
+#endif
+
+static int	nStringFieldLen = 0;
+static char * pszStringField = NULL;
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+/************************************************************************/
+/*                           DBFWriteHeader()                           */
+/*                                                                      */
+/*      This is called to write out the file header, and field          */
+/*      descriptions before writing any actual data records.  This      */
+/*      also computes all the DBFDataSet field offset/size/decimals     */
+/*      and so forth values.                                            */
+/************************************************************************/
+
+static void DBFWriteHeader(DBFHandle psDBF)
+
+{
+    unsigned char	abyHeader[XBASE_FLDHDR_SZ];
+    int		i;
+
+    if( !psDBF->bNoHeader )
+        return;
+
+    psDBF->bNoHeader = FALSE;
+
+/* -------------------------------------------------------------------- */
+/*	Initialize the file header information.				*/
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
+        abyHeader[i] = 0;
+
+    abyHeader[0] = 0x03;		/* memo field? - just copying 	*/
+
+    /* date updated on close, record count preset at zero */
+
+    abyHeader[8] = psDBF->nHeaderLength % 256;
+    abyHeader[9] = psDBF->nHeaderLength / 256;
+    
+    abyHeader[10] = psDBF->nRecordLength % 256;
+    abyHeader[11] = psDBF->nRecordLength / 256;
+
+/* -------------------------------------------------------------------- */
+/*      Write the initial 32 byte file header, and all the field        */
+/*      descriptions.                                     		*/
+/* -------------------------------------------------------------------- */
+    fseek( psDBF->fp, 0, 0 );
+    fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
+    fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
+
+/* -------------------------------------------------------------------- */
+/*      Write out the newline character if there is room for it.        */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
+    {
+        char	cNewline;
+
+        cNewline = 0x0d;
+        fwrite( &cNewline, 1, 1, psDBF->fp );
+    }
+}
+
+/************************************************************************/
+/*                           DBFFlushRecord()                           */
+/*                                                                      */
+/*      Write out the current record if there is one.                   */
+/************************************************************************/
+
+static void DBFFlushRecord( DBFHandle psDBF )
+
+{
+    int		nRecordOffset;
+
+    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
+    {
+	psDBF->bCurrentRecordModified = FALSE;
+
+	nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord 
+	                                             + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+    }
+}
+
+/************************************************************************/
+/*                              DBFOpen()                               */
+/*                                                                      */
+/*      Open a .dbf file.                                               */
+/************************************************************************/
+   
+DBFHandle SHPAPI_CALL
+DBFOpen( const char * pszFilename, const char * pszAccess )
+
+{
+    DBFHandle		psDBF;
+    unsigned char		*pabyBuf;
+    int			nFields, nHeadLen, nRecLen, iField, i;
+    char		*pszBasename, *pszFullname;
+
+/* -------------------------------------------------------------------- */
+/*      We only allow the access strings "rb" and "r+".                  */
+/* -------------------------------------------------------------------- */
+    if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 
+        && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
+        && strcmp(pszAccess,"r+b") != 0 )
+        return( NULL );
+
+    if( strcmp(pszAccess,"r") == 0 )
+        pszAccess = "rb";
+ 
+    if( strcmp(pszAccess,"r+") == 0 )
+        pszAccess = "rb+";
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszFilename)+5);
+    strcpy( pszBasename, pszFilename );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.dbf", pszBasename );
+        
+    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
+    psDBF->fp = fopen( pszFullname, pszAccess );
+
+    if( psDBF->fp == NULL )
+    {
+        sprintf( pszFullname, "%s.DBF", pszBasename );
+        psDBF->fp = fopen(pszFullname, pszAccess );
+    }
+    
+    free( pszBasename );
+    free( pszFullname );
+    
+    if( psDBF->fp == NULL )
+    {
+        free( psDBF );
+        return( NULL );
+    }
+
+    psDBF->bNoHeader = FALSE;
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+
+/* -------------------------------------------------------------------- */
+/*  Read Table Header info                                              */
+/* -------------------------------------------------------------------- */
+    pabyBuf = (unsigned char *) malloc(500);
+    if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
+    {
+        fclose( psDBF->fp );
+        free( pabyBuf );
+        free( psDBF );
+        return NULL;
+    }
+
+    psDBF->nRecords = 
+     pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
+
+    psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
+    psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
+    
+    psDBF->nFields = nFields = (nHeadLen - 32) / 32;
+
+    psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
+
+/* -------------------------------------------------------------------- */
+/*  Read in Field Definitions                                           */
+/* -------------------------------------------------------------------- */
+    
+    pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
+    psDBF->pszHeader = (char *) pabyBuf;
+
+    fseek( psDBF->fp, 32, 0 );
+    if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
+    {
+        fclose( psDBF->fp );
+        free( pabyBuf );
+        free( psDBF );
+        return NULL;
+    }
+
+    psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);
+    psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);
+    psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields);
+    psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields);
+
+    for( iField = 0; iField < nFields; iField++ )
+    {
+	unsigned char		*pabyFInfo;
+
+	pabyFInfo = pabyBuf+iField*32;
+
+	if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
+	{
+	    psDBF->panFieldSize[iField] = pabyFInfo[16];
+	    psDBF->panFieldDecimals[iField] = pabyFInfo[17];
+	}
+	else
+	{
+	    psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
+	    psDBF->panFieldDecimals[iField] = 0;
+	}
+
+	psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
+	if( iField == 0 )
+	    psDBF->panFieldOffset[iField] = 1;
+	else
+	    psDBF->panFieldOffset[iField] = 
+	      psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
+    }
+
+    return( psDBF );
+}
+
+/************************************************************************/
+/*                              DBFClose()                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+DBFClose(DBFHandle psDBF)
+{
+/* -------------------------------------------------------------------- */
+/*      Write out header if not already written.                        */
+/* -------------------------------------------------------------------- */
+    if( psDBF->bNoHeader )
+        DBFWriteHeader( psDBF );
+
+    DBFFlushRecord( psDBF );
+
+/* -------------------------------------------------------------------- */
+/*      Update last access date, and number of records if we have	*/
+/*	write access.                					*/
+/* -------------------------------------------------------------------- */
+    if( psDBF->bUpdated )
+    {
+	unsigned char		abyFileHeader[32];
+
+	fseek( psDBF->fp, 0, 0 );
+	fread( abyFileHeader, 32, 1, psDBF->fp );
+
+	abyFileHeader[1] = 95;			/* YY */
+	abyFileHeader[2] = 7;			/* MM */
+	abyFileHeader[3] = 26;			/* DD */
+
+	abyFileHeader[4] = psDBF->nRecords % 256;
+	abyFileHeader[5] = (psDBF->nRecords/256) % 256;
+	abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256;
+	abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256;
+
+	fseek( psDBF->fp, 0, 0 );
+	fwrite( abyFileHeader, 32, 1, psDBF->fp );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Close, and free resources.                                      */
+/* -------------------------------------------------------------------- */
+    fclose( psDBF->fp );
+
+    if( psDBF->panFieldOffset != NULL )
+    {
+        free( psDBF->panFieldOffset );
+        free( psDBF->panFieldSize );
+        free( psDBF->panFieldDecimals );
+        free( psDBF->pachFieldType );
+    }
+
+    free( psDBF->pszHeader );
+    free( psDBF->pszCurrentRecord );
+
+    free( psDBF );
+
+    if( pszStringField != NULL )
+    {
+        free( pszStringField );
+        pszStringField = NULL;
+        nStringFieldLen = 0;
+    }
+}
+
+/************************************************************************/
+/*                             DBFCreate()                              */
+/*                                                                      */
+/*      Create a new .dbf file.                                         */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreate( const char * pszFilename )
+
+{
+    DBFHandle	psDBF;
+    FILE	*fp;
+    char	*pszFullname, *pszBasename;
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszFilename)+5);
+    strcpy( pszBasename, pszFilename );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.dbf", pszBasename );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*      Create the file.                                                */
+/* -------------------------------------------------------------------- */
+    fp = fopen( pszFullname, "wb" );
+    if( fp == NULL )
+        return( NULL );
+
+    fputc( 0, fp );
+    fclose( fp );
+
+    fp = fopen( pszFullname, "rb+" );
+    if( fp == NULL )
+        return( NULL );
+
+    free( pszFullname );
+
+/* -------------------------------------------------------------------- */
+/*	Create the info structure.					*/
+/* -------------------------------------------------------------------- */
+    psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
+
+    psDBF->fp = fp;
+    psDBF->nRecords = 0;
+    psDBF->nFields = 0;
+    psDBF->nRecordLength = 1;
+    psDBF->nHeaderLength = 33;
+    
+    psDBF->panFieldOffset = NULL;
+    psDBF->panFieldSize = NULL;
+    psDBF->panFieldDecimals = NULL;
+    psDBF->pachFieldType = NULL;
+    psDBF->pszHeader = NULL;
+
+    psDBF->nCurrentRecord = -1;
+    psDBF->bCurrentRecordModified = FALSE;
+    psDBF->pszCurrentRecord = NULL;
+
+    psDBF->bNoHeader = TRUE;
+
+    return( psDBF );
+}
+
+/************************************************************************/
+/*                            DBFAddField()                             */
+/*                                                                      */
+/*      Add a field to a newly created .dbf file before any records     */
+/*      are written.                                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFAddField(DBFHandle psDBF, const char * pszFieldName, 
+            DBFFieldType eType, int nWidth, int nDecimals )
+
+{
+    char	*pszFInfo;
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*      Do some checking to ensure we can add records to this file.     */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nRecords > 0 )
+        return( -1 );
+
+    if( !psDBF->bNoHeader )
+        return( -1 );
+
+    if( eType != FTDouble && nDecimals != 0 )
+        return( -1 );
+
+    if( nWidth < 1 )
+        return -1;
+
+/* -------------------------------------------------------------------- */
+/*      SfRealloc all the arrays larger to hold the additional field      */
+/*      information.                                                    */
+/* -------------------------------------------------------------------- */
+    psDBF->nFields++;
+
+    psDBF->panFieldOffset = (int *) 
+      SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+
+    psDBF->panFieldSize = (int *) 
+      SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+
+    psDBF->panFieldDecimals = (int *) 
+      SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+
+    psDBF->pachFieldType = (char *) 
+      SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+
+/* -------------------------------------------------------------------- */
+/*      Assign the new field information fields.                        */
+/* -------------------------------------------------------------------- */
+    psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
+    psDBF->nRecordLength += nWidth;
+    psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
+    psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
+
+    if( eType == FTLogical )
+        psDBF->pachFieldType[psDBF->nFields-1] = 'L';
+    else if( eType == FTString )
+        psDBF->pachFieldType[psDBF->nFields-1] = 'C';
+    else
+        psDBF->pachFieldType[psDBF->nFields-1] = 'N';
+
+/* -------------------------------------------------------------------- */
+/*      Extend the required header information.                         */
+/* -------------------------------------------------------------------- */
+    psDBF->nHeaderLength += 32;
+    psDBF->bUpdated = FALSE;
+
+    psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
+
+    pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
+
+    for( i = 0; i < 32; i++ )
+        pszFInfo[i] = '\0';
+
+    if( (int) strlen(pszFieldName) < 10 )
+        strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
+    else
+        strncpy( pszFInfo, pszFieldName, 10);
+
+    pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
+
+    if( eType == FTString )
+    {
+        pszFInfo[16] = nWidth % 256;
+        pszFInfo[17] = nWidth / 256;
+    }
+    else
+    {
+        pszFInfo[16] = nWidth;
+        pszFInfo[17] = nDecimals;
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Make the current record buffer appropriately larger.            */
+/* -------------------------------------------------------------------- */
+    psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+					       psDBF->nRecordLength);
+
+    return( psDBF->nFields-1 );
+}
+
+/************************************************************************/
+/*                          DBFReadAttribute()                          */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
+                              char chReqType )
+
+{
+    int	       	nRecordOffset;
+    unsigned char	*pabyRec;
+    void	*pReturnField = NULL;
+
+    static double dDoubleField;
+
+/* -------------------------------------------------------------------- */
+/*      Verify selection.                                               */
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity >= psDBF->nRecords )
+        return( NULL );
+
+    if( iField < 0 || iField >= psDBF->nFields )
+        return( NULL );
+
+/* -------------------------------------------------------------------- */
+/*	Have we read the record?					*/
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
+        {
+            fprintf( stderr, "fseek(%d) failed on DBF file.\n",
+                     nRecordOffset );
+            return NULL;
+        }
+
+	if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 
+                   1, psDBF->fp ) != 1 )
+        {
+            fprintf( stderr, "fread(%d) failed on DBF file.\n",
+                     psDBF->nRecordLength );
+            return NULL;
+        }
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+/* -------------------------------------------------------------------- */
+/*	Ensure our field buffer is large enough to hold this buffer.	*/
+/* -------------------------------------------------------------------- */
+    if( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
+    {
+	nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
+	pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Extract the requested field.					*/
+/* -------------------------------------------------------------------- */
+    strncpy( pszStringField, 
+	     ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
+	     psDBF->panFieldSize[iField] );
+    pszStringField[psDBF->panFieldSize[iField]] = '\0';
+
+    pReturnField = pszStringField;
+
+/* -------------------------------------------------------------------- */
+/*      Decode the field.                                               */
+/* -------------------------------------------------------------------- */
+    if( chReqType == 'N' )
+    {
+        dDoubleField = atof(pszStringField);
+
+	pReturnField = &dDoubleField;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Should we trim white space off the string attribute value?      */
+/* -------------------------------------------------------------------- */
+#ifdef TRIM_DBF_WHITESPACE
+    else
+    {
+        char	*pchSrc, *pchDst;
+
+        pchDst = pchSrc = pszStringField;
+        while( *pchSrc == ' ' )
+            pchSrc++;
+
+        while( *pchSrc != '\0' )
+            *(pchDst++) = *(pchSrc++);
+        *pchDst = '\0';
+
+        while( pchDst != pszStringField && *(--pchDst) == ' ' )
+            *pchDst = '\0';
+    }
+#endif
+    
+    return( pReturnField );
+}
+
+/************************************************************************/
+/*                        DBFReadIntAttribute()                         */
+/*                                                                      */
+/*      Read an integer attribute.                                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    double	*pdValue;
+
+    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
+
+    if( pdValue == NULL )
+        return 0;
+    else
+        return( (int) *pdValue );
+}
+
+/************************************************************************/
+/*                        DBFReadDoubleAttribute()                      */
+/*                                                                      */
+/*      Read a double attribute.                                        */
+/************************************************************************/
+
+double SHPAPI_CALL
+DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    double	*pdValue;
+
+    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
+
+    if( pdValue == NULL )
+        return 0.0;
+    else
+        return( *pdValue );
+}
+
+/************************************************************************/
+/*                        DBFReadStringAttribute()                      */
+/*                                                                      */
+/*      Read a string attribute.                                        */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
+}
+
+/************************************************************************/
+/*                        DBFReadLogicalAttribute()                     */
+/*                                                                      */
+/*      Read a logical attribute.                                       */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
+}
+
+/************************************************************************/
+/*                         DBFIsAttributeNULL()                         */
+/*                                                                      */
+/*      Return TRUE if value for field is NULL.                         */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    const char	*pszValue;
+
+    pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+
+    switch(psDBF->pachFieldType[iField])
+    {
+      case 'N':
+      case 'F':
+        /* NULL numeric fields have value "****************" */
+        return pszValue[0] == '*';
+
+      case 'D':
+        /* NULL date fields have value "00000000" */
+        return strncmp(pszValue,"00000000",8) == 0;
+
+      case 'L':
+        /* NULL boolean fields have value "?" */ 
+        return pszValue[0] == '?';
+
+      default:
+        /* empty string fields are considered NULL */
+        return strlen(pszValue) == 0;
+    }
+}
+
+/************************************************************************/
+/*                          DBFGetFieldCount()                          */
+/*                                                                      */
+/*      Return the number of fields in this table.                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldCount( DBFHandle psDBF )
+
+{
+    return( psDBF->nFields );
+}
+
+/************************************************************************/
+/*                         DBFGetRecordCount()                          */
+/*                                                                      */
+/*      Return the number of records in this table.                     */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetRecordCount( DBFHandle psDBF )
+
+{
+    return( psDBF->nRecords );
+}
+
+/************************************************************************/
+/*                          DBFGetFieldInfo()                           */
+/*                                                                      */
+/*      Return any requested information about the field.               */
+/************************************************************************/
+
+DBFFieldType SHPAPI_CALL
+DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
+                 int * pnWidth, int * pnDecimals )
+
+{
+    if( iField < 0 || iField >= psDBF->nFields )
+        return( FTInvalid );
+
+    if( pnWidth != NULL )
+        *pnWidth = psDBF->panFieldSize[iField];
+
+    if( pnDecimals != NULL )
+        *pnDecimals = psDBF->panFieldDecimals[iField];
+
+    if( pszFieldName != NULL )
+    {
+	int	i;
+
+	strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 );
+	pszFieldName[11] = '\0';
+	for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- )
+	    pszFieldName[i] = '\0';
+    }
+
+    if ( psDBF->pachFieldType[iField] == 'L' )
+	return( FTLogical);
+
+    else if( psDBF->pachFieldType[iField] == 'N' 
+             || psDBF->pachFieldType[iField] == 'F'
+             || psDBF->pachFieldType[iField] == 'D' )
+    {
+	if( psDBF->panFieldDecimals[iField] > 0 )
+	    return( FTDouble );
+	else
+	    return( FTInteger );
+    }
+    else
+    {
+	return( FTString );
+    }
+}
+
+/************************************************************************/
+/*                         DBFWriteAttribute()                          */
+/*									*/
+/*	Write an attribute record to the file.				*/
+/************************************************************************/
+
+static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
+			     void * pValue )
+
+{
+    int	       	nRecordOffset, i, j, nRetResult = TRUE;
+    unsigned char	*pabyRec;
+    char	szSField[400], szFormat[20];
+
+/* -------------------------------------------------------------------- */
+/*	Is this a valid record?						*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity > psDBF->nRecords )
+        return( FALSE );
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader(psDBF);
+
+/* -------------------------------------------------------------------- */
+/*      Is this a brand new record?                                     */
+/* -------------------------------------------------------------------- */
+    if( hEntity == psDBF->nRecords )
+    {
+	DBFFlushRecord( psDBF );
+
+	psDBF->nRecords++;
+	for( i = 0; i < psDBF->nRecordLength; i++ )
+	    psDBF->pszCurrentRecord[i] = ' ';
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+    psDBF->bCurrentRecordModified = TRUE;
+    psDBF->bUpdated = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Translate NULL value to valid DBF file representation.          */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/* -------------------------------------------------------------------- */
+    if( pValue == NULL )
+    {
+        switch(psDBF->pachFieldType[iField])
+        {
+          case 'N':
+          case 'F':
+	    /* NULL numeric fields have value "****************" */
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', 
+                    psDBF->panFieldSize[iField] );
+            break;
+
+          case 'D':
+	    /* NULL date fields have value "00000000" */
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', 
+                    psDBF->panFieldSize[iField] );
+            break;
+
+          case 'L':
+	    /* NULL boolean fields have value "?" */ 
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', 
+                    psDBF->panFieldSize[iField] );
+            break;
+
+          default:
+            /* empty string fields are considered NULL */
+            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', 
+                    psDBF->panFieldSize[iField] );
+            break;
+        }
+        return TRUE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Assign all the record fields.                                   */
+/* -------------------------------------------------------------------- */
+    switch( psDBF->pachFieldType[iField] )
+    {
+      case 'D':
+      case 'N':
+      case 'F':
+	if( psDBF->panFieldDecimals[iField] == 0 )
+	{
+            int		nWidth = psDBF->panFieldSize[iField];
+
+            if( (int)sizeof(szSField)-2 < nWidth )
+                nWidth = sizeof(szSField)-2;
+
+	    sprintf( szFormat, "%%%dd", nWidth );
+	    sprintf(szSField, szFormat, (int) *((double *) pValue) );
+	    if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
+            {
+	        szSField[psDBF->panFieldSize[iField]] = '\0';
+                nRetResult = FALSE;
+            }
+
+	    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+		    szSField, strlen(szSField) );
+	}
+	else
+	{
+            int		nWidth = psDBF->panFieldSize[iField];
+
+            if( (int)sizeof(szSField)-2 < nWidth )
+                nWidth = sizeof(szSField)-2;
+
+	    sprintf( szFormat, "%%%d.%df", 
+                     nWidth, psDBF->panFieldDecimals[iField] );
+	    sprintf(szSField, szFormat, *((double *) pValue) );
+	    if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
+            {
+	        szSField[psDBF->panFieldSize[iField]] = '\0';
+                nRetResult = FALSE;
+            }
+	    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+		    szSField, strlen(szSField) );
+	}
+	break;
+
+      case 'L':
+        if (psDBF->panFieldSize[iField] >= 1  && 
+            (*(char*)pValue == 'F' || *(char*)pValue == 'T'))
+            *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
+        break;
+
+      default:
+	if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
+        {
+	    j = psDBF->panFieldSize[iField];
+            nRetResult = FALSE;
+        }
+	else
+        {
+            memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
+                    psDBF->panFieldSize[iField] );
+	    j = strlen((char *) pValue);
+        }
+
+	strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+		(char *) pValue, j );
+	break;
+    }
+
+    return( nRetResult );
+}
+
+/************************************************************************/
+/*                     DBFWriteAttributeDirectly()                      */
+/*                                                                      */
+/*      Write an attribute record to the file, but without any          */
+/*      reformatting based on type.  The provided buffer is written     */
+/*      as is to the field position in the record.                      */
+/************************************************************************/
+
+int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
+                              void * pValue )
+
+{
+    int	       	nRecordOffset, i, j;
+    unsigned char	*pabyRec;
+
+/* -------------------------------------------------------------------- */
+/*	Is this a valid record?						*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity > psDBF->nRecords )
+        return( FALSE );
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader(psDBF);
+
+/* -------------------------------------------------------------------- */
+/*      Is this a brand new record?                                     */
+/* -------------------------------------------------------------------- */
+    if( hEntity == psDBF->nRecords )
+    {
+	DBFFlushRecord( psDBF );
+
+	psDBF->nRecords++;
+	for( i = 0; i < psDBF->nRecordLength; i++ )
+	    psDBF->pszCurrentRecord[i] = ' ';
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+/* -------------------------------------------------------------------- */
+/*      Assign all the record fields.                                   */
+/* -------------------------------------------------------------------- */
+    if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
+        j = psDBF->panFieldSize[iField];
+    else
+    {
+        memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
+                psDBF->panFieldSize[iField] );
+        j = strlen((char *) pValue);
+    }
+
+    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
+            (char *) pValue, j );
+
+    psDBF->bCurrentRecordModified = TRUE;
+    psDBF->bUpdated = TRUE;
+
+    return( TRUE );
+}
+
+/************************************************************************/
+/*                      DBFWriteDoubleAttribute()                       */
+/*                                                                      */
+/*      Write a double attribute.                                       */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField,
+                         double dValue )
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteIntegerAttribute()                      */
+/*                                                                      */
+/*      Write a integer attribute.                                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField,
+                          int nValue )
+
+{
+    double	dValue = nValue;
+
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteStringAttribute()                       */
+/*                                                                      */
+/*      Write a string attribute.                                       */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField,
+                         const char * pszValue )
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteNULLAttribute()                         */
+/*                                                                      */
+/*      Write a string attribute.                                       */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField )
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) );
+}
+
+/************************************************************************/
+/*                      DBFWriteLogicalAttribute()                      */
+/*                                                                      */
+/*      Write a logical attribute.                                      */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField,
+		       const char lValue)
+
+{
+    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) );
+}
+
+/************************************************************************/
+/*                         DBFWriteTuple()                              */
+/*									*/
+/*	Write an attribute record to the file.				*/
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
+
+{
+    int	       	nRecordOffset, i;
+    unsigned char	*pabyRec;
+
+/* -------------------------------------------------------------------- */
+/*	Is this a valid record?						*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity > psDBF->nRecords )
+        return( FALSE );
+
+    if( psDBF->bNoHeader )
+        DBFWriteHeader(psDBF);
+
+/* -------------------------------------------------------------------- */
+/*      Is this a brand new record?                                     */
+/* -------------------------------------------------------------------- */
+    if( hEntity == psDBF->nRecords )
+    {
+	DBFFlushRecord( psDBF );
+
+	psDBF->nRecords++;
+	for( i = 0; i < psDBF->nRecordLength; i++ )
+	    psDBF->pszCurrentRecord[i] = ' ';
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Is this an existing record, but different than the last one     */
+/*      we accessed?                                                    */
+/* -------------------------------------------------------------------- */
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+    memcpy ( pabyRec, pRawTuple,  psDBF->nRecordLength );
+
+    psDBF->bCurrentRecordModified = TRUE;
+    psDBF->bUpdated = TRUE;
+
+    return( TRUE );
+}
+
+/************************************************************************/
+/*                          DBFReadTuple()                              */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFReadTuple(DBFHandle psDBF, int hEntity )
+
+{
+    int	       	nRecordOffset;
+    unsigned char	*pabyRec;
+    static char	*pReturnTuple = NULL;
+
+    static int	nTupleLen = 0;
+
+/* -------------------------------------------------------------------- */
+/*	Have we read the record?					*/
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity >= psDBF->nRecords )
+        return( NULL );
+
+    if( psDBF->nCurrentRecord != hEntity )
+    {
+	DBFFlushRecord( psDBF );
+
+	nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
+
+	fseek( psDBF->fp, nRecordOffset, 0 );
+	fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+	psDBF->nCurrentRecord = hEntity;
+    }
+
+    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+
+    if ( nTupleLen < psDBF->nRecordLength) {
+      nTupleLen = psDBF->nRecordLength;
+      pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
+    }
+    
+    memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
+        
+    return( pReturnTuple );
+}
+
+/************************************************************************/
+/*                          DBFCloneEmpty()                              */
+/*                                                                      */
+/*      Read one of the attribute fields of a record.                   */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) 
+{
+    DBFHandle	newDBF;
+
+   newDBF = DBFCreate ( pszFilename );
+   if ( newDBF == NULL ) return ( NULL ); 
+   
+   newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
+   memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
+   
+   newDBF->nFields = psDBF->nFields;
+   newDBF->nRecordLength = psDBF->nRecordLength;
+   newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
+    
+   newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); 
+   memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+   newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
+   memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+   newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
+   memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+   newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
+   memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
+
+   newDBF->bNoHeader = TRUE;
+   newDBF->bUpdated = TRUE;
+   
+   DBFWriteHeader ( newDBF );
+   DBFClose ( newDBF );
+   
+   newDBF = DBFOpen ( pszFilename, "rb+" );
+
+   return ( newDBF );
+}
+
+/************************************************************************/
+/*                       DBFGetNativeFieldType()                        */
+/*                                                                      */
+/*      Return the DBase field type for the specified field.            */
+/*                                                                      */
+/*      Value can be one of: 'C' (String), 'D' (Date), 'F' (Float),     */
+/*                           'N' (Numeric, with or without decimal),    */
+/*                           'L' (Logical),                             */
+/*                           'M' (Memo: 10 digits .DBT block ptr)       */
+/************************************************************************/
+
+char SHPAPI_CALL
+DBFGetNativeFieldType( DBFHandle psDBF, int iField )
+
+{
+    if( iField >=0 && iField < psDBF->nFields )
+        return psDBF->pachFieldType[iField];
+
+    return  ' ';
+}
+
+/************************************************************************/
+/*                            str_to_upper()                            */
+/************************************************************************/
+
+static void str_to_upper (char *string)
+{
+    int len;
+    short i = -1;
+
+    len = strlen (string);
+
+    while (++i < len)
+        if (isalpha(string[i]) && islower(string[i]))
+            string[i] = toupper ((int)string[i]);
+}
+
+/************************************************************************/
+/*                          DBFGetFieldIndex()                          */
+/*                                                                      */
+/*      Get the index number for a field in a .dbf file.                */
+/*                                                                      */
+/*      Contributed by Jim Matthews.                                    */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
+
+{
+    char          name[12], name1[12], name2[12];
+    int           i;
+
+    strncpy(name1, pszFieldName,11);
+    name1[11] = '\0';
+    str_to_upper(name1);
+
+    for( i = 0; i < DBFGetFieldCount(psDBF); i++ )
+    {
+        DBFGetFieldInfo( psDBF, i, name, NULL, NULL );
+        strncpy(name2,name,11);
+        str_to_upper(name2);
+
+        if(!strncmp(name1,name2,10))
+            return(i);
+    }
+    return(-1);
+}
diff --git a/src/shapelib/libtool b/src/shapelib/libtool
new file mode 100755
index 0000000..7706a8c
--- /dev/null
+++ b/src/shapelib/libtool
@@ -0,0 +1,4149 @@
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+# Generated automatically by ltconfig (GNU libtool 1.3 (1.385.2.117 1999/04/29 13:07:13))
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+# Libtool was configured as follows, on host cs46980-c:
+#
+# CC="gcc" CFLAGS="-g -O2" CPPFLAGS="" \
+# LD="/usr/bin/ld" LDFLAGS="" LIBS="" \
+# NM="/usr/bin/nm -B" RANLIB="ranlib" LN_S="ln -s" \
+# DLLTOOL="" OBJDUMP="" AS="" \
+#   ./ltconfig --cache-file=./config.cache --with-gcc --with-gnu-ld --no-verify ./ltmain.sh i586-pc-linux-gnu
+#
+# Compiler and other test output produced by ltconfig, useful for
+# debugging ltconfig, is in ./config.log if it exists.
+
+# The version of ltconfig that generated this script.
+LTCONFIG_VERSION="1.3"
+
+# Shell to use when invoking shell scripts.
+SHELL="/bin/sh"
+
+# Whether or not to build shared libraries.
+build_libtool_libs=yes
+
+# Whether or not to build static libraries.
+build_old_libs=yes
+
+# Whether or not to optimize for fast installation.
+fast_install=yes
+
+# The host system.
+host_alias=i586-pc-linux-gnu
+host=i586-pc-linux-gnu
+
+# An echo program that does not interpret backslashes.
+echo="echo"
+
+# The archiver.
+AR="ar"
+
+# The default C compiler.
+CC="gcc"
+
+# The linker used to build libraries.
+LD="/usr/bin/ld"
+
+# Whether we need hard or soft links.
+LN_S="ln -s"
+
+# A BSD-compatible nm program.
+NM="/usr/bin/nm -B"
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="dlltool"
+
+# Used on cygwin: object dumper.
+OBJDUMP="objdump"
+
+# Used on cygwin: assembler.
+AS="as"
+
+# The name of the directory that contains temporary libtool files.
+objdir=.libs
+
+# How to create reloadable object files.
+reload_flag=" -r"
+reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Object file suffix (normally "o").
+objext="o"
+
+# Old archive suffix (normally "a").
+libext="a"
+
+# Additional compiler flags for building library objects.
+pic_flag=" -fPIC"
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Can we write directly to a .lo ?
+compiler_o_lo="yes"
+
+# Must we lock files when doing compilation ?
+need_locks="no"
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=no
+
+# Do we need a version for libraries?
+need_version=no
+
+# Whether dlopen is supported.
+dlopen=unknown
+
+# Whether dlopen of programs is supported.
+dlopen_self=unknown
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=unknown
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="-static"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="\${wl}--export-dynamic"
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive"
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=""
+
+# Library versioning type.
+version_type=linux
+
+# Format of library name prefix.
+libname_spec="lib\$name"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="\${libname}\${release}.so\$versuffix \${libname}\${release}.so\$major \$libname.so"
+
+# The coded name of the library, if different from the real name.
+soname_spec="\${libname}\${release}.so\$major"
+
+# Commands used to build and install an old-style archive.
+RANLIB="ranlib"
+old_archive_cmds="\$AR cru \$oldlib\$oldobjs~\$RANLIB \$oldlib"
+old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib"
+old_postuninstall_cmds=""
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Commands used to build and install a shared archive.
+archive_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname -o \$lib"
+archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib"
+postinstall_cmds=""
+postuninstall_cmds=""
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )"
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd="/usr/bin/file"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=""
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=""
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir"
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=""
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="sed -n -e 's/^.*[ 	]\\([ABCDGISTW]\\)[ 	][ 	]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'"
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern char \\1;/p'"
+
+# This is the shared library runtime path variable.
+runpath_var=LD_RUN_PATH
+
+# This is the shared library path variable.
+shlibpath_var=LD_LIBRARY_PATH
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=no
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=no
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=no
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to yes if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs | \$global_symbol_pipe | sed 's/.* //' | sort | uniq > \$export_symbols"
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+### END LIBTOOL CONFIG
+
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3
+TIMESTAMP=" (1.385.2.117 1999/04/29 13:07:13)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \012 \040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    exit 0
+    ;;
+
+  --config)
+    sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+    exit 0
+    ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+	case "$arg" in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    user_target=no
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+	if test "$user_target" != "no"; then
+	  $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	  exit 1
+	fi
+	user_target=next
+	;;
+
+      -static)
+	build_old_libs=yes
+	continue
+	;;
+      esac
+
+      case "$user_target" in
+      next)
+	# The next one is the -o target name
+	user_target=yes
+	continue
+	;;
+      yes)
+	# We got the output file
+	user_target=set
+	libobj="$arg"
+	continue
+	;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+	base_compile="$lastarg"
+      else
+	base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    case "$user_target" in
+    set)
+      ;;
+    no)
+      # Get the name of the library object.
+      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    *)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSfmso]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $libobj"
+    else
+      removelist="$libobj"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until ln "$0" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+      echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      command="$base_compile $pic_flag -DPIC $srcfile"
+      if test "$build_old_libs" = yes; then
+	lo_libobj="$libobj"
+	dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+	if test "X$dir" = "X$libobj"; then
+	  dir="$objdir"
+	else
+	  dir="$dir/$objdir"
+	fi
+	libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+	if test -d "$dir"; then
+	  $show "$rm $libobj"
+	  $run $rm $libobj
+	else
+	  $show "$mkdir $dir"
+	  $run $mkdir $dir
+	  status=$?
+	  if test $status -ne 0 && test ! -d $dir; then
+	    exit $status
+	  fi
+	fi
+      fi
+      if test "$compiler_o_lo" = yes; then
+	output_obj="$libobj"
+	command="$command -o $output_obj"
+      elif test "$compiler_c_o" = yes; then
+	output_obj="$obj"
+	command="$command -o $output_obj"
+      fi
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+	echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test x"$output_obj" != x"$libobj"; then
+	$show "$mv $output_obj $libobj"
+	if $run $mv $output_obj $libobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+	# Rename the .lo from within objdir to obj
+	if test -f $obj; then
+	  $show $rm $obj
+	  $run $rm $obj
+	fi
+
+	$show "$mv $libobj $obj"
+	if $run $mv $libobj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+
+	# Now arrange that obj and lo_libobj become the same file
+	$show "$LN_S $obj $lo_libobj"
+	if $run $LN_S $obj $lo_libobj; then
+	  exit 0
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      command="$base_compile $srcfile"
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+	output_obj="$obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	$run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+	echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed
+      if test x"$output_obj" != x"$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Create an invalid libtool object if no PIC, so that we do not
+      # accidentally link it into a program.
+      if test "$build_libtool_libs" != yes; then
+	$show "echo timestamp > $libobj"
+	$run eval "echo timestamp > \$libobj" || exit $?
+      else
+	# Move the .lo from within objdir
+	$show "$mv $libobj $lo_libobj"
+	if $run $mv $libobj $lo_libobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+    fi
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    C_compiler="$CC" # save it, to compile generated C sources
+    CC="$nonopt"
+    case "$host" in
+    *-*-cygwin* | *-*-mingw* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invokation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+      # This is a source program that is used to create import libraries
+      # on Windows for dlls which lack them. Don't remove nor modify the
+      # starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999 Free Software Foundation, Inc.
+# 
+#  This file is part of GNU libtool.
+# 
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+# 
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+# 
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#  */
+# 
+#  #include <stdio.h>		/* for printf() */
+#  #include <unistd.h>		/* for open(), lseek(), read() */
+#  #include <fcntl.h>		/* for O_RDONLY, O_BINARY */
+#  #include <string.h>		/* for strdup() */
+# 
+#  static unsigned int
+#  pe_get16 (fd, offset)
+#       int fd;
+#       int offset;
+#  {
+#    unsigned char b[2];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 2);
+#    return b[0] + (b[1]<<8);
+#  }
+# 
+#  static unsigned int
+#  pe_get32 (fd, offset)
+#      int fd;
+#      int offset;
+#  {
+#    unsigned char b[4];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 4);
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  static unsigned int
+#  pe_as32 (ptr)
+#       void *ptr;
+#  {
+#    unsigned char *b = ptr;
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  int
+#  main (argc, argv)
+#      int argc;
+#      char *argv[];
+#  {
+#      int dll;
+#      unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#      unsigned long export_rva, export_size, nsections, secptr, expptr;
+#      unsigned long name_rvas, nexp;
+#      unsigned char *expdata, *erva;
+#      char *filename, *dll_name;
+# 
+#      filename = argv[1];
+# 
+#      dll = open(filename, O_RDONLY|O_BINARY);
+#      if (!dll)
+#  	return 1;
+# 
+#      dll_name = filename;
+#    
+#      for (i=0; filename[i]; i++)
+#  	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+#  	    dll_name = filename + i +1;
+# 
+#      pe_header_offset = pe_get32 (dll, 0x3c);
+#      opthdr_ofs = pe_header_offset + 4 + 20;
+#      num_entries = pe_get32 (dll, opthdr_ofs + 92);
+# 
+#      if (num_entries < 1) /* no exports */
+#  	return 1;
+# 
+#      export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#      export_size = pe_get32 (dll, opthdr_ofs + 100);
+#      nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#      secptr = (pe_header_offset + 4 + 20 +
+#  	      pe_get16 (dll, pe_header_offset + 4 + 16));
+# 
+#      expptr = 0;
+#      for (i = 0; i < nsections; i++)
+#      {
+#  	char sname[8];
+#  	unsigned long secptr1 = secptr + 40 * i;
+#  	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+#  	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+#  	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+#  	lseek(dll, secptr1, SEEK_SET);
+#  	read(dll, sname, 8);
+#  	if (vaddr <= export_rva && vaddr+vsize > export_rva)
+#  	{
+#  	    expptr = fptr + (export_rva - vaddr);
+#  	    if (export_rva + export_size > vaddr + vsize)
+#  		export_size = vsize - (export_rva - vaddr);
+#  	    break;
+#  	}
+#      }
+# 
+#      expdata = (unsigned char*)malloc(export_size);
+#      lseek (dll, expptr, SEEK_SET);
+#      read (dll, expdata, export_size);
+#      erva = expdata - export_rva;
+# 
+#      nexp = pe_as32 (expdata+24);
+#      name_rvas = pe_as32 (expdata+32);
+# 
+#      printf ("EXPORTS\n");
+#      for (i = 0; i<nexp; i++)
+#      {
+#  	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+#  	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#      }
+# 
+#      return 0;
+#  }
+# /* impgen.c ends here */
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    compile_command="$CC"
+    finalize_command="$CC"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    linkopts=
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      lib_search_path=
+    fi
+    # now prepend the system-specific ones
+    eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+    
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    module=no
+    objs=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+	if test "X$arg" = "X-all-static"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	else
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	fi
+	build_libtool_libs=no
+	build_old_libs=yes
+	prefer_static_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test $# -gt 0; do
+      arg="$1"
+      shift
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case "$prev" in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case "$prev" in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case "$arg" in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit 1
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case "$arg" in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit 1
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: not more than one -exported-symbols argument allowed"
+	  exit 1
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case "$dir" in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	    exit 1
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case " $deplibs " in
+	*" $arg "*) ;;
+	*) deplibs="$deplibs $arg";;
+	esac
+	case " $lib_search_path " in
+	*" $dir "*) ;;
+	*) lib_search_path="$lib_search_path $dir";;
+	esac
+	case "$host" in
+	*-*-cygwin* | *-*-mingw* | *-*-os2*)
+	  dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+	  case ":$dllsearchpath:" in
+	  ::) dllsearchpath="$dllsearchdir";;
+	  *":$dllsearchdir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+	  esac
+	  ;;
+	esac
+	;;
+
+      -l*)
+	if test "$arg" = "-lc"; then
+	  case "$host" in
+	  *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+	    # These systems don't actually have c library (as such)
+	    continue
+	    ;;
+	  esac
+	elif test "$arg" = "-lm"; then
+	  case "$host" in
+	  *-*-cygwin* | *-*-beos*)
+	    # These systems don't actually have math library (as such)
+	    continue
+	    ;;
+	  esac
+	fi
+	deplibs="$deplibs $arg"
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case "$dir" in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit 1
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static)
+	# If we have no pic_flag, then this is the same as -all-static.
+	if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case "$arg" in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+
+      *.o | *.obj | *.a | *.lib)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A library object.
+	if test "$prev" = dlfiles; then
+	  dlfiles="$dlfiles $arg"
+	  if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+	    prev=
+	    continue
+	  else
+	    # If libtool objects are unsupported, then we need to preload.
+	    prev=dlprefiles
+	  fi
+	fi
+
+	if test "$prev" = dlprefiles; then
+	  # Preload the old-style object.
+	  dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+	  prev=
+	fi
+	libobjs="$libobjs $arg"
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	dlname=
+	libdir=
+	library_names=
+	old_library=
+
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+	  exit 1
+	fi
+
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variable installed.
+	installed=yes
+
+	# Read the .la file
+	# If there is no directory component, then add one.
+	case "$arg" in
+	*/* | *\\*) . $arg ;;
+	*) . ./$arg ;;
+	esac
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+	  exit 1
+	fi
+
+	# Find the relevant object directory and library name.
+	name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+	if test "X$installed" = Xyes; then
+	  dir="$libdir"
+	else
+	  dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$dir" = "X$arg"; then
+	    dir="$objdir"
+	  else
+	    dir="$dir/$objdir"
+	  fi
+	fi
+
+	if test -n "$dependency_libs"; then
+	  # Extract -R from dependency_libs
+	  temp_deplibs=
+	  for deplib in $dependency_libs; do
+	    case "$deplib" in
+	    -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+		 case " $rpath $xrpath " in
+		 *" $temp_xrpath "*) ;;
+		 *) xrpath="$xrpath $temp_xrpath";;
+		 esac;;
+	    -L*) case "$compile_command $temp_deplibs " in
+		 *" $deplib "*) ;;
+		 *) temp_deplibs="$temp_deplibs $deplib";;
+		 esac;;
+	    *) temp_deplibs="$temp_deplibs $deplib";;
+	    esac
+	  done
+	  dependency_libs="$temp_deplibs"
+	fi
+
+	if test -z "$libdir"; then
+	  # It is a libtool convenience library, so add in its objects.
+	  convenience="$convenience $dir/$old_library"
+	  old_convenience="$old_convenience $dir/$old_library"
+	  deplibs="$deplibs$dependency_libs"
+	  compile_command="$compile_command $dir/$old_library$dependency_libs"
+	  finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+	  continue
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$prev" = dlfiles; then
+	  dlfiles="$dlfiles $arg"
+	  if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking statically,
+	    # we need to preload.
+	    prev=dlprefiles
+	  else
+	    # We should not create a dependency on this library, but we
+	    # may need any libraries it requires.
+	    compile_command="$compile_command$dependency_libs"
+	    finalize_command="$finalize_command$dependency_libs"
+	    prev=
+	    continue
+	  fi
+	fi
+
+	# The library was specified with -dlpreopen.
+	if test "$prev" = dlprefiles; then
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    dlprefiles="$dlprefiles $dir/$old_library"
+	  else
+	    dlprefiles="$dlprefiles $dir/$linklib"
+	  fi
+	  prev=
+	fi
+
+	if test -n "$library_names" &&
+	   { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	  link_against_libtool_libs="$link_against_libtool_libs $arg"
+	  if test -n "$shlibpath_var"; then
+	    # Make sure the rpath contains only unique directories.
+	    case "$temp_rpath " in
+	    *" $dir "*) ;;
+	    *) temp_rpath="$temp_rpath $dir" ;;
+	    esac
+	  fi
+
+	  # We need an absolute path.
+	  case "$dir" in
+	  [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+	  *)
+	    absdir=`cd "$dir" && pwd`
+	    if test -z "$absdir"; then
+	      $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	      exit 1
+	    fi
+	    ;;
+	  esac
+	  
+	  # This is the magic to use -rpath.
+	  # Skip directories that are in the system default run-time
+	  # search path, unless they have been requested with -R.
+	  case " $sys_lib_dlsearch_path " in
+	  *" $absdir "*) ;;
+	  *)
+	    case "$compile_rpath " in
+	    *" $absdir "*) ;;
+	    *) compile_rpath="$compile_rpath $absdir" 
+	    esac
+	    ;;
+	  esac
+
+	  case " $sys_lib_dlsearch_path " in
+	  *" $libdir "*) ;;
+	  *)
+	    case "$finalize_rpath " in
+	    *" $libdir "*) ;;
+	    *) finalize_rpath="$finalize_rpath $libdir"
+	    esac
+	    ;;
+	  esac
+
+	  lib_linked=yes
+	  case "$hardcode_action" in
+	  immediate | unsupported)
+	    if test "$hardcode_direct" = no; then
+	      compile_command="$compile_command $dir/$linklib"
+	      deplibs="$deplibs $dir/$linklib"
+	      case "$host" in
+	      *-*-cygwin* | *-*-mingw* | *-*-os2*)
+		dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+		if test -n "$dllsearchpath"; then
+		  dllsearchpath="$dllsearchpath:$dllsearchdir"
+		else
+		  dllsearchpath="$dllsearchdir"
+		fi
+		;;
+	      esac
+	    elif test "$hardcode_minus_L" = no; then
+	      case "$host" in
+	      *-*-sunos*)
+		compile_shlibpath="$compile_shlibpath$dir:"
+		;;
+	      esac
+	      case "$compile_command " in
+	      *" -L$dir "*) ;;
+	      *) compile_command="$compile_command -L$dir";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -L$dir -l$name"
+	    elif test "$hardcode_shlibpath_var" = no; then
+	      case ":$compile_shlibpath:" in
+	      *":$dir:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$dir:";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -l$name"
+	    else
+	      lib_linked=no
+	    fi
+	    ;;
+
+	  relink)
+	    if test "$hardcode_direct" = yes; then
+	      compile_command="$compile_command $absdir/$linklib"
+	      deplibs="$deplibs $absdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      case "$compile_command " in
+	      *" -L$absdir "*) ;;
+	      *) compile_command="$compile_command -L$absdir";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -L$absdir -l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case ":$compile_shlibpath:" in
+	      *":$absdir:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$absdir:";;
+	      esac
+	      compile_command="$compile_command -l$name"
+	      deplibs="$deplibs -l$name"
+	    else
+	      lib_linked=no
+	    fi
+	    ;;
+
+	  *)
+	    lib_linked=no
+	    ;;
+	  esac
+
+	  if test "$lib_linked" != yes; then
+	    $echo "$modename: configuration error: unsupported hardcode properties"
+	    exit 1
+	  fi
+
+	  # Finalize command for both is simple: just hardcode it.
+	  if test "$hardcode_direct" = yes; then
+	    finalize_command="$finalize_command $libdir/$linklib"
+	  elif test "$hardcode_minus_L" = yes; then
+	    case "$finalize_command " in
+	    *" -L$libdir "*) ;;
+	    *) finalize_command="$finalize_command -L$libdir";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  elif test "$hardcode_shlibpath_var" = yes; then
+	    case ":$finalize_shlibpath:" in
+	    *":$libdir:"*) ;;
+	    *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  else
+	    # We cannot seem to hardcode it, guess we'll fake it.
+	    case "$finalize_command " in
+	    *" -L$dir "*) ;;
+	    *) finalize_command="$finalize_command -L$libdir";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  fi
+	else
+	  # Transform directly to old archives if we don't build new libraries.
+	  if test -n "$pic_flag" && test -z "$old_library"; then
+	    $echo "$modename: cannot find static library for \`$arg'" 1>&2
+	    exit 1
+	  fi
+
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_command="$compile_command $dir/$linklib"
+	    finalize_command="$finalize_command $dir/$linklib"
+	  else
+	    case "$compile_command " in
+	    *" -L$dir "*) ;;
+	    *) compile_command="$compile_command -L$dir";;
+	    esac
+	    compile_command="$compile_command -l$name"
+	    case "$finalize_command " in
+	    *" -L$dir "*) ;;
+	    *) finalize_command="$finalize_command -L$dir";;
+	    esac
+	    finalize_command="$finalize_command -l$name"
+	  fi
+	fi
+
+	# Add in any libraries that this one depends upon.
+	compile_command="$compile_command$dependency_libs"
+	finalize_command="$finalize_command$dependency_libs"
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case "$arg" in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    *.a | *.lib)
+      if test -n "$link_against_libtool_libs"; then
+	$echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+	exit 1
+      fi
+
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$outputname" in
+      lib*)
+	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	if test "$module" = no; then
+	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	  eval libname=\"$libname_spec\"
+	else
+	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	fi
+	;;
+      esac
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+	output_objdir="$objdir"
+      else
+	output_objdir="$output_objdir/$objdir"
+      fi
+
+      if test -n "$objs"; then
+	$echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+	exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+	 $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+	 exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  libext=al
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+	dependency_libs="$deplibs"
+
+	if test -n "$vinfo"; then
+	  $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+	fi
+
+	if test -n "$release"; then
+	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+	fi
+      else
+
+	# Parse the version information argument.
+	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	IFS="$save_ifs"
+
+	if test -n "$8"; then
+	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	current="$2"
+	revision="$3"
+	age="$4"
+
+	# Check that each of the things are valid numbers.
+	case "$current" in
+	0 | [1-9] | [1-9][0-9]*) ;;
+	*)
+	  $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case "$revision" in
+	0 | [1-9] | [1-9][0-9]*) ;;
+	*)
+	  $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case "$age" in
+	0 | [1-9] | [1-9][0-9]*) ;;
+	*)
+	  $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	if test $age -gt $current; then
+	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case "$version_type" in
+	none) ;;
+
+	irix)
+	  major=`expr $current - $age + 1`
+	  versuffix="$major.$revision"
+	  verstring="sgi$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test $loop != 0; do
+	    iface=`expr $revision - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="sgi$major.$iface:$verstring"
+	  done
+	  ;;
+
+	linux)
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  major=`expr $current - $age`
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test $loop != 0; do
+	    iface=`expr $current - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current";
+	  ;;
+
+	windows)
+	  # Like Linux, but with '-' rather than '.', since we only
+	  # want one extension on Windows 95.
+	  major=`expr $current - $age`
+	  versuffix="-$major-$age-$revision"
+	  ;;
+
+	*)
+	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  verstring="0.0"
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+	
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+	dependency_libs="$deplibs"
+	case "$host" in
+	*-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+	  # these systems don't actually have a c library (as such)!
+	  ;;
+	*)
+	  # Add libc to deplibs on all other systems.
+	  deplibs="$deplibs -lc"
+	  ;;
+	esac
+      fi
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $output_objdir; then
+	$show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+	$run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+      else
+	$show "$mkdir $output_objdir"
+	$run $mkdir $output_objdir
+	status=$?
+	if test $status -ne 0 && test ! -d $output_objdir; then
+	  exit $status
+	fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case "$deplibs_check_method" in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behaviour.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $rm conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $rm conftest
+	  $C_compiler -o conftest conftest.c $deplibs
+	  if test $? -eq 0 ; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	      # If $name is empty we are operating on a -L argument.
+	      if test "$name" != "" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		set dummy $deplib_matches
+		deplib_match=$2
+		if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		  newdeplibs="$newdeplibs $i"
+		else
+		  droppeddeps=yes
+		  echo
+		  echo "*** Warning: This library needs some functionality provided by $i."
+		  echo "*** I have the capability to make that library automatically link in when"
+		  echo "*** you link to this library.  But I can only do this if you have a"
+		  echo "*** shared version of the library, which you do not appear to have."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  else
+	    # Error occured in the first compile.  Let's try to salvage the situation:
+	    # Compile a seperate program for each library.
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	     # If $name is empty we are operating on a -L argument.
+	      if test "$name" != "" ; then
+		$rm conftest
+		$C_compiler -o conftest conftest.c $i
+		# Did it work?
+		if test $? -eq 0 ; then
+		  ldd_output=`ldd conftest`
+		  libname=`eval \\$echo \"$libname_spec\"`
+		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		  set dummy $deplib_matches
+		  deplib_match=$2
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    echo "*** Warning: This library needs some functionality provided by $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which you do not appear to have."
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  echo "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "***  make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+	  for a_deplib in $deplibs; do
+	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    # If $name is empty we are operating on a -L argument.
+	    if test "$name" != "" ; then
+	      libname=`eval \\$echo \"$libname_spec\"`
+	      for i in $lib_search_path; do
+		    potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		    for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potlib" 2>/dev/null \
+			 | grep " -> " >/dev/null; then
+			continue 
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+			case "$potliblink" in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+			 | sed 10q \
+			 | egrep "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		    done
+	      done
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		echo "*** Warning: This library needs some functionality provided by $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have."
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+	       -e 's/ -[LR][^ ]*//g' -e 's/[ 	]//g' |
+	     grep . >/dev/null; then
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    echo "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	# Get the real and link names of the library.
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	realname="$2"
+	shift; shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+
+	lib="$output_objdir/$realname"
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Ensure that we have .o objects for linkers which dislike .lo
+	# (e.g. aix) incase we are running --disable-static
+	for obj in $libobjs; do
+	  oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"`
+	  if test ! -f $oldobj; then
+	    $show "${LN_S} $obj $oldobj"
+	    $run ${LN_S} $obj $oldobj || exit $?
+	  fi
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+	if test -n "$whole_archive_flag_spec"; then
+	  if test -n "$convenience"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  fi
+	else
+	  gentop="$output_objdir/${outputname}x"
+	  $show "${rm}r $gentop"
+	  $run ${rm}r "$gentop"
+	  $show "mkdir $gentop"
+	  $run mkdir "$gentop"
+	  status=$?
+	  if test $status -ne 0 && test ! -d "$gentop"; then
+	    exit $status
+	  fi
+	  generated="$generated $gentop"
+	  
+	  for xlib in $convenience; do
+	    # Extract the objects.
+	    case "$xlib" in
+	    [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	    *) xabs=`pwd`"/$xlib" ;;
+	    esac
+	    xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	    xdir="$gentop/$xlib"
+
+	    $show "${rm}r $xdir"
+	    $run ${rm}r "$xdir"
+	    $show "mkdir $xdir"
+	    $run mkdir "$xdir"
+	    status=$?
+	    if test $status -ne 0 && test ! -d "$xdir"; then
+	      exit $status
+	    fi
+	    $show "(cd $xdir && $AR x $xabs)"
+	    $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	    libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+	  done
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linkopts="$linkopts $flag"
+	fi
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    eval cmds=\"$export_symbols_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd" || exit $?
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex"; then
+	      $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+	      $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+	fi
+
+	# Do each of the archive commands.
+	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	  eval cmds=\"$archive_expsym_cmds\"
+	else
+	  eval cmds=\"$archive_cmds\"
+	fi
+	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    *.lo | *.o | *.obj)
+      if test -n "$link_against_libtool_libs"; then
+	$echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+	exit 1
+      fi
+
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+	if test -n "$objs"; then
+	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+	  exit 1
+	fi
+	libobj="$output"
+	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Create the old-style object.
+      reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      test -z "$libobj" && exit 0
+
+      if test "$build_libtool_libs" != yes; then
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	$show "echo timestamp > $libobj"
+	$run eval "echo timestamp > $libobj" || exit $?
+	exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs"
+	output="$libobj"
+	eval cmds=\"$reload_cmds\"
+	IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+      else
+	# Just create a symlink.
+	$show $rm $libobj
+	$run $rm $libobj
+	$show "$LN_S $obj $libobj"
+	$run $LN_S $obj $libobj || exit $?
+      fi
+
+      exit 0
+      ;;
+
+    # Anything else should be a program.
+    *)
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+	if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+	   test "$dlopen_self_static" = unknown; then
+	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+	fi 
+      fi
+    
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$compile_rpath " in
+	  *" $libdir "*) ;;
+	  *) compile_rpath="$compile_rpath $libdir" ;;
+	  esac
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+	output_objdir="$objdir"
+      else
+	output_objdir="$output_objdir/$objdir"
+      fi
+
+      # Create the binary in the object directory, then wrap it.
+      if test ! -d $output_objdir; then
+	$show "$mkdir $output_objdir"
+	$run $mkdir $output_objdir
+	status=$?
+	if test $status -ne 0 && test ! -d $output_objdir; then
+	  exit $status
+	fi
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" = yes; then
+	if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	  dlsyms="${outputname}S.c"
+	else
+	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+	fi
+      fi
+
+      if test -n "$dlsyms"; then
+	case "$dlsyms" in
+	"") ;;
+	*.c)
+	  # Discover the nlist of each of the dlfiles.
+	  nlist="$output_objdir/${outputname}.nm"
+
+	  $show "$rm $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Parse the name list into a source file.
+	  $show "creating $output_objdir/$dlsyms"
+
+	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	  if test "$dlself" = yes; then
+	    $show "generating symbol list for \`$output'"
+
+	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+	    # Add our own program objects to the symbol list.
+	    progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	    for arg in $progfiles; do
+	      $show "extracting global C symbols from \`$arg'"
+	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	    done
+
+	    if test -n "$exclude_expsyms"; then
+	      $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+	    
+	    if test -n "$export_symbols_regex"; then
+	      $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    # Prepare the list of exported symbols
+	    if test -z "$export_symbols"; then
+	      export_symbols="$output_objdir/$output.exp"
+	      $run $rm $export_symbols
+	      $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	    else
+	      $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+	      $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+	      $run eval 'mv "$nlist"T "$nlist"'
+	    fi
+	  fi
+
+	  for arg in $dlprefiles; do
+	    $show "extracting global C symbols from \`$arg'"
+	    name=`echo "$arg" | sed -e 's%^.*/%%'`
+	    $run eval 'echo ": $name " >> "$nlist"'
+	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -z "$run"; then
+	    # Make sure we have at least an empty file.
+	    test -f "$nlist" || : > "$nlist"
+
+	    if test -n "$exclude_expsyms"; then
+	      egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	      $mv "$nlist"T "$nlist"
+	    fi
+
+	    # Try sorting and uniquifying the output.
+	    if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+	      :
+	    else
+	      grep -v "^: " < "$nlist" > "$nlist"S
+	    fi
+
+	    if test -f "$nlist"S; then
+	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+	    else
+	      echo '/* NONE */' >> "$output_objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+	    sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
+		-e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
+		  < "$nlist" >> "$output_objdir/$dlsyms"
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	  fi
+
+	  pic_flag_for_symtable=
+	  case "$host" in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+	    esac
+	  esac
+
+	  # Now compile the dynamic symbol file.
+	  $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+	  # Clean up the generated files.
+	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Transform the symbol file into the correct name.
+	  compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  ;;
+	*)
+	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	  exit 1
+	  ;;
+	esac
+      else
+	# We keep going just in case the user didn't refer to
+	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+	# really was required.
+
+	# Nullify the symbol file.
+	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+	# Replace the output file specification.
+	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	$show "$link_command"
+	$run eval "$link_command"
+	status=$?
+	
+	# Delete the generated files.
+	if test -n "$dlsyms"; then
+	  $show "$rm $output_objdir/${outputname}S.${objext}"
+	  $run $rm "$output_objdir/${outputname}S.${objext}"
+	fi
+
+	exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+	# We should set the shlibpath_var
+	rpath=
+	for dir in $temp_rpath; do
+	  case "$dir" in
+	  [\\/]* | [A-Za-z]:[\\/]*)
+	    # Absolute path.
+	    rpath="$rpath$dir:"
+	    ;;
+	  *)
+	    # Relative path: add a thisdir entry.
+	    rpath="$rpath\$thisdir/$dir:"
+	    ;;
+	  esac
+	done
+	temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+	
+	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+	$echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+      
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+	case "$0" in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+	esac
+	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+	esac
+	$rm $output
+	trap "$rm $output; exit 1" 1 2 15
+
+	$echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  link_against_libtool_libs='$link_against_libtool_libs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  echo >> $output "\
+  program=lt-'$outputname'
+  progdir=\"\$thisdir/$objdir\"
+  
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+	  echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if (cd \"\$thisdir\" && eval \$relink_command); then :
+      else
+	$rm \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+	else
+	  echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	*-*-cygwin* | *-*-mingw | *-*-os2*)
+	  # win32 systems need to use the prog path for dll
+	  # lookup to work
+	  $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+	  ;;
+	*)
+	  $echo >> $output "\
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+	chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	$show "${rm}r $gentop"
+	$run ${rm}r "$gentop"
+	$show "mkdir $gentop"
+	$run mkdir "$gentop"
+	status=$?
+	if test $status -ne 0 && test ! -d "$gentop"; then
+	  exit $status
+	fi
+	generated="$generated $gentop"
+	  
+	# Add in members from convenience archives.
+	for xlib in $addlibs; do
+	  # Extract the objects.
+	  case "$xlib" in
+	  [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	  *) xabs=`pwd`"/$xlib" ;;
+	  esac
+	  xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	  xdir="$gentop/$xlib"
+
+	  $show "${rm}r $xdir"
+	  $run ${rm}r "$xdir"
+	  $show "mkdir $xdir"
+	  $run mkdir "$xdir"
+	  status=$?
+	  if test $status -ne 0 && test ! -d "$xdir"; then
+	    exit $status
+	  fi
+	  $show "(cd $xdir && $AR x $xabs)"
+	  $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	  oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+	done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	eval cmds=\"$old_archive_from_new_cmds\"
+      else
+	# Ensure that we have .o objects in place incase we decided
+	# not to build a shared library, and have fallen back to building
+	# static libs even though --disable-static was passed!
+	for oldobj in $oldobjs; do
+	  if test ! -f $oldobj; then
+	    obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"`
+	    $show "${LN_S} $obj $oldobj"
+	    $run ${LN_S} $obj $oldobj || exit $?
+	  fi
+	done
+
+	eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      if test -n "$xrpath"; then
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	done
+	dependency_libs="$temp_xrpath $dependency_libs"
+      fi
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	  fi
+	  $rm $output
+	  $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+	done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest="$arg"
+	continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*) ;;
+
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest="$arg"
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	$echo "$modename: no file or destination specified" 1>&2
+      else
+	$echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+	$echo "$modename: \`$dest' is not a directory" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+    fi
+    case "$destdir" in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case "$file" in
+	*.lo) ;;
+	*)
+	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a | *.lib)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	library_names=
+	old_library=
+	# If there is no directory component, then add one.
+	case "$file" in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+	test "X$dir" = "X$file/" && dir=
+	dir="$dir$objdir"
+
+	# See the names of the shared library.
+	set dummy $library_names
+	if test -n "$2"; then
+	  realname="$2"
+	  shift
+	  shift
+
+	  # Install the shared library and build the symlinks.
+	  $show "$install_prog $dir/$realname $destdir/$realname"
+	  $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+	  test "X$dlname" = "X$realname" && dlname=
+
+	  if test $# -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    for linkname
+	    do
+	      test "X$dlname" = "X$linkname" && dlname=
+	      if test "$linkname" != "$realname"; then
+		$show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+		$run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+	      fi
+	    done
+	  fi
+
+	  if test -n "$dlname"; then
+	    # Install the dynamically-loadable library.
+	    $show "$install_prog $dir/$dlname $destdir/$dlname"
+	    $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  eval cmds=\"$postinstall_cmds\"
+	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+	fi
+
+	# Install the pseudo-library for information purposes.
+	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	instname="$dir/$name"i
+	$show "$install_prog $instname $destdir/$name"
+	$run eval "$install_prog $instname $destdir/$name" || exit $?
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case "$destfile" in
+	*.lo)
+	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+	  ;;
+	*.o | *.obj)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	if test -n "$destfile"; then
+	  $show "$install_prog $file $destfile"
+	  $run eval "$install_prog $file $destfile" || exit $?
+	fi
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+	  $show "$install_prog $staticobj $staticdest"
+	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	fi
+	exit 0
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Do a test to see if this is really a libtool program.
+	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  link_against_libtool_libs=
+	  relink_command=
+
+	  # If there is no directory component, then add one.
+	  case "$file" in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Check the variables that should have been set.
+	  if test -z "$link_against_libtool_libs"; then
+	    $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+	    exit 1
+	  fi
+
+	  finalize=yes
+	  for lib in $link_against_libtool_libs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      # If there is no directory component, then add one.
+	      case "$lib" in
+	      */* | *\\*) . $lib ;;
+	      *) . ./$lib ;;
+	      esac
+	    fi
+	    libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+	      finalize=no
+	    fi
+	  done
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    if test "$finalize" = yes && test -z "$run"; then
+	      tmpdir="/tmp"
+	      test -n "$TMPDIR" && tmpdir="$TMPDIR"
+	      tmpdir="$tmpdir/libtool-$$"
+	      if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+	      else
+		$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+		continue
+	      fi
+	      outputname="$tmpdir/$file"
+	      # Replace the output file specification.
+	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	      $show "$relink_command"
+	      if $run eval "$relink_command"; then :
+	      else
+		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+		${rm}r "$tmpdir"
+		continue
+	      fi
+	      file="$outputname"
+	    else
+	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
+	    fi
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	$show "$install_prog$stripme $file $destfile"
+	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+	test -n "$outputname" && ${rm}r "$tmpdir"
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  eval cmds=\"$finish_cmds\"
+	  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+	  done
+	  IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit 0
+
+    echo "----------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "If you ever happen to want to link against installed libraries"
+    echo "in a given directory, LIBDIR, you must either use libtool, and"
+    echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+    echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+	# If there is no directory component, then add one.
+	case "$file" in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	  exit 1
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case "$file" in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      # Export the shlibpath_var.
+      eval "export $shlibpath_var"
+
+      # Restore saved enviroment variables
+      if test "${save_LC_ALL+set}" = set; then
+	LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+	LANG="$save_LANG"; export LANG
+      fi
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+      $echo "export $shlibpath_var"
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  . $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $dir/$n"
+	    test "X$n" = "X$dlname" && dlname=
+	  done
+	  test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+	  test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+	  $show "$rm $rmfiles"
+	  $run $rm $rmfiles
+
+	  if test -n "$library_names"; then
+	    # Do each command in the postuninstall commands.
+	    eval cmds=\"$postuninstall_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd"
+	    done
+	    IFS="$save_ifs"
+	  fi
+
+	  if test -n "$old_library"; then
+	    # Do each command in the old_postuninstall commands.
+	    eval cmds=\"$old_postuninstall_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd"
+	    done
+	    IFS="$save_ifs"
+	  fi
+
+	  # FIXME: should reinstall the best remaining shared library.
+	fi
+	;;
+
+      *.lo)
+	if test "$build_old_libs" = yes; then
+	  oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+	  rmfiles="$rmfiles $dir/$oldobj"
+	fi
+	$show "$rm $rmfiles"
+	$run $rm $rmfiles
+	;;
+
+      *)
+	$show "$rm $rmfiles"
+	$run $rm $rmfiles
+	;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+		    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+		    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+		    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/src/shapelib/makefile.vc b/src/shapelib/makefile.vc
new file mode 100644
index 0000000..0819a21
--- /dev/null
+++ b/src/shapelib/makefile.vc
@@ -0,0 +1,55 @@
+
+#CFLAGS	=	/DSHPAPI_CALL=__stdcall
+
+default:	all
+
+all:	shpcreate.exe shpadd.exe shpdump.exe shprewind.exe dbfcreate.exe \
+	dbfadd.exe dbfdump.exe shptest.exe shptreedump.exe shapelib.dll
+
+shpopen.obj:	shpopen.c shapefil.h
+	$(CC) $(CFLAGS) -c shpopen.c
+
+shptree.obj:	shptree.c shapefil.h
+	$(CC) $(CFLAGS) -c shptree.c
+
+dbfopen.obj:	dbfopen.c shapefil.h
+	$(CC) $(CFLAGS) -c dbfopen.c
+
+shpcreate.exe:	shpcreate.c shpopen.obj
+	$(CC) $(CFLAGS) shpcreate.c shpopen.obj $(LINKOPT) -o shpcreate
+
+shpadd.exe:		shpadd.c shpopen.obj
+	$(CC) $(CFLAGS) shpadd.c shpopen.obj $(LINKOPT)
+
+shpdump.exe:	shpdump.c shpopen.obj
+	$(CC) $(CFLAGS) shpdump.c shpopen.obj $(LINKOPT)
+
+shprewind.exe:	shprewind.c shpopen.obj
+	$(CC) $(CFLAGS) shprewind.c shpopen.obj $(LINKOPT)
+
+dbfcreate.exe:	dbfcreate.c dbfopen.obj
+	$(CC) $(CFLAGS) dbfcreate.c dbfopen.obj $(LINKOPT)
+
+dbfadd.exe:	dbfadd.c dbfopen.obj
+	$(CC) $(CFLAGS) dbfadd.c dbfopen.obj $(LINKOPT)
+
+dbfdump.exe:	dbfdump.c dbfopen.obj
+	$(CC) $(CFLAGS) dbfdump.c dbfopen.obj $(LINKOPT)
+
+shptest.exe:	shptest.c shpopen.obj
+	$(CC) $(CFLAGS) shptest.c shpopen.obj $(LINKOPT)
+
+shputils.exe:	shputils.c shpopen.obj dbfopen.obj
+	$(CC) $(CFLAGS) shputils.c shpopen.obj dbfopen.obj $(LINKOPT) 
+
+shptreedump.exe:	shptreedump.c shptree.obj shpopen.obj
+	$(CC) $(CFLAGS) shptreedump.c shptree.obj shpopen.obj $(LINKOPT)
+
+clean:
+	-del *.obj dbfdump dbfcreate dbfadd shpdump shpcreate shpadd shputils
+	-del *.lib
+	-del *.dll
+
+shapelib.dll:    shpopen.obj dbfopen.obj shptree.obj shapelib.def
+	link /dll /def:shapelib.def /out:shapelib.dll /implib:shapelib.lib \
+		shpopen.obj dbfopen.obj shptree.obj 
diff --git a/src/shapelib/makeshape.sh b/src/shapelib/makeshape.sh
new file mode 100755
index 0000000..6e5f271
--- /dev/null
+++ b/src/shapelib/makeshape.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+#
+#	Use example programs to create a very simple dataset that
+#	should display in ARCView II.
+#
+
+shpcreate test polygon
+dbfcreate test.dbf -s Description 30 -n TestInt 6 0 -n TestDouble 16 5
+
+shpadd test 0 0 100 0 100 100 0 100 0 0 + 20 20 20 30 30 30 20 20
+dbfadd test.dbf "Square with triangle missing" 1.5 2.5
+
+shpadd test 150 150 160 150 180 170 150 150
+dbfadd test.dbf "Smaller triangle" 100 1000.25
+
+shpadd test 150 150 160 150 180 170 150 150
+dbfadd test.dbf "" "" ""
+
+shpdump test.shp
+dbfdump test.dbf
diff --git a/src/shapelib/mkinstalldirs b/src/shapelib/mkinstalldirs
new file mode 100644
index 0000000..5e17cd3
--- /dev/null
+++ b/src/shapelib/mkinstalldirs
@@ -0,0 +1,38 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp"
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+  	  errstatus=$lasterr
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/src/shapelib/shapefil.h b/src/shapelib/shapefil.h
new file mode 100644
index 0000000..b47660b
--- /dev/null
+++ b/src/shapelib/shapefil.h
@@ -0,0 +1,507 @@
+#ifndef _SHAPEFILE_H_INCLUDED
+#define _SHAPEFILE_H_INCLUDED
+
+/******************************************************************************
+ * $Id: shapefil.h,v 1.1 2006/11/10 21:48:10 tvrusso Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Primary include file for Shapelib.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shapefil.h,v $
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.26  2002/09/29 00:00:08  warmerda
+ * added FTLogical and logical attribute read/write calls
+ *
+ * Revision 1.25  2002/05/07 13:46:30  warmerda
+ * added DBFWriteAttributeDirectly().
+ *
+ * Revision 1.24  2002/04/10 16:59:54  warmerda
+ * added SHPRewindObject
+ *
+ * Revision 1.23  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.22  2002/01/15 14:32:00  warmerda
+ * try to improve SHPAPI_CALL docs
+ *
+ * Revision 1.21  2001/11/01 16:29:55  warmerda
+ * move pabyRec into SHPInfo for thread safety
+ *
+ * Revision 1.20  2001/07/20 13:06:02  warmerda
+ * fixed SHPAPI attribute for SHPTreeFindLikelyShapes
+ *
+ * Revision 1.19  2001/05/31 19:20:13  warmerda
+ * added DBFGetFieldIndex()
+ *
+ * Revision 1.18  2001/05/31 18:15:40  warmerda
+ * Added support for NULL fields in DBF files
+ *
+ * Revision 1.17  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.16  2000/09/25 14:15:59  warmerda
+ * added DBFGetNativeFieldType()
+ *
+ * Revision 1.15  2000/02/16 16:03:51  warmerda
+ * added null shape support
+ *
+ * Revision 1.14  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.13  1999/06/02 18:24:21  warmerda
+ * added trimming code
+ *
+ * Revision 1.12  1999/06/02 17:56:12  warmerda
+ * added quad'' subnode support for trees
+ *
+ * Revision 1.11  1999/05/18 19:11:11  warmerda
+ * Added example searching capability
+ *
+ * Revision 1.10  1999/05/18 17:49:38  warmerda
+ * added initial quadtree support
+ *
+ * Revision 1.9  1999/05/11 03:19:28  warmerda
+ * added new Tuple api, and improved extension handling - add from candrsn
+ *
+ * Revision 1.8  1999/03/23 17:22:27  warmerda
+ * Added extern "C" protection for C++ users of shapefil.h.
+ *
+ * Revision 1.7  1998/12/31 15:31:07  warmerda
+ * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options.
+ *
+ * Revision 1.6  1998/12/03 15:48:15  warmerda
+ * Added SHPCalculateExtents().
+ *
+ * Revision 1.5  1998/11/09 20:57:16  warmerda
+ * Altered SHPGetInfo() call.
+ *
+ * Revision 1.4  1998/11/09 20:19:33  warmerda
+ * Added 3D support, and use of SHPObject.
+ *
+ * Revision 1.3  1995/08/23 02:24:05  warmerda
+ * Added support for reading bounds.
+ *
+ * Revision 1.2  1995/08/04  03:17:39  warmerda
+ * Added header.
+ *
+ */
+
+#include <stdio.h>
+
+#ifdef USE_DBMALLOC
+#include <dbmalloc.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************************************************************/
+/*                        Configuration options.                        */
+/************************************************************************/
+
+/* -------------------------------------------------------------------- */
+/*      Should the DBFReadStringAttribute() strip leading and           */
+/*      trailing white space?                                           */
+/* -------------------------------------------------------------------- */
+#define TRIM_DBF_WHITESPACE
+
+/* -------------------------------------------------------------------- */
+/*      Should we write measure values to the Multipatch object?        */
+/*      Reportedly ArcView crashes if we do write it, so for now it     */
+/*      is disabled.                                                    */
+/* -------------------------------------------------------------------- */
+#define DISABLE_MULTIPATCH_MEASURE
+
+/* -------------------------------------------------------------------- */
+/*      SHPAPI_CALL                                                     */
+/*                                                                      */
+/*      The following two macros are present to allow forcing           */
+/*      various calling conventions on the Shapelib API.                */
+/*                                                                      */
+/*      To force __stdcall conventions (needed to call Shapelib         */
+/*      from Visual Basic and/or Dephi I believe) the makefile could    */
+/*      be modified to define:                                          */
+/*                                                                      */
+/*        /DSHPAPI_CALL=__stdcall                                       */
+/*                                                                      */
+/*      If it is desired to force export of the Shapelib API without    */
+/*      using the shapelib.def file, use the following definition.      */
+/*                                                                      */
+/*        /DSHAPELIB_DLLEXPORT                                          */
+/*                                                                      */
+/*      To get both at once it will be necessary to hack this           */
+/*      include file to define:                                         */
+/*                                                                      */
+/*        #define SHPAPI_CALL __declspec(dllexport) __stdcall           */
+/*        #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall        */
+/*                                                                      */
+/*      The complexity of the situtation is partly caused by the        */
+/*      peculiar requirement of Visual C++ that __stdcall appear        */
+/*      after any "*"'s in the return value of a function while the     */
+/*      __declspec(dllexport) must appear before them.                  */
+/* -------------------------------------------------------------------- */
+
+#ifdef SHAPELIB_DLLEXPORT
+#  define SHPAPI_CALL __declspec(dllexport)
+#  define SHPAPI_CALL1(x)  __declspec(dllexport) x
+#endif
+
+#ifndef SHPAPI_CALL
+#  define SHPAPI_CALL
+#endif
+
+#ifndef SHPAPI_CALL1
+#  define SHPAPI_CALL1(x)      x SHPAPI_CALL
+#endif
+    
+/************************************************************************/
+/*                             SHP Support.                             */
+/************************************************************************/
+typedef	struct
+{
+    FILE        *fpSHP;
+    FILE	*fpSHX;
+
+    int		nShapeType;				/* SHPT_* */
+    
+    int		nFileSize;				/* SHP file */
+
+    int         nRecords;
+    int		nMaxRecords;
+    int		*panRecOffset;
+    int		*panRecSize;
+
+    double	adBoundsMin[4];
+    double	adBoundsMax[4];
+
+    int		bUpdated;
+
+    unsigned char *pabyRec;
+    int         nBufSize;
+} SHPInfo;
+
+typedef SHPInfo * SHPHandle;
+
+/* -------------------------------------------------------------------- */
+/*      Shape types (nSHPType)                                          */
+/* -------------------------------------------------------------------- */
+#define SHPT_NULL	0
+#define SHPT_POINT	1
+#define SHPT_ARC	3
+#define SHPT_POLYGON	5
+#define SHPT_MULTIPOINT	8
+#define SHPT_POINTZ	11
+#define SHPT_ARCZ	13
+#define SHPT_POLYGONZ	15
+#define SHPT_MULTIPOINTZ 18
+#define SHPT_POINTM	21
+#define SHPT_ARCM	23
+#define SHPT_POLYGONM	25
+#define SHPT_MULTIPOINTM 28
+#define SHPT_MULTIPATCH 31
+
+
+/* -------------------------------------------------------------------- */
+/*      Part types - everything but SHPT_MULTIPATCH just uses           */
+/*      SHPP_RING.                                                      */
+/* -------------------------------------------------------------------- */
+
+#define SHPP_TRISTRIP	0
+#define SHPP_TRIFAN	1
+#define SHPP_OUTERRING	2
+#define SHPP_INNERRING	3
+#define SHPP_FIRSTRING	4
+#define SHPP_RING	5
+
+/* -------------------------------------------------------------------- */
+/*      SHPObject - represents on shape (without attributes) read       */
+/*      from the .shp file.                                             */
+/* -------------------------------------------------------------------- */
+typedef struct
+{
+    int		nSHPType;
+
+    int		nShapeId; /* -1 is unknown/unassigned */
+
+    int		nParts;
+    int		*panPartStart;
+    int		*panPartType;
+    
+    int		nVertices;
+    double	*padfX;
+    double	*padfY;
+    double	*padfZ;
+    double	*padfM;
+
+    double	dfXMin;
+    double	dfYMin;
+    double	dfZMin;
+    double	dfMMin;
+
+    double	dfXMax;
+    double	dfYMax;
+    double	dfZMax;
+    double	dfMMax;
+} SHPObject;
+
+/* -------------------------------------------------------------------- */
+/*      SHP API Prototypes                                              */
+/* -------------------------------------------------------------------- */
+SHPHandle SHPAPI_CALL
+      SHPOpen( const char * pszShapeFile, const char * pszAccess );
+SHPHandle SHPAPI_CALL
+      SHPCreate( const char * pszShapeFile, int nShapeType );
+void SHPAPI_CALL
+      SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
+                  double * padfMinBound, double * padfMaxBound );
+
+SHPObject SHPAPI_CALL1(*)
+      SHPReadObject( SHPHandle hSHP, int iShape );
+int SHPAPI_CALL
+      SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
+
+void SHPAPI_CALL
+      SHPDestroyObject( SHPObject * psObject );
+void SHPAPI_CALL
+      SHPComputeExtents( SHPObject * psObject );
+SHPObject SHPAPI_CALL1(*)
+      SHPCreateObject( int nSHPType, int nShapeId,
+                       int nParts, int * panPartStart, int * panPartType,
+                       int nVertices, double * padfX, double * padfY,
+                       double * padfZ, double * padfM );
+SHPObject SHPAPI_CALL1(*)
+      SHPCreateSimpleObject( int nSHPType, int nVertices,
+                             double * padfX, double * padfY, double * padfZ );
+
+int SHPAPI_CALL
+      SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
+
+void SHPAPI_CALL
+      SHPClose( SHPHandle hSHP );
+
+const char SHPAPI_CALL1(*)
+      SHPTypeName( int nSHPType );
+const char SHPAPI_CALL1(*)
+      SHPPartTypeName( int nPartType );
+
+/* -------------------------------------------------------------------- */
+/*      Shape quadtree indexing API.                                    */
+/* -------------------------------------------------------------------- */
+
+/* this can be two or four for binary or quad tree */
+#define MAX_SUBNODE	4
+
+typedef struct shape_tree_node
+{
+    /* region covered by this node */
+    double	adfBoundsMin[4];
+    double	adfBoundsMax[4];
+
+    /* list of shapes stored at this node.  The papsShapeObj pointers
+       or the whole list can be NULL */
+    int		nShapeCount;
+    int		*panShapeIds;
+    SHPObject   **papsShapeObj;
+
+    int		nSubNodes;
+    struct shape_tree_node *apsSubNode[MAX_SUBNODE];
+    
+} SHPTreeNode;
+
+typedef struct
+{
+    SHPHandle   hSHP;
+    
+    int		nMaxDepth;
+    int		nDimension;
+    
+    SHPTreeNode	*psRoot;
+} SHPTree;
+
+SHPTree SHPAPI_CALL1(*)
+      SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
+                     double *padfBoundsMin, double *padfBoundsMax );
+void    SHPAPI_CALL
+      SHPDestroyTree( SHPTree * hTree );
+
+int	SHPAPI_CALL
+      SHPWriteTree( SHPTree *hTree, const char * pszFilename );
+SHPTree SHPAPI_CALL
+      SHPReadTree( const char * pszFilename );
+
+int	SHPAPI_CALL
+      SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
+int	SHPAPI_CALL
+      SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
+int	SHPAPI_CALL
+      SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
+
+void 	SHPAPI_CALL
+      SHPTreeTrimExtraNodes( SHPTree * hTree );
+
+int    SHPAPI_CALL1(*)
+      SHPTreeFindLikelyShapes( SHPTree * hTree,
+                               double * padfBoundsMin,
+                               double * padfBoundsMax,
+                               int * );
+int     SHPAPI_CALL
+      SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
+
+/************************************************************************/
+/*                             DBF Support.                             */
+/************************************************************************/
+typedef	struct
+{
+    FILE	*fp;
+
+    int         nRecords;
+
+    int		nRecordLength;
+    int		nHeaderLength;
+    int		nFields;
+    int		*panFieldOffset;
+    int		*panFieldSize;
+    int		*panFieldDecimals;
+    char	*pachFieldType;
+
+    char	*pszHeader;
+
+    int		nCurrentRecord;
+    int		bCurrentRecordModified;
+    char	*pszCurrentRecord;
+    
+    int		bNoHeader;
+    int		bUpdated;
+} DBFInfo;
+
+typedef DBFInfo * DBFHandle;
+
+typedef enum {
+  FTString,
+  FTInteger,
+  FTDouble,
+  FTLogical,
+  FTInvalid
+} DBFFieldType;
+
+#define XBASE_FLDHDR_SZ       32
+
+DBFHandle SHPAPI_CALL
+      DBFOpen( const char * pszDBFFile, const char * pszAccess );
+DBFHandle SHPAPI_CALL
+      DBFCreate( const char * pszDBFFile );
+
+int	SHPAPI_CALL
+      DBFGetFieldCount( DBFHandle psDBF );
+int	SHPAPI_CALL
+      DBFGetRecordCount( DBFHandle psDBF );
+int	SHPAPI_CALL
+      DBFAddField( DBFHandle hDBF, const char * pszFieldName,
+                   DBFFieldType eType, int nWidth, int nDecimals );
+
+DBFFieldType SHPAPI_CALL
+      DBFGetFieldInfo( DBFHandle psDBF, int iField, 
+                       char * pszFieldName, int * pnWidth, int * pnDecimals );
+
+int SHPAPI_CALL
+      DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
+
+int 	SHPAPI_CALL
+      DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
+double 	SHPAPI_CALL
+      DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
+const char SHPAPI_CALL1(*)
+      DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
+const char SHPAPI_CALL1(*)
+      DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField );
+int     SHPAPI_CALL
+      DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
+
+int SHPAPI_CALL
+      DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField, 
+                                int nFieldValue );
+int SHPAPI_CALL
+      DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
+                               double dFieldValue );
+int SHPAPI_CALL
+      DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
+                               const char * pszFieldValue );
+int SHPAPI_CALL
+     DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
+
+int SHPAPI_CALL
+     DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField,
+			       const char lFieldValue);
+int SHPAPI_CALL
+     DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
+                               void * pValue );
+const char SHPAPI_CALL1(*)
+      DBFReadTuple(DBFHandle psDBF, int hEntity );
+int SHPAPI_CALL
+      DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
+
+DBFHandle SHPAPI_CALL
+      DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
+ 
+void	SHPAPI_CALL
+      DBFClose( DBFHandle hDBF );
+char    SHPAPI_CALL
+      DBFGetNativeFieldType( DBFHandle hDBF, int iField );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef _SHAPEFILE_H_INCLUDED */
diff --git a/src/shapelib/shapelib.def b/src/shapelib/shapelib.def
new file mode 100644
index 0000000..01964c4
--- /dev/null
+++ b/src/shapelib/shapelib.def
@@ -0,0 +1,42 @@
+LIBRARY shapelib
+EXPORTS SHPOpen
+	SHPCreate
+	SHPGetInfo
+	SHPReadObject
+	SHPWriteObject
+	SHPDestroyObject
+	SHPComputeExtents
+	SHPCreateObject
+	SHPCreateSimpleObject
+	SHPClose
+	SHPTypeName
+	SHPPartTypeName
+	SHPCreateTree
+	SHPDestroyTree
+	SHPTreeAddShapeId
+	SHPTreeTrimExtraNodes
+	SHPTreeFindLikelyShapes
+	SHPCheckBoundsOverlap
+	DBFOpen
+	DBFCreate
+	DBFGetFieldCount
+	DBFGetRecordCount
+	DBFAddField
+	DBFGetFieldInfo
+	DBFReadIntegerAttribute
+	DBFReadDoubleAttribute
+	DBFReadStringAttribute
+	DBFWriteIntegerAttribute
+	DBFWriteDoubleAttribute
+	DBFWriteStringAttribute
+	DBFReadTuple
+	DBFWriteTuple
+	DBFCloneEmpty
+	DBFClose
+	DBFWriteNULLAttribute
+	DBFGetFieldIndex
+	DBFIsAttributeNULL
+	DBFWriteLogicalAttribute
+	DBFReadLogicalAttribute
+
+
diff --git a/src/shapelib/shapelib.html b/src/shapelib/shapelib.html
new file mode 100644
index 0000000..4372d1d
--- /dev/null
+++ b/src/shapelib/shapelib.html
@@ -0,0 +1,334 @@
+<html>
+<head>
+<title>Shapefile C Library V1.2</title>
+</head>
+
+<body>
+<h1>Shapefile C Library V1.2</h1>
+
+<h2>Purpose</h2>
+
+The Shapefile C Library provides the ability to write simple C programs
+for reading, writing and updating (to a limited extent) ESRI Shapefiles,
+and the associated attribute file (.dbf).<p>
+
+<h2>Manifest</h2>
+
+<ul>
+<li> <b>shapelib.html</b>: This file - general documentation on the 
+Shapefile C Library.<p>
+
+<li> <b><a href="shp_api.html">shp_api.html</a></b>: Documentation 
+for the API for accessing the .shp/.shx files. <p>
+
+<li> <b><a href="dbf_api.html">dbf_api.html</a></b>: Documentation 
+for the API for accessing the .dbf attribute files. <p>
+
+<li> <b>shpopen.c</b>: C code for access to .shp/.shx vertex files.<p>
+
+<li> <b>dbfopen.c</b>: C code for access to .dbf attribute file.<p>
+
+<li> <b>shapefil.h</b>:  Include file defining all the services of dbfopen.c 
+and shpopen.c.<p>
+
+<li> <b>contrib/</b>: A directory of "in progress" contributed programs
+from Carl Anderson.<p>
+
+<li> <b>dbfcreate.c</b>: Simple example program for creating a new .dbf file.
+     <p>
+
+<li> <b>dbfadd.c</b>: 
+	Simple example program for adding a record to a .dbf file.<p>
+
+<li> <b>dbfdump.c</b>: Simple example program for displaying the contents of
+		  a .dbf file.<p>
+
+<li> <b>shpcreate.c</b>: Simple example program for creating a new .shp and 
+.shx file.<p>
+
+<li> <b>shpadd.c</b>: Simple example program for adding a shape to an existing
+		  shape file.<p>
+
+<li> <b>shpdump.c</b>: Simple program for dumping all the vertices in a 
+		shapefile with an indicating of the parts.<p>
+
+<li> <b>shputils.c</b>: Complex contributed program capable of clipping and 
+		  appending
+                  shapefiles as well as a few other things.  Type shputils
+                  after building to get a full usage message.<p>
+
+<li> <b>Makefile</b>: A simple makefile to compile the library and example 
+		  programs.<p>
+
+<li> <b>makeshape.sh</b>: A simple script for running some of the example 
+programs.<p>
+
+<li> <b>shptest.c</b>: A simple test harnass to generate each of the supported
+		  types of shapefiles. <p>
+
+
+<li> <b>shptree.c</b>: Implements a simple quadtree algorithm for fast
+spatial searches of shapefiles.<p>
+
+<li> <b>shptreedump.c</b>: A simple mainly showing information on quad
+trees build using the quad tree api.<p>
+
+<li> <b>stream1.sh</b> - A test script, which should produce stream1.out.  
+Note this will only work if you have the example data downloaded.<p>
+
+<li> <b>stream1.out</b>: Expected output of stream1.sh test script.<p>
+
+<li> <b>stream2.sh</b>: A test script, which should produce stream2.out.<p>
+
+<li> <b>stream2.out</b>: Expected output of stream2.sh test script.<p>
+
+<li> <b>pyshapelib-0.1</b>: Prototype contributed Python bindings.<p>
+
+</ul>
+
+<h2>What is a Shapefile?</h2>
+
+If you don't know, you probably don't need this library.  The Shapefile
+format is a new working and interchange format promulagated by ESRI 
+(http://www.esri.com/) for simple vector data with attributes.  It is
+apparently the only file format that can be edited in ARCView 2/3, and can
+also be exported and imported in Arc/Info.  <p>
+
+An excellent white paper on the shapefile format is available from ESRI,
+but it is .pdf format, so you will need Adobe Acrobat to browse it.<p>
+
+The file format actually consists of three files.<p>
+
+<pre>
+XXX.shp - holds the actual vertices.
+XXX.shx - hold index data pointing to the structures in the .shp file.
+XXX.dbf - holds the attributes in xBase (dBase) format.  
+</pre>
+
+<h2>Release Notes</h2>
+
+To get notification of new releases of Shapelib <i>subscribe</i> to 
+the project at www.freshmeat.net.  This is currently the only reliable
+way of finding out about new releases since there is no shapelib specific
+mailing list.<p>
+
+<b>Release 1.2.10</b>: Added SHPRewindObject() function, and shprewind utility
+program.  Added FTLogical, DBFReadLogicalAttribute() and 
+DBFWriteLogicalAttribute() (thanks to Olek Neyman). <p>
+
+<b>Release 1.2.9</b>: Good support for reading and writing NULL fields 
+in .dbf files, good support for NULL shapes and addition of the
+DBFGetFieldIndex() functions (all contributed by Jim Matthews).<p>
+
+An upgraded shputils.c has been contributed by Bill Miller.  Daniel 
+Morissette contributed DBFGetNativeFieldType().  Better error checking
+for disk errors in dbfopen.c.  Various other bug fixes and safety improvements.
+<p>
+
+<b>Release 1.2.8</b>: Added hacked libtool support (supplied by Jan)
+and "rpm ready" install logic.<p>
+
+<b>Release 1.2.7</b>: Fix record size (was 4 bytes too long).  Modify 
+SHPReadObject() to handle null shapes properly.  Use atof() instead of
+sscanf().  Support .DBF as well as .dbf.<p>
+
+<b>Release 1.2.6</b>: Now available under old MIT style license, or at the
+users option, LGPL.  Added the contrib directory of stuff from Carl Anderson
+and the shptree.c API for quadtree based spatial searches.<p>
+
+<b>Release 1.2.5</b>: SHPOpen() now forcably uses "rb" or "r+b" access string
+to avoid common mistakes on Windows.  Also fixed a serious bug with .dbf
+files with a 'F' field type.<p>
+
+<b>Release 1.2.4</b>: DBFOpen() will now automatically translate a .shp
+extension to .dbf for convenience.  SHPOpen() will try datasets with lower
+and uppercase extension.  DBFAddField() now returns the field number,
+not TRUE/FALSE.<p>
+
+<b>Release 1.2.3</b>: Disable writing measures to multi-patches as ArcView
+seems to puke on them (as reported by Monika Sester).  Add white space 
+trimming, and string/numeric attribute interchangability in DBF API
+as suggested by Steve Lime.  Dbfdump was updated to include several 
+reporting options.<p>
+
+<b>Release 1.2.2</b>: Added proper support for multipatch (reading and 
+writing) - this release just for testing purposes.<p>
+
+<b>Release 1.2</b> is mostly a rewrite of the .shp/.shx access API to account 
+for ArcView 3.x 3D shapes, and to encapsulate the shapes in a structure.  
+Existing code using the shapefile library will require substantial changes
+to use release 1.2.<p>
+
+<b>Release V1.1</b> has been built on a number of platforms, and used by a 
+number of people successfully.  V1.1 is the first release with the xBase API 
+documentation.<p>
+
+
+<h2>Maintainer</h2>
+
+This library is maintained by me (Frank Warmerdam) on my own time.  Please 
+send me bug patches and suggestions for the library.  Email can be sent to 
+warmerdam at pobox.com.<p>
+
+The current status of the Shapelib code can be found at
+<a href="http://pobox.com/~warmerdam/root/projects/shapelib/">
+http://pobox.com/~warmerdam/root/projects/shapelib/</a>.  To find out about 
+new releases of Shapelib, select the "Subscribe to new releases" option 
+from the link at 
+<a href="http://freshmeat.net/projects/shapelib/">Freshmeat</a>.<p>
+
+The shputils.c module was contributed by Bill Miller (NC-DOT) who can be
+reached at bmiller at doh.dot.state.nc.us.  I had to modify it substantially
+to work with the 1.2 API, and I am not sure that it works as well as it
+did when it was originally provided by Bill.<p>
+
+<h2>Credits</h2>
+
+I didn't start this section anywhere near soon enough, so alot of earlier
+contributors to Shapelib are lost in pre-history.
+
+<ul>
+<li> Bill Miller (NY-DOT) for shputils.c
+<li> Carl Anderson for the contents of the contrib directory, and 
+the "tuple" additions to dbfopen.c.
+<li> Andrea Giacomelli for patches for dbfopen.c.
+<li> Doug Matthews for portability improvements.
+<li> Jan-Oliver Wagner for convincing me to make it available under LGPL,
+shared library support, and various other patches.
+<li> Dennis Christopher (of Avenza) for testing and bug fixes.
+<li> Miko Syrj� (of 3D-system Oy) for a record size bug fix.
+<li> Steven Lime and Curtis Hill for help with NULL shapes.
+<li> Jim Matthews for support of NULL attributes in dbf files.
+<li> <a href="http://www.pcigeomatics.com/">PCI Geomatics</a> who let me
+release a modified version of their shapefile code in the beginning and
+who hosted shapelib for years.
+</ul>
+
+<h2>In Memorium</h2>
+
+I would like to dedicate Shapelib to the memory of Sol Katz.  While I never
+met him in person, his generous contributions to the GIS community took 
+many forms, including free distribution of a variety of GIS translators
+with source.  The fact that he used this Shapelib in some of his utilities, 
+and thanked me was a great encouragement to me.  I hope I can do his memory 
+honour by trying to contribute in a similar fashion.<p>
+
+<h2>Portability</h2>
+
+The Shapefile C Library should port easily to 32bit systems with ANSI C
+compilers.  It should work on 64 bit architectures (such as the DEC AXP).<p>
+
+Care should also be taken to pass the binary access flag into SHPOpen()
+and DBFOpen() when operating on systems with special text file translation
+such as MSDOS.<p>
+
+The shputils.c module is contributed, and may not take the same approach
+to portability as the rest of the package.<p>
+
+On Linux, and most unix systems it should be possible to build and 
+install shapefile support as a shared library using the "lib" and "lib_install"
+targets of the Makefile.  Note that this Makefile doesn't use autoconf
+mechanisms and will generally require some hand tailoring for your environment.
+
+<h2>Limitations</h2>
+
+<ul>
+
+<li> You can't modify the vertices of existing structures (though you 
+   can update the attributes of existing structures, and create new 
+   structures).<p>
+
+<li> Not written in such a way as to be particularly fast.  This is 
+particularly true of the 1.2 API.  For applications more concerned with
+speed it may be worth using the V1.1 API.<p>
+
+<li> Doesn't set the last access time properly in the .dbf files.<p>
+
+<li> There is no way to synchronize information to the file except to close it.
+<p>
+
+<li> Poor error checking and reporting.<p>
+
+<li> Not professionally supported (well it can be, if you want to pay).<p>
+
+<li> Some aspects of xBase files not supported, though I believe they are
+not used by ESRI.<p>
+
+<li> The application must keep the .dbf file in sync with the .shp/.shx
+files through appropriate use of the DBF and SHP APIs.<p>
+
+<li> No support for the undocumented .sbn/.sbx spatial index files.<p>
+
+</ul>
+
+<h2>Copyright</h2>
+
+The source for the Shapefile C Library is (c) 1998 Frank Warmerdam, 
+and released under the following conditions.  The intent is that anyone
+can do anything with the code, but that I do not assume any liability, nor
+express any warranty for this code.  <p>
+
+As of Shapelib 1.2.6 the core portions of the library are made available
+under two possible licenses.  The licensee can choose to use the code
+under either the Library GNU Public License (LGPL) described in 
+LICENSE.LGPL or under the following MIT style license.  Any files in
+the Shapelib distribution without explicit copyright license terms
+(such as this documentation, the Makefile and so forth) should be
+considered to have the following licensing terms.  Some auxilary portions
+of Shapelib, notably some of the components in the contrib directory
+come under slightly different license restrictions.  Check the source
+files that you are actually using for conditions.<p>
+
+<h3>Default License Terms</h3>
+
+<quote>
+Copyright (c) 1999, Frank Warmerdam<p>
+
+This software is available under the following "MIT Style" license,
+or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+option is discussed in more detail in shapelib.html.<p>
+ 
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:<p>
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.<p>
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.<p>
+</quote>
+
+<h3>Shapelib Modifications</h3>
+
+I am pleased to receive bug fixes, and improvements for Shapelib.  Unless
+the submissions indicate otherwise I will assume that changes submitted to
+me remain under the the above "dual license" terms.  If changes are made
+to the library with the intention that those changes should be protected by
+the LGPL then I should be informed upon submission.  Note that I will not
+generally incorporate changes into the core of Shapelib that are protected 
+under the LGPL as this would effectively limit the whole file and 
+distribution to LGPL terms.<p>
+
+<h3>Opting for LGPL</h3>
+
+For licensee's opting to use Shapelib under LGPL as opposed to the MIT
+Style license above, and wishing to redistribute the software based on 
+Shapelib, I would ask that all "dual license" modules be updated to
+indicate that only the LGPL (and not the MIT Style license) applies.  This
+action represents opting for the LGPL, and thereafter LGPL terms apply to
+any redistribution and modification of the affected modules.<p>
+
+</body>
+</html>
+
+
+
diff --git a/src/shapelib/shp_api.html b/src/shapelib/shp_api.html
new file mode 100644
index 0000000..d773e3e
--- /dev/null
+++ b/src/shapelib/shp_api.html
@@ -0,0 +1,376 @@
+<html>
+<head>
+<title>.SHP File API</title>
+</head>
+<body>
+
+<h1>.SHP File API</h1>
+
+The .SHP API uses a SHPHandle to represent an open .shp/.shx file pair.
+The contents of the SHPHandle are visible (see shapefile.h) but should
+be ignored by the application.  It is intended that all information be
+accessed by the API functions.  <p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>Shape Types</h2>
+
+Shapes have types associated with them.  The following is a list of the
+different shapetypes supported by Shapefiles.  At this time all shapes in
+a Shapefile must be of the same type (with the exception of NULL shapes). <p>
+
+<pre>
+  #define SHPT_NULL             0
+
+  2D Shape Types (pre ArcView 3.x):
+
+  #define SHPT_POINT		1	Points
+  #define SHPT_ARC		3	Arcs (Polylines, possible in parts)
+  #define SHPT_POLYGON		5	Polygons (possible in parts)
+  #define SHPT_MULTIPOINT	8	MultiPoint (related points)
+
+  3D Shape Types (may include "measure" values for vertices):
+
+  #define SHPT_POINTZ		11	
+  #define SHPT_ARCZ		13
+  #define SHPT_POLYGONZ		15
+  #define SHPT_MULTIPOINTZ 	18
+
+  2D + Measure Types:
+
+  #define SHPT_POINTM		21
+  #define SHPT_ARCM		23
+  #define SHPT_POLYGONM		25
+  #define SHPT_MULTIPOINTM 	28
+
+  Complex (TIN-like) with Z, and Measure:
+
+  #define SHPT_MULTIPATCH 	31
+</pre>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPObject</h2>
+
+An individual shape is represented by the SHPObject structure.  SHPObject's
+created with SHPCreateObject(), SHPCreateSimpleObject(), or SHPReadObject()
+should be disposed of with SHPDestroyObject().<p>
+
+<pre>
+  typedef struct
+  {
+    int		nSHPType;	Shape Type (SHPT_* - see list above)
+
+    int		nShapeId; 	Shape Number (-1 is unknown/unassigned)
+
+    int		nParts;		# of Parts (0 implies single part with no info)
+    int		*panPartStart;  Start Vertex of part
+    int		*panPartType;	Part Type (SHPP_RING if not SHPT_MULTIPATCH)
+    
+    int		nVertices;	Vertex list 
+    double	*padfX;		
+    double	*padfY;
+    double	*padfZ;		(all zero if not provided)
+    double	*padfM;		(all zero if not provided)
+
+    double	dfXMin;		Bounds in X, Y, Z and M dimensions
+    double	dfYMin;
+    double	dfZMin;
+    double	dfMMin;
+
+    double	dfXMax;
+    double	dfYMax;
+    double	dfZMax;
+    double	dfMMax;
+  } SHPObject;
+</pre>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPOpen()</h2>
+
+<pre>
+SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
+
+  pszShapeFile:		The name of the layer to access.  This can be the
+			name of either the .shp or the .shx file or can
+			just be the path plus the basename of the pair.
+
+  pszAccess:		The fopen() style access string.  At this time only
+			"rb" (read-only binary) and "rb+" (read/write binary) 
+		        should be used.
+</pre>
+
+  The SHPOpen() function should be used to establish access to the two files
+  for accessing vertices (.shp and .shx).  Note that both files have to 
+  be in the indicated directory, and must have the expected extensions in
+  lower case.  The returned SHPHandle is passed to other access functions, 
+  and SHPClose() should be invoked to recover resources, and flush changes 
+  to disk when complete.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPGetInfo()</h2>
+
+<pre>
+void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
+                 double * padfMinBound, double * padfMaxBound );
+
+  hSHP:			The handle previously returned by SHPOpen() 
+			or SHPCreate().
+
+  pnEntities:		A pointer to an integer into which the number of
+			entities/structures should be placed.  May be NULL.
+
+  pnShapetype:		A pointer to an integer into which the shapetype
+			of this file should be placed.  Shapefiles may contain
+			either SHPT_POINT, SHPT_ARC, SHPT_POLYGON or 
+			SHPT_MULTIPOINT entities.  This may be NULL.
+
+  padfMinBound:		The X, Y, Z and M minimum values will be placed into
+                        this four entry array.  This may be NULL.
+			
+  padfMaxBound:		The X, Y, Z and M maximum values will be placed into
+                        this four entry array.  This may be NULL.
+</pre>
+
+ The SHPGetInfo() function retrieves various information about shapefile
+ as a whole.  The bounds are read from the file header, and may be 
+ inaccurate if the file was improperly generated. <p>
+			
+<!-------------------------------------------------------------------------->
+
+<h2>SHPReadObject()</h2>
+
+<pre>
+SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );
+
+  hSHP:			The handle previously returned by SHPOpen() 
+			or SHPCreate().
+
+  iShape:		The entity number of the shape to read.  Entity 
+			numbers are between 0 and nEntities-1 (as returned
+			by SHPGetInfo()).
+</pre>
+
+  The SHPReadObject() call is used to read a single structure, or entity
+  from the shapefile.  See the definition of the SHPObject structure for
+  detailed information on fields of a SHPObject.  SHPObject's returned from
+  SHPReadObject() should be deallocated with SHPDestroyShape().  
+  SHPReadObject() will return NULL if an illegal iShape value is requested.<p>
+
+  Note that the bounds placed into the SHPObject are those read from the
+  file, and may not be correct.   For points the bounds are generated from
+  the single point since bounds aren't normally provided for point types.<p>
+
+  Generally the shapes returned will be of the type of the file as a whole.
+  However, any file may also contain type SHPT_NULL shapes which will have
+  no geometry.  Generally speaking applications should skip rather than
+  preserve them, as they usually represented interactively deleted shapes.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPClose()</h2>
+
+<pre>
+void	SHPClose( SHPHandle hSHP );
+
+  hSHP:			The handle previously returned by SHPOpen() 
+			or SHPCreate().
+</pre>
+
+  The SHPClose() function will close the .shp and .shx files, and flush
+  all outstanding header information to the files.  It will also recover
+  resources associated with the handle.  After this call the hSHP handle
+  cannot be used again.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPCreate()</h2>
+
+<pre>
+SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );
+
+  pszShapeFile:		The name of the layer to access.  This can be the
+			name of either the .shp or the .shx file or can
+			just be the path plus the basename of the pair.
+
+  nShapeType:		The type of shapes to be stored in the newly created
+			file.  It may be either SHPT_POINT, SHPT_ARC, 
+		        SHPT_POLYGON or SHPT_MULTIPOINT.
+</pre>
+
+  The SHPCreate() function will create a new .shp and .shx file of the
+  desired type.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPCreateSimpleObject()</h2>
+
+<pre>
+SHPObject * 
+     SHPCreateSimpleObject( int nSHPType, int nVertices, 
+			    double *padfX, double * padfY, double *padfZ, );
+
+  nSHPType:		The SHPT_ type of the object to be created, such
+                        as SHPT_POINT, or SHPT_POLYGON.
+  
+  nVertices:		The number of vertices being passed in padfX,    
+                        padfY, and padfZ. 
+
+  padfX:		An array of nVertices X coordinates of the vertices
+                        for this object.
+
+  padfY:		An array of nVertices Y coordinates of the vertices
+                        for this object.
+
+  padfZ:		An array of nVertices Z coordinates of the vertices
+                        for this object.  This may be NULL in which case
+		        they are all assumed to be zero.
+</pre>
+
+  The SHPCreateSimpleObject() allows for the convenient creation of 
+  simple objects.  This is normally used so that the SHPObject can be
+  passed to SHPWriteObject() to write it to the file.  The simple object
+  creation API assumes an M (measure) value of zero for each vertex.  For
+  complex objects (such as polygons) it is assumed that there is only one
+  part, and that it is of the default type (SHPP_RING). <p>
+
+  Use the SHPCreateObject() function for more sophisticated objects.  The
+  SHPDestroyObject() function should be used to free resources associated with
+  an object allocated with SHPCreateSimpleObject(). <p>
+
+  This function computes a bounding box for the SHPObject from the given 
+  vertices.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPCreateObject()</h2>
+
+<pre>
+SHPObject * 
+     SHPCreateObject( int nSHPType, int iShape,
+                      int nParts, int * panPartStart, int * panPartType,
+                      int nVertices, double *padfX, double * padfY, 
+                      double *padfZ, double *padfM );
+
+  nSHPType:		The SHPT_ type of the object to be created, such
+                        as SHPT_POINT, or SHPT_POLYGON.
+
+  iShape:		The shapeid to be recorded with this shape.
+
+  nParts:		The number of parts for this object.  If this is
+                        zero for ARC, or POLYGON type objects, a single 
+                        zero valued part will be created internally.
+  
+  panPartStart:		The list of zero based start vertices for the rings
+                        (parts) in this object.  The first should always be
+                        zero.  This may be NULL if nParts is 0.
+  
+  panPartType:		The type of each of the parts.  This is only meaningful
+                        for MULTIPATCH files.  For all other cases this may
+                        be NULL, and will be assumed to be SHPP_RING.
+  
+  nVertices:		The number of vertices being passed in padfX,    
+                        padfY, and padfZ. 
+
+  padfX:		An array of nVertices X coordinates of the vertices
+                        for this object.
+
+  padfY:		An array of nVertices Y coordinates of the vertices
+                        for this object.
+
+  padfZ:		An array of nVertices Z coordinates of the vertices
+                        for this object.  This may be NULL in which case
+		        they are all assumed to be zero.
+
+  padfM:		An array of nVertices M (measure values) of the 
+			vertices for this object.  This may be NULL in which 
+			case they are all assumed to be zero.
+</pre>
+
+  The SHPCreateSimpleObject() allows for the creation of objects (shapes).  
+  This is normally used so that the SHPObject can be passed to 
+  SHPWriteObject() to write it to the file. <p>
+
+  The SHPDestroyObject() function should be used to free resources associated 
+  with an object allocated with SHPCreateObject(). <p>
+
+  This function computes a bounding box for the SHPObject from the given 
+  vertices.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPComputeExtents()</h2>
+
+<pre>
+void SHPComputeExtents( SHPObject * psObject );
+
+  psObject:		An existing shape object to be updated in place.
+</pre>
+ 
+  This function will recompute the extents of this shape, replacing the
+  existing values of the dfXMin, dfYMin, dfZMin, dfMMin, dfXMax, dfYMax, 
+  dfZMax, and dfMMax values based on the current set of vertices for the
+  shape.   This function is automatically called by SHPCreateObject() but
+  if the vertices of an existing object are altered it should be called again
+  to fix up the extents.<p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPWriteObject()</h2>
+
+<pre>
+int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject *psObject );
+
+  hSHP:			The handle previously returned by SHPOpen("r+") 
+			or SHPCreate().
+
+  iShape:		The entity number of the shape to write.  A value of
+		        -1 should be used for new shapes.  
+
+  psObject:		The shape to write to the file. This should have
+                        been created with SHPCreateObject(), or 
+                        SHPCreateSimpleObject().
+</pre>
+
+  The SHPWriteObject() call is used to write a single structure, or entity
+  to the shapefile.  See the definition of the SHPObject structure for
+  detailed information on fields of a SHPObject.  The return value is the
+  entity number of the written shape. <p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPDestroyObject()</h2>
+
+<pre>
+void SHPDestroyObject( SHPObject *psObject );
+
+  psObject:		The object to deallocate.
+</pre>
+
+  This function should be used to deallocate the resources associated with
+  a SHPObject when it is no longer needed, including those created with
+  SHPCreateSimpleObject(), SHPCreateObject() and returned from SHPReadObject().
+  <p>
+
+<!-------------------------------------------------------------------------->
+
+<h2>SHPRewindObject()</h2>
+
+<pre>
+int SHPRewindObject( SHPHandle hSHP, SHPObject *psObject );
+
+  hSHP:                 The shapefile (not used at this time).
+  psObject:		The object to deallocate.
+</pre>
+
+  This function will reverse any rings necessary in order to enforce the
+  shapefile restrictions on the required order of inner and outer rings in
+  the Shapefile specification.  It returns TRUE if a change is made and FALSE
+  if no change is made.  Only polygon objects will be affected though any   
+  object may be passed.
+  <p>
+
+</body>
+</html>
diff --git a/src/shapelib/shpadd.c b/src/shapelib/shpadd.c
new file mode 100644
index 0000000..f0009b3
--- /dev/null
+++ b/src/shapelib/shpadd.c
@@ -0,0 +1,197 @@
+/******************************************************************************
+ * $Id: shpadd.c,v 1.2 2009/06/04 04:25:19 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Sample application for adding a shape to a shapefile.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shpadd.c,v $
+ * Revision 1.2  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.13  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.12  2001/05/31 19:35:29  warmerda
+ * added support for writing null shapes
+ *
+ * Revision 1.11  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.10  2000/05/24 15:09:22  warmerda
+ * Added logic to graw vertex lists of needed.
+ *
+ * Revision 1.9  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.8  1998/12/03 16:36:26  warmerda
+ * Use r+b rather than rb+ for binary access.
+ *
+ * Revision 1.7  1998/11/09 20:57:04  warmerda
+ * Fixed SHPGetInfo() call.
+ *
+ * Revision 1.6  1998/11/09 20:19:16  warmerda
+ * Changed to use SHPObject based API.
+ *
+ * Revision 1.5  1997/03/06 14:05:02  warmerda
+ * fixed typo.
+ *
+ * Revision 1.4  1997/03/06 14:01:16  warmerda
+ * added memory allocation checking, and free()s.
+ *
+ * Revision 1.3  1995/10/21 03:14:37  warmerda
+ * Changed to use binary file access
+ *
+ * Revision 1.2  1995/08/04  03:18:01  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] =
+//    "$Id: shpadd.c,v 1.2 2009/06/04 04:25:19 we7u Exp $";
+
+#include <stdlib.h>
+#include <string.h>
+#include "shapefil.h"
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP;
+    int		nShapeType, nVertices, nParts, *panParts, i, nVMax;
+    double	*padfX, *padfY;
+    SHPObject	*psObject;
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc < 2 )
+    {
+	printf( "shpadd shp_file [[x y] [+]]*\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "r+b" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( hSHP, NULL, &nShapeType, NULL, NULL );
+
+    if( argc == 2 )
+        nShapeType = SHPT_NULL;
+
+/* -------------------------------------------------------------------- */
+/*	Build a vertex/part list from the command line arguments.	*/
+/* -------------------------------------------------------------------- */
+    nVMax = 1000;
+    padfX = (double *) malloc(sizeof(double) * nVMax);
+    padfY = (double *) malloc(sizeof(double) * nVMax);
+    
+    nVertices = 0;
+
+    if( (panParts = (int *) malloc(sizeof(int) * 1000 )) == NULL )
+    {
+        printf( "Out of memory\n" );
+        exit( 1 );
+    }
+    
+    nParts = 1;
+    panParts[0] = 0;
+
+    for( i = 2; i < argc;  )
+    {
+	if( argv[i][0] == '+' )
+	{
+	    panParts[nParts++] = nVertices;
+	    i++;
+	}
+	else if( i < argc-1 )
+	{
+            if( nVertices == nVMax )
+            {
+                nVMax = nVMax * 2;
+                padfX = (double *) realloc(padfX,sizeof(double)*nVMax);
+                padfY = (double *) realloc(padfY,sizeof(double)*nVMax);
+            }
+
+	    sscanf( argv[i], "%lg", padfX+nVertices );
+	    sscanf( argv[i+1], "%lg", padfY+nVertices );
+	    nVertices += 1;
+	    i += 2;
+	}
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Write the new entity to the shape file.                         */
+/* -------------------------------------------------------------------- */
+    psObject = SHPCreateObject( nShapeType, -1, nParts, panParts, NULL,
+                                nVertices, padfX, padfY, NULL, NULL );
+    SHPWriteObject( hSHP, -1, psObject );
+    SHPDestroyObject( psObject );
+    
+    SHPClose( hSHP );
+
+    free( panParts );
+    free( padfX );
+    free( padfY );
+
+    return 0;
+}
diff --git a/src/shapelib/shpcreate.c b/src/shapelib/shpcreate.c
new file mode 100644
index 0000000..8ff617e
--- /dev/null
+++ b/src/shapelib/shpcreate.c
@@ -0,0 +1,138 @@
+/******************************************************************************
+ * $Id: shpcreate.c,v 1.4 2009/06/04 04:25:19 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Sample application for creating a new shapefile.
+ * Author:   Frank Warmerdam, warmerdm at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shpcreate.c,v $
+ * Revision 1.4  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.3  2009/06/03 22:24:19  we7u
+ * Adding includes for string.h to get rid of compiler warnings.
+ *
+ * Revision 1.2  2007/07/25 15:37:50  we7u
+ * Added shprewind.c to the "clean" target of the original Makefile.  Added
+ * stdlib.h includes to some of the utilities to get a clean compile.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.5  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.4  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.3  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.2  1995/08/04 03:16:43  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] =
+//    "$Id: shpcreate.c,v 1.4 2009/06/04 04:25:19 we7u Exp $";
+
+#include "shapefil.h"
+#include <stdlib.h>
+
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP;
+    int		nShapeType;
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 3 )
+    {
+	printf( "shpcreate shp_file [point/arc/polygon/multipoint]\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Figure out the shape type.					*/
+/* -------------------------------------------------------------------- */
+    if( strcmp(argv[2],"POINT") == 0 || strcmp(argv[2],"point") == 0 )
+        nShapeType = SHPT_POINT;
+    else if( strcmp(argv[2],"ARC") == 0 || strcmp(argv[2],"arc") == 0 )
+        nShapeType = SHPT_ARC;
+    else if( strcmp(argv[2],"POLYGON") == 0 || strcmp(argv[2],"polygon") == 0 )
+        nShapeType = SHPT_POLYGON;
+    else if( strcmp(argv[2],"MULTIPOINT")==0 ||strcmp(argv[2],"multipoint")==0)
+        nShapeType = SHPT_MULTIPOINT;
+    else
+    {
+	printf( "Shape Type `%s' not recognised.\n", argv[2] );
+	exit( 2 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Create the requested layer.					*/
+/* -------------------------------------------------------------------- */
+    hSHP = SHPCreate( argv[1], nShapeType );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to create:%s\n", argv[1] );
+	exit( 3 );
+    }
+
+    SHPClose( hSHP );
+
+    return 0;
+}
diff --git a/src/shapelib/shpdump.c b/src/shapelib/shpdump.c
new file mode 100644
index 0000000..feec2d1
--- /dev/null
+++ b/src/shapelib/shpdump.c
@@ -0,0 +1,234 @@
+/******************************************************************************
+ * $Id: shpdump.c,v 1.4 2010/07/11 07:57:02 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Sample application for dumping contents of a shapefile to 
+ *           the terminal in human readable form.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shpdump.c,v $
+ * Revision 1.4  2010/07/11 07:57:02  we7u
+ * Fixing a few more compiler warnings.
+ *
+ * Revision 1.3  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.2  2007/07/25 15:37:50  we7u
+ * Added shprewind.c to the "clean" target of the original Makefile.  Added
+ * stdlib.h includes to some of the utilities to get a clean compile.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.10  2002/04/10 16:59:29  warmerda
+ * added -validate switch
+ *
+ * Revision 1.9  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.8  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.7  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.6  1998/12/03 15:48:48  warmerda
+ * Added report of shapefile type, and total number of shapes.
+ *
+ * Revision 1.5  1998/11/09 20:57:36  warmerda
+ * use SHPObject.
+ *
+ * Revision 1.4  1995/10/21 03:14:49  warmerda
+ * Changed to use binary file access.
+ *
+ * Revision 1.3  1995/08/23  02:25:25  warmerda
+ * Added support for bounds.
+ *
+ * Revision 1.2  1995/08/04  03:18:11  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] =
+//    "$Id: shpdump.c,v 1.4 2010/07/11 07:57:02 we7u Exp $";
+
+#include "shapefil.h"
+#include <stdlib.h>
+#include <string.h>
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP;
+    int		nShapeType, nEntities, i, iPart, bValidate = 0,nInvalidCount=0;
+    const char 	*pszPlus;
+    double 	adfMinBound[4], adfMaxBound[4];
+
+    if( argc > 1 && strcmp(argv[1],"-validate") == 0 )
+    {
+        bValidate = 1;
+        argv++;
+        argc--;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 2 )
+    {
+	printf( "shpdump [-validate] shp_file\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "rb" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Print out the file bounds.                                      */
+/* -------------------------------------------------------------------- */
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
+
+    printf( "Shapefile Type: %s   # of Shapes: %d\n\n",
+            SHPTypeName( nShapeType ), nEntities );
+    
+    printf( "File Bounds: (%12.3f,%12.3f,%g,%g)\n"
+            "         to  (%12.3f,%12.3f,%g,%g)\n",
+            adfMinBound[0], 
+            adfMinBound[1], 
+            adfMinBound[2], 
+            adfMinBound[3], 
+            adfMaxBound[0], 
+            adfMaxBound[1], 
+            adfMaxBound[2], 
+            adfMaxBound[3] );
+    
+/* -------------------------------------------------------------------- */
+/*	Skim over the list of shapes, printing all the vertices.	*/
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nEntities; i++ )
+    {
+	int		j;
+        SHPObject	*psShape;
+
+	psShape = SHPReadObject( hSHP, i );
+
+	printf( "\nShape:%d (%s)  nVertices=%d, nParts=%d\n"
+                "  Bounds:(%12.3f,%12.3f, %g, %g)\n"
+                "      to (%12.3f,%12.3f, %g, %g)\n",
+	        i, SHPTypeName(psShape->nSHPType),
+                psShape->nVertices, psShape->nParts,
+                psShape->dfXMin, psShape->dfYMin,
+                psShape->dfZMin, psShape->dfMMin,
+                psShape->dfXMax, psShape->dfYMax,
+                psShape->dfZMax, psShape->dfMMax );
+
+	for( j = 0, iPart = 1; j < psShape->nVertices; j++ )
+	{
+            const char	*pszPartType = "";
+
+            if( j == 0 && psShape->nParts > 0 )
+                pszPartType = SHPPartTypeName( psShape->panPartType[0] );
+            
+	    if( iPart < psShape->nParts
+                && psShape->panPartStart[iPart] == j )
+	    {
+                pszPartType = SHPPartTypeName( psShape->panPartType[iPart] );
+		iPart++;
+		pszPlus = "+";
+	    }
+	    else
+	        pszPlus = " ";
+
+	    printf("   %s (%12.3f,%12.3f, %g, %g) %s \n",
+                   pszPlus,
+                   psShape->padfX[j],
+                   psShape->padfY[j],
+                   psShape->padfZ[j],
+                   psShape->padfM[j],
+                   pszPartType );
+	}
+
+        if( bValidate )
+        {
+            int nAltered = SHPRewindObject( hSHP, psShape );
+
+            if( nAltered > 0 )
+            {
+                printf( "  %d rings wound in the wrong direction.\n",
+                        nAltered );
+                nInvalidCount++;
+            }
+        }
+        
+        SHPDestroyObject( psShape );
+    }
+
+    SHPClose( hSHP );
+
+    if( bValidate )
+    {
+        printf( "%d object has invalid ring orderings.\n", nInvalidCount );
+    }
+
+#ifdef USE_DBMALLOC
+    malloc_dump(2);
+#endif
+
+    exit( 0 );
+}
diff --git a/src/shapelib/shpopen.c b/src/shapelib/shpopen.c
new file mode 100644
index 0000000..95322de
--- /dev/null
+++ b/src/shapelib/shpopen.c
@@ -0,0 +1,1892 @@
+/******************************************************************************
+ * $Id: shpopen.c,v 1.2 2006/11/14 21:28:48 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Implementation of core Shapefile read/write functions.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, 2001, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shpopen.c,v $
+ * Revision 1.2  2006/11/14 21:28:48  we7u
+ * Commenting out some variables that give off compiler warnings.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.39  2002/08/26 06:46:56  warmerda
+ * avoid c++ comments
+ *
+ * Revision 1.38  2002/05/07 16:43:39  warmerda
+ * Removed debugging printf.
+ *
+ * Revision 1.37  2002/04/10 17:35:22  warmerda
+ * fixed bug in ring reversal code
+ *
+ * Revision 1.36  2002/04/10 16:59:54  warmerda
+ * added SHPRewindObject
+ *
+ * Revision 1.35  2001/12/07 15:10:44  warmerda
+ * fix if .shx fails to open
+ *
+ * Revision 1.34  2001/11/01 16:29:55  warmerda
+ * move pabyRec into SHPInfo for thread safety
+ *
+ * Revision 1.33  2001/07/03 12:18:15  warmerda
+ * Improved cleanup if SHX not found, provied by Riccardo Cohen.
+ *
+ * Revision 1.32  2001/06/22 01:58:07  warmerda
+ * be more careful about establishing initial bounds in face of NULL shapes
+ *
+ * Revision 1.31  2001/05/31 19:35:29  warmerda
+ * added support for writing null shapes
+ *
+ * Revision 1.30  2001/05/28 12:46:29  warmerda
+ * Add some checking on reasonableness of record count when opening.
+ *
+ * Revision 1.29  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.28  2001/02/06 22:25:06  warmerda
+ * fixed memory leaks when SHPOpen() fails
+ *
+ * Revision 1.27  2000/07/18 15:21:33  warmerda
+ * added better enforcement of -1 for append in SHPWriteObject
+ *
+ * Revision 1.26  2000/02/16 16:03:51  warmerda
+ * added null shape support
+ *
+ * Revision 1.25  1999/12/15 13:47:07  warmerda
+ * Fixed record size settings in .shp file (was 4 words too long)
+ * Added stdlib.h.
+ *
+ * Revision 1.24  1999/11/05 14:12:04  warmerda
+ * updated license terms
+ *
+ * Revision 1.23  1999/07/27 00:53:46  warmerda
+ * added support for rewriting shapes
+ *
+ * Revision 1.22  1999/06/11 19:19:11  warmerda
+ * Cleanup pabyRec static buffer on SHPClose().
+ *
+ * Revision 1.21  1999/06/02 14:57:56  kshih
+ * Remove unused variables
+ *
+ * Revision 1.20  1999/04/19 21:04:17  warmerda
+ * Fixed syntax error.
+ *
+ * Revision 1.19  1999/04/19 21:01:57  warmerda
+ * Force access string to binary in SHPOpen().
+ *
+ * Revision 1.18  1999/04/01 18:48:07  warmerda
+ * Try upper case extensions if lower case doesn't work.
+ *
+ * Revision 1.17  1998/12/31 15:29:39  warmerda
+ * Disable writing measure values to multipatch objects if
+ * DISABLE_MULTIPATCH_MEASURE is defined.
+ *
+ * Revision 1.16  1998/12/16 05:14:33  warmerda
+ * Added support to write MULTIPATCH.  Fixed reading Z coordinate of
+ * MULTIPATCH. Fixed record size written for all feature types.
+ *
+ * Revision 1.15  1998/12/03 16:35:29  warmerda
+ * r+b is proper binary access string, not rb+.
+ *
+ * Revision 1.14  1998/12/03 15:47:56  warmerda
+ * Fixed setting of nVertices in SHPCreateObject().
+ *
+ * Revision 1.13  1998/12/03 15:33:54  warmerda
+ * Made SHPCalculateExtents() separately callable.
+ *
+ * Revision 1.12  1998/11/11 20:01:50  warmerda
+ * Fixed bug writing ArcM/Z, and PolygonM/Z for big endian machines.
+ *
+ * Revision 1.11  1998/11/09 20:56:44  warmerda
+ * Fixed up handling of file wide bounds.
+ *
+ * Revision 1.10  1998/11/09 20:18:51  warmerda
+ * Converted to support 3D shapefiles, and use of SHPObject.
+ *
+ * Revision 1.9  1998/02/24 15:09:05  warmerda
+ * Fixed memory leak.
+ *
+ * Revision 1.8  1997/12/04 15:40:29  warmerda
+ * Fixed byte swapping of record number, and record length fields in the
+ * .shp file.
+ *
+ * Revision 1.7  1995/10/21 03:15:58  warmerda
+ * Added support for binary file access, the magic cookie 9997
+ * and tried to improve the int32 selection logic for 16bit systems.
+ *
+ * Revision 1.6  1995/09/04  04:19:41  warmerda
+ * Added fix for file bounds.
+ *
+ * Revision 1.5  1995/08/25  15:16:44  warmerda
+ * Fixed a couple of problems with big endian systems ... one with bounds
+ * and the other with multipart polygons.
+ *
+ * Revision 1.4  1995/08/24  18:10:17  warmerda
+ * Switch to use SfRealloc() to avoid problems with pre-ANSI realloc()
+ * functions (such as on the Sun).
+ *
+ * Revision 1.3  1995/08/23  02:23:15  warmerda
+ * Added support for reading bounds, and fixed up problems in setting the
+ * file wide bounds.
+ *
+ * Revision 1.2  1995/08/04  03:16:57  warmerda
+ * Added header.
+ *
+ */
+
+//static char rcsid[] = 
+//  "$Id: shpopen.c,v 1.2 2006/11/14 21:28:48 we7u Exp $";
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef unsigned char uchar;
+
+#if UINT_MAX == 65535
+typedef long	      int32;
+#else
+typedef int	      int32;
+#endif
+
+#ifndef FALSE
+#  define FALSE		0
+#  define TRUE		1
+#endif
+
+#define ByteCopy( a, b, c )	memcpy( b, a, c )
+#ifndef MAX
+#  define MIN(a,b)      ((a<b) ? a : b)
+#  define MAX(a,b)      ((a>b) ? a : b)
+#endif
+
+static int 	bBigEndian;
+
+
+/************************************************************************/
+/*                              SwapWord()                              */
+/*                                                                      */
+/*      Swap a 2, 4 or 8 byte word.                                     */
+/************************************************************************/
+
+static void	SwapWord( int length, void * wordP )
+
+{
+    int		i;
+    uchar	temp;
+
+    for( i=0; i < length/2; i++ )
+    {
+	temp = ((uchar *) wordP)[i];
+	((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1];
+	((uchar *) wordP)[length-i-1] = temp;
+    }
+}
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+/************************************************************************/
+/*                          SHPWriteHeader()                            */
+/*                                                                      */
+/*      Write out a header for the .shp and .shx files as well as the	*/
+/*	contents of the index (.shx) file.				*/
+/************************************************************************/
+
+static void SHPWriteHeader( SHPHandle psSHP )
+
+{
+    uchar     	abyHeader[100];
+    int		i;
+    int32	i32;
+    double	dValue;
+    int32	*panSHX;
+
+/* -------------------------------------------------------------------- */
+/*      Prepare header block for .shp file.                             */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < 100; i++ )
+      abyHeader[i] = 0;
+
+    abyHeader[2] = 0x27;				/* magic cookie */
+    abyHeader[3] = 0x0a;
+
+    i32 = psSHP->nFileSize/2;				/* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    i32 = 1000;						/* version */
+    ByteCopy( &i32, abyHeader+28, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+28 );
+    
+    i32 = psSHP->nShapeType;				/* shape type */
+    ByteCopy( &i32, abyHeader+32, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+32 );
+
+    dValue = psSHP->adBoundsMin[0];			/* set bounds */
+    ByteCopy( &dValue, abyHeader+36, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+36 );
+
+    dValue = psSHP->adBoundsMin[1];
+    ByteCopy( &dValue, abyHeader+44, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+44 );
+
+    dValue = psSHP->adBoundsMax[0];
+    ByteCopy( &dValue, abyHeader+52, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+52 );
+
+    dValue = psSHP->adBoundsMax[1];
+    ByteCopy( &dValue, abyHeader+60, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+60 );
+
+    dValue = psSHP->adBoundsMin[2];			/* z */
+    ByteCopy( &dValue, abyHeader+68, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+68 );
+
+    dValue = psSHP->adBoundsMax[2];
+    ByteCopy( &dValue, abyHeader+76, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+76 );
+
+    dValue = psSHP->adBoundsMin[3];			/* m */
+    ByteCopy( &dValue, abyHeader+84, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+84 );
+
+    dValue = psSHP->adBoundsMax[3];
+    ByteCopy( &dValue, abyHeader+92, 8 );
+    if( bBigEndian ) SwapWord( 8, abyHeader+92 );
+
+/* -------------------------------------------------------------------- */
+/*      Write .shp file header.                                         */
+/* -------------------------------------------------------------------- */
+    fseek( psSHP->fpSHP, 0, 0 );
+    fwrite( abyHeader, 100, 1, psSHP->fpSHP );
+
+/* -------------------------------------------------------------------- */
+/*      Prepare, and write .shx file header.                            */
+/* -------------------------------------------------------------------- */
+    i32 = (psSHP->nRecords * 2 * sizeof(int32) + 100)/2;   /* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    fseek( psSHP->fpSHX, 0, 0 );
+    fwrite( abyHeader, 100, 1, psSHP->fpSHX );
+
+/* -------------------------------------------------------------------- */
+/*      Write out the .shx contents.                                    */
+/* -------------------------------------------------------------------- */
+    panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords);
+
+    for( i = 0; i < psSHP->nRecords; i++ )
+    {
+	panSHX[i*2  ] = psSHP->panRecOffset[i]/2;
+	panSHX[i*2+1] = psSHP->panRecSize[i]/2;
+	if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
+	if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
+    }
+
+    fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX );
+
+    free( panSHX );
+}
+
+/************************************************************************/
+/*                              SHPOpen()                               */
+/*                                                                      */
+/*      Open the .shp and .shx files based on the basename of the       */
+/*      files or either file name.                                      */
+/************************************************************************/
+   
+SHPHandle SHPAPI_CALL
+SHPOpen( const char * pszLayer, const char * pszAccess )
+
+{
+    char		*pszFullname, *pszBasename;
+    SHPHandle		psSHP;
+    
+    uchar		*pabyBuf;
+    int			i;
+    double		dValue;
+    
+/* -------------------------------------------------------------------- */
+/*      Ensure the access string is one of the legal ones.  We          */
+/*      ensure the result string indicates binary to avoid common       */
+/*      problems on Windows.                                            */
+/* -------------------------------------------------------------------- */
+    if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0
+        || strcmp(pszAccess,"r+") == 0 )
+        pszAccess = "r+b";
+    else
+        pszAccess = "rb";
+    
+/* -------------------------------------------------------------------- */
+/*	Establish the byte order on this machine.			*/
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((uchar *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*	Initialize the info structure.					*/
+/* -------------------------------------------------------------------- */
+    psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
+
+    psSHP->bUpdated = FALSE;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszLayer)+5);
+    strcpy( pszBasename, pszLayer );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+/* -------------------------------------------------------------------- */
+/*	Open the .shp and .shx files.  Note that files pulled from	*/
+/*	a PC to Unix with upper case filenames won't work!		*/
+/* -------------------------------------------------------------------- */
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.shp", pszBasename );
+    psSHP->fpSHP = fopen(pszFullname, pszAccess );
+    if( psSHP->fpSHP == NULL )
+    {
+        sprintf( pszFullname, "%s.SHP", pszBasename );
+        psSHP->fpSHP = fopen(pszFullname, pszAccess );
+    }
+    
+    if( psSHP->fpSHP == NULL )
+    {
+        free( psSHP );
+        free( pszBasename );
+        free( pszFullname );
+        return( NULL );
+    }
+
+    sprintf( pszFullname, "%s.shx", pszBasename );
+    psSHP->fpSHX = fopen(pszFullname, pszAccess );
+    if( psSHP->fpSHX == NULL )
+    {
+        sprintf( pszFullname, "%s.SHX", pszBasename );
+        psSHP->fpSHX = fopen(pszFullname, pszAccess );
+    }
+    
+    if( psSHP->fpSHX == NULL )
+    {
+        fclose( psSHP->fpSHP );
+        free( psSHP );
+        free( pszBasename );
+        free( pszFullname );
+        return( NULL );
+    }
+
+    free( pszFullname );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*  Read the file size from the SHP file.				*/
+/* -------------------------------------------------------------------- */
+    pabyBuf = (uchar *) malloc(100);
+    fread( pabyBuf, 100, 1, psSHP->fpSHP );
+
+    psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
+			+ pabyBuf[25] * 256 * 256
+			+ pabyBuf[26] * 256
+			+ pabyBuf[27]) * 2;
+
+/* -------------------------------------------------------------------- */
+/*  Read SHX file Header info                                           */
+/* -------------------------------------------------------------------- */
+    fread( pabyBuf, 100, 1, psSHP->fpSHX );
+
+    if( pabyBuf[0] != 0 
+        || pabyBuf[1] != 0 
+        || pabyBuf[2] != 0x27 
+        || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
+    {
+	fclose( psSHP->fpSHP );
+	fclose( psSHP->fpSHX );
+	free( psSHP );
+
+	return( NULL );
+    }
+
+    psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
+      + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
+    psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
+
+    psSHP->nShapeType = pabyBuf[32];
+
+    if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
+    {
+        /* this header appears to be corrupt.  Give up. */
+	fclose( psSHP->fpSHP );
+	fclose( psSHP->fpSHX );
+	free( psSHP );
+
+	return( NULL );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the bounds.                                                */
+/* -------------------------------------------------------------------- */
+    if( bBigEndian ) SwapWord( 8, pabyBuf+36 );
+    memcpy( &dValue, pabyBuf+36, 8 );
+    psSHP->adBoundsMin[0] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+44 );
+    memcpy( &dValue, pabyBuf+44, 8 );
+    psSHP->adBoundsMin[1] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+52 );
+    memcpy( &dValue, pabyBuf+52, 8 );
+    psSHP->adBoundsMax[0] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+60 );
+    memcpy( &dValue, pabyBuf+60, 8 );
+    psSHP->adBoundsMax[1] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+68 );		/* z */
+    memcpy( &dValue, pabyBuf+68, 8 );
+    psSHP->adBoundsMin[2] = dValue;
+    
+    if( bBigEndian ) SwapWord( 8, pabyBuf+76 );
+    memcpy( &dValue, pabyBuf+76, 8 );
+    psSHP->adBoundsMax[2] = dValue;
+    
+    if( bBigEndian ) SwapWord( 8, pabyBuf+84 );		/* z */
+    memcpy( &dValue, pabyBuf+84, 8 );
+    psSHP->adBoundsMin[3] = dValue;
+
+    if( bBigEndian ) SwapWord( 8, pabyBuf+92 );
+    memcpy( &dValue, pabyBuf+92, 8 );
+    psSHP->adBoundsMax[3] = dValue;
+
+    free( pabyBuf );
+
+/* -------------------------------------------------------------------- */
+/*	Read the .shx file to get the offsets to each record in 	*/
+/*	the .shp file.							*/
+/* -------------------------------------------------------------------- */
+    psSHP->nMaxRecords = psSHP->nRecords;
+
+    psSHP->panRecOffset =
+        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
+    psSHP->panRecSize =
+        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
+
+    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
+    fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX );
+
+    for( i = 0; i < psSHP->nRecords; i++ )
+    {
+	int32		nOffset, nLength;
+
+	memcpy( &nOffset, pabyBuf + i * 8, 4 );
+	if( !bBigEndian ) SwapWord( 4, &nOffset );
+
+	memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
+	if( !bBigEndian ) SwapWord( 4, &nLength );
+
+	psSHP->panRecOffset[i] = nOffset*2;
+	psSHP->panRecSize[i] = nLength*2;
+    }
+    free( pabyBuf );
+
+    return( psSHP );
+}
+
+/************************************************************************/
+/*                              SHPClose()                              */
+/*								       	*/
+/*	Close the .shp and .shx files.					*/
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPClose(SHPHandle psSHP )
+
+{
+/* -------------------------------------------------------------------- */
+/*	Update the header if we have modified anything.			*/
+/* -------------------------------------------------------------------- */
+    if( psSHP->bUpdated )
+    {
+	SHPWriteHeader( psSHP );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Free all resources, and close files.                            */
+/* -------------------------------------------------------------------- */
+    free( psSHP->panRecOffset );
+    free( psSHP->panRecSize );
+
+    fclose( psSHP->fpSHX );
+    fclose( psSHP->fpSHP );
+
+    if( psSHP->pabyRec != NULL )
+    {
+        free( psSHP->pabyRec );
+    }
+    
+    free( psSHP );
+}
+
+/************************************************************************/
+/*                             SHPGetInfo()                             */
+/*                                                                      */
+/*      Fetch general information about the shape file.                 */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
+           double * padfMinBound, double * padfMaxBound )
+
+{
+    int		i;
+    
+    if( pnEntities != NULL )
+        *pnEntities = psSHP->nRecords;
+
+    if( pnShapeType != NULL )
+        *pnShapeType = psSHP->nShapeType;
+
+    for( i = 0; i < 4; i++ )
+    {
+        if( padfMinBound != NULL )
+            padfMinBound[i] = psSHP->adBoundsMin[i];
+        if( padfMaxBound != NULL )
+            padfMaxBound[i] = psSHP->adBoundsMax[i];
+    }
+}
+
+/************************************************************************/
+/*                             SHPCreate()                              */
+/*                                                                      */
+/*      Create a new shape file and return a handle to the open         */
+/*      shape file with read/write access.                              */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPCreate( const char * pszLayer, int nShapeType )
+
+{
+    char	*pszBasename, *pszFullname;
+    int		i;
+    FILE	*fpSHP, *fpSHX;
+    uchar     	abyHeader[100];
+    int32	i32;
+    double	dValue;
+    
+/* -------------------------------------------------------------------- */
+/*      Establish the byte order on this system.                        */
+/* -------------------------------------------------------------------- */
+    i = 1;
+    if( *((uchar *) &i) == 1 )
+        bBigEndian = FALSE;
+    else
+        bBigEndian = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*	Compute the base (layer) name.  If there is any extension	*/
+/*	on the passed in filename we will strip it off.			*/
+/* -------------------------------------------------------------------- */
+    pszBasename = (char *) malloc(strlen(pszLayer)+5);
+    strcpy( pszBasename, pszLayer );
+    for( i = strlen(pszBasename)-1; 
+	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+	       && pszBasename[i] != '\\';
+	 i-- ) {}
+
+    if( pszBasename[i] == '.' )
+        pszBasename[i] = '\0';
+
+/* -------------------------------------------------------------------- */
+/*      Open the two files so we can write their headers.               */
+/* -------------------------------------------------------------------- */
+    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
+    sprintf( pszFullname, "%s.shp", pszBasename );
+    fpSHP = fopen(pszFullname, "wb" );
+    if( fpSHP == NULL )
+        return( NULL );
+
+    sprintf( pszFullname, "%s.shx", pszBasename );
+    fpSHX = fopen(pszFullname, "wb" );
+    if( fpSHX == NULL )
+        return( NULL );
+
+    free( pszFullname );
+    free( pszBasename );
+
+/* -------------------------------------------------------------------- */
+/*      Prepare header block for .shp file.                             */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < 100; i++ )
+      abyHeader[i] = 0;
+
+    abyHeader[2] = 0x27;				/* magic cookie */
+    abyHeader[3] = 0x0a;
+
+    i32 = 50;						/* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    i32 = 1000;						/* version */
+    ByteCopy( &i32, abyHeader+28, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+28 );
+    
+    i32 = nShapeType;					/* shape type */
+    ByteCopy( &i32, abyHeader+32, 4 );
+    if( bBigEndian ) SwapWord( 4, abyHeader+32 );
+
+    dValue = 0.0;					/* set bounds */
+    ByteCopy( &dValue, abyHeader+36, 8 );
+    ByteCopy( &dValue, abyHeader+44, 8 );
+    ByteCopy( &dValue, abyHeader+52, 8 );
+    ByteCopy( &dValue, abyHeader+60, 8 );
+
+/* -------------------------------------------------------------------- */
+/*      Write .shp file header.                                         */
+/* -------------------------------------------------------------------- */
+    fwrite( abyHeader, 100, 1, fpSHP );
+
+/* -------------------------------------------------------------------- */
+/*      Prepare, and write .shx file header.                            */
+/* -------------------------------------------------------------------- */
+    i32 = 50;						/* file size */
+    ByteCopy( &i32, abyHeader+24, 4 );
+    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
+    
+    fwrite( abyHeader, 100, 1, fpSHX );
+
+/* -------------------------------------------------------------------- */
+/*      Close the files, and then open them as regular existing files.  */
+/* -------------------------------------------------------------------- */
+    fclose( fpSHP );
+    fclose( fpSHX );
+
+    return( SHPOpen( pszLayer, "r+b" ) );
+}
+
+/************************************************************************/
+/*                           _SHPSetBounds()                            */
+/*                                                                      */
+/*      Compute a bounds rectangle for a shape, and set it into the     */
+/*      indicated location in the record.                               */
+/************************************************************************/
+
+static void	_SHPSetBounds( uchar * pabyRec, SHPObject * psShape )
+
+{
+    ByteCopy( &(psShape->dfXMin), pabyRec +  0, 8 );
+    ByteCopy( &(psShape->dfYMin), pabyRec +  8, 8 );
+    ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 );
+    ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 );
+
+    if( bBigEndian )
+    {
+        SwapWord( 8, pabyRec + 0 );
+        SwapWord( 8, pabyRec + 8 );
+        SwapWord( 8, pabyRec + 16 );
+        SwapWord( 8, pabyRec + 24 );
+    }
+}
+
+/************************************************************************/
+/*                         SHPComputeExtents()                          */
+/*                                                                      */
+/*      Recompute the extents of a shape.  Automatically done by        */
+/*      SHPCreateObject().                                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPComputeExtents( SHPObject * psObject )
+
+{
+    int		i;
+    
+/* -------------------------------------------------------------------- */
+/*      Build extents for this object.                                  */
+/* -------------------------------------------------------------------- */
+    if( psObject->nVertices > 0 )
+    {
+        psObject->dfXMin = psObject->dfXMax = psObject->padfX[0];
+        psObject->dfYMin = psObject->dfYMax = psObject->padfY[0];
+        psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0];
+        psObject->dfMMin = psObject->dfMMax = psObject->padfM[0];
+    }
+    
+    for( i = 0; i < psObject->nVertices; i++ )
+    {
+        psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]);
+        psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]);
+        psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]);
+        psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]);
+
+        psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]);
+        psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]);
+        psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]);
+        psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]);
+    }
+}
+
+/************************************************************************/
+/*                          SHPCreateObject()                           */
+/*                                                                      */
+/*      Create a shape object.  It should be freed with                 */
+/*      SHPDestroyObject().                                             */
+/************************************************************************/
+
+SHPObject SHPAPI_CALL1(*)
+SHPCreateObject( int nSHPType, int nShapeId, int nParts,
+                 int * panPartStart, int * panPartType,
+                 int nVertices, double * padfX, double * padfY,
+                 double * padfZ, double * padfM )
+
+{
+    SHPObject	*psObject;
+    int		i, bHasM, bHasZ;
+
+    psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
+    psObject->nSHPType = nSHPType;
+    psObject->nShapeId = nShapeId;
+
+/* -------------------------------------------------------------------- */
+/*	Establish whether this shape type has M, and Z values.		*/
+/* -------------------------------------------------------------------- */
+    if( nSHPType == SHPT_ARCM
+        || nSHPType == SHPT_POINTM
+        || nSHPType == SHPT_POLYGONM
+        || nSHPType == SHPT_MULTIPOINTM )
+    {
+        bHasM = TRUE;
+        bHasZ = FALSE;
+    }
+    else if( nSHPType == SHPT_ARCZ
+             || nSHPType == SHPT_POINTZ
+             || nSHPType == SHPT_POLYGONZ
+             || nSHPType == SHPT_MULTIPOINTZ
+             || nSHPType == SHPT_MULTIPATCH )
+    {
+        bHasM = TRUE;
+        bHasZ = TRUE;
+    }
+    else
+    {
+        bHasM = FALSE;
+        bHasZ = FALSE;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Capture parts.  Note that part type is optional, and            */
+/*      defaults to ring.                                               */
+/* -------------------------------------------------------------------- */
+    if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON
+        || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM
+        || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ
+        || nSHPType == SHPT_MULTIPATCH )
+    {
+        psObject->nParts = MAX(1,nParts);
+
+        psObject->panPartStart = (int *)
+            malloc(sizeof(int) * psObject->nParts);
+        psObject->panPartType = (int *)
+            malloc(sizeof(int) * psObject->nParts);
+
+        psObject->panPartStart[0] = 0;
+        psObject->panPartType[0] = SHPP_RING;
+        
+        for( i = 0; i < nParts; i++ )
+        {
+            psObject->panPartStart[i] = panPartStart[i];
+            if( panPartType != NULL )
+                psObject->panPartType[i] = panPartType[i];
+            else
+                psObject->panPartType[i] = SHPP_RING;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Capture vertices.  Note that Z and M are optional, but X and    */
+/*      Y are not.                                                      */
+/* -------------------------------------------------------------------- */
+    if( nVertices > 0 )
+    {
+        psObject->padfX = (double *) calloc(sizeof(double),nVertices);
+        psObject->padfY = (double *) calloc(sizeof(double),nVertices);
+        psObject->padfZ = (double *) calloc(sizeof(double),nVertices);
+        psObject->padfM = (double *) calloc(sizeof(double),nVertices);
+
+        assert( padfX != NULL );
+        assert( padfY != NULL );
+    
+        for( i = 0; i < nVertices; i++ )
+        {
+            psObject->padfX[i] = padfX[i];
+            psObject->padfY[i] = padfY[i];
+            if( padfZ != NULL && bHasZ )
+                psObject->padfZ[i] = padfZ[i];
+            if( padfM != NULL && bHasM )
+                psObject->padfM[i] = padfM[i];
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Compute the extents.                                            */
+/* -------------------------------------------------------------------- */
+    psObject->nVertices = nVertices;
+    SHPComputeExtents( psObject );
+
+    return( psObject );
+}
+
+/************************************************************************/
+/*                       SHPCreateSimpleObject()                        */
+/*                                                                      */
+/*      Create a simple (common) shape object.  Destroy with            */
+/*      SHPDestroyObject().                                             */
+/************************************************************************/
+
+SHPObject SHPAPI_CALL1(*)
+SHPCreateSimpleObject( int nSHPType, int nVertices,
+                       double * padfX, double * padfY,
+                       double * padfZ )
+
+{
+    return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
+                             nVertices, padfX, padfY, padfZ, NULL ) );
+}
+                                  
+/************************************************************************/
+/*                           SHPWriteObject()                           */
+/*                                                                      */
+/*      Write out the vertices of a new structure.  Note that it is     */
+/*      only possible to write vertices at the end of the file.         */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
+		      
+{
+    int	       	nRecordOffset, i, nRecordSize;
+    uchar	*pabyRec;
+    int32	i32;
+
+    psSHP->bUpdated = TRUE;
+
+/* -------------------------------------------------------------------- */
+/*      Ensure that shape object matches the type of the file it is     */
+/*      being written to.                                               */
+/* -------------------------------------------------------------------- */
+    assert( psObject->nSHPType == psSHP->nShapeType 
+            || psObject->nSHPType == SHPT_NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Ensure that -1 is used for appends.  Either blow an             */
+/*      assertion, or if they are disabled, set the shapeid to -1       */
+/*      for appends.                                                    */
+/* -------------------------------------------------------------------- */
+    assert( nShapeId == -1 
+            || (nShapeId >= 0 && nShapeId < psSHP->nRecords) );
+
+    if( nShapeId != -1 && nShapeId >= psSHP->nRecords )
+        nShapeId = -1;
+
+/* -------------------------------------------------------------------- */
+/*      Add the new entity to the in memory index.                      */
+/* -------------------------------------------------------------------- */
+    if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
+    {
+	psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
+
+	psSHP->panRecOffset = (int *) 
+            SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
+	psSHP->panRecSize = (int *) 
+            SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Initialize record.                                              */
+/* -------------------------------------------------------------------- */
+    pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) 
+			       + psObject->nParts * 8 + 128);
+    
+/* -------------------------------------------------------------------- */
+/*  Extract vertices for a Polygon or Arc.				*/
+/* -------------------------------------------------------------------- */
+    if( psObject->nSHPType == SHPT_POLYGON
+        || psObject->nSHPType == SHPT_POLYGONZ
+        || psObject->nSHPType == SHPT_POLYGONM
+        || psObject->nSHPType == SHPT_ARC 
+        || psObject->nSHPType == SHPT_ARCZ
+        || psObject->nSHPType == SHPT_ARCM
+        || psObject->nSHPType == SHPT_MULTIPATCH )
+    {
+	int32		nPoints, nParts;
+	int    		i;
+
+	nPoints = psObject->nVertices;
+	nParts = psObject->nParts;
+
+	_SHPSetBounds( pabyRec + 12, psObject );
+
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+	if( bBigEndian ) SwapWord( 4, &nParts );
+
+	ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
+	ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
+
+        nRecordSize = 52;
+
+        /*
+         * Write part start positions.
+         */
+	ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
+                  4 * psObject->nParts );
+	for( i = 0; i < psObject->nParts; i++ )
+	{
+	    if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
+            nRecordSize += 4;
+	}
+
+        /*
+         * Write multipatch part types if needed.
+         */
+        if( psObject->nSHPType == SHPT_MULTIPATCH )
+        {
+            memcpy( pabyRec + nRecordSize, psObject->panPartType,
+                    4*psObject->nParts );
+            for( i = 0; i < psObject->nParts; i++ )
+            {
+                if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize );
+                nRecordSize += 4;
+            }
+        }
+
+        /*
+         * Write the (x,y) vertex values.
+         */
+	for( i = 0; i < psObject->nVertices; i++ )
+	{
+	    ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
+	    ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
+
+	    if( bBigEndian )
+                SwapWord( 8, pabyRec + nRecordSize );
+            
+	    if( bBigEndian )
+                SwapWord( 8, pabyRec + nRecordSize + 8 );
+
+            nRecordSize += 2 * 8;
+	}
+
+        /*
+         * Write the Z coordinates (if any).
+         */
+        if( psObject->nSHPType == SHPT_POLYGONZ
+            || psObject->nSHPType == SHPT_ARCZ
+            || psObject->nSHPType == SHPT_MULTIPATCH )
+        {
+            ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+
+        /*
+         * Write the M values, if any.
+         */
+        if( psObject->nSHPType == SHPT_POLYGONM
+            || psObject->nSHPType == SHPT_ARCM
+#ifndef DISABLE_MULTIPATCH_MEASURE            
+            || psObject->nSHPType == SHPT_MULTIPATCH
+#endif            
+            || psObject->nSHPType == SHPT_POLYGONZ
+            || psObject->nSHPType == SHPT_ARCZ )
+        {
+            ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*  Extract vertices for a MultiPoint.					*/
+/* -------------------------------------------------------------------- */
+    else if( psObject->nSHPType == SHPT_MULTIPOINT
+             || psObject->nSHPType == SHPT_MULTIPOINTZ
+             || psObject->nSHPType == SHPT_MULTIPOINTM )
+    {
+	int32		nPoints;
+	int    		i;
+
+	nPoints = psObject->nVertices;
+
+        _SHPSetBounds( pabyRec + 12, psObject );
+
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+	ByteCopy( &nPoints, pabyRec + 44, 4 );
+	
+	for( i = 0; i < psObject->nVertices; i++ )
+	{
+	    ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
+	    ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
+
+	    if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
+	    if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
+	}
+
+	nRecordSize = 48 + 16 * psObject->nVertices;
+
+        if( psObject->nSHPType == SHPT_MULTIPOINTZ )
+        {
+            ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+
+        if( psObject->nSHPType == SHPT_MULTIPOINTZ
+            || psObject->nSHPType == SHPT_MULTIPOINTM )
+        {
+            ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+
+            ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+            
+            for( i = 0; i < psObject->nVertices; i++ )
+            {
+                ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 );
+                if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+                nRecordSize += 8;
+            }
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Write point.							*/
+/* -------------------------------------------------------------------- */
+    else if( psObject->nSHPType == SHPT_POINT
+             || psObject->nSHPType == SHPT_POINTZ
+             || psObject->nSHPType == SHPT_POINTM )
+    {
+	ByteCopy( psObject->padfX, pabyRec + 12, 8 );
+	ByteCopy( psObject->padfY, pabyRec + 20, 8 );
+
+	if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
+	if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
+
+        nRecordSize = 28;
+        
+        if( psObject->nSHPType == SHPT_POINTZ )
+        {
+            ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+        }
+        
+        if( psObject->nSHPType == SHPT_POINTZ
+            || psObject->nSHPType == SHPT_POINTM )
+        {
+            ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
+            if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
+            nRecordSize += 8;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Not much to do for null geometries.                             */
+/* -------------------------------------------------------------------- */
+    else if( psObject->nSHPType == SHPT_NULL )
+    {
+        nRecordSize = 12;
+    }
+
+    else
+    {
+        /* unknown type */
+        assert( FALSE );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Establish where we are going to put this record. If we are      */
+/*      rewriting and existing record, and it will fit, then put it     */
+/*      back where the original came from.  Otherwise write at the end. */
+/* -------------------------------------------------------------------- */
+    if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
+    {
+        if( nShapeId == -1 )
+            nShapeId = psSHP->nRecords++;
+
+        psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize;
+        psSHP->panRecSize[nShapeId] = nRecordSize-8;
+        psSHP->nFileSize += nRecordSize;
+    }
+    else
+    {
+        nRecordOffset = psSHP->panRecOffset[nShapeId];
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Set the shape type, record number, and record size.             */
+/* -------------------------------------------------------------------- */
+    i32 = nShapeId+1;					/* record # */
+    if( !bBigEndian ) SwapWord( 4, &i32 );
+    ByteCopy( &i32, pabyRec, 4 );
+
+    i32 = (nRecordSize-8)/2;				/* record size */
+    if( !bBigEndian ) SwapWord( 4, &i32 );
+    ByteCopy( &i32, pabyRec + 4, 4 );
+
+    i32 = psObject->nSHPType;				/* shape type */
+    if( bBigEndian ) SwapWord( 4, &i32 );
+    ByteCopy( &i32, pabyRec + 8, 4 );
+
+/* -------------------------------------------------------------------- */
+/*      Write out record.                                               */
+/* -------------------------------------------------------------------- */
+    if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
+        || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
+    {
+        printf( "Error in fseek() or fwrite().\n" );
+        free( pabyRec );
+        return -1;
+    }
+    
+    free( pabyRec );
+
+/* -------------------------------------------------------------------- */
+/*	Expand file wide bounds based on this shape.			*/
+/* -------------------------------------------------------------------- */
+    if( psSHP->adBoundsMin[0] == 0.0
+        && psSHP->adBoundsMax[0] == 0.0
+        && psSHP->adBoundsMin[1] == 0.0
+        && psSHP->adBoundsMax[1] == 0.0 
+        && psObject->nSHPType != SHPT_NULL )
+    {
+        psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
+        psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
+        psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
+        psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
+    }
+
+    for( i = 0; i < psObject->nVertices; i++ )
+    {
+	psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
+	psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
+	psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
+	psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
+	psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
+	psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
+	psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
+	psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
+    }
+
+    return( nShapeId  );
+}
+
+/************************************************************************/
+/*                          SHPReadObject()                             */
+/*                                                                      */
+/*      Read the vertices, parts, and other non-attribute information	*/
+/*	for one shape.							*/
+/************************************************************************/
+
+SHPObject SHPAPI_CALL1(*)
+SHPReadObject( SHPHandle psSHP, int hEntity )
+
+{
+    SHPObject		*psShape;
+
+/* -------------------------------------------------------------------- */
+/*      Validate the record/entity number.                              */
+/* -------------------------------------------------------------------- */
+    if( hEntity < 0 || hEntity >= psSHP->nRecords )
+        return( NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Ensure our record buffer is large enough.                       */
+/* -------------------------------------------------------------------- */
+    if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
+    {
+	psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
+	psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Read the record.                                                */
+/* -------------------------------------------------------------------- */
+    fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 );
+    fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );
+
+/* -------------------------------------------------------------------- */
+/*	Allocate and minimally initialize the object.			*/
+/* -------------------------------------------------------------------- */
+    psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
+    psShape->nShapeId = hEntity;
+
+    memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
+    if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
+
+/* ==================================================================== */
+/*  Extract vertices for a Polygon or Arc.				*/
+/* ==================================================================== */
+    if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC
+        || psShape->nSHPType == SHPT_POLYGONZ
+        || psShape->nSHPType == SHPT_POLYGONM
+        || psShape->nSHPType == SHPT_ARCZ
+        || psShape->nSHPType == SHPT_ARCM
+        || psShape->nSHPType == SHPT_MULTIPATCH )
+    {
+	int32		nPoints, nParts;
+	int    		i, nOffset;
+
+/* -------------------------------------------------------------------- */
+/*	Get the X/Y bounds.						*/
+/* -------------------------------------------------------------------- */
+        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
+        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
+        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
+        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
+
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+
+/* -------------------------------------------------------------------- */
+/*      Extract part/point count, and build vertex and part arrays      */
+/*      to proper size.                                                 */
+/* -------------------------------------------------------------------- */
+	memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
+	memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
+
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+	if( bBigEndian ) SwapWord( 4, &nParts );
+
+	psShape->nVertices = nPoints;
+        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfM = (double *) calloc(nPoints,sizeof(double));
+
+	psShape->nParts = nParts;
+        psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
+        psShape->panPartType = (int *) calloc(nParts,sizeof(int));
+
+        for( i = 0; i < nParts; i++ )
+            psShape->panPartType[i] = SHPP_RING;
+
+/* -------------------------------------------------------------------- */
+/*      Copy out the part array from the record.                        */
+/* -------------------------------------------------------------------- */
+	memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
+	for( i = 0; i < nParts; i++ )
+	{
+	    if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
+	}
+
+	nOffset = 44 + 8 + 4*nParts;
+
+/* -------------------------------------------------------------------- */
+/*      If this is a multipatch, we will also have parts types.         */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts );
+            for( i = 0; i < nParts; i++ )
+            {
+                if( bBigEndian ) SwapWord( 4, psShape->panPartType+i );
+            }
+
+            nOffset += 4*nParts;
+        }
+        
+/* -------------------------------------------------------------------- */
+/*      Copy out the vertices from the record.                          */
+/* -------------------------------------------------------------------- */
+	for( i = 0; i < nPoints; i++ )
+	{
+	    memcpy(psShape->padfX + i,
+		   psSHP->pabyRec + nOffset + i * 16,
+		   8 );
+
+	    memcpy(psShape->padfY + i,
+		   psSHP->pabyRec + nOffset + i * 16 + 8,
+		   8 );
+
+	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+	}
+
+        nOffset += 16*nPoints;
+        
+/* -------------------------------------------------------------------- */
+/*      If we have a Z coordinate, collect that now.                    */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_POLYGONZ
+            || psShape->nSHPType == SHPT_ARCZ
+            || psShape->nSHPType == SHPT_MULTIPATCH )
+        {
+            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfZ + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
+            }
+
+            nOffset += 16 + 8*nPoints;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a M measure value, then read it now.  We assume      */
+/*      that the measure can be present for any shape if the size is    */
+/*      big enough, but really it will only occur for the Z shapes      */
+/*      (options), and the M shapes.                                    */
+/* -------------------------------------------------------------------- */
+        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        {
+            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfM + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
+            }
+        }
+        
+    }
+
+/* ==================================================================== */
+/*  Extract vertices for a MultiPoint.					*/
+/* ==================================================================== */
+    else if( psShape->nSHPType == SHPT_MULTIPOINT
+             || psShape->nSHPType == SHPT_MULTIPOINTM
+             || psShape->nSHPType == SHPT_MULTIPOINTZ )
+    {
+	int32		nPoints;
+	int    		i, nOffset;
+
+	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
+	if( bBigEndian ) SwapWord( 4, &nPoints );
+
+	psShape->nVertices = nPoints;
+        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
+        psShape->padfM = (double *) calloc(nPoints,sizeof(double));
+
+	for( i = 0; i < nPoints; i++ )
+	{
+	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
+	    memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
+
+	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+	}
+
+        nOffset = 48 + 16*nPoints;
+        
+/* -------------------------------------------------------------------- */
+/*	Get the X/Y bounds.						*/
+/* -------------------------------------------------------------------- */
+        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
+        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
+        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
+        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
+
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+
+/* -------------------------------------------------------------------- */
+/*      If we have a Z coordinate, collect that now.                    */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_MULTIPOINTZ )
+        {
+            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfZ + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
+            }
+
+            nOffset += 16 + 8*nPoints;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a M measure value, then read it now.  We assume      */
+/*      that the measure can be present for any shape if the size is    */
+/*      big enough, but really it will only occur for the Z shapes      */
+/*      (options), and the M shapes.                                    */
+/* -------------------------------------------------------------------- */
+        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+        {
+            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
+            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
+            
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
+            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
+            
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy( psShape->padfM + i,
+                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
+                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
+            }
+        }
+    }
+
+/* ==================================================================== */
+/*      Extract vertices for a point.                                   */
+/* ==================================================================== */
+    else if( psShape->nSHPType == SHPT_POINT
+             || psShape->nSHPType == SHPT_POINTM
+             || psShape->nSHPType == SHPT_POINTZ )
+    {
+        int	nOffset;
+        
+	psShape->nVertices = 1;
+        psShape->padfX = (double *) calloc(1,sizeof(double));
+        psShape->padfY = (double *) calloc(1,sizeof(double));
+        psShape->padfZ = (double *) calloc(1,sizeof(double));
+        psShape->padfM = (double *) calloc(1,sizeof(double));
+
+	memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
+	memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
+
+	if( bBigEndian ) SwapWord( 8, psShape->padfX );
+	if( bBigEndian ) SwapWord( 8, psShape->padfY );
+
+        nOffset = 20 + 8;
+        
+/* -------------------------------------------------------------------- */
+/*      If we have a Z coordinate, collect that now.                    */
+/* -------------------------------------------------------------------- */
+        if( psShape->nSHPType == SHPT_POINTZ )
+        {
+            memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 );
+        
+            if( bBigEndian ) SwapWord( 8, psShape->padfZ );
+            
+            nOffset += 8;
+        }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a M measure value, then read it now.  We assume      */
+/*      that the measure can be present for any shape if the size is    */
+/*      big enough, but really it will only occur for the Z shapes      */
+/*      (options), and the M shapes.                                    */
+/* -------------------------------------------------------------------- */
+        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
+        {
+            memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
+        
+            if( bBigEndian ) SwapWord( 8, psShape->padfM );
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Since no extents are supplied in the record, we will apply      */
+/*      them from the single vertex.                                    */
+/* -------------------------------------------------------------------- */
+        psShape->dfXMin = psShape->dfXMax = psShape->padfX[0];
+        psShape->dfYMin = psShape->dfYMax = psShape->padfY[0];
+        psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0];
+        psShape->dfMMin = psShape->dfMMax = psShape->padfM[0];
+    }
+
+    return( psShape );
+}
+
+/************************************************************************/
+/*                            SHPTypeName()                             */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+SHPTypeName( int nSHPType )
+
+{
+    switch( nSHPType )
+    {
+      case SHPT_NULL:
+        return "NullShape";
+
+      case SHPT_POINT:
+        return "Point";
+
+      case SHPT_ARC:
+        return "Arc";
+
+      case SHPT_POLYGON:
+        return "Polygon";
+
+      case SHPT_MULTIPOINT:
+        return "MultiPoint";
+        
+      case SHPT_POINTZ:
+        return "PointZ";
+
+      case SHPT_ARCZ:
+        return "ArcZ";
+
+      case SHPT_POLYGONZ:
+        return "PolygonZ";
+
+      case SHPT_MULTIPOINTZ:
+        return "MultiPointZ";
+        
+      case SHPT_POINTM:
+        return "PointM";
+
+      case SHPT_ARCM:
+        return "ArcM";
+
+      case SHPT_POLYGONM:
+        return "PolygonM";
+
+      case SHPT_MULTIPOINTM:
+        return "MultiPointM";
+
+      case SHPT_MULTIPATCH:
+        return "MultiPatch";
+
+      default:
+        return "UnknownShapeType";
+    }
+}
+
+/************************************************************************/
+/*                          SHPPartTypeName()                           */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+SHPPartTypeName( int nPartType )
+
+{
+    switch( nPartType )
+    {
+      case SHPP_TRISTRIP:
+        return "TriangleStrip";
+        
+      case SHPP_TRIFAN:
+        return "TriangleFan";
+
+      case SHPP_OUTERRING:
+        return "OuterRing";
+
+      case SHPP_INNERRING:
+        return "InnerRing";
+
+      case SHPP_FIRSTRING:
+        return "FirstRing";
+
+      case SHPP_RING:
+        return "Ring";
+
+      default:
+        return "UnknownPartType";
+    }
+}
+
+/************************************************************************/
+/*                          SHPDestroyObject()                          */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPDestroyObject( SHPObject * psShape )
+
+{
+    if( psShape == NULL )
+        return;
+    
+    if( psShape->padfX != NULL )
+        free( psShape->padfX );
+    if( psShape->padfY != NULL )
+        free( psShape->padfY );
+    if( psShape->padfZ != NULL )
+        free( psShape->padfZ );
+    if( psShape->padfM != NULL )
+        free( psShape->padfM );
+
+    if( psShape->panPartStart != NULL )
+        free( psShape->panPartStart );
+    if( psShape->panPartType != NULL )
+        free( psShape->panPartType );
+
+    free( psShape );
+}
+
+/************************************************************************/
+/*                          SHPRewindObject()                           */
+/*                                                                      */
+/*      Reset the winding of polygon objects to adhere to the           */
+/*      specification.                                                  */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
+
+{
+    int  iOpRing, bAltered = 0;
+
+/* -------------------------------------------------------------------- */
+/*      Do nothing if this is not a polygon object.                     */
+/* -------------------------------------------------------------------- */
+    if( psObject->nSHPType != SHPT_POLYGON
+        && psObject->nSHPType != SHPT_POLYGONZ
+        && psObject->nSHPType != SHPT_POLYGONM )
+        return 0;
+
+/* -------------------------------------------------------------------- */
+/*      Process each of the rings.                                      */
+/* -------------------------------------------------------------------- */
+    for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ )
+    {
+        int      bInner, iVert, nVertCount, nVertStart, iCheckRing;
+        double   dfSum, dfTestX, dfTestY;
+
+/* -------------------------------------------------------------------- */
+/*      Determine if this ring is an inner ring or an outer ring        */
+/*      relative to all the other rings.  For now we assume the         */
+/*      first ring is outer and all others are inner, but eventually    */
+/*      we need to fix this to handle multiple island polygons and      */
+/*      unordered sets of rings.                                        */
+/* -------------------------------------------------------------------- */
+        dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
+        dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
+
+        bInner = FALSE;
+        for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
+        {
+            int iEdge;
+
+            if( iCheckRing == iOpRing )
+                continue;
+            
+            nVertStart = psObject->panPartStart[iCheckRing];
+
+            if( iCheckRing == psObject->nParts-1 )
+                nVertCount = psObject->nVertices 
+                    - psObject->panPartStart[iCheckRing];
+            else
+                nVertCount = psObject->panPartStart[iCheckRing+1] 
+                    - psObject->panPartStart[iCheckRing];
+
+            for( iEdge = 0; iEdge < nVertCount; iEdge++ )
+            {
+                int iNext;
+
+                if( iEdge < nVertCount-1 )
+                    iNext = iEdge+1;
+                else
+                    iNext = 0;
+
+                if( (psObject->padfY[iEdge+nVertStart] < dfTestY 
+                     && psObject->padfY[iNext+nVertStart] >= dfTestY)
+                    || (psObject->padfY[iNext+nVertStart] < dfTestY 
+                        && psObject->padfY[iEdge+nVertStart] >= dfTestY) )
+                {
+                    if( psObject->padfX[iEdge+nVertStart] 
+                        + (dfTestY - psObject->padfY[iEdge+nVertStart])
+                           / (psObject->padfY[iNext+nVertStart]
+                              - psObject->padfY[iEdge+nVertStart])
+                           * (psObject->padfX[iNext+nVertStart]
+                              - psObject->padfX[iEdge+nVertStart]) < dfTestX )
+                        bInner = !bInner;
+                }
+            }
+        }
+
+/* -------------------------------------------------------------------- */
+/*      Determine the current order of this ring so we will know if     */
+/*      it has to be reversed.                                          */
+/* -------------------------------------------------------------------- */
+        nVertStart = psObject->panPartStart[iOpRing];
+
+        if( iOpRing == psObject->nParts-1 )
+            nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing];
+        else
+            nVertCount = psObject->panPartStart[iOpRing+1] 
+                - psObject->panPartStart[iOpRing];
+
+        dfSum = 0.0;
+        for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
+        {
+            dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1]
+                - psObject->padfY[iVert] * psObject->padfX[iVert+1];
+        }
+
+        dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
+               - psObject->padfY[iVert] * psObject->padfX[nVertStart];
+
+/* -------------------------------------------------------------------- */
+/*      Reverse if necessary.                                           */
+/* -------------------------------------------------------------------- */
+        if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) )
+        {
+            int   i;
+
+            bAltered++;
+            for( i = 0; i < nVertCount/2; i++ )
+            {
+                double dfSaved;
+
+                /* Swap X */
+                dfSaved = psObject->padfX[nVertStart+i];
+                psObject->padfX[nVertStart+i] = 
+                    psObject->padfX[nVertStart+nVertCount-i-1];
+                psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved;
+
+                /* Swap Y */
+                dfSaved = psObject->padfY[nVertStart+i];
+                psObject->padfY[nVertStart+i] = 
+                    psObject->padfY[nVertStart+nVertCount-i-1];
+                psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved;
+
+                /* Swap Z */
+                if( psObject->padfZ )
+                {
+                    dfSaved = psObject->padfZ[nVertStart+i];
+                    psObject->padfZ[nVertStart+i] = 
+                        psObject->padfZ[nVertStart+nVertCount-i-1];
+                    psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved;
+                }
+
+                /* Swap M */
+                if( psObject->padfM )
+                {
+                    dfSaved = psObject->padfM[nVertStart+i];
+                    psObject->padfM[nVertStart+i] = 
+                        psObject->padfM[nVertStart+nVertCount-i-1];
+                    psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved;
+                }
+            }
+        }
+    }
+
+    return bAltered;
+}
diff --git a/src/shapelib/shprewind.c b/src/shapelib/shprewind.c
new file mode 100644
index 0000000..590313e
--- /dev/null
+++ b/src/shapelib/shprewind.c
@@ -0,0 +1,140 @@
+/******************************************************************************
+ * $Id: shprewind.c,v 1.3 2010/07/11 07:24:37 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Utility to validate and reset the winding order of rings in
+ *           polygon geometries to match the ordering required by spec.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2002, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shprewind.c,v $
+ * Revision 1.3  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.2  2007/07/25 15:37:50  we7u
+ * Added shprewind.c to the "clean" target of the original Makefile.  Added
+ * stdlib.h includes to some of the utilities to get a clean compile.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.2  2002/04/10 17:23:11  warmerda
+ * copy from source to destination now
+ *
+ * Revision 1.1  2002/04/10 16:56:36  warmerda
+ * New
+ *
+ */
+
+#include "shapefil.h"
+#include <stdlib.h>
+
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP, hSHPOut;
+    int		nShapeType, nEntities, i, nInvalidCount=0;
+    double 	adfMinBound[4], adfMaxBound[4];
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 3 )
+    {
+	printf( "shprewind in_shp_file out_shp_file\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "rb" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
+    
+/* -------------------------------------------------------------------- */
+/*      Create output shapefile.                                        */
+/* -------------------------------------------------------------------- */
+    hSHPOut = SHPCreate( argv[2], nShapeType );
+
+    if( hSHPOut == NULL )
+    {
+	printf( "Unable to create:%s\n", argv[2] );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*	Skim over the list of shapes, printing all the vertices.	*/
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nEntities; i++ )
+    {
+//	int		j;
+        SHPObject	*psShape;
+
+	psShape = SHPReadObject( hSHP, i );
+        if( SHPRewindObject( hSHP, psShape ) )
+            nInvalidCount++;
+        SHPWriteObject( hSHPOut, -1, psShape );
+        SHPDestroyObject( psShape );
+    }
+
+    SHPClose( hSHP );
+    SHPClose( hSHPOut );
+
+    printf( "%d objects rewound.\n", nInvalidCount );
+
+    exit( 0 );
+}
diff --git a/src/shapelib/shptest.c b/src/shapelib/shptest.c
new file mode 100644
index 0000000..6ca23e5
--- /dev/null
+++ b/src/shapelib/shptest.c
@@ -0,0 +1,333 @@
+/******************************************************************************
+ * $Id: shptest.c,v 1.2 2009/06/04 04:25:19 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Application for generating sample Shapefiles of various types.
+ *           Used by the stream2.sh test script.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shptest.c,v $
+ * Revision 1.2  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.6  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.5  2001/06/22 02:18:20  warmerda
+ * Added null shape support
+ *
+ * Revision 1.4  2000/07/07 13:39:45  warmerda
+ * removed unused variables, and added system include files
+ *
+ * Revision 1.3  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.2  1998/12/16 05:15:20  warmerda
+ * Added support for writing multipatch.
+ *
+ * Revision 1.1  1998/11/09 20:18:42  warmerda
+ * Initial revision
+ *
+ */
+
+//static char rcsid[] = 
+//  "$Id: shptest.c,v 1.2 2009/06/04 04:25:19 we7u Exp $";
+
+#include <stdlib.h>
+#include <string.h>
+#include "shapefil.h"
+
+/************************************************************************/
+/*                          Test_WritePoints()                          */
+/*                                                                      */
+/*      Write a small point file.                                       */
+/************************************************************************/
+
+static void Test_WritePoints( int nSHPType, const char *pszFilename )
+
+{
+    SHPHandle	hSHPHandle;
+    SHPObject	*psShape;
+    double	x, y, z, m;
+
+    hSHPHandle = SHPCreate( pszFilename, nSHPType );
+
+    x = 1.0;
+    y = 2.0;
+    z = 3.0;
+    m = 4.0;
+    psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
+                               1, &x, &y, &z, &m );
+    SHPWriteObject( hSHPHandle, -1, psShape );
+    SHPDestroyObject( psShape );
+    
+    x = 10.0;
+    y = 20.0;
+    z = 30.0;
+    m = 40.0;
+    psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
+                               1, &x, &y, &z, &m );
+    SHPWriteObject( hSHPHandle, -1, psShape );
+    SHPDestroyObject( psShape );
+
+    SHPClose( hSHPHandle );
+}
+
+/************************************************************************/
+/*                       Test_WriteMultiPoints()                        */
+/*                                                                      */
+/*      Write a small multipoint file.                                  */
+/************************************************************************/
+
+static void Test_WriteMultiPoints( int nSHPType, const char *pszFilename )
+
+{
+    SHPHandle	hSHPHandle;
+    SHPObject	*psShape;
+    double	x[4], y[4], z[4], m[4];
+    int		i, iShape;
+
+    hSHPHandle = SHPCreate( pszFilename, nSHPType );
+
+    for( iShape = 0; iShape < 3; iShape++ )
+    {
+        for( i = 0; i < 4; i++ )
+        {
+            x[i] = iShape * 10 + i + 1.15;
+            y[i] = iShape * 10 + i + 2.25;
+            z[i] = iShape * 10 + i + 3.35;
+            m[i] = iShape * 10 + i + 4.45;
+        }
+        
+        psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
+                                   4, x, y, z, m );
+        SHPWriteObject( hSHPHandle, -1, psShape );
+        SHPDestroyObject( psShape );
+    }    
+
+    SHPClose( hSHPHandle );
+}
+
+/************************************************************************/
+/*                         Test_WriteArcPoly()                          */
+/*                                                                      */
+/*      Write a small arc or polygon file.                              */
+/************************************************************************/
+
+static void Test_WriteArcPoly( int nSHPType, const char *pszFilename )
+
+{
+    SHPHandle	hSHPHandle;
+    SHPObject	*psShape;
+    double	x[100], y[100], z[100], m[100];
+    int		anPartStart[100];
+    int		anPartType[100], *panPartType;
+    int		i, iShape;
+
+    hSHPHandle = SHPCreate( pszFilename, nSHPType );
+
+    if( nSHPType == SHPT_MULTIPATCH )
+        panPartType = anPartType;
+    else
+        panPartType = NULL;
+
+    for( iShape = 0; iShape < 3; iShape++ )
+    {
+        x[0] = 1.0;
+        y[0] = 1.0+iShape*3;
+        x[1] = 2.0;
+        y[1] = 1.0+iShape*3;
+        x[2] = 2.0;
+        y[2] = 2.0+iShape*3;
+        x[3] = 1.0;
+        y[3] = 2.0+iShape*3;
+        x[4] = 1.0;
+        y[4] = 1.0+iShape*3;
+
+        for( i = 0; i < 5; i++ )
+        {
+            z[i] = iShape * 10 + i + 3.35;
+            m[i] = iShape * 10 + i + 4.45;
+        }
+        
+        psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
+                                   5, x, y, z, m );
+        SHPWriteObject( hSHPHandle, -1, psShape );
+        SHPDestroyObject( psShape );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Do a multi part polygon (shape).  We close it, and have two     */
+/*      inner rings.                                                    */
+/* -------------------------------------------------------------------- */
+    x[0] = 0.0;
+    y[0] = 0.0;
+    x[1] = 0;
+    y[1] = 100;
+    x[2] = 100;
+    y[2] = 100;
+    x[3] = 100;
+    y[3] = 0;
+    x[4] = 0;
+    y[4] = 0;
+
+    x[5] = 10;
+    y[5] = 20;
+    x[6] = 30;
+    y[6] = 20;
+    x[7] = 30;
+    y[7] = 40;
+    x[8] = 10;
+    y[8] = 40;
+    x[9] = 10;
+    y[9] = 20;
+
+    x[10] = 60;
+    y[10] = 20;
+    x[11] = 90;
+    y[11] = 20;
+    x[12] = 90;
+    y[12] = 40;
+    x[13] = 60;
+    y[13] = 40;
+    x[14] = 60;
+    y[14] = 20;
+
+    for( i = 0; i < 15; i++ )
+    {
+        z[i] = i;
+        m[i] = i*2;
+    }
+
+    anPartStart[0] = 0;
+    anPartStart[1] = 5;
+    anPartStart[2] = 10;
+
+    anPartType[0] = SHPP_RING;
+    anPartType[1] = SHPP_INNERRING;
+    anPartType[2] = SHPP_INNERRING;
+    
+    psShape = SHPCreateObject( nSHPType, -1, 3, anPartStart, panPartType,
+                               15, x, y, z, m );
+    SHPWriteObject( hSHPHandle, -1, psShape );
+    SHPDestroyObject( psShape );
+    
+
+    SHPClose( hSHPHandle );
+}
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+int main( int argc, char ** argv )
+
+{
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc != 2 )
+    {
+	printf( "shptest test_number\n" );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Figure out which test to run.                                   */
+/* -------------------------------------------------------------------- */
+
+    if( atoi(argv[1]) == 0 )
+        Test_WritePoints( SHPT_NULL, "test0.shp" );
+
+    else if( atoi(argv[1]) == 1 )
+        Test_WritePoints( SHPT_POINT, "test1.shp" );
+    else if( atoi(argv[1]) == 2 )
+        Test_WritePoints( SHPT_POINTZ, "test2.shp" );
+    else if( atoi(argv[1]) == 3 )
+        Test_WritePoints( SHPT_POINTM, "test3.shp" );
+
+    else if( atoi(argv[1]) == 4 )
+        Test_WriteMultiPoints( SHPT_MULTIPOINT, "test4.shp" );
+    else if( atoi(argv[1]) == 5 )
+        Test_WriteMultiPoints( SHPT_MULTIPOINTZ, "test5.shp" );
+    else if( atoi(argv[1]) == 6 )
+        Test_WriteMultiPoints( SHPT_MULTIPOINTM, "test6.shp" );
+
+    else if( atoi(argv[1]) == 7 )
+        Test_WriteArcPoly( SHPT_ARC, "test7.shp" );
+    else if( atoi(argv[1]) == 8 )
+        Test_WriteArcPoly( SHPT_ARCZ, "test8.shp" );
+    else if( atoi(argv[1]) == 9 )
+        Test_WriteArcPoly( SHPT_ARCM, "test9.shp" );
+
+    else if( atoi(argv[1]) == 10 )
+        Test_WriteArcPoly( SHPT_POLYGON, "test10.shp" );
+    else if( atoi(argv[1]) == 11 )
+        Test_WriteArcPoly( SHPT_POLYGONZ, "test11.shp" );
+    else if( atoi(argv[1]) == 12 )
+        Test_WriteArcPoly( SHPT_POLYGONM, "test12.shp" );
+    
+    else if( atoi(argv[1]) == 13 )
+        Test_WriteArcPoly( SHPT_MULTIPATCH, "test13.shp" );
+    else
+    {
+        printf( "Test `%s' not recognised.\n", argv[1] );
+        exit( 10 );
+    }
+
+#ifdef USE_DBMALLOC
+    malloc_dump(2);
+#endif
+
+    exit( 0 );
+}
diff --git a/src/shapelib/shptree.c b/src/shapelib/shptree.c
new file mode 100644
index 0000000..dd6b2c7
--- /dev/null
+++ b/src/shapelib/shptree.c
@@ -0,0 +1,705 @@
+/******************************************************************************
+ * $Id: shptree.c,v 1.2 2006/11/14 21:28:48 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Implementation of quadtree building and searching functions.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shptree.c,v $
+ * Revision 1.2  2006/11/14 21:28:48  we7u
+ * Commenting out some variables that give off compiler warnings.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.9  2003/01/28 15:53:41  warmerda
+ * Avoid build warnings.
+ *
+ * Revision 1.8  2002/05/07 13:07:45  warmerda
+ * use qsort() - patch from Bernhard Herzog
+ *
+ * Revision 1.7  2002/01/15 14:36:07  warmerda
+ * updated email address
+ *
+ * Revision 1.6  2001/05/23 13:36:52  warmerda
+ * added use of SHPAPI_CALL
+ *
+ * Revision 1.5  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.4  1999/06/02 18:24:21  warmerda
+ * added trimming code
+ *
+ * Revision 1.3  1999/06/02 17:56:12  warmerda
+ * added quad'' subnode support for trees
+ *
+ * Revision 1.2  1999/05/18 19:11:11  warmerda
+ * Added example searching capability
+ *
+ * Revision 1.1  1999/05/18 17:49:20  warmerda
+ * New
+ *
+ */
+
+//static char rcsid[] = 
+//  "$Id: shptree.c,v 1.2 2006/11/14 21:28:48 we7u Exp $";
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef TRUE
+#  define TRUE 1
+#  define FALSE 0
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*      If the following is 0.5, nodes will be split in half.  If it    */
+/*      is 0.6 then each subnode will contain 60% of the parent         */
+/*      node, with 20% representing overlap.  This can be help to       */
+/*      prevent small objects on a boundary from shifting too high      */
+/*      up the tree.                                                    */
+/* -------------------------------------------------------------------- */
+
+#define SHP_SPLIT_RATIO	0.55
+
+/************************************************************************/
+/*                             SfRealloc()                              */
+/*                                                                      */
+/*      A realloc cover function that will access a NULL pointer as     */
+/*      a valid input.                                                  */
+/************************************************************************/
+
+static void * SfRealloc( void * pMem, int nNewSize )
+
+{
+    if( pMem == NULL )
+        return( (void *) malloc(nNewSize) );
+    else
+        return( (void *) realloc(pMem,nNewSize) );
+}
+
+/************************************************************************/
+/*                          SHPTreeNodeInit()                           */
+/*                                                                      */
+/*      Initialize a tree node.                                         */
+/************************************************************************/
+
+static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin,
+                                       double * padfBoundsMax )
+
+{
+    SHPTreeNode	*psTreeNode;
+
+    psTreeNode = (SHPTreeNode *) malloc(sizeof(SHPTreeNode));
+
+    psTreeNode->nShapeCount = 0;
+    psTreeNode->panShapeIds = NULL;
+    psTreeNode->papsShapeObj = NULL;
+
+    psTreeNode->nSubNodes = 0;
+
+    if( padfBoundsMin != NULL )
+        memcpy( psTreeNode->adfBoundsMin, padfBoundsMin, sizeof(double) * 4 );
+
+    if( padfBoundsMax != NULL )
+        memcpy( psTreeNode->adfBoundsMax, padfBoundsMax, sizeof(double) * 4 );
+
+    return psTreeNode;
+}
+
+
+/************************************************************************/
+/*                           SHPCreateTree()                            */
+/************************************************************************/
+
+SHPTree SHPAPI_CALL1(*)
+SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
+               double *padfBoundsMin, double *padfBoundsMax )
+
+{
+    SHPTree	*psTree;
+
+    if( padfBoundsMin == NULL && hSHP == NULL )
+        return NULL;
+
+/* -------------------------------------------------------------------- */
+/*      Allocate the tree object                                        */
+/* -------------------------------------------------------------------- */
+    psTree = (SHPTree *) malloc(sizeof(SHPTree));
+
+    psTree->hSHP = hSHP;
+    psTree->nMaxDepth = nMaxDepth;
+    psTree->nDimension = nDimension;
+
+/* -------------------------------------------------------------------- */
+/*      If no max depth was defined, try to select a reasonable one     */
+/*      that implies approximately 8 shapes per node.                   */
+/* -------------------------------------------------------------------- */
+    if( psTree->nMaxDepth == 0 && hSHP != NULL )
+    {
+        int	nMaxNodeCount = 1;
+        int	nShapeCount;
+
+        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
+        while( nMaxNodeCount*4 < nShapeCount )
+        {
+            psTree->nMaxDepth += 1;
+            nMaxNodeCount = nMaxNodeCount * 2;
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Allocate the root node.                                         */
+/* -------------------------------------------------------------------- */
+    psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax );
+
+/* -------------------------------------------------------------------- */
+/*      Assign the bounds to the root node.  If none are passed in,     */
+/*      use the bounds of the provided file otherwise the create        */
+/*      function will have already set the bounds.                      */
+/* -------------------------------------------------------------------- */
+    if( padfBoundsMin == NULL )
+    {
+        SHPGetInfo( hSHP, NULL, NULL,
+                    psTree->psRoot->adfBoundsMin, 
+                    psTree->psRoot->adfBoundsMax );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      If we have a file, insert all it's shapes into the tree.        */
+/* -------------------------------------------------------------------- */
+    if( hSHP != NULL )
+    {
+        int	iShape, nShapeCount;
+        
+        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
+
+        for( iShape = 0; iShape < nShapeCount; iShape++ )
+        {
+            SHPObject	*psShape;
+            
+            psShape = SHPReadObject( hSHP, iShape );
+            SHPTreeAddShapeId( psTree, psShape );
+            SHPDestroyObject( psShape );
+        }
+    }        
+
+    return psTree;
+}
+
+/************************************************************************/
+/*                         SHPDestroyTreeNode()                         */
+/************************************************************************/
+
+static void SHPDestroyTreeNode( SHPTreeNode * psTreeNode )
+
+{
+    int		i;
+    
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( psTreeNode->apsSubNode[i] != NULL )
+            SHPDestroyTreeNode( psTreeNode->apsSubNode[i] );
+    }
+    
+    if( psTreeNode->panShapeIds != NULL )
+        free( psTreeNode->panShapeIds );
+
+    if( psTreeNode->papsShapeObj != NULL )
+    {
+        for( i = 0; i < psTreeNode->nShapeCount; i++ )
+        {
+            if( psTreeNode->papsShapeObj[i] != NULL )
+                SHPDestroyObject( psTreeNode->papsShapeObj[i] );
+        }
+
+        free( psTreeNode->papsShapeObj );
+    }
+
+    free( psTreeNode );
+}
+
+/************************************************************************/
+/*                           SHPDestroyTree()                           */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPDestroyTree( SHPTree * psTree )
+
+{
+    SHPDestroyTreeNode( psTree->psRoot );
+    free( psTree );
+}
+
+/************************************************************************/
+/*                       SHPCheckBoundsOverlap()                        */
+/*                                                                      */
+/*      Do the given boxes overlap at all?                              */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPCheckBoundsOverlap( double * padfBox1Min, double * padfBox1Max,
+                       double * padfBox2Min, double * padfBox2Max,
+                       int nDimension )
+
+{
+    int		iDim;
+
+    for( iDim = 0; iDim < nDimension; iDim++ )
+    {
+        if( padfBox2Max[iDim] < padfBox1Min[iDim] )
+            return FALSE;
+        
+        if( padfBox1Max[iDim] < padfBox2Min[iDim] )
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                      SHPCheckObjectContained()                       */
+/*                                                                      */
+/*      Does the given shape fit within the indicated extents?          */
+/************************************************************************/
+
+static int SHPCheckObjectContained( SHPObject * psObject, int nDimension,
+                           double * padfBoundsMin, double * padfBoundsMax )
+
+{
+    if( psObject->dfXMin < padfBoundsMin[0]
+        || psObject->dfXMax > padfBoundsMax[0] )
+        return FALSE;
+    
+    if( psObject->dfYMin < padfBoundsMin[1]
+        || psObject->dfYMax > padfBoundsMax[1] )
+        return FALSE;
+
+    if( nDimension == 2 )
+        return TRUE;
+    
+    if( psObject->dfZMin < padfBoundsMin[2]
+        || psObject->dfZMax < padfBoundsMax[2] )
+        return FALSE;
+        
+    if( nDimension == 3 )
+        return TRUE;
+
+    if( psObject->dfMMin < padfBoundsMin[3]
+        || psObject->dfMMax < padfBoundsMax[3] )
+        return FALSE;
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                         SHPTreeSplitBounds()                         */
+/*                                                                      */
+/*      Split a region into two subregion evenly, cutting along the     */
+/*      longest dimension.                                              */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPTreeSplitBounds( double *padfBoundsMinIn, double *padfBoundsMaxIn,
+                    double *padfBoundsMin1, double * padfBoundsMax1,
+                    double *padfBoundsMin2, double * padfBoundsMax2 )
+
+{
+/* -------------------------------------------------------------------- */
+/*      The output bounds will be very similar to the input bounds,     */
+/*      so just copy over to start.                                     */
+/* -------------------------------------------------------------------- */
+    memcpy( padfBoundsMin1, padfBoundsMinIn, sizeof(double) * 4 );
+    memcpy( padfBoundsMax1, padfBoundsMaxIn, sizeof(double) * 4 );
+    memcpy( padfBoundsMin2, padfBoundsMinIn, sizeof(double) * 4 );
+    memcpy( padfBoundsMax2, padfBoundsMaxIn, sizeof(double) * 4 );
+    
+/* -------------------------------------------------------------------- */
+/*      Split in X direction.                                           */
+/* -------------------------------------------------------------------- */
+    if( (padfBoundsMaxIn[0] - padfBoundsMinIn[0])
+        			> (padfBoundsMaxIn[1] - padfBoundsMinIn[1]) )
+    {
+        double	dfRange = padfBoundsMaxIn[0] - padfBoundsMinIn[0];
+
+        padfBoundsMax1[0] = padfBoundsMinIn[0] + dfRange * SHP_SPLIT_RATIO;
+        padfBoundsMin2[0] = padfBoundsMaxIn[0] - dfRange * SHP_SPLIT_RATIO;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise split in Y direction.                                 */
+/* -------------------------------------------------------------------- */
+    else
+    {
+        double	dfRange = padfBoundsMaxIn[1] - padfBoundsMinIn[1];
+
+        padfBoundsMax1[1] = padfBoundsMinIn[1] + dfRange * SHP_SPLIT_RATIO;
+        padfBoundsMin2[1] = padfBoundsMaxIn[1] - dfRange * SHP_SPLIT_RATIO;
+    }
+}
+
+/************************************************************************/
+/*                       SHPTreeNodeAddShapeId()                        */
+/************************************************************************/
+
+static int
+SHPTreeNodeAddShapeId( SHPTreeNode * psTreeNode, SHPObject * psObject,
+                       int nMaxDepth, int nDimension )
+
+{
+    int		i;
+    
+/* -------------------------------------------------------------------- */
+/*      If there are subnodes, then consider wiether this object        */
+/*      will fit in them.                                               */
+/* -------------------------------------------------------------------- */
+    if( nMaxDepth > 1 && psTreeNode->nSubNodes > 0 )
+    {
+        for( i = 0; i < psTreeNode->nSubNodes; i++ )
+        {
+            if( SHPCheckObjectContained(psObject, nDimension,
+                                      psTreeNode->apsSubNode[i]->adfBoundsMin,
+                                      psTreeNode->apsSubNode[i]->adfBoundsMax))
+            {
+                return SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[i],
+                                              psObject, nMaxDepth-1,
+                                              nDimension );
+            }
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise, consider creating four subnodes if could fit into    */
+/*      them, and adding to the appropriate subnode.                    */
+/* -------------------------------------------------------------------- */
+#if MAX_SUBNODE == 4
+    else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 )
+    {
+        double	adfBoundsMinH1[4], adfBoundsMaxH1[4];
+        double	adfBoundsMinH2[4], adfBoundsMaxH2[4];
+        double	adfBoundsMin1[4], adfBoundsMax1[4];
+        double	adfBoundsMin2[4], adfBoundsMax2[4];
+        double	adfBoundsMin3[4], adfBoundsMax3[4];
+        double	adfBoundsMin4[4], adfBoundsMax4[4];
+
+        SHPTreeSplitBounds( psTreeNode->adfBoundsMin,
+                            psTreeNode->adfBoundsMax,
+                            adfBoundsMinH1, adfBoundsMaxH1,
+                            adfBoundsMinH2, adfBoundsMaxH2 );
+
+        SHPTreeSplitBounds( adfBoundsMinH1, adfBoundsMaxH1,
+                            adfBoundsMin1, adfBoundsMax1,
+                            adfBoundsMin2, adfBoundsMax2 );
+
+        SHPTreeSplitBounds( adfBoundsMinH2, adfBoundsMaxH2,
+                            adfBoundsMin3, adfBoundsMax3,
+                            adfBoundsMin4, adfBoundsMax4 );
+
+        if( SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin1, adfBoundsMax1)
+            || SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin2, adfBoundsMax2)
+            || SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin3, adfBoundsMax3)
+            || SHPCheckObjectContained(psObject, nDimension,
+                                    adfBoundsMin4, adfBoundsMax4) )
+        {
+            psTreeNode->nSubNodes = 4;
+            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
+                                                           adfBoundsMax1 );
+            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
+                                                           adfBoundsMax2 );
+            psTreeNode->apsSubNode[2] = SHPTreeNodeCreate( adfBoundsMin3,
+                                                           adfBoundsMax3 );
+            psTreeNode->apsSubNode[3] = SHPTreeNodeCreate( adfBoundsMin4,
+                                                           adfBoundsMax4 );
+
+            /* recurse back on this node now that it has subnodes */
+            return( SHPTreeNodeAddShapeId( psTreeNode, psObject,
+                                           nMaxDepth, nDimension ) );
+        }
+    }
+#endif /* MAX_SUBNODE == 4 */
+
+/* -------------------------------------------------------------------- */
+/*      Otherwise, consider creating two subnodes if could fit into     */
+/*      them, and adding to the appropriate subnode.                    */
+/* -------------------------------------------------------------------- */
+#if MAX_SUBNODE == 2
+    else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 )
+    {
+        double	adfBoundsMin1[4], adfBoundsMax1[4];
+        double	adfBoundsMin2[4], adfBoundsMax2[4];
+
+        SHPTreeSplitBounds( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax,
+                            adfBoundsMin1, adfBoundsMax1,
+                            adfBoundsMin2, adfBoundsMax2 );
+
+        if( SHPCheckObjectContained(psObject, nDimension,
+                                 adfBoundsMin1, adfBoundsMax1))
+        {
+            psTreeNode->nSubNodes = 2;
+            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
+                                                           adfBoundsMax1 );
+            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
+                                                           adfBoundsMax2 );
+
+            return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[0], psObject,
+                                           nMaxDepth - 1, nDimension ) );
+        }
+        else if( SHPCheckObjectContained(psObject, nDimension,
+                                         adfBoundsMin2, adfBoundsMax2) )
+        {
+            psTreeNode->nSubNodes = 2;
+            psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1,
+                                                           adfBoundsMax1 );
+            psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2,
+                                                           adfBoundsMax2 );
+
+            return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[1], psObject,
+                                           nMaxDepth - 1, nDimension ) );
+        }
+    }
+#endif /* MAX_SUBNODE == 2 */
+
+/* -------------------------------------------------------------------- */
+/*      If none of that worked, just add it to this nodes list.         */
+/* -------------------------------------------------------------------- */
+    psTreeNode->nShapeCount++;
+
+    psTreeNode->panShapeIds =
+        SfRealloc( psTreeNode->panShapeIds,
+                   sizeof(int) * psTreeNode->nShapeCount );
+    psTreeNode->panShapeIds[psTreeNode->nShapeCount-1] = psObject->nShapeId;
+
+    if( psTreeNode->papsShapeObj != NULL )
+    {
+        psTreeNode->papsShapeObj =
+            SfRealloc( psTreeNode->papsShapeObj,
+                       sizeof(void *) * psTreeNode->nShapeCount );
+        psTreeNode->papsShapeObj[psTreeNode->nShapeCount-1] = NULL;
+    }
+
+    return TRUE;
+}
+
+/************************************************************************/
+/*                         SHPTreeAddShapeId()                          */
+/*                                                                      */
+/*      Add a shape to the tree, but don't keep a pointer to the        */
+/*      object data, just keep the shapeid.                             */
+/************************************************************************/
+
+int SHPAPI_CALL
+SHPTreeAddShapeId( SHPTree * psTree, SHPObject * psObject )
+
+{
+    return( SHPTreeNodeAddShapeId( psTree->psRoot, psObject,
+                                   psTree->nMaxDepth, psTree->nDimension ) );
+}
+
+/************************************************************************/
+/*                      SHPTreeCollectShapesIds()                       */
+/*                                                                      */
+/*      Work function implementing SHPTreeFindLikelyShapes() on a       */
+/*      tree node by tree node basis.                                   */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPTreeCollectShapeIds( SHPTree *hTree, SHPTreeNode * psTreeNode,
+                        double * padfBoundsMin, double * padfBoundsMax,
+                        int * pnShapeCount, int * pnMaxShapes,
+                        int ** ppanShapeList )
+
+{
+    int		i;
+    
+/* -------------------------------------------------------------------- */
+/*      Does this node overlap the area of interest at all?  If not,    */
+/*      return without adding to the list at all.                       */
+/* -------------------------------------------------------------------- */
+    if( !SHPCheckBoundsOverlap( psTreeNode->adfBoundsMin,
+                                psTreeNode->adfBoundsMax,
+                                padfBoundsMin,
+                                padfBoundsMax,
+                                hTree->nDimension ) )
+        return;
+
+/* -------------------------------------------------------------------- */
+/*      Grow the list to hold the shapes on this node.                  */
+/* -------------------------------------------------------------------- */
+    if( *pnShapeCount + psTreeNode->nShapeCount > *pnMaxShapes )
+    {
+        *pnMaxShapes = (*pnShapeCount + psTreeNode->nShapeCount) * 2 + 20;
+        *ppanShapeList = (int *)
+            SfRealloc(*ppanShapeList,sizeof(int) * *pnMaxShapes);
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Add the local nodes shapeids to the list.                       */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nShapeCount; i++ )
+    {
+        (*ppanShapeList)[(*pnShapeCount)++] = psTreeNode->panShapeIds[i];
+    }
+    
+/* -------------------------------------------------------------------- */
+/*      Recurse to subnodes if they exist.                              */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( psTreeNode->apsSubNode[i] != NULL )
+            SHPTreeCollectShapeIds( hTree, psTreeNode->apsSubNode[i],
+                                    padfBoundsMin, padfBoundsMax,
+                                    pnShapeCount, pnMaxShapes,
+                                    ppanShapeList );
+    }
+}
+
+/************************************************************************/
+/*                      SHPTreeFindLikelyShapes()                       */
+/*                                                                      */
+/*      Find all shapes within tree nodes for which the tree node       */
+/*      bounding box overlaps the search box.  The return value is      */
+/*      an array of shapeids terminated by a -1.  The shapeids will     */
+/*      be in order, as hopefully this will result in faster (more      */
+/*      sequential) reading from the file.                              */
+/************************************************************************/
+
+/* helper for qsort */
+static int
+compare_ints( const void * a, const void * b)
+{
+    return (*(int*)a) - (*(int*)b);
+}
+
+int SHPAPI_CALL1(*)
+SHPTreeFindLikelyShapes( SHPTree * hTree,
+                         double * padfBoundsMin, double * padfBoundsMax,
+                         int * pnShapeCount )
+
+{
+    int	*panShapeList=NULL, nMaxShapes = 0;
+
+/* -------------------------------------------------------------------- */
+/*      Perform the search by recursive descent.                        */
+/* -------------------------------------------------------------------- */
+    *pnShapeCount = 0;
+
+    SHPTreeCollectShapeIds( hTree, hTree->psRoot,
+                            padfBoundsMin, padfBoundsMax,
+                            pnShapeCount, &nMaxShapes,
+                            &panShapeList );
+
+/* -------------------------------------------------------------------- */
+/*      Sort the id array                                               */
+/* -------------------------------------------------------------------- */
+
+    qsort(panShapeList, *pnShapeCount, sizeof(int), compare_ints);
+
+    return panShapeList;
+}
+
+/************************************************************************/
+/*                          SHPTreeNodeTrim()                           */
+/*                                                                      */
+/*      This is the recurve version of SHPTreeTrimExtraNodes() that     */
+/*      walks the tree cleaning it up.                                  */
+/************************************************************************/
+
+static int SHPTreeNodeTrim( SHPTreeNode * psTreeNode )
+
+{
+    int		i;
+
+/* -------------------------------------------------------------------- */
+/*      Trim subtrees, and free subnodes that come back empty.          */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( SHPTreeNodeTrim( psTreeNode->apsSubNode[i] ) )
+        {
+            SHPDestroyTreeNode( psTreeNode->apsSubNode[i] );
+
+            psTreeNode->apsSubNode[i] =
+                psTreeNode->apsSubNode[psTreeNode->nSubNodes-1];
+
+            psTreeNode->nSubNodes--;
+
+            i--; /* process the new occupant of this subnode entry */
+        }
+    }
+
+/* -------------------------------------------------------------------- */
+/*      We should be trimmed if we have no subnodes, and no shapes.     */
+/* -------------------------------------------------------------------- */
+    return( psTreeNode->nSubNodes == 0 && psTreeNode->nShapeCount == 0 );
+}
+
+/************************************************************************/
+/*                       SHPTreeTrimExtraNodes()                        */
+/*                                                                      */
+/*      Trim empty nodes from the tree.  Note that we never trim an     */
+/*      empty root node.                                                */
+/************************************************************************/
+
+void SHPAPI_CALL
+SHPTreeTrimExtraNodes( SHPTree * hTree )
+
+{
+    SHPTreeNodeTrim( hTree->psRoot );
+}
+
diff --git a/src/shapelib/shptreedump.c b/src/shapelib/shptreedump.c
new file mode 100644
index 0000000..c6347fb
--- /dev/null
+++ b/src/shapelib/shptreedump.c
@@ -0,0 +1,430 @@
+/******************************************************************************
+ * $Id: shptreedump.c,v 1.4 2010/07/11 07:57:02 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  Mainline for creating and dumping an ASCII representation of
+ *           a quadtree.
+ * Author:   Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shptreedump.c,v $
+ * Revision 1.4  2010/07/11 07:57:02  we7u
+ * Fixing a few more compiler warnings.
+ *
+ * Revision 1.3  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.2  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.7  2002/04/10 16:59:12  warmerda
+ * fixed email
+ *
+ * Revision 1.6  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.5  1999/06/02 18:24:21  warmerda
+ * added trimming code
+ *
+ * Revision 1.4  1999/06/02 17:56:12  warmerda
+ * added quad'' subnode support for trees
+ *
+ * Revision 1.3  1999/05/18 19:13:13  warmerda
+ * Use fabs() instead of abs().
+ *
+ * Revision 1.2  1999/05/18 19:11:11  warmerda
+ * Added example searching capability
+ *
+ * Revision 1.1  1999/05/18 17:49:20  warmerda
+ * New
+ *
+ */
+
+//static char rcsid[] = 
+//  "$Id: shptreedump.c,v 1.4 2010/07/11 07:57:02 we7u Exp $";
+
+#include "shapefil.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+static void SHPTreeNodeDump( SHPTree *, SHPTreeNode *, const char *, int );
+static void SHPTreeNodeSearchAndDump( SHPTree *, double *, double * );
+
+/************************************************************************/
+/*                               Usage()                                */
+/************************************************************************/
+
+static void Usage(void)
+{
+    printf( "shptreedump [-maxdepth n] [-search xmin ymin xmax ymax]\n"
+            "            [-v] shp_file\n" );
+    exit( 1 );
+}
+
+
+
+/************************************************************************/
+/*                                main()                                */
+/************************************************************************/
+int main( int argc, char ** argv )
+
+{
+    SHPHandle	hSHP;
+    SHPTree	*psTree;
+    int		nExpandShapes = 0;
+    int		nMaxDepth = 0;
+    int		nDoSearch = 0;
+    double	adfSearchMin[4], adfSearchMax[4];
+    
+
+/* -------------------------------------------------------------------- */
+/*	Consume flags.							*/
+/* -------------------------------------------------------------------- */
+    while( argc > 1 )
+    {
+        if( strcmp(argv[1],"-v") == 0 )
+        {
+            nExpandShapes = 1;
+            argv++;
+            argc--;
+        }
+        else if( strcmp(argv[1],"-maxdepth") == 0 && argc > 2 )
+        {
+            nMaxDepth = atoi(argv[2]);
+            argv += 2;
+            argc -= 2;
+        }
+        else if( strcmp(argv[1],"-search") == 0 && argc > 5 )
+        {
+            nDoSearch = 1;
+
+            adfSearchMin[0] = atof(argv[2]);
+            adfSearchMin[1] = atof(argv[3]);
+            adfSearchMax[0] = atof(argv[4]);
+            adfSearchMax[1] = atof(argv[5]);
+
+            adfSearchMin[2] = adfSearchMax[2] = 0.0;
+            adfSearchMin[3] = adfSearchMax[3] = 0.0;
+
+            if( adfSearchMin[0] > adfSearchMax[0]
+                || adfSearchMin[1] > adfSearchMax[1] )
+            {
+                printf( "Min greater than max in search criteria.\n" );
+                Usage();
+            }
+            
+            argv += 5;
+            argc -= 5;
+        }
+        else
+            break;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+    if( argc < 2 )
+    {
+        Usage();
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    hSHP = SHPOpen( argv[1], "rb" );
+
+    if( hSHP == NULL )
+    {
+	printf( "Unable to open:%s\n", argv[1] );
+	exit( 1 );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Build a quadtree structure for this file.                       */
+/* -------------------------------------------------------------------- */
+    psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Trim unused nodes from the tree.                                */
+/* -------------------------------------------------------------------- */
+    SHPTreeTrimExtraNodes( psTree );
+        
+/* -------------------------------------------------------------------- */
+/*      Dump tree by recursive descent.                                 */
+/* -------------------------------------------------------------------- */
+    if( !nDoSearch )
+        SHPTreeNodeDump( psTree, psTree->psRoot, "", nExpandShapes );
+
+/* -------------------------------------------------------------------- */
+/*      or do a search instead.                                         */
+/* -------------------------------------------------------------------- */
+    else
+        SHPTreeNodeSearchAndDump( psTree, adfSearchMin, adfSearchMax );
+
+/* -------------------------------------------------------------------- */
+/*      cleanup                                                         */
+/* -------------------------------------------------------------------- */
+    SHPDestroyTree( psTree );
+
+    SHPClose( hSHP );
+
+#ifdef USE_DBMALLOC
+    malloc_dump(2);
+#endif
+
+    exit( 0 );
+}
+
+/************************************************************************/
+/*                           EmitCoordinate()                           */
+/************************************************************************/
+
+static void EmitCoordinate( double * padfCoord, int nDimension )
+
+{
+    const char	*pszFormat;
+    
+    if( fabs(padfCoord[0]) < 180 && fabs(padfCoord[1]) < 180 )
+        pszFormat = "%.9f";
+    else
+        pszFormat = "%.2f";
+
+    printf( pszFormat, padfCoord[0] );
+    printf( "," );
+    printf( pszFormat, padfCoord[1] );
+
+    if( nDimension > 2 )
+    {
+        printf( "," );
+        printf( pszFormat, padfCoord[2] );
+    }
+    if( nDimension > 3 )
+    {
+        printf( "," );
+        printf( pszFormat, padfCoord[3] );
+    }
+}
+
+/************************************************************************/
+/*                             EmitShape()                              */
+/************************************************************************/
+
+static void EmitShape( SHPObject * psObject, const char * pszPrefix,
+                       int nDimension )
+
+{
+    int		i;
+    
+    printf( "%s( Shape\n", pszPrefix );
+    printf( "%s  ShapeId = %d\n", pszPrefix, psObject->nShapeId );
+
+    printf( "%s  Min = (", pszPrefix );
+    EmitCoordinate( &(psObject->dfXMin), nDimension );
+    printf( ")\n" );
+    
+    printf( "%s  Max = (", pszPrefix );
+    EmitCoordinate( &(psObject->dfXMax), nDimension );
+    printf( ")\n" );
+
+    for( i = 0; i < psObject->nVertices; i++ )
+    {
+        double	adfVertex[4];
+        
+        printf( "%s  Vertex[%d] = (", pszPrefix, i );
+
+        adfVertex[0] = psObject->padfX[i];
+        adfVertex[1] = psObject->padfY[i];
+        adfVertex[2] = psObject->padfZ[i];
+        adfVertex[3] = psObject->padfM[i];
+        
+        EmitCoordinate( adfVertex, nDimension );
+        printf( ")\n" );
+    }
+    printf( "%s)\n", pszPrefix );
+}
+
+/************************************************************************/
+/*                          SHPTreeNodeDump()                           */
+/*                                                                      */
+/*      Dump a tree node in a readable form.                            */
+/************************************************************************/
+
+static void SHPTreeNodeDump( SHPTree * psTree,
+                             SHPTreeNode * psTreeNode,
+                             const char * pszPrefix,
+                             int nExpandShapes )
+
+{
+    char	szNextPrefix[150];
+    int		i;
+
+    strcpy( szNextPrefix, pszPrefix );
+    if( strlen(pszPrefix) < sizeof(szNextPrefix) - 3 )
+        strcat( szNextPrefix, "  " );
+
+    printf( "%s( SHPTreeNode\n", pszPrefix );
+
+/* -------------------------------------------------------------------- */
+/*      Emit the bounds.                                                */
+/* -------------------------------------------------------------------- */
+    printf( "%s  Min = (", pszPrefix );
+    EmitCoordinate( psTreeNode->adfBoundsMin, psTree->nDimension );
+    printf( ")\n" );
+    
+    printf( "%s  Max = (", pszPrefix );
+    EmitCoordinate( psTreeNode->adfBoundsMax, psTree->nDimension );
+    printf( ")\n" );
+
+/* -------------------------------------------------------------------- */
+/*      Emit the list of shapes on this node.                           */
+/* -------------------------------------------------------------------- */
+    if( nExpandShapes )
+    {
+        printf( "%s  Shapes(%d):\n", pszPrefix, psTreeNode->nShapeCount );
+        for( i = 0; i < psTreeNode->nShapeCount; i++ )
+        {
+            SHPObject	*psObject;
+
+            psObject = SHPReadObject( psTree->hSHP,
+                                      psTreeNode->panShapeIds[i] );
+            assert( psObject != NULL );
+            if( psObject != NULL )
+            {
+                EmitShape( psObject, szNextPrefix, psTree->nDimension );
+            }
+
+            SHPDestroyObject( psObject );
+        }
+    }
+    else
+    {
+        printf( "%s  Shapes(%d): ", pszPrefix, psTreeNode->nShapeCount );
+        for( i = 0; i < psTreeNode->nShapeCount; i++ )
+        {
+            printf( "%d ", psTreeNode->panShapeIds[i] );
+        }
+        printf( "\n" );
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Emit subnodes.                                                  */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < psTreeNode->nSubNodes; i++ )
+    {
+        if( psTreeNode->apsSubNode[i] != NULL )
+            SHPTreeNodeDump( psTree, psTreeNode->apsSubNode[i],
+                             szNextPrefix, nExpandShapes );
+    }
+    
+    printf( "%s)\n", pszPrefix );
+
+    return;
+}
+
+/************************************************************************/
+/*                      SHPTreeNodeSearchAndDump()                      */
+/************************************************************************/
+
+static void SHPTreeNodeSearchAndDump( SHPTree * hTree,
+                                      double *padfBoundsMin,
+                                      double *padfBoundsMax )
+
+{
+    int		*panHits, nShapeCount, i;
+
+/* -------------------------------------------------------------------- */
+/*      Perform the search for likely candidates.  These are shapes     */
+/*      that fall into a tree node whose bounding box intersects our    */
+/*      area of interest.                                               */
+/* -------------------------------------------------------------------- */
+    panHits = SHPTreeFindLikelyShapes( hTree, padfBoundsMin, padfBoundsMax,
+                                       &nShapeCount );
+
+/* -------------------------------------------------------------------- */
+/*      Read all of these shapes, and establish whether the shape's     */
+/*      bounding box actually intersects the area of interest.  Note    */
+/*      that the bounding box could intersect the area of interest,     */
+/*      and the shape itself still not cross it but we don't try to     */
+/*      address that here.                                              */
+/* -------------------------------------------------------------------- */
+    for( i = 0; i < nShapeCount; i++ )
+    {
+        SHPObject	*psObject;
+
+        psObject = SHPReadObject( hTree->hSHP, panHits[i] );
+        if( psObject == NULL )
+            continue;
+        
+        if( !SHPCheckBoundsOverlap( padfBoundsMin, padfBoundsMax,
+                                    &(psObject->dfXMin),
+                                    &(psObject->dfXMax),
+                                    hTree->nDimension ) )
+        {
+            printf( "Shape %d: not in area of interest, but fetched.\n",
+                    panHits[i] );
+        }
+        else
+        {
+            printf( "Shape %d: appears to be in area of interest.\n",
+                    panHits[i] );
+        }
+
+        SHPDestroyObject( psObject );
+    }
+
+    if( nShapeCount == 0 )
+        printf( "No shapes found in search.\n" );
+}
diff --git a/src/shapelib/shputils.c b/src/shapelib/shputils.c
new file mode 100644
index 0000000..4f5c80b
--- /dev/null
+++ b/src/shapelib/shputils.c
@@ -0,0 +1,1124 @@
+/******************************************************************************
+ * $Id: shputils.c,v 1.7 2010/07/11 20:30:00 we7u Exp $
+ *
+ * Project:  Shapelib
+ * Purpose:  
+ *   Altered "shpdump" and "dbfdump" to allow two files to be appended.
+ *   Other Functions:
+ *     Selecting from the DBF before the write occurs.
+ *     Change the UNITS between Feet and Meters and Shift X,Y.
+ *     Clip and Erase boundary.  The program only passes thru the
+ *     data once.
+ *
+ *   Bill Miller   North Carolina - Department of Transporation 
+ *   Feb. 1997 -- bmiller at dot.state.nc.us
+ *         There was not a lot of time to debug hidden problems;
+ *         And the code is not very well organized or documented.
+ *         The clip/erase function was not well tested.
+ *   Oct. 2000 -- bmiller at dot.state.nc.us
+ *         Fixed the problem when select is using numbers
+ *         larger than short integer.  It now reads long integer.
+ *   NOTE: DBF files created using windows NT will read as a string with
+ *         a length of 381 characters.  This is a bug in "dbfopen".
+ *
+ *
+ * Author:   Bill Miller (bmiller at dot.state.nc.us)
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: shputils.c,v $
+ * Revision 1.7  2010/07/11 20:30:00  we7u
+ * More minor tweaks to get rid of compiler warnings.  Of particular note are
+ * some TODO entries added to a couple of files for two enumerated values that
+ * weren't being handled in "switch" statements.  There still isn't any code
+ * for those case statements, but the compiler warnings are gone.
+ *
+ * Revision 1.6  2010/07/11 08:01:27  we7u
+ * Adding some braces for some "if" statements so that the enclosed else
+ * clause won't be ambiguous.
+ *
+ * Revision 1.5  2010/07/11 07:51:03  we7u
+ * Fixing more compiler warnings.  There are a few left yet.
+ *
+ * Revision 1.4  2010/07/11 07:24:37  we7u
+ * Fixing multiple minor warnings with Shapelib.  Still plenty left.
+ *
+ * Revision 1.3  2010/07/11 06:22:55  we7u
+ * Setting up the rest of shapelib and shapelib/contrib so that everything
+ * compiles.  Had to add an include to shputils.c and add a "1" parameter to
+ * exit() in one spot.
+ *
+ * Revision 1.2  2009/06/04 04:25:19  we7u
+ * Getting rid of compiler warnings due to unused variable.
+ *
+ * Revision 1.1  2006/11/10 21:48:10  tvrusso
+ * Add shapelib as an internal library, and use it if we don't find an external
+ * one.
+ *
+ * Make a loud warning if we do so, because the result of this is that we'll
+ * have a bigger executable.
+ *
+ * This commit is bigger than it needs to be, because it includes all of
+ * shapelib, including the contrib directory.
+ *
+ * Added an automake-generated Makefile for this thing.
+ *
+ * Builds only a static library, and calls it "libshape.a" instead of
+ * "libshp.a" so that if we use ask to use the static one while there is
+ * also an external one installed, the linker doesn't pull in the shared
+ * library one unbidden.
+ *
+ * This stuff can be tested on a system with libshp installed by configuring with
+ * "--without-shapelib"
+ *
+ * I will be removing Makefile.in because it's not supposed to be in CVS.  My
+ * mistake.
+ *
+ * Revision 1.7  2003/02/25 17:20:22  warmerda
+ * Set psCShape to NULL after SHPDestroyObject() to avoid multi-frees of
+ * the same memory ... as submitted by Fred Fox.
+ *
+ * Revision 1.6  2001/08/28 13:57:14  warmerda
+ * fixed DBFAddField return value check
+ *
+ * Revision 1.5  2000/11/02 13:52:48  warmerda
+ * major upgrade from Bill Miller
+ *
+ * Revision 1.4  1999/11/05 14:12:05  warmerda
+ * updated license terms
+ *
+ * Revision 1.3  1998/12/03 15:47:39  warmerda
+ * Did a bunch of rewriting to make it work with the V1.2 API.
+ *
+ * Revision 1.2  1998/06/18 01:19:49  warmerda
+ * Made C++ compilable.
+ *
+ * Revision 1.1  1997/05/27 20:40:27  warmerda
+ * Initial revision
+ */
+
+//static char rcsid[] = 
+//  "$Id: shputils.c,v 1.7 2010/07/11 20:30:00 we7u Exp $";
+
+#include "shapefil.h"
+#include "string.h"
+#include <stdlib.h>
+
+#ifndef FALSE
+#  define FALSE		0
+#  define TRUE		1
+#endif
+
+char            infile[80], outfile[80], temp[400];
+
+/* Variables for shape files */
+SHPHandle	hSHP;
+SHPHandle	hSHPappend;
+int		nShapeType, nEntities, iPart;
+int		nShapeTypeAppend, nEntitiesAppend;
+SHPObject	*psCShape;
+double		adfBoundsMin[4], adfBoundsMax[4];
+
+
+/* Variables for DBF files */
+DBFHandle	hDBF;
+DBFHandle	hDBFappend;
+    
+DBFFieldType    iType;
+DBFFieldType    jType;
+    
+char	iszTitle[12];
+char	jszTitle[12];
+
+int	*pt;
+char	iszFormat[32], iszField[1024];
+char	jszFormat[32], jszField[1024];
+int	i, ti, iWidth, iDecimals, iRecord;
+int	j, tj, jWidth, jDecimals, jRecord;
+int     found, newdbf;
+
+
+void openfiles(void);
+void setext(char *pt, char *ext);
+int strncasecmp2(char *s1, char *s2, int n);
+void mergefields(void);
+void findselect(void);
+void showitems(void);
+int selectrec(void);
+void check_theme_bnd(void);
+int clip_boundary(void);
+void error(void);
+int findunit(char *unit);
+ 
+
+/* -------------------------------------------------------------------- */
+/* Variables for the DESCRIBE function */
+/* -------------------------------------------------------------------- */
+   int       ilist = FALSE, iall = FALSE;
+/* -------------------------------------------------------------------- */
+/* Variables for the SELECT function */
+/* -------------------------------------------------------------------- */
+   int       found = FALSE, newdbf = FALSE;
+   char      selectitem[40], *cpt;
+   long int  selectvalues[150], selcount=0;
+   int       iselect = FALSE, iselectitem = -1;
+   int       iunselect = FALSE;
+
+/* -------------------------------------------------------------------- */
+/* Variables for the CLIP and ERASE functions */
+/* -------------------------------------------------------------------- */
+   double  cxmin, cymin, cxmax, cymax; 
+   int     iclip  = FALSE, ierase = FALSE;
+   int     itouch = FALSE, iinside = FALSE, icut = FALSE;
+   int     ibound = FALSE, ipoly = FALSE;
+   char    clipfile[80];
+
+/* -------------------------------------------------------------------- */
+/* Variables for the FACTOR function */
+/* -------------------------------------------------------------------- */
+   double  infactor,outfactor,factor = 0;  /* NO FACTOR */
+   int     iunit = FALSE;
+   int     ifactor = FALSE;
+
+   
+/* -------------------------------------------------------------------- */
+/* Variables for the SHIFT function */
+/* -------------------------------------------------------------------- */
+   double  xshift = 0, yshift = 0;  /* NO SHIFT */
+      
+int main( int argc, char ** argv )
+{
+
+/* -------------------------------------------------------------------- */
+/*      Check command line usage.                                       */
+/* -------------------------------------------------------------------- */
+    if( argc < 2 ) error();
+    strcpy(infile, argv[1]);
+    if (argc > 2) {
+        strcpy(outfile,argv[2]);
+        if (strncasecmp2(outfile, "LIST",0) == 0) { ilist = TRUE; }
+        if (strncasecmp2(outfile, "ALL",0) == 0)  { iall  = TRUE; }
+    } 
+    if (ilist || iall || argc == 2 ) {
+        setext(infile, "shp");
+        printf("DESCRIBE: %s\n",infile);
+        strcpy(outfile,"");
+    }
+/* -------------------------------------------------------------------- */
+/*	Look for other functions on the command line. (SELECT, UNIT)  	*/
+/* -------------------------------------------------------------------- */
+    for (i = 3; i < argc; i++)
+    {
+    	if ((strncasecmp2(argv[i],  "SEL",3) == 0) ||
+            (strncasecmp2(argv[i],  "UNSEL",5) == 0))
+    	{
+            if (strncasecmp2(argv[i],  "UNSEL",5) == 0) iunselect=TRUE;
+    	    i++;
+    	    if (i >= argc) error();
+    	    strcpy(selectitem,argv[i]);
+    	    i++;
+    	    if (i >= argc) error();
+    	    selcount=0;
+    	    strcpy(temp,argv[i]);
+    	    cpt=temp;
+    	    tj = atoi(cpt);
+    	    ti = 0;
+    	    while (tj>0) {
+                selectvalues[selcount] = tj;
+                while( *cpt >= '0' && *cpt <= '9')
+                    cpt++; 
+                while( *cpt > '\0' && (*cpt < '0' || *cpt > '9') )
+                    cpt++; 
+                tj=atoi(cpt);
+                selcount++;
+    	    }
+    	    iselect=TRUE;
+    	}  /*** End SEL & UNSEL ***/
+    	else
+            if ((strncasecmp2(argv[i], "CLIP",4) == 0) ||
+                (strncasecmp2(argv[i],  "ERASE",5) == 0))
+            {
+                if (strncasecmp2(argv[i],  "ERASE",5) == 0) ierase=TRUE;
+                i++;
+                if (i >= argc) error();
+                strcpy(clipfile,argv[i]);
+                sscanf(argv[i],"%lf",&cxmin);
+                i++;
+                if (i >= argc) error();
+                if (strncasecmp2(argv[i],  "BOUND",5) == 0) {
+                    setext(clipfile, "shp");
+                    hSHP = SHPOpen( clipfile, "rb" );
+                    if( hSHP == NULL )
+                    {
+                        printf( "ERROR: Unable to open the clip shape file:%s\n", clipfile );
+                        exit( 1 );
+                    }
+                    SHPGetInfo( hSHPappend, NULL, NULL,
+                                adfBoundsMin, adfBoundsMax );
+                    cxmin = adfBoundsMin[0];
+                    cymin = adfBoundsMin[1];
+                    cxmax = adfBoundsMax[0];
+                    cymax = adfBoundsMax[1];
+                    printf("Theme Clip Boundary: (%lf,%lf) - (%lf,%lf)\n",
+                           cxmin, cymin, cxmax, cymax);
+                    ibound=TRUE;
+                } else {  /*** xmin,ymin,xmax,ymax ***/
+                    sscanf(argv[i],"%lf",&cymin);
+                    i++;
+                    if (i >= argc) error();
+                    sscanf(argv[i],"%lf",&cxmax);
+                    i++;
+                    if (i >= argc) error();
+                    sscanf(argv[i],"%lf",&cymax);
+                    printf("Clip Box: (%lf,%lf) - (%lf,%lf)\n",cxmin, cymin, cxmax, cymax);
+                }
+                i++;
+                if (i >= argc) error();
+                if      (strncasecmp2(argv[i], "CUT",3) == 0)    icut=TRUE;
+                else if (strncasecmp2(argv[i], "TOUCH",5) == 0)  itouch=TRUE;
+                else if (strncasecmp2(argv[i], "INSIDE",6) == 0) iinside=TRUE;
+                else error();
+                iclip=TRUE;
+            } /*** End CLIP & ERASE ***/
+            else if (strncasecmp2(argv[i],  "FACTOR",0) == 0)
+                {
+                i++;
+    	        if (i >= argc) error();
+    	        infactor=findunit(argv[i]);
+    	        if (infactor == 0) error();
+                iunit=TRUE;
+                i++;
+    	        if (i >= argc) error();
+    	        outfactor=findunit(argv[i]);
+    	        if (outfactor == 0)
+    	        {
+                   sscanf(argv[i],"%lf",&factor);
+                   if (factor == 0) error();
+                }
+                if (factor == 0)
+                {
+                  if (infactor ==0)
+                  { puts("ERROR: Input unit must be defined before output unit"); exit(1); }
+                  factor=infactor/outfactor;
+                }
+                printf("Output file coordinate values will be factored by %lg\n",factor);
+                ifactor=(factor != 1); /* True if a valid factor */
+             } /*** End FACTOR ***/
+             else if (strncasecmp2(argv[i],"SHIFT",5) == 0)
+                {
+                i++;
+                if (i >= argc) error();
+                sscanf(argv[i],"%lf",&xshift);
+                i++;
+                if (i >= argc) error();
+                sscanf(argv[i],"%lf",&yshift);
+                iunit=TRUE;
+                printf("X Shift: %lg   Y Shift: %lg\n",xshift,yshift);
+             } /*** End SHIFT ***/
+             else {
+                printf("ERROR: Unknown function %s\n",argv[i]);  error();
+                }
+    }
+/* -------------------------------------------------------------------- */
+/*	If there is no data in this file let the user know.		*/
+/* -------------------------------------------------------------------- */
+    openfiles();  /* Open the infile and the outfile for shape and dbf. */
+    if( DBFGetFieldCount(hDBF) == 0 )
+    {
+	puts( "There are no fields in this table!" );
+	exit( 1 );
+    }
+/* -------------------------------------------------------------------- */
+/*      Print out the file bounds.                                      */
+/* -------------------------------------------------------------------- */
+    iRecord = DBFGetRecordCount( hDBF );
+    SHPGetInfo( hSHP, NULL, NULL, adfBoundsMin, adfBoundsMax );
+
+    printf( "Input Bounds:  (%lg,%lg) - (%lg,%lg)   Entities: %d   DBF: %d\n",
+	    adfBoundsMin[0], adfBoundsMin[1],
+            adfBoundsMax[0], adfBoundsMax[1],
+            nEntities, iRecord );
+	    
+    if (strcmp(outfile,"") == 0) /* Describe the shapefile; No other functions */
+    {
+    	ti = DBFGetFieldCount( hDBF );
+	showitems();
+	exit(0);
+    }
+     
+    if (iclip) check_theme_bnd();
+    
+    jRecord = DBFGetRecordCount( hDBFappend );
+    SHPGetInfo( hSHPappend, NULL, NULL, adfBoundsMin, adfBoundsMax );
+    if (nEntitiesAppend == 0)
+        puts("New Output File\n");
+    else
+        printf( "Append Bounds: (%lg,%lg)-(%lg,%lg)   Entities: %d  DBF: %d\n",
+                adfBoundsMin[0], adfBoundsMin[1],
+                adfBoundsMax[0], adfBoundsMax[1],
+                nEntitiesAppend, jRecord );
+    
+/* -------------------------------------------------------------------- */
+/*	Find matching fields in the append file or add new items.       */
+/* -------------------------------------------------------------------- */
+    mergefields();
+/* -------------------------------------------------------------------- */
+/*	Find selection field if needed.                                 */
+/* -------------------------------------------------------------------- */
+    if (iselect)    findselect();
+
+/* -------------------------------------------------------------------- */
+/*  Read all the records 						*/
+/* -------------------------------------------------------------------- */
+    jRecord = DBFGetRecordCount( hDBFappend );
+    for( iRecord = 0; iRecord < nEntities; iRecord++)  /** DBFGetRecordCount(hDBF) **/
+    {
+/* -------------------------------------------------------------------- */
+/*      SELECT for values if needed. (Can the record be skipped.)       */
+/* -------------------------------------------------------------------- */
+        if (iselect)
+            if (selectrec() == 0) goto SKIP_RECORD;   /** SKIP RECORD **/
+
+/* -------------------------------------------------------------------- */
+/*      Read a Shape record                                             */
+/* -------------------------------------------------------------------- */
+        psCShape = SHPReadObject( hSHP, iRecord );
+
+/* -------------------------------------------------------------------- */
+/*      Clip coordinates of shapes if needed.                           */
+/* -------------------------------------------------------------------- */
+        if (iclip)
+            if (clip_boundary() == 0) goto SKIP_RECORD; /** SKIP RECORD **/
+
+/* -------------------------------------------------------------------- */
+/*      Read a DBF record and copy each field.                          */
+/* -------------------------------------------------------------------- */
+	for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
+	{
+/* -------------------------------------------------------------------- */
+/*      Store the record according to the type and formatting           */
+/*      information implicit in the DBF field description.              */
+/* -------------------------------------------------------------------- */
+            if (pt[i] > -1)  /* if the current field exists in output file */
+            {
+                switch( DBFGetFieldInfo( hDBF, i, NULL, &iWidth, &iDecimals ) )
+                {
+                  case FTString:
+                    DBFWriteStringAttribute(hDBFappend, jRecord, pt[i],
+                                            (DBFReadStringAttribute( hDBF, iRecord, i )) );
+                    break;
+
+                  case FTInteger:
+                    DBFWriteIntegerAttribute(hDBFappend, jRecord, pt[i],
+                                             (DBFReadIntegerAttribute( hDBF, iRecord, i )) );
+                    break;
+
+                  case FTDouble:
+                    DBFWriteDoubleAttribute(hDBFappend, jRecord, pt[i],
+                                            (DBFReadDoubleAttribute( hDBF, iRecord, i )) );
+                    break;
+
+                  case FTLogical:
+// TODO:  Add code here
+                    break;
+
+                  case FTInvalid:
+// TODO:  Add code here
+                    break;
+ 
+                }
+            }
+	}
+	jRecord++;
+/* -------------------------------------------------------------------- */
+/*      Change FACTOR and SHIFT coordinates of shapes if needed.        */
+/* -------------------------------------------------------------------- */
+         if (iunit)
+        {
+	    for( j = 0; j < psCShape->nVertices; j++ ) 
+	    {
+                psCShape->padfX[j] = psCShape->padfX[j] * factor + xshift;
+                psCShape->padfY[j] = psCShape->padfY[j] * factor + yshift;
+	    }
+        }
+        
+/* -------------------------------------------------------------------- */
+/*      Write the Shape record after recomputing current extents.       */
+/* -------------------------------------------------------------------- */
+        SHPComputeExtents( psCShape );
+        SHPWriteObject( hSHPappend, -1, psCShape );
+
+      SKIP_RECORD:
+        SHPDestroyObject( psCShape );
+        psCShape = NULL;
+        j=0;
+    }
+
+/* -------------------------------------------------------------------- */
+/*      Print out the # of Entities and the file bounds.                */
+/* -------------------------------------------------------------------- */
+    jRecord = DBFGetRecordCount( hDBFappend );
+    SHPGetInfo( hSHPappend, &nEntitiesAppend, &nShapeTypeAppend,
+                adfBoundsMin, adfBoundsMax );
+    
+    printf( "Output Bounds: (%lg,%lg) - (%lg,%lg)   Entities: %d  DBF: %d\n\n",
+	    adfBoundsMin[0], adfBoundsMin[1],
+            adfBoundsMax[0], adfBoundsMax[1],
+            nEntitiesAppend, jRecord );
+
+/* -------------------------------------------------------------------- */
+/*      Close the both shapefiles.                                      */
+/* -------------------------------------------------------------------- */
+    SHPClose( hSHP );
+    SHPClose( hSHPappend );
+    DBFClose( hDBF );
+    DBFClose( hDBFappend );
+    if (nEntitiesAppend == 0) {
+       puts("Remove the output files.");
+       setext(outfile, "dbf");
+       remove(outfile);
+       setext(outfile, "shp");
+       remove(outfile);
+       setext(outfile, "shx");
+       remove(outfile);
+    }
+    return( 0 );
+}
+
+
+/************************************************************************/
+/*                             openfiles()                              */
+/************************************************************************/
+
+void openfiles() {
+/* -------------------------------------------------------------------- */
+/*      Open the DBF file.                                              */
+/* -------------------------------------------------------------------- */
+    setext(infile, "dbf");
+    hDBF = DBFOpen( infile, "rb" );
+    if( hDBF == NULL )
+    {
+	printf( "ERROR: Unable to open the input DBF:%s\n", infile );
+	exit( 1 );
+    }
+/* -------------------------------------------------------------------- */
+/*      Open the append DBF file.                                       */
+/* -------------------------------------------------------------------- */
+    if (strcmp(outfile,"")) {
+        setext(outfile, "dbf");
+        hDBFappend = DBFOpen( outfile, "rb+" );
+        newdbf=0;
+        if( hDBFappend == NULL )
+        {
+            newdbf=1;
+            hDBFappend = DBFCreate( outfile );
+            if( hDBFappend == NULL )
+            {
+                printf( "ERROR: Unable to open the append DBF:%s\n", outfile );
+                exit( 1 );
+            }
+        }
+    }
+/* -------------------------------------------------------------------- */
+/*      Open the passed shapefile.                                      */
+/* -------------------------------------------------------------------- */
+    setext(infile, "shp");
+    hSHP = SHPOpen( infile, "rb" );
+
+    if( hSHP == NULL )
+    {
+	printf( "ERROR: Unable to open the input shape file:%s\n", infile );
+	exit( 1 );
+    }
+
+    SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL );
+
+/* -------------------------------------------------------------------- */
+/*      Open the passed append shapefile.                               */
+/* -------------------------------------------------------------------- */
+    if (strcmp(outfile,"")) {
+        setext(outfile, "shp");
+        hSHPappend = SHPOpen( outfile, "rb+" );
+
+        if( hSHPappend == NULL )
+        {
+            hSHPappend = SHPCreate( outfile, nShapeType );
+            if( hSHPappend == NULL )
+            {
+                printf( "ERROR: Unable to open the append shape file:%s\n",
+                        outfile );
+                exit( 1 );
+            }
+        }
+        SHPGetInfo( hSHPappend, &nEntitiesAppend, &nShapeTypeAppend,
+                    NULL, NULL );
+
+        if (nShapeType != nShapeTypeAppend) 
+        {
+            puts( "ERROR: Input and Append shape files are of different types.");
+            exit( 1 );
+        }
+    }
+}
+
+/* -------------------------------------------------------------------- */
+/*	Change the extension.  If there is any extension on the 	*/
+/*	filename, strip it off and add the new extension                */
+/* -------------------------------------------------------------------- */
+void setext(char *pt, char *ext)
+{
+int i;
+    for( i = strlen(pt)-1; 
+	 i > 0 && pt[i] != '.' && pt[i] != '/' && pt[i] != '\\';
+	 i-- ) {}
+
+    if( pt[i] == '.' )
+        pt[i] = '\0';
+        
+    strcat(pt,".");
+    strcat(pt,ext);
+}
+
+
+
+/* -------------------------------------------------------------------- */
+/*	Find matching fields in the append file.                        */
+/*      Output file must have zero records to add any new fields.       */
+/* -------------------------------------------------------------------- */
+void mergefields()
+{
+    int i,j;
+    ti = DBFGetFieldCount( hDBF );
+    tj = DBFGetFieldCount( hDBFappend );
+    /* Create a pointer array for the max # of fields in the output file */
+    pt = (int *) malloc( (ti+tj+1) * sizeof(int) ); 
+    
+    for( i = 0; i < ti; i++ )
+    {
+       pt[i]= -1;  /* Initial pt values to -1 */
+    }
+    /* DBF must be empty before adding items */
+    jRecord = DBFGetRecordCount( hDBFappend );
+    for( i = 0; i < ti; i++ )
+    {
+	iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals );
+        found=FALSE;
+        {
+      	    for( j = 0; j < tj; j++ )   /* Search all field names for a match */
+    	    {
+	        jType = DBFGetFieldInfo( hDBFappend, j, jszTitle, &jWidth, &jDecimals );
+	        if (iType == jType && (strcmp(iszTitle, jszTitle) == 0) )
+	        {
+	            if (found || newdbf)
+	            {
+	                if (i == j)  pt[i]=j;
+	                printf("Warning: Duplicate field name found (%s)\n",iszTitle);
+	                /* Duplicate field name
+	                   (Try to guess the correct field by position) */
+	            }
+	            else
+	            {
+	            	pt[i]=j;  found=TRUE; 
+	            }
+	        }
+	    }
+	}
+	
+	if (pt[i] == -1  && (! found) )  /* Try to force into an existing field */
+	{                                /* Ignore the field name, width, and decimal places */
+	    jType = DBFGetFieldInfo( hDBFappend, j, jszTitle, &jWidth, &jDecimals );
+	    if (iType == jType) 
+	    {
+	    	pt[i]=i;  found=1;
+	    }
+	}
+	if ( (! found) &&  jRecord == 0)  /* Add missing field to the append table */
+	{                 /* The output DBF must be is empty */
+	    pt[i]=tj;
+	    tj++;
+	    if( DBFAddField( hDBFappend, iszTitle, iType, iWidth, iDecimals )
+                == -1 )
+	    {
+		printf( "Warning: DBFAddField(%s, TYPE:%d, WIDTH:%d  DEC:%d, ITEM#:%d of %d) failed.\n",
+		         iszTitle, iType, iWidth, iDecimals, (i+1), (ti+1) );
+		pt[i]=-1;
+	    }
+	}
+    }
+}
+
+
+void findselect()
+{
+    /* Find the select field name */
+    iselectitem = -1;
+    for( i = 0; i < ti  &&  iselectitem < 0; i++ )
+    {
+	iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals );
+        if (strncasecmp2(iszTitle, selectitem, 0) == 0) iselectitem = i;
+    }
+    if (iselectitem == -1) 
+    {
+        printf("Warning: Item not found for selection (%s)\n",selectitem);
+        iselect = FALSE;
+        iall = FALSE;
+	showitems();
+        printf("Continued... (Selecting entire file)\n");
+    }
+    /* Extract all of the select values (by field type) */
+    
+}
+
+void showitems()
+{
+char      stmp[40],slow[40],shigh[40];
+double    dtmp,dlow,dhigh,dsum,mean;
+long int  itmp,ilow,ihigh,isum;
+long int  maxrec;
+char      *pt;
+
+        printf("Available Items: (%d)",ti);
+        maxrec = DBFGetRecordCount(hDBF);
+        if (maxrec > 5000 && ! iall) 
+                { maxrec=5000; printf("  ** ESTIMATED RANGES (MEAN)  For more records use \"All\""); }
+          else  { printf("          RANGES (MEAN)"); }
+          
+        for( i = 0; i < ti; i++ )
+        {
+	    switch( DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ) )
+	    {
+	      case FTString:
+	        strcpy(slow, "~");
+	        strcpy(shigh,"\0");
+                printf("\n  String  %3d  %-16s",iWidth,iszTitle);
+	        for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
+		        strncpy(stmp,DBFReadStringAttribute( hDBF, iRecord, i ),39);
+		        if (strcmp(stmp,"!!") > 0) {
+		          if (strncasecmp2(stmp,slow,0)  < 0) strncpy(slow, stmp,39);
+		          if (strncasecmp2(stmp,shigh,0) > 0) strncpy(shigh,stmp,39);
+		        }
+		}
+		pt=slow+strlen(slow)-1; 
+		while(*pt == ' ') { *pt='\0'; pt--; }
+		pt=shigh+strlen(shigh)-1;
+		while(*pt == ' ') { *pt='\0'; pt--; }
+		if (strncasecmp2(slow,shigh,0) < 0)		printf("%s to %s",slow,shigh);
+		else if (strncasecmp2(slow,shigh,0) == 0)	printf("= %s",slow);
+						    else	printf("No Values");
+		break;
+	      case FTInteger:
+		printf("\n  Integer %3d  %-16s",iWidth,iszTitle);
+		ilow =  1999999999;
+		ihigh= -1999999999;
+		isum =  0;
+	        for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
+		        itmp = DBFReadIntegerAttribute( hDBF, iRecord, i );
+		        if (ilow > itmp)  ilow = itmp;
+		        if (ihigh < itmp) ihigh = itmp;
+		        isum = isum + itmp;
+		}
+		mean=isum/maxrec;
+		if (ilow < ihigh)       printf("%ld to %ld \t(%.1f)",ilow,ihigh,mean);
+		else if (ilow == ihigh) printf("= %ld",ilow);
+		                   else printf("No Values");
+		break;
+
+	      case FTDouble:
+		printf("\n  Real  %3d,%d  %-16s",iWidth,iDecimals,iszTitle);
+		dlow =  999999999999999.0;
+		dhigh= -999999999999999.0;
+		dsum =  0;
+	        for( iRecord = 0; iRecord < maxrec; iRecord++ ) {
+		        dtmp = DBFReadDoubleAttribute( hDBF, iRecord, i );
+		        if (dlow > dtmp) dlow = dtmp;
+		        if (dhigh < dtmp) dhigh = dtmp;
+		        dsum = dsum + dtmp;
+		}
+		mean=dsum/maxrec;
+		sprintf(stmp,"%%.%df to %%.%df \t(%%.%df)",iDecimals,iDecimals,iDecimals);
+		if (dlow < dhigh)       printf(stmp,dlow,dhigh,mean);
+		else if (dlow == dhigh) {
+				        sprintf(stmp,"= %%.%df",iDecimals);
+		                        printf(stmp,dlow);
+		                        }
+		else printf("No Values");
+		break;
+
+          case FTLogical:
+// TODO:  Add code here
+        break;
+
+          case FTInvalid:
+// TODO:  Add code here
+        break;
+ 
+	    }
+
+        }
+	printf("\n");
+}
+
+int selectrec()
+{
+long int value, ty;
+
+   ty = DBFGetFieldInfo( hDBF, iselectitem, NULL, &iWidth, &iDecimals);
+      switch(ty)
+      {
+      case FTString:
+        puts("Invalid Item");
+        iselect=FALSE;
+	break;
+      case FTInteger:
+        value = DBFReadIntegerAttribute( hDBF, iRecord, iselectitem );
+        for (j = 0; j<selcount; j++)
+        {
+          if (selectvalues[j] == value)
+          {
+            if (iunselect) return(0);  /* Keep this record */
+                     else  return(1);  /* Skip this record */
+          }
+        }
+	break;
+      case FTDouble:
+        puts("Invalid Item");
+        iselect=FALSE;
+        break;
+      }
+      if (iunselect) return(1);  /* Skip this record */
+               else  return(0);  /* Keep this record */
+}
+
+
+void check_theme_bnd()
+{
+    if ( (adfBoundsMin[0] >= cxmin) && (adfBoundsMax[0] <= cxmax) &&
+         (adfBoundsMin[1] >= cymin) && (adfBoundsMax[1] <= cymax) )
+    {   /** Theme is totally inside clip area **/
+        if (ierase) nEntities=0; /** SKIP THEME  **/
+        else   iclip=FALSE; /** WRITE THEME (Clip not needed) **/
+    }
+            
+    if ( ( (adfBoundsMin[0] < cxmin) && (adfBoundsMax[0] < cxmin) ) ||
+         ( (adfBoundsMin[1] < cymin) && (adfBoundsMax[1] < cymin) ) ||
+         ( (adfBoundsMin[0] > cxmax) && (adfBoundsMax[0] > cxmax) ) ||
+         ( (adfBoundsMin[1] > cymax) && (adfBoundsMax[1] > cymax) ) )
+    {   /** Theme is totally outside clip area **/
+        if (ierase) iclip=FALSE; /** WRITE THEME (Clip not needed) **/
+             else   nEntities=0; /** SKIP THEME  **/
+    }
+            
+    if (nEntities == 0)
+        puts("WARNING: Theme is outside the clip area."); /** SKIP THEME  **/
+}
+
+int clip_boundary()
+{
+    int  inside;
+    int  prev_outside;
+    int  i2;
+    int  j2;
+    
+       /*** FIRST check the boundary of the feature ***/
+       if ( ( (psCShape->dfXMin < cxmin) && (psCShape->dfXMax < cxmin) ) ||
+            ( (psCShape->dfYMin < cymin) && (psCShape->dfYMax < cymin) ) ||
+            ( (psCShape->dfXMin > cxmax) && (psCShape->dfXMax > cxmax) ) ||
+            ( (psCShape->dfYMin > cymax) && (psCShape->dfYMax > cymax) ) )
+            {   /** Feature is totally outside clip area **/
+            	if (ierase) return(1); /** WRITE RECORD **/
+            	     else   return(0); /** SKIP  RECORD **/
+            }
+       
+       if ( (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax) &&
+            (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax) )
+            {   /** Feature is totally inside clip area **/
+            	if (ierase) return(0); /** SKIP  RECORD **/
+            	     else   return(1); /** WRITE RECORD **/
+            }
+            
+       if (iinside) 
+            { /** INSIDE * Feature might touch the boundary or could be outside **/
+            if (ierase)  return(1); /** WRITE RECORD **/
+                 else    return(0); /** SKIP  RECORD **/
+            }
+       
+       if (itouch)
+          {   /** TOUCH **/
+          if ( ( (psCShape->dfXMin <= cxmin) || (psCShape->dfXMax >= cxmax) ) && 
+                 (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax)    )
+               {   /** Feature intersects the clip boundary only on the X axis **/
+               if (ierase) return(0); /** SKIP  RECORD **/
+                    else   return(1); /** WRITE RECORD **/
+               }
+
+          if (   (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax)   && 
+               ( (psCShape->dfYMin <= cymin) || (psCShape->dfYMax >= cymax) )  )
+               {   /** Feature intersects the clip boundary only on the Y axis **/
+               if (ierase) return(0); /** SKIP  RECORD **/
+                    else   return(1); /** WRITE RECORD **/
+               }
+               
+          for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
+          {   /** At least one vertex must be inside the clip boundary **/
+            if ( (psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax) ||
+                 (psCShape->padfY[j2] >= cymin  && psCShape->padfY[j2] <= cymax)  )
+            {
+              if (ierase) return(0); /** SKIP  RECORD **/
+                   else   return(1); /** WRITE RECORD **/
+            }
+          }
+               
+          /** All vertices are outside the clip boundary **/ 
+          if (ierase) return(1); /** WRITE RECORD **/
+               else   return(0); /** SKIP  RECORD **/
+          }   /** End TOUCH **/
+          
+       if (icut)
+          {   /** CUT **/
+          /*** Check each vertex in the feature with the Boundary and "CUT" ***/
+          /*** THIS CODE WAS NOT COMPLETED!  READ NOTE AT THE BOTTOM ***/
+          i2=0;
+          prev_outside=FALSE;
+          for( j2 = 0; j2 < psCShape->nVertices; j2++ ) 
+             {
+             inside = psCShape->padfX[j2] >= cxmin  &&  psCShape->padfX[j2] <= cxmax  &&
+                      psCShape->padfY[j2] >= cymin  &&  psCShape->padfY[j2] <= cymax ;
+                      
+             if (ierase) inside=(! inside);
+             if (inside)
+                 {
+                 if (i2 != j2)
+                     {
+                     if (prev_outside)
+                         {
+                         // AddIntersection(i2);   /*** Add intersection ***/
+                         prev_outside=FALSE;
+                         }
+                     psCShape->padfX[i2]=psCShape->padfX[j2];     /** move vertex **/
+                     psCShape->padfY[i2]=psCShape->padfY[j2];
+                     }
+                 i2++;
+                 } else {
+                 if ( (! prev_outside) && (j2 > 0) )
+                     {
+                     // AddIntersection(i2);   /*** Add intersection (Watch out for j2==i2-1) ***/
+                     /*** Also a polygon may overlap twice and will split into a several parts  ***/
+                     prev_outside=TRUE;
+                     }
+                 }
+             }
+             
+        printf("Vertices:%d   OUT:%d   Number of Parts:%d\n",
+                psCShape->nVertices,i2, psCShape->nParts );
+               
+             psCShape->nVertices = i2;
+             
+             if (i2 < 2) return(0); /** SKIP RECORD **/
+             /*** (WE ARE NOT CREATING INTERESECTIONS and some lines could be reduced to one point) **/
+        
+             if (i2 == 0) return(0); /** SKIP  RECORD **/
+                  else    return(1); /** WRITE RECORD **/
+          }  /** End CUT **/
+
+//WE7U added this to remove a compiler warning
+    return(0);
+}
+
+
+/************************************************************************/
+/*                            strncasecmp2()                            */
+/*                                                                      */
+/*      Compare two strings up to n characters                          */
+/*      If n=0 then s1 and s2 must be an exact match                    */
+/************************************************************************/
+
+int strncasecmp2(char *s1, char *s2, int n)
+
+{
+int j,i;
+   if (n<1) n=strlen(s1)+1;
+   for (i=0; i<n; i++)
+   {
+      if (*s1 != *s2)
+      {
+         if (*s1 >= 'a' && *s1 <= 'z') {
+            j=*s1-32;
+            if (j != *s2) return(*s1-*s2);
+         } else {
+            if (*s1 >= 'A' && *s1 <= 'Z') { j=*s1+32; }
+                                   else   { j=*s1;    }
+            if (j != *s2) return(*s1-*s2); 
+         }
+      }
+      s1++;
+      s2++;
+   }
+   return(0);
+}
+
+
+#define  NKEYS (sizeof(unitkeytab) / sizeof(struct unitkey))
+int findunit(char *unit)
+   {
+
+   struct unitkey {
+     char   *name;
+     double value;
+   } unitkeytab[] = {
+     { "CM",            39.37 },
+     { "CENTIMETER",    39.37 },
+     { "CENTIMETERS",   39.37 },  /** # of inches * 100 in unit **/
+     { "METER",          3937 },
+     { "METERS",         3937 },
+     { "KM",          3937000 },
+     { "KILOMETER",   3937000 }, 
+     { "KILOMETERS",  3937000 },
+     { "INCH",            100 },
+     { "INCHES",          100 },
+     { "FEET",           1200 },
+     { "FOOT",           1200 },
+     { "YARD",           3600 },
+     { "YARDS",          3600 },       
+     { "MILE",        6336000 },
+     { "MILES",       6336000 }  
+   };
+
+   double unitfactor=0;
+   for (j = 0; j < (int)NKEYS; j++) {
+    if (strncasecmp2(unit, unitkeytab[j].name, 0) == 0) unitfactor=unitkeytab[j].value;
+   }
+   return(unitfactor);
+}
+
+/* -------------------------------------------------------------------- */
+/*      Display a usage message.                                        */
+/* -------------------------------------------------------------------- */
+void error()
+    {	
+	puts( "The program will append to an existing shape file or it will" );
+	puts( "create a new file if needed." );
+	puts( "Only the items in the first output file will be preserved." );
+	puts( "When an item does not match with the append theme then the item");
+	puts( "might be placed to an existing item at the same position and type." );
+	puts( "  OTHER FUNCTIONS:" );
+	puts( "  - Describe all items in the dbase file (Use ALL for more than 5000 recs.)");
+	puts( "  - Select a group of shapes from a comma separated selection list.");
+	puts( "  - UnSelect a group of shapes from a comma separated selection list.");
+	puts( "  - Clip boundary extent or by theme boundary." );
+	puts( "      Touch writes all the shapes that touch the boundary.");
+	puts( "      Inside writes all the shapes that are completely within the boundary.");
+	puts( "      Boundary clips are only the min and max of a theme boundary." );
+	puts( "  - Erase boundary extent or by theme boundary." );
+	puts( "      Erase is the direct opposite of the Clip function." );
+	puts( "  - Change coordinate value units between meters and feet.");
+	puts( "      There is no way to determine the input unit of a shape file.");
+	puts( "      Skip this function if the shape file is already in the correct unit.");
+	puts( "      Clip and Erase will be done before the unit is changed.");
+	puts( "      A shift will be done after the unit is changed."); 
+	puts( "  - Shift X and Y coordinates.\n" );
+	puts( "Finally, There can only be one select or unselect in the command line.");
+	puts( "         There can only be one clip or erase in the command line.");
+	puts( "         There can only be one unit and only one shift in the command line.\n");
+	puts( "Ex: shputils in.shp out.shp   SELECT countycode 3,5,9,13,17,27");
+	puts( "    shputils in.shp out.shp   CLIP   10 10 90 90 Touch   FACTOR Meter Feet");
+	puts( "    shputils in.shp out.shp   FACTOR Meter 3.0");
+	puts( "    shputils in.shp out.shp   CLIP   clip.shp Boundary Touch   SHIFT 40 40");
+	puts( "    shputils in.shp out.shp   SELECT co 112   CLIP clip.shp Boundary Touch\n");
+	puts( "USAGE: shputils  <DescribeShape>   {ALL}");
+	puts( "USAGE: shputils  <InputShape>  <OutShape|AppendShape>" );
+	puts( "   { <FACTOR>       <FEET|MILES|METERS|KM> <FEET|MILES|METERS|KM|factor> }" );
+	puts( "   { <SHIFT>        <xshift> <yshift> }" );
+	puts( "   { <SELECT|UNSEL> <Item> <valuelist> }" );
+	puts( "   { <CLIP|ERASE>   <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
+	puts( "   { <CLIP|ERASE>   <theme>      <BOUNDARY>     <TOUCH|INSIDE|CUT> }" );
+	puts( "     Note: CUT is not complete and does not create intersections.");
+	puts( "           For more information read programmer comment.");
+	
+	/****   Clip functions for Polygon and Cut is not supported
+	There are several web pages that describe methods of doing this function.
+	It seem easy to impliment until you start writting code.  I don't have the
+	time to add these functions but a did leave a simple cut routine in the 
+	program that can be called by using CUT instead of TOUCH in the 
+	CLIP or ERASE functions.  It does not add the intersection of the line and
+	the clip box, so polygons could look incomplete and lines will come up short.
+	
+	Information about clipping lines with a box:
+           http://www.csclub.uwaterloo.ca/u/mpslager/articles/sutherland/wr.html
+        Information about finding the intersection of two lines:
+	   http://www.whisqu.se/per/docs/math28.htm
+	   
+THE CODE LOOKS LIKE THIS:
+ ********************************************************	  
+void Intersect_Lines(float x0,float y0,float x1,float y1,
+                     float x2,float y2,float x3,float y3,
+                     float *xi,float *yi)
+                     {
+//  this function computes the intersection of the sent lines
+//  and returns the intersection point, note that the function assumes
+//  the lines intersect. the function can handle vertical as well
+//  as horizontal lines. note the function isn't very clever, it simply
+//  applies the math, but we don't need speed since this is a
+//  pre-processing step
+//  The Intersect_lines program came from (http://www.whisqu.se/per/docs/math28.htm)
+
+float a1,b1,c1, // constants of linear equations 
+      a2,b2,c2,
+      det_inv,  // the inverse of the determinant of the coefficientmatrix
+      m1,m2;    // the slopes of each line
+      
+// compute slopes, note the cludge for infinity, however, this will
+// be close enough
+if ((x1-x0)!=0)
+   m1 = (y1-y0)/(x1-x0);
+else
+   m1 = (float)1e+10;  // close enough to infinity
+   
+   
+if ((x3-x2)!=0) 
+   m2 = (y3-y2)/(x3-x2);
+else
+   m2 = (float)1e+10;  // close enough to infinity
+   
+// compute constants
+a1 = m1;
+a2 = m2;
+b1 = -1;
+b2 = -1;
+c1 = (y0-m1*x0);
+c2 = (y2-m2*x2);
+// compute the inverse of the determinate
+det_inv = 1/(a1*b2 - a2*b1);
+// use Kramers rule to compute xi and yi
+*xi=((b1*c2 - b2*c1)*det_inv);
+*yi=((a2*c1 - a1*c2)*det_inv);
+} // end Intersect_Lines
+ **********************************************************/
+
+	exit( 1 );
+    }
diff --git a/src/shapelib/stream1.out b/src/shapelib/stream1.out
new file mode 100644
index 0000000..de59c44
--- /dev/null
+++ b/src/shapelib/stream1.out
@@ -0,0 +1,1465 @@
+-------------------------------------------------------------------------
+Test 1: dump anno.shp
+-------------------------------------------------------------------------
+Shapefile Type: Polygon   # of Shapes: 201
+
+File Bounds: (  471276.281, 4751595.500,0,0)
+         to  (  492683.536, 4765390.413,0,0)
+
+Shape:0 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486019.130, 4764549.500, 0, 0)
+      to (  486356.183, 4765212.744, 0, 0)
+     (  486089.531, 4764549.500, 0, 0) Ring 
+     (  486019.130, 4764579.128, 0, 0)  
+     (  486285.782, 4765212.744, 0, 0)  
+     (  486356.183, 4765183.116, 0, 0)  
+     (  486089.531, 4764549.500, 0, 0)  
+
+Shape:1 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  484948.275, 4763866.500, 0, 0)
+      to (  485333.012, 4764070.376, 0, 0)
+     (  484974.719, 4763866.500, 0, 0) Ring 
+     (  484948.275, 4763938.159, 0, 0)  
+     (  485306.569, 4764070.376, 0, 0)  
+     (  485333.012, 4763998.717, 0, 0)  
+     (  484974.719, 4763866.500, 0, 0)  
+
+Shape:2 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  485577.021, 4764106.500, 0, 0)
+      to (  485818.355, 4764259.305, 0, 0)
+     (  485604.156, 4764106.500, 0, 0) Ring 
+     (  485577.021, 4764177.900, 0, 0)  
+     (  485791.220, 4764259.305, 0, 0)  
+     (  485818.355, 4764187.906, 0, 0)  
+     (  485604.156, 4764106.500, 0, 0)  
+
+Shape:3 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  484861.500, 4762570.513, 0, 0)
+      to (  485092.062, 4763026.856, 0, 0)
+     (  485092.062, 4762597.000, 0, 0) Ring 
+     (  485020.420, 4762570.513, 0, 0)  
+     (  484861.500, 4763000.370, 0, 0)  
+     (  484933.143, 4763026.856, 0, 0)  
+     (  485092.062, 4762597.000, 0, 0)  
+
+Shape:4 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  484452.624, 4763792.614, 0, 0)
+      to (  484628.031, 4764105.947, 0, 0)
+     (  484628.031, 4763818.500, 0, 0) Ring 
+     (  484556.169, 4763792.614, 0, 0)  
+     (  484452.624, 4764080.061, 0, 0)  
+     (  484524.486, 4764105.947, 0, 0)  
+     (  484628.031, 4763818.500, 0, 0)  
+
+Shape:5 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  484355.352, 4764139.435, 0, 0)
+      to (  484505.344, 4764380.892, 0, 0)
+     (  484505.344, 4764165.500, 0, 0) Ring 
+     (  484433.546, 4764139.435, 0, 0)  
+     (  484355.352, 4764354.827, 0, 0)  
+     (  484427.150, 4764380.892, 0, 0)  
+     (  484505.344, 4764165.500, 0, 0)  
+
+Shape:6 (Polygon)  nVertices=9, nParts=1
+  Bounds:(  484548.866, 4763118.531, 0, 0)
+      to (  484772.062, 4763742.258, 0, 0)
+     (  484772.062, 4763152.000, 0, 0) Ring 
+     (  484703.404, 4763118.531, 0, 0)  
+     (  484605.763, 4763318.832, 0, 0)  
+     (  484548.866, 4763471.149, 0, 0)  
+     (  484603.088, 4763742.258, 0, 0)  
+     (  484677.987, 4763727.278, 0, 0)  
+     (  484628.031, 4763477.500, 0, 0)  
+     (  484676.031, 4763349.000, 0, 0)  
+     (  484772.062, 4763152.000, 0, 0)  
+
+Shape:7 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  484671.739, 4763562.500, 0, 0)
+      to (  484911.415, 4763682.338, 0, 0)
+     (  484686.719, 4763562.500, 0, 0) Ring 
+     (  484671.739, 4763637.399, 0, 0)  
+     (  484896.435, 4763682.338, 0, 0)  
+     (  484911.415, 4763607.439, 0, 0)  
+     (  484686.719, 4763562.500, 0, 0)  
+
+Shape:8 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  484930.172, 4763125.500, 0, 0)
+      to (  485596.342, 4763453.269, 0, 0)
+     (  484958.719, 4763125.500, 0, 0) Ring 
+     (  484930.172, 4763196.347, 0, 0)  
+     (  485567.795, 4763453.269, 0, 0)  
+     (  485596.342, 4763382.423, 0, 0)  
+     (  484958.719, 4763125.500, 0, 0)  
+
+Shape:9 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  485102.757, 4763082.500, 0, 0)
+      to (  485344.154, 4763234.029, 0, 0)
+     (  485129.406, 4763082.500, 0, 0) Ring 
+     (  485102.757, 4763154.083, 0, 0)  
+     (  485317.505, 4763234.029, 0, 0)  
+     (  485344.154, 4763162.446, 0, 0)  
+     (  485129.406, 4763082.500, 0, 0)  
+
+Shape:10 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  485368.786, 4762538.500, 0, 0)
+      to (  485824.016, 4762774.029, 0, 0)
+     (  485396.156, 4762538.500, 0, 0) Ring 
+     (  485368.786, 4762609.810, 0, 0)  
+     (  485796.646, 4762774.029, 0, 0)  
+     (  485824.016, 4762702.719, 0, 0)  
+     (  485396.156, 4762538.500, 0, 0)  
+
+Shape:11 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487002.484, 4763184.000, 0, 0)
+      to (  487243.960, 4763333.368, 0, 0)
+     (  487028.312, 4763184.000, 0, 0) Ring 
+     (  487002.484, 4763255.883, 0, 0)  
+     (  487218.132, 4763333.368, 0, 0)  
+     (  487243.960, 4763261.486, 0, 0)  
+     (  487028.312, 4763184.000, 0, 0)  
+
+Shape:12 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486733.537, 4762455.413, 0, 0)
+      to (  487076.312, 4763275.483, 0, 0)
+     (  487076.312, 4762480.000, 0, 0) Ring 
+     (  487003.996, 4762455.413, 0, 0)  
+     (  486733.537, 4763250.896, 0, 0)  
+     (  486805.854, 4763275.483, 0, 0)  
+     (  487076.312, 4762480.000, 0, 0)  
+
+Shape:13 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486440.735, 4762331.029, 0, 0)
+      to (  486772.281, 4763075.311, 0, 0)
+     (  486772.281, 4762357.000, 0, 0) Ring 
+     (  486700.450, 4762331.029, 0, 0)  
+     (  486440.735, 4763049.339, 0, 0)  
+     (  486512.566, 4763075.311, 0, 0)  
+     (  486772.281, 4762357.000, 0, 0)  
+
+Shape:14 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486383.882, 4762986.530, 0, 0)
+      to (  486521.594, 4763227.908, 0, 0)
+     (  486521.594, 4763008.000, 0, 0) Ring 
+     (  486448.291, 4762986.530, 0, 0)  
+     (  486383.882, 4763206.438, 0, 0)  
+     (  486457.184, 4763227.908, 0, 0)  
+     (  486521.594, 4763008.000, 0, 0)  
+
+Shape:15 (Polygon)  nVertices=9, nParts=1
+  Bounds:(  486360.416, 4762774.310, 0, 0)
+      to (  486800.882, 4763656.208, 0, 0)
+     (  486489.594, 4763600.000, 0, 0) Ring 
+     (  486541.313, 4763656.208, 0, 0)  
+     (  486762.057, 4763453.094, 0, 0)  
+     (  486800.882, 4763266.659, 0, 0)  
+     (  486420.883, 4762774.310, 0, 0)  
+     (  486360.416, 4762820.979, 0, 0)  
+     (  486718.938, 4763285.500, 0, 0)  
+     (  486692.281, 4763413.500, 0, 0)  
+     (  486489.594, 4763600.000, 0, 0)  
+
+Shape:16 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486682.872, 4762181.000, 0, 0)
+      to (  487292.496, 4762415.463, 0, 0)
+     (  486702.969, 4762181.000, 0, 0) Ring 
+     (  486682.872, 4762254.691, 0, 0)  
+     (  487272.400, 4762415.463, 0, 0)  
+     (  487292.496, 4762341.772, 0, 0)  
+     (  486702.969, 4762181.000, 0, 0)  
+
+Shape:17 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487480.713, 4762283.320, 0, 0)
+      to (  487732.406, 4762812.552, 0, 0)
+     (  487732.406, 4762309.000, 0, 0) Ring 
+     (  487660.470, 4762283.320, 0, 0)  
+     (  487480.713, 4762786.872, 0, 0)  
+     (  487552.649, 4762812.552, 0, 0)  
+     (  487732.406, 4762309.000, 0, 0)  
+
+Shape:18 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487069.757, 4763685.709, 0, 0)
+      to (  487220.344, 4763927.145, 0, 0)
+     (  487220.344, 4763712.000, 0, 0) Ring 
+     (  487148.629, 4763685.709, 0, 0)  
+     (  487069.757, 4763900.854, 0, 0)  
+     (  487141.471, 4763927.145, 0, 0)  
+     (  487220.344, 4763712.000, 0, 0)  
+
+Shape:19 (Polygon)  nVertices=9, nParts=1
+  Bounds:(  487854.719, 4758279.000, 0, 0)
+      to (  488518.085, 4758475.003, 0, 0)
+     (  487854.719, 4758404.000, 0, 0) Ring 
+     (  487882.875, 4758475.003, 0, 0)  
+     (  488183.362, 4758355.845, 0, 0)  
+     (  488341.273, 4758360.840, 0, 0)  
+     (  488515.420, 4758366.919, 0, 0)  
+     (  488518.085, 4758290.583, 0, 0)  
+     (  488343.812, 4758284.500, 0, 0)  
+     (  488169.938, 4758279.000, 0, 0)  
+     (  487854.719, 4758404.000, 0, 0)  
+
+Shape:20 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486300.557, 4758366.000, 0, 0)
+      to (  486613.245, 4758546.262, 0, 0)
+     (  486327.781, 4758366.000, 0, 0) Ring 
+     (  486300.557, 4758437.366, 0, 0)  
+     (  486586.021, 4758546.262, 0, 0)  
+     (  486613.245, 4758474.896, 0, 0)  
+     (  486327.781, 4758366.000, 0, 0)  
+
+Shape:21 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  486709.618, 4758518.000, 0, 0)
+      to (  486949.999, 4758681.145, 0, 0)
+     (  486740.750, 4758518.000, 0, 0) Ring 
+     (  486709.618, 4758587.750, 0, 0)  
+     (  486918.867, 4758681.145, 0, 0)  
+     (  486949.999, 4758611.396, 0, 0)  
+     (  486740.750, 4758518.000, 0, 0)  
+
+Shape:22 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487325.398, 4757807.034, 0, 0)
+      to (  487555.844, 4758263.402, 0, 0)
+     (  487555.844, 4757833.500, 0, 0) Ring 
+     (  487484.193, 4757807.034, 0, 0)  
+     (  487325.398, 4758236.937, 0, 0)  
+     (  487397.049, 4758263.402, 0, 0)  
+     (  487555.844, 4757833.500, 0, 0)  
+
+Shape:23 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487255.256, 4758215.573, 0, 0)
+      to (  487387.406, 4758456.611, 0, 0)
+     (  487387.406, 4758235.000, 0, 0) Ring 
+     (  487313.536, 4758215.573, 0, 0)  
+     (  487255.256, 4758437.184, 0, 0)  
+     (  487329.126, 4758456.611, 0, 0)  
+     (  487387.406, 4758235.000, 0, 0)  
+
+Shape:24 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487248.714, 4758360.500, 0, 0)
+      to (  487559.687, 4758550.761, 0, 0)
+     (  487278.719, 4758360.500, 0, 0) Ring 
+     (  487248.714, 4758430.742, 0, 0)  
+     (  487529.682, 4758550.761, 0, 0)  
+     (  487559.687, 4758480.519, 0, 0)  
+     (  487278.719, 4758360.500, 0, 0)  
+
+Shape:25 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  487573.994, 4758496.500, 0, 0)
+      to (  487815.502, 4758644.603, 0, 0)
+     (  487599.344, 4758496.500, 0, 0) Ring 
+     (  487573.994, 4758568.553, 0, 0)  
+     (  487790.152, 4758644.603, 0, 0)  
+     (  487815.502, 4758572.550, 0, 0)  
+     (  487599.344, 4758496.500, 0, 0)  
+-------------------------------------------------------------------------
+Test 2: dump brklinz.shp
+-------------------------------------------------------------------------
+Shapefile Type: ArcZ   # of Shapes: 122
+
+File Bounds: ( 6294338.260, 1978444.010,0,0)
+         to  ( 6296321.860, 1979694.450,0,0)
+
+Shape:0 (ArcZ)  nVertices=92, nParts=1
+  Bounds:( 6294700.210, 1978579.390, 818.64, 0)
+      to ( 6295395.930, 1979050.330, 917.86, 0)
+     ( 6295372.750, 1978755.830, 823.06, 0) Ring 
+     ( 6295366.170, 1978739.190, 826.58, 0)  
+     ( 6295360.400, 1978718.540, 829.2, 0)  
+     ( 6295352.620, 1978697.000, 832.22, 0)  
+     ( 6295345.960, 1978677.040, 834.64, 0)  
+     ( 6295339.690, 1978656.810, 838.51, 0)  
+     ( 6295335.040, 1978637.600, 840.94, 0)  
+     ( 6295331.080, 1978621.450, 844.48, 0)  
+     ( 6295324.350, 1978607.940, 847.04, 0)  
+     ( 6295313.370, 1978598.450, 850.38, 0)  
+     ( 6295296.780, 1978594.950, 853.27, 0)  
+     ( 6295273.800, 1978594.990, 858.06, 0)  
+     ( 6295251.750, 1978595.380, 861.53, 0)  
+     ( 6295232.340, 1978598.400, 864.22, 0)  
+     ( 6295206.740, 1978606.390, 866.38, 0)  
+     ( 6295180.610, 1978616.970, 868.15, 0)  
+     ( 6295156.350, 1978630.540, 870.65, 0)  
+     ( 6295132.270, 1978645.210, 872.02, 0)  
+     ( 6295111.070, 1978659.740, 875.17, 0)  
+     ( 6295090.030, 1978674.920, 878.84, 0)  
+     ( 6295071.060, 1978689.340, 882.06, 0)  
+     ( 6295051.900, 1978705.080, 886.98, 0)  
+     ( 6295036.460, 1978719.260, 889.66, 0)  
+     ( 6295023.620, 1978732.910, 893.53, 0)  
+     ( 6295010.450, 1978750.380, 895.24, 0)  
+     ( 6294999.910, 1978767.850, 897.47, 0)  
+     ( 6294989.810, 1978783.860, 900.29, 0)  
+     ( 6294975.040, 1978795.570, 902.45, 0)  
+     ( 6294956.300, 1978806.830, 906.32, 0)  
+     ( 6294937.260, 1978814.620, 909.21, 0)  
+     ( 6294919.240, 1978821.960, 912.88, 0)  
+     ( 6294897.040, 1978832.210, 915.04, 0)  
+     ( 6294878.070, 1978844.070, 916.49, 0)  
+     ( 6294865.010, 1978855.820, 917.34, 0)  
+     ( 6294859.560, 1978870.150, 916.81, 0)  
+     ( 6294861.520, 1978882.920, 916.62, 0)  
+     ( 6294874.640, 1978906.220, 917.86, 0)  
+     ( 6294886.980, 1978926.880, 917.6, 0)  
+     ( 6294889.630, 1978953.270, 917.54, 0)  
+     ( 6294888.520, 1978978.280, 916.88, 0)  
+     ( 6294880.350, 1978998.390, 915.96, 0)  
+     ( 6294866.540, 1979018.920, 915.57, 0)  
+     ( 6294843.270, 1979039.140, 915.57, 0)  
+     ( 6294812.250, 1979049.040, 915.96, 0)  
+     ( 6294777.640, 1979050.330, 916.75, 0)  
+     ( 6294752.060, 1979040.520, 916.68, 0)  
+     ( 6294730.990, 1979028.850, 916.62, 0)  
+     ( 6294716.690, 1979008.420, 916.62, 0)  
+     ( 6294706.050, 1978987.490, 916.95, 0)  
+     ( 6294700.210, 1978965.390, 916.95, 0)  
+     ( 6294700.520, 1978937.670, 917.01, 0)  
+     ( 6294712.060, 1978911.340, 916.95, 0)  
+     ( 6294724.820, 1978893.560, 916.62, 0)  
+     ( 6294741.630, 1978878.010, 916.36, 0)  
+     ( 6294759.360, 1978865.090, 916.36, 0)  
+     ( 6294777.650, 1978855.370, 916.22, 0)  
+     ( 6294807.570, 1978846.970, 916.36, 0)  
+     ( 6294837.640, 1978836.590, 916.55, 0)  
+     ( 6294858.650, 1978831.390, 916.29, 0)  
+     ( 6294878.860, 1978825.840, 915.37, 0)  
+     ( 6294897.630, 1978817.860, 913.67, 0)  
+     ( 6294914.550, 1978809.520, 910.78, 0)  
+     ( 6294932.380, 1978798.580, 907.17, 0)  
+     ( 6294947.360, 1978788.370, 904.42, 0)  
+     ( 6294960.500, 1978778.120, 901.86, 0)  
+     ( 6294974.780, 1978761.900, 898.78, 0)  
+     ( 6294988.510, 1978747.610, 895.7, 0)  
+     ( 6295005.230, 1978730.220, 892.81, 0)  
+     ( 6295023.560, 1978713.470, 889.34, 0)  
+     ( 6295043.310, 1978696.320, 885.07, 0)  
+     ( 6295061.830, 1978680.810, 881.47, 0)  
+     ( 6295080.970, 1978664.550, 877.79, 0)  
+     ( 6295104.570, 1978648.190, 874.58, 0)  
+     ( 6295126.310, 1978633.890, 872.09, 0)  
+     ( 6295149.840, 1978618.720, 869.6, 0)  
+     ( 6295173.840, 1978605.030, 867.37, 0)  
+     ( 6295198.110, 1978594.150, 866.12, 0)  
+     ( 6295222.830, 1978586.990, 865.2, 0)  
+     ( 6295243.030, 1978583.810, 863.5, 0)  
+     ( 6295268.110, 1978581.290, 860.35, 0)  
+     ( 6295291.530, 1978579.390, 856.48, 0)  
+     ( 6295313.200, 1978582.040, 852.42, 0)  
+     ( 6295329.170, 1978591.410, 848.81, 0)  
+     ( 6295339.780, 1978603.880, 845.07, 0)  
+     ( 6295345.640, 1978621.110, 842.12, 0)  
+     ( 6295351.070, 1978642.970, 838.32, 0)  
+     ( 6295357.250, 1978666.560, 834.77, 0)  
+     ( 6295367.290, 1978691.000, 831.89, 0)  
+     ( 6295376.030, 1978718.470, 828.09, 0)  
+     ( 6295383.930, 1978744.860, 824.35, 0)  
+     ( 6295389.990, 1978768.720, 821.33, 0)  
+     ( 6295395.930, 1978790.090, 818.64, 0)  
+
+Shape:1 (ArcZ)  nVertices=9, nParts=1
+  Bounds:( 6295218.470, 1978444.010, 864.55, 0)
+      to ( 6295330.760, 1978581.880, 882.45, 0)
+     ( 6295330.760, 1978444.010, 882.45, 0) Ring 
+     ( 6295306.050, 1978461.190, 880.94, 0)  
+     ( 6295280.210, 1978482.710, 878.52, 0)  
+     ( 6295258.180, 1978504.050, 875.89, 0)  
+     ( 6295239.910, 1978524.670, 871.89, 0)  
+     ( 6295225.650, 1978546.540, 869.53, 0)  
+     ( 6295218.470, 1978565.550, 866.97, 0)  
+     ( 6295223.960, 1978575.510, 865.27, 0)  
+     ( 6295230.580, 1978581.880, 864.55, 0)  
+
+Shape:2 (ArcZ)  nVertices=10, nParts=1
+  Bounds:( 6295199.220, 1978444.010, 866.32, 0)
+      to ( 6295309.040, 1978588.800, 882.08, 0)
+     ( 6295200.070, 1978588.800, 866.32, 0) Ring 
+     ( 6295199.220, 1978571.840, 867.24, 0)  
+     ( 6295200.770, 1978555.740, 868.88, 0)  
+     ( 6295207.890, 1978538.040, 869.86, 0)  
+     ( 6295223.020, 1978520.530, 870.84, 0)  
+     ( 6295239.450, 1978502.440, 874.06, 0)  
+     ( 6295258.050, 1978483.440, 876.48, 0)  
+     ( 6295268.990, 1978473.760, 879.17, 0)  
+     ( 6295285.710, 1978461.560, 880.55, 0)  
+     ( 6295309.040, 1978444.010, 882.08, 0)  
+
+Shape:3 (ArcZ)  nVertices=5, nParts=1
+  Bounds:( 6294340.890, 1979449.280, 1031.78, 0)
+      to ( 6294394.080, 1979522.030, 1039.78, 0)
+     ( 6294394.080, 1979449.280, 1039.78, 0) Ring 
+     ( 6294378.800, 1979469.230, 1038.73, 0)  
+     ( 6294364.980, 1979486.740, 1037.28, 0)  
+     ( 6294350.800, 1979504.980, 1035.12, 0)  
+     ( 6294340.890, 1979522.030, 1031.78, 0)  
+
+Shape:4 (ArcZ)  nVertices=6, nParts=1
+  Bounds:( 6294344.380, 1979583.450, 1008.04, 0)
+      to ( 6294354.670, 1979678.070, 1023.45, 0)
+     ( 6294344.380, 1979583.450, 1023.45, 0) Ring 
+     ( 6294348.050, 1979601.580, 1019.18, 0)  
+     ( 6294349.570, 1979621.200, 1016.5, 0)  
+     ( 6294351.990, 1979637.890, 1012.95, 0)  
+     ( 6294353.090, 1979657.140, 1011.51, 0)  
+     ( 6294354.670, 1979678.070, 1008.04, 0)  
+
+Shape:5 (ArcZ)  nVertices=3, nParts=1
+  Bounds:( 6294338.260, 1979628.600, 1008.63, 0)
+      to ( 6294341.080, 1979674.100, 1015.71, 0)
+     ( 6294341.080, 1979674.100, 1008.63, 0) Ring 
+     ( 6294339.460, 1979649.880, 1011.71, 0)  
+     ( 6294338.260, 1979628.600, 1015.71, 0)  
+
+Shape:6 (ArcZ)  nVertices=3, nParts=1
+  Bounds:( 6294350.160, 1979437.980, 1038.6, 0)
+      to ( 6294379.980, 1979476.720, 1040.1, 0)
+     ( 6294350.160, 1979476.720, 1038.6, 0) Ring 
+     ( 6294368.100, 1979454.860, 1040.1, 0)  
+     ( 6294379.980, 1979437.980, 1039.32, 0)  
+
+Shape:7 (ArcZ)  nVertices=39, nParts=1
+  Bounds:( 6295371.530, 1978758.160, 754.11, 0)
+      to ( 6295534.560, 1979677.750, 823.3, 0)
+     ( 6295534.560, 1979677.750, 779.95, 0) Ring 
+     ( 6295534.380, 1979648.150, 778.57, 0)  
+     ( 6295534.480, 1979605.990, 775.16, 0)  
+     ( 6295533.970, 1979577.580, 772.21, 0)  
+     ( 6295532.310, 1979547.260, 768.41, 0)  
+     ( 6295532.970, 1979521.290, 763.82, 0)  
+     ( 6295532.390, 1979496.890, 759.1, 0)  
+     ( 6295532.940, 1979474.010, 755.49, 0)  
+     ( 6295533.680, 1979452.180, 754.11, 0)  
+     ( 6295533.850, 1979434.640, 754.11, 0)  
+     ( 6295532.170, 1979409.180, 755.75, 0)  
+     ( 6295531.580, 1979384.450, 758.7, 0)  
+     ( 6295531.590, 1979356.090, 760.28, 0)  
+     ( 6295530.190, 1979325.690, 761.13, 0)  
+     ( 6295530.020, 1979291.090, 761.66, 0)  
+     ( 6295529.210, 1979259.420, 762.7, 0)  
+     ( 6295526.250, 1979221.610, 762.77, 0)  
+     ( 6295524.260, 1979187.500, 763.75, 0)  
+     ( 6295522.640, 1979155.350, 764.61, 0)  
+     ( 6295521.540, 1979123.230, 765.33, 0)  
+     ( 6295518.460, 1979096.000, 765.92, 0)  
+     ( 6295511.670, 1979081.110, 767.16, 0)  
+     ( 6295500.700, 1979064.060, 768.41, 0)  
+     ( 6295489.330, 1979049.600, 770.11, 0)  
+     ( 6295475.500, 1979033.100, 773.07, 0)  
+     ( 6295462.530, 1979018.190, 775.16, 0)  
+     ( 6295447.760, 1979001.400, 779.49, 0)  
+     ( 6295433.380, 1978984.530, 782.9, 0)  
+     ( 6295419.040, 1978965.820, 785.92, 0)  
+     ( 6295409.020, 1978946.820, 790.58, 0)  
+     ( 6295399.860, 1978923.910, 795.1, 0)  
+     ( 6295391.010, 1978894.410, 800.94, 0)  
+     ( 6295387.440, 1978875.550, 805.53, 0)  
+     ( 6295382.030, 1978849.030, 809.79, 0)  
+     ( 6295382.190, 1978828.930, 813.33, 0)  
+     ( 6295383.570, 1978809.290, 817.4, 0)  
+     ( 6295380.880, 1978789.860, 819.69, 0)  
+     ( 6295375.630, 1978771.810, 822.58, 0)  
+     ( 6295371.530, 1978758.160, 823.3, 0)  
+
+Shape:8 (ArcZ)  nVertices=35, nParts=1
+  Bounds:( 6295396.480, 1978794.780, 753.98, 0)
+      to ( 6295549.010, 1979670.060, 818.58, 0)
+     ( 6295396.620, 1978794.780, 818.58, 0) Ring 
+     ( 6295397.330, 1978816.670, 815.76, 0)  
+     ( 6295396.480, 1978836.150, 812.22, 0)  
+     ( 6295397.670, 1978857.110, 807.95, 0)  
+     ( 6295401.180, 1978874.720, 804.61, 0)  
+     ( 6295406.260, 1978897.320, 799.95, 0)  
+     ( 6295413.580, 1978919.930, 794.77, 0)  
+     ( 6295421.330, 1978938.190, 790.31, 0)  
+     ( 6295431.450, 1978956.590, 786.51, 0)  
+     ( 6295444.950, 1978974.360, 782.38, 0)  
+     ( 6295461.420, 1978993.620, 777.66, 0)  
+     ( 6295479.760, 1979013.510, 773.26, 0)  
+     ( 6295494.630, 1979032.330, 771.1, 0)  
+     ( 6295510.990, 1979052.120, 767.69, 0)  
+     ( 6295524.170, 1979071.090, 766.84, 0)  
+     ( 6295532.180, 1979091.890, 765.33, 0)  
+     ( 6295536.530, 1979120.830, 764.8, 0)  
+     ( 6295537.480, 1979150.200, 764.08, 0)  
+     ( 6295539.470, 1979189.490, 763.43, 0)  
+     ( 6295541.670, 1979230.490, 762.64, 0)  
+     ( 6295541.760, 1979271.330, 761.79, 0)  
+     ( 6295543.650, 1979306.300, 761.46, 0)  
+     ( 6295544.470, 1979335.540, 760.47, 0)  
+     ( 6295544.960, 1979363.490, 759.23, 0)  
+     ( 6295545.620, 1979392.020, 757.13, 0)  
+     ( 6295546.340, 1979419.430, 754.9, 0)  
+     ( 6295547.120, 1979439.940, 753.98, 0)  
+     ( 6295546.510, 1979459.150, 754.38, 0)  
+     ( 6295545.460, 1979482.710, 757.66, 0)  
+     ( 6295545.530, 1979507.330, 761.13, 0)  
+     ( 6295545.610, 1979532.470, 765.59, 0)  
+     ( 6295546.490, 1979565.520, 770.44, 0)  
+     ( 6295547.960, 1979597.100, 775.03, 0)  
+     ( 6295548.990, 1979628.040, 777.26, 0)  
+     ( 6295549.010, 1979670.060, 780.15, 0)  
+
+Shape:9 (ArcZ)  nVertices=45, nParts=1
+  Bounds:( 6295694.040, 1978444.010, 696.95, 0)
+      to ( 6296208.790, 1979687.080, 787.43, 0)
+     ( 6295698.400, 1979687.080, 787.43, 0) Ring 
+     ( 6295694.040, 1979670.950, 786.31, 0)  
+     ( 6295696.410, 1979650.280, 785.13, 0)  
+     ( 6295700.080, 1979634.530, 784.8, 0)  
+     ( 6295704.080, 1979620.010, 784.15, 0)  
+     ( 6295708.420, 1979601.930, 782.44, 0)  
+     ( 6295711.230, 1979584.790, 781.99, 0)  
+     ( 6295712.060, 1979564.780, 780.8, 0)  
+     ( 6295710.550, 1979537.480, 779.69, 0)  
+     ( 6295711.290, 1979508.020, 777.59, 0)  
+     ( 6295710.010, 1979477.420, 776.08, 0)  
+     ( 6295709.300, 1979442.530, 773.59, 0)  
+     ( 6295709.160, 1979413.640, 772.21, 0)  
+     ( 6295707.090, 1979372.570, 769.46, 0)  
+     ( 6295708.140, 1979336.210, 767.49, 0)  
+     ( 6295709.710, 1979297.130, 764.67, 0)  
+     ( 6295710.960, 1979272.310, 763.29, 0)  
+     ( 6295714.640, 1979241.200, 761.2, 0)  
+     ( 6295719.050, 1979211.560, 759.82, 0)  
+     ( 6295724.280, 1979179.840, 758.31, 0)  
+     ( 6295729.460, 1979152.460, 756.74, 0)  
+     ( 6295735.770, 1979126.530, 754.44, 0)  
+     ( 6295744.970, 1979095.400, 752.87, 0)  
+     ( 6295755.820, 1979063.140, 750.31, 0)  
+     ( 6295767.590, 1979028.330, 747.62, 0)  
+     ( 6295782.240, 1978993.450, 744.21, 0)  
+     ( 6295801.580, 1978952.420, 741.26, 0)  
+     ( 6295825.730, 1978905.370, 736.87, 0)  
+     ( 6295842.330, 1978877.810, 734.7, 0)  
+     ( 6295859.110, 1978851.150, 731.55, 0)  
+     ( 6295875.620, 1978827.010, 729.52, 0)  
+     ( 6295899.080, 1978794.830, 727.42, 0)  
+     ( 6295923.640, 1978763.720, 724.34, 0)  
+     ( 6295949.340, 1978734.180, 721.39, 0)  
+     ( 6295975.020, 1978704.320, 718.57, 0)  
+     ( 6296000.320, 1978677.440, 716.01, 0)  
+     ( 6296026.940, 1978648.120, 713.45, 0)  
+     ( 6296053.500, 1978617.500, 709.78, 0)  
+     ( 6296078.620, 1978589.630, 706.9, 0)  
+     ( 6296098.880, 1978566.880, 704.47, 0)  
+     ( 6296126.050, 1978537.930, 702.37, 0)  
+     ( 6296150.670, 1978507.990, 700.14, 0)  
+     ( 6296179.280, 1978476.280, 698.7, 0)  
+     ( 6296208.030, 1978444.880, 696.99, 0)  
+     ( 6296208.790, 1978444.010, 696.95, 0)  
+
+Shape:10 (ArcZ)  nVertices=10, nParts=1
+  Bounds:( 6296270.060, 1979014.970, 712.54, 0)
+      to ( 6296315.990, 1979152.310, 725.13, 0)
+     ( 6296306.110, 1979152.310, 725.13, 0) Ring 
+     ( 6296288.270, 1979139.690, 723.42, 0)  
+     ( 6296276.630, 1979122.410, 721.98, 0)  
+     ( 6296270.060, 1979101.470, 719.95, 0)  
+     ( 6296270.390, 1979084.580, 719.36, 0)  
+     ( 6296275.110, 1979068.970, 717.26, 0)  
+     ( 6296284.280, 1979052.820, 716.41, 0)  
+     ( 6296294.680, 1979040.410, 715.49, 0)  
+     ( 6296305.720, 1979027.370, 713.59, 0)  
+     ( 6296315.990, 1979014.970, 712.54, 0)  
+
+Shape:11 (ArcZ)  nVertices=18, nParts=1
+  Bounds:( 6296044.930, 1978451.120, 690.11, 0)
+      to ( 6296312.920, 1978679.190, 713.72, 0)
+     ( 6296312.920, 1978493.560, 690.11, 0) Ring 
+     ( 6296301.160, 1978479.050, 690.9, 0)  
+     ( 6296287.840, 1978464.950, 692.4, 0)  
+     ( 6296276.430, 1978454.890, 693.58, 0)  
+     ( 6296262.580, 1978451.120, 694.44, 0)  
+     ( 6296249.650, 1978452.500, 694.9, 0)  
+     ( 6296237.110, 1978461.670, 696.08, 0)  
+     ( 6296223.600, 1978477.650, 697.78, 0)  
+     ( 6296209.320, 1978493.930, 698.7, 0)  
+     ( 6296193.640, 1978511.140, 699.16, 0)  
+     ( 6296176.980, 1978529.710, 700.6, 0)  
+     ( 6296157.700, 1978550.970, 701.98, 0)  
+     ( 6296136.720, 1978574.950, 703.49, 0)  
+     ( 6296121.400, 1978591.550, 705.39, 0)  
+     ( 6296102.290, 1978613.590, 707.36, 0)  
+     ( 6296084.440, 1978634.580, 709.13, 0)  
+     ( 6296065.890, 1978654.760, 711.29, 0)  
+     ( 6296044.930, 1978679.190, 713.72, 0)  
+
+Shape:12 (ArcZ)  nVertices=71, nParts=1
+  Bounds:( 6295741.070, 1978679.190, 713.72, 0)
+      to ( 6296321.860, 1979680.370, 813.79, 0)
+     ( 6296044.930, 1978679.190, 713.72, 0) Ring 
+     ( 6296025.660, 1978700.780, 716.6, 0)  
+     ( 6296006.480, 1978721.510, 718.37, 0)  
+     ( 6295987.070, 1978742.720, 721, 0)  
+     ( 6295970.410, 1978761.420, 722.44, 0)  
+     ( 6295953.490, 1978780.070, 724.28, 0)  
+     ( 6295932.470, 1978805.820, 726.44, 0)  
+     ( 6295913.490, 1978830.550, 728.67, 0)  
+     ( 6295896.490, 1978855.310, 731.16, 0)  
+     ( 6295881.220, 1978878.070, 733.39, 0)  
+     ( 6295867.710, 1978899.180, 734.7, 0)  
+     ( 6295853.950, 1978923.310, 737, 0)  
+     ( 6295839.810, 1978950.030, 739.56, 0)  
+     ( 6295825.270, 1978979.390, 742.11, 0)  
+     ( 6295809.100, 1979015.600, 745.46, 0)  
+     ( 6295796.940, 1979045.170, 748.02, 0)  
+     ( 6295785.770, 1979078.900, 750.97, 0)  
+     ( 6295777.080, 1979104.550, 752.54, 0)  
+     ( 6295768.950, 1979133.460, 754.84, 0)  
+     ( 6295762.170, 1979163.090, 756.87, 0)  
+     ( 6295755.640, 1979194.930, 758.9, 0)  
+     ( 6295750.610, 1979225.390, 760.48, 0)  
+     ( 6295746.300, 1979259.750, 762.64, 0)  
+     ( 6295743.320, 1979291.750, 764.54, 0)  
+     ( 6295741.650, 1979321.060, 766.64, 0)  
+     ( 6295741.070, 1979353.790, 768.54, 0)  
+     ( 6295741.170, 1979384.450, 770.71, 0)  
+     ( 6295742.010, 1979419.210, 772.48, 0)  
+     ( 6295743.010, 1979454.740, 774.44, 0)  
+     ( 6295743.910, 1979493.310, 776.94, 0)  
+     ( 6295744.990, 1979530.290, 778.97, 0)  
+     ( 6295745.900, 1979569.120, 781.46, 0)  
+     ( 6295745.940, 1979603.910, 783.3, 0)  
+     ( 6295747.600, 1979636.660, 785.85, 0)  
+     ( 6295751.850, 1979653.260, 787.49, 0)  
+     ( 6295760.490, 1979665.820, 788.87, 0)  
+     ( 6295773.510, 1979673.830, 790.18, 0)  
+     ( 6295788.460, 1979676.100, 791.95, 0)  
+     ( 6295823.990, 1979674.960, 793.46, 0)  
+     ( 6295871.620, 1979674.070, 796.94, 0)  
+     ( 6295918.980, 1979673.120, 798.97, 0)  
+     ( 6295971.200, 1979672.130, 802.25, 0)  
+     ( 6296019.370, 1979671.600, 803.95, 0)  
+     ( 6296054.350, 1979670.030, 805.92, 0)  
+     ( 6296074.580, 1979662.250, 806.58, 0)  
+     ( 6296085.660, 1979647.700, 806.97, 0)  
+     ( 6296089.370, 1979635.300, 807.69, 0)  
+     ( 6296086.380, 1979620.160, 808.61, 0)  
+     ( 6296080.060, 1979601.690, 810.32, 0)  
+     ( 6296074.440, 1979583.990, 811.17, 0)  
+     ( 6296070.250, 1979568.770, 812.22, 0)  
+     ( 6296072.470, 1979552.830, 812.94, 0)  
+     ( 6296083.220, 1979536.790, 813.46, 0)  
+     ( 6296102.650, 1979531.410, 813.79, 0)  
+     ( 6296121.290, 1979536.450, 813.73, 0)  
+     ( 6296133.190, 1979548.520, 813.2, 0)  
+     ( 6296138.010, 1979563.380, 812.61, 0)  
+     ( 6296135.460, 1979580.580, 811.37, 0)  
+     ( 6296129.950, 1979598.850, 810.18, 0)  
+     ( 6296124.490, 1979618.170, 809.46, 0)  
+     ( 6296122.100, 1979635.880, 808.35, 0)  
+     ( 6296126.820, 1979651.410, 807.36, 0)  
+     ( 6296136.390, 1979661.360, 806.51, 0)  
+     ( 6296149.630, 1979666.080, 806.05, 0)  
+     ( 6296163.380, 1979667.880, 805.73, 0)  
+     ( 6296186.080, 1979667.460, 805.14, 0)  
+     ( 6296215.190, 1979666.580, 805, 0)  
+     ( 6296247.690, 1979667.830, 803.5, 0)  
+     ( 6296273.580, 1979670.850, 802.32, 0)  
+     ( 6296295.410, 1979674.090, 800.68, 0)  
+     ( 6296321.860, 1979680.370, 799.23, 0)  
+
+Shape:13 (ArcZ)  nVertices=6, nParts=1
+  Bounds:( 6295372.650, 1979608.700, 773.19, 0)
+      to ( 6295470.330, 1979679.550, 780.15, 0)
+     ( 6295372.650, 1979679.550, 780.15, 0) Ring 
+     ( 6295387.140, 1979664.770, 777.85, 0)  
+     ( 6295406.650, 1979645.400, 776.21, 0)  
+     ( 6295422.760, 1979631.580, 775.29, 0)  
+     ( 6295442.800, 1979612.190, 773.65, 0)  
+     ( 6295470.330, 1979608.700, 773.19, 0)  
+
+Shape:14 (ArcZ)  nVertices=7, nParts=1
+  Bounds:( 6295415.710, 1979491.540, 772.08, 0)
+      to ( 6295453.550, 1979590.190, 773.85, 0)
+     ( 6295453.550, 1979590.110, 772.09, 0) Ring 
+     ( 6295453.110, 1979590.190, 772.08, 0)  
+     ( 6295439.430, 1979579.260, 772.74, 0)  
+     ( 6295430.870, 1979552.770, 772.93, 0)  
+     ( 6295420.940, 1979527.860, 773.19, 0)  
+     ( 6295415.710, 1979510.070, 773.79, 0)  
+     ( 6295421.080, 1979491.540, 773.85, 0)  
+
+Shape:15 (ArcZ)  nVertices=9, nParts=1
+  Bounds:( 6295351.240, 1979521.410, 773, 0)
+      to ( 6295430.330, 1979692.520, 782.11, 0)
+     ( 6295395.270, 1979521.410, 774.51, 0) Ring 
+     ( 6295415.880, 1979549.790, 773.85, 0)  
+     ( 6295426.030, 1979579.220, 773, 0)  
+     ( 6295430.330, 1979604.610, 773.06, 0)  
+     ( 6295418.610, 1979622.140, 774.31, 0)  
+     ( 6295398.970, 1979639.020, 776.34, 0)  
+     ( 6295382.220, 1979655.690, 778.31, 0)  
+     ( 6295365.040, 1979674.420, 780.15, 0)  
+     ( 6295351.240, 1979692.520, 782.11, 0)  
+
+Shape:16 (ArcZ)  nVertices=28, nParts=1
+  Bounds:( 6294520.270, 1979256.990, 932.36, 0)
+      to ( 6294743.290, 1979675.030, 1016.69, 0)
+     ( 6294531.940, 1979675.030, 932.36, 0) Ring 
+     ( 6294523.870, 1979650.550, 933.54, 0)  
+     ( 6294520.270, 1979620.920, 936.75, 0)  
+     ( 6294525.030, 1979592.840, 940.29, 0)  
+     ( 6294533.880, 1979567.770, 942.98, 0)  
+     ( 6294546.040, 1979543.320, 949.28, 0)  
+     ( 6294564.140, 1979524.750, 951.64, 0)  
+     ( 6294585.590, 1979515.130, 956.36, 0)  
+     ( 6294611.810, 1979503.890, 959.38, 0)  
+     ( 6294635.130, 1979494.900, 966.2, 0)  
+     ( 6294662.590, 1979487.470, 969.41, 0)  
+     ( 6294687.540, 1979482.070, 971.77, 0)  
+     ( 6294710.180, 1979470.160, 976.75, 0)  
+     ( 6294732.150, 1979450.140, 978.53, 0)  
+     ( 6294743.290, 1979431.460, 981.94, 0)  
+     ( 6294738.700, 1979402.930, 984.69, 0)  
+     ( 6294731.290, 1979380.980, 986.79, 0)  
+     ( 6294717.670, 1979358.290, 988.3, 0)  
+     ( 6294706.340, 1979342.050, 991.38, 0)  
+     ( 6294697.140, 1979315.920, 996.76, 0)  
+     ( 6294696.360, 1979292.580, 1000.17, 0)  
+     ( 6294691.930, 1979275.010, 1002.4, 0)  
+     ( 6294681.970, 1979259.950, 1004.76, 0)  
+     ( 6294665.150, 1979256.990, 1006.53, 0)  
+     ( 6294638.580, 1979258.930, 1010.33, 0)  
+     ( 6294617.350, 1979259.730, 1012.76, 0)  
+     ( 6294592.000, 1979262.260, 1015.32, 0)  
+     ( 6294572.550, 1979262.000, 1016.69, 0)  
+
+Shape:17 (ArcZ)  nVertices=43, nParts=1
+  Bounds:( 6294466.100, 1979253.610, 930.98, 0)
+      to ( 6294720.520, 1979678.410, 1018.46, 0)
+     ( 6294572.550, 1979262.000, 1016.69, 0) Ring 
+     ( 6294549.640, 1979260.720, 1017.48, 0)  
+     ( 6294522.440, 1979260.520, 1017.48, 0)  
+     ( 6294472.060, 1979253.610, 1016.63, 0)  
+     ( 6294469.530, 1979302.330, 1017.15, 0)  
+     ( 6294466.100, 1979341.240, 1016.63, 0)  
+     ( 6294469.480, 1979374.290, 1016.5, 0)  
+     ( 6294506.640, 1979382.010, 1016.96, 0)  
+     ( 6294538.320, 1979377.390, 1016.89, 0)  
+     ( 6294581.400, 1979377.510, 1017.74, 0)  
+     ( 6294603.050, 1979366.770, 1017.74, 0)  
+     ( 6294597.820, 1979338.470, 1018, 0)  
+     ( 6294587.060, 1979307.490, 1018.46, 0)  
+     ( 6294579.280, 1979283.460, 1017.87, 0)  
+     ( 6294593.320, 1979278.020, 1016.36, 0)  
+     ( 6294613.160, 1979275.640, 1013.15, 0)  
+     ( 6294634.390, 1979274.630, 1009.54, 0)  
+     ( 6294650.590, 1979272.960, 1006.4, 0)  
+     ( 6294666.970, 1979274.830, 1003.77, 0)  
+     ( 6294675.710, 1979289.290, 1001.81, 0)  
+     ( 6294681.310, 1979309.230, 998.13, 0)  
+     ( 6294686.190, 1979327.900, 995.64, 0)  
+     ( 6294692.280, 1979346.960, 991.64, 0)  
+     ( 6294699.730, 1979367.200, 989.08, 0)  
+     ( 6294709.530, 1979384.310, 985.74, 0)  
+     ( 6294716.160, 1979401.370, 983.25, 0)  
+     ( 6294720.520, 1979414.810, 980.1, 0)  
+     ( 6294718.980, 1979441.480, 978, 0)  
+-------------------------------------------------------------------------
+Test 3: dump polygon.shp
+-------------------------------------------------------------------------
+Shapefile Type: Polygon   # of Shapes: 474
+
+File Bounds: (  471127.188, 4751545.000,0,0)
+         to  (  489292.312, 4765610.500,0,0)
+
+Shape:0 (Polygon)  nVertices=20, nParts=1
+  Bounds:(  479647.000, 4764856.500, 0, 0)
+      to (  480389.688, 4765610.500, 0, 0)
+     (  479819.844, 4765180.500, 0, 0) Ring 
+     (  479690.188, 4765259.500, 0, 0)  
+     (  479647.000, 4765369.500, 0, 0)  
+     (  479730.375, 4765400.500, 0, 0)  
+     (  480039.031, 4765539.500, 0, 0)  
+     (  480035.344, 4765558.500, 0, 0)  
+     (  480159.781, 4765610.500, 0, 0)  
+     (  480202.281, 4765482.000, 0, 0)  
+     (  480365.000, 4765015.500, 0, 0)  
+     (  480389.688, 4764950.000, 0, 0)  
+     (  480133.969, 4764856.500, 0, 0)  
+     (  480080.281, 4764979.500, 0, 0)  
+     (  480082.969, 4765049.500, 0, 0)  
+     (  480088.812, 4765139.500, 0, 0)  
+     (  480059.906, 4765239.500, 0, 0)  
+     (  480019.719, 4765319.500, 0, 0)  
+     (  479980.219, 4765409.500, 0, 0)  
+     (  479909.875, 4765370.000, 0, 0)  
+     (  479859.875, 4765270.000, 0, 0)  
+     (  479819.844, 4765180.500, 0, 0)  
+
+Shape:1 (Polygon)  nVertices=20, nParts=1
+  Bounds:(  479014.938, 4764879.000, 0, 0)
+      to (  480039.031, 4765558.500, 0, 0)
+     (  480035.344, 4765558.500, 0, 0) Ring 
+     (  480039.031, 4765539.500, 0, 0)  
+     (  479730.375, 4765400.500, 0, 0)  
+     (  479647.000, 4765369.500, 0, 0)  
+     (  479690.188, 4765259.500, 0, 0)  
+     (  479819.844, 4765180.500, 0, 0)  
+     (  479779.844, 4765109.500, 0, 0)  
+     (  479681.781, 4764940.000, 0, 0)  
+     (  479468.000, 4764942.500, 0, 0)  
+     (  479411.438, 4764940.500, 0, 0)  
+     (  479353.000, 4764939.500, 0, 0)  
+     (  479208.656, 4764882.500, 0, 0)  
+     (  479196.812, 4764879.000, 0, 0)  
+     (  479123.281, 4765015.000, 0, 0)  
+     (  479046.531, 4765117.000, 0, 0)  
+     (  479029.719, 4765110.500, 0, 0)  
+     (  479014.938, 4765147.500, 0, 0)  
+     (  479149.938, 4765200.500, 0, 0)  
+     (  479639.625, 4765399.500, 0, 0)  
+     (  480035.344, 4765558.500, 0, 0)  
+
+Shape:2 (Polygon)  nVertices=54, nParts=1
+  Bounds:(  480882.688, 4763472.500, 0, 0)
+      to (  484519.969, 4765410.000, 0, 0)
+     (  481575.000, 4764999.500, 0, 0) Ring 
+     (  481542.312, 4765097.500, 0, 0)  
+     (  481443.688, 4765387.500, 0, 0)  
+     (  481499.656, 4765410.000, 0, 0)  
+     (  481631.000, 4765031.000, 0, 0)  
+     (  481693.312, 4764853.000, 0, 0)  
+     (  481759.281, 4764889.500, 0, 0)  
+     (  481860.031, 4764920.000, 0, 0)  
+     (  482002.969, 4764910.000, 0, 0)  
+     (  482180.094, 4764909.500, 0, 0)  
+     (  482359.812, 4764960.000, 0, 0)  
+     (  482510.500, 4765065.000, 0, 0)  
+     (  482619.906, 4765080.500, 0, 0)  
+     (  482809.500, 4765090.000, 0, 0)  
+     (  483189.812, 4765084.500, 0, 0)  
+     (  483330.312, 4765105.500, 0, 0)  
+     (  483591.094, 4765260.000, 0, 0)  
+     (  483700.500, 4765280.000, 0, 0)  
+     (  483799.938, 4765270.000, 0, 0)  
+     (  484039.844, 4765280.500, 0, 0)  
+     (  484115.688, 4765300.000, 0, 0)  
+     (  484120.625, 4765280.000, 0, 0)  
+     (  484131.125, 4765260.000, 0, 0)  
+     (  484167.844, 4765271.000, 0, 0)  
+     (  484277.875, 4765015.500, 0, 0)  
+     (  484455.062, 4764500.000, 0, 0)  
+     (  484519.969, 4764345.000, 0, 0)  
+     (  484482.031, 4764332.000, 0, 0)  
+     (  483904.719, 4764113.500, 0, 0)  
+     (  483334.844, 4763905.000, 0, 0)  
+     (  482941.031, 4763760.500, 0, 0)  
+     (  482590.719, 4763624.500, 0, 0)  
+     (  482185.656, 4763472.500, 0, 0)  
+     (  482009.844, 4763980.500, 0, 0)  
+     (  481960.438, 4764099.500, 0, 0)  
+     (  481767.500, 4764014.500, 0, 0)  
+     (  480955.500, 4763700.000, 0, 0)  
+     (  480882.688, 4763670.000, 0, 0)  
+     (  481039.938, 4763889.500, 0, 0)  
+     (  481130.312, 4763979.500, 0, 0)  
+     (  481143.438, 4764010.500, 0, 0)  
+     (  481199.844, 4764180.000, 0, 0)  
+     (  481141.625, 4764480.500, 0, 0)  
+     (  481140.469, 4764510.500, 0, 0)  
+     (  481159.938, 4764580.000, 0, 0)  
+     (  481185.500, 4764607.000, 0, 0)  
+     (  481199.219, 4764623.500, 0, 0)  
+     (  481209.812, 4764633.500, 0, 0)  
+     (  481235.312, 4764650.000, 0, 0)  
+     (  481635.969, 4764795.500, 0, 0)  
+     (  481645.312, 4764797.500, 0, 0)  
+     (  481629.844, 4764829.500, 0, 0)  
+     (  481602.125, 4764915.500, 0, 0)  
+     (  481575.000, 4764999.500, 0, 0)  
+
+Shape:3 (Polygon)  nVertices=29, nParts=1
+  Bounds:(  479117.812, 4764505.000, 0, 0)
+      to (  480088.812, 4765409.500, 0, 0)
+     (  479819.844, 4765180.500, 0, 0) Ring 
+     (  479859.875, 4765270.000, 0, 0)  
+     (  479909.875, 4765370.000, 0, 0)  
+     (  479980.219, 4765409.500, 0, 0)  
+     (  480019.719, 4765319.500, 0, 0)  
+     (  480059.906, 4765239.500, 0, 0)  
+     (  480088.812, 4765139.500, 0, 0)  
+     (  480082.969, 4765049.500, 0, 0)  
+     (  480000.281, 4765043.000, 0, 0)  
+     (  479934.969, 4765020.000, 0, 0)  
+     (  479895.125, 4765000.000, 0, 0)  
+     (  479734.375, 4764865.000, 0, 0)  
+     (  479680.281, 4764852.000, 0, 0)  
+     (  479644.781, 4764827.500, 0, 0)  
+     (  479637.875, 4764803.000, 0, 0)  
+     (  479617.219, 4764760.000, 0, 0)  
+     (  479587.281, 4764718.000, 0, 0)  
+     (  479548.031, 4764693.500, 0, 0)  
+     (  479504.906, 4764609.500, 0, 0)  
+     (  479239.812, 4764505.000, 0, 0)  
+     (  479117.812, 4764847.000, 0, 0)  
+     (  479196.812, 4764879.000, 0, 0)  
+     (  479208.656, 4764882.500, 0, 0)  
+     (  479353.000, 4764939.500, 0, 0)  
+     (  479411.438, 4764940.500, 0, 0)  
+     (  479468.000, 4764942.500, 0, 0)  
+     (  479681.781, 4764940.000, 0, 0)  
+     (  479779.844, 4765109.500, 0, 0)  
+     (  479819.844, 4765180.500, 0, 0)  
+
+Shape:4 (Polygon)  nVertices=22, nParts=1
+  Bounds:(  480537.156, 4764738.000, 0, 0)
+      to (  481575.000, 4765387.500, 0, 0)
+     (  480537.156, 4765014.000, 0, 0) Ring 
+     (  481090.281, 4765242.000, 0, 0)  
+     (  481443.688, 4765387.500, 0, 0)  
+     (  481542.312, 4765097.500, 0, 0)  
+     (  481575.000, 4764999.500, 0, 0)  
+     (  481538.906, 4764982.500, 0, 0)  
+     (  481509.656, 4764967.000, 0, 0)  
+     (  481457.375, 4764937.000, 0, 0)  
+     (  481465.906, 4764872.500, 0, 0)  
+     (  481291.094, 4764810.000, 0, 0)  
+     (  481281.312, 4764876.500, 0, 0)  
+     (  481136.844, 4764994.500, 0, 0)  
+     (  481088.188, 4764936.000, 0, 0)  
+     (  480984.250, 4764875.000, 0, 0)  
+     (  480930.719, 4764852.000, 0, 0)  
+     (  480922.031, 4764850.500, 0, 0)  
+     (  480824.969, 4764820.000, 0, 0)  
+     (  480761.469, 4764778.000, 0, 0)  
+     (  480701.062, 4764738.000, 0, 0)  
+     (  480605.000, 4764835.000, 0, 0)  
+     (  480567.969, 4764918.000, 0, 0)  
+     (  480537.156, 4765014.000, 0, 0)  
+
+Shape:5 (Polygon)  nVertices=60, nParts=1
+  Bounds:(  484482.031, 4760649.500, 0, 0)
+      to (  488408.281, 4765179.000, 0, 0)
+     (  484482.031, 4764332.000, 0, 0) Ring 
+     (  484519.969, 4764345.000, 0, 0)  
+     (  484817.938, 4764465.500, 0, 0)  
+     (  485615.406, 4764770.000, 0, 0)  
+     (  486269.688, 4765010.000, 0, 0)  
+     (  486320.062, 4765024.000, 0, 0)  
+     (  486340.594, 4765040.000, 0, 0)  
+     (  486369.844, 4765050.000, 0, 0)  
+     (  486719.969, 4765170.000, 0, 0)  
+     (  486738.625, 4765179.000, 0, 0)  
+     (  486987.781, 4764497.500, 0, 0)  
+     (  487019.875, 4764384.500, 0, 0)  
+     (  487077.375, 4764226.500, 0, 0)  
+     (  487120.031, 4764100.000, 0, 0)  
+     (  487160.250, 4763998.000, 0, 0)  
+     (  487186.812, 4763922.500, 0, 0)  
+     (  487408.250, 4763315.500, 0, 0)  
+     (  487608.062, 4762780.000, 0, 0)  
+     (  487659.406, 4762650.000, 0, 0)  
+     (  487719.406, 4762480.000, 0, 0)  
+     (  487741.062, 4762419.500, 0, 0)  
+     (  487747.875, 4762395.500, 0, 0)  
+     (  487880.875, 4762032.000, 0, 0)  
+     (  487899.438, 4761975.500, 0, 0)  
+     (  488082.000, 4761480.000, 0, 0)  
+     (  488408.281, 4760649.500, 0, 0)  
+     (  488050.375, 4760824.500, 0, 0)  
+     (  487690.906, 4760802.000, 0, 0)  
+     (  487640.062, 4760879.500, 0, 0)  
+     (  487594.938, 4761023.000, 0, 0)  
+     (  487341.375, 4761776.500, 0, 0)  
+     (  487037.125, 4761672.500, 0, 0)  
+     (  487005.375, 4761662.500, 0, 0)  
+     (  486788.219, 4761579.500, 0, 0)  
+     (  486822.250, 4761492.000, 0, 0)  
+     (  486838.312, 4761437.500, 0, 0)  
+     (  486841.312, 4761381.000, 0, 0)  
+     (  486850.562, 4761340.000, 0, 0)  
+     (  486810.750, 4761335.500, 0, 0)  
+     (  486775.438, 4761400.000, 0, 0)  
+     (  486710.094, 4761368.000, 0, 0)  
+     (  486606.188, 4761330.000, 0, 0)  
+     (  486548.656, 4761488.000, 0, 0)  
+     (  486380.656, 4761428.500, 0, 0)  
+     (  486152.906, 4761348.000, 0, 0)  
+     (  485900.250, 4761250.500, 0, 0)  
+     (  485666.875, 4761156.500, 0, 0)  
+     (  485585.875, 4761374.500, 0, 0)  
+     (  485564.875, 4761444.500, 0, 0)  
+     (  485496.219, 4761614.500, 0, 0)  
+     (  485438.688, 4761760.500, 0, 0)  
+     (  485264.969, 4762222.500, 0, 0)  
+     (  485192.688, 4762439.000, 0, 0)  
+     (  485175.406, 4762493.500, 0, 0)  
+     (  484947.344, 4763100.500, 0, 0)  
+     (  484888.000, 4763260.500, 0, 0)  
+     (  484785.469, 4763560.500, 0, 0)  
+     (  484760.219, 4763659.500, 0, 0)  
+     (  484696.969, 4763734.000, 0, 0)  
+     (  484482.031, 4764332.000, 0, 0)  
+
+Shape:6 (Polygon)  nVertices=26, nParts=1
+  Bounds:(  478315.531, 4764174.000, 0, 0)
+      to (  479305.875, 4765147.500, 0, 0)
+     (  479014.938, 4765147.500, 0, 0) Ring 
+     (  479029.719, 4765110.500, 0, 0)  
+     (  479117.812, 4764847.000, 0, 0)  
+     (  479239.812, 4764505.000, 0, 0)  
+     (  479305.875, 4764361.000, 0, 0)  
+     (  479256.031, 4764314.500, 0, 0)  
+     (  479220.906, 4764212.500, 0, 0)  
+     (  479114.500, 4764174.000, 0, 0)  
+     (  479018.281, 4764418.500, 0, 0)  
+     (  478896.938, 4764371.000, 0, 0)  
+     (  478748.812, 4764308.500, 0, 0)  
+     (  478503.031, 4764218.000, 0, 0)  
+     (  478461.750, 4764337.500, 0, 0)  
+     (  478443.938, 4764400.500, 0, 0)  
+     (  478447.812, 4764454.000, 0, 0)  
+     (  478448.688, 4764531.500, 0, 0)  
+     (  478502.188, 4764541.500, 0, 0)  
+     (  478683.000, 4764730.500, 0, 0)  
+     (  478621.031, 4764788.500, 0, 0)  
+     (  478597.344, 4764766.500, 0, 0)  
+     (  478532.500, 4764695.500, 0, 0)  
+     (  478460.125, 4764615.000, 0, 0)  
+     (  478408.062, 4764654.000, 0, 0)  
+     (  478315.531, 4764876.000, 0, 0)  
+     (  478889.250, 4765100.000, 0, 0)  
+     (  479014.938, 4765147.500, 0, 0)  
+
+Shape:7 (Polygon)  nVertices=6, nParts=1
+  Bounds:(  479029.719, 4764847.000, 0, 0)
+      to (  479196.812, 4765117.000, 0, 0)
+     (  479029.719, 4765110.500, 0, 0) Ring 
+     (  479046.531, 4765117.000, 0, 0)  
+     (  479123.281, 4765015.000, 0, 0)  
+     (  479196.812, 4764879.000, 0, 0)  
+     (  479117.812, 4764847.000, 0, 0)  
+     (  479029.719, 4765110.500, 0, 0)  
+
+Shape:8 (Polygon)  nVertices=20, nParts=1
+  Bounds:(  479504.906, 4764609.500, 0, 0)
+      to (  480133.969, 4765049.500, 0, 0)
+     (  480082.969, 4765049.500, 0, 0) Ring 
+     (  480080.281, 4764979.500, 0, 0)  
+     (  480133.969, 4764856.500, 0, 0)  
+     (  479968.469, 4764788.000, 0, 0)  
+     (  479750.688, 4764702.000, 0, 0)  
+     (  479735.906, 4764752.000, 0, 0)  
+     (  479640.094, 4764721.000, 0, 0)  
+     (  479658.594, 4764670.000, 0, 0)  
+     (  479504.906, 4764609.500, 0, 0)  
+     (  479548.031, 4764693.500, 0, 0)  
+     (  479587.281, 4764718.000, 0, 0)  
+     (  479617.219, 4764760.000, 0, 0)  
+     (  479637.875, 4764803.000, 0, 0)  
+     (  479644.781, 4764827.500, 0, 0)  
+     (  479680.281, 4764852.000, 0, 0)  
+     (  479734.375, 4764865.000, 0, 0)  
+     (  479895.125, 4765000.000, 0, 0)  
+     (  479934.969, 4765020.000, 0, 0)  
+     (  480000.281, 4765043.000, 0, 0)  
+     (  480082.969, 4765049.500, 0, 0)  
+
+Shape:9 (Polygon)  nVertices=31, nParts=1
+  Bounds:(  479968.469, 4764183.000, 0, 0)
+      to (  480731.656, 4765014.000, 0, 0)
+     (  480389.688, 4764950.000, 0, 0) Ring 
+     (  480537.156, 4765014.000, 0, 0)  
+     (  480567.969, 4764918.000, 0, 0)  
+     (  480605.000, 4764835.000, 0, 0)  
+     (  480701.062, 4764738.000, 0, 0)  
+     (  480710.250, 4764690.500, 0, 0)  
+     (  480588.594, 4764740.500, 0, 0)  
+     (  480540.719, 4764741.000, 0, 0)  
+     (  480515.125, 4764695.000, 0, 0)  
+     (  480731.656, 4764561.500, 0, 0)  
+     (  480692.188, 4764453.500, 0, 0)  
+     (  480677.844, 4764439.000, 0, 0)  
+     (  480655.344, 4764397.500, 0, 0)  
+     (  480584.375, 4764353.000, 0, 0)  
+     (  480500.406, 4764326.500, 0, 0)  
+     (  480358.531, 4764277.000, 0, 0)  
+     (  480192.312, 4764183.000, 0, 0)  
+     (  480157.125, 4764266.500, 0, 0)  
+     (  480234.312, 4764304.000, 0, 0)  
+     (  480289.125, 4764348.500, 0, 0)  
+     (  480316.000, 4764395.000, 0, 0)  
+     (  480343.562, 4764477.000, 0, 0)  
+     (  480343.719, 4764532.500, 0, 0)  
+     (  480258.031, 4764767.000, 0, 0)  
+     (  480177.156, 4764742.000, 0, 0)  
+     (  480093.750, 4764703.000, 0, 0)  
+     (  480011.000, 4764674.500, 0, 0)  
+     (  479985.062, 4764732.000, 0, 0)  
+     (  479968.469, 4764788.000, 0, 0)  
+     (  480133.969, 4764856.500, 0, 0)  
+     (  480389.688, 4764950.000, 0, 0)  
+
+Shape:10 (Polygon)  nVertices=61, nParts=1
+  Bounds:(  479492.688, 4762880.500, 0, 0)
+      to (  481645.312, 4764999.500, 0, 0)
+     (  480701.062, 4764738.000, 0, 0) Ring 
+     (  480761.469, 4764778.000, 0, 0)  
+     (  480824.969, 4764820.000, 0, 0)  
+     (  480922.031, 4764850.500, 0, 0)  
+     (  480930.719, 4764852.000, 0, 0)  
+     (  480984.250, 4764875.000, 0, 0)  
+     (  481088.188, 4764936.000, 0, 0)  
+     (  481136.844, 4764994.500, 0, 0)  
+     (  481281.312, 4764876.500, 0, 0)  
+     (  481291.094, 4764810.000, 0, 0)  
+     (  481465.906, 4764872.500, 0, 0)  
+     (  481457.375, 4764937.000, 0, 0)  
+     (  481509.656, 4764967.000, 0, 0)  
+     (  481538.906, 4764982.500, 0, 0)  
+     (  481575.000, 4764999.500, 0, 0)  
+     (  481602.125, 4764915.500, 0, 0)  
+     (  481629.844, 4764829.500, 0, 0)  
+     (  481645.312, 4764797.500, 0, 0)  
+     (  481635.969, 4764795.500, 0, 0)  
+     (  481235.312, 4764650.000, 0, 0)  
+     (  481209.812, 4764633.500, 0, 0)  
+     (  481199.219, 4764623.500, 0, 0)  
+     (  481185.500, 4764607.000, 0, 0)  
+     (  481159.938, 4764580.000, 0, 0)  
+     (  481140.469, 4764510.500, 0, 0)  
+     (  481141.625, 4764480.500, 0, 0)  
+     (  481199.844, 4764180.000, 0, 0)  
+     (  481143.438, 4764010.500, 0, 0)  
+     (  481130.312, 4763979.500, 0, 0)  
+     (  481039.938, 4763889.500, 0, 0)  
+     (  480882.688, 4763670.000, 0, 0)  
+     (  480826.062, 4763650.500, 0, 0)  
+     (  480745.188, 4763628.500, 0, 0)  
+     (  480654.438, 4763627.500, 0, 0)  
+     (  480599.812, 4763660.000, 0, 0)  
+     (  480281.938, 4763576.500, 0, 0)  
+     (  480221.500, 4763533.500, 0, 0)  
+     (  480199.688, 4763509.000, 0, 0)  
+     (  480195.094, 4763430.000, 0, 0)  
+     (  480273.688, 4763305.500, 0, 0)  
+     (  480309.688, 4763063.500, 0, 0)  
+     (  480201.844, 4762962.500, 0, 0)  
+     (  479855.312, 4762880.500, 0, 0)  
+     (  479848.531, 4762897.000, 0, 0)  
+     (  479728.875, 4763217.500, 0, 0)  
+     (  479492.688, 4763850.000, 0, 0)  
+     (  479550.062, 4763919.500, 0, 0)  
+     (  480120.219, 4764188.500, 0, 0)  
+     (  480192.312, 4764183.000, 0, 0)  
+     (  480358.531, 4764277.000, 0, 0)  
+     (  480500.406, 4764326.500, 0, 0)  
+     (  480584.375, 4764353.000, 0, 0)  
+     (  480655.344, 4764397.500, 0, 0)  
+     (  480677.844, 4764439.000, 0, 0)  
+     (  480692.188, 4764453.500, 0, 0)  
+     (  480731.656, 4764561.500, 0, 0)  
+     (  480515.125, 4764695.000, 0, 0)  
+     (  480540.719, 4764741.000, 0, 0)  
+     (  480588.594, 4764740.500, 0, 0)  
+     (  480710.250, 4764690.500, 0, 0)  
+     (  480701.062, 4764738.000, 0, 0)  
+
+Shape:11 (Polygon)  nVertices=21, nParts=1
+  Bounds:(  476732.906, 4763624.500, 0, 0)
+      to (  478408.062, 4764876.000, 0, 0)
+     (  478315.531, 4764876.000, 0, 0) Ring 
+     (  478408.062, 4764654.000, 0, 0)  
+     (  478325.250, 4764606.500, 0, 0)  
+     (  478220.094, 4764574.500, 0, 0)  
+     (  478140.344, 4764511.000, 0, 0)  
+     (  478065.062, 4764487.500, 0, 0)  
+     (  478080.938, 4764401.500, 0, 0)  
+     (  478110.500, 4764308.500, 0, 0)  
+     (  478149.969, 4764212.500, 0, 0)  
+     (  478180.219, 4764150.000, 0, 0)  
+     (  478192.500, 4764099.500, 0, 0)  
+     (  477893.125, 4763984.500, 0, 0)  
+     (  477417.031, 4763800.500, 0, 0)  
+     (  477005.594, 4763640.000, 0, 0)  
+     (  476958.312, 4763624.500, 0, 0)  
+     (  476947.250, 4763664.500, 0, 0)  
+     (  476732.906, 4764243.000, 0, 0)  
+     (  477322.375, 4764502.000, 0, 0)  
+     (  477599.906, 4764600.000, 0, 0)  
+     (  477949.656, 4764745.000, 0, 0)  
+     (  478315.531, 4764876.000, 0, 0)  
+
+Shape:12 (Polygon)  nVertices=22, nParts=1
+  Bounds:(  478065.062, 4764099.500, 0, 0)
+      to (  478683.000, 4764788.500, 0, 0)
+     (  478408.062, 4764654.000, 0, 0) Ring 
+     (  478460.125, 4764615.000, 0, 0)  
+     (  478532.500, 4764695.500, 0, 0)  
+     (  478597.344, 4764766.500, 0, 0)  
+     (  478621.031, 4764788.500, 0, 0)  
+     (  478683.000, 4764730.500, 0, 0)  
+     (  478502.188, 4764541.500, 0, 0)  
+     (  478448.688, 4764531.500, 0, 0)  
+     (  478447.812, 4764454.000, 0, 0)  
+     (  478443.938, 4764400.500, 0, 0)  
+     (  478461.750, 4764337.500, 0, 0)  
+     (  478503.031, 4764218.000, 0, 0)  
+     (  478192.500, 4764099.500, 0, 0)  
+     (  478180.219, 4764150.000, 0, 0)  
+     (  478149.969, 4764212.500, 0, 0)  
+     (  478110.500, 4764308.500, 0, 0)  
+     (  478080.938, 4764401.500, 0, 0)  
+     (  478065.062, 4764487.500, 0, 0)  
+     (  478140.344, 4764511.000, 0, 0)  
+     (  478220.094, 4764574.500, 0, 0)  
+     (  478325.250, 4764606.500, 0, 0)  
+     (  478408.062, 4764654.000, 0, 0)  
+
+Shape:13 (Polygon)  nVertices=27, nParts=1
+  Bounds:(  479239.812, 4763850.000, 0, 0)
+      to (  480343.719, 4764788.000, 0, 0)
+     (  479750.688, 4764702.000, 0, 0) Ring 
+     (  479968.469, 4764788.000, 0, 0)  
+     (  479985.062, 4764732.000, 0, 0)  
+     (  480011.000, 4764674.500, 0, 0)  
+     (  480093.750, 4764703.000, 0, 0)  
+     (  480177.156, 4764742.000, 0, 0)  
+     (  480258.031, 4764767.000, 0, 0)  
+     (  480343.719, 4764532.500, 0, 0)  
+     (  480343.562, 4764477.000, 0, 0)  
+     (  480316.000, 4764395.000, 0, 0)  
+     (  480289.125, 4764348.500, 0, 0)  
+     (  480234.312, 4764304.000, 0, 0)  
+     (  480157.125, 4764266.500, 0, 0)  
+     (  480192.312, 4764183.000, 0, 0)  
+     (  480120.219, 4764188.500, 0, 0)  
+     (  479550.062, 4763919.500, 0, 0)  
+     (  479492.688, 4763850.000, 0, 0)  
+     (  479487.750, 4763864.500, 0, 0)  
+     (  479442.750, 4763990.000, 0, 0)  
+     (  479436.000, 4764023.000, 0, 0)  
+     (  479398.938, 4764100.000, 0, 0)  
+     (  479349.625, 4764230.000, 0, 0)  
+     (  479305.875, 4764361.000, 0, 0)  
+     (  479239.812, 4764505.000, 0, 0)  
+     (  479504.906, 4764609.500, 0, 0)  
+     (  479658.594, 4764670.000, 0, 0)  
+     (  479750.688, 4764702.000, 0, 0)  
+
+Shape:14 (Polygon)  nVertices=5, nParts=1
+  Bounds:(  479640.094, 4764670.000, 0, 0)
+      to (  479750.688, 4764752.000, 0, 0)
+     (  479750.688, 4764702.000, 0, 0) Ring 
+     (  479658.594, 4764670.000, 0, 0)  
+     (  479640.094, 4764721.000, 0, 0)  
+     (  479735.906, 4764752.000, 0, 0)  
+     (  479750.688, 4764702.000, 0, 0)  
+
+Shape:15 (Polygon)  nVertices=28, nParts=1
+  Bounds:(  478503.031, 4763357.500, 0, 0)
+      to (  479349.625, 4764418.500, 0, 0)
+     (  479305.875, 4764361.000, 0, 0) Ring 
+     (  479349.625, 4764230.000, 0, 0)  
+     (  479218.156, 4764126.000, 0, 0)  
+     (  479128.344, 4764030.500, 0, 0)  
+     (  479103.406, 4764000.000, 0, 0)  
+     (  479099.594, 4763977.500, 0, 0)  
+     (  479080.812, 4763930.000, 0, 0)  
+     (  478999.812, 4763864.500, 0, 0)  
+-------------------------------------------------------------------------
+Test 4: dump pline.dbf - uses new F field type
+-------------------------------------------------------------------------
+Field 0: Type=Integer, Title=`FNODE_', Width=11, Decimals=0
+Field 1: Type=Integer, Title=`TNODE_', Width=11, Decimals=0
+Field 2: Type=Integer, Title=`LPOLY_', Width=11, Decimals=0
+Field 3: Type=Integer, Title=`RPOLY_', Width=11, Decimals=0
+Field 4: Type=Double, Title=`LENGTH', Width=13, Decimals=3
+Field 5: Type=Integer, Title=`PLINE_', Width=11, Decimals=0
+Field 6: Type=Integer, Title=`PLINE_ID', Width=11, Decimals=0
+Field 7: Type=Integer, Title=`UID', Width=11, Decimals=0
+Field 8: Type=Integer, Title=`GISO_TYPE_', Width=11, Decimals=0
+Field 9: Type=Integer, Title=`SYMBOL', Width=6, Decimals=0
+Field 10: Type=Integer, Title=`LOCK__ID', Width=11, Decimals=0
+Field 11: Type=Integer, Title=`PHASE__ID', Width=6, Decimals=0
+Field 12: Type=Integer, Title=`OBJECT__ID', Width=11, Decimals=0
+Field 13: Type=String, Title=`TYPE', Width=50, Decimals=0
+Field 14: Type=Integer, Title=`SYM_NBR', Width=6, Decimals=0
+Field 15: Type=String, Title=`PHASE', Width=4, Decimals=0
+Field 16: Type=String, Title=`CKT_NM', Width=30, Decimals=0
+Field 17: Type=String, Title=`VOLTAGE', Width=30, Decimals=0
+Field 18: Type=String, Title=`CMPN', Width=30, Decimals=0
+
+Record: 0
+FNODE_:         351
+TNODE_:         352
+LPOLY_:           0
+RPOLY_:           0
+LENGTH:       139.451
+PLINE_:           1
+PLINE_ID:        8588
+UID:      544484
+GISO_TYPE_:          13
+SYMBOL:    101
+LOCK__ID:           0
+PHASE__ID:      0
+OBJECT__ID:      131978
+TYPE: Overhead Primary                                  
+SYM_NBR:    101
+PHASE: ABC 
+CKT_NM: MED36                         
+VOLTAGE: (NULL)                        
+CMPN: (NULL)                        
+
+Record: 1
+FNODE_:         352
+TNODE_:         362
+LPOLY_:           0
+RPOLY_:           0
+LENGTH:       158.033
+PLINE_:           2
+PLINE_ID:        8695
+UID:      544591
+-------------------------------------------------------------------------
+Test 5: NULL Shapes.
+-------------------------------------------------------------------------
+Shapefile Type: Arc   # of Shapes: 124
+
+File Bounds: (  257104.880, 5176098.606,0,0)
+         to  (  335497.500, 5226768.100,0,0)
+
+Shape:0 (Arc)  nVertices=21, nParts=1
+  Bounds:(  317138.450, 5176398.916, 0, 0)
+      to (  317325.590, 5186063.780, 0, 0)
+     (  317255.906, 5176398.916, 0, 0) Ring 
+     (  317188.010, 5176506.460, 0, 0)  
+     (  317176.920, 5176524.510, 0, 0)  
+     (  317165.340, 5176546.850, 0, 0)  
+     (  317157.950, 5176566.020, 0, 0)  
+     (  317150.020, 5176587.650, 0, 0)  
+     (  317140.130, 5176623.380, 0, 0)  
+     (  317138.700, 5176637.220, 0, 0)  
+     (  317138.450, 5176652.790, 0, 0)  
+     (  317194.710, 5177654.350, 0, 0)  
+     (  317208.900, 5178001.150, 0, 0)  
+     (  317257.240, 5178791.400, 0, 0)  
+     (  317233.330, 5179171.730, 0, 0)  
+     (  317178.860, 5179593.910, 0, 0)  
+     (  317177.430, 5180161.330, 0, 0)  
+     (  317179.910, 5181231.060, 0, 0)  
+     (  317191.120, 5182009.000, 0, 0)  
+     (  317217.150, 5182812.160, 0, 0)  
+     (  317251.760, 5184426.350, 0, 0)  
+     (  317285.550, 5185242.720, 0, 0)  
+     (  317325.590, 5186063.780, 0, 0)  
+
+Shape:1 (Arc)  nVertices=14, nParts=1
+  Bounds:(  327417.340, 5176119.960, 0, 0)
+      to (  327575.150, 5179522.550, 0, 0)
+     (  327417.340, 5176119.960, 0, 0) Ring 
+     (  327472.250, 5177756.610, 0, 0)  
+     (  327475.670, 5178507.280, 0, 0)  
+     (  327487.420, 5179001.910, 0, 0)  
+     (  327488.760, 5179080.090, 0, 0)  
+     (  327485.310, 5179309.310, 0, 0)  
+     (  327487.010, 5179328.210, 0, 0)  
+     (  327491.800, 5179348.860, 0, 0)  
+     (  327499.800, 5179374.940, 0, 0)  
+     (  327512.980, 5179413.100, 0, 0)  
+     (  327527.290, 5179446.960, 0, 0)  
+     (  327538.870, 5179469.890, 0, 0)  
+     (  327552.260, 5179491.550, 0, 0)  
+     (  327575.150, 5179522.550, 0, 0)  
+
+Shape:2 (Arc)  nVertices=40, nParts=1
+  Bounds:(  326935.880, 5180924.980, 0, 0)
+      to (  327723.190, 5198803.660, 0, 0)
+     (  327370.950, 5180924.980, 0, 0) Ring 
+     (  327410.070, 5181060.540, 0, 0)  
+     (  327512.850, 5181435.450, 0, 0)  
+     (  327518.640, 5181464.010, 0, 0)  
+     (  327523.700, 5181488.920, 0, 0)  
+     (  327524.500, 5181514.570, 0, 0)  
+     (  327468.010, 5182633.640, 0, 0)  
+     (  327500.040, 5183199.840, 0, 0)  
+     (  327499.600, 5183224.920, 0, 0)  
+     (  327484.700, 5183355.010, 0, 0)  
+     (  327483.690, 5183400.900, 0, 0)  
+     (  327483.840, 5183464.480, 0, 0)  
+     (  327486.010, 5183494.980, 0, 0)  
+     (  327571.280, 5184207.820, 0, 0)  
+     (  327617.210, 5184599.430, 0, 0)  
+     (  327620.420, 5184623.780, 0, 0)  
+     (  327625.530, 5184650.530, 0, 0)  
+     (  327698.430, 5184927.070, 0, 0)  
+     (  327702.100, 5184946.520, 0, 0)  
+     (  327717.940, 5185394.820, 0, 0)  
+     (  327723.190, 5185719.320, 0, 0)  
+     (  327719.460, 5185737.170, 0, 0)  
+     (  327712.090, 5185755.740, 0, 0)  
+     (  327699.840, 5185775.080, 0, 0)  
+     (  327683.830, 5185791.480, 0, 0)  
+     (  327665.380, 5185807.950, 0, 0)  
+     (  327641.970, 5185822.740, 0, 0)  
+     (  327622.280, 5185829.070, 0, 0)  
+     (  327604.950, 5185832.940, 0, 0)  
+     (  326937.500, 5185829.310, 0, 0)  
+     (  326935.880, 5187515.510, 0, 0)  
+     (  326983.050, 5189115.230, 0, 0)  
+     (  326998.860, 5189920.820, 0, 0)  
+     (  327060.240, 5190715.870, 0, 0)  
+     (  327123.230, 5192332.220, 0, 0)  
+     (  327179.920, 5193766.290, 0, 0)  
+     (  327185.490, 5193921.940, 0, 0)  
+     (  327204.120, 5195553.580, 0, 0)  
+     (  327218.270, 5197179.250, 0, 0)  
+     (  327251.330, 5198803.660, 0, 0)  
+
+Shape:3 (NullShape)  nVertices=0, nParts=0
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (       0.000,       0.000, 0, 0)
+
+Shape:4 (NullShape)  nVertices=0, nParts=0
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (       0.000,       0.000, 0, 0)
+
+Shape:5 (NullShape)  nVertices=0, nParts=0
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (       0.000,       0.000, 0, 0)
+
+Shape:6 (Arc)  nVertices=2, nParts=1
+  Bounds:(  327123.230, 5192296.600, 0, 0)
+      to (  328480.850, 5192332.220, 0, 0)
+     (  327123.230, 5192332.220, 0, 0) Ring 
+     (  328480.850, 5192296.600, 0, 0)  
+
+Shape:7 (Arc)  nVertices=5, nParts=1
+  Bounds:(  329222.060, 5217943.490, 0, 0)
+      to (  335290.680, 5218084.780, 0, 0)
+     (  329222.060, 5218084.780, 0, 0) Ring 
+     (  330442.520, 5218057.650, 0, 0)  
+     (  332059.960, 5218033.810, 0, 0)  
+     (  333685.820, 5218004.860, 0, 0)  
+     (  335290.680, 5217943.490, 0, 0)  
+
+Shape:8 (Arc)  nVertices=65, nParts=1
+  Bounds:(  280048.100, 5177687.643, 0, 0)
+      to (  280439.410, 5182567.120, 0, 0)
+     (  280316.840, 5177687.643, 0, 0) Ring 
+     (  280325.310, 5177968.830, 0, 0)  
+     (  280324.630, 5178037.940, 0, 0)  
+     (  280324.150, 5178059.350, 0, 0)  
+     (  280320.130, 5178084.560, 0, 0)  
+     (  280299.860, 5178170.250, 0, 0)  
+     (  280288.710, 5178218.940, 0, 0)  
+     (  280274.280, 5178283.640, 0, 0)  
+     (  280268.000, 5178330.870, 0, 0)  
+     (  280267.910, 5178346.760, 0, 0)  
+     (  280270.510, 5178364.580, 0, 0)  
+     (  280274.820, 5178382.360, 0, 0)  
+     (  280278.440, 5178397.210, 0, 0)  
+     (  280351.400, 5178743.800, 0, 0)  
+     (  280369.860, 5178800.630, 0, 0)  
+     (  280378.670, 5178826.010, 0, 0)  
+     (  280400.350, 5178869.890, 0, 0)  
+     (  280414.870, 5178901.180, 0, 0)  
+     (  280427.030, 5178934.990, 0, 0)  
+     (  280436.250, 5178971.970, 0, 0)  
+     (  280439.410, 5178992.650, 0, 0)  
+     (  280439.170, 5179001.630, 0, 0)  
+     (  280437.010, 5179011.690, 0, 0)  
+     (  280434.930, 5179016.970, 0, 0)  
+     (  280431.870, 5179022.260, 0, 0)  
+     (  280413.610, 5179041.850, 0, 0)  
+     (  280410.040, 5179046.780, 0, 0)  
+     (  280406.640, 5179052.480, 0, 0)  
diff --git a/src/shapelib/stream1.sh b/src/shapelib/stream1.sh
new file mode 100755
index 0000000..8a32887
--- /dev/null
+++ b/src/shapelib/stream1.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+	
+EG_DATA=/u/www/projects/shapelib/eg_data
+
+echo -------------------------------------------------------------------------
+echo Test 1: dump anno.shp
+echo -------------------------------------------------------------------------
+./shpdump $EG_DATA/anno.shp | head -250
+
+echo -------------------------------------------------------------------------
+echo Test 2: dump brklinz.shp
+echo -------------------------------------------------------------------------
+./shpdump $EG_DATA/brklinz.shp | head -500
+
+echo -------------------------------------------------------------------------
+echo Test 3: dump polygon.shp
+echo -------------------------------------------------------------------------
+./shpdump $EG_DATA/polygon.shp | head -500
+
+echo -------------------------------------------------------------------------
+echo Test 4: dump pline.dbf - uses new F field type
+echo -------------------------------------------------------------------------
+./dbfdump -m -h $EG_DATA/pline.dbf | head -50
+
+echo -------------------------------------------------------------------------
+echo Test 5: NULL Shapes.
+echo -------------------------------------------------------------------------
+./shpdump $EG_DATA/csah.dbf | head -150
diff --git a/src/shapelib/stream2.out b/src/shapelib/stream2.out
new file mode 100644
index 0000000..424a9e6
--- /dev/null
+++ b/src/shapelib/stream2.out
@@ -0,0 +1,530 @@
+-----------------------------------------------------------------------
+Test 2/0
+-----------------------------------------------------------------------
+Shapefile Type: NullShape   # of Shapes: 2
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (      10.000,      20.000,0,0)
+
+Shape:0 (NullShape)  nVertices=0, nParts=0
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (       0.000,       0.000, 0, 0)
+
+Shape:1 (NullShape)  nVertices=0, nParts=0
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (       0.000,       0.000, 0, 0)
+-----------------------------------------------------------------------
+Test 2/1
+-----------------------------------------------------------------------
+Shapefile Type: Point   # of Shapes: 2
+
+File Bounds: (       1.000,       2.000,0,0)
+         to  (      10.000,      20.000,0,0)
+
+Shape:0 (Point)  nVertices=1, nParts=0
+  Bounds:(       1.000,       2.000, 0, 0)
+      to (       1.000,       2.000, 0, 0)
+     (       1.000,       2.000, 0, 0)  
+
+Shape:1 (Point)  nVertices=1, nParts=0
+  Bounds:(      10.000,      20.000, 0, 0)
+      to (      10.000,      20.000, 0, 0)
+     (      10.000,      20.000, 0, 0)  
+-----------------------------------------------------------------------
+Test 2/2
+-----------------------------------------------------------------------
+Shapefile Type: PointZ   # of Shapes: 2
+
+File Bounds: (       1.000,       2.000,3,4)
+         to  (      10.000,      20.000,30,40)
+
+Shape:0 (PointZ)  nVertices=1, nParts=0
+  Bounds:(       1.000,       2.000, 3, 4)
+      to (       1.000,       2.000, 3, 4)
+     (       1.000,       2.000, 3, 4)  
+
+Shape:1 (PointZ)  nVertices=1, nParts=0
+  Bounds:(      10.000,      20.000, 30, 40)
+      to (      10.000,      20.000, 30, 40)
+     (      10.000,      20.000, 30, 40)  
+-----------------------------------------------------------------------
+Test 2/3
+-----------------------------------------------------------------------
+Shapefile Type: PointM   # of Shapes: 2
+
+File Bounds: (       1.000,       2.000,0,4)
+         to  (      10.000,      20.000,0,40)
+
+Shape:0 (PointM)  nVertices=1, nParts=0
+  Bounds:(       1.000,       2.000, 0, 4)
+      to (       1.000,       2.000, 0, 4)
+     (       1.000,       2.000, 0, 4)  
+
+Shape:1 (PointM)  nVertices=1, nParts=0
+  Bounds:(      10.000,      20.000, 0, 40)
+      to (      10.000,      20.000, 0, 40)
+     (      10.000,      20.000, 0, 40)  
+-----------------------------------------------------------------------
+Test 2/4
+-----------------------------------------------------------------------
+Shapefile Type: MultiPoint   # of Shapes: 3
+
+File Bounds: (       1.150,       2.250,0,0)
+         to  (      24.150,      25.250,0,0)
+
+Shape:0 (MultiPoint)  nVertices=4, nParts=0
+  Bounds:(       1.150,       2.250, 0, 0)
+      to (       4.150,       5.250, 0, 0)
+     (       1.150,       2.250, 0, 0)  
+     (       2.150,       3.250, 0, 0)  
+     (       3.150,       4.250, 0, 0)  
+     (       4.150,       5.250, 0, 0)  
+
+Shape:1 (MultiPoint)  nVertices=4, nParts=0
+  Bounds:(      11.150,      12.250, 0, 0)
+      to (      14.150,      15.250, 0, 0)
+     (      11.150,      12.250, 0, 0)  
+     (      12.150,      13.250, 0, 0)  
+     (      13.150,      14.250, 0, 0)  
+     (      14.150,      15.250, 0, 0)  
+
+Shape:2 (MultiPoint)  nVertices=4, nParts=0
+  Bounds:(      21.150,      22.250, 0, 0)
+      to (      24.150,      25.250, 0, 0)
+     (      21.150,      22.250, 0, 0)  
+     (      22.150,      23.250, 0, 0)  
+     (      23.150,      24.250, 0, 0)  
+     (      24.150,      25.250, 0, 0)  
+-----------------------------------------------------------------------
+Test 2/5
+-----------------------------------------------------------------------
+Shapefile Type: MultiPointZ   # of Shapes: 3
+
+File Bounds: (       1.150,       2.250,3.35,4.45)
+         to  (      24.150,      25.250,26.35,27.45)
+
+Shape:0 (MultiPointZ)  nVertices=4, nParts=0
+  Bounds:(       1.150,       2.250, 3.35, 4.45)
+      to (       4.150,       5.250, 6.35, 7.45)
+     (       1.150,       2.250, 3.35, 4.45)  
+     (       2.150,       3.250, 4.35, 5.45)  
+     (       3.150,       4.250, 5.35, 6.45)  
+     (       4.150,       5.250, 6.35, 7.45)  
+
+Shape:1 (MultiPointZ)  nVertices=4, nParts=0
+  Bounds:(      11.150,      12.250, 13.35, 14.45)
+      to (      14.150,      15.250, 16.35, 17.45)
+     (      11.150,      12.250, 13.35, 14.45)  
+     (      12.150,      13.250, 14.35, 15.45)  
+     (      13.150,      14.250, 15.35, 16.45)  
+     (      14.150,      15.250, 16.35, 17.45)  
+
+Shape:2 (MultiPointZ)  nVertices=4, nParts=0
+  Bounds:(      21.150,      22.250, 23.35, 24.45)
+      to (      24.150,      25.250, 26.35, 27.45)
+     (      21.150,      22.250, 23.35, 24.45)  
+     (      22.150,      23.250, 24.35, 25.45)  
+     (      23.150,      24.250, 25.35, 26.45)  
+     (      24.150,      25.250, 26.35, 27.45)  
+-----------------------------------------------------------------------
+Test 2/6
+-----------------------------------------------------------------------
+Shapefile Type: MultiPointM   # of Shapes: 3
+
+File Bounds: (       1.150,       2.250,0,4.45)
+         to  (      24.150,      25.250,0,27.45)
+
+Shape:0 (MultiPointM)  nVertices=4, nParts=0
+  Bounds:(       1.150,       2.250, 0, 4.45)
+      to (       4.150,       5.250, 0, 7.45)
+     (       1.150,       2.250, 0, 4.45)  
+     (       2.150,       3.250, 0, 5.45)  
+     (       3.150,       4.250, 0, 6.45)  
+     (       4.150,       5.250, 0, 7.45)  
+
+Shape:1 (MultiPointM)  nVertices=4, nParts=0
+  Bounds:(      11.150,      12.250, 0, 14.45)
+      to (      14.150,      15.250, 0, 17.45)
+     (      11.150,      12.250, 0, 14.45)  
+     (      12.150,      13.250, 0, 15.45)  
+     (      13.150,      14.250, 0, 16.45)  
+     (      14.150,      15.250, 0, 17.45)  
+
+Shape:2 (MultiPointM)  nVertices=4, nParts=0
+  Bounds:(      21.150,      22.250, 0, 24.45)
+      to (      24.150,      25.250, 0, 27.45)
+     (      21.150,      22.250, 0, 24.45)  
+     (      22.150,      23.250, 0, 25.45)  
+     (      23.150,      24.250, 0, 26.45)  
+     (      24.150,      25.250, 0, 27.45)  
+-----------------------------------------------------------------------
+Test 2/7
+-----------------------------------------------------------------------
+Shapefile Type: Arc   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,0,0)
+
+Shape:0 (Arc)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 0, 0)
+      to (       2.000,       2.000, 0, 0)
+     (       1.000,       1.000, 0, 0) Ring 
+     (       2.000,       1.000, 0, 0)  
+     (       2.000,       2.000, 0, 0)  
+     (       1.000,       2.000, 0, 0)  
+     (       1.000,       1.000, 0, 0)  
+
+Shape:1 (Arc)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 0, 0)
+      to (       2.000,       5.000, 0, 0)
+     (       1.000,       4.000, 0, 0) Ring 
+     (       2.000,       4.000, 0, 0)  
+     (       2.000,       5.000, 0, 0)  
+     (       1.000,       5.000, 0, 0)  
+     (       1.000,       4.000, 0, 0)  
+
+Shape:2 (Arc)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 0, 0)
+      to (       2.000,       8.000, 0, 0)
+     (       1.000,       7.000, 0, 0) Ring 
+     (       2.000,       7.000, 0, 0)  
+     (       2.000,       8.000, 0, 0)  
+     (       1.000,       8.000, 0, 0)  
+     (       1.000,       7.000, 0, 0)  
+
+Shape:3 (Arc)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 0, 0)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 0, 0)  
+     (     100.000,     100.000, 0, 0)  
+     (     100.000,       0.000, 0, 0)  
+     (       0.000,       0.000, 0, 0)  
+   + (      10.000,      20.000, 0, 0) Ring 
+     (      30.000,      20.000, 0, 0)  
+     (      30.000,      40.000, 0, 0)  
+     (      10.000,      40.000, 0, 0)  
+     (      10.000,      20.000, 0, 0)  
+   + (      60.000,      20.000, 0, 0) Ring 
+     (      90.000,      20.000, 0, 0)  
+     (      90.000,      40.000, 0, 0)  
+     (      60.000,      40.000, 0, 0)  
+     (      60.000,      20.000, 0, 0)  
+-----------------------------------------------------------------------
+Test 2/8
+-----------------------------------------------------------------------
+Shapefile Type: ArcZ   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,27.35,28.45)
+
+Shape:0 (ArcZ)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 3.35, 4.45)
+      to (       2.000,       2.000, 7.35, 8.45)
+     (       1.000,       1.000, 3.35, 4.45) Ring 
+     (       2.000,       1.000, 4.35, 5.45)  
+     (       2.000,       2.000, 5.35, 6.45)  
+     (       1.000,       2.000, 6.35, 7.45)  
+     (       1.000,       1.000, 7.35, 8.45)  
+
+Shape:1 (ArcZ)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 13.35, 14.45)
+      to (       2.000,       5.000, 17.35, 18.45)
+     (       1.000,       4.000, 13.35, 14.45) Ring 
+     (       2.000,       4.000, 14.35, 15.45)  
+     (       2.000,       5.000, 15.35, 16.45)  
+     (       1.000,       5.000, 16.35, 17.45)  
+     (       1.000,       4.000, 17.35, 18.45)  
+
+Shape:2 (ArcZ)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 23.35, 24.45)
+      to (       2.000,       8.000, 27.35, 28.45)
+     (       1.000,       7.000, 23.35, 24.45) Ring 
+     (       2.000,       7.000, 24.35, 25.45)  
+     (       2.000,       8.000, 25.35, 26.45)  
+     (       1.000,       8.000, 26.35, 27.45)  
+     (       1.000,       7.000, 27.35, 28.45)  
+
+Shape:3 (ArcZ)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 14, 28)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 1, 2)  
+     (     100.000,     100.000, 2, 4)  
+     (     100.000,       0.000, 3, 6)  
+     (       0.000,       0.000, 4, 8)  
+   + (      10.000,      20.000, 5, 10) Ring 
+     (      30.000,      20.000, 6, 12)  
+     (      30.000,      40.000, 7, 14)  
+     (      10.000,      40.000, 8, 16)  
+     (      10.000,      20.000, 9, 18)  
+   + (      60.000,      20.000, 10, 20) Ring 
+     (      90.000,      20.000, 11, 22)  
+     (      90.000,      40.000, 12, 24)  
+     (      60.000,      40.000, 13, 26)  
+     (      60.000,      20.000, 14, 28)  
+-----------------------------------------------------------------------
+Test 2/9
+-----------------------------------------------------------------------
+Shapefile Type: ArcM   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,0,28.45)
+
+Shape:0 (ArcM)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 0, 4.45)
+      to (       2.000,       2.000, 0, 8.45)
+     (       1.000,       1.000, 0, 4.45) Ring 
+     (       2.000,       1.000, 0, 5.45)  
+     (       2.000,       2.000, 0, 6.45)  
+     (       1.000,       2.000, 0, 7.45)  
+     (       1.000,       1.000, 0, 8.45)  
+
+Shape:1 (ArcM)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 0, 14.45)
+      to (       2.000,       5.000, 0, 18.45)
+     (       1.000,       4.000, 0, 14.45) Ring 
+     (       2.000,       4.000, 0, 15.45)  
+     (       2.000,       5.000, 0, 16.45)  
+     (       1.000,       5.000, 0, 17.45)  
+     (       1.000,       4.000, 0, 18.45)  
+
+Shape:2 (ArcM)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 0, 24.45)
+      to (       2.000,       8.000, 0, 28.45)
+     (       1.000,       7.000, 0, 24.45) Ring 
+     (       2.000,       7.000, 0, 25.45)  
+     (       2.000,       8.000, 0, 26.45)  
+     (       1.000,       8.000, 0, 27.45)  
+     (       1.000,       7.000, 0, 28.45)  
+
+Shape:3 (ArcM)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 0, 28)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 0, 2)  
+     (     100.000,     100.000, 0, 4)  
+     (     100.000,       0.000, 0, 6)  
+     (       0.000,       0.000, 0, 8)  
+   + (      10.000,      20.000, 0, 10) Ring 
+     (      30.000,      20.000, 0, 12)  
+     (      30.000,      40.000, 0, 14)  
+     (      10.000,      40.000, 0, 16)  
+     (      10.000,      20.000, 0, 18)  
+   + (      60.000,      20.000, 0, 20) Ring 
+     (      90.000,      20.000, 0, 22)  
+     (      90.000,      40.000, 0, 24)  
+     (      60.000,      40.000, 0, 26)  
+     (      60.000,      20.000, 0, 28)  
+-----------------------------------------------------------------------
+Test 2/10
+-----------------------------------------------------------------------
+Shapefile Type: Polygon   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,0,0)
+
+Shape:0 (Polygon)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 0, 0)
+      to (       2.000,       2.000, 0, 0)
+     (       1.000,       1.000, 0, 0) Ring 
+     (       2.000,       1.000, 0, 0)  
+     (       2.000,       2.000, 0, 0)  
+     (       1.000,       2.000, 0, 0)  
+     (       1.000,       1.000, 0, 0)  
+
+Shape:1 (Polygon)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 0, 0)
+      to (       2.000,       5.000, 0, 0)
+     (       1.000,       4.000, 0, 0) Ring 
+     (       2.000,       4.000, 0, 0)  
+     (       2.000,       5.000, 0, 0)  
+     (       1.000,       5.000, 0, 0)  
+     (       1.000,       4.000, 0, 0)  
+
+Shape:2 (Polygon)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 0, 0)
+      to (       2.000,       8.000, 0, 0)
+     (       1.000,       7.000, 0, 0) Ring 
+     (       2.000,       7.000, 0, 0)  
+     (       2.000,       8.000, 0, 0)  
+     (       1.000,       8.000, 0, 0)  
+     (       1.000,       7.000, 0, 0)  
+
+Shape:3 (Polygon)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 0, 0)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 0, 0)  
+     (     100.000,     100.000, 0, 0)  
+     (     100.000,       0.000, 0, 0)  
+     (       0.000,       0.000, 0, 0)  
+   + (      10.000,      20.000, 0, 0) Ring 
+     (      30.000,      20.000, 0, 0)  
+     (      30.000,      40.000, 0, 0)  
+     (      10.000,      40.000, 0, 0)  
+     (      10.000,      20.000, 0, 0)  
+   + (      60.000,      20.000, 0, 0) Ring 
+     (      90.000,      20.000, 0, 0)  
+     (      90.000,      40.000, 0, 0)  
+     (      60.000,      40.000, 0, 0)  
+     (      60.000,      20.000, 0, 0)  
+-----------------------------------------------------------------------
+Test 2/11
+-----------------------------------------------------------------------
+Shapefile Type: PolygonZ   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,27.35,28.45)
+
+Shape:0 (PolygonZ)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 3.35, 4.45)
+      to (       2.000,       2.000, 7.35, 8.45)
+     (       1.000,       1.000, 3.35, 4.45) Ring 
+     (       2.000,       1.000, 4.35, 5.45)  
+     (       2.000,       2.000, 5.35, 6.45)  
+     (       1.000,       2.000, 6.35, 7.45)  
+     (       1.000,       1.000, 7.35, 8.45)  
+
+Shape:1 (PolygonZ)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 13.35, 14.45)
+      to (       2.000,       5.000, 17.35, 18.45)
+     (       1.000,       4.000, 13.35, 14.45) Ring 
+     (       2.000,       4.000, 14.35, 15.45)  
+     (       2.000,       5.000, 15.35, 16.45)  
+     (       1.000,       5.000, 16.35, 17.45)  
+     (       1.000,       4.000, 17.35, 18.45)  
+
+Shape:2 (PolygonZ)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 23.35, 24.45)
+      to (       2.000,       8.000, 27.35, 28.45)
+     (       1.000,       7.000, 23.35, 24.45) Ring 
+     (       2.000,       7.000, 24.35, 25.45)  
+     (       2.000,       8.000, 25.35, 26.45)  
+     (       1.000,       8.000, 26.35, 27.45)  
+     (       1.000,       7.000, 27.35, 28.45)  
+
+Shape:3 (PolygonZ)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 14, 28)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 1, 2)  
+     (     100.000,     100.000, 2, 4)  
+     (     100.000,       0.000, 3, 6)  
+     (       0.000,       0.000, 4, 8)  
+   + (      10.000,      20.000, 5, 10) Ring 
+     (      30.000,      20.000, 6, 12)  
+     (      30.000,      40.000, 7, 14)  
+     (      10.000,      40.000, 8, 16)  
+     (      10.000,      20.000, 9, 18)  
+   + (      60.000,      20.000, 10, 20) Ring 
+     (      90.000,      20.000, 11, 22)  
+     (      90.000,      40.000, 12, 24)  
+     (      60.000,      40.000, 13, 26)  
+     (      60.000,      20.000, 14, 28)  
+-----------------------------------------------------------------------
+Test 2/12
+-----------------------------------------------------------------------
+Shapefile Type: PolygonM   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,0,28.45)
+
+Shape:0 (PolygonM)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 0, 4.45)
+      to (       2.000,       2.000, 0, 8.45)
+     (       1.000,       1.000, 0, 4.45) Ring 
+     (       2.000,       1.000, 0, 5.45)  
+     (       2.000,       2.000, 0, 6.45)  
+     (       1.000,       2.000, 0, 7.45)  
+     (       1.000,       1.000, 0, 8.45)  
+
+Shape:1 (PolygonM)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 0, 14.45)
+      to (       2.000,       5.000, 0, 18.45)
+     (       1.000,       4.000, 0, 14.45) Ring 
+     (       2.000,       4.000, 0, 15.45)  
+     (       2.000,       5.000, 0, 16.45)  
+     (       1.000,       5.000, 0, 17.45)  
+     (       1.000,       4.000, 0, 18.45)  
+
+Shape:2 (PolygonM)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 0, 24.45)
+      to (       2.000,       8.000, 0, 28.45)
+     (       1.000,       7.000, 0, 24.45) Ring 
+     (       2.000,       7.000, 0, 25.45)  
+     (       2.000,       8.000, 0, 26.45)  
+     (       1.000,       8.000, 0, 27.45)  
+     (       1.000,       7.000, 0, 28.45)  
+
+Shape:3 (PolygonM)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 0, 28)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 0, 2)  
+     (     100.000,     100.000, 0, 4)  
+     (     100.000,       0.000, 0, 6)  
+     (       0.000,       0.000, 0, 8)  
+   + (      10.000,      20.000, 0, 10) Ring 
+     (      30.000,      20.000, 0, 12)  
+     (      30.000,      40.000, 0, 14)  
+     (      10.000,      40.000, 0, 16)  
+     (      10.000,      20.000, 0, 18)  
+   + (      60.000,      20.000, 0, 20) Ring 
+     (      90.000,      20.000, 0, 22)  
+     (      90.000,      40.000, 0, 24)  
+     (      60.000,      40.000, 0, 26)  
+     (      60.000,      20.000, 0, 28)  
+-----------------------------------------------------------------------
+Test 2/13
+-----------------------------------------------------------------------
+Shapefile Type: MultiPatch   # of Shapes: 4
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     100.000,     100.000,27.35,28.45)
+
+Shape:0 (MultiPatch)  nVertices=5, nParts=1
+  Bounds:(       1.000,       1.000, 3.35, 0)
+      to (       2.000,       2.000, 7.35, 0)
+     (       1.000,       1.000, 3.35, 0) Ring 
+     (       2.000,       1.000, 4.35, 0)  
+     (       2.000,       2.000, 5.35, 0)  
+     (       1.000,       2.000, 6.35, 0)  
+     (       1.000,       1.000, 7.35, 0)  
+
+Shape:1 (MultiPatch)  nVertices=5, nParts=1
+  Bounds:(       1.000,       4.000, 13.35, 0)
+      to (       2.000,       5.000, 17.35, 0)
+     (       1.000,       4.000, 13.35, 0) Ring 
+     (       2.000,       4.000, 14.35, 0)  
+     (       2.000,       5.000, 15.35, 0)  
+     (       1.000,       5.000, 16.35, 0)  
+     (       1.000,       4.000, 17.35, 0)  
+
+Shape:2 (MultiPatch)  nVertices=5, nParts=1
+  Bounds:(       1.000,       7.000, 23.35, 0)
+      to (       2.000,       8.000, 27.35, 0)
+     (       1.000,       7.000, 23.35, 0) Ring 
+     (       2.000,       7.000, 24.35, 0)  
+     (       2.000,       8.000, 25.35, 0)  
+     (       1.000,       8.000, 26.35, 0)  
+     (       1.000,       7.000, 27.35, 0)  
+
+Shape:3 (MultiPatch)  nVertices=15, nParts=3
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 14, 0)
+     (       0.000,       0.000, 0, 0) Ring 
+     (       0.000,     100.000, 1, 0)  
+     (     100.000,     100.000, 2, 0)  
+     (     100.000,       0.000, 3, 0)  
+     (       0.000,       0.000, 4, 0)  
+   + (      10.000,      20.000, 5, 0) InnerRing 
+     (      30.000,      20.000, 6, 0)  
+     (      30.000,      40.000, 7, 0)  
+     (      10.000,      40.000, 8, 0)  
+     (      10.000,      20.000, 9, 0)  
+   + (      60.000,      20.000, 10, 0) InnerRing 
+     (      90.000,      20.000, 11, 0)  
+     (      90.000,      40.000, 12, 0)  
+     (      60.000,      40.000, 13, 0)  
+     (      60.000,      20.000, 14, 0)  
diff --git a/src/shapelib/stream2.sh b/src/shapelib/stream2.sh
new file mode 100755
index 0000000..bd0b111
--- /dev/null
+++ b/src/shapelib/stream2.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13; do
+  echo -----------------------------------------------------------------------
+  echo Test 2/$i
+  echo -----------------------------------------------------------------------
+
+  ./shptest $i
+  ./shpdump test${i}.shp
+done
+
diff --git a/src/shapelib/stream3.out b/src/shapelib/stream3.out
new file mode 100644
index 0000000..b668233
--- /dev/null
+++ b/src/shapelib/stream3.out
@@ -0,0 +1,37 @@
+Shapefile Type: Polygon   # of Shapes: 3
+
+File Bounds: (       0.000,       0.000,0,0)
+         to  (     180.000,     170.000,0,0)
+
+Shape:0 (Polygon)  nVertices=9, nParts=2
+  Bounds:(       0.000,       0.000, 0, 0)
+      to (     100.000,     100.000, 0, 0)
+     (       0.000,       0.000, 0, 0) Ring 
+     (     100.000,       0.000, 0, 0)  
+     (     100.000,     100.000, 0, 0)  
+     (       0.000,     100.000, 0, 0)  
+     (       0.000,       0.000, 0, 0)  
+   + (      20.000,      20.000, 0, 0) Ring 
+     (      20.000,      30.000, 0, 0)  
+     (      30.000,      30.000, 0, 0)  
+     (      20.000,      20.000, 0, 0)  
+
+Shape:1 (Polygon)  nVertices=4, nParts=1
+  Bounds:(     150.000,     150.000, 0, 0)
+      to (     180.000,     170.000, 0, 0)
+     (     150.000,     150.000, 0, 0) Ring 
+     (     160.000,     150.000, 0, 0)  
+     (     180.000,     170.000, 0, 0)  
+     (     150.000,     150.000, 0, 0)  
+
+Shape:2 (Polygon)  nVertices=4, nParts=1
+  Bounds:(     150.000,     150.000, 0, 0)
+      to (     180.000,     170.000, 0, 0)
+     (     150.000,     150.000, 0, 0) Ring 
+     (     160.000,     150.000, 0, 0)  
+     (     180.000,     170.000, 0, 0)  
+     (     150.000,     150.000, 0, 0)  
+Descriptio                     TestInt       TestDouble 
+Square with triangle missing        1           2.50000 
+Smaller triangle                  100        1000.25000 
+(NULL)                         (NULL)            (NULL) 
diff --git a/src/shp_hash.c b/src/shp_hash.c
new file mode 100644
index 0000000..aa82a0d
--- /dev/null
+++ b/src/shp_hash.c
@@ -0,0 +1,390 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: shp_hash.c,v 1.29 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#ifdef USE_RTREE
+#ifdef HAVE_LIBSHP
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#ifdef HAVE_SHAPEFIL_H
+#include <shapefil.h>
+#else
+#ifdef HAVE_LIBSHP_SHAPEFIL_H
+#include <libshp/shapefil.h>
+#else
+#error HAVE_LIBSHP defined but no corresponding include defined
+#endif  // HAVE_LIBSHP_SHAPEFIL_H
+#endif  // HAVE_SHAPEFIL_H
+
+
+#include <rtree/index.h>
+
+#include "xastir.h"
+#include "util.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+/// THIS ONLY FOR DEBUGGING!
+#include "hashtable_private.h"
+#include "shp_hash.h"
+#include "snprintf.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define PURGE_PERIOD 3600     // One hour, hard coded for now.
+                              // This should be in a slider in the timing
+                              // configuration instead.
+
+//#define PURGE_PERIOD 120  //  debugging
+
+static struct hashtable *shp_hash=NULL;
+static time_t purge_time;
+
+#define SHP_HASH_SIZE 65535
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+
+
+
+
+unsigned int shape_hash_from_key(void *key) {
+    char *str=(char *)key;
+    unsigned int shphash=5381;
+    int c;
+    int i=0;
+    while (str[i]!='\0') {
+        c=str[i++];
+        shphash = ((shphash << 5) + shphash)^c;
+    }
+
+    return (shphash);
+}
+
+
+
+
+
+int shape_keys_equal(void *key1, void *key2) {
+
+    //    fprintf(stderr,"Comparing %s to %s\n",(char *)key1,(char *)key2);
+    if (strncmp((char *)key1,(char *)key2,strlen((char *)key1))==0) {
+        //        fprintf(stderr,"    match\n");
+        return(1);
+    } else {
+        //        fprintf(stderr,"  no  match\n");
+        return(0);
+    }
+}
+
+
+
+
+
+void init_shp_hash(int clobber) {
+    //fprintf(stderr," Initializing shape hash \n");
+    // make sure we don't leak
+    if (shp_hash) {
+        if (clobber) {
+            hashtable_destroy(shp_hash, 1);
+            shp_hash=create_hashtable(SHP_HASH_SIZE,
+                                      shape_hash_from_key,
+                                      shape_keys_equal);
+        }
+    } else {
+        shp_hash=create_hashtable(SHP_HASH_SIZE,
+                                  shape_hash_from_key,
+                                  shape_keys_equal);
+    }
+
+    // Now set the static timer value to the next time we need to run the purge
+    // routine
+    purge_time = sec_now() + PURGE_PERIOD;
+}
+
+
+
+
+
+// destructor for a single shapeinfo structure
+void destroy_shpinfo(shpinfo *si) {
+    if (si) {
+        empty_shpinfo(si);
+        //        fprintf(stderr,
+        //                "       Freeing shpinfo %lx\n",
+        //        (unsigned long int) si);
+        free(si);
+    }
+}
+
+
+
+
+
+// free the pointers in a shapinfo object
+void empty_shpinfo(shpinfo *si) {
+    if (si) {
+        if (si->root) {
+            //            fprintf(stderr,"        Freeing root\n");
+            Xastir_RTreeDestroyNode(si->root);
+            si->root=NULL;
+        }
+
+        // This is a little annoying --- the hashtable functions free the
+        // key, which is in our case the filename.  So since we're only going
+        // to empty the shpinfo when we're removing from the hashtable, we
+        // must not free the filename ourselves.
+        //        if (si->filename) {
+        //            fprintf(stderr,"        Freeing filename\n");
+        //            free(si->filename);
+        //            si->filename=NULL;
+        //        }
+    }
+}
+
+
+
+
+
+void destroy_shp_hash(void) {
+    struct hashtable_itr *iterator=NULL;
+    shpinfo *si;
+    int ret;
+
+    if (shp_hash) {
+        // walk through the hashtable, free any pointers in the values
+        // that aren't null, or we'll leak like a sieve.
+
+        // the hashtable functions always attempt to dereference iterator,
+        // and don't check if you give it a null, but will return null if
+        // there's nothing in the table.  Grrrr.
+        iterator=hashtable_iterator(shp_hash);
+        do {
+            ret=0;
+            if (iterator) {
+                si = hashtable_iterator_value(iterator);
+                if (si) 
+                    empty_shpinfo(si);
+                ret=hashtable_iterator_advance(iterator);
+            }
+        } while (ret);
+        hashtable_destroy(shp_hash, 1);  // destroy the hashtable, freeing
+                                         // what's left of the entries
+        shp_hash=NULL;
+        if (iterator) free(iterator);
+    }
+}
+
+
+
+
+
+void add_shp_to_hash(char *filename, SHPHandle sHP) {
+
+    // This function does NOT check whether there already is something in 
+    // the hashtable that matches.
+    // Check that before calling this routine.
+
+    shpinfo *temp;
+    int filenm_len;
+
+    filenm_len=strlen(filename);
+    if (!shp_hash) {  // no table to add to
+        init_shp_hash(1); // so create one
+    }
+    temp = (shpinfo *)malloc(sizeof(shpinfo));
+    CHECKMALLOC(temp);
+    // leave room for terminator
+    temp->filename = (char *) malloc(sizeof(char)*(filenm_len+1));
+    CHECKMALLOC(temp->filename);
+
+    strncpy(temp->filename,filename,filenm_len+1);
+    temp->filename[filenm_len]='\0';  // just to be safe
+//    xastir_snprintf(temp->filename,sizeof(shpinfo),"%s",filename);
+
+    temp->root = Xastir_RTreeNewIndex();  
+    temp->creation = sec_now();
+    temp->last_access = temp->creation;
+
+    build_rtree(&(temp->root),sHP);
+
+    //fprintf(stderr, "  adding %s...",temp->filename);
+    if (!hashtable_insert(shp_hash,temp->filename,temp)) {
+        fprintf(stderr,"Insert failed on shapefile hash --- fatal\n");
+        free(temp->filename);
+        free(temp);
+        exit(1);
+    }
+}
+
+
+
+
+
+shpinfo *get_shp_from_hash(char *filename) {
+    shpinfo *result;
+    if (!shp_hash) {  // no table to search
+        init_shp_hash(1); // so create one
+        return NULL;
+    }
+
+    //fprintf(stderr,"   searching for %s...",filename);
+
+    result=hashtable_search(shp_hash,filename);
+
+    //    if (result) {
+    //        fprintf(stderr,"      found it\n");
+    //    } else {
+    //        fprintf(stderr,"      it is not there\n");
+    //    }
+
+    // If there is one, we have now accessed it, so bump the last access time
+    if (result) {
+        result->last_access = sec_now();
+    }
+
+    return (result);
+
+}
+
+
+
+
+
+//CAREFUL:  note how adding things to the tree can change the root
+// Must not ever use cache a value of the root pointer if there's any
+// chance that the tree needs to be expanded!
+void build_rtree (struct Node **root, SHPHandle sHP) {
+    int nEntities;
+    intptr_t i;
+    SHPObject	*psCShape;
+    struct Rect bbox_shape;
+    SHPGetInfo(sHP, &nEntities, NULL, NULL, NULL);
+    for( i = 0; i < nEntities; i++ ) {
+        psCShape = SHPReadObject ( sHP, i );
+     	if (psCShape != NULL) {
+            bbox_shape.boundary[0]=(RectReal) psCShape->dfXMin;
+            bbox_shape.boundary[1]=(RectReal) psCShape->dfYMin;
+            bbox_shape.boundary[2]=(RectReal) psCShape->dfXMax;
+            bbox_shape.boundary[3]=(RectReal) psCShape->dfYMax;
+            SHPDestroyObject ( psCShape );
+            // Only insert the rect if it will not fail the assertion in 
+            // Xastir_RTreeInsertRect --- this will cause us to ignore any shapes that
+            // have invalid bboxes (or that return invalid bboxes from shapelib
+            // for whatever reason
+            if (bbox_shape.boundary[0] <= bbox_shape.boundary[2] &&
+                    bbox_shape.boundary[1] <= bbox_shape.boundary[3]) {
+                Xastir_RTreeInsertRect(&bbox_shape, (void *)(i+1), root, 0);
+            }
+        }
+    }
+}
+
+
+
+
+
+void purge_shp_hash(time_t secs_now) {
+    struct hashtable_itr *iterator=NULL;
+    shpinfo *si;
+    int ret;
+
+
+    if (secs_now > purge_time) {  // Time to purge
+        //time_now = localtime(&secs_now);
+        //(void)strftime(timestring,100,"%a %b %d %H:%M:%S %Z %Y",time_now);
+        //fprintf(stderr,"Purging...%s\n",timestring);
+
+        purge_time += PURGE_PERIOD;
+
+        if (shp_hash) {
+            // walk through the hash table and kill entries that are old
+
+            iterator=hashtable_iterator(shp_hash);
+            do {
+                ret=0;
+                if (iterator) {  // must check this, because could be null
+                                 // if the iterator malloc failed
+                    si=hashtable_iterator_value(iterator);
+                    
+                    if (si) {
+                        if (secs_now > si->last_access+PURGE_PERIOD) {
+                            // this is stale, hasn't been accessed in a while
+                            //fprintf(stderr,
+                            // "found stale entry for %s, deleting it.\n",
+                            // si->filename);
+                            //fprintf(stderr,"    Destroying si=%lx\n",
+                            //            (unsigned long int) si);
+                            ret=hashtable_iterator_remove(iterator);
+                            
+                            // Important that we NOT do the
+                            // destroy first, because we've used
+                            // the filename pointer field of the
+                            // structure as the key, and the
+                            // remove function will free that.  If
+                            // we clobber the struct first, we
+                            // invite segfaults
+                            destroy_shpinfo(si);
+                            
+                            //fprintf(stderr,"    removing from hashtable\n");
+                        } else {
+                            ret=hashtable_iterator_advance(iterator);
+                        }
+                    }
+                }
+            } while (ret);
+            // we're now done with the iterator.  Free it to stop us from
+            // leaking!
+            if (iterator) free(iterator);
+        }
+        //fprintf(stderr,"   done Purging...\n");
+    }
+}
+
+#endif  // HAVE_LIBSHP
+#endif // USE_RTREE
+
+
+// To get rid of "-pedantic" compiler warning:
+int NON_EMPTY_SOURCE_FILE;
+
+
diff --git a/src/shp_hash.h b/src/shp_hash.h
new file mode 100644
index 0000000..498e949
--- /dev/null
+++ b/src/shp_hash.h
@@ -0,0 +1,39 @@
+
+// $Id: shp_hash.h,v 1.11 2012/11/01 18:57:19 we7u Exp $
+// Copyright (C) 2004-2012  The Xastir Group
+
+
+#ifndef __XASTIR_SHP_HASH_H
+#define __XASTIR_SHP_HASH_H
+
+#ifdef USE_RTREE
+
+#ifdef HAVE_SHAPEFIL_H
+#include <shapefil.h>
+#else
+#ifdef HAVE_LIBSHP_SHAPEFIL_H
+#include <libshp/shapefil.h>
+#else
+#error HAVE_LIBSHP defined but no corresponding include defined
+#endif  // HAVE_LIBSHP_SHAPEFIL_H
+#endif  // HAVE_SHAPEFIL_H
+
+typedef struct _shpinfo{
+    char *filename;
+    struct Node* root;
+    time_t creation;
+    time_t last_access;
+    int num_accesses;
+}shpinfo;
+
+void init_shp_hash(int clobber);
+void add_shp_to_hash(char *filename,SHPHandle sHP);
+void build_rtree(struct Node **root, SHPHandle sHP);
+void destroy_shp_hash(void);
+void empty_shpinfo(shpinfo *si);
+void destroy_shpinfo(shpinfo *si);
+void purge_shp_hash(time_t secs_now);
+shpinfo *get_shp_from_hash(char *filename);
+
+#endif // USE_RTREE
+#endif // __XASTIR_SHP_HASH_H
diff --git a/src/snprintf.c b/src/snprintf.c
new file mode 100644
index 0000000..793b619
--- /dev/null
+++ b/src/snprintf.c
@@ -0,0 +1,747 @@
+/*
+ * snprintf.c - a portable implementation of snprintf and vsnprintf
+ *
+ * $Id: snprintf.c,v 1.14 2012/08/25 16:38:29 tvrusso Exp $
+ */
+/*
+ * Portions Copyright (C) 2000-2012 The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell (papowell at astart.com)
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions
+ */
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long <blong at fiction.net> 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long <blong at fiction.net> 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ *
+ *  Thomas Roessler <roessler at guug.de> 01/27/98 for mutt 0.89i
+ *    The PGP code was using unsigned hexadecimal formats.
+ *    Unfortunately, unsigned formats simply didn't work.
+ *
+ *  Michael Elkins <me at cs.hmc.edu> 03/05/98 for mutt 0.90.8
+ *    The original code assumed that both snprintf() and vsnprintf() were
+ *    missing.  Some systems only have snprintf() but not vsnprintf(), so
+ *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
+ *
+ *  Andrew Tridgell (tridge at samba.org) Oct 1998
+ *    fixed handling of %.0f
+ *    added test for HAVE_LONG_DOUBLE
+ *
+ *
+ **************************************************************/
+
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#ifndef HAVE_VSNPRINTF
+
+/* varargs declarations: */
+
+#if defined(__STDC__)
+#  ifdef HAVE_STDARG_H
+#    include <stdarg.h>
+#  else // HAVE_STDARG_H
+#    ifdef HAVE_STD_ARGS_H
+#      include <std_args.h>
+#    endif  // HAVE_STD_ARGS_H
+#  endif    // HAVE_STDARG_H
+#  include <stdarg.h>
+#  define HAVE_STDARGS  /* let's hope that works everywhere (mj) */
+#  define VA_LOCAL_DECL va_list ap
+#  define VA_START(f) va_start(ap, f)
+#  define VA_SHIFT(v,t); /* no-op for ANSI */
+#  define VA_END va_end(ap)
+#else   // __STDC__
+#  include <varargs.h>
+#  undef HAVE_STDARGS
+#  define VA_LOCAL_DECL va_list ap
+#  define VA_START(f) va_start(ap)      /* f is ignored! */
+#  define VA_SHIFT(v,t) v = va_arg(ap,t)
+#  define VA_END va_end(ap)
+#endif  // __STDC__
+
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#ifdef HAVE_LONG_DOUBLE
+#define LDOUBLE long double
+#else   // HAVE_LONG_DOUBLE
+#define LDOUBLE double
+#endif  // HAVE_LONG_DOUBLE
+
+static void dopr(char *buffer, size_t maxlen, const char *format, va_list args);
+static void fmtstr(char *buffer, size_t * currlen, size_t maxlen, char *value,
+        int flags, int min, int max);
+static void fmtint(char *buffer, size_t * currlen, size_t maxlen, long value,
+        int base, int min, int max, int flags);
+static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
+        LDOUBLE fvalue, int min, int max, int flags);
+static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen, char c);
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS      (1 << 0)
+#define DP_F_PLUS       (1 << 1)
+#define DP_F_SPACE      (1 << 2)
+#define DP_F_NUM        (1 << 3)
+#define DP_F_ZERO       (1 << 4)
+#define DP_F_UP         (1 << 5)
+#define DP_F_UNSIGNED   (1 << 6)
+
+/* Conversion Flags */
+#define DP_C_SHORT   1
+#define DP_C_LONG    2
+#define DP_C_LDOUBLE 3
+
+#define char_to_int(p) (p - '0')
+#define MAX(p, q) ((p >= q) ? p : q)
+
+static void dopr(char *buffer, size_t maxlen, const char *format, va_list args) {
+    char ch;
+    long value;
+    LDOUBLE fvalue;
+    char *strvalue;
+    int min;
+    int max;
+    int state;
+    int flags;
+    int cflags;
+    size_t currlen;
+
+    state = DP_S_DEFAULT;
+    currlen = flags = cflags = min = 0;
+    max = -1;
+    ch = *format++;
+
+    while (state != DP_S_DONE) {
+        if ((ch == '\0') || (currlen >= maxlen))
+            state = DP_S_DONE;
+
+        switch (state) {
+            case DP_S_DEFAULT:
+                if (ch == '%')
+                    state = DP_S_FLAGS;
+                else
+                    dopr_outch(buffer, &currlen, maxlen, ch);
+
+                ch = *format++;
+                break;
+            case DP_S_FLAGS:
+                switch (ch) {
+                    case '-':
+                        flags |= DP_F_MINUS;
+                        ch = *format++;
+                        break;
+                    case '+':
+                        flags |= DP_F_PLUS;
+                        ch = *format++;
+                        break;
+                    case ' ':
+                        flags |= DP_F_SPACE;
+                        ch = *format++;
+                        break;
+                    case '#':
+                        flags |= DP_F_NUM;
+                        ch = *format++;
+                        break;
+                    case '0':
+                        flags |= DP_F_ZERO;
+                        ch = *format++;
+                        break;
+                    default:
+                        state = DP_S_MIN;
+                        break;
+                }
+                break;
+            case DP_S_MIN:
+                if (isdigit(ch)) {
+                    min = 10 * min + char_to_int(ch);
+                    ch = *format++;
+                } else if (ch == '*') {
+                    min = va_arg(args, int);
+                    ch = *format++;
+                    state = DP_S_DOT;
+                } else
+                    state = DP_S_DOT;
+
+                break;
+            case DP_S_DOT:
+                if (ch == '.') {
+                    state = DP_S_MAX;
+                    ch = *format++;
+                } else
+                    state = DP_S_MOD;
+
+                break;
+            case DP_S_MAX:
+                if (isdigit(ch)) {
+                    if (max < 0)
+                        max = 0;
+
+                    max = 10 * max + char_to_int(ch);
+                    ch = *format++;
+                } else if (ch == '*') {
+                    max = va_arg(args, int);
+                    ch = *format++;
+                    state = DP_S_MOD;
+                } else
+                    state = DP_S_MOD;
+
+                break;
+            case DP_S_MOD:
+                /* Currently, we don't support Long Long, bummer */
+                switch (ch) {
+                    case 'h':
+                        cflags = DP_C_SHORT;
+                        ch = *format++;
+                        break;
+                    case 'l':
+                        cflags = DP_C_LONG;
+                        ch = *format++;
+                        break;
+                    case 'L':
+                        cflags = DP_C_LDOUBLE;
+                        ch = *format++;
+                        break;
+                    default:
+                        break;
+                }
+                state = DP_S_CONV;
+                break;
+            case DP_S_CONV:
+                switch (ch) {
+                    case 'd':
+                    case 'i':
+                        if (cflags == DP_C_SHORT)
+                            value = va_arg(args, short int);
+                        else if (cflags == DP_C_LONG)
+                            value = va_arg(args, long int);
+                        else
+                            value = va_arg(args, int);
+
+                        fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+                        break;
+                    case 'o':
+                        flags |= DP_F_UNSIGNED;
+                        if (cflags == DP_C_SHORT)
+                            value = va_arg(args, unsigned short int);
+                        else if (cflags == DP_C_LONG)
+                            value = va_arg(args, unsigned long int);
+                        else
+                            value = va_arg(args, unsigned int);
+
+                        fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
+                        break;
+                    case 'u':
+                        flags |= DP_F_UNSIGNED;
+                        if (cflags == DP_C_SHORT)
+                            value = va_arg(args, unsigned short int);
+                        else if (cflags == DP_C_LONG)
+                            value = va_arg(args, unsigned long int);
+                        else
+                            value = va_arg(args, unsigned int);
+
+                        fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+                        break;
+                    case 'X':
+                        flags |= DP_F_UP;
+                    case 'x':
+                        flags |= DP_F_UNSIGNED;
+                        if (cflags == DP_C_SHORT)
+                            value = va_arg(args, unsigned short int);
+                        else if (cflags == DP_C_LONG)
+                            value = va_arg(args, unsigned long int);
+                        else
+                            value = va_arg(args, unsigned int);
+
+                        fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
+                        break;
+                    case 'f':
+                        if (cflags == DP_C_LDOUBLE)
+                            fvalue = va_arg(args, LDOUBLE);
+                        else
+                            fvalue = va_arg(args, double);
+
+                        /* um, floating point? */
+                        fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
+                        break;
+                    case 'E':
+                        flags |= DP_F_UP;
+                    case 'e':
+                        if (cflags == DP_C_LDOUBLE)
+                            fvalue = va_arg(args, LDOUBLE);
+                        else
+                            fvalue = va_arg(args, double);
+                        break;
+                    case 'G':
+                        flags |= DP_F_UP;
+                    case 'g':
+                        if (cflags == DP_C_LDOUBLE)
+                            fvalue = va_arg(args, LDOUBLE);
+                        else
+                            fvalue = va_arg(args, double);
+
+                        break;
+                    case 'c':
+                        dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
+                        break;
+                    case 's':
+                        strvalue = va_arg(args, char *);
+                        if (max < 0)
+                            max = maxlen; /* ie, no max */
+
+                        fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
+                        break;
+                    case 'p':
+                        strvalue = va_arg(args, void *);
+                        fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min,
+                                max, flags);
+                        break;
+                    case 'n':
+                        if (cflags == DP_C_SHORT) {
+                            short int *num;
+                            num = va_arg(args, short int *);
+                            *num = currlen;
+                        } else if (cflags == DP_C_LONG) {
+                            long int *num;
+                            num = va_arg(args, long int *);
+                            *num = currlen;
+                        } else {
+                            int *num;
+                            num = va_arg(args, int *);
+                            *num = currlen;
+                        }
+                        break;
+                    case '%':
+                        dopr_outch(buffer, &currlen, maxlen, ch);
+                        break;
+                    case 'w':
+                        /* not supported yet, treat as next char */
+                        ch = *format++;
+                        break;
+                    default:
+                        /* Unknown, skip */
+                        break;
+                }
+                ch = *format++;
+                state = DP_S_DEFAULT;
+                flags = cflags = min = 0;
+                max = -1;
+                break;
+            case DP_S_DONE:
+                break;
+            default:
+                /* hmm? */
+                break;  /* some picky compilers need this */
+        }
+    }
+    if (currlen < maxlen - 1)
+        buffer[currlen] = '\0';
+    else
+        buffer[maxlen - 1] = '\0';
+}
+
+static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
+        char *value, int flags, int min, int max)
+{
+    int padlen, strln; /* amount to pad */
+    int cnt = 0;
+
+    if (value == 0) {
+        value = "<NULL>";
+    }
+
+    for (strln = 0; value[strln]; ++strln); /* strlen */
+    padlen = min - strln;
+    if (padlen < 0)
+        padlen = 0;
+
+    if (flags & DP_F_MINUS)
+        padlen = -padlen;   /* Left Justify */
+
+    while ((padlen > 0) && (cnt < max)) {
+        dopr_outch(buffer, currlen, maxlen, ' ');
+        --padlen;
+        ++cnt;
+    }
+
+    while (*value && (cnt < max)) {
+        dopr_outch(buffer, currlen, maxlen, *value++);
+        ++cnt;
+    }
+
+    while ((padlen < 0) && (cnt < max)) {
+        dopr_outch(buffer, currlen, maxlen, ' ');
+        ++padlen;
+        ++cnt;
+    }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
+        long value, int base, int min, int max, int flags)
+{
+    int signvalue = 0;
+    unsigned long uvalue;
+    char convert[20];
+    int place = 0;
+    int spadlen = 0; /* amount to space pad */
+    int zpadlen = 0; /* amount to zero pad */
+    int caps = 0;
+
+    if (max < 0)
+        max = 0;
+
+    uvalue = value;
+
+    if (!(flags & DP_F_UNSIGNED)) {
+        if (value < 0) {
+            signvalue = '-';
+            uvalue = -value;
+        } else if (flags & DP_F_PLUS)   /* Do a sign (+/i) */
+            signvalue = '+';
+        else if (flags & DP_F_SPACE)
+            signvalue = ' ';
+    }
+
+    if (flags & DP_F_UP)
+        caps = 1;   /* Should characters be upper case? */
+
+    do {
+        convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                [uvalue % (unsigned) base];
+
+        uvalue = (uvalue / (unsigned) base);
+    }
+
+    while (uvalue && (place < 20));
+    if (place == 20)
+        place--;
+
+    convert[place] = 0;
+
+    zpadlen = max - place;
+    spadlen = min - MAX(max, place) - (signvalue ? 1 : 0);
+
+    if (zpadlen < 0)
+        zpadlen = 0;
+
+    if (spadlen < 0)
+        spadlen = 0;
+
+    if (flags & DP_F_ZERO) {
+        zpadlen = MAX(zpadlen, spadlen);
+        spadlen = 0;
+    }
+
+    if (flags & DP_F_MINUS)
+        spadlen = -spadlen; /* Left Justifty */
+
+#ifdef DEBUG_SNPRINTF
+    dprint(1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
+            zpadlen, spadlen, min, max, place));
+#endif  // DEBUG_SNPRINTF
+
+    /* Spaces */
+    while (spadlen > 0) {
+        dopr_outch(buffer, currlen, maxlen, ' ');
+        --spadlen;
+    }
+
+    /* Sign */
+    if (signvalue)
+        dopr_outch(buffer, currlen, maxlen, signvalue);
+
+    /* Zeros */
+    if (zpadlen > 0) {
+        while (zpadlen > 0) {
+            dopr_outch(buffer, currlen, maxlen, '0');
+            --zpadlen;
+        }
+    }
+
+    /* Digits */
+    while (place > 0)
+        dopr_outch(buffer, currlen, maxlen, convert[--place]);
+
+    /* Left Justified spaces */
+    while (spadlen < 0) {
+        dopr_outch(buffer, currlen, maxlen, ' ');
+        ++spadlen;
+    }
+}
+
+static LDOUBLE abs_val(LDOUBLE value) {
+  LDOUBLE result = value;
+
+    if (value < 0)
+        result = -value;
+
+    return result;
+}
+
+static LDOUBLE pow10(int exp) {
+    LDOUBLE result = 1;
+
+    while (exp) {
+        result *= 10;
+        exp--;
+    }
+
+    return result;
+}
+
+static long round(LDOUBLE value) {
+    long intpart;
+
+    intpart = value;
+    value = value - intpart;
+    if (value >= 0.5)
+        intpart++;
+
+    return intpart;
+}
+
+static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
+        LDOUBLE fvalue, int min, int max, int flags)
+{
+    int signvalue = 0;
+    LDOUBLE ufvalue;
+    char iconvert[20];
+    char fconvert[20];
+    int iplace = 0;
+    int fplace = 0;
+    int padlen = 0; /* amount to pad */
+    int zpadlen = 0;
+    int caps = 0;
+    long intpart;
+    long fracpart;
+
+    /*
+    * AIX manpage says the default is 0, but Solaris says the default
+    * is 6, and sprintf on AIX defaults to 6
+    */
+    if (max < 0)
+        max = 6;
+
+    ufvalue = abs_val(fvalue);
+
+    if (fvalue < 0)
+        signvalue = '-';
+    else if (flags & DP_F_PLUS) /* Do a sign (+/i) */
+        signvalue = '+';
+    else if (flags & DP_F_SPACE)
+        signvalue = ' ';
+
+#if 0
+    if (flags & DP_F_UP)
+        caps = 1; /* Should characters be upper case? */
+#endif  // 0
+
+    intpart = ufvalue;
+
+    /*
+    * Sorry, we only support 9 digits past the decimal because of our
+    * conversion method
+    */
+    if (max > 9)
+        max = 9;
+
+    /* We "cheat" by converting the fractional part to integer by
+    * multiplying by a factor of 10
+    */
+    fracpart = round((pow10(max)) * (ufvalue - intpart));
+
+    if (fracpart >= pow10(max)) {
+        intpart++;
+        fracpart -= pow10(max);
+    }
+
+    /* Convert integer part */
+    do {
+        iconvert[iplace++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10];
+        intpart = (intpart / 10);
+    } while (intpart && (iplace < 20));
+
+    if (iplace == 20)
+        iplace--;
+
+    iconvert[iplace] = 0;
+
+    /* Convert fractional part */
+    do {
+        fconvert[fplace++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10];
+        fracpart = (fracpart / 10);
+    } while (fracpart && (fplace < 20));
+
+    if (fplace == 20)
+        fplace--;
+
+    fconvert[fplace] = 0;
+
+    /* -1 for decimal point, another -1 if we are printing a sign */
+    padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
+    zpadlen = max - fplace;
+
+    if (zpadlen < 0)
+        zpadlen = 0;
+
+    if (padlen < 0)
+        padlen = 0;
+
+    if (flags & DP_F_MINUS)
+        padlen = -padlen; /* Left Justifty */
+
+    if ((flags & DP_F_ZERO) && (padlen > 0)) {
+        if (signvalue) {
+            dopr_outch(buffer, currlen, maxlen, signvalue);
+            --padlen;
+            signvalue = 0;
+        }
+        while (padlen > 0) {
+            dopr_outch(buffer, currlen, maxlen, '0');
+            --padlen;
+        }
+    }
+
+    while (padlen > 0) {
+        dopr_outch(buffer, currlen, maxlen, ' ');
+        --padlen;
+    }
+
+    if (signvalue)
+        dopr_outch(buffer, currlen, maxlen, signvalue);
+
+    while (iplace > 0)
+        dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
+
+    /*
+    * Decimal point.  This should probably use locale to find the correct
+    * char to print out.
+    */
+    if (max > 0) {
+        dopr_outch(buffer, currlen, maxlen, '.');
+
+        while (fplace > 0)
+            dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
+    }
+
+    while (zpadlen > 0) {
+        dopr_outch(buffer, currlen, maxlen, '0');
+        --zpadlen;
+    }
+
+    while (padlen < 0) {
+        dopr_outch(buffer, currlen, maxlen, ' ');
+        ++padlen;
+    }
+}
+
+static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen, char c) {
+    if (*currlen < maxlen)
+        buffer[(*currlen)++] = c;
+}
+
+int xastir_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+    str[0] = 0;
+    dopr(str, count, fmt, args);
+    return (strlen(str));
+}
+#endif /* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+#  ifdef HAVE_STDARGS
+int xastir_snprintf(char *str, size_t count, const char *fmt, ...)
+#  else // HAVE_STDARGS
+int xastir_snprintf(va_alist) va_dcl
+#  endif    // HAVE_STDARGS
+{
+#  ifndef HAVE_STDARGS
+    char *str;
+    size_t count;
+    char *fmt;
+#  endif    // HAVE_STDARGS
+    VA_LOCAL_DECL;
+
+    VA_START(fmt);
+    VA_SHIFT(str, char *);
+    VA_SHIFT(count, size_t);
+    VA_SHIFT(fmt, char *);
+    (void) xastir_vsnprintf(str, count, fmt, ap);
+    VA_END;
+    return (strlen(str));
+}
+#endif /* !HAVE_SNPRINTF */
+
+
diff --git a/src/snprintf.h b/src/snprintf.h
new file mode 100644
index 0000000..00b6457
--- /dev/null
+++ b/src/snprintf.h
@@ -0,0 +1,59 @@
+/*
+ * snprintf.h
+ *   header file for snprintf.c
+ *
+ * $Id: snprintf.h,v 1.14 2012/11/01 18:57:19 we7u Exp $
+ */
+/*
+ * Copyright (C) 2000-2012 The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _XASTIR_COMPAT_SNPRINTF_H_
+#define _XASTIR_COMPAT_SNPRINTF_H_
+
+#include <stdio.h>
+#include "config.h"
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif  // HAVE_STDARG_H
+
+/* Use the system libraries version of vsnprintf() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_VSNPRINTF
+int xastir_vsnprintf(char *str, size_t count, const char *fmt, va_list ap);
+#else   // HAVE_VSNPRINTF
+#  define xastir_vsnprintf vsnprintf
+#endif  // HAVE_VSNPRINTF
+
+/* Use the system libraries version of snprintf() if available. Otherwise
+ * use our own.
+ */
+#ifndef HAVE_SNPRINTF
+  #ifdef __STDC__
+    int xastir_snprintf(char *str, size_t count, const char *fmt, ...);
+  #else // __STDC__
+    int xastir_snprintf();
+  #endif    // __STDC__
+#else   // HAVE_SNPRINTF
+  #define xastir_snprintf snprintf
+#endif  // HAVE_SNPRINTF
+
+#endif  /* !XASTIR_COMPAT_SNPRINTF_H_ */
+
+
diff --git a/src/sound.c b/src/sound.c
new file mode 100644
index 0000000..693c0da
--- /dev/null
+++ b/src/sound.c
@@ -0,0 +1,124 @@
+/*
+ * $Id: sound.c,v 1.22 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#include "xastir.h"
+#include "main.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+pid_t play_sound(char *sound_cmd, char *soundfile) {
+    pid_t sound_pid;
+    char command[600];
+
+    sound_pid=0;
+    if (strlen(sound_cmd)>3 && strlen(soundfile)>1) {
+        if (last_sound_pid==0) {
+
+            // Create a new process to run in
+            sound_pid = fork();
+            if (sound_pid!=-1) {
+                if(sound_pid==0) {
+// This is the child process
+
+
+                    // Go back to default signal handler instead of
+                    // calling restart() on SIGHUP
+                    (void) signal(SIGHUP,SIG_DFL);
+
+
+                    // Change the name of the new child process.  So
+                    // far this only works for "ps" listings, not
+                    // for "top".  This code only works on Linux.
+                    // For BSD use setproctitle(3), NetBSD can use
+                    // setprogname(2).
+#ifdef __linux__
+                    init_set_proc_title(my_argc, my_argv, my_envp);
+                    set_proc_title("%s", "festival process (xastir)");
+                    //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
+#endif  // __linux__
+
+
+                    xastir_snprintf(command,
+                        sizeof(command),
+                        "%s %s/%s",
+                        sound_cmd,
+                        SOUND_DIR,
+                        soundfile);
+
+                    (void)system(command);  // Note we're not caring about whether it succeeded or not
+                    exit(0);    // Exits only this process, not Xastir itself
+                }
+                else {
+// This is the parent process
+                    last_sound_pid=sound_pid;
+                }
+            } else
+                fprintf(stderr,"Error! trying to play sound\n");
+        } else {
+            sound_pid=last_sound_pid;
+            /*fprintf(stderr,"Sound already running\n");*/
+        }
+    }
+    return(sound_pid);
+}
+
+
+
+
+
+int sound_done(void) {
+    int done;
+    int *status;
+
+    status=NULL;
+    done=0;
+    if(last_sound_pid!=0) {
+        if(waitpid(last_sound_pid,status,WNOHANG)==last_sound_pid) {
+            done=1;
+            last_sound_pid=0;
+        }
+    }
+    return(done);
+}
+
+
diff --git a/src/symbols.h b/src/symbols.h
new file mode 100644
index 0000000..502b3de
--- /dev/null
+++ b/src/symbols.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: symbols.h,v 1.10 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef XASTIR_SYMBOLS_H
+#define XASTIR_SYMBOLS_H
+
+/* define Symbol Active */
+
+
+
+#endif /* XASTIR_SYMBOLS_H */
+
diff --git a/src/testdbfawk.c b/src/testdbfawk.c
new file mode 100644
index 0000000..3b12307
--- /dev/null
+++ b/src/testdbfawk.c
@@ -0,0 +1,282 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: testdbfawk.c,v 1.6 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifdef WITH_DBFAWK
+
+#ifdef HAVE_SHAPEFIL_H
+#include <shapefil.h>
+#else
+#ifdef HAVE_LIBSHP_SHAPEFIL_H
+#include <libshp/shapefil.h>
+#else
+#error HAVE_LIBSHP defined but no corresponding include defined
+#endif // HAVE_LIBSHP_SHAPEFIL_H
+#endif // HAVE_SHAPEFIL_H
+
+#include <ctype.h>
+#include <sys/types.h>
+#include "awk.h"
+#include "dbfawk.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+/*
+ * Sample test program
+ */
+
+void die(const char *s) {
+    fprintf(stderr,"%s\n",s);
+    exit(1);
+}
+
+
+
+
+
+/*
+ * print_symtbl: debugging
+ */
+void print_symtbl(awk_symtab *this) {
+    awk_symbol *s;
+    char buf[1024];
+    int len;
+    int i;
+
+//    fprintf(stderr,"symtbl 0%0x dump:\n",(u_int)this);
+    fprintf(stderr,"symtbl 0x%0lx dump:\n",
+        (uintptr_t)this);
+    for (i = 0; i < AWK_SYMTAB_HASH_SIZE; i++) {
+      for (s = this->hash[i]; s; s = s->next_sym) {
+        *buf = '\0';
+        awk_get_sym(s,buf,sizeof(buf),&len);
+        fprintf(stderr,"%d  %s = '%.*s'\n",i,s->name,len,buf);
+      }
+    }
+}
+
+
+
+
+
+awk_rule rules[] = {
+    { 0, BEGIN, NULL, NULL, 0, 0, "key=\"\"; lanes=1; color=8; name=\"\"; filled=0; pattern=1; display_level=8192; label_level=32",0 ,0 },
+    { 0, REGEXP, "^TLID=(.*)$", NULL, 0, 0, "key=\"$1\"",0,0  },
+    { 0, REGEXP, "^FENAME=United States Highway (.*)$", NULL, 0, 0, "name=\"US $1\"; next",0,0  },
+    { 0, REGEXP, "^FENAME=(.*)$", NULL, 0, 0, "name=\"$1\"; next",0,0  },
+    { 0, REGEXP, "^CFCC=A1", NULL, 0, 0, "lanes=4; color=4; next",0,0  },
+    { 0, REGEXP, "^CFCC=A3", NULL, 0, 0, "lanes=2; color=8",0,0  },
+    { 0, REGEXP, "^CFCC=A3[1-6]", NULL, 0, 0, "display_level=256; next",0,0  },
+};
+
+
+
+
+
+int nrules = sizeof(rules)/sizeof(rules[0]);
+
+void usage(void) {
+  fprintf(stderr,"Usage: testdbfawk [-f file.awk| -D dir] -d file.dbf\n");
+  fprintf(stderr," -D for dir containing *.dbfawk files.\n");
+  fprintf(stderr," or -f for file containing awk rules.\n");
+  fprintf(stderr," -d for dbf file to parse \n");
+}
+
+
+
+
+
+int debug = 0;
+
+
+
+
+
+int main(int argc, char *argv[]) {
+    awk_program *rs = NULL;
+    //    int args;
+    awk_symtab *symtbl;
+    /* variables to bind to: */
+    int color;
+    int lanes;
+    int font_size;
+    char dbfinfo[1024];		/* list of DBF field names */
+    char dbffields[1024];	/* subset we want to read */
+    char name[128];
+    char key[128];
+    char symbol[4];
+    int filled = 5;
+    int pattern=0;
+    int display_level = 1234;
+    int label_level = 9;
+    int label_color = 8;
+    char *dir = NULL,*file = NULL,*dfile = NULL;
+    dbfawk_sig_info *si = NULL, *sigs = NULL;
+
+// Allocates new memory!
+    symtbl = awk_new_symtab();
+    if (argc >= 2 && (strcmp(argv[1],"--help") == 0 || strcmp(argv[1],"-?") == 0)) {
+      usage();
+      exit(1);
+    }
+    if (argc > 2 && strcmp(argv[1],"-D") == 0) {
+      dir = argv[2];
+      argv++; argv++;
+      argc -= 2;
+      sigs = dbfawk_load_sigs(dir,".dbfawk");
+      if (!sigs) 
+	die("Couldn't find dbfawk sigs\n");
+    } else if (argc > 2 && strcmp(argv[1],"-f") == 0) {
+      file = argv[2];
+      argv++; argv++;
+      argc -= 2;
+      rs = awk_load_program_file(file); /* load up the program */
+    } else 
+      rs = awk_load_program_array(rules,nrules); /* load up the program */
+    if (argc > 2 && strcmp(argv[1],"-d") == 0) {
+      dfile = argv[2];
+      argv++; argv++;
+      argc -= 2;
+    }
+
+    /* declare/bind these symbols */
+// Allocates new memory!
+    awk_declare_sym(symtbl,"dbfinfo",STRING,dbfinfo,sizeof(dbfinfo));
+    awk_declare_sym(symtbl,"dbffields",STRING,dbffields,sizeof(dbffields));
+    awk_declare_sym(symtbl,"color",INT,&color,sizeof(color));
+    awk_declare_sym(symtbl,"lanes",INT,&lanes,sizeof(lanes));
+    awk_declare_sym(symtbl,"name",STRING,name,sizeof(name));
+    awk_declare_sym(symtbl,"key",STRING,key,sizeof(key));
+    awk_declare_sym(symtbl,"symbol",STRING,symbol,sizeof(symbol));
+    awk_declare_sym(symtbl,"filled",INT,&filled,sizeof(filled));
+    awk_declare_sym(symtbl,"pattern",INT,&pattern,sizeof(pattern));
+    awk_declare_sym(symtbl,"display_level",INT,&display_level,sizeof(display_level));
+    awk_declare_sym(symtbl,"label_level",INT,&label_level,sizeof(label_level));
+    awk_declare_sym(symtbl,"label_color",INT,&label_color,sizeof(label_color));
+    awk_declare_sym(symtbl,"font_size",INT,&font_size,sizeof(font_size));
+
+    if (dfile) {		/* parse dbf file */
+      DBFHandle dbf = DBFOpen(dfile,"rb");
+      int i;
+      char sig[sizeof(dbfinfo)]; /* write the signature here */
+      int nf;
+      dbfawk_field_info *fi;
+
+      if (!dbf)
+	die("DBFopen");
+
+      nf = dbfawk_sig(dbf,sig,sizeof(sig));
+      fprintf(stderr,"%d Columns,  %d Records in file\n",nf,
+	      DBFGetRecordCount(dbf));
+      fprintf(stderr,"sig: %s\n",sig);
+
+      /* If -D then search for matching sig; else use the supplied awk_prog */
+      if (sigs) {
+	si = dbfawk_find_sig(sigs,sig,dfile);
+	if (!si)
+	  die("No matching dbfawk signature found");
+	rs = si->prog;
+      }
+      if (awk_compile_program(symtbl,rs) < 0) {
+        die("couldn't compile rules");
+      }
+      
+      awk_exec_begin(rs);		/* execute a BEGIN rule if any */
+      //    print_symtbl(symtbl);
+
+      if (strcmp(sig,dbfinfo) == 0) {
+	fprintf(stderr,"DBF Signatures match!\n");
+      } else {
+	fprintf(stderr,"DBF Signatures DON'T match\n");
+      }
+      fi = dbfawk_field_list(dbf, dbffields);
+      /* now actually read the whole file */
+      for (i = 0; i < DBFGetRecordCount(dbf); i++ ) {
+	dbfawk_parse_record(rs,dbf,fi,i);
+	fprintf(stderr,"name=%s, ",name);
+	fprintf(stderr,"key=%s, ",key);
+	fprintf(stderr,"symbol=%s, ",symbol);
+	fprintf(stderr,"color=%d, ", color);
+	fprintf(stderr,"lanes=%d, ", lanes);
+	fprintf(stderr,"filled=%d, ",filled);
+	fprintf(stderr,"pattern=%d, ",pattern);
+	fprintf(stderr,"display_level=%d, ",display_level);
+	fprintf(stderr,"font_size=%d, ", font_size);
+	fprintf(stderr,"label_level=%d\n",label_level);
+	fprintf(stderr,"label_color=%d\n",label_color);
+	//	print_symtbl(symtbl);
+      }
+      DBFClose(dbf);
+    } else {			/* use cmdline args */
+        usage();
+        exit(1);
+        /*
+         * remove this capability because it leads to
+         * segfaults if user gives invalid command line arguments.
+         * better to just print usage string 
+      awk_exec_begin_record(rs);
+      for (args = 1; args < argc; args++) {
+	fprintf(stderr,"==> %s\n",argv[args]);
+        awk_exec_program(rs,argv[args],strlen(argv[args]));
+	// print_symtbl(symtbl);
+      }
+      awk_exec_end_record(rs);
+        */
+    }
+    awk_exec_end(rs);		/* execute an END rule if any */
+    //    print_symtbl(symtbl);
+    if (si)
+      dbfawk_free_sigs(si);
+    else if (rs)
+      awk_free_program(rs);
+    awk_free_symtab(symtbl);
+    exit(0);
+}
+#else /* !WITH_DBFAWK */
+
+
+
+
+
+int main(int argc, char *argv[]) {
+  fprintf(stderr,"DBFAWK support not compiled.\n");
+  exit(1);
+}
+#endif /* !WITH_DBFAWK */
+
+
diff --git a/src/tile_mgmnt.c b/src/tile_mgmnt.c
new file mode 100644
index 0000000..b628a2b
--- /dev/null
+++ b/src/tile_mgmnt.c
@@ -0,0 +1,355 @@
+/*
+ * $Id: tile_mgmnt.c,v 1.5 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <errno.h>
+
+#include "xastir.h"
+#include "fetch_remote.h"
+#include "util.h"
+#include "snprintf.h"
+#include "maps.h"
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif // HAVE_LIBCURL
+
+#include "tile_mgmnt.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+// OSM Minimum cache time
+#define SECONDS_7_DAYS (7 * 24 * 3600)
+
+/*
+ * latLon2tileNum - calculate tile number
+ *
+ * The tile number is returned in in the structure pointed to by the
+ * tilenum argument.
+ */
+void latLon2tileNum (double lon_deg,
+        double lat_deg,
+        int zoom,
+        tileNum_t *tilenum) {
+    unsigned long ntiles;
+    double lat_rad;
+    ntiles = 1 << zoom;
+
+    if (lat_deg > MAX_LAT_OSM) {
+        lat_deg = MAX_LAT_OSM;
+    }
+    else if (lat_deg < (-1.0 * MAX_LAT_OSM)) {
+        lat_deg = -1.0 * MAX_LAT_OSM;
+    }
+
+    if (lon_deg > MAX_LON_OSM) {
+        lon_deg = MAX_LON_OSM;
+    }
+    else if (lon_deg < (-1.0 * MAX_LON_OSM)) {
+        lon_deg = -1.0 * MAX_LON_OSM;
+    }
+
+    lat_rad = (lat_deg * M_PI) / 180.0;
+
+    tilenum->x = ((lon_deg + 180.0) / 360.0) * ntiles;
+    tilenum->y = ((1 - (log(tan(lat_rad)
+                            + (1.0 / cos(lat_rad))) / M_PI)) / 2.0) * ntiles;
+
+    if (tilenum->y >= ntiles) {
+        tilenum->y = (ntiles - 1);
+    }
+
+    if (tilenum->x >= ntiles) {
+        tilenum->x = (ntiles - 1);
+    }
+
+    return;
+
+} // latLon2tileNum()
+
+
+/*
+ * tile2coord - calculate lat/lon of NW corner of tile
+ *
+ * Use tilex+1 and tiley+1 to get the coordinates of the SE corner.
+ *
+ * Based on example code at
+ * http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
+ *
+ */
+void tile2coord (unsigned long tilex,
+        unsigned long tiley,
+        int zoom,
+        coord_t *NWcorner) {
+    unsigned long ntiles;
+    double lat_rad;
+
+    ntiles = 1 << zoom;
+    lat_rad = M_PI - ((2.0 * M_PI) * ((double)(tiley) / (double)ntiles));
+    NWcorner->lat = (180.0 / M_PI) * atan(0.5 * (exp((double)lat_rad) - exp(-1.0 * (double)lat_rad)));
+
+    NWcorner->lon = (((double)(tilex) / (double)ntiles) * 360.0) - 180.0;
+
+    return;
+
+} // tile2coord()
+
+/*
+ * calcTileArea - calculate the x and y range of tile numbers
+ *
+ * Returns the calculated values in the structure pointed to by the
+ * tiles argument.
+ */
+void calcTileArea (double lon_upper_left,
+        double lat_upper_left,
+        double lon_lower_right,
+        double lat_lower_right,
+        int zoom,
+        tileArea_t *tiles) {
+    tileNum_t tilenum;
+    latLon2tileNum(lon_upper_left, lat_upper_left, zoom, &tilenum);
+    tiles->startx = tilenum.x;
+    tiles->starty = tilenum.y;
+    latLon2tileNum(lon_lower_right, lat_lower_right, zoom, &tilenum);
+    tiles->endx = tilenum.x;
+    tiles->endy = tilenum.y;
+    return;
+
+} // calcTileArea()
+
+
+/*
+ * tilesMissing - return the count of tiles that are missing from the cache
+ */
+int tilesMissing (unsigned long startx,
+        unsigned long endx,
+        unsigned long starty,
+        unsigned long endy,
+        int zoom,
+        char *cacheDir,
+        char *tileExt) {
+    struct stat sb;
+    char local_filename[1100];
+    unsigned long x, y;
+    int numMissing = 0;
+
+    for (x = startx; x <= endx; x++) {
+        for (y = starty; y <= endy; y++) {
+
+            xastir_snprintf(local_filename, sizeof(local_filename),
+                    "%s/%u/%lu/%lu.%s", cacheDir, zoom, x, y, tileExt);
+
+            if (stat(local_filename, &sb) == -1) {
+                numMissing++;
+            }
+        }
+    }
+    return(numMissing);
+
+}  // end of tilesMissing()
+
+
+/*
+ * getOneTile - get one tile from the web
+ *
+ * The tile is fetched if it does not exist and 1 is returned.
+ *
+ * If the tile exists in the cache and it is older than 7 days, then it
+ * will be refreshed from the server.
+ *
+ * Returns 1 if a tile did not exist and download was attempted.
+ * Returns 0 if a tile exists in the cache (tile might be updated).
+ *
+ * Returns libcurl errors as a negative integer.
+ *
+ * WARNING: Download failures are not reported for wget.
+ *
+ */
+#ifdef HAVE_LIBCURL
+int getOneTile (CURL *session,
+        char *baseURL,
+        unsigned long x,
+        unsigned long y,
+        int zoom,
+        char *baseDir,
+        char *tileExt) {
+    CURLcode res;
+    time_t cacheTimeout;
+#else
+int getOneTile (char *baseURL,
+        unsigned long x,
+        unsigned long y,
+        int zoom,
+        char *baseDir,
+        char *tileExt) {
+#endif // HAVE_LIBCURL
+    
+    struct stat sb;
+    char url[1100];
+    char local_filename[1100];
+    int result = 0;
+
+    xastir_snprintf(url, sizeof(url), "%s/%u/%lu/%lu.%s", baseURL, zoom,
+            x, y, tileExt);
+    xastir_snprintf(local_filename, sizeof(local_filename),
+            "%s/%u/%lu/%lu.%s", baseDir, zoom, x, y, tileExt);
+
+    if (stat(local_filename, &sb) == -1) {
+        if (debug_level & 512) {
+            fprintf(stderr, "Fetching %s\n", url);
+        }
+        result = 1;  // only count files that do not exist
+
+#ifdef HAVE_LIBCURL
+        res = fetch_remote_tile(session, url, local_filename);
+
+    } else {
+
+        // Check for updated tiles after 7 days, per
+        // OSM Tile Usage Policy,
+        // http://wiki.openstreetmap.org/wiki/Tile_usage_policy,
+        // 2010/07/29
+        cacheTimeout = sb.st_mtime + SECONDS_7_DAYS;
+        if (cacheTimeout <= time(NULL)) {
+            // tile exists in the cache, but is older than 7 days, so
+            // check the server for a newer version.
+            if (debug_level & 512) {
+                fprintf(stderr, "Refreshing %s.\n", url);
+            }
+            res = fetch_remote_tile(session, url, local_filename);
+
+        } else {
+
+            if (debug_level & 512) {
+                fprintf(stderr, "Skipping- %s\n", url);
+                fprintf(stderr, "          because cache time has not expired.\n");
+                fprintf(stderr, "          cache expires %s",
+                        ctime(&cacheTimeout));
+            }
+
+            res = CURLE_OK;
+        }
+    }
+
+    if (CURLE_OK != res) {
+        // return the curl error as a negative value to distinqusih it
+        // successful values
+        result = -1 * (int)res;
+    }
+
+#else  // don't HAVE_LIBCURL
+        (void)fetch_remote_file(url, local_filename);
+    }
+#endif // HAVE_LIBCURL
+
+    return(result);
+
+} // getOneTile()
+
+
+/*
+ * mkpath() - attempt to make each directory in a path
+ */
+static void mkpath(const char *dir) {
+    char tmp[MAX_FILENAME];
+    char *p = NULL;
+    size_t len;
+
+    xastir_snprintf(tmp, sizeof(tmp),"%s", dir);
+    len = strlen(tmp);
+    if(tmp[len - 1] == '/') {
+        tmp[len - 1] = 0;
+    }
+
+    for (p = tmp + 1; *p; p++) {
+        if(*p == '/') {
+            *p = 0;
+            mkdir(tmp, S_IRWXU);
+            *p = '/';
+        }
+    }
+    mkdir(tmp, S_IRWXU);
+
+    return;
+}  // end of mkpath()
+
+
+/*
+ * mkOSMmapDirs - try to create all the directories needed for the tiles
+ *
+ * This is simply a best-effort attempt because there are valid reasons
+ * for mkdir() to fail. For example, the tiles could be buffered in a RO
+ * structure.
+ */
+void mkOSMmapDirs (char *baseDir,
+        unsigned long startx,
+        unsigned long endx,
+        int zoom) {
+    char fullPath[MAX_FILENAME];
+    char errmsg[1024];
+    struct stat sb;
+    unsigned long dnum;
+
+
+    xastir_snprintf(fullPath, sizeof(fullPath), "%s/%u/", baseDir, zoom);
+    mkpath(fullPath);
+
+    for (dnum = startx; dnum <= endx; dnum++) {
+        xastir_snprintf(fullPath, sizeof(fullPath), "%s/%u/%lu/",
+                baseDir, zoom, dnum);
+        mkdir(fullPath, S_IRWXU);
+
+        if (debug_level & 512) {
+            if (stat(fullPath, &sb) == -1) {
+#ifdef HAVE_POSIX_STRERROR_R
+                strerror_r(errno, errmsg, sizeof(errmsg));
+                fprintf(stderr, "%s: %s\n", errmsg, fullPath);
+#else
+                fprintf(stderr, "%s: %s\n",
+                        strerror_r(errno, errmsg, sizeof(errmsg)), fullPath);
+#endif
+            }
+            else if ((sb.st_mode & S_IWUSR) != S_IWUSR) {
+                fprintf(stderr, "warning: directory %s is not writable\n", fullPath);
+            }
+            else if (!S_ISDIR(sb.st_mode)) {
+                fprintf(stderr, "warning: %s is not a directory\n", fullPath);
+            }
+        }
+    }
+
+    return;
+} // mkOSMmapDirs()
+
+
diff --git a/src/tile_mgmnt.h b/src/tile_mgmnt.h
new file mode 100644
index 0000000..ea41985
--- /dev/null
+++ b/src/tile_mgmnt.h
@@ -0,0 +1,63 @@
+/*
+ * $Id: tile_mgmnt.h,v 1.4 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+#ifndef __TILE_MGMNT_H
+#define __TILE_MGMNT_H
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif // HAVE_LIBCURL
+
+typedef struct tileNum_s {
+    unsigned long x;
+    unsigned long y;
+} tileNum_t;
+
+typedef struct coord_s {
+    double lat;
+    double lon;
+} coord_t;
+
+typedef struct tileArea_s {
+    unsigned long startx;
+    unsigned long endx;
+    unsigned long starty;
+    unsigned long endy;
+} tileArea_t;
+
+#define MAX_LAT_OSM 85.0511
+#define MAX_LON_OSM 180.0
+
+void latLon2tileNum(double lon_deg, double lat_deg, int zoom, tileNum_t *tilenum);
+void tile2coord(unsigned long tilex, unsigned long tiley, int zoom, coord_t *NWcorner);
+void calcTileArea(double lon_upper_left,double lat_upper_left,double lon_lower_right,double lat_lower_right,int zoom,tileArea_t *tiles);
+
+#ifdef HAVE_LIBCURL
+int getOneTile(CURL *session, char *baseURL, unsigned long x, unsigned long y, int zoom, char *baseDir, char *tileExt);
+#else
+int getOneTile(char *baseURL, unsigned long x, unsigned long y, int zoom, char *baseDir, char *tileExt);
+#endif // HAVE_LIBCURL
+
+void mkOSMmapDirs(char *baseDir, unsigned long startx, unsigned long endx, int zoom);
+int tilesMissing (unsigned long startx, unsigned long endx, unsigned long starty, unsigned long endy, int zoom, char *baseDir, char *tileExt);
+
+#endif // __TILE_MGMNT_H
diff --git a/src/track_gui.c b/src/track_gui.c
new file mode 100644
index 0000000..abdc2cc
--- /dev/null
+++ b/src/track_gui.c
@@ -0,0 +1,1007 @@
+/*
+ * $Id: track_gui.c,v 1.77 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <Xm/XmAll.h>
+
+#include "xastir.h"
+#include "main.h"
+#include "lang.h"
+#include "objects.h"
+#include "popup.h"
+#include "fetch_remote.h"
+#include "util.h"
+#include "xa_config.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+Widget track_station_dialog = (Widget)NULL;
+Widget track_station_data = (Widget)NULL;
+Widget download_findu_dialog = (Widget)NULL;
+
+static xastir_mutex track_station_dialog_lock;
+static xastir_mutex download_findu_dialog_lock;
+
+// track values
+Widget track_case_data, track_match_data;
+
+// Download findu values
+Widget download_trail_station_data;
+Widget posit_start_value;
+Widget posit_length_value;
+
+int fetching_findu_trail_now = 0;
+
+int track_station_on = 0;       /* used for tracking stations */
+int track_me;
+int track_case;                 /* used for tracking stations */
+int track_match;                /* used for tracking stations */
+char tracking_station_call[30]; /* Tracking station callsign */
+char download_trail_station_call[30];   /* Trail station callsign */
+//N0VH
+#define MAX_FINDU_DURATION 120
+#define MAX_FINDU_START_TIME 336
+// Make these two match, as that will be the most desired case: Snag
+// the track for as far back as possible up to the present in one
+// shot...
+int posit_start = MAX_FINDU_DURATION;
+int posit_length = MAX_FINDU_DURATION;
+
+
+
+
+
+void track_gui_init(void)
+{
+    init_critical_section( &track_station_dialog_lock );
+    init_critical_section( &download_findu_dialog_lock );
+
+    if (temp_tracking_station_call[0] != '\0') {
+        xastir_snprintf(tracking_station_call,
+            sizeof(tracking_station_call),
+            "%s",
+            temp_tracking_station_call);
+        track_station_on = 1;
+    }
+    else {
+        tracking_station_call[0] = '\0';
+    }
+}
+
+
+
+
+
+/**** Track STATION ******/
+
+
+void track_station_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&track_station_dialog_lock, "track_gui.c:track_station_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    track_station_dialog = (Widget)NULL;
+
+end_critical_section(&track_station_dialog_lock, "track_gui.c:track_station_destroy_shell" );
+
+}
+
+
+
+
+
+void Track_station_clear(Widget w, XtPointer clientData, XtPointer callData) {
+
+    /* clear station */
+    track_station_on=0;
+    //track_station_data=NULL;
+    //tracking_station_call[0] = '\0';
+
+    // Clear the TrackMe button as well
+    XmToggleButtonSetState(trackme_button,FALSE,TRUE);
+
+    track_station_destroy_shell(w, clientData, callData);
+    display_zoom_status();
+}
+
+
+
+
+
+void Track_station_now(Widget w, XtPointer clientData, XtPointer callData) {
+    char temp[MAX_CALLSIGN+1];
+    char temp2[200];
+    int found = 0;
+    char *temp_ptr;
+
+
+    temp_ptr = XmTextFieldGetString(track_station_data);
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(temp);
+    (void)remove_trailing_dash_zero(temp);
+
+    xastir_snprintf(tracking_station_call,
+        sizeof(tracking_station_call),
+        "%s",
+        temp);
+    track_case  = (int)XmToggleButtonGetState(track_case_data);
+    track_match = (int)XmToggleButtonGetState(track_match_data);
+    found = locate_station(da, temp, track_case, track_match, 0);
+
+    if ( valid_object(tracking_station_call)    // Name of object is legal
+            || valid_call(tracking_station_call)
+            || valid_item(tracking_station_call ) ) {
+        track_station_on = 1;   // Track it whether we've seen it yet or not
+        if (!found) {
+            xastir_snprintf(temp2, sizeof(temp2), langcode("POPEM00026"), temp);
+            popup_message_always(langcode("POPEM00025"),temp2);
+        }
+        // Check for exact match, includes SSID
+        if ( track_me & !is_my_call( tracking_station_call, 1) ) {
+            XmToggleButtonSetState( trackme_button, FALSE, FALSE );
+            track_me = 0;
+        }
+    } else {
+        tracking_station_call[0] = '\0';    // Empty it out again
+        track_station_on = 0;
+        xastir_snprintf(temp2, sizeof(temp2), langcode("POPEM00002"), temp);
+        popup_message_always(langcode("POPEM00003"),temp2);
+    }
+
+    track_station_destroy_shell(w, clientData, callData);
+    display_zoom_status();
+}
+
+
+
+
+
+void Track_station( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget pane, my_form, button_ok, button_close, button_clear, call, sep;
+    Atom delw;
+
+    if (!track_station_dialog) {
+
+begin_critical_section(&track_station_dialog_lock, "track_gui.c:Track_station" );
+
+        track_station_dialog = XtVaCreatePopupShell(langcode("WPUPTSP001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Track_station pane",
+                xmPanedWindowWidgetClass, 
+                track_station_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Track_station my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 3,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        call = XtVaCreateManagedWidget(langcode("WPUPTSP002"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        track_station_data = XtVaCreateManagedWidget("Track_station track locate data", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 15,
+                XmNwidth, ((15*7)+2),
+                XmNmaxLength, 15,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, call,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        track_case_data  = XtVaCreateManagedWidget(langcode("WPUPTSP003"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, call,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset ,10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        track_match_data  = XtVaCreateManagedWidget(langcode("WPUPTSP004"),
+                xmToggleButtonWidgetClass,
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, call,
+                XmNtopOffset, 20,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget,track_case_data,
+                XmNrightOffset ,20,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        sep = XtVaCreateManagedWidget("Track_station sep", 
+                xmSeparatorGadgetClass,
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,track_case_data,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("WPUPTSP005"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_clear = XtVaCreateManagedWidget(langcode("WPUPTSP006"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 2,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 3,
+                XmNrightOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Track_station_now, track_station_dialog);
+        XtAddCallback(button_close, XmNactivateCallback, track_station_destroy_shell, track_station_dialog);
+        XtAddCallback(button_clear, XmNactivateCallback, Track_station_clear, track_station_dialog);
+
+        XmToggleButtonSetState(track_case_data,FALSE,FALSE);
+        XmToggleButtonSetState(track_match_data,TRUE,FALSE);
+
+        pos_dialog(track_station_dialog);
+
+        delw = XmInternAtom(XtDisplay(track_station_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(track_station_dialog, delw, track_station_destroy_shell, (XtPointer)track_station_dialog);
+
+//        if (track_station_on==1)
+            XmTextFieldSetString(track_station_data,tracking_station_call);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+end_critical_section(&track_station_dialog_lock, "track_gui.c:Track_station" );
+
+        XtPopup(track_station_dialog,XtGrabNone);
+        fix_dialog_size(track_station_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(track_station_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(track_station_dialog), XtWindow(track_station_dialog));
+}
+
+
+
+
+
+/***** DOWNLOAD FINDU TRAILS *****/
+
+
+
+// Struct used for passing two parameters to findu_transfer_thread
+typedef struct {
+    char *download_client_ptrs[2];
+} track_ptrs_struct;
+track_ptrs_struct track_ptrs;
+
+
+
+// This is the separate execution thread that fetches the track from
+// findu.  The thread is started up by the Download_trail_now()
+// function below.
+//
+static void* findu_transfer_thread(void *arg) {
+    char *fileimg;
+    char *log_filename;
+//    char log_filename_tmp[210];
+    char **ptrs;
+    char sys_cmd[128];
+
+
+    // Get fileimg and log_filename from parameters
+    ptrs = arg;
+    log_filename = ptrs[0];
+    fileimg = ptrs[1];
+
+    // Set global "busy" variable
+    fetching_findu_trail_now = 1;
+ 
+    if (fetch_remote_file(fileimg, log_filename)) {
+
+        // Had trouble getting the file.  Abort.
+
+// We may not be able to do any GUI stuff from multiple
+// threads/processes at the same time.  If that is found to be the
+// case we can write to STDERR instead.
+ 
+        // Dump a message to STDERR
+//        fprintf(stderr,
+//            "%s  %s\n",
+//            langcode("POPEM00035"),
+//            langcode("POPEM00044"));
+
+        // Fetch Findu Trail: Failed
+        popup_message_always(langcode("POPEM00035"),
+            langcode("POPEM00044"));
+
+        // Reset global "busy" variable
+        fetching_findu_trail_now = 0;
+
+        // End the thread
+        return(NULL);
+    }
+
+// We need to move this message up to the main thread if possible so
+// that we don't have multiple threads writing to the GUI.  This
+// sort of operation can cause segfaults.  In practice I haven't
+// seen any segfaults due to this particular popup though.
+
+    // Fetch Findu Trail: Complete
+    popup_message_always(langcode("POPEM00036"),
+        langcode("POPEM00045"));
+
+    // Set permissions on the file so that any user can overwrite it.
+    chmod(log_filename, 0666);
+
+#if defined(HAVE_SED)
+    // Add three spaces before each "<br>" and axe the "<br>".  This
+    // is so that Base-91 compressed packets with no comment and no
+    // speed/course/altitude will get decoded ok.  Otherwise the
+    // spaces that are critical to the Base-91 packets won't be
+    // there due to findu.com filtering them out.
+    //
+// "sed -i -e \"s/<br>/   <br>/\" %s",
+    sprintf(sys_cmd,
+        "%s -i -e \"s/<br>/   /\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+//fprintf(stderr,"%s\n", sys_cmd);
+
+// Greater-than symbol '>'
+    sprintf(sys_cmd,
+        "%s -i -e \"s/>/>/\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Less-than symbol '<'
+    sprintf(sys_cmd,
+        "%s -i -e \"s/</</\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Ampersand '&' (A difficult character to escape from the shell!)
+    sprintf(sys_cmd,
+        "%s -i -e \"s/&/\\&/\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Double-quote symbol '"'
+    sprintf(sys_cmd,
+        "%s -i -e \"s/"/""/\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Remove whitespace at the start of a line
+// sed 's/^[ \t]*//'
+    sprintf(sys_cmd,
+        "%s -i -e \"s/^[ \t]*//\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Remove any lines that start with '<'
+    sprintf(sys_cmd,
+        "%s -i -e \"s/^<.*$//\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Remove any lines that start with '"http'
+    sprintf(sys_cmd,
+        "%s -i -e \"/^\\\"http.*$/d\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+
+// Remove any blank lines from the file
+// sed '/^$/d'
+    sprintf(sys_cmd,
+        "%s -i -e \"/^$/d\" %s",
+        SED_PATH,
+        log_filename);
+    system(sys_cmd);
+#endif  // HAVE_SED
+
+/*
+#ifdef HAVE_HTML2TEXT
+    // Create temp filename
+    snprintf(log_filename_tmp, sizeof(log_filename_tmp), "%s%s",
+        log_filename,
+        ".tmp");
+    // Create html2text command
+    sprintf(sys_cmd,
+        "%s -width 300 -o %s %s",
+        HTML2TEXT_PATH,
+        log_filename_tmp,
+        log_filename);
+    // Convert the newly-downloaded file from html to text format
+    system(sys_cmd);
+    // Rename the file so that we can keep the static char* name
+    // pointing to it, needed for the read_file_ptr code in the main
+    // thread.
+#if defined(HAVE_MV)
+    sprintf(sys_cmd,
+        "%s %s %s",
+        MV_PATH,
+        log_filename_tmp,
+        log_filename);
+    system(sys_cmd);
+#endif  // HAVE_MV
+#endif  // HAVE_HTML2TEXT
+*/
+
+    // Here we do the findu stuff, if the findu_flag is set.  Else we do an imagemap.
+    // We have the log data we're interested in within the log_filename file.
+    // Cause that file to be read by the "File->Open Log File" routine.  HTML
+    // tags will be ignored just fine.
+    read_file_ptr = fopen(log_filename, "r");
+
+    if (read_file_ptr != NULL) {
+        read_file = 1;
+    }
+    else {
+        fprintf(stderr,"Couldn't open file: %s\n", log_filename);
+    }
+
+    // Reset global "busy" variable
+    fetching_findu_trail_now = 0;
+ 
+    // End the thread
+    return(NULL);
+}
+
+
+
+
+
+void Download_trail_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    download_findu_dialog = (Widget)NULL;
+
+end_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail_destroy_shell" );
+}
+
+
+
+
+
+void Download_trail_now(Widget w, XtPointer clientData, XtPointer callData) {
+    char temp[MAX_CALLSIGN+1];
+    static char fileimg[400];
+    static char log_filename[200];
+    char *temp_ptr;
+    pthread_t download_trail_thread;
+    static XtPointer download_client_data = NULL;
+
+    char tmp_base_dir[MAX_VALUE];
+
+    get_user_base_dir("tmp",tmp_base_dir, sizeof(tmp_base_dir));
+
+    // If we're already fetching a trail, we shouldn't be calling
+    // this callback function.  Get out.
+    if (fetching_findu_trail_now)
+        return;
+
+    // Pass two parameters to findu_transfer_thread via a struct
+    track_ptrs.download_client_ptrs[0] = log_filename;
+    track_ptrs.download_client_ptrs[1] = fileimg;
+    download_client_data = &track_ptrs;
+
+    // Check whether it's ok to do a download currently.
+    if (read_file) {
+        // No, we're already in the middle of reading in some file.
+        // Skip trying to download yet another file.
+
+        fprintf(stderr,"Processing another file.  Wait a bit, then try again\n");
+
+        popup_message_always(langcode("POPEM00035"),
+            langcode("POPEM00041"));
+
+        return;
+    }
+ 
+//    busy_cursor(appshell);
+
+    xastir_snprintf(log_filename,
+        sizeof(log_filename),
+        "%s/map.log",
+        tmp_base_dir);
+
+    // Erase any previously existing local file by the same name.
+    // This avoids the problem of having an old tracklog here and
+    // the code trying to display it when the download fails.
+    unlink( log_filename );
+
+
+    XmScaleGetValue(posit_start_value , &posit_start);
+    XmScaleGetValue(posit_length_value , &posit_length);
+
+    temp_ptr = XmTextFieldGetString(download_trail_station_data);
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s",
+        temp_ptr);
+    XtFree(temp_ptr);
+
+    (void)remove_trailing_spaces(temp);
+    (void)remove_trailing_dash_zero(temp);
+   
+    xastir_snprintf(download_trail_station_call,
+        sizeof(download_trail_station_call),
+        "%s",
+        temp);        
+    //Download_trail_destroy_shell(w, clientData, callData);
+
+
+// New URL's for findu.  The second one looks very promising.
+//http://www.findu.com/cgi-bin/raw.cgi?call=k4hg-8&time=1
+//http://www.findu.com/cgi-bin/rawposit.cgi?call=k4hg-8&time=1
+//
+// The last adds this to the beginning of the line:
+//
+//      "20030619235323,"
+//
+// which is a date/timestamp.  We'll need to do some extra stuff
+// here in order to actually use that date/timestamp though.
+// Setting the read_file_ptr to the downloaded file won't do it.
+
+
+
+//        "http://www.findu.com/cgi-bin/rawposit.cgi?call=%s&start=%d&length=%d&time=1", // New, with timestamp
+    xastir_snprintf(fileimg, sizeof(fileimg),
+        //
+        // Posits only:
+        // "http://www.findu.com/cgi-bin/rawposit.cgi?call=%s&start=%d&length=%d",
+        //
+        // Posits plus timestamps (we can't handle timestamps yet):
+        // "http://www.findu.com/cgi-bin/rawposit.cgi?call=%s&start=%d&length=%d&time=1", // New, with timestamp
+        // 
+        // Download all packets, not just posits:
+        "http://www.findu.com/cgi-bin/raw.cgi?call=%s&start=%d&length=%d",
+        //
+        download_trail_station_call,posit_start,posit_length);
+
+    if (debug_level & 1024) {
+        fprintf(stderr, "%s\n", fileimg);
+    }
+
+
+//----- Start New Thread -----
+
+    if (pthread_create(&download_trail_thread,
+            NULL,
+            findu_transfer_thread,
+            download_client_data)) {
+
+        fprintf(stderr,"Error creating findu transfer thread\n");
+    }
+    else {
+        // We're off and running with the new thread!
+    }
+
+    display_zoom_status();
+
+    Download_trail_destroy_shell(w, clientData, callData);
+}
+
+
+
+
+
+void Reset_posit_length_max(Widget w, XtPointer clientData, XtPointer callData) {
+
+    XmScaleGetValue(posit_length_value, &posit_length);
+    XmScaleGetValue(posit_start_value, &posit_start);
+
+    // Check whether start hours is greater than max findu allows
+    // for duration
+    //
+    if (posit_start > MAX_FINDU_DURATION) {    // Set the duration slider to
+                                // findu's max duration hours
+
+        XtVaSetValues(posit_length_value,
+            XmNvalue, MAX_FINDU_DURATION,
+            NULL);
+        posit_length = MAX_FINDU_DURATION;
+    }
+    else {  // Not near the max, so set the duration slider to match
+            // the start hours
+
+        XtVaSetValues(posit_length_value,
+            XmNvalue, posit_start,
+            NULL);
+        posit_length = posit_start;
+    }
+}
+
+
+
+
+
+void Download_findu_trail( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget pane, my_form, button_ok, button_cancel, call, sep;
+    Atom delw;
+    XmString x_str;
+
+
+    if (!download_findu_dialog) {
+
+begin_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_findu_trail" );
+
+        download_findu_dialog = XtVaCreatePopupShell(langcode("WPUPTSP007"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse,XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("Download_findu_trail pane",
+                xmPanedWindowWidgetClass, 
+                download_findu_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("Download_findu_trail my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 2,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        call = XtVaCreateManagedWidget(langcode("WPUPTSP008"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        download_trail_station_data = XtVaCreateManagedWidget("download_trail_station_data", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 15,
+                XmNwidth, ((15*7)+2),
+                XmNmaxLength, 15,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment,XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, call,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        x_str = XmStringCreateLocalized(langcode("WPUPTSP009"));
+        posit_start_value = XtVaCreateManagedWidget("Start of Trail (hrs ago)", 
+                xmScaleWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, call,
+                XmNtopOffset, 15,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                //XmNwidth, 190,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,
+                XmNmaximum, MAX_FINDU_START_TIME,
+                XmNshowValue, TRUE,
+                XmNvalue, posit_start,
+// Note:  Some versions of OpenMotif (distributed with Fedora,
+// perhaps others) don't work properly with XtVaTypedArg() as used
+// here, instead showing blank labels for the Scale widgets.
+//                XtVaTypedArg, XmNtitleString, XmRString, langcode("WPUPTSP009"), 22,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        x_str = XmStringCreateLocalized(langcode("WPUPTSP010"));
+        posit_length_value = XtVaCreateManagedWidget("Length of trail (hrs)", 
+                xmScaleWidgetClass, 
+                my_form,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget, posit_start_value,
+                XmNtopOffset, 15,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                //XmNwidth, 190,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNrightOffset, 10,
+                XmNsensitive, TRUE,
+                XmNorientation, XmHORIZONTAL,
+                XmNborderWidth, 1,
+                XmNminimum, 1,
+                XmNmaximum, MAX_FINDU_DURATION,
+                XmNshowValue, TRUE,
+                XmNvalue, posit_length,
+// Note:  Some versions of OpenMotif (distributed with Fedora,
+// perhaps others) don't work properly with XtVaTypedArg() as used
+// here, instead showing blank labels for the Scale widgets.
+//                XtVaTypedArg, XmNtitleString, XmRString, langcode("WPUPTSP010"), 19,
+                XmNtitleString, x_str,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        XmStringFree(x_str);
+
+        sep = XtVaCreateManagedWidget("Download_findu_trail sep", 
+                xmSeparatorGadgetClass,
+                my_form,
+                XmNorientation, XmHORIZONTAL,
+                XmNtopAttachment,XmATTACH_WIDGET,
+                XmNtopWidget,posit_length_value,
+                XmNtopOffset, 10,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNrightAttachment,XmATTACH_FORM,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_ok = XtVaCreateManagedWidget(langcode("WPUPTSP007"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 0,
+                XmNleftOffset, 5,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 1,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+        if (fetching_findu_trail_now)
+            XtSetSensitive(button_ok, FALSE);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, sep,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_FORM,
+                XmNbottomOffset, 5,
+                XmNleftAttachment, XmATTACH_POSITION,
+                XmNleftPosition, 1,
+                XmNrightAttachment, XmATTACH_POSITION,
+                XmNrightPosition, 2,
+                XmNrightOffset, 5,
+                XmNnavigationType, XmTAB_GROUP,
+                XmNtraversalOn, TRUE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_ok, XmNactivateCallback, Download_trail_now, download_findu_dialog);
+        XtAddCallback(button_cancel, XmNactivateCallback, Download_trail_destroy_shell, download_findu_dialog);
+        XtAddCallback(posit_start_value, XmNvalueChangedCallback, Reset_posit_length_max, download_findu_dialog);
+
+        pos_dialog(download_findu_dialog);
+
+        delw = XmInternAtom(XtDisplay(download_findu_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(download_findu_dialog, delw, Download_trail_destroy_shell, (XtPointer)download_findu_dialog);
+
+        XmTextFieldSetString(download_trail_station_data,download_trail_station_call);
+
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+end_critical_section(&download_findu_dialog_lock, "track_gui.c:Download_trail" );
+
+        XtPopup(download_findu_dialog,XtGrabNone);
+        fix_dialog_size(download_findu_dialog);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(download_findu_dialog);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+
+    } else
+        (void)XRaiseWindow(XtDisplay(download_findu_dialog), XtWindow(download_findu_dialog));
+}
+
+
diff --git a/src/track_gui.h b/src/track_gui.h
new file mode 100644
index 0000000..0c732d1
--- /dev/null
+++ b/src/track_gui.h
@@ -0,0 +1,42 @@
+/*
+ * $Id: track_gui.h,v 1.12 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ *
+ *
+ */
+
+#ifndef __TRACK_GUI_H
+#define __TRACK_GUI_H
+
+/* from track_gui.c */
+extern void track_gui_init(void);
+extern void Track_station(Widget w, XtPointer clientData, XtPointer callData);
+extern int track_station_on;
+extern int track_me;
+extern int track_case;
+extern int track_match;
+extern char tracking_station_call[30];
+extern void Download_findu_trail(Widget w, XtPointer clientData, XtPointer callData);
+
+#endif  // __TRACK_GUI_H
+
+
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..e08252f
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,5738 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: util.c,v 1.249 2012/09/23 16:19:22 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+// Needed for Solaris
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif  // HAVE_STRINGS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <math.h>
+#include <errno.h>
+
+#include "xastir.h"
+#include "util.h"
+#include "main.h"
+#include "xa_config.h"
+#include "datum.h"
+#include "hashtable.h"
+#include "hashtable_itr.h"
+#include "maps.h"
+
+
+#define CHECKMALLOC(m)  if (!m) { fprintf(stderr, "***** Malloc Failed *****\n"); exit(0); }
+
+// For mutex debugging with Linux threads only
+#ifdef MUTEX_DEBUG
+#include <asm/errno.h>
+//
+// Newer pthread function
+# ifdef HAVE_PTHREAD_MUTEXATTR_SETTYPE
+extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind);
+# endif  // HAVE_PTHREAD_MUTEXATTR_SETTYPE
+//
+// Older, deprecated pthread function
+# ifdef HAVE_PTHREAD_MUTEXATTR_SETKIND_NP
+extern int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
+# endif  // HAVE_PTHREAD_MUTEXATTR_SETKIND_NP
+//
+#endif  // MUTEX_DEBUG
+
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif  // HAVE_LIBCURL
+
+// Needed for size_t
+#include <sys/types.h>
+
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+int position_amb_chars;
+char echo_digis[6][MAX_CALLSIGN+1];
+
+#define ACCEPT_0N_0E    /* set this to see stations at 0N/0E on the map */
+
+struct timeval timer_start;
+struct timeval timer_stop;
+struct timezone tz;
+
+
+static struct hashtable *tactical_hash = NULL;
+#define TACTICAL_HASH_SIZE 1024
+
+#define MAX_LOGFILE_SIZE 2048000
+
+
+/////////////////////////////////////////////////////////////////////
+// convert_from_xastir_coordinates()
+//
+// Converts from Xastir coordinate system to lat/lon.  First two
+// parameters are the output floating point lat/lon values.  2nd two
+// are the input Xastir X/Y values.
+//
+//              0 (90 deg. or 90N)
+//
+// 0 (-180 deg. or 180W)      129,600,000 (180 deg. or 180E)
+//
+//          64,800,000 (-90 deg. or 90S)
+//
+// Returns 0 if error, 1 if good values were converted.
+//         Errors are due to the x and/or y values exceeding the above
+//         limits. In such cases the float values are set to appropriate
+//         minimum or maximum values.
+/////////////////////////////////////////////////////////////////////
+int convert_from_xastir_coordinates ( float *f_longitude,
+                                      float *f_latitude,
+                                      long x,
+                                      long y ) {
+
+//fprintf(stderr,"convert_from_xastir_coordinates\n");
+    int result = 1;  // assume the input values are in range
+
+    if (x < 0l ) {
+        fprintf(stderr,
+            "convert_from_xastir_coordinates:X out-of-range (too low):%lu\n",
+            x);
+        x = 0;
+        result = 0;
+    }
+
+    if (x > 129600000l) {
+        fprintf(stderr,
+            "convert_from_xastir_coordinates:X out-of-range (too high):%lu\n",
+            x);
+        x = 129600000l;
+        result = 0;
+    }
+
+    if (y < 0l) {
+        fprintf(stderr,
+            "convert_from_xastir_coordinates:Y out-of-range (too low):%lu\n",
+            y);
+        y = 0;
+        result = 0;
+    }
+
+    if (y > 64800000l) {
+        fprintf(stderr,
+            "convert_from_xastir_coordinates:Y out-of-range (too high):%lu\n",
+            y);
+        y = 64800000l;
+        result = 0;
+    }
+
+    *f_latitude  = (float)( -((y - 32400000l) / 360000.0) );
+    *f_longitude = (float)(   (x - 64800000l) / 360000.0  );
+
+//fprintf(stderr,"input x: %lu\tinput y: %lu\n",
+//    x,
+//    y);
+//fprintf(stderr,"latitude: %f\tlongitude: %f\n",
+//    *f_latitude,
+//    *f_longitude);
+
+    return(result);
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+// convert_to_xastir_coordinates()
+//
+// Converts from lat/lon to Xastir coordinate system.
+// First two parameters are the output Xastir X/Y values, 
+// 2nd two are the input floating point lat/lon values.
+//
+//              0 (90 deg. or 90N)
+//
+// 0 (-180 deg. or 180W)      129,600,000 (180 deg. or 180E)
+//
+//          64,800,000 (-90 deg. or 90S)
+//
+// Returns 0 if error, 1 if good values were converted.
+/////////////////////////////////////////////////////////////////////
+int convert_to_xastir_coordinates ( unsigned long* x,
+                                    unsigned long* y,
+                                    float f_longitude,
+                                    float f_latitude ) {
+
+    int ok = 1;
+
+    *y = (unsigned long)(32400000l + (360000.0 * (-f_latitude)));
+    *x = (unsigned long)(64800000l + (360000.0 * f_longitude));
+
+    if (f_longitude < -180.0) {
+        fprintf(stderr,
+            "convert_to_xastir_coordinates:Longitude out-of-range (too low):%f\n",
+            f_longitude);
+        *x = 0;
+        ok = 0;
+    }
+
+    if (f_longitude >  180.0) {
+        fprintf(stderr,
+            "convert_to_xastir_coordinates:Longitude out-of-range (too high):%f\n",
+            f_longitude);
+        *x = 129600000l;
+        ok = 0;
+    }
+
+    if (f_latitude <  -90.0) {
+        fprintf(stderr,
+            "convert_to_xastir_coordinates:Latitude out-of-range (too low):%f\n",
+            f_latitude);
+        *y = 0;
+        ok = 0;
+    }
+
+    if (f_latitude >   90.0) {
+        fprintf(stderr,
+            "convert_to_xastir_coordinates:Latitude out-of-range (too high):%f\n",
+            f_latitude);
+        *y = 64800000l;
+        ok =0;
+    }
+
+    return(ok);
+}
+
+
+
+
+
+// Multiply all the characters in the callsign, truncated to
+// TACTICAL_HASH_SIZE
+//
+unsigned int tactical_hash_from_key(void *key) {
+    unsigned char *jj = key;
+    unsigned int tac_hash = 1;
+
+    while (*jj != '\0') {
+       tac_hash = tac_hash * (unsigned int)*jj++;
+    }
+
+    tac_hash = tac_hash % TACTICAL_HASH_SIZE;
+
+//    fprintf(stderr,"hash = %d\n", tac_hash);
+    return (tac_hash);
+}
+
+
+
+
+
+int tactical_keys_equal(void *key1, void *key2) {
+
+//fprintf(stderr,"Comparing %s to %s\n",(char *)key1,(char *)key2);
+    if (strlen((char *)key1) == strlen((char *)key2)
+            && strncmp((char *)key1,(char *)key2,strlen((char *)key1))==0) {
+//fprintf(stderr,"    match\n");
+        return(1);
+    }
+    else {
+//fprintf(stderr,"  no match\n");
+        return(0);
+    }
+}
+
+
+
+
+
+void init_tactical_hash(int clobber) {
+//    fprintf(stderr," Initializing tactical hash \n");
+    // make sure we don't leak
+//fprintf(stderr,"init_tactical_hash\n");
+    if (tactical_hash) {
+//fprintf(stderr,"Already have one!\n");
+        if (clobber) {
+//fprintf(stderr,"Clobbering hash table\n");
+            hashtable_destroy(tactical_hash, 1);
+            tactical_hash=create_hashtable(TACTICAL_HASH_SIZE,
+                tactical_hash_from_key,
+                tactical_keys_equal);
+        }
+    }
+    else {
+//fprintf(stderr,"Creating hash table from scratch\n");
+        tactical_hash=create_hashtable(TACTICAL_HASH_SIZE,
+            tactical_hash_from_key,
+            tactical_keys_equal);
+    }
+}
+
+
+
+
+
+char *get_tactical_from_hash(char *callsign) {
+    char *result;
+
+    if (callsign == NULL || *callsign == '\0') {
+        fprintf(stderr,"Empty callsign passed to get_tactical_from_hash()\n");
+        return(NULL);
+    }
+
+    if (!tactical_hash) {  // no table to search
+//fprintf(stderr,"Creating hash table\n");
+        init_tactical_hash(1); // so create one
+        return NULL;
+    }
+
+//    fprintf(stderr,"   searching for %s...",callsign);
+
+    result=hashtable_search(tactical_hash,callsign);
+
+        if (result) {
+//            fprintf(stderr,"\t\tFound it, %s, len=%d, %s\n",
+//                callsign,
+//                strlen(callsign),
+//                result);
+        } else {
+//            fprintf(stderr,"\t\tNot found, %s, len=%d\n",
+//                callsign,
+//                strlen(callsign));
+        }
+
+    return (result);
+}
+
+
+
+
+
+// This function checks whether there already is something in the
+// hashtable that matches.  If a match found, it overwrites the
+// tactical call for that entry, else it inserts a new record.
+//
+void add_tactical_to_hash(char *callsign, char *tactical_call) {
+    char *temp1;    // tac-call
+    char *temp2;    // callsign
+    char *ptr;
+
+
+    // Note that tactical_call can be '\0', which means we're
+    // getting rid of a previous tactical call.
+    //
+    if (callsign == NULL || *callsign == '\0'
+            || tactical_call == NULL) {
+        return;
+    }
+
+    if (!tactical_hash) {  // no table to add to
+//fprintf(stderr,"init_tactical_hash\n");
+        init_tactical_hash(1); // so create one
+    }
+
+    // Remove any matching entry to avoid duplicates
+    ptr = hashtable_remove(tactical_hash, callsign);
+    if (ptr) {  // If value found, free the storage space for it as
+                // the hashtable_remove function doesn't.  It does
+                // however remove the key (callsign) ok.
+        free(ptr);
+    }
+
+    temp1 = (char *)malloc(MAX_TACTICAL_CALL+1);
+    CHECKMALLOC(temp1);
+
+    temp2 = (char *)malloc(MAX_CALLSIGN+1);
+    CHECKMALLOC(temp2);
+
+//fprintf(stderr, "\t\t\tAdding %s = %s...\n", callsign, tactical_call);
+
+    xastir_snprintf(temp2,
+        MAX_CALLSIGN+1,
+        "%s",
+        callsign);
+
+    xastir_snprintf(temp1,
+        MAX_TACTICAL_CALL+1,
+        "%s",
+        tactical_call);
+
+    //                                   (key)  (value)
+    //                         hash      call   tac-call
+    if (!hashtable_insert(tactical_hash, temp2, temp1)) {
+        fprintf(stderr,"Insert failed on tactical hash --- fatal\n");
+        free(temp1);
+        free(temp2);
+        exit(1);
+    }
+
+    // A check to see whether hash insert/update worked properly
+    ptr = get_tactical_from_hash(callsign);
+    if (!ptr) {
+        fprintf(stderr,"***Failed hash insert/update***\n");
+    }
+    else {
+//fprintf(stderr,"Current: %s -> %s\n",
+//    callsign,
+//    ptr);
+    }
+}
+
+
+
+
+
+void destroy_tactical_hash(void) {
+    struct hashtable_itr *iterator = NULL;
+    char *value;
+
+    if (tactical_hash && hashtable_count(tactical_hash) > 0) {
+
+        iterator = hashtable_iterator(tactical_hash);
+
+        do {
+            if (iterator) {
+                value = hashtable_iterator_value(iterator);
+                if (value) {
+                    free(value);
+                }
+            }
+        } while (hashtable_iterator_remove(iterator));
+
+        // Destroy the hashtable, freeing what's left of the
+        // entries.
+        hashtable_destroy(tactical_hash, 1);
+
+        tactical_hash = NULL;
+
+        if (iterator) free(iterator);
+    }
+}
+
+
+
+
+
+// Prints string to STDERR only if "my_debug_level" bits are set in
+// the global "debug_level" variable.  Used for getting extra debug
+// messages during various stages of debugging.
+//
+void xastir_debug(int my_debug_level, char *debug_string) {
+
+    if (debug_level & my_debug_level) {
+        fprintf(stderr, "%s", debug_string);
+    }
+}
+
+
+
+
+
+char *remove_all_spaces(char *data) {
+    char *ptr;
+    int length = strlen(data);
+
+    ptr = data;
+    while ( (ptr = strpbrk(data, " ")) ) {
+        memmove(ptr, ptr+1, strlen(ptr)+1);
+        length--;
+    }
+
+    // Terminate at the new string length
+    data[length] = '\0';
+
+    return(data);
+}
+
+
+
+
+
+char *remove_leading_spaces(char *data) {
+    int i,j;
+    int count;
+
+    if (data == NULL)
+        return NULL;
+
+    if (strlen(data) == 0)
+        return NULL;
+
+    count = 0;
+    // Count the leading space characters
+    for (i = 0; i < (int)strlen(data); i++) {
+        if (data[i] == ' ') {
+            count++;
+        }
+        else {  // Found a non-space
+            break;
+        }
+    }
+
+    // Check whether entire string was spaces
+    if (count == (int)strlen(data)) {
+        // Empty the string
+        data[0] = '\0';
+    }
+    else if (count > 0) {  // Found some spaces
+        i = 0;
+        for( j = count; j < (int)strlen(data); j++ ) {
+            data[i++] = data[j];    // Move string left
+        }
+        data[i] = '\0'; // Terminate the new string
+    }
+
+    return(data);
+}
+
+
+
+
+
+char *remove_trailing_spaces(char *data) {
+    int datalen;
+
+    if (data != NULL) {
+
+        datalen=strlen(data);
+        for(datalen--;datalen>=0;datalen--)
+            if(data[datalen] == ' ')
+                data[datalen] = '\0';
+            else
+                break;
+    }
+
+    // May end up with nothing left.
+    return(data);
+}
+
+
+
+
+
+char *remove_trailing_asterisk(char *data) {
+    int datalen;
+
+    if (data != NULL) {
+
+        datalen=strlen(data);
+        for(datalen--;datalen>0;datalen--) {
+            if(data[datalen] == '*')
+                data[datalen] = '\0';
+            else
+                break;
+        }
+    }
+    // May end up with nothing left.
+    return(data);
+}
+
+
+
+
+
+// Removes trailing "-0" from string.
+//
+// Modifies "data" variable.
+//
+char *remove_trailing_dash_zero(char *data) {
+    char *ptr;
+    char *ptr2;
+    int len = strlen(data);
+
+
+    // String too short?
+    if (len < 2)
+        return(data);
+
+    ptr2 = data + len - 1; // Point to last char
+    ptr = ptr2 - 1; // Point to next-to-last char
+
+    // Check for "-0" at end.  Remove if found.
+    if (*ptr == '-' && *ptr2 == '0') {
+        *ptr = '\0';    // Terminate
+    }
+
+    return(data);
+}
+
+
+
+
+
+// Save the current time, used for timing code sections.
+void start_timer(void) {
+    gettimeofday(&timer_start,&tz);
+}
+
+
+
+
+
+// Save the current time, used for timing code sections.
+void stop_timer(void) {
+    gettimeofday(&timer_stop,&tz);
+}
+
+
+
+
+
+// Print the difference in the two times saved above.
+void print_timer_results(void) {
+fprintf(stderr,"Total: %f sec\n",
+    (float)(timer_stop.tv_sec - timer_start.tv_sec +
+    ((timer_stop.tv_usec - timer_start.tv_usec) / 1000000.0) ));
+}
+
+
+
+
+
+//
+// Inserts localtime date/time in "timestring".  Timestring
+// Should be at least 101 characters long.
+//
+void get_timestamp(char *timestring) {
+    struct tm *time_now;
+    time_t secs_now;
+
+
+    secs_now=sec_now();
+    time_now = localtime(&secs_now);
+
+// %e is not implemented on all systems, but %d should be
+//    (void)strftime(timestring,100,"%a %b %e %H:%M:%S %Z %Y",time_now);
+    (void)strftime(timestring,100,"%a %b %d %H:%M:%S %Z %Y",time_now);
+}
+
+
+
+
+
+/* function get_iso_datetime converts time in seconds to an ISO date 
+ * time in the form yyyy-mm-dd hh:mm:ss utc_offset
+ * @param aTime time in seconds since the begining of the unix epoch
+ * @param timestring pointer to a char[101] into which the timestamp
+ * is written in the format yyyy-mm-dd hh:mm:ss followed by a utc 
+ * offset for the timezone.
+ * @param nowIfNotSet when true, if aTime is not set (int)aTime==0, 
+ * then return the current time rather than formatting aTime, when
+ * false, returns formatted aTime even if it was zero.  
+ * @param nowIfInvalid when true, if aTime is invalid (int)aTime=-1,
+ * then returns the formatted current time rather than formatting 
+ * aTime, otherwise returns formatted invalid time.
+ * @returns 0 on when (int)aTime==-1 where time provided invalid
+ * returns 1 otherwise. */
+int get_iso_datetime(time_t aTime, char *timestring,int nowIfNotSet, int nowIfInvalid) {
+    struct tm *time_now;
+    time_t secs_now;
+    int returnvalue = 1;
+    if (((int)aTime==0 && nowIfNotSet) || ((int)aTime==-1 && nowIfInvalid)) { 
+        secs_now=sec_now();
+        time_now = localtime(&secs_now);
+        (void)strftime(timestring,100,"%F %H:%M:%S %z",time_now);
+    } else { 
+        // will also end up here if time_t is -1
+        (void)strftime(timestring,100,"%F %H:%M:%S %z",localtime(&aTime));
+    }
+    if ((int)aTime==-1) { 
+        returnvalue = 0;
+    }
+    return returnvalue;
+}
+
+
+
+
+
+
+/* function get_W3CDTF_datetime converts time in seconds to a W3CDTF date 
+ * time in the form yyyy-mm-ddThh:mm:ss-utc_offsethh:mm
+ * See: http://www.w3.org/TR/NOTE-datetime 
+ * This is effectively an ISO date, with a T between the date and the 
+ * time, no space between the time and the utc offset, and a colon 
+ * separating utc offset hours from utc offset seconds.
+ * Example:  2008-01-25T08:35:20-05:00
+ * @param aTime time in seconds since the begining of the unix epoch
+ * @param timestring pointer to a char[101] into which the timestamp
+ * is written in the format yyyy-mm-ddThh:mm:ss followed by a utc 
+ * offset for the timezone, (e.g. -05:00).
+ * @param nowIfNotSet when true, if aTime is not set (int)aTime==0, 
+ * then return the current time rather than formatting aTime, when
+ * false, returns formatted aTime even if it was zero.  
+ * @param nowIfInvalid when true, if aTime is invalid (int)aTime=-1,
+ * then returns the formatted current time rather than formatting 
+ * aTime, otherwise returns formatted invalid time.
+ * @returns 0 on when (int)aTime==-1 where time provided invalid
+ * returns 1 otherwise. */
+int get_w3cdtf_datetime(time_t aTime, char *timestring,int nowIfNotSet, int nowIfInvalid) {
+    struct tm *time_now;
+    time_t secs_now;
+    int returnvalue = 1;
+    if (((int)aTime==0 && nowIfNotSet) || ((int)aTime==-1 && nowIfInvalid)) { 
+        secs_now=sec_now();
+        time_now = localtime(&secs_now);
+        (void)strftime(timestring,100,"%FT%H:%M:%S %z",time_now);
+        timestring[19] = timestring[20];
+        timestring[20] = timestring[21];
+        timestring[21] = timestring[22];
+        timestring[22] = ':';
+    } else { 
+        // will also end up here if time_t is -1
+        (void)strftime(timestring,100,"%FT%H:%M:%S %z",localtime(&aTime));
+        timestring[19] = timestring[20];
+        timestring[20] = timestring[21];
+        timestring[21] = timestring[22];
+        timestring[22] = ':';
+    }
+    if ((int)aTime==-1) { 
+        returnvalue = 0;
+    }
+    return returnvalue;
+}
+
+
+
+
+/***********************************************************/
+/* returns the hour (00..23), localtime                    */
+/***********************************************************/
+int get_hours(void) {
+    struct tm *time_now;
+    time_t secs_now;
+    char shour[5];
+
+    secs_now=sec_now();
+    time_now = localtime(&secs_now);
+    (void)strftime(shour,4,"%H",time_now);
+    return(atoi(shour));
+}
+
+
+
+
+
+/***********************************************************/
+/* returns the minute (00..59), localtime                  */
+/***********************************************************/
+int get_minutes(void) {
+    struct tm *time_now;
+    time_t secs_now;
+    char sminute[5];
+
+    secs_now=sec_now();
+    time_now = localtime(&secs_now);
+    (void)strftime(sminute,4,"%M",time_now);
+    return(atoi(sminute));
+}
+
+
+
+
+
+/***********************************************************/
+/* returns the second (00..61), localtime                  */
+/***********************************************************/
+int get_seconds(void) {
+    struct tm *time_now;
+    time_t secs_now;
+    char sminute[5];
+
+    secs_now=sec_now();
+    time_now = localtime(&secs_now);
+    (void)strftime(sminute,4,"%S",time_now);
+    return(atoi(sminute));
+}
+
+
+
+
+
+
+/*************************************************************************/
+/* output_lat - format position with position_amb_chars for transmission */
+/*************************************************************************/
+char *output_lat(char *in_lat, int comp_pos) {
+    int i,j;
+
+//fprintf(stderr,"in_lat:%s\n", in_lat);
+
+    if (!comp_pos) {
+        // Don't do this as it results in truncation!
+        //in_lat[7]=in_lat[8]; // Shift N/S down for transmission
+    }
+    else if (position_amb_chars>0) {
+        in_lat[7]='0';
+    }
+
+    j=0;
+    if (position_amb_chars>0 && position_amb_chars<5) {
+        for (i=6;i>(6-position_amb_chars-j);i--) {
+            if (i==4) {
+                i--;
+                j=1;
+            }
+            if (!comp_pos) {
+                in_lat[i]=' ';
+            } else
+                in_lat[i]='0';
+        }
+    }
+
+    if (!comp_pos) {
+        in_lat[8] = '\0';
+    }
+
+    return(in_lat);
+}
+
+
+
+
+
+/**************************************************************************/
+/* output_long - format position with position_amb_chars for transmission */
+/**************************************************************************/
+char *output_long(char *in_long, int comp_pos) {
+    int i,j;
+
+//fprintf(stderr,"in_long:%s\n", in_long);
+
+    if (!comp_pos) {
+        // Don't do this as it results in truncation!
+        //in_long[8]=in_long[9]; // Shift e/w down for transmission
+    }
+    else if (position_amb_chars>0) {
+        in_long[8]='0';
+    }
+
+    j=0;
+    if (position_amb_chars>0 && position_amb_chars<5) {
+        for (i=7;i>(7-position_amb_chars-j);i--) {
+            if (i==5) {
+                i--;
+                j=1;
+            }
+            if (!comp_pos) {
+                in_long[i]=' ';
+            } else
+                in_long[i]='0';
+        }
+    }
+
+    if (!comp_pos)
+        in_long[9] = '\0';
+
+    return(in_long);
+}
+
+
+
+
+
+/*********************************************************************/
+/* PHG range calculation                                             */
+/* NOTE: Keep these calculations consistent with phg_decode!         */
+/*       Yes, there is a reason why they both exist.                 */
+/*********************************************************************/
+double phg_range(char p, char h, char g) {
+    double power, height, gain, range;
+
+    if ( (p < '0') || (p > '9') )   // Power is outside limits
+        power = 0.0;
+    else
+        power = (double)( (p-'0')*(p-'0') );    // lclint said: "Assignment of char to double" here
+
+    if (h < '0')   // Height is outside limits (there is no upper limit according to the spec)
+        height = 10.0;
+    else
+        height = 10.0 * pow(2.0, (double)(h-'0'));
+
+    if ( (g < '0') || (g > '9') )   // Gain is outside limits
+        gain = 1.0;
+    else
+        gain = pow(10.0, (double)(g-'0') / 10.0);
+
+    range = sqrt(2.0 * height * sqrt((power / 10.0) * (gain / 2.0)));
+
+//    if (range > 70.0)
+//        fprintf(stderr,"PHG%c%c%c results in range of %f\n", p, h, g, range);
+
+    // Note:  Bob Bruninga, WB4APR, decided to cut PHG circles by
+    // 1/2 in order to show more realistic mobile ranges.
+    range = range / 2.0;
+
+    return(range);
+}
+
+
+
+
+
+/*********************************************************************/
+/* shg range calculation (for DF'ing)                                */
+/*                                                                   */
+/*********************************************************************/
+double shg_range(char s, char h, char g) {
+    double power, height, gain, range;
+
+    if ( (s < '0') || (s > '9') )   // Power is outside limits
+        s = '0';
+
+    if (s == '0')               // No signal strength
+        power = 10.0 / 0.8;     // Preventing divide by zero (same as DOSaprs does it)
+    else
+        power = 10 / (s - '0'); // Makes circle smaller with higher signal strengths
+
+    if (h < '0')   // Height is outside limits (there is no upper limit according to the spec)
+        height = 10.0;
+    else
+        height = 10.0 * pow(2.0, (double)(h-'0'));
+
+    if ( (g < '0') || (g > '9') )   // Gain is outside limits
+        gain = 1.0;
+    else
+        gain = pow(10.0, (double)(g-'0') / 10.0);
+
+    range = sqrt(2.0 * height * sqrt((power / 10.0) * (gain / 2.0)));
+
+    range = (range * 40) / 51;   // Present fudge factors used in DOSaprs
+
+    //fprintf(stderr,"SHG%c%c%c results in range of %f\n", s, h, g, range);
+
+    return(range);
+}
+
+
+
+
+
+/*********************************************************************/
+/* PHG decode                                                        */
+/* NOTE: Keep these calculations consistent with phg_range!          */
+/*       Yes, there is a reason why they both exist.                 */
+/*********************************************************************/
+void phg_decode(const char *langstr, const char *phg, char *phg_decoded, int phg_decoded_length) {
+    double power, height, gain, range;
+    char directivity[6], temp[64];
+    int  gain_db;
+    int len;
+
+    len = strlen(phg_decoded);
+
+    if (strlen(phg) != 7) {
+        xastir_snprintf(phg_decoded,
+            phg_decoded_length,
+            "%s %s",
+            langstr,
+            langcode("WPUPSTI073") ); // "BAD PHG"
+        return;
+    }
+
+    if ( (phg[3] < '0') || (phg[3] > '9') )   // Power is outside limits
+        power = 0.0;
+    else
+        power = (double)( (phg[3]-'0')*(phg[3]-'0') );
+
+    if (phg[4] < '0')   // Height is outside limits (there is no upper limit according to the spec)
+        height = 10.0;
+    else
+        height = 10.0 * pow(2.0, (double)(phg[4]-'0'));
+
+    if ( (phg[5] < '0') || (phg[5] > '9') ) { // Gain is outside limits
+        gain = 1.0;
+        gain_db = 0;
+    }
+    else {
+        gain = pow(10.0, (double)(phg[5]-'0') / 10.0);
+        gain_db = phg[5]-'0';
+    }
+
+    range = sqrt(2.0 * height * sqrt((power / 10.0) * (gain / 2.0)));
+    // Note:  Bob Bruninga, WB4APR, decided to cut PHG circles by
+    // 1/2 in order to show more realistic mobile ranges.
+    range = range / 2.0;
+
+    switch (phg[6]) {
+        case '0':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                langcode("WPUPSTI071") );   // "omni"
+            break;
+        case '1':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " NE");
+            break;
+        case '2':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " E");
+            break;
+        case '3':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " SE");
+            break;
+        case '4':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " S");
+            break;
+        case '5':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " SW");
+            break;
+        case '6':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " W");
+            break;
+        case '7':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " NW");
+            break;
+        case '8':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " N");
+            break;
+        default:
+            directivity[0] = '\0';  break;
+    }
+
+    if (english_units)
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%.0fW @ %.0fft %s, %ddB%s, %s %.1fmi",
+            power,
+            height,
+            langcode("WPUPSTI070"), // HAAT
+            gain_db,
+            directivity,
+            langcode("WPUPSTI072"), // range
+            range);
+    else
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%.0fW @ %.1fm %s, %ddB%s, %s %.1fkm",
+            power,
+            height*0.3048,
+            langcode("WPUPSTI070"), // HAAT
+            gain_db,
+            directivity,
+            langcode("WPUPSTI072"), // range
+            range*1.609344);
+
+    xastir_snprintf(phg_decoded,
+        phg_decoded_length,
+        "%s %s",
+        langstr,
+        temp);
+}
+
+
+
+
+
+/*********************************************************************/
+/* SHG decode                                                        */
+/*                                                                   */
+/*********************************************************************/
+void shg_decode(const char *langstr, const char *shg, char *shg_decoded, int shg_decoded_length) {
+    double power, height, gain, range;
+    char directivity[6], temp[80], signal[64];
+    int  gain_db;
+    char s;
+    int len;
+
+    len = strlen(shg_decoded);
+    if (strlen(shg) != 7) {
+        xastir_snprintf(shg_decoded,
+            shg_decoded_length,
+            langstr,
+            langcode("WPUPSTI074") );   // "BAD SHG"
+        return;
+    }
+
+    s = shg[3];
+
+    if ( (s < '0') || (s > '9') )   // Signal is outside limits
+        s = '0';                    // force to lowest legal value
+
+    switch (s) {
+        case '0':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI076") );
+                // "No signal detected"
+            break;
+        case '1':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI077") );
+                // "Detectible signal (Maybe)"
+            break;
+        case '2':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI078") );
+                // "Detectible signal but not copyable)"
+            break;
+        case '3':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI079") );
+                // "Weak signal, marginally readable"
+            break;
+        case '4':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI080") );
+                // "Noisy but copyable signal"
+            break;
+        case '5':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI081") );
+                // "Some noise, easy to copy signal"
+            break;
+        case '6':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI082") );
+                // "Good signal w/detectible noise"
+            break;
+        case '7':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI083") );
+                // "Near full-quieting signal"
+            break;
+        case '8':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI084") );
+                // "Full-quieting signal"
+            break;
+        case '9':
+            xastir_snprintf(signal,
+                sizeof(signal),
+                "%s",
+                langcode("WPUPSTI085") );
+                // "Extremely strong & full-quieting signal"
+            break;
+        default:
+            signal[0] = '\0';
+            break;
+    }
+
+    if (s == '0')
+        power = (double)( 10 / 0.8 );   // Preventing divide by zero (same as DOSaprs does it)
+    else
+        power = (double)( 10 / (s - '0') );
+
+    if (shg[4] < '0')   // Height is outside limits (there is no upper limit according to the spec)
+        height = 10.0;
+    else
+        height = 10.0 * pow(2.0, (double)(shg[4]-'0'));
+
+    if ( (shg[5] < '0') || (shg[5] > '9') ) { // Gain is outside limits
+        gain = 1.0;
+        gain_db = 0;
+    } else {
+        gain = pow(10.0, (double)(shg[5]-'0') / 10.0);
+        gain_db = shg[5]-'0';
+    }
+
+    range = sqrt(2.0 * height * sqrt((power / 10.0) * (gain / 2.0)));
+
+    range = range * 0.85;   // Present fudge factor (used by DOSaprs)
+
+    switch (shg[6]) {
+        case '0':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s ",
+                langcode("WPUPSTI071") );   // "omni"
+            break;
+        case '1':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " NE");
+            break;
+        case '2':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " E");
+            break;
+        case '3':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " SE");
+            break;
+        case '4':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " S");
+            break;
+        case '5':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " SW");
+            break;
+        case '6':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " W");
+            break;
+        case '7':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " NW");
+            break;
+        case '8':
+            xastir_snprintf(directivity,
+                sizeof(directivity),
+                "%s",
+                " N");
+            break;
+        default:
+            directivity[0] = '\0';  break;
+    }
+
+    if (english_units)
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%.0fft %s, %ddB%s, %s: %.1fmi, %s",
+            height,
+            langcode("WPUPSTI070"), // "HAAT"
+            gain_db,
+            directivity,
+            langcode("WPUPSTI075"), // "DF Range"
+            range,
+            signal);
+    else
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%.1fm %s, %ddB%s, %s: %.1fkm, %s",
+            height*0.3048,
+            langcode("WPUPSTI070"), // "HAAT"
+            gain_db,
+            directivity,
+            langcode("WPUPSTI075"), // "DF Range"
+            range*1.609344,
+            signal);
+
+    xastir_snprintf(shg_decoded,
+        shg_decoded_length,
+        langstr,
+        temp);
+}
+
+
+
+
+
+/*********************************************************************/
+/* Bearing decode                                                    */
+/*                                                                   */
+/*********************************************************************/
+void bearing_decode(const char *langstr, const char *bearing_str,
+        const char *NRQ, char *bearing_decoded, int bearing_decoded_length) {
+    int bearing, range, width;
+    char N,R,Q;
+    char temp[64];
+    int len;
+
+
+//fprintf(stderr,"bearing_decode incoming: bearing is %s, NRQ is %s\n", bearing_str, NRQ);
+
+    len = strlen(bearing_decoded);
+
+    if (strlen(bearing_str) != 3) {
+        xastir_snprintf(bearing_decoded,
+            bearing_decoded_length,
+            langstr,
+            langcode("WPUPSTI086") );   // "BAD BEARING"
+        return;
+    }
+
+    if (strlen(NRQ) != 3) {
+        xastir_snprintf(bearing_decoded,
+            bearing_decoded_length,
+            langstr,
+            langcode("WPUPSTI087") );   // "BAD NRQ"
+        return;
+    }
+
+    bearing = atoi(bearing_str);
+    N = NRQ[0];
+    R = NRQ[1];
+    Q = NRQ[2];
+
+    range = 0;
+    width = 0;
+
+    if (N != 0) {
+
+//fprintf(stderr,"N != 0\n");
+
+        range = (int)( pow(2.0,R - '0') );
+
+        switch (Q) {
+            case('1'):
+                width = 240;    // Degrees of beam width.  What's the point?
+                break;
+            case('2'):
+                width = 120;    // Degrees of beam width.  What's the point?
+                break;
+            case('3'):
+                width = 64; // Degrees of beam width.  What's the point?
+                break;
+            case('4'):
+                width = 32; // Degrees of beam width.  Starting to be usable.
+                break;
+            case('5'):
+                width = 16; // Degrees of beam width.  Usable.
+                break;
+            case('6'):
+                width = 8;  // Degrees of beam width.  Usable.
+                break;
+            case('7'):
+                width = 4;  // Degrees of beam width.  Nice!
+                break;
+            case('8'):
+                width = 2;  // Degrees of beam width.  Nice!
+                break;
+            case('9'):
+                width = 1;  // Degrees of beam width.  Very Nice!
+                break;
+            default:
+                width = 8;  // Degrees of beam width
+                break;
+        }
+
+//fprintf(stderr,"Width = %d\n",width);
+
+        if (english_units) {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%i�, %s: %i�, %s: %i mi",
+                bearing,
+                langcode("WPUPSTI088"), // DF Beamwidth
+                width,
+                langcode("WPUPSTI089"), // DF Length
+                range);
+        } else {
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%i�, %s: %i�, %s: %0.2f km",
+                bearing,
+                langcode("WPUPSTI088"), // DF Beamwidth
+                width,
+                langcode("WPUPSTI089"), // DF Length
+                range*1.609344);
+        }
+    } else {
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "%s",
+            langcode("WPUPSTI090") );   // "Not Valid"
+
+//fprintf(stderr,"N was 0\n");
+    }
+    xastir_snprintf(bearing_decoded,
+        bearing_decoded_length,
+        langstr,
+        temp);
+
+//fprintf(stderr,"bearing_decoded:%s\n", bearing_decoded);
+//fprintf(stderr,"temp:%s\n", temp);
+}
+
+
+
+
+
+//********************************************************************/
+// get_line - read a line from a file                                */
+//
+// NOTE: This routine will not work for binary files.  It works only
+// for ASCII-format files, and terminates each line at the first
+// control-character found (unless it's a tab).  Converts tab
+// character to 1 space character.
+//
+//********************************************************************/
+/*
+char *get_line(FILE *f, char *linedata, int maxline) {
+    char temp_line[32768];
+    int i;
+
+    // Snag one string from the file.  We'll end up with a
+    // terminating zero at temp_line[32767] in any case, because the
+    // max quantity we'll get here will be 32767 with a terminating
+    // zero added after whatever quantity is read.
+    (void)fgets(temp_line, 32768, f);
+
+    // A newline may have been added by the above fgets call.
+    // Change any newlines or other control characters to line-end
+    // characters.
+    for (i = 0; i < strlen(temp_line); i++) {
+        // Change any control characters to '\0';
+        if (temp_line[i] < 0x20) {
+            if (temp_line[i] == '\t') { // Found a tab char
+                temp_line[i] = ' '; // Convert to a space char
+            }
+            else {  // Not a tab
+                if (temp_line[i] != '\n') {                         // LF
+                    if ( (i != (strlen(temp_line) - 2) )            // CRLF
+                            && (i != (strlen(temp_line) - 1) ) ) {  // CR
+                        fprintf(stderr,"get_line: found control chars in: %s\n",
+                            temp_line);
+                    }
+                }
+                temp_line[i] = '\0';    // Terminate the string
+            }
+        }
+    }
+
+    xastir_snprintf(linedata,
+        maxline,
+        "%s",
+        temp_line);
+
+    return(linedata);
+}
+*/
+char *get_line(FILE *f, char *linedata, int maxline) {
+    int length;
+
+    // Write terminating chars throughout variable
+    memset(linedata,0,maxline);
+
+    // Get the data
+    (void)fgets(linedata, maxline, f);
+
+    // Change CR/LF to '\0'
+    length = strlen(linedata);
+
+    // Check the last two characters
+    if (length > 0) {
+        if ( (linedata[length - 1] == '\n')
+                || (linedata[length - 1] == '\r') ) {
+            linedata[length - 1] = '\0';
+        }
+    }
+
+    if (length > 1) {
+        if ( (linedata[length - 2] == '\n')
+                || (linedata[length - 2] == '\r') ) {
+            linedata[length - 2] = '\0';
+        }
+    }
+
+    return(linedata);
+}
+
+
+
+
+
+// time_from_aprsstring()
+//
+// Called from alert.c:alert_build_list() only.  Converts to
+// localtime if it's a zulu time string we're parsing.
+//
+time_t time_from_aprsstring(char *aprs_time) {
+    int day, hour, minute;
+    char tz[20];
+    struct tm *time_now, alert_time;
+    time_t timenw;
+    long zone;
+
+#ifndef HAVE_TM_GMTOFF
+    #ifdef __CYGWIN__
+        // Use "_timezone" instead of timezone in Cygwin
+        #define timezone _timezone
+    #else // __CYGWIN__
+        extern time_t timezone;
+    #endif  // __CYGWIN__
+#endif  // HAVE_TM_GMTOFF
+
+
+#ifdef __CYGWIN__
+    // Must call tzset before using the _timezone variable in
+    // Cygwin, else the timezone won't have been initialized.
+    tzset();
+#endif  // __CYGWIN__
+
+    // Compute our current time and the offset from GMT.  If
+    // daylight savings time is in effect, factor that in as well.
+    (void)time(&timenw);
+    time_now = localtime(&timenw);
+#ifdef HAVE_TM_GMTOFF
+    // tm_gmtoff is the GMT offset in seconds.  Some Unix systems
+    // have this extra field in the tm struct, some don't.
+    // tm_gmtoff is seconds EAST of UTC.
+    zone = time_now->tm_gmtoff;
+    //fprintf(stderr,"gmtoff: %ld, tm_isdst: %d\n",
+    //time_now->tm_gmtoff,
+    //time_now->tm_isdst);
+#else   // HAVE_TM_GMTOFF
+    // Note:  timezone is seconds WEST of UTC.  Need to negate
+    // timezone to have the offset occur in the correct direction.
+    zone = -((int)timezone - 3600 * (int)(time_now->tm_isdst > 0));
+    //fprintf(stderr,"timezone: %d, tm_isdst: %d\n",
+    //timezone,
+    //time_now->tm_isdst);
+#endif  // HAVE_TM_GMTOFF
+    // zone should now be the number to subtract in order to get
+    // localtime, in seconds.  For PST, I get -28800 which equals -8
+    // hours.  Summertime I should get -25200, or -7 hours.
+    //fprintf(stderr,"Zone: %ld\n",zone);
+
+
+    // Split the input time string into its component parts.
+    tz[0] = tz[1] = '\0';
+    switch (sscanf(aprs_time, "%2d%2d%2d%19s", &day, &hour, &minute, tz)) {
+        case 0:
+            day = 0;
+
+        case 1:
+            hour = 0;
+
+        case 2:
+            minute = 0;
+ 
+        default:
+            break;
+    }
+    if (day > 31) {
+        day = 31; // Wierd, can't have too many days in the month!
+        hour = 23;
+        minute = 59;
+    }
+
+    // We set up our alert_time so that it points into the same
+    // struct as time_now.  We do this both so that we can get
+    // automatically filled in pieces of the struct (year, etc), and
+    // so that we have a more global struct to return the time in.
+    // We'll have to adjust a few things like month/year if the time
+    // is too far distant from our current time and crosses some
+    // boundary.
+    alert_time = *time_now;
+    alert_time.tm_sec = 0;
+
+    //fprintf(stderr,"alert_time: %d %d %d\n",
+    //    alert_time.tm_mday,
+    //    alert_time.tm_hour,
+    //    alert_time.tm_min);
+
+    // Check to see how many parameters we parsed, and do our
+    // computations accordingly.
+    if (day) {  // If we parsed out the day
+        // Check whether our new day is more than ten days +/- from
+        // the current day of the month.  If so, assume it was from
+        // the month previous or after.
+        if (day < (time_now->tm_mday - 10)) {
+            // Day of month went down drastically.  Must be a date
+            // in the next month.  Bump up by one month and check
+            // whether we overflowed into the next year.  Note that
+            // month ranges from 0 to 11.
+            if (++alert_time.tm_mon > 11) {
+                alert_time.tm_mon = 0;
+                alert_time.tm_year++;
+            }
+        }
+        else if (day > (time_now->tm_mday + 10)) {
+            // Day of month went up drastically.  Must be a date
+            // during last month.  Decrement by one month and check
+            // whether we need to also decrement the year.
+            if (--alert_time.tm_mon < 0) {
+                alert_time.tm_mon = 11;
+                alert_time.tm_year--;
+            }
+        }
+
+        // Fill in the struct with our new values that we parsed.
+        alert_time.tm_mday = day;
+        alert_time.tm_min = minute;
+        alert_time.tm_hour = hour;
+
+        // Need to do conversions from zulu time?
+        if ((char)tolower((int)tz[0]) == 'z') {
+            // Yep, do the conversions.  Note that the zone variable
+            // already has the sign set correctly to get the correct
+            // time by using addition (PDT zone = -28800).
+
+            // Initialize daylight savings time to 0 in this
+            // instance, 'cuz we're starting with Zulu time and we
+            // want the localtime conversion to change it correctly.
+            // Zulu time has no daylight savings time offset.
+            //
+// WE7U:
+// No, it gave us an offset of 6 hours from UTC when we set this to
+// zero, 7 hours (correct) when we set it to one, during the summer.
+// Hopefully it will give us an 8-hour offset during the wintertime
+// but that remains to be seen...
+//
+// FYI:  We're in daylight savings time during the summer, when
+// we're at a 7-hour offset.  Winter is actual time and a -8 hour
+// offset.
+//
+// One on-line resource suggested setting it to -1 for automatic
+// determination of DST.  This works too, during the summer.  Again,
+// check during the wintertime too when we're at normal time.
+            //
+            alert_time.tm_isdst = -1;
+
+
+            // Do the hour offset
+            alert_time.tm_hour += zone/3600;
+
+            // Now check whether we have any offsets left to do.
+            zone %= 3600;
+            if (zone)
+                alert_time.tm_min += zone/60;
+
+            // Now check whether we have any overflows.  According
+            // to the "mktime()" man page, we probably don't need to
+            // do this for overflow (It normalizes the time itself),
+            // but I think we still need to for underflow.
+//WE7U: Check this stuff carefully!
+            if (alert_time.tm_min > 59) {
+                alert_time.tm_hour++;
+                alert_time.tm_min -= 60;
+            }
+            if (alert_time.tm_hour > 23) {
+                alert_time.tm_mday++;
+                alert_time.tm_hour -= 24;
+                if (mktime(&alert_time) == -1) {
+                    alert_time.tm_mday = 1;
+                    alert_time.tm_mon++;
+                    if (mktime(&alert_time) == -1) {
+                        alert_time.tm_mon = 0;
+                        alert_time.tm_year++;
+                    }
+                }
+            }
+            else if (alert_time.tm_hour < 0) {
+                alert_time.tm_hour += 24;
+                if (--alert_time.tm_mday <= 0) {
+                    if (--alert_time.tm_mon < 0) {
+                        alert_time.tm_year--;
+                        alert_time.tm_mon = 11;
+                        alert_time.tm_mday = 31;
+                    }
+                    else if (alert_time.tm_mon == 3 || alert_time.tm_mon == 5 ||
+                             alert_time.tm_mon == 8 || alert_time.tm_mon == 10) {
+                        alert_time.tm_mday = 30;
+                    }
+                    else if (alert_time.tm_mon == 1) {
+                        alert_time.tm_mday = (alert_time.tm_year%4 == 0) ? 29: 28;
+                    }
+                    else {
+                        alert_time.tm_mday = 31;
+                    }
+                }
+            }
+        }
+    }
+    else {  // We didn't parse out the day from the input string.
+
+        // What's this all about???  Different format of APRS
+        // time/date string?
+        alert_time.tm_year--;
+    }
+
+    if ( debug_level & 2 ) {
+        time_t a_time,now_time,diff;
+
+        fprintf(stderr,"\n Input: %s\n",aprs_time);
+
+        fprintf(stderr,"Output: %02d%02d%02d\n\n",
+            alert_time.tm_mday,
+            alert_time.tm_hour,
+            alert_time.tm_min);
+
+        a_time = mktime(&alert_time);
+        fprintf(stderr,"Alert: %ld\n", (long)a_time);
+
+        now_time = sec_now();
+        fprintf(stderr,"  Now: %ld\n", (long)now_time);
+
+        diff = now_time - a_time;
+
+        if (diff >= 0)
+            fprintf(stderr,"Expired by %ld minutes\n", (long)(diff/60) );
+        else
+            fprintf(stderr,"%ld minutes until expiration\n", (long)((-diff)/60) );
+
+        if (alert_time.tm_isdst > 0)
+            fprintf(stderr,"Daylight savings time is in effect\n");
+    }
+
+    return(mktime(&alert_time));
+}
+
+
+
+
+
+// Note: last_speed should be in knots.
+//
+// Input format for lat/long is DDMM.MM or DDMM.MMM format, like:
+// 4722.93N   12244.17W  or
+// 4722.938N  12244.177W
+//
+char *compress_posit(const char *input_lat, const char group, const char *input_lon, const char symbol,
+            const unsigned int last_course, const unsigned int last_speed, const char *phg) {
+    static char pos[100];
+    char lat[5], lon[5];
+    char c, s, t, ext;
+    int temp, deg;
+    double minutes;
+    char temp_str[20];
+
+
+//fprintf(stderr,"lat:%s, long:%s, symbol:%c%c, course:%d, speed:%d, phg:%s\n",
+//    input_lat,
+//    input_lon,
+//    group,
+//    symbol,
+//    last_course,
+//    last_speed,
+//    phg);
+
+    // Fetch degrees (first two chars)
+    temp_str[0] = input_lat[0];
+    temp_str[1] = input_lat[1];
+    temp_str[2] = '\0';
+    deg = atoi(temp_str);
+
+    // Fetch minutes (rest of numbers)
+    xastir_snprintf(temp_str,
+        sizeof(temp_str),
+        "%s",
+        input_lat);
+    temp_str[0] = ' ';  // Blank out degrees
+    temp_str[1] = ' ';  // Blank out degrees
+    minutes = atof(temp_str);
+
+    // Check for North latitude
+    if (strstr(input_lat, "N") || strstr(input_lat, "n"))
+        ext = 'N';
+    else
+        ext = 'S';
+
+//fprintf(stderr,"ext:%c\n", ext);
+
+    temp = 380926 * (90 - (deg + minutes / 60.0) * ( ext=='N' ? 1 : -1 ));
+
+//fprintf(stderr,"temp: %d\t",temp);
+
+    lat[3] = (char)(temp%91 + 33); temp /= 91;
+    lat[2] = (char)(temp%91 + 33); temp /= 91;
+    lat[1] = (char)(temp%91 + 33); temp /= 91;
+    lat[0] = (char)(temp    + 33);
+    lat[4] = '\0';
+
+//fprintf(stderr,"%s\n",lat);
+
+    // Fetch degrees (first three chars)
+    temp_str[0] = input_lon[0];
+    temp_str[1] = input_lon[1];
+    temp_str[2] = input_lon[2];
+    temp_str[3] = '\0';
+    deg = atoi(temp_str);
+
+    // Fetch minutes (rest of numbers)
+    xastir_snprintf(temp_str,
+        sizeof(temp_str),
+        "%s",
+        input_lon);
+    temp_str[0] = ' ';  // Blank out degrees
+    temp_str[1] = ' ';  // Blank out degrees
+    temp_str[2] = ' ';  // Blank out degrees
+    minutes = atof(temp_str);
+
+    // Check for West longitude
+    if (strstr(input_lon, "W") || strstr(input_lon, "w"))
+        ext = 'W';
+    else
+        ext = 'E';
+
+//fprintf(stderr,"ext:%c\n", ext);
+
+    temp = 190463 * (180 + (deg + minutes / 60.0) * ( ext=='W' ? -1 : 1 ));
+
+//fprintf(stderr,"temp: %d\t",temp);
+
+    lon[3] = (char)(temp%91 + 33); temp /= 91;
+    lon[2] = (char)(temp%91 + 33); temp /= 91;
+    lon[1] = (char)(temp%91 + 33); temp /= 91;
+    lon[0] = (char)(temp    + 33);
+    lon[4] = '\0';
+
+//fprintf(stderr,"%s\n",lon);
+
+    // Set up csT bytes for course/speed if either are non-zero
+    c = s = t = ' ';
+    if (last_course > 0 || last_speed > 0) {
+
+        if (last_course >= 360)
+            c = '!';    // 360 would be past 'z'.  Set it to zero.
+        else
+            c = (char)(last_course/4 + 33);
+
+        s = (char)(log(last_speed + 1.0) / log(1.08) + 33.5);  // Poor man's rounding + ASCII
+        t = 'C';
+    }
+    // Else set up csT bytes for PHG if within parameters
+    else if (strlen(phg) >= 6) {
+        double power, height, gain, range, s_temp;
+
+
+        c = '{';
+
+        if ( (phg[3] < '0') || (phg[3] > '9') ) { // Power is out of limits
+            power = 0.0;
+        }
+        else {
+            power = (double)((int)(phg[3]-'0'));
+            power = power * power;  // Lowest possible value is 0.0
+        }
+
+        if (phg[4] < '0') // Height is out of limits (no upper limit according to the spec)
+            height = 10.0;
+        else
+            height= 10.0 * pow(2.0,(double)phg[4] - (double)'0');   // Lowest possible value is 10.0
+
+        if ( (phg[5] < '0') || (phg[5] > '9') ) // Gain is out of limits
+            gain = 1.0;
+        else
+            gain = pow(10.0,((double)(phg[5]-'0') / 10.0)); // Lowest possible value is 1.0
+
+        range = sqrt(2.0 * height * sqrt((power / 10.0) * (gain / 2.0)));   // Lowest possible value is 0.0
+
+        // Check for range of 0, and skip log10 if so
+        if (range != 0.0)
+            s_temp = log10(range/2) / log10(1.08) + 33.0;
+        else
+            s_temp = 0.0 + 33.0;
+
+        s = (char)(s_temp + 0.5);    // Cheater's way of rounding, add 0.5 and truncate
+
+        t = 'C';
+    }
+    // Note that we can end up with three spaces at the end if no
+    // course/speed/phg were supplied.  Do not knock this down, as
+    // the compressed posit has a fixed 13-character length
+    // according to the spec!
+    //
+    xastir_snprintf(pos,
+        sizeof(pos),
+        "%c%s%s%c%c%c%c",
+        group,
+        lat,
+        lon,
+        symbol,
+        c,
+        s,
+        t);
+
+//fprintf(stderr,"New compressed pos: (%s)\n",pos);
+    return pos;
+}
+
+
+
+
+
+/*
+ * See if position is defined
+ * 90�N 180�W (0,0 in internal coordinates) is our undefined position
+ * 0N/0E is excluded from trails, could be excluded from map (#define ACCEPT_0N_0E)
+ */
+
+int position_defined(long lat, long lon, int strict) {
+
+    if (lat == 0l && lon == 0l)
+        return(0);              // undefined location
+#ifndef ACCEPT_0N_0E
+    if (strict)
+#endif  // ACCEPT_0N_0E
+        if (lat == 90*60*60*100l && lon == 180*60*60*100l)      // 0N/0E
+            return(0);          // undefined location
+    return(1);
+}
+
+
+
+
+
+// Function to convert from screen (pixel) coordinates to the Xastir
+// coordinate system.
+//
+void convert_screen_to_xastir_coordinates(int x,
+        int y,
+        long *lat,
+        long *lon) {
+
+    *lon = (center_longitude - ((screen_width  * scale_x)/2) + (x * scale_x));
+    *lat = (center_latitude  - ((screen_height * scale_y)/2) + (y * scale_y));
+
+    if (*lon < 0)
+    *lon = 0l;                 // 180�W
+
+    if (*lon > 129600000l)
+    *lon = 129600000l;         // 180�E
+
+    if (*lat < 0)
+    *lat = 0l;                 //  90�N
+
+    if (*lat > 64800000l)
+    *lat = 64800000l;          //  90�S
+}
+
+
+
+
+
+// Convert Xastir lat/lon to UTM printable string
+void convert_xastir_to_UTM_str(char *str, int str_len, long x, long y) {
+    double utmNorthing;
+    double utmEasting;
+    char utmZone[10];
+ 
+    ll_to_utm_ups(E_WGS_84,
+        (double)(-((y - 32400000l )/360000.0)),
+        (double)((x - 64800000l )/360000.0),
+        &utmNorthing,
+        &utmEasting,
+        utmZone,
+        sizeof(utmZone) );
+    utmZone[9] = '\0';
+    //fprintf(stderr,"%s %07.0f %07.0f\n", utmZone, utmEasting,
+    //utmNorthing );
+    xastir_snprintf(str,
+        str_len,
+        "%s %07.0f %07.0f",
+        utmZone,
+        utmEasting,
+        utmNorthing);
+}
+
+
+
+
+// To produce MGRS coordinates, we'll call ll_to_utm_ups() 
+// [?? Earlier text: "the above function" ??]
+// then convert the result to the 2-letter digraph format used 
+// for MGRS.  The ll_to_utm_ups() function switches to the special 
+// irregular UTM zones for the areas near Svalbard and SW Norway 
+// if the "coordinate_system" variable is set to "USE_MGRS", 
+// so we'll be using the correct zone boundaries for MGRS if that 
+// variable is set when we make the call.
+//
+// If "nice_format" == 1, we add leading spaces plus spaces between
+// the easting and northing in order to line up more nicely with the
+// UTM output format.
+//
+// convert_xastir_to_MGRS_str is a wrapper around the components
+// function below that returns the MGRS coordinate of x and y as a
+// single MGRS string.  
+//
+/* convert_xastir_to_MGRS_str_components returns each of the components 
+   of the MGRS string separately.
+   Example MGRS string: 18T VK 66790 55998
+   Parameters:
+   utmZone          Returns the UTM zone: e.g. 18T
+   utmZone_len      length of the utmZone char[]
+   EastingL         Returns the first letter of the MGRS digraph: e.g. V
+   EastingL_len     length of the EastingL char[]
+   NorthingL        Returns the second letter of the MGRS digraph: e.g. K
+   NorthingL_len    length of the NorthingL char[]
+   int_utmEasting   returns the MGRS easting: e.g. 66790
+   int_utmNorthing  returns the MGRS northing: e.g. 55998
+   x                xastir x coordinate to obtain MGRS coordinate for.
+   y                xastir x coordinate to obtain MGRS coordinate for.
+   nice_format      1 for populate space_string with three spaces
+                    0 to make space_string and empty string, see above.
+   space_string     Returned string that can be used to make MGRS strings
+                    allign more cleanly with UTM strings.
+   space_string_len length of the space_string char[]
+*/
+void convert_xastir_to_MGRS_str_components(char *utmZone, int utmZone_len, 
+       char *EastingL, int EastingL_len, 
+       char *NorthingL, int NorthingL_len, 
+       unsigned int *int_utmEasting, unsigned int *int_utmNorthing, 
+       long x,  long y, 
+       int nice_format, char *space_string, int space_string_len) {
+
+    double utmNorthing;
+    double utmEasting;
+    //char utmZone[10];
+    int start;
+    int my_east, my_north;
+    //unsigned int int_utmEasting, int_utmNorthing;
+    int UPS = 0;
+    int North_UPS = 0;
+    int coordinate_system_save = coordinate_system;
+    //char space_string[4] = "   ";    // Three spaces
+
+    // Set for correct zones
+    coordinate_system = USE_MGRS;
+
+    ll_to_utm_ups(E_WGS_84,
+        (double)(-((y - 32400000l )/360000.0)),
+        (double)((x - 64800000l )/360000.0),
+        &utmNorthing,
+        &utmEasting,
+        utmZone,
+        sizeof(utmZone) );
+    utmZone[9] = '\0';
+
+    // Restore it
+    coordinate_system = coordinate_system_save;
+
+
+    //fprintf(stderr,"%s %07.0f %07.0f\n", utmZone, utmEasting,
+    //utmNorthing );
+    //xastir_snprintf(str, str_len, "%s %07.0f %07.0f",
+    //    utmZone, utmEasting, utmNorthing );
+
+
+    // Convert the northing and easting values to the digraph letter
+    // format.  Letters 'I' and 'O' are skipped for both eastings
+    // and northings.  Letters 'W' through 'Z' are skipped for
+    // northings.
+    //
+    // N/S letters alternate in a cycle of two.  Begins at the
+    // equator with A and F in alternate zones.  Odd-numbered zones
+    // use A-V, even-numbered zones use F-V, then A-V.
+    //
+    // E/W letters alternate in a cycle of three.  Each E/W zone
+    // uses an 8-letter block.  Starts at A-H, then J-R, then S-Z,
+    // then repeats every 18 degrees.
+    //
+    // N/S letters have a cycle of two, E/W letters have a cycle of
+    // three.  The same lettering repeats after six zones (2,000,000
+    // meter intervals).
+    //
+    // AA is at equator and 180W.
+
+    // Easting:  Each zone covers 6 degrees.  Zone 1 = A-H, Zone 2 =
+    // J-R, Zone 3 = S-Z, then repeat.  So, take zone number-1,
+    // modulus 3, multiple that number by 8.  Modulus 24.  That's
+    // our starting letter for the zone.  Take the easting number,
+    // divide by 100,000, , add the starting number, compute modulus
+    // 24, then use that index into our E_W array.
+    //
+    // Northing:  Figure out whether even/odd zone number.  Divide
+    // by 100,000.  If even, add 5 (starts at 'F' if even).  Compute
+    // modulus 20, then use that index into our N_S array.
+
+
+    *int_utmEasting = (unsigned int)utmEasting;
+    *int_utmNorthing = (unsigned int)utmNorthing;
+    *int_utmEasting = *int_utmEasting % 100000;
+    *int_utmNorthing = *int_utmNorthing % 100000;
+
+
+    // Check for South Polar UPS area, set flags if found.
+    if (   utmZone[0] == 'A'
+        || utmZone[0] == 'B'
+        || utmZone[1] == 'A'
+        || utmZone[1] == 'B'
+        || utmZone[2] == 'A'
+        || utmZone[2] == 'B' ) {
+        // We're in the South Polar UPS area
+        UPS++;
+    }
+    // Check for North Polar UPS area, set flags if found.
+    else if (   utmZone[0] == 'Y'
+        || utmZone[0] == 'Z'
+        || utmZone[1] == 'Y'
+        || utmZone[1] == 'Z'
+        || utmZone[2] == 'Y'
+        || utmZone[2] == 'Z') {
+        // We're in the North Polar UPS area
+        UPS++;
+        North_UPS++;
+    }
+    else {
+        // We're in the UTM area.  Set no flags.
+    }
+
+
+    if (UPS) {  // Special processing for UPS area (A/B/Y/Z bands)
+
+        // Note: Zone number isn't used for UPS, but zone letter is.
+        if (nice_format) {  // Add two leading spaces
+            utmZone[2] = utmZone[0];
+            utmZone[0] = ' ';
+            utmZone[1] = ' ';
+            utmZone[3] = '\0';
+        }
+        else {
+            space_string[0] = '\0';
+        }
+
+        if (North_UPS) {    // North polar UPS zone
+            char UPS_N_Easting[15]  = "RSTUXYZABCFGHJ";
+            char UPS_N_Northing[15] = "ABCDEFGHJKLMNP";
+
+            // Calculate the index into the 2-letter digraph arrays.
+            my_east = (int)(utmEasting / 100000.0);
+            my_east = my_east - 13;
+            my_north = (int)(utmNorthing / 100000.0);
+            my_north = my_north - 13;
+
+            /*xastir_snprintf(str,
+                str_len,
+                "%s %c%c %05d %s%05d",
+                utmZone,
+                UPS_N_Easting[my_east],
+                UPS_N_Northing[my_north],
+                int_utmEasting,
+                space_string,
+                int_utmNorthing ); */
+           xastir_snprintf(EastingL,EastingL_len,
+                "%c", UPS_N_Easting[my_east]);
+           xastir_snprintf(NorthingL,NorthingL_len,
+                "%c", UPS_N_Northing[my_north]);
+        }
+        else {  // South polar UPS zone
+            char UPS_S_Easting[25]  = "JKLPQRSTUXYZABCFGHJKLPQR";
+            char UPS_S_Northing[25] = "ABCDEFGHJKLMNPQRSTUVWXYZ";
+
+            // Calculate the index into the 2-letter digraph arrays.
+            my_east = (int)(utmEasting / 100000.0);
+            my_east = my_east - 8;
+            my_north = (int)(utmNorthing / 100000.0);
+            my_north = my_north - 8;
+
+            /* xastir_snprintf(str,
+                str_len,
+                "%s %c%c %05d %s%05d",
+                utmZone,
+                UPS_S_Easting[my_east],
+                UPS_S_Northing[my_north],
+                int_utmEasting,
+                space_string,
+                int_utmNorthing ); */
+           xastir_snprintf(EastingL,EastingL_len,
+                "%c", UPS_S_Easting[my_east]);
+           xastir_snprintf(NorthingL,NorthingL_len,
+                "%c", UPS_S_Northing[my_north]);
+        }
+    }
+    else {  // UTM Area
+        char E_W[25] = "ABCDEFGHJKLMNPQRSTUVWXYZ";
+        char N_S[21] = "ABCDEFGHJKLMNPQRSTUV";
+
+
+        if (!nice_format) { 
+            space_string[0] = '\0';
+        }
+
+ 
+        // Calculate the indexes into the 2-letter digraph arrays.
+        start = atoi(utmZone);
+        start--;
+        start = start % 3;
+        start = start * 8;
+        start = start % 24;
+        // "start" is now an index into the starting letter for the
+        // zone.
+
+
+        my_east = (int)(utmEasting / 100000.0) - 1;
+        my_east = my_east + start;
+        my_east = my_east % 24;
+//        fprintf(stderr, "Start: %c   East (guess): %c   ",
+//            E_W[start],
+//            E_W[my_east]);
+
+
+        start = atoi(utmZone);
+        start = start % 2;
+        if (start) {    // Odd-numbered zone
+            start = 0;
+        }
+        else {  // Even-numbered zone
+            start = 5;
+        }
+        my_north = (int)(utmNorthing / 100000.0);
+        my_north = my_north + start;
+        my_north = my_north % 20;
+//        fprintf(stderr, "Start: %c   North (guess): %c\n",
+//            N_S[start],
+//            N_S[my_north]);
+
+        /* xastir_snprintf(str,
+            str_len,
+            "%s %c%c %05d %s%05d",
+            utmZone,
+            E_W[my_east],
+            N_S[my_north],
+            int_utmEasting,
+            space_string,
+            int_utmNorthing ); */
+        xastir_snprintf(EastingL, EastingL_len,
+             "%c", E_W[my_east]);
+        xastir_snprintf(NorthingL, NorthingL_len,
+             "%c", N_S[my_north]);
+    }
+}
+
+
+
+
+
+/* Wrapper around convert_xastir_to_MGRS_str_components 
+   to return an MGRS coordinate as a single string. 
+   Parameters:
+   str The character array to be populated with the MGRS string.
+   str_len Length of str.
+   x xastir x coordinate.
+   y xastir y coordinate.
+   If "nice_format" == 1, we add leading spaces plus spaces between
+   the easting and northing in order to line up more nicely with the
+   UTM output format.
+*/
+void convert_xastir_to_MGRS_str(char *str, int str_len, long x, long y, int nice_format) {
+    char space_string[4] = "   ";    // Three spaces
+    unsigned int intEasting = 0;
+    unsigned int intNorthing = 0;
+    char EastingL[3] = "  ";
+    char NorthingL[3] = "  ";
+    char utmZone[10];
+    convert_xastir_to_MGRS_str_components(utmZone, strlen(utmZone), 
+       EastingL, sizeof(EastingL), 
+       NorthingL, sizeof(NorthingL), 
+       &intEasting, &intNorthing, 
+       x,  y, 
+       nice_format, space_string, strlen(space_string)) ;
+    xastir_snprintf(str,
+       str_len,
+       "%s %c%c %05d %s%05d",
+       utmZone,
+       EastingL[0],
+       NorthingL[0],
+       intEasting,
+       space_string,
+       intNorthing );
+}
+
+
+
+
+ 
+// Convert Xastir lat/lon to UTM
+void convert_xastir_to_UTM(double *easting, double *northing, char *zone, int zone_len, long x, long y) {
+
+    ll_to_utm_ups(E_WGS_84,
+        (double)(-((y - 32400000l )/360000.0)),
+        (double)((x - 64800000l )/360000.0),
+        northing,
+        easting,
+        zone,
+        zone_len);
+    zone[zone_len-1] = '\0';
+}
+
+
+
+
+
+// Convert UTM to Xastir lat/lon
+void convert_UTM_to_xastir(double easting, double northing, char *zone, long *x, long *y) {
+    double lat, lon;
+
+    utm_ups_to_ll(E_WGS_84,
+        northing,
+        easting,
+        zone,
+        &lat,
+        &lon);
+
+    // Reverse latitude to fit our coordinate system then convert to
+    // Xastir units.
+    *y = (long)(lat * -360000.0) + 32400000l;
+
+    // Convert longitude to xastir units
+    *x = (long)(lon *  360000.0) + 64800000l;
+}
+
+
+
+
+// convert latitude from long to string 
+// Input is in Xastir coordinate system
+//
+// CONVERT_LP_NOSP      = DDMM.MMN
+// CONVERT_HP_NOSP      = DDMM.MMMN
+// CONVERT_VHP_NOSP     = DDMM.MMMMN
+// CONVERT_LP_NORMAL    = DD MM.MMN
+// CONVERT_HP_NORMAL    = DD MM.MMMN
+// CONVERT_UP_TRK       = NDD MM.MMMM
+// CONVERT_DEC_DEG      = DD.DDDDDN
+// CONVERT_DMS_NORMAL   = DD MM SS.SN
+// CONVERT_DMS_NORMAL_FORMATED   = DD'MM'SS.SN
+// CONVERT_HP_NORMAL_FORMATED   = DD'MM.MMMMN
+//
+void convert_lat_l2s(long lat, char *str, int str_len, int type) {
+    char ns;
+    float deg, min, sec;
+    int ideg, imin;
+    long temp;
+
+
+    str[0] = '\0';
+    deg = (float)(lat - 32400000l) / 360000.0;
+ 
+    // Switch to integer arithmetic to avoid floating-point
+    // rounding errors.
+    temp = (long)(deg * 100000);
+
+    ns = 'S';
+    if (temp <= 0) {
+        ns = 'N';
+        temp = labs(temp);
+    }   
+
+    ideg = (int)temp / 100000;
+    min = (temp % 100000) * 60.0 / 100000.0;
+
+    // Again switch to integer arithmetic to avoid floating-point
+    // rounding errors.
+    temp = (long)(min * 1000);
+    imin = (int)(temp / 1000);
+    sec = (temp % 1000) * 60.0 / 1000.0;
+
+    switch (type) {
+
+        case(CONVERT_LP_NOSP): /* do low P w/no space */
+            xastir_snprintf(str,
+                str_len,
+                "%02d%05.2f%c",
+                ideg,
+//                min+0.001, // Correct possible unbiased rounding
+                min,
+                ns);
+            break;
+
+        case(CONVERT_LP_NORMAL): /* do low P normal */
+            xastir_snprintf(str,
+                str_len,
+                "%02d %05.2f%c",
+                ideg,
+//                min+0.001, // Correct possible unbiased rounding
+                min,
+                ns);
+            break;
+
+        case(CONVERT_HP_NOSP): /* do HP w/no space */
+            xastir_snprintf(str,
+                str_len,
+                "%02d%06.3f%c",
+                ideg,
+//                min+0.0001, // Correct possible unbiased rounding
+                min,
+                ns);
+            break;
+
+        case(CONVERT_VHP_NOSP): /* do Very HP w/no space */
+            xastir_snprintf(str,
+                str_len,
+                "%02d%07.4f%c",
+                ideg,
+//                min+0.00001, // Correct possible unbiased rounding
+                min,
+                ns);
+            break;
+
+        case(CONVERT_UP_TRK): /* for tracklog files */
+            xastir_snprintf(str,
+                str_len,
+                "%c%02d %07.4f",
+                ns,
+                ideg,
+//                min+0.00001); // Correct possible unbiased rounding
+                min);
+            break;
+
+        case(CONVERT_DEC_DEG):
+            xastir_snprintf(str,
+                str_len,
+                "%08.5f%c",
+//                (ideg+min/60.0)+0.000001, // Correct possible unbiased rounding
+                ideg+min/60.0,
+                ns);
+            break;
+
+        case(CONVERT_DMS_NORMAL):
+            xastir_snprintf(str,
+                str_len,
+                "%02d %02d %04.1f%c",
+                ideg,
+                imin,
+//                sec+0.01, // Correct possible unbiased rounding
+                sec,
+                ns);
+            break;
+        
+        case(CONVERT_DMS_NORMAL_FORMATED):
+            xastir_snprintf(str,
+                str_len,
+                "%02d�%02d\'%04.1f%c",
+                ideg,
+                imin,
+//                sec+0.01, // Correct possible unbiased rounding
+                sec,
+                ns);
+            break;
+
+        case(CONVERT_HP_NORMAL_FORMATED):
+            xastir_snprintf(str,
+                str_len,
+                "%02d�%06.3f%c",
+                ideg,
+//                min+0.0001, // Correct possible unbiased roundin
+                min,
+                ns);
+            break;
+        
+        case(CONVERT_HP_NORMAL):
+        default: /* do HP normal */
+            xastir_snprintf(str,
+                str_len,
+                "%02d %06.3f%c",
+                ideg,
+//                min+0.0001, // Correct possible unbiased rounding
+                min,
+                ns);
+            break;
+    }
+}
+
+
+
+
+
+// convert longitude from long to string
+// Input is in Xastir coordinate system
+//
+// CONVERT_LP_NOSP      = DDDMM.MME
+// CONVERT_HP_NOSP      = DDDMM.MMME
+// CONVERT_VHP_NOSP     = DDDMM.MMMME
+// CONVERT_LP_NORMAL    = DDD MM.MME
+// CONVERT_HP_NORMAL    = DDD MM.MMME
+// CONVERT_UP_TRK       = EDDD MM.MMMM
+// CONVERT_DEC_DEG      = DDD.DDDDDE
+// CONVERT_DMS_NORMAL   = DDD MM SS.SN
+// CONVERT_DMS_NORMAL_FORMATED   = DDD'MM'SS.SN
+//
+void convert_lon_l2s(long lon, char *str, int str_len, int type) {
+    char ew;
+    float deg, min, sec;
+    int ideg, imin;
+    long temp;
+
+    str[0] = '\0';
+    deg = (float)(lon - 64800000l) / 360000.0;
+
+    // Switch to integer arithmetic to avoid floating-point rounding
+    // errors.
+    temp = (long)(deg * 100000);
+
+    ew = 'E';
+    if (temp <= 0) {
+        ew = 'W';
+        temp = labs(temp);
+    }
+
+    ideg = (int)temp / 100000;
+    min = (temp % 100000) * 60.0 / 100000.0;
+
+    // Again switch to integer arithmetic to avoid floating-point
+    // rounding errors.
+    temp = (long)(min * 1000);
+    imin = (int)(temp / 1000);
+    sec = (temp % 1000) * 60.0 / 1000.0;
+
+    switch(type) {
+
+        case(CONVERT_LP_NOSP): /* do low P w/nospacel */
+            xastir_snprintf(str,
+                str_len,
+                "%03d%05.2f%c",
+                ideg,
+//                min+0.001, // Correct possible unbiased rounding
+                min,
+                ew);
+            break;
+
+        case(CONVERT_LP_NORMAL): /* do low P normal */
+            xastir_snprintf(str,
+                str_len,
+                "%03d %05.2f%c",
+                ideg,
+//                min+0.001, // Correct possible unbiased rounding
+                min,
+                ew);
+            break;
+
+        case(CONVERT_HP_NOSP): /* do HP w/nospace */
+            xastir_snprintf(str,
+                str_len,
+                "%03d%06.3f%c",
+                ideg,
+//                min+0.0001, // Correct possible unbiased rounding
+                min,
+                ew);
+            break;
+
+        case(CONVERT_VHP_NOSP): /* do Very HP w/nospace */
+            xastir_snprintf(str,
+                str_len,
+                "%03d%07.4f%c",
+                ideg,
+//                min+0.00001, // Correct possible unbiased rounding
+                min,
+                ew);
+            break;
+
+        case(CONVERT_UP_TRK): /* for tracklog files */
+            xastir_snprintf(str,
+                str_len,
+                "%c%03d %07.4f",
+                ew,
+                ideg,
+//                min+0.00001); // Correct possible unbiased rounding
+                min);
+            break;
+
+        case(CONVERT_DEC_DEG):
+            xastir_snprintf(str,
+                str_len,
+                "%09.5f%c",
+//                (ideg+min/60.0)+0.000001, // Correct possible unbiased rounding
+                ideg+min/60.0,
+                ew);
+            break;
+
+        case(CONVERT_DMS_NORMAL):
+            xastir_snprintf(str,
+                str_len,
+                "%03d %02d %04.1f%c",
+                ideg,
+                imin,
+//                sec+0.01, // Correct possible unbiased rounding
+                sec,
+                ew);
+            break;
+
+        case(CONVERT_DMS_NORMAL_FORMATED):
+            xastir_snprintf(str,
+                str_len,
+                "%03d�%02d\'%04.1f%c",
+                ideg,
+                imin,
+//                sec+0.01, // Correct possible unbiased rounding
+                sec,
+                ew);
+            break;
+        
+        case(CONVERT_HP_NORMAL_FORMATED):
+            xastir_snprintf(str,
+                str_len,
+                "%03d�%06.3f%c",
+                ideg,
+//                min+0.0001, // Correct possible unbiased rounding
+                min,
+                ew);
+            break;
+
+        case(CONVERT_HP_NORMAL):
+        default: /* do HP normal */
+            xastir_snprintf(str,
+                str_len,
+                "%03d %06.3f%c",
+                ideg,
+//                min+0.0001, // Correct possible unbiased rounding
+                min,
+                ew);
+            break;
+    }
+}
+
+
+
+
+
+/* convert latitude from string to long with 1/100 sec resolution */
+//
+// Input is in [D]DMM.MM[MM]N format (degrees/decimal
+// minutes/direction)
+//
+long convert_lat_s2l(char *lat) {      /* N=0�, Ctr=90�, S=180� */
+    long centi_sec;
+    char copy[15];
+    char n[15];
+    char *p;
+    char offset;
+
+
+    // Find the decimal point if present
+    p = strstr(lat, ".");
+
+    if (p == NULL)  // No decimal point found
+        return(0l);
+
+    memset(copy, '\0', sizeof(copy));
+    offset = p - lat;   // Arithmetic on pointers
+    switch (offset) {
+        case 0:     // .MM[MM]N
+            return(0l); // Bad, no degrees or minutes
+            break;
+        case 1:     // M.MM[MM]N
+            return(0l); // Bad, no degrees
+            break;
+        case 2:     // MM.MM[MM]N
+            return(0l); // Bad, no degrees
+            break;
+        case 3:     // DMM.MM[MM]N
+            xastir_snprintf(copy,
+                sizeof(copy),
+                "0%s",  // Add a leading '0'
+                lat);
+            break;
+        case 4:     // DDMM.MM[MM]N
+            xastir_snprintf(copy,
+                sizeof(copy),
+                "%s",   // Copy verbatim
+                lat);
+            break;
+        default:
+            break;
+    }
+
+    copy[14] = '\0';
+    centi_sec=0l;
+    if (copy[4]=='.'
+            && (   (char)toupper((int)copy[ 5])=='N'
+                || (char)toupper((int)copy[ 6])=='N'
+                || (char)toupper((int)copy[ 7])=='N'
+                || (char)toupper((int)copy[ 8])=='N'
+                || (char)toupper((int)copy[ 9])=='N'
+                || (char)toupper((int)copy[10])=='N'
+                || (char)toupper((int)copy[11])=='N'
+                || (char)toupper((int)copy[ 5])=='S'
+                || (char)toupper((int)copy[ 6])=='S'
+                || (char)toupper((int)copy[ 7])=='S'
+                || (char)toupper((int)copy[ 8])=='S'
+                || (char)toupper((int)copy[ 9])=='S'
+                || (char)toupper((int)copy[10])=='S'
+                || (char)toupper((int)copy[11])=='S')) {
+
+        substr(n, copy, 2);       // degrees
+        centi_sec=atoi(n)*60*60*100;
+
+        substr(n, copy+2, 2);     // minutes
+        centi_sec += atoi(n)*60*100;
+
+        substr(n, copy+5, 4);     // fractional minutes
+        // Keep the fourth digit if present, as it resolves to 0.6
+        // of a 1/100 sec resolution.  Two counts make one count in
+        // the Xastir coordinate system.
+ 
+        // Extend the digits to full precision by adding zeroes on
+        // the end.
+        strncat(n, "0000", sizeof(n) - 1 - strlen(n));
+
+        // Get rid of the N/S character
+        if (!isdigit((int)n[2]))
+            n[2] = '0';
+        if (!isdigit((int)n[3]))
+            n[3] = '0';
+
+        // Terminate substring at the correct digit
+        n[4] = '\0';
+//fprintf(stderr,"Lat: %s\n", n);
+
+        // Add 0.5 (Poor man's rounding)
+        centi_sec += (long)((atoi(n) * 0.6) + 0.5);
+
+        if (       (char)toupper((int)copy[ 5])=='N'
+                || (char)toupper((int)copy[ 6])=='N'
+                || (char)toupper((int)copy[ 7])=='N'
+                || (char)toupper((int)copy[ 8])=='N'
+                || (char)toupper((int)copy[ 9])=='N'
+                || (char)toupper((int)copy[10])=='N'
+                || (char)toupper((int)copy[11])=='N') {
+            centi_sec = -centi_sec;
+        }
+
+        centi_sec += 90*60*60*100;
+    }
+    return(centi_sec);
+}
+
+
+
+
+
+/* convert longitude from string to long with 1/100 sec resolution */
+//
+// Input is in [DD]DMM.MM[MM]W format (degrees/decimal
+// minutes/direction).
+//
+long convert_lon_s2l(char *lon) {     /* W=0�, Ctr=180�, E=360� */
+    long centi_sec;
+    char copy[16];
+    char n[16];
+    char *p;
+    char offset;
+
+
+    // Find the decimal point if present
+    p = strstr(lon, ".");
+
+    if (p == NULL)  // No decimal point found
+        return(0l);
+
+    memset(copy, '\0', sizeof(copy));
+    offset = p - lon;   // Arithmetic on pointers
+    switch (offset) {
+        case 0:     // .MM[MM]N
+            return(0l); // Bad, no degrees or minutes
+            break;
+        case 1:     // M.MM[MM]N
+            return(0l); // Bad, no degrees
+            break;
+        case 2:     // MM.MM[MM]N
+            return(0l); // Bad, no degrees
+            break;
+        case 3:     // DMM.MM[MM]N
+            xastir_snprintf(copy,
+                sizeof(copy),
+                "00%s",  // Add two leading zeroes
+                lon);
+            break;
+        case 4:     // DDMM.MM[MM]N
+            xastir_snprintf(copy,
+                sizeof(copy),
+                "0%s",   // Add leading '0'
+                lon);
+            break;
+        case 5:     // DDDMM.MM[MM]N
+            xastir_snprintf(copy,
+                sizeof(copy),
+                "%s",   // Copy verbatim
+                lon);
+            break;
+        default:
+            break;
+    }
+
+    copy[15] = '\0';
+    centi_sec=0l;
+    if (copy[5]=='.'
+            && (   (char)toupper((int)copy[ 6])=='W'
+                || (char)toupper((int)copy[ 7])=='W'
+                || (char)toupper((int)copy[ 8])=='W'
+                || (char)toupper((int)copy[ 9])=='W'
+                || (char)toupper((int)copy[10])=='W'
+                || (char)toupper((int)copy[11])=='W'
+                || (char)toupper((int)copy[12])=='W'
+                || (char)toupper((int)copy[ 6])=='E'
+                || (char)toupper((int)copy[ 7])=='E'
+                || (char)toupper((int)copy[ 8])=='E'
+                || (char)toupper((int)copy[ 9])=='E'
+                || (char)toupper((int)copy[10])=='E'
+                || (char)toupper((int)copy[11])=='E'
+                || (char)toupper((int)copy[12])=='E')) {
+
+        substr(n,copy,3);    // degrees 013
+        centi_sec=atoi(n)*60*60*100;
+
+        substr(n,copy+3,2);  // minutes 26
+        centi_sec += atoi(n)*60*100;
+        // 01326.66E  01326.660E
+
+        substr(n,copy+6,4);  // fractional minutes 66E 660E or 6601
+        // Keep the fourth digit if present, as it resolves to 0.6
+        // of a 1/100 sec resolution.  Two counts make one count in
+        // the Xastir coordinate system.
+ 
+        // Extend the digits to full precision by adding zeroes on
+        // the end.
+        strncat(n, "0000", sizeof(n) - 1 - strlen(n));
+
+        // Get rid of the E/W character
+        if (!isdigit((int)n[2]))
+            n[2] = '0';
+        if (!isdigit((int)n[3]))
+            n[3] = '0';
+
+        n[4] = '\0';    // Make sure substring is terminated
+//fprintf(stderr,"Lon: %s\n", n);
+
+        // Add 0.5 (Poor man's rounding)
+        centi_sec += (long)((atoi(n) * 0.6) + 0.5);
+
+        if (       (char)toupper((int)copy[ 6])=='W'
+                || (char)toupper((int)copy[ 7])=='W'
+                || (char)toupper((int)copy[ 8])=='W'
+                || (char)toupper((int)copy[ 9])=='W'
+                || (char)toupper((int)copy[10])=='W'
+                || (char)toupper((int)copy[11])=='W'
+                || (char)toupper((int)copy[12])=='W') {
+            centi_sec = -centi_sec;
+        }
+
+        centi_sec +=180*60*60*100;;
+    }
+    return(centi_sec);
+}
+
+
+
+
+
+/*
+ *  Convert latitude from Xastir format to radian
+ */
+double convert_lat_l2r(long lat) {
+    double ret;
+    double degrees;
+
+    degrees = (double)(lat / (100.0*60.0*60.0)) -90.0;
+    ret = (-1)*degrees*(M_PI/180.0);
+    return(ret);
+}
+
+
+
+
+
+/*
+ *  Convert longitude from Xastir format to radian
+ */
+double convert_lon_l2r(long lon) {
+    double ret;
+    double degrees;
+
+    degrees = (double)(lon / (100.0*60.0*60.0)) -180.0;
+    ret = (-1)*degrees*(M_PI/180.0);
+    return(ret);
+}
+
+
+
+
+
+// Distance calculation (Great Circle) using the Haversine formula
+// (2-parameter arctan version), which gives better accuracy than
+// the "Law of Cosines" for short distances.  It should be
+// equivalent to the "Law of Cosines for Spherical Trigonometry" for
+// longer distances.  Haversine is a great-circle calculation.
+//
+//
+// Inputs:  lat1/long1/lat2/long2 in radians (double)
+//
+// Outputs: Distance in meters between them (double)
+//
+double calc_distance_haversine_radian(double lat1, double lon1, double lat2, double lon2) {
+    double dlon, dlat;
+    double a, c, d;
+    double R = EARTH_RADIUS_METERS;
+    #define square(x) (x)*(x)
+
+
+    dlon = lon2 - lon1;
+    dlat = lat2 - lat1;
+    a = square((sin(dlat/2.0))) + cos(lat1) * cos(lat2) * square((sin(dlon/2.0)));
+    c = 2.0 * atan2(sqrt(a), sqrt(1.0-a));
+    d = R * c;
+
+    return(d);
+}
+
+
+
+
+
+// Distance calculation (Great Circle) using the Haversine formula
+// (2-parameter arctan version), which gives better accuracy than
+// the "Law of Cosines" for short distances.  It should be
+// equivalent to the "Law of Cosines for Spherical Trigonometry" for
+// longer distances.  Haversine is a great-circle calculation.
+//
+//
+// Inputs:  lat1/long1/lat2/long2 in Xastir coordinate system (long)
+//
+// Outputs: Distance in meters between them (double)
+//
+double calc_distance_haversine(long lat1, long lon1, long lat2, long lon2) {
+    double r_lat1,r_lat2;
+    double r_lon1,r_lon2;
+
+    r_lat1 = convert_lat_l2r(lat1);
+    r_lon1 = convert_lon_l2r(lon1);
+    r_lat2 = convert_lat_l2r(lat2);
+    r_lon2 = convert_lon_l2r(lon2);
+
+    return(calc_distance_haversine_radian(r_lat1, r_lon1, r_lat2, r_lon2));
+}
+
+
+
+
+
+/*
+ *  Calculate distance in meters between two locations
+ *
+ *  What type of calculation is this, Rhumb Line distance or Great
+ *  Circle distance?
+ *  Answer:  "Law of Cosines for Spherical Trigonometry", which is a
+ *  great-circle calculation.
+ *
+ *
+ * Inputs:  lat1/long1/lat2/long2 in Xastir coordinate system (long)
+ *
+ * Outputs: Distance in meters between them (double)
+ *
+ */
+double calc_distance_law_of_cosines(long lat1, long lon1, long lat2, long lon2) {
+    double r_lat1,r_lat2;
+    double r_lon1,r_lon2;
+    double r_d;
+
+
+    r_lat1 = convert_lat_l2r(lat1);
+    r_lon1 = convert_lon_l2r(lon1);
+    r_lat2 = convert_lat_l2r(lat2);
+    r_lon2 = convert_lon_l2r(lon2);
+    r_d = acos(sin(r_lat1) * sin(r_lat2) + cos(r_lat1) * cos(r_lat2) * cos(r_lon1-r_lon2));
+
+//fprintf(stderr,"Law of Cosines Distance: %f\n",
+//    r_d*180*60/M_PI*1852);
+//fprintf(stderr,"     Haversine Distance: %f\n\n",
+//    calc_distance_haversine(lat1, lon1, lat2, lon2));
+
+    return(r_d*180*60/M_PI*1852);
+}
+
+
+
+
+
+// Here's where we choose which of the above two functions get used.
+//
+double calc_distance(long lat1, long lon1, long lat2, long lon2) {
+//    return(calc_distance_law_of_cosines(lat1, lon1, lat2, lon2));
+    return(calc_distance_haversine(lat1, lon1, lat2, lon2));
+}
+ 
+
+
+
+
+/*
+ *  Calculate distance between two locations in nautical miles and course from loc2 to loc1
+ *
+ *  What type of calculation is this, Rhumb Line distance or Great
+ *  Circle distance?
+ *  Answer:  "Law of Cosines for Spherical Trigonometry", which is a
+ *  great-circle calculation, or Haversine, also a great-circle
+ *  calculation.
+ *
+ *  NOTE:  The angle returned is a separate calculation, but using
+ *  the unit sphere distance in it's calculation.  A great circle
+ *  bearing is computed, not a Rhumb-line bearing.
+ *
+ *
+ * Inputs:  lat1/long1/lat2/long2 in Xastir coordinate system (long)
+ *          Length of course_deg string (int)
+ *
+ * Outputs: Distance in nautical miles between them (double).
+ *          course_deg (string)
+ *
+ */
+double calc_distance_course(long lat1, long lon1, long lat2, long lon2, char *course_deg, int course_deg_length) {
+    double ret;
+    double r_lat1, r_lat2;
+    double r_lon1, r_lon2;
+    double r_d, r_c, r_m;
+
+    r_lat1 = convert_lat_l2r(lat1);
+    r_lon1 = convert_lon_l2r(lon1);
+    r_lat2 = convert_lat_l2r(lat2);
+    r_lon2 = convert_lon_l2r(lon2);
+
+
+    // Compute the distance.  We have a choice between using Law of
+    // Cosines or Haversine Formula here.
+
+    // 1) Law of Cosines for Spherical Trigonometry.  This is
+    // unreliable for small distances because the inverse cosine is
+    // ill-conditioned.  A computer carrying seven significant
+    // digits can't distinguish the cosines of distances smaller
+    // than about one minute of arc.
+//    r_d = acos(sin(r_lat1) * sin(r_lat2) + cos(r_lat1) * cos(r_lat2) * cos(r_lon1-r_lon2));
+
+
+    // 2) Haversine Formula.  Returns answer in meters.
+    r_m = calc_distance_haversine_radian(r_lat1, r_lon1, r_lat2, r_lon2);
+    //
+    // Conversion from distance in meters back to unit sphere.  This
+    // is needed for the course calculation below as well as the
+    // later scaling up to feet/meters or miles/km.
+    r_d = r_m / EARTH_RADIUS_METERS; 
+
+
+    // Compute the great-circle bearing
+    if (cos(r_lat1) < 0.0000000001) {
+        if (r_lat1>0.0)
+            r_c=M_PI;
+        else
+            r_c=0.0;
+    } else {
+        if (sin((r_lon2-r_lon1))<0.0)
+            r_c = acos((sin(r_lat2)-sin(r_lat1)*cos(r_d))/(sin(r_d)*cos(r_lat1)));
+        else
+            r_c = (2*M_PI) - acos((sin(r_lat2)-sin(r_lat1)*cos(r_d))/(sin(r_d)*cos(r_lat1)));
+
+    }
+
+    // Return the course
+    xastir_snprintf(course_deg,
+        course_deg_length,
+        "%.1f",
+        (180.0/M_PI)*r_c);
+
+    // Return the distance (nautical miles?)
+    ret = r_d*180*60/M_PI;
+
+/*
+// Convert from nautical miles to feet
+fprintf(stderr,"Law of Cosines Distance: %fft\t%fmi\n",
+    ret*5280.0*1.15078, ret*1.15078);
+// Convert from meters to feet
+fprintf(stderr,"     Haversine Distance: %fft\t%fmi\n\n",
+    calc_distance_haversine(lat1, lon1, lat2, lon2)*3.28084,
+    calc_distance_haversine(lat1, lon1, lat2, lon2)/1000/1.609344);
+*/
+
+    return(ret);
+}
+
+
+
+
+
+//*****************************************************************
+// distance_from_my_station - compute distance from my station and
+//       course with a given call
+//
+// return distance and course
+//
+// Returns 0.0 for distance if station not found in database or the
+// station hasn't sent out a posit yet.
+//*****************************************************************
+
+double distance_from_my_station(char *call_sign, char *course_deg) {
+    DataRow *p_station;
+    double distance;
+    float value;
+    long l_lat, l_lon;
+
+    distance = 0.0;
+    l_lat = convert_lat_s2l(my_lat);
+    l_lon = convert_lon_s2l(my_long);
+    p_station = NULL;
+    if (search_station_name(&p_station,call_sign,1)) {
+        // Check whether we have a posit yet for this station
+        if ( (p_station->coord_lat == 0l)
+                && (p_station->coord_lon == 0l) ) {
+            distance = 0.0;
+        }
+        else {
+            value = (float)calc_distance_course(l_lat,
+                l_lon,
+                p_station->coord_lat,
+                p_station->coord_lon,
+                course_deg,
+                sizeof(course_deg));
+
+            if (english_units)
+                distance = value * 1.15078;         // nautical miles to miles
+            else
+                distance = value * 1.852;           // nautical miles to km
+        }
+//        fprintf(stderr,"DistFromMy: %s %s -> %f\n",temp_lat,temp_long,distance);
+    }
+    else {  // Station not found
+        distance = 0.0;
+    }
+
+    //fprintf(stderr,"Distance for %s: %f\n", call_sign, distance);
+
+    return(distance);
+}
+
+
+
+
+
+/*********************************************************************/
+/* convert_bearing_to_name - converts a bearing in degrees to        */
+/*   name for the bearing.  Expects the degrees as a text string     */
+/*   since that's what the preceding functions output.               */
+/* Set the opposite flag true for the inverse bearing (from vs to)   */
+/*********************************************************************/
+
+static struct {
+    double low,high;
+    char *dircode,*lang;
+} directions[] = {
+    {327.5,360,"N","SPCHDIRN00"},
+    {0,22.5,"N","SPCHDIRN00"},
+    {22.5,67.5,"NE","SPCHDIRNE0"},
+    {67.5,112.5,"E","SPCHDIRE00"},
+    {112.5,157.5,"SE","SPCHDIRSE0"},
+    {157.5,202.5,"S","SPCHDIRS00"},
+    {202.5,247.5,"SW","SPCHDIRSW0"},
+    {247.5,292.5,"W","SPCHDIRW00"},
+    {292.5,327.5,"NW","SPCHDIRNW0"},
+};
+
+
+
+char *convert_bearing_to_name(char *bearing, int opposite) {
+    double deg = atof(bearing);
+    int i;
+
+    if (opposite) {
+        if (deg > 180) deg -= 180.0;
+        else if (deg <= 180) deg += 180.0;
+    }
+    for (i = 0; i < (int)( sizeof(directions)/sizeof(directions[0]) ); i++) {
+        if (deg >= directions[i].low && deg < directions[i].high)
+            return langcode(directions[i].lang);
+    }
+    return "?";
+}
+
+
+
+
+
+// Calculate new position based on distance and angle.
+//
+// Input:   lat/long in Xastir coordinate system (100ths of seconds)
+//          distance in nautical miles
+//          angle in � true
+//
+// Outputs: *x_long, *y_lat in Xastir coordinate system (100ths of
+//           seconds)
+//
+//
+// From http://home.t-online.de/home/h.umland/Chapter12.pdf
+//
+// Dead-reckoning using distance in km, course C:
+// Lat_B� = Lat_A� + ( (360/40031.6) * distance * cos C )
+//
+// Dead-reckoning using distance in nm, course C:
+// Lat_B� = Lat_A� + ( (distance/60) * cos C )
+//
+// Average of two latitudes (required for next two equations)
+// Lat_M� = (Lat_A� + Lat_B�) / 2
+//
+// Dead-reckoning using distance in km, course C:
+// Lon_B� = Lon_A� + ( (360/40031.6) * distance * (sin C / cos
+// Lat_M) )
+//
+// Dead-reckoning using distance in nm, course C:
+// Lon_B� = Lon_A� + ( (distance/60) * (sin C / cos Lat_M) )
+//
+// If resulting longitude exceeds +/- 180�, subtract/add 360�.
+// 
+void compute_DR_position(long x_long,   // input
+        long y_lat,     // input
+        double range,   // input in nautical miles
+        double course,  // input in � true
+        long *x_long2,  // output
+        long *y_lat2) { // output
+    double bearing_radians, lat_M_radians;
+    float lat_A, lat_B, lon_A, lon_B, lat_M;
+    int ret;
+    unsigned long x_u_long, y_u_lat;
+
+
+//fprintf(stderr,"Distance:%fnm, Course:%f,  Time:%d\n",
+//    range,
+//    course,
+//    (int)(sec_now() - p_station->sec_heard));
+
+    // Bearing in radians
+    bearing_radians = (double)((course/360.0) * 2.0 * M_PI);
+
+    // Convert lat/long to floats
+    ret = convert_from_xastir_coordinates( &lon_A,
+        &lat_A,
+        x_long,
+        y_lat);
+
+    // Check if conversion ok
+    if (!ret) {
+        // Problem during conversion.  Exit without changes.
+        *x_long2 = x_long;
+        *y_lat2 = y_lat;
+        return;
+    }
+
+    // Compute new latitude
+    lat_B = (float)((double)(lat_A) + (range/60.0) * cos(bearing_radians));
+
+    // Compute mid-range latitude
+    lat_M = (lat_A + lat_B) / 2.0;
+
+    // Convert lat_M to radians
+    lat_M_radians = (double)((lat_M/360.0) * 2.0 * M_PI);
+
+    // Compute new longitude
+    lon_B = (float)((double)(lon_A)
+        + (range/60.0) * ( sin(bearing_radians) / cos(lat_M_radians)) );
+
+    // Test for out-of-bounds longitude, correct if so.
+    if (lon_B < -360.0)
+        lon_B = lon_B + 360.0;
+    if (lon_B >  360.0)
+        lon_B = lon_B - 360.0;
+
+//fprintf(stderr,"Lat:%f,  Lon:%f\n", lat_B, lon_B);
+
+    ret = convert_to_xastir_coordinates(&x_u_long,
+        &y_u_lat,
+        lon_B,
+        lat_B);
+
+    // Check if conversion ok
+    if (!ret) {
+        // Problem during conversion.  Exit without changes.
+        *x_long2 = x_long;
+        *y_lat2 = y_lat;
+        return;
+    }
+
+    // Convert from unsigned long to long
+    *x_long2 = (long)x_u_long;
+    *y_lat2  = (long)y_u_lat;
+}
+
+
+
+
+
+// Calculate new position based on speed/course/modified-time.
+// We'll call it from Create_object_item_tx_string() and from the
+// modify object/item routines to calculate a new position and stuff
+// it into the record along with the modification time before we
+// start off in a new direction.
+//
+// Input:   *p_station
+//
+// Outputs: *x_long, *y_lat in Xastir coordinate system (100ths of
+//           seconds)
+//
+//
+// From http://home.t-online.de/home/h.umland/Chapter12.pdf
+//
+// Dead-reckoning using distance in km, course C:
+// Lat_B� = Lat_A� + ( (360/40031.6) * distance * cos C )
+//
+// Dead-reckoning using distance in nm, course C:
+// Lat_B� = Lat_A� + ( (distance/60) * cos C )
+//
+// Average of two latitudes (required for next two equations)
+// Lat_M� = (Lat_A� + Lat_B�) / 2
+//
+// Dead-reckoning using distance in km, course C:
+// Lon_B� = Lon_A� + ( (360/40031.6) * distance * (sin C / cos
+// Lat_M) )
+//
+// Dead-reckoning using distance in nm, course C:
+// Lon_B� = Lon_A� + ( (distance/60) * (sin C / cos Lat_M) )
+//
+// If resulting longitude exceeds +/- 180�, subtract/add 360�.
+//
+//
+// Possible Problems/Changes:
+// --------------------------
+// *) Change to using last_modified_time for DR.  Also tweak the
+//    code so that we don't do incremental DR and use our own
+//    decoded objects to update everything.  If we keep the
+//    last_modified_time and the last_modified_position separate
+//    DR'ed objects/items, we can always use those instead of the
+//    other variables if we have a non-zero speed.
+//
+// *) Make sure not to corrupt our position of the object when we
+//    receive the packet back via loopback/RF/internet.  In
+//    particular the position and the last_modified_time should stay
+//    constant in this case so that dead-reckoning can continue to
+//    move the object consistently, plus we won't compound errors as
+//    we go.
+//
+// *) A server Xastir sees empty strings on it's server port when
+//    these objects are transmitted to it.  Investigate.  It
+//    sometimes does it when speed is 0, but it's not consistent.
+//
+// *) Get the last_modified_time embedded into the logfile so that
+//    we don't "lose time" if we shut down for a bit.  DR'ed objects
+//    will be at the proper positions when we start back up.
+// 
+void compute_current_DR_position(DataRow *p_station, long *x_long, long *y_lat) {
+    int my_course = 0;  // In � true
+    double range = 0.0;
+    double bearing_radians, lat_M_radians;
+    float lat_A, lat_B, lon_A, lon_B, lat_M;
+    int ret;
+    unsigned long x_u_long, y_u_lat;
+    time_t secs_now;
+
+
+    secs_now=sec_now();
+
+
+    // Check whether we have course in the current data
+    //
+    if ( (strlen(p_station->course)>0) && (atof(p_station->course) > 0) ) {
+
+        my_course = atoi(p_station->course);    // In � true
+    }
+    //
+    // Else check whether the previous position had a course.  Note
+    // that newest_trackpoint if it exists should be the same as the
+    // current data, so we have to go back one further trackpoint.
+    // Make sure in this case that this trackpoint has occurred
+    // within the dead-reckoning timeout period though, else ignore
+    // it.
+    //
+    else if ( (p_station->newest_trackpoint != NULL)
+            && (p_station->newest_trackpoint->prev != NULL)
+            && (p_station->newest_trackpoint->prev->course != -1)   // Undefined
+            && ( (secs_now-p_station->newest_trackpoint->prev->sec) < dead_reckoning_timeout) ) {
+
+        // In � true
+        my_course = p_station->newest_trackpoint->prev->course;
+    }
+
+
+    // Get distance in nautical miles from the current data
+    //
+    if ( (strlen(p_station->speed)>0) && (atof(p_station->speed) >= 0) ) {
+
+        // Speed is in knots (same as nautical miles/hour)
+        range = (double)( (sec_now() - p_station->sec_heard)
+            * ( atof(p_station->speed) / 3600.0 ) );
+    }
+    //
+    // Else check whether the previous position had speed.  Note
+    // that newest_trackpoint if it exists should be the same as the
+    // current data, so we have to go back one further trackpoint.
+    //
+    else if ( (p_station->newest_trackpoint != NULL)
+            && (p_station->newest_trackpoint->prev != NULL)
+            && (p_station->newest_trackpoint->prev->speed != -1) // Undefined
+            && ( (secs_now-p_station->newest_trackpoint->prev->sec) < dead_reckoning_timeout) ) {
+
+        // Speed is in units of 0.1km/hour.  Different than above!
+        range = (double)( (sec_now() - p_station->sec_heard)
+            * ( p_station->newest_trackpoint->prev->speed / 10 * 0.5399568 / 3600.0 ) );
+    }
+
+
+//fprintf(stderr,"Distance:%fnm, Course:%d,  Time:%d\n",
+//    range,
+//    my_course,
+//    (int)(sec_now() - p_station->sec_heard));
+
+    // Bearing in radians
+    bearing_radians = (double)((my_course/360.0) * 2.0 * M_PI);
+
+    // Convert lat/long to floats
+    ret = convert_from_xastir_coordinates( &lon_A,
+        &lat_A,
+        p_station->coord_lon,
+        p_station->coord_lat);
+
+    // Check if conversion ok
+    if (!ret) {
+        // Problem during conversion.  Exit without changes.
+        *x_long = p_station->coord_lon;
+        *y_lat = p_station->coord_lat;
+        return;
+    }
+
+    // Compute new latitude
+    lat_B = (float)((double)(lat_A) + (range/60.0) * cos(bearing_radians));
+
+    // Compute mid-range latitude
+    lat_M = (lat_A + lat_B) / 2.0;
+
+    // Convert lat_M to radians
+    lat_M_radians = (double)((lat_M/360.0) * 2.0 * M_PI);
+
+    // Compute new longitude
+    lon_B = (float)((double)(lon_A)
+        + (range/60.0) * ( sin(bearing_radians) / cos(lat_M_radians)) );
+
+    // Test for out-of-bounds longitude, correct if so.
+    if (lon_B < -360.0)
+        lon_B = lon_B + 360.0;
+    if (lon_B >  360.0)
+        lon_B = lon_B - 360.0;
+
+//fprintf(stderr,"Lat:%f,  Lon:%f\n", lat_B, lon_B);
+
+    ret = convert_to_xastir_coordinates(&x_u_long,
+        &y_u_lat,
+        lon_B,
+        lat_B);
+
+    // Check if conversion ok
+    if (!ret) {
+        // Problem during conversion.  Exit without changes.
+        *x_long = p_station->coord_lon;
+        *y_lat = p_station->coord_lat;
+        return;
+    }
+
+    // Convert from unsigned long to long
+    *x_long = (long)x_u_long;
+    *y_lat  = (long)y_u_lat;
+}
+
+
+
+
+
+int filethere(char *fn) {
+    FILE *f;
+    int ret;
+
+    ret =0;
+    f=fopen(fn,"r");
+    if (f != NULL) {
+        ret=1;
+        (void)fclose(f);
+    }
+    return(ret);
+}
+
+
+
+
+
+int filecreate(char *fn) {
+    FILE *f;
+    int ret;
+
+    if (! filethere(fn)) {   // If no file
+
+        ret = 0;
+        fprintf(stderr,"Making user %s file\n", fn);
+        f=fopen(fn,"w+");   // Create it
+        if (f != NULL) {
+            ret=1;          // We were successful
+            (void)fclose(f);
+        }
+        return(ret);        // Couldn't create file for some reason
+    }
+    return(1);  // File already exists
+}
+
+
+
+
+
+time_t file_time(char *fn) {
+    struct stat file_status;
+
+    if(stat(fn,&file_status)==0)
+        return((time_t)file_status.st_ctime);
+
+    return(-1);
+}
+
+
+
+
+
+// Function written by Adam Hahn, AI4QB.  Contributed to the public
+// domain.  We've modified it from his initial code so any bugs are
+// our fault.
+int copy_file(char *infilename, char *outfilename) {
+    FILE *infile, *outfile;
+    char *buffer;
+    size_t numread = 0;
+
+
+    if ((infile = fopen(infilename,"rb")) > (FILE *)0) {
+
+        if ((outfile = fopen(outfilename,"wb")) > (FILE *)0) {
+            buffer = (char *)malloc(1024);
+
+            while (!feof(infile)) {
+                numread = fread(buffer, 1, 1024, infile);
+                fwrite(buffer, 1, numread, outfile);
+            }
+            free(buffer);
+            fflush(outfile);
+            fclose(outfile);
+        }
+        else {
+            fprintf(stderr,"Error opening destination file %s for writing", outfilename);
+            fclose(infile);
+            return(1);
+        }
+        fclose(infile);
+    }
+    else {
+        fprintf(stderr,"Error opening source file %s for reading", infilename);
+        return(1);
+    }
+    return 0;
+}
+
+
+
+
+
+// used by log_data 
+void rotate_file(char *file, int max_keep ){
+    int i; 
+    char file_a[MAX_FILENAME];
+    char file_b[MAX_FILENAME];
+    struct stat file_status;
+
+    if (debug_level & 1) {
+        fprintf(stderr, "Rotating: %s. Will keep %d \n", file, max_keep);
+    }
+
+    for(i=max_keep;i>=1;i--){
+
+    if (debug_level & 1) {
+        fprintf(stderr, "rotate: %s : %s\n", file_b, file_a);
+    }
+
+        xastir_snprintf(file_a,sizeof(file_a),"%s.%d",file,i); 
+        xastir_snprintf(file_b,sizeof(file_b),"%s.%d",file,i-1); 
+
+        unlink (file_a);
+        if (stat(file_a, &file_status) == 0) {
+            // We got good status.  That means it didn't get deleted!
+            fprintf(stderr,
+                "Couldn't delete file '%s': %s",
+                file_a,strerror(errno));
+        return;
+        }
+
+        // Rename previous to next
+        //
+        // Check whether file_b exists
+        if (stat(file_b, &file_status) == 0) {
+            if (!S_ISREG(file_status.st_mode)) {
+                fprintf(stderr,
+                    "Couldn't stat %s\n",
+                    file_b);
+                break; 
+            }
+            if ( rename (file_b, file_a) ) {
+                fprintf(stderr,
+                    "Couldn't rename %s to %s, cancelling log_rotate()\n",
+                    file_b,
+                    file_a);
+                return;
+            }
+        }
+    
+    }
+
+    if (debug_level & 1) {
+        fprintf(stderr, "rotate: %s : %s\n", file, file_a);
+    }
+
+    if ( rename (file, file_a) ) {
+	fprintf(stderr,
+	"Couldn't rename %s to %s, cancelling log_rotate()\n",
+		file,
+                file_a);
+    }
+  
+    return; 
+}
+
+
+
+
+
+char *fetch_file_line(FILE *f, char *line) {
+    char cin;
+    int pos;
+
+
+    pos = 0;
+    line[0] = '\0';
+
+    while (!feof(f)) {
+
+        // Read one character at a time
+        if (fread(&cin,1,1,f) == 1) {
+
+            if (pos < MAX_LINE_SIZE) {
+                if (cin != (char)13)    // CR
+                    line[pos++] = cin;
+            }
+
+            if (cin == (char)10) { // Found LF as EOL char
+                line[pos++] = '\0'; // Always add a terminating zero after last char
+                pos = 0;          // start next line
+                return(line);
+            }
+        }
+    }
+
+    // Must be end of file
+    line[pos] = '\0';
+    return(line);
+}
+ 
+
+
+
+
+// Restore weather alerts so that we have a clear picture of the
+// current state.  Check timestamps on the file.  If relatively
+// current, read the file in.
+//
+void load_wx_alerts_from_log_working_sub(time_t time_now, char *filename) {
+    time_t file_timestamp;
+    int file_age;
+    int expire_limit;   // In seconds
+    char line[MAX_LINE_SIZE+1];
+    FILE *f;
+
+
+    expire_limit = 60 * 60 * 24 * 15;   // 15 days
+//    expire_limit = 60 * 60 * 24 * 1;   // 1 day
+ 
+    file_timestamp = file_time(filename);
+
+    if (file_timestamp == -1) {
+//        fprintf(stderr,"File %s doesn't exist\n", filename);
+        return;
+    }
+
+    file_age = time_now - file_timestamp;
+
+    if ( file_age > expire_limit) {
+//        fprintf(stderr,"Old file: %s, skipping...\n", filename);
+        return;
+    }
+ 
+//    fprintf(stderr,"File is current: %s\n", filename);
+
+    // Read the file in, as it exists and is relatively new.
+
+    // Check timestamps before each log line and skip those that are
+    // old.  Lines in the file should look about like this:
+    //
+    // # 1157027319  Thu Aug 31 05:28:39 PDT 2006
+    // OUNSWO>APRS::SKYOUN   :OUN Check For Activation VCEAB
+    // # 1157027319  Thu Aug 31 05:28:39 PDT 2006
+    // LZKFFS>APRS::NWS_ADVIS:311324z,FLOOD,ARC67-147 V1PAA
+    //
+    // We could try to use the regular read_file and read_file_ptr
+    // scheme for reading in the log file, but we'd have to modify
+    // it in two ways:  We need to keep from bringing up the
+    // interfaces so we'd need to set a flag when done reading and
+    // then start them, plus we'd need to have it check the
+    // timestamps and skip old ones.  Instead we'll do it all on our
+    // own here so that we can control everything ourselves.
+
+    f = fopen(filename, "r");
+    if (!f) {
+        fprintf(stderr,"Wx Alert log file could not be opened for reading\n");
+        return;
+    }
+
+    while (!feof(f)) {  // Read until end of file
+
+        (void)fetch_file_line(f, line);
+ 
+restart_sync:
+
+        if (line[0] == '\0') {
+            // Empty line found, skip
+        }
+
+        else if (line[0] == '#') { // Timestamp line, check the date
+            time_t line_stamp;
+            int line_age;
+
+            if (strlen(line) < 3) { // Line is too short, skip
+                goto restart_sync;
+            }
+
+            line_stamp = atoi(&line[2]);
+            line_age = time_now - line_stamp;
+//fprintf(stderr, "Age: %d\t", line_age);
+
+            if ( line_age < expire_limit) {
+                // Age is good, read next line and process it
+
+                (void)fetch_file_line(f, line);
+
+                if (line[0] != '#') { // It's a packet, not a timestamp line
+//fprintf(stderr,"%s\n",line);
+                    decode_ax25_line(line,'F',-1, 1);   // Decode the packet
+                }
+                else {
+                    goto restart_sync;
+                }
+            }
+        }
+    }
+    if (feof(f)) { // Close file if at the end
+        (void)fclose(f);
+    }
+}
+
+
+
+
+
+// Restore weather alerts so that we have a clear picture of the
+// current state.  Do this before we start the interfaces.  Only
+// reload if the log files datestamps are relatively current.
+//
+// Check timestamps on each file in turn.  If relatively
+// current, read them in the correct order:
+// wx_alert.log.3
+// wx_alert.log.2
+// wx_alert.log.1
+// wx.alert.log
+//
+void load_wx_alerts_from_log(void) {
+    time_t time_now;
+    char filename[MAX_FILENAME];
+    char logfile_path[MAX_VALUE];
+
+    get_user_base_dir(LOGFILE_WX_ALERT,logfile_path, sizeof(logfile_path));
+
+    time_now = sec_now();
+
+    fprintf(stderr,"*** Reading WX Alert log files\n");
+
+    // wx_alert.log.3
+    xastir_snprintf(filename,
+        sizeof(filename),
+        "%s.3",
+        logfile_path ); 
+    load_wx_alerts_from_log_working_sub(time_now, filename);
+
+    // wx_alert.log.2
+    xastir_snprintf(filename,
+        sizeof(filename),
+        "%s.2",
+        logfile_path ); 
+    load_wx_alerts_from_log_working_sub(time_now, filename);
+
+    // wx_alert.log.1
+    xastir_snprintf(filename,
+        sizeof(filename),
+        "%s.1",
+        logfile_path ); 
+    load_wx_alerts_from_log_working_sub(time_now, filename);
+
+    // wx_alert.log
+    xastir_snprintf(filename,
+        sizeof(filename),
+        "%s",
+        logfile_path ); 
+    load_wx_alerts_from_log_working_sub(time_now, filename);
+
+    fill_in_new_alert_entries();
+
+    fprintf(stderr,"*** Done with WX Alert log files\n");
+}
+
+
+
+
+
+// Note that the length of "line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+void log_data(char *file, char *line) {
+    FILE *f;
+    struct stat file_status; 
+    int reset_setuid = 0 ; 
+
+
+    // Check for "# Tickle" first, don't log it if found.
+    // It's an idle string designed to keep the socket active.
+    if ( (strncasecmp(line, "#Tickle", 7)==0)
+        || (strncasecmp(line, "# Tickle", 8) == 0) ) {
+        return;
+    }
+    else {
+        char temp[200];
+        char timestring[100+1];
+        struct tm *time_now;
+        time_t secs_now;
+
+        // Fetch the current date/time string
+//        get_timestamp(timestring);
+        secs_now=sec_now();
+
+        time_now = localtime(&secs_now);
+
+        (void)strftime(timestring,100,"%a %b %d %H:%M:%S %Z %Y",time_now);
+
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "# %ld  %s",
+            (unsigned long)secs_now,
+            timestring);
+
+        // Change back to the base directory
+
+// This call corrupts the "file" variable.  Commented it out as we
+// don't appear to need it anyway.  The complete root-anchored
+// path/filename are passed to us in the "file" parameter.
+//
+//        chdir(get_user_base_dir(""));
+
+        // check size and rotate if too big
+
+        if (stat(file, &file_status)==0){
+
+//            if (debug_level & 1) {
+//                fprintf(stderr, "log_data(): logfile size: %ld \n",(long) file_status.st_size);
+//            }
+
+            if ((file_status.st_size + strlen(temp) + strlen(line) )> MAX_LOGFILE_SIZE){
+                if (debug_level & 1) {
+                    fprintf(stderr, "log_data(): calling rotate_file()\n");
+                }       
+
+                rotate_file(file,3);        
+            }
+
+        }
+        else {
+            // ENOENT is ok -- we make the file below
+            if (errno != ENOENT ) {
+                fprintf(stderr,"Couldn't stat log file '%s': %s\n",
+                    file,strerror(errno));
+                return;                     
+            }
+
+        }        
+
+       if (getuid() != geteuid()){
+            reset_setuid=1; 
+            DISABLE_SETUID_PRIVILEGE;
+        }
+
+        f=fopen(file,"a");
+        if (f!=NULL) {
+            fprintf(f,"%s\n", temp); // Write the timestamp line
+            fprintf(f,"%s\n",line);  // Write the data line
+            (void)fclose(f);
+        }
+        else {
+            fprintf(stderr,"Couldn't open file for appending: %s\n", file);
+        }
+
+        if(reset_setuid){
+            ENABLE_SETUID_PRIVILEGE;
+        }
+    }
+}
+
+
+
+
+
+//
+// Tactical callsign logging
+//
+// Logging function called from the Assign Tactical Call right-click
+// menu option and also from db.c:fill_in_tactical_call.  Each
+// tactical assignment is logged as one line.
+//
+// We need to check for identical callsigns in the file, deleting
+// lines that have the same name and adding new records to the end.
+// Actually  BAD IDEA!  We want to keep the history of the tactical
+// calls so that we can trace the changes later.
+//
+// Best method:  Look for lines containing matching callsigns and
+// comment them out, adding the new tactical callsign at the end of
+// the file.
+//
+// Do we need to use a special marker to mean NO tactical callsign
+// is assigned?  This is for when we had a tactical call but now
+// we're removing it.  The reload_tactical_calls() routine below
+// would need to match.  Since we're using comma-delimited files, we
+// can just check for an empty string instead.
+//
+void log_tactical_call(char *call_sign, char *tactical_call_sign) {
+    char file[MAX_VALUE];
+    FILE *f;
+
+
+    // Add it to our in-memory hash so that if stations expire and
+    // then appear again they get assigned the same tac-call.
+    add_tactical_to_hash(call_sign, tactical_call_sign);
+
+ 
+    get_user_base_dir("config/tactical_calls.log", file, sizeof(file));
+
+    f=fopen(file,"a");
+    if (f!=NULL) {
+
+        if (tactical_call_sign == NULL)
+            fprintf(f,"%s,\n",call_sign);
+        else
+            fprintf(f,"%s,%s\n",call_sign,tactical_call_sign);
+
+        (void)fclose(f);
+
+        if (debug_level & 1) {
+            fprintf(stderr,
+                "Saving tactical call to file: %s:%s",
+                call_sign,
+                tactical_call_sign);
+        }
+    }
+    else {
+        fprintf(stderr,"Couldn't open file for appending: %s\n", file);
+    }
+}
+
+
+
+
+
+//
+// Function to load saved tactical calls back into xastir.  This
+// is called on startup.  This implements persistent tactical calls
+// across xastir restarts.
+//
+// Here we create a hash lookup and store one record for each valid
+// line read from the tactical calls log file.  The key for each
+// hash entry is the callsign-SSID.  Here we simply read them in and
+// create the hash.  When a new station is heard on the air, it is
+// checked against this hash and the tactical call field filled in
+// if there is a match.
+//
+// Note that the length of "line" can be up to max_device_buffer,
+// which is currently set to 4096.
+//
+void reload_tactical_calls(void) {
+    char file[MAX_VALUE];
+    FILE *f;
+    char line[300+1];
+
+
+    get_user_base_dir("config/tactical_calls.log", file, sizeof(file));
+
+    f=fopen(file,"r");
+    if (f!=NULL) {
+
+        while (fgets(line, 300, f) != NULL) {
+
+            if (debug_level & 1)
+                fprintf(stderr,"loading tactical calls from file: %s",line);
+   
+            if (line[0] != '#') {   // skip comment lines
+                char *ptr;
+
+                // we're dealing with comma-separated files, so
+                // break the two pieces at the comma.
+                ptr = index(line,',');
+
+                if (ptr != NULL) {
+                    char *ptr2;
+
+
+                    ptr[0] = '\0';  // terminate the callsign
+                    ptr++;  // point to the tactical callsign
+
+                    // check for lf
+                    ptr2 = index(ptr,'\n');
+                    if (ptr2 != NULL)
+                        ptr2[0] = '\0';
+
+                    // check for cr
+                    ptr2 = index(ptr,'\r');
+                    if (ptr2 != NULL)
+                        ptr2[0] = '\0';
+
+                    if (debug_level & 1)
+                        fprintf(stderr, "Call=%s,\tTactical=%s\n", line, ptr);
+
+                    //                   call tac-call
+                    add_tactical_to_hash(line, ptr);
+                }
+            }
+        }
+        (void)fclose(f);
+    }
+    else {
+        if (debug_level & 1)
+            fprintf(stderr,"couldn't open file for reading: %s\n", file);
+    }
+
+/*
+    if (tactical_hash) {
+        fprintf(stderr,"Stations w/tactical calls defined: %d\n",
+            hashtable_count(tactical_hash));
+    }
+*/
+
+}
+
+
+
+
+
+// Returns time in seconds since the Unix epoch.
+//
+time_t sec_now(void) {
+    time_t timenw;
+    time_t ret;
+
+    ret = time(&timenw);
+    return(ret);
+}
+
+
+
+
+
+char *get_time(char *time_here) {
+    struct tm *time_now;
+    time_t timenw;
+
+    (void)time(&timenw);
+    time_now = localtime(&timenw);
+    (void)strftime(time_here,MAX_TIME,"%m%d%Y%H%M%S",time_now);
+    return(time_here);
+}
+
+
+
+
+
+///////////////////////////////////  Utilities  ////////////////////////////////////////////////////
+
+
+/*
+ *  Check for valid path and change it to TAPR format
+ *  Add missing asterisk for stations that we must have heard via a digi
+ *  Extract port for KAM TNCs
+ *  Handle igate injection ID formats: "callsign-ssid,I" & "callsign-0ssid"
+ *
+ * TAPR-2 Format:
+ * KC2ELS-1*>SX0PWT,RELAY,WIDE:`2`$l##>/>"4)}
+ *
+ * AEA Format:
+ * KC2ELS-1*>RELAY>WIDE>SX0PWT:`2`$l##>/>"4)}
+ */
+
+int valid_path(char *path) {
+    int i,len,hops,j;
+    int type,ast,allast,ins;
+    char ch;
+
+
+    len  = (int)strlen(path);
+    type = 0;       // 0: unknown, 1: AEA '>', 2: TAPR2 ',', 3: mixed
+    hops = 1;
+    ast  = 0;
+    allast = 0;
+
+    // There are some multi-port TNCs that deliver the port at the end
+    // of the path. For now we discard this information. If there is
+    // multi-port TNC support some day, we should write the port into
+    // our database.
+    // KAM:        /V /H
+    // KPC-9612:   /0 /1 /2
+    if (len > 2 && path[len-2] == '/') {
+        ch = path[len-1];
+        if (ch == 'V' || ch == 'H' || ch == '0' || ch == '1' || ch == '2') {
+            path[len-2] = '\0';
+            len  = (int)strlen(path);
+        }
+    }
+
+
+    // One way of adding igate injection ID is to add "callsign-ssid,I".
+    // We need to remove the ",I" portion so it doesn't count as another
+    // digi here.  This should be at the end of the path.
+    if (len > 2 && path[len-2] == ',' && path[len-1] == 'I') {  // Found ",I"
+        //fprintf(stderr,"%s\n",path);
+        //fprintf(stderr,"Found ',I'\n");
+        path[len-2] = '\0';
+        len  = (int)strlen(path);
+        //fprintf(stderr,"%s\n\n",path);
+    }
+    // Now look for the same thing but with a '*' character at the end.
+    // This should be at the end of the path.
+    if (len > 3 && path[len-3] == ',' && path[len-2] == 'I' && path[len-1] == '*') {  // Found ",I*"
+        //fprintf(stderr,"%s\n",path);
+        //fprintf(stderr,"Found ',I*'\n");
+        path[len-3] = '\0';
+        len  = (int)strlen(path);
+        //fprintf(stderr,"%s\n\n",path);
+    }
+
+
+    // Another method of adding igate injection ID is to add a '0' in front of
+    // the SSID.  For WE7U it would change to WE7U-00, for WE7U-15 it would
+    // change to WE7U-015.  Take out this zero so the rest of the decoding will
+    // work.  This should be at the end of the path.
+    // Also look for the same thing but with a '*' character at the end.
+    if (len > 6) {
+        for (i=len-1; i>len-6; i--) {
+            if (path[i] == '-' && path[i+1] == '0') {
+                //fprintf(stderr,"%s\n",path);
+                for (j=i+1; j<len; j++) {
+                    path[j] = path[j+1];    // Shift everything left by one
+                }
+                len = (int)strlen(path);
+                //fprintf(stderr,"%s\n\n",path);
+            }
+            // Check whether we just chopped off the '0' from "-0".
+            // If so, chop off the dash as well.
+            if (path[i] == '-' && path[i+1] == '\0') {
+                //fprintf(stderr,"%s\tChopping off dash\n",path);
+                path[i] = '\0';
+                len = (int)strlen(path);
+                //fprintf(stderr,"%s\n",path);
+            }
+            // Check for "-*", change to '*' only
+            if (path[i] == '-' && path[i+1] == '*') {
+                //fprintf(stderr,"%s\tChopping off dash\n",path);
+                path[i] = '*';
+                path[i+1] = '\0';
+                len = (int)strlen(path);
+                //fprintf(stderr,"%s\n",path);
+            }
+            // Check for "-0" or "-0*".  Change to "" or "*".
+            if ( path[i] == '-' && path[i+1] == '0' ) {
+                //fprintf(stderr,"%s\tShifting left by two\n",path);
+                for (j=i; j<len; j++) {
+                    path[j] = path[j+2];    // Shift everything left by two
+                }
+                len = (int)strlen(path);
+                //fprintf(stderr,"%s\n",path);
+            }
+        }
+    }
+
+
+    for (i=0,j=0; i<len; i++) {
+        ch = path[i];
+
+        if (ch == '>' || ch == ',') {   // found digi call separator
+            // We're at the start of a callsign entry in the path
+
+            if (ast > 1 || (ast == 1 && i-j > 10) || (ast == 0 && (i == j || i-j > 9))) {
+                if (debug_level & 1)
+                    fprintf(stderr, "valid_path(): Bad Path: More than one * in call or wrong call size\n");
+                return(0);              // more than one asterisk in call or wrong call size
+            }
+            ast = 0;                    // reset local asterisk counter
+            
+            j = i+1;                    // set to start of next call
+            if (ch == ',')
+                type |= 0x02;           // set TAPR2 flag
+            else
+                type |= 0x01;           // set AEA flag (found '>')
+            hops++;                     // count hops
+        }
+
+        else {                          // digi call character or asterisk
+            // We're in the middle of a callsign entry
+
+            if (ch == '*') {
+                ast++;                  // count asterisks in call
+                allast++;               // count asterisks in path
+            }
+            else if ((ch <'A' || ch > 'Z')      // Not A-Z
+                    && (ch <'a' || ch > 'z')    // Not a-z
+                    && (ch <'0' || ch > '9')    // Not 0-9
+                    && ch != '-') {
+                // Note that Q-construct and internet callsigns can
+                // have a-z in them, AX.25 callsigns cannot unless
+                // they are in a 3rd-party packet.
+
+                if (debug_level & 1)
+                    fprintf(stderr, "valid_path: Bad Path: Anti-loop stuff from aprsd or lower-case chars found\n");
+                return(0);          // wrong character in path
+            }
+        }
+    }
+    if (ast > 1 || (ast == 1 && i-j > 10) || (ast == 0 && (i == j || i-j > 9))) {
+        if (debug_level & 1)
+            fprintf(stderr, "valid_path: Bad Path: More than one * or wrong call size (2)\n");
+        return(0);                      // more than one asterisk or wrong call size
+    }
+
+    if (type == 0x03) {
+        if (debug_level & 1)
+            fprintf(stderr, "valid_path: Bad Path: Wrong format, both > and , in path\n");
+        return(0);                      // wrong format, both '>' and ',' in path
+    }
+
+    if (hops > 9) {                     // [APRS Reference chapter 3]
+        if (debug_level & 1)
+            fprintf(stderr, "valid_path: Bad Path: hops > 9\n");
+        return(0);                      // too much hops, destination + 0-8 digipeater addresses
+    }
+
+    if (type == 0x01) {
+        int delimiters[20];
+        int k = 0;
+        char dest[15];
+        char rest[100];
+
+        for (i=0; i<len; i++) {
+            if (path[i] == '>') {
+                path[i] = ',';          // Exchange separator character
+                delimiters[k++] = i;    // Save the delimiter indexes
+            }
+        }
+
+        // We also need to move the destination callsign to the end.
+        // AEA has them in a different order than TAPR-2 format.
+        // We'll move the destination address between delimiters[0]
+        // and [1] to the end of the string.
+
+        //fprintf(stderr,"Orig. Path:%s\n",path);
+        // Save the destination
+        xastir_snprintf(dest,sizeof(dest),"%s",&path[delimiters[--k]+1]);
+        dest[strlen(path) - delimiters[k] - 1] = '\0'; // Terminate it
+        dest[14] = '\0';    // Just to make sure
+        path[delimiters[k]] = '\0'; // Delete it from the original path
+        //fprintf(stderr,"Destination: %s\n",dest);
+
+        // TAPR-2 Format:
+        // KC2ELS-1*>SX0PWT,RELAY,WIDE:`2`$l##>/>"4)}
+        //
+        // AEA Format:
+        // KC2ELS-1*>RELAY>WIDE>SX0PWT:`2`$l##>/>"4)}
+        //          9     15   20
+
+        // We now need to insert the destination into the middle of
+        // the string.  Save part of it in another variable first.
+        xastir_snprintf(rest,
+            sizeof(rest),
+            "%s",
+            path);
+        //fprintf(stderr,"Rest:%s\n",rest);
+        xastir_snprintf(path,len+1,"%s,%s",dest,rest);
+        //fprintf(stderr,"New Path:%s\n",path);
+    }
+
+    if (allast < 1) {                   // try to insert a missing asterisk
+        ins  = 0;
+        hops = 0;
+
+        for (i=0; i<len; i++) {
+
+            for (j=i; j<len; j++) {             // search for separator
+                if (path[j] == ',')
+                    break;
+            }
+
+            if (hops > 0 && (j - i) == 5) {     // WIDE3
+                if (  path[ i ] == 'W' && path[i+1] == 'I' && path[i+2] == 'D' 
+                   && path[i+3] == 'E' && path[i+4] >= '0' && path[i+4] <= '9') {
+                    ins = j;
+                }
+            }
+
+/*
+Don't do this!  It can mess up relay/wide1-1 digipeating by adding
+an asterisk later in the path than the first unused digi.
+            if (hops > 0 && (j - i) == 7) {     // WIDE3-2
+                if (  path[ i ] == 'W' && path[i+1] == 'I' && path[i+2] == 'D' 
+                   && path[i+3] == 'E' && path[i+4] >= '0' && path[i+4] <= '9'
+                   && path[i+5] == '-' && path[i+6] >= '0' && path[i+6] <= '9'
+                   && (path[i+4] != path[i+6]) ) {
+                    ins = j;
+                }
+            }
+*/
+
+            if (hops > 0 && (j - i) == 6) {     // TRACE3
+                if (  path[ i ] == 'T' && path[i+1] == 'R' && path[i+2] == 'A' 
+                   && path[i+3] == 'C' && path[i+4] == 'E'
+                   && path[i+5] >= '0' && path[i+5] <= '9') {
+                    if (hops == 1)
+                        ins = j;
+                    else
+                        ins = i-1;
+                }
+            }
+
+/*
+Don't do this!  It can mess up relay/wide1-1 digipeating by adding
+an asterisk later in the path than the first unused digi.
+            if (hops > 0 && (j - i) == 8) {     // TRACE3-2
+                if (  path[ i ] == 'T' && path[i+1] == 'R' && path[i+2] == 'A' 
+                   && path[i+3] == 'C' && path[i+4] == 'E' && path[i+5] >= '0'
+                   && path[i+5] <= '9' && path[i+6] == '-' && path[i+7] >= '0'
+                   && path[i+7] <= '9' && (path[i+5] != path[i+7]) ) {
+                    if (hops == 1)
+                        ins = j;
+                    else
+                        ins = i-1;
+                }
+            }
+*/
+
+            hops++;
+            i = j;                      // skip to start of next call
+        }
+        if (ins > 0) {
+            for (i=len;i>=ins;i--) {
+                path[i+1] = path[i];    // generate space for '*'
+                // we work on a separate path copy which is long enough to do it
+            }
+            path[ins] = '*';            // and insert it
+        }
+    }
+    return(1);  // Path is good
+}
+
+
+
+
+
+/*
+ *  Check for a valid AX.25 call
+ *      Valid calls consist of up to 6 uppercase alphanumeric characters
+ *      plus optional SSID (four-bit integer)       [APRS Reference, AX.25 Reference]
+ */
+int valid_call(char *call) {
+    int len, ok;
+    int i, del, has_num, has_chr;
+    char c;
+
+    has_num = 0;
+    has_chr = 0;
+    ok      = 1;
+    len = (int)strlen(call);
+
+    if (len == 0)
+        return(0);                              // wrong size
+
+    while (call[0]=='c' && call[1]=='m' && call[2]=='d' && call[3]==':') {
+        // Erase TNC prompts from beginning of callsign.  This may
+        // not be the right place to do this, but it came in handy
+        // here, so that's where I put it. -- KB6MER
+
+        if (debug_level & 1) {
+            char filtered_data[MAX_LINE_SIZE+1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                call);
+            makePrintable(filtered_data);
+            fprintf(stderr,"valid_call: Command Prompt removed from: %s",
+                filtered_data);
+        }
+
+        for(i=0; call[i+4]; i++)
+            call[i]=call[i+4];
+
+        call[i++]=0;
+        call[i++]=0;
+        call[i++]=0;
+        call[i++]=0;
+        len=strlen(call);
+
+        if (debug_level & 1) {
+            char filtered_data[MAX_LINE_SIZE+1];
+
+            xastir_snprintf(filtered_data,
+                sizeof(filtered_data),
+                "%s",
+                call);
+            makePrintable(filtered_data);
+            fprintf(stderr," result: %s", filtered_data);
+        }
+    }
+
+    if (len > 9)
+        return(0);      // Too long for valid call (6-2 max e.g. KB6MER-12)
+
+    del = 0;
+    for (i=len-2;ok && i>0 && i>=len-3;i--) {   // search for optional SSID
+        if (call[i] =='-')
+            del = i;                            // found the delimiter
+    }
+    if (del) {                                  // we have a SSID, so check it
+        if (len-del == 2) {                     // 2 char SSID
+            if (call[del+1] < '1' || call[del+1] > '9')                         //  -1 ...  -9
+                del = 0;
+        }
+        else {                                  // 3 char SSID
+            if (call[del+1] != '1' || call[del+2] < '0' || call[del+2] > '5')   // -10 ... -15
+                del = 0;
+        }
+    }
+
+    if (del)
+        len = del;                              // length of base call
+
+    for (i=0;ok && i<len;i++) {                 // check for uppercase alphanumeric
+        c = call[i];
+
+        if (c >= 'A' && c <= 'Z')
+            has_chr = 1;                        // we need at least one char
+        else if (c >= '0' && c <= '9')
+            has_num = 1;                        // we need at least one number
+        else
+            ok = 0;                             // wrong character in call
+    }
+
+//    if (!has_num || !has_chr)                 // with this we also discard NOCALL etc.
+    if (!has_chr)                               
+        ok = 0;
+
+    ok = (ok && strcmp(call,"NOCALL") != 0);    // check for errors
+    ok = (ok && strcmp(call,"ERROR!") != 0);
+    ok = (ok && strcmp(call,"WIDE")   != 0);
+    ok = (ok && strcmp(call,"RELAY")  != 0);
+    ok = (ok && strcmp(call,"MAIL")   != 0);
+
+    return(ok);
+}
+
+
+
+
+
+/*
+ *  Check for a valid internet name.
+ *  Accept darned-near anything here as long as it is the proper
+ *  length and printable.
+ */
+int valid_inet_name(char *name, char *info, char *origin, int origin_size) {
+    int len, i, ok, oknws, okbom;
+    char *ptr;
+    
+    len = (int)strlen(name);
+
+    if (len > 9 || len == 0)            // max 9 printable ASCII characters
+        return(0);                      // wrong size
+
+    for (i=0;i<len;i++)
+        if (!isprint((int)name[i]))
+            return(0);                  // not printable
+
+    // Modifies "origin" if a match found
+    //
+    if (len >= 5 && strncmp(name,"aprsd",5) == 0) {
+        xastir_snprintf(origin, origin_size, "INET");
+        origin[4] = '\0';   // Terminate it
+        return(1);                      // aprsdXXXX is ok
+    }
+
+    // Modifies "origin" if a match found
+    if (len == 6) {                     // check for NWS or BOM
+        ok = 1;
+        oknws = 0;
+        okbom = 0;
+        for (i=0;i<6;i++)
+            if (name[i] <'A' || name[i] > 'Z')  // 6 uppercase characters
+                ok = 0;
+        ok = ok && (info != NULL);      // check if we can test info
+        if (ok) {
+            ptr = strstr(info,":NWS-"); // "NWS-" in info field (non-compressed alert)
+            oknws = (ptr != NULL);     
+
+            if (!oknws) {
+                ptr = strstr(info,":NWS_"); // "NWS_" in info field (compressed alert)
+                oknws = (ptr != NULL);     
+            }
+      
+            // If we've got here, it's not an NWS message, let's see if its a BOM message
+            if (!oknws) {
+                ptr = strstr(info,":BOM-"); // "BOM-" in info field (compressed alert)
+                okbom = (ptr != NULL);
+            }
+
+            if (!okbom) {
+                ptr = strstr(info,":BOM_"); // "BOM_" in info field (compressed alert)
+                okbom = (ptr != NULL);
+            }
+        }
+
+        // Depending on whether we had an NWS or BOM message, se the origin appropriately
+        if (oknws) {
+            xastir_snprintf(origin, origin_size, "INET-NWS");
+            origin[8] = '\0';
+            return(1);                      // weather alerts
+        }
+        if (okbom) {
+            xastir_snprintf(origin, origin_size, "INET-BOM");
+            origin[8] = '\0';
+            return(1);                      // weather alerts
+        }
+    }
+
+    return(1);  // Accept anything else if we get to this point in
+                // the code.  After all, the message came from the
+                // internet, not from RF.
+}
+
+
+
+
+
+/*
+ *  Keep track of last six digis that echo my transmission
+ */
+void upd_echo(char *path) {
+    int i,j,len;
+
+    if (echo_digis[5][0] != '\0') {
+        for (i=0;i<5;i++) {
+            xastir_snprintf(echo_digis[i],
+                MAX_CALLSIGN+1,
+                "%s",
+                echo_digis[i+1]);
+
+        }
+        echo_digis[5][0] = '\0';
+    }
+    for (i=0,j=0;i < (int)strlen(path);i++) {
+        if (path[i] == '*')
+            break;
+        if (path[i] == ',')
+            j=i;
+    }
+    if (j > 0)
+        j++;                    // first char of call
+    if (i > 0 && i-j <= 9) {
+        len = i-j;
+        for (i=0;i<5;i++) {     // look for free entry
+            if (echo_digis[i][0] == '\0')
+                break;
+        }
+        substr(echo_digis[i],path+j,len);
+    }
+}
+
+
+
+
+
+// dl9sau:
+// I liked to have xastir to compute the locator along with the normal coordinates.
+// The algorithm derives from dk5sg's util/qth.c (wampes)
+//
+// This computes Maidenhead grid coordinates and is used for both
+// the status line ("text2" widget) and the Coordinate Calculator at
+// present.
+//
+char *sec_to_loc(long longitude, long latitude)
+{
+  static char buf[7];
+  char *loc = buf;
+
+  // database.h:    long coord_lon;                     // Xastir coordinates 1/100 sec, 0 = 180�W
+  // database.h:    long coord_lat;                     // Xastir coordinates 1/100 sec, 0 =  90�N
+
+  longitude /= 100L;
+  latitude  =  2L * 90L * 3600L - 1L - (latitude / 100L);
+
+  *loc++ = (char) (longitude / 72000L + 'A'); longitude = longitude % 72000L;
+  *loc++ = (char) (latitude  / 36000L + 'A'); latitude  = latitude %  36000L;
+  *loc++ = (char) (longitude /  7200L + '0'); longitude = longitude %  7200L;
+  *loc++ = (char) (latitude  /  3600L + '0'); latitude  = latitude %   3600L;
+  *loc++ = (char) (longitude /   300L + 'a');
+  *loc++ = (char) (latitude  /   150L + 'a');
+  *loc   = 0;   // Terminate the string
+  return buf;
+}
+
+
+
+
+
+/*
+ *  Substring function WITH a terminating NULL char, needs a string of at least size+1
+ */
+void substr(char *dest, char *src, int size) {
+    xastir_snprintf(dest, size+1, "%s", src);
+}
+
+
+
+
+
+
+char *to_upper(char *data) {
+    int i;
+
+    for(i=strlen(data)-1;i>=0;i--)
+        if(islower((int)data[i]))
+            data[i]=toupper((int)data[i]);
+
+    return(data);
+}
+
+
+
+
+
+char *to_lower(char *data) {
+    int i;
+
+    for(i=strlen(data)-1;i>=0;i--)
+        if(isupper((int)data[i]))
+            data[i]=tolower((int)data[i]);
+
+    return(data);
+}
+
+
+
+
+
+int is_num_chr(char ch) {
+    return((int)isdigit(ch));
+}
+
+
+
+
+
+
+int is_num_or_sp(char ch) {
+    return((int)((ch >= '0' && ch <= '9') || ch == ' '));
+}
+
+
+
+
+
+
+int is_xnum_or_dash(char *data, int max){
+    int i;
+    int ok;
+
+    ok=1;
+    for(i=0; i<max;i++)
+        if(!(isxdigit((int)data[i]) || data[i]=='-')) {
+            ok=0;
+            break;
+        }
+
+    return(ok);
+}
+
+
+
+
+
+// not used
+int is_num_stuff(char *data, int max) {
+    int i;
+    int ok;
+
+    ok=1;
+    for(i=0; i<max;i++)
+        if(!(isdigit((int)data[i]) || data[i]=='-' || data[i]=='+' || data[i]=='.')) {
+            ok=0;
+            break;
+        }
+
+    return(ok);
+}
+
+
+
+
+
+// not used
+int is_num(char *data) {
+    int i;
+    int ok;
+
+    ok=1;
+    for(i=strlen(data)-1;i>=0;i--)
+        if(!isdigit((int)data[i])) {
+            ok=0;
+            break;
+        }
+
+    return(ok);
+}
+
+
+
+
+
+//--------------------------------------------------------------------
+//Removes all control codes ( < 1Ch ) from a string and set the 8th bit to zero
+void removeCtrlCodes(char *cp) {
+    int i,j;
+    int len = (int)strlen(cp);
+    unsigned char *ucp = (unsigned char *)cp;
+
+    for (i=0, j=0; i<=len; i++) {
+        ucp[i] &= 0x7f;                 // Clear 8th bit
+        if ( (ucp[i] >= (unsigned char)0x1c)           // Check for printable plus the Mic-E codes
+                || ((char)ucp[i] == '\0') )   // or terminating 0
+            ucp[j++] = ucp[i] ;        // Copy to temp if printable
+    }
+}
+
+
+
+
+
+//--------------------------------------------------------------------
+//Removes all control codes ( <0x20 or >0x7e ) from a string, including
+// CR's, LF's, tab's, etc.
+//
+void makePrintable(char *cp) {
+    int i,j;
+    int len = (int)strlen(cp);
+    unsigned char *ucp = (unsigned char *)cp;
+
+    for (i=0, j=0; i<=len; i++) {
+        ucp[i] &= 0x7f;                 // Clear 8th bit
+        if ( ((ucp[i] >= (unsigned char)0x20) && (ucp[i] <= (unsigned char)0x7e))
+              || ((char)ucp[i] == '\0') )     // Check for printable or terminating 0
+            ucp[j++] = ucp[i] ;        // Copy to (possibly) new location if printable
+    }
+}
+
+
+
+
+
+
+//----------------------------------------------------------------------
+// Implements safer mutex locking.  Posix-compatible mutex's will lock
+// up a thread if lock's/unlock's aren't in perfect pairs.  They also
+// allow one thread to unlock a mutex that was locked by a different
+// thread.
+// Remember to keep this thread-safe.  Need dynamic storage (no statics)
+// and thread-safe calls.
+//
+// In order to keep track of process ID's in a portable way, we probably
+// can't use the process ID stored inside the pthread_mutex_t struct.
+// There's no easy way to get at it.  For that reason we'll create
+// another struct that contains both the process ID and a pointer to
+// the pthread_mutex_t, and pass pointers to those structs around in
+// our programs instead.  The new struct is "xastir_mutex".
+//
+
+
+// Function to initialize the new xastir_mutex
+// objects before use.
+//
+void init_critical_section(xastir_mutex *lock) {
+#ifdef MUTEX_DEBUG
+    pthread_mutexattr_t attr;
+
+    // Note that this stuff is not POSIX, so is considered non-portable.
+    // Exists in Linux Threads implementation only?
+
+# ifdef __LSB__
+    // LSB VERSION (Linux Standard Base)
+    // Note that we _must_ use the newer pthread function in this
+    // case per LSB specs.
+    (void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+# else   // __LSB__
+    // NON_LSB VERSION
+    // Check first for newer pthread function
+#  ifdef HAVE_PTHREAD_MUTEXATTR_SETTYPE
+    (void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+#  else
+    // Use older, deprecated pthread function
+    (void)pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+#  endif  // HAVE_PTHREAD_MUTEXATTR_SETTYPE
+# endif  // __LSB__
+
+    (void)pthread_mutexattr_init(&attr);
+    (void)pthread_mutex_init(&lock->lock, &attr);
+#else   // MUTEX_DEBUG
+    (void)pthread_mutex_init(&lock->lock, NULL); // Set to default POSIX-compatible type
+#endif  // MUTEX_DEBUG
+
+    lock->threadID = 0;  // No thread has locked it yet
+}
+
+
+
+
+
+// Function which uses xastir_mutex objects to lock a
+// critical shared section of code or variables.  Makes
+// sure that only one thread can access the critical section
+// at a time.  If there are no problems, it returns zero.
+//
+int begin_critical_section(xastir_mutex *lock, char *text) {
+    pthread_t calling_thread;
+    int problems;
+#ifdef MUTEX_DEBUG
+    int ret;
+#endif  // MUTEX_DEBUG
+
+    problems = 0;
+
+    // Note that /usr/include/bits/pthreadtypes.h has the
+    // definition for pthread_mutex_t, and it includes the
+    // owner thread number:  _pthread_descr pthread_mutex_t.__m_owner
+    // It's probably not portable to use it though.
+
+    // Get thread number we're currently running under
+    calling_thread = pthread_self();
+
+    if (pthread_equal( lock->threadID, calling_thread ))
+    {
+        // We tried to lock something that we already have the lock on.
+        fprintf(stderr,"%s:Warning:This thread already has the lock on this resource\n", text);
+        problems++;
+        return(0);  // Return the OK code.  Skip trying the lock.
+    }
+
+    //if (lock->threadID != 0)
+    //{
+        // We tried to lock something that another thread has the lock on.
+        // This is normal operation.  The pthread_mutex_lock call below
+        // will put our process to sleep until the mutex is unlocked.
+    //}
+
+    // Try to lock it.
+#ifdef MUTEX_DEBUG
+    // Instead of blocking the thread, we'll loop here until there's
+    // no deadlock, printing out status as we go.
+    do {
+        ret = pthread_mutex_lock(&lock->lock);
+        if (ret == EDEADLK) {   // Normal operation.  At least two threads want this lock.
+            fprintf(stderr,"%s:pthread_mutex_lock(&lock->lock) == EDEADLK\n", text);
+            sched_yield();  // Yield the cpu to another thread
+        }
+        else if (ret == EINVAL) {
+            fprintf(stderr,"%s:pthread_mutex_lock(&lock->lock) == EINVAL\n", text);
+            fprintf(stderr,"Forgot to initialize the mutex object...\n");
+            problems++;
+            sched_yield();  // Yield the cpu to another thread
+        }
+    } while (ret == EDEADLK);
+
+    if (problems)
+        fprintf(stderr,"Returning %d to calling thread\n", problems);
+#else   // MUTEX_DEBUG
+    pthread_mutex_lock(&lock->lock);
+#endif  // MUTEX_DEBUG
+
+    // Note:  This can only be set AFTER we already have the mutex lock.
+    // Otherwise there may be contention with other threads for setting
+    // this variable.
+    //
+    lock->threadID = calling_thread;    // Save the threadID that we used
+                                        // to lock this resource
+
+    return(problems);
+}
+
+
+
+
+
+// Function which ends the locking of a critical section
+// of code.  If there are no problems, it returns zero.
+//
+int end_critical_section(xastir_mutex *lock, char *text) {
+    pthread_t calling_thread;
+    int problems;
+#ifdef MUTEX_DEBUG
+    int ret;
+#endif  // MUTEX_DEBUG
+
+    problems = 0;
+
+    // Get thread number we're currently running under
+    calling_thread = pthread_self();
+
+    if (lock->threadID == 0)
+    {
+        // We have a problem.  This resource hasn't been locked.
+        fprintf(stderr,"%s:Warning:Trying to unlock a resource that hasn't been locked:%ld\n",
+            text,
+            (long int)lock->threadID);
+        problems++;
+    }
+
+    if (! pthread_equal( lock->threadID, calling_thread ))
+    {
+        // We have a problem.  We just tried to unlock a mutex which
+        // a different thread originally locked.  Not good.
+        fprintf(stderr,"%s:Trying to unlock a resource that a different thread locked originally: %ld:%ld\n",
+            text,
+            (long int)lock->threadID,
+            (long int)calling_thread);
+        problems++;
+    }
+
+
+    // We need to clear this variable BEFORE we unlock the mutex, 'cuz
+    // other threads might be waiting to lock the mutex.
+    //
+    lock->threadID = 0; // We're done with this lock.
+
+
+    // Try to unlock it.  Compare the thread identifier we used before to make
+    // sure we should.
+
+#ifdef MUTEX_DEBUG
+    // EPERM error: We're trying to unlock something that we don't have a lock on.
+    ret = pthread_mutex_unlock(&lock->lock);
+
+    if (ret == EPERM) {
+        fprintf(stderr,"%s:pthread_mutex_unlock(&lock->lock) == EPERM\n", text);
+        problems++;
+    }
+    else if (ret == EINVAL) {
+        fprintf(stderr,"%s:pthread_mutex_unlock(&lock->lock) == EINVAL\n", text);
+        fprintf(stderr,"Someone forgot to initialize the mutex object\n");
+        problems++;
+    }
+
+    if (problems)
+        fprintf(stderr,"Returning %d to calling thread\n", problems);
+#else   // MUTEX_DEBUG
+    (void)pthread_mutex_unlock(&lock->lock);
+#endif  // MUTEX_DEBUG
+
+    return(problems);
+}
+
+
+
+
+
+#ifdef TIMING_DEBUG
+void time_mark(int start)
+{
+    static struct timeval t_start;
+    struct timeval t_cur;
+    long sec, usec;
+
+    if (start) {
+        gettimeofday(&t_start, NULL);
+        fprintf(stderr,"\nstart: 0.000000s");
+    }
+    else {
+        gettimeofday(&t_cur, NULL);
+        sec  = t_cur.tv_sec  - t_start.tv_sec;
+        usec = t_cur.tv_usec - t_start.tv_usec;
+        if (usec < 0) {
+            sec--;
+            usec += 1000000;
+        }
+        fprintf(stderr,"time:  %ld.%06lds\n", sec, usec);
+    }
+}
+#endif  // TIMING_DEBUG
+
+
+
+
+
+// Function which adds commas to callsigns (and other abbreviations?)
+// in order to make the text sound better when run through a Text-to-
+// Speech system.  We try to change only normal amateur callsigns.
+// If we find a number in the text before a dash is found, we
+// consider it to be a normal callsign.  We don't add commas to the
+// SSID portion of a call.
+void spell_it_out(char *text, int max_length) {
+    char buffer[2000];
+    int i = 0;
+    int j = 0;
+    int number_found_before_dash = 0;
+    int dash_found = 0;
+
+    while (text[i] != '\0') {
+
+        if (text[i] == '-')
+            dash_found++;
+
+        if (is_num_chr(text[i]) && !dash_found)
+            number_found_before_dash++;
+
+        buffer[j++] = text[i];
+
+        if (!dash_found) // Don't add commas to SSID
+            buffer[j++] = ',';
+
+        i++;
+    }
+    buffer[j] = '\0';
+
+    // Only use the new string if it kind'a looks like a callsign
+    if (number_found_before_dash)
+        xastir_snprintf(text, max_length, "%s", buffer);
+}
+
+
+
+
+
+#define kKey 0x73e2 // This is the seed for the key
+
+
+
+
+
+static short doHash(char *theCall) {
+    char rootCall[10]; // need to copy call to remove ssid from parse
+    char *p1 = rootCall;
+    short hash;
+    short i,len;
+    char *ptr = rootCall;
+
+    while ((*theCall != '-') && (*theCall != '\0')) *p1++ = toupper((int)(*theCall++));
+        *p1 = '\0';
+
+    hash = kKey; // Initialize with the key value
+    i = 0;
+    len = (short)strlen(rootCall);
+
+    while (i<len) {// Loop through the string two bytes at a time
+        hash ^= (unsigned char)(*ptr++)<<8; // xor high byte with accumulated hash
+        hash ^= (*ptr++); // xor low byte with accumulated hash
+        i += 2;
+    }
+    return (short)(hash & 0x7fff); // mask off the high bit so number is always positive
+}
+
+
+
+
+
+short checkHash(char *theCall, short theHash) {
+    return (short)(doHash(theCall) == theHash);
+}
+
+
+
+
+
+// Breaks up a string into substrings using an arbitrary character
+// as the delimiter.  Makes each entry in the array of char ptrs
+// point to one substring.  Modifies incoming string and cptr[]
+// array.  Send a character constant string to it and you'll get an
+// instant segfault (the function can't modify a char constant
+// string).  Use this function instead of strtok().
+//
+void split_string( char *data, char *cptr[], int max, char search_char ) {
+  int ii;
+  char *temp;
+  char *current = data;
+
+
+  // NULL each char pointer
+  for (ii = 0; ii < max; ii++) {
+    cptr[ii] = NULL;
+  }
+
+  // Save the beginning substring address
+  cptr[0] = current;
+
+  for (ii = 1; ii < max; ii++) {
+    temp = strchr(current,search_char);  // Find next search character
+
+    if(!temp) { // No search characters found 
+      return; // All done with string
+    }
+
+    // Store pointer to next substring in array
+    cptr[ii] = &temp[1];
+    current  = &temp[1];
+
+    // Overwrite search character  with end-of-string char and bump
+    // pointer by one.
+    temp[0] = '\0';
+  }
+}
+
+
+
+
+
+// Function to check for proper relations between the n-N
+// numbers.  Called from check_unproto_path() function below.
+//
+int check_n_N (int prev, int last) {
+    int bad_path = 0;
+
+
+    if (prev < last) {
+        // Whoa, n < N, not good
+        bad_path = 1;
+    }
+    else if (last > MAX_WIDES) {
+        // N is greater than MAX_WIDES
+        bad_path = 1;
+    }
+    else if (prev > MAX_WIDES) {
+        // n is greater than MAX_WIDES
+        bad_path = 1;
+    }
+    else if (last == 0) {
+        // N is 0, it's a used-up digipeater slot
+        bad_path = 1;
+    }
+    if (debug_level & 1 && bad_path)
+        fprintf(stderr,"n-N wrong\n");
+
+    return(bad_path);
+}
+
+
+
+
+
+// This function checks to make sure an unproto path falls within
+// the socially acceptable values, such as only one RELAY or
+// WIDE1-1 which may appear only as the first option, use of WIDE4-4
+// and higher should be questioned, etc.
+//
+// "MAX_WIDES" is defined in util.h
+//
+// Returns:
+//  1 = bad path
+//  0 = good path
+//
+int check_unproto_path ( char *data ) {
+    char *tmpdata;
+    char *tmp;
+    char *ViaCalls[10];
+    int bad_path, ii, have_relay, have_wide, have_widen;
+    int have_trace, have_tracen;
+    int lastp = 0;
+    int prevp = 0;
+    int last = 0;
+    int prev = 0;
+    int total_digi_length = 0;
+
+
+    if (debug_level & 1)
+        fprintf(stderr, "Input string: %s\n", data);
+
+    bad_path = ii = have_relay = have_wide = 0;
+    have_widen = have_trace = have_tracen = 0;
+
+    // Remember to free() tmpdata before we return
+#ifdef HAVE_STRNDUP
+    tmpdata = (char *)strndup(data, strlen(data));
+#else
+    tmpdata = (char *)strdup(data);
+#endif
+    (void)to_upper(tmpdata);
+    if ((tmp = strchr(tmpdata, '/'))) *tmp ='\0';// Only check VHF portion of path
+    split_string(tmpdata, ViaCalls, 10, ',');
+
+    for (ii = 0; ii < 10; ii++) {
+        lastp = 0;
+        prevp = 0;
+        last = 0;
+        prev = 0;
+
+
+        // Check for empty string in this slot
+        if (ViaCalls[ii] == NULL) {
+            // We're done.  Exit the loop with whatever flags were
+            // set in previous iterations.
+            if (debug_level & 1) {
+                fprintf(stderr,"NULL string, slot %d\n", ii);
+            }
+            break;
+        }
+        else {
+            if (debug_level & 1)
+                fprintf(stderr,"%s string, slot %d\n", ViaCalls[ii], ii);
+        }
+
+        lastp = strlen(ViaCalls[ii]) - 1;
+        prevp = lastp - 2;
+        // Snag the N character, convert to integer
+        last  = ViaCalls[ii][lastp] - 0x30;
+ 
+        if (prevp >= 0) {
+            // Snag the n character, convert to integer
+            prev = ViaCalls[ii][prevp] - 0x30;
+        }
+
+        // Check whether RELAY appears later in the path
+        if (!strncmp(ViaCalls[ii], "RELAY", 5)) {
+            have_relay++;
+            total_digi_length++;
+            if (ii != 0) {
+                // RELAY should not appear after the first item in a
+                // path!
+                bad_path = 1;
+                if (debug_level & 1)
+                    fprintf(stderr,"RELAY appears later in the path\n");
+                break;
+            }
+        }
+
+        // Check whether WIDE1-1 appears later in the path (the new
+        // "RELAY")
+        else if (!strncmp(ViaCalls[ii], "WIDE1-1", 7)) {
+            have_relay++;
+            total_digi_length++;
+            if (ii != 0) {
+                // WIDE1-1 should not appear after the first item in
+                // a path!
+                bad_path = 1;
+                if (debug_level & 1)
+                    fprintf(stderr,"WIDE1-1 appears later in the path\n");
+                break;
+            }
+        }
+
+        // Check whether WIDE2-1 appears first in the path.  This is
+        // fine, but don't trigger an error later because of another
+        // WIDEn-N after an initial WIDE2-1.  This is to allow paths
+        // like "WIDE2-1,WIDE-2-2" or "WIDE2-1,MD2-2"
+        else if ( (ii == 0) && (!strncmp(ViaCalls[ii], "WIDE2-1", 7)) ) {
+            total_digi_length++;
+            if (debug_level & 1)
+                fprintf(stderr,"Found initial WIDE2-1 (a good thing)\n");
+        }
+
+        // Check for WIDE/TRACE/WIDEn-N/TRACEn-N in the path
+        else if (strstr(ViaCalls[ii], "WIDE") || strstr(ViaCalls[ii], "TRACE")) {
+            // This is some variant of WIDE or TRACE, could be
+            // WIDE/WIDEn-N/TRACE/TRACEn-N
+            int is_wide = 0;
+
+
+            if (strstr(ViaCalls[ii], "WIDE")) {
+                is_wide++;
+            }
+
+            // Check for WIDEn-N or TRACEn-N
+            if (strstr(ViaCalls[ii], "-")) {
+                // This is a WIDEn-N or TRACEn-N callsign
+
+
+                // Here we are adding the unused portion of the
+                // WIDEn-N/TRACEn-N to the total_digi_length
+                // variable.  We use the unused portion because that
+                // way we're not fooled if people start with a
+                // number for N that is higher/lower than n.  The
+                // initial thought was to grab the higher of n or N,
+                // but those lines are commented out here.
+                //
+                //if (last > prev)
+                    total_digi_length += last;
+                //else
+                //    total_digi_length += prev;
+
+
+                // Check for previous WIDEn-N/TRACEn-N
+                if (have_widen || have_tracen) {
+                    // Already have a large area via
+                    bad_path = 1;
+                    if (debug_level & 1)
+                        fprintf(stderr,"Previous WIDEn-N or TRACEn-N\n");
+                    break;
+                }
+
+                // Perform WIDEn-N checks
+                if (is_wide) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found wideN-n at slot %d\n", ii);
+
+                    if (strcmp(ViaCalls[ii], "WIDE1-1") !=0) // Home station, RELAY replacement
+                        have_widen++;  // Note: We mark "have_relay" for
+                                       // "WIDE1-1" instead of "have_widen"
+
+                    // We know its a WIDEn-N, time to find out what n is
+                    if (strlen(ViaCalls[ii]) != 7) {
+                        // This should be WIDEn-N and should be
+                        // exactly 7 characters
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"String length of widen-N is not 7 characters, slot %d\n", ii);
+                        break;
+                    }
+
+                    // Check for proper relations between the n-N
+                    // numbers.
+                    if ( check_n_N(prev, last) ) {
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"In WIDEn-N checks, slot %d\n", ii);
+                        break;
+                    }
+                }
+
+                // Perform similar checks for TRACEn-N
+                else {
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found traceN-n, slot %d\n", ii);
+                    have_tracen++;
+
+                    // We know its a TRACEn-N time to find out what
+                    // n is
+                    if (strlen(ViaCalls[ii]) != 8) {
+                        // This should be TRACEn-N and should be
+                        // exactly 8 characters
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"String length of tracen-N is not 8 characters, slot %d\n", ii);
+                        break;
+                    }
+
+                    // Check for proper relations between the n-N
+                    // numbers.
+                    if ( check_n_N(prev, last) ) {
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"In TRACEn-N checks, slot %d\n", ii);
+                        break;
+                    }
+                }
+
+            }
+
+            else {
+                // We know we have a WIDE or TRACE in this callsign slot
+                total_digi_length++;
+                if (is_wide) {
+                    have_wide++;
+                }
+                else {
+                    have_trace++;
+                }
+
+                if (have_relay && (ii > MAX_WIDES)) {
+                    // RELAY and more than "MAX_WIDES" WIDE/TRACE calls
+// Here we could check have_wide/have_trace to see what the actual
+// count of WIDE/TRACE calls is at this point...
+                    bad_path = 1;
+                    if (debug_level & 1)
+                        fprintf(stderr,"Have relay and ii > MAX_WIDES\n");
+                    break;
+                }
+                else if (!have_relay && ii > (MAX_WIDES - 1)) {
+                    // More than WIDE,WIDE,WIDE or TRACE,TRACE,TRACE
+// Here we could check have_wide/have_trace to see what the actual
+// count of WIDE/TRACE calls is at this point...
+                    bad_path = 1;
+                    if (debug_level & 1)
+                        fprintf(stderr,"No relay, but ii > MAX_WIDES-1\n");
+                    break;
+                }
+                else if (have_widen || have_tracen) {
+                    // WIDE/TRACE after something other than RELAY
+                    // or WIDE1-1
+                    bad_path = 1;
+                    if (debug_level & 1)
+                        fprintf(stderr,"WIDE or TRACE after something other than RELAY or WIDE1-1\n");
+                    break;
+                }
+            }
+        }
+
+        // Not RELAY/WIDE/TRACE/WIDEn-N/TRACEn-N call
+        else {
+            // Might as well stub this out, could be anything at
+            // this point, a LINKn-N or LANn-N or a explicit
+            // callsign
+            if (!strstr(ViaCalls[ii], "-")) {
+/*
+                // We do not have an SSID, treat it as a RELAY
+                if (have_relay) {
+                    bad_path = 1;
+                    if (debug_level & 1)
+                        fprintf(stderr,"No SSID\n");
+                    break;
+                }
+*/
+
+                have_relay++;
+            }
+
+            else {
+                // Could be a LAN or LINK or explicit call, check
+                // for a digit preceding the dash
+
+                if (prev > 0 && prev <= 9) {    // Found a digit
+                    // We've found an n-N */
+                    if (have_widen || have_tracen) {
+                        // Already have a previous wide path
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"Found n-N and previous WIDEn-N or TRACEn-N\n");
+                        break;
+                    }
+
+                    // Check for proper relations between the n-N
+                    // numbers.
+                    if ( check_n_N(prev, last) ) {
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"In OTHER checks\n");
+                        break;
+                    }
+
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found wideN-n, slot %d\n", ii);
+                    have_widen++;
+                }
+                else {
+/*
+                    // Must be an explicit callsign, treat as relay
+                    if (have_relay) {
+                        bad_path = 1;
+                        if (debug_level & 1)
+                            fprintf(stderr,"\n");
+                        break;
+                    }
+*/
+                    have_relay++;
+                }
+            }
+        }
+    }   // End of for loop
+
+    if (debug_level & 1)
+        fprintf(stderr,"Total digi length: %d\n", total_digi_length);
+
+    if (total_digi_length > MAX_WIDES + 1) {
+
+        if (debug_level & 1)
+            fprintf(stderr,"Total digi count is too high!\n");
+
+        bad_path = 1;
+    }
+
+    // Free the memory we allocated with strndup()
+    free(tmpdata);
+    return(bad_path);
+
+}   // End of check_unproto_path
+
+
+
+
+
+// Set string printed out by segfault handler
+void set_dangerous( char *ptr ) {
+    xastir_snprintf(dangerous_operation,
+        sizeof(dangerous_operation),
+        "%s",
+        ptr);
+}
+
+
+
+
+
+// Clear string printed out by segfault handler
+void clear_dangerous(void) {
+    dangerous_operation[0] = '\0';
+}
+
+
+
+
+
+// Write out a WKT file
+void xastirWriteWKT(char *filename)
+{
+    // This "WKT" string describes the coordinate system we use in Xastir.
+    // We'll use this string to write out ".prj" files to associate with 
+    // shapefiles we create from GPS or APRS tracks.
+    char Xastir_WKT[] = "GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]]";
+
+    FILE *f;
+
+    f=fopen(filename,"w"); // open for write
+    if (f != NULL) {
+        fprintf(f,"%s\n",Xastir_WKT);
+        fclose(f);
+    } else {
+        fprintf(stderr,"Could not open file %s for writing\n",filename);
+    }        
+}
+
+
+
+
+
+// makeMultiline
+// Create an APRS multiline string given an array of lat/lon pairs.
+//
+// Allocates memory that must be freed by the caller.
+//
+// lon and lat are arrays.  lonObj, latObj are return values of object
+// location (point from which offsets are computed).  
+//
+// lineType is 0 for a closed polygon, 1 for a polyline
+//
+// colorStyle is a character as defined in the wxsvr.net multiline protocol
+// web site at wxsvr.net.  
+//
+// character | color | style
+//   a          red     solid
+//   b          red     dashed
+//   c          red     double-dashed
+//   d          yellow  solid
+//   e          yellow  dashed
+//   f          yellow  double-dashed
+//   g          blue    solid
+//   h          blue    dashed
+//   i          blue    double-dashed
+//   j          green   solid
+//   k          green   dashed
+//   l          green   double-dashed
+
+// Returns a null pointer if user requested too many vertices, or if scale
+// is out of range, or if we fail to malloc the string.
+//
+// One could pass only a list of lat/lons here and get back a point at which
+// to create an object (at the centroid) and a string representing the 
+// multiline.
+#define minFun(a,b) ( ((a)<(b))?(a):(b))
+#define maxFun(a,b) ( ((a)>(b))?(a):(b))
+
+char * makeMultiline(int numPairs, double *lon, double *lat, char colorStyle,
+                     int lineType, char* sqnc,
+                     double *lonCentr, double *latCentr  )
+{
+    
+    char * returnString;
+    
+    // the APRS spec requires a max of 43 chars in the comment section of 
+    // objects, which leaves room for only so many vertices in a multiline 
+    //   number allowed= (43-(6-5))/2=16
+    // 43chars - 6 for the sequence number- 5 for the starting pattern leaves
+    // 32 characters for lat/lon pairs, or 16 pairs
+
+    if ( numPairs > 16) {
+        returnString = NULL;
+    } else {
+        double minLat, minLon;
+        double maxLat, maxLon;
+        int iPair;
+        double scale1,scale2,scale;
+        
+        // find min/max of arrays
+        minLat=minLon=180;
+        maxLat=maxLon=-180;
+        
+        for ( iPair=0; iPair < numPairs; iPair++) {
+            minLon = minFun(minLon,lon[iPair]);
+            minLat = minFun(minLat,lat[iPair]);
+            maxLon = maxFun(maxLon,lon[iPair]);
+            maxLat = maxFun(maxLat,lat[iPair]);
+        }
+
+        *lonCentr = (maxLon+minLon)/2;
+        *latCentr = (maxLat+minLat)/2;
+        
+        // Compute scale:
+        // The scale is the value that makes the maximum or minimum offset
+        // map to +44 or -45.  Pick the scale factor that keeps the
+        // offsets in that range:
+        
+        if (maxLat > maxLon) {
+            scale1= (maxLat-*latCentr)/44.0;
+        } else {
+            scale1= (maxLon-*lonCentr)/44.0;
+        }
+
+        if (minLat < minLon) {
+            scale2 = (minLat-*latCentr)/(-45.0);
+        } else {
+            scale2 = (minLon-*lonCentr)/(-45.0);
+        }
+
+        scale = maxFun(scale1,scale2);
+        
+        if (scale < .0001) {
+            scale=0.0001;
+        }
+
+        if (scale > 1) {
+            // Out of range, no shape returned
+            returnString = NULL;
+        } else {
+            // Not all systems have a log10(), but they all have log() 
+            // So let's stick with natural logs
+            double ln10=log(10.0);
+            // KLUDGE:  the multiline spec says we use 
+            // 20*(int)(log10(scale/.0001)) to generate the scale char,
+            // but this means we'll often produce real scales that are smaller
+            // than the one we just calculated, which means we'd produce
+            // offsets outside the (-45,44) allowed range.  So kludge and 
+            // add 1 to the value
+            int lnscalefac=20*log(scale/.0001)/ln10+1;
+            int rsMaxLen=numPairs*2+6+4+1;
+            int stringOffset=0;
+
+            // Now recompute the scale to be the one we actually transmitted
+            // This pretty much means we'll never have the best precision
+            // we could possibly have, but it'll be close enough
+            scale=pow(10,(double)lnscalefac/20-4);
+
+            // We're ready to produce the multiline string.  So get on with it
+            
+            // multiline string is "}CTS" (literal "}" followed by
+            // line Color-style specifier, followed by open/closed
+            // Type specifier, followed by Scale character), followed
+            // by even number of character pairs, followed by "{seqnc"
+            // (sequence number).
+
+
+            returnString=malloc(sizeof(char)*rsMaxLen);
+
+            if (returnString != NULL) {
+                returnString[stringOffset++]=' ';
+                returnString[stringOffset++]='}';
+                returnString[stringOffset++]=colorStyle;
+                returnString[stringOffset++]= (lineType == 0)?'0':'1';
+                
+                returnString[stringOffset++] = lnscalefac+33;
+                
+                for ( iPair=0; iPair<numPairs; ++iPair) {
+                    double latOffset=lat[iPair]-*latCentr;
+                    // the wxsvr protocol is Western Hemisphere-Centric,
+                    // and treats positive offsets in longitude as being
+                    // west of the reference point.  So have to reverse
+                    // the sense of direction here.
+                    // This will yield positive offsets if lonCenter is
+                    // negative (west) and lon[iPair] is more negative 
+                    // (more west)
+                    double lonOffset=*lonCentr-lon[iPair];
+                    
+                    returnString[stringOffset++]=
+                        (char)((int)(latOffset/scale)+78);
+                    returnString[stringOffset++]=
+                        (char)((int)(lonOffset/scale)+78);
+                }
+                returnString[stringOffset++]='{';
+                strncpy(&(returnString[stringOffset]),sqnc,6);
+                returnString[rsMaxLen-1] = '\0'; // Just to be safe
+            }
+        }
+    }
+    return (returnString);
+}
+
+
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..774eee4
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,179 @@
+/*
+ * $Id: util.h,v 1.63 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_UTIL_H
+#define __XASTIR_UTIL_H
+
+#include "database.h"
+#include <pthread.h>
+#include "hashtable.h"
+
+// Max number of WIDE digipeaters allowed
+#define MAX_WIDES 3
+
+static __inline__ short l16(long val) {
+    // This limits large integer values to the 16 bit range for X
+    // drawing
+    if (val < -32768) val = -32768;
+    if (val >  32767) val =  32767;
+    return (short)val;
+}
+
+static __inline__ unsigned short lu16(long val) {
+    // This limits large unsigned integer values to the 16 bit range
+    // for X drawing
+    if (val < 0) val = 0;
+    if (val > 65535) val = 65535;
+    return (unsigned short)val;
+}
+
+extern int convert_from_xastir_coordinates ( float *f_longitude,
+                                      float *f_latitude,
+                                      long x,
+                                      long y );
+extern int convert_to_xastir_coordinates (unsigned long* x,
+                      unsigned long* y,
+                      float f_longitude,
+                      float f_latitude);
+extern char *get_tactical_from_hash(char *callsign);
+extern void destroy_tactical_hash(void);
+extern void xastir_debug(int my_debug_level, char *debug_string);
+extern char *remove_all_spaces(char *data);
+extern char *remove_leading_spaces(char *data);
+extern char *remove_trailing_spaces(char *data);
+extern char *remove_trailing_asterisk(char *data);
+extern char *remove_trailing_dash_zero(char *data);
+extern int  position_amb_chars;
+extern void start_timer(void);
+extern void stop_timer(void);
+extern void print_timer_results(void);
+extern void get_timestamp(char *timestring);
+extern int get_iso_datetime(time_t aTime, char *timestring, int nowIfNotSet, int nowIfInvalid);
+extern int get_w3cdtf_datetime(time_t aTime, char *timestring,int nowIfNotSet, int nowIfInvalid);
+extern int get_hours(void);
+extern int get_minutes(void);
+extern int get_seconds(void);
+extern char *output_lat(char *in_lat, int comp_pos);
+extern char *output_long(char *in_long, int comp_pos);
+extern double phg_range(char p, char h, char g);
+extern double shg_range(char s, char h, char g);
+extern void phg_decode(const char *langstr, const char *phg, char *phg_decoded, int phg_decoded_length);
+extern void shg_decode(const char *langstr, const char *shg, char *shg_decoded, int shg_decoded_length);
+extern void bearing_decode(const char *langstr, const char *bearing_str, const char *NRQ, char *bearing_decoded, int bearing_decoded_length);
+extern char *get_line(FILE *f, char *linedata, int maxline);
+extern time_t time_from_aprsstring(char *timestamp);
+extern char *compress_posit(const char *lat, const char group, const char *lon, const char symbol,
+                const unsigned int course, const unsigned int speed, const char *phg);
+
+extern int  position_defined(long lat, long lon, int strict);
+extern void convert_screen_to_xastir_coordinates(int x, int y, long *lat, long *lon);
+extern void convert_xastir_to_UTM_str(char *str, int str_len, long x, long y);
+extern void convert_xastir_to_MGRS_str_components(char *utmZone, int utmZone_len, 
+                                           char *EastingL, int EastingL_len, 
+                                           char *NorthingL, int NorthingL_len, 
+                                           unsigned int *int_utmEasting, unsigned int *int_utmNorthing, 
+                                           long x,  long y, 
+                                           int nice_format, char *space_string, int space_string_len);
+extern void convert_xastir_to_MGRS_str(char *str, int str_len, long x, long y, int nice_format);
+extern void convert_xastir_to_UTM(double *easting, double *northing, char *zone, int zone_len, long x, long y);
+extern void convert_UTM_to_xastir(double easting, double northing, char *zone, long *x, long *y);
+extern double convert_lat_l2r(long lat);
+extern double convert_lon_l2r(long lon);
+extern void convert_lat_l2s(long lat, char *str, int str_len, int type);
+extern void convert_lon_l2s(long lon, char *str, int str_len, int type);
+extern long convert_lat_s2l(char *lat);
+extern long convert_lon_s2l(char *lon);
+
+extern double calc_distance(long lat1, long lon1, long lat2, long lon2);
+extern double calc_distance_course(long lat1, long lon1, long lat2, long lon2, char *course_deg, int course_deg_length);
+extern double distance_from_my_station(char *call_sign, char *course_deg);
+
+extern char *convert_bearing_to_name(char *bearing, int opposite);
+
+extern void compute_DR_position(long x_long, long y_lat, double range, double course, long *x_long2, long *y_lat2);
+extern void compute_current_DR_position(DataRow *p_station, long *x_long, long *y_lat);
+
+extern int  filethere(char *fn);
+extern int  filecreate(char *fn);
+extern int copy_file(char *infilename, char *outfilename);
+extern time_t file_time(char *fn);
+extern void load_wx_alerts_from_log(void);
+extern void log_data(char *file, char *line);
+extern void log_tactical_call(char *call_sign, char *tactical_call_sign);
+extern void reload_tactical_calls(void);
+extern time_t sec_now(void);
+extern char *get_time(char *time_here);
+
+extern void substr(char *dest, char *src, int size);
+extern int  valid_path(char *path);
+extern int  valid_call(char *call);
+extern int  valid_inet_name(char *name, char *info, char *origin, int origin_size);
+
+extern char echo_digis[6][9+1];
+extern void upd_echo(char *path);
+
+extern char *to_upper(char *data);
+extern char *to_lower(char *data);
+extern int  is_num_chr(char ch);
+extern int  is_num_or_sp(char ch);
+extern int  is_xnum_or_dash(char *data, int max);
+extern void removeCtrlCodes(char *cp);
+extern void makePrintable(char *cp);
+extern void spell_it_out(char *text, int max_length);
+
+typedef struct
+{
+    pthread_mutex_t lock;
+    pthread_t threadID;
+} xastir_mutex;
+
+extern void init_critical_section(xastir_mutex *lock);
+extern int begin_critical_section(xastir_mutex *lock, char *text);
+extern int end_critical_section(xastir_mutex *lock, char *text);
+
+//#define TIMING_DEBUG
+#ifdef TIMING_DEBUG
+void time_mark(int start);
+#endif  // TIMING_DEBUG
+
+// dl9sau
+extern char *sec_to_loc(long longitude, long latitude);
+
+extern short checkHash(char *theCall, short theHash);
+
+extern void split_string ( char *data, char *cptr[], int max, char search_char );
+extern int check_unproto_path( char *data );
+
+extern void set_dangerous( char *ptr );
+extern void clear_dangerous(void);
+
+void xastirWriteWKT(char *name);
+char * makeMultiline(int numPairs, double *lon, double *lat, char colorStyle,
+                     int lineType, char* sqnc,
+                     double *lonCentr, double *latCentr );
+
+#endif // __XASTIR_UTIL_H
+
+
diff --git a/src/view_message_gui.c b/src/view_message_gui.c
new file mode 100644
index 0000000..c6d96a2
--- /dev/null
+++ b/src/view_message_gui.c
@@ -0,0 +1,732 @@
+/*
+ * $Id: view_message_gui.c,v 1.43 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <Xm/XmAll.h>
+#include <X11/Xatom.h>
+#include <X11/Shell.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#else
+#  include <strings.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include "xastir.h"
+#include "main.h"
+#include "util.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+Widget All_messages_dialog = NULL;
+Widget view_messages_text = NULL;
+Widget vm_dist_data = NULL;
+
+static xastir_mutex All_messages_dialog_lock;
+
+int vm_range;
+int view_message_limit = 10000;
+int Read_messages_packet_data_type = 0; // 1=tnc_only, 2=net_only, 0=tnc&net
+int Read_messages_mine_only = 0;
+
+
+
+
+
+void view_message_gui_init(void)
+{
+    init_critical_section( &All_messages_dialog_lock );
+}
+
+
+
+
+
+void view_message_print_record(Message *m_fill) {
+    int pos;
+    char *temp;
+    int i;
+    int my_size = 200;
+    char temp_my_course[10];
+    XmTextPosition drop_ptr;
+    int distance;
+
+
+    // Make sure it's within our distance range we have set
+    distance = (int)distance_from_my_station(m_fill->from_call_sign,temp_my_course);
+
+    if (Read_messages_mine_only
+            || (!Read_messages_mine_only
+                && ( (vm_range == 0) || (distance <= vm_range) ) ) ) {
+ 
+        // Check that it's coming from the correct type of interface
+        // Compare Read_messages_packet_data_type against the port
+        // type associated with data_port to determine whether or
+        // not to display it.
+        //
+        // I = Internet
+        // L = Local
+        // T = TNC
+        // F = File
+        //
+        switch (Read_messages_packet_data_type) {
+
+            case 2:     // Display NET data only
+                // if not network_interface, return
+                if (m_fill->data_via != 'I')
+                    return; // Don't display it
+                break;
+
+            case 1:     // Display TNC data only
+                // if not local_tnc_interface, return
+                if (m_fill->data_via != 'T')
+                    return; // Don't display it
+                break;
+
+            case 0:     // Display both TNC and NET data
+            default:
+                break;
+        }
+
+        // Check for my stations only if set
+        if (Read_messages_mine_only) {
+            char short_call[MAX_CALLSIGN];
+            char *p;
+
+            xastir_snprintf(short_call,
+                sizeof(short_call),
+                "%s",
+                my_callsign);
+            if ( (p = index(short_call,'-')) ) {
+                *p = '\0';  // Terminate it
+            }
+
+            if (!strstr(m_fill->call_sign, short_call)
+                    && !strstr(m_fill->from_call_sign, short_call)) {
+                return;
+            }
+        }
+
+        if ((temp = malloc((size_t)my_size)) == NULL)
+            return;
+
+        sprintf(temp,"%-9s>%-9s %s:%5s %s:%c :%s\n",
+            m_fill->from_call_sign,
+            m_fill->call_sign,
+            langcode("WPUPMSB013"),
+            m_fill->seq,
+            langcode("WPUPMSB014"),
+            m_fill->type,
+            m_fill->message_line);
+
+        pos = (int)XmTextGetLastPosition(view_messages_text);
+
+
+        XmTextInsert(view_messages_text, pos, temp);
+        pos += strlen(temp);
+        while (pos > view_message_limit) {
+            for (drop_ptr = i = 0; i < 3; i++) {
+                (void)XmTextFindString(view_messages_text, drop_ptr, "\n", XmTEXT_FORWARD, &drop_ptr);
+                drop_ptr++;
+            }
+            XmTextReplace(view_messages_text, 0, drop_ptr, "");
+            pos = (int)XmTextGetLastPosition(view_messages_text);
+        }
+        XtVaSetValues(view_messages_text, XmNcursorPosition, pos, NULL);
+
+        free(temp);
+    }
+}
+
+
+
+
+
+void view_message_display_file(char msg_type) {
+    int pos;
+
+    if ((All_messages_dialog != NULL)) {
+        mscan_file(msg_type, view_message_print_record);
+    }
+    pos = (int)XmTextGetLastPosition(view_messages_text);
+    XmTextShowPosition(view_messages_text, pos);
+}
+
+
+
+
+
+void all_messages(char from, char *call_sign, char *from_call, char *message) {
+    char temp_my_course[10];
+    char *temp;
+    char data1[97];
+    char data2[97];
+    int pos;
+    int i;
+    int my_size = 200;
+    XmTextPosition drop_ptr;
+
+
+    if (Read_messages_mine_only
+            || (!Read_messages_mine_only
+                && ((vm_range == 0)
+                    || ((int)distance_from_my_station(call_sign,temp_my_course) <= vm_range)) ) ) {
+
+        // Check that it's coming from the correct type of interface
+        // Compare Read_messages_packet_data_type against the port
+        // type associated with data_port to determine whether or
+        // not to display it.
+        //
+        // I = Internet
+        // L = Local
+        // T = TNC
+        // F = File
+        //
+        switch (Read_messages_packet_data_type) {
+
+            case 2:     // Display NET data only
+                // if not network_interface, return
+                if (from != 'I')
+                    return; // Don't display it
+                break;
+
+            case 1:     // Display TNC data only
+                // if not local_tnc_interface, return
+                if (from != 'T')
+                    return; // Don't display it
+                break;
+
+            case 0:     // Display both TNC and NET data
+            default:
+                break;
+        }
+
+        // Check for my stations only if set
+        if (Read_messages_mine_only) {
+            char short_call[MAX_CALLSIGN];
+            char *p;
+
+            xastir_snprintf(short_call,
+                sizeof(short_call),
+                "%s",
+                my_callsign);
+            if ( (p = index(short_call,'-')) ) {
+                *p = '\0';  // Terminate it
+            }
+
+            if (!strstr(call_sign, short_call)
+                    && !strstr(from_call, short_call)) {
+                return;
+            }
+        }
+
+        if ((temp = malloc((size_t)my_size)) == NULL)
+            return;
+
+        if (strlen(message)>95) {
+            xastir_snprintf(data1,
+                sizeof(data1),
+                "%s",
+                message);
+            data1[95]='\0';
+            xastir_snprintf(data2,
+                sizeof(data2),
+                "\n\t%s",
+                message+95);
+        } else {
+            xastir_snprintf(data1,
+                sizeof(data1),
+                "%s",
+                message);
+            data2[0] = '\0';
+        }
+
+        if (strncmp(call_sign, "java",4) == 0) {
+            xastir_snprintf(call_sign,
+                MAX_CALLSIGN+1,
+                "%s", langcode("WPUPMSB015") );   // Broadcast
+            xastir_snprintf(temp,
+                my_size,
+                "%s %s\t%s%s\n",
+                from_call,
+                call_sign,
+                data1,
+                data2);
+        } else if (strncmp(call_sign, "USER", 4) == 0) {
+            xastir_snprintf(call_sign,
+                MAX_CALLSIGN+1,
+                "%s", langcode("WPUPMSB015") );   // Broadcast
+            xastir_snprintf(temp,
+                my_size,
+                "%s %s\t%s%s\n",
+                from_call,
+                call_sign,
+                data1,
+                data2);
+        } else
+            xastir_snprintf(temp,
+                my_size,
+                "%s to %s via:%c\t%s%s\n",
+                from_call,
+                call_sign,
+                from,
+                data1,
+                data2);
+
+        if ((All_messages_dialog != NULL)) {
+
+begin_critical_section(&All_messages_dialog_lock, "view_message_gui.c:all_messages" );
+
+            pos = (int)XmTextGetLastPosition(view_messages_text);
+            XmTextInsert(view_messages_text, pos, temp);
+            pos += strlen(temp);
+            while (pos > view_message_limit) {
+                for (drop_ptr = i = 0; i < 3; i++) {
+                    (void)XmTextFindString(view_messages_text, drop_ptr, "\n", XmTEXT_FORWARD, &drop_ptr);
+                    drop_ptr++;
+                }
+                XmTextReplace(view_messages_text, 0, drop_ptr, "");
+                pos = (int)XmTextGetLastPosition(view_messages_text);
+            }
+            XtVaSetValues(view_messages_text, XmNcursorPosition, pos, NULL);
+            XmTextShowPosition(view_messages_text, pos);
+
+end_critical_section(&All_messages_dialog_lock, "view_message_gui.c:all_messages" );
+
+        }
+        free(temp);
+    }
+}
+
+
+
+
+
+void All_messages_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    char *temp_ptr;
+
+
+    temp_ptr = XmTextFieldGetString(vm_dist_data);
+    vm_range = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    XtPopdown(shell);
+
+begin_critical_section(&All_messages_dialog_lock, "view_message_gui.c:All_messages_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    All_messages_dialog = (Widget)NULL;
+
+end_critical_section(&All_messages_dialog_lock, "view_message_gui.c:All_messages_destroy_shell" );
+
+}
+
+
+
+
+
+void All_messages_change_range( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget shell = (Widget) clientData;
+    char *temp_ptr;
+
+
+    temp_ptr = XmTextFieldGetString(vm_dist_data);
+    vm_range = atoi(temp_ptr);
+    XtFree(temp_ptr);
+
+    XtPopdown(shell);
+
+    All_messages_destroy_shell(widget, clientData, callData);
+    view_all_messages(widget, clientData, callData); 
+}
+
+ 
+
+
+
+void  Read_messages_packet_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set)
+        Read_messages_packet_data_type = atoi(which);
+    else
+        Read_messages_packet_data_type = 0;
+}
+
+
+
+
+
+Widget button_range;
+
+
+
+
+
+void  Read_messages_mine_only_toggle( /*@unused@*/ Widget widget, XtPointer clientData, XtPointer callData) {
+    char *which = (char *)clientData;
+    XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
+
+    if(state->set) {
+        Read_messages_mine_only = atoi(which);
+        XtSetSensitive(vm_dist_data, FALSE);
+    }
+    else {
+        Read_messages_mine_only = 0;
+        XtSetSensitive(vm_dist_data, TRUE);
+    }
+}
+
+
+
+
+
+void view_all_messages( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    Widget pane, my_form, button_close, dist, dist_units;
+    Widget option_box, tnc_data, net_data, tnc_net_data,
+        read_mine_only_button;
+    unsigned int n;
+#define NCNT 50
+#define IncN(n) if (n< NCNT) n++; else fprintf(stderr, "Oops, too many arguments for array!\a")
+    Arg args[NCNT];
+    Atom delw;
+    char temp[10];
+
+    if (!All_messages_dialog) {
+
+begin_critical_section(&All_messages_dialog_lock, "view_message_gui.c:view_all_messages" );
+
+        All_messages_dialog = XtVaCreatePopupShell(langcode("AMTMW00001"),
+                xmDialogShellWidgetClass, appshell,
+                XmNdeleteResponse, XmDESTROY,
+                XmNdefaultPosition, FALSE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        pane = XtVaCreateWidget("view_all_messages pane",
+                xmPanedWindowWidgetClass, 
+                All_messages_dialog,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        my_form =  XtVaCreateWidget("view_all_messages my_form",
+                xmFormWidgetClass, 
+                pane,
+                XmNfractionBase, 5,
+                XmNautoUnmanage, FALSE,
+                XmNshadowThickness, 1,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                NULL);
+
+        dist = XtVaCreateManagedWidget(langcode("AMTMW00002"),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_FORM,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        vm_dist_data = XtVaCreateManagedWidget("view_all_messages dist_data", 
+                xmTextFieldWidgetClass, 
+                my_form,
+                XmNeditable,   TRUE,
+                XmNcursorPositionVisible, TRUE,
+                XmNsensitive, TRUE,
+                XmNshadowThickness,    1,
+                XmNcolumns, 8,
+                XmNwidth, ((8*7)+2),
+                XmNmaxLength, 8,
+                XmNbackground, colors[0x0f],
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment,XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, dist,
+                XmNleftOffset, 10,
+                XmNrightAttachment,XmATTACH_NONE,
+                XmNfontList, fontlist1,
+                NULL);
+
+        dist_units = XtVaCreateManagedWidget((english_units?langcode("UNIOP00004"):langcode("UNIOP00005")),
+                xmLabelWidgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, vm_dist_data,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNtraversalOn, FALSE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        button_range = XtVaCreateManagedWidget(langcode("BULMW00003"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, dist_units,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_NONE,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_range, XmNactivateCallback, All_messages_change_range, All_messages_dialog);
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),
+                xmPushButtonGadgetClass, 
+                my_form,
+                XmNtopAttachment, XmATTACH_FORM,
+                XmNtopOffset, 5,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, button_range,
+                XmNleftOffset, 10,
+                XmNrightAttachment, XmATTACH_FORM,
+                XmNnavigationType, XmTAB_GROUP,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(button_close, XmNactivateCallback, All_messages_destroy_shell, All_messages_dialog);
+
+        n=0;
+        XtSetArg(args[n],XmNforeground, MY_FG_COLOR); n++;
+        XtSetArg(args[n],XmNbackground, MY_BG_COLOR); n++;
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
+        XtSetArg(args[n], XmNtopWidget, dist); n++;
+        XtSetArg(args[n], XmNtopOffset, 5); n++;
+        XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+        XtSetArg(args[n], XmNleftOffset, 5); n++;
+        XtSetArg(args[n], XmNrightAttachment, XmATTACH_NONE); n++;
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+
+        option_box = XmCreateRadioBox(my_form,
+                "Vew Messages option box",
+                args,
+                n);
+
+        XtVaSetValues(option_box,
+                XmNpacking, XmPACK_TIGHT,
+                XmNorientation, XmHORIZONTAL,
+                NULL);
+
+        tnc_data = XtVaCreateManagedWidget(langcode("WPUPDPD002"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(tnc_data,XmNvalueChangedCallback,Read_messages_packet_toggle,"1");
+
+        net_data = XtVaCreateManagedWidget(langcode("WPUPDPD003"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(net_data,XmNvalueChangedCallback,Read_messages_packet_toggle,"2");
+
+        tnc_net_data = XtVaCreateManagedWidget(langcode("WPUPDPD004"),
+                xmToggleButtonGadgetClass,
+                option_box,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+
+        XtAddCallback(tnc_net_data,XmNvalueChangedCallback,Read_messages_packet_toggle,"0");
+
+        read_mine_only_button = XtVaCreateManagedWidget(langcode("WPUPDPD008"),
+                xmToggleButtonGadgetClass,
+                my_form,
+                XmNvisibleWhenOff, TRUE,
+                XmNindicatorSize, 12,
+                XmNtopAttachment, XmATTACH_WIDGET,
+                XmNtopWidget, dist,
+                XmNtopOffset, 10,
+                XmNbottomAttachment, XmATTACH_NONE,
+                XmNleftAttachment, XmATTACH_WIDGET,
+                XmNleftWidget, option_box,
+                XmNleftOffset, 20,
+                XmNrightAttachment, XmATTACH_NONE,
+                MY_FOREGROUND_COLOR,
+                MY_BACKGROUND_COLOR,
+                XmNfontList, fontlist1,
+                NULL);
+ 
+        XtAddCallback(read_mine_only_button,XmNvalueChangedCallback,Read_messages_mine_only_toggle,"1");
+
+        n=0;
+        XtSetArg(args[n], XmNrows, 15); IncN(n);
+        XtSetArg(args[n], XmNcolumns, 85); IncN(n);
+        XtSetArg(args[n], XmNeditable, FALSE); IncN(n);
+        XtSetArg(args[n], XmNtraversalOn, TRUE); IncN(n);
+        XtSetArg(args[n], XmNlistSizePolicy, XmVARIABLE); IncN(n);
+        XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); IncN(n);
+        XtSetArg(args[n], XmNwordWrap, TRUE); IncN(n);
+        XtSetArg(args[n], XmNscrollHorizontal, TRUE); IncN(n);
+        XtSetArg(args[n], XmNscrollVertical, TRUE); IncN(n);
+//        XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); IncN(n);
+        XtSetArg(args[n], XmNselectionPolicy, XmMULTIPLE_SELECT); IncN(n);
+        XtSetArg(args[n], XmNcursorPositionVisible, FALSE); IncN(n);
+        XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); IncN(n);
+        XtSetArg(args[n], XmNtopWidget, option_box); IncN(n);
+        XtSetArg(args[n], XmNtopOffset, 5); IncN(n);
+        XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); IncN(n);
+        XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); IncN(n);
+        XtSetArg(args[n], XmNleftOffset, 5); IncN(n);
+        XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); IncN(n);
+        XtSetArg(args[n], XmNrightOffset, 5); IncN(n);
+        XtSetArg(args[n], XmNforeground, MY_FG_COLOR); IncN(n);
+        XtSetArg(args[n], XmNbackground, MY_BG_COLOR); IncN(n);
+        XtSetArg(args[n], XmNfontList, fontlist1); n++;
+ 
+        view_messages_text = XmCreateScrolledText(my_form,
+                "view_all_messages text",
+                args,
+                n);
+
+// It's hard to get tab groups working with ScrolledText widgets.  Tab'ing in is
+// fine, but then I'm stuck in insert mode and it absorbs the tabs and beeps.
+
+        pos_dialog(All_messages_dialog);
+
+        delw = XmInternAtom(XtDisplay(All_messages_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(All_messages_dialog, delw, All_messages_destroy_shell, (XtPointer)All_messages_dialog);
+
+        sprintf(temp,"%d",vm_range);
+        XmTextFieldSetString(vm_dist_data,temp);
+
+        switch (Read_messages_packet_data_type) {
+            case(0):
+                XmToggleButtonSetState(tnc_net_data,TRUE,FALSE);
+                break;
+
+            case(1):
+                XmToggleButtonSetState(tnc_data,TRUE,FALSE);
+                break;
+
+            case(2):
+                XmToggleButtonSetState(net_data,TRUE,FALSE);
+                break;
+
+            default:
+                XmToggleButtonSetState(tnc_net_data,TRUE,FALSE);
+                break;
+        }
+
+        if (Read_messages_mine_only) {
+            XmToggleButtonSetState(read_mine_only_button,TRUE,FALSE);
+            XtSetSensitive(vm_dist_data, FALSE);
+        }
+        else {
+            XmToggleButtonSetState(read_mine_only_button,FALSE,FALSE);
+            XtSetSensitive(vm_dist_data, TRUE);
+        }
+
+        XtManageChild(option_box);
+        XtManageChild(view_messages_text);
+        XtVaSetValues(view_messages_text, XmNbackground, colors[0x0f], NULL);
+        XtManageChild(my_form);
+        XtManageChild(pane);
+
+        redraw_on_new_packet_data=1;
+
+        // Dump all currently active messages to the new window
+        view_message_display_file('M');
+
+end_critical_section(&All_messages_dialog_lock, "view_message_gui.c:view_all_messages" );
+
+        XtPopup(All_messages_dialog,XtGrabNone);
+//        fix_dialog_vsize(All_messages_dialog);
+
+        // Move focus to the Close button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(All_messages_dialog);
+        XmProcessTraversal(button_close, XmTRAVERSE_CURRENT); 
+
+
+    }
+    else {
+        (void)XRaiseWindow(XtDisplay(All_messages_dialog), XtWindow(All_messages_dialog));
+    }
+}
+
+
diff --git a/src/wx.c b/src/wx.c
new file mode 100644
index 0000000..702b942
--- /dev/null
+++ b/src/wx.c
@@ -0,0 +1,3770 @@
+/*
+ * $Id: wx.c,v 1.80 2012/08/31 23:39:01 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+//
+// The code currently supports these types of locally-connected or
+// network-connected weather stations:
+//
+//   Peet Brothers Ultimeter 2000 (Set to Data logging mode)
+//   Peet Brothers Ultimeter 2000 (Set to Packet mode)
+//   Peet Brothers Ultimeter 2000 (Set to Complete Record Mode)
+//   Peet Brothers Ultimeter-II
+//   Qualimetrics Q-Net?
+//   Radio Shack WX-200/Huger WM-918/Oregon Scientific WM-918
+//   Dallas One-Wire Weather Station (via OWW network daemon)
+//   Davis Weather Monitor II/Wizard III/Vantage Pro (via meteo/db2APRS link)
+//
+
+
+// Need to modify code to use WX_rain_gauge_type.  Peet brothers.
+// See http://www.peetbros.com, FAQ's and owner's manuals for
+// details:
+//
+//  Peet Bros Ultimeter II:   0.1"/0.5mm or 0.01"/0.25mm
+//      Divide by 10 or 100 from the serial output.
+//
+//  Peet Bros Ultimeter 2000, 800, & 100:  0.01"/0.25mm or 0.1mm
+//      If 0.01" gauge, divide by 100.  If 0.1mm gauge, convert to
+//      proper English units.
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <string.h>
+
+#include <Xm/XmAll.h>
+
+#include "wx.h"
+#include "main.h"
+#include "xastir.h"
+#include "interface.h"
+#include "lang.h"
+#include "util.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define MAX_RAW_WX_STRING 800
+
+char wx_station_type[100];
+char raw_wx_string[MAX_RAW_WX_STRING+1];
+
+#define MAX_WX_STRING 300
+#define WX_TYPE 'X'
+
+/* rain totals */
+float rain_minute[60];              // Total rain for each min. of last hour, hundredths of an inch
+float rain_minute_total = 0.0;      // Total for last hour, hundredths of an inch
+int rain_minute_last_write = -1;    // Write pointer for rain_minute[] array, set to an invalid number
+float rain_00 = 0.0;                // hundredths of an inch
+float rain_24 = 0.0;                // hundredths of an inch
+float rain_base[24];                // hundredths of an inch
+int rain_check = 0;                 // Flag for re-checking rain_total each hour
+
+float wind_chill = 0;               // holder for wind chill calc
+
+// Gust totals
+float gust[60];                     // High wind gust for each min. of last hour
+int gust_write_ptr = 0;
+int gust_read_ptr = 0;
+int gust_last_write = 0;
+
+
+/* Other WX station data */
+char wx_dew_point[10];
+char wx_dew_point_on;
+char wx_high_wind[10];
+char wx_high_wind_on;
+char wx_wind_chill[10];
+char wx_wind_chill_on;
+char wx_three_hour_baro[10];  // hPa
+char wx_three_hour_baro_on;
+char wx_hi_temp[10];
+char wx_hi_temp_on;
+char wx_low_temp[10];
+char wx_low_temp_on;
+char wx_heat_index[10];
+char wx_heat_index_on;
+
+
+
+
+
+/***********************************************************/
+/* clear rain data                                         */
+/***********************************************************/
+void clear_rain_data(void) {
+    int x;
+
+
+    // Clear rain_base queue (starting rain total for each hour)
+    for ( x = 0; x < 24; x++ ) {
+        rain_base[x] = 0.0;
+    }
+
+    rain_00 = 0.0;
+    rain_24 = 0.0;
+    rain_check = 0;   // Set flag so we'll recheck rain_total
+                    // a few times at start of each hour
+
+    // Clear hourly rain queue
+    for ( x = 0; x < 60; x++ )
+        rain_minute[x] = 0.0;
+
+    rain_minute_total = 0.0;
+    rain_minute_last_write = 70;  // Invalid number so we'll know we're just starting.
+}
+
+
+
+
+
+/**************************************************************/
+/* compute_rain_hour - rolling average for the last 59.x      */
+/* minutes of rain.  I/O numbers are in hundredths of an inch.*/
+/* Output is in "rain_minute_total", a global variable.       */
+/**************************************************************/
+void compute_rain_hour(float rain_total) {
+    int current, j;
+    float lowest;
+
+
+    // Deposit the _starting_ rain_total for each minute into a separate bucket.
+    // Subtract lowest rain_total in queue from current rain_total to get total
+    // for the last hour.
+
+
+    current = get_minutes(); // Fetch the current minute value.  Use this as an index
+                        // into our minute "buckets" where we store the data.
+
+
+    rain_minute[ (current + 1) % 60 ] = 0.0;   // Zero out the next bucket (probably have data in
+                                                // there from the previous hour).
+
+
+    if (rain_minute[current] == 0.0)           // If no rain_total stored yet in this minute's bucket
+        rain_minute[current] = rain_total;      // Write into current bucket
+
+
+    // Find the lowest non-zero value for rain_total.  The max value is "rain_total".
+    lowest = rain_total;                    // Set to maximum to get things going
+    for (j = 0; j < 60; j++) {
+        if ( (rain_minute[j] > 0.0) && (rain_minute[j] < lowest) ) { // Found a lower non-zero value?
+            lowest = rain_minute[j];        // Snag it
+        }
+    }
+    // Found it, subtract the two to get total for the last hour
+    rain_minute_total = rain_total - lowest;
+
+    if (debug_level & 2)
+        fprintf(stderr,"Rain_total:%0.2f  Hourly:%0.2f  (Low:%0.2f)  ", rain_total, rain_minute_total, lowest);
+}
+
+
+
+
+
+/***********************************************************/
+/* compute_rain - compute rain totals from the total rain  */
+/* so far.  rain_total (in hundredths of an inch) keeps on */
+/* incrementing.                                           */
+/***********************************************************/
+void compute_rain(float rain_total) {
+    int current, i;
+    float lower;
+
+
+    // Skip the routine if input is outlandish (Negative value, zero, or 512 inches!).
+    // We seem to get occasional 0.0 packets from wx200d.  This makes them go away.
+    if ( (rain_total <= 0.0) || (rain_total > 51200.0) )
+        return;
+
+    compute_rain_hour(rain_total);
+
+    current = get_hours();
+
+    // Set rain_base:  The first rain_total for each hour.
+    if (rain_base[current] == 0.0) {       // If we don't have a start value yet for this hour,
+        rain_base[current] = rain_total;    // save it away.
+        rain_check = 0;                     // Set up rain_check so we'll do the following
+                                            // "else" clause a few times at start of each hour.
+    }
+    else {  // rain_base has been set, is it wrong?  We recheck three times at start of hour.
+        if (rain_check < 3) {
+            rain_check++;
+            // Is rain less than base?  It shouldn't be.
+            if (rain_total < rain_base[current])
+                rain_base[current] = rain_total;
+
+            // Difference greater than 10 inches since last reading?  It shouldn't be.
+            if (fabs(rain_total - rain_base[current]) > 1000.0) // Remember:  Hundredths of an inch
+                rain_base[current] = rain_total;
+        }
+    }
+    rain_base[ (current + 1) % 24 ] = 0.0;    // Clear next hour's index.
+
+
+    // Compute total rain in last 24 hours:  Really we'll compute the total rain
+    // in the last 23 hours plus the portion of an hour we've completed (Sum up
+    // all 24 of the hour totals).  This isn't the perfect way to do it, but to
+    // really do it right we'd need finer increments of time (to get closer to
+    // the goal of 24 hours of rain).
+    lower = rain_total;
+    for ( i = 0; i < 24; i++ ) {    // Find the lowest non-zero rain_base value in last 24 hours
+        if ( (rain_base[i] > 0.0) && (rain_base[i] < lower) ) {
+            lower = rain_base[i];
+        }
+    }
+    rain_24 = rain_total - lower;    // Hundredths of an inch
+
+
+    // Compute rain since midnight.  Note that this uses whatever local time was set
+    // on the machine.  It might not be local midnight if your box is set to GMT.
+    lower = rain_total;
+    for ( i = 0; i <= current; i++ ) {  // Find the lowest non-zero rain_base value since midnight
+        if ( (rain_base[i] > 0.0) && (rain_base[i] < lower) ) {
+            lower = rain_base[i];
+        }
+    }
+    rain_00 = rain_total - lower;    // Hundredths of an inch
+
+    // It is the responsibility of the calling program to save
+    // the new totals in the data structure for our station.
+    // We don't return anything except in global variables.
+
+
+    if (debug_level & 2) {
+        fprintf(stderr,"24hrs:%0.2f  ", rain_24);
+        fprintf(stderr,"rain_00:%0.2f\n", rain_00);
+    }
+}
+
+
+
+
+
+/**************************************************************/
+/* compute_gust - compute max wind gust during last 5 minutes */
+/*                                                            */
+/**************************************************************/
+float compute_gust(float wx_speed, float last_speed, time_t *last_speed_time) {
+    float computed_gust;
+    int current, j;
+
+
+    // Deposit max gust for each minute into a different bucket.
+    // Check all buckets for max gust within the last five minutes
+    // (Really 4 minutes plus whatever portion of a minute we've completed).
+
+    current = get_minutes(); // Fetch the current minute value.  We use this as an index
+                        // into our minute "buckets" where we store the data.
+
+    // If we haven't started collecting yet, set up to do so
+    if (gust_read_ptr == gust_write_ptr) {  // We haven't started yet
+        gust_write_ptr = current;           // Set to write into current bucket
+        gust_last_write = current;
+
+        gust_read_ptr = current - 1;        // Set read pointer back one, modulus 60
+        if (gust_read_ptr < 0)
+            gust_read_ptr = 59;
+
+        gust[gust_write_ptr] = 0.0;         // Zero the max gust
+        gust[gust_read_ptr] = 0.0;          // for both buckets.
+
+//WE7U: Debug
+//gust[gust_write_ptr] = 45.9;
+    }
+
+    // Check whether we've advanced at least one minute yet
+    if (current != gust_write_ptr) {        // We've advanced to a different minute
+        gust_write_ptr = current;           // Start writing into a new bucket.
+        gust[gust_write_ptr] = 0.0;         // Zero the new bucket
+
+        // Check how many bins of real data we have currently.  Note that this '5' is
+        // correct, as we just advanced "current" to the next minute.  We're just pulling
+        // along the read_ptr behind us if we have 5 bins worth of data by now.
+        if ( ((gust_read_ptr + 5) % 60) == gust_write_ptr)  // We have 5 bins of real data
+            gust_read_ptr = (gust_read_ptr + 1) % 60;       // So advance the read pointer,
+
+        // Check for really bad pointers, perhaps the weather station got
+        // unplugged for a while or it's just REALLY slow at sending us data?
+        // We're checking to see if gust_last_write happened in the previous
+        // minute.  If not, we skipped a minute or more somewhere.
+        if ( ((gust_last_write + 1) % 60) != current ) {
+            // We lost some time somewhere: Reset the pointers, older gust data is
+            // lost.  Start over collecting new gust data.
+
+            gust_read_ptr = current - 1;    // Set read pointer back one, modulus 60
+            if (gust_read_ptr < 0)
+                gust_read_ptr = 59;
+
+            gust[gust_read_ptr] = 0.0;
+        }
+        gust_last_write = current;
+    }
+
+    // Is current wind speed higher than the current minute bucket?
+    if (wx_speed > gust[gust_write_ptr])
+        gust[gust_write_ptr] = wx_speed;    // Save it in the bucket
+
+    // Read the last (up to) five buckets and find the max gust
+    computed_gust=gust[gust_write_ptr];
+    j = gust_read_ptr;
+    while (j != ((gust_write_ptr + 1) % 60) ) {
+        if ( computed_gust < gust[j] )
+            computed_gust = gust[j];
+        j = (j + 1) % 60;
+    }
+
+    if (debug_level & 2) {
+        j = gust_read_ptr;
+        while (j != ((gust_write_ptr + 1) % 60) ) {
+            fprintf(stderr,"%0.2f   ", gust[j]);
+            j = (j + 1) % 60;
+        }
+        fprintf(stderr,"gust:%0.2f\n", computed_gust);
+    }
+
+    *last_speed_time = sec_now();
+    return(computed_gust);
+}
+
+
+
+
+
+//
+// cycle_weather - keep the weather queues moving even if data from
+// weather station is scarce.  This is called from main.c:UpdateTime()
+// on a periodic basis.  This routine also does the 30 second timestamp
+// for the log files.
+//
+void cycle_weather(void) {
+    DataRow *p_station;
+    WeatherRow *weather;
+    float last_speed, computed_gust;
+    time_t last_speed_time;
+
+
+    // Find my own local weather data
+    if (search_station_name(&p_station,my_callsign,1)) {
+        if (p_station->weather_data != NULL) {  // If station has WX data
+            weather = p_station->weather_data;
+            // Cycle the rain queues, feed in the last rain total we had
+            (void)compute_rain((float)atof(weather->wx_rain_total));
+
+
+            // Note:  Some weather stations provide the per-hour, 24-hour,
+            // and since-midnight rain rates already.  Further, some stations 
+            // don't even provide total rain (Davis APRS DataLogger and the 
+            // db2APRS program), so anything we compute here is actually wrong.
+            // Do NOT clobber these if so.  This flag is set in fill_wx_data
+            // when the station provides its data.
+
+            if (weather->wx_compute_rain_rates) {
+              // Hourly rain total
+              xastir_snprintf(weather->wx_rain,
+                              sizeof(weather->wx_rain),
+                              "%0.2f",
+                              rain_minute_total);
+              
+              // Last 24 hour rain
+              xastir_snprintf(weather->wx_prec_24,
+                              sizeof(weather->wx_prec_24),
+                              "%0.2f",
+                              rain_24);
+              
+              // Rain since midnight
+              xastir_snprintf(weather->wx_prec_00,
+                              sizeof(weather->wx_prec_00),
+                              "%0.2f",
+                              rain_00);
+            }
+            else
+            {
+              // LaCrosse stations don't provide the since-midnight 
+              // numbers and so this will be blank.  
+              // So if we have blanks here, fill it in.
+              if ( weather->wx_prec_00[0] == '\0' && 
+                   weather->wx_rain_total[0] != '\0') {
+              
+                // Rain since midnight
+                xastir_snprintf(weather->wx_prec_00,
+                                sizeof(weather->wx_prec_00),
+                                "%0.2f",
+                                rain_00);
+              }
+            }
+                
+
+            /* get last gust speed */
+            if (strlen(weather->wx_gust) > 0) {
+                /* get last speed */
+                last_speed = (float)atof(weather->wx_gust);
+                last_speed_time = weather->wx_speed_sec_time;
+            } else
+                last_speed = 0.0;
+
+            /* wind speed */
+            computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                        last_speed,
+                                        &last_speed_time);
+            weather->wx_speed_sec_time = sec_now();
+            if ( (computed_gust > 0.0) || (weather->wx_gust != 0) )
+                xastir_snprintf(weather->wx_gust,
+                sizeof(weather->wx_gust),
+                "%03d",
+                (int)(computed_gust + 0.5)); // Cheater's way of rounding
+        }
+    }
+}
+
+
+
+
+
+/***********************************************************/
+/* clear other wx data                                     */
+/***********************************************************/
+void clear_local_wx_data(void) {
+    memset(wx_dew_point,0,sizeof(wx_dew_point));
+    wx_dew_point_on = 0;
+
+    memset(wx_high_wind,0,sizeof(wx_high_wind));
+    wx_high_wind_on = 0;
+
+    memset(wx_wind_chill,0,sizeof(wx_wind_chill));
+    wx_wind_chill_on = 0;
+
+    memset(wx_three_hour_baro,0,sizeof(wx_three_hour_baro));
+    wx_three_hour_baro_on = 0;
+
+    memset(wx_hi_temp,0,sizeof(wx_hi_temp));
+    wx_hi_temp_on = 0;
+
+    memset(wx_low_temp,0,sizeof(wx_low_temp));
+    wx_low_temp_on = 0;
+
+    memset(wx_heat_index,0,sizeof(wx_heat_index));
+    wx_heat_index_on = 0;
+}
+
+
+
+
+
+/***************************************************/
+/* Check last WX data received - clear data if old */
+/***************************************************/
+void wx_last_data_check(void) {
+    DataRow *p_station;
+
+    p_station = NULL;
+    if (search_station_name(&p_station,my_callsign,1)) {
+        if (p_station->weather_data != NULL)
+            if (p_station->weather_data->wx_speed_sec_time+360 < sec_now())
+                if (p_station->weather_data->wx_gust[0] != 0)
+                    xastir_snprintf(p_station->weather_data->wx_gust,
+                        sizeof(p_station->weather_data->wx_gust),
+                        "%03d",
+                        0);
+    }
+}
+
+
+
+
+
+//*********************************************************************
+// Decode Peet Brothers Ultimeter 2000 weather data (Data logging mode)
+//
+// This function is called from db.c:data_add() only.  Used for
+// decoding incoming packets, not for our own weather station data.
+//
+// The Ultimeter 2000 can be in any of three modes, Data Logging Mode,
+// Packet Mode, or Complete Record Mode.  This routine handles only
+// the Data Logging Mode.
+//*********************************************************************
+void decode_U2000_L(int from, unsigned char *data, WeatherRow *weather) {
+    time_t last_speed_time;
+    float last_speed;
+    float computed_gust;
+    char temp_data1[10];
+    char *temp_conv;
+    char format;
+
+    last_speed = 0.0;
+    last_speed_time = 0;
+    computed_gust = 0.0;
+    format = 0;
+
+    if (debug_level & 1)
+        fprintf(stderr,"APRS WX3 Peet Bros U-2k (data logging mode): |%s|\n", data);
+
+    weather->wx_type = WX_TYPE;
+    xastir_snprintf(weather->wx_station,
+        sizeof(weather->wx_station),
+        "U2k");
+
+    /* get last gust speed */
+    if (strlen(weather->wx_gust) > 0 && !from) {
+        /* get last speed */
+        last_speed = (float)atof(weather->wx_gust);
+        last_speed_time = weather->wx_speed_sec_time;
+    }
+
+    // 006B 00 58
+    // 00A4 00 46 01FF 380E 2755 02C1 03E8 ---- 0052 04D7    0001 007BM
+    // ^       ^  ^    ^    ^         ^                      ^
+    // 0       6  8    12   16        24                     40
+    /* wind speed */
+    if (data[0] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)data,4);
+        xastir_snprintf(weather->wx_speed,
+            sizeof(weather->wx_speed),
+            "%03d",
+            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+        if (from) {
+            weather->wx_speed_sec_time = sec_now();
+        } else {
+            /* local station */
+            computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                        last_speed,
+                                        &last_speed_time);
+            weather->wx_speed_sec_time = sec_now();
+            xastir_snprintf(weather->wx_gust,
+                sizeof(weather->wx_gust),
+                "%03d",
+                (int)(0.5 + computed_gust)); // Cheater's way of rounding
+        }
+    } else {
+        if (!from)
+            weather->wx_speed[0] = 0;
+    }
+
+    /* wind direction */
+    //
+    // Note that the first two digits here may be 00, or may be FF
+    // if a direction calibration has been entered.  We should zero
+    // them.
+    //
+    if (data[4] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+4),4);
+        temp_data1[0] = '0';
+        temp_data1[1] = '0';
+        xastir_snprintf(weather->wx_course,
+            sizeof(weather->wx_course),
+            "%03d",
+            (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+    } else {
+        xastir_snprintf(weather->wx_course,
+            sizeof(weather->wx_course),
+            "000");
+        if (!from)
+            weather->wx_course[0]=0;
+    }
+
+    /* outdoor temp */
+    if (data[8] != '-') { // '-' signifies invalid data
+        int temp4;
+
+        substr(temp_data1,(char *)(data+8),4);
+        temp4 = (int)strtol(temp_data1,&temp_conv,16);
+ 
+        if (temp_data1[0] > '7') {  // Negative value, convert
+            temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+        }
+
+        xastir_snprintf(weather->wx_temp,
+            sizeof(weather->wx_temp),
+            "%03d",
+            (int)((float)((temp4<<16)/65536)/10.0));
+
+    }
+    else {
+        if (!from)
+            weather->wx_temp[0]=0;
+    }
+
+    /* rain total long term */
+    if (data[12] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+12),4);
+        xastir_snprintf(weather->wx_rain_total,
+            sizeof(weather->wx_rain_total),
+            "%0.2f",
+            (float)strtol(temp_data1,&temp_conv,16)/100.0);
+        if (!from) {
+            /* local station */
+            compute_rain((float)atof(weather->wx_rain_total));
+            /*last hour rain */
+            xastir_snprintf(weather->wx_rain,
+                sizeof(weather->wx_rain),
+                "%0.2f",
+                rain_minute_total);
+            /*last 24 hour rain */
+            xastir_snprintf(weather->wx_prec_24,
+                sizeof(weather->wx_prec_24),
+                "%0.2f",
+                rain_24);
+            /* rain since midnight */
+            xastir_snprintf(weather->wx_prec_00,
+                sizeof(weather->wx_prec_00),
+                "%0.2f",
+                rain_00);
+        }
+    } else {
+        if (!from)
+            weather->wx_rain_total[0]=0;
+    }
+
+    /* baro */
+    if (data[16] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+16),4);
+        xastir_snprintf(weather->wx_baro,
+            sizeof(weather->wx_baro),
+            "%0.1f",
+            (float)strtol(temp_data1,&temp_conv,16)/10.0);
+    } else {
+        if (!from)
+            weather->wx_baro[0]=0;
+    }
+    
+
+    /* outdoor humidity */
+    if (data[24] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+24),4);
+        xastir_snprintf(weather->wx_hum,
+            sizeof(weather->wx_hum),
+            "%03d",
+            (int)((float)strtol(temp_data1,&temp_conv,16)/10.0));
+    } else {
+        if (!from)
+            weather->wx_hum[0]=0;
+    }
+
+    /* todays rain total */
+    if (data[40] != '-') { // '-' signifies invalid data
+        if (from) {
+            substr(temp_data1,(char *)(data+40),4);
+            xastir_snprintf(weather->wx_prec_00,
+                sizeof(weather->wx_prec_00),
+                "%0.2f",
+                (float)strtol(temp_data1,&temp_conv,16)/100.0);
+        }
+    } else {
+        if (!from)
+            weather->wx_prec_00[0] = 0;
+    }
+}
+
+
+
+
+
+//********************************************************************
+// Decode Peet Brothers Ultimeter 2000 weather data (Packet mode)
+//
+// This function is called from db.c:data_add() only.  Used for
+// decoding incoming packets, not for our own weather station data.
+//
+// The Ultimeter 2000 can be in any of three modes, Data Logging Mode,
+// Packet Mode, or Complete Record Mode.  This routine handles only
+// the Packet Mode.
+//********************************************************************
+void decode_U2000_P(int from, unsigned char *data, WeatherRow *weather) {
+    time_t last_speed_time;
+    float last_speed;
+    float computed_gust;
+    char temp_data1[10];
+    char *temp_conv;
+    int len;
+
+    last_speed      = 0.0;
+    last_speed_time = 0;
+    computed_gust   = 0.0;
+    len = (int)strlen((char *)data);
+
+    if (debug_level & 1)
+        fprintf(stderr,"APRS WX5 Peet Bros U-2k Packet (Packet mode): |%s|\n",data);
+
+    weather->wx_type = WX_TYPE;
+    xastir_snprintf(weather->wx_station,
+        sizeof(weather->wx_station),
+        "U2k");
+
+    /* get last gust speed */
+    if (strlen(weather->wx_gust) > 0 && !from) {
+        /* get last speed */
+        last_speed = (float)atof(weather->wx_gust);
+        last_speed_time = weather->wx_speed_sec_time;
+    }
+
+    // $ULTW   0031 00 37 02CE  0069 ---- 0000 86A0 0001 ---- 011901CC   0000 0005
+    //         ^       ^  ^     ^    ^                   ^               ^    ^
+    //         0       6  8     12   16                  32              44   48
+
+    /* wind speed peak over last 5 min */
+    if (data[0] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)data,4);
+        if (from) {
+            xastir_snprintf(weather->wx_gust,
+                sizeof(weather->wx_gust),
+                "%03d",
+                (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+            /* this may be the only wind data */
+            xastir_snprintf(weather->wx_speed,
+                sizeof(weather->wx_speed),
+                "%03d",
+                (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+        } else {
+            /* local station and may be the only wind data */
+            if (len < 51) {
+                xastir_snprintf(weather->wx_speed,
+                    sizeof(weather->wx_speed),
+                    "%03d",
+                    (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                        last_speed,
+                                        &last_speed_time);
+                weather->wx_speed_sec_time = sec_now();
+                xastir_snprintf(weather->wx_gust,
+                    sizeof(weather->wx_gust),
+                    "%03d",
+                    (int)(0.5 + computed_gust));
+            }
+        }
+    } else {
+        if (!from)
+            weather->wx_gust[0] = 0;
+    }
+
+    /* wind direction */
+    //
+    // Note that the first two digits here may be 00, or may be FF
+    // if a direction calibration has been entered.  We should zero
+    // them.
+    //
+    if (data[4] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+4),4);
+        temp_data1[0] = '0';
+        temp_data1[1] = '0';
+        xastir_snprintf(weather->wx_course,
+            sizeof(weather->wx_course),
+            "%03d",
+            (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+    } else {
+        xastir_snprintf(weather->wx_course,
+            sizeof(weather->wx_course),
+            "000");
+        if (!from)
+            weather->wx_course[0] = 0;
+    }
+
+    /* outdoor temp */
+    if (data[8] != '-') { // '-' signifies invalid data
+        int temp4;
+
+        substr(temp_data1,(char *)(data+8),4);
+        temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+        if (temp_data1[0] > '7') {  // Negative value, convert
+            temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+        }
+
+        xastir_snprintf(weather->wx_temp,
+            sizeof(weather->wx_temp),
+            "%03d",
+            (int)((float)((temp4<<16)/65536)/10.0));
+    }
+    else {
+        if (!from)
+            weather->wx_temp[0] = 0;
+    }
+    /* todays rain total (on some units) */
+    if ((data[44]) != '-') { // '-' signifies invalid data
+        if (from) {
+            substr(temp_data1,(char *)(data+44),4);
+            xastir_snprintf(weather->wx_prec_00,
+                sizeof(weather->wx_prec_00),
+                "%0.2f",
+                (float)strtol(temp_data1,&temp_conv,16)/100.0);
+        }
+    } else {
+        if (!from)
+            weather->wx_prec_00[0] = 0;
+    }
+
+    /* rain total long term */
+    if (data[12] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+12),4);
+        xastir_snprintf(weather->wx_rain_total,
+            sizeof(weather->wx_rain_total),
+            "%0.2f",
+            (float)strtol(temp_data1,&temp_conv,16)/100.0);
+        if (!from) {
+            /* local station */
+            compute_rain((float)atof(weather->wx_rain_total));
+            /*last hour rain */
+            xastir_snprintf(weather->wx_rain,
+                sizeof(weather->wx_rain),
+                "%0.2f",
+                rain_minute_total);
+            /*last 24 hour rain */
+            xastir_snprintf(weather->wx_prec_24,
+                sizeof(weather->wx_prec_24),
+                "%0.2f",
+                rain_24);
+            /* rain since midnight */
+            xastir_snprintf(weather->wx_prec_00,
+                sizeof(weather->wx_prec_00),
+                "%0.2f",
+                rain_00);
+        }
+    } else {
+        if (!from)
+            weather->wx_rain_total[0] = 0;
+    }
+
+    /* baro */
+    if (data[16] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+16),4);
+        xastir_snprintf(weather->wx_baro,
+            sizeof(weather->wx_baro),
+            "%0.1f",
+            (float)strtol(temp_data1,&temp_conv,16)/10.0);
+    } else {
+        if (!from)
+            weather->wx_baro[0] = 0;
+    }
+
+    /* outdoor humidity */
+    if (data[32] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+32),4);
+        xastir_snprintf(weather->wx_hum,
+            sizeof(weather->wx_hum),
+            "%03d",
+            (int)((float)strtol(temp_data1,&temp_conv,16)/10.0));
+    } else {
+        if (!from)
+            weather->wx_hum[0] = 0;
+    }
+
+    /* 1 min wind speed avg */
+    if (len > 48 && (data[48]) != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+48),4);
+        xastir_snprintf(weather->wx_speed,
+            sizeof(weather->wx_speed),
+            "%03d",
+            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+        if (from) {
+            weather->wx_speed_sec_time = sec_now();
+        } else {
+            /* local station */
+            computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                        last_speed,
+                                        &last_speed_time);
+            weather->wx_speed_sec_time = sec_now();
+            xastir_snprintf(weather->wx_gust,
+                sizeof(weather->wx_gust),
+                "%03d",
+                (int)(0.5 + computed_gust));
+        }
+    } else {
+        if (!from) {
+            if (len > 48)
+                weather->wx_speed[0] = 0;
+        }
+    }
+}
+
+
+
+
+
+//*****************************************************************
+// Decode Peet Brothers Ultimeter-II weather data
+//
+// This function is called from db.c:data_add() only.  Used for
+// decoding incoming packets, not for our own weather station data.
+//*****************************************************************
+void decode_Peet_Bros(int from, unsigned char *data, WeatherRow *weather, int type) {
+    time_t last_speed_time;
+    float last_speed;
+    float computed_gust;
+    char temp_data1[10];
+    char *temp_conv;
+
+    last_speed    = 0.0;
+    computed_gust = 0.0;
+    last_speed_time = 0;
+
+    if (debug_level & 1)
+        fprintf(stderr,"APRS WX4 Peet Bros U-II: |%s|\n",data);
+
+    weather->wx_type = WX_TYPE;
+    xastir_snprintf(weather->wx_station,
+        sizeof(weather->wx_station),
+        "UII");
+
+    // '*' = MPH
+    // '#' = km/h
+    //
+    // #  5 0B 75 0082 0082
+    // *  7 00 76 0000 0000
+    //    ^ ^  ^  ^
+    //            rain [1/100 inch ?]
+    //         outdoor temp
+    //      wind speed [mph / km/h]
+    //    wind dir
+
+    /* wind direction */
+    //
+    // 0x00 is N
+    // 0x04 is E
+    // 0x08 is S
+    // 0x0C is W
+    //
+    substr(temp_data1,(char *)data,1);
+    xastir_snprintf(weather->wx_course,
+        sizeof(weather->wx_course),
+        "%03d",
+        (int)(((float)strtol(temp_data1,&temp_conv,16)/16.0)*360.0));
+
+    /* get last gust speed */
+    if (strlen(weather->wx_gust) > 0 && !from) {
+        /* get last speed */
+        last_speed = (float)atof(weather->wx_gust);
+        last_speed_time = weather->wx_speed_sec_time;
+    }
+
+    /* wind speed */
+    substr(temp_data1,(char *)(data+1),2);
+    if (type == APRS_WX4) {     // '#'  speed in km/h, convert to mph
+        xastir_snprintf(weather->wx_speed,
+            sizeof(weather->wx_speed),
+            "%03d",
+            (int)(0.5 + (float)(strtol(temp_data1,&temp_conv,16)*0.62137)));
+    } else { // type == APRS_WX6,  '*'  speed in mph
+        xastir_snprintf(weather->wx_speed,
+            sizeof(weather->wx_speed),
+            "%03d",
+            (int)(0.5 + (float)strtol(temp_data1,&temp_conv,16)));
+    }
+
+    if (from) {
+        weather->wx_speed_sec_time = sec_now();
+    } else {
+        /* local station */
+        computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                last_speed,
+                                &last_speed_time);
+        weather->wx_speed_sec_time = sec_now();
+        xastir_snprintf(weather->wx_gust,
+            sizeof(weather->wx_gust),
+            "%03d",
+            (int)(0.5 + computed_gust));
+    }
+
+    /* outdoor temp */
+    if (data[3] != '-') { // '-' signifies invalid data
+        int temp4;
+
+        substr(temp_data1,(char *)(data+3),2);
+        temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+        if (temp_data1[0] > '7') {  // Negative value, convert
+            temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+        }
+
+        xastir_snprintf(weather->wx_temp,
+            sizeof(weather->wx_temp),
+            "%03d",
+            temp4-56);
+    } else {
+        if (!from)
+            weather->wx_temp[0] = 0;
+    }
+
+    // Rain divided by 100 for readings in hundredth of an inch
+    if (data[5] != '-') { // '-' signifies invalid data
+        substr(temp_data1,(char *)(data+5),4);
+        xastir_snprintf(weather->wx_rain_total,
+            sizeof(weather->wx_rain_total),
+            "%0.2f",
+            (float)strtol(temp_data1,&temp_conv,16)/100.0);
+        if (!from) {
+            /* local station */
+            compute_rain((float)atof(weather->wx_rain_total));
+            /*last hour rain */
+            xastir_snprintf(weather->wx_rain,
+                sizeof(weather->wx_rain),
+                "%0.2f",
+                rain_minute_total);
+            /*last 24 hour rain */
+            xastir_snprintf(weather->wx_prec_24,
+                sizeof(weather->wx_prec_24),
+                "%0.2f",
+                rain_24);
+            /* rain since midnight */
+            xastir_snprintf(weather->wx_prec_00,
+                sizeof(weather->wx_prec_00),
+                "%0.2f",
+                rain_00);
+        }
+    } else {
+        if (!from)
+            weather->wx_rain_total[0] = 0;
+    }
+}
+
+
+
+
+
+/**************************************************/
+/* RSW num convert.  For Radio Shack WX-200,      */
+/* converts two decimal nibbles into integer      */
+/* number.                                        */
+/**************************************************/
+int rswnc(unsigned char c) {
+    return( (int)( (c>>4) & 0x0f) * 10 + (int)(c&0x0f) );
+}
+
+
+
+
+
+//*********************************************************
+// wx fill data field
+// from: 0=local station, 1=regular decode (other stations)
+// type: type of WX packet
+// data: the packet of WX data
+// fill: the station data to fill
+//
+// This function is called only by wx.c:wx_decode()
+//
+// It is always called with a first parameter of 0, so we
+// use this only for our own serially-connected or network
+// connected weather station, not for decoding other
+// people's weather packets.
+//*********************************************************
+//
+// Note that the length of "data" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+void wx_fill_data(int from, int type, unsigned char *data, DataRow *fill) {
+    time_t last_speed_time;
+    float last_speed;
+    float computed_gust;
+    int  temp1;
+    int  temp2;
+    int  temp3;
+    float temp_temp;
+    char temp[MAX_DEVICE_BUFFER+1];
+    char temp_data1[10];
+    char *temp_conv;
+    int len;
+    int t2;
+    int hidx_temp;
+    int rh2;
+    int hi_hum;
+    int heat_index;
+    char format;
+    WeatherRow *weather;
+    float tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp9,tmp10,tmp11,tmp12,tmp13,tmp14,tmp15,tmp16,tmp17,tmp18,tmp19;
+    int tmp7,tmp8;
+    int dallas_type = 19;
+
+
+    last_speed=0.0;
+    computed_gust=0.0;
+    last_speed_time=0;
+    format = 0;
+
+
+    len=(int)strlen((char*)data);
+
+    weather = fill->weather_data;  // should always be defined
+
+    switch (type) {
+
+//WE7U
+        /////////////////////////////////////
+        // Dallas One-Wire Weather Station //
+        /////////////////////////////////////
+
+// KB1MTS - Added values for T13 thru T19 for humidity and barometer,
+// however only current values (not min or max) are used.
+
+
+        case (DALLAS_ONE_WIRE):
+
+            if (debug_level & 1)
+                fprintf(stderr,"APRS WX Dallas One-Wire %s:<%s>\n",fill->call_sign,data);
+
+            weather->wx_type=WX_TYPE;
+            xastir_snprintf(weather->wx_station,
+                sizeof(weather->wx_station),
+                "OWW");
+
+            if (19 == sscanf((const char *)data,
+                    "%f %f %f %f %f %f %d %d %f %f %f %f %f %f %f %f %f %f %f",
+                    &tmp1,
+                    &tmp2,
+                    &tmp3,
+                    &tmp4,
+                    &tmp5,
+                    &tmp6,
+                    &tmp7,
+                    &tmp8,
+                    &tmp9,
+                    &tmp10,
+                    &tmp11,
+                    &tmp12,
+                    &tmp13,
+                    &tmp14,
+                    &tmp15,
+                    &tmp16,
+                    &tmp17,
+                    &tmp18,
+                    &tmp19)) {
+                dallas_type = 19;
+            }
+            else if (12 == sscanf((const char *)data,
+                    "%f %f %f %f %f %f %d %d %f %f %f %f",
+                    &tmp1,
+                    &tmp2,
+                    &tmp3,
+                    &tmp4,
+                    &tmp5,
+                    &tmp6,
+                    &tmp7,
+                    &tmp8,
+                    &tmp9,
+                    &tmp10,
+                    &tmp11,
+                    &tmp12)) {
+                dallas_type = 12;
+            }
+            else {
+                fprintf(stderr,"wx_fill_data:sscanf parsing error\n");
+            }
+
+
+            // The format of the data originates here:
+            // http://weather.henriksens.net/
+
+            // tmp1: primary temp (C)
+            // tmp2: temp max (C)
+            // tmp3: temp min (C)
+            // tmp4: anemometer (mps)
+            // tmp5: anemometer gust (peak speed MS)
+            // tmp6: anemometer speed max * 0.447040972 (max speed MS)
+            // tmp7: vane bearing - 1 (current wind direction)
+            // tmp8: vane mode (max dir)
+            // tmp9: rain rate
+            // tmp10: rain total today
+            // tmp11: rain total week
+            // tmp12: rain since month
+            // tmp13: Current Humidity
+            // tmp14: Max Humidity
+            // tmp15: Min Humidity
+            // tmp16: Current Barometer
+            // tmp17: Max Barometer
+            // tmp18: Min Barometer
+            // tmp19: Barometer Rate
+
+            // Temperature
+            xastir_snprintf(weather->wx_temp,
+                sizeof(weather->wx_temp),
+                "%03d",
+                (int)(tmp1 * 9.0 / 5.0 + 32.0 + 0.5));
+            //fprintf(stderr,"Read: %2.1f C, Storing: %s F\n",tmp1,weather->wx_temp);
+
+            // Wind direction.  Each vane increment equals 22.5 degrees.
+            xastir_snprintf(weather->wx_course,
+                sizeof(weather->wx_course),
+                "%03d",
+                (int)(tmp7 * 22.5 + 0.5));
+
+            // Check for course = 0.  Change to 360.
+            if (strncmp(weather->wx_course,"000",3) == 0) {
+                xastir_snprintf(weather->wx_course,
+                sizeof(weather->wx_course),
+                "360");
+            }
+
+            // Wind speed.  We get it in meters per second, store it
+            // in mph.
+            tmp4 = tmp4 * 3600.0 / 1000.0; // kph
+            tmp4 = tmp4 * 0.62137;         // mph
+            xastir_snprintf(weather->wx_speed,
+                sizeof(weather->wx_speed),
+                "%03d",
+                (int)(tmp4 + 0.5));
+
+            if (dallas_type == 19) {
+                // Humidity.  This is received by percentage.
+                xastir_snprintf(weather->wx_hum,      
+                    sizeof(weather->wx_hum),
+                    "%2.1f", (double)(tmp13));
+                    
+                // Barometer. Sent in inHg
+                xastir_snprintf(weather->wx_baro,           
+                    sizeof(weather->wx_baro),
+                    "%4.4f", (float)(tmp16 * 33.864)); 
+            }
+
+
+// Rain:  I don't have a rain gauge, and I couldn't tell from the
+// "OWW" docs exactly which of the four rain fields did what.  If
+// someone can help me with that I'll add rain gauge code for the
+// Dallas One-Wire.
+              		
+
+
+            break;
+
+        ////////////////////////////////
+        // Peet Brothers Ultimeter-II //
+        ////////////////////////////////
+        case (APRS_WX4):    // '#', Wind speed in km/h
+        case (APRS_WX6):    // '*', Wind speed in mph
+
+            // This one assumes 0.1" rain gauge.  Must correct in software if
+            // any other type is used.
+
+            if (debug_level & 1)
+                fprintf(stderr,"APRS WX4 Peet Bros U-II %s:<%s>\n",fill->call_sign,data);
+
+            weather->wx_type=WX_TYPE;
+            xastir_snprintf(weather->wx_station,
+                sizeof(weather->wx_station),
+                "UII");
+
+            /* wind direction */
+            //
+            // 0x00 is N
+            // 0x04 is E
+            // 0x08 is S
+            // 0x0C is W
+            //
+            substr(temp_data1,(char *)(data+1),1);
+            xastir_snprintf(weather->wx_course,
+                sizeof(weather->wx_course),
+                "%03d",
+                (int)(((float)strtol(temp_data1,&temp_conv,16)/16.0)*360.0));
+
+            // Check for course == 0.  Change to 360.
+            if (strncmp(weather->wx_course,"000",3) == 0) {
+                xastir_snprintf(weather->wx_course,
+                sizeof(weather->wx_course),
+                "360");
+            }
+
+            /* get last gust speed */
+            if (strlen(weather->wx_gust) > 0 && !from) {    // From local station
+                /* get last speed */
+                last_speed=(float)atof(weather->wx_gust);
+                last_speed_time=weather->wx_speed_sec_time;
+            }
+
+            /* wind speed */
+            substr(temp_data1,(char *)(data+2),2);
+            if (type == APRS_WX4) { // '#', Data is in km/h, convert to mph
+                xastir_snprintf(weather->wx_speed,
+                    sizeof(weather->wx_speed),
+                    "%03d",
+                    (int)(0.5 + (float)(strtol(temp_data1,&temp_conv,16)*0.62137)));
+            } else { // APRS_WX6 or '*', Data is in MPH
+                xastir_snprintf(weather->wx_speed,
+                    sizeof(weather->wx_speed),
+                    "%03d",
+                    (int)(0.5 + (float)strtol(temp_data1,&temp_conv,16)));
+            }
+
+            if (from) { // From remote station
+                weather->wx_speed_sec_time = sec_now();
+            } else {
+                /* local station */
+                computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                        last_speed,
+                                        &last_speed_time);
+                weather->wx_speed_sec_time = sec_now();
+                if ( (computed_gust > 0.0) || (weather->wx_gust != 0) )
+                    xastir_snprintf(weather->wx_gust,
+                        sizeof(weather->wx_gust),
+                        "%03d",
+                        (int)(0.5 + computed_gust));
+            }
+
+            /* outdoor temp */
+            if (data[4]!='-') { // '-' signifies invalid data
+                int temp4;
+
+                substr(temp_data1,(char *)(data+4),2);
+                temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                if (temp_data1[0] > '7') {  // Negative value, convert
+                    temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                }
+
+                xastir_snprintf(weather->wx_temp,
+                    sizeof(weather->wx_temp),
+                    "%03d",
+                    temp4-56);
+            } else {
+                if (!from)  // From local station
+                    weather->wx_temp[0]=0;
+            }
+
+            /* rain div by 100 for readings 0.1 inch */
+// What?  Shouldn't this be /10?
+
+            if (data[6]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+6),4);
+                if (!from) {    // From local station
+                    switch (WX_rain_gauge_type) {
+                        case 1: // 0.1" rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)*10);
+                            break;
+                        case 3: // 0.1mm rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/2.54);
+                            break;
+                        case 2: // 0.01" rain gauge
+                        case 0: // No conversion
+                        default:
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16));
+                            break;
+                    }
+                    /* local station */
+                    compute_rain((float)atof(weather->wx_rain_total));
+                    weather->wx_compute_rain_rates=1;
+                    /*last hour rain */
+                    xastir_snprintf(weather->wx_rain,
+                        sizeof(weather->wx_rain),
+                        "%0.2f",
+                        rain_minute_total);
+                    /*last 24 hour rain */
+                    xastir_snprintf(weather->wx_prec_24,
+                        sizeof(weather->wx_prec_24),
+                        "%0.2f",
+                        rain_24);
+                    /* rain since midnight */
+                    xastir_snprintf(weather->wx_prec_00,
+                        sizeof(weather->wx_prec_00),
+                        "%0.2f",
+                        rain_00);
+                }
+            } else {
+                if (!from)  // From local station
+                    weather->wx_rain_total[0]=0;
+            }
+            break;
+
+
+
+        ///////////////////////////////////////////////////////
+        // Peet Brothers Ultimeter 2000 in data logging mode //
+        ///////////////////////////////////////////////////////
+        case (APRS_WX3):
+            if (debug_level & 1)
+                fprintf(stderr,"APRS WX3 Peet Bros U-2k (data logging mode) %s:<%s>\n",fill->call_sign,data+2);
+
+            weather->wx_type=WX_TYPE;
+            xastir_snprintf(weather->wx_station,
+                sizeof(weather->wx_station),
+                "U2k");
+
+            /* get last gust speed */
+            if (strlen(weather->wx_gust) > 0 && !from) {    // From local station
+                /* get last speed */
+                last_speed=(float)atof(weather->wx_gust);
+                last_speed_time=weather->wx_speed_sec_time;
+            }
+
+            /* wind speed */
+            if (data[2]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+2),4);
+                xastir_snprintf(weather->wx_speed,
+                    sizeof(weather->wx_speed),
+                    "%03d",
+                    (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                if (from) { // From remote station
+                    weather->wx_speed_sec_time = sec_now();
+                } else {
+                    /* local station */
+                    computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                        last_speed,
+                                        &last_speed_time);
+                    weather->wx_speed_sec_time = sec_now();
+                    if ( (computed_gust > 0.0) || (weather->wx_gust != 0) )
+                        xastir_snprintf(weather->wx_gust,
+                            sizeof(weather->wx_gust),
+                            "%03d",
+                            (int)(0.5 + computed_gust));
+                }
+            } else {
+                if (!from)  // From local station
+                    weather->wx_speed[0]=0;
+            }
+
+            /* wind direction */
+            //
+            // Note that the first two digits here may be 00, or may
+            // be FF if a direction calibration has been entered.
+            // We should zero them.
+            //
+            if (data[6]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+6),4);
+                // Zero out the first two bytes
+                temp_data1[0] = '0';
+                temp_data1[1] = '0';
+                xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "%03d",
+                    (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+
+                // Check for course = 0.  Change to 360.
+                if (strncmp(weather->wx_course,"000",3) == 0) {
+                    xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "360");
+                }
+
+            } else {
+                xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "000");
+                if (!from)  // From local station
+                    weather->wx_course[0]=0;
+            }
+
+            /* outdoor temp */
+            if (data[10]!='-') { // '-' signifies invalid data
+                int temp4;
+
+                substr(temp_data1,(char *)(data+10),4);
+                temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                if (temp_data1[0] > '7') {  // Negative value, convert
+                    temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                }
+
+                xastir_snprintf(weather->wx_temp,
+                    sizeof(weather->wx_temp),
+                    "%03d",
+                    (int)((float)((temp4<<16)/65536)/10.0));
+            } else {
+                if (!from)  // From local station
+                    weather->wx_temp[0]=0;
+            }
+
+            /* rain total long term */
+            if (data[14]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+14),4);
+                if (!from) {  // From local station
+                    switch (WX_rain_gauge_type) {
+                        case 1: // 0.1" rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)*10);
+                            break;
+                        case 3: // 0.1mm rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/2.54);
+                            break;
+                        case 2: // 0.01" rain gauge
+                        case 0: // No conversion
+                        default:
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16));
+                            break;
+                    }
+                    /* local station */
+                    compute_rain((float)atof(weather->wx_rain_total));
+                    weather->wx_compute_rain_rates=1;
+                    /*last hour rain */
+                    xastir_snprintf(weather->wx_rain,
+                        sizeof(weather->wx_rain),
+                        "%0.2f",
+                        rain_minute_total);
+                    /*last 24 hour rain */
+                    xastir_snprintf(weather->wx_prec_24,
+                        sizeof(weather->wx_prec_24),
+                        "%0.2f",
+                        rain_24);
+                    /* rain since midnight */
+                    xastir_snprintf(weather->wx_prec_00,
+                        sizeof(weather->wx_prec_00),
+                        "%0.2f",
+                        rain_00);
+                }
+            } else {
+                if (!from)  // From local station
+                    weather->wx_rain_total[0]=0;
+            }
+
+            /* baro */
+            if (data[18]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+18),4);
+                xastir_snprintf(weather->wx_baro,
+                    sizeof(weather->wx_baro),
+                    "%0.1f",
+                    (float)strtol(temp_data1,&temp_conv,16)/10.0);
+            }
+
+            /* outdoor humidity */
+            if (data[26]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+26),4);
+                xastir_snprintf(weather->wx_hum,
+                    sizeof(weather->wx_hum),
+                    "%03d",
+                    (int)((float)strtol(temp_data1,&temp_conv,16)/10.0));
+            } else {
+                if (!from)  // From local station
+                    weather->wx_hum[0]=0;
+            }
+
+            // Isn't this replaced by the above switch-case?
+            // No, I don't think so.  We can get these packets over
+            // RF as well.
+            /* todays rain total */
+            if (strlen((const char *)data) > 45) {
+                if (data[42]!='-') { // '-' signifies invalid data
+                    if (from) { // From remote station
+                        substr(temp_data1,(char *)(data+42),4);
+                        xastir_snprintf(weather->wx_prec_00,
+                            sizeof(weather->wx_prec_00),
+                            "%0.2f",
+                            (float)strtol(temp_data1,&temp_conv,16)/100.0);
+                    }
+                } else {
+                    if (!from)  // From local station
+                        weather->wx_prec_00[0]=0;
+                }
+            }
+            break;
+
+
+
+        /////////////////////////////////////////////////
+        // Peet Brothers Ultimeter 2000 in packet mode //
+        /////////////////////////////////////////////////
+        case(APRS_WX5):
+            if (debug_level & 1)
+                fprintf(stderr,"APRS WX5 Peet Bros U-2k Packet (Packet mode) %s:<%s>\n",fill->call_sign,data);
+
+            weather->wx_type=WX_TYPE;
+            xastir_snprintf(weather->wx_station,
+                sizeof(weather->wx_station),
+                "U2k");
+
+            /* get last gust speed */
+            if (strlen(weather->wx_gust) > 0 && !from) {    // From local station
+                /* get last speed */
+                last_speed=(float)atof(weather->wx_gust);
+                last_speed_time=weather->wx_speed_sec_time;
+            }
+
+            /* wind speed peak over last 5 min */
+            if (data[5]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+5),4);
+                if (from) { // From remote station
+                    xastir_snprintf(weather->wx_gust,
+                        sizeof(weather->wx_gust),
+                        "%03d",
+                        (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    /* this may be the only wind data */
+                    xastir_snprintf(weather->wx_speed,
+                        sizeof(weather->wx_speed),
+                        "%03d",
+                        (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                } else {
+                    /* local station and may be the only wind data */
+                    if (len<56) {
+                        xastir_snprintf(weather->wx_speed,
+                            sizeof(weather->wx_speed),
+                            "%03d",
+                            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                        computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                            last_speed,
+                                            &last_speed_time);
+                        weather->wx_speed_sec_time = sec_now();
+                        if ( (computed_gust > 0.0) || (weather->wx_gust != 0) )
+                            xastir_snprintf(weather->wx_gust,
+                                sizeof(weather->wx_gust),
+                                "%03d",
+                                (int)(0.5 + computed_gust));
+                    }
+                }
+            } else {
+                if (!from)  // From local station
+                    weather->wx_gust[0]=0;
+            }
+
+            /* wind direction */
+            //
+            // Note that the first two digits here may be 00, or may
+            // be FF if a direction calibration has been entered.
+            // We should zero them.
+            //
+            if (data[9]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+9),4);
+                temp_data1[0] = '0';
+                temp_data1[1] = '0';
+                xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "%03d",
+                    (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+
+                // Check for course = 0.  Change to 360.
+                if (strncmp(weather->wx_course,"000",3) == 0) {
+                    xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "360");
+                }
+
+            } else {
+                xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "000");
+                if (!from)  // From local station
+                    weather->wx_course[0]=0;
+            }
+
+            /* outdoor temp */
+            if (data[13]!='-') { // '-' signifies invalid data
+                int temp4;
+
+                substr(temp_data1,(char *)(data+13),4);
+                temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                if (temp_data1[0] > '7') {  // Negative value, convert
+                    temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                }
+
+                xastir_snprintf(weather->wx_temp,
+                    sizeof(weather->wx_temp),
+                    "%03d",
+                    (int)((float)((temp4<<16)/65536)/10.0));
+            } else {
+                if (!from)  // From local station
+                    weather->wx_temp[0]=0;
+            }
+            /* todays rain total (on some units) */
+            if (data[49]!='-') { // '-' signifies invalid data
+                if (from) { // From remote station
+                    substr(temp_data1,(char *)(data+49),4);
+                    xastir_snprintf(weather->wx_prec_00,
+                        sizeof(weather->wx_prec_00),
+                        "%0.2f",
+                        (float)strtol(temp_data1,&temp_conv,16)/100.0);
+                }
+            } else {
+                if (!from)  // From local station
+                    weather->wx_prec_00[0]=0;
+            }
+
+            /* rain total long term */
+            if (data[17]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+17),4);
+                if (!from) {    // From local station
+                    switch (WX_rain_gauge_type) {
+                        case 1: // 0.1" rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)*10);
+                            break;
+                        case 3: // 0.1mm rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/2.54);
+                            break;
+                        case 2: // 0.01" rain gauge
+                        case 0: // No conversion
+                        default:
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16));
+                            break;
+                    }
+                    /* local station */
+                    compute_rain((float)atof(weather->wx_rain_total));
+                    weather->wx_compute_rain_rates=1;
+                    /*last hour rain */
+                    xastir_snprintf(weather->wx_rain,
+                        sizeof(weather->wx_rain),
+                        "%0.2f",
+                        rain_minute_total);
+                    /*last 24 hour rain */
+                    xastir_snprintf(weather->wx_prec_24,
+                        sizeof(weather->wx_prec_24),
+                        "%0.2f",
+                        rain_24);
+                    /* rain since midnight */
+                    xastir_snprintf(weather->wx_prec_00,
+                        sizeof(weather->wx_prec_00),
+                        "%0.2f",
+                        rain_00);
+                }
+            } else {
+                if (!from)  // From local station
+                    weather->wx_rain_total[0]=0;
+            }
+
+            /* baro */
+            if (data[21]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+21),4);
+                xastir_snprintf(weather->wx_baro,
+                    sizeof(weather->wx_baro),
+                    "%0.1f",
+                    (float)strtol(temp_data1, &temp_conv, 16)/10.0);
+            } else {
+                if (!from)  // From local station
+                    weather->wx_baro[0]=0;
+            }
+
+            /* outdoor humidity */
+            if (data[37]!='-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+37),4);
+                xastir_snprintf(weather->wx_hum,
+                    sizeof(weather->wx_hum),
+                    "%03d",
+                    (int)((float)strtol(temp_data1,&temp_conv,16)/10.0));
+            } else {
+                if (!from)  // From local station
+                    weather->wx_hum[0]=0;
+            }
+
+            /* 1 min wind speed avg */
+            if (len>53 && (data[53]) != '-') { // '-' signifies invalid data
+                substr(temp_data1,(char *)(data+53),4);
+                xastir_snprintf(weather->wx_speed,
+                    sizeof(weather->wx_speed),
+                    "%03d",
+                    (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                if (from) { // From remote station
+                    weather->wx_speed_sec_time = sec_now();
+                } else {
+                    /* local station */
+                    computed_gust = compute_gust((float)atof(weather->wx_speed),
+                                            last_speed,
+                                            &last_speed_time);
+                    weather->wx_speed_sec_time = sec_now();
+                    if ( (computed_gust > 0.0) || (weather->wx_gust != 0) )
+                        xastir_snprintf(weather->wx_gust,
+                            sizeof(weather->wx_gust),
+                            "%03d",
+                            (int)(0.5 + computed_gust));
+                }
+            } else {
+                if (!from) {    // From local station
+                    if (len>53)
+                        weather->wx_speed[0]=0;
+                }
+            }
+            break;
+
+
+
+        //////////////////////////////////////////////////////////
+        // Peet Brothers Ultimeter 2000 in complete record mode //
+        //////////////////////////////////////////////////////////
+        //
+        // In this mode most fields are 4-bytes two's complement.  A
+        // few fields are 2-bytes wide.
+        //
+        // <http://www.peetbros.com/HTML_Pages/faqs.htm>
+        //
+        case(PEET_COMPLETE):
+            if (debug_level & 1)
+                fprintf(stderr,"Peet Bros U-2k Packet (Complete Record Mode) %s:<%s>\n",fill->call_sign,data);
+
+            if (!from) {    // From local station
+                int done_with_wx_speed = 0;
+
+
+                /* decode only for local station */
+                weather->wx_type=WX_TYPE;
+                xastir_snprintf(weather->wx_station,
+                    sizeof(weather->wx_station),
+                    "U2k");
+
+
+                if (data[12]!='-') { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+12),4);
+                    xastir_snprintf(weather->wx_gust,
+                        sizeof(weather->wx_gust),
+                        "%03d",
+                        (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                }
+                else
+                    weather->wx_gust[0]=0;
+
+
+                // Check whether field 115 is available at bytes 452
+                // through 455.  If so, that's the one-minute wind
+                // speed average in 0.1kph, which matches the APRS
+                // spec except for the units (which should be MPH).
+                if ( (len >= 456) && (data[452] != '-') ) { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+452),4);
+                    xastir_snprintf(weather->wx_speed,
+                        sizeof(weather->wx_speed),
+                        "%03d",
+                        (int)(0.5
+                            + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    done_with_wx_speed++;
+                }
+
+
+                // Some Peet units don't have that particular wind
+                // speed field, so snag what wind speed we can from
+                // the other wind speed fields, which don't quite
+                // match the APRS spec as they're instantaneous
+                // values, not one-minute sustained speeds.
+
+
+                // KG9AE
+                // Peet Bros CR mode wind values should be selected based on which are highest.
+                /* Wind Speed fields 1, 34, and 71.  Wind direction fields 2, 35, 72. */
+                if (data[4] !='-') { // '-' signifies invalid data
+                    substr(temp_data1, (char *)data+4, 4);
+                    temp1 = (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137);
+                }
+                else {
+                    temp1=0;
+                }
+                if (data[136] !='-') { // '-' signifies invalid data
+                    substr(temp_data1, (char *)data+136, 4);
+                    temp2 = (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137);
+                }
+                else {
+                    temp2=0;
+                }
+                if (data[284] !='-') { // '-' signifies invalid data
+                    substr(temp_data1, (char *)data+284, 4);
+                    temp3 = (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137);
+                }
+                else {
+                    temp3=0;
+                }
+
+                // fprintf(stderr,"WIND: wind1 %d, wind2 %d, wind3 %d\n", temp1, temp2, temp3);
+                    
+                // Select wind speed and direction based on which
+                // wind speed is the highest.  Ugh, surely there's a
+                // way to make this pretty. A function might be
+                // better.
+                if ( temp1 >= temp2 && temp1 >= temp3 ){
+                    // fprintf(stderr,"WIND:      ***\n");
+
+                    /* wind speed */
+                    if (!done_with_wx_speed) {
+                        substr(temp_data1,(char *)(data+4),4);
+                        xastir_snprintf(weather->wx_speed,
+                            sizeof(weather->wx_speed),
+                            "%03d",
+                            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    }
+
+                    /* wind direction */
+                    //
+                    // Note that the first two digits here may be
+                    // 00, or may be FF if a direction calibration
+                    // has been entered.  We should zero them.
+                    //
+                    if (data[8]!='-') { // '-' signifies invalid data
+                        substr(temp_data1,(char *)(data+8),4);
+                        temp_data1[0] = '0';
+                        temp_data1[1] = '0';
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "%03d",
+                            (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+
+                        // Check for course = 0.  Change to 360.
+                        if (strncmp(weather->wx_course,"000",3) == 0) {
+                            xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "360");
+                        }
+
+                    } else {
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "000");
+                        weather->wx_course[0]=0;
+                    }
+                }
+                else if ( temp2 >= temp1 && temp2 >= temp3 ){
+                    // fprintf(stderr,"WIND:               ***\n");
+
+                    if (!done_with_wx_speed) {
+                        /* wind speed */
+                        substr(temp_data1,(char *)(data+136),4);
+                        xastir_snprintf(weather->wx_speed,
+                            sizeof(weather->wx_speed),
+                            "%03d",
+                            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    }
+
+                    /* wind direction */
+                    //
+                    // Note that the first two digits here may be
+                    // 00, or may be FF if a direction calibration
+                    // has been entered.  We should zero them.
+                    //
+                    if (data[140]!='-') { // '-' signifies invalid data
+                        substr(temp_data1,(char *)(data+140),4);
+                        temp_data1[0] = '0';
+                        temp_data1[1] = '0';
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "%03d",
+                            (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+
+                        // Check for course = 0.  Change to 360.
+                        if (strncmp(weather->wx_course,"000",3) == 0) {
+                            xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "360");
+                        }
+
+                    } else {
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "000");
+                        weather->wx_course[0]=0;
+                    }
+                }
+                else if ( temp3 >= temp2 && temp3 >= temp1 ){
+                    // fprintf(stderr,"WIND:                        ***\n");
+
+                    if (!done_with_wx_speed) {
+                        /* wind speed */
+                        substr(temp_data1,(char *)(data+284),4);
+                        xastir_snprintf(weather->wx_speed,
+                            sizeof(weather->wx_speed),
+                            "%03d",
+                            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    }
+
+                    /* wind direction */
+                    //
+                    // Note that the first two digits here may be
+                    // 00, or may be FF if a direction calibration
+                    // has been entered.  We should zero them.
+                    //
+                    if (data[288]!='-') { // '-' signifies invalid data
+                        substr(temp_data1,(char *)(data+288),4);
+                        temp_data1[0] = '0';
+                        temp_data1[1] = '0';
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "%03d",
+                            (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+
+                        // Check for course = 0.  Change to 360.
+                        if (strncmp(weather->wx_course,"000",3) == 0) {
+                            xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "360");
+                        }
+
+                    } else {
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "000");
+                        weather->wx_course[0]=0;
+                    }
+                }
+                else {  /* Or default to the first value */
+                    // fprintf(stderr,"WIND: DEFAULTING!\n");
+
+                    if (!done_with_wx_speed) {
+                        /* wind speed */
+                        substr(temp_data1,(char *)(data+4),4);
+                        xastir_snprintf(weather->wx_speed,
+                            sizeof(weather->wx_speed),
+                            "%03d",
+                            (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    }
+
+                    /* wind direction */
+                    //
+                    // Note that the first two digits here may be
+                    // 00, or may be FF if a direction calibration
+                    // has been entered.  We should zero them.
+                    //
+                    if (data[8]!='-') { // '-' signifies invalid data
+                        substr(temp_data1,(char *)(data+8),4);
+                        temp_data1[0] = '0';
+                        temp_data1[1] = '0';
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "%03d",
+                            (int)(((float)strtol(temp_data1,&temp_conv,16)/256.0)*360.0));
+
+                        // Check for course = 0.  Change to 360.
+                        if (strncmp(weather->wx_course,"000",3) == 0) {
+                            xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "360");
+                        }
+
+                    } else {
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "000");
+                        weather->wx_course[0]=0;
+                    }
+                }
+
+
+                /* outdoor temp */
+                if (data[24]!='-') { // '-' signifies invalid data
+                    int temp4;
+
+                    substr(temp_data1,(char *)(data+24),4);
+                    temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                    if (temp_data1[0] > '7') {  // Negative value, convert
+                        temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                    }
+
+                    xastir_snprintf(weather->wx_temp,
+                        sizeof(weather->wx_temp),
+                        "%03d",
+                        (int)((float)((temp4<<16)/65536)/10.0));
+                } else
+                    weather->wx_temp[0]=0;
+
+// We don't want to parse this here because compute_rain()
+// calculates this for us from the accumulating long-term rain
+// total.  If we were to do it here as well, we'll get conflicting
+// results.  Since only some units put out today's rain total, we'll
+// just rely on our own calculations for it instead.  It'll work
+// across more units.
+/*
+                // todays rain total (on some units)
+                if (data[28]!='-') { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+28),4);
+                    switch (WX_rain_gauge_type) {
+                        case 1: // 0.1" rain gauge
+                            xastir_snprintf(weather->wx_prec_00,
+                                sizeof(weather->wx_prec_00),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/10.0);
+                            break;
+                        case 3: // 0.1mm rain gauge
+                            xastir_snprintf(weather->wx_prec_00,
+                                sizeof(weather->wx_prec_00),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/254.0);
+                            break;
+                        case 2: // 0.01" rain gauge
+                        case 0: // No conversion
+                        default:
+                            xastir_snprintf(weather->wx_prec_00,
+                                sizeof(weather->wx_prec_00),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/100.0);
+                            break;
+                    }
+                } else
+                    weather->wx_prec_00[0]=0;
+*/
+
+                /* rain total long term */
+                if ((char)data[432]!='-') { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+432),4);
+                    switch (WX_rain_gauge_type) {
+                        case 1: // 0.1" rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)*10);
+                            break;
+                        case 3: // 0.1mm rain gauge
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16)/2.54);
+                            break;
+                        case 2: // 0.01" rain gauge
+                        case 0: // No conversion
+                        default:
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                (float)strtol(temp_data1,&temp_conv,16));
+                            break;
+                    }
+                    /* Since local station only */
+                    compute_rain((float)atof(weather->wx_rain_total));
+                    weather->wx_compute_rain_rates=1;
+
+                    /*last hour rain */
+                    xastir_snprintf(weather->wx_rain,
+                        sizeof(weather->wx_rain),
+                        "%0.2f",
+                        rain_minute_total);
+
+                    /*last 24 hour rain */
+                    xastir_snprintf(weather->wx_prec_24,
+                        sizeof(weather->wx_prec_24),
+                        "%0.2f",
+                        rain_24);
+
+                    /* rain since midnight */
+                    xastir_snprintf(weather->wx_prec_00,
+                        sizeof(weather->wx_prec_00),
+                        "%0.2f",
+                        rain_00);
+                } else
+                    weather->wx_rain_total[0]=0;
+
+                /* baro */
+                if (data[32]!='-') { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+32),4);
+                    xastir_snprintf(weather->wx_baro,
+                        sizeof(weather->wx_baro),
+                        "%0.1f",
+                        (float)strtol(temp_data1,&temp_conv,16)/10.0);
+                } else
+                    weather->wx_baro[0]=0;
+
+                /* outdoor humidity */
+                if (data[52]!='-') { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+52),4);
+                    xastir_snprintf(weather->wx_hum,
+                        sizeof(weather->wx_hum),
+                        "%03d",
+                        (int)((float)strtol(temp_data1,&temp_conv,16)/10.0));
+                } else
+                    weather->wx_hum[0]=0;
+
+                /* dew point */
+                if (data[60]!='-') { // '-' signifies invalid data
+                    int temp4;
+
+                    substr(temp_data1,(char *)(data+60),4);
+                    temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                    if (temp_data1[0] > '7') {  // Negative value, convert
+                        temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                    }
+
+                    xastir_snprintf(wx_dew_point,
+                        sizeof(wx_dew_point),
+                        "%03d",
+                        (int)((float)((temp4<<16)/65536)/10.0));
+                    wx_dew_point_on = 1;
+                }
+
+                /*high winds for today*/
+                if (data[248]!='-') { // '-' signifies invalid data
+                    substr(temp_data1,(char *)(data+248),4);
+                    xastir_snprintf(wx_high_wind,
+                        sizeof(wx_high_wind),
+                        "%03d",
+                        (int)(0.5 + ((float)strtol(temp_data1,&temp_conv,16)/10.0)*0.62137));
+                    wx_high_wind_on = 1;
+                }
+
+                /*wind chill */
+                if (data[20]!='-') { // '-' signifies invalid data
+                    int temp4;
+
+                    substr(temp_data1,(char *)(data+20),4);
+                    temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                    if (temp_data1[0] > '7') {  // Negative value, convert
+                        temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                    }
+
+                    xastir_snprintf(wx_wind_chill,
+                            sizeof(wx_wind_chill),
+                            "%03d",
+                        (int)((float)((temp4<<16)/65536)/10.0));
+                    wx_wind_chill_on = 1;
+                }
+
+            /*3-Hr Barometric Change */
+            if (data[36]!='-') { // '-' signifies invalid data
+                int temp4;
+
+                substr(temp_data1,(char *)(data+36),4);
+                temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                if (temp_data1[0] > '7') {  // Negative value, convert
+                    temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                }
+
+                xastir_snprintf(wx_three_hour_baro,
+                    sizeof(wx_three_hour_baro),
+                    "%0.2f",
+// Old code
+//                  (float)((strtol(temp_data1,&temp_conv,16)<<16)/65536)/100.0/3.38639);
+// New code, fix by Matt Werner, kb0kqa:
+                    (float)((temp4<<16)/65536)/10.0);
+ 
+                wx_three_hour_baro_on = 1;
+            }
+
+            /* High Temp for Today*/
+            if (data[276]!='-') { // '-' signifies invalid data
+                int temp4;
+
+                substr(temp_data1,(char *)(data+276),4);
+                temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                if (temp_data1[0] > '7') {  // Negative value, convert
+                    temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                }
+
+                xastir_snprintf(wx_hi_temp,
+                    sizeof(wx_hi_temp),
+                    "%03d",
+                    (int)((float)((temp4<<16)/65536)/10.0));
+                wx_hi_temp_on = 1;
+            } else
+                wx_hi_temp_on = 0;
+
+            /* Low Temp for Today*/
+            if (data[100]!='-') { // '-' signifies invalid data
+                int temp4;
+
+                substr(temp_data1,(char *)(data+100),4);
+                temp4 = (int)strtol(temp_data1,&temp_conv,16);
+
+                if (temp_data1[0] > '7') {  // Negative value, convert
+                    temp4 = (temp4 & (temp4-0x7FFF)) - 0x8000;
+                }
+
+                xastir_snprintf(wx_low_temp,
+                    sizeof(wx_low_temp),
+                    "%03d",
+                    (int)((float)((temp4<<16)/65536)/10.0));
+                wx_low_temp_on = 1;
+            } else
+                wx_low_temp_on = 0;
+
+            /* Heat Index Calculation*/
+            hi_hum=atoi(weather->wx_hum);
+            rh2= atoi(weather->wx_hum);
+            rh2=(rh2 * rh2);
+            hidx_temp=atoi(weather->wx_temp);
+            t2= atoi(weather->wx_temp);
+            t2=(t2 * t2);
+
+            if (hidx_temp >= 70) {
+                heat_index=-42.379+2.04901523 * hidx_temp+10.1433127 * hi_hum-0.22475541
+                    * hidx_temp * hi_hum-0.00683783 * t2-0.05481717 * rh2+0.00122874
+                    * t2 * hi_hum+0.00085282 * hidx_temp * rh2-0.00000199 * t2 * rh2;
+                xastir_snprintf (wx_heat_index,
+                    sizeof(wx_heat_index),
+                    "%03d",
+                    heat_index);
+                wx_heat_index_on = 1;
+            } else
+                wx_heat_index_on = 0;
+        }
+        break;
+
+
+
+        ////////////////////////
+        // Qualimetrics Q-Net //
+        ////////////////////////
+        case(QM_WX):
+            if (debug_level & 1)
+                fprintf(stderr,"Qualimetrics Q-Net %s:<%s>\n",fill->call_sign,data);
+
+            weather->wx_type=WX_TYPE;
+            xastir_snprintf(weather->wx_station,
+                sizeof(weather->wx_station),
+                "Q-N");
+
+            // Can this sscanf overflow the "temp" buffer?  I
+            // changed the length of temp to MAX_DEVICE_BUFFER to
+            // avoid this problem.
+            if (6 != sscanf((char *)data,"%19s %d %19s %d %19s %d",temp,&temp1,temp,&temp2,temp,&temp3)) {
+                fprintf(stderr,"wx_fill_data:sscanf parsing error\n");
+            }
+
+            /* outdoor temp */
+            xastir_snprintf(weather->wx_temp,
+                sizeof(weather->wx_temp),
+                "%03d",
+                (int)((temp2/10.0)));
+
+            /* baro */
+            xastir_snprintf(weather->wx_baro,
+                sizeof(weather->wx_baro),
+                "%0.1f",
+                ((float)temp3/100.0)*33.864);
+
+            /* outdoor humidity */
+            xastir_snprintf(weather->wx_hum,
+                sizeof(weather->wx_hum),
+                "%03d",
+                temp1);
+
+            if (!from) {    // From local station
+                weather->wx_gust[0]=0;
+                weather->wx_course[0]=0;
+                weather->wx_rain[0]=0;
+                weather->wx_prec_00[0]=0;
+                weather->wx_prec_24[0]=0;
+                weather->wx_rain_total[0]=0;
+                weather->wx_gust[0]=0;
+                weather->wx_speed[0]=0;
+            }
+            break;
+
+
+
+        ///////////////////////////////////////////////////////////
+        //  Radio Shack WX-200 or Huger/Oregon Scientific WM-918 //
+        ///////////////////////////////////////////////////////////
+        case(RSWX200):
+
+            // Notes:  Many people run the wx200d daemon connected to the weather station,
+            // with Xastir then connected to wx200d.  Note that wx200d changes the protocol
+            // slightly:  It only sends frames that have changed to the clients.  This means
+            // even if the weather station is sending regular packets, wx200d won't send
+            // them along to Xastir if all the bits are the same as the last packet of that
+            // type.  To fix this I had to tie into the main.c:UpdateTime() function to do
+            // regular updates at a 30 second rate, to keep the rain and gust queues cycling
+            // on a regular basis.
+            //
+            // 2nd Note:  Some WX-200 weather stations send bogus data.  I had to add in a
+            // bunch of filtering to keep the global variables from getting corrupted by
+            // this data.  More filtering may need to be done and/or the limits may need to
+            // be changed.
+
+            if (!from) {    // From local station
+                if (debug_level & 1)
+                    fprintf(stderr,"RSWX200 WX (binary)\n");
+
+                weather->wx_type=WX_TYPE;
+                xastir_snprintf(weather->wx_station,
+                    sizeof(weather->wx_station),
+                    "RSW");
+
+                switch (data[0]) {
+                    case 0x8f: /* humidity */
+                        if ( (rswnc(data[20]) <= 100) && (rswnc(data[2]) >= 0) )
+                            xastir_snprintf(weather->wx_hum,
+                                sizeof(weather->wx_hum),
+                                "%03d",
+                                rswnc(data[20]));
+                        else
+                            //sprintf(weather->wx_hum,"100");
+                            fprintf(stderr,"Humidity out-of-range, ignoring: %03d\n",rswnc(data[20]) );
+                        break;
+
+                    case 0x9f: /* temp */
+                        /* all data in C ?*/
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%c%d%0.1f",
+                            ((data[17]&0x08) ? '-' : '+'),(data[17]&0x7),rswnc(data[16])/10.0);
+                        /*fprintf(stderr,"temp data: <%s> %d %d %d\n", temp_data1,((data[17]&0x08)==0x08),(data[17]&0x7),rswnc(data[16]));*/
+                        temp_temp = (float)((atof(temp_data1)*1.8)+32);
+                        if ( (temp_temp >= -99.0) && (temp_temp < 200.0) ) {
+                            xastir_snprintf(weather->wx_temp,
+                                sizeof(weather->wx_temp),
+                                "%03d",
+                                (int)((atof(temp_data1)*1.8)+32));
+                            /*fprintf(stderr,"Temp %s C %0.2f %03d\n",temp_data1,atof(temp_data1),(int)atof(temp_data1));
+                            fprintf(stderr,"Temp F %0.2f %03d\n",(atof(temp_data1)*1.8)+32,(int)(atof(temp_data1)*1.8)+32);
+                            */
+                        } else {  // We don't want to save this one
+                            fprintf(stderr,"Temp out-of-range, ignoring: %0.2f\n", temp_temp);
+                        }
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%c%d%d.%d",
+                            ((data[18]&0x80) ? '-' : '+'),(data[18]&0x70)>>4,(data[18]&0x0f),(data[17] & 0xf0) >> 4);
+                        xastir_snprintf(wx_hi_temp,
+                            sizeof(wx_hi_temp),
+                            "%03d",
+                            (int)((atof(temp_data1)*1.8)+32));
+                        wx_hi_temp_on=1;
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%c%d%d.%d",
+                            ((data[23]&0x80) ? '-' : '+'),(data[23]&0x70)>>4,(data[23]&0x0f),(data[22] & 0xf0) >> 4);
+                        xastir_snprintf(wx_low_temp,
+                            sizeof(wx_low_temp),
+                            "%03d",
+                            (int)((atof(temp_data1)*1.8)+32));
+                        wx_low_temp_on=1;
+                        break;
+
+                    case 0xaf: /* baro/dewpt */
+                        // local baro pressure in mb?
+                        // sprintf(weather->wx_baro,"%02d%02d",rswnc(data[2]),rswnc(data[1]));
+                        // Sea Level Adjusted baro in mb
+                        xastir_snprintf(weather->wx_baro,
+                            sizeof(weather->wx_baro),
+                            "%0d%02d%0.1f",
+                            (data[5]&0x0f),
+                            rswnc(data[4]),
+                            ((float)rswnc(data[3])/10.0));
+
+                        /* dew point in C */
+                        temp_temp = (int)((rswnc(data[18])*1.8)+32);
+                        if ( (temp_temp >= 32.0) && (temp_temp < 150.0) )
+                            xastir_snprintf(wx_dew_point,
+                                sizeof(wx_dew_point),
+                                "%03d",
+                                (int)((rswnc(data[18])*1.8)+32));
+                        else
+                            fprintf(stderr,"Dew point out-of-range, ignoring: %0.2f\n", temp_temp);
+                        break;
+
+                    case 0xbf: /* Rain */
+                        // All data in mm.  Convert to hundredths of an inch.
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%02d%02d",
+                            rswnc(data[6]),
+                            rswnc(data[5]));
+
+                        temp_temp = (float)(atof(temp_data1) * 3.9370079);
+
+                        if ( (temp_temp >= 0) && (temp_temp < 51200.0) ) { // Between 0 and 512 inches
+                            xastir_snprintf(weather->wx_rain_total,
+                                sizeof(weather->wx_rain_total),
+                                "%0.2f",
+                                atof(temp_data1) * 3.9370079);
+
+                            /* Since local station only */
+                            compute_rain((float)atof(weather->wx_rain_total));
+                            weather->wx_compute_rain_rates=1;
+                    
+                            /* Last hour rain */
+                            xastir_snprintf(weather->wx_rain,
+                                sizeof(weather->wx_rain),
+                                "%0.2f",
+                                rain_minute_total);
+
+                            /* Last 24 hour rain */
+                            xastir_snprintf(weather->wx_prec_24,
+                                sizeof(weather->wx_prec_24),
+                                "%0.2f",
+                                rain_24);
+
+                            /* Rain since midnight */
+                            xastir_snprintf(weather->wx_prec_00,
+                                sizeof(weather->wx_prec_00),
+                                "%0.2f",
+                                rain_00);
+                        } else {
+                            fprintf(stderr,"Total Rain out-of-range, ignoring: %0.2f\n", temp_temp);
+                        }
+                        break;
+
+                    case 0xcf: /* Wind w/chill*/
+                        /* get last gust speed */
+                        if (strlen(weather->wx_gust) > 0) {
+                            /* get last speed */
+                            last_speed=(float)atof(weather->wx_gust);
+                            last_speed_time=weather->wx_speed_sec_time;
+                        }
+                        /* all data in m/s */
+                        /* average wind speed */
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%01d%0.1f",
+                            (data[5]&0xf),
+                            (float)( rswnc(data[4]) / 10 ));
+                        // Convert to mph
+                        xastir_snprintf(weather->wx_speed,
+                            sizeof(weather->wx_speed),
+                            "%03d",
+                            (int)(0.5 + (atof(temp_data1)*2.2369)));
+
+                        /* wind gust */
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%01d%0.1f",
+                            (data[2]&0xf),
+                            (float)( rswnc(data[1]) / 10 ));
+                        /*sprintf(weather->wx_gust,"%03d",(int)(0.5 + (atof(temp_data1)*2.2369)));*/
+
+                        /* do computed gust, convert to mph */
+                        computed_gust = compute_gust((int)(0.5 + (atof(temp_data1)*2.2369)),
+                                            last_speed,
+                                            &last_speed_time);
+                        weather->wx_speed_sec_time = sec_now();
+                        if ( (computed_gust > 0.0) || (weather->wx_gust != 0) )
+                            xastir_snprintf(weather->wx_gust,
+                                sizeof(weather->wx_gust),
+                                "%03d",
+                                (int)(0.5 + computed_gust));
+
+                        /* high wind gust */
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%01d%0.1f",
+                            (data[8]&0xf),
+                            (float)( rswnc(data[7]) / 10 ));
+                        xastir_snprintf(wx_high_wind,
+                            sizeof(wx_high_wind),
+                            "%03d",
+                            (int)(0.5 + (atof(temp_data1)*2.2369)));
+                        wx_high_wind_on = 1;
+
+                        xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "%02d%01d",
+                            rswnc(data[3]),
+                            (data[2]&0xf0)>>4);
+
+                        // Check for course = 0.  Change to 360.
+                        if (strncmp(weather->wx_course,"000",3) == 0) {
+                            xastir_snprintf(weather->wx_course,
+                            sizeof(weather->wx_course),
+                            "360");
+                        }
+
+                        /* wind chill in C */
+                        xastir_snprintf(temp_data1,
+                            sizeof(temp_data1),
+                            "%c%d",
+                            ((data[21]&0x20) ? '-' : '+'),
+                            rswnc(data[16]));
+
+                        temp_temp = (float)((atof(temp_data1)*1.8)+32);
+                        if ( (temp_temp > -200.0) && (temp_temp < 200.0) )
+                            xastir_snprintf(wx_wind_chill,
+                                sizeof(wx_wind_chill),
+                                "%03d",
+                                (int)((atof(temp_data1)*1.8)+32));
+                        else
+                            fprintf(stderr,"Wind_chill out-of-range, ignoring: %0.2f\n", temp_temp);
+
+                        wx_wind_chill_on = 1;
+                        break;
+                    default:
+                        break;
+                }
+
+                if (strlen(weather->wx_hum) > 0 && strlen(weather->wx_temp) > 0) {
+                    /* Heat Index Calculation*/
+                    hi_hum=atoi(weather->wx_hum);
+                    rh2= atoi(weather->wx_hum);
+                    rh2=(rh2 * rh2);
+                    hidx_temp=atoi(weather->wx_temp);
+                    t2= atoi(weather->wx_temp);
+                    t2=(t2 * t2);
+
+                    if (hidx_temp >= 70) {
+                        heat_index=(-42.379+2.04901523 * hidx_temp+10.1433127 * hi_hum-0.22475541 * hidx_temp *
+                                hi_hum-0.00683783 * t2-0.05481717 * rh2+0.00122874 * t2 * hi_hum+0.00085282 *
+                                hidx_temp * rh2-0.00000199 * t2 * rh2);
+                        xastir_snprintf(wx_heat_index,
+                            sizeof(wx_heat_index),
+                            "%03d",
+                            heat_index);
+
+                        wx_heat_index_on=1;
+                    }
+                    else {
+                            wx_heat_index[0] = 0;
+                    }
+                }   // end of heat index calculation
+            }   // end of if (!from)
+            break;  // End of case for RSWX200 weather station
+
+
+        ///////////////////////////////////////////////////////////
+        //  Davis WMII/WWIII/Vantage Pro via meteo & db2APRS     //
+        ///////////////////////////////////////////////////////////
+
+        // Note: format is really APRS Spec 'positionless' WX string w/tag for X and Davis
+
+        case(DAVISMETEO) :
+
+
+            // todo - need to deal with lack of values, such as c...s...g...t045 string
+
+            memset(weather->wx_course,0,4);    // Keep out fradulent data...
+            memset(weather->wx_speed,0,4);
+            memset(weather->wx_gust,0,4);
+            memset(weather->wx_temp,0,5);
+            memset(weather->wx_rain,0,10);
+            memset(weather->wx_prec_00,0,10);
+            memset(weather->wx_prec_24,0,10);
+            memset(weather->wx_rain_total,0,10);
+            memset(weather->wx_hum,0,5);
+            memset(weather->wx_baro,0,10);
+            memset(weather->wx_station,0,MAX_WXSTATION);
+			
+            if ((temp_conv=strchr((char *)data,'c'))) { // Wind Direction in Degrees 
+                xastir_snprintf(weather->wx_course,
+                    sizeof(weather->wx_course),
+                    "%s",
+                    temp_conv+1);
+                weather->wx_course[3] = '\0';
+            }
+
+            // Check for course = 0.  Change to 360.
+            if (strncmp(weather->wx_course,"000",3) == 0) {
+                xastir_snprintf(weather->wx_course,
+                sizeof(weather->wx_course),
+                "360");
+            }
+				
+            if ((temp_conv=strchr((char *)data,'s'))) { // Wind Speed in MPH - not snowfall
+                xastir_snprintf(weather->wx_speed,
+                    sizeof(weather->wx_speed),
+                    "%s",
+                    temp_conv+1);
+                weather->wx_speed[3] = '\0';
+            }
+
+            if ((temp_conv=strchr((char *)data,'g'))) { // Wind Gust in MPH
+                xastir_snprintf(weather->wx_gust,
+                    sizeof(weather->wx_gust),
+                    "%s",
+                    temp_conv+1);
+                weather->wx_gust[3] = '\0';
+
+                // compute high wind
+                if(wx_high_wind[0] == '\0' ||   // first time
+                        (get_hours() == 0 && get_minutes() == 0) || // midnite
+                        (atol(weather->wx_gust) > atol(wx_high_wind))) { // gust
+                    xastir_snprintf(wx_high_wind,
+                        sizeof(wx_high_wind),
+                        "%s",
+                        weather->wx_gust);
+                }
+                wx_high_wind_on=1;
+            }
+
+            if ((temp_conv=strchr((char *)data,'t'))) { // Temperature in Degrees F
+                xastir_snprintf(weather->wx_temp,
+                    sizeof(weather->wx_temp),
+                    "%s",
+                    temp_conv+1);
+                weather->wx_temp[3] = '\0';  	
+
+                // compute hi temp, since APRS doesn't send that
+                if(wx_hi_temp[0] == '\0' || // first time 
+                        (get_hours() == 0 && get_minutes() == 0) || // midnite
+                        (atol(weather->wx_temp) > atol(wx_hi_temp))) {
+                    xastir_snprintf(wx_hi_temp,
+                        sizeof(wx_hi_temp),
+                        "%s",
+                        weather->wx_temp);
+                }
+                wx_hi_temp_on=1;
+
+                // compute low temp, since APRS doesn't send that
+                if(wx_low_temp[0] == '\0' || // first time 
+                        (get_hours() == 0 && get_minutes() == 0) || // midnite
+                        (atol(weather->wx_temp) < atol(wx_low_temp))) {
+                    xastir_snprintf(wx_low_temp,
+                        sizeof(wx_low_temp),
+                        "%s",
+                        weather->wx_temp);
+                }
+                wx_low_temp_on=1;
+            }
+
+            if ((temp_conv=strchr((char *)data,'r'))) { // Rain per hour
+                xastir_snprintf(weather->wx_rain,
+                    sizeof(weather->wx_rain),
+                    "%s",
+                    temp_conv+1);
+                weather->wx_rain[3] = '\0';
+            }
+
+            if ((temp_conv=strchr((char *)data,'p'))) { // Rain per 24 hrs/total
+                xastir_snprintf(weather->wx_prec_24,
+                    sizeof(weather->wx_prec_24),
+                    "%s",
+                    temp_conv+1);
+                    weather->wx_prec_24[3] = '\0';
+            }
+
+            if ((temp_conv=strchr((char *)data,'P'))) { // Rain since midnight
+                xastir_snprintf(weather->wx_prec_00,
+                    sizeof(weather->wx_prec_00),
+                    "%s",
+                    temp_conv+1);
+                    weather->wx_prec_00[3] = '\0';
+            }
+
+            if ((temp_conv=strchr((char *)data,'T'))) { // Total Rain since
+                                                        // wx station reset
+                xastir_snprintf(weather->wx_rain_total,
+                    sizeof(weather->wx_rain_total),
+                    "%s",
+                    temp_conv+1);
+                    weather->wx_rain_total[4] = '\0';
+            }
+
+            // Ok, here's the deal --- if we got total rain AND we didn't get
+            // rain-since-midnight, fix it up.
+            // This is a problem with LaCrosse --- no rain-since-midnight
+            // provided.  Don't do anything at all if we didn't get total rain
+            // from the station.  compute_rain *depends* on "total rain" being
+            // a strictly increasing number that is never reset to zero during
+            // Xastir's run.  
+            if (strlen(weather->wx_rain_total) >0 ) {
+              compute_rain((float)atof(weather->wx_rain_total));
+              if (weather->wx_prec_00[0] == '\0') {
+                /* rain since midnight */
+                xastir_snprintf(weather->wx_prec_00,
+                                sizeof(weather->wx_prec_00),
+                                "%0.2f",
+                                rain_00);
+              }
+            } 
+
+            // we are should be getting total rain from the station, but
+            // we are also getting the rates.
+            // Davis gives 24-hour, since-midnight, and 1-hour rates.
+            // LaCrosse gives 24 and 1 hour.
+            // Don't recompute what the station already gave us.
+            weather->wx_compute_rain_rates=0;
+
+            if ((temp_conv=strchr((char *)data,'h'))) { // Humidity %
+
+                if (!strncmp(temp_conv+1,"00",2)) {  // APRS says 00 is	
+                    xastir_snprintf(weather->wx_hum, // 100% humidity
+                        sizeof(weather->wx_hum),
+                        "%s",
+                        "100");
+                        weather->wx_hum[3] = '\0';
+    		    } else {
+                    xastir_snprintf(weather->wx_hum, // humidity less than
+                        sizeof(weather->wx_hum),     // 100%
+                        "%s",
+                        temp_conv+1);
+                        weather->wx_hum[2] = '\0';
+                }
+            } 	 
+
+            if ((temp_conv=strchr((char *)data,'b'))) { // Air Pressure in 1/10 hPa
+			    memset(temp_data1,0,sizeof(temp_data1));
+
+                xastir_snprintf(temp_data1,
+                    sizeof(temp_data1),
+                    "%s",
+                    temp_conv+1);
+                temp_data1[5] = '\0';
+
+			    temp_temp = (float)(atof(temp_data1))/10.0;
+                xastir_snprintf(temp_data1,
+                    sizeof(temp_data1),
+                    "%0.1f",
+                    temp_temp);
+                xastir_snprintf(weather->wx_baro,
+                    sizeof(weather->wx_baro),
+                    "%s",
+                    temp_data1);
+            }
+
+            if ((temp_conv=strchr((char *)data,'x'))) { // WX Station Identifier
+                xastir_snprintf(weather->wx_station,
+                    sizeof(weather->wx_station),
+                    "%s",
+                    temp_conv+1);
+                weather->wx_station[MAX_WXSTATION-1] = '\0';
+            }
+
+            // now compute wind chill
+            wind_chill = 35.74 + .6215 * atof(weather->wx_temp) - 
+                35.75 * pow(atof(weather->wx_gust), .16) + 
+                .4275 * atof(weather->wx_temp) * 
+                pow(atof(weather->wx_gust), .16);
+
+            if((wind_chill < atof(weather->wx_temp)) && 
+                    (atof(weather->wx_temp) < 50)) {
+
+                xastir_snprintf(wx_wind_chill,
+                    sizeof(wx_wind_chill),
+                    "%.0f",
+                    wind_chill);
+                wx_wind_chill_on = 1;	
+            }
+            else {
+                wx_wind_chill_on = 0;
+                wx_wind_chill[0] = '\0';
+            }
+
+            // The rest of the optional WX data is not used by
+            // xastir (Luminosity, etc), except for snow, which
+            // conflicts with wind speed (both are lower case 's')
+
+            if (debug_level & 1)
+                fprintf(stdout,"Davis Decode: wd-%s,ws-%s,wg-%s,t-%s,rh-%s,r00-%s,r24-%s,rt-%s,h-%s,ap-%s,station-%s\n",
+
+                        weather->wx_course,weather->wx_speed,weather->wx_gust,
+                        weather->wx_temp,weather->wx_rain,weather->wx_prec_00,
+                        weather->wx_prec_24,weather->wx_rain_total,
+                        weather->wx_hum,weather->wx_baro,weather->wx_station);
+            break;
+         // This is the output of the Davis APRS Data Logger.  The format
+         // is in fact exactly the same as a regular APRS weather packet,
+         // complete with position information.  Ignore that.
+         // @xxxxxxzDDMM.mmN/DDDMM.mmW_CSE/SPDgGGGtTTTrRRRpRRRPRRRhXXbXXXXX.DsVP
+        case (DAVISAPRSDL):
+
+            memset(weather->wx_course,0,4);    // Keep out fradulent data...
+            memset(weather->wx_speed,0,4);
+            memset(weather->wx_gust,0,4);
+            memset(weather->wx_temp,0,5);
+            memset(weather->wx_rain,0,10);
+            memset(weather->wx_prec_00,0,10);
+            memset(weather->wx_prec_24,0,10);
+            memset(weather->wx_rain_total,0,10);
+            memset(weather->wx_hum,0,5);
+            memset(weather->wx_baro,0,10);
+            memset(weather->wx_station,0,MAX_WXSTATION);
+			
+            if (sscanf((char *)data,
+                       "%*27s%3s/%3sg%3st%3sr%3sp%3sP%3sh%2sb%5s.DsVP",
+                       weather->wx_course,
+                       weather->wx_speed,
+                       weather->wx_gust,
+                       weather->wx_temp,
+                       weather->wx_rain,
+                       weather->wx_prec_24,
+                       weather->wx_prec_00,
+                       weather->wx_hum,
+                       weather->wx_baro) == 9){
+              // then we got all the data out of the packet... now process
+              // First null-terminate all the strings:
+              weather->wx_course[3]='\0';
+              weather->wx_speed[3]='\0';
+              weather->wx_gust[3]='\0';
+              weather->wx_temp[3]='\0';
+              weather->wx_rain[3]='\0';
+              weather->wx_prec_24[3]='\0';
+              weather->wx_prec_00[3]='\0';
+              weather->wx_hum[2]='\0';
+              weather->wx_baro[6]='\0';
+
+
+              // NOTE:  Davis APRS Data Logger does NOT provide total rain,
+              // and so data from compute_rain (which needs total rain) will
+              // be wrong.  Set this flag to stop that from clobbering our
+              // good rain rate data.
+              weather->wx_compute_rain_rates=0;
+
+              // Check for course = 0.  Change to 360.
+              if (strncmp(weather->wx_course,"000",3) == 0) {
+                xastir_snprintf(weather->wx_course,
+                                sizeof(weather->wx_course),
+                                "360");
+              }
+              
+              // compute high wind
+              if(wx_high_wind[0] == '\0' ||   // first time
+                 (get_hours() == 0 && get_minutes() == 0) || // midnite
+                 (atol(weather->wx_gust) > atol(wx_high_wind))) { // gust
+                xastir_snprintf(wx_high_wind,
+                                sizeof(wx_high_wind),
+                                "%s",
+                                weather->wx_gust);
+              }
+              wx_high_wind_on=1;
+              
+              // compute hi temp, since APRS doesn't send that
+              if(wx_hi_temp[0] == '\0' || // first time 
+                 (get_hours() == 0 && get_minutes() == 0) || // midnite
+                 (atol(weather->wx_temp) > atol(wx_hi_temp))) {
+                xastir_snprintf(wx_hi_temp,
+                                sizeof(wx_hi_temp),
+                                "%s",
+                                weather->wx_temp);
+              }
+              wx_hi_temp_on=1;
+              
+              // compute low temp, since APRS doesn't send that
+              if(wx_low_temp[0] == '\0' || // first time 
+                 (get_hours() == 0 && get_minutes() == 0) || // midnite
+                 (atol(weather->wx_temp) < atol(wx_low_temp))) {
+                xastir_snprintf(wx_low_temp,
+                                sizeof(wx_low_temp),
+                                "%s",
+                                weather->wx_temp);
+              }
+              wx_low_temp_on=1;
+              
+              
+              // fix up humidity --- 00 in APRS means 100%:
+              if (strncmp(weather->wx_hum,"00",2)==0) {
+                weather->wx_hum[0]='1'; 
+                weather->wx_hum[1]=weather->wx_hum[2]='0'; 
+                weather->wx_hum[3]='\0';
+              }
+              
+              // fix up barometer.  APRS sends in 10ths of millibars:
+              temp_temp=(float)(atof(weather->wx_baro))/10.0;
+              weather->wx_baro[0]='\0'; // zero out so snprintf doesn't append
+              xastir_snprintf(weather->wx_baro,
+                              sizeof(weather->wx_baro),
+                              "%0.1f",
+                              temp_temp);  // this should terminate Just Fine.
+              
+              // now compute wind chill
+              wind_chill = 35.74 + .6215 * atof(weather->wx_temp) - 
+                35.75 * pow(atof(weather->wx_gust), .16) + 
+                .4275 * atof(weather->wx_temp) * 
+                pow(atof(weather->wx_gust), .16);
+              
+              if((wind_chill < atof(weather->wx_temp)) && 
+                 (atof(weather->wx_temp) < 50)) {
+                
+                xastir_snprintf(wx_wind_chill,
+                                sizeof(wx_wind_chill),
+                                "%.0f",
+                                wind_chill);
+                wx_wind_chill_on = 1;	
+              }
+              else {
+                wx_wind_chill_on = 0;
+                wx_wind_chill[0] = '\0';
+              }
+              xastir_snprintf(weather->wx_station,
+                              sizeof(weather->wx_station),
+                              "%s",
+                              (char *) &(data[63]));
+              
+              /* Heat Index Calculation*/
+              hi_hum=atoi(weather->wx_hum);
+              rh2= atoi(weather->wx_hum);
+              rh2=(rh2 * rh2);
+              hidx_temp=atoi(weather->wx_temp);
+              t2= atoi(weather->wx_temp);
+              t2=(t2 * t2);
+              
+              if (hidx_temp >= 70) {
+                heat_index=-42.379+2.04901523 * hidx_temp+10.1433127 * hi_hum-0.22475541
+                  * hidx_temp * hi_hum-0.00683783 * t2-0.05481717 * rh2+0.00122874
+                  * t2 * hi_hum+0.00085282 * hidx_temp * rh2-0.00000199 * t2 * rh2;
+                xastir_snprintf (wx_heat_index,
+                                 sizeof(wx_heat_index),
+                                 "%03d",
+                                 heat_index);
+                wx_heat_index_on = 1;
+              } else
+                wx_heat_index_on = 0;
+              
+              
+              if (debug_level & 1)
+                fprintf(stdout,"Davis APRS DataLogger Decode $Revision: 1.80 $: wd-%s,ws-%s,wg-%s,t-%s,rh-%s,r24-%s,r00-%s,h-%s,ap-%s,station-%s\n",
+                        
+                        weather->wx_course,weather->wx_speed,weather->wx_gust,
+                        weather->wx_temp, weather->wx_rain,
+                        weather->wx_prec_24, weather->wx_prec_00,weather->wx_hum,weather->wx_baro,
+                        weather->wx_station);
+            }
+            break;
+            
+    }            
+       // End of big switch
+}   // End of wx_fill_data()
+
+
+
+
+
+//**********************************************************
+// Decode WX data line
+// wx_line: raw wx data to decode
+//
+// This is called from main.c:UpdateTime() only.  It
+// decodes data for serially-connected and network-connected
+// WX interfaces only.   It calls wx_fill_data() to do the
+// real work once it figures out what type of data it has.
+//**********************************************************
+//
+// Note that the length of "wx_line" can be up to MAX_DEVICE_BUFFER,
+// which is currently set to 4096.
+//
+void wx_decode(unsigned char *wx_line, int data_length, int port) {
+    DataRow *p_station;
+    int decoded;
+    int find;
+    int i;
+    int len;
+    char time_data[MAX_TIME];
+    unsigned int check_sum;
+    int max;
+    WeatherRow *weather;
+    float t1,t2,t3,t4,t5,t6,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19;
+    int t7,t8;
+
+
+    //fprintf(stderr,"wx_decode: %s\n",wx_line);
+    //fprintf(stderr,"\nwx_decode: %d bytes\n", data_length);
+
+    find=0;
+
+    len = data_length;
+    if (len == 0) {
+        len=strlen((char *)wx_line);
+    }
+
+    if (len>10 || ((int)wx_line[0]!=0 && port_data[port].data_type==1)) {
+        if (search_station_name(&p_station,my_callsign,1)) {
+            if (get_weather_record(p_station)) {    // DK7IN: only add record if we found something...
+                weather = p_station->weather_data;
+        
+                decoded=0;
+                /* Ok decode wx data */
+                if (wx_line[0]=='!'
+                        && wx_line[1]=='!'
+                        && is_xnum_or_dash((char *)(wx_line+2),40)
+                        && port_data[port].data_type==0) {
+
+                    /* Found Peet Bros U-2k */
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found Peet Bros U-2k WX:%s\n",wx_line+2);
+
+                    xastir_snprintf(wx_station_type,
+                        sizeof(wx_station_type),
+                        "%s",
+                        langcode("WXPUPSI011"));
+
+                    xastir_snprintf(raw_wx_string,
+                        sizeof(raw_wx_string),
+                        "%s",
+                        wx_line);
+
+                    raw_wx_string[MAX_RAW_WX_STRING] = '\0';    // Terminate it
+
+                    xastir_snprintf(weather->wx_time,
+                        sizeof(weather->wx_time),
+                        "%s",
+                        get_time(time_data));
+
+                    weather->wx_sec_time=sec_now();
+                    //weather->wx_data=1;
+                    wx_fill_data(0,APRS_WX3,wx_line,p_station);
+                    decoded=1;
+                }
+                else if (((wx_line[0]=='#') || (wx_line[0]=='*'))
+                        && is_xnum_or_dash((char *)(wx_line+1),13)
+                        && port_data[port].data_type==0) {
+
+                    /* Found Peet Bros raw U2 data */
+                    xastir_snprintf(wx_station_type,
+                        sizeof(wx_station_type),
+                        "%s",
+                        langcode("WXPUPSI012"));
+
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found Peet Bros raw U2 data WX#:%s\n",wx_line+1);
+
+                    xastir_snprintf(raw_wx_string,
+                        sizeof(raw_wx_string),
+                        "%s",
+                        wx_line);
+
+                    raw_wx_string[MAX_RAW_WX_STRING] = '\0'; // Terminate it
+
+                    xastir_snprintf(weather->wx_time,
+                        sizeof(weather->wx_time),
+                        "%s",
+                        get_time(time_data));
+                    weather->wx_sec_time=sec_now();
+                    //weather->wx_data=1;
+
+                    if (wx_line[0]=='#')    // Wind speed in km/h
+                        wx_fill_data(0,APRS_WX4,wx_line,p_station);
+                    else               // '*', Wind speed in mph
+                        wx_fill_data(0,APRS_WX6,wx_line,p_station);
+
+                    decoded=1;
+                }
+                else if (strncmp("$ULTW",(char *)wx_line,5)==0
+                        && is_xnum_or_dash((char *)(wx_line+5),44)
+                        && port_data[port].data_type==0) {
+
+                    /* Found Peet Bros raw U2 data */
+
+                    xastir_snprintf(wx_station_type,
+                        sizeof(wx_station_type),
+                        "%s",
+                        langcode("WXPUPSI013"));
+
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found Peet Bros Ultimeter Packet data WX#:%s\n",wx_line+5);
+
+                    xastir_snprintf(raw_wx_string,
+                        sizeof(raw_wx_string),
+                        "%s",
+                        wx_line);
+                    raw_wx_string[MAX_RAW_WX_STRING] = '\0'; // Terminate it
+
+                    weather->wx_sec_time=sec_now();
+                    //weather->wx_data=1;
+                    wx_fill_data(0,APRS_WX5,wx_line,p_station);
+                    decoded=1;
+                }
+                else if (wx_line[2]==' ' && wx_line[5]==' ' && wx_line[8]=='/' && wx_line[11]=='/'
+                        && wx_line[14]==' ' && wx_line[17]==':' && wx_line[20]==':'
+                        && strncmp(" #0:",(char *)wx_line+23,4)==0 && port_data[port].data_type==0) {
+                    find=0;
+                    for (i=len;i>23 && !find;i--) {
+                        if ((int)wx_line[i]==0x03) {
+                            find=1;
+                            wx_line[i] = 0;
+                        }
+                    }
+                    if (find) {
+
+                        /* found Qualimetrics Q-Net station */
+
+                        xastir_snprintf(wx_station_type,
+                            sizeof(wx_station_type),
+                            "%s",
+                            langcode("WXPUPSI016"));
+
+                        if (debug_level & 1)
+                            fprintf(stderr,"Found Qualimetrics Q-Net station data WX#:%s\n",wx_line+23);
+
+                        xastir_snprintf(weather->wx_time,
+                            sizeof(weather->wx_time),
+                            "%s",
+                            get_time(time_data));
+                        weather->wx_sec_time=sec_now();
+                        //weather->wx_data=1;
+                        wx_fill_data(0,QM_WX,wx_line+24,p_station);
+                        decoded=1;
+                    }
+                }
+
+//WE7U
+                // else look for ten ASCII decimal point chars in the input, or do an
+                // sscanf looking for the correct number and types of fields for the
+                // OWW server in ARNE mode.  6 %f's, 2 %d's, 11 %f's.
+                else if (sscanf((const char *)wx_line,"%f %f %f %f %f %f %d %d %f %f %f %f %f %f %f %f %f %f %f", &t1,&t2,&t3,&t4,&t5,&t6,&t7,&t8,&t9,&t10,&t11,&t12,&t13,&t14,&t15,&t16,&t17,&t18,&t19) == 19) {
+
+                    // Found Dallas One-Wire Weather Station
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found OWW ARNE-mode(19) one-wire weather station data\n");
+
+                    weather->wx_sec_time=sec_now();
+                    wx_fill_data(0,DALLAS_ONE_WIRE,wx_line,p_station);
+                    decoded=1;
+                }
+
+                else if (sscanf((const char *)wx_line,"%f %f %f %f %f %f %d %d %f %f %f %f", &t1,&t2,&t3,&t4,&t5,&t6,&t7,&t8,&t9,&t10,&t11,&t12) == 12) {
+
+                    // Found Dallas One-Wire Weather Station
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found OWW ARNE-mode(12) one-wire weather station data\n");
+
+                    weather->wx_sec_time=sec_now();
+                    wx_fill_data(0,DALLAS_ONE_WIRE,wx_line,p_station);
+                    decoded=1;
+                }
+
+                else if (strncmp("&CR&",(char *)wx_line,4)==0
+                        && is_xnum_or_dash((char *)(wx_line+5),44)
+                        && port_data[port].data_type==0) {
+
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found Peet Complete station data\n");
+ 
+                    xastir_snprintf(wx_station_type,
+                        sizeof(wx_station_type),
+                        "%s",
+                        langcode("WXPUPSI017"));
+
+                    xastir_snprintf(raw_wx_string,
+                        sizeof(raw_wx_string),
+                        "%s",
+                        wx_line);
+
+                    raw_wx_string[MAX_RAW_WX_STRING] = '\0'; // Terminate it
+
+                    weather->wx_sec_time=sec_now();
+                    //weather->wx_data=1;
+                    wx_fill_data(0,PEET_COMPLETE,wx_line,p_station);
+                    decoded=1;
+                }
+
+                else if (port_data[port].data_type==1) {
+//                    int jj;
+
+                    /* binary data type */
+                    if (debug_level & 1)
+                        fprintf(stderr,"Found binary data:  %d bytes\n", len);
+ 
+                    /* clear raw string */
+                    memset(raw_wx_string,0,sizeof(raw_wx_string));
+                    max=0;
+                    switch (wx_line[0]) {
+                        case 0x8f:
+                            max=34;
+                            break;
+
+                        case 0x9f:
+                            max=33;
+                            break;
+
+                        case 0xaf:
+                            max=30;
+                            break;
+
+                        case 0xbf:
+                            max=13;
+                            break;
+
+                        case 0xcf:
+                            max=26;
+                            break;
+
+                        default:
+                            break;
+                    }
+
+//                    fprintf(stderr, "wx_decode binary: ");
+//                    for (jj = 0; jj < len+1; jj++) {
+//                        fprintf(stderr, "%02x ", wx_line[jj]);
+//                    }
+//                    fprintf(stderr, "\n");
+//                    fprintf(stderr, "Integers: ");
+//                    for (jj = 0; jj < max+1; jj++) {
+//                        fprintf(stderr, "%0d ", wx_line[jj]);
+//                    }
+//                    fprintf(stderr, "\n");
+
+
+                    if (len < (max+1)) {
+                        fprintf(stderr, " Short NET_WX packet, %d bytes\n", len);
+                    }
+
+                    if (max > 0 && len >= (max+1) ) {
+
+                        // Compute the checksum from the data
+                        check_sum = 0;
+ 
+                        for (i = 0; i < max; i++) {
+                            check_sum += wx_line[i];
+                        }
+//                        fprintf(stderr," Checksum: 0x%02x ", 0x0ff & check_sum);
+
+                        if ( wx_line[max] == (0xff & check_sum) ) {
+
+                            /* good RS WX-200 data */
+                            //fprintf(stderr,"GOOD RS WX-200 %0X data\n",wx_line[0]);
+                            /* found RS WX-200 */
+                            xastir_snprintf(wx_station_type,
+                                sizeof(wx_station_type),
+                                "%s",
+                                langcode("WXPUPSI025"));
+                            xastir_snprintf(weather->wx_time,
+                                sizeof(weather->wx_time),
+                                "%s",
+                                get_time(time_data));
+                            weather->wx_sec_time=sec_now();
+                            //weather->wx_data=1;
+                            wx_fill_data(0,RSWX200,wx_line,p_station);
+                            decoded=1;
+                        }
+                        else {
+//                            fprintf(stderr, "bad");
+                        }
+                    }
+                }
+                else if (wx_line[0]=='@' && strncmp((char *)&(wx_line[63]),".DsVP",5)==0) {
+                  // this is a Davis Vantage Pro with APRS Data Logger
+                  if (debug_level & 1)
+                    fprintf(stdout,"Davis VP APRS Data Logger data found ... %s\n", wx_line);
+                  xastir_snprintf(wx_station_type,
+                                  sizeof(wx_station_type),
+                                  "%s",
+                                  langcode("WXPUPSI028"));
+                  
+                  xastir_snprintf(weather->wx_time,
+                                  sizeof(weather->wx_time),
+                                  "%s",
+                                  get_time(time_data));
+                  weather->wx_sec_time=sec_now();
+                  wx_fill_data(0,DAVISAPRSDL,wx_line,p_station);
+                  decoded=1;
+                }
+                else {	// ASCII data of undetermined type
+
+                    // Davis Weather via meteo -> db2APRS -> TCP port
+
+                    if (strstr((const char *)wx_line, "xDvs")) {  // APRS 'postionless' WX data w/ Davis & X tag
+
+                        if (debug_level & 1)
+                            fprintf(stdout,"Davis Data found... %s\n",wx_line);
+			    
+                        xastir_snprintf(wx_station_type,
+                            sizeof(wx_station_type),
+                            "%s",
+                            langcode("WXPUPSI026"));
+                        xastir_snprintf(weather->wx_time,
+                            sizeof(weather->wx_time),
+                            "%s",
+                            get_time(time_data));
+                        weather->wx_sec_time=sec_now();
+                        wx_fill_data(0,DAVISMETEO,wx_line,p_station);
+                        decoded=1;
+                    }
+
+                    else if (debug_level & 1) {
+                        fprintf(stderr,"Unknown WX DATA:%s\n",wx_line);
+                    }
+                }
+
+                if (decoded) {
+                /* save data back */
+
+if (begin_critical_section(&port_data_lock, "wx.c:wx_decode(1)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+                    port_data[port].decode_errors=0;
+
+if (end_critical_section(&port_data_lock, "wx.c:wx_decode(2)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+                    statusline(langcode("BBARSTA032"),1);       // Decoded WX Data
+                    /* redraw now */
+                    //redraw_on_new_data=2;
+                    redraw_on_new_data=1;
+                    fill_wx_data();
+                }
+                else {
+                    /* Undecoded packet */
+                    memset(raw_wx_string,0,sizeof(raw_wx_string));
+
+if (begin_critical_section(&port_data_lock, "wx.c:wx_decode(3)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+                    port_data[port].decode_errors++;    // We have errors in decoding
+                    if (port_data[port].decode_errors>10) {
+                        /* wrong data type? */
+                        port_data[port].data_type++;    // Try another data type. 0=ascii, 1=wx binary
+                        port_data[port].data_type&=0x01;
+                        /*if (debug_level & 1)*/
+                        fprintf(stderr,"Data type %d\n",port_data[port].data_type);
+                        port_data[port].decode_errors=0;
+                    }
+
+if (end_critical_section(&port_data_lock, "wx.c:wx_decode(4)" ) > 0)
+    fprintf(stderr,"port_data_lock, Port = %d\n", port);
+
+                }
+            }
+        }
+    }
+}
+
+
+
+
+
+/***********************************************************/
+/* fill string with WX data for transmit                   */
+/*                            */
+/***********************************************************/
+
+time_t wx_tx_data1(char *st, int st_size) {
+    DataRow *p_station;
+    time_t wx_time;
+    char temp[100];
+    WeatherRow *weather;
+
+    st[0] = '\0';
+    wx_time = 0;
+    if (search_station_name(&p_station,my_callsign,1)) {
+        if (get_weather_record(p_station)) {    // station has wx data
+            weather = p_station->weather_data;
+
+
+//WE7U: For debugging purposes only
+//weather->wx_sec_time=sec_now();
+//sprintf(weather->wx_course,"359");          // degrees
+//sprintf(weather->wx_speed,"001");           // mph
+//sprintf(weather->wx_gust,"010");            // mph
+//sprintf(weather->wx_temp,"069");            // Farenheit
+
+//if ( strlen(weather->wx_rain_total) == 0)
+//    sprintf(weather->wx_rain_total,"1900.40");
+
+//sprintf(weather->wx_rain_total,"1987.6");   // hundredths of an inch
+//compute_rain(atof(weather->wx_rain_total));
+//sprintf(weather->wx_rain_total,"1988.6");
+//compute_rain(atof(weather->wx_rain_total));
+//sprintf(weather->wx_rain_total,"1990.6");
+
+//compute_rain(atof(weather->wx_rain_total));
+//sprintf(weather->wx_rain,"%0.2f",rain_minute_total);
+//sprintf(weather->wx_prec_24,"%0.2f",rain_24);
+//sprintf(weather->wx_prec_00,"%0.2f",rain_00);
+
+//sprintf(weather->wx_rain,"0");            // hundredths of an inch
+//sprintf(weather->wx_prec_00,"0");         // hundredths of an inch
+//sprintf(weather->wx_prec_24,"0");         // hundredths of an inch
+
+//sprintf(weather->wx_hum,"92");              // %
+//sprintf(weather->wx_baro,"1013.0");         // hPa
+//weather->wx_type = WX_TYPE;
+//xastir_snprintf(weather->wx_station,sizeof(weather->wx_station),"RSW");
+//  359/000g000t065r010P020p030h92b01000
+
+
+            if (strlen(weather->wx_course) > 0 && strlen(weather->wx_speed) > 0) {
+                // We have enough wx_data
+                wx_time=weather->wx_sec_time;
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "%s",
+                    weather->wx_course);
+                if (strlen(temp) > 3) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_course too long: %s\n", temp);
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "...");
+                }
+                if ( (atoi(weather->wx_course) > 360) || (atoi(weather->wx_course) < 0) ) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_course out-of-range: %s\n", weather->wx_course);
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "...");
+                }
+                //sprintf(st,"%s/%s",weather->wx_course,weather->wx_speed);
+                strncat(st, temp, st_size - 1 - strlen(st));
+                strncat(st, "/", st_size - 1 - strlen(st));
+
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "%s",
+                    weather->wx_speed);
+                if (strlen(temp) > 3) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_speed too long: %s\n", temp);
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "...");
+                }
+                if ( (atoi(weather->wx_speed) < 0) || (atoi(weather->wx_speed) > 999) ) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_speed out-of-range: %s\n", weather->wx_speed);
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "...");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else {
+                // We don't have enough wx_data, may be from a Qualimetrics Q-Net?
+                wx_time=weather->wx_sec_time;
+                xastir_snprintf(st,
+                    st_size,
+                    ".../...");
+
+
+            if (debug_level & 1) {
+                fprintf(stderr,"\n\nAt least one field was empty: Course: %s\tSpeed: %s\n", weather->wx_course, weather->wx_speed);
+                fprintf(stderr,"Will be sending '.../...' instead of real values.\n\n\n");
+            }
+
+
+            }
+            if (strlen(weather->wx_gust) > 0) {
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "g%s",
+                    weather->wx_gust);
+                if (strlen(temp) > 4) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_gust too long: %s\n", temp);
+
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "g...");
+                }
+                if (atoi(weather->wx_gust) < 0) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_gust out-of-range: %s\n", weather->wx_gust);
+
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "g...");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else
+                strncat(st, "g...", st_size - 1 - strlen(st));
+
+            if (strlen(weather->wx_temp) > 0) {
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "t%s",
+                    weather->wx_temp);
+                if (strlen(temp) > 4) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_temp too long: %s\n", temp);
+
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "t...");
+                }
+                if ( (atoi(weather->wx_temp) > 999) || (atoi(weather->wx_temp) < -99) ) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_temp out-of-bounds: %s\n", weather->wx_temp);
+
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "t...");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else
+                strncat(st, "t...", st_size - 1 - strlen(st));
+
+            if (strlen(weather->wx_rain) > 0) {
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "r%03d",
+                    (int)(atof(weather->wx_rain) + 0.5) );  // Cheater's way of rounding
+                if (strlen(temp)>4) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_rain too long: %s\n", temp);
+
+                    // Don't transmit this field if it's not valid
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "r   ");
+                }
+                if ((int)(atof(weather->wx_rain)) < 0) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_rain out-of-bounds: %s\n", weather->wx_rain);
+
+                    // Don't transmit this field if it's not valid
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "r...");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else {
+                // Don't transmit this field if it's not valid
+                //strncat(st, "r...", st_size - 1 - strlen(st));
+            }
+
+            if (strlen(weather->wx_prec_00) > 0) {
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "P%03d",
+                    (int)(atof(weather->wx_prec_00) + 0.5) );   // Cheater's way of rounding
+                if (strlen(temp)>4) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_prec_00 too long: %s\n", temp);
+
+                    // Don't transmit this field if it's not valid
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "P   ");
+                }
+                if ((int)(atof(weather->wx_prec_00)) < 0) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_prec_00 out-of-bounds: %s\n", weather->wx_prec_00);
+
+                    // Don't transmit this field if it's not valid
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "P...");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else {
+                // Don't transmit this field if it's not valid
+                //strncat(st, "P...", st_size - 1 - strlen(st));
+            }
+
+            if (strlen(weather->wx_prec_24) > 0) {
+                xastir_snprintf(temp,
+                     sizeof(temp),
+                    "p%03d",
+                    (int)(atof(weather->wx_prec_24) + 0.5) );   // Cheater's way of rounding
+                if (strlen(temp)>4) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_prec_24 too long: %s\n", temp);
+
+                    // Don't transmit this field if it's not valid
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "p   ");
+                }
+                if ((int)(atof(weather->wx_prec_24)) < 0) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_prec_24 out-of-bounds: %s\n", weather->wx_prec_24);
+
+                    // Don't transmit this field if it's not valid
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "p...");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else {
+                // Don't transmit this field if it's not valid
+                //strncat(st, "p...", st_size - 1 - strlen(st));
+            }
+
+            if (strlen(weather->wx_hum) > 0) {
+                if (atoi(weather->wx_hum)>99) {
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "h00");
+                } else
+                    xastir_snprintf(temp,
+                        sizeof(temp),
+                        "h%02d",
+                        atoi(weather->wx_hum));
+
+                if (strlen(temp) > 4) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_hum too long: %s\n", temp);
+
+                    // Don't transmit this field if it's not valid
+                    //xastir_snprintf(temp,sizeof(temp),"h..");
+                }
+                if (atoi(weather->wx_hum) < 0) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_hum out-of-bounds: %s\n", weather->wx_hum);
+                    // Don't transmit this field if it's not valid
+                    //xastir_snprintf(temp,sizeof(temp),"h..");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else {
+                // Don't transmit this field if it's not valid
+                //strncat(st, "h..", st_size - 1 - strlen(st));
+            }
+
+            if (strlen(weather->wx_baro) > 0) {
+                xastir_snprintf(temp,
+                    sizeof(temp),
+                    "b%05d",
+                    (int)((atof(weather->wx_baro) * 10.0)) );
+                if (strlen(temp)>6) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_baro too long: %s\n", temp);
+                    // Don't transmit this field if it's not valid
+                    //xastir_snprintf(temp,sizeof(temp),"b.....");
+                }
+                if ((int)((atof(weather->wx_baro) * 10.0) < 0)) {
+                    if (debug_level & 1)
+                        fprintf(stderr,"wx_baro out-of-bounds: %s\n", weather->wx_baro);
+                    // Don't transmit this field if it's not valid
+                    //xastir_snprintf(temp,sizeof(temp),"b.....");
+                }
+                strncat(st, temp, st_size - 1 - strlen(st));
+            } else {
+                // Don't transmit this field if it's not valid
+                //strncat(st, "b.....", st_size - 1 - strlen(st));
+            }
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%c%s",
+                weather->wx_type,
+                weather->wx_station);
+            strncat(st, temp, st_size - 1 - strlen(st));
+        }
+    }
+
+
+    if (debug_level & 1)
+        fprintf(stderr,"Weather String:  %s\n", st);
+
+
+    return(wx_time);
+}
+
+
+
+
+
+/***********************************************************/
+/* transmit raw wx data                                    */
+/*                                                         */
+/***********************************************************/
+void tx_raw_wx_data(void) {
+
+    if (strlen(raw_wx_string)>10) {
+        output_my_data(raw_wx_string,-1,0,0,0,NULL);
+        if (debug_level & 1)
+            fprintf(stderr,"Sending Raw WX data <%s>\n",raw_wx_string);
+    }
+}
+
+
diff --git a/src/wx.h b/src/wx.h
new file mode 100644
index 0000000..0123783
--- /dev/null
+++ b/src/wx.h
@@ -0,0 +1,79 @@
+/*
+ * $Id: wx.h,v 1.16 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#ifndef __XASTIR_WX_H
+#define __XASTIR_WX_H
+
+#include "database.h"
+
+extern void fill_wx_data(void);
+
+extern Widget GetTopShell(Widget w);
+extern void pos_dialog(Widget w);
+extern char wx_station_type[];
+
+/* from wx.c */
+extern char wx_dew_point[10];
+extern char wx_dew_point_on;
+extern char wx_high_wind[10];
+extern char wx_high_wind_on;
+extern char wx_wind_chill[10];
+extern char wx_wind_chill_on;
+extern char wx_three_hour_baro[10]; // hPa
+extern char wx_three_hour_baro_on;  // hPa
+extern char wx_hi_temp[10];
+extern char wx_hi_temp_on;
+extern char wx_low_temp[10];
+extern char wx_low_temp_on;
+extern char wx_heat_index[10];
+extern char wx_heat_index_on;
+extern char wx_station_type[];
+
+
+/* from wx.c */
+extern time_t wx_tx_data1(char *st, int st_size);
+extern void wx_decode(unsigned char *wx_line, int data_length, int port);
+extern void fill_wx_data(void);
+extern void clear_rain_data(void);
+extern void tx_raw_wx_data(void);
+extern void clear_local_wx_data(void);
+extern void wx_last_data_check(void);
+extern void wx_fill_data(int from, int type, unsigned char *data, DataRow *fill);
+extern void decode_U2000_L(int from, unsigned char *data, WeatherRow *weather);
+extern void decode_U2000_P(int from, unsigned char *data, WeatherRow *weather);
+extern void decode_Peet_Bros(int from, unsigned char *data, WeatherRow *weather, int type);
+extern void cycle_weather(void);
+
+
+/* wx_gui.c */
+extern void wx_alert_update_list(void);
+
+extern void WX_station(Widget w, XtPointer clientData, XtPointer callData);
+
+extern void wx_alert_finger_output( Widget widget, char *handle);
+
+#endif  // __XASTIR_WX_H
+
+
diff --git a/src/wx_gui.c b/src/wx_gui.c
new file mode 100644
index 0000000..fc79441
--- /dev/null
+++ b/src/wx_gui.c
@@ -0,0 +1,2116 @@
+/*
+ * $Id: wx_gui.c,v 1.60 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "snprintf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef  HAVE_LOCALE_H
+#include <locale.h>
+#endif  // HAVE_LOCALE_H
+
+#ifdef  HAVE_LIBINTL_H
+#include <libintl.h>
+#define _(x)        gettext(x)
+#else   // HAVE_LIBINTL_H
+#define _(x)        (x)
+#endif  // HAVE_LIBINTL_H
+
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif  // HAVE_MATH_H
+
+#include "xastir.h"
+#include "wx.h"
+#include "main.h"
+#include "alert.h"
+#include "lang.h"
+
+#include <Xm/XmAll.h>
+#ifdef HAVE_XBAE_MATRIX_H
+#include <Xbae/Matrix.h>
+#endif  // HAVE_XBAE_MATRIX_H
+#include <X11/cursorfont.h>
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+extern XmFontList fontlist1;    // Menu/System fontlist
+
+/************ Weather Alerts ****************/
+Widget wx_alert_shell = (Widget)NULL;
+Widget wx_detailed_alert_shell = (Widget)NULL;
+static Widget wx_alert_list;
+
+static xastir_mutex wx_alert_shell_lock;
+static xastir_mutex wx_detailed_alert_shell_lock;
+static xastir_mutex wx_station_dialog_lock;
+
+
+
+
+
+void wx_gui_init(void)
+{
+    init_critical_section( &wx_alert_shell_lock );
+    init_critical_section( &wx_detailed_alert_shell_lock );
+    init_critical_section( &wx_station_dialog_lock );
+}
+
+
+
+
+
+void wx_detailed_alert_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&wx_detailed_alert_shell_lock, "wx_gui.c:wx_detailed_alert_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    wx_detailed_alert_shell = (Widget)NULL;
+
+end_critical_section(&wx_detailed_alert_shell_lock, "wx_gui.c:wx_detailed_alert_destroy_shell" );
+
+}
+
+
+
+
+
+// This gets/displays the "finger" output from the WXSVR.  Called
+// from both the Station Info "NWS" button and by double-clicking on
+// the view weather alerts window.
+//
+void wx_alert_finger_output( Widget widget, char *handle) {
+    static Widget pane, my_form, mess, button_cancel,wx_detailed_alert_list;
+    Atom delw;
+    Arg al[50];                     // Arg List
+    register unsigned int ac = 0;   // Arg Count
+    char temp[1024];
+    XmString item;
+    FILE *fd;
+    int ret;
+    int server_fd;
+    struct sockaddr_in serv_addr;
+    struct hostent *serverhost;
+
+
+    if (debug_level & 1)
+        fprintf(stderr,"Handle: %s\n",handle);
+
+    if(!wx_detailed_alert_shell) {
+
+begin_critical_section(&wx_detailed_alert_shell_lock, "wx_gui.c:wx_alert_double_click_action" );
+
+        wx_detailed_alert_shell = XtVaCreatePopupShell(langcode("WPUPWXA001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNminWidth, 600,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("wx_alert_double_click_action pane",xmPanedWindowWidgetClass, wx_detailed_alert_shell,
+                        XmNbackground, colors[0xff],
+                        NULL); 
+
+        my_form =  XtVaCreateWidget("wx_alert_double_click_action my_form", xmFormWidgetClass, pane,
+                        XmNtraversalOn, TRUE,
+                        XmNfractionBase, 5,
+                        XmNbackground, colors[0xff], 
+                        XmNwidth, 600,
+                        XmNautoUnmanage, FALSE,
+                        XmNshadowThickness, 1,  
+                        NULL);
+        
+        mess = XtVaCreateManagedWidget(langcode("WPUPWXA002"), xmLabelWidgetClass, my_form,
+                        XmNtraversalOn, FALSE,
+                        XmNtopAttachment, XmATTACH_FORM,
+                        XmNtopOffset, 5,
+                        XmNbottomAttachment, XmATTACH_NONE,
+                        XmNleftAttachment, XmATTACH_FORM,
+                        XmNleftOffset, 5,
+                        XmNrightAttachment, XmATTACH_FORM,
+                        XmNrightOffset, 5,
+                        XmNbackground, colors[0xff],
+                        XmNfontList, fontlist1,
+                        NULL);
+
+
+        /* set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+        XtSetArg(al[ac], XmNvisibleItemCount, 13); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+
+        XtSetArg(al[ac], XmNvisualPolicy, XmCONSTANT); ac++;
+        XtSetArg(al[ac], XmNscrollingPolicy,XmAUTOMATIC); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNscrollBarDisplayPolicy,XmAS_NEEDED); ac++;
+        XtSetArg(al[ac], XmNlistSizePolicy, XmCONSTANT); ac++;
+
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+        XtSetArg(al[ac], XmNtopWidget, mess); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNbottomOffset, 45); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        wx_detailed_alert_list = XmCreateScrolledList(my_form, "wx_alert_double_click_action wx_detailed_alert_list", al, ac);
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, my_form,
+                        XmNtopAttachment, XmATTACH_NONE,
+                        XmNbottomAttachment, XmATTACH_FORM,
+                        XmNbottomOffset,10,
+                        XmNleftAttachment, XmATTACH_POSITION,
+                        XmNleftPosition, 2,
+                        XmNrightAttachment, XmATTACH_POSITION,
+                        XmNrightPosition, 3,
+                        XmNbackground, colors[0xff], 
+                        XmNnavigationType, XmTAB_GROUP,
+                        XmNfontList, fontlist1,
+                        NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, wx_detailed_alert_destroy_shell, wx_detailed_alert_shell);
+
+end_critical_section(&wx_detailed_alert_shell_lock, "wx_gui.c:wx_alert_double_click_action" );
+
+        pos_dialog(wx_detailed_alert_shell);
+
+        delw = XmInternAtom(XtDisplay(wx_detailed_alert_shell), "WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(wx_detailed_alert_shell, delw, wx_detailed_alert_destroy_shell, (XtPointer)wx_detailed_alert_shell);
+
+        XtManageChild(my_form);
+        XtManageChild(wx_detailed_alert_list);
+        XtVaSetValues(wx_detailed_alert_list, XmNbackground, colors[0x0f], NULL);    
+        XtManageChild(pane);
+
+        XtPopup(wx_detailed_alert_shell, XtGrabNone);
+//        fix_dialog_vsize(wx_detailed_alert_shell);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(wx_detailed_alert_shell);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+    } else {
+        (void)XRaiseWindow(XtDisplay(wx_detailed_alert_shell), XtWindow(wx_detailed_alert_shell));
+    }
+
+    // Erase the entire list before we start writing to it in
+    // case it was left up from a previous query.
+    XmListDeleteAllItems(wx_detailed_alert_list);
+
+    // Perform a "finger" command, which is really just a telnet
+    // with a single line command sent to the remote host, then a
+    // bunch of text sent back.  We implement it here via our own
+    // TCP code, as it's really very simple.
+
+    // Allocate a socket for our use
+    if ((server_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+//        fprintf(stderr,"wx_alert_finger_output: can't get socket\n");
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "wx_alert_finger_output: can't get socket");
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+        return;
+    }
+
+    memset(&serv_addr, 0, sizeof(serv_addr));
+
+
+    // Changing Finger host because WXSVR.net has been down for a
+    // month or more and Pete, AE5PL, has a replacement online that
+    // performs this function.
+    //serverhost = gethostbyname("wxsvr.net");
+    serverhost = gethostbyname("wx.aprs-is.net");
+
+
+    if (serverhost == (struct hostent *)0) {
+//        fprintf(stderr,"wx_alert_finger_output: gethostbyname failed\n");
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "wx_alert_finger_output: gethostbyname failed");
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+        (void)close(server_fd); // Close the socket
+        return;
+    }
+    memmove(&serv_addr.sin_addr,serverhost->h_addr, (size_t)serverhost->h_length);
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_port = htons(79); // Finger protocol uses port 79
+
+    if (connect(server_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
+//        fprintf(stderr,"wx_alert_finger_output: connect to server failed\n");
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "wx_alert_finger_output: connect to server failed");
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+        (void)close(server_fd);    // Close the socket
+        return;
+    }
+
+    // Create a file descriptor for the socket
+    fd = fdopen(dup(server_fd),"wb");
+    if (fd == NULL) {
+//        fprintf(stderr,"Couldn't create duplicate write socket\n");
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "Couldn't create duplicate write socket");
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+        (void)close(server_fd); // Close the socket
+        return;
+    }
+
+    // Set up the text we're going to send to the remote finger
+    // server.
+    xastir_snprintf(temp,
+        sizeof(temp),
+        "%s\r\n",
+        handle);
+
+    // Send the request text out the socket
+    ret = fprintf(fd, "%s", temp);
+
+    if (ret == 0 || ret == -1) {
+//        fprintf(stderr,"Couldn't send finger command to wxsvr\n");
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "Couldn't send finger command to wxsvr");
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+        (void)fclose(fd);
+        (void)close(server_fd); // Close the socket
+        return;
+    }
+
+    // Close the duplicate port we used for writing
+    (void)fclose(fd);
+
+//
+// Read back the results from the socket
+//
+
+    // Create a file descriptor for the socket
+    fd = fdopen(dup(server_fd),"rb");
+    if (fd == NULL) {
+//        fprintf(stderr,"Couldn't create duplicate read socket\n");
+        xastir_snprintf(temp,
+            sizeof(temp),
+            "Couldn't create duplicate read socket");
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+        (void)close(server_fd); // Close the socket
+        return;
+    }
+
+    // Process the data we received from the remote finger server
+    //
+    while (fgets (temp, sizeof (temp), fd)) {   // While we have data to process
+        char *ptr;
+
+        // Remove any linefeeds or carriage returns from each
+        // string.
+        ptr = temp;
+        while ( (ptr = strpbrk(temp, "\n\r")) )
+            memmove(ptr, ptr+1, strlen(ptr)+1);
+
+        if (debug_level & 1)
+            fprintf(stderr,"%s\n",temp);
+
+        // Create an XmString for each line and add it to the
+        // end of the list.
+        item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+        XmListAddItemUnselected(wx_detailed_alert_list, item, 0);
+        XmStringFree(item);
+    }
+
+    // All done!
+    fclose(fd);
+    (void)close(server_fd); // Close the socket
+}
+
+
+
+
+
+void wx_alert_double_click_action( Widget widget, XtPointer clientData, XtPointer callData) {
+    char *choice;
+    XmListCallbackStruct *selection = callData;
+    char handle[14];
+    char *ptr;
+
+
+    XmStringGetLtoR(selection->item, XmFONTLIST_DEFAULT_TAG, &choice);
+    //fprintf(stderr,"Selected item %d (%s)\n", selection->item_position, choice);
+
+    // Grab the first 13 characters.  Remove spaces.  This is our handle
+    // into the weather server for the full weather alert text.
+
+    xastir_snprintf(handle,
+        sizeof(handle),
+        "%s",
+        choice);
+
+    XtFree(choice);	// Release as soon as we're done!
+
+    handle[13] = '\0';  // Terminate the string
+    // Remove spaces
+    ptr = handle;
+    while ( (ptr = strpbrk(handle, " ")) )
+        memmove(ptr, ptr+1, strlen(ptr)+1);
+    handle[9] = '\0';   // Terminate after first 9 chars
+
+    if (debug_level & 1)
+        fprintf(stderr,"Handle: %s\n",handle);
+
+    wx_alert_finger_output( widget, handle);
+}
+
+
+
+
+
+void wx_alert_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&wx_alert_shell_lock, "wx_gui.c:wx_alert_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    wx_alert_shell = (Widget)NULL;
+
+end_critical_section(&wx_alert_shell_lock, "wx_gui.c:wx_alert_destroy_shell" );
+
+}
+
+
+static int alert_comp(const void *a, const void *b) {
+    alert_entry *a_entry = *(alert_entry **)a;
+    alert_entry *b_entry = *(alert_entry **)b;
+    int a_active, b_active;
+
+    if (a_entry->title[on_screen] && !b_entry->title[on_screen])
+        return (-1);
+
+    if (!a_entry->title[0] && b_entry->title[0])
+        return (1);
+
+    if (a_entry->flags[on_screen] == 'Y' && b_entry->flags[on_screen] != 'Y')
+        return (-1);
+
+    if (a_entry->flags[on_screen] != 'Y' && b_entry->flags[on_screen] == 'Y')
+        return (1);
+
+    if (a_entry->flags[on_screen] == '?' && b_entry->flags[on_screen] == 'N')
+        return (-1);
+
+    if (a_entry->flags[on_screen] == 'N' && b_entry->flags[on_screen] == '?')
+        return (1);
+
+    a_active = alert_active(a_entry, ALERT_ALL);
+    b_active = alert_active(b_entry, ALERT_ALL);
+    if (a_active && b_active) {
+        if (a_active - b_active) {
+            return (a_active - b_active);
+        }
+    } else if (a_active) {
+        return (-1);
+    }
+    else if (b_active) {
+        return (1);
+    }
+
+    return (strcmp(a_entry->title, b_entry->title));
+}
+
+
+void wx_alert_update_list(void) {
+    int nn;         // index into alert table.  Starts at 0
+    int ii;         // index into dialog lines.  Starts at 1
+    int max_item_count; // max dialog lines
+    char temp[600];
+    XmString item;
+    static alert_entry **alert_list;
+    static int alert_list_limit;
+
+    if (wx_alert_shell) {
+        struct hashtable_itr *iterator;
+        alert_entry *alert;
+
+begin_critical_section(&wx_alert_shell_lock, "wx_gui.c:wx_alert_update_list" );
+
+        // Get the previous alert count from the alert list window
+        XtVaGetValues(wx_alert_list, XmNitemCount, &max_item_count, NULL);
+
+	if ((nn = alert_list_count()) > alert_list_limit) {
+	    alert_entry **tmp = realloc(alert_list, nn * sizeof(alert_entry *));
+	    if (tmp) {
+		alert_list = tmp;
+		alert_list_limit = nn;
+	    } else {
+		fprintf(stderr, "wx_gui: Alert list allocation error\n");
+		exit(1);
+	    }
+
+	}
+        // Iterate through the alert hash.  Create a string for each
+        // non-expired/non-blank entry.
+        iterator = create_wx_alert_iterator();
+        for (nn = 0, alert = get_next_wx_alert(iterator); iterator != NULL && alert; alert = get_next_wx_alert(iterator)) {
+
+            // Check whether alert record is empty/filled.  This
+            // code is from the earlier array implementation.  If
+            // we're expiring records from our hash properly we
+            // probably don't need this anymore.
+            //
+//            if (alert->title[0] == '\0') {    // It's empty
+//		fprintf(stderr, "wx_gui:alert->title NULL\n");
+//                break;
+//            }
+	    alert_list[nn++] = alert;
+	}
+	qsort(alert_list, nn, sizeof(alert_entry *), alert_comp);
+	for (ii = 0; ii < nn; 
+) {
+            alert = alert_list[ii];
+            // AFGNPW      NWS-WARN    Until: 191500z   AK_Z213   WIND               P7IAA
+            // TSATOR      NWS-ADVIS   Until: 190315z   OK_C127   TORNDO             H2VAA
+            //xastir_snprintf(temp, sizeof(temp), "%-9s   %-9s   Until: %-7s   %-7s   %-20s   %s",
+
+            xastir_snprintf(temp,
+                sizeof(temp),
+                "%-9s %-5s %-9s %c%c @%c%c%c%cz ==> %c%c @%c%c%c%cz %c%c %-7s %s %s%s%s%s",
+                alert->from,
+                alert->seq,
+                alert->to,
+                alert->issue_date_time[0],
+                alert->issue_date_time[1],
+                alert->issue_date_time[2],
+                alert->issue_date_time[3],
+                alert->issue_date_time[4],
+                alert->issue_date_time[5],
+                alert->activity[0],
+                alert->activity[1],
+                alert->activity[2],
+                alert->activity[3],
+                alert->activity[4],
+                alert->activity[5],
+                alert->flags[on_screen],
+                alert->flags[source],
+                alert->title,
+                alert->alert_tag,
+                alert->desc0,
+                alert->desc1,
+                alert->desc2,
+                alert->desc3);
+
+            item = XmStringGenerate(temp, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, NULL);
+
+            ii++;
+
+            // It looks like if we are higher than 'max_item_count',
+            // it must be a new entry that we haven't written to the
+            // window yet.  Add it.
+            if (max_item_count < ii) {
+                XmListAddItemUnselected(wx_alert_list, item, 0);
+            } else {
+		// Replace it in the window.  Note: This might re-order the list each time.
+                XmListReplaceItemsPos(wx_alert_list, &item, 1, ii);
+            }
+
+            XmStringFree(item);
+
+        }   // End of for loop
+#ifndef USING_LIBGC
+//fprintf(stderr,"free iterator 9\n");
+        if (iterator) free(iterator);
+#endif  // USING_LIBGC
+
+        // If we have fewer alerts now, delete the extras from the window
+        if (ii < max_item_count) {
+            XmListDeleteItemsPos(wx_alert_list, max_item_count - ii, ii+1);
+        }
+
+end_critical_section(&wx_alert_shell_lock, "wx_gui.c:wx_alert_update_list" );
+
+    }
+}
+
+
+
+
+
+void Display_Wx_Alert( /*@unused@*/ Widget wdgt, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget pane, my_form, mess, button_cancel;
+    Atom delw;
+    Arg al[50];                    /* Arg List */
+    register unsigned int ac = 0;           /* Arg Count */
+
+    if(!wx_alert_shell) {
+
+begin_critical_section(&wx_alert_shell_lock, "wx_gui.c:Display_Wx_Alert" );
+
+        wx_alert_shell = XtVaCreatePopupShell(langcode("WPUPWXA001"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNminWidth, 600,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("Display_Wx_Alert pane",xmPanedWindowWidgetClass, wx_alert_shell,
+                        XmNbackground, colors[0xff],
+                        NULL); 
+
+        my_form =  XtVaCreateWidget("Display_Wx_Alert my_form", xmFormWidgetClass, pane,
+                        XmNtraversalOn, TRUE,
+                        XmNfractionBase, 5,
+                        XmNbackground, colors[0xff], 
+                        XmNwidth, 600,
+                        XmNautoUnmanage, FALSE,
+                        XmNshadowThickness, 1,  
+                        NULL);
+        
+        mess = XtVaCreateManagedWidget(langcode("WPUPWXA002"), xmLabelWidgetClass, my_form,
+                        XmNtraversalOn, FALSE,
+                        XmNtopAttachment, XmATTACH_FORM,
+                        XmNtopOffset, 5,
+                        XmNbottomAttachment, XmATTACH_NONE,
+                        XmNleftAttachment, XmATTACH_FORM,
+                        XmNleftOffset, 5,
+                        XmNrightAttachment, XmATTACH_FORM,
+                        XmNrightOffset, 5,
+                        XmNbackground, colors[0xff], 
+                        XmNfontList, fontlist1,
+                        NULL);
+
+
+        /* set args for color */
+        ac=0;
+        XtSetArg(al[ac], XmNbackground, colors[0xff]); ac++;
+        XtSetArg(al[ac], XmNvisibleItemCount, 13); ac++;
+        XtSetArg(al[ac], XmNtraversalOn, TRUE); ac++;
+        XtSetArg(al[ac], XmNshadowThickness, 3); ac++;
+//        XtSetArg(al[ac], XmNselectionPolicy, XmMULTIPLE_SELECT); ac++;
+        XtSetArg(al[ac], XmNselectionPolicy, XmSINGLE_SELECT); ac++;
+
+        XtSetArg(al[ac], XmNvisualPolicy, XmCONSTANT); ac++;
+        XtSetArg(al[ac], XmNscrollingPolicy,XmAUTOMATIC); ac++;
+        XtSetArg(al[ac], XmNscrollBarPlacement, XmBOTTOM_RIGHT); ac++;
+        XtSetArg(al[ac], XmNscrollBarDisplayPolicy,XmAS_NEEDED); ac++;
+//        XtSetArg(al[ac], XmNscrollBarDisplayPolicy, XmSTATIC); ac++;
+        XtSetArg(al[ac], XmNlistSizePolicy, XmCONSTANT); ac++;
+//        XtSetArg(al[ac], XmNlistSizePolicy, XmVARIABLE); ac++;
+
+        XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
+        XtSetArg(al[ac], XmNtopWidget, mess); ac++;
+        XtSetArg(al[ac], XmNtopOffset, 5); ac++;
+        XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNbottomOffset, 45); ac++;
+        XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNrightOffset, 5); ac++;
+        XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
+        XtSetArg(al[ac], XmNleftOffset, 5); ac++;
+        XtSetArg(al[ac], XmNfontList, fontlist1); ac++;
+
+        wx_alert_list = XmCreateScrolledList(my_form, "Display_Wx_Alert wx_alert_list", al, ac);
+
+end_critical_section(&wx_alert_shell_lock, "wx_gui.c:Display_Wx_Alert" );
+
+        wx_alert_update_list();
+
+        button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, my_form,
+                        XmNtopAttachment, XmATTACH_NONE,
+//                        XmNtopOffset, 265,
+                        XmNbottomAttachment, XmATTACH_FORM,
+                        XmNbottomOffset,10,
+                        XmNleftAttachment, XmATTACH_POSITION,
+                        XmNleftPosition, 2,
+                        XmNrightAttachment, XmATTACH_POSITION,
+                        XmNrightPosition, 3,
+                        XmNbackground, colors[0xff], 
+                        XmNnavigationType, XmTAB_GROUP,
+                        XmNfontList, fontlist1,
+                        NULL);
+
+        XtAddCallback(button_cancel, XmNactivateCallback, wx_alert_destroy_shell, wx_alert_shell);
+        XtAddCallback(wx_alert_list, XmNdefaultActionCallback, wx_alert_double_click_action, NULL);
+
+        pos_dialog(wx_alert_shell);
+
+        delw = XmInternAtom(XtDisplay(wx_alert_shell), "WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(wx_alert_shell, delw, wx_alert_destroy_shell, (XtPointer)wx_alert_shell);
+
+        XtManageChild(my_form);
+        XtManageChild(wx_alert_list);
+        XtVaSetValues(wx_alert_list, XmNbackground, colors[0x0f], NULL);    
+        XtManageChild(pane);
+
+        XtPopup(wx_alert_shell, XtGrabNone);
+//        fix_dialog_vsize(wx_alert_shell);
+
+        // Move focus to the Cancel button.  This appears to highlight the
+        // button fine, but we're not able to hit the <Enter> key to
+        // have that default function happen.  Note:  We _can_ hit the
+        // <SPACE> key, and that activates the option.
+//        XmUpdateDisplay(wx_alert_shell);
+        XmProcessTraversal(button_cancel, XmTRAVERSE_CURRENT);
+    } else {
+        (void)XRaiseWindow(XtDisplay(wx_alert_shell), XtWindow(wx_alert_shell));
+    }
+} /* Display_Wx_Alert */
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////
+
+
+
+
+
+/**** WX Station *******/
+Widget wx_station_dialog=(Widget)NULL;
+Widget WX_type_data;
+Widget WX_temp_data;
+Widget WX_wind_cse_data;
+Widget WX_wind_spd_data;
+Widget WX_wind_gst_data;
+Widget WX_rain_data;
+Widget WX_to_rain_data;
+Widget WX_rain_h_data;
+Widget WX_rain_24_data;
+Widget WX_humidity_data;
+Widget WX_speed_label;
+Widget WX_gust_label;
+Widget WX_temp_label;
+Widget WX_rain_label;
+Widget WX_to_rain_label;
+Widget WX_rain_h_label;
+Widget WX_rain_24_label;
+Widget WX_dew_point_data;
+Widget WX_high_wind_data;
+Widget WX_wind_chill_data;
+Widget WX_heat_index_data;
+Widget WX_baro_data;
+Widget WX_baro_label;
+Widget WX_three_hour_baro_data;
+Widget WX_three_hour_baro_label;
+Widget WX_hi_temp_data;
+Widget WX_low_temp_data;
+Widget WX_dew_point_label;
+Widget WX_wind_chill_label;
+Widget WX_heat_index_label;
+Widget WX_hi_temp_label;
+Widget WX_low_temp_label;
+Widget WX_high_wind_label;
+
+
+
+
+
+void WX_station_destroy_shell( /*@unused@*/ Widget widget, XtPointer clientData, /*@unused@*/ XtPointer callData) {
+
+    Widget shell = (Widget) clientData;
+    XtPopdown(shell);
+
+begin_critical_section(&wx_station_dialog_lock, "wx_gui.c:WX_station_destroy_shell" );
+
+    XtDestroyWidget(shell);
+    wx_station_dialog = (Widget)NULL;
+
+end_critical_section(&wx_station_dialog_lock, "wx_gui.c:WX_station_destroy_shell" );
+
+}
+
+
+
+
+
+void WX_station_change_data(Widget widget, XtPointer clientData, XtPointer callData) {
+
+    WX_station_destroy_shell(widget,clientData,callData);
+}
+
+
+
+
+
+// This is the "Own Weather Station" Dialog
+//
+void WX_station( /*@unused@*/ Widget w, /*@unused@*/ XtPointer clientData, /*@unused@*/ XtPointer callData) {
+    static Widget  pane, my_form, form1, button_close, frame, 
+            WX_type, temp, wind_cse, wind_deg, wind_spd, wind_gst, 
+            my_rain, to_rain, rain_h, my_rain_24, baro,
+            humidity, humidity_n,
+            dew_point,
+            high_wind, wind_chill,
+            heat_index, three_hour_baro,
+            hi_temp, low_temp,
+            sts;
+
+    Atom delw;
+
+    if(!wx_station_dialog) {
+
+begin_critical_section(&wx_station_dialog_lock, "wx_gui.c:WX_station" );
+
+        wx_station_dialog = XtVaCreatePopupShell(langcode("WXPUPSI000"),
+            xmDialogShellWidgetClass, appshell,
+            XmNdeleteResponse, XmDESTROY,
+            XmNdefaultPosition, FALSE,
+            XmNfontList, fontlist1,
+            NULL);
+
+        pane = XtVaCreateWidget("WX_station pane",xmPanedWindowWidgetClass, wx_station_dialog,
+                          XmNbackground, colors[0xff],
+                          NULL); 
+
+        my_form =  XtVaCreateWidget("WX_station my_form",xmFormWidgetClass, pane,
+                            XmNfractionBase,7, 
+                            XmNbackground, colors[0xff],
+                            XmNautoUnmanage, FALSE,
+                            XmNshadowThickness, 1, 
+                            NULL);
+
+        WX_type = XtVaCreateManagedWidget(langcode("WXPUPSI001"),xmLabelWidgetClass, my_form,
+XmNtraversalOn, FALSE,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 10,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_type_data = XtVaCreateManagedWidget("WX_station type data", xmTextFieldWidgetClass, my_form,
+XmNtraversalOn, FALSE,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 70,
+                                      XmNtopOffset, 6, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment,XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_type,
+                                      XmNleftOffset, 5,
+                                      XmNtopAttachment,XmATTACH_FORM,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,                                
+                                      XmNrightAttachment,XmATTACH_FORM,
+                                      XmNrightOffset, 30,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        frame = XtVaCreateManagedWidget("WX_station frame", xmFrameWidgetClass, my_form,
+                                    XmNtopAttachment,XmATTACH_WIDGET,
+                                    XmNtopWidget, WX_type_data,
+                                    XmNtopOffset,10,
+                                    XmNbottomAttachment,XmATTACH_NONE,
+                                    XmNleftAttachment, XmATTACH_FORM,
+                                    XmNleftOffset, 10,
+                                    XmNrightAttachment,XmATTACH_FORM,
+                                    XmNrightOffset, 10,
+                                    XmNbackground, colors[0xff], 
+                                    NULL);
+
+        sts  = XtVaCreateManagedWidget(langcode("WXPUPSI002"),xmLabelWidgetClass,frame,
+XmNtraversalOn, FALSE,
+                                    XmNchildType, XmFRAME_TITLE_CHILD,
+                                    XmNbackground, colors[0xff], 
+                                    XmNfontList, fontlist1,
+                                    NULL);
+
+        form1 =  XtVaCreateWidget("WX_station form1",xmFormWidgetClass, frame,
+XmNtraversalOn, FALSE,
+                            XmNfractionBase, 7, 
+                            XmNbackground, colors[0xff],
+                            XmNtopAttachment, XmATTACH_FORM,
+                            XmNbottomAttachment, XmATTACH_FORM,
+                            XmNleftAttachment, XmATTACH_FORM,
+                            XmNrightAttachment, XmATTACH_FORM,
+                            XmNfontList, fontlist1,
+                            NULL);
+
+
+        wind_cse = XtVaCreateManagedWidget(langcode("WXPUPSI003"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_wind_cse_data = XtVaCreateManagedWidget("WX_station wc data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 3,
+                                      XmNtopOffset, 6, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_FORM,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        wind_deg = XtVaCreateManagedWidget(langcode("UNIOP00024"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_wind_cse_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        wind_spd = XtVaCreateManagedWidget(langcode("WXPUPSI004"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_cse,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_wind_spd_data = XtVaCreateManagedWidget("WX_station ws data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 3,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_cse,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+         WX_speed_label= XtVaCreateManagedWidget("WX_station speed label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,5,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_cse, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_wind_spd_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        wind_gst = XtVaCreateManagedWidget(langcode("WXPUPSI005"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_spd,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_wind_gst_data = XtVaCreateManagedWidget("WX_station wg data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 3,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_spd,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_gust_label= XtVaCreateManagedWidget("WX_station gust label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,5,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_spd, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_wind_gst_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        temp = XtVaCreateManagedWidget(langcode("WXPUPSI006"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_gst,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_temp_data = XtVaCreateManagedWidget("WX_station temp data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 8,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_gst,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+         WX_temp_label= XtVaCreateManagedWidget("WX_station temp label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,5,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_gst, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_temp_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        my_rain = XtVaCreateManagedWidget(langcode("WXPUPSI007"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, temp,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_rain_data = XtVaCreateManagedWidget("WX_station rain data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 10,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, temp,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+         WX_rain_label= XtVaCreateManagedWidget("WX_station rain label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,5,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, temp, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_rain_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        to_rain = XtVaCreateManagedWidget(langcode("WXPUPSI008"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, my_rain,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_to_rain_data = XtVaCreateManagedWidget("WX_station today rain data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 10,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, my_rain,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+         WX_to_rain_label= XtVaCreateManagedWidget("WX_station to label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,10,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, my_rain, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_to_rain_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        rain_h = XtVaCreateManagedWidget(langcode("WXPUPSI014"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, to_rain,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_rain_h_data = XtVaCreateManagedWidget("WX_station hour rain data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 10,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, to_rain,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+         WX_rain_h_label= XtVaCreateManagedWidget("WX_station hour label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,10,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, to_rain, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_rain_h_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        my_rain_24 = XtVaCreateManagedWidget(langcode("WXPUPSI015"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, rain_h,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_rain_24_data = XtVaCreateManagedWidget("WX_station 24h rain data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 10,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, rain_h,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+         WX_rain_24_label= XtVaCreateManagedWidget("WX_station 24h label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,      0,
+                                      XmNcolumns,10,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, rain_h, 
+                                      XmNtopOffset, 9,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_rain_24_data,
+                                      XmNleftOffset, 0,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        humidity = XtVaCreateManagedWidget(langcode("WXPUPSI010"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, my_rain_24,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_FORM,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        WX_humidity_data = XtVaCreateManagedWidget("WX_station Humidity data", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,    1,
+                                      XmNcolumns, 6,
+                                      XmNmaxLength, 8,
+                                      XmNtopOffset, 7, 
+                                      XmNbackground, colors[0x0f],
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 2,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, my_rain_24,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        humidity_n = XtVaCreateManagedWidget(langcode("UNIOP00026"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, my_rain_24, 
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_humidity_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        dew_point = XtVaCreateManagedWidget(langcode("WXPUPSI018"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_dew_point_data = XtVaCreateManagedWidget("WX_station dew point", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,1,
+                                      XmNcolumns, 6,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f],    
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_dew_point_label = XtVaCreateManagedWidget("WX_station dew label" ,xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_FORM,
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_dew_point_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        high_wind = XtVaCreateManagedWidget(langcode("WXPUPSI019"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, dew_point,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_high_wind_data = XtVaCreateManagedWidget("WX_station High Wind", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive, TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, dew_point,
+                                      XmNtopOffset, 7,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_high_wind_label = XtVaCreateManagedWidget("WX_station high wind label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,dew_point,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_high_wind_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        wind_chill = XtVaCreateManagedWidget(langcode("WXPUPSI020"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, high_wind,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_wind_chill_data = XtVaCreateManagedWidget("WX_station Wind Chill", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive,TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, high_wind,
+                                      XmNtopOffset, 7,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_wind_chill_label = XtVaCreateManagedWidget("WX_station wind label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,high_wind,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_wind_chill_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        heat_index = XtVaCreateManagedWidget(langcode("WXPUPSI021"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_chill,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_heat_index_data = XtVaCreateManagedWidget("WX_station Heat Index", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive,TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, wind_chill,
+                                      XmNtopOffset, 7,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_heat_index_label = XtVaCreateManagedWidget("WX_station heat label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,wind_chill,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_heat_index_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        baro = XtVaCreateManagedWidget(langcode("WXPUPSI009"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, heat_index,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_baro_data = XtVaCreateManagedWidget("WX_station Baro", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive,TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, heat_index,
+                                      XmNtopOffset, 7,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_baro_label = XtVaCreateManagedWidget("WX_Station baro unit label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,heat_index,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_baro_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        three_hour_baro = XtVaCreateManagedWidget(langcode("WXPUPSI022"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, baro,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_three_hour_baro_data = XtVaCreateManagedWidget("WX_station 3-Hr Baro", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive,TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, baro,
+                                      XmNtopOffset, 7,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_three_hour_baro_label = XtVaCreateManagedWidget("WX_station 3hr baro unit label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,  baro,
+                                      XmNtopOffset, 12,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_three_hour_baro_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        hi_temp = XtVaCreateManagedWidget(langcode("WXPUPSI023"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, three_hour_baro,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_hi_temp_data = XtVaCreateManagedWidget("WX_station Today's High Temp", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive,TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, three_hour_baro,
+                                      XmNtopOffset, 7,
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f],
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_hi_temp_label = XtVaCreateManagedWidget("WX_station high temp label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,  three_hour_baro,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_hi_temp_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        low_temp = XtVaCreateManagedWidget(langcode("WXPUPSI024"),xmLabelWidgetClass, form1,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, hi_temp,
+                                      XmNtopOffset, 11,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 4,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_low_temp_data = XtVaCreateManagedWidget("WX_station Today's Low Temp", xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNcolumns, 6,
+                                      XmNsensitive,TRUE,
+                                      XmNshadowThickness,1,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNtopAttachment,XmATTACH_WIDGET,
+                                      XmNtopWidget, hi_temp,
+                                      XmNtopOffset, 7,                    
+                                      XmNbottomAttachment,XmATTACH_NONE,
+                                      XmNbackground, colors[0x0f], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        WX_low_temp_label = XtVaCreateManagedWidget("WX_station low temp label",xmTextFieldWidgetClass, form1,
+                                      XmNeditable,   FALSE,
+                                      XmNcursorPositionVisible, FALSE,
+                                      XmNsensitive, STIPPLE,
+                                      XmNshadowThickness,0,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget,  hi_temp,
+                                      XmNtopOffset, 8,
+                                      XmNbottomAttachment, XmATTACH_NONE,
+                                      XmNleftAttachment, XmATTACH_WIDGET,
+                                      XmNleftWidget, WX_low_temp_data,
+                                      XmNleftOffset, 5,
+                                      XmNrightAttachment, XmATTACH_NONE,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+
+        button_close = XtVaCreateManagedWidget(langcode("UNIOP00003"),xmPushButtonGadgetClass, my_form,
+XmNtraversalOn, TRUE,
+                                      XmNtopAttachment, XmATTACH_WIDGET,
+                                      XmNtopWidget, frame, 
+                                      XmNtopOffset, 10,
+                                      XmNbottomAttachment, XmATTACH_FORM,
+                                      XmNbottomOffset,10,
+                                      XmNleftAttachment, XmATTACH_POSITION,
+                                      XmNleftPosition, 3,
+                                      XmNrightAttachment, XmATTACH_POSITION,
+                                      XmNrightPosition, 4,
+                                      XmNbackground, colors[0xff], 
+                                      XmNfontList, fontlist1,
+                                      NULL);
+
+        XtAddCallback(button_close, XmNactivateCallback, WX_station_destroy_shell, wx_station_dialog);
+
+        pos_dialog(wx_station_dialog);
+
+        delw = XmInternAtom(XtDisplay(wx_station_dialog),"WM_DELETE_WINDOW", FALSE);
+        XmAddWMProtocolCallback(wx_station_dialog, delw, WX_station_destroy_shell, (XtPointer)wx_station_dialog);
+
+        XtManageChild(my_form);
+        XtManageChild(form1);
+        XtManageChild(pane);
+
+end_critical_section(&wx_station_dialog_lock, "wx_gui.c:WX_station" );
+
+        XtPopup(wx_station_dialog,XtGrabNone);
+        fix_dialog_size(wx_station_dialog);
+        fill_wx_data();
+    } else {
+        (void)XRaiseWindow(XtDisplay(wx_station_dialog), XtWindow(wx_station_dialog));
+    }
+}
+
+
+
+
+
+void fill_wx_data(void) {
+    DataRow *p_station;
+    char temp[20];
+    WeatherRow *weather;
+
+    if (wx_station_dialog != NULL) {
+
+begin_critical_section(&wx_station_dialog_lock, "wx_gui.c:fill_wx_data" );
+
+        if (search_station_name(&p_station,my_callsign,1)) {
+            if (get_weather_record(p_station)) {    // DK7IN: only add record if we found something...
+                weather = p_station->weather_data;
+
+                if (strlen(wx_station_type) > 1)
+                    XmTextFieldSetString(WX_type_data,wx_station_type);
+                else
+                    XmTextFieldSetString(WX_type_data,"");
+                XtManageChild(WX_type_data);
+
+                if (weather != 0) {  // we have weather data
+                    if (strlen(weather->wx_temp) > 0) {
+                       if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(((atof(weather->wx_temp)-32)*5.0)/9.0));
+
+                            XmTextFieldSetString(WX_temp_data,temp);
+                        } else XmTextFieldSetString(WX_temp_data,weather->wx_temp);
+                    } else
+                        XmTextFieldSetString(WX_temp_data,"");
+                    XtManageChild(WX_temp_data);
+
+                    if (strlen(weather->wx_course) > 0)
+                        XmTextFieldSetString(WX_wind_cse_data,weather->wx_course);
+                    else
+                        XmTextFieldSetString(WX_wind_cse_data,"");
+
+                    XtManageChild(WX_wind_cse_data);
+
+                    if (strlen(weather->wx_speed) > 0) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(atof(weather->wx_speed)*1.6094));
+
+                            XmTextFieldSetString(WX_wind_spd_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_wind_spd_data,weather->wx_speed);
+                    } else
+                        XmTextFieldSetString(WX_wind_spd_data,"");
+
+                    XtManageChild(WX_wind_spd_data);
+
+                    if (strlen(weather->wx_gust) > 0) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(atof(weather->wx_gust)*1.6094));
+
+                            XmTextFieldSetString(WX_wind_gst_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_wind_gst_data,weather->wx_gust);
+                    } else
+                        XmTextFieldSetString(WX_wind_gst_data,"");
+
+                    XtManageChild(WX_wind_gst_data);
+
+                    if (strlen(weather->wx_rain_total) > 0) {
+                        if (!english_units)
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_rain_total)*.254);
+                        else
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_rain_total)/100.0);
+
+                        XmTextFieldSetString(WX_rain_data,temp);
+                    } else
+                        XmTextFieldSetString(WX_rain_data,"");
+
+                    XtManageChild(WX_rain_data);
+
+                    if (strlen(weather->wx_rain) > 0) {
+                        if (!english_units)
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_rain)*.254);
+                        else
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                               atof(weather->wx_rain)/100.0);
+
+                        XmTextFieldSetString(WX_rain_h_data,temp);
+                    } else
+                        XmTextFieldSetString(WX_rain_h_data,"");
+
+                    XtManageChild(WX_rain_h_data);
+
+                    if (strlen(weather->wx_prec_24) > 0) {
+                        if (!english_units)
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_prec_24)*.254);
+                        else
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_prec_24)/100.0);
+
+                        XmTextFieldSetString(WX_rain_24_data,temp);
+                    } else
+                        XmTextFieldSetString(WX_rain_24_data,"");
+
+                    XtManageChild(WX_rain_24_data);
+
+                    if (strlen(weather->wx_prec_00) > 0) {
+                        if (!english_units)
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_prec_00)*.254);
+                        else
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                atof(weather->wx_prec_00)/100.0);
+
+                        XmTextFieldSetString(WX_to_rain_data,temp);
+                    } else
+                        XmTextFieldSetString(WX_to_rain_data,"");
+
+                    XtManageChild(WX_rain_data);
+
+                    if (strlen(weather->wx_hum) > 0)
+                        XmTextFieldSetString(WX_humidity_data,weather->wx_hum);
+                    else
+                        XmTextFieldSetString(WX_humidity_data,"");
+
+                    XtManageChild(WX_humidity_data);
+
+                    if (strlen(wx_dew_point) > 0) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(((atof(wx_dew_point)-32)*5.0)/9.0));
+                            XmTextFieldSetString(WX_dew_point_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_dew_point_data,wx_dew_point);
+                    } else
+                        XmTextFieldSetString(WX_dew_point_data,"");
+
+                    XtManageChild(WX_dew_point_data);
+
+                    if (strlen(wx_high_wind) > 0) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(atof(wx_high_wind)*1.6094));
+                            XmTextFieldSetString(WX_high_wind_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_high_wind_data,wx_high_wind);
+                    } else
+                        XmTextFieldSetString(WX_high_wind_data,"");
+
+                    XtManageChild(WX_high_wind_data);
+
+                    if (strlen(wx_wind_chill) > 0) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(((atof(wx_wind_chill)-32)*5.0)/9.0));
+                            XmTextFieldSetString(WX_wind_chill_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_wind_chill_data,wx_wind_chill);
+                    } else
+                        XmTextFieldSetString(WX_wind_chill_data,"");
+
+                    XtManageChild(WX_wind_chill_data);
+
+                    if (strlen(weather->wx_baro) > 0) {
+                        if (!english_units) {
+                            //xastir_snprintf(temp, sizeof(temp), "%0.0f",
+                            //        atof(wx_baro_inHg)*25.4); // inch Hg -> mm Hg
+                            //XmTextFieldSetString(WX_baro_data,temp);
+                            XmTextFieldSetString(WX_baro_data,weather->wx_baro); // hPa
+                        }
+                        else {  // inches mercury
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                (atof(weather->wx_baro)*0.02953));
+                            XmTextFieldSetString(WX_baro_data,temp);
+                        }
+                    } else
+                        XmTextFieldSetString(WX_baro_data,"");
+
+                    XtManageChild(WX_baro_data);
+
+                    if (wx_three_hour_baro_on) {
+                        if (!english_units) {  // hPa
+                            //xastir_snprintf(temp, sizeof(temp), "%0.0f",
+                            //        atof(wx_three_hour_baro)*25.4); // inch Hg -> mm Hg
+                            XmTextFieldSetString(WX_three_hour_baro_data,wx_three_hour_baro);
+                        } else {  // inches mercury
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%0.2f",
+                                (atof(wx_three_hour_baro)*0.02953));
+                            XmTextFieldSetString(WX_three_hour_baro_data,temp);
+                        }
+                    } else
+                        XmTextFieldSetString(WX_three_hour_baro_data,"");
+
+                    XtManageChild(WX_three_hour_baro_data);
+
+                    if (wx_hi_temp_on) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(((atof(wx_hi_temp)-32)*5.0)/9.0));
+                            XmTextFieldSetString(WX_hi_temp_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_hi_temp_data,wx_hi_temp);
+                    } else
+                        XmTextFieldSetString(WX_hi_temp_data,"");
+
+                    XtManageChild(WX_hi_temp_data);
+
+                    if (wx_low_temp_on) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(((atof(wx_low_temp)-32)*5.0)/9.0));
+                            XmTextFieldSetString(WX_low_temp_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_low_temp_data,wx_low_temp);
+                    } else
+                        XmTextFieldSetString(WX_low_temp_data,"");
+
+                    XtManageChild(WX_low_temp_data);
+
+                    if (wx_heat_index_on) {
+                        if (!english_units) {
+                            xastir_snprintf(temp,
+                                sizeof(temp),
+                                "%03d",
+                                (int)(((atof(wx_heat_index)-32)*5.0)/9.0));
+                            XmTextFieldSetString(WX_heat_index_data,temp);
+                        } else
+                            XmTextFieldSetString(WX_heat_index_data,wx_heat_index);
+                    } else
+                        XmTextFieldSetString(WX_heat_index_data,"");
+
+                    XtManageChild(WX_heat_index_data);
+                }
+            }
+        }
+
+        /* labels */
+        if (!english_units)
+            XmTextFieldSetString(WX_speed_label,langcode("UNIOP00012"));
+        else
+            XmTextFieldSetString(WX_speed_label,langcode("UNIOP00013"));
+
+        XtManageChild(WX_speed_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_gust_label,langcode("UNIOP00012"));
+        else
+            XmTextFieldSetString(WX_gust_label,langcode("UNIOP00013"));
+
+        XtManageChild(WX_gust_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_temp_label,langcode("UNIOP00014"));
+        else
+            XmTextFieldSetString(WX_temp_label,langcode("UNIOP00015"));
+
+        XtManageChild(WX_temp_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_rain_label,langcode("UNIOP00016"));
+        else
+            XmTextFieldSetString(WX_rain_label,langcode("UNIOP00017"));
+
+        XtManageChild(WX_rain_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_to_rain_label,langcode("UNIOP00022"));
+        else
+            XmTextFieldSetString(WX_to_rain_label,langcode("UNIOP00023"));
+
+        XtManageChild(WX_to_rain_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_rain_h_label,langcode("UNIOP00020"));
+        else
+            XmTextFieldSetString(WX_rain_h_label,langcode("UNIOP00021"));
+
+        XtManageChild(WX_rain_h_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_rain_24_label,langcode("UNIOP00018"));
+        else
+            XmTextFieldSetString(WX_rain_24_label,langcode("UNIOP00019"));
+
+        XtManageChild(WX_rain_24_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_dew_point_label,langcode("UNIOP00014"));
+        else
+            XmTextFieldSetString(WX_dew_point_label,langcode("UNIOP00015"));
+
+        XtManageChild(WX_dew_point_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_wind_chill_label,langcode("UNIOP00014"));
+        else
+            XmTextFieldSetString(WX_wind_chill_label,langcode("UNIOP00015"));
+
+        XtManageChild(WX_wind_chill_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_heat_index_label,langcode("UNIOP00014"));
+        else
+            XmTextFieldSetString(WX_heat_index_label,langcode("UNIOP00015"));
+
+        XtManageChild(WX_heat_index_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_hi_temp_label,langcode("UNIOP00014"));
+        else
+            XmTextFieldSetString(WX_hi_temp_label,langcode("UNIOP00015"));
+
+        XtManageChild(WX_hi_temp_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_low_temp_label,langcode("UNIOP00014"));
+        else
+            XmTextFieldSetString(WX_low_temp_label,langcode("UNIOP00015"));
+
+        XtManageChild(WX_low_temp_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_high_wind_label,langcode("UNIOP00012"));
+        else
+            XmTextFieldSetString(WX_high_wind_label,langcode("UNIOP00013"));
+
+        XtManageChild(WX_high_wind_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_baro_label,langcode("UNIOP00025"));
+        else
+            XmTextFieldSetString(WX_baro_label,langcode("UNIOP00027"));
+
+        XtManageChild(WX_baro_label);
+
+        if (!english_units)
+            XmTextFieldSetString(WX_three_hour_baro_label,langcode("UNIOP00025"));
+        else
+            XmTextFieldSetString(WX_three_hour_baro_label,langcode("UNIOP00027"));
+
+        XtManageChild(WX_three_hour_baro_label);
+
+end_critical_section(&wx_station_dialog_lock, "wx_gui.c:fill_wx_data" );
+
+    }
+}
+
+
diff --git a/src/x_spider.c b/src/x_spider.c
new file mode 100644
index 0000000..b19a354
--- /dev/null
+++ b/src/x_spider.c
@@ -0,0 +1,1725 @@
+/*
+ * $Id: x_spider.c,v 1.67 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+
+//
+// The idea here:  Have Xastir spawn off a separate server (via a
+// system() call?) which can provide listening sockets for other
+// APRS clients to connect to.  This allows other clients to share
+// Xastir's TNC ports.  Forking Xastir directly and running the
+// server code doesn't work out well:  The new process ends up with
+// the large Xastir memory image.  We need a separate app with a
+// small memory image for the server.  It might spawn off quite a
+// few processes, and we need it to be small and fast.
+//
+// The initial goal here is to take one box that is RF-rich (running
+// one or more TNC's), and have the ability to let other APRS
+// clients (Xastir or otherwise) to share the RF and/or internet
+// connections of the "master" Xastir session.  This could be useful
+// in an EOC (Emergency Operations Center), a large SAR mission with
+// multiple computers, or simply to allow one to connect to their
+// home Xastir session from work and gain the use of the RF ports.
+// My use:  On a SAR mission, using wireless networking and laptops
+// to let everyone see the same picture, multiplexing to one Xastir
+// session running a TNC.  As usual, I'm sure other users will
+// figure out new and inventive uses for it.
+//
+// Yes, this does pose some security risks to the license of the
+// operator.  I wouldn't recommend having an open port on the
+// internet to allow people to use your RF ports.  Of course with
+// the authentication stuff that'll be in here, it's as secure as
+// the igating stuff that we currently have for APRS.
+//
+// I thought about using IPC Messaging or FIFO's (named pipes) in
+// order to make the connection from this server back to the
+// "master" Xastir session.  I looked at the lack of support for
+// them in Cygwin and decided to use sockets instead.  We'll set up
+// a special registration for Xastir so that this server code knows
+// which port is the "master" port (controlling port).
+//
+// Xastir will end up with a togglebutton to enable the server:
+//   Starts up x_spider.
+//   Connects to x_spider with a socket.
+//   Sends a special string so x_spider knows which one is the
+//     controlling (master) socket.
+//   All packets received/transmitted by Xastir on any port also get
+//     sent to x_spider.
+//
+// x_spider:
+//   Accepts client socket connections.
+//   Spawns a new process for each one.
+//   Each new process talks to the main x_spider via two pipes.
+//   Authenticate each connecting client in the normal manner.
+//   Accept data from any socket, echo data out _all_ sockets.
+//   If the "master" Xastir sends a shutdown packet, all connections
+//     are dropped and x_spider and all it's children will exit.
+//   x_spider uses select() calls to multiplex all pipes and the
+//     listening socket.  It shouldn't use up much CPU as it'll be
+//     in the blocking select call until it has data to process.
+//   x_spider's children should also wait in blocking calls until
+//     there is data to process.
+//   
+// This makes the design of the server rather simple:  It needs to
+// authenticate clients and it needs to parse the shutdown message
+// from the "master" socket.  Other than that it just needs to
+// re-transmit anything heard on one socket to all of the other
+// connected sockets.
+//
+// Xastir itself will have to change a bit in order to add the
+// togglebutton, to send anything transmit/received to the special
+// socket, and to send the registration and shutdown strings to the
+// server at the appropriate times.  Not earth-shaking changes, but
+// changes nonetheless.
+//
+// Most of this code is adapted directly from W. Richard Steven's
+// book:  "Unix Network Programming".  Highly recommended book, as
+// are the other books by him that I own.  I was sorry to hear of
+// his passing.
+//
+// Name for this?  Spider, centipede, millipede, octopus,
+// multiplexer, repeater.
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include "x_spider.h"
+#include "snprintf.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <signal.h>
+#include <termios.h>
+#include <pwd.h>
+
+#include <termios.h>
+#include <setjmp.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <netinet/in.h>     // Moved ahead of inet.h as reports of some *BSD's not
+                            // including this as they should.
+#include <arpa/inet.h>
+#include <netinet/tcp.h>    // Needed for TCP_NODELAY setsockopt() (disabling Nagle algorithm)
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif  // HAVE_NETDB_H
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else   // TIME_WITH_SYS_TIME
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else  // HAVE_SYS_TIME_H
+#  include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif  // TIME_WITH_SYS_TIME
+
+#include <errno.h>
+
+#ifdef  HAVE_LOCALE_H
+#include <locale.h>
+#endif  // HAVE_LOCALE_H
+
+#ifdef  HAVE_LIBINTL_H
+#include <libintl.h>
+#define _(x)        gettext(x)
+#else   // HAVE_LIBINTL_H
+#define _(x)        (x)
+#endif  // HAVE_LIBINTL_H
+
+
+#ifndef SIGRET
+#define SIGRET  void
+#endif  // SIGRET
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+// Define this if you wish to use this as a standalone program
+// instead of as a function in another program.
+//
+//#define STANDALONE_PROGRAM
+
+
+
+// These are from util.h/util.c.  We can't include util.h here
+// because it causes other problems.
+extern short checkHash(char *theCall, short theHash);
+extern void get_timestamp(char *timestring);
+extern void split_string( char *data, char *cptr[], int max, char search_char );
+
+
+// From database.h
+extern char my_callsign[];
+
+
+typedef struct _pipe_object {
+    int to_child[2];
+    int to_parent[2];
+    char callsign[20];
+    int authenticated;
+    int active;		// Mark for deletion after every task is finished
+    struct _pipe_object *next;
+} pipe_object;
+
+
+pipe_object *pipe_head = NULL;
+//int master_fd = -1; // Start with an invalid value
+
+pipe_object *xastir_tcp_pipe = NULL;
+pipe_object *xastir_udp_pipe = NULL;
+
+// TCP server pipes to/from Xastir proper
+int pipe_xastir_to_tcp_server = -1;
+int pipe_tcp_server_to_xastir = -1;
+
+// UDP server pipes to/from Xastir proper
+int pipe_xastir_to_udp_server = -1; // (not currently used)
+int pipe_udp_server_to_xastir = -1;
+
+
+
+
+
+/*
+// Read "n" bytes from a descriptor.  Use in place of read() when fd
+// is a stream socket.  This routine is from "Unix Network
+// Programming".
+//
+// This routine is not used currently.
+//
+int readn(register int fd, register char *ptr, register int nbytes) {
+    int nleft, nread;
+
+    nleft = nbytes;
+    while (nleft > 0) {
+        nread = read(fd, ptr, nleft);
+        if (nread < 0) {
+            return(nread);  // Error, return < 0
+        }
+        else if (nread == 0) {
+            break;  // EOF
+        }
+
+        nleft -= nread;
+        ptr += nread;
+    }
+    return(nbytes - nleft); // Return >= 0
+}
+*/
+
+
+
+
+
+// Write "n" bytes to a descriptor.  Use in place of write() when fd
+// is a stream socket.  This routine is from "Unix Network
+// Programming".
+//
+int writen(register int fd, register char *ptr, register int nbytes) {
+    int nleft, nwritten;
+
+    nleft = nbytes;
+    while (nleft > 0) {
+        nwritten = write(fd,  ptr, nleft);
+        if (nwritten <= 0) {
+            return(nwritten);   // Error
+        }
+
+        nleft -= nwritten;
+        ptr += nwritten;
+    }
+
+//    fprintf(stderr,
+//        "writen: %d bytes written, %d bytes left to write\n",
+//        nleft,
+//        nbytes - nleft);
+
+    return(nbytes - nleft);
+}
+
+
+
+
+
+// Read a line from a descriptor.  Read the line one byte at a time,
+// looking for the newline.  We store the newline in the buffer,
+// then follow it with a null (the same as fgets(3)).  We return the
+// number of characters up to, but not including, the null (the same
+// as strlen(3));  This routine is from "Unix Network Programming".
+//
+int readline(register int fd, register char *ptr, register int maxlen) {
+    int n, rc;
+    char c;
+
+    for (n = 1; n < maxlen; n++) {
+        if ( (rc = read(fd, &c, 1)) == 1) {
+            *ptr++ = c;
+            if (c == '\n') {
+                break;
+            }
+        }
+        else if (rc == 0) {
+            if (n == 1) {
+                return(0);  // EOF, no data read
+            }
+            else {
+                break;      // EOF, some data was read
+            }
+        }
+        else {
+            return(-1);     // Error
+        }
+    }
+    *ptr = 0;
+    return(n);
+}
+
+
+
+
+
+#define MAXLINE 512
+
+
+// Read a stream socket one line at a time, and write each line back
+// to the sender.  Return when the connection is terminated.  This
+// routine is from "Unix Network Programming".
+//
+/*
+void str_echo(int sockfd) {
+    int n;  
+    char line[MAXLINE];
+
+    for ( ; ; ) {
+        n = readline(sockfd, line, MAXLINE);
+        if (n == 0) {
+            return; // Connection terminated
+        }
+        if (n < 0) {
+            fprintf(stderr,"str_echo: No data to read\n");
+        }
+
+        if (writen(sockfd, line, n) != n) {
+            fprintf(stderr,"str_echo: Writen error\n");
+        }
+    }
+}
+*/
+
+
+
+
+
+// Read a stream socket one line at a time, and write each line back
+// to the sender.  Return when the connection is terminated.  This
+// routine is from "Unix Network Programming".
+//
+void str_echo2(int sockfd, int pipe_from_parent, int pipe_to_parent) {
+    int n;  
+    char line[MAXLINE];
+
+
+    // Set socket to be non-blocking.
+    //
+    if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) {
+        fprintf(stderr,"str_echo2: Couldn't set socket non-blocking\n");
+    }
+
+    // Set read-end of pipe to be non-blocking.
+    //
+    if (fcntl(pipe_from_parent, F_SETFL, O_NONBLOCK) < 0) {
+        fprintf(stderr,"str_echo2: Couldn't set read-end of pipe_from_parent non-blocking\n");
+    }
+
+
+    //Send our callsign to spider clients as "#callsign" much like APRS-IS sends "# javaAPRS"
+    // # xastir 1.5.1 callsign:<mycall>
+    sprintf(line,"# Welcome to Xastir's server port, callsign: %s\r\n",my_callsign);
+    writen(sockfd,line,strlen(line));
+
+    // Infinite loop
+    for ( ; ; ) {
+
+        //
+        // Read data from socket, write to pipe (parent)
+        //
+        if (!sockfd)    // Socket is closed
+            return; // Connection terminated
+ 
+        n = readline(sockfd, line, MAXLINE);
+        if (n == 0) {
+            return; // Connection terminated
+        }
+        if (n < 0) {
+            //fprintf(stderr,"str_echo2: Readline error: %d\n",errno);
+            if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                // This is normal if we have no data to read
+                //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
+            }
+            else {  // Non-normal error.  Report it.
+                fprintf(stderr,"str_echo2: Readline error socket: %d\n",errno);
+//close(sockfd);
+return;
+            }
+        }
+        else {  // We received some data.  Send it down the pipe.
+//            fprintf(stderr,"str_echo2: %s\n",line);
+            if (writen(pipe_to_parent, line, n) != n) {
+                fprintf(stderr,"str_echo2: Writen error socket: %d\n",errno);
+//close(sockfd);
+return;
+            }
+        }
+
+
+        //
+        // Read data from pipe (parent), write to socket
+        //
+        if (!pipe_from_parent)
+            exit(0);
+ 
+        n = readline(pipe_from_parent, line, MAXLINE);
+        if (n == 0) {
+            exit(0);    // Connection terminated
+        }
+        if (n < 0) {
+            //fprintf(stderr,"str_echo2: Readline error: %d\n",errno);
+            if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                // This is normal if we have no data to read
+                //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
+            }
+            else {  // Non-normal error.  Report it.
+                fprintf(stderr,"str_echo2: Readline error pipe: %d\n",errno);
+//close(pipe_from_parent);
+return;
+            }
+        }
+        else {  // We received some data.  Send it down the socket.
+//            fprintf(stderr,"str_echo2: %s\n",line);
+
+            if (writen(sockfd, line, n) != n) {
+                fprintf(stderr,"str_echo2: Writen error pipe: %d\n",errno);
+//close(pipe_from_parent);
+return;
+            }
+        }
+
+        // Slow the loop down to prevent excessive CPU.
+
+// NOTE:  We must be faster at processing packets than the
+// main.c:UpdateTime() can send them to us through the pipe!  If
+// we're not, we lose or corrupt packets.
+
+        usleep(1000); // 1ms
+    }
+}
+
+
+
+
+
+// Function which checks the incoming pipes to see if there's any
+// data.  If there is, checks to see if it is a control packet or a
+// registration packet from the master.  If not, echoes the data out
+// all outgoing pipes.
+// 
+// If we get a shutdown from the verified master, send a "1" as the
+// return value, which will shut down the server.  Otherwise send a
+// "0" return value.
+//
+// Incoming registration data:  Record only the master socket.  All
+// others should be handled by the child processes, and they should
+// not pass the registration info down to us.  Same for control
+// packets.  Actually, the child process handling the master socket
+// could skip notifying us as well, and just pass down the control
+// packets if the master sent any (like the shutdown packet).  If we
+// lost the connection between Xastir and x_spider, we might not
+// have a clean way of shutting down the server in that case though.
+// Might be better to record it down here, and if the pipes ever
+// closed, we shut down x_spider and all the child processes.
+//
+int pipe_check(char *client_address) {
+    pipe_object *p = pipe_head;
+    int n;  
+    char line[MAXLINE];
+
+
+    // Need a select here with a timeout?  Also need a method of
+    // revising the read bits we send to select.  Should we revise
+    // them every time through the loop, or set a variable in the
+    // main() routine whenever a new connect comes in.  What about
+    // connects that go away?  We need a way to free up the pipes
+    // and sockets in that case, and revise the select bits again.
+
+//    select();
+
+//fprintf(stderr,"pipe_check()\n");
+
+    // All of the read ends of the pipes have been set non-blocking
+    // by this point.
+
+    // Check all the pipes in the linked list looking for something
+    // to read.
+    while (p != NULL) {
+//        fprintf(stderr,"Running through pipes\n");
+
+        //
+        // Read data from pipe, write to all pipes except the one
+        // who sent it.
+        //
+        n = p->active ? readline(p->to_parent[0], line, MAXLINE): 0;
+        if (n == 0 && p->active) {
+            char timestring[101];
+
+            get_timestamp(timestring);
+
+            if (p->authenticated) { 
+                fprintf(stderr,
+                    "%s X_spider session terminated, callsign: %s, address: %s\n",
+                    timestring,
+                    p->callsign,
+                    client_address);
+            }
+            else {
+                fprintf(stderr,
+                    "%s X_spider session terminated, unauthenticated user, address %s\n",
+                    timestring,
+                    client_address);
+            }
+
+            // Close the pipe
+            close(p->to_child[1]);
+            close(p->to_parent[0]);
+
+            p->active = 0;	// This task is ready to let go.
+
+            wait(NULL); // Reap the status of the dead process
+        }
+        else if (n < 0) {
+            //fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
+            if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                // This is normal if we have no data to read
+                //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
+            }
+            else {  // Non-normal error.  Report it.
+                fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
+            }
+        }
+        else if (p->active) {  // We received some data.  Send it down all of the
+                // pipes except the one that sent it.
+
+            pipe_object *q;
+
+
+// Check for an authentication string.  If the pipe has not been
+// authenticated, we don't allow it to send anything to the upstream
+// server.  It's probably ok to send it to downstream connections
+// though.
+
+            // Check for "user" "pass" string.
+            // "user WE7U-13 pass XXXX vers XASTIR 1.3.3"
+            if (strstr(line,"user") && strstr(line,"pass")) {
+                char line2[MAXLINE];
+                char *callsign;
+                char *passcode_str;
+                short passcode;
+                char *space;
+
+                // We have a string with user/pass in it, but they
+                // can be anywhere along the line.  We'll have to
+                // search for each piece.
+
+//fprintf(stderr,"x_spider:Found an authentication string\n");
+
+                // Copy the line
+                xastir_snprintf(line2, sizeof(line2), "%s", line);
+
+                // Add white space to the end.
+                strncat(line2,
+                    "                                    ",
+                    sizeof(line2) - 1 - strlen(line2));
+
+                // Find the "user" string position
+                callsign = strstr(line2,"user");
+
+                if (callsign == NULL)
+                    continue;
+
+                // Fast-forward past the "user" word.
+                callsign += 4;
+
+                // Skip past any additional spaces that might be
+                // present between "user" and callsign.
+                while (callsign[0] == ' ' && callsign[0] != '\0') {
+                    callsign += 1;
+                }
+
+                if (callsign[0] == '\0')
+                    continue;
+
+                // We should now be pointing at the beginning of the
+                // callsign.
+
+                // Find the space after the callsign
+                space = strstr(callsign," ");
+
+                if (space == NULL)
+                    continue;
+
+                // Terminate the callsign string
+                space[0] = '\0';
+
+                // Snag the passcode string 
+
+                // Find the "pass" string
+                passcode_str = strstr(&space[1],"pass");
+
+                if (passcode_str == NULL)
+                    continue;
+
+                // Fast-forward past the "pass" word.
+                passcode_str = passcode_str + 4;
+
+                // Skip past any additional spaces that might be
+                // present between "pass" and the passcode.
+                while (passcode_str[0] == ' ' && passcode_str[0] != '\0') {
+                    passcode_str += 1;
+                }
+
+                if (passcode_str[0] == '\0')
+                    continue;
+
+                // Find the space after the passcode
+                space = strstr(&passcode_str[0]," ");
+
+                if (space == NULL)
+                    continue;
+
+                // Terminate the passcode string
+                space[0] = '\0';
+
+                passcode = atoi(passcode_str);
+
+//fprintf(stderr,"x_spider: user:.%s., pass:%d\n", callsign, passcode);
+
+                if (checkHash(callsign, passcode)) {
+                    // Authenticate the pipe.  It is now allowed to send
+                    // to the upstream server.
+                    //fprintf(stderr,
+                    //    "x_spider: Authenticated user %s\n",
+                    //    callsign);
+                    p->authenticated = 1;
+                    xastir_snprintf(p->callsign,
+                        sizeof(p->callsign),
+                        "%s",
+                        callsign);
+                    p->callsign[19] = '\0';
+                }
+                else {
+                    fprintf(stderr,
+                        "X_spider: Bad authentication, user %s, pass %d\n",
+                        callsign,
+                        passcode);
+                    fprintf(stderr,
+                        "Line: %s\n",
+                        line);
+                }
+            }
+
+            q = pipe_head;
+
+            while (q != NULL) {
+//                fprintf(stderr,"pipe_check: %s\n",line);
+
+                // Only send to active pipes
+                if (q != p && q->active) {
+                    if (writen(q->to_child[1], line, n) != n) {
+                        fprintf(stderr,"pipe_check: Writen error1: %d\n",errno);
+                    }
+                }
+                q = q->next;
+            }
+
+            // Here we send it to Xastir itself.  We use a couple of
+            // global variables just like channel_data() does, but
+            // we don't have to protect them in the same manner as
+            // we only have one process on each end.
+            //
+
+// Send it down the pipe to Xastir's main thread.  Knock off any
+// carriage return that might be present.  We only want a linefeed
+// on the end.
+            if (n > 0 && (line[n-1] == '\r' || line[n-1] == '\n')) {
+                line[n-1] = '\0';
+                n--;
+            }
+            if (n > 0 && (line[n-1] == '\r' || line[n-1] == '\n')) {
+                line[n-1] = '\0';
+                n--;
+            }
+            // Add the linefeed on the end
+            strncat(line,"\n",1);
+            n++;
+
+// Only send to upstream server if this client has authenticated.
+            if (p->authenticated) {
+
+//fprintf(stderr,"Data available, sending to server\n");
+//fprintf(stderr,"\t%s\n",line);
+
+                if (writen(pipe_tcp_server_to_xastir, line, n) != n) {
+                    fprintf(stderr, "pipe_check: Writen error2: %d\n", errno);
+                }
+            }
+        }
+
+        if (p) p = p->next;
+    }
+
+
+    // Check the pipe from Xastir's main thread to see if it is
+    // sending us any data
+    n = readline(pipe_xastir_to_tcp_server, line, MAXLINE);
+
+    if (n == 0) {
+        exit(0); // Connection terminated
+    }
+
+    if (n < 0) {
+        //fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
+        if (errno == EAGAIN || errno == EWOULDBLOCK) {
+            // This is normal if we have no data to read
+            //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
+        }
+        else {  // Non-normal error.  Report it.
+            fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
+        }
+    }
+
+    else {  // We received some data.  Send it down all of the
+            // pipes.
+// Also send it down the socket.
+
+        // Check for disconnected clients and delete their records
+        // from the chain.
+        pipe_object *q = pipe_head;
+        pipe_object *r = pipe_head;
+        for (q = pipe_head; q != NULL; ) {
+
+            if (!q->active) { // Marked for deletion.
+
+                // Check for head of list, handle it in a special
+                // manner.  We don't have to fix up the "next"
+                // pointer on the previous object (it doesn't exist)
+                // but must fix up "pipe_head" pointer.
+                if (q == pipe_head) {
+                    pipe_head = q->next;  // New head of list
+                    p = q; // Assign temporary pointer
+                    q = q->next; // Keep pointer to next object
+                    r = q;  // Keep 'r' and 'q' the same for now,
+                            // later 'r' will lag 'q' by one object
+                    free(p); // Free struct at temporary pointer
+                }
+                else { // Not the head object
+                    r->next = q->next; // Bridge soon-to-be-made gap
+                    p = q; // Assign temporary pointer
+                    q = q->next; // Keep pointer to next connection.
+                    free(p); // Free struct at temp pointer
+                }
+            }
+            else {
+                r = q;  // Pointer to last object (so we can get to
+                        // the "next" pointer)
+                q = q->next; // Pointer to next object
+            }
+        }
+        q = pipe_head; // Reset pointer to beginning of list
+
+        //fprintf(stderr,"n:%d\n",n);
+        // Terminate it
+        line[n] = '\0';
+        //fprintf(stderr,"sp %s\n", line);
+ 
+        // The internet protocol for sending lines is "\r\n".  Knock
+        // off any line-end characters that might be present, then
+        // add a "\r\n" combo on the end.
+        //
+        if (n >= 1 && (line[n-1] == '\r' || line[n-1] == '\n')) {
+            line[n-1] = '\0';
+            n--;
+        }
+        if (n >= 1 && (line[n-1] == '\r' || line[n-1] == '\n')) {
+            line[n-1] = '\0';
+            n--;
+        }
+        // Add carriage-return/linefeed onto the end
+        strncat(line, "\r\n", 2);
+        n += 2;
+
+        while (q != NULL && q->active) {
+//          fprintf(stderr,"pipe_check: %s\n",line);
+
+            if (writen(q->to_child[1], line, n) != n) {
+                fprintf(stderr,"pipe_check: Writen error1: %d\n",errno);
+            }
+            q = q->next;
+        }
+    }
+
+    return(0);
+}
+
+
+
+
+
+// The below three functions init_set_proc_title() and
+// set_proc_title() are from:
+// http://lightconsulting.com/~thalakan/process-title-notes.html
+// They seems to work fine on Linux, but they only change the "ps"
+// listings, not the top listings.  I don't know why yet.
+
+// Here's another good web page for Linux:
+// http://www.uwsg.iu.edu/hypermail/linux/kernel/0006.1/0610.html 
+
+// clear_proc_title is to clean up internal pointers for environment.
+
+/* Globals */
+static char **Argv = ((void *)0);
+#ifdef __linux__
+#ifndef __LSB__
+extern char *__progname, *__progname_full;
+#endif  // __LSB__
+#endif  // __linux__
+static char *LastArgv = ((void *)0);
+static char **local_environ;
+static char *old_progname, *old_progname_full;
+
+
+
+void clear_proc_title(void)
+{
+  int i;
+  for(i = 0; local_environ && local_environ[i] != NULL; i++) {
+    free(local_environ[i]);
+  }
+  if (local_environ) {
+    free(local_environ);
+    local_environ = NULL;
+  }
+#ifdef __linux__
+#ifndef __LSB__
+  free(__progname);
+  free(__progname_full);
+  __progname = old_progname;
+  __progname_full = old_progname_full;
+#endif  // __LSB__
+#endif  // __linux__
+}
+
+void init_set_proc_title(int argc, char *argv[], char *envp[]) {
+    int i, envpsize;
+    char **p;
+
+    for(i = envpsize = 0; envp[i] != NULL; i++)
+        envpsize += strlen(envp[i]) + 1;
+  
+    if((p = (char **) malloc((i + 1) * sizeof(char *))) != NULL ) {
+        local_environ = p;
+
+    for(i = 0; envp[i] != NULL; i++) {
+        if((local_environ[i] = malloc(strlen(envp[i]) + 1)) != NULL)
+            xastir_snprintf(local_environ[i],
+                strlen(envp[i])+1,
+                "%s",
+                envp[i]);
+        }
+    }
+    local_environ[i] = NULL;
+
+    Argv = argv;
+  
+    for(i = 0; argv[i] != NULL; i++) {
+        if((LastArgv + 1) == argv[i]) // Not sure if this conditional is needed
+        LastArgv = envp[i] + strlen(envp[i]);
+    }
+#ifdef __linux__
+#ifndef __LSB__
+    // Pretty sure you don't need this either
+    old_progname = __progname;
+    old_progname_full = __progname_full;
+    __progname = strdup("xastir");
+    __progname_full = strdup(argv[0]);
+#endif  // __LSB__
+#endif  // __linux__
+    atexit(clear_proc_title);
+}
+
+
+void set_proc_title(char *fmt,...) {
+    va_list msg;
+    static char statbuf[8192];
+    char *p;
+    int i,maxlen = (LastArgv - Argv[0]) - 2;
+
+    //fprintf(stderr,"DEBUG: maxlen: %i\n", maxlen);
+
+    va_start(msg,fmt);
+
+    memset(statbuf, 0, sizeof(statbuf));
+    xastir_vsnprintf(statbuf, sizeof(statbuf), fmt, msg);
+
+    va_end(msg);
+
+    i = strlen(statbuf);
+
+    xastir_snprintf(Argv[0], maxlen, "%s", statbuf);
+    p = &Argv[0][i];
+  
+    while(p < LastArgv)
+        *p++ = '\0';
+    Argv[1] = ((void *)0) ;
+}
+
+
+
+
+
+// This TCP server provides a listening socket.  When a client
+// connects, the server forks off a separate process to handle it
+// and goes back to listening for new connects.  The initial code
+// framework here is from the book:  "Unix Network Programming".
+//
+// Create two pipes between this server and each child process.
+// Identify and record which socket is the master socket connection
+// (back to the Xastir session that started up x_spider).  Set this
+// variable once, don't change it if another client connects and
+// claims to be the master.  If we get control commands from the
+// master, service them.
+//
+// If anything that comes in from a client that's not a registration
+// or a control packet, repeat it to all of the other connected
+// clients, including sending it to the controlling Xastir socket
+// (which is also a data channel).
+//
+// We need to make the "accept" call non-blocking so that we can
+// keep servicing all of the pipes from the children.  If any pipe
+// has data, check whether it's a registration from the master or a
+// control packet.  If not, send the data out each client
+// connection.  Each child will take care of normal APRS
+// authentication.  If the client doesn't authenticate, close the
+// socket and exit from the child process.  Notify the main process
+// as well?
+//
+#ifdef STANDALONE_PROGRAM
+int main(int argc, char *argv[]) {
+#else   // !STANDALONE_PROGRAM 
+void TCP_Server(int argc, char *argv[], char *envp[]) {
+#endif  // STANDALONE_PROGRAM
+
+    int sockfd, newsockfd, childpid;
+    socklen_t clilen;
+    struct sockaddr_in cli_addr, serv_addr;
+    pipe_object *p;
+    int sendbuff;
+    int pipe_to_parent; /* symbolic names to reduce confusion */
+    int pipe_from_parent;
+    char timestring[101];
+
+    
+    // Open a TCP listening socket
+    //
+    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        fprintf(stderr,"x_spider: Can't open socket for listening\n");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+        exit(1);
+    }
+
+    // Set the new socket to be non-blocking.
+    //
+    if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) {
+        fprintf(stderr,"x_spider: Couldn't set socket non-blocking\n");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+    }
+
+    // Set up to reuse the port number (good for debug so we can
+    // restart the server quickly against the same port).
+    //
+    sendbuff = 1;
+    if (setsockopt(sockfd,
+            SOL_SOCKET,
+            SO_REUSEADDR,
+            (char *)&sendbuff,
+            sizeof(sendbuff)) < 0) {
+        fprintf(stderr,"x_spider: Couldn't set socket REUSEADDR\n");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+    }
+
+    // Bind our local address so that the client can send to us.
+    //
+    memset((char *)&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    serv_addr.sin_port = htons(SERV_TCP_PORT);
+
+    if (bind(sockfd,
+            (struct sockaddr *)&serv_addr,
+            sizeof(serv_addr)) < 0) {
+        fprintf(stderr,"x_spider: Can't bind local address\n");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+        exit(1);
+    }
+
+    // Set up to listen.  We allow up to five backlog connections
+    // (unserviced connects that get put on a queue until we can
+    // service them).
+    //
+    listen(sockfd, 5);
+    memset((char *)&cli_addr, 0, sizeof(cli_addr));
+
+    // Infinite loop
+    //
+    for ( ; ; ) {
+        int flag;
+
+
+        // Look for a connection from a client process.  This is a
+        // concurrent server (allows multiple concurrent
+        // connections).
+
+        clilen = (socklen_t)sizeof(cli_addr);
+
+        // "accept" is the call where we wait for a connection.  We
+        // made the socket non-blocking above so that we pop out of
+        // it with an EAGAIN if we don't have an incoming socket
+        // connection.  This lets us check all of our pipe
+        // connections for incoming data periodically.
+        //
+        newsockfd = accept(sockfd,
+                        (struct sockaddr *)&cli_addr,
+                        &clilen);
+
+        if (newsockfd == -1) {
+            if (errno == EAGAIN || errno == EWOULDBLOCK) {
+
+                // We returned from the non-blocking accept but with
+                // no incoming socket connection.  Check the pipe
+                // queues for incoming data.
+                //
+                if (pipe_check(inet_ntoa(cli_addr.sin_addr)) == -1) {
+
+                    // We received a shutdown command from the
+                    // master socket connection.
+                    exit(0);
+                }
+                goto finis;
+            }
+            else if (newsockfd < 0) {
+
+                // Some error happened in accept().  Skip the rest
+                // of the loop.
+                //
+                fprintf(stderr,"x_spider: Accept error: %d\n", errno);
+                fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+                goto finis;
+            }
+        }
+
+        // Else we returned from the accept with an incoming
+        // connection.  Service it.
+        //
+        // Allocate a new pipe before we fork.
+        //
+        p = (pipe_object *)malloc(sizeof(pipe_object));
+        if (p == NULL) {
+            fprintf(stderr,"x_spider: Couldn't malloc pipe_object\n");
+            close(newsockfd);
+            goto finis;
+        }
+
+        // We haven't authenticated this user client yet.
+        p->authenticated = 0;
+        p->callsign[0] = '\0';
+
+        get_timestamp(timestring);
+
+        fprintf(stderr,"%s X_spider client connected from address %s\n",
+            timestring,
+            inet_ntoa(cli_addr.sin_addr));
+ 
+        if (pipe(p->to_child) < 0 || pipe(p->to_parent) < 0) {
+            fprintf(stderr,"x_spider: Can't create pipes\n");
+            if (p->to_child[1]) close(p->to_child[1]);
+            if (p->to_child[0]) close(p->to_child[0]);
+            free(p);    // Free the malloc'd memory.
+            p = NULL;
+            close(newsockfd);
+            goto finis;
+        }
+
+        // Indicate active connection!
+        p->active = 1;
+
+        // Link it into the head of the chain.
+        //
+        p->next = pipe_head;
+        pipe_head = p;
+
+        flag = 1;
+
+        // Turn on the socket keepalive option
+        (void)setsockopt(newsockfd,  SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int));
+
+        // Disable the Nagle algorithm (speeds things up)
+        (void)setsockopt(newsockfd, IPPROTO_TCP,  TCP_NODELAY, (char *) &flag, sizeof(int));
+
+        if ( (childpid = fork()) < 0) {
+            //
+            // Problem forking.  Clean up and continue loop.
+            //
+
+            fprintf(stderr,"x_spider: Fork error\n");
+            // Close pipes
+            close(p->to_child[0]);
+            close(p->to_child[1]);
+            close(p->to_parent[0]);
+            close(p->to_parent[1]);
+            pipe_head = p->next;
+            free(p);    // Free the malloc'd memory.
+            p = NULL;
+            close(newsockfd);
+            goto finis;
+        }
+        else if (childpid == 0) {
+            //
+            // child process
+            //
+
+
+            // Go back to default signal handler instead of calling
+            // restart() on SIGHUP
+            (void) signal(SIGHUP,SIG_DFL);
+
+
+/*
+            fprintf(stderr,
+                "Client address: %s\n",
+                inet_ntoa(cli_addr.sin_addr));
+*/
+
+            // Change the name of the new child process.  So far
+            // this only works for "ps" listings, not for "top".
+            // This code only works on Linux.  For BSD use
+            // setproctitle(3), NetBSD can use setprogname(2).
+#ifdef __linux__
+            init_set_proc_title(argc, argv, envp);
+            set_proc_title("%s%s %s",
+                "x-spider client @",
+                inet_ntoa(cli_addr.sin_addr),
+                "(xastir)");
+            //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
+	    (void) signal(SIGHUP, exit);
+#endif  // __linux__
+
+// It'd be very cool here to include the IP address of the remote
+// client on the "ps" line, and include the callsign of the
+// connecting client once the client authenticates.  Both of these
+// are do-able.
+
+
+            // New naming system so that we don't have to remember
+            // the longer name:
+            //
+            pipe_to_parent = p->to_parent[1];
+            pipe_from_parent = p->to_child[0];
+
+            close(sockfd);      // Close original socket.  Child
+                                // doesn't need the listening
+                                // socket.
+            close(p->to_child[1]);  // Close write end of pipe
+            close(p->to_parent[0]); // Close read end of pipe
+
+//            str_echo(newsockfd);    // Process the request
+            str_echo2(newsockfd,
+                pipe_from_parent,
+                pipe_to_parent);
+ 
+
+            // Clean up and exit
+            //
+            close(pipe_to_parent);
+            close(pipe_from_parent);
+            exit(0);
+
+        }
+        //
+        // Parent process
+        //
+
+        close(newsockfd);
+        close(p->to_parent[1]); // Close write end of pipe
+        close(p->to_child[0]);  // Close read end of pipe
+
+        // Set read-end of pipe to be non-blocking.
+        //
+        if (fcntl(p->to_parent[0], F_SETFL, O_NONBLOCK) < 0) {
+            fprintf(stderr,"x_spider: Couldn't set read-end of pipe_to_parent non-blocking\n");
+            fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+        }
+
+finis:
+        // Need a delay so that we don't use too much CPU, at least
+        // for debug.  Put the delay into the select() call in the
+        // pipe_check() function once we get to that stage of
+        // coding.
+        //
+
+// NOTE:  We must be faster at processing packets than the
+// main.c:UpdateTime() can send them to us through the pipe!  If
+// we're not, we lose or corrupt packets.
+
+        usleep(1000); // 1ms
+    }
+}
+
+
+
+
+
+// Send a nack back to the xastir_udp_client program 
+void send_udp_nack(int sock, struct sockaddr_in from, int fromlen) {
+    int n;
+
+    n = sendto(sock,
+        "NACK", // Negative Acknowledgment
+        5,
+        0,
+        (struct sockaddr *)&from,
+        fromlen);
+    if (n < 0) {
+        fprintf(stderr, "Error: sendto");
+    }
+}
+ 
+
+
+
+
+// Create a UDP listening port.  This allows scripts and other
+// programs to inject packets into Xastir via UDP protocol.
+//
+void UDP_Server(int argc, char *argv[], char *envp[]) {
+    int sock, length, n1, n2;
+    socklen_t fromlen;
+    struct sockaddr_in server;
+    struct sockaddr_in from;
+    char buf[1024];
+    char buf2[512];
+    char *callsign;
+    short passcode;
+    char *cptr[10];
+    char *message = NULL;
+    char message2[1024];
+    int send_to_inet;
+    int send_to_rf;
+
+
+    sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+    if (sock < 0) {
+        fprintf(stderr, "Error: Opening socket");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+        return;
+    }
+
+    length = sizeof(server);
+    memset(&server, 0, length);
+
+    server.sin_family = AF_INET;
+    server.sin_addr.s_addr = INADDR_ANY;
+    server.sin_port = htons(SERV_UDP_PORT);
+
+    if (bind(sock, (struct sockaddr *)&server, length) < 0) {
+        fprintf(stderr, "Error: Binding");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+        return;
+    }
+
+    fromlen = sizeof(struct sockaddr_in);
+
+    while (1) {
+        n1 = recvfrom(sock,
+            buf,
+            1024,
+            0,
+            (struct sockaddr *)&from,
+            &fromlen);
+        if (n1 < 0) {
+            fprintf(stderr, "Error: recvfrom");
+        }
+        else if (n1 == 0) {
+            continue;
+        }
+        else {
+            buf[n1] = '\0';    // Terminate the buffer
+        }
+
+fprintf(stderr, "Received datagram: %s", buf);
+
+
+        send_to_inet = 0;
+        send_to_rf = 0;
+
+
+        //
+        // Authenticate the packet.  First line should contain:
+        //
+        //      callsign,passcode,[TO_RF],[TO_INET]
+        //
+        // The second line should contain the APRS packet
+        //
+
+        // Copy the entire buffer so that we can modify it
+        xastir_snprintf(buf2, sizeof(buf2), "%s", buf);
+        split_string(buf2, cptr, 10, ',');
+
+        if (cptr[0] == NULL || cptr[0][0] == '\0') {    // callsign
+            send_udp_nack(sock, from, fromlen);
+            continue;
+        }
+
+        callsign = cptr[0];
+
+        if (cptr[1] == NULL || cptr[1][0] == '\0') {    // passcode
+            send_udp_nack(sock, from, fromlen);
+            continue;
+        }
+
+        passcode = atoi(cptr[1]);
+
+fprintf(stderr,"x_spider udp:  user:%s  pass:%d\n", callsign, passcode);
+
+        if (checkHash(callsign, passcode)) {
+            // Authenticate the pipe.  It is now allowed to send
+            // to the upstream server.
+            //fprintf(stderr,
+            //    "x_spider: Authenticated user %s\n",
+            //    callsign);
+        }
+        else {
+            fprintf(stderr,
+                "X_spider: Bad authentication, user %s, pass %d\n",
+                callsign,
+                passcode);
+            fprintf(stderr,
+                "UDP Packet: %s\n",
+                buf);
+            send_udp_nack(sock, from, fromlen);
+            continue;
+        }
+
+
+        // Here's where we would look for the optional flags in the
+        // first line.  Here we implement these flags:
+        //      -identify
+        //      -to_rf
+        //      -to_inet
+
+
+        // Look for the "-identify" flag in the UDP packet
+        //
+        if (strstr(buf, "-identify")) {
+            
+            // Send the callsign back to the xastir_udp_client
+            // program
+            n1 = sendto(sock,
+                my_callsign,
+                strlen(my_callsign)+1,
+                0,
+                (struct sockaddr *)&from,
+                fromlen);
+            if (n1 < 0) {
+                fprintf(stderr, "Error: sendto");
+            }
+            continue;
+        }
+
+
+        // Look for the "-to_inet" flag in the UDP packet
+        //
+        if (strstr(buf, "-to_inet")) {
+//fprintf(stderr,"Sending to INET\n");
+            send_to_inet++;
+        }
+
+
+        // Look for the "-to_rf" flag in the UDP packet
+        //
+        if (strstr(buf, "-to_rf")) {
+//fprintf(stderr,"Sending to local RF\n");
+            send_to_rf++;
+        }
+
+
+        // Now snag the text message from the second line using the
+        // original buffer.  Look for the first '\n' character which
+        // is just before the text message itself.
+        message = strchr(buf, '\n');
+        message++;  // Point to the first char after the '\n'
+
+        if (message == NULL || message[0] == '\0') {
+//fprintf(stderr,"Empty message field\n");
+            send_udp_nack(sock, from, fromlen);
+            continue;
+        }
+
+//fprintf(stderr,"Message:  %s", message);
+
+        xastir_snprintf(message2,
+            sizeof(message2),
+            "%s%s%s",
+            (send_to_inet) ? "TO_INET," : "",
+            (send_to_rf) ? "TO_RF," : "",
+            message);
+
+//fprintf(stderr,"Message2: %s", message2);
+
+
+
+//
+//
+// NOTE:
+// Should we refuse to send the message on if "callsign" and the
+// FROM callsign in the packet don't match?
+//
+// Should we change to third-party format if "my_callsign" and the
+// FROM callsign in the packet don't match?
+//
+// Require all three callsigns to match?
+//
+//
+
+
+
+        n1 = strlen(message);
+        n2 = strlen(message2);
+
+
+        // Send to Xastir udp pipe
+        //
+//fprintf(stderr,"Sending to Xastir itself\n");
+        if (writen(pipe_udp_server_to_xastir, message2, n2) != n2) {
+            fprintf(stderr,"UDP_Server: Writen error1: %d\n", errno);
+        }
+
+        // Send to the x_spider TCP server, so it can go to all
+        // connected TCP clients
+//fprintf(stderr,"Sending to TCP clients\n");
+        if (writen(pipe_xastir_to_tcp_server, message, n1) != n1) {
+            fprintf(stderr, "UDP_Server: Writen error2: %d\n", errno);
+        }
+ 
+        // Send an ACK back to the xastir_udp_client program 
+        n1 = sendto(sock,
+            "ACK",  // Acknowledgment.  Good UDP packet.
+            4,
+            0,
+            (struct sockaddr *)&from,
+            fromlen);
+        if (n1 < 0) {
+            fprintf(stderr, "Error: sendto");
+        }
+    }
+}
+
+
+
+
+
+// Function used to start a separate process for the server.  This
+// way the server can be running concurrently with the main part of
+// Xastir.
+//
+// Turns out that with a "fork", the memory image of the server was
+// too large.  Might try it with a thread instead before abandoning
+// that method altogether.  It would be nice to have this be more
+// integrated with Xastir, instead of having to have a socket to
+// communicate between Xastir and the server.
+//
+#ifndef STANDALONE_PROGRAM
+int Fork_TCP_server(int argc, char *argv[], char *envp[]) {
+    int childpid;
+
+
+    // Allocate a pipe before we fork.
+    //
+    xastir_tcp_pipe = (pipe_object *)malloc(sizeof(pipe_object));
+    if (xastir_tcp_pipe == NULL) {
+        fprintf(stderr,"x_spider: Couldn't malloc pipe_object\n");
+        return(0);
+    }
+
+    if (pipe(xastir_tcp_pipe->to_child) < 0 || pipe(xastir_tcp_pipe->to_parent) < 0) {
+        fprintf(stderr,"x_spider: Can't create pipes\n");
+        free(xastir_tcp_pipe);    // Free the malloc'd memory.
+        xastir_tcp_pipe = NULL;
+        return(0);
+    }
+ 
+    xastir_tcp_pipe->authenticated = 1;
+    xastir_tcp_pipe->callsign[0] = '\0';
+ 
+    if ( (childpid = fork()) < 0) {
+        fprintf(stderr,"Fork_TCP_server: Fork error\n");
+
+        // Close pipes
+        close(xastir_tcp_pipe->to_child[0]);
+        close(xastir_tcp_pipe->to_child[1]);
+        close(xastir_tcp_pipe->to_parent[0]);
+        close(xastir_tcp_pipe->to_parent[1]);
+        free(xastir_tcp_pipe);    // Free the malloc'd memory.
+        xastir_tcp_pipe = NULL;
+        return(0);
+    }
+    else if (childpid == 0) {
+        //
+        // Child process
+        //
+
+
+        // Go back to default signal handler instead of calling
+        // restart() on SIGHUP
+        (void) signal(SIGHUP,SIG_DFL);
+
+
+        // Change the name of the new child process.  So far this
+        // only works for "ps" listings, not for "top".  This code
+        // only works on Linux.  For BSD use setproctitle(3), NetBSD
+        // can use setprogname(2).
+#ifdef __linux__
+        init_set_proc_title(argc, argv, envp);
+        set_proc_title("%s", "x-spider TCP daemon (xastir)");
+        //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
+	(void) signal(SIGHUP, exit);
+#endif  // __linux__
+ 
+
+        close(xastir_tcp_pipe->to_child[1]);  // Close write end of pipe
+        close(xastir_tcp_pipe->to_parent[0]); // Close read end of pipe
+
+        // Assign the global variables
+        pipe_tcp_server_to_xastir = xastir_tcp_pipe->to_parent[1];
+        pipe_xastir_to_tcp_server = xastir_tcp_pipe->to_child[0];
+
+        // Set read-end of pipe to be non-blocking.
+        //
+        if (fcntl(pipe_xastir_to_tcp_server, F_SETFL, O_NONBLOCK) < 0) {
+            fprintf(stderr,"x_spider: Couldn't set read-end of pipe_xastir_to_tcp_server non-blocking\n");
+            fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+        }
+
+        // Go into an infinite loop here which restarts the
+        // listening process whenever it dies.
+        //
+//        while (1) {
+//            fprintf(stderr,"Starting TCP_Server...\n");
+
+            TCP_Server(argc, argv, envp);
+
+//            fprintf(stderr,"TCP_Server process died.\n");
+//        }
+    }
+    //
+    // Parent process
+    //
+
+    close(xastir_tcp_pipe->to_parent[1]); // Close write end of pipe
+    close(xastir_tcp_pipe->to_child[0]);  // Close read end of pipe
+
+    // Assign the global variables so that Xastir itself will know
+    // how to talk to the pipes
+    pipe_tcp_server_to_xastir = xastir_tcp_pipe->to_parent[0];
+    pipe_xastir_to_tcp_server = xastir_tcp_pipe->to_child[1];
+
+    // Set read-end of pipe to be non-blocking.
+    //
+    if (fcntl(pipe_tcp_server_to_xastir, F_SETFL, O_NONBLOCK) < 0) {
+        fprintf(stderr,"x_spider: Couldn't set read-end of pipe_tcp_server_to_xastir non-blocking\n");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+    }
+
+//    // Set write-end of pipe to be non-blocking.
+//    //
+//    if (fcntl(pipe_xastir_to_tcp_server, F_SETFL, O_NONBLOCK) < 0) {
+//        fprintf(stderr,"x_spider: Couldn't set read-end of pipe_xastir_to_tcp_server non-blocking\n");
+//    }
+
+    // We don't need to do anything here except return back to the
+    // calling routine with the PID of the new server process, so
+    // that it can request the server and all it's children to quit
+    // when Xastir quits or segfaults.
+    return(childpid);   // Really the parent PID in this case
+}
+#endif  // STANDALONE_PROGRAM
+
+
+
+
+
+int Fork_UDP_server(int argc, char *argv[], char *envp[]) {
+    int childpid;
+
+
+    // Allocate a pipe before we fork.
+    //
+    xastir_udp_pipe = (pipe_object *)malloc(sizeof(pipe_object));
+    if (xastir_udp_pipe == NULL) {
+        fprintf(stderr,"x_spider: Couldn't malloc pipe_object\n");
+        return(0);
+    }
+
+    if (pipe(xastir_udp_pipe->to_child) < 0 || pipe(xastir_udp_pipe->to_parent) < 0) {
+        fprintf(stderr,"x_spider: Can't create pipes\n");
+        free(xastir_udp_pipe);    // Free the malloc'd memory.
+        xastir_udp_pipe = NULL;
+        return(0);
+    }
+ 
+    xastir_udp_pipe->authenticated = 1;
+    xastir_udp_pipe->callsign[0] = '\0';
+ 
+    if ( (childpid = fork()) < 0) {
+        fprintf(stderr,"Fork_UDP_server: Fork error\n");
+
+        // Close pipes
+        close(xastir_udp_pipe->to_child[0]);
+        close(xastir_udp_pipe->to_child[1]);
+        close(xastir_udp_pipe->to_parent[0]);
+        close(xastir_udp_pipe->to_parent[1]);
+        free(xastir_udp_pipe);    // Free the malloc'd memory.
+        xastir_udp_pipe = NULL;
+        return(0);
+    }
+    else if (childpid == 0) {
+        //
+        // Child process
+        //
+
+
+        // Go back to default signal handler instead of calling
+        // restart() on SIGHUP
+        (void) signal(SIGHUP,SIG_DFL);
+
+
+        // Change the name of the new child process.  So far this
+        // only works for "ps" listings, not for "top".  This code
+        // only works on Linux.  For BSD use setproctitle(3), NetBSD
+        // can use setprogname(2).
+#ifdef __linux__
+        init_set_proc_title(argc, argv, envp);
+        set_proc_title("%s", "x-spider UDP daemon (xastir)");
+        //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
+	(void) signal(SIGHUP, exit);
+#endif  // __linux__
+ 
+
+        close(xastir_udp_pipe->to_child[1]);  // Close write end of pipe
+        close(xastir_udp_pipe->to_parent[0]); // Close read end of pipe
+
+        // Assign the global variables
+        pipe_udp_server_to_xastir = xastir_udp_pipe->to_parent[1];
+        pipe_xastir_to_udp_server = xastir_udp_pipe->to_child[0];
+
+        // Set read-end of pipe to be non-blocking.
+        //
+//        if (fcntl(pipe_xastir_to_udp_server, F_SETFL, O_NONBLOCK) < 0) {
+//            fprintf(stderr,
+//                "x_spider: Couldn't set read-end of pipe_xastir_to_udp_server non-blocking\n");
+//        }
+
+        // Go into an infinite loop here which restarts the
+        // listening process whenever it dies.
+        //
+//        while (1) {
+//            fprintf(stderr,"Starting UDP_Server...\n");
+
+	UDP_Server(argc, argv, envp);
+
+	fprintf(stderr,"UDP_Server process died.\n");
+//        }
+    }
+    //
+    // Parent process
+    //
+
+    close(xastir_udp_pipe->to_parent[1]); // Close write end of pipe
+    close(xastir_udp_pipe->to_child[0]);  // Close read end of pipe
+
+    // Assign the global variables so that Xastir itself will know
+    // how to talk to the pipes
+    pipe_udp_server_to_xastir = xastir_udp_pipe->to_parent[0];
+    pipe_xastir_to_udp_server = xastir_udp_pipe->to_child[1];
+
+
+    // Set read-end of pipe to be non-blocking.
+    //
+    if (fcntl(pipe_udp_server_to_xastir, F_SETFL, O_NONBLOCK) < 0) {
+        fprintf(stderr,"x_spider: Couldn't set read-end of pipe_udp_server_to_xastir non-blocking\n");
+        fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
+    }
+
+//    // Set write-end of pipe to be non-blocking.
+//    //
+//    if (fcntl(pipe_xastir_to_udp_server, F_SETFL, O_NONBLOCK) < 0) {
+//        fprintf(stderr,"x_spider: Couldn't set read-end of pipe_xastir_to_udp_server non-blocking\n");
+//    }
+
+
+    // We don't need to do anything here except return back to the
+    // calling routine with the PID of the new server process, so
+    // that it can request the server and all it's children to quit
+    // when Xastir quits or segfaults.
+    return(childpid);   // Really the parent PID in this case
+}
+
+ 
diff --git a/src/x_spider.h b/src/x_spider.h
new file mode 100644
index 0000000..beb9b18
--- /dev/null
+++ b/src/x_spider.h
@@ -0,0 +1,48 @@
+/*
+ * $Id: x_spider.h,v 1.16 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifndef __XASTIR_SERVER_H
+#define __XASTIR_SERVER_H
+
+//#include "xastir.h"
+
+
+#define NET_CONNECT_TIMEOUT 20
+#define SERV_TCP_PORT       2023
+#define SERV_UDP_PORT       2023
+
+
+char *pname;
+extern int pipe_xastir_to_tcp_server;
+extern int pipe_tcp_server_to_xastir;
+extern int pipe_xastir_to_udp_server;
+extern int pipe_udp_server_to_xastir;
+
+extern int writen(register int fd, register char *ptr, register int nbytes);
+extern int readline(register int fd, register char *ptr, register int maxlen);
+extern int Fork_TCP_server(int argc, char *argv[], char *envp[]);
+extern int Fork_UDP_server(int argc, char *argv[], char *envp[]);
+
+
+#endif /* XASTIR_SERVER_H */
+
diff --git a/src/xa_config.c b/src/xa_config.c
new file mode 100644
index 0000000..8341d6f
--- /dev/null
+++ b/src/xa_config.c
@@ -0,0 +1,2489 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: xa_config.c,v 1.193 2012/10/22 23:59:55 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <locale.h>
+
+#include <Xm/XmAll.h>
+
+#include "xa_config.h"
+#include "interface.h"
+#include "xastir.h"
+#include "main.h"
+#include "util.h"
+#include "bulletin_gui.h"
+#include "list_gui.h"
+#include "messages.h"
+#include "draw_symbols.h"
+#include "maps.h"
+#include "track_gui.h"
+#include "geo.h"
+#include "snprintf.h"
+#include "objects.h"
+#include "db_gis.h"
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+#define CONFIG_FILE      "config/xastir.cnf"
+#define CONFIG_FILE_BAK1 "config/xastir.cnf.1"
+#define CONFIG_FILE_BAK2 "config/xastir.cnf.2"
+#define CONFIG_FILE_BAK3 "config/xastir.cnf.3"
+#define CONFIG_FILE_BAK4 "config/xastir.cnf.4"
+#define CONFIG_FILE_TMP  "config/xastir.cnf.tmp"
+
+#define MAX_VALUE 300
+
+//extern char xa_config_dir[];
+
+
+
+void store_string(FILE * fout, char *option, char *value) {
+
+//    if (debug_level & 1)
+//        fprintf(stderr,"Store String Start\n");
+
+// TODO:  Replace with function which doesn't depend on locale.
+// We'd also need to replace any xastir_snprintf() functions
+// throughout.
+    fprintf (fout, "%s:%s\n", option, value);
+
+//    if (debug_level & 1)
+//        fprintf(stderr,"Store String Stop\n");
+
+}
+
+
+
+
+
+void store_char(FILE * fout, char *option, char value) {
+    char value_o[2];
+
+    value_o[0] = value;
+    value_o[1] = '\0';
+    store_string (fout, option, value_o);
+}
+
+
+
+
+
+void store_int(FILE * fout, char *option, int value) {
+    char value_o[MAX_VALUE];
+
+    xastir_snprintf (value_o, sizeof(value_o), "%d", value);
+    store_string (fout, option, value_o);
+}
+
+
+
+
+
+void store_long (FILE * fout, char *option, long value) {
+    char value_o[MAX_VALUE];
+
+    xastir_snprintf(value_o, sizeof(value_o), "%ld", value);
+    store_string (fout, option, value_o);
+}
+
+
+
+
+
+void store_float (FILE * fout, char *option, float value) {
+    char value_o[MAX_VALUE];
+
+    xastir_snprintf(value_o, sizeof(value_o), "%f", value);
+    store_string (fout, option, value_o);
+}
+
+
+
+
+
+FILE * fin;
+
+void input_close(void)
+{
+    if(fin != NULL)
+        (void)fclose(fin);
+    fin = NULL;
+}
+
+
+
+
+
+/*
+    This function will read the configuration file (xastir.cnf) until it finds
+    the requested option. When the requested option is found it will return
+    the value of that option.
+    The return value of the function will be 1 if the option is found and 0
+    if the option is not found.
+    May return empty string in "value".
+*/
+int get_string(char *option, char *value, int value_size) {
+    char config_file[MAX_VALUE];
+    char config_line[256];
+    short option_found;
+    char *value_array[2];
+
+    option_found = 0;
+
+    if (fin == NULL) {
+
+        get_user_base_dir(CONFIG_FILE, config_file, sizeof(config_file));
+
+        // filecreate() refuses to create a new file if it already
+        // exists.
+        (void)filecreate(config_file);
+        fin = fopen (config_file, "r");
+    }
+
+    if (fin != NULL) {
+        int loop_counter = 0;
+
+        while (!option_found && loop_counter < 2) {
+            // Search to the end of file and then repeat from the
+            // beginning (once) if not found the first time.  As
+            // long as we keep the order of saves/restores to/from
+            // the file the same, this will mean exactly one fgets()
+            // per variable sought.
+            if (loop_counter == 1) {
+                // We didn't find it the first time through, try
+                // once more from the start of file.
+                (void)fseek(fin, 0, SEEK_SET);
+            }
+
+            // Read the file line-by-line.  fgets() also reads in
+            // the line-end characters so we'll have to remove
+            // those.
+            while (!option_found && (fgets (&config_line[0], 256, fin) != NULL)) {
+
+                // Find the line containing "option"
+                // Here we assume no leading/trailing white space
+                // for value_array[0].
+                split_string(config_line, value_array, 2, ':');
+
+                if (strcmp (value_array[0], option) == 0) {
+                    int len;
+
+                    // Found the correct line
+                    option_found = 1;
+
+                    remove_leading_spaces(value_array[1]);
+
+                    // Eliminate line-end chars.  Do this twice 'cuz
+                    // some operating systems add two characters
+                    // (\r\n)
+                    len = strlen(value_array[1]);
+                    if (len > 0) {
+                        if ( (value_array[1][len-1] == '\n')
+                                || (value_array[1][len-1] == '\r') ) {
+                        value_array[1][len-1] = '\0';
+                        }
+                    }
+                    len = strlen(value_array[1]);
+                    if (len > 0) {
+                        if ( (value_array[1][len-1] == '\n')
+                                || (value_array[1][len-1] == '\r') ) {
+                            value_array[1][len-1] = '\0';
+                        }
+                    }
+
+                    remove_trailing_spaces(value_array[1]);
+                
+                    if (value_array[1] == NULL)
+                        value = "";
+                    else
+                        xastir_snprintf(value,
+                            value_size,
+                            "%s",
+                            value_array[1]);
+
+                    //fprintf(stderr,"%s = %s\n", value_array[0], value);
+                }
+            }  // End of while (fgets)
+            loop_counter++;
+        } // End of while (!option_found)
+    } // End of if
+    else
+        fprintf(stderr,"Couldn't open file: %s\n", config_file);
+
+    return (option_found);
+}
+
+
+
+
+
+int get_char(char *option, char *value) {
+    char value_o[MAX_VALUE];
+    int ret;
+
+    ret = get_string (option, value_o, sizeof(value_o));
+    if (ret)
+        *value = value_o[0];
+
+    return (ret);
+}
+
+
+
+
+
+// Snags an int and checks whether it is within the correct range.
+// If not, it assigns a default value.  Returns the value.
+int get_int(char *option, int low, int high, int def) {
+    char value_o[MAX_VALUE];
+    int ret;
+
+    ret = get_string (option, value_o, sizeof(value_o));
+    if (ret && (atoi(value_o) >= low) && (atoi(value_o) <= high) ) {
+        return(atoi (value_o));
+    }
+
+    if (!ret) {
+//        fprintf(stderr,"xastir.cnf: %s not found, inserting default: %d\n",
+//            option,
+//            def);
+        return(def);
+    }
+
+    fprintf(stderr,"xastir.cnf: %s out-of-range: %d, changing to default: %d\n",
+        option,
+        atoi(value_o),
+        def);
+    return(def);
+}
+
+
+
+
+
+// Snags a long and checks whether it is within the correct range.
+// If not, it assigns a default value.  Returns the value.
+long get_long(char *option, long low, long high, long def) {
+    char value_o[MAX_VALUE];
+    int ret;
+
+    ret = get_string (option, value_o, sizeof(value_o));
+    if (ret && (atol(value_o) >= low) && (atol(value_o) <= high) ) {
+        return(atol(value_o));
+    }
+
+    if (!ret) {
+//        fprintf(stderr,"xastir.cnf: %s not found, inserting default: %ld\n",
+//            option,
+//            def);
+        return(def);
+    }
+
+    fprintf(stderr,
+        "xastir.cnf: %s out-of-range: %ld, changing to default: %ld\n",
+        option,
+        atol(value_o),
+        def);
+    return(def);
+}
+
+
+
+
+
+// Snags a float value and checks whether it is within the correct
+// range.  If not, it assigns a default value.  Returns the value.
+float get_float(char *option, float low, float high, float def) {
+    char value_o[MAX_VALUE];
+    int ret;
+
+    ret = get_string (option, value_o, sizeof(value_o));
+    if (ret && (strtof(value_o, NULL) >= low) && (strtof(value_o, NULL) <= high ) ) {
+        return(strtof(value_o, NULL));
+    }
+
+    if (!ret) {
+//        fprintf(stderr,"xastir.cnf: %s not found, inserting default: %f\n",
+//            option,
+//            def);
+        return(def);
+    }
+
+    fprintf(stderr,
+        "xastir.cnf: %s out-of-range: %f, changing to default: %f\n",
+        option,
+        strtof(value_o, NULL),
+        def);
+    return(def);
+}
+
+
+
+
+// Note on get_user_base_dir
+//
+// The original implementation of this function used a static char array
+// to do all the path construction, and returned a pointer to that array.
+// 
+// This function was changed in Sept 2012 to remove its original use
+// of a single static char array.  That version was highly unsafe in a 
+// threaded environment, and was used routinely in multiple threads.
+// Even inserting mutexes to prevent simultaneous writes by multiple threads
+// wasn't good enough, because once the mutex was released there was no
+// guarantee that one thread would not write into the static array while
+// another thread was reading it.  The result was that it was sometimes 
+// possible for paths to get corrupted, especially if multiple logging
+// options and png snapshots were simultaneously selected.
+//
+// Prior to the change, one called this as:
+// ptr = get_user_base_dir("pathfragment");
+// and ptr was always a pointer to the static char array.  Now 
+// the caller is responsible for passing in the array into which we'll 
+// write.  This way, threads should never be clobbering each other's paths
+// returned from this routine.
+// 
+char *get_user_base_dir(char *dir, char * base, size_t base_size) {
+    char *env_ptr;
+
+   // fprintf(stderr,"base: %s \nxa_config_dir: %s\n", base, xa_config_dir);
+
+    switch (xa_config_dir[0]) {
+    case '/':
+	//have some path
+        xastir_snprintf(base, base_size, "%s",xa_config_dir);
+        break; 
+
+    case '\0' : 
+        // build from scratch
+        xastir_snprintf(base,
+            base_size,
+            "%s",
+            ((env_ptr = getenv ("XASTIR_USER_BASE")) != NULL) ? env_ptr : user_dir);
+
+        if (base[strlen (base) - 1] != '/')
+            strncat (base, "/", base_size - 1 - strlen(base));
+
+        strncat (base, ".xastir/", base_size - 1 - strlen(base));
+        break ;
+
+    default: 
+        // Unqualified path
+        xastir_snprintf(base, base_size, "%s",
+            ((env_ptr = getenv ("PWD")) != NULL) ? env_ptr : user_dir);
+
+       	if (base[strlen (base) - 1] != '/')
+            strncat (base, "/", base_size - 1 - strlen(base));
+
+        strncat (base, xa_config_dir, base_size - 1 - strlen(base));
+    }
+    
+    if (base[strlen (base) - 1] != '/')
+        strncat (base, "/", base_size - 1 - strlen(base));
+
+    // Save base so we monkey around less later. 
+    
+    xastir_snprintf(xa_config_dir,sizeof(xa_config_dir),"%s", base);
+
+    // Append dir and return 
+    
+    return strncat(base, dir, base_size - 1 - strlen(base));
+
+}
+
+
+
+
+
+char *get_data_base_dir(char *dir) {
+    static char base[MAX_VALUE];
+    char *env_ptr;
+
+    // Snag this variable from the environment if it exists there,
+    // else grab it from the define from the compile command-line
+    // that should look like one of these:
+    //
+    // -DXASTIR_DATA_BASE=\"/opt/Xastir/share/xastir\"
+    // -DXASTIR_DATA_BASE=\"/usr/local/share/xastir\"
+    //
+    xastir_snprintf(base,
+        sizeof(base),
+        "%s",
+        ((env_ptr = getenv ("XASTIR_DATA_BASE")) != NULL) ? env_ptr : XASTIR_DATA_BASE);
+
+    if (base[strlen (base) - 1] != '/')
+        strncat(base, "/", sizeof(base) - 1 - strlen(base));
+
+    strncat(base, dir, sizeof(base) - 1 - strlen(base));
+    return base;
+}
+
+
+
+
+
+// Care should be taken here to make sure that no out-of-range data
+// is saved, as it will mess up Xastir startup from that point on.
+// Also: Config file should be owned by the user, and not by root.
+// If chmod 4755 is done on the executable, then the config file ends
+// up being owned by root from then on.
+//
+// Yea, I could have made this nicer by algorithmically figuring out
+// the backup filenames and rotating among .1 through .9.  Perhaps
+// next go-around!  Just having multiples is a big win, in case some
+// of them get blown away.
+//
+// Another step that needs to be made is to restore config settings
+// for the cases where Xastir comes up with a nonexistent or empty
+// xastir.cnf file.  If the backups exist, we should copy them
+// across.
+//
+void save_data(void)  {
+    int i;
+    char name_temp[20];
+    char name[50];
+    FILE * fout;
+    char config_file_tmp[MAX_VALUE];
+    char config_file[MAX_VALUE];
+    char config_file_bak1[MAX_VALUE];
+    char config_file_bak2[MAX_VALUE];
+    char config_file_bak3[MAX_VALUE];
+    char config_file_bak4[MAX_VALUE];
+    struct stat file_status;
+
+
+    // Force the locale to a default so that we don't have
+    // conversion problems due to LANG/LC_ALL/LC_CTYPE/LC_NUMERIC
+    // environment variables.
+    (void)setlocale(LC_NUMERIC, "C");
+    (void)setlocale(LC_CTYPE, "C");
+
+//    if (debug_level & 1)
+//        fprintf(stderr,"Store String Start\n");
+
+    // The new file we'll create
+    get_user_base_dir(CONFIG_FILE_TMP, config_file_tmp, 
+                      sizeof(config_file_tmp));
+
+    // Save to the new config file
+    fout = fopen (config_file_tmp, "a");
+    if (fout != NULL) {
+//        Position x_return;
+//        Position y_return;
+
+ 
+        if (debug_level & 1)
+            fprintf(stderr,"Save Data Start\n");
+
+        /* language */
+        store_string (fout, "LANGUAGE", lang_to_use);
+
+        /* my data */
+        store_string (fout, "STATION_CALLSIGN", my_callsign);
+
+        store_string (fout, "STATION_LAT", my_lat);
+        store_string (fout, "STATION_LONG", my_long);
+        store_char (fout, "STATION_GROUP", my_group);
+        store_char (fout, "STATION_SYMBOL", my_symbol);
+        store_char (fout, "STATION_MESSAGE_TYPE", aprs_station_message_type);
+        store_string (fout, "STATION_POWER", my_phg);
+        store_string (fout, "STATION_COMMENTS", my_comment);
+        store_int (fout, "MY_TRAIL_DIFF_COLOR", my_trail_diff_color);
+        if (debug_level & 1)
+            fprintf(stderr,"Save Data 1\n");
+
+        /* default values */
+        store_long (fout, "SCREEN_WIDTH", screen_width);
+        store_long (fout, "SCREEN_HEIGHT", screen_height);
+
+
+/*
+        // Get the X/Y offsets for the main window
+        XtVaGetValues(appshell,
+            XmNx, &x_return,
+            XmNy, &y_return,
+            NULL);
+
+fprintf(stderr,"X:%d  y:%d\n", (int)x_return, (int)y_return);
+        store_int (fout, "SCREEN_X_OFFSET", (int)x_return);
+        store_int (fout, "SCREEN_Y_OFFSET", (int)y_return);
+*/
+
+
+        store_long (fout, "SCREEN_LAT", center_latitude);
+        store_long (fout, "SCREEN_LONG", center_longitude);
+
+        store_string(fout, "RELAY_DIGIPEAT_CALLS", relay_digipeater_calls);
+
+        store_int (fout, "COORDINATE_SYSTEM", coordinate_system);
+
+        store_int (fout, "STATION_TRANSMIT_AMB", position_amb_chars);
+
+        if (scale_y > 0)
+            store_long (fout, "SCREEN_ZOOM", scale_y);
+        else
+            store_long (fout, "SCREEN_ZOOM", 1);
+
+        store_int (fout, "MAP_BGCOLOR", map_background_color);
+
+        store_int (fout, "MAP_DRAW_FILLED_COLORS", map_color_fill);
+
+#if !defined(NO_GRAPHICS)
+#if defined(HAVE_MAGICK)
+        store_float (fout, "IMAGEMAGICK_GAMMA_ADJUST", imagemagick_gamma_adjust);
+#endif  // HAVE_MAGICK
+        store_float(fout, "RASTER_MAP_INTENSITY", raster_map_intensity);
+#endif  // NO_GRAPHICS
+
+        store_string(fout, "PRINT_PROGRAM", printer_program);
+        store_string(fout, "PREVIEWER_PROGRAM", previewer_program);
+
+        store_int (fout, "MAP_LETTERSTYLE", letter_style);
+        store_int (fout, "MAP_ICONOUTLINESTYLE", icon_outline_style);
+        store_int (fout, "MAP_WX_ALERT_STYLE", wx_alert_style);
+        store_string(fout, "ALTNET_CALL", altnet_call);
+        store_int(fout, "ALTNET", altnet);
+        store_int(fout, "SKIP_DUPE_CHECK", skip_dupe_checking);
+        store_string (fout, "AUTO_MAP_DIR", AUTO_MAP_DIR);
+        store_string (fout, "ALERT_MAP_DIR", ALERT_MAP_DIR);
+        store_string (fout, "SELECTED_MAP_DIR", SELECTED_MAP_DIR);
+        store_string (fout, "SELECTED_MAP_DATA", SELECTED_MAP_DATA);
+        store_string (fout, "MAP_INDEX_DATA", MAP_INDEX_DATA);
+        store_string (fout, "SYMBOLS_DIR", SYMBOLS_DIR);
+        store_string (fout, "SOUND_DIR", SOUND_DIR);
+        store_string (fout, "GROUP_DATA_FILE", group_data_file);
+        store_string (fout, "GNIS_FILE", locate_gnis_filename);
+        store_string (fout, "GEOCODE_FILE", geocoder_map_filename);
+        store_int (fout, "SHOW_FIND_TARGET", show_destination_mark);
+
+        /* maps */
+        store_int (fout, "MAPS_LONG_LAT_GRID", long_lat_grid);
+        store_int (fout, "MAPS_LABELED_GRID_BORDER", draw_labeled_grid_border);
+        store_int (fout, "MAPS_LEVELS", map_color_levels);
+        store_int (fout, "MAPS_LABELS", map_labels);
+        store_int (fout, "MAP_LOCK_PAN_ZOOM", map_lock_pan_zoom);
+        store_int (fout, "MAPS_AUTO_MAPS", map_auto_maps);
+        store_int (fout, "MAPS_AUTO_MAPS_SKIP_RASTER", auto_maps_skip_raster);
+        store_int (fout, "MAPS_INDEX_ON_STARTUP", index_maps_on_startup);
+
+        store_string (fout, "MAPS_LABEL_FONT_TINY", rotated_label_fontname[FONT_TINY]);
+        store_string (fout, "MAPS_LABEL_FONT_SMALL", rotated_label_fontname[FONT_SMALL]);
+        store_string (fout, "MAPS_LABEL_FONT_MEDIUM", rotated_label_fontname[FONT_MEDIUM]);
+        // NOTE:  FONT_DEFAULT points to FONT_MEDIUM.
+        store_string (fout, "MAPS_LABEL_FONT_LARGE", rotated_label_fontname[FONT_LARGE]);
+        store_string (fout, "MAPS_LABEL_FONT_HUGE", rotated_label_fontname[FONT_HUGE]);
+        store_string (fout, "MAPS_LABEL_FONT_BORDER", rotated_label_fontname[FONT_BORDER]);
+        store_string (fout, "SYSTEM_FIXED_FONT", rotated_label_fontname[FONT_SYSTEM]);
+        store_string (fout, "STATION_FONT", rotated_label_fontname[FONT_STATION]);
+        store_string (fout, "ATV_ID_FONT", rotated_label_fontname[FONT_ATV_ID]);
+
+
+//N0VH
+#if defined(HAVE_MAGICK)
+        store_int (fout, "NET_MAP_TIMEOUT", net_map_timeout);
+        store_int (fout, "TIGERMAP_SHOW_GRID", tiger_show_grid);
+        store_int (fout, "TIGERMAP_SHOW_COUNTIES", tiger_show_counties);
+        store_int (fout, "TIGERMAP_SHOW_CITIES", tiger_show_cities);
+        store_int (fout, "TIGERMAP_SHOW_PLACES", tiger_show_places);
+        store_int (fout, "TIGERMAP_SHOW_MAJROADS", tiger_show_majroads);
+        store_int (fout, "TIGERMAP_SHOW_STREETS", tiger_show_streets);
+        store_int (fout, "TIGERMAP_SHOW_RAILROAD", tiger_show_railroad);
+        store_int (fout, "TIGERMAP_SHOW_STATES", tiger_show_states);
+        store_int (fout, "TIGERMAP_SHOW_INTERSTATE", tiger_show_interstate);
+        store_int (fout, "TIGERMAP_SHOW_USHWY", tiger_show_ushwy);
+        store_int (fout, "TIGERMAP_SHOW_STATEHWY", tiger_show_statehwy);
+        store_int (fout, "TIGERMAP_SHOW_WATER", tiger_show_water);
+        store_int (fout, "TIGERMAP_SHOW_LAKES", tiger_show_lakes);
+        store_int (fout, "TIGERMAP_SHOW_MISC", tiger_show_misc);
+#endif //HAVE_MAGICK
+
+#ifdef HAVE_LIBGEOTIFF
+        store_int (fout, "DRG_XOR_COLORS", DRG_XOR_colors);
+        store_int (fout, "DRG_SHOW_COLORS_0", DRG_show_colors[0]);
+        store_int (fout, "DRG_SHOW_COLORS_1", DRG_show_colors[1]);
+        store_int (fout, "DRG_SHOW_COLORS_2", DRG_show_colors[2]);
+        store_int (fout, "DRG_SHOW_COLORS_3", DRG_show_colors[3]);
+        store_int (fout, "DRG_SHOW_COLORS_4", DRG_show_colors[4]);
+        store_int (fout, "DRG_SHOW_COLORS_5", DRG_show_colors[5]);
+        store_int (fout, "DRG_SHOW_COLORS_6", DRG_show_colors[6]);
+        store_int (fout, "DRG_SHOW_COLORS_7", DRG_show_colors[7]);
+        store_int (fout, "DRG_SHOW_COLORS_8", DRG_show_colors[8]);
+        store_int (fout, "DRG_SHOW_COLORS_9", DRG_show_colors[9]);
+        store_int (fout, "DRG_SHOW_COLORS_10", DRG_show_colors[10]);
+        store_int (fout, "DRG_SHOW_COLORS_11", DRG_show_colors[11]);
+        store_int (fout, "DRG_SHOW_COLORS_12", DRG_show_colors[12]);
+#endif  // HAVE_LIBGEOTIFF
+
+        // filter values
+        // NOT SAVED: Select_.none
+        store_int (fout, "DISPLAY_MY_STATION",            Select_.mine);
+        store_int (fout, "DISPLAY_TNC_STATIONS",          Select_.tnc);
+        store_int (fout, "DISPLAY_TNC_DIRECT_STATIONS",   Select_.direct);
+        store_int (fout, "DISPLAY_TNC_VIADIGI_STATIONS",  Select_.via_digi);
+        store_int (fout, "DISPLAY_NET_STATIONS",          Select_.net);
+        store_int (fout, "DISPLAY_TACTICAL_STATIONS",     Select_.tactical);
+        store_int (fout, "DISPLAY_OLD_STATION_DATA",      Select_.old_data);
+        store_int (fout, "DISPLAY_STATIONS",              Select_.stations);
+        store_int (fout, "DISPLAY_FIXED_STATIONS",        Select_.fixed_stations);
+        store_int (fout, "DISPLAY_MOVING_STATIONS",       Select_.moving_stations);
+        store_int (fout, "DISPLAY_WEATHER_STATIONS",      Select_.weather_stations);
+        store_int (fout, "DISPLAY_CWOP_WX_STATIONS",      Select_.CWOP_wx_stations);
+        store_int (fout, "DISPLAY_OBJECTS",               Select_.objects);
+        store_int (fout, "DISPLAY_STATION_WX_OBJ",        Select_.weather_objects);
+        store_int (fout, "DISPLAY_WATER_GAGE_OBJ",        Select_.gauge_objects);
+        store_int (fout, "DISPLAY_OTHER_OBJECTS",         Select_.other_objects);
+
+        // display values
+        store_int (fout, "DISPLAY_CALLSIGN",              Display_.callsign);
+        store_int (fout, "DISPLAY_LABEL_ALL_TRACKPOINTS", Display_.label_all_trackpoints);
+        store_int (fout, "DISPLAY_SYMBOL",                Display_.symbol);
+        store_int (fout, "DISPLAY_SYMBOL_ROTATE",         Display_.symbol_rotate);
+        store_int (fout, "DISPLAY_STATION_PHG",           Display_.phg);
+        store_int (fout, "DISPLAY_DEFAULT_PHG",           Display_.default_phg);
+        store_int (fout, "DISPLAY_MOBILES_PHG",           Display_.phg_of_moving);
+        store_int (fout, "DISPLAY_ALTITUDE",              Display_.altitude);
+        store_int (fout, "DISPLAY_COURSE",                Display_.course);
+        store_int (fout, "DISPLAY_SPEED",                 Display_.speed);
+        store_int (fout, "DISPLAY_SPEED_SHORT",           Display_.speed_short);
+        store_int (fout, "DISPLAY_DIST_COURSE",           Display_.dist_bearing);
+        store_int (fout, "DISPLAY_WEATHER",               Display_.weather);
+        store_int (fout, "DISPLAY_STATION_WX",            Display_.weather_text);
+        store_int (fout, "DISPLAY_TEMP_ONLY",             Display_.temperature_only);
+        store_int (fout, "DISPLAY_WIND_BARB",             Display_.wind_barb);
+        store_int (fout, "DISPLAY_STATION_TRAILS",        Display_.trail);
+        store_int (fout, "DISPLAY_LAST_HEARD",            Display_.last_heard);
+        store_int (fout, "DISPLAY_POSITION_AMB",          Display_.ambiguity);
+        store_int (fout, "DISPLAY_DF_INFO",               Display_.df_data);
+        store_int (fout, "DISPLAY_DF_BEAMWIDTH_INFO",     Display_.df_beamwidth_data);
+        store_int (fout, "DISPLAY_DF_BEARING_INFO",               Display_.df_bearing_data);
+        store_int (fout, "DISPLAY_DEAD_RECKONING_INFO",   Display_.dr_data);
+        store_int (fout, "DISPLAY_DEAD_RECKONING_ARC",    Display_.dr_arc);
+        store_int (fout, "DISPLAY_DEAD_RECKONING_COURSE", Display_.dr_course);
+        store_int (fout, "DISPLAY_DEAD_RECKONING_SYMBOL", Display_.dr_symbol);
+
+
+        store_int (fout, "DISPLAY_UNITS_ENGLISH",         english_units);
+        store_int (fout, "DISPLAY_DIST_BEAR_STATUS",      do_dbstatus);
+
+
+        // CAD Objects
+        store_int (fout, "DISPLAY_CAD_OBJECT_LABEL",       CAD_show_label);
+        store_int (fout, "DISPLAY_CAD_OBJECT_PROBABILITY", CAD_show_raw_probability);
+        store_int (fout, "DISPLAY_CAD_OBJECT_COMMENT",     CAD_show_comment);
+        store_int (fout, "DISPLAY_CAD_OBJECT_AREA",        CAD_show_area);
+
+
+        // Interface values
+        store_int (fout, "DISABLE_TRANSMIT",   transmit_disable);
+        store_int (fout, "DISABLE_POSIT_TX",   posit_tx_disable);
+        store_int (fout, "DISABLE_OBJECT_TX",  object_tx_disable);
+        store_int (fout, "ENABLE_SERVER_PORT", enable_server_port);
+
+
+        for (i = 0; i < MAX_IFACE_DEVICES; i++) {
+            xastir_snprintf (name_temp, sizeof(name_temp), "DEVICE%0d_", i);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TYPE", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].device_type);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "NAME", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].device_name);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "RADIO_PORT", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].radio_port);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "CONVERSE_CMD", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].device_converse_string);
+
+
+#ifdef HAVE_DB
+            
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "DATABASE_TYPE", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].database_type);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "DATABASE_SCHEMA_TYPE", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].database_schema_type);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "DATABASE_USERNAME", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].database_username);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "DATABASE_SCHEMA", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].database_schema);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "DATABASE_UNIX_SOCKET", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].database_unix_socket);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "QUERY_ON_STARTUP", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].query_on_startup);
+
+#endif /* HAVE_DB */
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "INTERFACE_COMMENT", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].comment);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "HOST", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].device_host_name);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "PASSWD", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].device_host_pswd);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "FILTER_PARAMS", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].device_host_filter_string);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "UNPROTO1", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].unproto1);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "UNPROTO2", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].unproto2);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "UNPROTO3", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].unproto3);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "UNPROTO_IGATE", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].unproto_igate);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_UP_FILE", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].tnc_up_file);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_DOWN_FILE", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].tnc_down_file);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_TXDELAY", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].txdelay);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_PERSISTENCE", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].persistence);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_SLOTTIME", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].slottime);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_TXTAIL", sizeof(name) - 1 - strlen(name));
+            store_string (fout, name, devices[i].txtail);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_FULLDUPLEX", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].fullduplex);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNC_INIT_KISSMODE", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].init_kiss);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "SPEED", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].sp);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "STYLE", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].style);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "IGATE_OPTION", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].igate_options);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TXMT", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].transmit_data);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "RELAY_DIGIPEAT", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].relay_digipeat);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "RECONN", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].reconnect);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "ONSTARTUP", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].connect_on_startup);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat(name, "GPSRETR", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].gps_retrieve);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "SETTIME", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].set_time);
+
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "TNCEXTRADELAY", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, devices[i].tnc_extra_delay);
+ 
+        }
+        /* TNC */
+        store_int (fout, "TNC_LOG_DATA", log_tnc_data);
+        store_string (fout, "LOGFILE_TNC", LOGFILE_TNC);
+
+        /* NET */
+        store_int (fout, "NET_LOG_DATA", log_net_data);
+
+        store_int (fout, "NET_RUN_AS_IGATE", operate_as_an_igate);
+        store_int (fout, "NETWORK_WAITTIME", NETWORK_WAITTIME);
+
+        // LOGGING
+        store_int (fout, "LOG_IGATE", log_igate);
+        store_int (fout, "LOG_WX", log_wx);
+        store_int (fout, "LOG_MESSAGE", log_message_data);
+        store_int (fout, "LOG_WX_ALERT", log_wx_alert_data);
+        store_string (fout, "LOGFILE_IGATE", LOGFILE_IGATE);
+        store_string (fout, "LOGFILE_NET", LOGFILE_NET);
+        store_string (fout, "LOGFILE_WX", LOGFILE_WX);
+        store_string (fout, "LOGFILE_MESSAGE", LOGFILE_MESSAGE);
+        store_string (fout, "LOGFILE_WX_ALERT", LOGFILE_WX_ALERT);
+
+        // SNAPSHOTS
+        store_int (fout, "SNAPSHOTS_ENABLED", snapshots_enabled);
+
+        // KML SNAPSHOTS
+        store_int (fout, "KMLSNAPSHOTS_ENABLED", kmlsnapshots_enabled);
+
+        /* WX ALERTS */
+        store_long (fout, "WX_ALERTS_REFRESH_TIME", (long)WX_ALERTS_REFRESH_TIME);
+
+        /* GPS */
+        store_long (fout, "GPS_TIME", (long)gps_time);    /* still needed */
+
+        /* POSIT RATE */
+        store_long (fout, "POSIT_RATE", (long)POSIT_rate);
+
+        /* OBJECT RATE */
+        store_long (fout, "OBJECT_RATE", (long)OBJECT_rate);
+
+        /* UPDATE DR RATE */
+        store_long (fout, "UPDATE_DR_RATE", (long)update_DR_rate);
+
+        /* station broadcast type */
+        store_int (fout, "BST_TYPE", output_station_type);
+
+#ifdef TRANSMIT_RAW_WX
+        store_int (fout, "BST_WX_RAW", transmit_raw_wx);
+#endif  // TRANSMIT_RAW_WX
+
+        store_int (fout, "BST_COMPRESSED_POSIT", transmit_compressed_posit);
+
+        store_int (fout, "COMPRESSED_OBJECTS_ITEMS", transmit_compressed_objects_items);
+
+        store_int (fout, "SMART_BEACONING", smart_beaconing);
+        store_int (fout, "SB_TURN_MIN", sb_turn_min);
+        store_int (fout, "SB_TURN_SLOPE", sb_turn_slope);
+        store_int (fout, "SB_TURN_TIME", sb_turn_time);
+        store_int (fout, "SB_POSIT_FAST", sb_posit_fast);
+        store_int (fout, "SB_POSIT_SLOW", sb_posit_slow);
+        store_int (fout, "SB_LOW_SPEED_LIMIT", sb_low_speed_limit);
+        store_int (fout, "SB_HIGH_SPEED_LIMIT", sb_high_speed_limit);
+
+        store_int (fout, "POP_UP_NEW_BULLETINS", pop_up_new_bulletins);
+        store_int (fout, "VIEW_ZERO_DISTANCE_BULLETINS", view_zero_distance_bulletins);
+
+        store_int (fout, "WARN_ABOUT_MOUSE_MODIFIERS", warn_about_mouse_modifiers);
+
+        /* -dk7in- variable beacon interval */
+        /*         mobile:   max  2 min */
+        /*         fixed:    max 15 min  */
+        if ((output_station_type >= 1) && (output_station_type <= 3))
+            max_transmit_time = (time_t)120l;       /*  2 min @ mobile */
+        else
+            max_transmit_time = (time_t)900l;       /* 15 min @ fixed */
+
+        /* Audio Alarms */
+        store_string (fout, "SOUND_COMMAND", sound_command);
+
+        store_int (fout, "SOUND_PLAY_ONS", sound_play_new_station);
+        store_string (fout, "SOUND_ONS_FILE", sound_new_station);
+        store_int (fout, "SOUND_PLAY_ONM", sound_play_new_message);
+        store_string (fout, "SOUND_ONM_FILE", sound_new_message);
+
+        store_int (fout, "SOUND_PLAY_PROX", sound_play_prox_message);
+        store_string (fout, "SOUND_PROX_FILE", sound_prox_message);
+        store_string (fout, "PROX_MIN", prox_min);
+        store_string (fout, "PROX_MAX", prox_max);
+        store_int (fout, "SOUND_PLAY_BAND", sound_play_band_open_message);
+        store_string (fout, "SOUND_BAND_FILE", sound_band_open_message);
+        store_string (fout, "BANDO_MIN", bando_min);
+        store_string (fout, "BANDO_MAX", bando_max);
+        store_int (fout, "SOUND_PLAY_WX_ALERT", sound_play_wx_alert_message);
+        store_string (fout, "SOUND_WX_ALERT_FILE", sound_wx_alert_message);
+
+#ifdef HAVE_FESTIVAL
+            /* Festival speech settings */
+        store_int (fout, "SPEAK_NEW_STATION",festival_speak_new_station);
+        store_int (fout, "SPEAK_PROXIMITY_ALERT",festival_speak_proximity_alert);
+        store_int (fout, "SPEAK_TRACKED_ALERT",festival_speak_tracked_proximity_alert);
+        store_int (fout, "SPEAK_BAND_OPENING",festival_speak_band_opening);
+        store_int (fout, "SPEAK_MESSAGE_ALERT",festival_speak_new_message_alert);
+        store_int (fout, "SPEAK_MESSAGE_BODY",festival_speak_new_message_body);
+        store_int (fout, "SPEAK_WEATHER_ALERT",festival_speak_new_weather_alert);
+        store_int (fout, "SPEAK_ID",festival_speak_ID);
+#endif  // HAVE_FESTIVAL
+        store_int (fout, "ATV_SCREEN_ID", ATV_screen_ID);
+
+        /* defaults */
+        store_long (fout, "DEFAULT_STATION_OLD", (long)sec_old);
+
+        store_long (fout, "DEFAULT_STATION_CLEAR", (long)sec_clear);
+        store_long(fout, "DEFAULT_STATION_REMOVE", (long)sec_remove);
+        store_string (fout, "HELP_DATA", HELP_FILE);
+
+        store_string (fout, "MESSAGE_COUNTER", message_counter);
+
+        store_string (fout, "AUTO_MSG_REPLY", auto_reply_message);
+        store_int (fout, "DISPLAY_PACKET_TYPE", Display_packet_data_type);
+
+        store_int (fout, "BULLETIN_RANGE", bulletin_range);
+        store_int(fout,"VIEW_MESSAGE_RANGE",vm_range);
+        store_int(fout,"VIEW_MESSAGE_LIMIT",view_message_limit);
+        store_int(fout,"PREDEF_MENU_LOAD",predefined_menu_from_file);
+        store_string(fout,"PREDEF_MENU_FILE",predefined_object_definition_filename);
+
+        store_int(fout, "READ_MESSAGES_PACKET_DATA_TYPE", Read_messages_packet_data_type);
+        store_int(fout, "READ_MESSAGES_MINE_ONLY", Read_messages_mine_only);
+
+        /* printer variables */
+        store_int (fout, "PRINT_ROTATED", print_rotated);
+        store_int (fout, "PRINT_AUTO_ROTATION", print_auto_rotation);
+        store_int (fout, "PRINT_AUTO_SCALE", print_auto_scale);
+        store_int (fout, "PRINT_IN_MONOCHROME", print_in_monochrome);
+        store_int (fout, "PRINT_INVERT_COLORS", print_invert);
+
+        /* Rain Gauge Type, set in the Serial Weather interface
+            properties dialog, but really a global default */
+        store_int (fout, "RAIN_GAUGE_TYPE", WX_rain_gauge_type);
+
+
+        /* list attributes */
+        for (i = 0; i < LST_NUM; i++) {
+            xastir_snprintf (name_temp, sizeof(name_temp), "LIST%0d_", i);
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "H", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, list_size_h[i]);
+            xastir_snprintf(name,
+                sizeof(name),
+                "%s",
+                name_temp);
+            strncat (name, "W", sizeof(name) - 1 - strlen(name));
+            store_int (fout, name, list_size_w[i]);
+        }
+
+        store_int (fout, "TRACK_ME", track_me);
+        store_string (fout, "TRACKING_STATION_CALLSIGN", tracking_station_call);
+        store_int (fout, "MAP_CHOOSER_EXPAND_DIRS", map_chooser_expand_dirs);
+        store_int (fout, "ST_DIRECT_TIMEOUT", st_direct_timeout);
+        store_int (fout, "DEAD_RECKONING_TIMEOUT", dead_reckoning_timeout);
+        store_int (fout, "SERIAL_CHAR_PACING", serial_char_pacing);
+        store_int (fout, "TRAIL_SEGMENT_TIME", trail_segment_time);
+        store_int (fout, "TRAIL_SEGMENT_DISTANCE", trail_segment_distance);
+        store_int (fout, "RINO_DOWNLOAD_INTERVAL", RINO_download_interval);
+        store_int (fout, "SNAPSHOT_INTERVAL", snapshot_interval);
+
+
+        if (debug_level & 1)
+            fprintf(stderr,"Save Data Stop\n");
+
+        // Close the config_file_tmp file, we're done writing it.
+        (void)fclose (fout);
+
+
+        get_user_base_dir(CONFIG_FILE, config_file, sizeof(config_file));
+
+        get_user_base_dir(CONFIG_FILE_BAK1, config_file_bak1, 
+                          sizeof(config_file_bak1));
+
+        get_user_base_dir(CONFIG_FILE_BAK2, config_file_bak2, 
+                          sizeof(config_file_bak2));
+
+        get_user_base_dir(CONFIG_FILE_BAK3, config_file_bak3, 
+                          sizeof(config_file_bak3));
+ 
+        get_user_base_dir(CONFIG_FILE_BAK4,config_file_bak4, 
+                          sizeof(config_file_bak4));
+
+
+        //
+        // Rename the old config files so that we have a few
+        // backups in case of corruption:
+        //
+        //   xastir.cnf.3   -> xastir.cnf.4
+        //   xastir.cnf.2   -> xastir.cnf.3
+        //   xastir.cnf.1   -> xastir.cnf.2
+        //   xastir.cnf     -> xastir.cnf.1
+        //   xastir.cnf.tmp -> xastir.cnf
+        //
+
+        // Rename bak3 to bak4
+        // NOTE: bak3 won't exist until a few saves have happened.
+        //
+        // Check whether bak3 exists
+        if (stat(config_file_bak3, &file_status) == 0) {
+            if (!S_ISREG(file_status.st_mode)) {
+                fprintf(stderr,
+                    "Couldn't stat %s, cancelling save_data()\n",
+                    config_file_bak3);
+                return;
+            }
+            if ( rename (config_file_bak3, config_file_bak4) ) {
+                fprintf(stderr,
+                    "Couldn't rename %s to %s, cancelling save_data()\n",
+                    config_file_bak3,
+                    config_file_bak4);
+
+                // Attempt to restore to previous state
+                // Nothing to do here!
+                return;
+            }
+        }
+
+        // Rename bak2 to bak3
+        // NOTE: bak2 won't exist until a few saves have happened.
+        //
+        // Check whether bak2 exists
+        if (stat(config_file_bak2, &file_status) == 0) {
+            if (!S_ISREG(file_status.st_mode)) {
+                fprintf(stderr,
+                    "Couldn't stat %s, cancelling save_data()\n",
+                    config_file_bak2);
+                return;
+            }
+            if ( rename (config_file_bak2, config_file_bak3) ) {
+                fprintf(stderr,
+                    "Couldn't rename %s to %s, cancelling save_data()\n",
+                    config_file_bak2,
+                    config_file_bak3);
+
+                // Attempt to restore to previous state
+                rename (config_file_bak4, config_file_bak3);
+                // Nothing to do here!
+                return;
+            }
+        }
+
+        // Rename bak1 to bak2
+        // NOTE: bak1 won't exist until a couple of saves have happened.
+        //
+        // Check whether bak1 exists
+        if (stat(config_file_bak1, &file_status) == 0) {
+            if (!S_ISREG(file_status.st_mode)) {
+                fprintf(stderr,
+                    "Couldn't stat %s, cancelling save_data()\n",
+                    config_file_bak1);
+                return;
+            }
+            if ( rename (config_file_bak1, config_file_bak2) ) {
+                fprintf(stderr,
+                    "Couldn't rename %s to %s, cancelling save_data()\n",
+                    config_file_bak1,
+                    config_file_bak2);
+
+                // Attempt to restore to previous state
+                rename (config_file_bak3, config_file_bak2);
+                rename (config_file_bak4, config_file_bak3);
+                return;
+            }
+        }
+
+// NOTE:  To minimize the possibility that we'll end up with a
+// missing or corrupt config file, we actually should COPY
+// config_file to config_file_bak1 here so that there's always a
+// config file in place no matter what.  In the next block we can do
+// the rename of config_file_tmp to config_file and not miss a beat.
+// See "man 2 rename".
+
+        // Rename config to bak1
+        // NOTE: config won't exist until the first save happens.
+        //
+        // Check whether config exists
+        if (stat(config_file, &file_status) == 0) {
+            if (!S_ISREG(file_status.st_mode)) {
+                fprintf(stderr,
+                    "Couldn't stat %s, cancelling save_data()\n",
+                    config_file);
+                return;
+            }
+            //
+            // Note "copy_file()" instead of "rename()".  This
+            // assures that we always have a config file in place no
+            // matter what errors might occur.
+            //
+            if ( copy_file(config_file, config_file_bak1) ) {
+                fprintf(stderr,
+                    "Couldn't copy %s to %s, cancelling save_data()\n",
+                    config_file,
+                    config_file_bak1);
+
+                // Attempt to restore to previous state
+                rename (config_file_bak2, config_file_bak1);
+                rename (config_file_bak3, config_file_bak2);
+                rename (config_file_bak4, config_file_bak3);
+                return;
+            }
+        }
+
+        // Rename config.tmp to xastir.cnf
+        // NOTE: config won't exist until the first save happens.
+        //
+        // Check whether config.tmp exists
+        if (stat(config_file_tmp, &file_status) == 0) {
+            if (!S_ISREG(file_status.st_mode)) {
+                fprintf(stderr,
+                    "Couldn't stat %s, cancelling save_data()\n",
+                    config_file_tmp);
+                return;
+            }
+            if ( rename (config_file_tmp, config_file) ) {
+                fprintf(stderr,
+                    "Couldn't rename %s to %s, cancelling save_data()\n",
+                    config_file_tmp,
+                    config_file);
+
+                // Attempt to restore to previous state
+                rename (config_file_bak1, config_file);
+                rename (config_file_bak2, config_file_bak1);
+                rename (config_file_bak3, config_file_bak2);
+                rename (config_file_bak4, config_file_bak3);
+                return;
+            }
+        }
+    } else  {
+        // Couldn't create new config (out of filespace?).
+        fprintf(stderr,"Couldn't open config file for appending: %s\n", config_file);
+
+        // Back out the changes done to the config and backup files.
+        // 
+        // Continue using original config file.
+        if ( rename (config_file_bak1, config_file) ) {
+            // Problem here, couldn't rename bak1 file to xastir.cnf
+            fprintf(stderr,
+                "Couldn't recover %s from %s file\n",
+                config_file,
+                config_file_bak1);
+            return;
+        }
+    }
+}
+
+
+
+
+
+void load_data_or_default(void) {
+    int i;
+    char name_temp[20];
+    char name[50];
+    long temp;
+    char user_base_dir[MAX_VALUE];
+
+    // Force the locale to a default so that we don't have
+    // conversion problems due to LANG/LC_ALL/LC_CTYPE/LC_NUMERIC
+    // environment variables.
+    (void)setlocale(LC_NUMERIC, "C");
+    (void)setlocale(LC_CTYPE, "C");
+    
+    /* language */
+    if (!get_string ("LANGUAGE", lang_to_use, sizeof(lang_to_use))
+            || lang_to_use[0] == '\0') {
+        xastir_snprintf(lang_to_use,
+            sizeof(lang_to_use),
+            "English");
+    }
+
+    /* my data */
+    if (!get_string ("STATION_CALLSIGN", my_callsign, sizeof(my_callsign))
+            || my_callsign[0] == '\0') {
+        xastir_snprintf(my_callsign,
+            sizeof(my_callsign),
+            "NOCALL");
+    }
+
+    if (!get_string ("STATION_LAT", my_lat, sizeof(my_lat))
+            || my_lat[0] == '\0') {
+        xastir_snprintf(my_lat,
+            sizeof(my_lat),
+            "0000.000N");
+    }
+    if ( (my_lat[4] != '.')
+            || (my_lat[8] != 'N' && my_lat[8] != 'S') ) {
+        xastir_snprintf(my_lat,
+            sizeof(my_lat),
+            "0000.000N");
+        fprintf(stderr,"Invalid Latitude, changing it to 0000.000N\n");
+    }
+    // convert old data to high prec
+    temp = convert_lat_s2l (my_lat);
+    convert_lat_l2s (temp, my_lat, sizeof(my_lat), CONVERT_HP_NOSP);
+
+
+    if (!get_string ("STATION_LONG", my_long, sizeof(my_long))
+            || my_long[0] == '\0') {
+        xastir_snprintf(my_long,
+            sizeof(my_long),
+            "00000.000W");
+    }
+    if ( (my_long[5] != '.')
+            || (my_long[9] != 'W' && my_long[9] != 'E') ) {
+        xastir_snprintf(my_long,
+            sizeof(my_long),
+            "00000.000W");
+        fprintf(stderr,"Invalid Longitude, changing it to 00000.000W\n");
+    }
+    // convert old data to high prec
+    temp = convert_lon_s2l (my_long);
+    convert_lon_l2s (temp, my_long, sizeof(my_long), CONVERT_HP_NOSP);
+
+
+    position_amb_chars = get_int ("STATION_TRANSMIT_AMB", 0, 4, 0);
+
+    if (!get_char ("STATION_GROUP", &my_group))
+        my_group = '/';
+
+    if (!get_char ("STATION_SYMBOL", &my_symbol))
+        my_symbol = 'x';
+
+    if (!get_char ("STATION_MESSAGE_TYPE", &aprs_station_message_type))
+        aprs_station_message_type = '=';
+
+    // Empty string is ok here.
+    if (!get_string ("STATION_POWER", my_phg, sizeof(my_phg)))
+        my_phg[0] = '\0';
+
+    if (!get_string ("STATION_COMMENTS", my_comment, sizeof(my_comment))
+            || my_comment[0] == '\0') {
+        xastir_snprintf (my_comment, sizeof(my_comment), "XASTIR-%s", XASTIR_SYSTEM);
+    }
+    /* replacing defined MY_TRAIL_DIFF_COLOR from db.c, default 0 matches 
+       default value of MY_TRAIL_DIFF_COLOR to show all mycall-ssids in 
+       the same color.  */
+    my_trail_diff_color = get_int ("MY_TRAIL_DIFF_COLOR", 0, 1, 0);
+
+    /* default values */
+    screen_width = get_long ("SCREEN_WIDTH", 61l, 10000l, 590l);
+    screen_height = get_long ("SCREEN_HEIGHT", 1l, 10000l, 420l);
+
+//    screen_x_offset = (Position)get_int ("SCREEN_X_OFFSET", 0, 10000, 0);
+//    screen_y_offset = (Position)get_int ("SCREEN_Y_OFFSET", 0, 10000, 0);
+
+
+    center_latitude = get_long ("SCREEN_LAT", 0l, 64800000l, 32400000l);
+    center_longitude = get_long ("SCREEN_LONG", 0l, 129600000l, 64800000l);
+
+    // Empty string is ok here
+    if (!get_string("RELAY_DIGIPEAT_CALLS", relay_digipeater_calls, sizeof(relay_digipeater_calls)))
+        xastir_snprintf (relay_digipeater_calls, sizeof(relay_digipeater_calls), "WIDE1-1");
+    // Make them all upper-case.
+    (void)to_upper(relay_digipeater_calls);
+    // And take out all spaces
+    (void)remove_all_spaces(relay_digipeater_calls);
+
+    coordinate_system = get_int ("COORDINATE_SYSTEM", 0, 5, USE_DDMMMM);
+
+    scale_y = get_long ("SCREEN_ZOOM", 1l, 500000l, 327680l);
+
+    scale_x = get_x_scale(center_longitude,center_latitude,scale_y);
+
+    map_background_color = get_int ("MAP_BGCOLOR", 0, 11, 0);
+
+    map_color_fill = get_int ( "MAP_DRAW_FILLED_COLORS", 0, 1, 1);
+
+#if !defined(NO_GRAPHICS)
+#if defined(HAVE_MAGICK)
+    imagemagick_gamma_adjust = get_float("IMAGEMAGICK_GAMMA_ADJUST", 0.0, 1.0, 0.0);
+#endif  // HAVE_MAGICK
+    raster_map_intensity = get_float("RASTER_MAP_INTENSITY", 0.0, 1.0, 1.0);
+#endif  // NO_GRAPHICS
+
+    if (!get_string ("PRINT_PROGRAM", printer_program, sizeof(printer_program))
+            || printer_program[0] == '\0') {
+        xastir_snprintf(printer_program,
+            sizeof(printer_program),
+            "%s",
+#ifdef LPR_PATH
+            // Path to LPR if defined
+            LPR_PATH
+#else // LPR_PATH
+            // Empty path
+            ""
+#endif // LPR_PATH
+            );
+    }
+    if (!get_string ("PREVIEWER_PROGRAM", previewer_program, sizeof(previewer_program))
+            || previewer_program[0] == '\0') {
+        xastir_snprintf(previewer_program,
+            sizeof(previewer_program),
+            "%s",
+#ifdef GV_PATH
+            // Path to GV if defined
+            GV_PATH
+#else // GV_PATH
+            // Empty path
+            ""
+#endif // GV_PATH
+            );
+    }
+
+    letter_style = get_int ("MAP_LETTERSTYLE", 0, 2, 1);
+
+    icon_outline_style = get_int ("MAP_ICONOUTLINESTYLE", 0, 3, 0);
+
+    wx_alert_style = get_int ("MAP_WX_ALERT_STYLE", 0, 1, 0);
+
+    // Empty string is ok here
+    if (!get_string("ALTNET_CALL", altnet_call, sizeof(altnet_call)))
+        xastir_snprintf(altnet_call,
+            sizeof(altnet_call),
+            "XASTIR");
+
+    altnet = get_int("ALTNET", 0, 1, 0);
+
+    skip_dupe_checking = get_int("SKIP_DUPE_CHECK", 0, 1, 0);
+
+    if (!get_string ("AUTO_MAP_DIR", AUTO_MAP_DIR, sizeof(AUTO_MAP_DIR))
+            || AUTO_MAP_DIR[0] == '\0') {
+        xastir_snprintf(AUTO_MAP_DIR,
+            sizeof(AUTO_MAP_DIR),
+            "%s",
+            get_data_base_dir ("maps"));
+    }
+
+    if (!get_string ("ALERT_MAP_DIR", ALERT_MAP_DIR, sizeof(ALERT_MAP_DIR))
+            || ALERT_MAP_DIR[0] == '\0') {
+        xastir_snprintf(ALERT_MAP_DIR,
+            sizeof(ALERT_MAP_DIR),
+            "%s",
+            get_data_base_dir ("Counties"));
+    }
+
+    if (!get_string ("SELECTED_MAP_DIR", SELECTED_MAP_DIR, sizeof(SELECTED_MAP_DIR))
+            || SELECTED_MAP_DIR[0] == '\0') {
+        xastir_snprintf(SELECTED_MAP_DIR,
+            sizeof(SELECTED_MAP_DIR),
+            "%s",
+            get_data_base_dir ("maps"));
+    }
+
+    if (!get_string ("SELECTED_MAP_DATA", SELECTED_MAP_DATA, sizeof(SELECTED_MAP_DATA))
+            || SELECTED_MAP_DATA[0] == '\0') {
+        xastir_snprintf(SELECTED_MAP_DATA,
+            sizeof(SELECTED_MAP_DATA),
+            "%s",
+            "config/selected_maps.sys");
+    }
+    
+    // get the base path for the user base directory, so we can use it over
+    // and over without having to call get_user_base_dir a godzillion times.
+    get_user_base_dir("",user_base_dir, sizeof(user_base_dir));
+
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, SELECTED_MAP_DATA, strlen(user_base_dir)) == 0)
+         xastir_snprintf(SELECTED_MAP_DATA,
+            sizeof(SELECTED_MAP_DATA),
+            "%s",
+            "config/selected_maps.sys");
+
+    if (!get_string ("MAP_INDEX_DATA", MAP_INDEX_DATA, sizeof(MAP_INDEX_DATA))
+            || MAP_INDEX_DATA[0] == '\0') {
+        xastir_snprintf(MAP_INDEX_DATA,
+            sizeof(MAP_INDEX_DATA),
+            "%s",
+            "config/map_index.sys");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, MAP_INDEX_DATA, strlen(user_base_dir)) == 0)
+        xastir_snprintf(MAP_INDEX_DATA,
+            sizeof(MAP_INDEX_DATA),
+            "%s",
+            "config/map_index.sys");
+ 
+    if (!get_string ("SYMBOLS_DIR", SYMBOLS_DIR, sizeof(SYMBOLS_DIR))
+            || SYMBOLS_DIR[0] == '\0') {
+        xastir_snprintf(SYMBOLS_DIR,
+            sizeof(SYMBOLS_DIR),
+            "%s",
+            get_data_base_dir ("symbols"));
+    }
+
+    if (!get_string ("SOUND_DIR", SOUND_DIR, sizeof(SOUND_DIR))
+            || SOUND_DIR[0] == '\0') {
+        xastir_snprintf(SOUND_DIR,
+            sizeof(SOUND_DIR),
+            "%s",
+            get_data_base_dir ("sounds"));
+    }
+
+    if (!get_string ("GROUP_DATA_FILE", group_data_file, sizeof(group_data_file))
+            || group_data_file[0] == '\0') {
+        xastir_snprintf(group_data_file,
+            sizeof(group_data_file),
+            "%s",
+            "config/groups");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, group_data_file, strlen(user_base_dir)) == 0)
+        xastir_snprintf(group_data_file,
+             sizeof(group_data_file),
+            "%s",
+            "config/groups");
+
+    if (!get_string ("GNIS_FILE", locate_gnis_filename, sizeof(locate_gnis_filename))
+            || locate_gnis_filename[0] == '\0') {
+        xastir_snprintf(locate_gnis_filename,
+            sizeof(locate_gnis_filename),
+            "%s",
+            get_data_base_dir ("GNIS/WA.gnis"));
+    }
+
+    if (!get_string ("GEOCODE_FILE", geocoder_map_filename, sizeof(geocoder_map_filename))
+            || geocoder_map_filename[0] == '\0') {
+        xastir_snprintf(geocoder_map_filename,
+            sizeof(geocoder_map_filename),
+            "%s",
+            get_data_base_dir ("GNIS/geocode"));
+    }
+
+    show_destination_mark = get_int ("SHOW_FIND_TARGET", 0, 1, 1);
+
+    /* maps */
+    long_lat_grid = get_int ("MAPS_LONG_LAT_GRID", 0, 1, 1);
+
+    draw_labeled_grid_border = get_int ("MAPS_LABELED_GRID_BORDER", 0, 1, 0);
+
+    map_color_levels = get_int ("MAPS_LEVELS", 0, 1, 1);
+
+    map_labels = get_int ("MAPS_LABELS", 0, 1, 1);
+
+    map_lock_pan_zoom = get_int ("MAP_LOCK_PAN_ZOOM", 0, 1, 0);
+
+    map_auto_maps = get_int ("MAPS_AUTO_MAPS", 0, 1, 0);
+
+    auto_maps_skip_raster = get_int ("MAPS_AUTO_MAPS_SKIP_RASTER", 0, 1, 0);
+
+    index_maps_on_startup = get_int ("MAPS_INDEX_ON_STARTUP", 0, 1, 1);
+
+    if (!get_string ("MAPS_LABEL_FONT_TINY", rotated_label_fontname[FONT_TINY], sizeof(rotated_label_fontname[FONT_TINY]))
+            || rotated_label_fontname[FONT_TINY][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_TINY],
+            sizeof(rotated_label_fontname[FONT_TINY]),
+            "-adobe-helvetica-medium-r-normal--8-*-*-*-*-*-iso8859-1");
+    }
+
+    if (!get_string ("MAPS_LABEL_FONT_SMALL", rotated_label_fontname[FONT_SMALL], sizeof(rotated_label_fontname[FONT_SMALL]))
+            || rotated_label_fontname[FONT_SMALL][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_SMALL],
+            sizeof(rotated_label_fontname[FONT_SMALL]),
+            "-adobe-helvetica-medium-r-normal--10-*-*-*-*-*-iso8859-1");
+    }
+
+    if (!get_string ("MAPS_LABEL_FONT_MEDIUM", rotated_label_fontname[FONT_MEDIUM], sizeof(rotated_label_fontname[FONT_MEDIUM]))
+            || rotated_label_fontname[FONT_MEDIUM][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_MEDIUM],
+            sizeof(rotated_label_fontname[FONT_MEDIUM]),
+            "-adobe-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1");
+    }
+    // NOTE:  FONT_DEFAULT points to FONT_MEDIUM
+
+    if (!get_string ("MAPS_LABEL_FONT_LARGE", rotated_label_fontname[FONT_LARGE], sizeof(rotated_label_fontname[FONT_LARGE]))
+            || rotated_label_fontname[FONT_LARGE][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_LARGE],
+            sizeof(rotated_label_fontname[FONT_LARGE]),
+            "-adobe-helvetica-medium-r-normal--14-*-*-*-*-*-iso8859-1");
+    }
+
+    if (!get_string ("MAPS_LABEL_FONT_HUGE", rotated_label_fontname[FONT_HUGE], sizeof(rotated_label_fontname[FONT_HUGE]))
+            || rotated_label_fontname[FONT_HUGE][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_HUGE],
+            sizeof(rotated_label_fontname[FONT_HUGE]),
+            "-adobe-helvetica-medium-r-normal--24-*-*-*-*-*-iso8859-1");
+    }
+    
+    if (!get_string ("MAPS_LABEL_FONT_BORDER", rotated_label_fontname[FONT_BORDER], sizeof(rotated_label_fontname[FONT_BORDER]))
+            || rotated_label_fontname[FONT_BORDER][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_BORDER],
+            sizeof(rotated_label_fontname[FONT_BORDER]),
+            "-adobe-helvetica-medium-r-normal--14-*-*-*-*-*-iso8859-1");
+    }
+
+    if (!get_string ("SYSTEM_FIXED_FONT", rotated_label_fontname[FONT_SYSTEM], sizeof(rotated_label_fontname[FONT_SYSTEM]))
+            || rotated_label_fontname[FONT_SYSTEM][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_SYSTEM],
+            sizeof(rotated_label_fontname[FONT_SYSTEM]),
+            "fixed");
+            // NOTE:  This same default font is hard-coded into
+            // main.c, to be used for the case when the user enters
+            // an invalid font (so the program won't crash).
+    }
+
+    if (!get_string ("STATION_FONT", rotated_label_fontname[FONT_STATION], sizeof(rotated_label_fontname[FONT_STATION]))
+            || rotated_label_fontname[FONT_STATION][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_STATION],
+            sizeof(rotated_label_fontname[FONT_STATION]),
+            "fixed");
+            // NOTE:  This same default font is hard-coded into
+            // main.c, to be used for the case when the user enters
+            // an invalid font (so the program won't crash).
+    }
+
+    if (!get_string ("ATV_ID_FONT", rotated_label_fontname[FONT_ATV_ID], sizeof(rotated_label_fontname[FONT_ATV_ID]))
+            || rotated_label_fontname[FONT_ATV_ID][0] == '\0') {
+        xastir_snprintf(rotated_label_fontname[FONT_ATV_ID],
+            sizeof(rotated_label_fontname[FONT_ATV_ID]),
+            "-*-helvetica-*-*-*-*-*-240-*-*-*-*-*-*");
+    }
+
+
+//N0VH
+#if defined(HAVE_MAGICK)
+    net_map_timeout = get_int ("NET_MAP_TIMEOUT", 10, 300, 120);
+
+    tiger_show_grid = get_int ("TIGERMAP_SHOW_GRID", 0, 1, 0);
+    tiger_show_counties = get_int ("TIGERMAP_SHOW_COUNTIES", 0, 1, 1);
+    tiger_show_cities = get_int ("TIGERMAP_SHOW_CITIES", 0, 1, 1);
+    tiger_show_places = get_int ("TIGERMAP_SHOW_PLACES", 0, 1, 1);
+    tiger_show_majroads = get_int ("TIGERMAP_SHOW_MAJROADS", 0, 1, 1);
+    tiger_show_streets = get_int ("TIGERMAP_SHOW_STREETS", 0, 1, 0);
+    tiger_show_railroad = get_int ("TIGERMAP_SHOW_RAILROAD", 0, 1, 1);
+    tiger_show_states = get_int ("TIGERMAP_SHOW_STATES", 0, 1, 0);
+    tiger_show_interstate = get_int ("TIGERMAP_SHOW_INTERSTATE", 0, 1, 1);
+    tiger_show_ushwy = get_int ("TIGERMAP_SHOW_USHWY", 0, 1, 1);
+    tiger_show_statehwy = get_int ("TIGERMAP_SHOW_STATEHWY", 0, 1, 1);
+    tiger_show_water = get_int ("TIGERMAP_SHOW_WATER", 0, 1, 1);
+    tiger_show_lakes = get_int ("TIGERMAP_SHOW_LAKES", 0, 1, 1);
+    tiger_show_misc = get_int ("TIGERMAP_SHOW_MISC", 0, 1, 1);
+#endif //HAVE_MAGICK
+
+#ifdef HAVE_LIBGEOTIFF
+    DRG_XOR_colors = get_int ("DRG_XOR_COLORS", 0, 1, 0);
+    DRG_show_colors[0] = get_int ("DRG_SHOW_COLORS_0", 0, 1, 1);
+    DRG_show_colors[1] = get_int ("DRG_SHOW_COLORS_1", 0, 1, 1);
+    DRG_show_colors[2] = get_int ("DRG_SHOW_COLORS_2", 0, 1, 1);
+    DRG_show_colors[3] = get_int ("DRG_SHOW_COLORS_3", 0, 1, 1);
+    DRG_show_colors[4] = get_int ("DRG_SHOW_COLORS_4", 0, 1, 1);
+    DRG_show_colors[5] = get_int ("DRG_SHOW_COLORS_5", 0, 1, 1);
+    DRG_show_colors[6] = get_int ("DRG_SHOW_COLORS_6", 0, 1, 1);
+    DRG_show_colors[7] = get_int ("DRG_SHOW_COLORS_7", 0, 1, 1);
+    DRG_show_colors[8] = get_int ("DRG_SHOW_COLORS_8", 0, 1, 1);
+    DRG_show_colors[9] = get_int ("DRG_SHOW_COLORS_9", 0, 1, 1);
+    DRG_show_colors[10] = get_int ("DRG_SHOW_COLORS_10", 0, 1, 1);
+    DRG_show_colors[11] = get_int ("DRG_SHOW_COLORS_11", 0, 1, 1);
+    DRG_show_colors[12] = get_int ("DRG_SHOW_COLORS_12", 0, 1, 1);
+#endif  // HAVE_LIBGEOTIFF
+
+    // filter values
+    // NOT SAVED: Select_.none
+    Select_.mine = get_int ("DISPLAY_MY_STATION", 0, 1, 1);
+    Select_.tnc = get_int ("DISPLAY_TNC_STATIONS", 0, 1, 1);
+    Select_.direct = get_int ("DISPLAY_TNC_DIRECT_STATIONS", 0, 1, 1);
+    Select_.via_digi = get_int ("DISPLAY_TNC_VIADIGI_STATIONS", 0, 1, 1);
+    Select_.net = get_int ("DISPLAY_NET_STATIONS", 0, 1, 1);
+    Select_.tactical = get_int ("DISPLAY_TACTICAL_STATIONS", 0, 1, 0);
+    Select_.old_data = get_int ("DISPLAY_OLD_STATION_DATA", 0, 1, 0);
+    Select_.stations = get_int ("DISPLAY_STATIONS", 0, 1, 1);
+    Select_.fixed_stations = get_int ("DISPLAY_FIXED_STATIONS", 0, 1, 1);
+    Select_.moving_stations = get_int ("DISPLAY_MOVING_STATIONS", 0, 1, 1);
+    Select_.weather_stations = get_int ("DISPLAY_WEATHER_STATIONS", 0, 1, 1);
+    Select_.CWOP_wx_stations = get_int ("DISPLAY_CWOP_WX_STATIONS", 0, 1, 1);
+    Select_.objects = get_int ("DISPLAY_OBJECTS", 0, 1, 1);
+    Select_.weather_objects = get_int ("DISPLAY_STATION_WX_OBJ", 0, 1, 1);
+    Select_.gauge_objects = get_int ("DISPLAY_WATER_GAGE_OBJ", 0, 1, 1);
+    Select_.other_objects = get_int ("DISPLAY_OTHER_OBJECTS", 0, 1, 1);
+
+    // display values
+    Display_.callsign = get_int ("DISPLAY_CALLSIGN", 0, 1, 1);
+    Display_.label_all_trackpoints = get_int ("DISPLAY_LABEL_ALL_TRACKPOINTS", 0, 1, 0);
+    Display_.symbol = get_int ("DISPLAY_SYMBOL", 0, 1, 1);
+    Display_.symbol_rotate = get_int ("DISPLAY_SYMBOL_ROTATE", 0, 1, 1);
+    Display_.phg = get_int ("DISPLAY_STATION_PHG", 0, 1, 0);
+    Display_.default_phg = get_int ("DISPLAY_DEFAULT_PHG", 0, 1, 0);
+    Display_.phg_of_moving = get_int ("DISPLAY_MOBILES_PHG", 0, 1, 0);
+    Display_.altitude = get_int ("DISPLAY_ALTITUDE", 0, 1, 0);
+    Display_.course = get_int ("DISPLAY_COURSE", 0, 1, 0);
+    Display_.speed = get_int ("DISPLAY_SPEED", 0, 1, 1);
+    Display_.speed_short = get_int ("DISPLAY_SPEED_SHORT", 0, 1, 0);
+    Display_.dist_bearing = get_int ("DISPLAY_DIST_COURSE", 0, 1, 0);
+    Display_.weather = get_int ("DISPLAY_WEATHER", 0, 1, 1);
+    Display_.weather_text = get_int ("DISPLAY_STATION_WX", 0, 1, 1);
+    Display_.temperature_only = get_int ("DISPLAY_TEMP_ONLY", 0, 1, 0);
+    Display_.wind_barb = get_int ("DISPLAY_WIND_BARB", 0, 1, 1);
+    Display_.trail = get_int ("DISPLAY_STATION_TRAILS", 0, 1, 1);
+    Display_.last_heard = get_int ("DISPLAY_LAST_HEARD", 0, 1, 0);
+    Display_.ambiguity = get_int ("DISPLAY_POSITION_AMB", 0, 1, 1);
+    Display_.df_data = get_int ("DISPLAY_DF_INFO", 0, 1, 1);
+    Display_.df_beamwidth_data = get_int ("DISPLAY_DF_BEAMWIDTH_INFO", 0, 1, 1);
+    Display_.df_bearing_data = get_int ("DISPLAY_DF_BEARING_INFO", 0, 1, 0);
+    Display_.dr_data = get_int ("DISPLAY_DEAD_RECKONING_INFO", 0, 1, 1);
+    Display_.dr_arc = get_int ("DISPLAY_DEAD_RECKONING_ARC", 0, 1, 1);
+    Display_.dr_course = get_int ("DISPLAY_DEAD_RECKONING_COURSE", 0, 1, 1);
+    Display_.dr_symbol = get_int ("DISPLAY_DEAD_RECKONING_SYMBOL", 0, 1, 1);
+
+
+
+    english_units = get_int ("DISPLAY_UNITS_ENGLISH", 0, 1, 0);
+    do_dbstatus = get_int ("DISPLAY_DIST_BEAR_STATUS", 0, 1, 0);
+
+
+    CAD_show_label = get_int ("DISPLAY_CAD_OBJECT_LABEL", 0, 1, 1);
+    CAD_show_raw_probability = get_int ("DISPLAY_CAD_OBJECT_PROBABILITY", 0, 1, 1 );
+    CAD_show_comment = get_int ("DISPLAY_CAD_OBJECT_COMMENT", 0, 1, 1 );
+    CAD_show_area = get_int ("DISPLAY_CAD_OBJECT_AREA", 0, 1, 1 );
+
+
+    transmit_disable = get_int ("DISABLE_TRANSMIT", 0, 1, 0);
+    posit_tx_disable = get_int ("DISABLE_POSIT_TX", 0, 1, 0);
+    object_tx_disable = get_int ("DISABLE_OBJECT_TX", 0, 1, 0);
+    enable_server_port = get_int ("ENABLE_SERVER_PORT", 0, 1, 0);
+
+
+    for (i = 0; i < MAX_IFACE_DEVICES; i++) {
+        xastir_snprintf (name_temp, sizeof(name_temp), "DEVICE%0d_", i);
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TYPE", sizeof(name) - 1 - strlen(name));
+        devices[i].device_type = get_int (name, 0,MAX_IFACE_DEVICE_TYPES,DEVICE_NONE);
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "NAME", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].device_name, sizeof(devices[i].device_name)))
+            devices[i].device_name[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "RADIO_PORT", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].radio_port, sizeof(devices[i].radio_port)))
+            xastir_snprintf(devices[i].radio_port,
+                sizeof(devices[i].radio_port),
+                "0");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "CONVERSE_CMD", sizeof(name) - 1 - strlen(name));
+        if (!get_string (name, devices[i].device_converse_string, sizeof(devices[i].device_converse_string))
+                || (strlen(devices[i].device_converse_string) == 0))
+            xastir_snprintf(devices[i].device_converse_string,
+                sizeof(devices[i].device_converse_string),
+                "k");
+
+
+#ifdef HAVE_DB        
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "DATABASE_TYPE", sizeof(name) - 1 - strlen(name));
+        
+        devices[i].database_type = get_int (name, 0,MAX_DB_TYPE,MAX_DB_TYPE);
+        
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "DATABASE_SCHEMA_TYPE", sizeof(name) - 1 - strlen(name));
+        devices[i].database_schema_type = get_int (name, 0,MAX_XASTIR_SCHEMA,XASTIR_SCHEMA_SIMPLE);
+        
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "DATABASE_USERNAME", sizeof(name) - 1 - strlen(name));
+        // default to xastir
+        if (!get_string (name, devices[i].database_username, sizeof(devices[i].database_username)))
+            xastir_snprintf(devices[i].database_username,
+                sizeof(devices[i].database_username),
+                "xastir");
+        
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "DATABASE_SCHEMA", sizeof(name) - 1 - strlen(name));
+        // default to xastir
+        if (!get_string (name, devices[i].database_schema, sizeof(devices[i].database_schema)))
+            xastir_snprintf(devices[i].database_schema,
+                sizeof(devices[i].database_schema),
+                "xastir");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "DATABASE_UNIX_SOCKET", sizeof(name) - 1 - strlen(name));
+        // empty string is ok here
+        if (!get_string (name, devices[i].database_unix_socket, sizeof(devices[i].database_unix_socket)))
+            xastir_snprintf(devices[i].database_unix_socket,
+                sizeof(devices[i].database_unix_socket),
+                "0");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "QUERY_ON_STARTUP", sizeof(name) - 1 - strlen(name));
+        devices[i].query_on_startup = get_int (name, 0,1,0);
+
+#endif /* HAVE_DB */
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "INTERFACE_COMMENT", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].comment, sizeof(devices[i].comment)))
+            devices[i].comment[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "HOST", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].device_host_name, sizeof(devices[i].device_host_name)))
+            devices[i].device_host_name[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "PASSWD", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].device_host_pswd, sizeof(devices[i].device_host_pswd)))
+            devices[i].device_host_pswd[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "FILTER_PARAMS", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].device_host_filter_string, sizeof(devices[i].device_host_filter_string)))
+            devices[i].device_host_filter_string[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "UNPROTO1", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].unproto1, sizeof(devices[i].unproto1)))
+            devices[i].unproto1[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "UNPROTO2", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].unproto2, sizeof(devices[i].unproto2)))
+            devices[i].unproto2[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "UNPROTO3", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].unproto3, sizeof(devices[i].unproto3)))
+            devices[i].unproto3[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "UNPROTO_IGATE", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].unproto_igate, sizeof(devices[i].unproto_igate))
+                || devices[i].unproto_igate[0] == '\0') {
+            xastir_snprintf(devices[i].unproto_igate, sizeof(devices[i].unproto_igate), "WIDE2-1");
+        }
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_UP_FILE", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].tnc_up_file, sizeof(devices[i].tnc_up_file)))
+            devices[i].tnc_up_file[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_DOWN_FILE", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].tnc_down_file, sizeof(devices[i].tnc_down_file)))
+            devices[i].tnc_down_file[0] = '\0';
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_TXDELAY", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].txdelay, sizeof(devices[i].txdelay)))
+            xastir_snprintf(devices[i].txdelay,
+                sizeof(devices[i].txdelay),
+                "40");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_PERSISTENCE", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].persistence, sizeof(devices[i].persistence)))
+            xastir_snprintf(devices[i].persistence,
+                sizeof(devices[i].persistence),
+                "63");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_SLOTTIME", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].slottime, sizeof(devices[i].slottime)))
+            xastir_snprintf(devices[i].slottime,
+                sizeof(devices[i].slottime),
+                "10");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_TXTAIL", sizeof(name) - 1 - strlen(name));
+        // Empty string is ok here.
+        if (!get_string (name, devices[i].txtail, sizeof(devices[i].txtail)))
+            xastir_snprintf(devices[i].txtail,
+                sizeof(devices[i].txtail),
+                "30");
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_FULLDUPLEX", sizeof(name) - 1 - strlen(name));
+        devices[i].fullduplex = get_int (name, 0, 1, 0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNC_INIT_KISSMODE", sizeof(name) - 1 - strlen(name));
+        devices[i].init_kiss = get_int (name, 0, 1, 0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "SPEED", sizeof(name) - 1 - strlen(name));
+        devices[i].sp = get_int (name, 0,230400,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "STYLE", sizeof(name) - 1 - strlen(name));
+        devices[i].style = get_int (name, 0,2,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "IGATE_OPTION", sizeof(name) - 1 - strlen(name));
+        devices[i].igate_options = get_int (name, 0,2,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TXMT", sizeof(name) - 1 - strlen(name));
+        devices[i].transmit_data = get_int (name, 0,1,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "RELAY_DIGIPEAT", sizeof(name) - 1 - strlen(name));
+        devices[i].relay_digipeat = get_int (name, 0,1,1);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "RECONN", sizeof(name) - 1 - strlen(name));
+        devices[i].reconnect = get_int (name, 0,1,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "ONSTARTUP", sizeof(name) - 1 - strlen(name));
+        devices[i].connect_on_startup = get_int (name, 0,1,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "GPSRETR", sizeof(name) - 1 - strlen(name));
+        devices[i].gps_retrieve = get_int (name, 0,255,DEFAULT_GPS_RETR);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "SETTIME", sizeof(name) - 1 - strlen(name));
+        devices[i].set_time = get_int (name, 0,1,0);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "TNCEXTRADELAY", sizeof(name) - 1 - strlen(name));
+        devices[i].tnc_extra_delay = get_int (name, 0,9999999,0);
+    }
+
+    /* TNC */
+    log_tnc_data = get_int ("TNC_LOG_DATA", 0,1,0);
+
+    if (!get_string ("LOGFILE_TNC", LOGFILE_TNC, sizeof(LOGFILE_TNC))
+            || LOGFILE_TNC[0] == '\0') {
+        xastir_snprintf(LOGFILE_TNC,
+            sizeof(LOGFILE_TNC),
+            "%s",
+            "logs/tnc.log");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, LOGFILE_TNC, strlen(user_base_dir)) == 0)
+         xastir_snprintf(LOGFILE_TNC,
+            sizeof(LOGFILE_TNC),
+            "%s",
+            "logs/tnc.log");
+
+    /* NET */
+    log_net_data = get_int ("NET_LOG_DATA", 0,1,0);
+
+    operate_as_an_igate = get_int ("NET_RUN_AS_IGATE", 0,2,0);
+
+    log_igate = get_int ("LOG_IGATE", 0,1,0);
+
+    NETWORK_WAITTIME = get_int ("NETWORK_WAITTIME", 10,120,10);
+
+    // LOGGING
+    log_wx = get_int ("LOG_WX", 0,1,0);
+    log_message_data = get_int ("LOG_MESSAGE", 0, 1, 0);
+    log_wx_alert_data = get_int ("LOG_WX_ALERT", 0, 1, 0);
+
+    if (!get_string ("LOGFILE_IGATE", LOGFILE_IGATE, sizeof(LOGFILE_IGATE))
+            || LOGFILE_IGATE[0] == '\0') {
+        xastir_snprintf(LOGFILE_IGATE,
+            sizeof(LOGFILE_IGATE),
+            "%s",
+            "logs/igate.log");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, LOGFILE_IGATE, strlen(user_base_dir)) == 0)
+         xastir_snprintf(LOGFILE_IGATE,
+            sizeof(LOGFILE_IGATE),
+            "%s",
+            "logs/igate.log");
+
+    if (!get_string ("LOGFILE_NET", LOGFILE_NET, sizeof(LOGFILE_NET))
+            || LOGFILE_NET[0] == '\0') {
+        xastir_snprintf(LOGFILE_NET,
+            sizeof(LOGFILE_NET),
+            "%s",
+            "logs/net.log");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, LOGFILE_NET, strlen(user_base_dir)) == 0)
+        xastir_snprintf(LOGFILE_NET,
+            sizeof(LOGFILE_NET),
+            "%s",
+            "logs/net.log");
+  
+    if (!get_string ("LOGFILE_WX", LOGFILE_WX, sizeof(LOGFILE_WX))
+            || LOGFILE_WX[0] == '\0') {
+        xastir_snprintf(LOGFILE_WX,
+            sizeof(LOGFILE_WX),
+            "%s",
+            "logs/wx.log");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, LOGFILE_WX, strlen(user_base_dir)) == 0)
+        xastir_snprintf(LOGFILE_WX,
+            sizeof(LOGFILE_WX),
+            "%s",
+            "logs/wx.log");
+
+    if (!get_string ("LOGFILE_MESSAGE", LOGFILE_MESSAGE, sizeof(LOGFILE_MESSAGE))
+            || LOGFILE_MESSAGE[0] == '\0') {
+        xastir_snprintf(LOGFILE_MESSAGE,
+            sizeof(LOGFILE_MESSAGE),
+            "%s",
+            "logs/message.log");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, LOGFILE_MESSAGE, strlen(user_base_dir)) == 0)
+        xastir_snprintf(LOGFILE_MESSAGE,
+            sizeof(LOGFILE_MESSAGE),
+            "%s",
+            "logs/message.log");
+ 
+    if (!get_string ("LOGFILE_WX_ALERT", LOGFILE_WX_ALERT, sizeof(LOGFILE_WX_ALERT))
+            || LOGFILE_WX_ALERT[0] == '\0') {
+        xastir_snprintf(LOGFILE_WX_ALERT,
+            sizeof(LOGFILE_WX_ALERT),
+            "%s",
+            "logs/wx_alert.log");
+    }
+    // Check for old complete path, change to new short path if a
+    // match
+    if (strncmp( user_base_dir, LOGFILE_WX_ALERT, strlen(user_base_dir)) == 0)
+        xastir_snprintf(LOGFILE_WX_ALERT,
+            sizeof(LOGFILE_WX_ALERT),
+            "%s",
+            "logs/wx_alert.log");
+  
+    // SNAPSHOTS
+    snapshots_enabled = get_int ("SNAPSHOTS_ENABLED", 0,1,0);
+
+    // KML SNAPSHOTS
+    kmlsnapshots_enabled = get_int ("KMLSNAPSHOTS_ENABLED", 0,1,0);
+
+    /* WX ALERTS */
+    WX_ALERTS_REFRESH_TIME = (time_t) get_long ("WX_ALERTS_REFRESH_TIME", 10l, 86400l, 60l);
+
+    /* gps */
+    gps_time = (time_t) get_long ("GPS_TIME", 1l, 86400l, 60l);
+
+    /* POSIT RATE */
+    POSIT_rate = (time_t) get_long ("POSIT_RATE", 0l, 86400l, 30*60l);
+
+    /* OBJECT RATE */
+    OBJECT_rate = (time_t) get_long ("OBJECT_RATE", 1l, 86400l, 30*60l);
+
+    /* UPDATE DR RATE */
+    update_DR_rate = (time_t) get_long ("UPDATE_DR_RATE", 1l, 86400l, 30l);
+
+    /* station broadcast type */
+    output_station_type = get_int ("BST_TYPE", 0,5,0);
+
+#ifdef TRANSMIT_RAW_WX
+    /* raw wx transmit */
+    transmit_raw_wx = get_int ("BST_WX_RAW", 0,1,0);
+#endif  // TRANSMIT_RAW_WX
+
+    /* compressed posit transmit */
+    transmit_compressed_posit = get_int ("BST_COMPRESSED_POSIT", 0,1,0);
+
+    /* compressed objects/items transmit */
+    transmit_compressed_objects_items = get_int ("COMPRESSED_OBJECTS_ITEMS", 0,1,0);
+
+    smart_beaconing = get_int ("SMART_BEACONING", 0,1,1);
+    sb_turn_min = get_int ("SB_TURN_MIN", 1,360,20);
+    sb_turn_slope = get_int ("SB_TURN_SLOPE", 0,360,25);
+    sb_turn_time = get_int ("SB_TURN_TIME", 0,3600,5);
+    sb_posit_fast = get_int ("SB_POSIT_FAST", 1,1440,60);
+    sb_posit_slow = get_int ("SB_POSIT_SLOW", 1,1440,30);
+    sb_low_speed_limit = get_int ("SB_LOW_SPEED_LIMIT", 0,999,2);
+    sb_high_speed_limit = get_int ("SB_HIGH_SPEED_LIMIT", 0,999,60);
+
+    pop_up_new_bulletins = get_int ("POP_UP_NEW_BULLETINS", 0,1,1);
+    view_zero_distance_bulletins = get_int ("VIEW_ZERO_DISTANCE_BULLETINS", 0,1,1);
+
+    warn_about_mouse_modifiers = get_int ("WARN_ABOUT_MOUSE_MODIFIERS", 0,1,1);
+
+
+    /* Audio Alarms*/
+    // Empty string is ok here.
+    if (!get_string ("SOUND_COMMAND", sound_command, sizeof(sound_command)))
+        xastir_snprintf(sound_command,
+            sizeof(sound_command),
+            "play");
+
+    sound_play_new_station = get_int ("SOUND_PLAY_ONS", 0,1,0);
+
+    if (!get_string ("SOUND_ONS_FILE", sound_new_station, sizeof(sound_new_station))
+            || sound_new_station[0] == '\0') {
+        xastir_snprintf(sound_new_station,
+            sizeof(sound_new_station),
+            "newstation.wav");
+    }
+
+    sound_play_new_message = get_int ("SOUND_PLAY_ONM", 0,1,0);
+
+    if (!get_string ("SOUND_ONM_FILE", sound_new_message, sizeof(sound_new_message))
+            || sound_new_message[0] == '\0') {
+        xastir_snprintf(sound_new_message,
+            sizeof(sound_new_message),
+            "newmessage.wav");
+    }
+
+    sound_play_prox_message = get_int ("SOUND_PLAY_PROX", 0,1,0);
+
+    if (!get_string ("SOUND_PROX_FILE", sound_prox_message, sizeof(sound_prox_message))
+            || sound_prox_message[0] == '\0') {
+        xastir_snprintf(sound_prox_message,
+            sizeof(sound_prox_message),
+            "proxwarn.wav");
+    }
+
+    if (!get_string ("PROX_MIN", prox_min, sizeof(prox_min))
+            || prox_min[0] == '\0') {
+        xastir_snprintf(prox_min,
+            sizeof(prox_min),
+            "0.01");
+    }
+
+    if (!get_string ("PROX_MAX", prox_max, sizeof(prox_max))
+            || prox_max[0] == '\0') {
+        xastir_snprintf(prox_max,
+            sizeof(prox_max),
+            "10");
+    }
+
+    sound_play_band_open_message = get_int ("SOUND_PLAY_BAND", 0,1,0);
+
+    if (!get_string ("SOUND_BAND_FILE", sound_band_open_message, sizeof(sound_band_open_message))
+            || sound_band_open_message[0] == '\0') {
+        xastir_snprintf(sound_band_open_message,
+            sizeof(sound_band_open_message),
+            "bandopen.wav");
+    }
+
+    if (!get_string ("BANDO_MIN", bando_min, sizeof(bando_min))
+            || bando_min[0] == '\0') {
+        xastir_snprintf(bando_min,
+            sizeof(bando_min),
+            "200");
+    }
+
+    if (!get_string ("BANDO_MAX", bando_max, sizeof(bando_max))
+            || bando_max[0] == '\0') {
+        xastir_snprintf(bando_max,
+            sizeof(bando_max),
+            "2000");
+    }
+
+    sound_play_wx_alert_message = get_int ("SOUND_PLAY_WX_ALERT", 0,1,0);
+
+    if (!get_string ("SOUND_WX_ALERT_FILE", sound_wx_alert_message, sizeof(sound_wx_alert_message))
+            || sound_wx_alert_message[0] == '\0') {
+        xastir_snprintf(sound_wx_alert_message,
+            sizeof(sound_wx_alert_message),
+            "thunder.wav");
+    }
+
+#ifdef HAVE_FESTIVAL
+    /* Festival Speech defaults */
+    festival_speak_new_station = get_int ("SPEAK_NEW_STATION",0,1,0);
+    festival_speak_proximity_alert = get_int ("SPEAK_PROXIMITY_ALERT",0,1,0);
+    festival_speak_tracked_proximity_alert = get_int ("SPEAK_TRACKED_ALERT",0,1,0);
+    festival_speak_band_opening = get_int ("SPEAK_BAND_OPENING",0,1,0);
+    festival_speak_new_message_alert = get_int ("SPEAK_MESSAGE_ALERT",0,1,0);
+    festival_speak_new_message_body = get_int ("SPEAK_MESSAGE_BODY",0,1,0);
+    festival_speak_new_weather_alert = get_int ("SPEAK_WEATHER_ALERT",0,1,0);
+    festival_speak_new_station = get_int ("SPEAK_ID",0,1,0);
+#endif  // HAVE_FESTIVAL
+
+    ATV_screen_ID = get_int ("ATV_SCREEN_ID",0,1,0);
+ 
+    /* defaults */
+    sec_old = (time_t) get_long ("DEFAULT_STATION_OLD", 1l, 604800l, 4800l);
+
+    sec_clear = (time_t) get_long ("DEFAULT_STATION_CLEAR", 1l, 604800l, 43200l);
+
+    sec_remove = get_long("DEFAULT_STATION_REMOVE", 1l, 604800*2, sec_clear*2);
+
+    if (!get_string ("MESSAGE_COUNTER", message_counter, sizeof(message_counter))
+            || message_counter[0] == '\0') {
+        xastir_snprintf(message_counter,
+            sizeof(message_counter),
+            "00");
+    }
+
+    message_counter[2] = '\0';  // Terminate at 2 chars
+    // Check that chars are within the correct ranges
+    if (         (message_counter[0] < '0')
+            ||   (message_counter[1] < '0')
+            || ( (message_counter[0] > '9') && (message_counter[0] < 'A') )
+            || ( (message_counter[1] > '9') && (message_counter[1] < 'A') )
+            || ( (message_counter[0] > 'Z') && (message_counter[0] < 'a') )
+            || ( (message_counter[1] > 'Z') && (message_counter[1] < 'a') )
+            ||   (message_counter[0] > 'z')
+            ||   (message_counter[1] > 'z') ) {
+        message_counter[0] = '0';
+        message_counter[1] = '0'; 
+    }
+
+    if (!get_string ("AUTO_MSG_REPLY", auto_reply_message, sizeof(auto_reply_message))
+        || auto_reply_message[0] == '\0') {
+        xastir_snprintf(auto_reply_message,
+            sizeof(auto_reply_message),
+            "Autoreply- No one is at the keyboard");
+    }
+
+    Display_packet_data_type = get_int ("DISPLAY_PACKET_TYPE", 0,2,0);
+
+    bulletin_range = get_int ("BULLETIN_RANGE", 0,99999,0);
+
+    vm_range = get_int("VIEW_MESSAGE_RANGE", 0,99999,0);
+
+    view_message_limit = get_int("VIEW_MESSAGE_LIMIT", 10000,99999,10000);
+    predefined_menu_from_file = get_int("PREDEF_MENU_LOAD",0,1,0);
+    if (!get_string ("PREDEF_MENU_FILE", predefined_object_definition_filename, sizeof(predefined_object_definition_filename))
+            || predefined_object_definition_filename[0] == '\0') {
+        xastir_snprintf(predefined_object_definition_filename,
+            sizeof(predefined_object_definition_filename),
+            "predefined_SAR.sys");
+    }
+
+    Read_messages_packet_data_type = get_int ("READ_MESSAGES_PACKET_DATA_TYPE", 0,2,0);
+    Read_messages_mine_only = get_int ("READ_MESSAGES_MINE_ONLY", 0,1,0);
+
+    /* printer variables */
+    print_rotated = get_int ("PRINT_ROTATED", 0,1,0);
+    print_auto_rotation = get_int ("PRINT_AUTO_ROTATION", 0,1,1);
+    print_auto_scale = get_int ("PRINT_AUTO_SCALE", 0,1,1);
+    print_in_monochrome = get_int ("PRINT_IN_MONOCHROME", 0,1,0);
+    print_invert = get_int ("PRINT_INVERT_COLORS", 0,1,0);
+
+    // 0 = no correction
+    WX_rain_gauge_type = get_int ("RAIN_GAUGE_TYPE", 0,3,0);
+
+
+    /* list attributes */
+    for (i = 0; i < LST_NUM; i++) {
+        xastir_snprintf (name_temp, sizeof(name_temp), "LIST%0d_", i);
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "H", sizeof(name) - 1 - strlen(name));
+        list_size_h[i] = get_int (name, -1,8192,-1);
+
+        xastir_snprintf(name,
+            sizeof(name),
+            "%s",
+            name_temp);
+        strncat (name, "W", sizeof(name) - 1 - strlen(name));
+        list_size_w[i] = get_int (name, -1,8192,-1);
+    }
+
+    // 0 = no tracking
+    track_me = get_int ("TRACK_ME", 0,1,0);
+
+//    store_string (fout, "TRACKING_STATION_CALLSIGN", tracking_station_call);
+    if (!get_string ("TRACKING_STATION_CALLSIGN", tracking_station_call, sizeof(tracking_station_call))) {
+        tracking_station_call[0] = '\0';
+    }
+
+
+    map_chooser_expand_dirs = get_int ("MAP_CHOOSER_EXPAND_DIRS", 0,1,1);
+
+    // One hour default
+    st_direct_timeout = get_int ("ST_DIRECT_TIMEOUT", 1,60*60*24*30,60*60);
+
+    // Ten minute default
+    dead_reckoning_timeout = get_int ("DEAD_RECKONING_TIMEOUT", 1,60*60*24*30,60*10);
+
+    // 1ms default
+    serial_char_pacing = get_int ("SERIAL_CHAR_PACING", 0,50,1);
+
+    // 45 minutes default, 12 hours max
+    trail_segment_time = get_int ("TRAIL_SEGMENT_TIME", 0,12*60,45);
+
+    // 1 degree default
+    trail_segment_distance = get_int ("TRAIL_SEGMENT_DISTANCE", 0,45,1);
+
+    // 0 minutes default (function disabled)
+    RINO_download_interval = get_int ("RINO_DOWNLOAD_INTERVAL", 0,30,0);
+
+    // 5 minutes default
+    snapshot_interval = get_int ("SNAPSHOT_INTERVAL", 1,30,5);
+
+    input_close();
+}
+
+
diff --git a/src/xa_config.h b/src/xa_config.h
new file mode 100644
index 0000000..ad4388b
--- /dev/null
+++ b/src/xa_config.h
@@ -0,0 +1,35 @@
+/*
+ * $Id: xa_config.h,v 1.14 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+#define MAX_VALUE 300
+
+extern time_t next_time;
+
+char *get_user_base_dir(char *dir, char *dest, size_t dest_size);
+char *get_data_base_dir(char *dir);
+void save_data(void);
+void load_data_or_default(void);
+
+char xa_config_dir[1000];       /* cmdline option user config dir */
diff --git a/src/xastir.h b/src/xastir.h
new file mode 100644
index 0000000..c1506f7
--- /dev/null
+++ b/src/xastir.h
@@ -0,0 +1,270 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
+ * $Id: xastir.h,v 1.65 2012/11/01 18:57:19 we7u Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 1999,2000  Frank Giannandrea
+ * Copyright (C) 2000-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+/* All of the misc entry points to be included for all packages */
+
+#ifndef _XASTIR_H
+#define _XASTIR_H
+
+
+
+// Macros that help us avoid warnings on 64-bit CPU's.
+// Borrowed from the freeciv project (also a GPL project).
+#define INT_TO_XTPOINTER(m_i)  ((XtPointer)((long)(m_i)))
+#define XTPOINTER_TO_INT(m_p)  ((int)((long)(m_p)))
+
+
+#define SERIAL_KISS_RELAY_DIGI
+
+
+#include <X11/Intrinsic.h>
+
+//#include "database.h"
+#include "util.h"
+#include "messages.h"
+#include "fcc_data.h"
+#include "rac_data.h"
+
+
+#define MAX_CALLSIGN 9       // Objects are up to 9 chars
+
+
+// black
+#define MY_FG_COLOR             colors[0x08]
+#define MY_FOREGROUND_COLOR     XmNforeground,colors[0x08]
+// gray73
+#define MY_BG_COLOR             colors[0xff]
+#define MY_BACKGROUND_COLOR     XmNbackground,colors[0xff]
+
+// Latitude and longitude string formats.
+#define CONVERT_HP_NORMAL       0
+#define CONVERT_HP_NOSP         1
+#define CONVERT_LP_NORMAL       2
+#define CONVERT_LP_NOSP         3
+#define CONVERT_DEC_DEG         4
+#define CONVERT_UP_TRK          5
+#define CONVERT_DMS_NORMAL      6
+#define CONVERT_VHP_NOSP        7
+#define CONVERT_DMS_NORMAL_FORMATED      8
+#define CONVERT_HP_NORMAL_FORMATED       9
+
+#ifndef M_PI                      /* if not defined in math.h */
+#define M_PI 3.14159265358979323846
+#endif  // M_PI
+
+#define SPEECH_TEST_STRING      "Greeteengz frum eggzaster"
+
+/* GLOBAL DEFINES */
+extern char dangerous_operation[200];
+extern GC gc;
+extern Pixmap  pixmap;
+extern Pixmap  pixmap_final;
+extern Pixmap  pixmap_alerts;
+extern Pixmap  pixmap_50pct_stipple;
+extern Pixmap  pixmap_25pct_stipple;
+extern Pixmap  pixmap_13pct_stipple;
+extern Pixmap  pixmap_wx_stipple;
+
+extern Widget appshell;
+
+
+extern int wait_to_redraw;
+/*extern char my_callsign[MAX_CALLSIGN+1];*/
+
+extern void pad_callsign(char *callsignout, char *callsignin);
+
+
+
+extern char *to_upper(char *data);
+
+extern void Send_message(Widget w, XtPointer clientData, XtPointer callData);
+
+extern void create_gc(Widget w);
+
+extern void Station_info(Widget w, XtPointer clientData, XtPointer calldata);
+
+extern void fix_dialog_size(Widget w);
+extern void fix_dialog_vsize(Widget w);
+
+extern int debug_level;
+extern GC gc;
+extern Pixel colors[];
+
+
+extern float f_center_longitude;   // Floating point map center longitude
+extern float f_center_latitude;    // Floating point map center latitude
+extern float f_NW_corner_longitude;// longitude of NW corner
+extern float f_NW_corner_latitude; // latitude of NW corner
+extern float f_SE_corner_longitude;// longitude of SE corner
+extern float f_SE_corner_latitude; // latitude of SE corner
+
+extern long center_longitude;      // Longitude at center of map
+extern long center_latitude;       // Latitude at center of map
+extern long NW_corner_longitude;   // longitude of NW corner
+extern long NW_corner_latitude;    // latitude of NW corner
+extern long SE_corner_longitude;   // longitude of SE corner
+extern long SE_corner_latitude;    // latitude of SE corner
+
+extern long scale_x;               // x scaling in 1/100 sec per pixel
+extern long scale_y;               // y scaling in 1/100 sec per pixel
+
+
+extern long screen_width;
+extern long screen_height;
+extern Position screen_x_offset;
+extern Position screen_y_offset;
+extern int long_lat_grid;
+//extern Pixmap  pixmap;
+//extern Pixmap  pixmap_final;
+//extern Pixmap  pixmap_alerts;
+extern int map_color_levels;
+extern int map_labels;
+extern int map_lock_pan_zoom;
+extern int map_auto_maps;
+extern int auto_maps_skip_raster;
+extern time_t sec_remove;
+extern Widget da;
+extern Widget text;
+extern XtAppContext app_context;
+extern int redraw_on_new_data;
+//extern Widget hidden_shell;
+extern int tiger_flag;
+extern int index_maps_on_startup;
+#define MAX_LABEL_FONTNAME 256
+#define FONT_SYSTEM  0
+#define FONT_STATION 1
+#define FONT_TINY    2
+#define FONT_SMALL   3
+#define FONT_MEDIUM  4
+#define FONT_LARGE   5
+#define FONT_HUGE    6
+#define FONT_BORDER  7
+#define FONT_ATV_ID  8
+#define FONT_MAX     9
+#define FONT_DEFAULT FONT_MEDIUM
+#define MAX_FONTNAME 256
+extern char rotated_label_fontname[FONT_MAX][MAX_LABEL_FONTNAME];
+
+#ifdef HAVE_MAGICK  //N0VH
+extern int tiger_show_grid;
+extern int tiger_show_counties;
+extern int tiger_show_cities;
+extern int tiger_show_places;
+extern int tiger_show_majroads;
+extern int tiger_show_streets;
+extern int tiger_show_railroad;
+extern int tiger_show_states;
+extern int tiger_show_interstate;
+extern int tiger_show_ushwy;
+extern int tiger_show_statehwy;
+extern int tiger_show_water;
+extern int tiger_show_lakes;
+extern int tiger_show_misc;
+#endif  // HAVE_MAGICK
+
+#ifdef HAVE_LIBGEOTIFF
+extern int DRG_XOR_colors;
+extern int DRG_show_colors[13];
+#endif  // HAVE_LIBGEOTIFF
+
+
+extern int net_map_timeout;
+
+extern void sort_list(char *filename,int size, Widget list, int *item);
+extern void redraw_symbols(Widget w);
+
+extern Colormap cmap;
+
+
+
+/* from messages.c */
+extern char  message_counter[5+1];
+extern int  auto_reply;
+extern char auto_reply_message[100];
+extern int  satellite_ack_mode;
+extern void clear_outgoing_messages(void);
+extern void reset_outgoing_messages(void);
+extern void output_message(char *from, char *to, char *message, char *path);
+extern void check_and_transmit_messages(time_t time);
+extern Message_Window mw[MAX_MESSAGE_WINDOWS+1];
+extern void clear_message_windows(void);
+
+/* from sound.c */
+extern pid_t play_sound(char *sound_cmd, char *soundfile);
+extern int sound_done(void);
+
+/* from fcc_data.c */
+
+
+
+/* from rac_data.c */
+
+/* from lang.c */
+extern int load_language_file(char *filename);
+extern char *langcode(char *code);
+extern char langcode_hotkey(char *code);
+
+/* from sound.c */
+extern pid_t play_sound(char *sound_cmd, char *soundfile);
+
+/* from location.c */
+extern void set_last_position(void);
+extern void map_pos_last_position(void);
+
+/* from location_gui.c */
+extern char locate_station_call[30];
+extern void Last_location(Widget w, XtPointer clientData, XtPointer callData);
+extern void Jump_location(Widget w, XtPointer clientData, XtPointer callData);
+extern void map_pos(long mid_y, long mid_x, long sz);
+extern char locate_gnis_filename[200];
+
+// This needs to be quite long for some of the weather station
+// serial data to get through ok (Peet Bros U2k Complete Record Mode
+// for one).
+#define MAX_LINE_SIZE 512
+
+// from main.c
+extern char gprmc_save_string[MAX_LINE_SIZE+1];
+extern char gpgga_save_string[MAX_LINE_SIZE+1];
+extern int gps_port_save;
+
+// from map.c
+extern double calc_dscale_x(long x, long y);
+
+/* from popup_gui.c */
+extern void popup_message_always(char *banner, char *message);
+extern void popup_message(char *banner, char *message);
+extern void popup_ID_message(char *banner, char *message);
+
+
+/* from view_messages.c */
+extern void all_messages(char from, char *call_sign, char *from_call, char *message);
+extern void view_all_messages(Widget w, XtPointer clientData, XtPointer callData);   
+
+/* from db.c */
+extern void setup_in_view(void);
+
+#endif /* XASTIR_H */
+
+
diff --git a/src/xastir_udp_client.c b/src/xastir_udp_client.c
new file mode 100644
index 0000000..295e6af
--- /dev/null
+++ b/src/xastir_udp_client.c
@@ -0,0 +1,212 @@
+/*
+ * $Id: xastir_udp_client.c,v 1.16 2012/08/25 16:38:29 tvrusso Exp $
+ *
+ * XASTIR, Amateur Station Tracking and Information Reporting
+ * Copyright (C) 2003-2012  The Xastir Group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Look at the README for more information on the program.
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif  // HAVE_CONFIG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include <netinet/in.h>     // Moved ahead of inet.h as reports of some *BSD's not
+                            // including this as they should.
+#include <arpa/inet.h>
+//#include <netinet/tcp.h>    // Needed for TCP_NODELAY setsockopt() (disabling Nagle algorithm)
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif  // HAVE_NETDB_H
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+
+// Must be last include file
+#include "leak_detection.h"
+
+
+
+
+
+// Send a UDP packet to a UDP listening port.  This allows scripts
+// and other programs to inject packets into Xastir via UDP
+// protocol.
+// Inputs:
+//      hostname    (argv[1])
+//      port        (argv[2])
+//      callsign    (argv[3])
+//      passcode    (argv[4])
+//      optional flags:  -identify
+//                       -to_rf
+//                       -to_inet
+//      APRS Packet (argv[5])
+// Returns:
+//      0: Message sent, ack received
+//      1: Error condition
+//
+// 
+//
+int main(int argc, char *argv[]) {
+    int sockfd, n;
+    socklen_t length;
+    struct sockaddr_in server, from;
+    struct hostent *hostinfo;
+    char buffer[512];
+    char callsign[10];
+    char extra[100];
+    int passcode;
+    char message[256];
+    int ii;
+
+
+    if (argc < 6) {
+        fprintf(stderr,
+            "\nUsage: xastir_udp_client server port call passcode -identify\n");
+        fprintf(stderr,
+            "       xastir_udp_client server port call passcode [-to_rf] [-to_inet] \"APRS Packet\"\n");
+ 
+        fprintf(stderr,
+            "\nExample: xastir_udp_client localhost 2023 ab7cd 1234 \"APRS packet goes here\"\n");
+        return(1);
+    }
+
+    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sockfd < 0) {
+        fprintf(stderr, "socket\n");
+        return(1);
+    }
+
+    memset(&server, 0, sizeof(struct sockaddr_in));
+
+    server.sin_family = AF_INET;
+
+    hostinfo = gethostbyname(argv[1]);
+    if (hostinfo == NULL) {
+        fprintf(stderr, "Unknown host\n");
+        return(1);
+    }
+
+//    server.sin_addr.s_addr = inet_addr("127.0.0.1");
+    memcpy(&server.sin_addr, hostinfo->h_addr, hostinfo->h_length);
+
+    server.sin_port = htons(atoi(argv[2]));
+
+    length = (socklen_t)sizeof(struct sockaddr_in);
+
+    // Fetch the callsign
+    snprintf(callsign, sizeof(callsign), "%s", argv[3]);
+    callsign[sizeof(callsign)-1] = '\0';  // Terminate it
+
+    // Fetch the passcode
+    passcode = atoi(argv[4]);
+
+    // Check for optional flags here:
+    //      -identify
+    //      -to_rf
+    //      -to_inet
+    //
+    extra[0] = '\0';
+    for (ii = 5; ii < argc; ii++) {
+        if (strstr(argv[ii], "-identify")) {
+//fprintf(stderr,"Found -identify\n");
+            strncat(extra, ",-identify", 10);
+        }
+        else if (strstr(argv[ii], "-to_rf")) {
+//fprintf(stderr,"Found -to_rf\n");
+            strncat(extra, ",-to_rf", 7);
+        }
+        else if (strstr(argv[ii], "-to_inet")) {
+//fprintf(stderr,"Found -to_inet\n");
+            strncat(extra, ",-to_inet", 9);
+        }
+    }
+
+
+//    fprintf(stdout, "Please enter the message: ");
+
+    // Fetch message portion from the end of the command-line
+    snprintf(message, sizeof(message), "%s", argv[argc-1]);
+    message[sizeof(message)-1] = '\0';  // Terminate it
+
+    if (message[0] == '\0') // Empty message
+        return(1);
+
+    memset(buffer, 0, 256);
+//    fgets(buffer, 255, stdin);
+
+    snprintf(buffer,
+        sizeof(buffer),
+        "%s,%d%s\n%s\n",
+        callsign,
+        passcode,
+        extra,
+        message);
+
+//fprintf(stderr, "%s", buffer);
+
+    n = sendto(sockfd,
+        buffer,
+        (size_t)strlen(buffer),
+        0,
+        (struct sockaddr *)&server,
+        length);
+    if (n < 0) {
+        fprintf(stderr, "Sendto\n");
+        return(1);
+    }
+
+    n = recvfrom(sockfd,
+        buffer,
+        256,
+        0,
+        (struct sockaddr *)&from,
+        &length);
+    if (n < 0) {
+        fprintf(stderr, "recvfrom\n");
+        return(1);
+    }
+
+    fprintf(stdout,"Received: %s\n", buffer);
+
+    if (strncmp(buffer, "NACK", 4) == 0) {
+//fprintf(stderr,"returning 1\n");
+        return(1);  // Received a NACK
+    }
+    else if (strncmp(buffer, "ACK", 3) == 0) {
+//fprintf(stderr,"returning 0\n");
+        return(0);  // Received an ACK
+    }
+    else {
+//fprintf(stderr,"returning 1\n");
+        return(1);  // Received something other than ACK or NACK
+    }
+}
+
+
diff --git a/symbols/13pct.xbm b/symbols/13pct.xbm
new file mode 100644
index 0000000..e51a2ec
--- /dev/null
+++ b/symbols/13pct.xbm
@@ -0,0 +1,5 @@
+/* Created with The GIMP */
+#define 13pct_width 4
+#define 13pct_height 4
+static unsigned char 13pct_bits[] = {
+   0x01, 0x00, 0x04, 0x00 };
diff --git a/symbols/25pct.xbm b/symbols/25pct.xbm
new file mode 100644
index 0000000..0359058
--- /dev/null
+++ b/symbols/25pct.xbm
@@ -0,0 +1,5 @@
+/* Created with The GIMP */
+#define 25pct_width 4
+#define 25pct_height 4
+static unsigned char 25pct_bits[] = {
+   0x01, 0x04, 0x01, 0x04 };
diff --git a/symbols/2x2.xbm b/symbols/2x2.xbm
new file mode 100644
index 0000000..c0d8165
--- /dev/null
+++ b/symbols/2x2.xbm
@@ -0,0 +1,5 @@
+/* Created with The GIMP */
+#define 2x2_width 2
+#define 2x2_height 2
+static unsigned char 2x2_bits[] = {
+   0x01, 0x02 };
diff --git a/symbols/Makefile.am b/symbols/Makefile.am
new file mode 100644
index 0000000..d3d244c
--- /dev/null
+++ b/symbols/Makefile.am
@@ -0,0 +1,8 @@
+# $Id: Makefile.am,v 1.17 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+symbolsdir=${pkgdatadir}/symbols
+EXTRA_DIST=symbols.dat 2x2.xbm 25pct.xbm 13pct.xbm alert.xbm  flood.xbm  red_flag.xbm  snow.xbm  torndo.xbm  wind.xbm  winter_storm.xbm  winter_weather.xbm icon.png
+symbols_DATA= symbols.dat 2x2.xbm 25pct.xbm 13pct.xbm alert.xbm  flood.xbm  red_flag.xbm  snow.xbm  torndo.xbm  wind.xbm  winter_storm.xbm  winter_weather.xbm icon.png
diff --git a/symbols/Makefile.in b/symbols/Makefile.in
new file mode 100644
index 0000000..b0a9ce3
--- /dev/null
+++ b/symbols/Makefile.in
@@ -0,0 +1,414 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id: Makefile.am,v 1.17 2012/11/01 18:57:19 we7u Exp $
+#
+# Copyright (C) 2000-2012  The Xastir Group
+#
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = symbols
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(symbolsdir)"
+DATA = $(symbols_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONTSHP = @CONTSHP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GMAGIC_BIN = @GMAGIC_BIN@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBCOMPAT = @LIBCOMPAT@
+LIBOBJS = @LIBOBJS@
+LIBRTREE = @LIBRTREE@
+LIBS = @LIBS@
+LIBSHP = @LIBSHP@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LWPOSTGIS = @LWPOSTGIS@
+MAGIC_BIN = @MAGIC_BIN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PG_CONFIG = @PG_CONFIG@
+POW_LIB = @POW_LIB@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUBRTREE = @SUBRTREE@
+SUBSHP = @SUBSHP@
+VERSION = @VERSION@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+convert = @convert@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+festival = @festival@
+found_gdal_config = @found_gdal_config@
+gm = @gm@
+gpsman = @gpsman@
+gv = @gv@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lpr = @lpr@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mv = @mv@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sed = @sed@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wget = @wget@
+xfontsel = @xfontsel@
+symbolsdir = ${pkgdatadir}/symbols
+EXTRA_DIST = symbols.dat 2x2.xbm 25pct.xbm 13pct.xbm alert.xbm  flood.xbm  red_flag.xbm  snow.xbm  torndo.xbm  wind.xbm  winter_storm.xbm  winter_weather.xbm icon.png
+symbols_DATA = symbols.dat 2x2.xbm 25pct.xbm 13pct.xbm alert.xbm  flood.xbm  red_flag.xbm  snow.xbm  torndo.xbm  wind.xbm  winter_storm.xbm  winter_weather.xbm icon.png
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu symbols/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu symbols/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-symbolsDATA: $(symbols_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(symbolsdir)" || $(MKDIR_P) "$(DESTDIR)$(symbolsdir)"
+	@list='$(symbols_DATA)'; test -n "$(symbolsdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(symbolsdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(symbolsdir)" || exit $$?; \
+	done
+
+uninstall-symbolsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(symbols_DATA)'; test -n "$(symbolsdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(symbolsdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(symbolsdir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(symbolsdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-symbolsDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-symbolsDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip install-symbolsDATA installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
+	uninstall-am uninstall-symbolsDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/symbols/alert.xbm b/symbols/alert.xbm
new file mode 100644
index 0000000..25a6210
--- /dev/null
+++ b/symbols/alert.xbm
@@ -0,0 +1,41 @@
+#define alert_width 109
+#define alert_height 32
+static unsigned char alert_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x82,
+   0xef, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x21, 0x82, 0x20, 0x22, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x15, 0x50, 0x82, 0x20, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x50, 0x82, 0xe7, 0x21, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x20, 0x22, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x20, 0x22,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xbe,
+   0x2f, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/symbols/flood.xbm b/symbols/flood.xbm
new file mode 100644
index 0000000..c48ce62
--- /dev/null
+++ b/symbols/flood.xbm
@@ -0,0 +1,41 @@
+#define flood_width 110
+#define flood_height 32
+static unsigned char flood_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc0, 0x17, 0x38, 0xce, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x44, 0x51, 0x04, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x44, 0x51, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x13, 0x44, 0x51,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10,
+   0x44, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x10, 0x44, 0x51, 0x54, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0xf0, 0x39, 0xce, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/symbols/icon.png b/symbols/icon.png
new file mode 100644
index 0000000..38851b4
Binary files /dev/null and b/symbols/icon.png differ
diff --git a/symbols/red_flag.xbm b/symbols/red_flag.xbm
new file mode 100644
index 0000000..382e2df
--- /dev/null
+++ b/symbols/red_flag.xbm
@@ -0,0 +1,41 @@
+#define red_flag_width 110
+#define red_flag_height 32
+static unsigned char red_flag_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xcf, 0xf7, 0x00, 0x5f, 0x40, 0x38, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x10, 0x01, 0x41, 0x40, 0x44,
+   0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, 0x51, 0x10, 0x01, 0x41,
+   0xa0, 0x04, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x13,
+   0x01, 0x4f, 0xa0, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x51, 0x10, 0x01, 0x41, 0xf0, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x51, 0x10, 0x01, 0x41, 0x10, 0x45, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xd1, 0xf7, 0x00, 0xc1, 0x17, 0x79, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0x2a };
diff --git a/symbols/snow.xbm b/symbols/snow.xbm
new file mode 100644
index 0000000..d2fcd6a
--- /dev/null
+++ b/symbols/snow.xbm
@@ -0,0 +1,41 @@
+#define snow_width 110
+#define snow_height 32
+static unsigned char snow_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x22,
+   0x27, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x88, 0xa6, 0x28, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x08, 0xaa, 0x28, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x70, 0xb2, 0x28, 0x09, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xa2, 0x28, 0xa9, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, 0x88, 0xa2, 0x28, 0x09,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x22,
+   0xe7, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/symbols/symbols.dat b/symbols/symbols.dat
new file mode 100644
index 0000000..9c7b50d
--- /dev/null
+++ b/symbols/symbols.dat
@@ -0,0 +1,4758 @@
+# XASTIR, Amateur Station Tracking and Information Reporting
+# Copyright (C) 1999,2000  Frank Giannandrea
+# Copyright (C) 2001-2012  The Xastir Group
+#
+# $Id: symbols.dat,v 1.35 2012/11/01 18:57:19 we7u Exp $
+#
+# Symbol definitions for XASTIR
+#
+# If the 20th char in the APRS symbol line is a "l" (small letter L),
+# all four orientations of that symbol will be generated, in this
+# case the symbol graphic should be oriented to the left.
+#
+# The text behind the APRS symbol line is the definition text
+# according to the APRS Reference, optionally followed by the
+# current use of that symbol in [] braces.
+#
+# Symbol graphics are defined similar to XPM but with a fixed
+# palette.
+#
+# If an entry doesn't exist, it will display as the first entry
+# defined here (currently says "NO SYM YET").
+#
+# Symbol colors are defined in:
+# draw_symbols.c:read_symbol_from_file()
+#
+#
+# -------------------------------
+#
+TABLE !              description from APRS101.pdf [used here as]
+APRS #
+....................
+....q...q...qqq.....
+....qq..q..q...q....
+....q.q.q..q...q....
+....q..qq..q...q....
+....q...q...qqq.....
+....................
+..qqq..q...q..q...q.
+.q......q.q...qq.qq.
+..qq.....q....q.q.q.
+....q....q....q...q.
+.qqq.....q....q...q.
+....................
+.q...q..qqqq..qqqqq.
+..q.q...q.......q...
+...q....qqq.....q...
+...q....q.......q...
+...q....qqqq....q...
+....................
+....................
+#
+#
+# -----------------------------------
+# Primary table section starts here
+#
+TABLE /
+#
+APRS !               Police, Sheriff
+....................
+.........pp.........
+.........pp.........
+........p##p........
+........p##p........
+.......p####p.......
+.......p#####p......
+ppppppp#######pppppp
+.p################p.
+...p############p...
+...p############p...
+.....p########p.....
+.....p########p.....
+....p##########p....
+....................
+pp....pppppp.pp...p.
+pp....pp...p.pp.p.p.
+pp....pppppp.pp.p.p.
+pp....pp...p.pppppp.
+ppppp.pp...p.pppppp.
+#APRS "               Reserved
+#
+APRS #               Digi (green star with white center)
+....................
+....................
+.........kk.........
+.........kk.........
+........kkkk........
+.......kkkkkk.......
+..kkkkkkkkkkkkkkkk..
+...kkkkkmmmmkkkkk...
+....kkkmmmmmmkkk....
+.....kkmmmmmmkk.....
+.....kkmmmmmmkk.....
+....kkkmmmmmmkkk....
+...kkkkkmmmmkkkkk...
+..kkkkkkkkkkkkkkkk..
+.......kkkkkk.......
+........kkkk........
+.........kk.........
+.........kk.........
+....................
+....................
+#
+APRS $               Phone
+....................
+....................
+..llllllllllllllll..
+..llllllllllmmmmll..
+..lllllllllmllllml..
+..lllllllllmllllml..
+..lllllllllmllllml..
+..llllllllllmlllml..
+..llllllllllmlllml..
+..lllllllllmlllmll..
+..llllllllmlllmlll..
+..llmmmllmlllmllll..
+..lmlllmmlllmlllll..
+..lmlllllllmllllll..
+..lmllllllmlllllll..
+..lmlllllmllllllll..
+..llmmmmmlllllllll..
+..llllllllllllllll..
+....................
+....................
+#
+APRS %               DX Cluster
+....................
+....................
+.mmmmmm..mmmm..mmmm.
+.mqqqqqm.mqqm..mqqm.
+.mqqqqqqmmqqm..mqqm.
+.mqqmmqqqmmqqmmqqm..
+.mqqm.mqqmmqqmmqqm..
+.mqqm.mqqm.mqqqqm...
+.mqqm.mqqm.mqqqqm...
+.mqqm.mqqm..mqqm....
+.mqqm.mqqm..mqqm....
+.mqqm.mqqm.mqqqqm...
+.mqqm.mqqm.mqqqqm...
+.mqqm.mqqmmqqmmqqm..
+.mqqmmqqqmmqqmmqqm..
+.mqqqqqqmmqqm..mqqm.
+.mqqqqqm.mqqm..mqqm.
+.mmmmmm..mmmm..mmmm.
+....................
+....................
+#
+APRS &               HF Gateway
+....................
+....................
+.........qq.........
+........qqqq........
+.......qqqqqq.......
+......qqqqqqqq......
+.....qqq####qqq.....
+....qqq######qqq....
+...qqq##qqqq##qqq...
+..qqqq##qqqqqqqqqq..
+..qqqq##qqq###qqqq..
+...qqq##qqqq##qqq...
+....qqq######qqq....
+.....qqq####qqq.....
+......qqqqqqqq......
+.......qqqqqq.......
+........qqqq........
+.........qq.........
+....................
+....................
+#
+APRS '             l Small Aircraft  (SSID -7)
+....................
+....................
+........ooo.........
+.......oooo.........
+.......oooo.........
+.......oooo...oo....
+.......oooo...oo....
+.......oooo...oo....
+.....ooooooooooo....
+.....ooooooooooo....
+.....ooooooooooo....
+.....ooooooooooo....
+.......oooo...oo....
+.......oooo...oo....
+.......oooo...oo....
+.......oooo.........
+.......oooo.........
+........ooo.........
+....................
+....................
+#
+APRS (               Mobile Satellite Groundstation
+.................p..
+.................p..
+................ppp.
+................ppp.
+....................
+..............p.....
+....................
+............p.......
+....................
+..........p.........
+p...................
+p.......p...........
+p...................
+p...................
+p...................
+p...................
+pp.p................
+ppp.................
+pppp................
+pppppppppp..........
+#
+APRS )               Wheelchair (handicapped)
+....................
+..llllllllllllllll..
+.llllllmmmlllllllll.
+.llllllmmmlllllllll.
+.llllllmmllllllllll.
+.llllllmmllllllllll.
+.lllllllmmlllllllll.
+.llllmmlmmmmmmmllll.
+.llmmmllmmlllllllll.
+.llmmllllmmmmmmmlll.
+.lmmllllllmmmmmmlll.
+.lmmlllllllmmlmmlll.
+.lmmlllllllmmlmmlll.
+.lmmlllllllmmlmmlll.
+.llmmlllllmmllmmlll.
+.llmmmllllmmllmmmml.
+.lllmmmmmmmllllllll.
+.llllmmmmmlllllllll.
+..llllllllllllllll..
+....................
+#
+APRS *             l Snowmobile
+....................
+....................
+....................
+....................
+...........qq.......
+..........qq........
+.........qq.........
+........qq..........
+......q###q.........
+.....q#####q.......q
+....q######qqqqqqqqq
+....q######qqqqqqqqq
+q....q######qqqqqqqq
+qqq..qqqqqqqqqqqqqqq
+.qqqqqqqqqqqqqqqqqqq
+....................
+....................
+....................
+....................
+....................
+#
+APRS +               Red Cross
+....................
+....................
+........jjjj........
+........jjjj........
+........jjjj........
+........jjjj........
+........jjjj........
+........jjjj........
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+........jjjj........
+........jjjj........
+........jjjj........
+........jjjj........
+........jjjj........
+........jjjj........
+....................
+....................
+#
+APRS ,               Boy Scouts
+.........n..........
+........nbn.........
+.......nbbbn........
+.......nbbbn........
+....n.nbbbbbn.n.....
+...nbnnbbbbbnnbn....
+..nbbbbnbbbnbbbbn...
+..nbbbbbnbnbbbbbn...
+..nbbnnbnbnbnnbbn...
+...nn..qqqqq..nn....
+.......qqqqq........
+......nbbnbbn.......
+.....nbbnbnbbn......
+.....nnnbbbnnn......
+.......nbbbn........
+.ppp....nnn......p..
+p................p..
+.pp..pp.ppp.p.p.ppp.
+...p.p..p.p.p.p..p..
+ppp..pp.ppp.ppp..p..
+#
+APRS -               House QTH (VHF)
+....................
+......q.............
+......q.............
+......q...q.........
+......q..qqq........
+......q.qqqqq.......
+......qqqqqqqq......
+......qqqqqqqqq.....
+.....qqqqqqqqqqq....
+....qqqqqqqqqqqqq...
+......q#######q.....
+......q#q###q#q.....
+......q###q###q.....
+......q###q###q.....
+......qqqqqqqqq.....
+....................
+....................
+....................
+....................
+....................
+#
+APRS .               X
+....................
+....................
+....................
+....................
+....................
+....................
+......j......j......
+.......j....j.......
+........j..j........
+.........jj.........
+.........jj.........
+........j..j........
+.......j....j.......
+......j......j......
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS /               Dot
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+........jjjj........
+.......jjjjjj.......
+.......jjjjjj.......
+.......jjjjjj.......
+.......jjjjjj.......
+........jjjj........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 0               Numerical Circle 0 (obsolete, use overlay)
+....................
+....................
+..qqqqqqqqqqqqqqqq..
+..qqqqqqqqqqqqqqqq..
+..qqqqqqmmmmqqqqqq..
+..qqqqqmmmmmmqqqqq..
+..qqqqmmmqqmmmqqqq..
+..qqqqmmqqqqmmqqqq..
+..qqqmmmqqqqmmmqqq..
+..qqqmmmqqqqmmmqqq..
+..qqqmmmqqqqmmmqqq..
+..qqqmmmqqqqmmmqqq..
+..qqqqmmqqqqmmqqqq..
+..qqqqmmmqqmmmqqqq..
+..qqqqqmmmmmmqqqqq..
+..qqqqqqmmmmqqqqqq..
+..qqqqqqqqqqqqqqqq..
+..qqqqqqqqqqqqqqqq..
+....................
+....................
+#
+APRS 1               Numerical Circle 1 (obsolete, use overlay)
+....................
+....................
+..ffffffffffffffff..
+..ffffffffffffffff..
+..ffffffffmmffffff..
+..fffffffmmmffffff..
+..ffffffmmmmffffff..
+..fffffmmmmmffffff..
+..fffffffmmmffffff..
+..fffffffmmmffffff..
+..fffffffmmmffffff..
+..fffffffmmmffffff..
+..fffffffmmmffffff..
+..fffffmmmmmmmffff..
+..fffffmmmmmmmffff..
+..ffffffffffffffff..
+..ffffffffffffffff..
+..ffffffffffffffff..
+....................
+....................
+#
+APRS 2               Numerical Circle 2 (obsolete, use overlay)
+....................
+....................
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+..jjjjmmmmmmmmjjjj..
+..jjjmmmmmmmmmmjjj..
+..jjjmmmjjjjmmmjjj..
+..jjjjjjjjjjmmmjjj..
+..jjjjjjjjjmmmjjjj..
+..jjjjjjjmmmjjjjjj..
+..jjjjjmmmjjjjjjjj..
+..jjjjmmmjjjjjjjjj..
+..jjjmmmmmmmmmmjjj..
+..jjjmmmmmmmmmmjjj..
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+..jjjjjjjjjjjjjjjj..
+....................
+....................
+#
+APRS 3               Numerical Circle 3 (obsolete, use overlay)
+....................
+....................
+..aaaaaaaaaaaaaaaa..
+..aaaaaaaaaaaaaaaa..
+..aaaaaaaaaaaaaaaa..
+..aaaammmmmmmaaaaa..
+..aaaammmmmmmmaaaa..
+..aaaaaaaaaammaaaa..
+..aaaaaaaaaammaaaa..
+..aaaaaammmmmaaaaa..
+..aaaaaammmmmaaaaa..
+..aaaaaaaaaammaaaa..
+..aaaaaaaaaammaaaa..
+..aaaammmmmmmmaaaa..
+..aaaammmmmmmaaaaa..
+..aaaaaaaaaaaaaaaa..
+..aaaaaaaaaaaaaaaa..
+..aaaaaaaaaaaaaaaa..
+....................
+....................
+#
+APRS 4               Numerical Circle 4 (obsolete, use overlay)
+....................
+....................
+..################..
+..################..
+..################..
+..#####ooo#ooo####..
+..#####ooo#ooo####..
+..####ooo##ooo####..
+..####ooo##ooo####..
+..###oooooooooo###..
+..###oooooooooo###..
+..#########ooo####..
+..#########ooo####..
+..#########ooo####..
+..#########ooo####..
+..################..
+..################..
+..################..
+....................
+....................
+#
+APRS 5               Numerical Circle 5 (obsolete, use overlay)
+....................
+....................
+..kkkkkkkkkkkkkkkk..
+..kkkkkkkkkkkkkkkk..
+..kkkkkkkkkkkkkkkk..
+..kkkkmmmmmmmmkkkk..
+..kkkkmmmmmmmmkkkk..
+..kkkkmmkkkkkkkkkk..
+..kkkkmmkkkkkkkkkk..
+..kkkkmmmmmmmkkkkk..
+..kkkkmmmmmmmmkkkk..
+..kkkkkkkkkkmmkkkk..
+..kkkkkkkkkkmmkkkk..
+..kkkkmmmmmmmmkkkk..
+..kkkkmmmmmmmkkkkk..
+..kkkkkkkkkkkkkkkk..
+..kkkkkkkkkkkkkkkk..
+..kkkkkkkkkkkkkkkk..
+....................
+....................
+#
+APRS 6               Numerical Circle 6 (obsolete, use overlay)
+....................
+....................
+..llllllllllllllll..
+..llllllllllllllll..
+..llllllllllllllll..
+..lllllmmmmmmmllll..
+..llllmmmmmmmmllll..
+..llllmmllllllllll..
+..llllmmllllllllll..
+..llllmmmmmmmlllll..
+..llllmmmmmmmmllll..
+..llllmmllllmmllll..
+..llllmmllllmmllll..
+..llllmmmmmmmmllll..
+..lllllmmmmmmlllll..
+..llllllllllllllll..
+..llllllllllllllll..
+..llllllllllllllll..
+....................
+....................
+#
+APRS 7               Numerical Circle 7 (obsolete, use overlay)
+....................
+....................
+..bbbbbbbbbbbbbbbb..
+..bbbbbbbbbbbbbbbb..
+..bbbbbbbbbbbbbbbb..
+..bbbbmmmmmmmbbbbb..
+..bbbbmmmmmmmbbbbb..
+..bbbbbbbbbmmbbbbb..
+..bbbbbbbbbmmbbbbb..
+..bbbbbbbbbmmbbbbb..
+..bbbbbbbbmmbbbbbb..
+..bbbbbbbbmmbbbbbb..
+..bbbbbbbbmmbbbbbb..
+..bbbbbbbmmbbbbbbb..
+..bbbbbbbmmbbbbbbb..
+..bbbbbbbmmbbbbbbb..
+..bbbbbbbbbbbbbbbb..
+..bbbbbbbbbbbbbbbb..
+....................
+....................
+#
+APRS 8               Numerical Circle 8 (obsolete, use overlay)
+....................
+....................
+..cccccccccccccccc..
+..cccccccccccccccc..
+..cccccccccccccccc..
+..cccccmmmmmmccccc..
+..ccccmmmmmmmmcccc..
+..ccccmmccccmmcccc..
+..ccccmmccccmmcccc..
+..cccccmmmmmmccccc..
+..cccccmmmmmmccccc..
+..ccccmmccccmmcccc..
+..ccccmmccccmmcccc..
+..ccccmmmmmmmmcccc..
+..cccccmmmmmmccccc..
+..cccccccccccccccc..
+..cccccccccccccccc..
+..cccccccccccccccc..
+....................
+....................
+#
+APRS 9               Numerical Circle 9 (obsolete, use overlay)
+....................
+....................
+..qqqqqqqqqqqqqqqq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmqqqqqqmmmmq..
+..qmmmqqqqqqqqmmmq..
+..qmmmqqmmmmqqmmmq..
+..qmmmqqmmmmqqmmmq..
+..qmmmqqqqqqqqmmmq..
+..qmmmmqqqqqqqmmmq..
+..qmmmmmmmmmqqmmmq..
+..qmmmmmmmmmqqmmmq..
+..qmmmqqqqqqqqmmmq..
+..qmmmqqqqqqqmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qqqqqqqqqqqqqqqq..
+....................
+....................
+#
+APRS :               Fire
+....................
+....................
+....q...............
+...q#q...........q..
+...qjq..........q#q.
+...q#q.........q##q.
+...qqq..qq.qq.q#qq..
+..q#q#qq#q.q#qq#q...
+...qq#q##qq#jqqq#q..
+...q#q#jfj##j#f#qq..
+..q#j#jj#j#jj#jjq...
+..qjjjfjjj#j#j#q....
+...qjjfjj#jjjjfq....
+....qjjffjjfjfjjq...
+...qjjffjfjjfjjfqq..
+...qjfffjjfjfjfjjq..
+..qjffjjfffjjffjq...
+..qjffjjfjffjjffjq..
+..qffffffffffffffq..
+....................
+#
+APRS ;               Campground (Portable Ops!)
+....................
+....................
+..........e.........
+..........e.........
+..........e.........
+..........e.........
+.........iei........
+.........iei........
+........ikeki.......
+.......ikkekki......
+......ikkceckki.....
+.....ikkkoeokkki....
+....ikkkcieickkki...
+...ikkkkoieiokkkki..
+....kkkciieiickkk...
+....kkkoiieiiokkk...
+....kkciiieiiickk...
+..eeeeeeeeeeeeeeee..
+....................
+....................
+#
+APRS <             l Motorcycle (SSID -10)
+....................
+....................
+....................
+.......ppp..........
+.......p............
+.......ppppp........
+......pp.........p..
+.....pppppp....pp...
+.pppppp####pppppppp.
+p.pmppp####pppppmp.p
+.pmppp.ppppppqpmmmp.
+pmmpmmppppppppppppmp
+pmpmmmppppppppmmmmmp
+.pmmmp..ppppp.pmmmp.
+..pmp..........pmp..
+...p............p...
+....................
+....................
+....................
+....................
+#
+APRS =             l Railroad Engine
+....................
+....................
+.....cmccmcccc......
+....ccccmc..........
+....pp..............
+..qqqqqq...qqqqqqq..
+...qqqq....qqqqqqq..
+....qq.....qq...qq..
+....qq.....qq...qq..
+....qq.....qq...qq..
+..qqqqqqqqqqqqqqqq..
+..qqqqqqqqqqqqqqqq..
+..qqqqqqqqqqqqqqqq..
+..qqqqqqqqqqqqqqqq..
+..qqqqqqqqqqqqqqqq..
+...q..q..qmmq.qmmq..
+..qmqqmq.qmmq.qmmq..
+...q..q...qq...qq...
+....................
+....................
+#
+APRS >             l Car (SSID -9)
+....................
+....................
+....................
+....................
+.........ppppp......
+........pcccncp.....
+.......pccccnccp....
+......pcccccncccp...
+...pppdqdddddddddp..
+..pjjjjdjjjjdjjjjjp.
+.pjjjjjdjjjjdjjjjjdp
+p#jjoojdjjjjdjjoojjp
+pjjonnodjjjjdjonnojp
+.ppqnnqpppppppqnnqp.
+....qq.........qq...
+....................
+....................
+....................
+....................
+....................
+#
+APRS ?               File Server
+....................
+....................
+pppp..p..p.....pppp.
+p.....p..p.....p....
+p.....p..p.....p....
+pppp..p..p.....pppp.
+p.....p..p.....p....
+p.....p..p.....p....
+p.....p..pppp..pppp.
+....................
+....................
+....................
+.ppp.pp.ppp..p.p.ppp
+p....p..p..p.p.p.p..
+p....p..p..p.p.p.p..
+.pp..pp.ppp..p.p.ppp
+...p.p..p.p..p.p.p..
+...p.p..p.p..p.p.p..
+ppp..pp.p..p..p..ppp
+....................
+#
+APRS @               Hurricane Future Prediction (dot)
+ppp..ppp...ppp..ppp.
+p..p.p..p..p....p..p
+ppp..ppp...ppp..p..p
+p....p.p...p....p..p
+p....p..p..ppp..ppp.
+....................
+....ll.....ll.......
+...ll....ll..ll.....
+...ll...llll...ll...
+....ll.lllllll......
+......lllllll.ll....
+...ll...llll...ll...
+.....ll..ll...ll....
+.......ll....ll.....
+....................
+ppp...ppp...ppppp...
+.p...p...p....p.....
+.p...p........p.....
+.p...p...p....p.....
+ppp...ppp.....p.....
+#
+APRS A               Aid Station
+....................
+....................
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhmmmmmmmmmmmmhh..
+..hhmmmmmmmmmmmmhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+....................
+....................
+#
+APRS B               BBS or PBBS
+....................
+....................
+....................
+....................
+....................
+...ggg..ggg...gg....
+...g..g.g..g.g..g...
+...g..g.g..g.g......
+...ggg..ggg...g.....
+...g..g.g..g..g.....
+...g..g.g..g...g....
+...g..g.g..g....g...
+...g..g.g..g.g..g...
+...gggg.ggg...gg....
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS C             l Canoe
+....................
+....................
+....................
+....................
+....................
+.............p......
+pppp........p...pppp
+peeppppppppppppppeep
+peeeeeeeeepeeeeeeeep
+.peeeeeeepeeeeeeeep.
+..peeeeepeeeeeeeep..
+...pppppppppppppp...
+......p.............
+.....p..............
+...ppp..............
+..ppp...............
+.ppp................
+....................
+....................
+....................
+#
+#APRS D
+#
+APRS E               Eyeball (eye catcher)
+....................
+....................
+........pppp........
+......pmmmmmmp......
+....pmmmmmmmmmmp....
+..pmmmmmhhhhmmmmmp..
+.pmmmmhhhhhhhhmmmmp.
+.pmmmmhhhhhhhhmmmmp.
+pmmmhhhhhpphhhhhmmmp
+pmmmhhhhpppphhhhmmmp
+pmmmhhhhpppphhhhmmmp
+pmmmhhhhhpphhhhhmmmp
+.pmmmmhhhhhhhhmmmmp.
+.pmmmmhhhhhhhhmmmmp.
+..pmmmmmhhhhmmmmmp..
+....pmmmmmmmmmmp....
+......pmmmmmmp......
+........pppp........
+....................
+....................
+#
+APRS F             l Farm Equipment
+....................
+....................
+....................
+....................
+....................
+............qqqqqqq.
+............qkkkkkq.
+...qq.......qkmmmkq.
+...qq.......qkmmmkq.
+...qq.......qkmmmkq.
+..qqqqqqqqqqkkkkkkq.
+.qkkkkkkkkkkkqqqqqq.
+.qkkkkkkkkkkqqqqqqq.
+..qqqkkkkkkqqqkkkqq.
+.qqqqqqqqqqqqqkkkqq.
+.qqqqq......qqkkkqq.
+.qqqqq......qqqqqqq.
+.qqqq........qqqqq..
+....................
+....................
+#
+APRS G               Grid Square (6-character)
+....................
+..q.q.q......q.q.q..
+..q.q.q.qjjq.q.q.q..
+..qqqqqqqqqqqqqqqq..
+..q.q.q.qjjq.q.q.q..
+..q.q.q.qjjq.q.q.q..
+........qjjq........
+........qjjq........
+........qjjq........
+........qjjq........
+.......qqjjqq.......
+.......qjqqjq.......
+...qq..qqjjqq..qq...
+..q..q.qqjjqq.q..q..
+..q....qjqqjq..q....
+..q.qq.qjqqjq...q...
+..q..q.qqjjqq.q..q..
+...qq..qqqqqq..qq...
+....................
+....................
+#
+APRS H               Hotel (blue bed icon)
+....................
+....................
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hmhhhhhhhhhhhhhh..
+..hmhhhhhhhhhhhhhh..
+..hmhhhhhhhhhhhhhh..
+..hmhmmhhmmmmmmhmh..
+..hmhmmmmmmmmmmhmh..
+..hmhmmhhmmmmmmhmh..
+..hmhhhhhhhhhhhhmh..
+..hmmmmmmmmmmmmmmh..
+..hmhhhhhhhhhhhhmh..
+..hmhhhhhhhhhhhhmh..
+..hhhhhhhhhhhhhhhh..
+....................
+....................
+#
+APRS I               TCP/IP on air network station
+....................
+....................
+....................
+.#################..
+.##iiiii#iii#iii##..
+..###i###i#i#i#i#...
+..###i###i###iii#...
+..###i###i#i#i###...
+...##i###iii#i##....
+...#############....
+...#############....
+...###iii#iii###....
+....###i##i#i##.....
+....###i##iii##.....
+....###i##i####.....
+.....#iii#i###......
+.....#########......
+.....#########......
+....................
+....................
+#
+#APRS J
+#
+APRS K               School
+.........pp.........
+........p##p........
+.......p####p.......
+......p######p......
+.....p########p.....
+....p##########p....
+...p############p...
+..pppppppppppppppp..
+..p##############p..
+..p##pp##ppp##pp#p..
+..p##pp##ppp##pp#p..
+..p######ppp#####p..
+..pppppppppppppppp..
+....................
+....................
+.pp....p...........p
+p......p...........p
+.p..pp.ppp.ppp.ppp.p
+..p.p..p.p.p.p.p.p.p
+pp..pp.p.p.ppp.ppp.p
+#
+APRS L               Logged-on Internet User (Desktop Computer)
+qqqqq.qqqqqqqqqqqqqq
+qmqmq.qqqqqqqqqqqqqq
+qqmqq.qqmmmmmmmmmmqq
+qmqmq.qqmmmqmmmqmmqq
+qqmqq.qqmmmmqmqmmmqq
+qmqmq.qqmmmmmqmmmmqq
+qqmqq.qqmmmmqmqmmmqq
+qmqmq.qqmmmqmmmqmmqq
+qqmqq.qqmmmmmmmmmmqq
+qmqmq.qqqqqqqqqqqqqq
+qqmqq.qqqqqqqqqqqqqq
+qmqmq.q............q
+qqqqq.qqqqqqqqqqqqqq
+....................
+....................
+....qqqqqqqqqqqqqqqq
+...qmqmqmqmqmqmqmqq.
+..qqmqmqmqmqmqmqmq..
+.qmmqmqmqmqmqmqmq...
+qqqqqqqqqqqqqqqq....
+#
+APRS M               MacAPRS
+....................
+....................
+...........kk.......
+..........kkk.......
+.........kkk........
+.........kkk........
+.....kkkkkkkkkk.....
+....kkkkkkkkkkkk....
+...############.....
+...###########......
+...aaaaaaaaaaa......
+...aaaaaaaaaaa......
+...jjjjjjjjjjjj.....
+...jjjjjjjjjjjj.....
+....bbbbbbbbbbbb....
+....bbbbbbbbbbbb....
+.....llllllllll.....
+......llllllll......
+....................
+....................
+#
+APRS N               NTS Station
+....................
+.......gggggg.......
+......gggggggg......
+.....ggmmgggmgg.....
+.....ggmgmggmgg.....
+....gggmggmgmggg....
+....gggmgggmmggg....
+...gggggggggggggg...
+...ggggmmmmmmgggg...
+..gggggggmmggggggg..
+..gggggggmmggggggg..
+...gggggggggggggg...
+...gggggmmmmmgggg...
+....gggmgggggggg....
+....ggggmmmmgggg....
+.....gggggggmgg.....
+.....ggmmmmmggg.....
+......gggggggg......
+.......gggggg.......
+....................
+#
+APRS O               Balloon (SSID -11)
+....................
+....................
+......hffjffh.......
+.....h##kjk##h......
+....h###jjj###h.....
+...h####jjj####h....
+...###jj###jj###....
+...jjjjj###jjjjj....
+...jjjjj###jjjjj....
+...jjjblllllbjjj....
+....lllllllllll.....
+.....lllllllll......
+......lllllll.......
+.......h.a.h........
+........pcp.........
+.......fefef........
+.......fefef........
+.......oqqqo........
+....................
+....................
+#
+APRS P             l Police
+....................
+....................
+..........ll........
+..........ll........
+.........ppppp......
+........pcccncp.....
+.......pccccnccp....
+......pcccccncccp...
+...pppnqnnnnnnnnnp..
+..pmmmmkkkkkkmmmmmp.
+.pmmmmmkccckkmmmmmep
+p#mmoomkkkkkkmmoommp
+pmmonnokkkkkkmonnomp
+.ppqnnqpppppppqnnqp.
+....qq.........qq...
+....................
+....................
+....................
+....................
+....................
+#
+#APRS Q
+#
+APRS R             l Recreational Vehicle (SSID -13) (motor-home)
+....................
+....................
+....................
+....................
+....................
+........pppppppppp..
+..pqqqqqqqqqqqqqqqqq
+.pmmmmmmmmmmmmmmmmmq
+ppppmmmmmpppmmpppmmq
+qpppmmmmmpppmmpppmmq
+qmmmmmmmmmmmmmmmmmmq
+qmmmmmmmqmmmqmmmqmmq
+qmmmmmmmmmmmmmmmmmmq
+qqqqqqqqqqqqqqqqqqqq
+.qqqq.......qqqq....
+..qq.........qq.....
+....................
+....................
+....................
+....................
+#
+APRS S             l Space Shuttle
+................qqq.
+...............qmcq.
+..............qmmcq.
+.............qnmecq.
+............qnmmhcq.
+..........qqnmmmmcq.
+........pqnmmmmmcnqq
+...oqqqonnnnnnnncmmq
+.qqomcmmmmmmmmmcmmmq
+qqmqcnmmmmmmmmmcqqqn
+.qqomcmmmmmmmmmcmmmq
+...oqqqonnnnnnnncmmq
+........pqnmmmmmcnqq
+..........qqnmmmmcq.
+............qnmmecq.
+.............qnhlcq.
+..............qmmcq.
+...............qmcq.
+................qqq.
+....................
+#
+APRS T               SSTV
+..pppp.......pppp...
+.p....p.....p....p..
+p......p...p......p.
+p....... ..p........
+.pppppp.....pppppp..
+.......p..........p.
+p......p...p......p.
+.p....p.....p....p..
+..pppp.......pppp...
+....................
+....................
+ppppppp....p.......p
+...p.......p.......p
+...p.......p.......p
+...p........p.....p.
+...p........p.....p.
+...p.........p...p..
+...p.........p...p..
+...p..........p.p...
+...p...........p....
+#
+APRS U             l Bus (SSID -2)
+....................
+....................
+....................
+....................
+....................
+.....aaaaaaaaaaaaaa.
+....a##############a
+...ac#cc#cc#cc#cc#ca
+..acc#cc#cc#cc#cc#ca
+aa#################a
+a##################a
+a##################a
+aannaaaaaaaaaaaannaa
+.qooq..........qooq.
+..qq............qq..
+....................
+....................
+....................
+....................
+....................
+#
+APRS V               ATV
+.........pp.........
+........p..p........
+.......p....p.......
+......p. ....p......
+.....p........p.....
+....pppppppppppp....
+...p............p...
+..p..............p..
+.p................p.
+....................
+....................
+ppppppp....p.......p
+...p.......p.......p
+...p.......p.......p
+...p........p.....p.
+...p........p.....p.
+...p.........p...p..
+...p.........p...p..
+...p..........p.p...
+...p...........p....
+#
+APRS W               National Weather Service Site
+....................
+....................
+.......gggggg.......
+.....gghhhhhhgg.....
+....ghhhhhhhhhhg....
+...ghhhhhhhhhhhhg...
+...ghhhhhhhhhhhhg...
+..gmmhhhmmhmmhhmmg..
+..gmmhhhmmhmmmmmmg..
+..gmmhhhmmhhmmmmhg..
+..gmmhmhmmhhmmmmhg..
+..gmmmmmmmhmmmmmmg..
+..gmmmhmmmhmmhhmmg..
+...ghhhhhhhhhhhhg...
+...ghhhhhhhhhhhhg...
+....ghhhhhhhhhhg....
+.....gghhhhhhgg.....
+.......gggggg.......
+....................
+....................
+#
+APRS X             l Helicopter (SSID -6)
+....................
+....................
+....................
+..mqqmqqmqqmqqm.....
+qmqmqmqmqmqmqmqmq...
+..qmqqmqqmqqmqq.....
+.......mq...........
+...qqqqqq...........
+..qqqqjjq.......mmm.
+.qmmmqjjjq.....mqqqm
+qmmmmqjjjjqjqjqmqmqm
+qqqqqqjjjjjqjqjmqqqm
+.qjjjjjjjq......mmm.
+..qjqqjqq...........
+...jq.jq............
+j..jq.jq............
+qjjjjjjjjjjj........
+.qqqqqqqqqqq........
+....................
+....................
+#
+APRS Y             l Yacht (sail boat) (SSID -5)
+....................
+....................
+...........q........
+..........qqq.......
+.........qcqcq......
+........qccqcq......
+.......qcccqcq......
+......qccccqccq.....
+.....qcccccqccq.....
+....qccccccqcccq....
+...qcccccccqcccq....
+..qqqqqqqqqqqqqqqq..
+...qkkkkkkkkkkkkq...
+....qkkkkkkkkkkq....
+.....qqqqqqqqqq.....
+....................
+....................
+....................
+....................
+....................
+#
+APRS Z               WinAPRS
+....................
+....................
+....................
+.........qqqqqq.....
+........qjjjqkkqq...
+.qq...qqjjjjqkkkkq..
+...qqq.qjjjjqkkkkq..
+.qq...qqjjjjqkkkkq..
+...qqq.qjjjjqkkkkq..
+.qq...qqjjqqqqkkkq..
+...qqq.qqqllq#qqkq..
+.qq...qqllllq###qq..
+...qqq.qllllq####q..
+.qq...qqllllq####q..
+...qqq.qllllq####q..
+.qq...qqllllq####q..
+...qqq.qlqqqqq###q..
+.qq...qqq.....qq#q..
+...qqq..........qq..
+....................
+#
+APRS [             l Jogger
+....................
+....................
+....................
+....................
+.......qq...........
+.......qq...........
+.......qqllpp.......
+...p...lelleep......
+...pe...lll..ep.....
+....pe..lll..ep.....
+.....ppqqll..ep.....
+......qqqqqq........
+.....qqqqqqq........
+.....qqq..qqqqq.....
+......llq..qllq.....
+.....qqq......q.....
+....................
+....................
+....................
+....................
+#
+APRS \               Triangle (DF station)
+....................
+....................
+.........qq.........
+........q##q........
+........q##q........
+.......q####q.......
+.......q####q.......
+......q######q......
+......q######q......
+.....q########q.....
+.....q########q.....
+....q#qqq##qqq#q....
+....q#q##q#q###q....
+...q##q##q#qq###q...
+...q##q##q#q####q...
+..q###qqq##q#####q..
+..q##############q..
+..qqqqqqqqqqqqqqqq..
+....................
+....................
+#
+APRS ]               Mail/Post Office
+....................
+....................
+.....llllllllll.....
+...llllllllllllll...
+..llllmhmhmhmhllll..
+..lllmhmhmhmhmhlll..
+..llllllllllllllll..
+..llllllllllllllll..
+..llmlmllmllmlmlll..
+..llmmmlmlmlmlmlll..
+..llmhmlmmmlmlmlll..
+..llmlmlmlmlmlmlll..
+..llmlmlmlmlmlmmll..
+..llllllllllllllll..
+..llllllllllllllll..
+..llll........llll..
+..lll..........lll..
+..lll..........lll..
+....................
+....................
+#
+APRS ^             l Large Aircraft
+....................
+....................
+.........oo.........
+.........oo.........
+........ooo.........
+........ooo.........
+........ooo......o..
+.......oooo.....oo..
+.......oooo....ooo..
+..oooooooooooooooo..
+..oooooooooooooooo..
+.......oooo....ooo..
+.......oooo.....oo..
+........ooo......o..
+........ooo.........
+........ooo.........
+.........oo.........
+.........oo.........
+....................
+....................
+#
+APRS _               Weather Station (blue)
+....................
+....................
+.......hhhhhh.......
+.....hhhhhhhhhh.....
+....hhhhhhhhhhhh....
+...hhhhhhhhhhhhhh...
+...hhhhhhhhhhhhhh...
+..hmmhhhmmhmmhhmmh..
+..hmmhhhmmhmmmmmmh..
+..hmmhhhmmhhmmmmhh..
+..hmmhmhmmhhmmmmhh..
+..hmmmmmmmhmmmmmmh..
+..hmmmhmmmhmmhhmmh..
+...hhhhhhhhhhhhhh...
+...hhhhhhhhhhhhhh...
+....hhhhhhhhhhhh....
+.....hhhhhhhhhh.....
+.......hhhhhh.......
+....................
+....................
+#
+APRS `               Dish Antenna
+....................
+....................
+..q.................
+..qq................
+..qoq...............
+..qooq..............
+...qooqqqqqqqq......
+...qoooq....qq......
+...qooooq..q.q......
+...pqooooqq..q......
+....qoooooq..q......
+.....qoooooq.q......
+....qpqoooooqq......
+...qqqpqoooooq......
+..qqqqqpqoooooq.....
+..qqqqqq.qqooooq....
+..qqqqqqp..pqqooq...
+..qqqqqqqp....qqqq..
+....................
+....................
+#
+APRS a             l Ambulance (SSID -1)
+....................
+....................
+....................
+....................
+....................
+.......qqqqqqqqqqq..
+......qqmmjjmmmmmq..
+.....qoqmmjjmmmmmq..
+..qqqqqqjjjjjjmmmq..
+..qmmmmmjjjjjjmmmq..
+..qmmmmmmmjjmmmmmq..
+..qmqqqqmmjjqqqqmq..
+..qqqqqqqmmqqqqqqq..
+..qqqoqqqqqqqqoqqq..
+....qqoq....qoqq....
+.....qq......qq.....
+....................
+....................
+....................
+....................
+#
+APRS b             l Bicycle (SSID -4)
+....................
+....................
+.........q..........
+.........qqq........
+.........q..........
+........q...........
+.......qq...qqq.....
+....qqqmqq..q.......
+...qq..m.qqqq.......
+..qq......qqqq......
+..q....m...q.qq.....
+..q...m....q..qq....
+..q....m...q...qq...
+..q.....m..q...qq...
+..qq......qq..q..q..
+...qq....qq...q..q..
+....qqqqqq.....qq...
+....................
+....................
+....................
+#
+APRS c              Incident Command Post
+qqqqqqqqqqqqqqqqqqqq
+qmmmmmmmmmmmmmmmmmlq
+qmmmmmmmmmmmmmmmmllq
+qmmmmmmmmmmmmmmmlllq
+qmmmmmmmmmmmmmmllllq
+qmmmmmmmmmmmmmlllllq
+qmmmmmmmmmmmmllllllq
+qmmmmmmmmmmmlllllllq
+qmmmmmmmmmmllllllllq
+qmmmmmmmmmlllllllllq
+qmmmmmmmmllllllllllq
+qmmmmmmmlllllllllllq
+qmmmmmmllllllllllllq
+qmmmmmlllllllllllllq
+qmmmmllllllllllllllq
+qmmmlllllllllllllllq
+qmmllllllllllllllllq
+qmlllllllllllllllllq
+qllllllllllllllllllq
+qqqqqqqqqqqqqqqqqqqq
+#
+APRS d               Dual Garage (Fire Department)
+....................
+.........qq.........
+........qjjq........
+.......qjjjjq.......
+......qjjjjjjq......
+.....qjjjjjjjjq.....
+....qjjjjjjjjjjq....
+...qjjjjjjjjjjjjq...
+..qqqqqqqqqqqqqqqq..
+..qjjjjjjjjjjjjjjq..
+..qjmmmjmjmmmjmmjq..
+..qjmjjjmjmjmjmjjq..
+..qjmmjjmjmmmjmmjq..
+..qjmjjjmjmjmjmjjq..
+..qjmjjjmjmjmjmmjq..
+..qjjjjjjjjjjjjjjq..
+..qqqqqqqqqqqqqqqq..
+....................
+....................
+....................
+#
+APRS e             l Horse (equestrian)
+....................
+....................
+....................
+..........qq........
+.........qqqq.......
+..........qq........
+.........qqq........
+...qq...q.qq........
+..qqqq....qq........
+.qqqqqqqqqqqqqqqq...
+.qq..qqqqqqqqqqq.q..
+......qqqqqqqqqq..q.
+.......qqq....q.q...
+......q.q....q...q..
+.....q...q....q..q..
+.....q....q....q..q.
+....................
+....................
+....................
+....................
+#
+APRS f             l Fire Truck (SSID -3)
+....................
+....................
+....................
+....................
+....................
+....................
+...jjjjmmmmmmmmmmmm.
+..jcccjjmjjmjjmjjmj.
+.jccccjjmjjmjjmjjmj.
+.jjjjjjmmmmmmmmmmmm.
+.jjjjjjjjjjjjjjjjoo.
+.oojqjjjjjjqjjjqjoo.
+...qqq....qqq.qqq...
+....q......q...q....
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS g               Glider
+....................
+....................
+....................
+....................
+..jjjj..............
+..jaaajjjj..........
+..jaaaaaaajjjj......
+..j###########jjjj..
+..jjjjjjjjjjjjjjjj..
+....p..........p....
+.....p........p.....
+......p......p......
+.......pccccp.......
+.....gggggggggg.....
+.....ggggggg.gg.....
+....................
+....................
+....................
+....................
+....................
+#
+APRS h               Hospital
+....................
+.........qq.........
+........qmmq........
+.......qmmmmq.......
+......qmmmmmmq......
+.....qmmmmmmmmq.....
+....qmmmmmmmmmmq....
+...qmmmmmmmmmmmmq...
+..qqqqqqqqqqqqqqqq..
+...qmmmmmjjmmmmmq...
+...qmmmmmjjmmmmmq...
+...qmmmjjjjjjmmmq...
+...qmmmjjjjjjmmmq...
+...qmmmjjjjjjmmmq...
+...qmmmmmjjmmmmmq...
+...qmmmmmjjmmmmmq...
+...qqqqqqqqqqqqqq...
+....................
+....................
+....................
+#
+APRS i               IOTA (island on the air)
+....................
+......k..k..........
+....kkkkkkkkkk......
+....kkkiiiik#kkk....
+..kk##kkii#kk#k.kk..
+..k#kkk#ffk#k.#k....
+.k.k.k#.ffk....k....
+k..k..k.ff..........
+........ff..........
+........ff..........
+........ff..........
+....aeaeffaeaea.....
+..eaeaeaeaeaeaeaea..
+.haeaeaeaeaeaeaeaeh.
+.hhaeaeaeaeaeaeaehh.
+..hhhhhhhhhhhhhhhh..
+...hhhhhhhhhhhhh....
+....................
+....................
+....................
+#
+APRS j             l Jeep (SSID -12)
+....................
+....................
+....................
+....................
+..........koooooo...
+.........k...o...o..
+........k...co...co.
+.......kkp..no...po.
+.kkkkkkkkc..nkkkkkkq
+k#kkkkkkk..okkkkkkkq
+nkqqqkkkkpppkkqqqkkq
+nqqcqqkkkkkkkqqcqqnn
+.qcmcqoonnnnnqcmcqq.
+.oqcqo.......oqcqo..
+..oqo.........oqo...
+....................
+....................
+....................
+....................
+....................
+#
+APRS k             l Truck (SSID -14)
+....................
+....................
+....................
+....................
+........jjj.........
+.......jjmj.........
+......jjmmj.........
+.....jjmmmj.........
+..jjjjpjjqpjjjjjjj..
+..jjjjpjjjpjjjjjjj..
+..jjjjjpjjpjjjjjjj..
+..qpppjppppjjpppjq..
+..qpcpjjjjjjjpcpjq..
+...ppp.......ppp....
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS l               Logged-on Laptop
+....................
+....................
+....qqqqqqqqqqqqqqqq
+....qmmmmmmmmmmmmmmq
+....qmmmmmmmmmmmmmmq
+....qmmmmmmmmmmmmmmq
+....qmmmmmqmmqmmmmmq
+....qmmmmmmqqmmmmmmq
+....qmmmmmmqqmmmmmmq
+....qmmmmmqmmqmmmmmq
+....qmmmmmmmmmmmmmmq
+....qmmmmmmmmmmmmmmq
+....qmmmmmmmmmmmmmmq
+....qqqqqqqqqqqqqqqq
+...qmqmqmqmqmqmqmqq.
+..qqmqmqmqmqmqmqmq..
+.qmmqmqmqmqmqmqmq...
+qqqqqqqqqqqqqqqq....
+....................
+....................
+#
+APRS m               Mic-Repeater
+....................
+.......g....g.......
+.......gg..gg.......
+.......g.gg.g.......
+.......g....g.......
+.......g....g.......
+....................
+........gggg........
+.........gg.........
+.........gg.........
+........gggg........
+....................
+........gggg........
+.......g....g.......
+.......g............
+.......g....g.......
+........gggg........
+..ggggg......ggggg..
+....................
+....................
+#
+APRS n               Node
+....................
+....................
+....................
+....................
+....................
+....................
+......qqq..qq.......
+......qqq..qq.......
+......qqqq.qq.......
+......qqqq.qq.......
+......qq.qqqq.......
+......qq.qqqq.......
+......qq..qqq.......
+......qq..qqq.......
+......qq...qq.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS o               Emergency Operations Center
+....................
+.........pp.........
+........pjjp........
+.......pjjjjp.......
+......pjjjjjjp......
+.....pjjjjjjjjp.....
+....pjjjjjjjjjjp....
+...pjjjjjjjjjjjjp...
+..pjjjjjjjjjjjjjjp..
+...pjmmjjmjjjmjjp...
+...pjmjjmjmjmjmjp...
+...pjmjjmjmjmjjjp...
+...pjmmjmjmjmjjjp...
+...pjmjjmjmjmjjjp...
+...pjmjjmjmjmjmjp...
+...pjmmjjmjjjmjjp...
+...pjjjjjjjjjjjjp...
+....................
+....................
+....................
+#
+APRS p             l Rover (puppy dog)
+....................
+....................
+....................
+....................
+....qqqq............
+....qqqq.........q..
+...qmqmq........qq..
+..qqmmmqq......qmq..
+..qqqqmmmqqqqqqmmq..
+.....qmmmmqqqqmmqq..
+......qqmmmmmmmmq...
+......qqmmmmmmmmq...
+......qmqqqqqmmmq...
+......qmq....qmmq...
+......qmq.....qmq...
+.....qqqq....qqmq...
+.....qqq.....qqq....
+....................
+....................
+....................
+#
+APRS q               Grid Square Above 128m
+....................
+..q.q.q......q.q.q..
+..q.q.q.ikki.q.q.q..
+..qqqqqqqqqqqqqqqq..
+..q.q.q.ikki.q.q.q..
+..q.q.q.ikki.q.q.q..
+........ikki........
+........ikki........
+........ikki........
+........ikki........
+.......iikkii.......
+.......ikiiki.......
+...qq..iikkii..qq...
+..q..q.iikkii.q..q..
+..q....ikiiki..q....
+..q.qq.ikiiki...q...
+..q..q.iikkii.q..q..
+...qq..iiiiii..qq...
+....................
+....................
+#
+APRS r               Antenna, like radio station
+....................
+..q.q.q......q.q.q..
+..q.q.q.lhhl.q.q.q..
+..qqqqqqqqqqqqqqqq..
+..q.q.q.lhhl.q.q.q..
+..q.q.q.lhhl.q.q.q..
+........lhhl........
+........lhhl........
+........lhhl........
+........lhhl........
+.......llhhll.......
+.......lhllhl.......
+.......llhhll.......
+.......llhhll.......
+.......lhllhl.......
+.......lhllhl.......
+.......llhhll.......
+.......llllll.......
+....................
+....................
+#
+APRS s             l Ship (power boat) (SSID -8)
+....................
+....................
+....................
+....................
+....................
+....................
+........qqqq.....q..
+.......qqccq....q...
+......qqqqqq...q....
+..iiiiiiiiiiiiiiii..
+..iiiiiiiiiiiiiiii..
+...iiiiiiiiiiiiiii..
+....iiiiiiiiiiiiii..
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS t               Truck Stop
+....................
+....................
+..gggggggggggggggg..
+..gggggggggggggggg..
+..gmmmmmmmmggggggg..
+..gmmmmmmmmggggggg..
+..ggggmmggggmmmmgg..
+..ggggmmgggmmmmmmg..
+..ggggmmgggmmggmmg..
+..ggggmmgggmmggggg..
+..ggggmmggggmmgggg..
+..ggggmmgggggmmggg..
+..ggggmmggggggmmgg..
+..ggggmmgggggggmmg..
+..gggggggggmmggmmg..
+..gggggggggmmmmmmg..
+..ggggggggggmmmmgg..
+..gggggggggggggggg..
+....................
+....................
+#
+APRS u             l Truck (18-wheeler)
+....................
+....................
+....................
+....................
+....................
+....................
+.llll.llllllllllllll
+.lcll.llllllllllllll
+.lcll.llgggllgglggll
+lllll.llllllllllllll
+lllll.llllllllllllll
+lnlnlqnnnllllllnnnll
+oqoqooqoqo....oqoqo.
+.o....o.o......o.o..
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS v             l Van (SSID -15)
+....................
+....................
+....................
+....................
+....................
+.......hhhhhhhhhhh..
+......hccchccchccch.
+.....hcccchccchccch.
+....hccccchccchccch.
+..hhhphhhhhhhhhhhhh.
+.hhhhhhhhhhhhhhhhhj.
+.hhhhhhhhhhhhhhhhhh.
+.ohqqhhhhhhhhhhqqho.
+.hqccqhhhhhhhhqccqh.
+..qccq........qccq..
+...qq..........qq...
+....................
+....................
+....................
+....................
+#
+APRS w               Water Station
+....................
+....................
+..gggggggggggggggg..
+..gggggggggggggggg..
+..gmggmgggggggmmgg..
+..gmggmggggggmggmg..
+..gmggmggggggmggmg..
+..gmggmggggggmggmg..
+..gmmmmggmmggmggmg..
+..gmggmgmggmgmggmg..
+..gmggmggggmgmggmg..
+..gmggmggggmgmggmg..
+..gmggmgggmggmggmg..
+..gmggmggmggggmmgg..
+..ggggggmggggggggg..
+..ggggggmmmmgggggg..
+..gggggggggggggggg..
+..gggggggggggggggg..
+....................
+....................
+#
+APRS x               X-APRS (Unix)
+....................
+....................
+....................
+.qqqq............qq.
+..qqqq..........qq..
+...qqqq........qq...
+....qqqq......qq....
+.....qqqq....qq.....
+......qqqq..qq......
+.......qqq.qq.......
+.......qq.qqq.......
+......qq..qqqq......
+.....qq....qqqq.....
+....qq......qqqq....
+...qq........qqqq...
+..qq..........qqqq..
+.qq............qqqq.
+....................
+....................
+....................
+#
+APRS y               Yagi at QTH
+....................
+..q.q.q.q.q.........
+..qqqqqqqqq.........
+..q.q.q.q.q.........
+......q.............
+......q..qqq........
+......q.qqqqq.......
+......qqqqqqqq......
+......qqqqqqqqq.....
+.....qqqqqqqqqqq....
+....qqqqqqqqqqqqq...
+......q#######q.....
+......q#q###q#q.....
+......q###q###q.....
+......q###q###q.....
+......qqqqqqqqq.....
+....................
+....................
+....................
+....................
+#
+#APRS z
+#
+#APRS {
+#
+#APRS |               Reserved - TNC Stream Switch
+#
+#APRS }
+#
+#APRS ~               Reserved - TNC Stream Switch
+#
+#
+#
+# -----------------------------------
+# -----------------------------------
+#
+# Secondary table section starts here
+# -----------------------------------
+# -----------------------------------
+#
+#
+#
+TABLE \
+#
+APRS !               Emergency
+....................
+.........jj.........
+........jjjj........
+........jjjj........
+.......jjmmjj.......
+.......jjmmjj.......
+......jjmqqmjj......
+......jjmqqmjj......
+.....jjmmqqmmjj.....
+.....jjmmqqmmjj.....
+....jjmmmqqmmmjj....
+....jjmmmqqmmmjj....
+...jjmmmmmmmmmmjj...
+...jjmmmmqqmmmmjj...
+..jjmmmmmqqmmmmmjj..
+..jjmmmmmmmmmmmmjj..
+.jjjjjjjjjjjjjjjjjj.
+..jjjjjjjjjjjjjjjj..
+....................
+....................
+#
+#APRS "               Reserved
+#
+APRS #               Digi (green star) (w overlay)
+....................
+....................
+.........kk.........
+.........kk.........
+........kmmk........
+........kmmk........
+..kkkkkkkmmkkkkkkk..
+...kmmmmmmmmmmmmk...
+....kmmmmmmmmmmk....
+.....kmmmmmmmmk.....
+.....kmmmmmmmmk.....
+....kmmmmmmmmmmk....
+...kmmmmmmmmmmmmk...
+..kkkkkkkmmkkkkkkk..
+........kmmk........
+........kmmk........
+.........kk.........
+.........kk.........
+....................
+....................
+#
+APRS $               Bank or ATM (green box)
+....................
+....................
+....kkkkkkkkkkk.....
+...kkkkkmkmkkkkk....
+..kkkkkmmmmmkkkkk...
+..kkkkmkmkmkmkkkk...
+..kkkkmkmkmkkkkkk...
+..kkkkmkmkmkkkkkk...
+..kkkkkmmkmkkkkkk...
+..kkkkkkmkmkkkkkk...
+..kkkkkkmmmkkkkkk...
+..kkkkkkmkmmkkkkk...
+..kkkkkkmkmkmkkkk...
+..kkkkkkmkmkmkkkk...
+..kkkkmkmkmkmkkkk...
+..kkkkkmmmmmkkkkk...
+...kkkkkmkmkkkkk....
+....kkkkkkkkkkk.....
+....................
+....................
+#
+APRS %               Power Plant (w overlay)
+nnoooooooooonn......
+..nnnooooooooon.....
+.....nnnooooooonn...
+........nnnoooooon..
+...........nnnoooon.
+..............nnnoon
+................qqqq
+................qqqq
+..........q...q.qqqq
+.........qq..qq.qqqq
+........qqq.qqq.qqqq
+......qqqqqqqqqqqqqq
+......qqqqqqqq#qqqqq
+......qqqqqqq#qqqqqq
+......qqqqqq#qqqqqqq
+......qqqqqqq#qqqqqq
+......qqqqqqqq#qqqqq
+......qqqqqqq#qqqqqq
+......qqqqqq#qqqqqqq
+......qqqqqqqqqqqqqq
+#
+APRS &               Any Gateway (diamond) (w overlay)
+....................
+....................
+.........qq.........
+........qqqq........
+.......qqqqqq.......
+......qqmmmmqq......
+.....qqmmmmmmqq.....
+....qqmmmmmmmmqq....
+...qqmmmmmmmmmmqq...
+..qqqmmmmmmmmmmqqq..
+..qqqmmmmmmmmmmqqq..
+...qqmmmmmmmmmmqq...
+....qqmmmmmmmmqq....
+.....qqmmmmmmqq.....
+......qqmmmmqq......
+.......qqqqqq.......
+........qqqq........
+.........qq.........
+....................
+....................
+#
+APRS '               Crash Site
+..ppppppppp.........
+....pppppppp........
+.......ppppp........
+.......ppppp........
+.......pppp.........
+......pppp..........
+.....ppp........j...
+.....ppp.......jmj..
+......ppp.....jmmj..
+.......ppp....jmaj..
+..jjj....pp...jamj..
+..jmmj...pp..jammj..
+..jmmmj.p...jmmmj...
+...jmmmjj..jmmmj....
+....jmmmj.jmmmj.....
+.....jmmjjjjjj......
+..kkkkjjjjjjjkkkkk..
+..ffffffffffffffff..
+j.....j.j...........
+..jj..j..j..........
+#
+APRS (               Cloudy
+....................
+....................
+..ccccccccc.........
+...ccccccccccc......
+.....ccnccccccc.....
+........ncccccccc...
+...cccccccccccccc...
+..ccccccccnccccccc..
+..cccccccccncccccc..
+..cccccccccncccccc..
+..ccccccccnccccccc..
+..nnnccnnnccccccnn..
+...nnpppnnnppppnn...
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS )               MEO (MODIS EARTH OBSERVATION)
+....................
+....................
+....................
+....................
+....................
+....jjjjjqqjjjjj....
+....jqqjjqqjjqqj....
+....jjjqjqqjqjjj....
+....jjjjqqqqjjjj....
+....jqqqqqqqqqqj....
+....jqqqqqqqqqqj....
+....jjjjqqqqjjjj....
+....jjjqjqqjqjjj....
+....jqqjjqqjjqqj....
+....jjjjjqqjjjjj....
+....................
+....................
+....................
+....................
+....................
+#
+APRS *               Snow
+....................
+....................
+............h.......
+...........hh.......
+....hh....hhh.......
+....hhhh..hhh.......
+.....hhhh.hhh.......
+......hhhhhh..hhhh..
+......hhhhhhhhhhh...
+.......hhhhhhhhh....
+....hhhhhhhhh.......
+...hhhhhhhhhhh......
+..hhhh..hhhhhh......
+........hh.hhhh.....
+.......hhh..hhhh....
+.......hhh....hh....
+.......hh...........
+.......h............
+....................
+....................
+#
+APRS +               Church
+....................
+....................
+.........qq.........
+.........qq.........
+.........qq.........
+...qqqqqqqqqqqqqq...
+...qqqqqqqqqqqqqq...
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+....................
+....................
+#
+APRS ,               Girl Scouts
+....................
+....................
+......jjjjjjj.......
+......j.....j.......
+.......j...j........
+..jj...j...j...jjj..
+..j.jjjj...jjjj..j..
+..j..............j..
+..j..............j..
+..j..............j..
+..j..............j..
+..jjjj.......jjjjj..
+......j.....j.......
+.......j...j........
+........j.j.........
+.ppp.....j.......p..
+p................p..
+.pp..pp.ppp.p.p.ppp.
+...p.p..p.p.p.p..p..
+ppp..pp.ppp.ppp..p..
+#
+APRS -               House (HF)
+....................
+.........qqq........
+..q..q....q...qqqq..
+..q..q....q...q.....
+..qqqq....q...qqq...
+..q..q....q...q.....
+..q..q...qqq..q.....
+........qqqqq.......
+.......qqqqqqq......
+......qqqqqqqqq.....
+.....qqqqqqqqqqq....
+....qqqqqqqqqqqqq...
+......q#######q.....
+......q#q###q#q.....
+......q###q###q.....
+......q###q###q.....
+......qqqqqqqqq.....
+....................
+....................
+....................
+#
+APRS .               Ambiguous Plot (Big Question Mark)
+.....jjjjjjjjjj.....
+....jjjjjjjjjjjj....
+..jjjj........jjjj..
+.jjj............jjj.
+jjj..............jjj
+jjj..............jjj
+.................jjj
+................jjj.
+...............jjj..
+..............jjj...
+...........jjjjj....
+........jjjjjj......
+........jjjj........
+........jjjj........
+........jjjj........
+....................
+....................
+........jjjj........
+........jjjj........
+........jjjj........
+#
+APRS /               Waypoint (destination)
+..q.......q.qqqqqq..
+..q.......q.q....q..
+..q.......q.q....q..
+...q..q..q..qqqqqq..
+...qq.q.qq..q.......
+....qq.qq...q.......
+....................
+........jjjj........
+.......jjjjjj.......
+.......jjjjjj.......
+.......jjjjjj.......
+.......jjjjjj.......
+........jjjj........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 0               Circle (w overlay)
+........qqqq........
+......qmmmmmmq......
+.....qmmmmmmmmq.....
+...qmmmmmmmmmmmmq...
+..qmmmmmmmmmmmmmmq..
+.qmmmmmmmmmmmmmmmmq.
+.qmmmmmmmmmmmmmmmmq.
+qmmmmmmmmmmmmmmmmmmq
+qmmmmmmmmmmmmmmmmmmq
+qmmmmmmmmmmmmmmmmmmq
+qmmmmmmmmmmmmmmmmmmq
+qmmmmmmmmmmmmmmmmmmq
+qmmmmmmmmmmmmmmmmmmq
+.qmmmmmmmmmmmmmmmmq.
+.qmmmmmmmmmmmmmmmmq.
+..qmmmmmmmmmmmmmmq..
+...qmmmmmmmmmmmmq...
+.....qmmmmmmmmq.....
+......qmmmmmmq......
+........qqqq........
+#
+#APRS 1
+#
+#APRS 2
+#
+#APRS 3
+#
+#APRS 4
+#
+#APRS 5
+#
+#APRS 6
+#
+#APRS 7
+#
+#APRS 8
+#
+APRS 9               Gas Station (blue pump)
+....................
+....................
+......llll..........
+.....llllll.........
+....llmmmmlll.......
+....lllllllll.......
+....llmmmmll.l......
+....llllllll.l......
+....llllllll..l.....
+....llllllll..l.....
+....llllllll..l.....
+....llllllll..l.....
+....lllllllll.l.....
+....llllllll.l......
+....llllllll........
+....llllllll........
+....llllllll........
+....llllllll........
+....................
+....................
+#
+APRS :               Hail
+....................
+....................
+.........qq.........
+........qmmq........
+.......qmmmmq.......
+......qmmmmmmq......
+.....qmmmmmmmmq.....
+....qmmmmmmmmmmq....
+...qqqqqqqqqqqqqq...
+....................
+....................
+...qqqqqqqqqqqqqq...
+....qmmmmmmmmmmq....
+.....qmmmmmmmmq.....
+......qmmmmmmq......
+.......qmmmmq.......
+........qmmq........
+.........qq.........
+....................
+....................
+#
+APRS ;               Park/Picnic Area
+....................
+....................
+....hhhhhhhhhhhh....
+...hhhhhhhhhhhhhh...
+...hhhhhhhhhhhhhh...
+...hhhhhhhhhhhhhh...
+...hhhhmmmmmmhhhh...
+...hhhhhmhhmhhhhh...
+...hhhhhhmmhhhhhh...
+...hhhhhhmmhhhhhh...
+...hhhhhmhhmhhhhh...
+...hmmmmmmmmmmmmh...
+...hhhmhhhhhhmhhh...
+...hhmhhhhhhhhmhh...
+...hmhhhhhhhhhhmh...
+...hhhhhhhhhhhhhh...
+...hhhhhhhhhhhhhh...
+....hhhhhhhhhhhh....
+....................
+....................
+#
+APRS <               NWS Advisory (gale flag)
+....................
+....................
+........qq..........
+........qjqq........
+........qjjjqq......
+........qjjjjjq.....
+........qjjjqq......
+........qjqq........
+........qq..........
+........q...........
+........q...........
+........q...........
+........q...........
+........q...........
+........q...........
+........q...........
+........q...........
+........q...........
+....................
+....................
+#
+#APRS =
+#
+APRS >             l Car (w overlay)
+....................
+....................
+....................
+....................
+.........ppppp......
+........pcccncp.....
+.......pccccnccp....
+......pcccccncccp...
+...pppnqnnnnnnnnnp..
+..pmmmmmmmmmmmmmmmp.
+.pmmmmmmmmmmmmmmmmep
+p#mmoommmmmmmmmoommp
+pmmonnommmmmmmonnomp
+.ppqnnqpppppppqnnqp.
+....qq.........qq...
+....................
+....................
+....................
+....................
+....................
+#
+APRS ?               Information Kiosk (blue box with ?)
+....................
+....................
+..hhhhhhhhhhhhhhhh..
+..hhhhhhmmmhhhhhhh..
+..hhhhhmmmmmhhhhhh..
+..hhhhmmhhhmmhhhhh..
+..hhhmmhhhhhmmhhhh..
+..hhhmmhhhhhmmhhhh..
+..hhhhhhhhhhmmhhhh..
+..hhhhhhhhhmmhhhhh..
+..hhhhhhhhmmhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhmmhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+....................
+....................
+#
+APRS @               Hurricane/Tropical Storm
+....................
+....................
+.....l...lggggl.....
+....g..lgllllllgl...
+...lg..glllgggllg...
+...g..llllglllglll..
+..ll..gllglllllglg..
+..gl..lllglllllllg..
+..ll..llgllgll.lll..
+..ll..lll..lll..ll..
+..ll..lll..lll..ll..
+..gll.llgllgll..lg..
+..glllllllglll..lg..
+..glglllllgllg..ll..
+..lllglllgllll..g...
+...lllggglllg..gl...
+...lgglllllgl..g....
+.....lggggl...l.....
+....................
+....................
+#
+APRS A               Box (w overlay)
+....................
+....................
+..qqqqqqqqqqqqqqqq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qqqqqqqqqqqqqqqq..
+....................
+....................
+#
+APRS B               Blowing Snow
+....................
+....................
+....................
+..qq..q...q..q...q..
+..q.q.q..q.q.q...q..
+..qq..q..q.q.q.q.q..
+..q.q.q..q.q.qq.qq..
+..qq..qq..q..q...q..
+....................
+..qq.q.q..q..q...q..
+..q..qqq.q.q.q...q..
+...q.qqq.q.q.q.q.q..
+...q.qqq.q.q.qq.qq..
+..qq.q.q..q..q...q..
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS C               Coast Guard
+....................
+....................
+....................
+....................
+....................
+...qqqq.....qqqqq...
+..q....q...q........
+..q........q........
+..q........q........
+..q........q..qqqq..
+..q........q.....q..
+..q....q...q.....q..
+...qqqq.....qqqqqq..
+....................
+..g.g.g.g.g.g.g.g...
+...g.g.g.g.g.g.g.g..
+....................
+....................
+....................
+....................
+#
+APRS D               Drizzle
+....................
+....................
+....................
+..qq..qqq..q.qqqqq..
+..q.q.q..q.q....q...
+..q.q.qqq..q...q....
+..q.q.q.q..q..q.....
+..qq..q..q.q.qqqqq..
+....................
+..qqq....q...q.q.q..
+..q..q..q.q..q.qqq..
+..qqq..qqqqq.q.qqq..
+..q.q..q...q.q.qqq..
+..q..q.q...q.q.q.q..
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS E               Smoke
+....................
+....................
+...mqqqqqqqqqqqm....
+.mqqqqqqqqqqqqqqm...
+...mqqqqqqqqqqqm....
+......mqqqqqqqqqqm..
+........mqqqqm......
+..........mqppqm....
+........mqqqqm......
+.......mqppqm.......
+........mqjjqm......
+........mqjpqm......
+......mqqjjqqqm.....
+....mqqqjjqqqqqm....
+...mqqqjjjqqqppqm...
+..mqqqqqjjppqqqqqm..
+.mqqqqqqqjjqqqqqqqm.
+.mqqqqqqppjjjjrqqqm.
+.mmmmmmmmmmmmmmmmmm.
+....................
+#
+APRS F               Freezing Rain
+....................
+....................
+....................
+..qqqqq.qqq..qqqqq..
+..q.....q..q....q...
+..qqqq..qqq....q....
+..q.....q.q...q.....
+..q.....q..q.qqqqq..
+....................
+..qqq....q...q.q.q..
+..q..q..q.q..q.qqq..
+..qqq..qqqqq.q.qqq..
+..q.q..q...q.q.qqq..
+..q..q.q...q.q.q.q..
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS G               Snow Shower
+....................
+....................
+.......q....q.......
+........qq.q........
+.........qqqqq......
+......qqqqq.........
+........q.qq........
+.......q....q.......
+....................
+..qqqqqqqqqqqqqqqq..
+..qmmmmmmmmmmmmmmq..
+...qmmmmmmmmmmmmq...
+....qmmmmmmmmmmq....
+.....qmmmmmmmmq.....
+......qmmmmmmq......
+.......qmmmmq.......
+........qmmq........
+.........qq.........
+....................
+....................
+#
+APRS H               Haze
+q..q................
+q..q................
+qqqq................
+q..q................
+q..q................
+......q.............
+.....q.q............
+....q...q...........
+....qqqqq...........
+....q...q...........
+..........qqqqq.....
+.............q......
+............q.......
+...........q........
+..........qqqqq.....
+................qqqq
+................q...
+................qqqq
+................q...
+................qqqq
+#
+APRS I               Rain Shower
+....................
+....................
+........qqqq........
+.......qqqqqq.......
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+.......qqqqqq.......
+........qqqq........
+..qqqqqqqqqqqqqqqq..
+..qmmmmmmmmmmmmmmq..
+...qmmmmmmmmmmmmq...
+....qmmmmmmmmmmq....
+.....qmmmmmmmmq.....
+......qmmmmmmq......
+.......qmmmmq.......
+........qmmq........
+.........qq.........
+....................
+....................
+#
+APRS J               Lightning
+....................
+....................
+..............qqqq..
+.............qq##q..
+.............q###q..
+............qq##qq..
+.......q....q###q...
+......qqq...q##qq...
+......q#qq.q##qq....
+.....qq##qqq##q.....
+.....q####q##qq.....
+....qq#qq###qq......
+....q#qqqq#qq.......
+...qq#q..qqq........
+...q#q....q.........
+..qq#q..............
+..q#q...............
+..qq................
+..q.................
+....................
+#
+APRS K               Kenwood
+....................
+....................
+....................
+.......jjjjjjj......
+....qqq.jjjjj.qqq...
+....qqq..jjj..qqq...
+....qqq..jjj..qqq...
+....qqqq.cqc.qqq....
+.....qqqqcqcqqqq....
+......qqqqqqqqq.....
+......qqqqcqqqq.....
+.......qqq.qqq......
+.......qqq.qqq......
+........qq.qq.......
+........q...q.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS L               Lighthouse
+....................
+....................
+....q..........q....
+.....q..qqqq..q.....
+......q.qmmq.q......
+......qqqmmqqq......
+.....q.qqqqqq.q.....
+....q..qqqqqq..q....
+.......qqqqqq.......
+.......qqqqqq.......
+.......qqqqqq.......
+.......qqqqqq.......
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+....................
+....................
+#
+#APRS M
+#
+APRS N               Navigation Buoy
+....................
+....................
+........qqqqq.......
+........q...q.......
+........q...q.......
+........qqqqq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+...qqqqqqqqqqqqqqq..
+hh.....hhh.....hhh..
+..h...h...h...h...h.
+...hhh.....hhh.....h
+....h.......h......h
+....................
+....................
+#
+APRS O               Rocket
+..........q.........
+..........q.........
+..........q.........
+..........q.........
+.........qmq........
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmmmq.......
+........qmqmq.......
+........qmqmq.......
+.......qqmqmqq......
+......qqqmqmqqq.....
+.....qqqqmqmqqqq....
+....qqqqqmqmqqqqq...
+....qqqqqqqqqqqqq...
+#
+APRS P               Parking
+....................
+....................
+....hhhhhhhhhhh.....
+...hhhhhhhhhhhhh....
+...hhmmmmmmmmhhh....
+...hhmmmmmmmmmhh....
+...hhmmhhhhhmmhh....
+...hhmmhhhhhmmhh....
+...hhmmhhhhhmmhh....
+...hhmmmmmmmmmhh....
+...hhmmmmmmmmhhh....
+...hhmmhhhhhhhhh....
+...hhmmhhhhhhhhh....
+...hhmmhhhhhhhhh....
+...hhmmhhhhhhhhh....
+...hhmmhhhhhhhhh....
+...hhhhhhhhhhhhh....
+....hhhhhhhhhhh.....
+....................
+....................
+#
+APRS Q               Earthquake
+....................
+....................
+.......qqqqqq.......
+.....qqmmmmmmqq.....
+....qmmmmmmmmmmq....
+...qmmmmqqqqmmmmq...
+...qmmqqmmmmqqmmq...
+..qmmmqmmmmmmqmmmq..
+..qmmqmmmmmmmmqmmq..
+..qmmqmmmqqmmmqmmq..
+..qmmqmmmqqmmmqmmq..
+..qmmqmmmmmmmmqmmq..
+..qmmmqmmmmmmqmmmq..
+...qmmqqmmmmqqmmq...
+...qmmmmqqqqmmmmq...
+....qmmmmmmmmmmq....
+.....qqmmmmmmqq.....
+.......qqqqqq.......
+....................
+....................
+#
+APRS R               Restaurant
+....................
+....................
+..hhhhhhhhhhhhhhhh..
+..hhhhhhhhmhhhhhhh..
+..hmhhhmhhmhhhmhhh..
+..hmhmhmhhmhhmhmhh..
+..hmhmhmhhmhmhhhmh..
+..hmhmhmhhmhmhhhmh..
+..hmhmhmhhmhmhhhmh..
+..hhmmmhhhmhhmhmhh..
+..hhhmhhhhmhhhmhhh..
+..hhhmhhhhmhhhmhhh..
+..hhhmhhhhmhhhmhhh..
+..hhhmhhhhmhhhmhhh..
+..hhhmhhhhmhhhmhhh..
+..hhhmhhhhmhhhmhhh..
+..hhhhhhhhmhhhhhhh..
+..hhhhhhhhhhhhhhhh..
+....................
+....................
+#
+APRS S               Satellite/Pacsat
+....................
+..........q.........
+..........q.........
+..........q.........
+..........q.........
+....n...qqqqqqqq....
+....cn.q..q...qq....
+....cnqqqqqqqq.q....
+....cnqqqqqqqq.q....
+....cnqqqqqqqq.q....
+....n.qqqqqqqq.q....
+......qqqqqqqq.q....
+......qqqqqqqqq.....
+......qqqqqqqq......
+.....q........q.....
+....q..........q....
+...q............q...
+..q..............q..
+....................
+....................
+#
+APRS T               Thunderstorm
+....................
+....................
+.....qqqqqqqqqqq....
+...qqqmmqqqcmmmmq...
+...qmmmmmqqcmmmmq...
+..qmmmmmmqqqcmpppq..
+..qmmmccqqqqcppppq..
+..pqqqqccqqqcppppq..
+..pppqpcpppppppppp..
+..pppppppppppppppp..
+..ppppppppppppppp...
+...pppppppppppp.....
+.........q#q........
+........q#q.........
+.......q###q........
+........q#q.........
+.......q#q..........
+.......qq...........
+....................
+....................
+#
+APRS U               Sunny
+....................
+....................
+....................
+......a..a..a.......
+.......a.a.a........
+....a.........a.....
+.....a.#####.a......
+..a...#######...a...
+...a.#########.a....
+.....#########......
+..aa.#########.aa...
+.....#########......
+...a.#########.a....
+..a...#######...a...
+.....a.#####.a......
+....a.........a.....
+.......a.a.a........
+......a..a..a.......
+....................
+....................
+#
+APRS V               VORTAC Nav Aid
+....................
+....................
+....................
+....................
+...qq..........qq...
+..qqqqqqqqqqqqqqqq..
+.qqqqq........qqqqq.
+qqqqq..........qqqqq
+qqqq.....qq.....qqqq
+.qq.....qqqq.....qq.
+..q.....qqqq.....q..
+...q.....qq.....q...
+....q..........q....
+.....q........q.....
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+......qqqqqqqq......
+....................
+....................
+#
+APRS W               NWS Site (w overlay)
+....................
+....................
+.......hhhhhh.......
+.....hhmmmmmmhh.....
+....hmmmmmmmmmmh....
+...hmmmmmmmmmmmmh...
+...hmmmmmmmmmmmmh...
+..hppmmmppmppmmpph..
+..hppmmmppmpppppph..
+..hppmmmppmmppppmh..
+..hppmpmppmmppppmh..
+..hpppppppmpppppph..
+..hpppmpppmppmmpph..
+...hmmmmmmmmmmmmh...
+...hmmmmmmmmmmmmh...
+....hmmmmmmmmmmh....
+.....hhmmmmmmhh.....
+.......hhhhhh.......
+....................
+....................
+#
+APRS X               Pharmacy Rx
+....................
+....................
+..pppppppp..........
+..ppppppppp.........
+..pp.....pp.........
+..pp.....pp.........
+..pp....pp..........
+..ppppppp...........
+..pppppp............
+..pp..pp............
+..pp...pp...........
+..pp....pp.....pp...
+..pp.....pp...pp....
+..pp......pp.pp.....
+...........ppp......
+...........pp.......
+..........pp.pp.....
+.........pp...pp....
+........pp.....pp...
+....................
+#
+#APRS Y
+#
+#APRS Z
+#
+APRS [               Wall Cloud
+....................
+....................
+................ll..
+..............llcl..
+............llcccl..
+..........llccllcl..
+........llccclllcl..
+......llccccllcccl..
+....llcccllcllcccl..
+..llcccccllcllcccl..
+..lccccccllcllcccl..
+..lcllcccllcllcccl..
+..lcllclcllcllcccl..
+..lclllllllcllcccl..
+..lclllclllcllllcl..
+..lcllcccllcclllcl..
+..lccccccccccccccl..
+..llllllllllllllll..
+....................
+....................
+#
+#APRS \
+#
+#APRS ]
+#
+APRS ^             l Aircraft (w overlay)
+....................
+....................
+.........nn.........
+.........nn.........
+........n.n.........
+........n.n.........
+........n.n......n..
+.......n..n.....nn..
+.......n..n....n.n..
+..n.n.n.n.n.n.n..n..
+..n.n.n.n.n.n.n..n..
+.......n..n....n.n..
+.......n..n.....nn..
+........n.n......n..
+........n.n.........
+........n.n.........
+.........nn.........
+.........nn.........
+....................
+....................
+#
+APRS _               WX Stn with digi (green) (w overlay)
+....................
+....................
+.......kkkkkk.......
+.....kkkkkkkkkk.....
+....kkkkkkkkkkkk....
+...kkkkkkkkkkkkkk...
+...kkkkkkkkkkkkkk...
+..kmmkkkmmkmmkkmmk..
+..kmmkkkmmkmmmmmmk..
+..kmmkkkmmkkmmmmkk..
+..kmmkmkmmkkmmmmkk..
+..kmmmmmmmkmmmmmmk..
+..kmmmkmmmkmmkkmmk..
+...kkkkkkkkkkkkkk...
+...kkkkkkkkkkkkkk...
+....kkkkkkkkkkkk....
+.....kkkkkkkkkk.....
+.......kkkkkk.......
+....................
+....................
+#
+APRS `               Rain
+....................
+....................
+pppppppppppppppppppp
+pppppppppppppppppppp
+pppppppppppppppppppp
+pppppppppppppppppppp
+...pp...pp...pp...pp
+....................
+....................
+..p..p..p..p..p..p..
+....................
+....................
+.p..p..p..p..p..p...
+....................
+....................
+...p..p..p..p..p..p.
+....................
+....................
+.p..p...p...p...p...
+....................
+#
+APRS a               A=ARES R=RACES W=Winlink etc. (w overlay)
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+...q..qq..qq..q.....
+..q.q.q.q.q.q.q.....
+..qqq.qq..qq..q.....
+..q.q.qq..qq..q.....
+..q.q.q.q.q.q.qqq...
+....................
+....................
+#
+APRS b               Blowing Dust/Sand
+....................
+....................
+.....qqq............
+...qqqmmq.......q...
+...qmmmmmq....qq..q.
+..qmmmmmmq..qq..qq..
+..qmmmmqqqqqqqqq....
+..qnmnmccqqqqq......
+..qmnmncqqqq..qqqq..
+..qnmnmnmnq.qqq.....
+..qmnmnmnmq....qqq..
+...qqqqqqq.......q..
+....................
+..qq..q...q..q...q..
+..q.q.q..q.q.q...q..
+..qq..q..q.q.q.q.q..
+..q.q.q..q.q.qq.qq..
+..qq..qq..q..q...q..
+....................
+....................
+#
+APRS c               Civil Defense (R=RACES, C=CERTS) (w overlay)
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+...qqqq...qqqq......
+..q.......q...q.....
+..q.......q...q.....
+..q.......q...q.....
+...qqqq...qqqq......
+....................
+....................
+#
+APRS d               DX spot (by callsign prefix)
+....................
+..q.q.q......q.q.q..
+..q.q.q.lhhl.q.q.q..
+..qqqqqqqqqqqqqqqq..
+..q.q.q.lhhl.q.q.q..
+..q.q.q.lhhl.q.q.q..
+........lhhl........
+........lhhl........
+........lhhl........
+........lhhl........
+.......llhhll.......
+.......lhllhl.......
+.......llhhll.......
+..qqq..llhhll.q..q..
+..q..q.lhllhl.q..q..
+..q..q.lhllhl..qq...
+..q..q.llhhll.q..q..
+..qqq..llllll.q..q..
+....................
+....................
+#
+APRS e               Sleet
+....................
+....................
+.....qqqqqqqqqqq....
+...qqqmmqqqqmmmmq...
+..qmmmmmmqqqmmmmmq..
+.qmmmmmmmqqqcmppppq.
+.qmmmmqqqqqqcpppppq.
+.ppqqqqccqqqcpppppq.
+.pppqpccppppppppppp.
+.pppppppppppppppppp.
+..pppppppppppppppp..
+...ppppppppppppp....
+....................
+...qq.q..qq.qq.qqq..
+..q...q..q..q...q...
+...q..q..qq.qq..q...
+....q.q..q..q...q...
+..qq..qq.qq.qq..q...
+....................
+....................
+#
+APRS f               Funnel Cloud
+....................
+....................
+..qqqq....cnnnnnc...
+..q......cnnppppnc..
+..qqq....nnppppppn..
+..q......cnpppppnc..
+..q.......cnpppnc...
+..q........cpppn....
+............npppc...
+............cpppc...
+...qq......cnppn....
+..q..q.....pppc.....
+..q.......npp.......
+..q.......pppc......
+..q.......pppc..c...
+..q..q....npncc.c...
+...qq......cppcc....
+.............pq.....
+....................
+....................
+#
+APRS g               Gale Flags
+....................
+....................
+........qq..........
+........qjqq........
+........qjjjqq......
+........qjjjjjq.....
+........qjjqqq......
+........qjq.........
+........qq..........
+........qjqq........
+........qjjjqq......
+........qjjjjjq.....
+........qjjjqq......
+........qjqq........
+........qq..........
+........q...........
+........q...........
+........q...........
+....................
+....................
+#
+APRS h               Ham Store
+....................
+.........pp.........
+........p##p........
+.......p####p.......
+......p######p......
+.....p########p.....
+....p##########p....
+...p############p...
+..p##############p..
+.pp##############pp.
+..p##############p..
+..p#p##p##p##p#p#p..
+..p#p##p#p#p#ppp#p..
+..p#pppp#ppp#p#p#p..
+..p#p##p#p#p#p#p#p..
+..p#p##p#p#p#p#p#p..
+..p##############p..
+..pppppppppppppppp..
+....................
+....................
+....................
+#
+APRS i               Indoor Short Range Digi (w overlay)
+....................
+....................
+..ppp...............
+..p..p..............
+..p..p..............
+..p..p..............
+..ppp...p...........
+........p...........
+........p...........
+........p...........
+........p...ppp.....
+...........p........
+...........p.pp.....
+...........p..p.....
+............ppp..p..
+.................p..
+.................p..
+.................p..
+.................p..
+....................
+#
+APRS j             l Work Zone (steam shovel)
+....................
+....................
+....................
+....................
+........pp..........
+.......pppp.........
+......pp..pp........
+.....pp....pp.......
+p...pp......pppppp..
+.ppppp......p#pp#p..
+.p###p......p#pp#p..
+.ppppp....pp#####p..
+..........p######p..
+..........ppppppppp.
+.........pmmmp.pmmmp
+.........ppppp.ppppp
+....................
+....................
+....................
+....................
+#
+APRS k             l SUV
+....................
+....................
+....................
+....................
+..........ddddddddd.
+.........d...d....d.
+........d....d....d.
+.......ddp...d....d.
+.ddddddddddddddddddq
+d#dddddddddddddddddq
+ndqqqddddpppddqqqddq
+nqqcqqdddddddqqcqqnn
+.qcmcqoonnnnnqcmcqq.
+.oqcqo.......oqcqo..
+..oqo.........oqo...
+....................
+....................
+....................
+....................
+....................
+#
+APRS l               Area Symbols (box, circle, etc)
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+.........jj.........
+.........jj.........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS m               Value Signpost (3-char display)
+....................
+....................
+.........qq.........
+...qqqqqqqqqqqqqq...
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+..qmmmmmmmmmmmmmmq..
+...qqqqqqqqqqqqqq...
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+.........qq.........
+....................
+....................
+#
+APRS n               Triangle (w overlay)
+....................
+....................
+....................
+....................
+....................
+....................
+.........jj.........
+.........jj.........
+........jjjj........
+........jjjj........
+.......jjjjjj.......
+.......jjjjjj.......
+......jjjjjjjj......
+......jjjjjjjj......
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS o               Small Circle
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+.........jj.........
+.......j....j.......
+......j......j......
+......j......j......
+......j......j......
+.......j....j.......
+.........jj.........
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS p               Partly Cloudy
+............q.......
+........i.i.k.i.k...
+.........k......i...
+...........q#q...i..
+......iqqq#####k.k..
+.....qooooq#####i.ik
+....ioooooo#####q...
+...iioonnooqqq###.ki
+..qooqqncoqqonq##...
+.qoonooonooooooqk.ik
+.qnncnonnnonnooq....
+.qoonnnccnnccnoq.i..
+..qqoonnnnnnoqi.k...
+....qqqqqqqqq.i.i...
+....hlhlh.lhq.k.....
+....h.h.l.hh........
+....l.lh.l.l........
+....h.hh.h.h........
+...l.l.l.lh.........
+....................
+#
+#APRS q
+#
+APRS r               Restrooms
+hhhhhhhhhhhhhhhhhhhh
+hhhhhhhhhmhhhhhhhhhh
+hhhhhhhhhmhhhhhhhhhh
+hhhhmhhhhmhhhhhmhhhh
+hhhmmmhhhmhhhhmmmhhh
+hhhhmhhhhmhhhhhmhhhh
+hhhhmhhhhmhhhhhmhhhh
+hmmmmmmmhmhhmmmmmmmh
+hhhhmhhhhmhhhhhmhhhh
+hhhhmhhhhmhhhhhmhhhh
+hhhhmhhhhmhhhhmmmhhh
+hhhhmhhhhmhhhhmmmhhh
+hhhmhmhhhmhhhmmmmmhh
+hhmhhhmhhmhhhmmmmmhh
+hmhhhhhmhmhhmmmmmmmh
+hhhhhhhhhmhhhhhhhhhh
+hhhhhhhhhmhhhhhhhhhh
+hhhhhhhhhmhhhhhhhhhh
+hhhhhhhhhmhhhhhhhhhh
+hhhhhhhhhhhhhhhhhhhh
+#
+APRS s             l Ship/Boat (top view) (w overlay)
+....................
+....................
+....................
+....................
+....................
+....................
+........qqqq.....q..
+.......q...q....q...
+......q....q...q....
+..iiii.....iiiiiii..
+..i..............i..
+...i.............i..
+....iiiiiiiiiiiiii..
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS t               Tornado
+.......mmmmmmmm.....
+......mmqqqqqqmm....
+....mmqjnnnnnnnqjmm
+...mmqjnnnppppnnjqmm
+...mmqjnnppppppppjqm
+....mmqjnpppppnjqmm.
+.....mmqjnpppnjqmm..
+......mmqjpppnqmm...
+.......mmqnpppqqmm..
+.......mmqjpppqqmm..
+......mmqjnppnqmm...
+......mmqpppqqmm....
+.....mmqnppqmm......
+.....mmqpppbmmqmm...
+.....mmqpppbmmbqmm..
+.....mmqnpnbbmbqmm..
+......mmqcppmbqmm...
+........mmqpqqmm....
+.........mmqmm......
+..........mmm.......
+#
+APRS u             l Truck (w overlay)
+....................
+....................
+....................
+....................
+........jjj.........
+.......j..j.........
+......j...j.........
+.....j....j.........
+..jjj......jjjjjjj..
+..j..............j..
+..j..............j..
+..qpppj.....jpppjq..
+..qpcpjjjjjjjpcpjq..
+...ppp.......ppp....
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS v             l Van (w overlay)
+....................
+....................
+....................
+....................
+....................
+.......hhhhhhhhhhh..
+......h...........h.
+.....h............h.
+....h.............h.
+..h...............h.
+.h................j.
+.h................h.
+.ohqqh........hqqho.
+.hqccqhhhhhhhhqccqh.
+..qccq........qccq..
+...qq..........qq...
+....................
+....................
+....................
+....................
+#
+APRS w               Flooding
+....................
+....................
+....................
+....................
+....................
+...c.....c.....c....
+....h.....h.....h...
+...lll...lll...lll..
+..llllllllllllllll..
+..llllllllllllllll..
+..llllllllllllllll..
+..llllllllllllllll..
+..llllllllllllllll..
+..cchclhchlhchlcch..
+..cllclclclclclclc..
+..cclclclclclclclc..
+..cllcchchlhchlcch..
+..llllllllllllllll..
+....................
+....................
+#
+#APRS x
+#
+APRS y               Skywarn
+qqqqqqqqqmmqqqqqqqqq
+qqqqqqqmqqqqmqqqqqqq
+qqqqqmqqqqqqqqmqqqqq
+qqqqmqqqqqqqqqqmqqqq
+qqqmmqqqqqqqqqqmmqqq
+qqmmqqaqqqqqqaqqmmqq
+qmmmqqaaqqqqaaqqmmmq
+qmmqqaaaqqqqaaaqqmmq
+mmmqqaaaqqqqaaaqqmmm
+mmmqqaaaqqqaaaaqqmmm
+mmmqqaaaqqqaaaaqqmmm
+mmmqqaaaaqqaaaaqqmmm
+qmmqqaaaaaqqaaaqqmmq
+qmmmqqaaaaqqaaqqmmmq
+qqmmqqaaaaqqaaqqmmqq
+qqqmmqqaaqqaaqqmmqqq
+qqqqmqqaaqaaaqqmqqqq
+qqqqqmqqqqqqqqmqqqqq
+qqqqqqqmqqqqmqqqqqqq
+qqqqqqqqqmmqqqqqqqqq
+#
+APRS z                Shelter (Evacuation) w overlay
+....................
+.........pp.........
+........pjjp........
+.......pjjjjp.......
+......pjjjjjjp......
+.....pjjjjjjjjp.....
+....pjjjjjjjjjjp....
+...pjjjjjjjjjjjjp...
+..pjjjjjjjjjjjjjjp..
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+...pjjjjjjjjjjjjp...
+....................
+....................
+....................
+#
+APRS {               Fog
+....................
+....................
+....................
+....................
+....................
+..qqqq..qqq...qqq...
+..q....q...q.q...q..
+..q....q...q.q...q..
+..qqq..q...q.q......
+..q....q...q.q......
+..q....q...q.q..qq..
+..q....q...q.q...q..
+..q....q...q.q...q..
+..q.....qqq...qqq...
+....................
+....................
+....................
+....................
+....................
+....................
+#
+#APRS |               Reserved - TNC Stream Switch
+#
+#APRS }
+#
+#APRS ~               Reserved - TNC Stream Switch
+#
+#
+# -------------------------
+#
+TABLE #
+#
+APRS 0               Overlay Characters, etc
+....................
+....................
+....................
+....................
+.........cc.........
+........cqqc........
+.......cqccqc.......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+.......cqccqc.......
+........cqqc........
+.........cc.........
+....................
+....................
+....................
+....................
+....................
+#
+APRS 1
+....................
+....................
+....................
+....................
+.........ccc........
+........ccqc........
+........cqqc........
+........ccqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........ccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS 2
+....................
+....................
+....................
+....................
+........ccccc.......
+.......ccqqqqc......
+......ccqcccqc......
+......cqcc.cqc......
+......ccc.ccqc......
+.........ccqcc......
+........ccqcc.......
+.......ccqcc........
+......ccqccccc......
+......cqqqqqqc......
+......cccccccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS 3
+....................
+....................
+....................
+....................
+......cccccccc......
+......cqqqqqqc......
+......cccccqcc......
+........ccqcc.......
+.........qqcc.......
+........cccqcc......
+..........ccqc......
+......ccc.ccqc......
+......cqcccqcc......
+......ccqqqcc.......
+.......ccccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS 4
+....................
+....................
+....................
+....................
+...........ccc......
+..........ccqc......
+.........ccqqc......
+........ccqcqc......
+.......ccqccqc......
+......ccqc.cqc......
+......cqccccqcc.....
+......cqqqqqqqc.....
+......ccccccqcc.....
+...........cqc......
+...........ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS 5
+....................
+....................
+....................
+....................
+......cccccccc......
+......cqqqqqqc......
+......cqcccccc......
+......cqcccc........
+......cqqqqqc.......
+.......cccccqc......
+...........cqc......
+......ccc..cqc......
+......cqccccqc......
+......ccqqqqc.......
+.......cccccc.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS 6
+....................
+....................
+....................
+....................
+.........ccc........
+........cqqqc.......
+.......cqccc........
+......cqcccc........
+......cqqqqqc.......
+......cqccccqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+.......cqqqqc.......
+........cccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS 7
+....................
+....................
+....................
+....................
+......cccccccc......
+......cqqqqqqc......
+......ccccccqc......
+..........cqcc......
+.........ccqc.......
+.........cqcc.......
+........ccqc........
+........cqcc........
+........cqc.........
+........cqc.........
+........ccc.........
+....................
+....................
+....................
+....................
+....................
+#
+APRS 8
+....................
+....................
+....................
+....................
+........cccc........
+.......cqqqqc.......
+......cqccccqc......
+......cqccccqc......
+......ccqqqqcc......
+......cqccccqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+.......cqqqqc.......
+........cccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS 9
+....................
+....................
+....................
+....................
+........cccc........
+.......cqqqqc.......
+......cqccccqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+.......cqqqqqc......
+........ccccqc......
+........cccqcc......
+.......cqqqcc.......
+........cccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS A
+....................
+....................
+....................
+....................
+.........ccc........
+.........cqc........
+........ccqcc.......
+........cqcqc.......
+.......ccqcqcc......
+.......cqc.cqc......
+......ccqc.cqcc.....
+......cqqqqqqqc.....
+......cqcccccqc.....
+......cqc...cqc.....
+......ccc...ccc.....
+....................
+....................
+....................
+....................
+....................
+#
+APRS B
+....................
+....................
+....................
+....................
+......cccccc........
+......cqqqqqc.......
+......cqccccqc......
+......cqccccqc......
+......cqqqqqcc......
+......cqccccqc......
+......cqc...qc......
+......cqc..cqc......
+......cqccccqc......
+......cqqqqqc.......
+......cccccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS C
+....................
+....................
+....................
+....................
+.......cccccc.......
+......ccqqqqcc......
+......cqccccqc......
+......cqc..ccc......
+......cqc...........
+......cqc...........
+......cqc...........
+......cqc..ccc......
+......cqccccqc......
+......ccqqqqcc......
+.......cccccc.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS D
+....................
+....................
+....................
+....................
+......cccccc........
+......cqqqqcc.......
+......cqcccqcc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqcccqcc......
+......cqqqqcc.......
+......cccccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS E
+....................
+....................
+....................
+....................
+......ccccccc.......
+......cqqqqqc.......
+......cqccccc.......
+......cqc...........
+......cqcccc........
+......cqqqqc........
+......cqcccc........
+......cqc...........
+......cqccccc.......
+......cqqqqqc.......
+......ccccccc.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS F
+....................
+....................
+....................
+....................
+......ccccccc.......
+......cqqqqqc.......
+......cqccccc.......
+......cqc...........
+......cqcccc........
+......cqqqqc........
+......cqcccc........
+......cqc...........
+......cqc...........
+......cqc...........
+......ccc...........
+....................
+....................
+....................
+....................
+....................
+#
+APRS G
+....................
+....................
+....................
+....................
+.......cccccc.......
+......ccqqqqcc......
+......cqccccqc......
+......cqc...c.......
+......cqc.cccc......
+......cqccqqqc......
+......cqc.ccqc......
+......cqc...qc......
+......cqccccqc......
+......ccqqqqcc......
+.......cccccc.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS H
+....................
+....................
+....................
+....................
+......ccc..ccc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+......cqqqqqqc......
+......cqccccqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......ccc..ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS I
+....................
+....................
+....................
+....................
+........ccc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........cqc.........
+........ccc.........
+....................
+....................
+....................
+....................
+....................
+#
+APRS J
+....................
+....................
+....................
+....................
+..........ccc.......
+..........cqc.......
+..........cqc.......
+..........cqc.......
+..........cqc.......
+..........cqc.......
+.....ccc..cqc.......
+.....cqc..cqc.......
+.....cqccccqc.......
+.....ccqqqqcc.......
+......cccccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS K
+....................
+....................
+....................
+....................
+......ccc..ccc......
+......cqc..cqc......
+......cqc.cqcc......
+......cqccqcc.......
+......cqcqcc........
+......cqqcc.........
+......cqcqcc........
+......cqccqcc.......
+......cqc.cqcc......
+......cqc..cqc......
+......ccc..ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS L
+....................
+....................
+....................
+....................
+......ccc...........
+......cqc...........
+......cqc...........
+......cqc...........
+......cqc...........
+......cqc...........
+......cqc...........
+......cqc...........
+......cqccccc.......
+......cqqqqqc.......
+......ccccccc.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS M
+....................
+....................
+....................
+....................
+......ccc...ccc.....
+......cqcc.ccqc.....
+......cqqc.cqqc.....
+......cqcqcqcqc.....
+......cqccqccqc.....
+......cqcccccqc.....
+......cqc...cqc.....
+......cqc...cqc.....
+......cqc...cqc.....
+......cqc...cqc.....
+......ccc...ccc.....
+....................
+....................
+....................
+....................
+....................
+#
+APRS N
+....................
+....................
+....................
+....................
+......cccc.ccc......
+......cqqc.cqc......
+......cqqc.cqc......
+......cqcqccqc......
+......cqcqccqc......
+......cqccqcqc......
+......cqccqcqc......
+......cqc.cqqc......
+......cqc.cqqc......
+......cqc..cqc......
+......ccc..ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS O
+....................
+....................
+....................
+....................
+........cccc........
+.......cqqqqc.......
+......cqccccqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+.......cqqqqc.......
+........cccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS P
+....................
+....................
+....................
+....................
+......ccccccc.......
+......cqqqqqcc......
+......cqccccqc......
+......cqc..cqc......
+......cqccccqc......
+......cqqqqqcc......
+......cqccccc.......
+......cqc...........
+......cqc...........
+......cqc...........
+......ccc...........
+....................
+....................
+....................
+....................
+....................
+#
+APRS Q
+....................
+....................
+....................
+....................
+........cccc........
+.......cqqqqc.......
+......cqccccqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+......cqccqcqc......
+.......cqqqqc.......
+........ccccqc......
+............cc......
+....................
+....................
+....................
+....................
+#
+APRS R
+....................
+....................
+....................
+....................
+......ccccccc.......
+......cqqqqqcc......
+......cqccccqc......
+......cqc..cqc......
+......cqccccqc......
+......cqqqqqcc......
+......cqcqccc.......
+......cqccqcc.......
+......cqc.cqcc......
+......cqc..cqc......
+......ccc..ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS S
+....................
+....................
+....................
+....................
+........cccc........
+.......cqqqqc.......
+......cqccccqc......
+......cqc...c.......
+......cqcccc........
+.......cqqqqc.......
+........ccccqc......
+......ccc..cqc......
+......cqccccqc......
+.......cqqqqc.......
+........cccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS T
+....................
+....................
+....................
+....................
+......ccccccccc.....
+......cqqqqqqqc.....
+......ccccqcccc.....
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........cqc........
+.........ccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS U
+....................
+....................
+....................
+....................
+......ccc..ccc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqc..cqc......
+......cqccccqc......
+......ccqqqqcc......
+.......cccccc.......
+....................
+....................
+....................
+....................
+....................
+#
+APRS V
+....................
+....................
+....................
+....................
+......ccc...ccc.....
+......cqc...cqc.....
+......cqc...cqc.....
+......cqcc.ccqc.....
+......ccqc.cqcc.....
+.......cqc.cqc......
+.......ccqcqcc......
+........cqcqc.......
+........ccqcc.......
+.........cqc........
+.........ccc........
+....................
+....................
+....................
+....................
+....................
+#
+APRS W
+....................
+....................
+....................
+....................
+.....ccc.....ccc....
+.....cqc.....cqc....
+.....cqc..c..cqc....
+.....cqc.cqc.cqc....
+.....ccqccqccqcc....
+......cqcqcqcqc.....
+......cqcqcqcqc.....
+......ccqc.cqcc.....
+.......cqc.cqc......
+.......cqc.cqc......
+.......ccc.ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS X
+....................
+....................
+....................
+....................
+.......ccc.ccc......
+.......cqc.cqc......
+.......cqc.cqc......
+.......ccqcqcc......
+........cqcqc.......
+.........cqc........
+........cqcqc.......
+.......ccqcqcc......
+.......cqc.cqc......
+.......cqc.cqc......
+.......ccc.ccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS Y
+....................
+....................
+....................
+....................
+......ccc.ccc.......
+......cqc.cqc.......
+......cqc.cqc.......
+......cqc.cqc.......
+......ccqcqcc.......
+.......cqcqc........
+.......ccqcc........
+........cqc.........
+........cqc.........
+........cqc.........
+........ccc.........
+....................
+....................
+....................
+....................
+....................
+#
+APRS Z
+....................
+....................
+....................
+....................
+......cccccccc......
+......cqqqqqqq......
+......ccccccqc......
+..........ccqc......
+.........ccqcc......
+........ccqcc.......
+.......ccqcc........
+......ccqcc.........
+......cqcccccc......
+......cqqqqqqc......
+......cccccccc......
+....................
+....................
+....................
+....................
+....................
+#
+APRS >
+....................
+....................
+....................
+....................
+.....d..............
+.....dd.............
+.ddddddd............
+ndddddddd...........
+nddddddd............
+nnnnndd.............
+....nd..............
+....................
+....................
+..kkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nnnnnnn............
+....................
+#
+APRS <
+....................
+....................
+....................
+....................
+...d................
+..dd................
+.dddddddd...........
+ddddddddd...........
+ndddddddd...........
+.nddnnnn............
+..nd................
+....................
+....................
+..kkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nnnnnnn............
+....................
+#
+APRS *
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+..ddddddd...........
+.nddddddd...........
+.nddddddd...........
+.nddddddd...........
+.nddddddd...........
+.nnnnnnn............
+....................
+#
+APRS ^
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+..kkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nkkkkkkk...........
+.nnnnnnn............
+....................
+#
+#
+# -------------------------
+#
+TABLE ~
+#
+APRS 0
+..gggggg............
+.gggggggg...........
+gggggggggg..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 1
+..hhhhhh............
+.hhhhhhhh...........
+hhhhhhhhhh..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 2
+..iiiiii............
+.iiiiiiii...........
+iiiiiiiiii..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 3
+..aaaaaa............
+.aaaaaaaa...........
+aaaaaaaaaa..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 4
+..######............
+.########...........
+##########..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 5
+..llllll............
+.llllllll...........
+llllllllll..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 6
+..kkkkkk............
+.kkkkkkkk...........
+kkkkkkkkkk..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 7
+..jjjjjj............
+.jjjjjjjj...........
+jjjjjjjjjj..........
+nnnnnnnnn...........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS 8
+npllllllpn..........
+lnllllllnl..........
+lhhhhhhhhl..........
+npllllllpn..........
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+....................
+#
+APRS #
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+~~~~~~~~~~..........
+#
+APRS $
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~
+DONE
diff --git a/symbols/torndo.xbm b/symbols/torndo.xbm
new file mode 100644
index 0000000..d8362d1
--- /dev/null
+++ b/symbols/torndo.xbm
@@ -0,0 +1,41 @@
+#define tornado_width 110
+#define tornado_height 32
+static unsigned char tornado_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0xf8, 0x9c,
+   0x27, 0x22, 0x1e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x20, 0xa2, 0x68, 0x22, 0xa2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x20, 0xa2, 0xa8, 0x52, 0xa2, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x20, 0xa2, 0x27, 0x53, 0xa2, 0x08, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xa2, 0x28, 0xfa, 0xa2, 0x08,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xa2, 0x28, 0x8a,
+   0xa2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x9c,
+   0x28, 0x8a, 0x1e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/symbols/wind.xbm b/symbols/wind.xbm
new file mode 100644
index 0000000..64436dc
--- /dev/null
+++ b/symbols/wind.xbm
@@ -0,0 +1,41 @@
+#define wind_width 109
+#define wind_height 32
+static unsigned char wind_bits[] = {
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+   0x12, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x49, 0x32, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x49, 0x52, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x45, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x12, 0x45, 0x00, 0x00,
+   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x49, 0x12, 0x45,
+   0x54, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+   0x12, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/symbols/winter_storm.xbm b/symbols/winter_storm.xbm
new file mode 100644
index 0000000..9bcd780
--- /dev/null
+++ b/symbols/winter_storm.xbm
@@ -0,0 +1,41 @@
+#define wntr_strm_width 110
+#define wntr_strm_height 32
+static unsigned char wntr_strm_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x24, 0x49, 0xf4, 0x7d, 0x0f, 0xe0, 0x7c, 0xce, 0x13, 0x04,
+   0x00, 0x00, 0x00, 0x00, 0x24, 0xc9, 0x44, 0x04, 0x11, 0x10, 0x11, 0x51,
+   0x34, 0x06, 0x00, 0x00, 0x00, 0x00, 0x24, 0x49, 0x45, 0x04, 0x11, 0x10,
+   0x10, 0x51, 0x54, 0x05, 0x00, 0x00, 0x00, 0x00, 0x24, 0x49, 0x46, 0x3c,
+   0x0f, 0xe0, 0x10, 0xd1, 0x93, 0x04, 0x00, 0x00, 0x00, 0x00, 0x24, 0x49,
+   0x44, 0x04, 0x11, 0x00, 0x11, 0x51, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00,
+   0x24, 0x49, 0x44, 0x04, 0x11, 0x10, 0x11, 0x51, 0x14, 0x04, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xfc, 0x48, 0x44, 0x7c, 0x11, 0xe0, 0x10, 0x4e, 0x14, 0x24,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/symbols/winter_weather.xbm b/symbols/winter_weather.xbm
new file mode 100644
index 0000000..c2b6521
--- /dev/null
+++ b/symbols/winter_weather.xbm
@@ -0,0 +1,41 @@
+#define winter_wx_width 109
+#define winter_wx_height 32
+static unsigned char winter_wx_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x92, 0x44, 0xdf,
+   0xf7, 0x00, 0x49, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x4a, 0x92,
+   0x4c, 0x44, 0x10, 0x01, 0x49, 0x8a, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00,
+   0x40, 0x92, 0x54, 0x44, 0x10, 0x01, 0x49, 0x04, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0x92, 0x64, 0xc4, 0xf3, 0x00, 0x49, 0x04, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x40, 0x92, 0x44, 0x44, 0x10, 0x01, 0x49, 0x04,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x92, 0x44, 0x44, 0x10, 0x01,
+   0x49, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8f, 0x44, 0xc4,
+   0x17, 0x01, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+   0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00 };
diff --git a/terraserver-reflectivity.geo b/terraserver-reflectivity.geo
new file mode 100644
index 0000000..a96a8ad
--- /dev/null
+++ b/terraserver-reflectivity.geo
@@ -0,0 +1,2 @@
+TERRASERVER-REFLECTIVITY
+
diff --git a/terraserver-topo.geo b/terraserver-topo.geo
new file mode 100644
index 0000000..043744d
--- /dev/null
+++ b/terraserver-topo.geo
@@ -0,0 +1,2 @@
+TERRASERVER-TOPO
+
diff --git a/terraserver-urban.geo b/terraserver-urban.geo
new file mode 100644
index 0000000..7e5dbaf
--- /dev/null
+++ b/terraserver-urban.geo
@@ -0,0 +1,2 @@
+TERRASERVER-URBAN
+
diff --git a/terraserver.geo b/terraserver.geo
new file mode 100644
index 0000000..6159ce4
--- /dev/null
+++ b/terraserver.geo
@@ -0,0 +1,2 @@
+TERRASERVER-SATELLITE
+
diff --git a/testdbfawk.1 b/testdbfawk.1
new file mode 100644
index 0000000..24ec346
--- /dev/null
+++ b/testdbfawk.1
@@ -0,0 +1,48 @@
+.TH testdbfawk 1 2009-12-22 "The Xastir Group"
+
+.SH NAME
+testdbfawk \- scan dbfawk files for matching dbf file for map rendering in xastir
+
+.SH SYNOPSIS
+.B testdbfawk
+.I [-f file.awk| -D dir] -d file.dbf
+
+.SH DESCRIPTION
+Scan dbfawk files for matching dbf file for map rendering in xastir
+.br
+.PP
+.B --help
+prints command line usage
+.br
+.B -D
+for dir containing *.dbfawk files.
+.br
+.B -f
+for file containing awk rules.
+.br
+.B -d
+for dbf file to parse
+.SH EXAMPLES
+testdbfawk \-D . \-d tgr36119lkA.dbf 2>&1|less
+
+testdbfawk scans the current directory for dbfawk files with signatures that match tgr36119lkA.dbf's
+signature.  testdbfawk dumps its output to standard error, so in the example standard error is
+redirected to standard out and piped into "less" for paging.
+
+.SH NOTES
+Dbfawk hints and kinks:  You have to think like an awk programmer and
+realize that the order that rules are listed matters, that it's important
+to use "next" as soon as it makes sense so other rules aren't looked at
+unnecessarily and, to use "skip" when you want to fix bad dbf data.
+
+.SH SEE ALSO
+README.MAPS in xastir documentation
+.br
+.PP
+.B APRS[tm]
+is a Trademark of Bob Bruninga, his home page is at "http://www.aprs.org/aprs.html"
+
+.SH COPYING
+Copyright (C) 1999,2000 Frank Giannandrea KC2GJS
+.br
+Copyright (C) 2000-2012 The Xastir Group
diff --git a/worldhi.map b/worldhi.map
new file mode 100644
index 0000000..d88de89
Binary files /dev/null and b/worldhi.map differ
diff --git a/xastir-lsb.spec.in b/xastir-lsb.spec.in
new file mode 100644
index 0000000..c11258f
--- /dev/null
+++ b/xastir-lsb.spec.in
@@ -0,0 +1,108 @@
+# NOTE:
+# “Free Standards Group, FSG, Linux Standard Base, LSB, Free
+# Standards Certified, LSB Certified and the Free Standards
+# Certified logo are trademarks, service marks and certification
+# marks, as appropriate, of Free Standards Group in the United
+# States and in other countries.”
+#
+# We are in no way representing that Xastir has been certified by
+# the FSG.  To do so costs real money.  We do intend some Xastir
+# binaries to install and run properly on LSB-3.0 compliant x86
+# Linux systems though...
+#
+Summary      : Amateur Station Tracking and Reporting system for Amateur Radio APRS
+Name         : xastir
+Version      : @VERSION@
+Release      : 1
+Copyright    : GPL
+Group        : Applications/Networking
+Packager     : Curt Mills, WE7U <archer at eskimo.com>
+# Icon       : src/xastir.xpm
+Source       : http://prdownloads.sourceforge.net/xastir/xastir-@VERSION@.tar.gz
+URL          : http://www.xastir.org
+#BuildRoot   : %{_tmppath}/%{name}-buildroot
+BuildRoot    : RPM
+#Requires    :
+#AutoReqProv : no
+PreReq       : lsb >= 3.0
+#
+#
+# Stuff gleaned from the LSB appbat RPM build files:
+#
+# Force a 486 target
+#buildarchtranslate: i686 i486
+#buildarchtranslate: i586 i486
+#buildarchtranslate: pentium3 i486
+#buildarchtranslate: pentium4 i486
+#buildarchtranslate: athlon i486
+#buildarchtranslate: k6 i486a
+#
+# Overrides for LSB packaging
+# We want a non-root build.  Just put everything in the same directory.
+# Only _rpmdir and _builddir are actually used in these builds but we
+# define all five of the directories for completeness.
+#%_topdir	/home/archer/xastir
+#%_rpmdir	%{_topdir}/rpm
+#%_specdir	%{_topdir}/rpm
+#%_builddir	%{_topdir}/rpm
+#%_sourcedir	%{_topdir}/rpm
+#%_srcrpmdir	%{_topdir}/rpm
+#%pkgroot	%{_topdir}/rpm
+#
+#%_messagelevel 0
+#
+# Replace the "buildpolicy" defined in the distro's brp-(distro) file.
+# Forces uncompressed manpages so the specfiles don't vary.
+#%__os_install_post \
+#	/usr/lib/rpm/brp-strip \
+#	/usr/lib/rpm/brp-strip-comment-note
+#
+# Unpackaged files in a build root don't terminate a build
+#%_unpackaged_files_terminate_build 0
+#
+# Missing %doc files in the build directory don't terminate a build
+#%_missing_doc_files_terminate_build 0
+#
+# Force gzip payload
+#%_binary_payload w9.gzdio
+
+
+%description
+Xastir is a graphical application that interfaces HAM radio
+and internet access to real-time mapping software.
+
+Install XASTIR if you are interested in APRS(tm) and HAM radio
+software.
+
+%prep
+%setup -q
+#%patch
+%build
+%install
+%clean
+
+%files
+%defattr(-,root,root)
+
+# Documents:  Go into special doc area at /opt/Xastir/share/doc/xastir/
+%doc AUTHORS ChangeLog COPYING DEBUG_LEVELS FAQ INSTALL LICENSE
+%doc README README.Contributing README.CVS README.Getting-Started
+%doc README.MAPS README.win32 UPGRADE COPYING.LIB.LESSTIF
+
+/opt/Xastir/bin
+/opt/Xastir/share/xastir/help
+/opt/Xastir/share/xastir/config
+/opt/Xastir/share/xastir/symbols
+/opt/Xastir/share/man
+/opt/Xastir/lib/xastir
+
+# protect user-installed map and other files from being clobbered
+%config /opt/Xastir/share/xastir/maps
+%dir %attr(666,root,root) /opt/Xastir/share/xastir/maps/GPS
+%config /opt/Xastir/share/xastir/Counties
+%config /opt/Xastir/share/xastir/fcc
+%config /opt/Xastir/share/xastir/GNIS
+%config /opt/Xastir/share/xastir/sounds
+
+%changelog
+
diff --git a/xastir-min.spec b/xastir-min.spec
new file mode 100644
index 0000000..a3dc74e
--- /dev/null
+++ b/xastir-min.spec
@@ -0,0 +1,77 @@
+Summary   : Amateur Station Tracking and Reporting system for amateur radio
+Name      : xastir
+Version   : 2.0.4
+Release   : 1
+#Epoch    : 1
+License   : GPL
+Group     : Applications/Networking
+Packager  : n2ygk at weca.org
+# Icon    : src/xastir.xpm
+Source    : http://prdownloads.sourceforge.net/xastir/xastir-2.0.4.tar.gz
+URL       : http://www.xastir.org
+BuildRoot : %{_tmppath}/%{name}-buildroot
+#Requires  :
+
+%description
+Xastir is a graphical application that interfaces HAM radio
+and internet access to realtime mapping software.
+
+Install XASTIR if you are interested in APRS(tm) and HAM radio
+software.
+
+%prep
+%setup -q
+#%patch
+
+%build
+./bootstrap.sh
+%configure --without-ax25 --without-festival --without-gpsman --without-graphicsmagick --with-imagemagick --with-internal-shapelib --without-libproj --without-geotiff --without-gdal --without-pcre --without-dbfawk --without-map-cache
+make
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+%makeinstall
+# Docs go into package docs area instead of the Makefile install
+# locations listed here:
+rm -rf ${RPM_BUILD_ROOT}/usr/share/doc
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%files
+%defattr(-,root,root)
+
+# Documents:  Go into special doc area at /usr/share/doc/xastir/ or
+# /usr/share/doc/packages/xastir/
+%doc AUTHORS ChangeLog COPYING DEBUG_LEVELS FAQ INSTALL LICENSE
+%doc README README.Contributing README.CVS README.Getting-Started
+%doc README.MAPS README.win32 UPGRADE
+
+
+%{_prefix}/bin
+%{_prefix}/share/xastir/help
+%{_prefix}/share/xastir/config
+%{_prefix}/share/xastir/symbols
+%{_prefix}/share/man
+%{_prefix}/lib/xastir
+
+# protect user-installed map and other files from being clobbered
+
+%config %{_prefix}/share/xastir/maps
+%dir %attr(666,root,root) %{_prefix}/share/xastir/maps/GPS
+%config %{_prefix}/share/xastir/Counties
+%config %{_prefix}/share/xastir/fcc
+%config %{_prefix}/share/xastir/GNIS
+%config %{_prefix}/share/xastir/sounds
+
+%changelog
+* Thu Jul 03 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.1 my patches now integrated into the main trunk.
+* Sat Jun 21 2003 Alan Crosswell <n2ygk at weca.org> 
+- added xastir-maps.patch
+* Mon Jun 16 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.0
+* Fri Jun 06 2003 Alan Crosswell <n2ygk at weca.org> 
+- June 5 snapshot
+* Thu May 15 2003 Alan Crosswell <n2ygk at weca.org> 
+- start with chuck's spec file for 1.1.4
diff --git a/xastir-min.spec.in b/xastir-min.spec.in
new file mode 100644
index 0000000..15f522f
--- /dev/null
+++ b/xastir-min.spec.in
@@ -0,0 +1,77 @@
+Summary   : Amateur Station Tracking and Reporting system for amateur radio
+Name      : @PACKAGE@
+Version   : @VERSION@
+Release   : 1
+#Epoch    : 1
+License   : GPL
+Group     : Applications/Networking
+Packager  : n2ygk at weca.org
+# Icon    : src/@PACKAGE at .xpm
+Source    : http://prdownloads.sourceforge.net/@PACKAGE@/@PACKAGE@-@VERSION@.tar.gz
+URL       : http://www.xastir.org
+BuildRoot : %{_tmppath}/%{name}-buildroot
+#Requires  :
+
+%description
+Xastir is a graphical application that interfaces HAM radio
+and internet access to realtime mapping software.
+
+Install XASTIR if you are interested in APRS(tm) and HAM radio
+software.
+
+%prep
+%setup -q
+#%patch
+
+%build
+./bootstrap.sh
+%configure --without-ax25 --without-festival --without-gpsman --without-graphicsmagick --with-imagemagick --with-internal-shapelib --without-libproj --without-geotiff --without-gdal --without-pcre --without-dbfawk --without-map-cache
+make
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+%makeinstall
+# Docs go into package docs area instead of the Makefile install
+# locations listed here:
+rm -rf ${RPM_BUILD_ROOT}/usr/share/doc
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%files
+%defattr(-,root,root)
+
+# Documents:  Go into special doc area at /usr/share/doc/xastir/ or
+# /usr/share/doc/packages/xastir/
+%doc AUTHORS ChangeLog COPYING DEBUG_LEVELS FAQ INSTALL LICENSE
+%doc README README.Contributing README.CVS README.Getting-Started
+%doc README.MAPS README.win32 UPGRADE
+
+
+%{_prefix}/bin
+%{_prefix}/share/xastir/help
+%{_prefix}/share/xastir/config
+%{_prefix}/share/xastir/symbols
+%{_prefix}/share/man
+%{_prefix}/lib/xastir
+
+# protect user-installed map and other files from being clobbered
+
+%config %{_prefix}/share/xastir/maps
+%dir %attr(666,root,root) %{_prefix}/share/xastir/maps/GPS
+%config %{_prefix}/share/xastir/Counties
+%config %{_prefix}/share/xastir/fcc
+%config %{_prefix}/share/xastir/GNIS
+%config %{_prefix}/share/xastir/sounds
+
+%changelog
+* Thu Jul 03 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.1 my patches now integrated into the main trunk.
+* Sat Jun 21 2003 Alan Crosswell <n2ygk at weca.org> 
+- added xastir-maps.patch
+* Mon Jun 16 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.0
+* Fri Jun 06 2003 Alan Crosswell <n2ygk at weca.org> 
+- June 5 snapshot
+* Thu May 15 2003 Alan Crosswell <n2ygk at weca.org> 
+- start with chuck's spec file for 1.1.4
diff --git a/xastir.1 b/xastir.1
new file mode 100644
index 0000000..fd6e76a
--- /dev/null
+++ b/xastir.1
@@ -0,0 +1,108 @@
+.TH XASTIR 1 "HI8GN on Apr 09 2002" "By Jose R. Marte A." "Xastir APRS(tm) Client APPLICATION"
+.SH NAME
+Xastir \- graphical application that interfaces HAM radio
+and APRS(tm) internet access to real-time mapping software.
+.SH "DESCRIPTION"
+This manual page briefly documents the
+.BR Xastir
+commands.
+.SH SYNOPSIS
+.B xastir
+.I "[options] Language ..."
+.SH OPTIONS
+The program follows the usual GNU command line syntax, with long
+options starting with one dash (`-').
+A summary of options is included below.
+.TP
+.br
+.B \-c /path/dir
+Specify an optional config directory. Defaults to ~/.xastir
+.TP
+.br
+.B \-f callsign
+Track callsign
+.TP
+.br
+.B \-i
+Use a private colormap
+.TP
+.br
+.B \-geometry WxH+x+y
+Set Window Geometry/Position
+.TP
+.br
+.B \-l Language
+Xastir remembers the language once you set it the first time.
+.TP
+.br
+.B \-m
+Deselect Maps
+.TP
+.br
+.B \-p
+Disable popups
+.TP
+.br
+.B \-t
+Internal SIGSEGV handler enabled
+.TP
+.br
+.B \-v Level
+Set the debug level
+.TP
+.br
+.B \-?
+Show summary of options available.
+.br
+.SH AVAILABLE LANGUAGES
+Current choices are:
+.br
+.B Dutch English French German Italian Portuguese Spanish.
+.SH Usage is:
+.br
+.B xastir -i -v 2047 -l Dutch &
+.br
+.SH SIGNALS
+.B SIGINT, SIQQUIT, SIGTERM
+Cause Xastir to exit.
+.br
+.B SIGHUP
+Causes a restart.
+.br
+.B SIGUSR1
+Causes a snapshot to occur.
+.br
+.SH NETWORK PORTS
+Enable these ports on this menu:  "Interface->Enable Server Ports"
+.br
+.PP
+.B TCP:2023
+Bidirectional TCP port for clients to connect to.  Requires login if
+client will be transmitting.
+.br
+.B UDP:2023
+Unidirectional UDP input port for clients to inject packets.  See
+the documentation for the format.
+.br
+.SH "SEE ALSO"
+The program is documented fully by
+.IR "help-English.dat" ,
+available via the HELP menu option in Xastir, plus the various
+README and INSTALL text files that come with the program.  Also see
+<http://www.xastir.org> and the Documentation Wiki there.
+.br
+.PP
+.B Xastir
+is a program for APRS(tm)...
+.br
+.PP
+.B APRS[tm]
+is a Trademark of Bob Bruninga, his home page is at
+"http://www.aprs.org/aprs.html"
+.SH COPYING
+Copyright (C) 1999,2000 Frank Giannandrea KC2GJS
+.br
+Copyright (C) 2000-2012 The Xastir Group
+.SH AUTHOR
+This manual page was written by Jose <hi8gn at amsat.org>,
+for the Debian GNU/Linux system (but may be used by others).
diff --git a/xastir.spec b/xastir.spec
new file mode 100644
index 0000000..65f22ae
--- /dev/null
+++ b/xastir.spec
@@ -0,0 +1,77 @@
+Summary   : Amateur Station Tracking and Reporting system for amateur radio
+Name      : xastir
+Version   : 2.0.4
+Release   : 1
+#Epoch    : 1
+License   : GPL
+Group     : Applications/Networking
+Packager  : n2ygk at weca.org
+# Icon    : src/xastir.xpm
+Source    : http://prdownloads.sourceforge.net/xastir/xastir-2.0.4.tar.gz
+URL       : http://www.xastir.org
+BuildRoot : %{_tmppath}/%{name}-buildroot
+#Requires  :
+
+%description
+Xastir is a graphical application that interfaces HAM radio
+and internet access to realtime mapping software.
+
+Install XASTIR if you are interested in APRS(tm) and HAM radio
+software.
+
+%prep
+%setup -q
+#%patch
+
+%build
+./bootstrap.sh
+%configure --without-graphicsmagick --with-rtree
+make
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+%makeinstall
+# Docs go into package docs area instead of the Makefile install
+# locations listed here:
+rm -rf ${RPM_BUILD_ROOT}/usr/share/doc
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%files
+%defattr(-,root,root)
+
+# Documents:  Go into special doc area at /usr/share/doc/xastir/ or
+# /usr/share/doc/packages/xastir/
+%doc AUTHORS ChangeLog COPYING DEBUG_LEVELS FAQ INSTALL LICENSE
+%doc README README.Contributing README.CVS README.Getting-Started
+%doc README.MAPS README.win32 UPGRADE
+
+
+%{_prefix}/bin
+%{_prefix}/share/xastir/help
+%{_prefix}/share/xastir/config
+%{_prefix}/share/xastir/symbols
+%{_prefix}/share/man
+%{_prefix}/%{lib}/xastir
+
+# protect user-installed map and other files from being clobbered
+
+%config %{_prefix}/share/xastir/maps
+%dir %attr(666,root,root) %{_prefix}/share/xastir/maps/GPS
+%config %{_prefix}/share/xastir/Counties
+%config %{_prefix}/share/xastir/fcc
+%config %{_prefix}/share/xastir/GNIS
+%config %{_prefix}/share/xastir/sounds
+
+%changelog
+* Thu Jul 03 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.1 my patches now integrated into the main trunk.
+* Sat Jun 21 2003 Alan Crosswell <n2ygk at weca.org> 
+- added xastir-maps.patch
+* Mon Jun 16 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.0
+* Fri Jun 06 2003 Alan Crosswell <n2ygk at weca.org> 
+- June 5 snapshot
+* Thu May 15 2003 Alan Crosswell <n2ygk at weca.org> 
+- start with chuck's spec file for 1.1.4
diff --git a/xastir.spec.in b/xastir.spec.in
new file mode 100644
index 0000000..706511a
--- /dev/null
+++ b/xastir.spec.in
@@ -0,0 +1,77 @@
+Summary   : Amateur Station Tracking and Reporting system for amateur radio
+Name      : @PACKAGE@
+Version   : @VERSION@
+Release   : 1
+#Epoch    : 1
+License   : GPL
+Group     : Applications/Networking
+Packager  : n2ygk at weca.org
+# Icon    : src/@PACKAGE at .xpm
+Source    : http://prdownloads.sourceforge.net/@PACKAGE@/@PACKAGE@-@VERSION@.tar.gz
+URL       : http://www.xastir.org
+BuildRoot : %{_tmppath}/%{name}-buildroot
+#Requires  :
+
+%description
+Xastir is a graphical application that interfaces HAM radio
+and internet access to realtime mapping software.
+
+Install XASTIR if you are interested in APRS(tm) and HAM radio
+software.
+
+%prep
+%setup -q
+#%patch
+
+%build
+./bootstrap.sh
+%configure --without-graphicsmagick --with-rtree
+make
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+%makeinstall
+# Docs go into package docs area instead of the Makefile install
+# locations listed here:
+rm -rf ${RPM_BUILD_ROOT}/usr/share/doc
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%files
+%defattr(-,root,root)
+
+# Documents:  Go into special doc area at /usr/share/doc/xastir/ or
+# /usr/share/doc/packages/xastir/
+%doc AUTHORS ChangeLog COPYING DEBUG_LEVELS FAQ INSTALL LICENSE
+%doc README README.Contributing README.CVS README.Getting-Started
+%doc README.MAPS README.win32 UPGRADE
+
+
+%{_prefix}/bin
+%{_prefix}/share/xastir/help
+%{_prefix}/share/xastir/config
+%{_prefix}/share/xastir/symbols
+%{_prefix}/share/man
+%{_prefix}/%{lib}/xastir
+
+# protect user-installed map and other files from being clobbered
+
+%config %{_prefix}/share/xastir/maps
+%dir %attr(666,root,root) %{_prefix}/share/xastir/maps/GPS
+%config %{_prefix}/share/xastir/Counties
+%config %{_prefix}/share/xastir/fcc
+%config %{_prefix}/share/xastir/GNIS
+%config %{_prefix}/share/xastir/sounds
+
+%changelog
+* Thu Jul 03 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.1 my patches now integrated into the main trunk.
+* Sat Jun 21 2003 Alan Crosswell <n2ygk at weca.org> 
+- added xastir-maps.patch
+* Mon Jun 16 2003 Alan Crosswell <n2ygk at weca.org> 
+- 1.2.0
+* Fri Jun 06 2003 Alan Crosswell <n2ygk at weca.org> 
+- June 5 snapshot
+* Thu May 15 2003 Alan Crosswell <n2ygk at weca.org> 
+- start with chuck's spec file for 1.1.4
diff --git a/xastir_udp_client.1 b/xastir_udp_client.1
new file mode 100644
index 0000000..cce85c2
--- /dev/null
+++ b/xastir_udp_client.1
@@ -0,0 +1,43 @@
+.TH xastir_udp_client 1 2009-12-22 "The Xastir Group"
+
+.SH NAME
+xastir_udp_client \- send simple messages to xastir for APRS(tm) network.
+
+.SH SYNOPSIS
+.B xastir_udp_client
+.I <hostname> <port> <callsign> <passcode> {-identify | [-to_rf] <message>}
+
+.SH DESCRIPTION
+
+xastir_udp_client sends packets into the UDP listening port of an enabled xastir instance.
+
+.SH EXAMPLES
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> "APRS Packet Goes Here"
+
+Currently that will inject the packet into Xastir's decoding routines and send
+it to any TCP-connected clients. It will also igate it to the INET if you have
+igating enabled.  It will send the packet out the RF ports as third-party
+packets only if you add the "\-to_rf" flag after the passcode like this:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> \-to_rf "APRS Packet"
+
+The UDP client is useful for generating and injecting APRS packets from
+external scripts.  It can also be used to fetch the callsign of the remote
+xastir server by using the \-identify flag:
+
+ xastir_udp_client localhost 2023 <callsign> <passcode> \-identify
+
+.SH NOTES
+This is a very simple utility that provides no validation of message content.
+
+.SH SEE ALSO
+xastir help file
+.br
+.PP
+.B APRS[tm]
+is a Trademark of Bob Bruninga, his home page is at "http://www.aprs.org/aprs.html"
+.SH COPYING
+Copyright (C) 1999,2000 Frank Giannandrea KC2GJS
+.br
+Copyright (C) 2000-2012 The Xastir Group

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/xastir.git



More information about the pkg-hamradio-commits mailing list